diff --git a/.mailmap b/.mailmap index 7e6c5334c337ae0c792a36ec5a2e9309b4128061..90c0aefc276d4c2444098fba232e3f8e2f200ae0 100644 --- a/.mailmap +++ b/.mailmap @@ -33,6 +33,7 @@ Björn Steinbrink Brian Avery Brian King Christoph Hellwig +Christophe Ricard Corey Minyard Damian Hobson-Garcia David Brownell diff --git a/CREDITS b/CREDITS index a3887b59b9f94dffce186079756b29d01fb7b91b..4312cd076b5b4306f2a799e4d12bb8db15f0f011 100644 --- a/CREDITS +++ b/CREDITS @@ -3054,6 +3054,7 @@ D: PLX USB338x driver D: PCA9634 driver D: Option GTM671WFS D: Fintek F81216A +D: AD5761 iio driver D: Various kernel hacks S: Qtechnology A/S S: Valby Langgade 142 diff --git a/Documentation/ABI/obsolete/sysfs-class-rfkill b/Documentation/ABI/obsolete/sysfs-class-rfkill deleted file mode 100644 index ff60ad9eca4c7ba390e22bd0eda0378bfbe236f1..0000000000000000000000000000000000000000 --- a/Documentation/ABI/obsolete/sysfs-class-rfkill +++ /dev/null @@ -1,29 +0,0 @@ -rfkill - radio frequency (RF) connector kill switch support - -For details to this subsystem look at Documentation/rfkill.txt. - -What: /sys/class/rfkill/rfkill[0-9]+/state -Date: 09-Jul-2007 -KernelVersion v2.6.22 -Contact: linux-wireless@vger.kernel.org -Description: Current state of the transmitter. - This file is deprecated and scheduled to be removed in 2014, - because its not possible to express the 'soft and hard block' - state of the rfkill driver. -Values: A numeric value. - 0: RFKILL_STATE_SOFT_BLOCKED - transmitter is turned off by software - 1: RFKILL_STATE_UNBLOCKED - transmitter is (potentially) active - 2: RFKILL_STATE_HARD_BLOCKED - transmitter is forced off by something outside of - the driver's control. - -What: /sys/class/rfkill/rfkill[0-9]+/claim -Date: 09-Jul-2007 -KernelVersion v2.6.22 -Contact: linux-wireless@vger.kernel.org -Description: This file is deprecated because there no longer is a way to - claim just control over a single rfkill instance. - This file is scheduled to be removed in 2012. -Values: 0: Kernel handles events diff --git a/Documentation/ABI/removed/sysfs-class-rfkill b/Documentation/ABI/removed/sysfs-class-rfkill new file mode 100644 index 0000000000000000000000000000000000000000..3ce6231f20b251fc46b15c803f8001f1c9c53d3c --- /dev/null +++ b/Documentation/ABI/removed/sysfs-class-rfkill @@ -0,0 +1,13 @@ +rfkill - radio frequency (RF) connector kill switch support + +For details to this subsystem look at Documentation/rfkill.txt. + +What: /sys/class/rfkill/rfkill[0-9]+/claim +Date: 09-Jul-2007 +KernelVersion v2.6.22 +Contact: linux-wireless@vger.kernel.org +Description: This file was deprecated because there no longer was a way to + claim just control over a single rfkill instance. + This file was scheduled to be removed in 2012, and was removed + in 2016. +Values: 0: Kernel handles events diff --git a/Documentation/ABI/stable/firewire-cdev b/Documentation/ABI/stable/firewire-cdev index 16d030827368b2c49cbbe396588635dfa69d6c08..f72ed653878a619c62720b17c8428ba208842170 100644 --- a/Documentation/ABI/stable/firewire-cdev +++ b/Documentation/ABI/stable/firewire-cdev @@ -100,4 +100,5 @@ Description: Users: libraw1394 libdc1394 - tools like jujuutils, fwhack, ... + libhinawa + tools like linux-firewire-utils, fwhack, ... diff --git a/Documentation/ABI/stable/sysfs-class-rfkill b/Documentation/ABI/stable/sysfs-class-rfkill index 097f522c33bb7b5c3632a9ca200e099fea32b2cf..e1ba4a10475364cd8fcf201b323c26de5ee8b62b 100644 --- a/Documentation/ABI/stable/sysfs-class-rfkill +++ b/Documentation/ABI/stable/sysfs-class-rfkill @@ -2,9 +2,8 @@ rfkill - radio frequency (RF) connector kill switch support For details to this subsystem look at Documentation/rfkill.txt. -For the deprecated /sys/class/rfkill/*/state and -/sys/class/rfkill/*/claim knobs of this interface look in -Documentation/ABI/obsolete/sysfs-class-rfkill. +For the deprecated /sys/class/rfkill/*/claim knobs of this interface look in +Documentation/ABI/removed/sysfs-class-rfkill. What: /sys/class/rfkill Date: 09-Jul-2007 @@ -42,6 +41,28 @@ Values: A numeric value. 1: true +What: /sys/class/rfkill/rfkill[0-9]+/state +Date: 09-Jul-2007 +KernelVersion v2.6.22 +Contact: linux-wireless@vger.kernel.org +Description: Current state of the transmitter. + This file was scheduled to be removed in 2014, but due to its + large number of users it will be sticking around for a bit + longer. Despite it being marked as stabe, the newer "hard" and + "soft" interfaces should be preffered, since it is not possible + to express the 'soft and hard block' state of the rfkill driver + through this interface. There will likely be another attempt to + remove it in the future. +Values: A numeric value. + 0: RFKILL_STATE_SOFT_BLOCKED + transmitter is turned off by software + 1: RFKILL_STATE_UNBLOCKED + transmitter is (potentially) active + 2: RFKILL_STATE_HARD_BLOCKED + transmitter is forced off by something outside of + the driver's control. + + What: /sys/class/rfkill/rfkill[0-9]+/hard Date: 12-March-2010 KernelVersion v2.6.34 diff --git a/Documentation/ABI/stable/sysfs-fs-orangefs b/Documentation/ABI/stable/sysfs-fs-orangefs new file mode 100644 index 0000000000000000000000000000000000000000..affdb114bd3310e4fc97297bdebd01b22cfbd708 --- /dev/null +++ b/Documentation/ABI/stable/sysfs-fs-orangefs @@ -0,0 +1,87 @@ +What: /sys/fs/orangefs/perf_counters/* +Date: Jun 2015 +Contact: Mike Marshall +Description: + Counters and settings for various caches. + Read only. + + +What: /sys/fs/orangefs/perf_counter_reset +Date: June 2015 +Contact: Mike Marshall +Description: + echo a 0 or a 1 into perf_counter_reset to + reset all the counters in + /sys/fs/orangefs/perf_counters + except ones with PINT_PERF_PRESERVE set. + + +What: /sys/fs/orangefs/perf_time_interval_secs +Date: Jun 2015 +Contact: Mike Marshall +Description: + Length of perf counter intervals in + seconds. + + +What: /sys/fs/orangefs/perf_history_size +Date: Jun 2015 +Contact: Mike Marshall +Description: + The perf_counters cache statistics have N, or + perf_history_size, samples. The default is + one. + + Every perf_time_interval_secs the (first) + samples are reset. + + If N is greater than one, the "current" set + of samples is reset, and the samples from the + other N-1 intervals remain available. + + +What: /sys/fs/orangefs/op_timeout_secs +Date: Jun 2015 +Contact: Mike Marshall +Description: + Service operation timeout in seconds. + + +What: /sys/fs/orangefs/slot_timeout_secs +Date: Jun 2015 +Contact: Mike Marshall +Description: + "Slot" timeout in seconds. A "slot" + is an indexed buffer in the shared + memory segment used for communication + between the kernel module and userspace. + Slots are requested and waited for, + the wait times out after slot_timeout_secs. + + +What: /sys/fs/orangefs/acache/* +Date: Jun 2015 +Contact: Mike Marshall +Description: + Attribute cache configurable settings. + + +What: /sys/fs/orangefs/ncache/* +Date: Jun 2015 +Contact: Mike Marshall +Description: + Name cache configurable settings. + + +What: /sys/fs/orangefs/capcache/* +Date: Jun 2015 +Contact: Mike Marshall +Description: + Capability cache configurable settings. + + +What: /sys/fs/orangefs/ccache/* +Date: Jun 2015 +Contact: Mike Marshall +Description: + Credential cache configurable settings. diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio index 0439c2aaf7419867c1dce0c223190530eb970d70..3c66248813750f2016d6c1a541489e359bfaf0d0 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio +++ b/Documentation/ABI/testing/sysfs-bus-iio @@ -496,8 +496,11 @@ Description: 1kohm_to_gnd: connected to ground via an 1kOhm resistor, 6kohm_to_gnd: connected to ground via a 6kOhm resistor, 20kohm_to_gnd: connected to ground via a 20kOhm resistor, + 90kohm_to_gnd: connected to ground via a 90kOhm resistor, 100kohm_to_gnd: connected to ground via an 100kOhm resistor, + 125kohm_to_gnd: connected to ground via an 125kOhm resistor, 500kohm_to_gnd: connected to ground via a 500kOhm resistor, + 640kohm_to_gnd: connected to ground via a 640kOhm resistor, three_state: left floating. For a list of available output power down options read outX_powerdown_mode_available. If Y is not present the @@ -1491,3 +1494,10 @@ Description: This ABI is especially applicable for humidity sensors to heatup the device and get rid of any condensation in some humidity environment + +What: /sys/bus/iio/devices/iio:deviceX/in_ph_raw +KernelVersion: 4.5 +Contact: linux-iio@vger.kernel.org +Description: + Raw (unscaled no offset etc.) pH reading of a substance as a negative + base-10 logarithm of hydrodium ions in a litre of water. diff --git a/Documentation/ABI/testing/sysfs-bus-iio-health-afe440x b/Documentation/ABI/testing/sysfs-bus-iio-health-afe440x new file mode 100644 index 0000000000000000000000000000000000000000..3740f253d406975ca7a6d13ebb96acd2cfc5d8f8 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-iio-health-afe440x @@ -0,0 +1,54 @@ +What: /sys/bus/iio/devices/iio:deviceX/tia_resistanceY + /sys/bus/iio/devices/iio:deviceX/tia_capacitanceY +Date: December 2015 +KernelVersion: +Contact: Andrew F. Davis +Description: + Get and set the resistance and the capacitance settings for the + Transimpedance Amplifier. Y is 1 for Rf1 and Cf1, Y is 2 for + Rf2 and Cf2 values. + +What: /sys/bus/iio/devices/iio:deviceX/tia_separate_en +Date: December 2015 +KernelVersion: +Contact: Andrew F. Davis +Description: + Enable or disable separate settings for the TransImpedance + Amplifier above, when disabled both values are set by the + first channel. + +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_ledY_raw + /sys/bus/iio/devices/iio:deviceX/in_intensity_ledY_ambient_raw +Date: December 2015 +KernelVersion: +Contact: Andrew F. Davis +Description: + Get measured values from the ADC for these stages. Y is the + specific LED number. The values are expressed in 24-bit twos + complement. + +What: /sys/bus/iio/devices/iio:deviceX/in_intensity_ledY-ledY_ambient_raw +Date: December 2015 +KernelVersion: +Contact: Andrew F. Davis +Description: + Get differential values from the ADC for these stages. Y is the + specific LED number. The values are expressed in 24-bit twos + complement for the specified LEDs. + +What: /sys/bus/iio/devices/iio:deviceX/out_current_ledY_offset + /sys/bus/iio/devices/iio:deviceX/out_current_ledY_ambient_offset +Date: December 2015 +KernelVersion: +Contact: Andrew F. Davis +Description: + Get and set the offset cancellation DAC setting for these + stages. The values are expressed in 5-bit sign-magnitude. + +What: /sys/bus/iio/devices/iio:deviceX/out_current_ledY_raw +Date: December 2015 +KernelVersion: +Contact: Andrew F. Davis +Description: + Get and set the LED current for the specified LED. Y is the + specific LED number. diff --git a/Documentation/ABI/testing/sysfs-bus-iio-magnetometer-hmc5843 b/Documentation/ABI/testing/sysfs-bus-iio-magnetometer-hmc5843 new file mode 100644 index 0000000000000000000000000000000000000000..6275e9f56e6c3d668d8429df3986a2f3625696e7 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-iio-magnetometer-hmc5843 @@ -0,0 +1,15 @@ +What: /sys/bus/iio/devices/iio:deviceX/meas_conf +What: /sys/bus/iio/devices/iio:deviceX/meas_conf_available +KernelVersion: 4.5 +Contact: linux-iio@vger.kernel.org +Description: + Current configuration and available configurations + for the bias current. + normal - Normal measurement configurations (default) + positivebias - Positive bias configuration + negativebias - Negative bias configuration + disabled - Only available on HMC5983. Disables magnetic + sensor and enables temperature sensor. + Note: The effect of this configuration may vary + according to the device. For exact documentation + check the device's datasheet. diff --git a/Documentation/ABI/testing/sysfs-bus-iio-vf610 b/Documentation/ABI/testing/sysfs-bus-iio-vf610 index ecbc1f4af921c3daba3b9ba7618b42ad03eb8356..308a6756d3bf3fab4812b2edb735b5978ccc4e5a 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio-vf610 +++ b/Documentation/ABI/testing/sysfs-bus-iio-vf610 @@ -5,3 +5,12 @@ Description: Specifies the hardware conversion mode used. The three available modes are "normal", "high-speed" and "low-power", where the last is the default mode. + + +What: /sys/bus/iio/devices/iio:deviceX/out_conversion_mode +KernelVersion: 4.6 +Contact: linux-iio@vger.kernel.org +Description: + Specifies the hardware conversion mode used within DAC. + The two available modes are "high-power" and "low-power", + where "low-power" mode is the default mode. diff --git a/Documentation/ABI/testing/sysfs-class-cxl b/Documentation/ABI/testing/sysfs-class-cxl index b07e86d4597f2196207b9f0e14617e4bcd461d44..7fd737eed38acd7f794daea91d9561a435a67e00 100644 --- a/Documentation/ABI/testing/sysfs-class-cxl +++ b/Documentation/ABI/testing/sysfs-class-cxl @@ -159,7 +159,7 @@ Description: read only Decimal value of the Per Process MMIO space length. Users: https://github.com/ibm-capi/libcxl -What: /sys/class/cxl/m/pp_mmio_off +What: /sys/class/cxl/m/pp_mmio_off (not in a guest) Date: September 2014 Contact: linuxppc-dev@lists.ozlabs.org Description: read only @@ -183,7 +183,7 @@ Description: read only Identifies the revision level of the PSL. Users: https://github.com/ibm-capi/libcxl -What: /sys/class/cxl//base_image +What: /sys/class/cxl//base_image (not in a guest) Date: September 2014 Contact: linuxppc-dev@lists.ozlabs.org Description: read only @@ -193,7 +193,7 @@ Description: read only during the initial program load. Users: https://github.com/ibm-capi/libcxl -What: /sys/class/cxl//image_loaded +What: /sys/class/cxl//image_loaded (not in a guest) Date: September 2014 Contact: linuxppc-dev@lists.ozlabs.org Description: read only @@ -201,7 +201,7 @@ Description: read only onto the card. Users: https://github.com/ibm-capi/libcxl -What: /sys/class/cxl//load_image_on_perst +What: /sys/class/cxl//load_image_on_perst (not in a guest) Date: December 2014 Contact: linuxppc-dev@lists.ozlabs.org Description: read/write @@ -224,7 +224,7 @@ Description: write only to reload the FPGA depending on load_image_on_perst. Users: https://github.com/ibm-capi/libcxl -What: /sys/class/cxl//perst_reloads_same_image +What: /sys/class/cxl//perst_reloads_same_image (not in a guest) Date: July 2015 Contact: linuxppc-dev@lists.ozlabs.org Description: read/write diff --git a/Documentation/ABI/testing/sysfs-class-net-batman-adv b/Documentation/ABI/testing/sysfs-class-net-batman-adv index 7f34a95bb9634c9d8d1d9505d31b68c36bc58f76..518f6a1dbc0c0b7009fc5fbea85064b22a48b60e 100644 --- a/Documentation/ABI/testing/sysfs-class-net-batman-adv +++ b/Documentation/ABI/testing/sysfs-class-net-batman-adv @@ -1,4 +1,20 @@ +What: /sys/class/net//batman-adv/throughput_override +Date: Feb 2014 +Contact: Antonio Quartulli +description: + Defines the throughput value to be used by B.A.T.M.A.N. V + when estimating the link throughput using this interface. + If the value is set to 0 then batman-adv will try to + estimate the throughput by itself. + +What: /sys/class/net//batman-adv/elp_interval +Date: Feb 2014 +Contact: Linus Lüssing +Description: + Defines the interval in milliseconds in which batman + sends its probing packets for link quality measurements. + What: /sys/class/net//batman-adv/iface_status Date: May 2010 Contact: Marek Lindner @@ -12,4 +28,3 @@ Description: The /sys/class/net//batman-adv/mesh_iface file displays the batman mesh interface this currently is associated with. - diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu index b683e8ee69ecc59a353c700330b7162f50652123..16501334b99fe88544534274c837b822a03d0d70 100644 --- a/Documentation/ABI/testing/sysfs-devices-system-cpu +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu @@ -271,3 +271,72 @@ Description: Parameters for the CPU cache attributes - WriteBack: data is written only to the cache line and the modified cache line is written to main memory only when it is replaced + +What: /sys/devices/system/cpu/cpuX/cpufreq/throttle_stats + /sys/devices/system/cpu/cpuX/cpufreq/throttle_stats/turbo_stat + /sys/devices/system/cpu/cpuX/cpufreq/throttle_stats/sub_turbo_stat + /sys/devices/system/cpu/cpuX/cpufreq/throttle_stats/unthrottle + /sys/devices/system/cpu/cpuX/cpufreq/throttle_stats/powercap + /sys/devices/system/cpu/cpuX/cpufreq/throttle_stats/overtemp + /sys/devices/system/cpu/cpuX/cpufreq/throttle_stats/supply_fault + /sys/devices/system/cpu/cpuX/cpufreq/throttle_stats/overcurrent + /sys/devices/system/cpu/cpuX/cpufreq/throttle_stats/occ_reset +Date: March 2016 +Contact: Linux kernel mailing list + Linux for PowerPC mailing list +Description: POWERNV CPUFreq driver's frequency throttle stats directory and + attributes + + 'cpuX/cpufreq/throttle_stats' directory contains the CPU frequency + throttle stat attributes for the chip. The throttle stats of a cpu + is common across all the cpus belonging to a chip. Below are the + throttle attributes exported in the 'throttle_stats' directory: + + - turbo_stat : This file gives the total number of times the max + frequency is throttled to lower frequency in turbo (at and above + nominal frequency) range of frequencies. + + - sub_turbo_stat : This file gives the total number of times the + max frequency is throttled to lower frequency in sub-turbo(below + nominal frequency) range of frequencies. + + - unthrottle : This file gives the total number of times the max + frequency is unthrottled after being throttled. + + - powercap : This file gives the total number of times the max + frequency is throttled due to 'Power Capping'. + + - overtemp : This file gives the total number of times the max + frequency is throttled due to 'CPU Over Temperature'. + + - supply_fault : This file gives the total number of times the + max frequency is throttled due to 'Power Supply Failure'. + + - overcurrent : This file gives the total number of times the + max frequency is throttled due to 'Overcurrent'. + + - occ_reset : This file gives the total number of times the max + frequency is throttled due to 'OCC Reset'. + + The sysfs attributes representing different throttle reasons like + powercap, overtemp, supply_fault, overcurrent and occ_reset map to + the reasons provided by OCC firmware for throttling the frequency. + +What: /sys/devices/system/cpu/cpufreq/policyX/throttle_stats + /sys/devices/system/cpu/cpufreq/policyX/throttle_stats/turbo_stat + /sys/devices/system/cpu/cpufreq/policyX/throttle_stats/sub_turbo_stat + /sys/devices/system/cpu/cpufreq/policyX/throttle_stats/unthrottle + /sys/devices/system/cpu/cpufreq/policyX/throttle_stats/powercap + /sys/devices/system/cpu/cpufreq/policyX/throttle_stats/overtemp + /sys/devices/system/cpu/cpufreq/policyX/throttle_stats/supply_fault + /sys/devices/system/cpu/cpufreq/policyX/throttle_stats/overcurrent + /sys/devices/system/cpu/cpufreq/policyX/throttle_stats/occ_reset +Date: March 2016 +Contact: Linux kernel mailing list + Linux for PowerPC mailing list +Description: POWERNV CPUFreq driver's frequency throttle stats directory and + attributes + + 'policyX/throttle_stats' directory and all the attributes are same as + the /sys/devices/system/cpu/cpuX/cpufreq/throttle_stats directory and + attributes which give the frequency throttle information of the chip. diff --git a/Documentation/ABI/testing/sysfs-driver-toshiba_acpi b/Documentation/ABI/testing/sysfs-driver-toshiba_acpi index eed922ef42e533ae9bf16da6d224a50d2b46e16b..f34221b52b14b796377893207692c48ddaabf7fb 100644 --- a/Documentation/ABI/testing/sysfs-driver-toshiba_acpi +++ b/Documentation/ABI/testing/sysfs-driver-toshiba_acpi @@ -179,3 +179,19 @@ Description: This file controls the USB 3 functionality, valid values are: Note that toggling this value requires a reboot for changes to take effect. Users: KToshiba + +What: /sys/devices/LNXSYSTM:00/LNXSYBUS:00/TOS{1900,620{0,7,8}}:00/cooling_method +Date: 2016 +KernelVersion: 4.6 +Contact: Azael Avalos +Description: This file controls the Cooling Method feature. + Reading this file prints two values, the first is the actual cooling method + and the second is the maximum cooling method supported. + When the maximum cooling method is ONE, valid values are: + * 0 -> Maximum Performance + * 1 -> Battery Optimized + When the maximum cooling method is TWO, valid values are: + * 0 -> Maximum Performance + * 1 -> Performance + * 2 -> Battery Optimized +Users: KToshiba diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs index e5200f354abfe933d3fbe69f919da2dcc0e585a6..a809f6005f1464ed7c86133db7b4b95d4a3c7388 100644 --- a/Documentation/ABI/testing/sysfs-fs-f2fs +++ b/Documentation/ABI/testing/sysfs-fs-f2fs @@ -98,3 +98,17 @@ Date: October 2015 Contact: "Chao Yu" Description: Controls the count of nid pages to be readaheaded. + +What: /sys/fs/f2fs//dirty_nats_ratio +Date: January 2016 +Contact: "Chao Yu" +Description: + Controls dirty nat entries ratio threshold, if current + ratio exceeds configured threshold, checkpoint will + be triggered for flushing dirty nat entries. + +What: /sys/fs/f2fs//lifetime_write_kbytes +Date: January 2016 +Contact: "Shuoran Liu" +Description: + Shows total written kbytes issued to disk. diff --git a/Documentation/ABI/testing/sysfs-platform-i2c-demux-pinctrl b/Documentation/ABI/testing/sysfs-platform-i2c-demux-pinctrl new file mode 100644 index 0000000000000000000000000000000000000000..3c3514815cd53bada6852068370d7cd193be9293 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-platform-i2c-demux-pinctrl @@ -0,0 +1,18 @@ +What: /sys/devices/platform//available_masters +Date: January 2016 +KernelVersion: 4.6 +Contact: Wolfram Sang +Description: + Reading the file will give you a list of masters which can be + selected for a demultiplexed bus. The format is + ":". Example from a Renesas Lager board: + + 0:/i2c@e6500000 1:/i2c@e6508000 + +What: /sys/devices/platform//current_master +Date: January 2016 +KernelVersion: 4.6 +Contact: Wolfram Sang +Description: + This file selects/shows the active I2C master for a demultiplexed + bus. It uses the value from the file 'available_masters'. diff --git a/Documentation/DMA-attributes.txt b/Documentation/DMA-attributes.txt index 18dc52c4f2a0b13a42d9867c36c94f4774bf58e2..e8cf9cf873b37577eeed325b4b7cc8dc0710ec9a 100644 --- a/Documentation/DMA-attributes.txt +++ b/Documentation/DMA-attributes.txt @@ -100,3 +100,29 @@ allocated by dma_alloc_attrs() function from individual pages if it can be mapped as contiguous chunk into device dma address space. By specifying this attribute the allocated buffer is forced to be contiguous also in physical memory. + +DMA_ATTR_ALLOC_SINGLE_PAGES +--------------------------- + +This is a hint to the DMA-mapping subsystem that it's probably not worth +the time to try to allocate memory to in a way that gives better TLB +efficiency (AKA it's not worth trying to build the mapping out of larger +pages). You might want to specify this if: +- You know that the accesses to this memory won't thrash the TLB. + You might know that the accesses are likely to be sequential or + that they aren't sequential but it's unlikely you'll ping-pong + between many addresses that are likely to be in different physical + pages. +- You know that the penalty of TLB misses while accessing the + memory will be small enough to be inconsequential. If you are + doing a heavy operation like decryption or decompression this + might be the case. +- You know that the DMA mapping is fairly transitory. If you expect + the mapping to have a short lifetime then it may be worth it to + optimize allocation (avoid coming up with large pages) instead of + getting the slight performance win of larger pages. +Setting this hint doesn't guarantee that you won't get huge pages, but it +means that we won't try quite as hard to get them. + +NOTE: At the moment DMA_ATTR_ALLOC_SINGLE_PAGES is only implemented on ARM, +though ARM64 patches will likely be posted soon. diff --git a/Documentation/DocBook/gpu.tmpl b/Documentation/DocBook/gpu.tmpl index a8669330b456eff026895af70af1121559998d2e..1692c4dd548727867d1c6fa4de3878cf8a30d6a8 100644 --- a/Documentation/DocBook/gpu.tmpl +++ b/Documentation/DocBook/gpu.tmpl @@ -1816,7 +1816,7 @@ void intel_crt_init(struct drm_device *dev) Description/Restrictions - DRM + DRM Generic “rotation” BITMASK @@ -2068,7 +2068,7 @@ void intel_crt_init(struct drm_device *dev) property to suggest an Y offset for a connector - Optional + Optional “scaling mode” ENUM { "None", "Full", "Center", "Full aspect" } @@ -2092,6 +2092,61 @@ void intel_crt_init(struct drm_device *dev) TBD + “DEGAMMA_LUT” + BLOB + 0 + CRTC + DRM property to set the degamma lookup table + (LUT) mapping pixel data from the framebuffer before it is + given to the transformation matrix. The data is an interpreted + as an array of struct drm_color_lut elements. Hardware might + choose not to use the full precision of the LUT elements nor + use all the elements of the LUT (for example the hardware + might choose to interpolate between LUT[0] and LUT[4]). + + + “DEGAMMA_LUT_SIZE” + RANGE | IMMUTABLE + Min=0, Max=UINT_MAX + CRTC + DRM property to gives the size of the lookup + table to be set on the DEGAMMA_LUT property (the size depends + on the underlying hardware). + + + “CTM” + BLOB + 0 + CRTC + DRM property to set the current + transformation matrix (CTM) apply to pixel data after the + lookup through the degamma LUT and before the lookup through + the gamma LUT. The data is an interpreted as a struct + drm_color_ctm. + + + “GAMMA_LUT” + BLOB + 0 + CRTC + DRM property to set the gamma lookup table + (LUT) mapping pixel data after to the transformation matrix to + data sent to the connector. The data is an interpreted as an + array of struct drm_color_lut elements. Hardware might choose + not to use the full precision of the LUT elements nor use all + the elements of the LUT (for example the hardware might choose + to interpolate between LUT[0] and LUT[4]). + + + “GAMMA_LUT_SIZE” + RANGE | IMMUTABLE + Min=0, Max=UINT_MAX + CRTC + DRM property to gives the size of the lookup + table to be set on the GAMMA_LUT property (the size depends on + the underlying hardware). + + i915 Generic "Broadcast RGB" @@ -2886,52 +2941,8 @@ void (*postclose) (struct drm_device *, struct drm_file *); File Operations - const struct file_operations *fops - File operations for the DRM device node. - - Drivers must define the file operations structure that forms the DRM - userspace API entry point, even though most of those operations are - implemented in the DRM core. The open, - release and ioctl - operations are handled by - - .owner = THIS_MODULE, - .open = drm_open, - .release = drm_release, - .unlocked_ioctl = drm_ioctl, - #ifdef CONFIG_COMPAT - .compat_ioctl = drm_compat_ioctl, - #endif - - - - Drivers that implement private ioctls that requires 32/64bit - compatibility support must provide their own - compat_ioctl handler that processes private - ioctls and calls drm_compat_ioctl for core ioctls. - - - The read and poll - operations provide support for reading DRM events and polling them. They - are implemented by - - .poll = drm_poll, - .read = drm_read, - .llseek = no_llseek, - - - - The memory mapping implementation varies depending on how the driver - manages memory. Pre-GEM drivers will use drm_mmap, - while GEM-aware drivers will use drm_gem_mmap. See - . - - .mmap = drm_gem_mmap, - - - - No other file operation is supported by the DRM API. - +!Pdrivers/gpu/drm/drm_fops.c file operations +!Edrivers/gpu/drm/drm_fops.c IOCTLs @@ -3319,6 +3330,12 @@ int num_ioctls; !Pdrivers/gpu/drm/i915/intel_csr.c csr support for dmc !Idrivers/gpu/drm/i915/intel_csr.c + + Video BIOS Table (VBT) +!Pdrivers/gpu/drm/i915/intel_bios.c Video BIOS Table (VBT) +!Idrivers/gpu/drm/i915/intel_bios.c +!Idrivers/gpu/drm/i915/intel_bios.h + @@ -3460,6 +3477,7 @@ int num_ioctls; Public constants +!Finclude/linux/vga_switcheroo.h vga_switcheroo_handler_flags_t !Finclude/linux/vga_switcheroo.h vga_switcheroo_client_id !Finclude/linux/vga_switcheroo.h vga_switcheroo_state @@ -3488,6 +3506,10 @@ int num_ioctls; Backlight control !Pdrivers/platform/x86/apple-gmux.c Backlight control + + Public functions +!Iinclude/linux/apple-gmux.h + diff --git a/Documentation/arm/Marvell/README b/Documentation/arm/Marvell/README index ae89b67d8e23c6c2ae8b05511c6a3049208961ab..b5bb7f5188406f8b47a0b55d921512c06dcf817f 100644 --- a/Documentation/arm/Marvell/README +++ b/Documentation/arm/Marvell/README @@ -22,7 +22,7 @@ Orion family 88F5281 Datasheet : http://www.ocmodshop.com/images/reviews/networking/qnap_ts409u/marvel_88f5281_data_sheet.pdf 88F6183 - Core: Feroceon ARMv5 compatible + Core: Feroceon 88fr331 (88f51xx) or 88fr531-vd (88f52xx) ARMv5 compatible Linux kernel mach directory: arch/arm/mach-orion5x Linux kernel plat directory: arch/arm/plat-orion @@ -52,7 +52,7 @@ Kirkwood family Hardware Spec : http://www.marvell.com/embedded-processors/kirkwood/assets/HW_88F6281_OpenSource.pdf Functional Spec: http://www.marvell.com/embedded-processors/kirkwood/assets/FS_88F6180_9x_6281_OpenSource.pdf Homepage: http://www.marvell.com/embedded-processors/kirkwood/ - Core: Feroceon ARMv5 compatible + Core: Feroceon 88fr131 ARMv5 compatible Linux kernel mach directory: arch/arm/mach-mvebu Linux kernel plat directory: none @@ -71,7 +71,7 @@ Discovery family MV76100 Not supported by the Linux kernel. - Core: Feroceon ARMv5 compatible + Core: Feroceon 88fr571-vd ARMv5 compatible Linux kernel mach directory: arch/arm/mach-mv78xx0 Linux kernel plat directory: arch/arm/plat-orion @@ -86,20 +86,26 @@ EBU Armada family Product Brief: http://www.marvell.com/embedded-processors/armada-300/assets/Marvell_ARMADA_370_SoC.pdf Hardware Spec: http://www.marvell.com/embedded-processors/armada-300/assets/ARMADA370-datasheet.pdf Functional Spec: http://www.marvell.com/embedded-processors/armada-300/assets/ARMADA370-FunctionalSpec-datasheet.pdf + Core: Sheeva ARMv7 compatible PJ4B Armada 375 Flavors: 88F6720 Product Brief: http://www.marvell.com/embedded-processors/armada-300/assets/ARMADA_375_SoC-01_product_brief.pdf - - Armada 380/385 Flavors: - 88F6810 - 88F6820 - 88F6828 - - Armada 390/398 Flavors: - 88F6920 - 88F6928 + Core: ARM Cortex-A9 + + Armada 38x Flavors: + 88F6810 Armada 380 + 88F6820 Armada 385 + 88F6828 Armada 388 + Product infos: http://www.marvell.com/embedded-processors/armada-38x/ + Functional Spec: https://marvellcorp.wufoo.com/forms/marvell-armada-38x-functional-specifications/ + Core: ARM Cortex-A9 + + Armada 39x Flavors: + 88F6920 Armada 390 + 88F6928 Armada 398 Product infos: http://www.marvell.com/embedded-processors/armada-39x/ + Core: ARM Cortex-A9 Armada XP Flavors: MV78230 @@ -112,12 +118,43 @@ EBU Armada family http://www.marvell.com/embedded-processors/armada-xp/assets/HW_MV78230_OS.PDF http://www.marvell.com/embedded-processors/armada-xp/assets/HW_MV78260_OS.PDF http://www.marvell.com/embedded-processors/armada-xp/assets/HW_MV78460_OS.PDF - - Core: Sheeva ARMv7 compatible + Core: Sheeva ARMv7 compatible Dual-core or Quad-core PJ4B-MP Linux kernel mach directory: arch/arm/mach-mvebu Linux kernel plat directory: none +EBU Armada family ARMv8 +----------------------- + + Armada 3710/3720 Flavors: + 88F3710 + 88F3720 + Core: ARM Cortex A53 (ARMv8) + + Homepage: http://www.marvell.com/embedded-processors/armada-3700/ + Product Brief: http://www.marvell.com/embedded-processors/assets/PB-88F3700-FNL.pdf + Device tree files: arch/arm64/boot/dts/marvell/armada-37* + + Armada 7K Flavors: + 88F7020 (AP806 Dual + one CP110) + 88F7040 (AP806 Quad + one CP110) + Core: ARM Cortex A72 + + Homepage: http://www.marvell.com/embedded-processors/armada-70xx/ + Product Brief: http://www.marvell.com/embedded-processors/assets/Armada7020PB-Jan2016.pdf + http://www.marvell.com/embedded-processors/assets/Armada7040PB-Jan2016.pdf + Device tree files: arch/arm64/boot/dts/marvell/armada-70* + + Armada 8K Flavors: + 88F8020 (AP806 Dual + two CP110) + 88F8040 (AP806 Quad + two CP110) + Core: ARM Cortex A72 + + Homepage: http://www.marvell.com/embedded-processors/armada-80xx/ + Product Brief: http://www.marvell.com/embedded-processors/assets/Armada8020PB-Jan2016.pdf + http://www.marvell.com/embedded-processors/assets/Armada8040PB-Jan2016.pdf + Device tree files: arch/arm64/boot/dts/marvell/armada-80* + Avanta family ------------- @@ -135,6 +172,15 @@ Avanta family Linux kernel mach directory: no code in mainline yet, planned for the future Linux kernel plat directory: no code in mainline yet, planned for the future +Storage family +-------------- + + Armada SP: + 88RC1580 + Product infos: http://www.marvell.com/storage/armada-sp/ + Core: Sheeva ARMv7 comatible Quad-core PJ4C + (not supported in upstream Linux kernel) + Dove family (application processor) ----------------------------------- @@ -155,7 +201,7 @@ PXA 2xx/3xx/93x/95x family Flavors: PXA21x, PXA25x, PXA26x Application processor only - Core: ARMv5 XScale core + Core: ARMv5 XScale1 core PXA270, PXA271, PXA272 Product Brief : http://www.marvell.com/application-processors/pxa-family/assets/pxa_27x_pb.pdf Design guide : http://www.marvell.com/application-processors/pxa-family/assets/pxa_27x_design_guide.pdf @@ -163,7 +209,7 @@ PXA 2xx/3xx/93x/95x family Specification : http://www.marvell.com/application-processors/pxa-family/assets/pxa_27x_emts.pdf Specification update : http://www.marvell.com/application-processors/pxa-family/assets/pxa_27x_spec_update.pdf Application processor only - Core: ARMv5 XScale core + Core: ARMv5 XScale2 core PXA300, PXA310, PXA320 PXA 300 Product Brief : http://www.marvell.com/application-processors/pxa-family/assets/PXA300_PB_R4.pdf PXA 310 Product Brief : http://www.marvell.com/application-processors/pxa-family/assets/PXA310_PB_R4.pdf @@ -174,10 +220,10 @@ PXA 2xx/3xx/93x/95x family Specification Update : http://www.marvell.com/application-processors/pxa-family/assets/PXA3xx_Spec_Update.zip Reference Manual : http://www.marvell.com/application-processors/pxa-family/assets/PXA3xx_TavorP_BootROM_Ref_Manual.pdf Application processor only - Core: ARMv5 XScale core + Core: ARMv5 XScale3 core PXA930, PXA935 Application processor with Communication processor - Core: ARMv5 XScale core + Core: ARMv5 XScale3 core PXA955 Application processor with Communication processor Core: ARMv7 compatible Sheeva PJ4 core @@ -196,7 +242,7 @@ PXA 2xx/3xx/93x/95x family Linux kernel mach directory: arch/arm/mach-pxa Linux kernel plat directory: arch/arm/plat-pxa -MMP/MMP2 family (communication processor) +MMP/MMP2/MMP3 family (communication processor) ----------------------------------------- Flavors: @@ -209,16 +255,32 @@ MMP/MMP2 family (communication processor) Boot ROM manual : http://www.marvell.com/application-processors/armada-100/assets/armada_16x_ref_manual.pdf App node package : http://www.marvell.com/application-processors/armada-100/assets/armada_16x_app_note_package.pdf Application processor only - Core: ARMv5 compatible Marvell PJ1 (Mohawk) - PXA910 + Core: ARMv5 compatible Marvell PJ1 88sv331 (Mohawk) + PXA910/PXA920 Homepage : http://www.marvell.com/communication-processors/pxa910/ Product Brief : http://www.marvell.com/communication-processors/pxa910/assets/Marvell_PXA910_Platform-001_PB_final.pdf Application processor with Communication processor - Core: ARMv5 compatible Marvell PJ1 (Mohawk) - MMP2, a.k.a Armada 610 + Core: ARMv5 compatible Marvell PJ1 88sv331 (Mohawk) + PXA688, a.k.a. MMP2, a.k.a Armada 610 Product Brief : http://www.marvell.com/application-processors/armada-600/assets/armada610_pb.pdf Application processor only - Core: ARMv7 compatible Sheeva PJ4 core + Core: ARMv7 compatible Sheeva PJ4 88sv581x core + PXA2128, a.k.a. MMP3 (OLPC XO4, Linux support not upstream) + Product Brief : http://www.marvell.com/application-processors/armada/pxa2128/assets/Marvell-ARMADA-PXA2128-SoC-PB.pdf + Application processor only + Core: Dual-core ARMv7 compatible Sheeva PJ4C core + PXA960/PXA968/PXA978 (Linux support not upstream) + Application processor with Communication Processor + Core: ARMv7 compatible Sheeva PJ4 core + PXA986/PXA988 (Linux support not upstream) + Application processor with Communication Processor + Core: Dual-core ARMv7 compatible Sheeva PJ4B-MP core + PXA1088/PXA1920 (Linux support not upstream) + Application processor with Communication Processor + Core: quad-core ARMv7 Cortex-A7 + PXA1908/PXA1928/PXA1936 + Application processor with Communication Processor + Core: multi-core ARMv8 Cortex-A53 Comments: @@ -237,6 +299,10 @@ Berlin family (Multimedia Solutions) ------------------------------------- Flavors: + 88DE3010, Armada 1000 (no Linux support) + Core: Marvell PJ1 (ARMv5TE), Dual-core + Product Brief: http://www.marvell.com.cn/digital-entertainment/assets/armada_1000_pb.pdf + 88DE3005, Armada 1500-mini 88DE3005, Armada 1500 Mini Design name: BG2CD Core: ARM Cortex-A9, PL310 L2CC @@ -247,14 +313,16 @@ Berlin family (Multimedia Solutions) Homepage: http://www.marvell.com/multimedia-solutions/armada-1500-mini-plus/ 88DE3100, Armada 1500 Design name: BG2 - Core: Marvell PJ4B (ARMv7), Tauros3 L2CC - Product Brief: http://www.marvell.com/multimedia-solutions/armada-1500/assets/Marvell-ARMADA-1500-Product-Brief.pdf + Core: Marvell PJ4B-MP (ARMv7), Tauros3 L2CC + Product Brief: http://www.marvell.com/digital-entertainment/armada-1500/assets/Marvell-ARMADA-1500-Product-Brief.pdf 88DE3114, Armada 1500 Pro Design name: BG2Q Core: Quad Core ARM Cortex-A9, PL310 L2CC - 88DE???? + 88DE3214, Armada 1500 Pro 4K Design name: BG3 Core: ARM Cortex-A15, CA15 integrated L2CC + 88DE3218, ARMADA 1500 Ultra + Core: ARM Cortex-A53 Homepage: http://www.marvell.com/multimedia-solutions/ Directory: arch/arm/mach-berlin @@ -263,6 +331,49 @@ Berlin family (Multimedia Solutions) * This line of SoCs is based on Marvell Sheeva or ARM Cortex CPUs with Synopsys DesignWare (IRQ, GPIO, Timers, ...) and PXA IP (SDHCI, USB, ETH, ...). +CPU Cores +--------- + +The XScale cores were designed by Intel, and shipped by Marvell in the older +PXA processors. Feroceon is a Marvell designed core that developed in-house, +and that evolved into Sheeva. The XScale and Feroceon cores were phased out +over time and replaced with Sheeva cores in later products, which subsequently +got replaced with licensed ARM Cortex-A cores. + + XScale 1 + CPUID 0x69052xxx + ARMv5, iWMMXt + XScale 2 + CPUID 0x69054xxx + ARMv5, iWMMXt + XScale 3 + CPUID 0x69056xxx or 0x69056xxx + ARMv5, iWMMXt + Feroceon-1850 88fr331 "Mohawk" + CPUID 0x5615331x or 0x41xx926x + ARMv5TE, single issue + Feroceon-2850 88fr531-vd "Jolteon" + CPUID 0x5605531x or 0x41xx926x + ARMv5TE, VFP, dual-issue + Feroceon 88fr571-vd "Jolteon" + CPUID 0x5615571x + ARMv5TE, VFP, dual-issue + Feroceon 88fr131 "Mohawk-D" + CPUID 0x5625131x + ARMv5TE, single-issue in-order + Sheeva PJ1 88sv331 "Mohawk" + CPUID 0x561584xx + ARMv5, single-issue iWMMXt v2 + Sheeva PJ4 88sv581x "Flareon" + CPUID 0x560f581x + ARMv7, idivt, optional iWMMXt v2 + Sheeva PJ4B 88sv581x + CPUID 0x561f581x + ARMv7, idivt, optional iWMMXt v2 + Sheeva PJ4B-MP / PJ4C + CPUID 0x562f584x + ARMv7, idivt/idiva, LPAE, optional iWMMXt v2 and/or NEON + Long-term plans --------------- diff --git a/Documentation/arm/sunxi/README b/Documentation/arm/sunxi/README index 430d279a8df374883f5038d0f86961843928f2a7..e5a115f244717aa93122a07d8bc3dc968833f588 100644 --- a/Documentation/arm/sunxi/README +++ b/Documentation/arm/sunxi/README @@ -72,6 +72,5 @@ SunXi family * Octa ARM Cortex-A7 based SoCs - Allwinner A83T - + Not Supported + Datasheet http://dl.linux-sunxi.org/A83T/A83T_datasheet_Revision_1.1.pdf diff --git a/Documentation/blockdev/cpqarray.txt b/Documentation/blockdev/cpqarray.txt deleted file mode 100644 index c7154e20ef5ed8720a1c7ea93eed137e8f8983ea..0000000000000000000000000000000000000000 --- a/Documentation/blockdev/cpqarray.txt +++ /dev/null @@ -1,93 +0,0 @@ -This driver is for Compaq's SMART2 Intelligent Disk Array Controllers. - -Supported Cards: ----------------- - -This driver is known to work with the following cards: - - * SMART (EISA) - * SMART-2/E (EISA) - * SMART-2/P - * SMART-2DH - * SMART-2SL - * SMART-221 - * SMART-3100ES - * SMART-3200 - * Integrated Smart Array Controller - * SA 4200 - * SA 4250ES - * SA 431 - * RAID LC2 Controller - -It should also work with some really old Disk array adapters, but I am -unable to test against these cards: - - * IDA - * IDA-2 - * IAES - - -EISA Controllers: ------------------ - -If you want to use an EISA controller you'll have to supply some -modprobe/lilo parameters. If the driver is compiled into the kernel, must -give it the controller's IO port address at boot time (it is not -necessary to specify the IRQ). For example, if you had two SMART-2/E -controllers, in EISA slots 1 and 2 you'd give it a boot argument like -this: - - smart2=0x1000,0x2000 - -If you were loading the driver as a module, you'd give load it like this: - - modprobe cpqarray eisa=0x1000,0x2000 - -You can use EISA and PCI adapters at the same time. - - -Device Naming: --------------- - -You need some entries in /dev for the ida device. MAKEDEV in the /dev -directory can make device nodes for you automatically. The device setup is -as follows: - -Major numbers: - 72 ida0 - 73 ida1 - 74 ida2 - 75 ida3 - 76 ida4 - 77 ida5 - 78 ida6 - 79 ida7 - -Minor numbers: - b7 b6 b5 b4 b3 b2 b1 b0 - |----+----| |----+----| - | | - | +-------- Partition ID (0=wholedev, 1-15 partition) - | - +-------------------- Logical Volume number - -The device naming scheme is: -/dev/ida/c0d0 Controller 0, disk 0, whole device -/dev/ida/c0d0p1 Controller 0, disk 0, partition 1 -/dev/ida/c0d0p2 Controller 0, disk 0, partition 2 -/dev/ida/c0d0p3 Controller 0, disk 0, partition 3 - -/dev/ida/c1d1 Controller 1, disk 1, whole device -/dev/ida/c1d1p1 Controller 1, disk 1, partition 1 -/dev/ida/c1d1p2 Controller 1, disk 1, partition 2 -/dev/ida/c1d1p3 Controller 1, disk 1, partition 3 - - -Changelog: -========== - -10-28-2004 : General cleanup, syntax fixes for in-kernel driver version. - James Nelson - - -1999 : Original Document diff --git a/Documentation/cgroup-v1/00-INDEX b/Documentation/cgroup-v1/00-INDEX index 6ad425f7cf56737522833c862d985ea7dbacf669..106885ad670d6543a2804d234c2ca97b9e011090 100644 --- a/Documentation/cgroup-v1/00-INDEX +++ b/Documentation/cgroup-v1/00-INDEX @@ -24,5 +24,3 @@ net_prio.txt - Network priority cgroups details and usages. pids.txt - Process number cgroups details and usages. -unified-hierarchy.txt - - Description the new/next cgroup interface. diff --git a/Documentation/cgroup-v1/cgroups.txt b/Documentation/cgroup-v1/cgroups.txt index c6256ae9885b8ac7445f6d10066ee541ebb388b8..947e6fe31ef9271f29c3692090f4ab6450519468 100644 --- a/Documentation/cgroup-v1/cgroups.txt +++ b/Documentation/cgroup-v1/cgroups.txt @@ -8,7 +8,7 @@ Original copyright statements from cpusets.txt: Portions Copyright (C) 2004 BULL SA. Portions Copyright (c) 2004-2006 Silicon Graphics, Inc. Modified by Paul Jackson -Modified by Christoph Lameter +Modified by Christoph Lameter CONTENTS: ========= diff --git a/Documentation/cgroup-v1/cpusets.txt b/Documentation/cgroup-v1/cpusets.txt index fdf7dff3f607d96bd03a896d92ba585b2a2d5ab0..e5cdcd4456153d83e0d88e2d2b06387627667d6b 100644 --- a/Documentation/cgroup-v1/cpusets.txt +++ b/Documentation/cgroup-v1/cpusets.txt @@ -6,7 +6,7 @@ Written by Simon.Derr@bull.net Portions Copyright (c) 2004-2006 Silicon Graphics, Inc. Modified by Paul Jackson -Modified by Christoph Lameter +Modified by Christoph Lameter Modified by Paul Menage Modified by Hidetoshi Seto diff --git a/Documentation/cgroup-v2.txt b/Documentation/cgroup-v2.txt index ff49cf901148d895b765800ec6ddb79c0e38ed53..4cc07ce3b8dd00ee109ef888b05931f4ce6e30e1 100644 --- a/Documentation/cgroup-v2.txt +++ b/Documentation/cgroup-v2.txt @@ -47,6 +47,11 @@ CONTENTS 5-3. IO 5-3-1. IO Interface Files 5-3-2. Writeback +6. Namespace + 6-1. Basics + 6-2. The Root and Views + 6-3. Migration and setns(2) + 6-4. Interaction with Other Namespaces P. Information on Kernel Programming P-1. Filesystem Support for Writeback D. Deprecated v1 Core Features @@ -132,6 +137,12 @@ strongly discouraged for production use. It is recommended to decide the hierarchies and controller associations before starting using the controllers after system boot. +During transition to v2, system management software might still +automount the v1 cgroup filesystem and so hijack all controllers +during boot, before manual intervention is possible. To make testing +and experimenting easier, the kernel parameter cgroup_no_v1= allows +disabling controllers in v1 and make them always available in v2. + 2-2. Organizing Processes @@ -843,6 +854,15 @@ PAGE_SIZE multiple when read back. Amount of memory used to cache filesystem data, including tmpfs and shared memory. + kernel_stack + + Amount of memory allocated to kernel stacks. + + slab + + Amount of memory used for storing in-kernel data + structures. + sock Amount of memory used in network transmission buffers @@ -871,6 +891,16 @@ PAGE_SIZE multiple when read back. on the internal memory management lists used by the page reclaim algorithm + slab_reclaimable + + Part of "slab" that might be reclaimed, such as + dentries and inodes. + + slab_unreclaimable + + Part of "slab" that cannot be reclaimed on memory + pressure. + pgfault Total number of page faults incurred @@ -896,7 +926,7 @@ PAGE_SIZE multiple when read back. limit, anonymous meomry of the cgroup will not be swapped out. -5-2-2. General Usage +5-2-2. Usage Guidelines "memory.high" is the main mechanism to control memory usage. Over-committing on high limit (sum of high limits > available memory) @@ -1089,6 +1119,148 @@ writeback as follows. vm.dirty[_background]_ratio. +6. Namespace + +6-1. Basics + +cgroup namespace provides a mechanism to virtualize the view of the +"/proc/$PID/cgroup" file and cgroup mounts. The CLONE_NEWCGROUP clone +flag can be used with clone(2) and unshare(2) to create a new cgroup +namespace. The process running inside the cgroup namespace will have +its "/proc/$PID/cgroup" output restricted to cgroupns root. The +cgroupns root is the cgroup of the process at the time of creation of +the cgroup namespace. + +Without cgroup namespace, the "/proc/$PID/cgroup" file shows the +complete path of the cgroup of a process. In a container setup where +a set of cgroups and namespaces are intended to isolate processes the +"/proc/$PID/cgroup" file may leak potential system level information +to the isolated processes. For Example: + + # cat /proc/self/cgroup + 0::/batchjobs/container_id1 + +The path '/batchjobs/container_id1' can be considered as system-data +and undesirable to expose to the isolated processes. cgroup namespace +can be used to restrict visibility of this path. For example, before +creating a cgroup namespace, one would see: + + # ls -l /proc/self/ns/cgroup + lrwxrwxrwx 1 root root 0 2014-07-15 10:37 /proc/self/ns/cgroup -> cgroup:[4026531835] + # cat /proc/self/cgroup + 0::/batchjobs/container_id1 + +After unsharing a new namespace, the view changes. + + # ls -l /proc/self/ns/cgroup + lrwxrwxrwx 1 root root 0 2014-07-15 10:35 /proc/self/ns/cgroup -> cgroup:[4026532183] + # cat /proc/self/cgroup + 0::/ + +When some thread from a multi-threaded process unshares its cgroup +namespace, the new cgroupns gets applied to the entire process (all +the threads). This is natural for the v2 hierarchy; however, for the +legacy hierarchies, this may be unexpected. + +A cgroup namespace is alive as long as there are processes inside or +mounts pinning it. When the last usage goes away, the cgroup +namespace is destroyed. The cgroupns root and the actual cgroups +remain. + + +6-2. The Root and Views + +The 'cgroupns root' for a cgroup namespace is the cgroup in which the +process calling unshare(2) is running. For example, if a process in +/batchjobs/container_id1 cgroup calls unshare, cgroup +/batchjobs/container_id1 becomes the cgroupns root. For the +init_cgroup_ns, this is the real root ('/') cgroup. + +The cgroupns root cgroup does not change even if the namespace creator +process later moves to a different cgroup. + + # ~/unshare -c # unshare cgroupns in some cgroup + # cat /proc/self/cgroup + 0::/ + # mkdir sub_cgrp_1 + # echo 0 > sub_cgrp_1/cgroup.procs + # cat /proc/self/cgroup + 0::/sub_cgrp_1 + +Each process gets its namespace-specific view of "/proc/$PID/cgroup" + +Processes running inside the cgroup namespace will be able to see +cgroup paths (in /proc/self/cgroup) only inside their root cgroup. +From within an unshared cgroupns: + + # sleep 100000 & + [1] 7353 + # echo 7353 > sub_cgrp_1/cgroup.procs + # cat /proc/7353/cgroup + 0::/sub_cgrp_1 + +From the initial cgroup namespace, the real cgroup path will be +visible: + + $ cat /proc/7353/cgroup + 0::/batchjobs/container_id1/sub_cgrp_1 + +From a sibling cgroup namespace (that is, a namespace rooted at a +different cgroup), the cgroup path relative to its own cgroup +namespace root will be shown. For instance, if PID 7353's cgroup +namespace root is at '/batchjobs/container_id2', then it will see + + # cat /proc/7353/cgroup + 0::/../container_id2/sub_cgrp_1 + +Note that the relative path always starts with '/' to indicate that +its relative to the cgroup namespace root of the caller. + + +6-3. Migration and setns(2) + +Processes inside a cgroup namespace can move into and out of the +namespace root if they have proper access to external cgroups. For +example, from inside a namespace with cgroupns root at +/batchjobs/container_id1, and assuming that the global hierarchy is +still accessible inside cgroupns: + + # cat /proc/7353/cgroup + 0::/sub_cgrp_1 + # echo 7353 > batchjobs/container_id2/cgroup.procs + # cat /proc/7353/cgroup + 0::/../container_id2 + +Note that this kind of setup is not encouraged. A task inside cgroup +namespace should only be exposed to its own cgroupns hierarchy. + +setns(2) to another cgroup namespace is allowed when: + +(a) the process has CAP_SYS_ADMIN against its current user namespace +(b) the process has CAP_SYS_ADMIN against the target cgroup + namespace's userns + +No implicit cgroup changes happen with attaching to another cgroup +namespace. It is expected that the someone moves the attaching +process under the target cgroup namespace root. + + +6-4. Interaction with Other Namespaces + +Namespace specific cgroup hierarchy can be mounted by a process +running inside a non-init cgroup namespace. + + # mount -t cgroup2 none $MOUNT_POINT + +This will mount the unified cgroup hierarchy with cgroupns root as the +filesystem root. The process needs CAP_SYS_ADMIN against its user and +mount namespaces. + +The virtualization of /proc/self/cgroup file combined with restricting +the view of cgroup hierarchy by namespace-private cgroupfs mount +provides a properly isolated cgroup view inside the container. + + P. Information on Kernel Programming This section contains kernel programming information in the areas @@ -1368,6 +1540,12 @@ system than killing the group. Otherwise, memory.max is there to limit this type of spillover and ultimately contain buggy or even malicious applications. +Setting the original memory.limit_in_bytes below the current usage was +subject to a race condition, where concurrent charges could cause the +limit setting to fail. memory.max on the other hand will first set the +limit to prevent new charges, and then reclaim and OOM kill until the +new limit is met - or the task writing to memory.max is killed. + The combined memory+swap accounting and limiting is replaced by real control over swap space. diff --git a/Documentation/devicetree/bindings/arm/amlogic.txt b/Documentation/devicetree/bindings/arm/amlogic.txt index 1dfee20eee744efa2ec7cc248475501f4ae84cb7..8a5122ab19b0222277de6503dfe0b4cb77f3aa90 100644 --- a/Documentation/devicetree/bindings/arm/amlogic.txt +++ b/Documentation/devicetree/bindings/arm/amlogic.txt @@ -13,8 +13,15 @@ Boards with the Amlogic Meson8b SoC shall have the following properties: Required root node property: compatible: "amlogic,meson8b"; +Boards with the Amlogic Meson GXBaby SoC shall have the following properties: + Required root node property: + compatible: "amlogic,meson-gxbb"; + Board compatible values: - "geniatech,atv1200" (Meson6) - "minix,neo-x8" (Meson8) - "tronfy,mxq" (Meson8b) - "hardkernel,odroid-c1" (Meson8b) + - "tronsmart,vega-s95-pro", "tronsmart,vega-s95" (Meson gxbb) + - "tronsmart,vega-s95-meta", "tronsmart,vega-s95" (Meson gxbb) + - "tronsmart,vega-s95-telos", "tronsmart,vega-s95" (Meson gxbb) diff --git a/Documentation/devicetree/bindings/arm/arm-boards b/Documentation/devicetree/bindings/arm/arm-boards index 1a709970e7f7826aba3de7847fcf964389e237e3..0226bc2cc1f6ec49607c39725c5b911ca881c717 100644 --- a/Documentation/devicetree/bindings/arm/arm-boards +++ b/Documentation/devicetree/bindings/arm/arm-boards @@ -123,7 +123,9 @@ Required nodes: - syscon: some subnode of the RealView SoC node must be a system controller node pointing to the control registers, - with the compatible string set to one of these tuples: + with the compatible string set to one of these: + "arm,realview-eb11mp-revb-syscon", "arm,realview-eb-syscon", "syscon" + "arm,realview-eb11mp-revc-syscon", "arm,realview-eb-syscon", "syscon" "arm,realview-eb-syscon", "syscon" "arm,realview-pb1176-syscon", "syscon" "arm,realview-pb11mp-syscon", "syscon" @@ -180,6 +182,7 @@ described under the RS1 memory mapping. Required properties (in root node): compatible = "arm,juno"; /* For Juno r0 board */ compatible = "arm,juno-r1"; /* For Juno r1 board */ + compatible = "arm,juno-r2"; /* For Juno r2 board */ Required nodes: The description for the board must include: diff --git a/Documentation/devicetree/bindings/arm/axis.txt b/Documentation/devicetree/bindings/arm/axis.txt new file mode 100644 index 0000000000000000000000000000000000000000..ae345e1c8d2b8f514865f70374cada6e4b868654 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/axis.txt @@ -0,0 +1,29 @@ +Axis Communications AB +ARTPEC series SoC Device Tree Bindings + +ARTPEC-6 ARM SoC +================ + +Required root node properties: +- compatible = "axis,artpec6"; + +ARTPEC-6 System Controller +-------------------------- + +The ARTPEC-6 has a system controller with mixed functions controlling DMA, PCIe +and resets. + +Required properties: +- compatible: "axis,artpec6-syscon", "syscon" +- reg: Address and length of the register bank. + +Example: + syscon { + compatible = "axis,artpec6-syscon", "syscon"; + reg = <0xf8000000 0x48>; + }; + +ARTPEC-6 Development board: +--------------------------- +Required root node properties: +- compatible = "axis,artpec6-dev-board", "axis,artpec6"; diff --git a/Documentation/devicetree/bindings/arm/bcm/brcm,vulcan-soc.txt b/Documentation/devicetree/bindings/arm/bcm/brcm,vulcan-soc.txt new file mode 100644 index 0000000000000000000000000000000000000000..223ed3471c0846f6d23068d6512a00a8c54aec25 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/bcm/brcm,vulcan-soc.txt @@ -0,0 +1,10 @@ +Broadcom Vulcan device tree bindings +------------------------------------ + +Boards with Broadcom Vulcan shall have the following root property: + +Broadcom Vulcan Evaluation Board: + compatible = "brcm,vulcan-eval", "brcm,vulcan-soc"; + +Generic Vulcan board: + compatible = "brcm,vulcan-soc"; diff --git a/Documentation/devicetree/bindings/arm/cci.txt b/Documentation/devicetree/bindings/arm/cci.txt index aef1d200a9b28f4d3643812312b3dd9aa3b86209..a1a5a7ecc2fb0d5d087152b6a21eaca618394576 100644 --- a/Documentation/devicetree/bindings/arm/cci.txt +++ b/Documentation/devicetree/bindings/arm/cci.txt @@ -34,6 +34,7 @@ specific to ARM. Definition: must contain one of the following: "arm,cci-400" "arm,cci-500" + "arm,cci-550" - reg Usage: required @@ -101,6 +102,7 @@ specific to ARM. "arm,cci-400-pmu" - DEPRECATED, permitted only where OS has secure acces to CCI registers "arm,cci-500-pmu,r0" + "arm,cci-550-pmu,r0" - reg: Usage: required Value type: Integer cells. A register entry, expressed diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt index ae9be074d09f66d503adccc539c892e6cf13af90..ccc62f1453066fc10ba23cc3f3fa037ee9ccac9c 100644 --- a/Documentation/devicetree/bindings/arm/cpus.txt +++ b/Documentation/devicetree/bindings/arm/cpus.txt @@ -167,6 +167,7 @@ nodes to be present and contain the properties described below. "arm,cortex-r5" "arm,cortex-r7" "brcm,brahma-b15" + "brcm,vulcan" "cavium,thunder" "faraday,fa526" "intel,sa110" @@ -178,6 +179,7 @@ nodes to be present and contain the properties described below. "marvell,sheeva-v5" "nvidia,tegra132-denver" "qcom,krait" + "qcom,kryo" "qcom,scorpion" - enable-method Value type: @@ -250,7 +252,7 @@ nodes to be present and contain the properties described below. Usage: optional Value type: Definition: A u32 value that represents the running time dynamic - power coefficient in units of mW/MHz/uVolt^2. The + power coefficient in units of mW/MHz/uV^2. The coefficient can either be calculated from power measurements or derived by analysis. diff --git a/Documentation/devicetree/bindings/arm/keystone/keystone.txt b/Documentation/devicetree/bindings/arm/keystone/keystone.txt index 3090a8a008c03ed61cfb42b94d2cf36f3b5756ed..48f6703a28c8f50108a1d9f3bdda62462d9b099e 100644 --- a/Documentation/devicetree/bindings/arm/keystone/keystone.txt +++ b/Documentation/devicetree/bindings/arm/keystone/keystone.txt @@ -22,6 +22,8 @@ SoCs: compatible = "ti,k2l", "ti,keystone" - Keystone 2 Edison compatible = "ti,k2e", "ti,keystone" +- K2G + compatible = "ti,k2g", "ti,keystone" Boards: - Keystone 2 Hawking/Kepler EVM @@ -32,3 +34,6 @@ Boards: - Keystone 2 Edison EVM compatible = "ti,k2e-evm", "ti,k2e", "ti,keystone" + +- K2G EVM + compatible = "ti,k2g-evm", "ti,k2g", "ti-keystone" diff --git a/Documentation/devicetree/bindings/arm/armada-370-xp-pmsu.txt b/Documentation/devicetree/bindings/arm/marvell/armada-370-xp-pmsu.txt similarity index 100% rename from Documentation/devicetree/bindings/arm/armada-370-xp-pmsu.txt rename to Documentation/devicetree/bindings/arm/marvell/armada-370-xp-pmsu.txt diff --git a/Documentation/devicetree/bindings/arm/armada-370-xp.txt b/Documentation/devicetree/bindings/arm/marvell/armada-370-xp.txt similarity index 100% rename from Documentation/devicetree/bindings/arm/armada-370-xp.txt rename to Documentation/devicetree/bindings/arm/marvell/armada-370-xp.txt diff --git a/Documentation/devicetree/bindings/arm/armada-375.txt b/Documentation/devicetree/bindings/arm/marvell/armada-375.txt similarity index 100% rename from Documentation/devicetree/bindings/arm/armada-375.txt rename to Documentation/devicetree/bindings/arm/marvell/armada-375.txt diff --git a/Documentation/devicetree/bindings/arm/marvell/armada-37xx.txt b/Documentation/devicetree/bindings/arm/marvell/armada-37xx.txt new file mode 100644 index 0000000000000000000000000000000000000000..51336e5fc761274d0928192766cf8a5b664f82d5 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/marvell/armada-37xx.txt @@ -0,0 +1,16 @@ +Marvell Armada 37xx Platforms Device Tree Bindings +-------------------------------------------------- + +Boards using a SoC of the Marvell Armada 37xx family must carry the +following root node property: + + - compatible: must contain "marvell,armada3710" + +In addition, boards using the Marvell Armada 3720 SoC shall have the +following property before the previous one: + + - compatible: must contain "marvell,armada3720" + +Example: + +compatible = "marvell,armada-3720-db", "marvell,armada3720", "marvell,armada3710"; diff --git a/Documentation/devicetree/bindings/arm/armada-380-mpcore-soc-ctrl.txt b/Documentation/devicetree/bindings/arm/marvell/armada-380-mpcore-soc-ctrl.txt similarity index 100% rename from Documentation/devicetree/bindings/arm/armada-380-mpcore-soc-ctrl.txt rename to Documentation/devicetree/bindings/arm/marvell/armada-380-mpcore-soc-ctrl.txt diff --git a/Documentation/devicetree/bindings/arm/armada-38x.txt b/Documentation/devicetree/bindings/arm/marvell/armada-38x.txt similarity index 100% rename from Documentation/devicetree/bindings/arm/armada-38x.txt rename to Documentation/devicetree/bindings/arm/marvell/armada-38x.txt diff --git a/Documentation/devicetree/bindings/arm/armada-39x.txt b/Documentation/devicetree/bindings/arm/marvell/armada-39x.txt similarity index 100% rename from Documentation/devicetree/bindings/arm/armada-39x.txt rename to Documentation/devicetree/bindings/arm/marvell/armada-39x.txt diff --git a/Documentation/devicetree/bindings/arm/marvell/armada-7k-8k.txt b/Documentation/devicetree/bindings/arm/marvell/armada-7k-8k.txt new file mode 100644 index 0000000000000000000000000000000000000000..df98a9c82a8c7ce4352457ba96c63c0a5cc19fb9 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/marvell/armada-7k-8k.txt @@ -0,0 +1,24 @@ +Marvell Armada 7K/8K Platforms Device Tree Bindings +--------------------------------------------------- + +Boards using a SoC of the Marvell Armada 7K or 8K families must carry +the following root node property: + + - compatible, with one of the following values: + + - "marvell,armada7020", "marvell,armada-ap806-dual", "marvell,armada-ap806" + when the SoC being used is the Armada 7020 + + - "marvell,armada7040", "marvell,armada-ap806-quad", "marvell,armada-ap806" + when the SoC being used is the Armada 7040 + + - "marvell,armada8020", "marvell,armada-ap806-dual", "marvell,armada-ap806" + when the SoC being used is the Armada 8020 + + - "marvell,armada8040", "marvell,armada-ap806-quad", "marvell,armada-ap806" + when the SoC being used is the Armada 8040 + +Example: + +compatible = "marvell,armada7040-db", "marvell,armada7040", + "marvell,armada-ap806-quad", "marvell,armada-ap806"; diff --git a/Documentation/devicetree/bindings/arm/armada-cpu-reset.txt b/Documentation/devicetree/bindings/arm/marvell/armada-cpu-reset.txt similarity index 100% rename from Documentation/devicetree/bindings/arm/armada-cpu-reset.txt rename to Documentation/devicetree/bindings/arm/marvell/armada-cpu-reset.txt diff --git a/Documentation/devicetree/bindings/arm/coherency-fabric.txt b/Documentation/devicetree/bindings/arm/marvell/coherency-fabric.txt similarity index 100% rename from Documentation/devicetree/bindings/arm/coherency-fabric.txt rename to Documentation/devicetree/bindings/arm/marvell/coherency-fabric.txt diff --git a/Documentation/devicetree/bindings/arm/kirkwood.txt b/Documentation/devicetree/bindings/arm/marvell/kirkwood.txt similarity index 100% rename from Documentation/devicetree/bindings/arm/kirkwood.txt rename to Documentation/devicetree/bindings/arm/marvell/kirkwood.txt diff --git a/Documentation/devicetree/bindings/arm/marvell,berlin.txt b/Documentation/devicetree/bindings/arm/marvell/marvell,berlin.txt similarity index 100% rename from Documentation/devicetree/bindings/arm/marvell,berlin.txt rename to Documentation/devicetree/bindings/arm/marvell/marvell,berlin.txt diff --git a/Documentation/devicetree/bindings/arm/marvell,dove.txt b/Documentation/devicetree/bindings/arm/marvell/marvell,dove.txt similarity index 100% rename from Documentation/devicetree/bindings/arm/marvell,dove.txt rename to Documentation/devicetree/bindings/arm/marvell/marvell,dove.txt diff --git a/Documentation/devicetree/bindings/arm/marvell,kirkwood.txt b/Documentation/devicetree/bindings/arm/marvell/marvell,kirkwood.txt similarity index 94% rename from Documentation/devicetree/bindings/arm/marvell,kirkwood.txt rename to Documentation/devicetree/bindings/arm/marvell/marvell,kirkwood.txt index ab0c9cdf388e9e5769bf7ecfa88f5bbc869b58fb..7d28fe4bf654e8d1fa9c1a3cc06a8fab0631ef9a 100644 --- a/Documentation/devicetree/bindings/arm/marvell,kirkwood.txt +++ b/Documentation/devicetree/bindings/arm/marvell/marvell,kirkwood.txt @@ -19,9 +19,12 @@ SoC. Currently known SoC compatibles are: And in addition, the compatible shall be extended with the specific board. Currently known boards are: +"buffalo,linkstation-lsqvl" +"buffalo,linkstation-lsvl" +"buffalo,linkstation-lswsxl" +"buffalo,linkstation-lswxl" +"buffalo,linkstation-lswvl" "buffalo,lschlv2" -"buffalo,lswvl" -"buffalo,lswxl" "buffalo,lsxhl" "buffalo,lsxl" "cloudengines,pogo02" diff --git a/Documentation/devicetree/bindings/arm/mvebu-cpu-config.txt b/Documentation/devicetree/bindings/arm/marvell/mvebu-cpu-config.txt similarity index 100% rename from Documentation/devicetree/bindings/arm/mvebu-cpu-config.txt rename to Documentation/devicetree/bindings/arm/marvell/mvebu-cpu-config.txt diff --git a/Documentation/devicetree/bindings/arm/mvebu-system-controller.txt b/Documentation/devicetree/bindings/arm/marvell/mvebu-system-controller.txt similarity index 100% rename from Documentation/devicetree/bindings/arm/mvebu-system-controller.txt rename to Documentation/devicetree/bindings/arm/marvell/mvebu-system-controller.txt diff --git a/Documentation/devicetree/bindings/arm/mediatek.txt b/Documentation/devicetree/bindings/arm/mediatek.txt index 54f43bc2df443370ab0d4391a7ab6e6c713aa566..d9c2a37a4090be5d59f0bd74314bc37ba7769985 100644 --- a/Documentation/devicetree/bindings/arm/mediatek.txt +++ b/Documentation/devicetree/bindings/arm/mediatek.txt @@ -11,6 +11,7 @@ compatible: Must contain one of "mediatek,mt6589" "mediatek,mt6592" "mediatek,mt6795" + "mediatek,mt7623" "mediatek,mt8127" "mediatek,mt8135" "mediatek,mt8173" @@ -33,6 +34,9 @@ Supported boards: - Evaluation board for MT6795(Helio X10): Required root node properties: - compatible = "mediatek,mt6795-evb", "mediatek,mt6795"; +- Evaluation board for MT7623: + Required root node properties: + - compatible = "mediatek,mt7623-evb", "mediatek,mt7623"; - MTK mt8127 tablet moose EVB: Required root node properties: - compatible = "mediatek,mt8127-moose", "mediatek,mt8127"; diff --git a/Documentation/devicetree/bindings/arm/lpc32xx.txt b/Documentation/devicetree/bindings/arm/nxp/lpc32xx.txt similarity index 100% rename from Documentation/devicetree/bindings/arm/lpc32xx.txt rename to Documentation/devicetree/bindings/arm/nxp/lpc32xx.txt diff --git a/Documentation/devicetree/bindings/arm/omap/omap.txt b/Documentation/devicetree/bindings/arm/omap/omap.txt index 66422d6631841d9e6eba9be63e453176ebd43f2e..21e71a5e866e0604a3074bcb9999602574811792 100644 --- a/Documentation/devicetree/bindings/arm/omap/omap.txt +++ b/Documentation/devicetree/bindings/arm/omap/omap.txt @@ -155,7 +155,7 @@ Boards: compatible = "compulab,am437x-sbc-t43", "compulab,am437x-cm-t43", "ti,am4372", "ti,am43" - AM43x EPOS EVM - compatible = "ti,am43x-epos-evm", "ti,am4372", "ti,am43" + compatible = "ti,am43x-epos-evm", "ti,am43", "ti,am438x" - AM437x GP EVM compatible = "ti,am437x-gp-evm", "ti,am4372", "ti,am43" diff --git a/Documentation/devicetree/bindings/arm/pmu.txt b/Documentation/devicetree/bindings/arm/pmu.txt index 56518839f52a7908922aa9a88d60575be57cdbe3..6eb73be9433e8af323b96d99728b42a131e1de4b 100644 --- a/Documentation/devicetree/bindings/arm/pmu.txt +++ b/Documentation/devicetree/bindings/arm/pmu.txt @@ -25,6 +25,7 @@ Required properties: "qcom,scorpion-pmu" "qcom,scorpion-mp-pmu" "qcom,krait-pmu" + "cavium,thunder-pmu" - interrupts : 1 combined interrupt or 1 per core. If the interrupt is a per-cpu interrupt (PPI) then 1 interrupt should be specified. @@ -46,6 +47,16 @@ Optional properties: - qcom,no-pc-write : Indicates that this PMU doesn't support the 0xc and 0xd events. +- secure-reg-access : Indicates that the ARMv7 Secure Debug Enable Register + (SDER) is accessible. This will cause the driver to do + any setup required that is only possible in ARMv7 secure + state. If not present the ARMv7 SDER will not be touched, + which means the PMU may fail to operate unless external + code (bootloader or security monitor) has performed the + appropriate initialisation. Note that this property is + not valid for non-ARMv7 CPUs or ARMv7 CPUs booting Linux + in Non-secure state. + Example: pmu { diff --git a/Documentation/devicetree/bindings/arm/qcom.txt b/Documentation/devicetree/bindings/arm/qcom.txt new file mode 100644 index 0000000000000000000000000000000000000000..3e24518c6678d1e1e7a8c4def669e1bf12dada2d --- /dev/null +++ b/Documentation/devicetree/bindings/arm/qcom.txt @@ -0,0 +1,51 @@ +QCOM device tree bindings +------------------------- + +Some qcom based bootloaders identify the dtb blob based on a set of +device properties like SoC and platform and revisions of those components. +To support this scheme, we encode this information into the board compatible +string. + +Each board must specify a top-level board compatible string with the following +format: + + compatible = "qcom,[-][-]-[/][-]" + +The 'SoC' and 'board' elements are required. All other elements are optional. + +The 'SoC' element must be one of the following strings: + + apq8016 + apq8074 + apq8084 + apq8096 + msm8916 + msm8974 + msm8996 + +The 'board' element must be one of the following strings: + + cdp + liquid + dragonboard + mtp + sbc + +The 'soc_version' and 'board_version' elements take the form of v. +where the minor number may be omitted when it's zero, i.e. v1.0 is the same +as v1. If all versions of the 'board_version' elements match, then a +wildcard '*' should be used, e.g. 'v*'. + +The 'foundry_id' and 'subtype' elements are one or more digits from 0 to 9. + +Examples: + + "qcom,msm8916-v1-cdp-pm8916-v2.1" + +A CDP board with an msm8916 SoC, version 1 paired with a pm8916 PMIC of version +2.1. + + "qcom,apq8074-v2.0-2-dragonboard/1-v0.1" + +A dragonboard board v0.1 of subtype 1 with an apq8074 SoC version 2, made in +foundry 2. diff --git a/Documentation/devicetree/bindings/arm/sunxi.txt b/Documentation/devicetree/bindings/arm/sunxi.txt index bb9b0faa919d098309c9eb22289f8cef3b995d9b..7e79fcc36b0db60c8b147bf7a498d8013c120d16 100644 --- a/Documentation/devicetree/bindings/arm/sunxi.txt +++ b/Documentation/devicetree/bindings/arm/sunxi.txt @@ -11,5 +11,6 @@ using one of the following compatible strings: allwinner,sun7i-a20 allwinner,sun8i-a23 allwinner,sun8i-a33 + allwinner,sun8i-a83t allwinner,sun8i-h3 allwinner,sun9i-a80 diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt index c2340eeeb97ff072196dbcd49144897813b1573d..30df832a6f2f513f4e23841dd0a0ad888cc13dba 100644 --- a/Documentation/devicetree/bindings/ata/ahci-platform.txt +++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt @@ -11,8 +11,10 @@ Required properties: - compatible : compatible string, one of: - "allwinner,sun4i-a10-ahci" - "hisilicon,hisi-ahci" + - "cavium,octeon-7130-ahci" - "ibm,476gtr-ahci" - "marvell,armada-380-ahci" + - "marvell,armada-3700-ahci" - "snps,dwc-ahci" - "snps,exynos5440-ahci" - "snps,spear-ahci" diff --git a/Documentation/devicetree/bindings/bus/ti-gpmc.txt b/Documentation/devicetree/bindings/bus/ti-gpmc.txt index 704be9306c9fb5e0da668d002b5390af92cf94c1..01683707060bfdc60f2e4d2ebd9a6534c50d9658 100644 --- a/Documentation/devicetree/bindings/bus/ti-gpmc.txt +++ b/Documentation/devicetree/bindings/bus/ti-gpmc.txt @@ -46,6 +46,9 @@ Timing properties for child nodes. All are optional and default to 0. - gpmc,adv-on-ns: Assertion time - gpmc,adv-rd-off-ns: Read deassertion time - gpmc,adv-wr-off-ns: Write deassertion time + - gpmc,adv-aad-mux-on-ns: Assertion time for AAD + - gpmc,adv-aad-mux-rd-off-ns: Read deassertion time for AAD + - gpmc,adv-aad-mux-wr-off-ns: Write deassertion time for AAD WE signals timings (in nanoseconds) corresponding to GPMC_CONFIG4: - gpmc,we-on-ns Assertion time @@ -54,6 +57,8 @@ Timing properties for child nodes. All are optional and default to 0. OE signals timings (in nanoseconds) corresponding to GPMC_CONFIG4: - gpmc,oe-on-ns: Assertion time - gpmc,oe-off-ns: Deassertion time + - gpmc,oe-aad-mux-on-ns: Assertion time for AAD + - gpmc,oe-aad-mux-off-ns: Deassertion time for AAD Access time and cycle time timings (in nanoseconds) corresponding to GPMC_CONFIG5: diff --git a/Documentation/devicetree/bindings/clock/axi-clkgen.txt b/Documentation/devicetree/bindings/clock/axi-clkgen.txt index 20e1704e7df2110c518ce71ca07e94a0b4db574a..fb40da303d25c8f13093aafe43df83eaf2f88f47 100644 --- a/Documentation/devicetree/bindings/clock/axi-clkgen.txt +++ b/Documentation/devicetree/bindings/clock/axi-clkgen.txt @@ -8,7 +8,10 @@ Required properties: - compatible : shall be "adi,axi-clkgen-1.00.a" or "adi,axi-clkgen-2.00.a". - #clock-cells : from common clock binding; Should always be set to 0. - reg : Address and length of the axi-clkgen register set. -- clocks : Phandle and clock specifier for the parent clock. +- clocks : Phandle and clock specifier for the parent clock(s). This must + either reference one clock if only the first clock input is connected or two + if both clock inputs are connected. For the later case the clock connected + to the first input must be specified first. Optional properties: - clock-output-names : From common clock binding. diff --git a/Documentation/devicetree/bindings/clock/brcm,iproc-clocks.txt b/Documentation/devicetree/bindings/clock/brcm,iproc-clocks.txt index 0b35e71b39e891fb15cfbac0d6af1d4763192e40..6f66e9aa354c1996beb76e3e9c830dc25b288159 100644 --- a/Documentation/devicetree/bindings/clock/brcm,iproc-clocks.txt +++ b/Documentation/devicetree/bindings/clock/brcm,iproc-clocks.txt @@ -92,6 +92,7 @@ PLL and leaf clock compatible strings for Cygnus are: "brcm,cygnus-lcpll0" "brcm,cygnus-mipipll" "brcm,cygnus-asiu-clk" + "brcm,cygnus-audiopll" The following table defines the set of PLL/clock index and ID for Cygnus. These clock IDs are defined in: @@ -131,6 +132,11 @@ These clock IDs are defined in: ch4_unused mipipll 5 BCM_CYGNUS_MIPIPLL_CH4_UNUSED ch5_unused mipipll 6 BCM_CYGNUS_MIPIPLL_CH5_UNUSED + audiopll crystal 0 BCM_CYGNUS_AUDIOPLL + ch0_audio audiopll 1 BCM_CYGNUS_AUDIOPLL_CH0 + ch1_audio audiopll 2 BCM_CYGNUS_AUDIOPLL_CH1 + ch2_audio audiopll 3 BCM_CYGNUS_AUDIOPLL_CH2 + Northstar and Northstar Plus ------ PLL and leaf clock compatible strings for Northstar and Northstar Plus are: diff --git a/Documentation/devicetree/bindings/clock/lpc1850-creg-clk.txt b/Documentation/devicetree/bindings/clock/lpc1850-creg-clk.txt new file mode 100644 index 0000000000000000000000000000000000000000..6f1c7b4e4d2ca8419db996e105b86fd855cce173 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/lpc1850-creg-clk.txt @@ -0,0 +1,52 @@ +* NXP LPC1850 CREG clocks + +The NXP LPC18xx/43xx CREG (Configuration Registers) block contains +control registers for two low speed clocks. One of the clocks is a +32 kHz oscillator driver with power up/down and clock gating. Next +is a fixed divider that creates a 1 kHz clock from the 32 kHz osc. + +These clocks are used by the RTC and the Event Router peripherials. +The 32 kHz can also be routed to other peripherials to enable low +power modes. + +This binding uses the common clock binding: + Documentation/devicetree/bindings/clock/clock-bindings.txt + +Required properties: +- compatible: + Should be "nxp,lpc1850-creg-clk" +- #clock-cells: + Shall have value <1>. +- clocks: + Shall contain a phandle to the fixed 32 kHz crystal. + +The creg-clk node must be a child of the creg syscon node. + +The following clocks are available from the clock node. + +Clock ID Name + 0 1 kHz clock + 1 32 kHz Oscillator + +Example: +soc { + creg: syscon@40043000 { + compatible = "nxp,lpc1850-creg", "syscon", "simple-mfd"; + reg = <0x40043000 0x1000>; + + creg_clk: clock-controller { + compatible = "nxp,lpc1850-creg-clk"; + clocks = <&xtal32>; + #clock-cells = <1>; + }; + + ... + }; + + rtc: rtc@40046000 { + ... + clocks = <&creg_clk 0>, <&ccu1 CLK_CPU_BUS>; + clock-names = "rtc", "reg"; + ... + }; +}; diff --git a/Documentation/devicetree/bindings/clock/qca,ath79-pll.txt b/Documentation/devicetree/bindings/clock/qca,ath79-pll.txt index e0fc2c11dd00bb9bc903b746b709829b3108bc9d..241fb0545b9eebce2bd70277d44fcffd77365a28 100644 --- a/Documentation/devicetree/bindings/clock/qca,ath79-pll.txt +++ b/Documentation/devicetree/bindings/clock/qca,ath79-pll.txt @@ -3,7 +3,7 @@ Binding for Qualcomm Atheros AR7xxx/AR9XXX PLL controller The PPL controller provides the 3 main clocks of the SoC: CPU, DDR and AHB. Required Properties: -- compatible: has to be "qca,-cpu-intc" and one of the following +- compatible: has to be "qca,-pll" and one of the following fallbacks: - "qca,ar7100-pll" - "qca,ar7240-pll" @@ -21,8 +21,8 @@ Optional properties: Example: - memory-controller@18050000 { - compatible = "qca,ar9132-ppl", "qca,ar9130-pll"; + pll-controller@18050000 { + compatible = "qca,ar9132-pll", "qca,ar9130-pll"; reg = <0x18050000 0x20>; clock-names = "ref"; diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc.txt b/Documentation/devicetree/bindings/clock/qcom,gcc.txt index 72f82f444091361b9486b118a830690db3e70cbc..9a60fde32b02c286d2c845300de326284041d5ff 100644 --- a/Documentation/devicetree/bindings/clock/qcom,gcc.txt +++ b/Documentation/devicetree/bindings/clock/qcom,gcc.txt @@ -7,6 +7,7 @@ Required properties : "qcom,gcc-apq8064" "qcom,gcc-apq8084" "qcom,gcc-ipq8064" + "qcom,gcc-ipq4019" "qcom,gcc-msm8660" "qcom,gcc-msm8916" "qcom,gcc-msm8960" diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt index 59297d34b2084429430c4a3cdc3c8934e3ec7f1f..fefb8023020f1a543b61fb230c9de2985c3cfb03 100644 --- a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt @@ -61,7 +61,7 @@ Examples reg = <0 0xe6e88000 0 64>; interrupts = ; clocks = <&cpg CPG_MOD 310>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac1 0x13>, <&dmac1 0x12>; dma-names = "tx", "rx"; power-domains = <&cpg>; diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt index e59f57b24777c473c5c92faefbc0bec1ec17ecb9..834436fbe83d50539914108a79b0b814c144ad9e 100644 --- a/Documentation/devicetree/bindings/clock/sunxi.txt +++ b/Documentation/devicetree/bindings/clock/sunxi.txt @@ -18,6 +18,7 @@ Required properties: "allwinner,sun4i-a10-cpu-clk" - for the CPU multiplexer clock "allwinner,sun4i-a10-axi-clk" - for the AXI clock "allwinner,sun8i-a23-axi-clk" - for the AXI clock on A23 + "allwinner,sun4i-a10-gates-clk" - for generic gates on all compatible SoCs "allwinner,sun4i-a10-axi-gates-clk" - for the AXI gates "allwinner,sun4i-a10-ahb-clk" - for the AHB clock "allwinner,sun5i-a13-ahb-clk" - for the AHB clock on A13 @@ -39,12 +40,14 @@ Required properties: "allwinner,sun6i-a31-apb0-clk" - for the APB0 clock on A31 "allwinner,sun8i-a23-apb0-clk" - for the APB0 clock on A23 "allwinner,sun9i-a80-apb0-clk" - for the APB0 bus clock on A80 + "allwinner,sun8i-a83t-apb0-gates-clk" - for the APB0 gates on A83T "allwinner,sun4i-a10-apb0-gates-clk" - for the APB0 gates on A10 "allwinner,sun5i-a13-apb0-gates-clk" - for the APB0 gates on A13 "allwinner,sun5i-a10s-apb0-gates-clk" - for the APB0 gates on A10s "allwinner,sun6i-a31-apb0-gates-clk" - for the APB0 gates on A31 "allwinner,sun7i-a20-apb0-gates-clk" - for the APB0 gates on A20 "allwinner,sun8i-a23-apb0-gates-clk" - for the APB0 gates on A23 + "allwinner,sun8i-h3-apb0-gates-clk" - for the APB0 gates on H3 "allwinner,sun9i-a80-apb0-gates-clk" - for the APB0 gates on A80 "allwinner,sun4i-a10-apb1-clk" - for the APB1 clock "allwinner,sun9i-a80-apb1-clk" - for the APB1 bus clock on A80 @@ -57,6 +60,7 @@ Required properties: "allwinner,sun9i-a80-apb1-gates-clk" - for the APB1 gates on A80 "allwinner,sun6i-a31-apb2-gates-clk" - for the APB2 gates on A31 "allwinner,sun8i-a23-apb2-gates-clk" - for the APB2 gates on A23 + "allwinner,sun8i-a83t-bus-gates-clk" - for the bus gates on A83T "allwinner,sun8i-h3-bus-gates-clk" - for the bus gates on H3 "allwinner,sun9i-a80-apbs-gates-clk" - for the APBS gates on A80 "allwinner,sun4i-a10-dram-gates-clk" - for the DRAM gates on A10 diff --git a/Documentation/devicetree/bindings/clock/ti/adpll.txt b/Documentation/devicetree/bindings/clock/ti/adpll.txt new file mode 100644 index 0000000000000000000000000000000000000000..4c8a2ce2cd70181ead140f3df75472fdc0151bdb --- /dev/null +++ b/Documentation/devicetree/bindings/clock/ti/adpll.txt @@ -0,0 +1,41 @@ +Binding for Texas Instruments ADPLL clock. + +Binding status: Unstable - ABI compatibility may be broken in the future + +This binding uses the common clock binding[1]. It assumes a +register-mapped ADPLL with two to three selectable input clocks +and three to four children. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt + +Required properties: +- compatible : shall be one of "ti,dm814-adpll-s-clock" or + "ti,dm814-adpll-lj-clock" depending on the type of the ADPLL +- #clock-cells : from common clock binding; shall be set to 1. +- clocks : link phandles of parent clocks clkinp and clkinpulow, note + that the adpll-s-clock also has an optional clkinphif +- reg : address and length of the register set for controlling the ADPLL. + +Examples: + adpll_mpu_ck: adpll@40 { + #clock-cells = <1>; + compatible = "ti,dm814-adpll-s-clock"; + reg = <0x40 0x40>; + clocks = <&devosc_ck &devosc_ck &devosc_ck>; + clock-names = "clkinp", "clkinpulow", "clkinphif"; + clock-output-names = "481c5040.adpll.dcoclkldo", + "481c5040.adpll.clkout", + "481c5040.adpll.clkoutx2", + "481c5040.adpll.clkouthif"; + }; + + adpll_dsp_ck: adpll@80 { + #clock-cells = <1>; + compatible = "ti,dm814-adpll-lj-clock"; + reg = <0x80 0x30>; + clocks = <&devosc_ck &devosc_ck>; + clock-names = "clkinp", "clkinpulow"; + clock-output-names = "481c5080.adpll.dcoclkldo", + "481c5080.adpll.clkout", + "481c5080.adpll.clkoutldo"; + }; diff --git a/Documentation/devicetree/bindings/clock/xgene.txt b/Documentation/devicetree/bindings/clock/xgene.txt index 1c4ef773feea1b7ee659d887f1f03287268db9b4..82f9638121dbf31fd36d24b02e714e410b7c5be7 100644 --- a/Documentation/devicetree/bindings/clock/xgene.txt +++ b/Documentation/devicetree/bindings/clock/xgene.txt @@ -9,6 +9,8 @@ Required properties: "apm,xgene-socpll-clock" - for a X-Gene SoC PLL clock "apm,xgene-pcppll-clock" - for a X-Gene PCP PLL clock "apm,xgene-device-clock" - for a X-Gene device clock + "apm,xgene-socpll-v2-clock" - for a X-Gene SoC PLL v2 clock + "apm,xgene-pcppll-v2-clock" - for a X-Gene PCP PLL v2 clock Required properties for SoC or PCP PLL clocks: - reg : shall be the physical PLL register address for the pll clock. diff --git a/Documentation/devicetree/bindings/display/arm,hdlcd.txt b/Documentation/devicetree/bindings/display/arm,hdlcd.txt new file mode 100644 index 0000000000000000000000000000000000000000..78bc24296f3e477770decb7e9af40cf5d59c88d1 --- /dev/null +++ b/Documentation/devicetree/bindings/display/arm,hdlcd.txt @@ -0,0 +1,79 @@ +ARM HDLCD + +This is a display controller found on several development platforms produced +by ARM Ltd and in more modern of its' Fast Models. The HDLCD is an RGB +streamer that reads the data from a framebuffer and sends it to a single +digital encoder (DVI or HDMI). + +Required properties: + - compatible: "arm,hdlcd" + - reg: Physical base address and length of the controller's registers. + - interrupts: One interrupt used by the display controller to notify the + interrupt controller when any of the interrupt sources programmed in + the interrupt mask register have activated. + - clocks: A list of phandle + clock-specifier pairs, one for each + entry in 'clock-names'. + - clock-names: A list of clock names. For HDLCD it should contain: + - "pxlclk" for the clock feeding the output PLL of the controller. + +Required sub-nodes: + - port: The HDLCD connection to an encoder chip. The connection is modeled + using the OF graph bindings specified in + Documentation/devicetree/bindings/graph.txt. + +Optional properties: + - memory-region: phandle to a node describing memory (see + Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt) to be + used for the framebuffer; if not present, the framebuffer may be located + anywhere in memory. + + +Example: + +/ { + ... + + hdlcd@2b000000 { + compatible = "arm,hdlcd"; + reg = <0 0x2b000000 0 0x1000>; + interrupts = ; + clocks = <&oscclk5>; + clock-names = "pxlclk"; + port { + hdlcd_output: endpoint@0 { + remote-endpoint = <&hdmi_enc_input>; + }; + }; + }; + + /* HDMI encoder on I2C bus */ + i2c@7ffa0000 { + .... + hdmi-transmitter@70 { + compatible = "....."; + reg = <0x70>; + port@0 { + hdmi_enc_input: endpoint { + remote-endpoint = <&hdlcd_output>; + }; + + hdmi_enc_output: endpoint { + remote-endpoint = <&hdmi_1_port>; + }; + }; + }; + + }; + + hdmi1: connector@1 { + compatible = "hdmi-connector"; + type = "a"; + port { + hdmi_1_port: endpoint { + remote-endpoint = <&hdmi_enc_output>; + }; + }; + }; + + ... +}; diff --git a/Documentation/devicetree/bindings/display/brcm,bcm-vc4.txt b/Documentation/devicetree/bindings/display/brcm,bcm-vc4.txt index 56a961aa50613054ff4354b2ebfa86fd3503bfa1..9f97df4d51524bf55beff1f3e3eaace0b8e61637 100644 --- a/Documentation/devicetree/bindings/display/brcm,bcm-vc4.txt +++ b/Documentation/devicetree/bindings/display/brcm,bcm-vc4.txt @@ -35,6 +35,12 @@ Optional properties for HDMI: as an interrupt/status bit in the HDMI controller itself). See bindings/pinctrl/brcm,bcm2835-gpio.txt +Required properties for V3D: +- compatible: Should be "brcm,bcm2835-v3d" +- reg: Physical base address and length of the V3D's registers +- interrupts: The interrupt number + See bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt + Example: pixelvalve@7e807000 { compatible = "brcm,bcm2835-pixelvalve2"; @@ -60,6 +66,12 @@ hdmi: hdmi@7e902000 { clock-names = "pixel", "hdmi"; }; +v3d: v3d@7ec00000 { + compatible = "brcm,bcm2835-v3d"; + reg = <0x7ec00000 0x1000>; + interrupts = <1 10>; +}; + vc4: gpu { compatible = "brcm,bcm2835-vc4"; }; diff --git a/Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt b/Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt index 0e6f0c02485878ecf60a3b9b73ecb09417d8ab4d..22756b3dede2a3a839ea9889c23562b5ac305dfc 100644 --- a/Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt +++ b/Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt @@ -6,6 +6,7 @@ Required properties: "samsung,exynos4210-mipi-dsi" /* for Exynos4 SoCs */ "samsung,exynos4415-mipi-dsi" /* for Exynos4415 SoC */ "samsung,exynos5410-mipi-dsi" /* for Exynos5410/5420/5440 SoCs */ + "samsung,exynos5422-mipi-dsi" /* for Exynos5422/5800 SoCs */ "samsung,exynos5433-mipi-dsi" /* for Exynos5433 SoCs */ - reg: physical base address and length of the registers set for the device - interrupts: should contain DSI interrupt diff --git a/Documentation/devicetree/bindings/display/exynos/samsung-fimd.txt b/Documentation/devicetree/bindings/display/exynos/samsung-fimd.txt index 27c3ce0db16a3c43a525b55a03d3869cc5edcb07..c7c6b9af87ac4f6e36ebdeb8b5c29cbc3d90ca1e 100644 --- a/Documentation/devicetree/bindings/display/exynos/samsung-fimd.txt +++ b/Documentation/devicetree/bindings/display/exynos/samsung-fimd.txt @@ -12,7 +12,8 @@ Required properties: "samsung,exynos3250-fimd"; /* for Exynos3250/3472 SoCs */ "samsung,exynos4210-fimd"; /* for Exynos4 SoCs */ "samsung,exynos4415-fimd"; /* for Exynos4415 SoC */ - "samsung,exynos5250-fimd"; /* for Exynos5 SoCs */ + "samsung,exynos5250-fimd"; /* for Exynos5250 SoCs */ + "samsung,exynos5420-fimd"; /* for Exynos5420/5422/5800 SoCs */ - reg: physical base address and length of the FIMD registers set. diff --git a/Documentation/devicetree/bindings/display/msm/dsi.txt b/Documentation/devicetree/bindings/display/msm/dsi.txt index e7423bea1424a95532031e7561ccbd52c509c68c..f5948c48b9a23582e63a7573a3e394ed9b37360c 100644 --- a/Documentation/devicetree/bindings/display/msm/dsi.txt +++ b/Documentation/devicetree/bindings/display/msm/dsi.txt @@ -44,9 +44,34 @@ Optional properties: - pinctrl-names: the pin control state names; should contain "default" - pinctrl-0: the default pinctrl state (active) - pinctrl-n: the "sleep" pinctrl state -- port: DSI controller output port. This contains one endpoint subnode, with its - remote-endpoint set to the phandle of the connected panel's endpoint. - See Documentation/devicetree/bindings/graph.txt for device graph info. +- port: DSI controller output port, containing one endpoint subnode. + + DSI Endpoint properties: + - remote-endpoint: set to phandle of the connected panel's endpoint. + See Documentation/devicetree/bindings/graph.txt for device graph info. + - qcom,data-lane-map: this describes how the logical DSI lanes are mapped + to the physical lanes on the given platform. The value contained in + index n describes what logical data lane is mapped to the physical data + lane n (DATAn, where n lies between 0 and 3). + + For example: + + qcom,data-lane-map = <3 0 1 2>; + + The above mapping describes that the logical data lane DATA3 is mapped to + the physical data lane DATA0, logical DATA0 to physical DATA1, logic DATA1 + to phys DATA2 and logic DATA2 to phys DATA3. + + There are only a limited number of physical to logical mappings possible: + + "0123": Logic 0->Phys 0; Logic 1->Phys 1; Logic 2->Phys 2; Logic 3->Phys 3; + "3012": Logic 3->Phys 0; Logic 0->Phys 1; Logic 1->Phys 2; Logic 2->Phys 3; + "2301": Logic 2->Phys 0; Logic 3->Phys 1; Logic 0->Phys 2; Logic 1->Phys 3; + "1230": Logic 1->Phys 0; Logic 2->Phys 1; Logic 3->Phys 2; Logic 0->Phys 3; + "0321": Logic 0->Phys 0; Logic 3->Phys 1; Logic 2->Phys 2; Logic 1->Phys 3; + "1032": Logic 1->Phys 0; Logic 0->Phys 1; Logic 3->Phys 2; Logic 2->Phys 3; + "2103": Logic 2->Phys 0; Logic 1->Phys 1; Logic 0->Phys 2; Logic 3->Phys 3; + "3210": Logic 3->Phys 0; Logic 2->Phys 1; Logic 1->Phys 2; Logic 0->Phys 3; DSI PHY: Required properties: @@ -131,6 +156,7 @@ Example: port { dsi0_out: endpoint { remote-endpoint = <&panel_in>; + lanes = <0 1 2 3>; }; }; }; diff --git a/Documentation/devicetree/bindings/display/msm/hdmi.txt b/Documentation/devicetree/bindings/display/msm/hdmi.txt index 379ee2ea9a3d848e881af9cc45809004cd1022ea..b63f614e0c045fd9e28eff611cabab6cc4f8fb16 100644 --- a/Documentation/devicetree/bindings/display/msm/hdmi.txt +++ b/Documentation/devicetree/bindings/display/msm/hdmi.txt @@ -11,6 +11,7 @@ Required properties: - reg: Physical base address and length of the controller's registers - reg-names: "core_physical" - interrupts: The interrupt signal from the hdmi block. +- power-domains: Should be <&mmcc MDSS_GDSC>. - clocks: device clocks See ../clocks/clock-bindings.txt for details. - qcom,hdmi-tx-ddc-clk-gpio: ddc clk pin @@ -18,6 +19,8 @@ Required properties: - qcom,hdmi-tx-hpd-gpio: hpd pin - core-vdda-supply: phandle to supply regulator - hdmi-mux-supply: phandle to mux regulator +- phys: the phandle for the HDMI PHY device +- phy-names: the name of the corresponding PHY device Optional properties: - qcom,hdmi-tx-mux-en-gpio: hdmi mux enable pin @@ -27,15 +30,38 @@ Optional properties: - pinctrl-0: the default pinctrl state (active) - pinctrl-1: the "sleep" pinctrl state +HDMI PHY: +Required properties: +- compatible: Could be the following + * "qcom,hdmi-phy-8660" + * "qcom,hdmi-phy-8960" + * "qcom,hdmi-phy-8974" + * "qcom,hdmi-phy-8084" + * "qcom,hdmi-phy-8996" +- #phy-cells: Number of cells in a PHY specifier; Should be 0. +- reg: Physical base address and length of the registers of the PHY sub blocks. +- reg-names: The names of register regions. The following regions are required: + * "hdmi_phy" + * "hdmi_pll" + For HDMI PHY on msm8996, these additional register regions are required: + * "hdmi_tx_l0" + * "hdmi_tx_l1" + * "hdmi_tx_l3" + * "hdmi_tx_l4" +- power-domains: Should be <&mmcc MDSS_GDSC>. +- clocks: device clocks + See Documentation/devicetree/bindings/clocks/clock-bindings.txt for details. +- core-vdda-supply: phandle to vdda regulator device node + Example: / { ... - hdmi: qcom,hdmi-tx-8960@4a00000 { + hdmi: hdmi@4a00000 { compatible = "qcom,hdmi-tx-8960"; reg-names = "core_physical"; - reg = <0x04a00000 0x1000>; + reg = <0x04a00000 0x2f0>; interrupts = ; power-domains = <&mmcc MDSS_GDSC>; clock-names = @@ -54,5 +80,21 @@ Example: pinctrl-names = "default", "sleep"; pinctrl-0 = <&hpd_active &ddc_active &cec_active>; pinctrl-1 = <&hpd_suspend &ddc_suspend &cec_suspend>; + + phys = <&hdmi_phy>; + phy-names = "hdmi_phy"; + }; + + hdmi_phy: phy@4a00400 { + compatible = "qcom,hdmi-phy-8960"; + reg-names = "hdmi_phy", + "hdmi_pll"; + reg = <0x4a00400 0x60>, + <0x4a00500 0x100>; + #phy-cells = <0>; + power-domains = <&mmcc MDSS_GDSC>; + clock-names = "slave_iface_clk"; + clocks = <&mmcc HDMI_S_AHB_CLK>; + core-vdda-supply = <&pm8921_hdmi_mvs>; }; }; diff --git a/Documentation/devicetree/bindings/display/panel/lg,lp120up1.txt b/Documentation/devicetree/bindings/display/panel/lg,lp120up1.txt new file mode 100644 index 0000000000000000000000000000000000000000..8c5de692c55ce6036219b9c812832ddb75ea14cb --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/lg,lp120up1.txt @@ -0,0 +1,7 @@ +LG 12.0" (1920x1280 pixels) TFT LCD panel + +Required properties: +- compatible: should be "lg,lp120up1" + +This binding is compatible with the simple-panel binding, which is specified +in simple-panel.txt in this directory. diff --git a/Documentation/devicetree/bindings/display/panel/urt,umsh-8596md.txt b/Documentation/devicetree/bindings/display/panel/urt,umsh-8596md.txt new file mode 100644 index 0000000000000000000000000000000000000000..088a6cea5015fa5590c5b3c31d0d90b549f0ca0a --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/urt,umsh-8596md.txt @@ -0,0 +1,16 @@ +United Radiant Technology UMSH-8596MD-xT 7.0" WVGA TFT LCD panel + +Supported are LVDS versions (-11T, -19T) and parallel ones +(-T, -1T, -7T, -20T). + +Required properties: +- compatible: should be one of: + "urt,umsh-8596md-t", + "urt,umsh-8596md-1t", + "urt,umsh-8596md-7t", + "urt,umsh-8596md-11t", + "urt,umsh-8596md-19t", + "urt,umsh-8596md-20t". + +This binding is compatible with the simple-panel binding, which is specified +in simple-panel.txt in this directory. diff --git a/Documentation/devicetree/bindings/display/renesas,du.txt b/Documentation/devicetree/bindings/display/renesas,du.txt index eccd4f4867b29cd9e5a1c6fee231fadfb79b5e8e..0d30e42e40bea1512428f0d7c15910f5daae7a19 100644 --- a/Documentation/devicetree/bindings/display/renesas,du.txt +++ b/Documentation/devicetree/bindings/display/renesas,du.txt @@ -8,6 +8,7 @@ Required Properties: - "renesas,du-r8a7791" for R8A7791 (R-Car M2-W) compatible DU - "renesas,du-r8a7793" for R8A7793 (R-Car M2-N) compatible DU - "renesas,du-r8a7794" for R8A7794 (R-Car E2) compatible DU + - "renesas,du-r8a7795" for R8A7795 (R-Car H3) compatible DU - reg: A list of base address and length of each memory resource, one for each entry in the reg-names property. @@ -24,7 +25,7 @@ Required Properties: - clock-names: Name of the clocks. This property is model-dependent. - R8A7779 uses a single functional clock. The clock doesn't need to be named. - - R8A779[0134] use one functional clock per channel and one clock per LVDS + - R8A779[01345] use one functional clock per channel and one clock per LVDS encoder (if available). The functional clocks must be named "du.x" with "x" being the channel numerical index. The LVDS clocks must be named "lvds.x" with "x" being the LVDS encoder numerical index. @@ -41,13 +42,14 @@ bindings specified in Documentation/devicetree/bindings/graph.txt. The following table lists for each supported model the port number corresponding to each DU output. - Port 0 Port1 Port2 + Port 0 Port1 Port2 Port3 ----------------------------------------------------------------------------- - R8A7779 (H1) DPAD 0 DPAD 1 - - R8A7790 (H2) DPAD LVDS 0 LVDS 1 - R8A7791 (M2-W) DPAD LVDS 0 - - R8A7793 (M2-N) DPAD LVDS 0 - - R8A7794 (E2) DPAD 0 DPAD 1 - + R8A7779 (H1) DPAD 0 DPAD 1 - - + R8A7790 (H2) DPAD LVDS 0 LVDS 1 - + R8A7791 (M2-W) DPAD LVDS 0 - - + R8A7793 (M2-N) DPAD LVDS 0 - - + R8A7794 (E2) DPAD 0 DPAD 1 - - + R8A7795 (H3) DPAD HDMI 0 HDMI 1 LVDS Example: R8A7790 (R-Car H2) DU diff --git a/Documentation/devicetree/bindings/display/rockchip/inno_hdmi-rockchip.txt b/Documentation/devicetree/bindings/display/rockchip/inno_hdmi-rockchip.txt new file mode 100644 index 0000000000000000000000000000000000000000..8096a29f9776aa133249a51ac4b2b3912d507fab --- /dev/null +++ b/Documentation/devicetree/bindings/display/rockchip/inno_hdmi-rockchip.txt @@ -0,0 +1,50 @@ +Rockchip specific extensions to the Innosilicon HDMI +================================ + +Required properties: +- compatible: + "rockchip,rk3036-inno-hdmi"; +- reg: + Physical base address and length of the controller's registers. +- clocks, clock-names: + Phandle to hdmi controller clock, name should be "pclk" +- interrupts: + HDMI interrupt number +- ports: + Contain one port node with endpoint definitions as defined in + Documentation/devicetree/bindings/graph.txt. +- pinctrl-0, pinctrl-name: + Switch the iomux of HPD/CEC pins to HDMI function. + +Example: +hdmi: hdmi@20034000 { + compatible = "rockchip,rk3036-inno-hdmi"; + reg = <0x20034000 0x4000>; + interrupts = ; + clocks = <&cru PCLK_HDMI>; + clock-names = "pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&hdmi_ctl>; + status = "disabled"; + + hdmi_in: port { + #address-cells = <1>; + #size-cells = <0>; + hdmi_in_lcdc: endpoint@0 { + reg = <0>; + remote-endpoint = <&lcdc_out_hdmi>; + }; + }; +}; + +&pinctrl { + hdmi { + hdmi_ctl: hdmi-ctl { + rockchip,pins = <1 8 RK_FUNC_1 &pcfg_pull_none>, + <1 9 RK_FUNC_1 &pcfg_pull_none>, + <1 10 RK_FUNC_1 &pcfg_pull_none>, + <1 11 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + +}; diff --git a/Documentation/devicetree/bindings/dma/mmp-dma.txt b/Documentation/devicetree/bindings/dma/mmp-dma.txt index 7a802f64e5bd8f89e08b0bd4b34a388eeb926254..8f7364a7b349edc76bdad6737234dd97907c75d4 100644 --- a/Documentation/devicetree/bindings/dma/mmp-dma.txt +++ b/Documentation/devicetree/bindings/dma/mmp-dma.txt @@ -12,6 +12,8 @@ Required properties: Optional properties: - #dma-channels: Number of DMA channels supported by the controller (defaults to 32 when not specified) +- #dma-requests: Number of DMA requestor lines supported by the controller + (defaults to 32 when not specified) "marvell,pdma-1.0" Used platforms: pxa25x, pxa27x, pxa3xx, pxa93x, pxa168, pxa910, pxa688. diff --git a/Documentation/devicetree/bindings/goldfish/audio.txt b/Documentation/devicetree/bindings/goldfish/audio.txt new file mode 100644 index 0000000000000000000000000000000000000000..d043fda433bac51e42b99bb464ee7ba9c3a689db --- /dev/null +++ b/Documentation/devicetree/bindings/goldfish/audio.txt @@ -0,0 +1,17 @@ +Android Goldfish Audio + +Android goldfish audio device generated by android emulator. + +Required properties: + +- compatible : should contain "google,goldfish-audio" to match emulator +- reg : +- interrupts : + +Example: + + goldfish_audio@9030000 { + compatible = "google,goldfish-audio"; + reg = <0x9030000 0x100>; + interrupts = <0x4>; + }; diff --git a/Documentation/devicetree/bindings/goldfish/events.txt b/Documentation/devicetree/bindings/goldfish/events.txt new file mode 100644 index 0000000000000000000000000000000000000000..5babf46317a4e46e55d00f57c35e21caba4a6c78 --- /dev/null +++ b/Documentation/devicetree/bindings/goldfish/events.txt @@ -0,0 +1,17 @@ +Android Goldfish Events Keypad + +Android goldfish events keypad device generated by android emulator. + +Required properties: + +- compatible : should contain "google,goldfish-events-keypad" to match emulator +- reg : +- interrupts : + +Example: + + goldfish-events@9040000 { + compatible = "google,goldfish-events-keypad"; + reg = <0x9040000 0x1000>; + interrupts = <0x5>; + }; diff --git a/Documentation/devicetree/bindings/i2c/i2c-demux-pinctrl.txt b/Documentation/devicetree/bindings/i2c/i2c-demux-pinctrl.txt new file mode 100644 index 0000000000000000000000000000000000000000..6078aefe7ed481bb9474623ac2dc67d8a0fda7f8 --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/i2c-demux-pinctrl.txt @@ -0,0 +1,135 @@ +Pinctrl-based I2C Bus DeMux + +This binding describes an I2C bus demultiplexer that uses pin multiplexing to +route the I2C signals, and represents the pin multiplexing configuration using +the pinctrl device tree bindings. This may be used to select one I2C IP core at +runtime which may have a better feature set for a given task than another I2C +IP core on the SoC. The most simple example is to fall back to GPIO bitbanging +if your current runtime configuration hits an errata of the internal IP core. + + +-------------------------------+ + | SoC | + | | +-----+ +-----+ + | +------------+ | | dev | | dev | + | |I2C IP Core1|--\ | +-----+ +-----+ + | +------------+ \-------+ | | | + | |Pinctrl|--|------+--------+ + | +------------+ +-------+ | + | |I2C IP Core2|--/ | + | +------------+ | + | | + +-------------------------------+ + +Required properties: +- compatible: "i2c-demux-pinctrl" +- i2c-parent: List of phandles of I2C masters available for selection. The first + one will be used as default. +- i2c-bus-name: The name of this bus. Also needed as pinctrl-name for the I2C + parents. + +Furthermore, I2C mux properties and child nodes. See mux.txt in this directory. + +Example: + +Here is a snipplet for a bus to be demuxed. It contains various i2c clients for +HDMI, so the bus is named "i2c-hdmi": + + i2chdmi: i2c@8 { + + compatible = "i2c-demux-pinctrl"; + i2c-parent = <&gpioi2c>, <&iic2>, <&i2c2>; + i2c-bus-name = "i2c-hdmi"; + #address-cells = <1>; + #size-cells = <0>; + + ak4643: sound-codec@12 { + compatible = "asahi-kasei,ak4643"; + + #sound-dai-cells = <0>; + reg = <0x12>; + }; + + composite-in@20 { + compatible = "adi,adv7180"; + reg = <0x20>; + remote = <&vin1>; + + port { + adv7180: endpoint { + bus-width = <8>; + remote-endpoint = <&vin1ep0>; + }; + }; + }; + + hdmi@39 { + compatible = "adi,adv7511w"; + reg = <0x39>; + interrupt-parent = <&gpio1>; + interrupts = <15 IRQ_TYPE_LEVEL_LOW>; + + adi,input-depth = <8>; + adi,input-colorspace = "rgb"; + adi,input-clock = "1x"; + adi,input-style = <1>; + adi,input-justification = "evenly"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + adv7511_in: endpoint { + remote-endpoint = <&du_out_lvds0>; + }; + }; + + port@1 { + reg = <1>; + adv7511_out: endpoint { + remote-endpoint = <&hdmi_con>; + }; + }; + }; + }; + }; + +And for clarification, here are the snipplets for the i2c-parents: + + gpioi2c: i2c@9 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "i2c-gpio"; + status = "disabled"; + gpios = <&gpio5 6 GPIO_ACTIVE_HIGH /* sda */ + &gpio5 5 GPIO_ACTIVE_HIGH /* scl */ + >; + i2c-gpio,delay-us = <5>; + }; + +... + +&i2c2 { + pinctrl-0 = <&i2c2_pins>; + pinctrl-names = "i2c-hdmi"; + + clock-frequency = <100000>; +}; + +... + +&iic2 { + pinctrl-0 = <&iic2_pins>; + pinctrl-names = "i2c-hdmi"; + + clock-frequency = <100000>; +}; + +Please note: + +- pinctrl properties for the parent I2C controllers need a pinctrl state + with the same name as i2c-bus-name, not "default"! + +- the i2c masters must have their status "disabled". This driver will + enable them at runtime when needed. diff --git a/Documentation/devicetree/bindings/i2c/i2c-imx.txt b/Documentation/devicetree/bindings/i2c/i2c-imx.txt index eab5836ba7f98a10dedeb8d30b997cc45470944d..b967544590e804c413063cfbd4c1d56bee6f486b 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-imx.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-imx.txt @@ -11,7 +11,7 @@ Required properties: Optional properties: - clock-frequency : Constains desired I2C/HS-I2C bus clock frequency in Hz. - The absence of the propoerty indicates the default frequency 100 kHz. + The absence of the property indicates the default frequency 100 kHz. - dmas: A list of two dma specifiers, one for each entry in dma-names. - dma-names: should contain "tx" and "rx". - scl-gpios: specify the gpio related to SCL pin diff --git a/Documentation/devicetree/bindings/i2c/i2c-rcar.txt b/Documentation/devicetree/bindings/i2c/i2c-rcar.txt index 95e97223a71c83005c1d0acca9b39c7479f34002..cf8bfc956cdcea64691351b977356f4df9691a02 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-rcar.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-rcar.txt @@ -17,7 +17,7 @@ Required properties: Optional properties: - clock-frequency: desired I2C bus clock frequency in Hz. The absence of this - propoerty indicates the default frequency 100 kHz. + property indicates the default frequency 100 kHz. - clocks: clock specifier. - i2c-scl-falling-time-ns: see i2c.txt diff --git a/Documentation/devicetree/bindings/i2c/i2c-sirf.txt b/Documentation/devicetree/bindings/i2c/i2c-sirf.txt index 7baf9e133fa8670cbffd74eb86d3671c163a5ed0..2701eefb00f77c9f64d79c63efed43c4b2cec239 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-sirf.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-sirf.txt @@ -8,7 +8,7 @@ Required properties : Optional properties: - clock-frequency : Constains desired I2C/HS-I2C bus clock frequency in Hz. - The absence of the propoerty indicates the default frequency 100 kHz. + The absence of the property indicates the default frequency 100 kHz. Examples : diff --git a/Documentation/devicetree/bindings/i2c/i2c-xiic.txt b/Documentation/devicetree/bindings/i2c/i2c-xiic.txt index ceabbe91ae449f2f2a7d006e45ff746995841e50..caf42e98946255098ddbff95c19efa360655fc09 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-xiic.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-xiic.txt @@ -6,14 +6,17 @@ Required properties: - interrupts : IIC controller unterrupt - #address-cells = <1> - #size-cells = <0> +- clocks: Input clock specifier. Refer to common clock bindings. Optional properties: - Child nodes conforming to i2c bus binding +- clock-names: Input clock name, should be 'pclk'. Example: axi_iic_0: i2c@40800000 { compatible = "xlnx,xps-iic-2.00.a"; + clocks = <&clkc 15>; interrupts = < 1 2 >; reg = < 0x40800000 0x10000 >; diff --git a/Documentation/devicetree/bindings/iio/accel/mma8452.txt b/Documentation/devicetree/bindings/iio/accel/mma8452.txt index 3c10e8581144a128f380240ea8537bfc2a963956..165937e1ac1c4da1b029af3341b6f860e2f956ba 100644 --- a/Documentation/devicetree/bindings/iio/accel/mma8452.txt +++ b/Documentation/devicetree/bindings/iio/accel/mma8452.txt @@ -1,8 +1,10 @@ -Freescale MMA8452Q, MMA8453Q, MMA8652FC or MMA8653FC triaxial accelerometer +Freescale MMA8451Q, MMA8452Q, MMA8453Q, MMA8652FC or MMA8653FC +triaxial accelerometer Required properties: - compatible: should contain one of + * "fsl,mma8451" * "fsl,mma8452" * "fsl,mma8453" * "fsl,mma8652" diff --git a/Documentation/devicetree/bindings/iio/adc/at91-sama5d2_adc.txt b/Documentation/devicetree/bindings/iio/adc/at91-sama5d2_adc.txt new file mode 100644 index 0000000000000000000000000000000000000000..3223684a643b81791454ee48b250a5fba4cb094a --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/at91-sama5d2_adc.txt @@ -0,0 +1,28 @@ +* AT91 SAMA5D2 Analog to Digital Converter (ADC) + +Required properties: + - compatible: Should be "atmel,sama5d2-adc". + - reg: Should contain ADC registers location and length. + - interrupts: Should contain the IRQ line for the ADC. + - clocks: phandle to device clock. + - clock-names: Must be "adc_clk". + - vref-supply: Supply used as reference for conversions. + - vddana-supply: Supply for the adc device. + - atmel,min-sample-rate-hz: Minimum sampling rate, it depends on SoC. + - atmel,max-sample-rate-hz: Maximum sampling rate, it depends on SoC. + - atmel,startup-time-ms: Startup time expressed in ms, it depends on SoC. + +Example: + +adc: adc@fc030000 { + compatible = "atmel,sama5d2-adc"; + reg = <0xfc030000 0x100>; + interrupts = <40 IRQ_TYPE_LEVEL_HIGH 7>; + clocks = <&adc_clk>; + clock-names = "adc_clk"; + atmel,min-sample-rate-hz = <200000>; + atmel,max-sample-rate-hz = <20000000>; + atmel,startup-time-ms = <4>; + vddana-supply = <&vdd_3v3_lp_reg>; + vref-supply = <&vdd_3v3_lp_reg>; +} diff --git a/Documentation/devicetree/bindings/iio/adc/fsl,imx25-gcq.txt b/Documentation/devicetree/bindings/iio/adc/fsl,imx25-gcq.txt new file mode 100644 index 0000000000000000000000000000000000000000..b0866d36a30741f59937fecfc32e69213b84fa4f --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/fsl,imx25-gcq.txt @@ -0,0 +1,58 @@ +Freescale i.MX25 ADC GCQ device + +This is a generic conversion queue device that can convert any of the +analog inputs using the ADC unit of the i.MX25. + +Required properties: + - compatible: Should be "fsl,imx25-gcq". + - reg: Should be the register range of the module. + - interrupts: Should be the interrupt number of the module. + Typically this is <1>. + - interrupt-parent: phandle to the tsadc module of the i.MX25. + - #address-cells: Should be <1> (setting for the subnodes) + - #size-cells: Should be <0> (setting for the subnodes) + +Optional properties: + - vref-ext-supply: The regulator supplying the ADC reference voltage. + Required when at least one subnode uses the this reference. + - vref-xp-supply: The regulator supplying the ADC reference voltage on pin XP. + Required when at least one subnode uses this reference. + - vref-yp-supply: The regulator supplying the ADC reference voltage on pin YP. + Required when at least one subnode uses this reference. + +Sub-nodes: +Optionally you can define subnodes which define the reference voltage +for the analog inputs. + +Required properties for subnodes: + - reg: Should be the number of the analog input. + 0: xp + 1: yp + 2: xn + 3: yn + 4: wiper + 5: inaux0 + 6: inaux1 + 7: inaux2 +Optional properties for subnodes: + - fsl,adc-refp: specifies the positive reference input as defined in + + - fsl,adc-refn: specifies the negative reference input as defined in + + +Example: + + adc: adc@50030800 { + compatible = "fsl,imx25-gcq"; + reg = <0x50030800 0x60>; + interrupt-parent = <&tscadc>; + interrupts = <1>; + #address-cells = <1>; + #size-cells = <0>; + + inaux@5 { + reg = <5>; + fsl,adc-refp = ; + fsl,adc-refn = ; + }; + }; diff --git a/Documentation/devicetree/bindings/iio/adc/mcp3422.txt b/Documentation/devicetree/bindings/iio/adc/mcp3422.txt index dcae4ccfcc5284b8f116e2c788fbc30c996603c9..82bcce07255d4792baee3038b0a2dfadbff7b3c4 100644 --- a/Documentation/devicetree/bindings/iio/adc/mcp3422.txt +++ b/Documentation/devicetree/bindings/iio/adc/mcp3422.txt @@ -6,6 +6,7 @@ Required properties: "microchip,mcp3422" or "microchip,mcp3423" or "microchip,mcp3424" or + "microchip,mcp3425" or "microchip,mcp3426" or "microchip,mcp3427" or "microchip,mcp3428" diff --git a/Documentation/devicetree/bindings/iio/adc/ti-adc0832.txt b/Documentation/devicetree/bindings/iio/adc/ti-adc0832.txt new file mode 100644 index 0000000000000000000000000000000000000000..d91130587d016ab8e88cb193e8e787188a251435 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/ti-adc0832.txt @@ -0,0 +1,19 @@ +* Texas Instruments' ADC0831/ADC0832/ADC0832/ADC0838 + +Required properties: + - compatible: Should be one of + * "ti,adc0831" + * "ti,adc0832" + * "ti,adc0834" + * "ti,adc0838" + - reg: spi chip select number for the device + - vref-supply: The regulator supply for ADC reference voltage + - spi-max-frequency: Max SPI frequency to use (< 400000) + +Example: +adc@0 { + compatible = "ti,adc0832"; + reg = <0>; + vref-supply = <&vdd_supply>; + spi-max-frequency = <200000>; +}; diff --git a/Documentation/devicetree/bindings/iio/chemical/atlas,ph-sm.txt b/Documentation/devicetree/bindings/iio/chemical/atlas,ph-sm.txt new file mode 100644 index 0000000000000000000000000000000000000000..cffa1907463a21bc334a46db0b2fade4bc4879b6 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/chemical/atlas,ph-sm.txt @@ -0,0 +1,22 @@ +* Atlas Scientific pH-SM OEM sensor + +http://www.atlas-scientific.com/_files/_datasheets/_oem/pH_oem_datasheet.pdf + +Required properties: + + - compatible: must be "atlas,ph-sm" + - reg: the I2C address of the sensor + - interrupt-parent: should be the phandle for the interrupt controller + - interrupts: the sole interrupt generated by the device + + Refer to interrupt-controller/interrupts.txt for generic interrupt client + node bindings. + +Example: + +atlas@65 { + compatible = "atlas,ph-sm"; + reg = <0x65>; + interrupt-parent = <&gpio1>; + interrupts = <16 2>; +}; diff --git a/Documentation/devicetree/bindings/iio/dac/vf610-dac.txt b/Documentation/devicetree/bindings/iio/dac/vf610-dac.txt new file mode 100644 index 0000000000000000000000000000000000000000..20c6c7ae9687b06c1a478326bfebb083186b88a4 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/dac/vf610-dac.txt @@ -0,0 +1,20 @@ +Freescale vf610 Digital to Analog Converter bindings + +The devicetree bindings are for the new DAC driver written for +vf610 SoCs from Freescale. + +Required properties: +- compatible: Should contain "fsl,vf610-dac" +- reg: Offset and length of the register set for the device +- interrupts: Should contain the interrupt for the device +- clocks: The clock is needed by the DAC controller +- clock-names: Must contain "dac" matching entry in the clocks property. + +Example: +dac0: dac@400cc000 { + compatible = "fsl,vf610-dac"; + reg = <0x400cc000 0x1000>; + interrupts = <55 IRQ_TYPE_LEVEL_HIGH>; + clock-names = "dac"; + clocks = <&clks VF610_CLK_DAC0>; +}; diff --git a/Documentation/devicetree/bindings/iio/health/afe4403.txt b/Documentation/devicetree/bindings/iio/health/afe4403.txt new file mode 100644 index 0000000000000000000000000000000000000000..2fffd70336ba2eb52ae91346f942f3e3d395a1d2 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/health/afe4403.txt @@ -0,0 +1,34 @@ +Texas Instruments AFE4403 Heart rate and Pulse Oximeter + +Required properties: + - compatible : Should be "ti,afe4403". + - reg : SPI chip select address of device. + - tx-supply : Regulator supply to transmitting LEDs. + - interrupt-parent : Phandle to he parent interrupt controller. + - interrupts : The interrupt line the device ADC_RDY pin is + connected to. For details refer to, + ../../interrupt-controller/interrupts.txt. + +Optional properties: + - reset-gpios : GPIO used to reset the device. + For details refer to, ../../gpio/gpio.txt. + +For other required and optional properties of SPI slave nodes +please refer to ../../spi/spi-bus.txt. + +Example: + +&spi0 { + heart_mon@0 { + compatible = "ti,afe4403"; + reg = <0>; + spi-max-frequency = <10000000>; + + tx-supply = <&vbat>; + + interrupt-parent = <&gpio1>; + interrupts = <28 IRQ_TYPE_EDGE_RISING>; + + reset-gpios = <&gpio1 16 GPIO_ACTIVE_LOW>; + }; +}; diff --git a/Documentation/devicetree/bindings/iio/health/afe4404.txt b/Documentation/devicetree/bindings/iio/health/afe4404.txt new file mode 100644 index 0000000000000000000000000000000000000000..de69f203edfae9959c5b9481569a3eb8c0cefe8e --- /dev/null +++ b/Documentation/devicetree/bindings/iio/health/afe4404.txt @@ -0,0 +1,30 @@ +Texas Instruments AFE4404 Heart rate and Pulse Oximeter + +Required properties: + - compatible : Should be "ti,afe4404". + - reg : I2C address of the device. + - tx-supply : Regulator supply to transmitting LEDs. + - interrupt-parent : Phandle to he parent interrupt controller. + - interrupts : The interrupt line the device ADC_RDY pin is + connected to. For details refer to, + ../interrupt-controller/interrupts.txt. + +Optional properties: + - reset-gpios : GPIO used to reset the device. + For details refer to, ../gpio/gpio.txt. + +Example: + +&i2c2 { + heart_mon@58 { + compatible = "ti,afe4404"; + reg = <0x58>; + + tx-supply = <&vbat>; + + interrupt-parent = <&gpio1>; + interrupts = <28 IRQ_TYPE_EDGE_RISING>; + + reset-gpios = <&gpio1 16 GPIO_ACTIVE_LOW>; + }; +}; diff --git a/Documentation/devicetree/bindings/iio/health/max30100.txt b/Documentation/devicetree/bindings/iio/health/max30100.txt index f6fbac66ad06e7429e9ab218a48b20d16abe0ab9..295a9edfa4fdcf89506c54321e573fa7cf044bcd 100644 --- a/Documentation/devicetree/bindings/iio/health/max30100.txt +++ b/Documentation/devicetree/bindings/iio/health/max30100.txt @@ -11,11 +11,19 @@ Required properties: Refer to interrupt-controller/interrupts.txt for generic interrupt client node bindings. +Optional properties: + - maxim,led-current-microamp: configuration for LED current in microamperes + while the engine is running. First indexed value is the configuration for + the RED LED, and second value is for the IR LED. + + Refer to the datasheet for the allowed current values. + Example: max30100@057 { compatible = "maxim,max30100"; reg = <57>; + maxim,led-current-microamp = <24000 50000>; interrupt-parent = <&gpio1>; interrupts = <16 2>; }; diff --git a/Documentation/devicetree/bindings/iio/light/opt3001.txt b/Documentation/devicetree/bindings/iio/light/opt3001.txt new file mode 100644 index 0000000000000000000000000000000000000000..eac30d508849f1cc3a9b714e6cd60c06aef8d017 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/light/opt3001.txt @@ -0,0 +1,26 @@ +* Texas Instruments OPT3001 Ambient Light Sensor + +The driver supports interrupt-driven and interrupt-less operation, depending +on whether an interrupt property has been populated into the DT. Note that +the optional generation of IIO events on rising/falling light threshold changes +requires the use of interrupts. Without interrupts, only the simple reading +of the current light value is supported through the IIO API. + +http://www.ti.com/product/opt3001 + +Required properties: + - compatible: should be "ti,opt3001" + - reg: the I2C address of the sensor + +Optional properties: + - interrupt-parent: should be the phandle for the interrupt controller + - interrupts: interrupt mapping for GPIO IRQ (configure for falling edge) + +Example: + +opt3001@44 { + compatible = "ti,opt3001"; + reg = <0x44>; + interrupt-parent = <&gpio1>; + interrupts = <28 IRQ_TYPE_EDGE_FALLING>; +}; diff --git a/Documentation/devicetree/bindings/input/ads7846.txt b/Documentation/devicetree/bindings/input/ads7846.txt index 33a1638b61d6bb950b45f0b14ceccaf7ff58eb19..c6cfe2e3ed4119f4d4831312b962b47cd7009c85 100644 --- a/Documentation/devicetree/bindings/input/ads7846.txt +++ b/Documentation/devicetree/bindings/input/ads7846.txt @@ -29,6 +29,8 @@ Optional properties: ti,vref-delay-usecs vref supply delay in usecs, 0 for external vref (u16). ti,vref-mv The VREF voltage, in millivolts (u16). + Set to 0 to use internal refernce + (ADS7846). ti,keep-vref-on set to keep vref on for differential measurements as well ti,swap-xy swap x and y axis diff --git a/Documentation/devicetree/bindings/input/rmi4/rmi_2d_sensor.txt b/Documentation/devicetree/bindings/input/rmi4/rmi_2d_sensor.txt new file mode 100644 index 0000000000000000000000000000000000000000..f2c30c8b725dff3f6ba8c2b55b4f4e2e416e97a7 --- /dev/null +++ b/Documentation/devicetree/bindings/input/rmi4/rmi_2d_sensor.txt @@ -0,0 +1,56 @@ +Synaptics RMI4 2D Sensor Device Binding + +The Synaptics RMI4 core is able to support RMI4 devices using different +transports and different functions. This file describes the device tree +bindings for devices which contain 2D sensors using Function 11 or +Function 12. Complete documentation for transports and other functions +can be found in: +Documentation/devicetree/bindings/input/rmi4. + +RMI4 Function 11 and Function 12 are for 2D touch position sensing. +Additional documentation for F11 can be found at: +http://www.synaptics.com/sites/default/files/511-000136-01-Rev-E-RMI4-Interfacing-Guide.pdf + +Optional Touch Properties: +Description in Documentation/devicetree/bindings/input/touch +- touchscreen-inverted-x +- touchscreen-inverted-y +- touchscreen-swapped-x-y +- touchscreen-x-mm +- touchscreen-y-mm + +Optional Properties: +- syna,clip-x-low: Sets a minimum value for X. +- syna,clip-y-low: Sets a minimum value for Y. +- syna,clip-x-high: Sets a maximum value for X. +- syna,clip-y-high: Sets a maximum value for Y. +- syna,offset-x: Add an offset to X. +- syna,offset-y: Add an offset to Y. +- syna,delta-x-threshold: Set the minimum distance on the X axis required + to generate an interrupt in reduced reporting + mode. +- syna,delta-y-threshold: Set the minimum distance on the Y axis required + to generate an interrupt in reduced reporting + mode. +- syna,sensor-type: Set the sensor type. 1 for touchscreen 2 for touchpad. +- syna,disable-report-mask: Mask for disabling posiiton reporting. Used to + disable reporing absolute position data. +- syna,rezero-wait-ms: Time in miliseconds to wait after issuing a rezero + command. + + +Example of a RMI4 I2C device with F11: +Example: + &i2c1 { + rmi4-i2c-dev@2c { + compatible = "syna,rmi4-i2c"; + + ... + + rmi4-f11@11 { + reg = <0x11>; + touchscreen-inverted-y; + syna,sensor-type = <2>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/input/rmi4/rmi_f01.txt b/Documentation/devicetree/bindings/input/rmi4/rmi_f01.txt new file mode 100644 index 0000000000000000000000000000000000000000..079cad2b6843b62290c735e1bf260348e223e847 --- /dev/null +++ b/Documentation/devicetree/bindings/input/rmi4/rmi_f01.txt @@ -0,0 +1,39 @@ +Synaptics RMI4 F01 Device Binding + +The Synaptics RMI4 core is able to support RMI4 devices using different +transports and different functions. This file describes the device tree +bindings for devices which contain Function 1. Complete documentation +for transports and other functions can be found in: +Documentation/devicetree/bindings/input/rmi4. + +Additional documentation for F01 can be found at: +http://www.synaptics.com/sites/default/files/511-000136-01-Rev-E-RMI4-Interfacing-Guide.pdf + +Optional Properties: +- syna,nosleep-mode: If set the device will run at full power without sleeping. + nosleep has 3 modes, 0 will not change the default + setting, 1 will disable nosleep (allow sleeping), + and 2 will enable nosleep (disabling sleep). +- syna,wakeup-threshold: Defines the amplitude of the disturbance to the + background capacitance that will cause the + device to wake from dozing. +- syna,doze-holdoff-ms: The delay to wait after the last finger lift and the + first doze cycle. +- syna,doze-interval-ms: The time period that the device sleeps between finger + activity. + + +Example of a RMI4 I2C device with F01: + Example: + &i2c1 { + rmi4-i2c-dev@2c { + compatible = "syna,rmi4-i2c"; + + ... + + rmi4-f01@1 { + reg = <0x1>; + syna,nosleep-mode = <1>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/input/rmi4/rmi_i2c.txt b/Documentation/devicetree/bindings/input/rmi4/rmi_i2c.txt new file mode 100644 index 0000000000000000000000000000000000000000..95fa715c604611c204a2a0000d286cd6742b6a30 --- /dev/null +++ b/Documentation/devicetree/bindings/input/rmi4/rmi_i2c.txt @@ -0,0 +1,53 @@ +Synaptics RMI4 I2C Device Binding + +The Synaptics RMI4 core is able to support RMI4 devices using different +transports and different functions. This file describes the device tree +bindings for devices using the I2C transport driver. Complete documentation +for other transports and functions can be found in +Documentation/devicetree/bindings/input/rmi4. + +Required Properties: +- compatible: syna,rmi4-i2c +- reg: I2C address +- #address-cells: Set to 1 to indicate that the function child nodes + consist of only on uint32 value. +- #size-cells: Set to 0 to indicate that the function child nodes do not + have a size property. + +Optional Properties: +- interrupts: interrupt which the rmi device is connected to. +- interrupt-parent: The interrupt controller. +See Documentation/devicetree/bindings/interrupt-controller/interrupts.txt + +- syna,reset-delay-ms: The number of milliseconds to wait after resetting the + device. + +Function Parameters: +Parameters specific to RMI functions are contained in child nodes of the rmi device + node. Documentation for the parameters of each function can be found in: +Documentation/devicetree/bindings/input/rmi4/rmi_f*.txt. + + + +Example: + &i2c1 { + rmi4-i2c-dev@2c { + compatible = "syna,rmi4-i2c"; + reg = <0x2c>; + #address-cells = <1>; + #size-cells = <0>; + interrupt-parent = <&gpio>; + interrupts = <4 2>; + + rmi4-f01@1 { + reg = <0x1>; + syna,nosleep-mode = <1>; + }; + + rmi4-f11@11 { + reg = <0x11>; + touchscreen-inverted-y; + syna,sensor-type = <2>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/input/rmi4/rmi_spi.txt b/Documentation/devicetree/bindings/input/rmi4/rmi_spi.txt new file mode 100644 index 0000000000000000000000000000000000000000..a4ca7828f21df402e391cecde408c1f9cf94b74d --- /dev/null +++ b/Documentation/devicetree/bindings/input/rmi4/rmi_spi.txt @@ -0,0 +1,57 @@ +Synaptics RMI4 SPI Device Binding + +The Synaptics RMI4 core is able to support RMI4 devices using different +transports and different functions. This file describes the device tree +bindings for devices using the SPI transport driver. Complete documentation +for other transports and functions can be found in +Documentation/devicetree/bindings/input/rmi4. + +Required Properties: +- compatible: syna,rmi4-spi +- reg: Chip select address for the device +- #address-cells: Set to 1 to indicate that the function child nodes + consist of only on uint32 value. +- #size-cells: Set to 0 to indicate that the function child nodes do not + have a size property. + +Optional Properties: +- interrupts: interrupt which the rmi device is connected to. +- interrupt-parent: The interrupt controller. +See Documentation/devicetree/bindings/interrupt-controller/interrupts.txt + +- spi-rx-delay-us: microsecond delay after a read transfer. +- spi-tx-delay-us: microsecond delay after a write transfer. + +Function Parameters: +Parameters specific to RMI functions are contained in child nodes of the rmi device + node. Documentation for the parameters of each function can be found in: +Documentation/devicetree/bindings/input/rmi4/rmi_f*.txt. + + + +Example: + spi@7000d800 { + rmi4-spi-dev@0 { + compatible = "syna,rmi4-spi"; + reg = <0x0>; + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <4000000>; + spi-cpha; + spi-cpol; + interrupt-parent = <&gpio>; + interrupts = ; + spi-rx-delay-us = <30>; + + rmi4-f01@1 { + reg = <0x1>; + syna,nosleep-mode = <1>; + }; + + rmi4-f11@11 { + reg = <0x11>; + touchscreen-inverted-y; + syna,sensor-type = <2>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/input/rotary-encoder.txt b/Documentation/devicetree/bindings/input/rotary-encoder.txt index de99cbbbf6da074fee825423636a0ca164364ee7..6c9f0c8a846c89a18532d56c488b7b133327113b 100644 --- a/Documentation/devicetree/bindings/input/rotary-encoder.txt +++ b/Documentation/devicetree/bindings/input/rotary-encoder.txt @@ -1,7 +1,7 @@ Rotary encoder DT bindings Required properties: -- gpios: a spec for two GPIOs to be used +- gpios: a spec for at least two GPIOs to be used, most significant first Optional properties: - linux,axis: the input subsystem axis to map to this rotary encoder. diff --git a/Documentation/devicetree/bindings/input/touchscreen/ad7879.txt b/Documentation/devicetree/bindings/input/touchscreen/ad7879.txt new file mode 100644 index 0000000000000000000000000000000000000000..e3f22d23fc8fa8b91db6521afe540a46daeef5a8 --- /dev/null +++ b/Documentation/devicetree/bindings/input/touchscreen/ad7879.txt @@ -0,0 +1,53 @@ +* Analog Devices AD7879(-1)/AD7889(-1) touchscreen interface (SPI/I2C) + +Required properties: +- compatible : for SPI slave, use "adi,ad7879" + for I2C slave, use "adi,ad7879-1" +- reg : SPI chipselect/I2C slave address + See spi-bus.txt for more SPI slave properties +- interrupt-parent : the phandle for the interrupt controller +- interrupts : touch controller interrupt +- touchscreen-max-pressure : maximum reported pressure +- adi,resistance-plate-x : total resistance of X-plate (for pressure + calculation) +Optional properties: +- touchscreen-swapped-x-y : X and Y axis are swapped (boolean) +- adi,first-conversion-delay : 0-12: In 128us steps (starting with 128us) + 13 : 2.560ms + 14 : 3.584ms + 15 : 4.096ms + This property has to be a '/bits/ 8' value +- adi,acquisition-time : 0: 2us + 1: 4us + 2: 8us + 3: 16us + This property has to be a '/bits/ 8' value +- adi,median-filter-size : 0: disabled + 1: 4 measurements + 2: 8 measurements + 3: 16 measurements + This property has to be a '/bits/ 8' value +- adi,averaging : 0: 2 middle values (1 if median disabled) + 1: 4 middle values + 2: 8 middle values + 3: 16 values + This property has to be a '/bits/ 8' value +- adi,conversion-interval: : 0 : convert one time only + 1-255: 515us + val * 35us (up to 9.440ms) + This property has to be a '/bits/ 8' value + +Example: + + ad7879@2c { + compatible = "adi,ad7879-1"; + reg = <0x2c>; + interrupt-parent = <&gpio1>; + interrupts = <13 IRQ_TYPE_EDGE_FALLING>; + touchscreen-max-pressure = <4096>; + adi,resistance-plate-x = <120>; + adi,first-conversion-delay = /bits/ 8 <3>; + adi,acquisition-time = /bits/ 8 <1>; + adi,median-filter-size = /bits/ 8 <2>; + adi,averaging = /bits/ 8 <1>; + adi,conversion-interval = /bits/ 8 <255>; + }; diff --git a/Documentation/devicetree/bindings/input/touchscreen/cyttsp.txt b/Documentation/devicetree/bindings/input/touchscreen/cyttsp.txt new file mode 100644 index 0000000000000000000000000000000000000000..b75d4cfd2c367893f7dd2b4447989f88b49882e3 --- /dev/null +++ b/Documentation/devicetree/bindings/input/touchscreen/cyttsp.txt @@ -0,0 +1,95 @@ +* Cypress cyttsp touchscreen controller + +Required properties: + - compatible : must be "cypress,cyttsp-i2c" or "cypress,cyttsp-spi" + - reg : Device I2C address or SPI chip select number + - spi-max-frequency : Maximum SPI clocking speed of the device (for cyttsp-spi) + - interrupt-parent : the phandle for the gpio controller + (see interrupt binding[0]). + - interrupts : (gpio) interrupt to which the chip is connected + (see interrupt binding[0]). + - bootloader-key : the 8-byte bootloader key that is required to switch + the chip from bootloader mode (default mode) to + application mode. + This property has to be specified as an array of 8 + '/bits/ 8' values. + +Optional properties: + - reset-gpios : the reset gpio the chip is connected to + (see GPIO binding[1] for more details). + - touchscreen-size-x : horizontal resolution of touchscreen (in pixels) + - touchscreen-size-y : vertical resolution of touchscreen (in pixels) + - touchscreen-fuzz-x : horizontal noise value of the absolute input device + (in pixels) + - touchscreen-fuzz-y : vertical noise value of the absolute input device + (in pixels) + - active-distance : the distance in pixels beyond which a touch must move + before movement is detected and reported by the device. + Valid values: 0-15. + - active-interval-ms : the minimum period in ms between consecutive + scanning/processing cycles when the chip is in active mode. + Valid values: 0-255. + - lowpower-interval-ms : the minimum period in ms between consecutive + scanning/processing cycles when the chip is in low-power mode. + Valid values: 0-2550 + - touch-timeout-ms : minimum time in ms spent in the active power state while no + touches are detected before entering low-power mode. + Valid values: 0-2550 + - use-handshake : enable register-based handshake (boolean). This should + only be used if the chip is configured to use 'blocking + communication with timeout' (in this case the device + generates an interrupt at the end of every + scanning/processing cycle). + +[0]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt +[1]: Documentation/devicetree/bindings/gpio/gpio.txt + +Example: + &i2c1 { + /* ... */ + cyttsp@a { + compatible = "cypress,cyttsp-i2c"; + reg = <0xa>; + interrupt-parent = <&gpio0>; + interrupts = <28 0>; + reset-gpios = <&gpio3 4 GPIO_ACTIVE_LOW>; + + touchscreen-size-x = <800>; + touchscreen-size-y = <480>; + touchscreen-fuzz-x = <4>; + touchscreen-fuzz-y = <7>; + + bootloader-key = /bits/ 8 <0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08>; + active-distance = <8>; + active-interval-ms = <0>; + lowpower-interval-ms = <200>; + touch-timeout-ms = <100>; + }; + + /* ... */ + }; + + &mcspi1 { + /* ... */ + cyttsp@0 { + compatible = "cypress,cyttsp-spi"; + spi-max-frequency = <6000000>; + reg = <0>; + interrupt-parent = <&gpio0>; + interrupts = <28 0>; + reset-gpios = <&gpio3 4 GPIO_ACTIVE_LOW>; + + touchscreen-size-x = <800>; + touchscreen-size-y = <480>; + touchscreen-fuzz-x = <4>; + touchscreen-fuzz-y = <7>; + + bootloader-key = /bits/ 8 <0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08>; + active-distance = <8>; + active-interval-ms = <0>; + lowpower-interval-ms = <200>; + touch-timeout-ms = <100>; + }; + + /* ... */ + }; diff --git a/Documentation/devicetree/bindings/input/touchscreen/fsl-mx25-tcq.txt b/Documentation/devicetree/bindings/input/touchscreen/fsl-mx25-tcq.txt new file mode 100644 index 0000000000000000000000000000000000000000..cdf05f9b232967075bb86d4998984e01dc31624e --- /dev/null +++ b/Documentation/devicetree/bindings/input/touchscreen/fsl-mx25-tcq.txt @@ -0,0 +1,35 @@ +Freescale mx25 TS conversion queue module + +mx25 touchscreen conversion queue module which controls the ADC unit of the +mx25 for attached touchscreens. + +Required properties: + - compatible: Should be "fsl,imx25-tcq". + - reg: Memory range of the device. + - interrupts: Should be the interrupt number associated with this module within + the tscadc unit (<0>). + - interrupt-parent: Should be a phandle to the tscadc unit. + - fsl,wires: Should be '<4>' or '<5>' + +Optional properties: + - fsl,pen-debounce-ns: Pen debounce time in nanoseconds. + - fsl,pen-threshold: Pen-down threshold for the touchscreen. This is a value + between 1 and 4096. It is the ratio between the internal reference voltage + and the measured voltage after the plate was precharged. Resistence between + plates and therefore the voltage decreases with pressure so that a smaller + value is equivalent to a higher pressure. + - fsl,settling-time-ns: Settling time in nanoseconds. The settling time is before + the actual touch detection to wait for an even charge distribution in the + plate. + +This device includes two conversion queues which can be added as subnodes. +The first queue is for the touchscreen, the second for general purpose ADC. + +Example: + tsc: tcq@50030400 { + compatible = "fsl,imx25-tcq"; + reg = <0x50030400 0x60>; + interrupt-parent = <&tscadc>; + interrupts = <0>; + fsl,wires = <4>; + }; diff --git a/Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt b/Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt index ac23caf518ad07b59ef0aa17feae18519b3ba0be..bccaa4e7304530b559c411afc2fab9cbccd068b3 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt +++ b/Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt @@ -18,6 +18,8 @@ Optional properties for Touchscreens: - touchscreen-inverted-y : Y axis is inverted (boolean) - touchscreen-swapped-x-y : X and Y axis are swapped (boolean) Swapping is done after inverting the axis + - touchscreen-x-mm : horizontal length in mm of the touchscreen + - touchscreen-y-mm : vertical length in mm of the touchscreen Deprecated properties for Touchscreens: - x-size : deprecated name for touchscreen-size-x diff --git a/Documentation/devicetree/bindings/interrupt-controller/hisilicon,mbigen-v2.txt b/Documentation/devicetree/bindings/interrupt-controller/hisilicon,mbigen-v2.txt index 720f7c92e9a1016cd3b174bb5b74f3b2acabab90..3b2f4c43ad8d2bdf1148826a9cb86de3053fe61c 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/hisilicon,mbigen-v2.txt +++ b/Documentation/devicetree/bindings/interrupt-controller/hisilicon,mbigen-v2.txt @@ -21,6 +21,8 @@ Mbigen main node required properties: - reg: Specifies the base physical address and size of the Mbigen registers. +Mbigen sub node required properties: +------------------------------------------ - interrupt controller: Identifies the node as an interrupt controller - msi-parent: Specifies the MSI controller this mbigen use. @@ -45,13 +47,23 @@ Mbigen main node required properties: Examples: - mbigen_device_gmac:intc { + mbigen_chip_dsa { compatible = "hisilicon,mbigen-v2"; reg = <0x0 0xc0080000 0x0 0x10000>; - interrupt-controller; - msi-parent = <&its_dsa 0x40b1c>; - num-pins = <9>; - #interrupt-cells = <2>; + + mbigen_gmac:intc_gmac { + interrupt-controller; + msi-parent = <&its_dsa 0x40b1c>; + num-pins = <9>; + #interrupt-cells = <2>; + }; + + mbigen_i2c:intc_i2c { + interrupt-controller; + msi-parent = <&its_dsa 0x40b0e>; + num-pins = <2>; + #interrupt-cells = <2>; + }; }; Devices connect to mbigen required properties: diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt b/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt new file mode 100644 index 0000000000000000000000000000000000000000..cd1b1cd7b5c488b502f37fa9afd657484629734d --- /dev/null +++ b/Documentation/devicetree/bindings/iommu/mediatek,iommu.txt @@ -0,0 +1,68 @@ +* Mediatek IOMMU Architecture Implementation + + Some Mediatek SOCs contain a Multimedia Memory Management Unit (M4U) which +uses the ARM Short-Descriptor translation table format for address translation. + + About the M4U Hardware Block Diagram, please check below: + + EMI (External Memory Interface) + | + m4u (Multimedia Memory Management Unit) + | + SMI Common(Smart Multimedia Interface Common) + | + +----------------+------- + | | + | | + SMI larb0 SMI larb1 ... SoCs have several SMI local arbiter(larb). + (display) (vdec) + | | + | | + +-----+-----+ +----+----+ + | | | | | | + | | |... | | | ... There are different ports in each larb. + | | | | | | +OVL0 RDMA0 WDMA0 MC PP VLD + + As above, The Multimedia HW will go through SMI and M4U while it +access EMI. SMI is a bridge between m4u and the Multimedia HW. It contain +smi local arbiter and smi common. It will control whether the Multimedia +HW should go though the m4u for translation or bypass it and talk +directly with EMI. And also SMI help control the power domain and clocks for +each local arbiter. + Normally we specify a local arbiter(larb) for each multimedia HW +like display, video decode, and camera. And there are different ports +in each larb. Take a example, There are many ports like MC, PP, VLD in the +video decode local arbiter, all these ports are according to the video HW. + +Required properties: +- compatible : must be "mediatek,mt8173-m4u". +- reg : m4u register base and size. +- interrupts : the interrupt of m4u. +- clocks : must contain one entry for each clock-names. +- clock-names : must be "bclk", It is the block clock of m4u. +- mediatek,larbs : List of phandle to the local arbiters in the current Socs. + Refer to bindings/memory-controllers/mediatek,smi-larb.txt. It must sort + according to the local arbiter index, like larb0, larb1, larb2... +- iommu-cells : must be 1. This is the mtk_m4u_id according to the HW. + Specifies the mtk_m4u_id as defined in + dt-binding/memory/mt8173-larb-port.h. + +Example: + iommu: iommu@10205000 { + compatible = "mediatek,mt8173-m4u"; + reg = <0 0x10205000 0 0x1000>; + interrupts = ; + clocks = <&infracfg CLK_INFRA_M4U>; + clock-names = "bclk"; + mediatek,larbs = <&larb0 &larb1 &larb2 &larb3 &larb4 &larb5>; + #iommu-cells = <1>; + }; + +Example for a client device: + display { + compatible = "mediatek,mt8173-disp"; + iommus = <&iommu M4U_PORT_DISP_OVL0>, + <&iommu M4U_PORT_DISP_RDMA0>; + ... + }; diff --git a/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt b/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt index 48ffb38f699e18b3d3e10ebdf0c0f9fa3c5d409e..3ed027cfca95cc98010342cf5d68363bbc801301 100644 --- a/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt +++ b/Documentation/devicetree/bindings/iommu/renesas,ipmmu-vmsa.txt @@ -7,23 +7,34 @@ connected to the IPMMU through a port called micro-TLB. Required Properties: - - compatible: Must contain SoC-specific and generic entries from below. + - compatible: Must contain SoC-specific and generic entry below in case + the device is compatible with the R-Car Gen2 VMSA-compatible IPMMU. - "renesas,ipmmu-r8a73a4" for the R8A73A4 (R-Mobile APE6) IPMMU. - "renesas,ipmmu-r8a7790" for the R8A7790 (R-Car H2) IPMMU. - "renesas,ipmmu-r8a7791" for the R8A7791 (R-Car M2-W) IPMMU. - "renesas,ipmmu-r8a7793" for the R8A7793 (R-Car M2-N) IPMMU. - "renesas,ipmmu-r8a7794" for the R8A7794 (R-Car E2) IPMMU. + - "renesas,ipmmu-r8a7795" for the R8A7795 (R-Car H3) IPMMU. - "renesas,ipmmu-vmsa" for generic R-Car Gen2 VMSA-compatible IPMMU. - reg: Base address and size of the IPMMU registers. - interrupts: Specifiers for the MMU fault interrupts. For instances that support secure mode two interrupts must be specified, for non-secure and secure mode, in that order. For instances that don't support secure mode a - single interrupt must be specified. + single interrupt must be specified. Not required for cache IPMMUs. - #iommu-cells: Must be 1. +Optional properties: + + - renesas,ipmmu-main: reference to the main IPMMU instance in two cells. + The first cell is a phandle to the main IPMMU and the second cell is + the interrupt bit number associated with the particular cache IPMMU device. + The interrupt bit number needs to match the main IPMMU IMSSTR register. + Only used by cache IPMMU instances. + + Each bus master connected to an IPMMU must reference the IPMMU in its device node with the following property: diff --git a/Documentation/devicetree/bindings/iommu/samsung,sysmmu.txt b/Documentation/devicetree/bindings/iommu/samsung,sysmmu.txt index bc620fe32a707375113f50d7f7b386967f0f29e0..85f068805dd8a58648ec790dc3fae21ed9ce4796 100644 --- a/Documentation/devicetree/bindings/iommu/samsung,sysmmu.txt +++ b/Documentation/devicetree/bindings/iommu/samsung,sysmmu.txt @@ -23,28 +23,24 @@ MMUs. for window 1, 2 and 3. * M2M Scalers and G2D in Exynos5420 has one System MMU on the read channel and the other System MMU on the write channel. -The drivers must consider how to handle those System MMUs. One of the idea is -to implement child devices or sub-devices which are the client devices of the -System MMU. -Note: -The current DT binding for the Exynos System MMU is incomplete. -The following properties can be removed or changed, if found incompatible with -the "Generic IOMMU Binding" support for attaching devices to the IOMMU. +For information on assigning System MMU controller to its peripheral devices, +see generic IOMMU bindings. Required properties: - compatible: Should be "samsung,exynos-sysmmu" - reg: A tuple of base address and size of System MMU registers. +- #iommu-cells: Should be <0>. - interrupt-parent: The phandle of the interrupt controller of System MMU - interrupts: An interrupt specifier for interrupt signal of System MMU, according to the format defined by a particular interrupt controller. -- clock-names: Should be "sysmmu" if the System MMU is needed to gate its clock. +- clock-names: Should be "sysmmu" or a pair of "aclk" and "pclk" to gate + SYSMMU core clocks. Optional "master" if the clock to the System MMU is gated by - another gate clock other than "sysmmu". - Exynos4 SoCs, there needs no "master" clock. - Exynos5 SoCs, some System MMUs must have "master" clocks. -- clocks: Required if the System MMU is needed to gate its clock. + another gate clock other core (usually main gate clock + of peripheral device this SYSMMU belongs to). +- clocks: Phandles for respective clocks described by clock-names. - power-domains: Required if the System MMU is needed to gate its power. Please refer to the following document: Documentation/devicetree/bindings/power/pd-samsung.txt @@ -57,6 +53,7 @@ Examples: power-domains = <&pd_gsc>; clocks = <&clock CLK_GSCL0>; clock-names = "gscl"; + iommus = <&sysmmu_gsc0>; }; sysmmu_gsc0: sysmmu@13E80000 { @@ -67,4 +64,5 @@ Examples: clock-names = "sysmmu", "master"; clocks = <&clock CLK_SMMU_GSCL0>, <&clock CLK_GSCL0>; power-domains = <&pd_gsc>; + #iommu-cells = <0>; }; diff --git a/Documentation/devicetree/bindings/mailbox/hisilicon,hi6220-mailbox.txt b/Documentation/devicetree/bindings/mailbox/hisilicon,hi6220-mailbox.txt new file mode 100644 index 0000000000000000000000000000000000000000..044b17f3a77a6bd1958d0d2e0e9d73b48c073adb --- /dev/null +++ b/Documentation/devicetree/bindings/mailbox/hisilicon,hi6220-mailbox.txt @@ -0,0 +1,74 @@ +Hisilicon Hi6220 Mailbox Driver +=============================== + +Hisilicon Hi6220 mailbox supports up to 32 channels. Each channel +is unidirectional with a maximum message size of 8 words. I/O is +performed using register access (there is no DMA) and the cell +raises an interrupt when messages are received. + +Mailbox Device Node: +==================== + +Required properties: +-------------------- +- compatible: Shall be "hisilicon,hi6220-mbox" +- reg: Contains the mailbox register address range (base + address and length); the first item is for IPC + registers, the second item is shared buffer for + slots. +- #mbox-cells: Common mailbox binding property to identify the number + of cells required for the mailbox specifier. Must be 3. + <&phandle slot_id dst_irq ack_irq> + phandle: Label name of mailbox controller + slot_id: Slot id used either for TX or RX + dst_irq: IRQ identifier index number which used by MCU + ack_irq: IRQ identifier index number with generating a + TX/RX interrupt to application processor, + mailbox driver uses it to acknowledge interrupt +- interrupts: Contains the interrupt information for the mailbox + device. The format is dependent on which interrupt + controller the SoCs use. + +Optional Properties: +-------------------- +- hi6220,mbox-tx-noirq: Property of MCU firmware's feature, so mailbox driver + use this flag to ask MCU to enable "automatic idle + flag" mode or IRQ generated mode to acknowledge a TX + completion. + +Example: +-------- + + mailbox: mailbox@f7510000 { + compatible = "hisilicon,hi6220-mbox"; + reg = <0x0 0xf7510000 0x0 0x1000>, /* IPC_S */ + <0x0 0x06dff800 0x0 0x0800>; /* Mailbox */ + interrupt-parent = <&gic>; + interrupts = ; + #mbox-cells = <3>; + }; + + +Mailbox client +=============== + +Required properties: +-------------------- +- compatible: Many (See the client docs). +- mboxes: Standard property to specify a Mailbox (See ./mailbox.txt) + Cells must match 'mbox-cells' (See Mailbox Device Node above). + +Optional Properties: +-------------------- +- mbox-names: Name given to channels seen in the 'mboxes' property. + +Example: +-------- + + stub_clock: stub_clock { + compatible = "hisilicon,hi6220-stub-clk"; + hisilicon,hi6220-clk-sram = <&sram>; + #clock-cells = <1>; + mbox-names = "mbox-tx", "mbox-rx"; + mboxes = <&mailbox 1 0 11>, <&mailbox 0 1 10>; + }; diff --git a/Documentation/devicetree/bindings/mailbox/rockchip-mailbox.txt b/Documentation/devicetree/bindings/mailbox/rockchip-mailbox.txt new file mode 100644 index 0000000000000000000000000000000000000000..b6bb84acf5be65d96a47af56ccd051ed57cead32 --- /dev/null +++ b/Documentation/devicetree/bindings/mailbox/rockchip-mailbox.txt @@ -0,0 +1,32 @@ +Rockchip mailbox + +The Rockchip mailbox is used by the Rockchip CPU cores to communicate +requests to MCU processor. + +Refer to ./mailbox.txt for generic information about mailbox device-tree +bindings. + +Required properties: + + - compatible: should be one of the following. + - "rockchip,rk3368-mbox" for rk3368 + - reg: physical base address of the controller and length of memory mapped + region. + - interrupts: The interrupt number to the cpu. The interrupt specifier format + depends on the interrupt controller. + - #mbox-cells: Common mailbox binding property to identify the number + of cells required for the mailbox specifier. Should be 1 + +Example: +-------- + +/* RK3368 */ +mbox: mbox@ff6b0000 { + compatible = "rockchip,rk3368-mailbox"; + reg = <0x0 0xff6b0000 0x0 0x1000>, + interrupts = , + , + , + ; + #mbox-cells = <1>; +}; diff --git a/Documentation/devicetree/bindings/mailbox/sti-mailbox.txt b/Documentation/devicetree/bindings/mailbox/sti-mailbox.txt index b61eec92035906c807bf82c17f49e7920a0c3f4d..351f612673fc5368ba3d4f8116114fbdd2fb5659 100644 --- a/Documentation/devicetree/bindings/mailbox/sti-mailbox.txt +++ b/Documentation/devicetree/bindings/mailbox/sti-mailbox.txt @@ -44,7 +44,7 @@ Optional properties Example: mailbox_test { - compatible = "mailbox_test"; + compatible = "mailbox-test"; reg = <0x[shared_memory_address], [shared_memory_size]>; mboxes = <&mailbox2 0 1>, <&mailbox0 2 1>; mbox-names = "tx", "rx"; diff --git a/Documentation/devicetree/bindings/mailbox/ti,message-manager.txt b/Documentation/devicetree/bindings/mailbox/ti,message-manager.txt new file mode 100644 index 0000000000000000000000000000000000000000..b449d025049f005fbbdfcaf539f7286f777e83ca --- /dev/null +++ b/Documentation/devicetree/bindings/mailbox/ti,message-manager.txt @@ -0,0 +1,50 @@ +Texas Instruments' Message Manager Driver +======================================== + +The Texas Instruments' Message Manager is a mailbox controller that has +configurable queues selectable at SoC(System on Chip) integration. The Message +manager is broken up into queues in different address regions that are called +"proxies" - each instance is unidirectional and is instantiated at SoC +integration level to indicate receive or transmit path. + +Message Manager Device Node: +=========================== +Required properties: +-------------------- +- compatible: Shall be: "ti,k2g-message-manager" +- reg-names queue_proxy_region - Map the queue proxy region. + queue_state_debug_region - Map the queue state debug + region. +- reg: Contains the register map per reg-names. +- #mbox-cells Shall be 2. Contains the queue ID and proxy ID in that + order referring to the transfer path. +- interrupt-names: Contains interrupt names matching the rx transfer path + for a given SoC. Receive interrupts shall be of the + format: "rx__". + For ti,k2g-message-manager, this shall contain: + "rx_005_002", "rx_057_002" +- interrupts: Contains the interrupt information corresponding to + interrupt-names property. + +Example(K2G): +------------ + + msgmgr: msgmgr@02a00000 { + compatible = "ti,k2g-message-manager"; + #mbox-cells = <2>; + reg-names = "queue_proxy_region", "queue_state_debug_region"; + reg = <0x02a00000 0x400000>, <0x028c3400 0x400>; + interrupt-names = "rx_005", "rx_057"; + interrupts = , + ; + }; + + pmmc: pmmc { + [...] + mbox-names = "rx", "tx"; + # RX queue ID is 5, proxy ID is 2 + # TX queue ID is 0, proxy ID is 0 + mboxes= <&msgmgr 5 2>, + <&msgmgr 0 0>; + [...] + }; diff --git a/Documentation/devicetree/bindings/mailbox/xgene-slimpro-mailbox.txt b/Documentation/devicetree/bindings/mailbox/xgene-slimpro-mailbox.txt new file mode 100644 index 0000000000000000000000000000000000000000..e46451bb242f3d577b4ed8240b202ba2e29b1c95 --- /dev/null +++ b/Documentation/devicetree/bindings/mailbox/xgene-slimpro-mailbox.txt @@ -0,0 +1,35 @@ +The APM X-Gene SLIMpro mailbox is used to communicate messages between +the ARM64 processors and the Cortex M3 (dubbed SLIMpro). It uses a simple +interrupt based door bell mechanism and can exchange simple messages using the +internal registers. + +There are total of 8 interrupts in this mailbox. Each used for an individual +door bell (or mailbox channel). + +Required properties: +- compatible: Should be as "apm,xgene-slimpro-mbox". + +- reg: Contains the mailbox register address range. + +- interrupts: 8 interrupts must be from 0 to 7, interrupt 0 define the + the interrupt for mailbox channel 0 and interrupt 1 for + mailbox channel 1 and so likewise for the reminder. + +- #mbox-cells: only one to specify the mailbox channel number. + +Example: + +Mailbox Node: + mailbox: mailbox@10540000 { + compatible = "apm,xgene-slimpro-mbox"; + reg = <0x0 0x10540000 0x0 0xa000>; + #mbox-cells = <1>; + interrupts = <0x0 0x0 0x4>, + <0x0 0x1 0x4>, + <0x0 0x2 0x4>, + <0x0 0x3 0x4>, + <0x0 0x4 0x4>, + <0x0 0x5 0x4>, + <0x0 0x6 0x4>, + <0x0 0x7 0x4>, + }; diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt new file mode 100644 index 0000000000000000000000000000000000000000..06a83ceebba734504c7299a1d0f6d8e3154241b6 --- /dev/null +++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt @@ -0,0 +1,24 @@ +SMI (Smart Multimedia Interface) Common + +The hardware block diagram please check bindings/iommu/mediatek,iommu.txt + +Required properties: +- compatible : must be "mediatek,mt8173-smi-common" +- reg : the register and size of the SMI block. +- power-domains : a phandle to the power domain of this local arbiter. +- clocks : Must contain an entry for each entry in clock-names. +- clock-names : must contain 2 entries, as follows: + - "apb" : Advanced Peripheral Bus clock, It's the clock for setting + the register. + - "smi" : It's the clock for transfer data and command. + They may be the same if both source clocks are the same. + +Example: + smi_common: smi@14022000 { + compatible = "mediatek,mt8173-smi-common"; + reg = <0 0x14022000 0 0x1000>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + clocks = <&mmsys CLK_MM_SMI_COMMON>, + <&mmsys CLK_MM_SMI_COMMON>; + clock-names = "apb", "smi"; + }; diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt new file mode 100644 index 0000000000000000000000000000000000000000..55ff3b7e0bb9d17e6cc8a09816ed613f4a903788 --- /dev/null +++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt @@ -0,0 +1,25 @@ +SMI (Smart Multimedia Interface) Local Arbiter + +The hardware block diagram please check bindings/iommu/mediatek,iommu.txt + +Required properties: +- compatible : must be "mediatek,mt8173-smi-larb" +- reg : the register and size of this local arbiter. +- mediatek,smi : a phandle to the smi_common node. +- power-domains : a phandle to the power domain of this local arbiter. +- clocks : Must contain an entry for each entry in clock-names. +- clock-names: must contain 2 entries, as follows: + - "apb" : Advanced Peripheral Bus clock, It's the clock for setting + the register. + - "smi" : It's the clock for transfer data and command. + +Example: + larb1: larb@16010000 { + compatible = "mediatek,mt8173-smi-larb"; + reg = <0 0x16010000 0 0x1000>; + mediatek,smi = <&smi_common>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_VDEC>; + clocks = <&vdecsys CLK_VDEC_CKEN>, + <&vdecsys CLK_VDEC_LARB_CKEN>; + clock-names = "apb", "smi"; + }; diff --git a/Documentation/devicetree/bindings/mfd/act8945a.txt b/Documentation/devicetree/bindings/mfd/act8945a.txt new file mode 100644 index 0000000000000000000000000000000000000000..f71283055685e2d1774d8efffcb36aa43c6ec659 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/act8945a.txt @@ -0,0 +1,76 @@ +Device-Tree bindings for Active-semi ACT8945A MFD driver + +Required properties: + - compatible: "active-semi,act8945a". + - reg: the I2C slave address for the ACT8945A chip + +The chip exposes two subdevices: + - a regulators: see ../regulator/act8945a-regulator.txt + - a charger: see ../power/act8945a-charger.txt + +Example: + pmic@5b { + compatible = "active-semi,act8945a"; + reg = <0x5b>; + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_charger_chglev>; + active-semi,chglev-gpio = <&pioA 12 GPIO_ACTIVE_HIGH>; + active-semi,input-voltage-threshold-microvolt = <6600>; + active-semi,precondition-timeout = <40>; + active-semi,total-timeout = <3>; + + active-semi,vsel-high; + + regulators { + vdd_1v35_reg: REG_DCDC1 { + regulator-name = "VDD_1V35"; + regulator-min-microvolt = <1350000>; + regulator-max-microvolt = <1350000>; + regulator-always-on; + }; + + vdd_1v2_reg: REG_DCDC2 { + regulator-name = "VDD_1V2"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1300000>; + regulator-always-on; + }; + + vdd_3v3_reg: REG_DCDC3 { + regulator-name = "VDD_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vdd_fuse_reg: REG_LDO1 { + regulator-name = "VDD_FUSE"; + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; + regulator-always-on; + }; + + vdd_3v3_lp_reg: REG_LDO2 { + regulator-name = "VDD_3V3_LP"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vdd_led_reg: REG_LDO3 { + regulator-name = "VDD_LED"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vdd_sdhc_1v8_reg: REG_LDO4 { + regulator-name = "VDD_SDHC_1V8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/mfd/axp20x.txt b/Documentation/devicetree/bindings/mfd/axp20x.txt index a474359dd206e900fdc503b47fc39705f5af1327..fd39fa54571b799ad8a19fcebfc19599735027ec 100644 --- a/Documentation/devicetree/bindings/mfd/axp20x.txt +++ b/Documentation/devicetree/bindings/mfd/axp20x.txt @@ -5,11 +5,12 @@ axp152 (X-Powers) axp202 (X-Powers) axp209 (X-Powers) axp221 (X-Powers) +axp223 (X-Powers) Required properties: - compatible: "x-powers,axp152", "x-powers,axp202", "x-powers,axp209", - "x-powers,axp221" -- reg: The I2C slave address for the AXP chip + "x-powers,axp221", "x-powers,axp223" +- reg: The I2C slave address or RSB hardware address for the AXP chip - interrupt-parent: The parent interrupt controller - interrupts: SoC NMI / GPIO interrupt connected to the PMIC's IRQ pin - interrupt-controller: The PMIC has its own internal IRQs @@ -51,7 +52,7 @@ LDO3 : LDO : ldo3in-supply LDO4 : LDO : ldo24in-supply : shared supply LDO5 : LDO : ldo5in-supply -AXP221 regulators, type, and corresponding input supply names: +AXP221/AXP223 regulators, type, and corresponding input supply names: Regulator Type Supply Name Notes --------- ---- ----------- ----- diff --git a/Documentation/devicetree/bindings/mfd/fsl-imx25-tsadc.txt b/Documentation/devicetree/bindings/mfd/fsl-imx25-tsadc.txt new file mode 100644 index 0000000000000000000000000000000000000000..b0350528699764c49e388362aaceb2311e9ec57e --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/fsl-imx25-tsadc.txt @@ -0,0 +1,47 @@ +Freescale MX25 ADC/TSC MultiFunction Device (MFD) + +This device combines two general purpose conversion queues one used for general +ADC and the other used for touchscreens. + +Required properties: + - compatible: Should be "fsl,imx25-tsadc". + - reg: Start address and size of the memory area of + the device + - interrupts: Interrupt for this device + (See: ../interrupt-controller/interrupts.txt) + - clocks: An 'ipg' clock (See: ../clock/clock-bindings.txt) + - interrupt-controller: This device is an interrupt controller. It + controls the interrupts of both + conversion queues. + - #interrupt-cells: Should be '<1>'. + - #address-cells: Should be '<1>'. + - #size-cells: Should be '<1>'. + +This device includes two conversion queues which can be added as subnodes. +The first queue is for the touchscreen, the second for general purpose ADC. + +Example: + tscadc: tscadc@50030000 { + compatible = "fsl,imx25-tsadc"; + reg = <0x50030000 0xc>; + interrupts = <46>; + clocks = <&clks 119>; + clock-names = "ipg"; + interrupt-controller; + #interrupt-cells = <1>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + tsc: tcq@50030400 { + compatible = "fsl,imx25-tcq"; + reg = <0x50030400 0x60>; + ... + }; + + adc: gcq@50030800 { + compatible = "fsl,imx25-gcq"; + reg = <0x50030800 0x60>; + ... + }; + }; diff --git a/Documentation/devicetree/bindings/mfd/mt6397.txt b/Documentation/devicetree/bindings/mfd/mt6397.txt index 15043e6526990c3ae4c2dba184f215fe7f85ec22..949c85f8d02c62c34c01b994df1806968c6aa0c5 100644 --- a/Documentation/devicetree/bindings/mfd/mt6397.txt +++ b/Documentation/devicetree/bindings/mfd/mt6397.txt @@ -1,6 +1,6 @@ -MediaTek MT6397 Multifunction Device Driver +MediaTek MT6397/MT6323 Multifunction Device Driver -MT6397 is a multifunction device with the following sub modules: +MT6397/MT6323 is a multifunction device with the following sub modules: - Regulator - RTC - Audio codec @@ -8,14 +8,14 @@ MT6397 is a multifunction device with the following sub modules: - Clock It is interfaced to host controller using SPI interface by a proprietary hardware -called PMIC wrapper or pwrap. MT6397 MFD is a child device of pwrap. +called PMIC wrapper or pwrap. MT6397/MT6323 MFD is a child device of pwrap. See the following for pwarp node definitions: Documentation/devicetree/bindings/soc/pwrap.txt This document describes the binding for MFD device and its sub module. Required properties: -compatible: "mediatek,mt6397" +compatible: "mediatek,mt6397" or "mediatek,mt6323" Optional subnodes: @@ -26,6 +26,8 @@ Optional subnodes: Required properties: - compatible: "mediatek,mt6397-regulator" see Documentation/devicetree/bindings/regulator/mt6397-regulator.txt + - compatible: "mediatek,mt6323-regulator" + see Documentation/devicetree/bindings/regulator/mt6323-regulator.txt - codec Required properties: - compatible: "mediatek,mt6397-codec" diff --git a/Documentation/devicetree/bindings/mfd/tps65086.txt b/Documentation/devicetree/bindings/mfd/tps65086.txt new file mode 100644 index 0000000000000000000000000000000000000000..d3705612a84655b59bfa235eb73a679e40de0c66 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/tps65086.txt @@ -0,0 +1,55 @@ +* TPS65086 Power Management Integrated Circuit (PMIC) bindings + +Required properties: + - compatible : Should be "ti,tps65086". + - reg : I2C slave address. + - interrupt-parent : Phandle to the parent interrupt controller. + - interrupts : The interrupt line the device is connected to. + - interrupt-controller : Marks the device node as an interrupt controller. + - #interrupt-cells : The number of cells to describe an IRQ, should be 2. + The first cell is the IRQ number. + The second cell is the flags, encoded as trigger + masks from ../interrupt-controller/interrupts.txt. + - 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 flags. + See ../gpio/gpio.txt for more information. + - regulators: : List of child nodes that specify the regulator + initialization data. Child nodes must be named + after their hardware counterparts: buck[1-6], + ldoa[1-3], swa1, swb[1-2], and vtt. Each child + node is defined using the standard binding for + regulators and the optional regulator properties + defined below. + +Optional regulator properties: + - ti,regulator-step-size-25mv : This is applicable for buck[1,2,6], set this + if the regulator is factory set with a 25mv + step voltage mapping. + - ti,regulator-decay : This is applicable for buck[1-6], set this if + the output needs to decay, default is for + the output to slew down. + +Example: + + pmic: tps65086@5e { + compatible = "ti,tps65086"; + reg = <0x5e>; + interrupt-parent = <&gpio1>; + interrupts = <28 IRQ_TYPE_LEVEL_LOW>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-controller; + #gpio-cells = <2>; + + regulators { + buck1 { + regulator-name = "vcc1"; + regulator-min-microvolt = <1600000>; + regulator-max-microvolt = <1600000>; + regulator-boot-on; + ti,regulator-decay; + ti,regulator-step-size-25mv; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/mips/cavium/sata-uctl.txt b/Documentation/devicetree/bindings/mips/cavium/sata-uctl.txt new file mode 100644 index 0000000000000000000000000000000000000000..3bd3c2f0b9b1de7b22df8192eaae58d5580516ce --- /dev/null +++ b/Documentation/devicetree/bindings/mips/cavium/sata-uctl.txt @@ -0,0 +1,42 @@ +* UCTL SATA controller glue + +UCTL is the bridge unit between the I/O interconnect (an internal bus) +and the SATA AHCI host controller (UAHC). It performs the following functions: + - provides interfaces for the applications to access the UAHC AHCI + registers on the CN71XX I/O space. + - provides a bridge for UAHC to fetch AHCI command table entries and data + buffers from Level 2 Cache. + - posts interrupts to the CIU. + - contains registers that: + - control the behavior of the UAHC + - control the clock/reset generation to UAHC + - control endian swapping for all UAHC registers and DMA accesses + +Properties: + +- compatible: "cavium,octeon-7130-sata-uctl" + + Compatibility with the cn7130 SOC. + +- reg: The base address of the UCTL register bank. + +- #address-cells, #size-cells, ranges and dma-ranges must be present and hold + suitable values to map all child nodes. + +Example: + + uctl@118006c000000 { + compatible = "cavium,octeon-7130-sata-uctl"; + reg = <0x11800 0x6c000000 0x0 0x100>; + ranges; /* Direct mapping */ + dma-ranges; + #address-cells = <2>; + #size-cells = <2>; + + sata: sata@16c0000000000 { + compatible = "cavium,octeon-7130-ahci"; + reg = <0x16c00 0x00000000 0x0 0x200>; + interrupt-parent = <&cibsata>; + interrupts = <2 4>; /* Bit: 2, level */ + }; + }; diff --git a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt index da541c3631f81880c6e87b62e8ca2cb133d1aec4..31b35c3a5e478191cb5faa427b5aaec57ec87fff 100644 --- a/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt +++ b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt @@ -1,11 +1,12 @@ Device Tree Bindings for the Arasan SDHCI Controller - The bindings follow the mmc[1], clock[2] and interrupt[3] bindings. Only - deviations are documented here. + The bindings follow the mmc[1], clock[2], interrupt[3] and phy[4] bindings. + Only deviations are documented here. [1] Documentation/devicetree/bindings/mmc/mmc.txt [2] Documentation/devicetree/bindings/clock/clock-bindings.txt [3] Documentation/devicetree/bindings/interrupt-controller/interrupts.txt + [4] Documentation/devicetree/bindings/phy/phy-bindings.txt Required Properties: - compatible: Compatibility string. Must be 'arasan,sdhci-8.9a' or @@ -17,6 +18,10 @@ Required Properties: - interrupt-parent: Phandle for the interrupt controller that services interrupts for this device. +Required Properties for "arasan,sdhci-5.1": + - phys: From PHY bindings: Phandle for the Generic PHY for arasan. + - phy-names: MUST be "phy_arasan". + Example: sdhci@e0100000 { compatible = "arasan,sdhci-8.9a"; @@ -26,3 +31,14 @@ Example: interrupt-parent = <&gic>; interrupts = <0 24 4>; } ; + + sdhci@e2800000 { + compatible = "arasan,sdhci-5.1"; + reg = <0xe2800000 0x1000>; + clock-names = "clk_xin", "clk_ahb"; + clocks = <&cru 8>, <&cru 18>; + interrupt-parent = <&gic>; + interrupts = <0 24 4>; + phys = <&emmc_phy>; + phy-names = "phy_arasan"; + } ; diff --git a/Documentation/devicetree/bindings/mmc/brcm,sdhci-iproc.txt b/Documentation/devicetree/bindings/mmc/brcm,sdhci-iproc.txt index 72cc9cc95880ad8cd3915c8d1648c20ee0e8e363..be56d2bd474a0c309729128c97c4a3a91bc7b918 100644 --- a/Documentation/devicetree/bindings/mmc/brcm,sdhci-iproc.txt +++ b/Documentation/devicetree/bindings/mmc/brcm,sdhci-iproc.txt @@ -4,7 +4,10 @@ This file documents differences between the core properties described by mmc.txt and the properties that represent the IPROC SDHCI controller. Required properties: -- compatible : Should be "brcm,sdhci-iproc-cygnus". +- compatible : Should be one of the following + "brcm,bcm2835-sdhci" + "brcm,sdhci-iproc-cygnus" + - clocks : The clock feeding the SDHCI controller. Optional properties: diff --git a/Documentation/devicetree/bindings/mmc/microchip,sdhci-pic32.txt b/Documentation/devicetree/bindings/mmc/microchip,sdhci-pic32.txt new file mode 100644 index 0000000000000000000000000000000000000000..71ad57e050b1e1c8574b1348d386cbf2bf7a6705 --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/microchip,sdhci-pic32.txt @@ -0,0 +1,29 @@ +* Microchip PIC32 SDHCI Controller + +This file documents differences between the core properties in mmc.txt +and the properties used by the sdhci-pic32 driver. + +Required properties: +- compatible: Should be "microchip,pic32mzda-sdhci" +- interrupts: Should contain interrupt +- clock-names: Should be "base_clk", "sys_clk". + See: Documentation/devicetree/bindings/resource-names.txt +- clocks: Phandle to the clock. + See: Documentation/devicetree/bindings/clock/clock-bindings.txt +- pinctrl-names: A pinctrl state names "default" must be defined. +- pinctrl-0: Phandle referencing pin configuration of the SDHCI controller. + See: Documentation/devicetree/bindings/pinctrl/pinctrl-binding.txt + +Example: + + sdhci@1f8ec000 { + compatible = "microchip,pic32mzda-sdhci"; + reg = <0x1f8ec000 0x100>; + interrupts = <191 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&REFCLKO4>, <&PBCLK5>; + clock-names = "base_clk", "sys_clk"; + bus-width = <4>; + cap-sd-highspeed; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sdhc1>; + }; diff --git a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt index 3dc13b68fc3ffb6dd136038f9116a96fbde996c7..ea5614b6f6130f32219e63115541f1bea328d47d 100644 --- a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt +++ b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt @@ -13,6 +13,8 @@ Required Properties: - "rockchip,rk2928-dw-mshc": for Rockchip RK2928 and following, before RK3288 - "rockchip,rk3288-dw-mshc": for Rockchip RK3288 + - "rockchip,rk3036-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK3036 + - "rockchip,rk3368-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK3368 Optional Properties: * clocks: from common clock binding: if ciu_drive and ciu_sample are diff --git a/Documentation/devicetree/bindings/mmc/tmio_mmc.txt b/Documentation/devicetree/bindings/mmc/tmio_mmc.txt index 400b640fabc768642f3c4b7f8ac9314067af5836..7fb746dd1a68caead326db419bac13c554785de8 100644 --- a/Documentation/devicetree/bindings/mmc/tmio_mmc.txt +++ b/Documentation/devicetree/bindings/mmc/tmio_mmc.txt @@ -22,6 +22,7 @@ Required properties: "renesas,sdhi-r8a7792" - SDHI IP on R8A7792 SoC "renesas,sdhi-r8a7793" - SDHI IP on R8A7793 SoC "renesas,sdhi-r8a7794" - SDHI IP on R8A7794 SoC + "renesas,sdhi-r8a7795" - SDHI IP on R8A7795 SoC Optional properties: - toshiba,mmc-wrprotect-disable: write-protect detection is unavailable diff --git a/Documentation/devicetree/bindings/mtd/atmel-nand.txt b/Documentation/devicetree/bindings/mtd/atmel-nand.txt index 7d4c8eb775a5fff5da9861b632d11e18a6786eee..d53aba98fbc98dec899cfa4c7e51f078189b001b 100644 --- a/Documentation/devicetree/bindings/mtd/atmel-nand.txt +++ b/Documentation/devicetree/bindings/mtd/atmel-nand.txt @@ -1,7 +1,10 @@ Atmel NAND flash Required properties: -- compatible : should be "atmel,at91rm9200-nand" or "atmel,sama5d4-nand". +- compatible: The possible values are: + "atmel,at91rm9200-nand" + "atmel,sama5d2-nand" + "atmel,sama5d4-nand" - reg : should specify localbus address and size used for the chip, and hardware ECC controller if available. If the hardware ECC is PMECC, it should contain address and size for @@ -21,10 +24,11 @@ Optional properties: - nand-ecc-mode : String, operation mode of the NAND ecc mode, soft by default. Supported values are: "none", "soft", "hw", "hw_syndrome", "hw_oob_first", "soft_bch". -- atmel,has-pmecc : boolean to enable Programmable Multibit ECC hardware. - Only supported by at91sam9x5 or later sam9 product. +- atmel,has-pmecc : boolean to enable Programmable Multibit ECC hardware, + capable of BCH encoding and decoding, on devices where it is present. - atmel,pmecc-cap : error correct capability for Programmable Multibit ECC - Controller. Supported values are: 2, 4, 8, 12, 24. + Controller. Supported values are: 2, 4, 8, 12, 24. If the compatible string + is "atmel,sama5d2-nand", 32 is also valid. - atmel,pmecc-sector-size : sector size for ECC computation. Supported values are: 512, 1024. - atmel,pmecc-lookup-table-offset : includes two offsets of lookup table in ROM @@ -32,15 +36,16 @@ Optional properties: sector size 1024. If not specified, driver will build the table in runtime. - nand-bus-width : 8 or 16 bus width if not present 8 - nand-on-flash-bbt: boolean to enable on flash bbt option if not present false -- Nand Flash Controller(NFC) is a slave driver under Atmel nand flash - - Required properties: - - compatible : "atmel,sama5d3-nfc". - - reg : should specify the address and size used for NFC command registers, - NFC registers and NFC Sram. NFC Sram address and size can be absent - if don't want to use it. - - clocks: phandle to the peripheral clock - - Optional properties: - - atmel,write-by-sram: boolean to enable NFC write by sram. + +Nand Flash Controller(NFC) is an optional sub-node +Required properties: +- compatible : "atmel,sama5d3-nfc" or "atmel,sama5d4-nfc". +- reg : should specify the address and size used for NFC command registers, + NFC registers and NFC SRAM. NFC SRAM address and size can be absent + if don't want to use it. +- clocks: phandle to the peripheral clock +Optional properties: +- atmel,write-by-sram: boolean to enable NFC write by SRAM. Examples: nand0: nand@40000000,0 { diff --git a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt index 00c587b3d3ae77eb958ba769b7a494edbee127e6..0333ec87dc49669b0ffb887f2c21746e056d55ae 100644 --- a/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt +++ b/Documentation/devicetree/bindings/mtd/fsl-quadspi.txt @@ -3,7 +3,9 @@ Required properties: - compatible : Should be "fsl,vf610-qspi", "fsl,imx6sx-qspi", "fsl,imx7d-qspi", "fsl,imx6ul-qspi", - "fsl,ls1021-qspi" + "fsl,ls1021a-qspi" + or + "fsl,ls2080a-qspi" followed by "fsl,ls1021a-qspi" - reg : the first contains the register location and length, the second contains the memory mapping address and length - reg-names: Should contain the reg names "QuadSPI" and "QuadSPI-memory" @@ -19,6 +21,7 @@ Optional properties: But if there are two NOR flashes connected to the bus, you should enable this property. (Please check the board's schematic.) + - big-endian : That means the IP register is big endian Example: diff --git a/Documentation/devicetree/bindings/mtd/qcom_nandc.txt b/Documentation/devicetree/bindings/mtd/qcom_nandc.txt new file mode 100644 index 0000000000000000000000000000000000000000..70dd5118a3247c19b14e673b3673fd095973dd8e --- /dev/null +++ b/Documentation/devicetree/bindings/mtd/qcom_nandc.txt @@ -0,0 +1,86 @@ +* Qualcomm NAND controller + +Required properties: +- compatible: should be "qcom,ipq806x-nand" +- reg: MMIO address range +- clocks: must contain core clock and always on clock +- clock-names: must contain "core" for the core clock and "aon" for the + always on clock +- dmas: DMA specifier, consisting of a phandle to the ADM DMA + controller node and the channel number to be used for + NAND. Refer to dma.txt and qcom_adm.txt for more details +- dma-names: must be "rxtx" +- qcom,cmd-crci: must contain the ADM command type CRCI block instance + number specified for the NAND controller on the given + platform +- qcom,data-crci: must contain the ADM data type CRCI block instance + number specified for the NAND controller on the given + platform +- #address-cells: <1> - subnodes give the chip-select number +- #size-cells: <0> + +* NAND chip-select + +Each controller may contain one or more subnodes to represent enabled +chip-selects which (may) contain NAND flash chips. Their properties are as +follows. + +Required properties: +- compatible: should contain "qcom,nandcs" +- reg: a single integer representing the chip-select + number (e.g., 0, 1, 2, etc.) +- #address-cells: see partition.txt +- #size-cells: see partition.txt +- nand-ecc-strength: see nand.txt +- nand-ecc-step-size: must be 512. see nand.txt for more details. + +Optional properties: +- nand-bus-width: see nand.txt + +Each nandcs device node may optionally contain a 'partitions' sub-node, which +further contains sub-nodes describing the flash partition mapping. See +partition.txt for more detail. + +Example: + +nand@1ac00000 { + compatible = "qcom,ebi2-nandc"; + reg = <0x1ac00000 0x800>; + + clocks = <&gcc EBI2_CLK>, + <&gcc EBI2_AON_CLK>; + clock-names = "core", "aon"; + + dmas = <&adm_dma 3>; + dma-names = "rxtx"; + qcom,cmd-crci = <15>; + qcom,data-crci = <3>; + + #address-cells = <1>; + #size-cells = <0>; + + nandcs@0 { + compatible = "qcom,nandcs"; + reg = <0>; + + nand-ecc-strength = <4>; + nand-ecc-step-size = <512>; + nand-bus-width = <8>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "boot-nand"; + reg = <0 0x58a0000>; + }; + + partition@58a0000 { + label = "fs-nand"; + reg = <0x58a0000 0x4000000>; + }; + }; + }; +}; diff --git a/Documentation/devicetree/bindings/net/arc_emac.txt b/Documentation/devicetree/bindings/net/arc_emac.txt index a1d71eb43b209485ac7bec4832119f25fe68a49e..c73a0e9c625e7fe852919fea75e4b204a7cf4637 100644 --- a/Documentation/devicetree/bindings/net/arc_emac.txt +++ b/Documentation/devicetree/bindings/net/arc_emac.txt @@ -7,6 +7,13 @@ Required properties: - max-speed: see ethernet.txt file in the same directory. - phy: see ethernet.txt file in the same directory. +Optional properties: +- phy-reset-gpios : Should specify the gpio for phy reset +- phy-reset-duration : Reset duration in milliseconds. Should present + only if property "phy-reset-gpios" is available. Missing the property + will have the duration be 1 millisecond. Numbers greater than 1000 are + invalid and 1 millisecond will be used instead. + Clock handling: The clock frequency is needed to calculate and set polling period of EMAC. It must be provided by one of: diff --git a/Documentation/devicetree/bindings/net/can/ifi_canfd.txt b/Documentation/devicetree/bindings/net/can/ifi_canfd.txt new file mode 100644 index 0000000000000000000000000000000000000000..20ea5c70ab824faa597948b3f3909c2521e1d230 --- /dev/null +++ b/Documentation/devicetree/bindings/net/can/ifi_canfd.txt @@ -0,0 +1,15 @@ +IFI CANFD controller +-------------------- + +Required properties: + - compatible: Should be "ifi,canfd-1.0" + - reg: Should contain CAN controller registers location and length + - interrupts: Should contain IRQ line for the CAN controller + +Example: + + canfd0: canfd@ff220000 { + compatible = "ifi,canfd-1.0"; + reg = <0xff220000 0x00001000>; + interrupts = <0 43 0>; + }; diff --git a/Documentation/devicetree/bindings/net/can/rcar_can.txt b/Documentation/devicetree/bindings/net/can/rcar_can.txt index 002d8440bf66f6a00054895b75c47e724cbcd5b9..8d40ab27bc8ca0964ddf1a0f6f02b372dceb5c62 100644 --- a/Documentation/devicetree/bindings/net/can/rcar_can.txt +++ b/Documentation/devicetree/bindings/net/can/rcar_can.txt @@ -6,6 +6,17 @@ Required properties: "renesas,can-r8a7779" if CAN controller is a part of R8A7779 SoC. "renesas,can-r8a7790" if CAN controller is a part of R8A7790 SoC. "renesas,can-r8a7791" if CAN controller is a part of R8A7791 SoC. + "renesas,can-r8a7792" if CAN controller is a part of R8A7792 SoC. + "renesas,can-r8a7793" if CAN controller is a part of R8A7793 SoC. + "renesas,can-r8a7794" if CAN controller is a part of R8A7794 SoC. + "renesas,can-r8a7795" if CAN controller is a part of R8A7795 SoC. + "renesas,rcar-gen1-can" for a generic R-Car Gen1 compatible device. + "renesas,rcar-gen2-can" for a generic R-Car Gen2 compatible device. + "renesas,rcar-gen3-can" for a generic R-Car Gen3 compatible device. + When compatible with the generic version, nodes must list the + SoC-specific version corresponding to the platform first + followed by the generic version. + - reg: physical base address and size of the R-Car CAN register map. - interrupts: interrupt specifier for the sole interrupt. - clocks: phandles and clock specifiers for 3 CAN clock inputs. @@ -13,6 +24,15 @@ Required properties: - pinctrl-0: pin control group to be used for this controller. - pinctrl-names: must be "default". +Required properties for "renesas,can-r8a7795" compatible: +In R8A7795 SoC, "clkp2" can be CANFD clock. This is a div6 clock and can be +used by both CAN and CAN FD controller at the same time. It needs to be scaled +to maximum frequency if any of these controllers use it. This is done using +the below properties. + +- assigned-clocks: phandle of clkp2(CANFD) clock. +- assigned-clock-rates: maximum frequency of this clock. + Optional properties: - renesas,can-clock-select: R-Car CAN Clock Source Select. Valid values are: <0x0> (default) : Peripheral clock (clkp1) @@ -25,7 +45,7 @@ Example SoC common .dtsi file: can0: can@e6e80000 { - compatible = "renesas,can-r8a7791"; + compatible = "renesas,can-r8a7791", "renesas,rcar-gen2-can"; reg = <0 0xe6e80000 0 0x1000>; interrupts = <0 186 IRQ_TYPE_LEVEL_HIGH>; clocks = <&mstp9_clks R8A7791_CLK_RCAN0>, diff --git a/Documentation/devicetree/bindings/net/can/sja1000.txt b/Documentation/devicetree/bindings/net/can/sja1000.txt index b4a6d53fb01ae8827ba69b33bbc60e6db21d90a7..ac3160eca96a2dc38f085f165aee2d912e8c927c 100644 --- a/Documentation/devicetree/bindings/net/can/sja1000.txt +++ b/Documentation/devicetree/bindings/net/can/sja1000.txt @@ -2,7 +2,7 @@ Memory mapped SJA1000 CAN controller from NXP (formerly Philips) Required properties: -- compatible : should be "nxp,sja1000". +- compatible : should be one of "nxp,sja1000", "technologic,sja1000". - reg : should specify the chip select, address offset and size required to map the registers of the SJA1000. The size is usually 0x80. @@ -14,6 +14,7 @@ Optional properties: - reg-io-width : Specify the size (in bytes) of the IO accesses that should be performed on the device. Valid value is 1, 2 or 4. + This property is ignored for technologic version. Default to 1 (8 bits). - nxp,external-clock-frequency : Frequency of the external oscillator diff --git a/Documentation/devicetree/bindings/net/cavium-mdio.txt b/Documentation/devicetree/bindings/net/cavium-mdio.txt index 04cb7491d23253555949bbcf7e48bf546cb118d0..020df08b8a30f4df80766bb90e100ae6210a777b 100644 --- a/Documentation/devicetree/bindings/net/cavium-mdio.txt +++ b/Documentation/devicetree/bindings/net/cavium-mdio.txt @@ -1,9 +1,12 @@ * System Management Interface (SMI) / MDIO Properties: -- compatible: "cavium,octeon-3860-mdio" +- compatible: One of: - Compatibility with all cn3XXX, cn5XXX and cn6XXX SOCs. + "cavium,octeon-3860-mdio": Compatibility with all cn3XXX, cn5XXX + and cn6XXX SOCs. + + "cavium,thunder-8890-mdio": Compatibility with all cn8XXX SOCs. - reg: The base address of the MDIO bus controller register bank. @@ -25,3 +28,57 @@ Example: reg = <0>; }; }; + + +* System Management Interface (SMI) / MDIO Nexus + + Several mdio buses may be gathered as children of a single PCI + device, this PCI device is the nexus of the buses. + +Properties: + +- compatible: "cavium,thunder-8890-mdio-nexus"; + +- reg: The PCI device and function numbers of the nexus device. + +- #address-cells: Must be <2>. + +- #size-cells: Must be <2>. + +- ranges: As needed for mapping of the MDIO bus device registers. + +- assigned-addresses: As needed for mapping of the MDIO bus device registers. + +Example: + + mdio-nexus@1,3 { + compatible = "cavium,thunder-8890-mdio-nexus"; + #address-cells = <2>; + #size-cells = <2>; + reg = <0x0b00 0 0 0 0>; /* DEVFN = 0x0b (1:3) */ + assigned-addresses = <0x03000000 0x87e0 0x05000000 0x0 0x800000>; + ranges = <0x87e0 0x05000000 0x03000000 0x87e0 0x05000000 0x0 0x800000>; + + mdio0@87e0,05003800 { + compatible = "cavium,thunder-8890-mdio"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x87e0 0x05003800 0x0 0x30>; + + ethernet-phy@0 { + ... + reg = <0>; + }; + }; + mdio0@87e0,05003880 { + compatible = "cavium,thunder-8890-mdio"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x87e0 0x05003880 0x0 0x30>; + + ethernet-phy@0 { + ... + reg = <0>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/net/emac_rockchip.txt b/Documentation/devicetree/bindings/net/emac_rockchip.txt index 8dc1c79fef7fcad6b46470a05b716e1a761b4445..05bd7dafce171fda64d9dd18cad4bdef1dcd8902 100644 --- a/Documentation/devicetree/bindings/net/emac_rockchip.txt +++ b/Documentation/devicetree/bindings/net/emac_rockchip.txt @@ -1,8 +1,10 @@ -* ARC EMAC 10/100 Ethernet platform driver for Rockchip Rk3066/RK3188 SoCs +* ARC EMAC 10/100 Ethernet platform driver for Rockchip RK3036/RK3066/RK3188 SoCs Required properties: -- compatible: Should be "rockchip,rk3066-emac" or "rockchip,rk3188-emac" - according to the target SoC. +- compatible: should be "rockchip,-emac" + "rockchip,rk3036-emac": found on RK3036 SoCs + "rockchip,rk3066-emac": found on RK3066 SoCs + "rockchip,rk3188-emac": found on RK3188 SoCs - reg: Address and length of the register set for the device - interrupts: Should contain the EMAC interrupts - rockchip,grf: phandle to the syscon grf used to control speed and mode diff --git a/Documentation/devicetree/bindings/net/fsl-fec.txt b/Documentation/devicetree/bindings/net/fsl-fec.txt index a9eb611bee68121a01f587a9c296852d0b6a46ce..b037a9d78d931312f9f950db4e358c8e86a5c86b 100644 --- a/Documentation/devicetree/bindings/net/fsl-fec.txt +++ b/Documentation/devicetree/bindings/net/fsl-fec.txt @@ -12,6 +12,9 @@ Optional properties: only if property "phy-reset-gpios" is available. Missing the property will have the duration be 1 millisecond. Numbers greater than 1000 are invalid and 1 millisecond will be used instead. +- phy-reset-active-high : If present then the reset sequence using the GPIO + specified in the "phy-reset-gpios" property is reversed (H=reset state, + L=operation state). - phy-supply : regulator that powers the Ethernet PHY. - phy-handle : phandle to the PHY device connected to this device. - fixed-link : Assume a fixed link. See fixed-link.txt in the same directory. diff --git a/Documentation/devicetree/bindings/net/macb.txt b/Documentation/devicetree/bindings/net/macb.txt index d2e243b1ec0e14cae6a576e615857928777e40f8..b5a42df4c9281d20c27cb726b0fac57ff58187c3 100644 --- a/Documentation/devicetree/bindings/net/macb.txt +++ b/Documentation/devicetree/bindings/net/macb.txt @@ -25,6 +25,8 @@ Required properties: Optional properties for PHY child node: - reset-gpios : Should specify the gpio for phy reset +- magic-packet : If present, indicates that the hardware supports waking + up via magic packet. Examples: diff --git a/Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt b/Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt index d0cb8693963b51f447afbb9b6e6c5bd42e87f34e..73be8970815eef93c17d80b68422d82ac055e068 100644 --- a/Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt +++ b/Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt @@ -18,15 +18,30 @@ Optional properties: "core" for core clock and "bus" for the optional bus clock. +Optional properties (valid only for Armada XP/38x): + +- buffer-manager: a phandle to a buffer manager node. Please refer to + Documentation/devicetree/bindings/net/marvell-neta-bm.txt +- bm,pool-long: ID of a pool, that will accept all packets of a size + higher than 'short' pool's threshold (if set) and up to MTU value. + Obligatory, when the port is supposed to use hardware + buffer management. +- bm,pool-short: ID of a pool, that will be used for accepting + packets of a size lower than given threshold. If not set, the port + will use a single 'long' pool for all packets, as defined above. + Example: -ethernet@d0070000 { +ethernet@70000 { compatible = "marvell,armada-370-neta"; - reg = <0xd0070000 0x2500>; + reg = <0x70000 0x2500>; interrupts = <8>; clocks = <&gate_clk 4>; tx-csum-limit = <9800> status = "okay"; phy = <&phy0>; phy-mode = "rgmii-id"; + buffer-manager = <&bm>; + bm,pool-long = <0>; + bm,pool-short = <1>; }; diff --git a/Documentation/devicetree/bindings/net/marvell-neta-bm.txt b/Documentation/devicetree/bindings/net/marvell-neta-bm.txt new file mode 100644 index 0000000000000000000000000000000000000000..c1b1d7c3bde13a25afaa520fd5bb53438f2692e7 --- /dev/null +++ b/Documentation/devicetree/bindings/net/marvell-neta-bm.txt @@ -0,0 +1,49 @@ +* Marvell Armada 380/XP Buffer Manager driver (BM) + +Required properties: + +- compatible: should be "marvell,armada-380-neta-bm". +- reg: address and length of the register set for the device. +- clocks: a pointer to the reference clock for this device. +- internal-mem: a phandle to BM internal SRAM definition. + +Optional properties (port): + +- pool<0 : 3>,capacity: size of external buffer pointers' ring maintained + in DRAM. Can be set for each pool (id 0 : 3) separately. The value has + to be chosen between 128 and 16352 and it also has to be aligned to 32. + Otherwise the driver would adjust a given number or choose default if + not set. +- pool<0 : 3>,pkt-size: maximum size of a packet accepted by a given buffer + pointers' pool (id 0 : 3). It will be taken into consideration only when pool + type is 'short'. For 'long' ones it would be overridden by port's MTU. + If not set a driver will choose a default value. + +In order to see how to hook the BM to a given ethernet port, please +refer to Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt. + +Example: + +- main node: + +bm: bm@c8000 { + compatible = "marvell,armada-380-neta-bm"; + reg = <0xc8000 0xac>; + clocks = <&gateclk 13>; + internal-mem = <&bm_bppi>; + status = "okay"; + pool2,capacity = <4096>; + pool1,pkt-size = <512>; +}; + +- internal SRAM node: + +bm_bppi: bm-bppi { + compatible = "mmio-sram"; + reg = ; + ranges = <0 MBUS_ID(0x0c, 0x04) 0 0x100000>; + #address-cells = <1>; + #size-cells = <1>; + clocks = <&gateclk 13>; + status = "okay"; +}; diff --git a/Documentation/devicetree/bindings/net/mediatek-net.txt b/Documentation/devicetree/bindings/net/mediatek-net.txt new file mode 100644 index 0000000000000000000000000000000000000000..5ca79290eabf0fc65c1a37c03b10fa60ef9e71c4 --- /dev/null +++ b/Documentation/devicetree/bindings/net/mediatek-net.txt @@ -0,0 +1,77 @@ +MediaTek Frame Engine Ethernet controller +========================================= + +The frame engine ethernet controller can be found on MediaTek SoCs. These SoCs +have dual GMAC each represented by a child node.. + +* Ethernet controller node + +Required properties: +- compatible: Should be "mediatek,mt7623-eth" +- reg: Address and length of the register set for the device +- interrupts: Should contain the frame engines interrupt +- clocks: the clock used by the core +- clock-names: the names of the clock listed in the clocks property. These are + "ethif", "esw", "gp2", "gp1" +- power-domains: phandle to the power domain that the ethernet is part of +- resets: Should contain a phandle to the ethsys reset signal +- reset-names: Should contain the reset signal name "eth" +- mediatek,ethsys: phandle to the syscon node that handles the port setup +- mediatek,pctl: phandle to the syscon node that handles the ports slew rate + and driver current + +Optional properties: +- interrupt-parent: Should be the phandle for the interrupt controller + that services interrupts for this device + + +* Ethernet MAC node + +Required properties: +- compatible: Should be "mediatek,eth-mac" +- reg: The number of the MAC +- phy-handle: see ethernet.txt file in the same directory. + +Example: + +eth: ethernet@1b100000 { + compatible = "mediatek,mt7623-eth"; + reg = <0 0x1b100000 0 0x20000>; + clocks = <&topckgen CLK_TOP_ETHIF_SEL>, + <ðsys CLK_ETHSYS_ESW>, + <ðsys CLK_ETHSYS_GP2>, + <ðsys CLK_ETHSYS_GP1>; + clock-names = "ethif", "esw", "gp2", "gp1"; + interrupts = ; + power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>; + resets = <ðsys MT2701_ETHSYS_ETH_RST>; + reset-names = "eth"; + mediatek,ethsys = <ðsys>; + mediatek,pctl = <&syscfg_pctl_a>; + #address-cells = <1>; + #size-cells = <0>; + + gmac1: mac@0 { + compatible = "mediatek,eth-mac"; + reg = <0>; + phy-handle = <&phy0>; + }; + + gmac2: mac@1 { + compatible = "mediatek,eth-mac"; + reg = <1>; + phy-handle = <&phy1>; + }; + + mdio-bus { + phy0: ethernet-phy@0 { + reg = <0>; + phy-mode = "rgmii"; + }; + + phy1: ethernet-phy@1 { + reg = <1>; + phy-mode = "rgmii"; + }; + }; +}; diff --git a/Documentation/devicetree/bindings/net/micrel-ks8995.txt b/Documentation/devicetree/bindings/net/micrel-ks8995.txt new file mode 100644 index 0000000000000000000000000000000000000000..281bc2498d12764740dab821e8cabcb5e0a3d8fc --- /dev/null +++ b/Documentation/devicetree/bindings/net/micrel-ks8995.txt @@ -0,0 +1,20 @@ +Micrel KS8995 SPI controlled Ethernet Switch families + +Required properties (according to spi-bus.txt): +- compatible: either "micrel,ks8995", "micrel,ksz8864" or "micrel,ksz8795" + +Optional properties: +- reset-gpios : phandle of gpio that will be used to reset chip during probe + +Example: + +spi-master { + ... + switch@0 { + compatible = "micrel,ksz8795"; + + reg = <0>; + spi-max-frequency = <50000000>; + reset-gpios = <&gpio0 46 GPIO_ACTIVE_LOW>; + }; +}; diff --git a/Documentation/devicetree/bindings/net/stmmac.txt b/Documentation/devicetree/bindings/net/stmmac.txt index e862a922bd3f957daca0989d1a94ae246afa48ca..6605d19601c2a6bcce217ef02a60f5afb42e0d55 100644 --- a/Documentation/devicetree/bindings/net/stmmac.txt +++ b/Documentation/devicetree/bindings/net/stmmac.txt @@ -17,7 +17,25 @@ Required properties: The 1st cell is reset pre-delay in micro seconds. The 2nd cell is reset pulse in micro seconds. The 3rd cell is reset post-delay in micro seconds. + +Optional properties: +- resets: Should contain a phandle to the STMMAC reset signal, if any +- reset-names: Should contain the reset signal name "stmmaceth", if a + reset phandle is given +- max-frame-size: See ethernet.txt file in the same directory +- clocks: If present, the first clock should be the GMAC main clock and + the second clock should be peripheral's register interface clock. Further + clocks may be specified in derived bindings. +- clock-names: One name for each entry in the clocks property, the + first one should be "stmmaceth" and the second one should be "pclk". +- clk_ptp_ref: this is the PTP reference clock; in case of the PTP is + available this clock is used for programming the Timestamp Addend Register. + If not passed then the system clock will be used and this is fine on some + platforms. +- tx-fifo-depth: See ethernet.txt file in the same directory +- rx-fifo-depth: See ethernet.txt file in the same directory - snps,pbl Programmable Burst Length +- snps,aal Address-Aligned Beats - snps,fixed-burst Program the DMA to use the fixed burst mode - snps,mixed-burst Program the DMA to use the mixed burst mode - snps,force_thresh_dma_mode Force DMA to use the threshold mode for @@ -29,27 +47,28 @@ Required properties: supported by this device instance - snps,perfect-filter-entries: Number of perfect filter entries supported by this device instance - -Optional properties: -- resets: Should contain a phandle to the STMMAC reset signal, if any -- reset-names: Should contain the reset signal name "stmmaceth", if a - reset phandle is given -- max-frame-size: See ethernet.txt file in the same directory -- clocks: If present, the first clock should be the GMAC main clock - The optional second clock should be peripheral's register interface clock. - The third optional clock should be the ptp reference clock. - Further clocks may be specified in derived bindings. -- clock-names: One name for each entry in the clocks property. - The first one should be "stmmaceth". - The optional second one should be "pclk". - The optional third one should be "clk_ptp_ref". -- snps,burst_len: The AXI burst lenth value of the AXI BUS MODE register. -- tx-fifo-depth: See ethernet.txt file in the same directory -- rx-fifo-depth: See ethernet.txt file in the same directory +- AXI BUS Mode parameters: below the list of all the parameters to program the + AXI register inside the DMA module: + - snps,lpi_en: enable Low Power Interface + - snps,xit_frm: unlock on WoL + - snps,wr_osr_lmt: max write oustanding req. limit + - snps,rd_osr_lmt: max read oustanding req. limit + - snps,kbbe: do not cross 1KiB boundary. + - snps,axi_all: align address + - snps,blen: this is a vector of supported burst length. + - snps,fb: fixed-burst + - snps,mb: mixed-burst + - snps,rb: rebuild INCRx Burst - mdio: with compatible = "snps,dwmac-mdio", create and register mdio bus. Examples: + stmmac_axi_setup: stmmac-axi-config { + snps,wr_osr_lmt = <0xf>; + snps,rd_osr_lmt = <0xf>; + snps,blen = <256 128 64 32 0 0 0>; + }; + gmac0: ethernet@e0800000 { compatible = "st,spear600-gmac"; reg = <0xe0800000 0x8000>; @@ -65,6 +84,7 @@ Examples: tx-fifo-depth = <16384>; clocks = <&clock>; clock-names = "stmmaceth"; + snps,axi-config = <&stmmac_axi_setup>; mdio0 { #address-cells = <1>; #size-cells = <0>; diff --git a/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt b/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt index edefc26c62042baad86259cc4737c60c507612fb..96aae6b4f736802df34a6524202a5dd2653e4231 100644 --- a/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt +++ b/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt @@ -1,17 +1,46 @@ * Qualcomm Atheros ath10k wireless devices -For ath10k devices the calibration data can be provided through Device -Tree. The node is a child node of the PCI controller. - Required properties: --compatible : Should be "qcom,ath10k" +- compatible: Should be one of the following: + * "qcom,ath10k" + * "qcom,ipq4019-wifi" + +PCI based devices uses compatible string "qcom,ath10k" and takes only +calibration data via "qcom,ath10k-calibration-data". Rest of the properties +are not applicable for PCI based devices. + +AHB based devices (i.e. ipq4019) uses compatible string "qcom,ipq4019-wifi" +and also uses most of the properties defined in this doc. Optional properties: +- reg: Address and length of the register set for the device. +- resets: Must contain an entry for each entry in reset-names. + See ../reset/reseti.txt for details. +- reset-names: Must include the list of following reset names, + "wifi_cpu_init" + "wifi_radio_srif" + "wifi_radio_warm" + "wifi_radio_cold" + "wifi_core_warm" + "wifi_core_cold" +- clocks: List of clock specifiers, must contain an entry for each required + entry in clock-names. +- clock-names: Should contain the clock names "wifi_wcss_cmd", "wifi_wcss_ref", + "wifi_wcss_rtc". +- interrupts: List of interrupt lines. Must contain an entry + for each entry in the interrupt-names property. +- interrupt-names: Must include the entries for MSI interrupt + names ("msi0" to "msi15") and legacy interrupt + name ("legacy"), +- qcom,msi_addr: MSI interrupt address. +- qcom,msi_base: Base value to add before writing MSI data into + MSI address register. - qcom,ath10k-calibration-data : calibration data as an array, the length can vary between hw versions +Example (to supply the calibration data alone): -Example: +In this example, the node is defined as child node of the PCI controller. pci { pcie@0 { @@ -28,3 +57,53 @@ pci { }; }; }; + +Example (to supply ipq4019 SoC wifi block details): + +wifi0: wifi@a000000 { + compatible = "qcom,ipq4019-wifi"; + reg = <0xa000000 0x200000>; + resets = <&gcc WIFI0_CPU_INIT_RESET>, + <&gcc WIFI0_RADIO_SRIF_RESET>, + <&gcc WIFI0_RADIO_WARM_RESET>, + <&gcc WIFI0_RADIO_COLD_RESET>, + <&gcc WIFI0_CORE_WARM_RESET>, + <&gcc WIFI0_CORE_COLD_RESET>; + reset-names = "wifi_cpu_init", + "wifi_radio_srif", + "wifi_radio_warm", + "wifi_radio_cold", + "wifi_core_warm", + "wifi_core_cold"; + clocks = <&gcc GCC_WCSS2G_CLK>, + <&gcc GCC_WCSS2G_REF_CLK>, + <&gcc GCC_WCSS2G_RTC_CLK>; + clock-names = "wifi_wcss_cmd", + "wifi_wcss_ref", + "wifi_wcss_rtc"; + interrupts = <0 0x20 0x1>, + <0 0x21 0x1>, + <0 0x22 0x1>, + <0 0x23 0x1>, + <0 0x24 0x1>, + <0 0x25 0x1>, + <0 0x26 0x1>, + <0 0x27 0x1>, + <0 0x28 0x1>, + <0 0x29 0x1>, + <0 0x2a 0x1>, + <0 0x2b 0x1>, + <0 0x2c 0x1>, + <0 0x2d 0x1>, + <0 0x2e 0x1>, + <0 0x2f 0x1>, + <0 0xa8 0x0>; + interrupt-names = "msi0", "msi1", "msi2", "msi3", + "msi4", "msi5", "msi6", "msi7", + "msi8", "msi9", "msi10", "msi11", + "msi12", "msi13", "msi14", "msi15", + "legacy"; + qcom,msi_addr = <0x0b006040>; + qcom,msi_base = <0x40>; + qcom,ath10k-calibration-data = [ 01 02 03 ... ]; +}; diff --git a/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt b/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt new file mode 100644 index 0000000000000000000000000000000000000000..9180724e182c30fcb28d3356e525f581fd0adf0c --- /dev/null +++ b/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt @@ -0,0 +1,36 @@ +* Texas Instruments wl1271 wireless lan controller + +The wl1271 chip can be connected via SPI or via SDIO. This +document describes the binding for the SPI connected chip. + +Required properties: +- compatible : Should be "ti,wl1271" +- reg : Chip select address of device +- spi-max-frequency : Maximum SPI clocking speed of device in Hz +- ref-clock-frequency : Reference clock frequency +- interrupt-parent, interrupts : + Should contain parameters for 1 interrupt line. + Interrupt parameters: parent, line number, type. +- vwlan-supply : Point the node of the regulator that powers/enable the wl1271 chip + +Optional properties: +- clock-xtal : boolean, clock is generated from XTAL + +- Please consult Documentation/devicetree/bindings/spi/spi-bus.txt + for optional SPI connection related properties, + +Examples: + +&spi1 { + wl1271@1 { + compatible = "ti,wl1271"; + + reg = <1>; + spi-max-frequency = <48000000>; + clock-xtal; + ref-clock-frequency = <38400000>; + interrupt-parent = <&gpio3>; + interrupts = <8 IRQ_TYPE_LEVEL_HIGH>; + vwlan-supply = <&vwlan_fixed>; + }; +}; diff --git a/Documentation/devicetree/bindings/pci/layerscape-pci.txt b/Documentation/devicetree/bindings/pci/layerscape-pci.txt index e3767857d30df98ef8a8d1b658e56bb6f6afadef..ef683b2fd23a4e0070f624fff295982a166ff371 100644 --- a/Documentation/devicetree/bindings/pci/layerscape-pci.txt +++ b/Documentation/devicetree/bindings/pci/layerscape-pci.txt @@ -14,7 +14,7 @@ information. Required properties: - compatible: should contain the platform identifier such as: "fsl,ls1021a-pcie", "snps,dw-pcie" - "fsl,ls2080a-pcie", "snps,dw-pcie" + "fsl,ls2080a-pcie", "fsl,ls2085a-pcie", "snps,dw-pcie" - reg: base addresses and lengths of the PCIe controller - interrupts: A list of interrupt outputs of the controller. Must contain an entry for each entry in the interrupt-names property. diff --git a/Documentation/devicetree/bindings/pinctrl/img,pistachio-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/img,pistachio-pinctrl.txt index 08a4a32c8eb0db76b533259db2c740316e32a9a3..0326154c792548997457fe6f3252867bbd19a6b4 100644 --- a/Documentation/devicetree/bindings/pinctrl/img,pistachio-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/img,pistachio-pinctrl.txt @@ -134,12 +134,12 @@ mfio80 ddr_debug, mips_trace_data, mips_debug mfio81 dreq0, mips_trace_data, eth_debug mfio82 dreq1, mips_trace_data, eth_debug mfio83 mips_pll_lock, mips_trace_data, usb_debug -mfio84 sys_pll_lock, mips_trace_data, usb_debug -mfio85 wifi_pll_lock, mips_trace_data, sdhost_debug -mfio86 bt_pll_lock, mips_trace_data, sdhost_debug -mfio87 rpu_v_pll_lock, dreq2, socif_debug -mfio88 rpu_l_pll_lock, dreq3, socif_debug -mfio89 audio_pll_lock, dreq4, dreq5 +mfio84 audio_pll_lock, mips_trace_data, usb_debug +mfio85 rpu_v_pll_lock, mips_trace_data, sdhost_debug +mfio86 rpu_l_pll_lock, mips_trace_data, sdhost_debug +mfio87 sys_pll_lock, dreq2, socif_debug +mfio88 wifi_pll_lock, dreq3, socif_debug +mfio89 bt_pll_lock, dreq4, dreq5 tck trstn tdi diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,armada-370-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/marvell,armada-370-pinctrl.txt index add7c38ec7d888b958df828139c1847ddc61c7e4..8662f3aaf312d9484a8e74373a5971a47d6b908a 100644 --- a/Documentation/devicetree/bindings/pinctrl/marvell,armada-370-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/marvell,armada-370-pinctrl.txt @@ -91,6 +91,9 @@ mpp60 60 gpio, dev(ale1), uart1(rxd), sata0(prsnt), pcie(rstout), mpp61 61 gpo, dev(we1), uart1(txd), audio(lrclk) mpp62 62 gpio, dev(a2), uart1(cts), tdm(drx), pcie(clkreq0), audio(mclk), uart0(cts) -mpp63 63 gpo, spi0(sck), tclk +mpp63 63 gpio, spi0(sck), tclk mpp64 64 gpio, spi0(miso), spi0(cs1) mpp65 65 gpio, spi0(mosi), spi0(cs2) + +Note: According to the datasheet mpp63 is a gpo but there is at least +one example of a gpio usage on the board D-Link DNS-327L diff --git a/Documentation/devicetree/bindings/power/rockchip-io-domain.txt b/Documentation/devicetree/bindings/power/rockchip-io-domain.txt index b8627e763dba0f9db458178ebbb98e1c32cec5a7..c84fb47265ebc5cf82020e4b9f9d828fc009cd53 100644 --- a/Documentation/devicetree/bindings/power/rockchip-io-domain.txt +++ b/Documentation/devicetree/bindings/power/rockchip-io-domain.txt @@ -35,6 +35,8 @@ Required properties: - "rockchip,rk3288-io-voltage-domain" for rk3288 - "rockchip,rk3368-io-voltage-domain" for rk3368 - "rockchip,rk3368-pmu-io-voltage-domain" for rk3368 pmu-domains + - "rockchip,rk3399-io-voltage-domain" for rk3399 + - "rockchip,rk3399-pmu-io-voltage-domain" for rk3399 pmu-domains - rockchip,grf: phandle to the syscon managing the "general register files" @@ -79,6 +81,15 @@ Possible supplies for rk3368 pmu-domains: - pmu-supply: The supply connected to PMUIO_VDD. - vop-supply: The supply connected to LCDC_VDD. +Possible supplies for rk3399: +- bt656-supply: The supply connected to APIO2_VDD. +- audio-supply: The supply connected to APIO5_VDD. +- sdmmc-supply: The supply connected to SDMMC0_VDD. +- gpio1830 The supply connected to APIO4_VDD. + +Possible supplies for rk3399 pmu-domains: +- pmu1830-supply:The supply connected to PMUIO2_VDD. + Example: io-domains { diff --git a/Documentation/devicetree/bindings/powerpc/fsl/fman.txt b/Documentation/devicetree/bindings/powerpc/fsl/fman.txt index 1fc5328c0651bb7d5219fa75887d8c2f630df3dc..55c2c03fc81e28e564508c9c3e57b4109d23996f 100644 --- a/Documentation/devicetree/bindings/powerpc/fsl/fman.txt +++ b/Documentation/devicetree/bindings/powerpc/fsl/fman.txt @@ -315,6 +315,16 @@ PROPERTIES Value type: Definition: A phandle for 1EEE1588 timer. +- pcsphy-handle + Usage required for "fsl,fman-memac" MACs + Value type: + Definition: A phandle for pcsphy. + +- tbi-handle + Usage required for "fsl,fman-dtsec" MACs + Value type: + Definition: A phandle for tbiphy. + EXAMPLE fman1_tx28: port@a8000 { @@ -340,6 +350,7 @@ ethernet@e0000 { reg = <0xe0000 0x1000>; fsl,fman-ports = <&fman1_rx8 &fman1_tx28>; ptp-timer = <&ptp-timer>; + tbi-handle = <&tbi0>; }; ============================================================================ @@ -415,6 +426,13 @@ PROPERTIES The settings and programming routines for internal/external MDIO are different. Must be included for internal MDIO. +For internal PHY device on internal mdio bus, a PHY node should be created. +See the definition of the PHY node in booting-without-of.txt for an +example of how to define a PHY (Internal PHY has no interrupt line). +- For "fsl,fman-mdio" compatible internal mdio bus, the PHY is TBI PHY. +- For "fsl,fman-memac-mdio" compatible internal mdio bus, the PHY is PCS PHY, + PCS PHY addr must be '0'. + EXAMPLE Example for FMan v2 external MDIO: @@ -425,12 +443,29 @@ mdio@f1000 { interrupts = <101 2 0 0>; }; +Example for FMan v2 internal MDIO: + +mdio@e3120 { + compatible = "fsl,fman-mdio"; + reg = <0xe3120 0xee0>; + fsl,fman-internal-mdio; + + tbi1: tbi-phy@8 { + reg = <0x8>; + device_type = "tbi-phy"; + }; +}; + Example for FMan v3 internal MDIO: mdio@f1000 { compatible = "fsl,fman-memac-mdio"; reg = <0xf1000 0x1000>; fsl,fman-internal-mdio; + + pcsphy6: ethernet-phy@0 { + reg = <0x0>; + }; }; ============================================================================= @@ -568,6 +603,7 @@ fman@400000 { cell-index = <0>; reg = <0xe0000 0x1000>; fsl,fman-ports = <&fman1_rx_0x8 &fman1_tx_0x28>; + tbi-handle = <&tbi5>; }; ethernet@e2000 { @@ -575,6 +611,7 @@ fman@400000 { cell-index = <1>; reg = <0xe2000 0x1000>; fsl,fman-ports = <&fman1_rx_0x9 &fman1_tx_0x29>; + tbi-handle = <&tbi6>; }; ethernet@e4000 { @@ -582,6 +619,7 @@ fman@400000 { cell-index = <2>; reg = <0xe4000 0x1000>; fsl,fman-ports = <&fman1_rx_0xa &fman1_tx_0x2a>; + tbi-handle = <&tbi7>; }; ethernet@e6000 { @@ -589,6 +627,7 @@ fman@400000 { cell-index = <3>; reg = <0xe6000 0x1000>; fsl,fman-ports = <&fman1_rx_0xb &fman1_tx_0x2b>; + tbi-handle = <&tbi8>; }; ethernet@e8000 { @@ -596,6 +635,7 @@ fman@400000 { cell-index = <4>; reg = <0xf0000 0x1000>; fsl,fman-ports = <&fman1_rx_0xc &fman1_tx_0x2c>; + tbi-handle = <&tbi9>; ethernet@f0000 { cell-index = <8>; diff --git a/Documentation/devicetree/bindings/property-units.txt b/Documentation/devicetree/bindings/property-units.txt new file mode 100644 index 0000000000000000000000000000000000000000..12278d79f6c0478ac9a2533d7cc5693a393b9ded --- /dev/null +++ b/Documentation/devicetree/bindings/property-units.txt @@ -0,0 +1,39 @@ +Standard Unit Suffixes for Property names + +Properties which have a unit of measure are recommended to have a unit +suffix appended to the property name. The list below contains the +recommended suffixes. Other variations exist in bindings, but should not +be used in new bindings or added here. The inconsistency in the unit +prefixes is due to selecting the most commonly used variants. + +It is also recommended to use the units listed here and not add additional +unit prefixes. + +Time/Frequency +---------------------------------------- +-mhz : megahertz +-hz : Hertz (preferred) +-sec : seconds +-ms : milliseconds +-us : microseconds +-ns : nanoseconds + +Distance +---------------------------------------- +-mm : millimeters + +Electricity +---------------------------------------- +-microamp : micro amps +-ohms : Ohms +-micro-ohms : micro Ohms +-microvolt : micro volts + +Temperature +---------------------------------------- +-celsius : Degrees Celsius +-millicelsius : Degreee milli-Celsius + +Pressure +---------------------------------------- +-kpascal : kiloPascal diff --git a/Documentation/devicetree/bindings/reset/img,pistachio-reset.txt b/Documentation/devicetree/bindings/reset/img,pistachio-reset.txt new file mode 100644 index 0000000000000000000000000000000000000000..8c05d16367df88a9a52e93e56d803f05e0752d2c --- /dev/null +++ b/Documentation/devicetree/bindings/reset/img,pistachio-reset.txt @@ -0,0 +1,55 @@ +Pistachio Reset Controller +============================================================================= + +This binding describes a reset controller device that is used to enable and +disable individual IP blocks within the Pistachio SoC using "soft reset" +control bits found in the Pistachio SoC top level registers. + +The actual action taken when soft reset is asserted is hardware dependent. +However, when asserted it may not be possible to access the hardware's +registers, and following an assert/deassert sequence the hardware's previous +state may no longer be valid. + +Please refer to Documentation/devicetree/bindings/reset/reset.txt +for common reset controller binding usage. + +Required properties: + +- compatible: Contains "img,pistachio-reset" + +- #reset-cells: Contains 1 + +Example: + + cr_periph: clk@18148000 { + compatible = "img,pistachio-cr-periph", "syscon", "simple-mfd"; + reg = <0x18148000 0x1000>; + clocks = <&clk_periph PERIPH_CLK_SYS>; + clock-names = "sys"; + #clock-cells = <1>; + + pistachio_reset: reset-controller { + compatible = "img,pistachio-reset"; + #reset-cells = <1>; + }; + }; + +Specifying reset control of devices +======================================= + +Device nodes should specify the reset channel required in their "resets" +property, containing a phandle to the pistachio reset device node and an +index specifying which reset to use, as described in +Documentation/devicetree/bindings/reset/reset.txt. + +Example: + + spdif_out: spdif-out@18100d00 { + ... + resets = <&pistachio_reset PISTACHIO_RESET_SPDIF_OUT>; + reset-names = "rst"; + ... + }; + +Macro definitions for the supported resets can be found in: +include/dt-bindings/reset/pistachio-resets.h diff --git a/Documentation/devicetree/bindings/rtc/maxim,mcp795.txt b/Documentation/devicetree/bindings/rtc/maxim,mcp795.txt new file mode 100644 index 0000000000000000000000000000000000000000..a59fdd8c236d2a7beee87b7b581408cda7aa6a17 --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/maxim,mcp795.txt @@ -0,0 +1,11 @@ +* Maxim MCP795 SPI Serial Real-Time Clock + +Required properties: +- compatible: Should contain "maxim,mcp795". +- reg: SPI address for chip + +Example: + mcp795: rtc@0 { + compatible = "maxim,mcp795"; + reg = <0>; + }; diff --git a/Documentation/devicetree/bindings/serial/mtk-uart.txt b/Documentation/devicetree/bindings/serial/mtk-uart.txt index a833a016f656783314a7c92d3f75f8a6a66f29ed..e99e10ab9ecbb8533b01746c1dc3b53a30853b7a 100644 --- a/Documentation/devicetree/bindings/serial/mtk-uart.txt +++ b/Documentation/devicetree/bindings/serial/mtk-uart.txt @@ -7,6 +7,7 @@ Required properties: * "mediatek,mt6582-uart" for MT6582 compatible UARTS * "mediatek,mt6589-uart" for MT6589 compatible UARTS * "mediatek,mt6795-uart" for MT6795 compatible UARTS + * "mediatek,mt7623-uart" for MT7623 compatible UARTS * "mediatek,mt8127-uart" for MT8127 compatible UARTS * "mediatek,mt8135-uart" for MT8135 compatible UARTS * "mediatek,mt8173-uart" for MT8173 compatible UARTS diff --git a/Documentation/devicetree/bindings/soc/fsl/rcpm.txt b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt new file mode 100644 index 0000000000000000000000000000000000000000..e284e4e1ccd543c5d82ac96fd2d008a603401a23 --- /dev/null +++ b/Documentation/devicetree/bindings/soc/fsl/rcpm.txt @@ -0,0 +1,63 @@ +* Run Control and Power Management +------------------------------------------- +The RCPM performs all device-level tasks associated with device run control +and power management. + +Required properites: + - reg : Offset and length of the register set of the RCPM block. + - fsl,#rcpm-wakeup-cells : The number of IPPDEXPCR register cells in the + fsl,rcpm-wakeup property. + - compatible : Must contain a chip-specific RCPM block compatible string + and (if applicable) may contain a chassis-version RCPM compatible + string. Chip-specific strings are of the form "fsl,-rcpm", + such as: + * "fsl,p2041-rcpm" + * "fsl,p5020-rcpm" + * "fsl,t4240-rcpm" + + Chassis-version strings are of the form "fsl,qoriq-rcpm-", + such as: + * "fsl,qoriq-rcpm-1.0": for chassis 1.0 rcpm + * "fsl,qoriq-rcpm-2.0": for chassis 2.0 rcpm + * "fsl,qoriq-rcpm-2.1": for chassis 2.1 rcpm + +All references to "1.0" and "2.0" refer to the QorIQ chassis version to +which the chip complies. +Chassis Version Example Chips +--------------- ------------------------------- +1.0 p4080, p5020, p5040, p2041, p3041 +2.0 t4240, b4860, b4420 +2.1 t1040, ls1021 + +Example: +The RCPM node for T4240: + rcpm: global-utilities@e2000 { + compatible = "fsl,t4240-rcpm", "fsl,qoriq-rcpm-2.0"; + reg = <0xe2000 0x1000>; + fsl,#rcpm-wakeup-cells = <2>; + }; + +* Freescale RCPM Wakeup Source Device Tree Bindings +------------------------------------------- +Required fsl,rcpm-wakeup property should be added to a device node if the device +can be used as a wakeup source. + + - fsl,rcpm-wakeup: Consists of a phandle to the rcpm node and the IPPDEXPCR + register cells. The number of IPPDEXPCR register cells is defined in + "fsl,#rcpm-wakeup-cells" in the rcpm node. The first register cell is + the bit mask that should be set in IPPDEXPCR0, and the second register + cell is for IPPDEXPCR1, and so on. + + Note: IPPDEXPCR(IP Powerdown Exception Control Register) provides a + mechanism for keeping certain blocks awake during STANDBY and MEM, in + order to use them as wake-up sources. + +Example: + lpuart0: serial@2950000 { + compatible = "fsl,ls1021a-lpuart"; + reg = <0x0 0x2950000 0x0 0x1000>; + interrupts = ; + clocks = <&sysclk>; + clock-names = "ipg"; + fsl,rcpm-wakeup = <&rcpm 0x0 0x40000000>; + }; diff --git a/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt b/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt index 112756e11802c7ccfbaccca4462e0987f88e0053..13dc6a3fdb4a1b239a38f1cd19dd0bb1ff2a681d 100644 --- a/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt +++ b/Documentation/devicetree/bindings/soc/rockchip/power_domain.txt @@ -6,6 +6,7 @@ powered up/down by software based on different application scenes to save power. Required properties for power domain controller: - compatible: Should be one of the following. "rockchip,rk3288-power-controller" - for RK3288 SoCs. + "rockchip,rk3368-power-controller" - for RK3368 SoCs. - #power-domain-cells: Number of cells in a power-domain specifier. Should be 1 for multiple PM domains. - #address-cells: Should be 1. @@ -14,6 +15,7 @@ Required properties for power domain controller: Required properties for power domain sub nodes: - reg: index of the power domain, should use macros in: "include/dt-bindings/power/rk3288-power.h" - for RK3288 type power domain. + "include/dt-bindings/power/rk3368-power.h" - for RK3368 type power domain. - clocks (optional): phandles to clocks which need to be enabled while power domain switches state. @@ -31,11 +33,24 @@ Example: }; }; + power: power-controller { + compatible = "rockchip,rk3368-power-controller"; + #power-domain-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; + + pd_gpu_1 { + reg = ; + clocks = <&cru ACLK_GPU_CFG>; + }; + }; + Node of a device using power domains must have a power-domains property, containing a phandle to the power device node and an index specifying which power domain to use. The index should use macros in: "include/dt-bindings/power/rk3288-power.h" - for rk3288 type power domain. + "include/dt-bindings/power/rk3368-power.h" - for rk3368 type power domain. Example of the node using power domain: @@ -44,3 +59,9 @@ Example of the node using power domain: power-domains = <&power RK3288_PD_GPU>; /* ... */ }; + + node { + /* ... */ + power-domains = <&power RK3368_PD_GPU_1>; + /* ... */ + }; diff --git a/Documentation/devicetree/bindings/sound/adi,adau17x1.txt b/Documentation/devicetree/bindings/sound/adi,adau17x1.txt new file mode 100644 index 0000000000000000000000000000000000000000..8dbce0e18dda266b3c824e1c34c5ad9b744ca2d2 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/adi,adau17x1.txt @@ -0,0 +1,24 @@ +Analog Devices ADAU1361/ADAU1461/ADAU1761/ADAU1961/ADAU1381/ADAU1781 + +Required properties: + + - compatible: Should contain one of the following: + "adi,adau1361" + "adi,adau1461" + "adi,adau1761" + "adi,adau1961" + "adi,adau1381" + "adi,adau1781" + + - reg: The i2c address. Value depends on the state of ADDR0 + and ADDR1, as wired in hardware. + +Examples: +#include + + i2c_bus { + adau1361@38 { + compatible = "adi,adau1761"; + reg = <0x38>; + }; + }; diff --git a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt index 4da41bf1888e9baaf2471a73db7d8019be9d6d0c..ceaef512698967ff16677b3771d2fd8c5227aaac 100644 --- a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt +++ b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt @@ -24,6 +24,9 @@ The compatible list for this generic sound card currently: "fsl,imx-audio-cs42888" + "fsl,imx-audio-cs427x" + (compatible with CS4271 and CS4272) + "fsl,imx-audio-wm8962" (compatible with Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt) @@ -63,6 +66,12 @@ Optional properties: - audio-asrc : The phandle of ASRC. It can be absent if there's no need to add ASRC support via DPCM. +Optional unless SSI is selected as a CPU DAI: + + - mux-int-port : The internal port of the i.MX audio muxer (AUDMUX) + + - mux-ext-port : The external port of the i.MX audio muxer + Example: sound-cs42888 { compatible = "fsl,imx-audio-cs42888"; diff --git a/Documentation/devicetree/bindings/sound/max9867.txt b/Documentation/devicetree/bindings/sound/max9867.txt new file mode 100644 index 0000000000000000000000000000000000000000..394cd4eb17ec47531edabc161f93506925775805 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/max9867.txt @@ -0,0 +1,17 @@ +max9867 codec + +This device supports I2C mode only. + +Required properties: + +- compatible : "maxim,max9867" +- reg : The chip select number on the I2C bus + +Example: + +&i2c { + max9867: max9867@0x18 { + compatible = "maxim,max9867"; + reg = <0x18>; + }; +}; diff --git a/Documentation/devicetree/bindings/sound/max98926.txt b/Documentation/devicetree/bindings/sound/max98926.txt new file mode 100644 index 0000000000000000000000000000000000000000..0b7f4e4d5f9a5c18b53398fe2291cc84e5e2b134 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/max98926.txt @@ -0,0 +1,32 @@ +max98926 audio CODEC + +This device supports I2C. + +Required properties: + + - compatible : "maxim,max98926" + + - vmon-slot-no : slot number used to send voltage information + or in inteleave mode this will be used as + interleave slot. + + - imon-slot-no : slot number used to send current information + + - interleave-mode : When using two MAX98926 in a system it is + possible to create ADC data that that will + overflow the frame size. Digital Audio Interleave + mode provides a means to output VMON and IMON data + from two devices on a single DOUT line when running + smaller frames sizes such as 32 BCLKS per LRCLK or + 48 BCLKS per LRCLK. + + - reg : the I2C address of the device for I2C + +Example: + +codec: max98926@1a { + compatible = "maxim,max98926"; + vmon-slot-no = <0>; + imon-slot-no = <2>; + reg = <0x1a>; +}; diff --git a/Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5514.txt b/Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5514.txt new file mode 100644 index 0000000000000000000000000000000000000000..e8b3c80c6fffd1b2dcc94070e49762170f13120e --- /dev/null +++ b/Documentation/devicetree/bindings/sound/mt8173-rt5650-rt5514.txt @@ -0,0 +1,15 @@ +MT8173 with RT5650 RT5514 CODECS + +Required properties: +- compatible : "mediatek,mt8173-rt5650-rt5514" +- mediatek,audio-codec: the phandles of rt5650 and rt5514 codecs +- mediatek,platform: the phandle of MT8173 ASoC platform + +Example: + + sound { + compatible = "mediatek,mt8173-rt5650-rt5514"; + mediatek,audio-codec = <&rt5650 &rt5514>; + mediatek,platform = <&afe>; + }; + diff --git a/Documentation/devicetree/bindings/sound/mt8173-rt5650.txt b/Documentation/devicetree/bindings/sound/mt8173-rt5650.txt new file mode 100644 index 0000000000000000000000000000000000000000..fe5a5ef1714d7468771d74afee84aa377081c3b5 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/mt8173-rt5650.txt @@ -0,0 +1,15 @@ +MT8173 with RT5650 CODECS + +Required properties: +- compatible : "mediatek,mt8173-rt5650" +- mediatek,audio-codec: the phandles of rt5650 codecs +- mediatek,platform: the phandle of MT8173 ASoC platform + +Example: + + sound { + compatible = "mediatek,mt8173-rt5650"; + mediatek,audio-codec = <&rt5650>; + mediatek,platform = <&afe>; + }; + diff --git a/Documentation/devicetree/bindings/sound/pcm179x.txt b/Documentation/devicetree/bindings/sound/pcm179x.txt index 4ae70d3462d65e6539278f4036e3fe26dc73f0ca..436c2b247693f5a9a60a58b28c365aecd1741644 100644 --- a/Documentation/devicetree/bindings/sound/pcm179x.txt +++ b/Documentation/devicetree/bindings/sound/pcm179x.txt @@ -1,6 +1,6 @@ Texas Instruments pcm179x DT bindings -This driver supports the SPI bus. +This driver supports both the I2C and SPI bus. Required properties: @@ -9,6 +9,11 @@ Required properties: For required properties on SPI, please consult Documentation/devicetree/bindings/spi/spi-bus.txt +Required properties on I2C: + + - reg: the I2C address + + Examples: codec_spi: 1792a@0 { @@ -16,3 +21,7 @@ Examples: spi-max-frequency = <600000>; }; + codec_i2c: 1792a@4c { + compatible = "ti,pcm1792a"; + reg = <0x4c>; + }; diff --git a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt index 8ee0fa91e4a067e622435d937378bee5288f6c53..c7b29df4a96353735f23d75576f284d8f16aa649 100644 --- a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt +++ b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt @@ -1,6 +1,337 @@ Renesas R-Car sound +============================================= +* Modules +============================================= + +Renesas R-Car sound is constructed from below modules +(for Gen2 or later) + + SCU : Sampling Rate Converter Unit + - SRC : Sampling Rate Converter + - CMD + - CTU : Channel Transfer Unit + - MIX : Mixer + - DVC : Digital Volume and Mute Function + SSIU : Serial Sound Interface Unit + SSI : Serial Sound Interface + +See detail of each module's channels, connection, limitation on datasheet + +============================================= +* Multi channel +============================================= + +Multi channel is supported by Multi-SSI, or TDM-SSI. + + Multi-SSI : 6ch case, you can use stereo x 3 SSI + TDM-SSI : 6ch case, you can use TDM + +============================================= +* Enable/Disable each modules +============================================= + +See datasheet to check SRC/CTU/MIX/DVC connect-limitation. +DT controls enabling/disabling module. +${LINUX}/arch/arm/boot/dts/r8a7790-lager.dts can be good example. +This is example of + +Playback: [MEM] -> [SRC2] -> [DVC0] -> [SSIU0/SSI0] -> [codec] +Capture: [MEM] <- [DVC1] <- [SRC3] <- [SSIU1/SSI1] <- [codec] + + &rcar_sound { + ... + rcar_sound,dai { + dai0 { + playback = <&ssi0 &src2 &dvc0>; + capture = <&ssi1 &src3 &dvc1>; + }; + }; + }; + +You can use below. +${LINUX}/arch/arm/boot/dts/r8a7790.dts can be good example. + + &src0 &ctu00 &mix0 &dvc0 &ssi0 + &src1 &ctu01 &mix1 &dvc1 &ssi1 + &src2 &ctu02 &ssi2 + &src3 &ctu03 &ssi3 + &src4 &ssi4 + &src5 &ctu10 &ssi5 + &src6 &ctu11 &ssi6 + &src7 &ctu12 &ssi7 + &src8 &ctu13 &ssi8 + &src9 &ssi9 + +============================================= +* SRC (Sampling Rate Converter) +============================================= + + [xx]Hz [yy]Hz + ------> [SRC] ------> + +SRC can convert [xx]Hz to [yy]Hz. Then, it has below 2 modes + + Asynchronous mode: input data / output data are based on different clocks. + you can use this mode on Playback / Capture + Synchronous mode: input data / output data are based on same clocks. + This mode will be used if system doesn't have its input clock, + for example digital TV case. + you can use this mode on Playback + +------------------ +** Asynchronous mode +------------------ + +You need to use "renesas,rsrc-card" sound card for it. +example) + + sound { + compatible = "renesas,rsrc-card"; + ... + /* + * SRC Asynchronous mode setting + * Playback: + * All input data will be converted to 48kHz + * Capture: + * Inputed 48kHz data will be converted to + * system specified Hz + */ + convert-rate = <48000>; + ... + cpu { + sound-dai = <&rcar_sound>; + }; + codec { + ... + }; + }; + +------------------ +** Synchronous mode +------------------ + + > amixer set "SRC Out Rate" on + > aplay xxxx.wav + > amixer set "SRC Out Rate" 48000 + > amixer set "SRC Out Rate" 44100 + +============================================= +* CTU (Channel Transfer Unit) +============================================= + + [xx]ch [yy]ch + ------> [CTU] --------> + +CTU can convert [xx]ch to [yy]ch, or exchange outputed channel. +CTU conversion needs matrix settings. +For more detail information, see below + + Renesas R-Car datasheet + - Sampling Rate Converter Unit (SCU) + - SCU Operation + - CMD Block + - Functional Blocks in CMD + + Renesas R-Car datasheet + - Sampling Rate Converter Unit (SCU) + - Register Description + - CTUn Scale Value exx Register (CTUn_SVxxR) + + ${LINUX}/sound/soc/sh/rcar/ctu.c + - comment of header + +You need to use "renesas,rsrc-card" sound card for it. +example) + + sound { + compatible = "renesas,rsrc-card"; + ... + /* + * CTU setting + * All input data will be converted to 2ch + * as output data + */ + convert-channels = <2>; + ... + cpu { + sound-dai = <&rcar_sound>; + }; + codec { + ... + }; + }; + +Ex) Exchange output channel + Input -> Output + 1ch -> 0ch + 0ch -> 1ch + + example of using matrix + output 0ch = (input 0ch x 0) + (input 1ch x 1) + output 1ch = (input 0ch x 1) + (input 1ch x 0) + + amixer set "CTU Reset" on + amixer set "CTU Pass" 9,10 + amixer set "CTU SV0" 0,4194304 + amixer set "CTU SV1" 4194304,0 + + example of changing connection + amixer set "CTU Reset" on + amixer set "CTU Pass" 2,1 + +============================================= +* MIX (Mixer) +============================================= + +MIX merges 2 sounds path. You can see 2 sound interface on system, +and these sounds will be merged by MIX. + + aplay -D plughw:0,0 xxxx.wav & + aplay -D plughw:0,1 yyyy.wav + +You need to use "renesas,rsrc-card" sound card for it. +Ex) + [MEM] -> [SRC1] -> [CTU02] -+-> [MIX0] -> [DVC0] -> [SSI0] + | + [MEM] -> [SRC2] -> [CTU03] -+ + + sound { + compatible = "renesas,rsrc-card"; + ... + cpu@0 { + sound-dai = <&rcar_sound 0>; + }; + cpu@1 { + sound-dai = <&rcar_sound 1>; + }; + codec { + ... + }; + }; + + &rcar_sound { + ... + rcar_sound,dai { + dai0 { + playback = <&src1 &ctu02 &mix0 &dvc0 &ssi0>; + }; + dai1 { + playback = <&src2 &ctu03 &mix0 &dvc0 &ssi0>; + }; + }; + }; + +============================================= +* DVC (Digital Volume and Mute Function) +============================================= + +DVC controls Playback/Capture volume. + +Playback Volume + amixer set "DVC Out" 100% + +Capture Volume + amixer set "DVC In" 100% + +Playback Mute + amixer set "DVC Out Mute" on + +Capture Mute + amixer set "DVC In Mute" on + +Volume Ramp + amixer set "DVC Out Ramp Up Rate" "0.125 dB/64 steps" + amixer set "DVC Out Ramp Down Rate" "0.125 dB/512 steps" + amixer set "DVC Out Ramp" on + aplay xxx.wav & + amixer set "DVC Out" 80% // Volume Down + amixer set "DVC Out" 100% // Volume Up + +============================================= +* SSIU (Serial Sound Interface Unit) +============================================= + +There is no DT settings for SSIU, because SSIU will be automatically +selected via SSI. +SSIU can avoid some under/over run error, because it has some buffer. +But you can't use it if SSI was PIO mode. +In DMA mode, you can select not to use SSIU by using "no-busif" on DT. + + &ssi0 { + no-busif; + }; + +============================================= +* SSI (Serial Sound Interface) +============================================= + +** PIO mode + +You can use PIO mode which is for connection check by using. +Note: The system will drop non-SSI modules in PIO mode +even though if DT is selecting other modules. + + &ssi0 { + pio-transfer + }; + +** DMA mode without SSIU + +You can use DMA without SSIU. +Note: under/over run, or noise are likely to occur + + &ssi0 { + no-busif; + }; + +** PIN sharing + +Each SSI can share WS pin. It is based on platform. +This is example if SSI1 want to share WS pin with SSI0 + + &ssi1 { + shared-pin; + }; + +** Multi-SSI + +You can use Multi-SSI. +This is example of SSI0/SSI1/SSI2 (= for 6ch) + + &rcar_sound { + ... + rcar_sound,dai { + dai0 { + playback = <&ssi0 &ssi1 &ssi2 &src0 &dvc0>; + }; + }; + }; + +** TDM-SSI + +You can use TDM with SSI. +This is example of TDM 6ch. +Driver can automatically switches TDM <-> stereo mode in this case. + + rsnd_tdm: sound { + compatible = "simple-audio-card"; + ... + simple-audio-card,cpu { + /* system can use TDM 6ch */ + dai-tdm-slot-num = <6>; + sound-dai = <&rcar_sound>; + }; + simple-audio-card,codec { + ... + }; + }; + + +============================================= Required properties: +============================================= + - compatible : "renesas,rcar_sound-", fallbacks "renesas,rcar_sound-gen1" if generation1, and "renesas,rcar_sound-gen2" if generation2 @@ -64,7 +395,10 @@ DAI subnode properties: - playback : list of playback modules - capture : list of capture modules + +============================================= Example: +============================================= rcar_sound: sound@ec500000 { #sound-dai-cells = <1>; @@ -250,7 +584,9 @@ rcar_sound: sound@ec500000 { }; }; +============================================= Example: simple sound card +============================================= rsnd_ak4643: sound { compatible = "simple-audio-card"; @@ -290,7 +626,9 @@ Example: simple sound card shared-pin; }; +============================================= Example: simple sound card for TDM +============================================= rsnd_tdm: sound { compatible = "simple-audio-card"; @@ -309,7 +647,9 @@ Example: simple sound card for TDM }; }; +============================================= Example: simple sound card for Multi channel +============================================= &rcar_sound { pinctrl-0 = <&sound_pins &sound_clk_pins>; diff --git a/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt b/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt index 2b2caa281ce38abcb46f688318a3479efcf02cfa..255ece3043adc42decf1ede321618321057d3dd8 100644 --- a/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt +++ b/Documentation/devicetree/bindings/sound/renesas,rsrc-card.txt @@ -30,6 +30,7 @@ Optional subnode properties: - frame-inversion : bool property. Add this if the dai-link uses frame clock inversion. - convert-rate : platform specified sampling rate convert +- convert-channels : platform specified converted channel size (2 - 8 ch) - audio-prefix : see audio-routing - audio-routing : A list of the connections between audio components. Each entry is a pair of strings, the first being the connection's sink, diff --git a/Documentation/devicetree/bindings/sound/rockchip-i2s.txt b/Documentation/devicetree/bindings/sound/rockchip-i2s.txt index b7f3a9325ebd564c9e455ced818acbe113b6182d..6e86d8aa29b4639397f51a8e73b8d8ede79c28fe 100644 --- a/Documentation/devicetree/bindings/sound/rockchip-i2s.txt +++ b/Documentation/devicetree/bindings/sound/rockchip-i2s.txt @@ -9,6 +9,7 @@ Required properties: - "rockchip,rk3066-i2s": for rk3066 - "rockchip,rk3188-i2s", "rockchip,rk3066-i2s": for rk3188 - "rockchip,rk3288-i2s", "rockchip,rk3066-i2s": for rk3288 + - "rockchip,rk3399-i2s", "rockchip,rk3066-i2s": for rk3399 - reg: physical base address of the controller and length of memory mapped region. - interrupts: should contain the I2S interrupt. diff --git a/Documentation/devicetree/bindings/sound/rockchip-spdif.txt b/Documentation/devicetree/bindings/sound/rockchip-spdif.txt index e64dbdea7db9b4e8f4745b343dccbfcbd0268d98..11046429a118a00356850528450c07a680c30a55 100644 --- a/Documentation/devicetree/bindings/sound/rockchip-spdif.txt +++ b/Documentation/devicetree/bindings/sound/rockchip-spdif.txt @@ -7,8 +7,12 @@ a fibre cable. Required properties: - compatible: should be one of the following: - - "rockchip,rk3288-spdif", "rockchip,rk3188-spdif" or - "rockchip,rk3066-spdif" + - "rockchip,rk3066-spdif" + - "rockchip,rk3188-spdif" + - "rockchip,rk3288-spdif" + - "rockchip,rk3366-spdif" + - "rockchip,rk3368-spdif" + - "rockchip,rk3399-spdif" - reg: physical base address of the controller and length of memory mapped region. - interrupts: should contain the SPDIF interrupt. diff --git a/Documentation/devicetree/bindings/sound/rt5514.txt b/Documentation/devicetree/bindings/sound/rt5514.txt new file mode 100644 index 0000000000000000000000000000000000000000..e24436fc5ea9986ae845cbfc03fff0216ed03d70 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/rt5514.txt @@ -0,0 +1,25 @@ +RT5514 audio CODEC + +This device supports I2C only. + +Required properties: + +- compatible : "realtek,rt5514". + +- reg : The I2C address of the device. + +Pins on the device (for linking into audio routes) for RT5514: + + * DMIC1L + * DMIC1R + * DMIC2L + * DMIC2R + * AMICL + * AMICR + +Example: + +codec: rt5514@57 { + compatible = "realtek,rt5514"; + reg = <0x57>; +}; diff --git a/Documentation/devicetree/bindings/sound/rt5616.txt b/Documentation/devicetree/bindings/sound/rt5616.txt index efc48c65198db044c10c2516d9988ebcf8c91f76..e410858185596a0fb74ec5812cef3dd3e6282762 100644 --- a/Documentation/devicetree/bindings/sound/rt5616.txt +++ b/Documentation/devicetree/bindings/sound/rt5616.txt @@ -8,6 +8,12 @@ Required properties: - reg : The I2C address of the device. +Optional properties: + +- clocks: The phandle of the master clock to the CODEC. + +- clock-names: Should be "mclk". + Pins on the device (for linking into audio routes) for RT5616: * IN1P diff --git a/Documentation/devicetree/bindings/sound/rt5640.txt b/Documentation/devicetree/bindings/sound/rt5640.txt index 9e62f6eb348f9499923dbcb473dad6ff22678bfa..57fe64643050a5e9f41072dd0d4ae0376f5d6958 100644 --- a/Documentation/devicetree/bindings/sound/rt5640.txt +++ b/Documentation/devicetree/bindings/sound/rt5640.txt @@ -12,6 +12,9 @@ Required properties: Optional properties: +- clocks: The phandle of the master clock to the CODEC +- clock-names: Should be "mclk" + - realtek,in1-differential - realtek,in2-differential - realtek,in3-differential diff --git a/Documentation/devicetree/bindings/sound/sunxi,sun4i-spdif.txt b/Documentation/devicetree/bindings/sound/sunxi,sun4i-spdif.txt new file mode 100644 index 0000000000000000000000000000000000000000..13503aa505a9cc4e4a3920f69e1fb61c6746fa09 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/sunxi,sun4i-spdif.txt @@ -0,0 +1,39 @@ +Allwinner Sony/Philips Digital Interface Format (S/PDIF) Controller + +The Allwinner S/PDIF audio block is a transceiver that allows the +processor to receive and transmit digital audio via an coaxial cable or +a fibre cable. +For now only playback is supported. + +Required properties: + + - compatible : should be one of the following: + - "allwinner,sun4i-a10-spdif": for the Allwinner A10 SoC + + - reg : Offset and length of the register set for the device. + + - interrupts : Contains the spdif interrupt. + + - dmas : Generic dma devicetree binding as described in + Documentation/devicetree/bindings/dma/dma.txt. + + - dma-names : Two dmas have to be defined, "tx" and "rx". + + - clocks : Contains an entry for each entry in clock-names. + + - clock-names : Includes the following entries: + "apb" clock for the spdif bus. + "spdif" clock for spdif controller. + +Example: + +spdif: spdif@01c21000 { + compatible = "allwinner,sun4i-a10-spdif"; + reg = <0x01c21000 0x40>; + interrupts = <13>; + clocks = <&apb0_gates 1>, <&spdif_clk>; + clock-names = "apb", "spdif"; + dmas = <&dma 0 2>, <&dma 0 2>; + dma-names = "rx", "tx"; + status = "okay"; +}; diff --git a/Documentation/devicetree/bindings/sound/ti,ads117x.txt b/Documentation/devicetree/bindings/sound/ti,ads117x.txt new file mode 100644 index 0000000000000000000000000000000000000000..7db19b50865a9878b284d0e1fabf26dbd9081ec9 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/ti,ads117x.txt @@ -0,0 +1,11 @@ +Texas Intstruments ADS117x ADC + +Required properties: + + - compatible : "ti,ads1174" or "ti,ads1178" + +Example: + +ads1178 { + compatible = "ti,ads1178"; +}; diff --git a/Documentation/devicetree/bindings/spi/spi-bus.txt b/Documentation/devicetree/bindings/spi/spi-bus.txt index bbaa857dd68fd938612b8c137badc79faf2c9479..42d595425dfb9f3cd8040f0dac7797ad006857d7 100644 --- a/Documentation/devicetree/bindings/spi/spi-bus.txt +++ b/Documentation/devicetree/bindings/spi/spi-bus.txt @@ -61,6 +61,8 @@ contain the following properties. used for MOSI. Defaults to 1 if not present. - spi-rx-bus-width - (optional) The bus width(number of data wires) that used for MISO. Defaults to 1 if not present. +- spi-rx-delay-us - (optional) Microsecond delay after a read transfer. +- spi-tx-delay-us - (optional) Microsecond delay after a write transfer. Some SPI controllers and devices support Dual and Quad SPI transfer mode. It allows data in the SPI system to be transferred in 2 wires(DUAL) or 4 wires(QUAD). diff --git a/Documentation/devicetree/bindings/sram/sram.txt b/Documentation/devicetree/bindings/sram/sram.txt index 42ee9438b77162ea8e9c5eb4b38468c88c92258e..227e3a341af1e2b525a4c59a3bc842041ddff1c3 100644 --- a/Documentation/devicetree/bindings/sram/sram.txt +++ b/Documentation/devicetree/bindings/sram/sram.txt @@ -25,6 +25,11 @@ Required properties in the sram node: - ranges : standard definition, should translate from local addresses within the sram to bus addresses +Optional properties in the sram node: + +- no-memory-wc : the flag indicating, that SRAM memory region has not to + be remapped as write combining. WC is used by default. + Required properties in the area nodes: - reg : iomem address range, relative to the SRAM range diff --git a/Documentation/devicetree/bindings/thermal/exynos-thermal.txt b/Documentation/devicetree/bindings/thermal/exynos-thermal.txt index 695150a4136bb3c3291e94fcbf7f7cdddfe6045e..70b4c16c7ed8374098557aee923375e0e94714c1 100644 --- a/Documentation/devicetree/bindings/thermal/exynos-thermal.txt +++ b/Documentation/devicetree/bindings/thermal/exynos-thermal.txt @@ -11,6 +11,7 @@ "samsung,exynos5420-tmu" for TMU channel 0, 1 on Exynos5420 "samsung,exynos5420-tmu-ext-triminfo" for TMU channels 2, 3 and 4 Exynos5420 (Must pass triminfo base and triminfo clock) + "samsung,exynos5433-tmu" "samsung,exynos5440-tmu" "samsung,exynos7-tmu" - interrupt-parent : The phandle for the interrupt controller @@ -40,9 +41,14 @@ for current TMU channel -- "tmu_sclk" clock for functional operation of the current TMU channel -- vtmu-supply: This entry is optional and provides the regulator node supplying - voltage to TMU. If needed this entry can be placed inside - board/platform specific dts file. + +The Exynos TMU supports generating interrupts when reaching given +temperature thresholds. Number of supported thermal trip points depends +on the SoC (only first trip points defined in DT will be configured): + - most of SoC: 4 + - samsung,exynos5433-tmu: 8 + - samsung,exynos7-tmu: 8 + Following properties are mandatory (depending on SoC): - samsung,tmu_gain: Gain value for internal TMU operation. - samsung,tmu_reference_voltage: Value of TMU IP block's reference voltage @@ -56,6 +62,12 @@ Following properties are mandatory (depending on SoC): - samsung,tmu_default_temp_offset: Default temperature offset - samsung,tmu_cal_type: Callibration type +** Optional properties: + +- vtmu-supply: This entry is optional and provides the regulator node supplying + voltage to TMU. If needed this entry can be placed inside + board/platform specific dts file. + Example 1): tmu@100C0000 { diff --git a/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt b/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt new file mode 100644 index 0000000000000000000000000000000000000000..81f9a512bc2a93d079ac6f2c0a5b121e560e9bb8 --- /dev/null +++ b/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt @@ -0,0 +1,43 @@ +* Mediatek Thermal + +This describes the device tree binding for the Mediatek thermal controller +which measures the on-SoC temperatures. This device does not have its own ADC, +instead it directly controls the AUXADC via AHB bus accesses. For this reason +this device needs phandles to the AUXADC. Also it controls a mux in the +apmixedsys register space via AHB bus accesses, so a phandle to the APMIXEDSYS +is also needed. + +Required properties: +- compatible: "mediatek,mt8173-thermal" +- reg: Address range of the thermal controller +- interrupts: IRQ for the thermal controller +- clocks, clock-names: Clocks needed for the thermal controller. required + clocks are: + "therm": Main clock needed for register access + "auxadc": The AUXADC clock +- resets: Reference to the reset controller controlling the thermal controller. +- mediatek,auxadc: A phandle to the AUXADC which the thermal controller uses +- mediatek,apmixedsys: A phandle to the APMIXEDSYS controller. +- #thermal-sensor-cells : Should be 0. See ./thermal.txt for a description. + +Optional properties: +- nvmem-cells: A phandle to the calibration data provided by a nvmem device. If + unspecified default values shall be used. +- nvmem-cell-names: Should be "calibration-data" + +Example: + + thermal: thermal@1100b000 { + #thermal-sensor-cells = <1>; + compatible = "mediatek,mt8173-thermal"; + reg = <0 0x1100b000 0 0x1000>; + interrupts = <0 70 IRQ_TYPE_LEVEL_LOW>; + clocks = <&pericfg CLK_PERI_THERM>, <&pericfg CLK_PERI_AUXADC>; + clock-names = "therm", "auxadc"; + resets = <&pericfg MT8173_PERI_THERM_SW_RST>; + reset-names = "therm"; + mediatek,auxadc = <&auxadc>; + mediatek,apmixedsys = <&apmixedsys>; + nvmem-cells = <&thermal_calibration_data>; + nvmem-cell-names = "calibration-data"; + }; diff --git a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt index 8ff54eb464dc6bf0f25f44bf4296c29371e44804..b1fe7e9de1b47b056778d1bafe69e06bac1534c4 100644 --- a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt +++ b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt @@ -6,6 +6,7 @@ Required properties: * "mediatek,mt2701-timer" for MT2701 compatible timers * "mediatek,mt6580-timer" for MT6580 compatible timers * "mediatek,mt6589-timer" for MT6589 compatible timers + * "mediatek,mt7623-timer" for MT7623 compatible timers * "mediatek,mt8127-timer" for MT8127 compatible timers * "mediatek,mt8135-timer" for MT8135 compatible timers * "mediatek,mt8173-timer" for MT8173 compatible timers diff --git a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt index 03c0e989e020a98ec28195896c8f8612686a580e..66f6adf8d44da55c87cb1fdd5ef501e40c3ea273 100644 --- a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt +++ b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt @@ -38,6 +38,9 @@ Optional properties: defined or a value in the array is "0" then it is assumed that the frequency is set by the parent clock or a fixed rate clock source. +-lanes-per-direction : number of lanes available per direction - either 1 or 2. + Note that it is assume same number of lanes is used both + directions at once. If not specified, default is 2 lanes per direction. Note: If above properties are not defined it can be assumed that the supply regulators or clocks are always on. diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 83700da22b7970cbc6a0f6a7a3c030921dde4551..86740d4a270d39c8d3fd3c97f16faeb96a2960ce 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -10,6 +10,7 @@ ad Avionic Design GmbH adapteva Adapteva, Inc. adh AD Holdings Plc. adi Analog Devices, Inc. +advantech Advantech Corporation aeroflexgaisler Aeroflex Gaisler AB al Annapurna Labs allwinner Allwinner Technology Co., Ltd. @@ -28,6 +29,7 @@ arm ARM Ltd. armadeus ARMadeus Systems SARL artesyn Artesyn Embedded Technologies Inc. asahi-kasei Asahi Kasei Corp. +atlas Atlas Scientific LLC atmel Atmel Corporation auo AU Optronics Corporation avago Avago Technologies @@ -71,6 +73,7 @@ dmo Data Modul AG ea Embedded Artists AB ebv EBV Elektronik edt Emerging Display Technologies +eeti eGalax_eMPIA Technology Inc elan Elan Microelectronic Corp. emmicro EM Microelectronic energymicro Silicon Laboratories (formerly Energy Micro AS) @@ -87,6 +90,7 @@ fcs Fairchild Semiconductor firefly Firefly focaltech FocalTech Systems Co.,Ltd fsl Freescale Semiconductor +ge General Electric Company GEFanuc GE Fanuc Intelligent Platforms Embedded Systems, Inc. gef GE Fanuc Intelligent Platforms Embedded Systems, Inc. geniatech Geniatech, Inc. @@ -111,6 +115,7 @@ hp Hewlett Packard i2se I2SE GmbH ibm International Business Machines (IBM) idt Integrated Device Technologies, Inc. +ifi Ingenieurburo Fur Ic-Technologie (I/F/I) iom Iomega Corporation img Imagination Technologies Ltd. ingenic Ingenic Semiconductor @@ -229,6 +234,7 @@ st STMicroelectronics startek Startek ste ST-Ericsson stericsson ST-Ericsson +syna Synaptics Inc. synology Synology, Inc. SUNW Sun Microsystems, Inc tbs TBS Technologies @@ -242,8 +248,10 @@ toshiba Toshiba Corporation toumaz Toumaz tplink TP-LINK Technologies Co., Ltd. tronfy Tronfy +tronsmart Tronsmart truly Truly Semiconductors Limited upisemi uPI Semiconductor Corp. +urt United Radiant Technology Corporation usi Universal Scientific Industrial Co., Ltd. v3 V3 Semiconductor variscite Variscite Ltd. diff --git a/Documentation/devicetree/bindings/watchdog/arm,sp805.txt b/Documentation/devicetree/bindings/watchdog/arm,sp805.txt new file mode 100644 index 0000000000000000000000000000000000000000..ca99d64e62118c70f7901cb379daeb932b246095 --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/arm,sp805.txt @@ -0,0 +1,17 @@ +ARM AMBA Primecell SP805 Watchdog + +Required properties: +- compatible: Should be "arm,sp805" & "arm,primecell" +- reg: Should contain location and length for watchdog timer register. +- interrupts: Should contain the list of watchdog timer interrupts. +- clocks: clocks driving the watchdog timer hardware. This list should be 2 + clocks. With 2 clocks, the order is wdogclk clock, apb_pclk. + +Example: + watchdog@66090000 { + compatible = "arm,sp805", "arm,primecell"; + reg = <0x66090000 0x1000>; + interrupts = ; + clocks = <&apb_pclk>,<&apb_pclk>; + clock-names = "wdogclk", "apb_pclk"; + }; diff --git a/Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txt b/Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txt new file mode 100644 index 0000000000000000000000000000000000000000..6f2d5f91964d50c029ee8be0cfbdf3e245b74f92 --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/sbsa-gwdt.txt @@ -0,0 +1,31 @@ +* SBSA (Server Base System Architecture) Generic Watchdog + +The SBSA Generic Watchdog Timer is used to force a reset of the system +after two stages of timeout have elapsed. A detailed definition of the +watchdog timer can be found in the ARM document: ARM-DEN-0029 - Server +Base System Architecture (SBSA) + +Required properties: +- compatible: Should at least contain "arm,sbsa-gwdt". + +- reg: Each entry specifies the base physical address of a register frame + and the length of that frame; currently, two frames must be defined, + in this order: + 1: Watchdog control frame; + 2: Refresh frame. + +- interrupts: Should contain the Watchdog Signal 0 (WS0) SPI (Shared + Peripheral Interrupt) number of SBSA Generic Watchdog. + +Optional properties +- timeout-sec: Watchdog timeout values (in seconds). + +Example for FVP Foundation Model v8: + +watchdog@2a440000 { + compatible = "arm,sbsa-gwdt"; + reg = <0x0 0x2a440000 0 0x1000>, + <0x0 0x2a450000 0 0x1000>; + interrupts = <0 27 4>; + timeout-sec = <30>; +}; diff --git a/Documentation/devicetree/booting-without-of.txt b/Documentation/devicetree/booting-without-of.txt index 04d34f6a58f350635d09d34ba2c5021bf9d89095..3f1437fbca6b49f39235b82305d7b51769f47ab4 100644 --- a/Documentation/devicetree/booting-without-of.txt +++ b/Documentation/devicetree/booting-without-of.txt @@ -16,6 +16,7 @@ Table of Contents 2) Entry point for arch/powerpc 3) Entry point for arch/x86 4) Entry point for arch/mips/bmips + 5) Entry point for arch/sh II - The DT block format 1) Header @@ -316,6 +317,18 @@ it with special cases. This convention is defined for 32-bit systems only, as there are not currently any 64-bit BMIPS implementations. +5) Entry point for arch/sh +-------------------------- + + Device-tree-compatible SH bootloaders are expected to provide the physical + address of the device tree blob in r4. Since legacy bootloaders did not + guarantee any particular initial register state, kernels built to + inter-operate with old bootloaders must either use a builtin DTB or + select a legacy board option (something other than CONFIG_SH_DEVICE_TREE) + that does not use device tree. Support for the latter is being phased out + in favor of device tree. + + II - The DT block format ======================== diff --git a/Documentation/dma-buf-sharing.txt b/Documentation/dma-buf-sharing.txt index 480c8de3c2c44786174e112795f61b2381d3b09f..ca44c58205858bdfc4115139c380f75a85ac1c3c 100644 --- a/Documentation/dma-buf-sharing.txt +++ b/Documentation/dma-buf-sharing.txt @@ -257,17 +257,15 @@ Access to a dma_buf from the kernel context involves three steps: Interface: int dma_buf_begin_cpu_access(struct dma_buf *dmabuf, - size_t start, size_t len, enum dma_data_direction direction) This allows the exporter to ensure that the memory is actually available for cpu access - the exporter might need to allocate or swap-in and pin the backing storage. The exporter also needs to ensure that cpu access is - coherent for the given range and access direction. The range and access - direction can be used by the exporter to optimize the cache flushing, i.e. - access outside of the range or with a different direction (read instead of - write) might return stale or even bogus data (e.g. when the exporter needs to - copy the data to temporary storage). + coherent for the access direction. The direction can be used by the exporter + to optimize the cache flushing, i.e. access with a different direction (read + instead of write) might return stale or even bogus data (e.g. when the + exporter needs to copy the data to temporary storage). This step might fail, e.g. in oom conditions. @@ -322,14 +320,13 @@ Access to a dma_buf from the kernel context involves three steps: 3. Finish access - When the importer is done accessing the range specified in begin_cpu_access, - it needs to announce this to the exporter (to facilitate cache flushing and - unpinning of any pinned resources). The result of any dma_buf kmap calls - after end_cpu_access is undefined. + When the importer is done accessing the CPU, it needs to announce this to + the exporter (to facilitate cache flushing and unpinning of any pinned + resources). The result of any dma_buf kmap calls after end_cpu_access is + undefined. Interface: void dma_buf_end_cpu_access(struct dma_buf *dma_buf, - size_t start, size_t len, enum dma_data_direction dir); @@ -353,7 +350,27 @@ Being able to mmap an export dma-buf buffer object has 2 main use-cases: 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. + No special interfaces, userspace simply calls mmap on the dma-buf fd, making + sure that the cache synchronization ioctl (DMA_BUF_IOCTL_SYNC) is *always* + used when the access happens. Note that DMA_BUF_IOCTL_SYNC can fail with + -EAGAIN or -EINTR, in which case it must be restarted. + + Some systems might need some sort of cache coherency management e.g. when + CPU and GPU domains are being accessed through dma-buf at the same time. To + circumvent this problem there are begin/end coherency markers, that forward + directly to existing dma-buf device drivers vfunc hooks. Userspace can make + use of those markers through the DMA_BUF_IOCTL_SYNC ioctl. The sequence + would be used like following: + - mmap dma-buf fd + - for each drawing/upload cycle in CPU 1. SYNC_START ioctl, 2. read/write + to mmap area 3. SYNC_END ioctl. This can be repeated as often as you + want (with the new data being consumed by the GPU or say scanout device) + - munmap once you don't need the buffer any more + + For correctness and optimal performance, it is always required to use + SYNC_START and SYNC_END before and after, respectively, when accessing the + mapped address. Userspace cannot rely on coherent access, even when there + are systems where it just works without calling these ioctls. 2. Supporting existing mmap interfaces in importers diff --git a/Documentation/driver-model/porting.txt b/Documentation/driver-model/porting.txt index 92d86f7271b4d960431e3333ce5d0de3b9f9889e..453053f1661f47e2dc3c75d0564b2105e8ddfb22 100644 --- a/Documentation/driver-model/porting.txt +++ b/Documentation/driver-model/porting.txt @@ -340,8 +340,10 @@ comparison: int (*match)(struct device * dev, struct device_driver * drv); -match should return '1' if the driver supports the device, and '0' -otherwise. +match should return positive value if the driver supports the device, +and zero otherwise. It may also return error code (for example +-EPROBE_DEFER) if determining that given driver supports the device is +not possible. When a device is registered, the bus's list of drivers is iterated over. bus->match() is called for each one until a match is found. diff --git a/Documentation/efi-stub.txt b/Documentation/efi-stub.txt index 7747024d3bb70023fbff500cd3fc44546b31511b..e157469882614ae96ddced101a5fc77315d49043 100644 --- a/Documentation/efi-stub.txt +++ b/Documentation/efi-stub.txt @@ -10,12 +10,12 @@ arch/x86/boot/header.S and arch/x86/boot/compressed/eboot.c, respectively. For ARM the EFI stub is implemented in arch/arm/boot/compressed/efi-header.S and arch/arm/boot/compressed/efi-stub.c. EFI stub code that is shared -between architectures is in drivers/firmware/efi/efi-stub-helper.c. +between architectures is in drivers/firmware/efi/libstub. For arm64, there is no compressed kernel support, so the Image itself masquerades as a PE/COFF image and the EFI stub is linked into the kernel. The arm64 EFI stub lives in arch/arm64/kernel/efi-entry.S -and arch/arm64/kernel/efi-stub.c. +and drivers/firmware/efi/libstub/arm64-stub.c. 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 diff --git a/Documentation/filesystems/btrfs.txt b/Documentation/filesystems/btrfs.txt index c772b47e7ef06e0b8f06538d32ea883343d51081..f9dad22d95cebe1ac1f1e5e0770da73777aba0de 100644 --- a/Documentation/filesystems/btrfs.txt +++ b/Documentation/filesystems/btrfs.txt @@ -1,20 +1,10 @@ - BTRFS ===== -Btrfs is a copy on write filesystem for Linux aimed at -implementing advanced features while focusing on fault tolerance, -repair and easy administration. Initially developed by Oracle, Btrfs -is licensed under the GPL and open for contribution from anyone. - -Linux has a wealth of filesystems to choose from, but we are facing a -number of challenges with scaling to the large storage subsystems that -are becoming common in today's data centers. Filesystems need to scale -in their ability to address and manage large storage, and also in -their ability to detect, repair and tolerate errors in the data stored -on disk. Btrfs is under heavy development, and is not suitable for -any uses other than benchmarking and review. The Btrfs disk format is -not yet finalized. +Btrfs is a copy on write filesystem for Linux aimed at implementing advanced +features while focusing on fault tolerance, repair and easy administration. +Jointly developed by several companies, licensed under the GPL and open for +contribution from anyone. The main Btrfs features include: @@ -28,243 +18,14 @@ The main Btrfs features include: * Checksums on data and metadata (multiple algorithms available) * Compression * Integrated multiple device support, with several raid algorithms - * Online filesystem check (not yet implemented) - * Very fast offline filesystem check - * Efficient incremental backup and FS mirroring (not yet implemented) + * Offline filesystem check + * Efficient incremental backup and FS mirroring * Online filesystem defragmentation +For more information please refer to the wiki -Mount Options -============= - -When mounting a btrfs filesystem, the following option are accepted. -Options with (*) are default options and will not show in the mount options. - - alloc_start= - Debugging option to force all block allocations above a certain - byte threshold on each block device. The value is specified in - bytes, optionally with a K, M, or G suffix, case insensitive. - Default is 1MB. - - noautodefrag(*) - autodefrag - Disable/enable auto defragmentation. - Auto defragmentation detects small random writes into files and queue - them up for the defrag process. Works best for small files; - Not well suited for large database workloads. - - check_int - check_int_data - check_int_print_mask= - These debugging options control the behavior of the integrity checking - module (the BTRFS_FS_CHECK_INTEGRITY config option required). - - check_int enables the integrity checker module, which examines all - block write requests to ensure on-disk consistency, at a large - memory and CPU cost. - - check_int_data includes extent data in the integrity checks, and - implies the check_int option. - - check_int_print_mask takes a bitmask of BTRFSIC_PRINT_MASK_* values - as defined in fs/btrfs/check-integrity.c, to control the integrity - checker module behavior. - - See comments at the top of fs/btrfs/check-integrity.c for more info. - - commit= - Set the interval of periodic commit, 30 seconds by default. Higher - values defer data being synced to permanent storage with obvious - consequences when the system crashes. The upper bound is not forced, - but a warning is printed if it's more than 300 seconds (5 minutes). - - compress - compress= - compress-force - compress-force= - Control BTRFS file data compression. Type may be specified as "zlib" - "lzo" or "no" (for no compression, used for remounting). If no type - is specified, zlib is used. If compress-force is specified, - all files will be compressed, whether or not they compress well. - If compression is enabled, nodatacow and nodatasum are disabled. - - degraded - Allow mounts to continue with missing devices. A read-write mount may - fail with too many devices missing, for example if a stripe member - is completely missing. - - device= - Specify a device during mount so that ioctls on the control device - can be avoided. Especially useful when trying to mount a multi-device - setup as root. May be specified multiple times for multiple devices. - - nodiscard(*) - discard - Disable/enable discard mount option. - Discard issues frequent commands to let the block device reclaim space - freed by the filesystem. - This is useful for SSD devices, thinly provisioned - LUNs and virtual machine images, but may have a significant - performance impact. (The fstrim command is also available to - initiate batch trims from userspace). - - noenospc_debug(*) - enospc_debug - Disable/enable debugging option to be more verbose in some ENOSPC conditions. - - fatal_errors= - Action to take when encountering a fatal error: - "bug" - BUG() on a fatal error. This is the default. - "panic" - panic() on a fatal error. - - noflushoncommit(*) - flushoncommit - The 'flushoncommit' mount option forces any data dirtied by a write in a - prior transaction to commit as part of the current commit. This makes - the committed state a fully consistent view of the file system from the - application's perspective (i.e., it includes all completed file system - operations). This was previously the behavior only when a snapshot is - created. - - inode_cache - Enable free inode number caching. Defaults to off due to an overflow - problem when the free space crcs don't fit inside a single page. - - max_inline= - Specify the maximum amount of space, in bytes, that can be inlined in - a metadata B-tree leaf. The value is specified in bytes, optionally - with a K, M, or G suffix, case insensitive. In practice, this value - is limited by the root sector size, with some space unavailable due - to leaf headers. For a 4k sector size, max inline data is ~3900 bytes. - - metadata_ratio= - Specify that 1 metadata chunk should be allocated after every - data chunks. Off by default. - - acl(*) - noacl - Enable/disable support for Posix Access Control Lists (ACLs). See the - acl(5) manual page for more information about ACLs. - - barrier(*) - nobarrier - Enable/disable the use of block layer write barriers. Write barriers - ensure that certain IOs make it through the device cache and are on - persistent storage. If disabled on a device with a volatile - (non-battery-backed) write-back cache, nobarrier option will lead to - filesystem corruption on a system crash or power loss. - - datacow(*) - nodatacow - Enable/disable data copy-on-write for newly created files. - Nodatacow implies nodatasum, and disables all compression. - - datasum(*) - nodatasum - Enable/disable data checksumming for newly created files. - Datasum implies datacow. - - treelog(*) - notreelog - Enable/disable the tree logging used for fsync and O_SYNC writes. - - recovery - Enable autorecovery attempts if a bad tree root is found at mount time. - Currently this scans a list of several previous tree roots and tries to - use the first readable. - - rescan_uuid_tree - Force check and rebuild procedure of the UUID tree. This should not - normally be needed. - - skip_balance - Skip automatic resume of interrupted balance operation after mount. - May be resumed with "btrfs balance resume." - - space_cache (*) - Enable the on-disk freespace cache. - nospace_cache - Disable freespace cache loading without clearing the cache. - clear_cache - Force clearing and rebuilding of the disk space cache if something - has gone wrong. - - ssd - nossd - ssd_spread - Options to control ssd allocation schemes. By default, BTRFS will - enable or disable ssd allocation heuristics depending on whether a - rotational or non-rotational disk is in use. The ssd and nossd options - can override this autodetection. - - The ssd_spread mount option attempts to allocate into big chunks - of unused space, and may perform better on low-end ssds. ssd_spread - implies ssd, enabling all other ssd heuristics as well. - - subvol= - Mount subvolume at rather than the root subvolume. is - relative to the top level subvolume. - - subvolid= - Mount subvolume specified by an ID number rather than the root subvolume. - This allows mounting of subvolumes which are not in the root of the mounted - filesystem. - You can use "btrfs subvolume list" to see subvolume ID numbers. - - subvolrootid= (deprecated) - Mount subvolume specified by rather than the root subvolume. - This allows mounting of subvolumes which are not in the root of the mounted - filesystem. - You can use "btrfs subvolume show " to see the object ID for a subvolume. - - thread_pool= - The number of worker threads to allocate. The default number is equal - to the number of CPUs + 2, or 8, whichever is smaller. - - user_subvol_rm_allowed - Allow subvolumes to be deleted by a non-root user. Use with caution. - -MAILING LIST -============ - -There is a Btrfs mailing list hosted on vger.kernel.org. You can -find details on how to subscribe here: - -http://vger.kernel.org/vger-lists.html#linux-btrfs - -Mailing list archives are available from gmane: - -http://dir.gmane.org/gmane.comp.file-systems.btrfs - - - -IRC -=== - -Discussion of Btrfs also occurs on the #btrfs channel of the Freenode -IRC network. - - - - UTILITIES - ========= - -Userspace tools for creating and manipulating Btrfs file systems are -available from the git repository at the following location: - - http://git.kernel.org/?p=linux/kernel/git/mason/btrfs-progs.git - git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-progs.git - -These include the following tools: - -* mkfs.btrfs: create a filesystem - -* btrfs: a single tool to manage the filesystems, refer to the manpage for more details - -* 'btrfsck' or 'btrfs check': do a consistency check of the filesystem - -Other tools for specific tasks: - -* btrfs-convert: in-place conversion from ext2/3/4 filesystems + https://btrfs.wiki.kernel.org -* btrfs-image: dump filesystem metadata for debugging +that maintains information about administration tasks, frequently asked +questions, use cases, mount options, comprehensible changelogs, features, +manual pages, source code repositories, contacts etc. diff --git a/Documentation/filesystems/cramfs.txt b/Documentation/filesystems/cramfs.txt index 31f53f0ab95754a62e5aad6f08e73e3d2715cfac..4006298f670700b1da158616df1718dde422ef48 100644 --- a/Documentation/filesystems/cramfs.txt +++ b/Documentation/filesystems/cramfs.txt @@ -38,7 +38,7 @@ the update lasts only as long as the inode is cached in memory, after which the timestamp reverts to 1970, i.e. moves backwards in time. Currently, cramfs must be written and read with architectures of the -same endianness, and can be read only by kernels with PAGE_CACHE_SIZE +same endianness, and can be read only by kernels with PAGE_SIZE == 4096. At least the latter of these is a bug, but it hasn't been decided what the best fix is. For the moment if you have larger pages you can just change the #define in mkcramfs.c, so long as you don't diff --git a/Documentation/filesystems/nfs/pnfs-scsi-server.txt b/Documentation/filesystems/nfs/pnfs-scsi-server.txt new file mode 100644 index 0000000000000000000000000000000000000000..5bef7268bd9fb6035ae98f14bc5a845723c1ca99 --- /dev/null +++ b/Documentation/filesystems/nfs/pnfs-scsi-server.txt @@ -0,0 +1,23 @@ + +pNFS SCSI layout server user guide +================================== + +This document describes support for pNFS SCSI layouts in the Linux NFS server. +With pNFS SCSI layouts, the NFS server acts as Metadata Server (MDS) for pNFS, +which in addition to handling all the metadata access to the NFS export, +also hands out layouts to the clients so that they can directly access the +underlying SCSI LUNs that are shared with the client. + +To use pNFS SCSI layouts with with the Linux NFS server, the exported file +system needs to support the pNFS SCSI layouts (currently just XFS), and the +file system must sit on a SCSI LUN that is accessible to the clients in +addition to the MDS. As of now the file system needs to sit directly on the +exported LUN, striping or concatenation of LUNs on the MDS and clients +is not supported yet. + +On a server built with CONFIG_NFSD_SCSI, the pNFS SCSI volume support is +automatically enabled if the file system is exported using the "pnfs" +option and the underlying SCSI device support persistent reservations. +On the client make sure the kernel has the CONFIG_PNFS_BLOCK option +enabled, and the file system is mounted using the NFSv4.1 protocol +version (mount -o vers=4.1). diff --git a/Documentation/filesystems/ocfs2-online-filecheck.txt b/Documentation/filesystems/ocfs2-online-filecheck.txt new file mode 100644 index 0000000000000000000000000000000000000000..1ab07860430d512389483cfb93e0fcb51480b48e --- /dev/null +++ b/Documentation/filesystems/ocfs2-online-filecheck.txt @@ -0,0 +1,94 @@ + OCFS2 online file check + ----------------------- + +This document will describe OCFS2 online file check feature. + +Introduction +============ +OCFS2 is often used in high-availaibility systems. However, OCFS2 usually +converts the filesystem to read-only when encounters an error. This may not be +necessary, since turning the filesystem read-only would affect other running +processes as well, decreasing availability. +Then, a mount option (errors=continue) is introduced, which would return the +-EIO errno to the calling process and terminate furhter processing so that the +filesystem is not corrupted further. The filesystem is not converted to +read-only, and the problematic file's inode number is reported in the kernel +log. The user can try to check/fix this file via online filecheck feature. + +Scope +===== +This effort is to check/fix small issues which may hinder day-to-day operations +of a cluster filesystem by turning the filesystem read-only. The scope of +checking/fixing is at the file level, initially for regular files and eventually +to all files (including system files) of the filesystem. + +In case of directory to file links is incorrect, the directory inode is +reported as erroneous. + +This feature is not suited for extravagant checks which involve dependency of +other components of the filesystem, such as but not limited to, checking if the +bits for file blocks in the allocation has been set. In case of such an error, +the offline fsck should/would be recommended. + +Finally, such an operation/feature should not be automated lest the filesystem +may end up with more damage than before the repair attempt. So, this has to +be performed using user interaction and consent. + +User interface +============== +When there are errors in the OCFS2 filesystem, they are usually accompanied +by the inode number which caused the error. This inode number would be the +input to check/fix the file. + +There is a sysfs directory for each OCFS2 file system mounting: + + /sys/fs/ocfs2//filecheck + +Here, indicates the name of OCFS2 volumn device which has been already +mounted. The file above would accept inode numbers. This could be used to +communicate with kernel space, tell which file(inode number) will be checked or +fixed. Currently, three operations are supported, which includes checking +inode, fixing inode and setting the size of result record history. + +1. If you want to know what error exactly happened to before fixing, do + + # echo "" > /sys/fs/ocfs2//filecheck/check + # cat /sys/fs/ocfs2//filecheck/check + +The output is like this: + INO DONE ERROR +39502 1 GENERATION + + lists the inode numbers. + indicates whether the operation has been finished. + says what kind of errors was found. For the detailed error numbers, +please refer to the file linux/fs/ocfs2/filecheck.h. + +2. If you determine to fix this inode, do + + # echo "" > /sys/fs/ocfs2//filecheck/fix + # cat /sys/fs/ocfs2//filecheck/fix + +The output is like this: + INO DONE ERROR +39502 1 SUCCESS + +This time, the column indicates whether this fix is successful or not. + +3. The record cache is used to store the history of check/fix results. It's +defalut size is 10, and can be adjust between the range of 10 ~ 100. You can +adjust the size like this: + + # echo "" > /sys/fs/ocfs2//filecheck/set + +Fixing stuff +============ +On receivng the inode, the filesystem would read the inode and the +file metadata. In case of errors, the filesystem would fix the errors +and report the problems it fixed in the kernel log. As a precautionary measure, +the inode must first be checked for errors before performing a final fix. + +The inode and the result history will be maintained temporarily in a +small linked list buffer which would contain the last (N) inodes +fixed/checked, the detailed errors which were fixed/checked are printed in the +kernel log. diff --git a/Documentation/filesystems/orangefs.txt b/Documentation/filesystems/orangefs.txt new file mode 100644 index 0000000000000000000000000000000000000000..e1a0056a365ffd42c0e93aa1233d04beb40b4e72 --- /dev/null +++ b/Documentation/filesystems/orangefs.txt @@ -0,0 +1,406 @@ +ORANGEFS +======== + +OrangeFS is an LGPL userspace scale-out parallel storage system. It is ideal +for large storage problems faced by HPC, BigData, Streaming Video, +Genomics, Bioinformatics. + +Orangefs, originally called PVFS, was first developed in 1993 by +Walt Ligon and Eric Blumer as a parallel file system for Parallel +Virtual Machine (PVM) as part of a NASA grant to study the I/O patterns +of parallel programs. + +Orangefs features include: + + * Distributes file data among multiple file servers + * Supports simultaneous access by multiple clients + * Stores file data and metadata on servers using local file system + and access methods + * Userspace implementation is easy to install and maintain + * Direct MPI support + * Stateless + + +MAILING LIST +============ + +http://beowulf-underground.org/mailman/listinfo/pvfs2-users + + +DOCUMENTATION +============= + +http://www.orangefs.org/documentation/ + + +USERSPACE FILESYSTEM SOURCE +=========================== + +http://www.orangefs.org/download + +Orangefs versions prior to 2.9.3 would not be compatible with the +upstream version of the kernel client. + + +BUILDING THE USERSPACE FILESYSTEM ON A SINGLE SERVER +==================================================== + +When Orangefs is upstream, "--with-kernel" shouldn't be needed, but +until then the path to where the kernel with the Orangefs kernel client +patch was built is needed to ensure that pvfs2-client-core (the bridge +between kernel space and user space) will build properly. You can omit +--prefix if you don't care that things are sprinkled around in +/usr/local. + +./configure --prefix=/opt/ofs --with-kernel=/path/to/orangefs/kernel + +make + +make install + +Create an orangefs config file: +/opt/ofs/bin/pvfs2-genconfig /etc/pvfs2.conf + + for "Enter hostnames", use the hostname, don't let it default to + localhost. + +create a pvfs2tab file in /etc: +cat /etc/pvfs2tab +tcp://myhostname:3334/orangefs /mymountpoint pvfs2 defaults,noauto 0 0 + +create the mount point you specified in the tab file if needed: +mkdir /mymountpoint + +bootstrap the server: +/opt/ofs/sbin/pvfs2-server /etc/pvfs2.conf -f + +start the server: +/opt/osf/sbin/pvfs2-server /etc/pvfs2.conf + +Now the server is running. At this point you might like to +prove things are working with: + +/opt/osf/bin/pvfs2-ls /mymountpoint + +You might not want to enforce selinux, it doesn't seem to matter by +linux 3.11... + +If stuff seems to be working, turn on the client core: +/opt/osf/sbin/pvfs2-client -p /opt/osf/sbin/pvfs2-client-core + +Mount your filesystem. +mount -t pvfs2 tcp://myhostname:3334/orangefs /mymountpoint + + +OPTIONS +======= + +The following mount options are accepted: + + acl + Allow the use of Access Control Lists on files and directories. + + intr + Some operations between the kernel client and the user space + filesystem can be interruptible, such as changes in debug levels + and the setting of tunable parameters. + + local_lock + Enable posix locking from the perspective of "this" kernel. The + default file_operations lock action is to return ENOSYS. Posix + locking kicks in if the filesystem is mounted with -o local_lock. + Distributed locking is being worked on for the future. + + +DEBUGGING +========= + +If you want the debug (GOSSIP) statements in a particular +source file (inode.c for example) go to syslog: + + echo inode > /sys/kernel/debug/orangefs/kernel-debug + +No debugging (the default): + + echo none > /sys/kernel/debug/orangefs/kernel-debug + +Debugging from several source files: + + echo inode,dir > /sys/kernel/debug/orangefs/kernel-debug + +All debugging: + + echo all > /sys/kernel/debug/orangefs/kernel-debug + +Get a list of all debugging keywords: + + cat /sys/kernel/debug/orangefs/debug-help + + +PROTOCOL BETWEEN KERNEL MODULE AND USERSPACE +============================================ + +Orangefs is a user space filesystem and an associated kernel module. +We'll just refer to the user space part of Orangefs as "userspace" +from here on out. Orangefs descends from PVFS, and userspace code +still uses PVFS for function and variable names. Userspace typedefs +many of the important structures. Function and variable names in +the kernel module have been transitioned to "orangefs", and The Linux +Coding Style avoids typedefs, so kernel module structures that +correspond to userspace structures are not typedefed. + +The kernel module implements a pseudo device that userspace +can read from and write to. Userspace can also manipulate the +kernel module through the pseudo device with ioctl. + +THE BUFMAP: + +At startup userspace allocates two page-size-aligned (posix_memalign) +mlocked memory buffers, one is used for IO and one is used for readdir +operations. The IO buffer is 41943040 bytes and the readdir buffer is +4194304 bytes. Each buffer contains logical chunks, or partitions, and +a pointer to each buffer is added to its own PVFS_dev_map_desc structure +which also describes its total size, as well as the size and number of +the partitions. + +A pointer to the IO buffer's PVFS_dev_map_desc structure is sent to a +mapping routine in the kernel module with an ioctl. The structure is +copied from user space to kernel space with copy_from_user and is used +to initialize the kernel module's "bufmap" (struct orangefs_bufmap), which +then contains: + + * refcnt - a reference counter + * desc_size - PVFS2_BUFMAP_DEFAULT_DESC_SIZE (4194304) - the IO buffer's + partition size, which represents the filesystem's block size and + is used for s_blocksize in super blocks. + * desc_count - PVFS2_BUFMAP_DEFAULT_DESC_COUNT (10) - the number of + partitions in the IO buffer. + * desc_shift - log2(desc_size), used for s_blocksize_bits in super blocks. + * total_size - the total size of the IO buffer. + * page_count - the number of 4096 byte pages in the IO buffer. + * page_array - a pointer to page_count * (sizeof(struct page*)) bytes + of kcalloced memory. This memory is used as an array of pointers + to each of the pages in the IO buffer through a call to get_user_pages. + * desc_array - a pointer to desc_count * (sizeof(struct orangefs_bufmap_desc)) + bytes of kcalloced memory. This memory is further intialized: + + user_desc is the kernel's copy of the IO buffer's ORANGEFS_dev_map_desc + structure. user_desc->ptr points to the IO buffer. + + pages_per_desc = bufmap->desc_size / PAGE_SIZE + offset = 0 + + bufmap->desc_array[0].page_array = &bufmap->page_array[offset] + bufmap->desc_array[0].array_count = pages_per_desc = 1024 + bufmap->desc_array[0].uaddr = (user_desc->ptr) + (0 * 1024 * 4096) + offset += 1024 + . + . + . + bufmap->desc_array[9].page_array = &bufmap->page_array[offset] + bufmap->desc_array[9].array_count = pages_per_desc = 1024 + bufmap->desc_array[9].uaddr = (user_desc->ptr) + + (9 * 1024 * 4096) + offset += 1024 + + * buffer_index_array - a desc_count sized array of ints, used to + indicate which of the IO buffer's partitions are available to use. + * buffer_index_lock - a spinlock to protect buffer_index_array during update. + * readdir_index_array - a five (ORANGEFS_READDIR_DEFAULT_DESC_COUNT) element + int array used to indicate which of the readdir buffer's partitions are + available to use. + * readdir_index_lock - a spinlock to protect readdir_index_array during + update. + +OPERATIONS: + +The kernel module builds an "op" (struct orangefs_kernel_op_s) when it +needs to communicate with userspace. Part of the op contains the "upcall" +which expresses the request to userspace. Part of the op eventually +contains the "downcall" which expresses the results of the request. + +The slab allocator is used to keep a cache of op structures handy. + +At init time the kernel module defines and initializes a request list +and an in_progress hash table to keep track of all the ops that are +in flight at any given time. + +Ops are stateful: + + * unknown - op was just initialized + * waiting - op is on request_list (upward bound) + * inprogr - op is in progress (waiting for downcall) + * serviced - op has matching downcall; ok + * purged - op has to start a timer since client-core + exited uncleanly before servicing op + * given up - submitter has given up waiting for it + +When some arbitrary userspace program needs to perform a +filesystem operation on Orangefs (readdir, I/O, create, whatever) +an op structure is initialized and tagged with a distinguishing ID +number. The upcall part of the op is filled out, and the op is +passed to the "service_operation" function. + +Service_operation changes the op's state to "waiting", puts +it on the request list, and signals the Orangefs file_operations.poll +function through a wait queue. Userspace is polling the pseudo-device +and thus becomes aware of the upcall request that needs to be read. + +When the Orangefs file_operations.read function is triggered, the +request list is searched for an op that seems ready-to-process. +The op is removed from the request list. The tag from the op and +the filled-out upcall struct are copy_to_user'ed back to userspace. + +If any of these (and some additional protocol) copy_to_users fail, +the op's state is set to "waiting" and the op is added back to +the request list. Otherwise, the op's state is changed to "in progress", +and the op is hashed on its tag and put onto the end of a list in the +in_progress hash table at the index the tag hashed to. + +When userspace has assembled the response to the upcall, it +writes the response, which includes the distinguishing tag, back to +the pseudo device in a series of io_vecs. This triggers the Orangefs +file_operations.write_iter function to find the op with the associated +tag and remove it from the in_progress hash table. As long as the op's +state is not "canceled" or "given up", its state is set to "serviced". +The file_operations.write_iter function returns to the waiting vfs, +and back to service_operation through wait_for_matching_downcall. + +Service operation returns to its caller with the op's downcall +part (the response to the upcall) filled out. + +The "client-core" is the bridge between the kernel module and +userspace. The client-core is a daemon. The client-core has an +associated watchdog daemon. If the client-core is ever signaled +to die, the watchdog daemon restarts the client-core. Even though +the client-core is restarted "right away", there is a period of +time during such an event that the client-core is dead. A dead client-core +can't be triggered by the Orangefs file_operations.poll function. +Ops that pass through service_operation during a "dead spell" can timeout +on the wait queue and one attempt is made to recycle them. Obviously, +if the client-core stays dead too long, the arbitrary userspace processes +trying to use Orangefs will be negatively affected. Waiting ops +that can't be serviced will be removed from the request list and +have their states set to "given up". In-progress ops that can't +be serviced will be removed from the in_progress hash table and +have their states set to "given up". + +Readdir and I/O ops are atypical with respect to their payloads. + + - readdir ops use the smaller of the two pre-allocated pre-partitioned + memory buffers. The readdir buffer is only available to userspace. + The kernel module obtains an index to a free partition before launching + a readdir op. Userspace deposits the results into the indexed partition + and then writes them to back to the pvfs device. + + - io (read and write) ops use the larger of the two pre-allocated + pre-partitioned memory buffers. The IO buffer is accessible from + both userspace and the kernel module. The kernel module obtains an + index to a free partition before launching an io op. The kernel module + deposits write data into the indexed partition, to be consumed + directly by userspace. Userspace deposits the results of read + requests into the indexed partition, to be consumed directly + by the kernel module. + +Responses to kernel requests are all packaged in pvfs2_downcall_t +structs. Besides a few other members, pvfs2_downcall_t contains a +union of structs, each of which is associated with a particular +response type. + +The several members outside of the union are: + - int32_t type - type of operation. + - int32_t status - return code for the operation. + - int64_t trailer_size - 0 unless readdir operation. + - char *trailer_buf - initialized to NULL, used during readdir operations. + +The appropriate member inside the union is filled out for any +particular response. + + PVFS2_VFS_OP_FILE_IO + fill a pvfs2_io_response_t + + PVFS2_VFS_OP_LOOKUP + fill a PVFS_object_kref + + PVFS2_VFS_OP_CREATE + fill a PVFS_object_kref + + PVFS2_VFS_OP_SYMLINK + fill a PVFS_object_kref + + PVFS2_VFS_OP_GETATTR + fill in a PVFS_sys_attr_s (tons of stuff the kernel doesn't need) + fill in a string with the link target when the object is a symlink. + + PVFS2_VFS_OP_MKDIR + fill a PVFS_object_kref + + PVFS2_VFS_OP_STATFS + fill a pvfs2_statfs_response_t with useless info . It is hard for + us to know, in a timely fashion, these statistics about our + distributed network filesystem. + + PVFS2_VFS_OP_FS_MOUNT + fill a pvfs2_fs_mount_response_t which is just like a PVFS_object_kref + except its members are in a different order and "__pad1" is replaced + with "id". + + PVFS2_VFS_OP_GETXATTR + fill a pvfs2_getxattr_response_t + + PVFS2_VFS_OP_LISTXATTR + fill a pvfs2_listxattr_response_t + + PVFS2_VFS_OP_PARAM + fill a pvfs2_param_response_t + + PVFS2_VFS_OP_PERF_COUNT + fill a pvfs2_perf_count_response_t + + PVFS2_VFS_OP_FSKEY + file a pvfs2_fs_key_response_t + + PVFS2_VFS_OP_READDIR + jamb everything needed to represent a pvfs2_readdir_response_t into + the readdir buffer descriptor specified in the upcall. + +Userspace uses writev() on /dev/pvfs2-req to pass responses to the requests +made by the kernel side. + +A buffer_list containing: + - a pointer to the prepared response to the request from the + kernel (struct pvfs2_downcall_t). + - and also, in the case of a readdir request, a pointer to a + buffer containing descriptors for the objects in the target + directory. +... is sent to the function (PINT_dev_write_list) which performs +the writev. + +PINT_dev_write_list has a local iovec array: struct iovec io_array[10]; + +The first four elements of io_array are initialized like this for all +responses: + + io_array[0].iov_base = address of local variable "proto_ver" (int32_t) + io_array[0].iov_len = sizeof(int32_t) + + io_array[1].iov_base = address of global variable "pdev_magic" (int32_t) + io_array[1].iov_len = sizeof(int32_t) + + io_array[2].iov_base = address of parameter "tag" (PVFS_id_gen_t) + io_array[2].iov_len = sizeof(int64_t) + + io_array[3].iov_base = address of out_downcall member (pvfs2_downcall_t) + of global variable vfs_request (vfs_request_t) + io_array[3].iov_len = sizeof(pvfs2_downcall_t) + +Readdir responses initialize the fifth element io_array like this: + + io_array[4].iov_base = contents of member trailer_buf (char *) + from out_downcall member of global variable + vfs_request + io_array[4].iov_len = contents of member trailer_size (PVFS_size) + from out_downcall member of global variable + vfs_request + + diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index 843b045b4069a62c154bdf6c2723b3061bd81abd..7f5607a089b447eb2f741ff544db9eefe30f44fc 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt @@ -43,6 +43,7 @@ Table of Contents 3.7 /proc//task//children - Information about task children 3.8 /proc//fdinfo/ - Information about opened file 3.9 /proc//map_files - Information about memory mapped files + 3.10 /proc//timerslack_ns - Task timerslack value 4 Configuring procfs 4.1 Mount options @@ -1862,6 +1863,23 @@ time one can open(2) mappings from the listings of two processes and comparing their inode numbers to figure out which anonymous memory areas are actually shared. +3.10 /proc//timerslack_ns - Task timerslack value +--------------------------------------------------------- +This file provides the value of the task's timerslack value in nanoseconds. +This value specifies a amount of time that normal timers may be deferred +in order to coalesce timers and avoid unnecessary wakeups. + +This allows a task's interactivity vs power consumption trade off to be +adjusted. + +Writing 0 to the file will set the tasks timerslack to the default value. + +Valid values are from 0 - ULLONG_MAX + +An application setting the value must have PTRACE_MODE_ATTACH_FSCREDS level +permissions on the task specified to change its timerslack_ns value. + + ------------------------------------------------------------------------------ Configuring procfs ------------------------------------------------------------------------------ diff --git a/Documentation/filesystems/tmpfs.txt b/Documentation/filesystems/tmpfs.txt index d392e1505f170b1c6c6e828c37388b2443a38b89..d9c11d25bf02132bebeeceb1b5c2c7e04901d4c7 100644 --- a/Documentation/filesystems/tmpfs.txt +++ b/Documentation/filesystems/tmpfs.txt @@ -60,7 +60,7 @@ size: The limit of allocated bytes for this tmpfs instance. The default is half of your physical RAM without swap. If you oversize your tmpfs instances the machine will deadlock since the OOM handler will not be able to free that memory. -nr_blocks: The same as size, but in blocks of PAGE_CACHE_SIZE. +nr_blocks: The same as size, but in blocks of PAGE_SIZE. nr_inodes: The maximum number of inodes for this instance. The default is half of the number of your physical RAM pages, or (on a machine with highmem) the number of lowmem RAM pages, diff --git a/Documentation/filesystems/vfat.txt b/Documentation/filesystems/vfat.txt index 223c32171dcc2b562ee0995a708e87ba1829cc8c..cf51360e3a9fb795e9b76833b9e487eda47e27f8 100644 --- a/Documentation/filesystems/vfat.txt +++ b/Documentation/filesystems/vfat.txt @@ -56,9 +56,10 @@ iocharset= -- Character set to use for converting between the you should consider the following option instead. utf8= -- UTF-8 is the filesystem safe version of Unicode that - is used by the console. It can be enabled for the - filesystem with this option. If 'uni_xlate' gets set, - UTF-8 gets disabled. + is used by the console. It can be enabled or disabled + for the filesystem with this option. + If 'uni_xlate' gets set, UTF-8 gets disabled. + By default, FAT_DEFAULT_UTF8 setting is used. uni_xlate= -- Translate unhandled Unicode characters to special escaped sequences. This would let you backup and diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index b02a7d598258542e890eae7ab3b4b4503db251e2..4164bd6397a28efc94f5fc3ff3cd22369d84f4d3 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt @@ -708,9 +708,9 @@ struct address_space_operations { from the address space. This generally corresponds to either a truncation, punch hole or a complete invalidation of the address space (in the latter case 'offset' will always be 0 and 'length' - will be PAGE_CACHE_SIZE). Any private data associated with the page + will be PAGE_SIZE). Any private data associated with the page should be updated to reflect this truncation. If offset is 0 and - length is PAGE_CACHE_SIZE, then the private data should be released, + length is PAGE_SIZE, then the private data should be released, because the page must be able to be completely discarded. This may be done by calling the ->releasepage function, but in this case the release MUST succeed. diff --git a/Documentation/infiniband/sysfs.txt b/Documentation/infiniband/sysfs.txt index 9028b025501a6e4fab03a3e4be152c8fbbc6694c..3ecf0c3a133fb6a50cd40b42d0d8b87a2d1c99b9 100644 --- a/Documentation/infiniband/sysfs.txt +++ b/Documentation/infiniband/sysfs.txt @@ -78,9 +78,10 @@ HFI1 chip_reset - diagnostic (root only) boardversion - board version ports/1/ - CMgtA/ + CCMgtA/ cc_settings_bin - CCA tables used by PSM2 cc_table_bin + cc_prescan - enable prescaning for faster BECN response sc2v/ - 32 files (0 - 31) used to translate sl->vl sl2sc/ - 32 files (0 - 31) used to translate sl->sc vl2mtu/ - 16 (0 - 15) files used to determine MTU for vl diff --git a/Documentation/isdn/00-INDEX b/Documentation/isdn/00-INDEX index e87e336f590ef256bb2a2e446a1222328261f700..2d1889b6c1fa8127fdf386042aec1ab5b2a8ab4d 100644 --- a/Documentation/isdn/00-INDEX +++ b/Documentation/isdn/00-INDEX @@ -16,8 +16,6 @@ README.FAQ - general info for FAQ. README.HiSax - info on the HiSax driver which replaces the old teles. -README.act2000 - - info on driver for IBM ACT-2000 card. README.audio - info for running audio over ISDN. README.avmb1 @@ -34,14 +32,8 @@ README.hfc-pci - info on hfc-pci based cards. README.hysdn - info on driver for Hypercope active HYSDN cards -README.icn - - info on the ICN-ISDN-card and its driver. README.mISDN - info on the Modular ISDN subsystem (mISDN) -README.pcbit - - info on the PCBIT-D ISDN adapter and driver. -README.sc - - info on driver for Spellcaster cards. README.syncppp - info on running Sync PPP over ISDN. README.x25 diff --git a/Documentation/kasan.txt b/Documentation/kasan.txt index aa1e0c91e368885ba90e152abd377ce18dd4bdc3..7dd95b35cd7cd2dd17cbbd9bb9db48fc3590d542 100644 --- a/Documentation/kasan.txt +++ b/Documentation/kasan.txt @@ -12,8 +12,7 @@ KASAN uses compile-time instrumentation for checking every memory access, therefore you will need a GCC version 4.9.2 or later. GCC 5.0 or later is required for detection of out-of-bounds accesses to stack or global variables. -Currently KASAN is supported only for x86_64 architecture and requires the -kernel to be built with the SLUB allocator. +Currently KASAN is supported only for x86_64 architecture. 1. Usage ======== @@ -27,7 +26,7 @@ inline are compiler instrumentation types. The former produces smaller binary the latter is 1.1 - 2 times faster. Inline instrumentation requires a GCC version 5.0 or later. -Currently KASAN works only with the SLUB memory allocator. +KASAN works with both SLUB and SLAB memory allocators. For better bug detection and nicer reporting, enable CONFIG_STACKTRACE. To disable instrumentation for specific files or directories, add a line diff --git a/Documentation/kcov.txt b/Documentation/kcov.txt new file mode 100644 index 0000000000000000000000000000000000000000..779ff4ab1c1da09b98bed78b5df76436ad8d316a --- /dev/null +++ b/Documentation/kcov.txt @@ -0,0 +1,111 @@ +kcov: code coverage for fuzzing +=============================== + +kcov exposes kernel code coverage information in a form suitable for coverage- +guided fuzzing (randomized testing). Coverage data of a running kernel is +exported via the "kcov" debugfs file. Coverage collection is enabled on a task +basis, and thus it can capture precise coverage of a single system call. + +Note that kcov does not aim to collect as much coverage as possible. It aims +to collect more or less stable coverage that is function of syscall inputs. +To achieve this goal it does not collect coverage in soft/hard interrupts +and instrumentation of some inherently non-deterministic parts of kernel is +disbled (e.g. scheduler, locking). + +Usage: +====== + +Configure kernel with: + + CONFIG_KCOV=y + +CONFIG_KCOV requires gcc built on revision 231296 or later. +Profiling data will only become accessible once debugfs has been mounted: + + mount -t debugfs none /sys/kernel/debug + +The following program demonstrates kcov usage from within a test program: + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define KCOV_INIT_TRACE _IOR('c', 1, unsigned long) +#define KCOV_ENABLE _IO('c', 100) +#define KCOV_DISABLE _IO('c', 101) +#define COVER_SIZE (64<<10) + +int main(int argc, char **argv) +{ + int fd; + unsigned long *cover, n, i; + + /* A single fd descriptor allows coverage collection on a single + * thread. + */ + fd = open("/sys/kernel/debug/kcov", O_RDWR); + if (fd == -1) + perror("open"), exit(1); + /* Setup trace mode and trace size. */ + if (ioctl(fd, KCOV_INIT_TRACE, COVER_SIZE)) + perror("ioctl"), exit(1); + /* Mmap buffer shared between kernel- and user-space. */ + cover = (unsigned long*)mmap(NULL, COVER_SIZE * sizeof(unsigned long), + PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if ((void*)cover == MAP_FAILED) + perror("mmap"), exit(1); + /* Enable coverage collection on the current thread. */ + if (ioctl(fd, KCOV_ENABLE, 0)) + perror("ioctl"), exit(1); + /* Reset coverage from the tail of the ioctl() call. */ + __atomic_store_n(&cover[0], 0, __ATOMIC_RELAXED); + /* That's the target syscal call. */ + read(-1, NULL, 0); + /* Read number of PCs collected. */ + n = __atomic_load_n(&cover[0], __ATOMIC_RELAXED); + for (i = 0; i < n; i++) + printf("0x%lx\n", cover[i + 1]); + /* Disable coverage collection for the current thread. After this call + * coverage can be enabled for a different thread. + */ + if (ioctl(fd, KCOV_DISABLE, 0)) + perror("ioctl"), exit(1); + /* Free resources. */ + if (munmap(cover, COVER_SIZE * sizeof(unsigned long))) + perror("munmap"), exit(1); + if (close(fd)) + perror("close"), exit(1); + return 0; +} + +After piping through addr2line output of the program looks as follows: + +SyS_read +fs/read_write.c:562 +__fdget_pos +fs/file.c:774 +__fget_light +fs/file.c:746 +__fget_light +fs/file.c:750 +__fget_light +fs/file.c:760 +__fdget_pos +fs/file.c:784 +SyS_read +fs/read_write.c:562 + +If a program needs to collect coverage from several threads (independently), +it needs to open /sys/kernel/debug/kcov in each thread separately. + +The interface is fine-grained to allow efficient forking of test processes. +That is, a parent process opens /sys/kernel/debug/kcov, enables trace mode, +mmaps coverage buffer and then forks child processes in a loop. Child processes +only need to enable coverage (disable happens automatically on thread end). diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 0ee46a8f64010f7881b3ecaaa8fe5252cb07186b..ecc74fa4bfde8a55d9fee00d96ae5ae4123560e9 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -614,6 +614,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted. cut the overhead, others just disable the usage. So only cgroup_disable=memory is actually worthy} + cgroup_no_v1= [KNL] Disable one, multiple, all cgroup controllers in v1 + Format: { controller[,controller...] | "all" } + Like cgroup_disable, but only applies to cgroup v1; + the blacklisted controllers remain available in cgroup2. + cgroup.memory= [KNL] Pass options to the cgroup memory controller. Format: nosocket -- Disable socket memory accounting. @@ -982,6 +987,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted. See Documentation/x86/intel_mpx.txt for more information about the feature. + nopku [X86] Disable Memory Protection Keys CPU feature found + in some Intel CPUs. + eagerfpu= [X86] on enable eager fpu restore off disable eager fpu restore @@ -2615,7 +2623,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted. nolapic_timer [X86-32,APIC] Do not use the local APIC timer. noltlbs [PPC] Do not use large page/tlb entries for kernel - lowmem mapping on PPC40x. + lowmem mapping on PPC40x and PPC8xx nomca [IA-64] Disable machine check abort handling diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt index 904ee42d078e51d8b43fe6548611219c2c0444c0..3729cbe60e4169340b5bc522951d9e0f40c4cb46 100644 --- a/Documentation/memory-barriers.txt +++ b/Documentation/memory-barriers.txt @@ -232,7 +232,7 @@ And there are a number of things that _must_ or _must_not_ be assumed: with memory references that are not protected by READ_ONCE() and WRITE_ONCE(). Without them, the compiler is within its rights to do all sorts of "creative" transformations, which are covered in - the Compiler Barrier section. + the COMPILER BARRIER section. (*) It _must_not_ be assumed that independent loads and stores will be issued in the order given. This means that for: @@ -555,6 +555,30 @@ between the address load and the data load: This enforces the occurrence of one of the two implications, and prevents the third possibility from arising. +A data-dependency barrier must also order against dependent writes: + + CPU 1 CPU 2 + =============== =============== + { A == 1, B == 2, C = 3, P == &A, Q == &C } + B = 4; + + WRITE_ONCE(P, &B); + Q = READ_ONCE(P); + + *Q = 5; + +The data-dependency barrier must order the read into Q with the store +into *Q. This prohibits this outcome: + + (Q == B) && (B == 4) + +Please note that this pattern should be rare. After all, the whole point +of dependency ordering is to -prevent- writes to the data structure, along +with the expensive cache misses associated with those writes. This pattern +can be used to record rare error conditions and the like, and the ordering +prevents such records from being lost. + + [!] Note that this extremely counterintuitive situation arises most easily on machines with split caches, so that, for example, one cache bank processes even-numbered cache lines and the other bank processes odd-numbered cache @@ -565,21 +589,6 @@ odd-numbered bank is idle, one can see the new value of the pointer P (&B), but the old value of the variable B (2). -Another example of where data dependency barriers might be required is where a -number is read from memory and then used to calculate the index for an array -access: - - CPU 1 CPU 2 - =============== =============== - { M[0] == 1, M[1] == 2, M[3] = 3, P == 0, Q == 3 } - M[1] = 4; - - WRITE_ONCE(P, 1); - Q = READ_ONCE(P); - - D = M[Q]; - - The data dependency barrier is very important to the RCU system, for example. See rcu_assign_pointer() and rcu_dereference() in include/linux/rcupdate.h. This permits the current target of an RCU'd @@ -800,9 +809,13 @@ In summary: use smp_rmb(), smp_wmb(), or, in the case of prior stores and later loads, smp_mb(). - (*) If both legs of the "if" statement begin with identical stores - to the same variable, a barrier() statement is required at the - beginning of each leg of the "if" statement. + (*) If both legs of the "if" statement begin with identical stores to + the same variable, then those stores must be ordered, either by + preceding both of them with smp_mb() or by using smp_store_release() + to carry out the stores. Please note that it is -not- sufficient + to use barrier() at beginning of each leg of the "if" statement, + as optimizing compilers do not necessarily respect barrier() + in this case. (*) Control dependencies require at least one run-time conditional between the prior load and the subsequent store, and this @@ -814,7 +827,7 @@ In summary: (*) Control dependencies require that the compiler avoid reordering the dependency into nonexistence. Careful use of READ_ONCE() or atomic{,64}_read() can help to preserve your control dependency. - Please see the Compiler Barrier section for more information. + Please see the COMPILER BARRIER section for more information. (*) Control dependencies pair normally with other types of barriers. @@ -1257,7 +1270,7 @@ TRANSITIVITY Transitivity is a deeply intuitive notion about ordering that is not always provided by real computer systems. The following example -demonstrates transitivity (also called "cumulativity"): +demonstrates transitivity: CPU 1 CPU 2 CPU 3 ======================= ======================= ======================= @@ -1305,8 +1318,86 @@ or a level of cache, CPU 2 might have early access to CPU 1's writes. General barriers are therefore required to ensure that all CPUs agree on the combined order of CPU 1's and CPU 2's accesses. -To reiterate, if your code requires transitivity, use general barriers -throughout. +General barriers provide "global transitivity", so that all CPUs will +agree on the order of operations. In contrast, a chain of release-acquire +pairs provides only "local transitivity", so that only those CPUs on +the chain are guaranteed to agree on the combined order of the accesses. +For example, switching to C code in deference to Herman Hollerith: + + int u, v, x, y, z; + + void cpu0(void) + { + r0 = smp_load_acquire(&x); + WRITE_ONCE(u, 1); + smp_store_release(&y, 1); + } + + void cpu1(void) + { + r1 = smp_load_acquire(&y); + r4 = READ_ONCE(v); + r5 = READ_ONCE(u); + smp_store_release(&z, 1); + } + + void cpu2(void) + { + r2 = smp_load_acquire(&z); + smp_store_release(&x, 1); + } + + void cpu3(void) + { + WRITE_ONCE(v, 1); + smp_mb(); + r3 = READ_ONCE(u); + } + +Because cpu0(), cpu1(), and cpu2() participate in a local transitive +chain of smp_store_release()/smp_load_acquire() pairs, the following +outcome is prohibited: + + r0 == 1 && r1 == 1 && r2 == 1 + +Furthermore, because of the release-acquire relationship between cpu0() +and cpu1(), cpu1() must see cpu0()'s writes, so that the following +outcome is prohibited: + + r1 == 1 && r5 == 0 + +However, the transitivity of release-acquire is local to the participating +CPUs and does not apply to cpu3(). Therefore, the following outcome +is possible: + + r0 == 0 && r1 == 1 && r2 == 1 && r3 == 0 && r4 == 0 + +As an aside, the following outcome is also possible: + + r0 == 0 && r1 == 1 && r2 == 1 && r3 == 0 && r4 == 0 && r5 == 1 + +Although cpu0(), cpu1(), and cpu2() will see their respective reads and +writes in order, CPUs not involved in the release-acquire chain might +well disagree on the order. This disagreement stems from the fact that +the weak memory-barrier instructions used to implement smp_load_acquire() +and smp_store_release() are not required to order prior stores against +subsequent loads in all cases. This means that cpu3() can see cpu0()'s +store to u as happening -after- cpu1()'s load from v, even though +both cpu0() and cpu1() agree that these two operations occurred in the +intended order. + +However, please keep in mind that smp_load_acquire() is not magic. +In particular, it simply reads from its argument with ordering. It does +-not- ensure that any particular value will be read. Therefore, the +following outcome is possible: + + r0 == 0 && r1 == 0 && r2 == 0 && r5 == 0 + +Note that this outcome can happen even on a mythical sequentially +consistent system where nothing is ever reordered. + +To reiterate, if your code requires global transitivity, use general +barriers throughout. ======================== @@ -1459,7 +1550,7 @@ of optimizations: the following: a = 0; - /* Code that does not store to variable a. */ + ... Code that does not store to variable a ... a = 0; The compiler sees that the value of variable 'a' is already zero, so @@ -1471,7 +1562,7 @@ of optimizations: wrong guess: WRITE_ONCE(a, 0); - /* Code that does not store to variable a. */ + ... Code that does not store to variable a ... WRITE_ONCE(a, 0); (*) The compiler is within its rights to reorder memory accesses unless diff --git a/drivers/staging/panel/lcd-panel-cgram.txt b/Documentation/misc-devices/lcd-panel-cgram.txt similarity index 100% rename from drivers/staging/panel/lcd-panel-cgram.txt rename to Documentation/misc-devices/lcd-panel-cgram.txt diff --git a/Documentation/networking/00-INDEX b/Documentation/networking/00-INDEX index df27a1a507767101e8aa203d90ace8d8d5cc55c8..415154a487d072446036a5adab5758311867d9f6 100644 --- a/Documentation/networking/00-INDEX +++ b/Documentation/networking/00-INDEX @@ -44,6 +44,8 @@ can.txt - documentation on CAN protocol family. cdc_mbim.txt - 3G/LTE USB modem (Mobile Broadband Interface Model) +checksum-offloads.txt + - Explanation of checksum offloads; LCO, RCO cops.txt - info on the COPS LocalTalk Linux driver cs89x0.txt diff --git a/Documentation/networking/batman-adv.txt b/Documentation/networking/batman-adv.txt index ff23b755f5e45cc8b6d367f2e55564cdf3a1782d..1b5e7a7f2185be117ba99d3c4303d14671cb9840 100644 --- a/Documentation/networking/batman-adv.txt +++ b/Documentation/networking/batman-adv.txt @@ -187,7 +187,7 @@ interfaces to the kernel module settings. For more information, please see the manpage (man batctl). -batctl is available on http://www.open-mesh.org/ +batctl is available on https://www.open-mesh.org/ CONTACT diff --git a/Documentation/networking/checksum-offloads.txt b/Documentation/networking/checksum-offloads.txt new file mode 100644 index 0000000000000000000000000000000000000000..de2a327766a7ed2285b65cf4023c214205f47e70 --- /dev/null +++ b/Documentation/networking/checksum-offloads.txt @@ -0,0 +1,119 @@ +Checksum Offloads in the Linux Networking Stack + + +Introduction +============ + +This document describes a set of techniques in the Linux networking stack + to take advantage of checksum offload capabilities of various NICs. + +The following technologies are described: + * TX Checksum Offload + * LCO: Local Checksum Offload + * RCO: Remote Checksum Offload + +Things that should be documented here but aren't yet: + * RX Checksum Offload + * CHECKSUM_UNNECESSARY conversion + + +TX Checksum Offload +=================== + +The interface for offloading a transmit checksum to a device is explained + in detail in comments near the top of include/linux/skbuff.h. +In brief, it allows to request the device fill in a single ones-complement + checksum defined by the sk_buff fields skb->csum_start and + skb->csum_offset. The device should compute the 16-bit ones-complement + checksum (i.e. the 'IP-style' checksum) from csum_start to the end of the + packet, and fill in the result at (csum_start + csum_offset). +Because csum_offset cannot be negative, this ensures that the previous + value of the checksum field is included in the checksum computation, thus + it can be used to supply any needed corrections to the checksum (such as + the sum of the pseudo-header for UDP or TCP). +This interface only allows a single checksum to be offloaded. Where + encapsulation is used, the packet may have multiple checksum fields in + different header layers, and the rest will have to be handled by another + mechanism such as LCO or RCO. +No offloading of the IP header checksum is performed; it is always done in + software. This is OK because when we build the IP header, we obviously + have it in cache, so summing it isn't expensive. It's also rather short. +The requirements for GSO are more complicated, because when segmenting an + encapsulated packet both the inner and outer checksums may need to be + edited or recomputed for each resulting segment. See the skbuff.h comment + (section 'E') for more details. + +A driver declares its offload capabilities in netdev->hw_features; see + Documentation/networking/netdev-features for more. Note that a device + which only advertises NETIF_F_IP[V6]_CSUM must still obey the csum_start + and csum_offset given in the SKB; if it tries to deduce these itself in + hardware (as some NICs do) the driver should check that the values in the + SKB match those which the hardware will deduce, and if not, fall back to + checksumming in software instead (with skb_checksum_help or one of the + skb_csum_off_chk* functions as mentioned in include/linux/skbuff.h). This + is a pain, but that's what you get when hardware tries to be clever. + +The stack should, for the most part, assume that checksum offload is + supported by the underlying device. The only place that should check is + validate_xmit_skb(), and the functions it calls directly or indirectly. + That function compares the offload features requested by the SKB (which + may include other offloads besides TX Checksum Offload) and, if they are + not supported or enabled on the device (determined by netdev->features), + performs the corresponding offload in software. In the case of TX + Checksum Offload, that means calling skb_checksum_help(skb). + + +LCO: Local Checksum Offload +=========================== + +LCO is a technique for efficiently computing the outer checksum of an + encapsulated datagram when the inner checksum is due to be offloaded. +The ones-complement sum of a correctly checksummed TCP or UDP packet is + equal to the sum of the pseudo header, because everything else gets + 'cancelled out' by the checksum field. This is because the sum was + complemented before being written to the checksum field. +More generally, this holds in any case where the 'IP-style' ones complement + checksum is used, and thus any checksum that TX Checksum Offload supports. +That is, if we have set up TX Checksum Offload with a start/offset pair, we + know that _after the device has filled in that checksum_, the ones + complement sum from csum_start to the end of the packet will be equal to + _whatever value we put in the checksum field beforehand_. This allows us + to compute the outer checksum without looking at the payload: we simply + stop summing when we get to csum_start, then add the 16-bit word at + (csum_start + csum_offset). +Then, when the true inner checksum is filled in (either by hardware or by + skb_checksum_help()), the outer checksum will become correct by virtue of + the arithmetic. + +LCO is performed by the stack when constructing an outer UDP header for an + encapsulation such as VXLAN or GENEVE, in udp_set_csum(). Similarly for + the IPv6 equivalents, in udp6_set_csum(). +It is also performed when constructing an IPv4 GRE header, in + net/ipv4/ip_gre.c:build_header(). It is *not* currently performed when + constructing an IPv6 GRE header; the GRE checksum is computed over the + whole packet in net/ipv6/ip6_gre.c:ip6gre_xmit2(), but it should be + possible to use LCO here as IPv6 GRE still uses an IP-style checksum. +All of the LCO implementations use a helper function lco_csum(), in + include/linux/skbuff.h. + +LCO can safely be used for nested encapsulations; in this case, the outer + encapsulation layer will sum over both its own header and the 'middle' + header. This does mean that the 'middle' header will get summed multiple + times, but there doesn't seem to be a way to avoid that without incurring + bigger costs (e.g. in SKB bloat). + + +RCO: Remote Checksum Offload +============================ + +RCO is a technique for eliding the inner checksum of an encapsulated + datagram, allowing the outer checksum to be offloaded. It does, however, + involve a change to the encapsulation protocols, which the receiver must + also support. For this reason, it is disabled by default. +RCO is detailed in the following Internet-Drafts: +https://tools.ietf.org/html/draft-herbert-remotecsumoffload-00 +https://tools.ietf.org/html/draft-herbert-vxlan-rco-00 +In Linux, RCO is implemented individually in each encapsulation protocol, + and most tunnel types have flags controlling its use. For instance, VXLAN + has the flag VXLAN_F_REMCSUM_TX (per struct vxlan_rdst) to indicate that + RCO should be used when transmitting to a given remote destination. diff --git a/Documentation/networking/dsa/dsa.txt b/Documentation/networking/dsa/dsa.txt index aa9c1f9313cda7edf9f6a73dcf0e17cd44eb0574..3b196c304b73242ca17912ba931e878712c5b3c0 100644 --- a/Documentation/networking/dsa/dsa.txt +++ b/Documentation/networking/dsa/dsa.txt @@ -521,20 +521,17 @@ See Documentation/hwmon/sysfs-interface for details. Bridge layer ------------ -- port_join_bridge: bridge layer function invoked when a given switch port is +- port_bridge_join: bridge layer function invoked when a given switch port is added to a bridge, this function should be doing the necessary at the switch level to permit the joining port from being added to the relevant logical - domain for it to ingress/egress traffic with other members of the bridge. DSA - does nothing but calculate a bitmask of switch ports currently members of the - specified bridge being requested the join + domain for it to ingress/egress traffic with other members of the bridge. -- port_leave_bridge: bridge layer function invoked when a given switch port is +- port_bridge_leave: bridge layer function invoked when a given switch port is removed from a bridge, this function should be doing the necessary at the switch level to deny the leaving port from ingress/egress traffic from the remaining bridge members. When the port leaves the bridge, it should be aged out at the switch hardware for the switch to (re) learn MAC addresses behind - this port. DSA calculates the bitmask of ports still members of the bridge - being left + this port. - port_stp_update: bridge layer function invoked when a given switch port STP state is computed by the bridge layer and should be propagated to switch @@ -545,20 +542,15 @@ Bridge layer Bridge VLAN filtering --------------------- -- port_pvid_get: bridge layer function invoked when a Port-based VLAN ID is - queried for the given switch port - -- port_pvid_set: bridge layer function invoked when a Port-based VLAN ID needs - to be configured on the given switch port - - port_vlan_add: bridge layer function invoked when a VLAN is configured (tagged or untagged) for the given switch port - port_vlan_del: bridge layer function invoked when a VLAN is removed from the given switch port -- vlan_getnext: bridge layer function invoked to query the next configured VLAN - in the switch, i.e. returns the bitmaps of members and untagged ports +- port_vlan_dump: bridge layer function invoked with a switchdev callback + function that the driver has to call for each VLAN the given port is a member + of. A switchdev object is used to carry the VID and bridge flags. - port_fdb_add: bridge layer function invoked when the bridge wants to install a Forwarding Database entry, the switch hardware should be programmed with the diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 73b36d7c7b0d67309cce7bf0bd8a46f0c6ee7ea1..b183e2b606c8a8e39ea8ce9a95857b60224d139d 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -946,15 +946,20 @@ igmp_max_memberships - INTEGER The value 5459 assumes no IP header options, so in practice this number may be lower. - conf/interface/* changes special settings per interface (where - "interface" is the name of your network interface) - - conf/all/* is special, changes the settings for all interfaces +igmp_max_msf - INTEGER + Maximum number of addresses allowed in the source filter list for a + multicast group. + Default: 10 igmp_qrv - INTEGER - Controls the IGMP query robustness variable (see RFC2236 8.1). - Default: 2 (as specified by RFC2236 8.1) - Minimum: 1 (as specified by RFC6636 4.5) + Controls the IGMP query robustness variable (see RFC2236 8.1). + Default: 2 (as specified by RFC2236 8.1) + Minimum: 1 (as specified by RFC6636 4.5) + +conf/interface/* changes special settings per interface (where +"interface" is the name of your network interface) + +conf/all/* is special, changes the settings for all interfaces log_martians - BOOLEAN Log packets with impossible addresses to kernel log. @@ -1216,6 +1221,19 @@ promote_secondaries - BOOLEAN promote a corresponding secondary IP address instead of removing all the corresponding secondary IP addresses. +drop_unicast_in_l2_multicast - BOOLEAN + Drop any unicast IP packets that are received in link-layer + multicast (or broadcast) frames. + This behavior (for multicast) is actually a SHOULD in RFC + 1122, but is disabled by default for compatibility reasons. + Default: off (0) + +drop_gratuitous_arp - BOOLEAN + Drop all gratuitous ARP frames, for example if there's a known + good ARP proxy on the network and such frames need not be used + (or in the case of 802.11, must not be used to prevent attacks.) + Default: off (0) + tag - INTEGER Allows you to write a number, which can be used as required. @@ -1550,6 +1568,15 @@ temp_prefered_lft - INTEGER Preferred lifetime (in seconds) for temporary addresses. Default: 86400 (1 day) +keep_addr_on_down - INTEGER + Keep all IPv6 addresses on an interface down event. If set static + global addresses with no expiration time are not flushed. + >0 : enabled + 0 : system default + <0 : disabled + + Default: 0 (addresses are removed) + max_desync_factor - INTEGER Maximum value for DESYNC_FACTOR, which is a random value that ensures that clients don't synchronize with each @@ -1661,6 +1688,19 @@ stable_secret - IPv6 address By default the stable secret is unset. +drop_unicast_in_l2_multicast - BOOLEAN + Drop any unicast IPv6 packets that are received in link-layer + multicast (or broadcast) frames. + + By default this is turned off. + +drop_unsolicited_na - BOOLEAN + Drop all unsolicited neighbor advertisements, for example if there's + a known good NA proxy on the network and such frames need not be used + (or in the case of 802.11, must not be used to prevent attacks.) + + By default this is turned off. + icmp/*: ratelimit - INTEGER Limit the maximal rates for sending ICMPv6 packets. diff --git a/Documentation/networking/kcm.txt b/Documentation/networking/kcm.txt new file mode 100644 index 0000000000000000000000000000000000000000..3476ede5bc2c9431a6dc5d1027345f05da54c594 --- /dev/null +++ b/Documentation/networking/kcm.txt @@ -0,0 +1,285 @@ +Kernel Connection Mulitplexor +----------------------------- + +Kernel Connection Multiplexor (KCM) is a mechanism that provides a message based +interface over TCP for generic application protocols. With KCM an application +can efficiently send and receive application protocol messages over TCP using +datagram sockets. + +KCM implements an NxM multiplexor in the kernel as diagrammed below: + ++------------+ +------------+ +------------+ +------------+ +| KCM socket | | KCM socket | | KCM socket | | KCM socket | ++------------+ +------------+ +------------+ +------------+ + | | | | + +-----------+ | | +----------+ + | | | | + +----------------------------------+ + | Multiplexor | + +----------------------------------+ + | | | | | + +---------+ | | | ------------+ + | | | | | ++----------+ +----------+ +----------+ +----------+ +----------+ +| Psock | | Psock | | Psock | | Psock | | Psock | ++----------+ +----------+ +----------+ +----------+ +----------+ + | | | | | ++----------+ +----------+ +----------+ +----------+ +----------+ +| TCP sock | | TCP sock | | TCP sock | | TCP sock | | TCP sock | ++----------+ +----------+ +----------+ +----------+ +----------+ + +KCM sockets +----------- + +The KCM sockets provide the user interface to the muliplexor. All the KCM sockets +bound to a multiplexor are considered to have equivalent function, and I/O +operations in different sockets may be done in parallel without the need for +synchronization between threads in userspace. + +Multiplexor +----------- + +The multiplexor provides the message steering. In the transmit path, messages +written on a KCM socket are sent atomically on an appropriate TCP socket. +Similarly, in the receive path, messages are constructed on each TCP socket +(Psock) and complete messages are steered to a KCM socket. + +TCP sockets & Psocks +-------------------- + +TCP sockets may be bound to a KCM multiplexor. A Psock structure is allocated +for each bound TCP socket, this structure holds the state for constructing +messages on receive as well as other connection specific information for KCM. + +Connected mode semantics +------------------------ + +Each multiplexor assumes that all attached TCP connections are to the same +destination and can use the different connections for load balancing when +transmitting. The normal send and recv calls (include sendmmsg and recvmmsg) +can be used to send and receive messages from the KCM socket. + +Socket types +------------ + +KCM supports SOCK_DGRAM and SOCK_SEQPACKET socket types. + +Message delineation +------------------- + +Messages are sent over a TCP stream with some application protocol message +format that typically includes a header which frames the messages. The length +of a received message can be deduced from the application protocol header +(often just a simple length field). + +A TCP stream must be parsed to determine message boundaries. Berkeley Packet +Filter (BPF) is used for this. When attaching a TCP socket to a multiplexor a +BPF program must be specified. The program is called at the start of receiving +a new message and is given an skbuff that contains the bytes received so far. +It parses the message header and returns the length of the message. Given this +information, KCM will construct the message of the stated length and deliver it +to a KCM socket. + +TCP socket management +--------------------- + +When a TCP socket is attached to a KCM multiplexor data ready (POLLIN) and +write space available (POLLOUT) events are handled by the multiplexor. If there +is a state change (disconnection) or other error on a TCP socket, an error is +posted on the TCP socket so that a POLLERR event happens and KCM discontinues +using the socket. When the application gets the error notification for a +TCP socket, it should unattach the socket from KCM and then handle the error +condition (the typical response is to close the socket and create a new +connection if necessary). + +KCM limits the maximum receive message size to be the size of the receive +socket buffer on the attached TCP socket (the socket buffer size can be set by +SO_RCVBUF). If the length of a new message reported by the BPF program is +greater than this limit a corresponding error (EMSGSIZE) is posted on the TCP +socket. The BPF program may also enforce a maximum messages size and report an +error when it is exceeded. + +A timeout may be set for assembling messages on a receive socket. The timeout +value is taken from the receive timeout of the attached TCP socket (this is set +by SO_RCVTIMEO). If the timer expires before assembly is complete an error +(ETIMEDOUT) is posted on the socket. + +User interface +============== + +Creating a multiplexor +---------------------- + +A new multiplexor and initial KCM socket is created by a socket call: + + socket(AF_KCM, type, protocol) + + - type is either SOCK_DGRAM or SOCK_SEQPACKET + - protocol is KCMPROTO_CONNECTED + +Cloning KCM sockets +------------------- + +After the first KCM socket is created using the socket call as described +above, additional sockets for the multiplexor can be created by cloning +a KCM socket. This is accomplished by an ioctl on a KCM socket: + + /* From linux/kcm.h */ + struct kcm_clone { + int fd; + }; + + struct kcm_clone info; + + memset(&info, 0, sizeof(info)); + + err = ioctl(kcmfd, SIOCKCMCLONE, &info); + + if (!err) + newkcmfd = info.fd; + +Attach transport sockets +------------------------ + +Attaching of transport sockets to a multiplexor is performed by calling an +ioctl on a KCM socket for the multiplexor. e.g.: + + /* From linux/kcm.h */ + struct kcm_attach { + int fd; + int bpf_fd; + }; + + struct kcm_attach info; + + memset(&info, 0, sizeof(info)); + + info.fd = tcpfd; + info.bpf_fd = bpf_prog_fd; + + ioctl(kcmfd, SIOCKCMATTACH, &info); + +The kcm_attach structure contains: + fd: file descriptor for TCP socket being attached + bpf_prog_fd: file descriptor for compiled BPF program downloaded + +Unattach transport sockets +-------------------------- + +Unattaching a transport socket from a multiplexor is straightforward. An +"unattach" ioctl is done with the kcm_unattach structure as the argument: + + /* From linux/kcm.h */ + struct kcm_unattach { + int fd; + }; + + struct kcm_unattach info; + + memset(&info, 0, sizeof(info)); + + info.fd = cfd; + + ioctl(fd, SIOCKCMUNATTACH, &info); + +Disabling receive on KCM socket +------------------------------- + +A setsockopt is used to disable or enable receiving on a KCM socket. +When receive is disabled, any pending messages in the socket's +receive buffer are moved to other sockets. This feature is useful +if an application thread knows that it will be doing a lot of +work on a request and won't be able to service new messages for a +while. Example use: + + int val = 1; + + setsockopt(kcmfd, SOL_KCM, KCM_RECV_DISABLE, &val, sizeof(val)) + +BFP programs for message delineation +------------------------------------ + +BPF programs can be compiled using the BPF LLVM backend. For exmple, +the BPF program for parsing Thrift is: + + #include "bpf.h" /* for __sk_buff */ + #include "bpf_helpers.h" /* for load_word intrinsic */ + + SEC("socket_kcm") + int bpf_prog1(struct __sk_buff *skb) + { + return load_word(skb, 0) + 4; + } + + char _license[] SEC("license") = "GPL"; + +Use in applications +=================== + +KCM accelerates application layer protocols. Specifically, it allows +applications to use a message based interface for sending and receiving +messages. The kernel provides necessary assurances that messages are sent +and received atomically. This relieves much of the burden applications have +in mapping a message based protocol onto the TCP stream. KCM also make +application layer messages a unit of work in the kernel for the purposes of +steerng and scheduling, which in turn allows a simpler networking model in +multithreaded applications. + +Configurations +-------------- + +In an Nx1 configuration, KCM logically provides multiple socket handles +to the same TCP connection. This allows parallelism between in I/O +operations on the TCP socket (for instance copyin and copyout of data is +parallelized). In an application, a KCM socket can be opened for each +processing thread and inserted into the epoll (similar to how SO_REUSEPORT +is used to allow multiple listener sockets on the same port). + +In a MxN configuration, multiple connections are established to the +same destination. These are used for simple load balancing. + +Message batching +---------------- + +The primary purpose of KCM is load balancing between KCM sockets and hence +threads in a nominal use case. Perfect load balancing, that is steering +each received message to a different KCM socket or steering each sent +message to a different TCP socket, can negatively impact performance +since this doesn't allow for affinities to be established. Balancing +based on groups, or batches of messages, can be beneficial for performance. + +On transmit, there are three ways an application can batch (pipeline) +messages on a KCM socket. + 1) Send multiple messages in a single sendmmsg. + 2) Send a group of messages each with a sendmsg call, where all messages + except the last have MSG_BATCH in the flags of sendmsg call. + 3) Create "super message" composed of multiple messages and send this + with a single sendmsg. + +On receive, the KCM module attempts to queue messages received on the +same KCM socket during each TCP ready callback. The targeted KCM socket +changes at each receive ready callback on the KCM socket. The application +does not need to configure this. + +Error handling +-------------- + +An application should include a thread to monitor errors raised on +the TCP connection. Normally, this will be done by placing each +TCP socket attached to a KCM multiplexor in epoll set for POLLERR +event. If an error occurs on an attached TCP socket, KCM sets an EPIPE +on the socket thus waking up the application thread. When the application +sees the error (which may just be a disconnect) it should unattach the +socket from KCM and then close it. It is assumed that once an error is +posted on the TCP socket the data stream is unrecoverable (i.e. an error +may have occurred in in the middle of receiving a messssge). + +TCP connection monitoring +------------------------- + +In KCM there is no means to correlate a message to the TCP socket that +was used to send or receive the message (except in the case there is +only one attached TCP socket). However, the application does retain +an open file descriptor to the socket so it will be able to get statistics +from the socket which can be used in detecting issues (such as high +retransmissions on the socket). diff --git a/Documentation/networking/mac80211-injection.txt b/Documentation/networking/mac80211-injection.txt index 3a930072b161fd51b3b1d007daac673526609dc2..ec8f934c2eb240f93a54b0044faadd913e7855f8 100644 --- a/Documentation/networking/mac80211-injection.txt +++ b/Documentation/networking/mac80211-injection.txt @@ -28,6 +28,23 @@ radiotap headers and used to control injection: IEEE80211_RADIOTAP_F_TX_NOACK: frame should be sent without waiting for an ACK even if it is a unicast frame + * IEEE80211_RADIOTAP_RATE + + legacy rate for the transmission (only for devices without own rate control) + + * IEEE80211_RADIOTAP_MCS + + HT rate for the transmission (only for devices without own rate control). + Also some flags are parsed + + IEEE80211_TX_RC_SHORT_GI: use short guard interval + IEEE80211_TX_RC_40_MHZ_WIDTH: send in HT40 mode + + * IEEE80211_RADIOTAP_DATA_RETRIES + + number of retries when either IEEE80211_RADIOTAP_RATE or + IEEE80211_RADIOTAP_MCS was used + The injection code can also skip all other currently defined radiotap fields facilitating replay of captured radiotap headers directly. diff --git a/Documentation/networking/netlink_mmap.txt b/Documentation/networking/netlink_mmap.txt deleted file mode 100644 index 54f10478e8e30ccda77da9d345c01b9ace781e07..0000000000000000000000000000000000000000 --- a/Documentation/networking/netlink_mmap.txt +++ /dev/null @@ -1,332 +0,0 @@ -This file documents how to use memory mapped I/O with netlink. - -Author: Patrick McHardy - -Overview --------- - -Memory mapped netlink I/O can be used to increase throughput and decrease -overhead of unicast receive and transmit operations. Some netlink subsystems -require high throughput, these are mainly the netfilter subsystems -nfnetlink_queue and nfnetlink_log, but it can also help speed up large -dump operations of f.i. the routing database. - -Memory mapped netlink I/O used two circular ring buffers for RX and TX which -are mapped into the processes address space. - -The RX ring is used by the kernel to directly construct netlink messages into -user-space memory without copying them as done with regular socket I/O, -additionally as long as the ring contains messages no recvmsg() or poll() -syscalls have to be issued by user-space to get more message. - -The TX ring is used to process messages directly from user-space memory, the -kernel processes all messages contained in the ring using a single sendmsg() -call. - -Usage overview --------------- - -In order to use memory mapped netlink I/O, user-space needs three main changes: - -- ring setup -- conversion of the RX path to get messages from the ring instead of recvmsg() -- conversion of the TX path to construct messages into the ring - -Ring setup is done using setsockopt() to provide the ring parameters to the -kernel, then a call to mmap() to map the ring into the processes address space: - -- setsockopt(fd, SOL_NETLINK, NETLINK_RX_RING, ¶ms, sizeof(params)); -- setsockopt(fd, SOL_NETLINK, NETLINK_TX_RING, ¶ms, sizeof(params)); -- ring = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0) - -Usage of either ring is optional, but even if only the RX ring is used the -mapping still needs to be writable in order to update the frame status after -processing. - -Conversion of the reception path involves calling poll() on the file -descriptor, once the socket is readable the frames from the ring are -processed in order until no more messages are available, as indicated by -a status word in the frame header. - -On kernel side, in order to make use of memory mapped I/O on receive, the -originating netlink subsystem needs to support memory mapped I/O, otherwise -it will use an allocated socket buffer as usual and the contents will be - copied to the ring on transmission, nullifying most of the performance gains. -Dumps of kernel databases automatically support memory mapped I/O. - -Conversion of the transmit path involves changing message construction to -use memory from the TX ring instead of (usually) a buffer declared on the -stack and setting up the frame header appropriately. Optionally poll() can -be used to wait for free frames in the TX ring. - -Structured and definitions for using memory mapped I/O are contained in -. - -RX and TX rings ----------------- - -Each ring contains a number of continuous memory blocks, containing frames of -fixed size dependent on the parameters used for ring setup. - -Ring: [ block 0 ] - [ frame 0 ] - [ frame 1 ] - [ block 1 ] - [ frame 2 ] - [ frame 3 ] - ... - [ block n ] - [ frame 2 * n ] - [ frame 2 * n + 1 ] - -The blocks are only visible to the kernel, from the point of view of user-space -the ring just contains the frames in a continuous memory zone. - -The ring parameters used for setting up the ring are defined as follows: - -struct nl_mmap_req { - unsigned int nm_block_size; - unsigned int nm_block_nr; - unsigned int nm_frame_size; - unsigned int nm_frame_nr; -}; - -Frames are grouped into blocks, where each block is a continuous region of memory -and holds nm_block_size / nm_frame_size frames. The total number of frames in -the ring is nm_frame_nr. The following invariants hold: - -- frames_per_block = nm_block_size / nm_frame_size - -- nm_frame_nr = frames_per_block * nm_block_nr - -Some parameters are constrained, specifically: - -- nm_block_size must be a multiple of the architectures memory page size. - The getpagesize() function can be used to get the page size. - -- nm_frame_size must be equal or larger to NL_MMAP_HDRLEN, IOW a frame must be - able to hold at least the frame header - -- nm_frame_size must be smaller or equal to nm_block_size - -- nm_frame_size must be a multiple of NL_MMAP_MSG_ALIGNMENT - -- nm_frame_nr must equal the actual number of frames as specified above. - -When the kernel can't allocate physically continuous memory for a ring block, -it will fall back to use physically discontinuous memory. This might affect -performance negatively, in order to avoid this the nm_frame_size parameter -should be chosen to be as small as possible for the required frame size and -the number of blocks should be increased instead. - -Ring frames ------------- - -Each frames contain a frame header, consisting of a synchronization word and some -meta-data, and the message itself. - -Frame: [ header message ] - -The frame header is defined as follows: - -struct nl_mmap_hdr { - unsigned int nm_status; - unsigned int nm_len; - __u32 nm_group; - /* credentials */ - __u32 nm_pid; - __u32 nm_uid; - __u32 nm_gid; -}; - -- nm_status is used for synchronizing processing between the kernel and user- - space and specifies ownership of the frame as well as the operation to perform - -- nm_len contains the length of the message contained in the data area - -- nm_group specified the destination multicast group of message - -- nm_pid, nm_uid and nm_gid contain the netlink pid, UID and GID of the sending - process. These values correspond to the data available using SOCK_PASSCRED in - the SCM_CREDENTIALS cmsg. - -The possible values in the status word are: - -- NL_MMAP_STATUS_UNUSED: - RX ring: frame belongs to the kernel and contains no message - for user-space. Approriate action is to invoke poll() - to wait for new messages. - - TX ring: frame belongs to user-space and can be used for - message construction. - -- NL_MMAP_STATUS_RESERVED: - RX ring only: frame is currently used by the kernel for message - construction and contains no valid message yet. - Appropriate action is to invoke poll() to wait for - new messages. - -- NL_MMAP_STATUS_VALID: - RX ring: frame contains a valid message. Approriate action is - to process the message and release the frame back to - the kernel by setting the status to - NL_MMAP_STATUS_UNUSED or queue the frame by setting the - status to NL_MMAP_STATUS_SKIP. - - TX ring: the frame contains a valid message from user-space to - be processed by the kernel. After completing processing - the kernel will release the frame back to user-space by - setting the status to NL_MMAP_STATUS_UNUSED. - -- NL_MMAP_STATUS_COPY: - RX ring only: a message is ready to be processed but could not be - stored in the ring, either because it exceeded the - frame size or because the originating subsystem does - not support memory mapped I/O. Appropriate action is - to invoke recvmsg() to receive the message and release - the frame back to the kernel by setting the status to - NL_MMAP_STATUS_UNUSED. - -- NL_MMAP_STATUS_SKIP: - RX ring only: user-space queued the message for later processing, but - processed some messages following it in the ring. The - kernel should skip this frame when looking for unused - frames. - -The data area of a frame begins at a offset of NL_MMAP_HDRLEN relative to the -frame header. - -TX limitations --------------- - -As of Jan 2015 the message is always copied from the ring frame to an -allocated buffer due to unresolved security concerns. -See commit 4682a0358639b29cf ("netlink: Always copy on mmap TX."). - -Example -------- - -Ring setup: - - unsigned int block_size = 16 * getpagesize(); - struct nl_mmap_req req = { - .nm_block_size = block_size, - .nm_block_nr = 64, - .nm_frame_size = 16384, - .nm_frame_nr = 64 * block_size / 16384, - }; - unsigned int ring_size; - void *rx_ring, *tx_ring; - - /* Configure ring parameters */ - if (setsockopt(fd, SOL_NETLINK, NETLINK_RX_RING, &req, sizeof(req)) < 0) - exit(1); - if (setsockopt(fd, SOL_NETLINK, NETLINK_TX_RING, &req, sizeof(req)) < 0) - exit(1) - - /* Calculate size of each individual ring */ - ring_size = req.nm_block_nr * req.nm_block_size; - - /* Map RX/TX rings. The TX ring is located after the RX ring */ - rx_ring = mmap(NULL, 2 * ring_size, PROT_READ | PROT_WRITE, - MAP_SHARED, fd, 0); - if ((long)rx_ring == -1L) - exit(1); - tx_ring = rx_ring + ring_size: - -Message reception: - -This example assumes some ring parameters of the ring setup are available. - - unsigned int frame_offset = 0; - struct nl_mmap_hdr *hdr; - struct nlmsghdr *nlh; - unsigned char buf[16384]; - ssize_t len; - - while (1) { - struct pollfd pfds[1]; - - pfds[0].fd = fd; - pfds[0].events = POLLIN | POLLERR; - pfds[0].revents = 0; - - if (poll(pfds, 1, -1) < 0 && errno != -EINTR) - exit(1); - - /* Check for errors. Error handling omitted */ - if (pfds[0].revents & POLLERR) - - - /* If no new messages, poll again */ - if (!(pfds[0].revents & POLLIN)) - continue; - - /* Process all frames */ - while (1) { - /* Get next frame header */ - hdr = rx_ring + frame_offset; - - if (hdr->nm_status == NL_MMAP_STATUS_VALID) { - /* Regular memory mapped frame */ - nlh = (void *)hdr + NL_MMAP_HDRLEN; - len = hdr->nm_len; - - /* Release empty message immediately. May happen - * on error during message construction. - */ - if (len == 0) - goto release; - } else if (hdr->nm_status == NL_MMAP_STATUS_COPY) { - /* Frame queued to socket receive queue */ - len = recv(fd, buf, sizeof(buf), MSG_DONTWAIT); - if (len <= 0) - break; - nlh = buf; - } else - /* No more messages to process, continue polling */ - break; - - process_msg(nlh); -release: - /* Release frame back to the kernel */ - hdr->nm_status = NL_MMAP_STATUS_UNUSED; - - /* Advance frame offset to next frame */ - frame_offset = (frame_offset + frame_size) % ring_size; - } - } - -Message transmission: - -This example assumes some ring parameters of the ring setup are available. -A single message is constructed and transmitted, to send multiple messages -at once they would be constructed in consecutive frames before a final call -to sendto(). - - unsigned int frame_offset = 0; - struct nl_mmap_hdr *hdr; - struct nlmsghdr *nlh; - struct sockaddr_nl addr = { - .nl_family = AF_NETLINK, - }; - - hdr = tx_ring + frame_offset; - if (hdr->nm_status != NL_MMAP_STATUS_UNUSED) - /* No frame available. Use poll() to avoid. */ - exit(1); - - nlh = (void *)hdr + NL_MMAP_HDRLEN; - - /* Build message */ - build_message(nlh); - - /* Fill frame header: length and status need to be set */ - hdr->nm_len = nlh->nlmsg_len; - hdr->nm_status = NL_MMAP_STATUS_VALID; - - if (sendto(fd, NULL, 0, 0, &addr, sizeof(addr)) < 0) - exit(1); - - /* Advance frame offset to next frame */ - frame_offset = (frame_offset + frame_size) % ring_size; diff --git a/Documentation/networking/phy.txt b/Documentation/networking/phy.txt index e839e7efc835c548e869cbda2e55850245b979b9..7ab9404a8412088cc9bc9446ea833779b9284697 100644 --- a/Documentation/networking/phy.txt +++ b/Documentation/networking/phy.txt @@ -267,13 +267,23 @@ Writing a PHY driver config_intr: Enable or disable interrupts remove: Does any driver take-down ts_info: Queries about the HW timestamping status + match_phy_device: used for Clause 45 capable PHYs to match devices + in package and ensure they are compatible hwtstamp: Set the PHY HW timestamping configuration rxtstamp: Requests a receive timestamp at the PHY level for a 'skb' txtsamp: Requests a transmit timestamp at the PHY level for a 'skb' set_wol: Enable Wake-on-LAN at the PHY level get_wol: Get the Wake-on-LAN status at the PHY level + link_change_notify: called to inform the core is about to change the + link state, can be used to work around bogus PHY between state changes read_mmd_indirect: Read PHY MMD indirect register write_mmd_indirect: Write PHY MMD indirect register + module_info: Get the size and type of an EEPROM contained in an plug-in + module + module_eeprom: Get EEPROM information of a plug-in module + get_sset_count: Get number of strings sets that get_strings will count + get_strings: Get strings from requested objects (statistics) + get_stats: Get the extended statistics from the PHY device Of these, only config_aneg and read_status are required to be assigned by the driver code. The rest are optional. Also, it is diff --git a/Documentation/networking/rds.txt b/Documentation/networking/rds.txt index e1a3d59bbe0f5f7e75889776dfb0979a7ef20cff..9d219d856d46bf3235ce99c40e3a26454c51adfc 100644 --- a/Documentation/networking/rds.txt +++ b/Documentation/networking/rds.txt @@ -19,9 +19,7 @@ to N*N if you use a connection-oriented socket transport like TCP. RDS is not Infiniband-specific; it was designed to support different transports. The current implementation used to support RDS over TCP as well -as IB. Work is in progress to support RDS over iWARP, and using DCE to -guarantee no dropped packets on Ethernet, it may be possible to use RDS over -UDP in the future. +as IB. The high-level semantics of RDS from the application's point of view are diff --git a/Documentation/networking/switchdev.txt b/Documentation/networking/switchdev.txt index fad63136ee3eb8ecf5ad013da54b4013fc9c6e10..2f659129694bd59e685792abb568e80ad477e7da 100644 --- a/Documentation/networking/switchdev.txt +++ b/Documentation/networking/switchdev.txt @@ -386,7 +386,7 @@ used. First phase is to "prepare" anything needed, including various checks, memory allocation, etc. The goal is to handle the stuff that is not unlikely to fail here. The second phase is to "commit" the actual changes. -Switchdev provides an inftrastructure for sharing items (for example memory +Switchdev provides an infrastructure for sharing items (for example memory allocations) between the two phases. The object created by a driver in "prepare" phase and it is queued up by: diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt index 7328cf85236c2b2bc5a4c078dc9f81f2e3febd11..1fd1fbe9ce95adf9b37109cfea9833d586fcfffe 100644 --- a/Documentation/power/runtime_pm.txt +++ b/Documentation/power/runtime_pm.txt @@ -586,6 +586,10 @@ drivers to make their ->remove() callbacks avoid races with runtime PM directly, but also it allows of more flexibility in the handling of devices during the removal of their drivers. +Drivers in ->remove() callback should undo the runtime PM changes done +in ->probe(). Usually this means calling pm_runtime_disable(), +pm_runtime_dont_use_autosuspend() etc. + The user space can effectively disallow the driver of the device to power manage it at run time by changing the value of its /sys/devices/.../power/control attribute to "on", which causes pm_runtime_forbid() to be called. In principle, diff --git a/Documentation/powerpc/cxl.txt b/Documentation/powerpc/cxl.txt index 205c1b81625c3175aa4cb99865e1033d181dd19b..d5506ba0fef718559ef7f2d4d60669a93e6d44e9 100644 --- a/Documentation/powerpc/cxl.txt +++ b/Documentation/powerpc/cxl.txt @@ -116,6 +116,8 @@ Work Element Descriptor (WED) User API ======== +1. AFU character devices + For AFUs operating in AFU directed mode, two character device files will be created. /dev/cxl/afu0.0m will correspond to a master context and /dev/cxl/afu0.0s will correspond to a slave @@ -362,6 +364,59 @@ read reserved fields: For future extensions and padding + +2. Card character device (powerVM guest only) + + In a powerVM guest, an extra character device is created for the + card. The device is only used to write (flash) a new image on the + FPGA accelerator. Once the image is written and verified, the + device tree is updated and the card is reset to reload the updated + image. + +open +---- + + Opens the device and allocates a file descriptor to be used with + the rest of the API. The device can only be opened once. + +ioctl +----- + +CXL_IOCTL_DOWNLOAD_IMAGE: +CXL_IOCTL_VALIDATE_IMAGE: + Starts and controls flashing a new FPGA image. Partial + reconfiguration is not supported (yet), so the image must contain + a copy of the PSL and AFU(s). Since an image can be quite large, + the caller may have to iterate, splitting the image in smaller + chunks. + + Takes a pointer to a struct cxl_adapter_image: + struct cxl_adapter_image { + __u64 flags; + __u64 data; + __u64 len_data; + __u64 len_image; + __u64 reserved1; + __u64 reserved2; + __u64 reserved3; + __u64 reserved4; + }; + + flags: + These flags indicate which optional fields are present in + this struct. Currently all fields are mandatory. + + data: + Pointer to a buffer with part of the image to write to the + card. + + len_data: + Size of the buffer pointed to by data. + + len_image: + Full size of the image. + + Sysfs Class =========== diff --git a/Documentation/rapidio/mport_cdev.txt b/Documentation/rapidio/mport_cdev.txt new file mode 100644 index 0000000000000000000000000000000000000000..20c120d4b3b80df882837373292b0f9e751d65ba --- /dev/null +++ b/Documentation/rapidio/mport_cdev.txt @@ -0,0 +1,104 @@ +RapidIO subsystem mport character device driver (rio_mport_cdev.c) +================================================================== + +Version History: +---------------- + 1.0.0 - Initial driver release. + +================================================================== + +I. Overview + +This device driver is the result of collaboration within the RapidIO.org +Software Task Group (STG) between Texas Instruments, Freescale, +Prodrive Technologies, Nokia Networks, BAE and IDT. Additional input was +received from other members of RapidIO.org. The objective was to create a +character mode driver interface which exposes the capabilities of RapidIO +devices directly to applications, in a manner that allows the numerous and +varied RapidIO implementations to interoperate. + +This driver (MPORT_CDEV) provides access to basic RapidIO subsystem operations +for user-space applications. Most of RapidIO operations are supported through +'ioctl' system calls. + +When loaded this device driver creates filesystem nodes named rio_mportX in /dev +directory for each registered RapidIO mport device. 'X' in the node name matches +to unique port ID assigned to each local mport device. + +Using available set of ioctl commands user-space applications can perform +following RapidIO bus and subsystem operations: + +- Reads and writes from/to configuration registers of mport devices + (RIO_MPORT_MAINT_READ_LOCAL/RIO_MPORT_MAINT_WRITE_LOCAL) +- Reads and writes from/to configuration registers of remote RapidIO devices. + This operations are defined as RapidIO Maintenance reads/writes in RIO spec. + (RIO_MPORT_MAINT_READ_REMOTE/RIO_MPORT_MAINT_WRITE_REMOTE) +- Set RapidIO Destination ID for mport devices (RIO_MPORT_MAINT_HDID_SET) +- Set RapidIO Component Tag for mport devices (RIO_MPORT_MAINT_COMPTAG_SET) +- Query logical index of mport devices (RIO_MPORT_MAINT_PORT_IDX_GET) +- Query capabilities and RapidIO link configuration of mport devices + (RIO_MPORT_GET_PROPERTIES) +- Enable/Disable reporting of RapidIO doorbell events to user-space applications + (RIO_ENABLE_DOORBELL_RANGE/RIO_DISABLE_DOORBELL_RANGE) +- Enable/Disable reporting of RIO port-write events to user-space applications + (RIO_ENABLE_PORTWRITE_RANGE/RIO_DISABLE_PORTWRITE_RANGE) +- Query/Control type of events reported through this driver: doorbells, + port-writes or both (RIO_SET_EVENT_MASK/RIO_GET_EVENT_MASK) +- Configure/Map mport's outbound requests window(s) for specific size, + RapidIO destination ID, hopcount and request type + (RIO_MAP_OUTBOUND/RIO_UNMAP_OUTBOUND) +- Configure/Map mport's inbound requests window(s) for specific size, + RapidIO base address and local memory base address + (RIO_MAP_INBOUND/RIO_UNMAP_INBOUND) +- Allocate/Free contiguous DMA coherent memory buffer for DMA data transfers + to/from remote RapidIO devices (RIO_ALLOC_DMA/RIO_FREE_DMA) +- Initiate DMA data transfers to/from remote RapidIO devices (RIO_TRANSFER). + Supports blocking, asynchronous and posted (a.k.a 'fire-and-forget') data + transfer modes. +- Check/Wait for completion of asynchronous DMA data transfer + (RIO_WAIT_FOR_ASYNC) +- Manage device objects supported by RapidIO subsystem (RIO_DEV_ADD/RIO_DEV_DEL). + This allows implementation of various RapidIO fabric enumeration algorithms + as user-space applications while using remaining functionality provided by + kernel RapidIO subsystem. + +II. Hardware Compatibility + +This device driver uses standard interfaces defined by kernel RapidIO subsystem +and therefore it can be used with any mport device driver registered by RapidIO +subsystem with limitations set by available mport implementation. + +At this moment the most common limitation is availability of RapidIO-specific +DMA engine framework for specific mport device. Users should verify available +functionality of their platform when planning to use this driver: + +- IDT Tsi721 PCIe-to-RapidIO bridge device and its mport device driver are fully + compatible with this driver. +- Freescale SoCs 'fsl_rio' mport driver does not have implementation for RapidIO + specific DMA engine support and therefore DMA data transfers mport_cdev driver + are not available. + +III. Module parameters + +- 'dbg_level' - This parameter allows to control amount of debug information + generated by this device driver. This parameter is formed by set of + This parameter can be changed bit masks that correspond to the specific + functional block. + For mask definitions see 'drivers/rapidio/devices/rio_mport_cdev.c' + This parameter can be changed dynamically. + Use CONFIG_RAPIDIO_DEBUG=y to enable debug output at the top level. + +IV. Known problems + + None. + +V. User-space Applications and API + +API library and applications that use this device driver are available from +RapidIO.org. + +VI. TODO List + +- Add support for sending/receiving "raw" RapidIO messaging packets. +- Add memory mapped DMA data transfers as an option when RapidIO-specific DMA + is not available. diff --git a/Documentation/rapidio/tsi721.txt b/Documentation/rapidio/tsi721.txt index 626052f403bb3300899659eb86676f62a9702618..7c1c7bf48ec0ae58f506a75655d5a8ef176879fc 100644 --- a/Documentation/rapidio/tsi721.txt +++ b/Documentation/rapidio/tsi721.txt @@ -16,6 +16,15 @@ For inbound messages this driver uses destination ID matching to forward message into the corresponding message queue. Messaging callbacks are implemented to be fully compatible with RIONET driver (Ethernet over RapidIO messaging services). +1. Module parameters: +- 'dbg_level' - This parameter allows to control amount of debug information + generated by this device driver. This parameter is formed by set of + This parameter can be changed bit masks that correspond to the specific + functional block. + For mask definitions see 'drivers/rapidio/devices/tsi721.h' + This parameter can be changed dynamically. + Use CONFIG_RAPIDIO_DEBUG=y to enable debug output at the top level. + II. Known problems None. diff --git a/Documentation/rfkill.txt b/Documentation/rfkill.txt index 2ee6ef9a6554d600088ae572b3256ffe44e51d08..1f0c27049340d9603ec90fa1694d4e0e14dbb5c7 100644 --- a/Documentation/rfkill.txt +++ b/Documentation/rfkill.txt @@ -83,6 +83,8 @@ rfkill drivers that control devices that can be hard-blocked unless they also assign the poll_hw_block() callback (then the rfkill core will poll the device). Don't do this unless you cannot get the event in any other way. +RFKill provides per-switch LED triggers, which can be used to drive LEDs +according to the switch state (LED_FULL when blocked, LED_OFF otherwise). 5. Userspace support diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 48148d6d930786849c97cf79329b92fec755e946..fc53ccd9a6293c542b60cb62d3466dd7cc70e07b 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -1910,6 +1910,12 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. - Default: 0x0000 ignore_ctl_error - Ignore any USB-controller regarding mixer interface (default: no) + autoclock - Enable auto-clock selection for UAC2 devices + (default: yes) + quirk_alias - Quirk alias list, pass strings like + "0123abcd:5678beef", which applies the existing + quirk for the device 5678:beef to a new device + 0123:abcd. This module supports multiple devices, autoprobe and hotplugging. @@ -1919,6 +1925,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. NB: ignore_ctl_error=1 may help when you get an error at accessing the mixer element such as URB error -22. This happens on some buggy USB device or the controller. + NB: quirk_alias option is provided only for testing / development. + If you want to have a proper support, contact to upstream for + adding the matching quirk in the driver code statically. Module snd-usb-caiaq -------------------- diff --git a/Documentation/sound/alsa/HD-Audio-DP-MST-audio.txt b/Documentation/sound/alsa/HD-Audio-DP-MST-audio.txt new file mode 100644 index 0000000000000000000000000000000000000000..82744ac3513d83c108b81b1fe70526f9f9a73b8d --- /dev/null +++ b/Documentation/sound/alsa/HD-Audio-DP-MST-audio.txt @@ -0,0 +1,74 @@ +To support DP MST audio, HD Audio hdmi codec driver introduces virtual pin +and dynamic pcm assignment. + +Virtual pin is an extension of per_pin. The most difference of DP MST +from legacy is that DP MST introduces device entry. Each pin can contain +several device entries. Each device entry behaves as a pin. + +As each pin may contain several device entries and each codec may contain +several pins, if we use one pcm per per_pin, there will be many PCMs. +The new solution is to create a few PCMs and to dynamically bind pcm to +per_pin. Driver uses spec->dyn_pcm_assign flag to indicate whether to use +the new solution. + +PCM +=== +To be added + + +Jack +==== + +Presume: + - MST must be dyn_pcm_assign, and it is acomp (for Intel scenario); + - NON-MST may or may not be dyn_pcm_assign, it can be acomp or !acomp; + +So there are the following scenarios: + a. MST (&& dyn_pcm_assign && acomp) + b. NON-MST && dyn_pcm_assign && acomp + c. NON-MST && !dyn_pcm_assign && !acomp + +Below discussion will ignore MST and NON-MST difference as it doesn't +impact on jack handling too much. + +Driver uses struct hdmi_pcm pcm[] array in hdmi_spec and snd_jack is +a member of hdmi_pcm. Each pin has one struct hdmi_pcm * pcm pointer. + +For !dyn_pcm_assign, per_pin->pcm will assigned to spec->pcm[n] statically. + +For dyn_pcm_assign, per_pin->pcm will assigned to spec->pcm[n] +when monitor is hotplugged. + + +Build Jack +---------- + +- dyn_pcm_assign +Will not use hda_jack but use snd_jack in spec->pcm_rec[pcm_idx].jack directly. + +- !dyn_pcm_assign +Use hda_jack and assign spec->pcm_rec[pcm_idx].jack = jack->jack statically. + + +Unsolicited Event Enabling +-------------------------- +Enable unsolicited event if !acomp. + + +Monitor Hotplug Event Handling +------------------------------ +- acomp +pin_eld_notify() -> check_presence_and_report() -> hdmi_present_sense() -> +sync_eld_via_acomp(). +Use directly snd_jack_report() on spec->pcm_rec[pcm_idx].jack for +both dyn_pcm_assign and !dyn_pcm_assign + +- !acomp +Hdmi_unsol_event() -> hdmi_intrinsic_event() -> check_presence_and_report() -> +hdmi_present_sense() -> hdmi_prepsent_sense_via_verbs() +Use directly snd_jack_report() on spec->pcm_rec[pcm_idx].jack for dyn_pcm_assign. +Use hda_jack mechanism to handle jack events. + + +Others to be added later +======================== diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt index 89a887c7662930844ea59850e65866bbd43c3786..cb0368459da31409996c8e01fa8add867ec0c5d8 100644 --- a/Documentation/sysctl/vm.txt +++ b/Documentation/sysctl/vm.txt @@ -803,6 +803,24 @@ performance impact. Reclaim code needs to take various locks to find freeable directory and inode objects. With vfs_cache_pressure=1000, it will look for ten times more freeable objects than there are. +============================================================= + +watermark_scale_factor: + +This factor controls the aggressiveness of kswapd. It defines the +amount of memory left in a node/system before kswapd is woken up and +how much memory needs to be free before kswapd goes back to sleep. + +The unit is in fractions of 10,000. The default value of 10 means the +distances between watermarks are 0.1% of the available memory in the +node/system. The maximum value is 1000, or 10% of memory. + +A high rate of threads entering direct reclaim (allocstall) or kswapd +going to sleep prematurely (kswapd_low_wmark_hit_quickly) can indicate +that the number of free pages kswapd maintains for latency reasons is +too small for the allocation bursts occurring in the system. This knob +can then be used to tune kswapd aggressiveness accordingly. + ============================================================== zone_reclaim_mode: diff --git a/Documentation/target/tcmu-design.txt b/Documentation/target/tcmu-design.txt index bef81e42788f2b8e48238b63318afd556e843979..4cebc1ebf99a6f46f4de658125e29a5239a81086 100644 --- a/Documentation/target/tcmu-design.txt +++ b/Documentation/target/tcmu-design.txt @@ -117,7 +117,9 @@ userspace (respectively) to put commands on the ring, and indicate when the commands are completed. version - 1 (userspace should abort if otherwise) -flags - none yet defined. +flags: +- TCMU_MAILBOX_FLAG_CAP_OOOC: indicates out-of-order completion is + supported. See "The Command Ring" for details. cmdr_off - The offset of the start of the command ring from the start of the memory region, to account for the mailbox size. cmdr_size - The size of the command ring. This does *not* need to be a @@ -162,6 +164,13 @@ rsp.sense_buffer if necessary. Userspace then increments mailbox.cmd_tail by entry.hdr.length (mod cmdr_size) and signals the kernel via the UIO method, a 4-byte write to the file descriptor. +If TCMU_MAILBOX_FLAG_CAP_OOOC is set for mailbox->flags, kernel is +capable of handling out-of-order completions. In this case, userspace can +handle command in different order other than original. Since kernel would +still process the commands in the same order it appeared in the command +ring, userspace need to update the cmd->id when completing the +command(a.k.a steal the original command's entry). + When the opcode is PAD, userspace only updates cmd_tail as above -- it's a no-op. (The kernel inserts PAD entries to ensure each CMD entry is contiguous within the command ring.) diff --git a/Documentation/thermal/sysfs-api.txt b/Documentation/thermal/sysfs-api.txt index 8c745c8931da05a5fb57d5a10a5aa4a3cd376a22..ed419d6c8dec8d4db73d4cf432c937f9b0bc3126 100644 --- a/Documentation/thermal/sysfs-api.txt +++ b/Documentation/thermal/sysfs-api.txt @@ -72,6 +72,74 @@ temperature) and throttle appropriate devices. It deletes the corresponding entry form /sys/class/thermal folder and unbind all the thermal cooling devices it uses. +1.1.3 struct thermal_zone_device *thermal_zone_of_sensor_register( + struct device *dev, int sensor_id, void *data, + const struct thermal_zone_of_device_ops *ops) + + This interface adds a new sensor to a DT thermal zone. + This function will search the list of thermal zones described in + device tree and look for the zone that refer to the sensor device + pointed by dev->of_node as temperature providers. For the zone + pointing to the sensor node, the sensor will be added to the DT + thermal zone device. + + The parameters for this interface are: + dev: Device node of sensor containing valid node pointer in + dev->of_node. + sensor_id: a sensor identifier, in case the sensor IP has more + than one sensors + data: a private pointer (owned by the caller) that will be + passed back, when a temperature reading is needed. + ops: struct thermal_zone_of_device_ops *. + + get_temp: a pointer to a function that reads the + sensor temperature. This is mandatory + callback provided by sensor driver. + get_trend: a pointer to a function that reads the + sensor temperature trend. + set_emul_temp: a pointer to a function that sets + sensor emulated temperature. + The thermal zone temperature is provided by the get_temp() function + pointer of thermal_zone_of_device_ops. When called, it will + have the private pointer @data back. + + It returns error pointer if fails otherwise valid thermal zone device + handle. Caller should check the return handle with IS_ERR() for finding + whether success or not. + +1.1.4 void thermal_zone_of_sensor_unregister(struct device *dev, + struct thermal_zone_device *tzd) + + This interface unregisters a sensor from a DT thermal zone which was + successfully added by interface thermal_zone_of_sensor_register(). + This function removes the sensor callbacks and private data from the + thermal zone device registered with thermal_zone_of_sensor_register() + interface. It will also silent the zone by remove the .get_temp() and + get_trend() thermal zone device callbacks. + +1.1.5 struct thermal_zone_device *devm_thermal_zone_of_sensor_register( + struct device *dev, int sensor_id, + void *data, const struct thermal_zone_of_device_ops *ops) + + This interface is resource managed version of + thermal_zone_of_sensor_register(). + All details of thermal_zone_of_sensor_register() described in + section 1.1.3 is applicable here. + The benefit of using this interface to register sensor is that it + is not require to explicitly call thermal_zone_of_sensor_unregister() + in error path or during driver unbinding as this is done by driver + resource manager. + +1.1.6 void devm_thermal_zone_of_sensor_unregister(struct device *dev, + struct thermal_zone_device *tzd) + + This interface is resource managed version of + thermal_zone_of_sensor_unregister(). + All details of thermal_zone_of_sensor_unregister() described in + section 1.1.4 is applicable here. + Normally this function will not need to be called and the resource + management code will ensure that the resource is freed. + 1.2 thermal cooling device interface 1.2.1 struct thermal_cooling_device *thermal_cooling_device_register(char *name, void *devdata, struct thermal_cooling_device_ops *) diff --git a/Documentation/vm/transhuge.txt b/Documentation/vm/transhuge.txt index 21cf34f3ddb268c5a64478db776d05333027cc54..d9cb65cf5cfdf786650f3d8345f6d6346f05f930 100644 --- a/Documentation/vm/transhuge.txt +++ b/Documentation/vm/transhuge.txt @@ -113,9 +113,26 @@ guaranteed, but it may be more likely in case the allocation is for a MADV_HUGEPAGE region. echo always >/sys/kernel/mm/transparent_hugepage/defrag +echo defer >/sys/kernel/mm/transparent_hugepage/defrag echo madvise >/sys/kernel/mm/transparent_hugepage/defrag echo never >/sys/kernel/mm/transparent_hugepage/defrag +"always" means that an application requesting THP will stall on allocation +failure and directly reclaim pages and compact memory in an effort to +allocate a THP immediately. This may be desirable for virtual machines +that benefit heavily from THP use and are willing to delay the VM start +to utilise them. + +"defer" means that an application will wake kswapd in the background +to reclaim pages and wake kcompact to compact memory so that THP is +available in the near future. It's the responsibility of khugepaged +to then install the THP pages later. + +"madvise" will enter direct reclaim like "always" but only for regions +that are have used madvise(MADV_HUGEPAGE). This is the default behaviour. + +"never" should be self-explanatory. + By default kernel tries to use huge zero page on read page fault. It's possible to disable huge zero page by writing 0 or enable it back by writing 1: @@ -229,6 +246,11 @@ thp_split_page is incremented every time a huge page is split into base thp_split_page_failed is is incremented if kernel fails to split huge page. This can happen if the page was pinned by somebody. +thp_deferred_split_page is incremented when a huge page is put onto split + queue. This happens when a huge page is partially unmapped and + splitting it would free up some memory. Pages on split queue are + going to be split under memory pressure. + thp_split_pmd is incremented every time a PMD split into table of PTEs. This can happen, for instance, when application calls mprotect() or munmap() on part of huge page. It doesn't split huge page, only diff --git a/Documentation/watchdog/watchdog-kernel-api.txt b/Documentation/watchdog/watchdog-kernel-api.txt index 55120a055a14d57f98053cb7147b25ad4c2a6214..917eeeabfa5eaefd3396c66e4b1032dd49a6f2b4 100644 --- a/Documentation/watchdog/watchdog-kernel-api.txt +++ b/Documentation/watchdog/watchdog-kernel-api.txt @@ -52,6 +52,8 @@ struct watchdog_device { unsigned int timeout; unsigned int min_timeout; unsigned int max_timeout; + unsigned int min_hw_heartbeat_ms; + unsigned int max_hw_heartbeat_ms; struct notifier_block reboot_nb; struct notifier_block restart_nb; void *driver_data; @@ -73,8 +75,21 @@ It contains following fields: 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. * timeout: the watchdog timer's timeout value (in seconds). + This is the time after which the system will reboot if user space does + not send a heartbeat request if WDOG_ACTIVE is set. * min_timeout: the watchdog timer's minimum timeout value (in seconds). -* max_timeout: the watchdog timer's maximum timeout value (in seconds). + If set, the minimum configurable value for 'timeout'. +* max_timeout: the watchdog timer's maximum timeout value (in seconds), + as seen from userspace. If set, the maximum configurable value for + 'timeout'. Not used if max_hw_heartbeat_ms is non-zero. +* min_hw_heartbeat_ms: Minimum time between heartbeats sent to the chip, + in milli-seconds. +* max_hw_heartbeat_ms: Maximum hardware heartbeat, in milli-seconds. + If set, the infrastructure will send heartbeats to the watchdog driver + if 'timeout' is larger than max_hw_heartbeat_ms, unless WDOG_ACTIVE + is set and userspace failed to send a heartbeat for at least 'timeout' + seconds. max_hw_heartbeat_ms must be set if a driver does not implement + the stop function. * reboot_nb: notifier block that is registered for reboot notifications, for internal use only. If the driver calls watchdog_stop_on_reboot, watchdog core will stop the watchdog on such notifications. @@ -123,17 +138,20 @@ are: device. The routine needs a pointer to the watchdog timer device structure as a parameter. It returns zero on success or a negative errno code for failure. -* stop: with this routine the watchdog timer device is being stopped. - The routine needs a pointer to the watchdog timer device structure as a - parameter. It returns zero on success or a negative errno code for failure. - Some watchdog timer hardware can only be started and not be stopped. The - driver supporting this hardware needs to make sure that a start and stop - routine is being provided. This can be done by using a timer in the driver - that regularly sends a keepalive ping to the watchdog timer hardware. Not all watchdog timer hardware supports the same functionality. That's why all other routines/operations are optional. They only need to be provided if they are supported. These optional routines/operations are: +* stop: with this routine the watchdog timer device is being stopped. + The routine needs a pointer to the watchdog timer device structure as a + parameter. It returns zero on success or a negative errno code for failure. + Some watchdog timer hardware can only be started and not be stopped. A + driver supporting such hardware does not have to implement the stop routine. + If a driver has no stop function, the watchdog core will set WDOG_HW_RUNNING + and start calling the driver's keepalive pings function after the watchdog + device is closed. + If a watchdog driver does not implement the stop function, it must set + max_hw_heartbeat_ms. * ping: this is the routine that sends a keepalive ping to the watchdog timer hardware. The routine needs a pointer to the watchdog timer device structure as a @@ -153,9 +171,18 @@ they are supported. These optional routines/operations are: and -EIO for "could not write value to the watchdog". On success this routine should set the timeout value of the watchdog_device to the achieved timeout value (which may be different from the requested one - because the watchdog does not necessarily has a 1 second resolution). + because the watchdog does not necessarily have a 1 second resolution). + Drivers implementing max_hw_heartbeat_ms set the hardware watchdog heartbeat + to the minimum of timeout and max_hw_heartbeat_ms. Those drivers set the + timeout value of the watchdog_device either to the requested timeout value + (if it is larger than max_hw_heartbeat_ms), or to the achieved timeout value. (Note: the WDIOF_SETTIMEOUT needs to be set in the options field of the watchdog's info structure). + If the watchdog driver does not have to perform any action but setting the + watchdog_device.timeout, this callback can be omitted. + If set_timeout is not provided but, WDIOF_SETTIMEOUT is set, the watchdog + infrastructure updates the timeout value of the watchdog_device internally + to the requested value. * get_timeleft: this routines returns the time that's left before a reset. * restart: this routine restarts the machine. It returns 0 on success or a negative errno code for failure. @@ -169,11 +196,19 @@ The 'ref' and 'unref' operations are no longer used and deprecated. The status bits should (preferably) be set with the set_bit and clear_bit alike bit-operations. The status bits that are defined are: * WDOG_ACTIVE: this status bit indicates whether or not a watchdog timer device - is active or not. When the watchdog is active after booting, then you should - set this status bit (Note: when you register the watchdog timer device with - this bit set, then opening /dev/watchdog will skip the start operation) + is active or not from user perspective. User space is expected to send + heartbeat requests to the driver while this flag is set. * 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_HW_RUNNING: Set by the watchdog driver if the hardware watchdog is + running. The bit must be set if the watchdog timer hardware can not be + stopped. The bit may also be set if the watchdog timer is running after + booting, before the watchdog device is opened. If set, the watchdog + infrastructure will send keepalives to the watchdog hardware while + WDOG_ACTIVE is not set. + Note: when you register the watchdog timer device with this bit set, + then opening /dev/watchdog will skip the start operation but send a keepalive + request instead. To set the WDOG_NO_WAY_OUT status bit (before registering your watchdog timer device) you can either: diff --git a/Documentation/watchdog/watchdog-parameters.txt b/Documentation/watchdog/watchdog-parameters.txt index 4e4b6f10d8410f84d8ea64ac51c68a6932bf2158..c161399a6b5c134932512b6ae74e6e1676f5051c 100644 --- a/Documentation/watchdog/watchdog-parameters.txt +++ b/Documentation/watchdog/watchdog-parameters.txt @@ -200,6 +200,11 @@ mv64x60_wdt: nowayout: Watchdog cannot be stopped once started (default=kernel config parameter) ------------------------------------------------- +ni903x_wdt: +timeout: Initial watchdog timeout in seconds (0 and Borislav Petkov . + +The main aim of the topology facilities is to present adequate interfaces to +code which needs to know/query/use the structure of the running system wrt +threads, cores, packages, etc. + +The kernel does not care about the concept of physical sockets because a +socket has no relevance to software. It's an electromechanical component. In +the past a socket always contained a single package (see below), but with the +advent of Multi Chip Modules (MCM) a socket can hold more than one package. So +there might be still references to sockets in the code, but they are of +historical nature and should be cleaned up. + +The topology of a system is described in the units of: + + - packages + - cores + - threads + +* Package: + + Packages contain a number of cores plus shared resources, e.g. DRAM + controller, shared caches etc. + + AMD nomenclature for package is 'Node'. + + Package-related topology information in the kernel: + + - cpuinfo_x86.x86_max_cores: + + The number of cores in a package. This information is retrieved via CPUID. + + - cpuinfo_x86.phys_proc_id: + + The physical ID of the package. This information is retrieved via CPUID + and deduced from the APIC IDs of the cores in the package. + + - cpuinfo_x86.logical_id: + + The logical ID of the package. As we do not trust BIOSes to enumerate the + packages in a consistent way, we introduced the concept of logical package + ID so we can sanely calculate the number of maximum possible packages in + the system and have the packages enumerated linearly. + + - topology_max_packages(): + + The maximum possible number of packages in the system. Helpful for per + package facilities to preallocate per package information. + + +* Cores: + + A core consists of 1 or more threads. It does not matter whether the threads + are SMT- or CMT-type threads. + + AMDs nomenclature for a CMT core is "Compute Unit". The kernel always uses + "core". + + Core-related topology information in the kernel: + + - smp_num_siblings: + + The number of threads in a core. The number of threads in a package can be + calculated by: + + threads_per_package = cpuinfo_x86.x86_max_cores * smp_num_siblings + + +* Threads: + + A thread is a single scheduling unit. It's the equivalent to a logical Linux + CPU. + + AMDs nomenclature for CMT threads is "Compute Unit Core". The kernel always + uses "thread". + + Thread-related topology information in the kernel: + + - topology_core_cpumask(): + + The cpumask contains all online threads in the package to which a thread + belongs. + + The number of online threads is also printed in /proc/cpuinfo "siblings." + + - topology_sibling_mask(): + + The cpumask contains all online threads in the core to which a thread + belongs. + + - topology_logical_package_id(): + + The logical package ID to which a thread belongs. + + - topology_physical_package_id(): + + The physical package ID to which a thread belongs. + + - topology_core_id(); + + The ID of the core to which a thread belongs. It is also printed in /proc/cpuinfo + "core_id." + + + +System topology examples + +Note: + +The alternative Linux CPU enumeration depends on how the BIOS enumerates the +threads. Many BIOSes enumerate all threads 0 first and then all threads 1. +That has the "advantage" that the logical Linux CPU numbers of threads 0 stay +the same whether threads are enabled or not. That's merely an implementation +detail and has no practical impact. + +1) Single Package, Single Core + + [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 + +2) Single Package, Dual Core + + a) One thread per core + + [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 + -> [core 1] -> [thread 0] -> Linux CPU 1 + + b) Two threads per core + + [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 + -> [thread 1] -> Linux CPU 1 + -> [core 1] -> [thread 0] -> Linux CPU 2 + -> [thread 1] -> Linux CPU 3 + + Alternative enumeration: + + [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 + -> [thread 1] -> Linux CPU 2 + -> [core 1] -> [thread 0] -> Linux CPU 1 + -> [thread 1] -> Linux CPU 3 + + AMD nomenclature for CMT systems: + + [node 0] -> [Compute Unit 0] -> [Compute Unit Core 0] -> Linux CPU 0 + -> [Compute Unit Core 1] -> Linux CPU 1 + -> [Compute Unit 1] -> [Compute Unit Core 0] -> Linux CPU 2 + -> [Compute Unit Core 1] -> Linux CPU 3 + +4) Dual Package, Dual Core + + a) One thread per core + + [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 + -> [core 1] -> [thread 0] -> Linux CPU 1 + + [package 1] -> [core 0] -> [thread 0] -> Linux CPU 2 + -> [core 1] -> [thread 0] -> Linux CPU 3 + + b) Two threads per core + + [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 + -> [thread 1] -> Linux CPU 1 + -> [core 1] -> [thread 0] -> Linux CPU 2 + -> [thread 1] -> Linux CPU 3 + + [package 1] -> [core 0] -> [thread 0] -> Linux CPU 4 + -> [thread 1] -> Linux CPU 5 + -> [core 1] -> [thread 0] -> Linux CPU 6 + -> [thread 1] -> Linux CPU 7 + + Alternative enumeration: + + [package 0] -> [core 0] -> [thread 0] -> Linux CPU 0 + -> [thread 1] -> Linux CPU 4 + -> [core 1] -> [thread 0] -> Linux CPU 1 + -> [thread 1] -> Linux CPU 5 + + [package 1] -> [core 0] -> [thread 0] -> Linux CPU 2 + -> [thread 1] -> Linux CPU 6 + -> [core 1] -> [thread 0] -> Linux CPU 3 + -> [thread 1] -> Linux CPU 7 + + AMD nomenclature for CMT systems: + + [node 0] -> [Compute Unit 0] -> [Compute Unit Core 0] -> Linux CPU 0 + -> [Compute Unit Core 1] -> Linux CPU 1 + -> [Compute Unit 1] -> [Compute Unit Core 0] -> Linux CPU 2 + -> [Compute Unit Core 1] -> Linux CPU 3 + + [node 1] -> [Compute Unit 0] -> [Compute Unit Core 0] -> Linux CPU 4 + -> [Compute Unit Core 1] -> Linux CPU 5 + -> [Compute Unit 1] -> [Compute Unit Core 0] -> Linux CPU 6 + -> [Compute Unit Core 1] -> Linux CPU 7 diff --git a/Documentation/x86/x86_64/mm.txt b/Documentation/x86/x86_64/mm.txt index 05712ac83e3826bfe7802e01932bde593128b129..c518dce7da4d62da22b192cbc3595ebf62ae3037 100644 --- a/Documentation/x86/x86_64/mm.txt +++ b/Documentation/x86/x86_64/mm.txt @@ -16,6 +16,8 @@ ffffec0000000000 - fffffc0000000000 (=44 bits) kasan shadow memory (16TB) ... unused hole ... ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp fixup stacks ... unused hole ... +ffffffef00000000 - ffffffff00000000 (=64 GB) EFI region mapping space +... unused hole ... ffffffff80000000 - ffffffffa0000000 (=512 MB) kernel text mapping, from phys 0 ffffffffa0000000 - ffffffffff5fffff (=1525 MB) module mapping space ffffffffff600000 - ffffffffffdfffff (=8 MB) vsyscalls @@ -32,11 +34,9 @@ reference. Current X86-64 implementations only support 40 bits of address space, but we support up to 46 bits. This expands into MBZ space in the page tables. -->trampoline_pgd: - -We map EFI runtime services in the aforementioned PGD in the virtual -range of 64Gb (arbitrarily set, can be raised if needed) - -0xffffffef00000000 - 0xffffffff00000000 +We map EFI runtime services in the 'efi_pgd' PGD in a 64Gb large virtual +memory window (this size is arbitrary, it can be raised later if needed). +The mappings are not part of any other kernel PGD and are only available +during EFI runtime calls. -Andi Kleen, Jul 2004 diff --git a/MAINTAINERS b/MAINTAINERS index e32f4847e251490359d8a093796dc954add21e21..61a323a6b2cfe7348c63f49eadcd858100dc8a03 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -151,7 +151,7 @@ S: Maintained F: drivers/scsi/53c700* 6LOWPAN GENERIC (BTLE/IEEE 802.15.4) -M: Alexander Aring +M: Alexander Aring M: Jukka Rissanen L: linux-bluetooth@vger.kernel.org L: linux-wpan@vger.kernel.org @@ -228,13 +228,13 @@ F: kernel/sys_ni.c ABIT UGURU 1,2 HARDWARE MONITOR DRIVER M: Hans de Goede -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: drivers/hwmon/abituguru.c ABIT UGURU 3 HARDWARE MONITOR DRIVER M: Alistair John Strachan -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: drivers/hwmon/abituguru3.c @@ -392,14 +392,14 @@ F: Documentation/devicetree/bindings/net/ieee802154/adf7242.txt ADM1025 HARDWARE MONITOR DRIVER M: Jean Delvare -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/adm1025 F: drivers/hwmon/adm1025.c ADM1029 HARDWARE MONITOR DRIVER M: Corentin Labbe -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: drivers/hwmon/adm1029.c @@ -444,7 +444,7 @@ F: drivers/video/backlight/adp8860_bl.c ADS1015 HARDWARE MONITOR DRIVER M: Dirk Eibach -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/ads1015 F: drivers/hwmon/ads1015.c @@ -457,7 +457,7 @@ F: drivers/macintosh/therm_adt746x.c ADT7475 HARDWARE MONITOR DRIVER M: Jean Delvare -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/adt7475 F: drivers/hwmon/adt7475.c @@ -634,7 +634,7 @@ F: include/linux/ccp.h AMD FAM15H PROCESSOR POWER MONITORING DRIVER M: Huang Rui -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Supported F: Documentation/hwmon/fam15h_power F: drivers/hwmon/fam15h_power.c @@ -679,11 +679,19 @@ F: drivers/gpu/drm/radeon/radeon_kfd.c F: drivers/gpu/drm/radeon/radeon_kfd.h F: include/uapi/linux/kfd_ioctl.h +AMD SEATTLE DEVICE TREE SUPPORT +M: Brijesh Singh +M: Suravee Suthikulpanit +M: Tom Lendacky +S: Supported +F: arch/arm64/boot/dts/amd/ + AMD XGBE DRIVER M: Tom Lendacky L: netdev@vger.kernel.org S: Supported F: drivers/net/ethernet/amd/xgbe/ +F: arch/arm64/boot/dts/amd/amd-seattle-xgbe*.dtsi AMS (Apple Motion Sensor) DRIVER M: Michael Hanselmann @@ -775,6 +783,12 @@ L: alsa-devel@alsa-project.org (moderated for non-subscribers) S: Maintained F: sound/aoa/ +APEX EMBEDDED SYSTEMS STX104 DAC DRIVER +M: William Breathitt Gray +L: linux-iio@vger.kernel.org +S: Maintained +F: drivers/iio/dac/stx104.c + APM DRIVER M: Jiri Kosina S: Odd fixes @@ -792,7 +806,7 @@ F: drivers/input/mouse/bcm5974.c APPLE SMC DRIVER M: Henrik Rydberg -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Odd fixes F: drivers/hwmon/applesmc.c @@ -833,6 +847,12 @@ S: Maintained F: drivers/net/arcnet/ F: include/uapi/linux/if_arcnet.h +ARM HDLCD DRM DRIVER +M: Liviu Dudau +S: Supported +F: drivers/gpu/drm/arm/ +F: Documentation/devicetree/bindings/display/arm,hdlcd.txt + ARM MFM AND FLOPPY DRIVERS M: Ian Molton S: Maintained @@ -945,6 +965,16 @@ F: arch/arm/boot/dts/alpine* F: arch/arm64/boot/dts/al/ F: drivers/*/*alpine* +ARM/ARTPEC MACHINE SUPPORT +M: Jesper Nilsson +M: Lars Persson +M: Niklas Cassel +S: Maintained +L: linux-arm-kernel@axis.com +F: arch/arm/mach-artpec +F: arch/arm/boot/dts/artpec6* +F: drivers/clk/clk-artpec6.c + ARM/ATMEL AT91RM9200, AT91SAM9 AND SAMA5 SOC SUPPORT M: Nicolas Ferre M: Alexandre Belloni @@ -1291,6 +1321,7 @@ F: arch/arm/mach-mvebu/ F: drivers/rtc/rtc-armada38x.c F: arch/arm/boot/dts/armada* F: arch/arm/boot/dts/kirkwood* +F: arch/arm64/boot/dts/marvell/armada* ARM/Marvell Berlin SoC support @@ -1509,6 +1540,7 @@ F: arch/arm/mach-s5p*/ F: arch/arm/mach-exynos*/ F: drivers/*/*s3c2410* F: drivers/*/*/*s3c2410* +F: drivers/soc/samsung/* F: drivers/spi/spi-s3c* F: sound/soc/samsung/* F: Documentation/arm/Samsung/ @@ -1806,11 +1838,13 @@ F: drivers/edac/synopsys_edac.c ARM SMMU DRIVERS M: Will Deacon +R: Robin Murphy L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: drivers/iommu/arm-smmu.c F: drivers/iommu/arm-smmu-v3.c F: drivers/iommu/io-pgtable-arm.c +F: drivers/iommu/io-pgtable-arm-v7s.c ARM64 PORT (AARCH64 ARCHITECTURE) M: Catalin Marinas @@ -1831,7 +1865,7 @@ F: include/media/i2c/as3645a.h ASC7621 HARDWARE MONITOR DRIVER M: George Joseph -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/asc7621 F: drivers/hwmon/asc7621.c @@ -1924,7 +1958,7 @@ F: drivers/net/wireless/ath/carl9170/ ATK0110 HWMON DRIVER M: Luca Tettamanti -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: drivers/hwmon/asus_atk0110.c @@ -1962,6 +1996,12 @@ M: Nicolas Ferre S: Supported F: drivers/tty/serial/atmel_serial.c +ATMEL SAMA5D2 ADC DRIVER +M: Ludovic Desroches +L: linux-iio@vger.kernel.org +S: Supported +F: drivers/iio/adc/at91-sama5d2_adc.c + ATMEL Audio ALSA driver M: Nicolas Ferre L: alsa-devel@alsa-project.org (moderated for non-subscribers) @@ -2164,7 +2204,8 @@ M: Marek Lindner M: Simon Wunderlich M: Antonio Quartulli L: b.a.t.m.a.n@lists.open-mesh.org -W: http://www.open-mesh.org/ +W: https://www.open-mesh.org/ +Q: https://patchwork.open-mesh.org/project/batman/list/ S: Maintained F: net/batman-adv/ @@ -2393,8 +2434,9 @@ F: arch/arm/boot/dts/bcm470* BROADCOM BCM63XX ARM ARCHITECTURE M: Florian Fainelli -L: linux-arm-kernel@lists.infradead.org -T: git git://github.com/broadcom/arm-bcm63xx.git +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +L: bcm-kernel-feedback-list@broadcom.com +T: git git://github.com/broadcom/stblinux.git S: Maintained F: arch/arm/mach-bcm/bcm63xx.c F: arch/arm/include/debug/bcm63xx.S @@ -2435,6 +2477,7 @@ F: include/linux/bcm963xx_nvram.h F: include/linux/bcm963xx_tag.h BROADCOM TG3 GIGABIT ETHERNET DRIVER +M: Siva Reddy Kallam M: Prashant Sreedharan M: Michael Chan L: netdev@vger.kernel.org @@ -2526,6 +2569,13 @@ L: netdev@vger.kernel.org S: Supported F: drivers/net/ethernet/broadcom/bcmsysport.* +BROADCOM VULCAN ARM64 SOC +M: Jayachandran C. +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +L: bcm-kernel-feedback-list@broadcom.com +S: Maintained +F: arch/arm64/boot/dts/broadcom/vulcan* + BROCADE BFA FC SCSI DRIVER M: Anil Gurumurthy M: Sudarsana Kalluru @@ -3044,7 +3094,7 @@ F: mm/swap_cgroup.c CORETEMP HARDWARE MONITORING DRIVER M: Fenghua Yu -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/coretemp F: drivers/hwmon/coretemp.c @@ -3511,6 +3561,14 @@ F: include/linux/device-mapper.h F: include/linux/dm-*.h F: include/uapi/linux/dm-*.h +DEVLINK +M: Jiri Pirko +L: netdev@vger.kernel.org +S: Supported +F: net/core/devlink.c +F: include/net/devlink.h +F: include/uapi/linux/devlink.h + DIALOG SEMICONDUCTOR DRIVERS M: Support Opensource W: http://www.dialog-semiconductor.com/products @@ -3548,13 +3606,6 @@ L: driverdev-devel@linuxdriverproject.org S: Maintained F: drivers/staging/dgnc/ -DIGI EPCA PCI PRODUCTS -M: Lidza Louina -M: Daeseok Youn -L: driverdev-devel@linuxdriverproject.org -S: Maintained -F: drivers/staging/dgap/ - DIOLAN U2C-12 I2C DRIVER M: Guenter Roeck L: linux-i2c@vger.kernel.org @@ -3632,7 +3683,7 @@ T: git git://git.infradead.org/users/vkoul/slave-dma.git DME1737 HARDWARE MONITOR DRIVER M: Juerg Haefliger -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/dme1737 F: drivers/hwmon/dme1737.c @@ -3711,7 +3762,7 @@ F: drivers/gpu/vga/ F: include/drm/ F: include/uapi/drm/ -RADEON DRM DRIVERS +RADEON and AMDGPU DRM DRIVERS M: Alex Deucher M: Christian König L: dri-devel@lists.freedesktop.org @@ -3719,6 +3770,8 @@ T: git git://people.freedesktop.org/~agd5f/linux S: Supported F: drivers/gpu/drm/radeon/ F: include/uapi/drm/radeon* +F: drivers/gpu/drm/amd/ +F: include/uapi/drm/amdgpu* DRM PANEL DRIVERS M: Thierry Reding @@ -3763,7 +3816,7 @@ F: include/drm/exynos* F: include/uapi/drm/exynos* DRM DRIVERS FOR FREESCALE DCU -M: Jianwei Wang +M: Stefan Agner M: Alison Wang L: dri-devel@lists.freedesktop.org S: Supported @@ -4235,13 +4288,6 @@ M: Maxim Levitsky S: Maintained F: drivers/media/rc/ene_ir.* -ENHANCED ERROR HANDLING (EEH) -M: Gavin Shan -L: linuxppc-dev@lists.ozlabs.org -S: Supported -F: Documentation/powerpc/eeh-pci-error-recovery.txt -F: arch/powerpc/kernel/eeh*.c - EPSON S1D13XXX FRAMEBUFFER DRIVER M: Kristoffer Ericson S: Maintained @@ -4256,7 +4302,7 @@ F: drivers/net/ethernet/agere/ ETHERNET BRIDGE M: Stephen Hemminger -L: bridge@lists.linux-foundation.org +L: bridge@lists.linux-foundation.org (moderated for non-subscribers) L: netdev@vger.kernel.org W: http://www.linuxfoundation.org/en/Net:Bridge S: Maintained @@ -4318,6 +4364,12 @@ L: dri-devel@lists.freedesktop.org S: Maintained F: drivers/gpu/drm/exynos/exynos_dp* +EXYNOS SYSMMU (IOMMU) driver +M: Marek Szyprowski +L: iommu@lists.linux-foundation.org +S: Maintained +F: drivers/iommu/exynos-iommu.c + EXYNOS MIPI DISPLAY DRIVERS M: Inki Dae M: Donghwa Lee @@ -4329,7 +4381,7 @@ F: include/video/exynos_mipi* F71805F HARDWARE MONITORING DRIVER M: Jean Delvare -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/f71805f F: drivers/hwmon/f71805f.c @@ -4408,7 +4460,7 @@ F: fs/* FINTEK F75375S HARDWARE MONITOR AND FAN CONTROLLER DRIVER M: Riku Voipio -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: drivers/hwmon/f75375s.c F: include/linux/f75375s.h @@ -4969,8 +5021,8 @@ F: drivers/media/usb/hackrf/ HARDWARE MONITORING M: Jean Delvare M: Guenter Roeck -L: lm-sensors@lm-sensors.org -W: http://www.lm-sensors.org/ +L: linux-hwmon@vger.kernel.org +W: http://hwmon.wiki.kernel.org/ T: quilt http://jdelvare.nerim.net/devel/linux/jdelvare-hwmon/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git S: Maintained @@ -4990,6 +5042,7 @@ F: include/linux/hw_random.h HARDWARE SPINLOCK CORE M: Ohad Ben-Cohen M: Bjorn Andersson +L: linux-remoteproc@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/ohad/hwspinlock.git F: Documentation/hwspinlock.txt @@ -5011,12 +5064,6 @@ T: git git://linuxtv.org/anttip/media_tree.git S: Maintained F: drivers/media/dvb-frontends/hd29l2* -HEWLETT-PACKARD SMART2 RAID DRIVER -L: iss_storagedev@hp.com -S: Orphan -F: Documentation/blockdev/cpqarray.txt -F: drivers/block/cpqarray.* - HEWLETT-PACKARD SMART ARRAY RAID DRIVER (hpsa) M: Don Brace L: iss_storagedev@hp.com @@ -5029,9 +5076,9 @@ F: include/linux/cciss*.h F: include/uapi/linux/cciss*.h HEWLETT-PACKARD SMART CISS RAID DRIVER (cciss) -M: Don Brace +M: Don Brace L: iss_storagedev@hp.com -L: storagedev@pmcs.com +L: esc.storagedev@microsemi.com L: linux-scsi@vger.kernel.org S: Supported F: Documentation/blockdev/cciss.txt @@ -5224,6 +5271,16 @@ F: include/linux/hyperv.h F: tools/hv/ F: Documentation/ABI/stable/sysfs-bus-vmbus +I2C MUXES +M: Peter Rosin +L: linux-i2c@vger.kernel.org +S: Maintained +F: Documentation/i2c/muxes/ +F: Documentation/devicetree/bindings/i2c/i2c-mux* +F: drivers/i2c/i2c-mux.c +F: drivers/i2c/muxes/ +F: include/linux/i2c-mux.h + I2C OVER PARALLEL PORT M: Jean Delvare L: linux-i2c@vger.kernel.org @@ -5448,10 +5505,11 @@ S: Supported F: drivers/idle/i7300_idle.c IEEE 802.15.4 SUBSYSTEM -M: Alexander Aring +M: Alexander Aring L: linux-wpan@vger.kernel.org -W: https://github.com/linux-wpan -T: git git://github.com/linux-wpan/linux-wpan-next.git +W: http://wpan.cakelab.org/ +T: git git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git S: Maintained F: net/ieee802154/ F: net/mac802154/ @@ -5497,7 +5555,7 @@ F: drivers/usb/atm/ueagle-atm.c INA209 HARDWARE MONITOR DRIVER M: Guenter Roeck -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/ina209 F: Documentation/devicetree/bindings/i2c/ina209.txt @@ -5505,7 +5563,7 @@ F: drivers/hwmon/ina209.c INA2XX HARDWARE MONITOR DRIVER M: Guenter Roeck -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/ina2xx F: drivers/hwmon/ina2xx.c @@ -5581,6 +5639,7 @@ F: drivers/input/ F: include/linux/input.h F: include/uapi/linux/input.h F: include/linux/input/ +F: Documentation/devicetree/bindings/input/ INPUT MULTITOUCH (MT) PROTOCOL M: Henrik Rydberg @@ -5692,7 +5751,7 @@ R: Don Skidmore R: Bruce Allan R: John Ronciak R: Mitch Williams -L: intel-wired-lan@lists.osuosl.org +L: intel-wired-lan@lists.osuosl.org (moderated for non-subscribers) W: http://www.intel.com/support/feedback.htm W: http://e1000.sourceforge.net/ Q: http://patchwork.ozlabs.org/project/intel-wired-lan/list/ @@ -5712,6 +5771,16 @@ F: Documentation/networking/i40evf.txt F: drivers/net/ethernet/intel/ F: drivers/net/ethernet/intel/*/ +INTEL RDMA RNIC DRIVER +M: Faisal Latif +R: Chien Tin Tung +R: Mustafa Ismail +R: Shiraz Saleem +R: Tatyana Nikolova +L: linux-rdma@vger.kernel.org +S: Supported +F: drivers/infiniband/hw/i40iw/ + INTEL-MID GPIO DRIVER M: David Cohen L: linux-gpio@vger.kernel.org @@ -5999,7 +6068,7 @@ F: drivers/isdn/hardware/eicon/ IT87 HARDWARE MONITORING DRIVER M: Jean Delvare -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/it87 F: drivers/hwmon/it87.c @@ -6035,7 +6104,7 @@ F: drivers/media/dvb-frontends/ix2505v* JC42.4 TEMPERATURE SENSOR DRIVER M: Guenter Roeck -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: drivers/hwmon/jc42.c F: Documentation/hwmon/jc42 @@ -6085,18 +6154,32 @@ F: drivers/tty/serial/jsm/ K10TEMP HARDWARE MONITORING DRIVER M: Clemens Ladisch -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/k10temp F: drivers/hwmon/k10temp.c K8TEMP HARDWARE MONITORING DRIVER M: Rudolf Marek -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/k8temp F: drivers/hwmon/k8temp.c +KASAN +M: Andrey Ryabinin +R: Alexander Potapenko +R: Dmitry Vyukov +L: kasan-dev@googlegroups.com +S: Maintained +F: arch/*/include/asm/kasan.h +F: arch/*/mm/kasan_init* +F: Documentation/kasan.txt +F: include/linux/kasan.h +F: lib/test_kasan.c +F: mm/kasan/ +F: scripts/Makefile.kasan + KCONFIG M: "Yann E. MORIN" L: linux-kbuild@vger.kernel.org @@ -6320,7 +6403,7 @@ KPROBES M: Ananth N Mavinakayanahalli M: Anil S Keshavamurthy M: "David S. Miller" -M: Masami Hiramatsu +M: Masami Hiramatsu S: Maintained F: Documentation/kprobes.txt F: include/linux/kprobes.h @@ -6596,9 +6679,10 @@ F: drivers/platform/x86/hp_accel.c LIVE PATCHING M: Josh Poimboeuf -M: Seth Jennings +M: Jessica Yu M: Jiri Kosina -M: Vojtech Pavlik +M: Miroslav Benes +R: Petr Mladek S: Maintained F: kernel/livepatch/ F: include/linux/livepatch.h @@ -6624,27 +6708,27 @@ F: net/llc/ LM73 HARDWARE MONITOR DRIVER M: Guillaume Ligneul -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: drivers/hwmon/lm73.c LM78 HARDWARE MONITOR DRIVER M: Jean Delvare -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/lm78 F: drivers/hwmon/lm78.c LM83 HARDWARE MONITOR DRIVER M: Jean Delvare -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/lm83 F: drivers/hwmon/lm83.c LM90 HARDWARE MONITOR DRIVER M: Jean Delvare -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/lm90 F: Documentation/devicetree/bindings/hwmon/lm90.txt @@ -6652,7 +6736,7 @@ F: drivers/hwmon/lm90.c LM95234 HARDWARE MONITOR DRIVER M: Guenter Roeck -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/lm95234 F: drivers/hwmon/lm95234.c @@ -6718,7 +6802,7 @@ F: drivers/scsi/sym53c8xx_2/ LTC4261 HARDWARE MONITOR DRIVER M: Guenter Roeck -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/ltc4261 F: drivers/hwmon/ltc4261.c @@ -6888,28 +6972,28 @@ F: include/uapi/linux/matroxfb.h MAX16065 HARDWARE MONITOR DRIVER M: Guenter Roeck -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/max16065 F: drivers/hwmon/max16065.c MAX20751 HARDWARE MONITOR DRIVER M: Guenter Roeck -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/max20751 F: drivers/hwmon/max20751.c MAX6650 HARDWARE MONITOR AND FAN CONTROLLER DRIVER M: "Hans J. Koch" -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/max6650 F: drivers/hwmon/max6650.c MAX6697 HARDWARE MONITOR DRIVER M: Guenter Roeck -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/max6697 F: Documentation/devicetree/bindings/i2c/max6697.txt @@ -7042,6 +7126,13 @@ F: include/uapi/linux/meye.h F: include/uapi/linux/ivtv* F: include/uapi/linux/uvcvideo.h +MEDIATEK ETHERNET DRIVER +M: Felix Fietkau +M: John Crispin +L: netdev@vger.kernel.org +S: Maintained +F: drivers/net/ethernet/mediatek/ + MEDIATEK MT7601U WIRELESS LAN DRIVER M: Jakub Kicinski L: linux-wireless@vger.kernel.org @@ -7471,7 +7562,7 @@ F: drivers/scsi/NCR_D700.* NCT6775 HARDWARE MONITOR DRIVER M: Guenter Roeck -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/nct6775 F: drivers/hwmon/nct6775.c @@ -7485,7 +7576,7 @@ F: drivers/infiniband/hw/nes/ NETEM NETWORK EMULATOR M: Stephen Hemminger -L: netem@lists.linux-foundation.org +L: netem@lists.linux-foundation.org (moderated for non-subscribers) S: Maintained F: net/sched/sch_netem.c @@ -7539,7 +7630,6 @@ F: net/netrom/ NETRONOME ETHERNET DRIVERS M: Jakub Kicinski -M: Rolf Neugebauer L: oss-drivers@netronome.com S: Maintained F: drivers/net/ethernet/netronome/ @@ -7676,7 +7766,6 @@ F: net/nfc/ F: include/net/nfc/ F: include/uapi/linux/nfc.h F: drivers/nfc/ -F: include/linux/platform_data/microread.h F: include/linux/platform_data/nfcmrvl.h F: include/linux/platform_data/nxp-nci.h F: include/linux/platform_data/pn544.h @@ -7827,6 +7916,11 @@ L: alsa-devel@alsa-project.org (moderated for non-subscribers) S: Maintained F: sound/soc/codecs/tfa9879* +OBJTOOL +M: Josh Poimboeuf +S: Supported +F: tools/objtool/ + OMAP SUPPORT M: Tony Lindgren L: linux-omap@vger.kernel.org @@ -7877,7 +7971,7 @@ S: Maintained F: arch/arm/*omap*/*clock* OMAP POWER MANAGEMENT SUPPORT -M: Kevin Hilman +M: Kevin Hilman L: linux-omap@vger.kernel.org S: Maintained F: arch/arm/*omap*/*pm* @@ -7981,7 +8075,7 @@ F: arch/arm/*omap*/usb* OMAP GPIO DRIVER M: Grygorii Strashko M: Santosh Shilimkar -M: Kevin Hilman +M: Kevin Hilman L: linux-omap@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/gpio/gpio-omap.txt @@ -8158,6 +8252,14 @@ S: Supported F: fs/overlayfs/ F: Documentation/filesystems/overlayfs.txt +ORANGEFS FILESYSTEM +M: Mike Marshall +L: pvfs2-developers@beowulf-underground.org (subscribers-only) +T: git git://git.kernel.org/pub/scm/linux/kernel/git/hubcap/linux.git +S: Supported +F: fs/orangefs/ +F: Documentation/filesystems/orangefs.txt + P54 WIRELESS DRIVER M: Christian Lamparter L: linux-wireless@vger.kernel.org @@ -8200,6 +8302,13 @@ S: Maintained F: Documentation/mn10300/ F: arch/mn10300/ +PARALLEL LCD/KEYPAD PANEL DRIVER +M: Willy Tarreau +M: Ksenija Stanojevic +S: Odd Fixes +F: Documentation/misc-devices/lcd-panel-cgram.txt +F: drivers/misc/panel.c + PARALLEL PORT SUBSYSTEM M: Sudip Mukherjee M: Sudip Mukherjee @@ -8251,7 +8360,7 @@ F: drivers/video/logo/logo_parisc* PC87360 HARDWARE MONITORING DRIVER M: Jim Cromie -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/pc87360 F: drivers/hwmon/pc87360.c @@ -8263,7 +8372,7 @@ F: drivers/char/pc8736x_gpio.c PC87427 HARDWARE MONITORING DRIVER M: Jean Delvare -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/pc87427 F: drivers/hwmon/pc87427.c @@ -8291,6 +8400,15 @@ L: linux-pci@vger.kernel.org S: Supported F: Documentation/PCI/pci-error-recovery.txt +PCI ENHANCED ERROR HANDLING (EEH) FOR POWERPC +M: Russell Currey +L: linuxppc-dev@lists.ozlabs.org +S: Supported +F: Documentation/powerpc/eeh-pci-error-recovery.txt +F: arch/powerpc/kernel/eeh*.c +F: arch/powerpc/platforms/*/eeh*.c +F: arch/powerpc/include/*/eeh*.h + PCI SUBSYSTEM M: Bjorn Helgaas L: linux-pci@vger.kernel.org @@ -8490,7 +8608,7 @@ F: include/crypto/pcrypt.h PER-CPU MEMORY ALLOCATOR M: Tejun Heo -M: Christoph Lameter +M: Christoph Lameter T: git git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu.git S: Maintained F: include/linux/percpu*.h @@ -8594,6 +8712,8 @@ F: drivers/pinctrl/sh-pfc/ PIN CONTROLLER - SAMSUNG M: Tomasz Figa +M: Krzysztof Kozlowski +M: Sylwester Nawrocki L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) S: Maintained @@ -8634,8 +8754,8 @@ F: drivers/rtc/rtc-puv3.c PMBUS HARDWARE MONITORING DRIVERS M: Guenter Roeck -L: lm-sensors@lm-sensors.org -W: http://www.lm-sensors.org/ +L: linux-hwmon@vger.kernel.org +W: http://hwmon.wiki.kernel.org/ W: http://www.roeck-us.net/linux/drivers/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git S: Maintained @@ -8840,7 +8960,7 @@ F: drivers/media/usb/pwc/* PWM FAN DRIVER M: Kamil Debski -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Supported F: Documentation/devicetree/bindings/hwmon/pwm-fan.txt F: Documentation/hwmon/pwm-fan @@ -9022,6 +9142,13 @@ T: git git://github.com/KrasnikovEugene/wcn36xx.git S: Supported F: drivers/net/wireless/ath/wcn36xx/ +QEMU MACHINE EMULATOR AND VIRTUALIZER SUPPORT +M: Gabriel Somlo +M: "Michael S. Tsirkin" +L: qemu-devel@nongnu.org +S: Maintained +F: drivers/firmware/qemu_fw_cfg.c + RADOS BLOCK DEVICE (RBD) M: Ilya Dryomov M: Sage Weil @@ -9130,10 +9257,20 @@ S: Maintained F: drivers/net/ethernet/rdc/r6040.c RDS - RELIABLE DATAGRAM SOCKETS -M: Chien Yen +M: Santosh Shilimkar +L: netdev@vger.kernel.org +L: linux-rdma@vger.kernel.org L: rds-devel@oss.oracle.com (moderated for non-subscribers) +W: https://oss.oracle.com/projects/rds/ S: Supported F: net/rds/ +F: Documentation/networking/rds.txt + +RDMAVT - RDMA verbs software +M: Dennis Dalessandro +L: linux-rdma@vger.kernel.org +S: Supported +F: drivers/infiniband/sw/rdmavt READ-COPY UPDATE (RCU) M: "Paul E. McKenney" @@ -9187,6 +9324,7 @@ F: include/linux/regmap.h REMOTE PROCESSOR (REMOTEPROC) SUBSYSTEM M: Ohad Ben-Cohen M: Bjorn Andersson +L: linux-remoteproc@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/ohad/remoteproc.git S: Maintained F: drivers/remoteproc/ @@ -9196,6 +9334,7 @@ F: include/linux/remoteproc.h REMOTE PROCESSOR MESSAGING (RPMSG) SUBSYSTEM M: Ohad Ben-Cohen M: Bjorn Andersson +L: linux-remoteproc@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/ohad/rpmsg.git S: Maintained F: drivers/rpmsg/ @@ -9534,6 +9673,7 @@ F: drivers/media/i2c/s5k5baf.c SAMSUNG S3FWRN5 NFC DRIVER M: Robert Baldyga +M: Krzysztof Opasiak L: linux-nfc@lists.01.org (moderated for non-subscribers) S: Supported F: drivers/nfc/s3fwrn5 @@ -9596,9 +9736,9 @@ F: Documentation/devicetree/bindings/net/snps,dwc-qos-ethernet.txt F: drivers/net/ethernet/synopsys/dwc_eth_qos.c SYNOPSYS DESIGNWARE I2C DRIVER -M: Andy Shevchenko M: Jarkko Nikula -M: Mika Westerberg +R: Andy Shevchenko +R: Mika Westerberg L: linux-i2c@vger.kernel.org S: Maintained F: drivers/i2c/busses/i2c-designware-* @@ -9764,10 +9904,12 @@ S: Maintained F: drivers/mmc/host/sdricoh_cs.c SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) DRIVER +M: Adrian Hunter L: linux-mmc@vger.kernel.org -S: Orphan -F: drivers/mmc/host/sdhci.* -F: drivers/mmc/host/sdhci-pltfm.[ch] +T: git git://git.infradead.org/users/ahunter/linux-sdhci.git +S: Maintained +F: drivers/mmc/host/sdhci* +F: include/linux/mmc/sdhci* SECURE COMPUTING M: Kees Cook @@ -10017,7 +10159,7 @@ F: arch/arm/mach-s3c24xx/bast-irq.c TI DAVINCI MACHINE SUPPORT M: Sekhar Nori -M: Kevin Hilman +M: Kevin Hilman T: git git://gitorious.org/linux-davinci/linux-davinci.git Q: http://patchwork.kernel.org/project/linux-davinci/list/ S: Supported @@ -10148,28 +10290,28 @@ F: Documentation/devicetree/bindings/media/i2c/nokia,smia.txt SMM665 HARDWARE MONITOR DRIVER M: Guenter Roeck -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/smm665 F: drivers/hwmon/smm665.c SMSC EMC2103 HARDWARE MONITOR DRIVER M: Steve Glendinning -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/emc2103 F: drivers/hwmon/emc2103.c SMSC SCH5627 HARDWARE MONITOR DRIVER M: Hans de Goede -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Supported F: Documentation/hwmon/sch5627 F: drivers/hwmon/sch5627.c SMSC47B397 HARDWARE MONITOR DRIVER M: Jean Delvare -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/smsc47b397 F: drivers/hwmon/smsc47b397.c @@ -10219,7 +10361,7 @@ F: drivers/media/pci/solo6x10/ SOFTWARE RAID (Multiple Disks) SUPPORT M: Shaohua Li L: linux-raid@vger.kernel.org -T: git git://neil.brown.name/md +T: git git://git.kernel.org/pub/scm/linux/kernel/git/shli/md.git S: Supported F: drivers/md/ F: include/linux/raid/ @@ -10461,11 +10603,6 @@ W: http://wiki.laptop.org/go/DCON S: Maintained F: drivers/staging/olpc_dcon/ -STAGING - PARALLEL LCD/KEYPAD PANEL DRIVER -M: Willy Tarreau -S: Odd Fixes -F: drivers/staging/panel/ - STAGING - REALTEK RTL8712U DRIVERS M: Larry Finger M: Florian Schilhabel . @@ -11020,8 +11157,8 @@ F: include/uapi/linux/tipc*.h F: net/tipc/ TILE ARCHITECTURE -M: Chris Metcalf -W: http://www.ezchip.com/scm/ +M: Chris Metcalf +W: http://www.mellanox.com/repository/solutions/tile-scm/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile.git S: Supported F: arch/tile/ @@ -11110,7 +11247,7 @@ F: include/linux/mmc/sh_mobile_sdhi.h TMP401 HARDWARE MONITOR DRIVER M: Guenter Roeck -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/tmp401 F: drivers/hwmon/tmp401.c @@ -11231,12 +11368,13 @@ S: Maintained F: drivers/scsi/u14-34f.c UBI FILE SYSTEM (UBIFS) +M: Richard Weinberger M: Artem Bityutskiy M: Adrian Hunter L: linux-mtd@lists.infradead.org T: git git://git.infradead.org/ubifs-2.6.git W: http://www.linux-mtd.infradead.org/doc/ubifs.html -S: Maintained +S: Supported F: Documentation/filesystems/ubifs.txt F: fs/ubifs/ @@ -11301,7 +11439,6 @@ F: include/linux/cdrom.h F: include/uapi/linux/cdrom.h UNISYS S-PAR DRIVERS -M: Benjamin Romer M: David Kershner L: sparmaintainer@unisys.com (Unisys internal) S: Supported @@ -11411,6 +11548,13 @@ S: Maintained F: drivers/usb/host/isp116x* F: include/linux/usb/isp116x.h +USB LAN78XX ETHERNET DRIVER +M: Woojung Huh +M: Microchip Linux Driver Support +L: netdev@vger.kernel.org +S: Maintained +F: drivers/net/usb/lan78xx.* + USB MASS STORAGE DRIVER M: Matthew Dharm L: linux-usb@vger.kernel.org @@ -11856,14 +12000,14 @@ F: Documentation/networking/vrf.txt VT1211 HARDWARE MONITOR DRIVER M: Juerg Haefliger -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/vt1211 F: drivers/hwmon/vt1211.c VT8231 HARDWARE MONITOR DRIVER M: Roger Lucas -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: drivers/hwmon/vt8231.c @@ -11882,21 +12026,21 @@ F: drivers/w1/ W83791D HARDWARE MONITORING DRIVER M: Marc Hulsman -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/w83791d F: drivers/hwmon/w83791d.c W83793 HARDWARE MONITORING DRIVER M: Rudolf Marek -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: Documentation/hwmon/w83793 F: drivers/hwmon/w83793.c W83795 HARDWARE MONITORING DRIVER M: Jean Delvare -L: lm-sensors@lm-sensors.org +L: linux-hwmon@vger.kernel.org S: Maintained F: drivers/hwmon/w83795.c @@ -11941,6 +12085,12 @@ M: David Härdeman S: Maintained F: drivers/media/rc/winbond-cir.c +WINSYSTEMS EBC-C384 WATCHDOG DRIVER +M: William Breathitt Gray +L: linux-watchdog@vger.kernel.org +S: Maintained +F: drivers/watchdog/ebc-c384_wdt.c + WINSYSTEMS WS16C48 GPIO DRIVER M: William Breathitt Gray L: linux-gpio@vger.kernel.org @@ -12072,9 +12222,9 @@ S: Maintained F: drivers/media/tuners/tuner-xc2028.* XEN HYPERVISOR INTERFACE -M: Konrad Rzeszutek Wilk M: Boris Ostrovsky M: David Vrabel +M: Juergen Gross L: xen-devel@lists.xenproject.org (moderated for non-subscribers) T: git git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip.git S: Supported @@ -12086,16 +12236,16 @@ F: include/xen/ F: include/uapi/xen/ XEN HYPERVISOR ARM -M: Stefano Stabellini +M: Stefano Stabellini L: xen-devel@lists.xenproject.org (moderated for non-subscribers) -S: Supported +S: Maintained F: arch/arm/xen/ F: arch/arm/include/asm/xen/ XEN HYPERVISOR ARM64 -M: Stefano Stabellini +M: Stefano Stabellini L: xen-devel@lists.xenproject.org (moderated for non-subscribers) -S: Supported +S: Maintained F: arch/arm64/xen/ F: arch/arm64/include/asm/xen/ diff --git a/Makefile b/Makefile index 6798c6b4775de48c949240dff1b6ac9f061251d4..1d0aef03eae7fae72f70016575c2f54502706bbb 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 4 -PATCHLEVEL = 5 +PATCHLEVEL = 6 SUBLEVEL = 0 -EXTRAVERSION = +EXTRAVERSION = -rc3 NAME = Blurry Fish Butt # *DOCUMENTATION* @@ -365,6 +365,7 @@ LDFLAGS_MODULE = CFLAGS_KERNEL = AFLAGS_KERNEL = CFLAGS_GCOV = -fprofile-arcs -ftest-coverage +CFLAGS_KCOV = -fsanitize-coverage=trace-pc # Use USERINCLUDE when you must reference the UAPI directories only. @@ -411,7 +412,7 @@ export MAKE AWK GENKSYMS INSTALLKERNEL PERL PYTHON UTS_MACHINE export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS -export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE CFLAGS_GCOV CFLAGS_KASAN CFLAGS_UBSAN +export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE CFLAGS_GCOV CFLAGS_KCOV CFLAGS_KASAN CFLAGS_UBSAN export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_LDFLAGS_MODULE export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL @@ -673,6 +674,14 @@ endif endif KBUILD_CFLAGS += $(stackp-flag) +ifdef CONFIG_KCOV + ifeq ($(call cc-option, $(CFLAGS_KCOV)),) + $(warning Cannot use CONFIG_KCOV: \ + -fsanitize-coverage=trace-pc is not supported by compiler) + CFLAGS_KCOV = + endif +endif + ifeq ($(cc-name),clang) KBUILD_CPPFLAGS += $(call cc-option,-Qunused-arguments,) KBUILD_CPPFLAGS += $(call cc-option,-Wno-unknown-warning-option,) @@ -773,6 +782,9 @@ KBUILD_CFLAGS += $(call cc-option,-Werror=strict-prototypes) # Prohibit date/time macros, which would make the build non-deterministic KBUILD_CFLAGS += $(call cc-option,-Werror=date-time) +# enforce correct pointer usage +KBUILD_CFLAGS += $(call cc-option,-Werror=incompatible-pointer-types) + # use the deterministic mode of AR if available KBUILD_ARFLAGS := $(call ar-option,D) @@ -993,7 +1005,21 @@ prepare0: archprepare FORCE $(Q)$(MAKE) $(build)=. # All the preparing.. -prepare: prepare0 +prepare: prepare0 prepare-objtool + +ifdef CONFIG_STACK_VALIDATION + has_libelf := $(shell echo "int main() {}" | $(HOSTCC) -xc -o /dev/null -lelf - &> /dev/null && echo 1 || echo 0) + ifeq ($(has_libelf),1) + objtool_target := tools/objtool FORCE + else + $(warning "Cannot use CONFIG_STACK_VALIDATION, please install libelf-dev or elfutils-libelf-devel") + SKIP_STACK_VALIDATION := 1 + export SKIP_STACK_VALIDATION + endif +endif + +PHONY += prepare-objtool +prepare-objtool: $(objtool_target) # Generate some files # --------------------------------------------------------------------------- @@ -1516,11 +1542,11 @@ image_name: # Clear a bunch of variables before executing the submake tools/: FORCE $(Q)mkdir -p $(objtree)/tools - $(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(filter --j% -j,$(MAKEFLAGS))" O=$(O) subdir=tools -C $(src)/tools/ + $(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(filter --j% -j,$(MAKEFLAGS))" O=$(shell cd $(objtree) && /bin/pwd) subdir=tools -C $(src)/tools/ tools/%: FORCE $(Q)mkdir -p $(objtree)/tools - $(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(filter --j% -j,$(MAKEFLAGS))" O=$(O) subdir=tools -C $(src)/tools/ $* + $(Q)$(MAKE) LDFLAGS= MAKEFLAGS="$(filter --j% -j,$(MAKEFLAGS))" O=$(shell cd $(objtree) && /bin/pwd) subdir=tools -C $(src)/tools/ $* # Single targets # --------------------------------------------------------------------------- diff --git a/REPORTING-BUGS b/REPORTING-BUGS index 0cb8cdfa63bcf0837582d5db2a443d511e5ddf48..914baf9cf5fa1cf2faaadfd910fdb6760d9b74f0 100644 --- a/REPORTING-BUGS +++ b/REPORTING-BUGS @@ -9,7 +9,7 @@ Please see https://www.kernel.org/ for a list of supported kernels. Any kernel marked with [EOL] is "end of life" and will not have any fixes backported to it. -If you've found a bug on a kernel version isn't listed on kernel.org, +If you've found a bug on a kernel version that isn't listed on kernel.org, contact your Linux distribution or embedded vendor for support. Alternatively, you can attempt to run one of the supported stable or -rc kernels, and see if you can reproduce the bug on that. It's preferable diff --git a/arch/Kconfig b/arch/Kconfig index f6b649d88ec82ec44913d6a81ee0136498d88b92..81869a5e7e174ae470ba7746d88f8cdb35065c36 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -583,6 +583,12 @@ config HAVE_COPY_THREAD_TLS normal C parameter passing, rather than extracting the syscall argument from pt_regs. +config HAVE_STACK_VALIDATION + bool + help + Architecture supports the 'objtool check' host tool command, which + performs compile-time stack metadata validation. + # # ABI hall of shame # diff --git a/arch/alpha/include/asm/checksum.h b/arch/alpha/include/asm/checksum.h index d3854bbf0a9e6ab0bf430b96d48008d2d69f24ae..f2bbdd2ace511464bd9c6ca0a671a0aedca6bc5c 100644 --- a/arch/alpha/include/asm/checksum.h +++ b/arch/alpha/include/asm/checksum.h @@ -13,14 +13,11 @@ extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl); * computes the checksum of the TCP/UDP pseudo-header * returns a 16-bit checksum, already complemented */ -extern __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum); +__sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, + __u32 len, __u8 proto, __wsum sum); __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, - unsigned short len, unsigned short proto, - __wsum sum); + __u32 len, __u8 proto, __wsum sum); /* * computes the checksum of a memory block at buff, length len, @@ -70,6 +67,5 @@ static inline __sum16 csum_fold(__wsum csum) #define _HAVE_ARCH_IPV6_CSUM extern __sum16 csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, - __u32 len, unsigned short proto, - __wsum sum); + __u32 len, __u8 proto, __wsum sum); #endif diff --git a/arch/alpha/include/asm/uaccess.h b/arch/alpha/include/asm/uaccess.h index 9b0d40093c9a377ff142ffe2241c44b152e41ffd..c419b43c461dc3326638870919d8f00ec95e7ae6 100644 --- a/arch/alpha/include/asm/uaccess.h +++ b/arch/alpha/include/asm/uaccess.h @@ -483,7 +483,13 @@ struct exception_table_entry (pc) + (_fixup)->fixup.bits.nextinsn; \ }) -#define ARCH_HAS_SORT_EXTABLE -#define ARCH_HAS_SEARCH_EXTABLE +#define ARCH_HAS_RELATIVE_EXTABLE + +#define swap_ex_entry_fixup(a, b, tmp, delta) \ + do { \ + (a)->fixup.unit = (b)->fixup.unit; \ + (b)->fixup.unit = (tmp).fixup.unit; \ + } while (0) + #endif /* __ALPHA_UACCESS_H */ diff --git a/arch/alpha/include/uapi/asm/socket.h b/arch/alpha/include/uapi/asm/socket.h index c5fb9e6bc3a51df64245d31987373aa37930888c..9e46d6e656d978cd203abe4202f8b1ee353bea90 100644 --- a/arch/alpha/include/uapi/asm/socket.h +++ b/arch/alpha/include/uapi/asm/socket.h @@ -95,4 +95,6 @@ #define SO_ATTACH_REUSEPORT_CBPF 51 #define SO_ATTACH_REUSEPORT_EBPF 52 +#define SO_CNX_ADVICE 53 + #endif /* _UAPI_ASM_SOCKET_H */ diff --git a/arch/alpha/kernel/pci-noop.c b/arch/alpha/kernel/pci-noop.c index 2b1f4a1e92723bf67450c3d3ba4006e792971c70..8e735b5e56bd338873d17173960da02dc3cd260a 100644 --- a/arch/alpha/kernel/pci-noop.c +++ b/arch/alpha/kernel/pci-noop.c @@ -123,44 +123,6 @@ static void *alpha_noop_alloc_coherent(struct device *dev, size_t size, return ret; } -static void alpha_noop_free_coherent(struct device *dev, size_t size, - void *cpu_addr, dma_addr_t dma_addr, - struct dma_attrs *attrs) -{ - free_pages((unsigned long)cpu_addr, get_order(size)); -} - -static dma_addr_t alpha_noop_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t size, - enum dma_data_direction dir, - struct dma_attrs *attrs) -{ - return page_to_pa(page) + offset; -} - -static int alpha_noop_map_sg(struct device *dev, struct scatterlist *sgl, int nents, - enum dma_data_direction dir, struct dma_attrs *attrs) -{ - int i; - struct scatterlist *sg; - - for_each_sg(sgl, sg, nents, i) { - void *va; - - BUG_ON(!sg_page(sg)); - va = sg_virt(sg); - sg_dma_address(sg) = (dma_addr_t)virt_to_phys(va); - sg_dma_len(sg) = sg->length; - } - - return nents; -} - -static int alpha_noop_mapping_error(struct device *dev, dma_addr_t dma_addr) -{ - return 0; -} - static int alpha_noop_supported(struct device *dev, u64 mask) { return mask < 0x00ffffffUL ? 0 : 1; @@ -168,10 +130,10 @@ static int alpha_noop_supported(struct device *dev, u64 mask) struct dma_map_ops alpha_noop_ops = { .alloc = alpha_noop_alloc_coherent, - .free = alpha_noop_free_coherent, - .map_page = alpha_noop_map_page, - .map_sg = alpha_noop_map_sg, - .mapping_error = alpha_noop_mapping_error, + .free = dma_noop_free_coherent, + .map_page = dma_noop_map_page, + .map_sg = dma_noop_map_sg, + .mapping_error = dma_noop_mapping_error, .dma_supported = alpha_noop_supported, }; diff --git a/arch/alpha/lib/checksum.c b/arch/alpha/lib/checksum.c index 199f6efa83faa9d809faec8aab319672dc4eed4f..377f9e34eb9709631e50aa20ce87417ebdeac3a8 100644 --- a/arch/alpha/lib/checksum.c +++ b/arch/alpha/lib/checksum.c @@ -42,9 +42,7 @@ static inline unsigned short from64to16(unsigned long x) * returns a 16-bit checksum, already complemented. */ __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum) + __u32 len, __u8 proto, __wsum sum) { return (__force __sum16)~from64to16( (__force u64)saddr + (__force u64)daddr + @@ -52,9 +50,7 @@ __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, } __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum) + __u32 len, __u8 proto, __wsum sum) { unsigned long result; diff --git a/arch/alpha/mm/Makefile b/arch/alpha/mm/Makefile index c993d3f93cf6a40b15b557f4a41349ac3c7dc08c..5a98079364110bc6eb47f2a9ff0610e917b9a8d8 100644 --- a/arch/alpha/mm/Makefile +++ b/arch/alpha/mm/Makefile @@ -4,6 +4,6 @@ ccflags-y := -Werror -obj-y := init.o fault.o extable.o +obj-y := init.o fault.o obj-$(CONFIG_DISCONTIGMEM) += numa.o diff --git a/arch/alpha/mm/extable.c b/arch/alpha/mm/extable.c deleted file mode 100644 index 813c9b63c0e17de3577b5924b54072ad382244d9..0000000000000000000000000000000000000000 --- a/arch/alpha/mm/extable.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * linux/arch/alpha/mm/extable.c - */ - -#include -#include -#include - -static inline unsigned long ex_to_addr(const struct exception_table_entry *x) -{ - return (unsigned long)&x->insn + x->insn; -} - -static void swap_ex(void *a, void *b, int size) -{ - struct exception_table_entry *ex_a = a, *ex_b = b; - unsigned long addr_a = ex_to_addr(ex_a), addr_b = ex_to_addr(ex_b); - unsigned int t = ex_a->fixup.unit; - - ex_a->fixup.unit = ex_b->fixup.unit; - ex_b->fixup.unit = t; - ex_a->insn = (int)(addr_b - (unsigned long)&ex_a->insn); - ex_b->insn = (int)(addr_a - (unsigned long)&ex_b->insn); -} - -/* - * The exception table needs to be sorted so that the binary - * search that we use to find entries in it works properly. - * This is used both for the kernel exception table and for - * the exception tables of modules that get loaded. - */ -static int cmp_ex(const void *a, const void *b) -{ - const struct exception_table_entry *x = a, *y = b; - - /* avoid overflow */ - if (ex_to_addr(x) > ex_to_addr(y)) - return 1; - if (ex_to_addr(x) < ex_to_addr(y)) - return -1; - return 0; -} - -void sort_extable(struct exception_table_entry *start, - struct exception_table_entry *finish) -{ - sort(start, finish - start, sizeof(struct exception_table_entry), - cmp_ex, swap_ex); -} - -#ifdef CONFIG_MODULES -/* - * Any entry referring to the module init will be at the beginning or - * the end. - */ -void trim_init_extable(struct module *m) -{ - /*trim the beginning*/ - while (m->num_exentries && - within_module_init(ex_to_addr(&m->extable[0]), m)) { - m->extable++; - m->num_exentries--; - } - /*trim the end*/ - while (m->num_exentries && - within_module_init(ex_to_addr(&m->extable[m->num_exentries-1]), - m)) - m->num_exentries--; -} -#endif /* CONFIG_MODULES */ - -const struct exception_table_entry * -search_extable(const struct exception_table_entry *first, - const struct exception_table_entry *last, - unsigned long value) -{ - while (first <= last) { - const struct exception_table_entry *mid; - unsigned long mid_value; - - mid = (last - first) / 2 + first; - mid_value = ex_to_addr(mid); - if (mid_value == value) - return mid; - else if (mid_value < value) - first = mid+1; - else - last = mid-1; - } - - return NULL; -} diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index 07a5cb944d4ff730d1015cdcbff9ffc82d3905f8..12d0284a46e54a6cc74edde0fb5956924673a183 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -391,7 +391,7 @@ config ARC_HAS_LLSC config ARC_STAR_9000923308 bool "Workaround for llock/scond livelock" - default y + default n depends on ISA_ARCV2 && SMP && ARC_HAS_LLSC config ARC_HAS_SWAPE @@ -462,7 +462,6 @@ config ARC_HAS_PAE40 bool "Support for the 40-bit Physical Address Extension" default n depends on ISA_ARCV2 - select HIGHMEM help Enable access to physical memory beyond 4G, only supported on ARC cores with 40 bit Physical Addressing support @@ -473,6 +472,9 @@ config ARCH_PHYS_ADDR_T_64BIT config ARCH_DMA_ADDR_T_64BIT bool +config ARC_PLAT_NEEDS_PHYS_TO_DMA + bool + config ARC_CURR_IN_REG bool "Dedicate Register r25 for current_task pointer" default y @@ -591,7 +593,6 @@ config PCI_SYSCALL def_bool PCI source "drivers/pci/Kconfig" -source "drivers/pci/pcie/Kconfig" endmenu diff --git a/arch/arc/Makefile b/arch/arc/Makefile index c8230f3395f281f9c11ee6de130137d84e1bb543..def69e347b2da7c880e716179f4804407005feb1 100644 --- a/arch/arc/Makefile +++ b/arch/arc/Makefile @@ -9,7 +9,11 @@ UTS_MACHINE := arc ifeq ($(CROSS_COMPILE),) +ifndef CONFIG_CPU_BIG_ENDIAN CROSS_COMPILE := arc-linux- +else +CROSS_COMPILE := arceb-linux- +endif endif KBUILD_DEFCONFIG := nsim_700_defconfig @@ -18,6 +22,20 @@ cflags-y += -fno-common -pipe -fno-builtin -D__linux__ cflags-$(CONFIG_ISA_ARCOMPACT) += -mA7 cflags-$(CONFIG_ISA_ARCV2) += -mcpu=archs +is_700 = $(shell $(CC) -dM -E - < /dev/null | grep -q "ARC700" && echo 1 || echo 0) + +ifdef CONFIG_ISA_ARCOMPACT +ifeq ($(is_700), 0) + $(error Toolchain not configured for ARCompact builds) +endif +endif + +ifdef CONFIG_ISA_ARCV2 +ifeq ($(is_700), 1) + $(error Toolchain not configured for ARCv2 builds) +endif +endif + ifdef CONFIG_ARC_CURR_IN_REG # For a global register defintion, make sure it gets passed to every file # We had a customer reported bug where some code built in kernel was NOT using @@ -58,7 +76,9 @@ endif ifndef CONFIG_CC_OPTIMIZE_FOR_SIZE # Generic build system uses -O2, we want -O3 # Note: No need to add to cflags-y as that happens anyways -ARCH_CFLAGS += -O3 +# +# Disable the false maybe-uninitialized warings gcc spits out at -O3 +ARCH_CFLAGS += -O3 $(call cc-disable-warning,maybe-uninitialized,) endif # small data is default for elf32 tool-chain. If not usable, disable it diff --git a/arch/arc/boot/dts/nsim_hs.dts b/arch/arc/boot/dts/nsim_hs.dts index fc81879bc1f5800e5efe8eb43395eb2c5509f481..f46633eeb06b86453868862b989fd36623a05c11 100644 --- a/arch/arc/boot/dts/nsim_hs.dts +++ b/arch/arc/boot/dts/nsim_hs.dts @@ -35,7 +35,8 @@ #address-cells = <1>; #size-cells = <1>; - /* only perip space at end of low mem accessible */ + /* only perip space at end of low mem accessible + bus addr, parent bus addr, size */ ranges = <0x80000000 0x0 0x80000000 0x80000000>; core_intc: core-interrupt-controller { diff --git a/arch/arc/boot/dts/nsimosci.dts b/arch/arc/boot/dts/nsimosci.dts index 1c169dc74ad1399685e0eb965bb94da5562327d2..d94b4ce516ad4015d4de1e13487a79212c0ada61 100644 --- a/arch/arc/boot/dts/nsimosci.dts +++ b/arch/arc/boot/dts/nsimosci.dts @@ -65,10 +65,9 @@ }; eth0: ethernet@f0003000 { - compatible = "snps,oscilan"; + compatible = "ezchip,nps-mgt-enet"; reg = <0xf0003000 0x44>; - interrupts = <7>, <8>; - interrupt-names = "rx", "tx"; + interrupts = <7>; }; }; }; diff --git a/arch/arc/boot/dts/nsimosci_hs.dts b/arch/arc/boot/dts/nsimosci_hs.dts index d64a96f8515ada58b27599122d775960889e2a3f..034a3139c1e23bfab51cbabf5c2f5d4d343982e7 100644 --- a/arch/arc/boot/dts/nsimosci_hs.dts +++ b/arch/arc/boot/dts/nsimosci_hs.dts @@ -65,10 +65,9 @@ }; eth0: ethernet@f0003000 { - compatible = "snps,oscilan"; + compatible = "ezchip,nps-mgt-enet"; reg = <0xf0003000 0x44>; - interrupts = <25>, <26>; - interrupt-names = "rx", "tx"; + interrupts = <25>; }; arcpct0: pct { diff --git a/arch/arc/boot/dts/nsimosci_hs_idu.dts b/arch/arc/boot/dts/nsimosci_hs_idu.dts index f6bf0ca95a5724c087dc0e762f054ba38d1b2fc2..8a1297e0254050fb16579bad03b764f0c92316ab 100644 --- a/arch/arc/boot/dts/nsimosci_hs_idu.dts +++ b/arch/arc/boot/dts/nsimosci_hs_idu.dts @@ -85,11 +85,10 @@ }; eth0: ethernet@f0003000 { - compatible = "snps,oscilan"; + compatible = "ezchip,nps-mgt-enet"; reg = <0xf0003000 0x44>; interrupt-parent = <&idu_intc>; - interrupts = <1 2>, <2 2>; - interrupt-names = "rx", "tx"; + interrupts = <1 2>; }; arcpct0: pct { diff --git a/arch/arc/configs/axs101_defconfig b/arch/arc/configs/axs101_defconfig index 5d4e2a07ad3eb8d11c605f385b881769d44b16ae..6cdffea3a914650eafd5ce4baf1da178043d02e5 100644 --- a/arch/arc/configs/axs101_defconfig +++ b/arch/arc/configs/axs101_defconfig @@ -1,4 +1,3 @@ -CONFIG_CROSS_COMPILE="arc-linux-" CONFIG_DEFAULT_HOSTNAME="ARCLinux" # CONFIG_SWAP is not set CONFIG_SYSVIPC=y diff --git a/arch/arc/configs/axs103_defconfig b/arch/arc/configs/axs103_defconfig index 87ee46b237ef7baa6dc5008f968e5c914d03aee4..491b3b5f22bdcad4e787f9770448de4544241a53 100644 --- a/arch/arc/configs/axs103_defconfig +++ b/arch/arc/configs/axs103_defconfig @@ -1,4 +1,3 @@ -CONFIG_CROSS_COMPILE="arc-linux-" CONFIG_DEFAULT_HOSTNAME="ARCLinux" # CONFIG_SWAP is not set CONFIG_SYSVIPC=y @@ -43,6 +42,7 @@ CONFIG_DEVTMPFS=y # CONFIG_STANDALONE is not set # CONFIG_PREVENT_FIRMWARE_BUILD is not set # CONFIG_FIRMWARE_IN_KERNEL is not set +CONFIG_BLK_DEV_LOOP=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_NETDEVICES=y diff --git a/arch/arc/configs/axs103_smp_defconfig b/arch/arc/configs/axs103_smp_defconfig index d80daf4f7e735aa3787df6f75957c2b9a273b361..b25ee73b2e79a7967bfe9c31b0949ff9ece52b4d 100644 --- a/arch/arc/configs/axs103_smp_defconfig +++ b/arch/arc/configs/axs103_smp_defconfig @@ -1,4 +1,3 @@ -CONFIG_CROSS_COMPILE="arc-linux-" CONFIG_DEFAULT_HOSTNAME="ARCLinux" # CONFIG_SWAP is not set CONFIG_SYSVIPC=y @@ -44,6 +43,7 @@ CONFIG_DEVTMPFS=y # CONFIG_STANDALONE is not set # CONFIG_PREVENT_FIRMWARE_BUILD is not set # CONFIG_FIRMWARE_IN_KERNEL is not set +CONFIG_BLK_DEV_LOOP=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_NETDEVICES=y diff --git a/arch/arc/configs/nsim_700_defconfig b/arch/arc/configs/nsim_700_defconfig index f41095340b6a7a8662fc4e51e16e39524f359ae7..7314f538847bd13cf75ee94689b2612c19045e1a 100644 --- a/arch/arc/configs/nsim_700_defconfig +++ b/arch/arc/configs/nsim_700_defconfig @@ -1,4 +1,3 @@ -CONFIG_CROSS_COMPILE="arc-linux-" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_DEFAULT_HOSTNAME="ARCLinux" # CONFIG_SWAP is not set diff --git a/arch/arc/configs/nsim_hs_defconfig b/arch/arc/configs/nsim_hs_defconfig index cfaa33cb59217c6261667ec4d51b2762fea985ab..a99dc7a3f0af5b523097c4370e88d6349f9eb0e2 100644 --- a/arch/arc/configs/nsim_hs_defconfig +++ b/arch/arc/configs/nsim_hs_defconfig @@ -1,4 +1,3 @@ -CONFIG_CROSS_COMPILE="arc-linux-" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_DEFAULT_HOSTNAME="ARCLinux" # CONFIG_SWAP is not set diff --git a/arch/arc/configs/nsim_hs_smp_defconfig b/arch/arc/configs/nsim_hs_smp_defconfig index bb2a8dc778b5be48943f25f4415abbe73c476969..59f221fc9a41c8a4d1b9931fc5502709be48b740 100644 --- a/arch/arc/configs/nsim_hs_smp_defconfig +++ b/arch/arc/configs/nsim_hs_smp_defconfig @@ -1,4 +1,3 @@ -CONFIG_CROSS_COMPILE="arc-linux-" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_DEFAULT_HOSTNAME="ARCLinux" # CONFIG_SWAP is not set diff --git a/arch/arc/configs/nsimosci_defconfig b/arch/arc/configs/nsimosci_defconfig index 646182e93753af74110471f7739fab2454246b1b..42bafa552498fb5b65af2ca8ac00853d0ad562e3 100644 --- a/arch/arc/configs/nsimosci_defconfig +++ b/arch/arc/configs/nsimosci_defconfig @@ -1,4 +1,3 @@ -CONFIG_CROSS_COMPILE="arc-linux-" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_DEFAULT_HOSTNAME="ARCLinux" # CONFIG_SWAP is not set @@ -39,6 +38,7 @@ CONFIG_DEVTMPFS=y # CONFIG_FIRMWARE_IN_KERNEL is not set # CONFIG_BLK_DEV is not set CONFIG_NETDEVICES=y +CONFIG_EZCHIP_NPS_MANAGEMENT_ENET=y # CONFIG_INPUT_MOUSEDEV is not set CONFIG_INPUT_EVDEV=y # CONFIG_MOUSE_PS2_ALPS is not set diff --git a/arch/arc/configs/nsimosci_hs_defconfig b/arch/arc/configs/nsimosci_hs_defconfig index ceca2541950d1bbe7f950bad17ab2c598c79c65a..4bb60c1cd4a2fcb895eac30b17e95ba5af8e5769 100644 --- a/arch/arc/configs/nsimosci_hs_defconfig +++ b/arch/arc/configs/nsimosci_hs_defconfig @@ -1,4 +1,3 @@ -CONFIG_CROSS_COMPILE="arc-linux-" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_DEFAULT_HOSTNAME="ARCLinux" # CONFIG_SWAP is not set @@ -40,6 +39,7 @@ CONFIG_DEVTMPFS=y # CONFIG_FIRMWARE_IN_KERNEL is not set # CONFIG_BLK_DEV is not set CONFIG_NETDEVICES=y +CONFIG_EZCHIP_NPS_MANAGEMENT_ENET=y CONFIG_INPUT_EVDEV=y # CONFIG_MOUSE_PS2_ALPS is not set # CONFIG_MOUSE_PS2_LOGIPS2PP is not set diff --git a/arch/arc/configs/nsimosci_hs_smp_defconfig b/arch/arc/configs/nsimosci_hs_smp_defconfig index 4b6da90f6f261e3d9783719a5bbc2060bf2e8408..7e88f4c720f80a874f53ae61d8146e5d704fe2d0 100644 --- a/arch/arc/configs/nsimosci_hs_smp_defconfig +++ b/arch/arc/configs/nsimosci_hs_smp_defconfig @@ -1,4 +1,3 @@ -CONFIG_CROSS_COMPILE="arc-linux-" CONFIG_DEFAULT_HOSTNAME="ARCLinux" # CONFIG_SWAP is not set CONFIG_SYSVIPC=y @@ -21,6 +20,7 @@ CONFIG_MODULES=y CONFIG_ARC_PLAT_SIM=y CONFIG_ISA_ARCV2=y CONFIG_SMP=y +# CONFIG_ARC_HAS_GFRC is not set CONFIG_ARC_BUILTIN_DTB_NAME="nsimosci_hs_idu" CONFIG_PREEMPT=y # CONFIG_COMPACTION is not set @@ -46,6 +46,7 @@ CONFIG_NETDEVICES=y # CONFIG_NET_VENDOR_ARC is not set # CONFIG_NET_CADENCE is not set # CONFIG_NET_VENDOR_BROADCOM is not set +CONFIG_EZCHIP_NPS_MANAGEMENT_ENET=y # CONFIG_NET_VENDOR_INTEL is not set # CONFIG_NET_VENDOR_MARVELL is not set # CONFIG_NET_VENDOR_MICREL is not set diff --git a/arch/arc/configs/tb10x_defconfig b/arch/arc/configs/tb10x_defconfig index 9b342eaf95aec97830e155a00250d3d419e6d24d..4c5118384eb5f1c393208cde601fddc1be773494 100644 --- a/arch/arc/configs/tb10x_defconfig +++ b/arch/arc/configs/tb10x_defconfig @@ -1,4 +1,3 @@ -CONFIG_CROSS_COMPILE="arc-linux-" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_DEFAULT_HOSTNAME="tb10x" CONFIG_SYSVIPC=y diff --git a/arch/arc/configs/vdk_hs38_defconfig b/arch/arc/configs/vdk_hs38_defconfig index a07f20de221ba1f0b0963ca1f1d44053c6b1b89a..c0d6a010751a9f80e4139fa6a9b833de4b24b6a8 100644 --- a/arch/arc/configs/vdk_hs38_defconfig +++ b/arch/arc/configs/vdk_hs38_defconfig @@ -1,4 +1,3 @@ -CONFIG_CROSS_COMPILE="arc-linux-" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_DEFAULT_HOSTNAME="ARCLinux" # CONFIG_CROSS_MEMORY_ATTACH is not set diff --git a/arch/arc/configs/vdk_hs38_smp_defconfig b/arch/arc/configs/vdk_hs38_smp_defconfig index 735985974a3136d2a1b1d6184ff754efd0a02743..52ec315dc5c954722e182a41bd13372618287f2f 100644 --- a/arch/arc/configs/vdk_hs38_smp_defconfig +++ b/arch/arc/configs/vdk_hs38_smp_defconfig @@ -1,4 +1,3 @@ -CONFIG_CROSS_COMPILE="arc-linux-" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_DEFAULT_HOSTNAME="ARCLinux" # CONFIG_CROSS_MEMORY_ATTACH is not set diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h index f9f4c6f59fdbb3f450ec13420e94f2ee1cb4428c..7fbaea00a3366746b16d869c364df522392cb657 100644 --- a/arch/arc/include/asm/arcregs.h +++ b/arch/arc/include/asm/arcregs.h @@ -381,12 +381,6 @@ static inline int is_isa_arcompact(void) return IS_ENABLED(CONFIG_ISA_ARCOMPACT); } -#if defined(CONFIG_ISA_ARCOMPACT) && !defined(_CPU_DEFAULT_A7) -#error "Toolchain not configured for ARCompact builds" -#elif defined(CONFIG_ISA_ARCV2) && !defined(_CPU_DEFAULT_HS) -#error "Toolchain not configured for ARCv2 builds" -#endif - #endif /* __ASEMBLY__ */ #endif /* _ASM_ARC_ARCREGS_H */ diff --git a/arch/arc/include/asm/bitops.h b/arch/arc/include/asm/bitops.h index 57c1f33844d44f1f9d16ed448ce0b13e87b88cea..0352fb8d21b998223b03e2bc327c3f4554df6ec5 100644 --- a/arch/arc/include/asm/bitops.h +++ b/arch/arc/include/asm/bitops.h @@ -35,21 +35,6 @@ static inline void op##_bit(unsigned long nr, volatile unsigned long *m)\ \ m += nr >> 5; \ \ - /* \ - * ARC ISA micro-optimization: \ - * \ - * Instructions dealing with bitpos only consider lower 5 bits \ - * e.g (x << 33) is handled like (x << 1) by ASL instruction \ - * (mem pointer still needs adjustment to point to next word) \ - * \ - * Hence the masking to clamp @nr arg can be elided in general. \ - * \ - * However if @nr is a constant (above assumed in a register), \ - * and greater than 31, gcc can optimize away (x << 33) to 0, \ - * as overflow, given the 32-bit ISA. Thus masking needs to be \ - * done for const @nr, but no code is generated due to gcc \ - * const prop. \ - */ \ nr &= 0x1f; \ \ __asm__ __volatile__( \ diff --git a/arch/arc/include/asm/cache.h b/arch/arc/include/asm/cache.h index 210ef3e7233224b099bd40e85106d2d864e70987..23706c635c30af915e0bc92dfc8f09f04556244c 100644 --- a/arch/arc/include/asm/cache.h +++ b/arch/arc/include/asm/cache.h @@ -54,6 +54,7 @@ extern char *arc_cache_mumbojumbo(int cpu_id, char *buf, int len); extern void read_decode_cache_bcr(void); extern int ioc_exists; +extern unsigned long perip_base; #endif /* !__ASSEMBLY__ */ diff --git a/arch/arc/include/asm/cacheflush.h b/arch/arc/include/asm/cacheflush.h index fbe3587c4f36f1add284667fd8a04edbe90ea2ef..a093adbdb017580f6da74abb551ea02e14e04da5 100644 --- a/arch/arc/include/asm/cacheflush.h +++ b/arch/arc/include/asm/cacheflush.h @@ -40,9 +40,9 @@ void __flush_dcache_page(phys_addr_t paddr, unsigned long vaddr); void flush_dcache_page(struct page *page); -void dma_cache_wback_inv(unsigned long start, unsigned long sz); -void dma_cache_inv(unsigned long start, unsigned long sz); -void dma_cache_wback(unsigned long start, unsigned long sz); +void dma_cache_wback_inv(phys_addr_t start, unsigned long sz); +void dma_cache_inv(phys_addr_t start, unsigned long sz); +void dma_cache_wback(phys_addr_t start, unsigned long sz); #define flush_dcache_mmap_lock(mapping) do { } while (0) #define flush_dcache_mmap_unlock(mapping) do { } while (0) diff --git a/arch/arc/include/asm/checksum.h b/arch/arc/include/asm/checksum.h index 10957298b7a3b3a8ff0d31cae7dc959fddcd938b..913eb4aab05bd518d2ec002ff307d37dee4eb87b 100644 --- a/arch/arc/include/asm/checksum.h +++ b/arch/arc/include/asm/checksum.h @@ -70,8 +70,8 @@ ip_fast_csum(const void *iph, unsigned int ihl) * SA [4], DA [4], zeroes [1], Proto[1], TCP Seg(hdr+data) Len [2] */ static inline __wsum -csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) +csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len, + __u8 proto, __wsum sum) { __asm__ __volatile__( " add.f %0, %0, %1 \n" diff --git a/arch/arc/include/asm/cmpxchg.h b/arch/arc/include/asm/cmpxchg.h index af7a2db139c96887a758f711140175f88b85845d..a444be67cd53e7906d2c2d808a08b75182463918 100644 --- a/arch/arc/include/asm/cmpxchg.h +++ b/arch/arc/include/asm/cmpxchg.h @@ -149,7 +149,7 @@ static inline unsigned long __xchg(unsigned long val, volatile void *ptr, * Since xchg() doesn't always do that, it would seem that following defintion * is incorrect. But here's the rationale: * SMP : Even xchg() takes the atomic_ops_lock, so OK. - * LLSC: atomic_ops_lock are not relevent at all (even if SMP, since LLSC + * LLSC: atomic_ops_lock are not relevant at all (even if SMP, since LLSC * is natively "SMP safe", no serialization required). * UP : other atomics disable IRQ, so no way a difft ctxt atomic_xchg() * could clobber them. atomic_xchg() itself would be 1 insn, so it diff --git a/arch/arc/include/asm/dma-mapping.h b/arch/arc/include/asm/dma-mapping.h index 660205414f1da1c199461ccc2c2eee46ecacd3b9..266f11c9bd593e58775d12a5dac214817da3110e 100644 --- a/arch/arc/include/asm/dma-mapping.h +++ b/arch/arc/include/asm/dma-mapping.h @@ -11,6 +11,13 @@ #ifndef ASM_ARC_DMA_MAPPING_H #define ASM_ARC_DMA_MAPPING_H +#ifndef CONFIG_ARC_PLAT_NEEDS_PHYS_TO_DMA +#define plat_dma_to_phys(dev, dma_handle) ((phys_addr_t)(dma_handle)) +#define plat_phys_to_dma(dev, paddr) ((dma_addr_t)(paddr)) +#else +#include +#endif + extern struct dma_map_ops arc_dma_ops; static inline struct dma_map_ops *get_dma_ops(struct device *dev) diff --git a/arch/arc/include/asm/entry-compact.h b/arch/arc/include/asm/entry-compact.h index 1aff3be9107563ca620072a49abf9e9925d4ec6b..1d8f57cd605773a106cbf03fd6836ae4fa8eeff0 100644 --- a/arch/arc/include/asm/entry-compact.h +++ b/arch/arc/include/asm/entry-compact.h @@ -231,7 +231,7 @@ /* free up r9 as scratchpad */ PROLOG_FREEUP_REG r9, @int\LVL\()_saved_reg - /* Which mode (user/kernel) was the system in when intr occured */ + /* Which mode (user/kernel) was the system in when intr occurred */ lr r9, [status32_l\LVL\()] SWITCH_TO_KERNEL_STK diff --git a/arch/arc/include/asm/fb.h b/arch/arc/include/asm/fb.h new file mode 100644 index 0000000000000000000000000000000000000000..bd3f68c9ddfcaa25c6320dcc3eb0c8f3afcb0fa1 --- /dev/null +++ b/arch/arc/include/asm/fb.h @@ -0,0 +1,19 @@ +#ifndef _ASM_FB_H_ +#define _ASM_FB_H_ + +#include +#include +#include + +static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma, + unsigned long off) +{ + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); +} + +static inline int fb_is_primary_device(struct fb_info *info) +{ + return 0; +} + +#endif /* _ASM_FB_H_ */ diff --git a/arch/arc/include/asm/hugepage.h b/arch/arc/include/asm/hugepage.h index c5094de86403be046ce70f6d10777aa13918ceed..7afe3356b770287d30fba05c7c6d16db531efa43 100644 --- a/arch/arc/include/asm/hugepage.h +++ b/arch/arc/include/asm/hugepage.h @@ -30,19 +30,16 @@ static inline pmd_t pte_pmd(pte_t pte) #define pmd_mkyoung(pmd) pte_pmd(pte_mkyoung(pmd_pte(pmd))) #define pmd_mkhuge(pmd) pte_pmd(pte_mkhuge(pmd_pte(pmd))) #define pmd_mknotpresent(pmd) pte_pmd(pte_mknotpresent(pmd_pte(pmd))) -#define pmd_mksplitting(pmd) pte_pmd(pte_mkspecial(pmd_pte(pmd))) #define pmd_mkclean(pmd) pte_pmd(pte_mkclean(pmd_pte(pmd))) #define pmd_write(pmd) pte_write(pmd_pte(pmd)) #define pmd_young(pmd) pte_young(pmd_pte(pmd)) #define pmd_pfn(pmd) pte_pfn(pmd_pte(pmd)) #define pmd_dirty(pmd) pte_dirty(pmd_pte(pmd)) -#define pmd_special(pmd) pte_special(pmd_pte(pmd)) #define mk_pmd(page, prot) pte_pmd(mk_pte(page, prot)) #define pmd_trans_huge(pmd) (pmd_val(pmd) & _PAGE_HW_SZ) -#define pmd_trans_splitting(pmd) (pmd_trans_huge(pmd) && pmd_special(pmd)) #define pfn_pmd(pfn, prot) (__pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot))) diff --git a/arch/arc/include/asm/io.h b/arch/arc/include/asm/io.h index 947bf0cfdec0065632f6b9831ddbe2f48a3b8a33..17f85c9c73cfe830a40280ad79bf9decb1b65a17 100644 --- a/arch/arc/include/asm/io.h +++ b/arch/arc/include/asm/io.h @@ -13,8 +13,8 @@ #include #include -extern void __iomem *ioremap(unsigned long physaddr, unsigned long size); -extern void __iomem *ioremap_prot(phys_addr_t offset, unsigned long size, +extern void __iomem *ioremap(phys_addr_t paddr, unsigned long size); +extern void __iomem *ioremap_prot(phys_addr_t paddr, unsigned long size, unsigned long flags); static inline void __iomem *ioport_map(unsigned long port, unsigned int nr) { @@ -138,15 +138,23 @@ static inline void __raw_writel(u32 w, volatile void __iomem *addr) #define writel(v,c) ({ __iowmb(); writel_relaxed(v,c); }) /* - * Relaxed API for drivers which can handle any ordering themselves + * Relaxed API for drivers which can handle barrier ordering themselves + * + * Also these are defined to perform little endian accesses. + * To provide the typical device register semantics of fixed endian, + * swap the byte order for Big Endian + * + * http://lkml.kernel.org/r/201603100845.30602.arnd@arndb.de */ #define readb_relaxed(c) __raw_readb(c) -#define readw_relaxed(c) __raw_readw(c) -#define readl_relaxed(c) __raw_readl(c) +#define readw_relaxed(c) ({ u16 __r = le16_to_cpu((__force __le16) \ + __raw_readw(c)); __r; }) +#define readl_relaxed(c) ({ u32 __r = le32_to_cpu((__force __le32) \ + __raw_readl(c)); __r; }) #define writeb_relaxed(v,c) __raw_writeb(v,c) -#define writew_relaxed(v,c) __raw_writew(v,c) -#define writel_relaxed(v,c) __raw_writel(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) #include diff --git a/arch/arc/include/asm/page.h b/arch/arc/include/asm/page.h index 429957f1c2365566006d674bb37311cddb97cc00..36da89e2c853ef0551bfcee0f145454e23a81dd6 100644 --- a/arch/arc/include/asm/page.h +++ b/arch/arc/include/asm/page.h @@ -10,12 +10,8 @@ #include - #ifndef __ASSEMBLY__ -#define get_user_page(vaddr) __get_free_page(GFP_KERNEL) -#define free_user_page(page, addr) free_page(addr) - #define clear_page(paddr) memset((paddr), 0, PAGE_SIZE) #define copy_page(to, from) memcpy((to), (from), PAGE_SIZE) @@ -76,30 +72,26 @@ typedef unsigned long pgprot_t; typedef pte_t * pgtable_t; -#define ARCH_PFN_OFFSET (CONFIG_LINUX_LINK_BASE >> PAGE_SHIFT) +#define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT) -#define pfn_valid(pfn) (((pfn) - ARCH_PFN_OFFSET) < max_mapnr) +#define ARCH_PFN_OFFSET virt_to_pfn(CONFIG_LINUX_LINK_BASE) + +#define pfn_valid(pfn) (((pfn) - ARCH_PFN_OFFSET) < max_mapnr) /* * __pa, __va, virt_to_page (ALERT: deprecated, don't use them) * * These macros have historically been misnamed * virt here means link-address/program-address as embedded in object code. - * So if kernel img is linked at 0x8000_0000 onwards, 0x8010_0000 will be - * 128th page, and virt_to_page( ) will return the struct page corresp to it. - * mem_map[ ] is an array of struct page for each page frame in the system - * - * Independent of where linux is linked at, link-addr = physical address - * So the old macro __pa = vaddr + PAGE_OFFSET - CONFIG_LINUX_LINK_BASE - * would have been wrong in case kernel is not at 0x8zs + * And for ARC, link-addr = physical address */ #define __pa(vaddr) ((unsigned long)vaddr) #define __va(paddr) ((void *)((unsigned long)(paddr))) #define virt_to_page(kaddr) \ - (mem_map + ((__pa(kaddr) - CONFIG_LINUX_LINK_BASE) >> PAGE_SHIFT)) + (mem_map + virt_to_pfn((kaddr) - CONFIG_LINUX_LINK_BASE)) -#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) +#define virt_addr_valid(kaddr) pfn_valid(virt_to_pfn(kaddr)) /* Default Permissions for stack/heaps pages (Non Executable) */ #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE) diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h index d426d4215513333289ac85bebea412015e7562d2..7d6c93e63adf3af60a0642b03b3ae798061b1e65 100644 --- a/arch/arc/include/asm/pgtable.h +++ b/arch/arc/include/asm/pgtable.h @@ -12,7 +12,7 @@ * - Utilise some unused free bits to confine PTE flags to 12 bits * This is a must for 4k pg-sz * - * vineetg: Mar 2011 - changes to accomodate MMU TLB Page Descriptor mods + * vineetg: Mar 2011 - changes to accommodate MMU TLB Page Descriptor mods * -TLB Locking never really existed, except for initial specs * -SILENT_xxx not needed for our port * -Per my request, MMU V3 changes the layout of some of the bits @@ -278,15 +278,14 @@ static inline void pmd_set(pmd_t *pmdp, pte_t *ptep) #define pmd_present(x) (pmd_val(x)) #define pmd_clear(xp) do { pmd_val(*(xp)) = 0; } while (0) -#define pte_page(x) (mem_map + \ - (unsigned long)(((pte_val(x) - CONFIG_LINUX_LINK_BASE) >> \ - PAGE_SHIFT))) +#define pte_page(pte) \ + (mem_map + virt_to_pfn(pte_val(pte) - CONFIG_LINUX_LINK_BASE)) #define mk_pte(page, prot) pfn_pte(page_to_pfn(page), prot) -#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT) +#define pte_pfn(pte) virt_to_pfn(pte_val(pte)) #define pfn_pte(pfn, prot) (__pte(((pte_t)(pfn) << PAGE_SHIFT) | \ pgprot_val(prot))) -#define __pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) +#define __pte_index(addr) (virt_to_pfn(addr) & (PTRS_PER_PTE - 1)) /* * pte_offset gets a @ptr to PMD entry (PGD in our 2-tier paging system) diff --git a/arch/arc/include/asm/tlbflush.h b/arch/arc/include/asm/tlbflush.h index 1fe9c8c80280b9c53006a695994548aa6296cd56..f0d42f1e83f5a26d91b1a3ced885b43fc30e7596 100644 --- a/arch/arc/include/asm/tlbflush.h +++ b/arch/arc/include/asm/tlbflush.h @@ -17,8 +17,10 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page); void local_flush_tlb_kernel_range(unsigned long start, unsigned long end); void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end); +#ifdef CONFIG_TRANSPARENT_HUGEPAGE void local_flush_pmd_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end); +#endif #ifndef CONFIG_SMP #define flush_tlb_range(vma, s, e) local_flush_tlb_range(vma, s, e) @@ -26,7 +28,9 @@ void local_flush_pmd_tlb_range(struct vm_area_struct *vma, unsigned long start, #define flush_tlb_kernel_range(s, e) local_flush_tlb_kernel_range(s, e) #define flush_tlb_all() local_flush_tlb_all() #define flush_tlb_mm(mm) local_flush_tlb_mm(mm) +#ifdef CONFIG_TRANSPARENT_HUGEPAGE #define flush_pmd_tlb_range(vma, s, e) local_flush_pmd_tlb_range(vma, s, e) +#endif #else extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end); @@ -34,7 +38,8 @@ extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long page); extern void flush_tlb_kernel_range(unsigned long start, unsigned long end); extern void flush_tlb_all(void); extern void flush_tlb_mm(struct mm_struct *mm); +#ifdef CONFIG_TRANSPARENT_HUGEPAGE extern void flush_pmd_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end); - +#endif #endif /* CONFIG_SMP */ #endif diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c index cdc821df1809209df9792bcf9ecada0bc991753f..151acf0c9383fd2ea187b6d9beb3e3261a4e7306 100644 --- a/arch/arc/kernel/setup.c +++ b/arch/arc/kernel/setup.c @@ -91,11 +91,9 @@ static void read_decode_ccm_bcr(struct cpuinfo_arc *cpu) static void read_arc_build_cfg_regs(void) { - struct bcr_perip uncached_space; struct bcr_timer timer; struct bcr_generic bcr; struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; - unsigned long perip_space; FIX_PTR(cpu); READ_BCR(AUX_IDENTITY, cpu->core); @@ -108,14 +106,6 @@ static void read_arc_build_cfg_regs(void) cpu->vec_base = read_aux_reg(AUX_INTR_VEC_BASE); - READ_BCR(ARC_REG_D_UNCACH_BCR, uncached_space); - if (uncached_space.ver < 3) - perip_space = uncached_space.start << 24; - else - perip_space = read_aux_reg(AUX_NON_VOL) & 0xF0000000; - - BUG_ON(perip_space != ARC_UNCACHED_ADDR_SPACE); - READ_BCR(ARC_REG_MUL_BCR, cpu->extn_mpy); cpu->extn.norm = read_aux_reg(ARC_REG_NORM_BCR) > 1 ? 1 : 0; /* 2,3 */ @@ -288,8 +278,8 @@ static char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len) FIX_PTR(cpu); n += scnprintf(buf + n, len - n, - "Vector Table\t: %#x\nUncached Base\t: %#x\n", - cpu->vec_base, ARC_UNCACHED_ADDR_SPACE); + "Vector Table\t: %#x\nUncached Base\t: %#lx\n", + cpu->vec_base, perip_base); if (cpu->extn.fpu_sp || cpu->extn.fpu_dp) n += scnprintf(buf + n, len - n, "FPU\t\t: %s%s\n", @@ -357,11 +347,6 @@ static void arc_chk_core_config(void) pr_warn("CONFIG_ARC_FPU_SAVE_RESTORE needed for working apps\n"); else if (!cpu->extn.fpu_dp && fpu_enabled) panic("FPU non-existent, disable CONFIG_ARC_FPU_SAVE_RESTORE\n"); - - if (is_isa_arcv2() && IS_ENABLED(CONFIG_SMP) && cpu->isa.atomic && - IS_ENABLED(CONFIG_ARC_HAS_LLSC) && - !IS_ENABLED(CONFIG_ARC_STAR_9000923308)) - panic("llock/scond livelock workaround missing\n"); } /* @@ -464,7 +449,7 @@ static int __init customize_machine(void) * Traverses flattened DeviceTree - registering platform devices * (if any) complete with their resources */ - of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + of_platform_default_populate(NULL, NULL, NULL); if (machine_desc->init_machine) machine_desc->init_machine(); diff --git a/arch/arc/kernel/stacktrace.c b/arch/arc/kernel/stacktrace.c index 001de4ce711eae2b095451a52f68e77db3d81ef4..e0efff15a5aece29f9bf8ca45b95f856fc206eab 100644 --- a/arch/arc/kernel/stacktrace.c +++ b/arch/arc/kernel/stacktrace.c @@ -232,7 +232,7 @@ void show_stack(struct task_struct *tsk, unsigned long *sp) } /* Another API expected by schedular, shows up in "ps" as Wait Channel - * Ofcourse just returning schedule( ) would be pointless so unwind until + * Of course just returning schedule( ) would be pointless so unwind until * the function is not in schedular code */ unsigned int get_wchan(struct task_struct *tsk) diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c index 156d9833ff84b5c77b7a7bd95d2be15c81d7cbf9..7d9a736fc7e5cb0e7e242bdb6a08dc7c8c3f3c46 100644 --- a/arch/arc/kernel/time.c +++ b/arch/arc/kernel/time.c @@ -55,8 +55,8 @@ #define ARC_REG_TIMER1_CTRL 0x101 /* timer 1 control */ #define ARC_REG_TIMER1_CNT 0x100 /* timer 1 count */ -#define TIMER_CTRL_IE (1 << 0) /* Interupt when Count reachs limit */ -#define TIMER_CTRL_NH (1 << 1) /* Count only when CPU NOT halted */ +#define TIMER_CTRL_IE (1 << 0) /* Interrupt when Count reaches limit */ +#define TIMER_CTRL_NH (1 << 1) /* Count only when CPU NOT halted */ #define ARC_TIMER_MAX 0xFFFFFFFF diff --git a/arch/arc/mm/cache.c b/arch/arc/mm/cache.c index b65f797e9ad6723abd7c38bba09e382df52450b4..9e5eddbb856f1f32dd25f4b13132dd527725249c 100644 --- a/arch/arc/mm/cache.c +++ b/arch/arc/mm/cache.c @@ -24,13 +24,14 @@ static int l2_line_sz; int ioc_exists; volatile int slc_enable = 1, ioc_enable = 1; +unsigned long perip_base = ARC_UNCACHED_ADDR_SPACE; /* legacy value for boot */ void (*_cache_line_loop_ic_fn)(phys_addr_t paddr, unsigned long vaddr, unsigned long sz, const int cacheop); -void (*__dma_cache_wback_inv)(unsigned long start, unsigned long sz); -void (*__dma_cache_inv)(unsigned long start, unsigned long sz); -void (*__dma_cache_wback)(unsigned long start, unsigned long sz); +void (*__dma_cache_wback_inv)(phys_addr_t start, unsigned long sz); +void (*__dma_cache_inv)(phys_addr_t start, unsigned long sz); +void (*__dma_cache_wback)(phys_addr_t start, unsigned long sz); char *arc_cache_mumbojumbo(int c, char *buf, int len) { @@ -75,6 +76,7 @@ char *arc_cache_mumbojumbo(int c, char *buf, int len) static void read_decode_cache_bcr_arcv2(int cpu) { struct cpuinfo_arc_cache *p_slc = &cpuinfo_arc700[cpu].slc; + struct bcr_generic uncached_space; struct bcr_generic sbcr; struct bcr_slc_cfg { @@ -104,6 +106,11 @@ static void read_decode_cache_bcr_arcv2(int cpu) READ_BCR(ARC_REG_CLUSTER_BCR, cbcr); if (cbcr.c && ioc_enable) ioc_exists = 1; + + /* Legacy Data Uncached BCR is deprecated from v3 onwards */ + READ_BCR(ARC_REG_D_UNCACH_BCR, uncached_space); + if (uncached_space.ver > 2) + perip_base = read_aux_reg(AUX_NON_VOL) & 0xF0000000; } void read_decode_cache_bcr(void) @@ -621,7 +628,7 @@ void flush_dcache_page(struct page *page) /* kernel reading from page with U-mapping */ phys_addr_t paddr = (unsigned long)page_address(page); - unsigned long vaddr = page->index << PAGE_CACHE_SHIFT; + unsigned long vaddr = page->index << PAGE_SHIFT; if (addr_not_cache_congruent(paddr, vaddr)) __flush_dcache_page(paddr, vaddr); @@ -633,38 +640,38 @@ EXPORT_SYMBOL(flush_dcache_page); * DMA ops for systems with L1 cache only * Make memory coherent with L1 cache by flushing/invalidating L1 lines */ -static void __dma_cache_wback_inv_l1(unsigned long start, unsigned long sz) +static void __dma_cache_wback_inv_l1(phys_addr_t start, unsigned long sz) { __dc_line_op_k(start, sz, OP_FLUSH_N_INV); } -static void __dma_cache_inv_l1(unsigned long start, unsigned long sz) +static void __dma_cache_inv_l1(phys_addr_t start, unsigned long sz) { __dc_line_op_k(start, sz, OP_INV); } -static void __dma_cache_wback_l1(unsigned long start, unsigned long sz) +static void __dma_cache_wback_l1(phys_addr_t start, unsigned long sz) { __dc_line_op_k(start, sz, OP_FLUSH); } /* * DMA ops for systems with both L1 and L2 caches, but without IOC - * Both L1 and L2 lines need to be explicity flushed/invalidated + * Both L1 and L2 lines need to be explicitly flushed/invalidated */ -static void __dma_cache_wback_inv_slc(unsigned long start, unsigned long sz) +static void __dma_cache_wback_inv_slc(phys_addr_t start, unsigned long sz) { __dc_line_op_k(start, sz, OP_FLUSH_N_INV); slc_op(start, sz, OP_FLUSH_N_INV); } -static void __dma_cache_inv_slc(unsigned long start, unsigned long sz) +static void __dma_cache_inv_slc(phys_addr_t start, unsigned long sz) { __dc_line_op_k(start, sz, OP_INV); slc_op(start, sz, OP_INV); } -static void __dma_cache_wback_slc(unsigned long start, unsigned long sz) +static void __dma_cache_wback_slc(phys_addr_t start, unsigned long sz) { __dc_line_op_k(start, sz, OP_FLUSH); slc_op(start, sz, OP_FLUSH); @@ -675,26 +682,26 @@ static void __dma_cache_wback_slc(unsigned long start, unsigned long sz) * IOC hardware snoops all DMA traffic keeping the caches consistent with * memory - eliding need for any explicit cache maintenance of DMA buffers */ -static void __dma_cache_wback_inv_ioc(unsigned long start, unsigned long sz) {} -static void __dma_cache_inv_ioc(unsigned long start, unsigned long sz) {} -static void __dma_cache_wback_ioc(unsigned long start, unsigned long sz) {} +static void __dma_cache_wback_inv_ioc(phys_addr_t start, unsigned long sz) {} +static void __dma_cache_inv_ioc(phys_addr_t start, unsigned long sz) {} +static void __dma_cache_wback_ioc(phys_addr_t start, unsigned long sz) {} /* * Exported DMA API */ -void dma_cache_wback_inv(unsigned long start, unsigned long sz) +void dma_cache_wback_inv(phys_addr_t start, unsigned long sz) { __dma_cache_wback_inv(start, sz); } EXPORT_SYMBOL(dma_cache_wback_inv); -void dma_cache_inv(unsigned long start, unsigned long sz) +void dma_cache_inv(phys_addr_t start, unsigned long sz) { __dma_cache_inv(start, sz); } EXPORT_SYMBOL(dma_cache_inv); -void dma_cache_wback(unsigned long start, unsigned long sz) +void dma_cache_wback(phys_addr_t start, unsigned long sz) { __dma_cache_wback(start, sz); } diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c index 01eaf88bf821398fecb19dae6780e6702242ff64..8c8e36fa5659411c6705e46d538e7c506fc42c96 100644 --- a/arch/arc/mm/dma.c +++ b/arch/arc/mm/dma.c @@ -24,22 +24,22 @@ static void *arc_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp, struct dma_attrs *attrs) { - void *paddr, *kvaddr; - - /* This is linear addr (0x8000_0000 based) */ - paddr = alloc_pages_exact(size, gfp); - if (!paddr) + unsigned long order = get_order(size); + struct page *page; + phys_addr_t paddr; + void *kvaddr; + int need_coh = 1, need_kvaddr = 0; + + page = alloc_pages(gfp, order); + if (!page) return NULL; - /* This is bus address, platform dependent */ - *dma_handle = (dma_addr_t)paddr; - /* * IOC relies on all data (even coherent DMA data) being in cache * Thus allocate normal cached memory * * The gains with IOC are two pronged: - * -For streaming data, elides needs for cache maintenance, saving + * -For streaming data, elides need for cache maintenance, saving * cycles in flush code, and bus bandwidth as all the lines of a * buffer need to be flushed out to memory * -For coherent data, Read/Write to buffers terminate early in cache @@ -47,12 +47,31 @@ static void *arc_dma_alloc(struct device *dev, size_t size, */ if ((is_isa_arcv2() && ioc_exists) || dma_get_attr(DMA_ATTR_NON_CONSISTENT, attrs)) - return paddr; + need_coh = 0; + + /* + * - A coherent buffer needs MMU mapping to enforce non-cachability + * - A highmem page needs a virtual handle (hence MMU mapping) + * independent of cachability + */ + if (PageHighMem(page) || need_coh) + need_kvaddr = 1; + + /* This is linear addr (0x8000_0000 based) */ + paddr = page_to_phys(page); + + *dma_handle = plat_phys_to_dma(dev, paddr); /* This is kernel Virtual address (0x7000_0000 based) */ - kvaddr = ioremap_nocache((unsigned long)paddr, size); - if (kvaddr == NULL) - return NULL; + if (need_kvaddr) { + kvaddr = ioremap_nocache(paddr, size); + if (kvaddr == NULL) { + __free_pages(page, order); + return NULL; + } + } else { + kvaddr = (void *)(u32)paddr; + } /* * Evict any existing L1 and/or L2 lines for the backing page @@ -64,7 +83,8 @@ static void *arc_dma_alloc(struct device *dev, size_t size, * Currently flush_cache_vmap nukes the L1 cache completely which * will be optimized as a separate commit */ - dma_cache_wback_inv((unsigned long)paddr, size); + if (need_coh) + dma_cache_wback_inv(paddr, size); return kvaddr; } @@ -72,11 +92,16 @@ static void *arc_dma_alloc(struct device *dev, size_t size, static void arc_dma_free(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle, struct dma_attrs *attrs) { - if (!dma_get_attr(DMA_ATTR_NON_CONSISTENT, attrs) && - !(is_isa_arcv2() && ioc_exists)) + struct page *page = virt_to_page(dma_handle); + int is_non_coh = 1; + + is_non_coh = dma_get_attr(DMA_ATTR_NON_CONSISTENT, attrs) || + (is_isa_arcv2() && ioc_exists); + + if (PageHighMem(page) || !is_non_coh) iounmap((void __force __iomem *)vaddr); - free_pages_exact((void *)dma_handle, size); + __free_pages(page, get_order(size)); } /* @@ -84,7 +109,7 @@ static void arc_dma_free(struct device *dev, size_t size, void *vaddr, * CPU accesses page via normal paddr, thus needs to explicitly made * consistent before each use */ -static void _dma_cache_sync(unsigned long paddr, size_t size, +static void _dma_cache_sync(phys_addr_t paddr, size_t size, enum dma_data_direction dir) { switch (dir) { @@ -98,7 +123,7 @@ static void _dma_cache_sync(unsigned long paddr, size_t size, dma_cache_wback_inv(paddr, size); break; default: - pr_err("Invalid DMA dir [%d] for OP @ %lx\n", dir, paddr); + pr_err("Invalid DMA dir [%d] for OP @ %pa[p]\n", dir, &paddr); } } @@ -106,9 +131,9 @@ static dma_addr_t arc_dma_map_page(struct device *dev, struct page *page, unsigned long offset, size_t size, enum dma_data_direction dir, struct dma_attrs *attrs) { - unsigned long paddr = page_to_phys(page) + offset; + phys_addr_t paddr = page_to_phys(page) + offset; _dma_cache_sync(paddr, size, dir); - return (dma_addr_t)paddr; + return plat_phys_to_dma(dev, paddr); } static int arc_dma_map_sg(struct device *dev, struct scatterlist *sg, @@ -127,13 +152,13 @@ static int arc_dma_map_sg(struct device *dev, struct scatterlist *sg, static void arc_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction dir) { - _dma_cache_sync(dma_handle, size, DMA_FROM_DEVICE); + _dma_cache_sync(plat_dma_to_phys(dev, dma_handle), size, DMA_FROM_DEVICE); } static void arc_dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction dir) { - _dma_cache_sync(dma_handle, size, DMA_TO_DEVICE); + _dma_cache_sync(plat_dma_to_phys(dev, dma_handle), size, DMA_TO_DEVICE); } static void arc_dma_sync_sg_for_cpu(struct device *dev, @@ -144,7 +169,7 @@ static void arc_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg; for_each_sg(sglist, sg, nelems, i) - _dma_cache_sync((unsigned int)sg_virt(sg), sg->length, dir); + _dma_cache_sync(sg_phys(sg), sg->length, dir); } static void arc_dma_sync_sg_for_device(struct device *dev, @@ -155,7 +180,7 @@ static void arc_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg; for_each_sg(sglist, sg, nelems, i) - _dma_cache_sync((unsigned int)sg_virt(sg), sg->length, dir); + _dma_cache_sync(sg_phys(sg), sg->length, dir); } static int arc_dma_supported(struct device *dev, u64 dma_mask) diff --git a/arch/arc/mm/highmem.c b/arch/arc/mm/highmem.c index 92dd92cad7f92db32f9ecc1b73992e1ea0a5f74d..04f83322c9fdaf09444bb55eb4d095a68190cf9f 100644 --- a/arch/arc/mm/highmem.c +++ b/arch/arc/mm/highmem.c @@ -18,7 +18,7 @@ /* * HIGHMEM API: * - * kmap() API provides sleep semantics hence refered to as "permanent maps" + * kmap() API provides sleep semantics hence referred to as "permanent maps" * It allows mapping LAST_PKMAP pages, using @last_pkmap_nr as the cursor * for book-keeping * diff --git a/arch/arc/mm/ioremap.c b/arch/arc/mm/ioremap.c index 739e65f355deac569d68e6fa6bff3d18bce73e3a..49b8abd1115c284251557bb745a612bed66c0e1b 100644 --- a/arch/arc/mm/ioremap.c +++ b/arch/arc/mm/ioremap.c @@ -14,18 +14,33 @@ #include #include -void __iomem *ioremap(unsigned long paddr, unsigned long size) +static inline bool arc_uncached_addr_space(phys_addr_t paddr) { - unsigned long end; + if (is_isa_arcompact()) { + if (paddr >= ARC_UNCACHED_ADDR_SPACE) + return true; + } else if (paddr >= perip_base && paddr <= 0xFFFFFFFF) { + return true; + } + + return false; +} + +void __iomem *ioremap(phys_addr_t paddr, unsigned long size) +{ + phys_addr_t end; /* Don't allow wraparound or zero size */ end = paddr + size - 1; if (!size || (end < paddr)) return NULL; - /* If the region is h/w uncached, avoid MMU mappings */ - if (paddr >= ARC_UNCACHED_ADDR_SPACE) - return (void __iomem *)paddr; + /* + * If the region is h/w uncached, MMU mapping can be elided as optim + * The cast to u32 is fine as this region can only be inside 4GB + */ + if (arc_uncached_addr_space(paddr)) + return (void __iomem *)(u32)paddr; return ioremap_prot(paddr, size, PAGE_KERNEL_NO_CACHE); } @@ -41,9 +56,9 @@ EXPORT_SYMBOL(ioremap); void __iomem *ioremap_prot(phys_addr_t paddr, unsigned long size, unsigned long flags) { - void __iomem *vaddr; + unsigned long vaddr; struct vm_struct *area; - unsigned long off, end; + phys_addr_t off, end; pgprot_t prot = __pgprot(flags); /* Don't allow wraparound, zero size */ @@ -70,9 +85,8 @@ void __iomem *ioremap_prot(phys_addr_t paddr, unsigned long size, if (!area) return NULL; area->phys_addr = paddr; - vaddr = (void __iomem *)area->addr; - if (ioremap_page_range((unsigned long)vaddr, - (unsigned long)vaddr + size, paddr, prot)) { + vaddr = (unsigned long)area->addr; + if (ioremap_page_range(vaddr, vaddr + size, paddr, prot)) { vunmap((void __force *)vaddr); return NULL; } @@ -83,7 +97,8 @@ EXPORT_SYMBOL(ioremap_prot); void iounmap(const void __iomem *addr) { - if (addr >= (void __force __iomem *)ARC_UNCACHED_ADDR_SPACE) + /* weird double cast to handle phys_addr_t > 32 bits */ + if (arc_uncached_addr_space((phys_addr_t)(u32)addr)) return; vfree((void *)(PAGE_MASK & (unsigned long __force)addr)); diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c index daf2bf52b984c6781dbb6831e22f013b04e58d0d..7046c12c58edd3779990c3b16911c72d4a985e37 100644 --- a/arch/arc/mm/tlb.c +++ b/arch/arc/mm/tlb.c @@ -45,7 +45,7 @@ * in interrupt-safe region. * * Vineetg: April 23rd Bug #93131 - * Problem: tlb_flush_kernel_range() doesnt do anything if the range to + * Problem: tlb_flush_kernel_range() doesn't do anything if the range to * flush is more than the size of TLB itself. * * Rahul Trivedi : Codito Technologies 2004 @@ -167,7 +167,7 @@ static void utlb_invalidate(void) /* MMU v2 introduced the uTLB Flush command. * There was however an obscure hardware bug, where uTLB flush would * fail when a prior probe for J-TLB (both totally unrelated) would - * return lkup err - because the entry didnt exist in MMU. + * return lkup err - because the entry didn't exist in MMU. * The Workround was to set Index reg with some valid value, prior to * flush. This was fixed in MMU v3 hence not needed any more */ @@ -210,7 +210,7 @@ static void tlb_entry_insert(unsigned int pd0, pte_t pd1) /* * Commit the Entry to MMU - * It doesnt sound safe to use the TLBWriteNI cmd here + * It doesn't sound safe to use the TLBWriteNI cmd here * which doesn't flush uTLBs. I'd rather be safe than sorry. */ write_aux_reg(ARC_REG_TLBCOMMAND, TLBWrite); @@ -636,7 +636,7 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long vaddr_unaligned, * support. * * Normal and Super pages can co-exist (ofcourse not overlap) in TLB with a - * new bit "SZ" in TLB page desciptor to distinguish between them. + * new bit "SZ" in TLB page descriptor to distinguish between them. * Super Page size is configurable in hardware (4K to 16M), but fixed once * RTL builds. * diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 1d00da16d980707e633a2391fac51381254276a7..cdfa6c2b7626f3a761364ac072fc359b5f02592a 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -527,10 +527,10 @@ config ARCH_LPC32XX select ARCH_REQUIRE_GPIOLIB select ARM_AMBA select CLKDEV_LOOKUP - select CLKSRC_MMIO + select CLKSRC_LPC32XX + select COMMON_CLK select CPU_ARM926T select GENERIC_CLOCKEVENTS - select HAVE_IDE select USE_OF help Support for the NXP LPC32XX family of processors @@ -547,6 +547,7 @@ config ARCH_PXA select CLKSRC_PXA select CLKSRC_MMIO select CLKSRC_OF + select CPU_XSCALE if !CPU_XSC3 select GENERIC_CLOCKEVENTS select GPIO_PXA select HAVE_IDE @@ -572,7 +573,6 @@ config ARCH_RPC select NEED_MACH_IO_H select NEED_MACH_MEMORY_H select NO_IOPORT_MAP - select VIRT_TO_BUS help On the Acorn Risc-PC, Linux can support the internal IDE disk and CD-ROM interface, serial and parallel port, and the floppy drive. @@ -623,6 +623,7 @@ config ARCH_DAVINCI select ARCH_HAS_HOLES_MEMORYMODEL select ARCH_REQUIRE_GPIOLIB select CLKDEV_LOOKUP + select CPU_ARM926T select GENERIC_ALLOCATOR select GENERIC_CLOCKEVENTS select GENERIC_IRQ_CHIP @@ -724,6 +725,8 @@ source "arch/arm/mach-mvebu/Kconfig" source "arch/arm/mach-alpine/Kconfig" +source "arch/arm/mach-artpec/Kconfig" + source "arch/arm/mach-asm9260/Kconfig" source "arch/arm/mach-at91/Kconfig" @@ -879,10 +882,16 @@ config ARCH_STM32 select ARCH_HAS_RESET_CONTROLLER select ARMV7M_SYSTICK select CLKSRC_STM32 + select PINCTRL select RESET_CONTROLLER help Support for STMicroelectronics STM32 processors. +config MACH_STM32F429 + bool "STMicrolectronics STM32F429" + depends on ARCH_STM32 + default y + # Definitions to make life easier config ARCH_ACORN bool @@ -1336,7 +1345,6 @@ config BIG_LITTLE config BL_SWITCHER bool "big.LITTLE switcher support" depends on BIG_LITTLE && MCPM && HOTPLUG_CPU && ARM_GIC - select ARM_CPU_SUSPEND select CPU_PM help The big.LITTLE "switcher" provides the core functionality to @@ -2110,7 +2118,8 @@ config ARCH_SUSPEND_POSSIBLE def_bool y config ARM_CPU_SUSPEND - def_bool PM_SLEEP + def_bool PM_SLEEP || BL_SWITCHER || ARM_PSCI_FW + depends on ARCH_SUSPEND_POSSIBLE config ARCH_HIBERNATION_POSSIBLE bool diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index c6b6175d020329ac74eeefb0eebf1a6c353d6ea8..1098e91d6d3f34ff5ca9abd4784dd1793897115c 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -1368,6 +1368,7 @@ config DEBUG_SIRFSOC_UART config DEBUG_LL_INCLUDE string default "debug/sa1100.S" if DEBUG_SA1100 + default "debug/palmchip.S" if DEBUG_UART_8250_PALMCHIP default "debug/8250.S" if DEBUG_LL_UART_8250 || DEBUG_UART_8250 default "debug/at91.S" if DEBUG_AT91_UART default "debug/asm9260.S" if DEBUG_ASM9260_UART @@ -1656,6 +1657,14 @@ config DEBUG_UART_8250_WORD DEBUG_BCM_KONA_UART || DEBUG_RK32_UART2 || \ DEBUG_BRCMSTB_UART +config DEBUG_UART_8250_PALMCHIP + bool "8250 UART is Palmchip BK-310x" + depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250 + help + Palmchip provides a UART implementation compatible with 16550 + except for having a different register layout. Say Y here if + the debug UART is of this type. + config DEBUG_UART_8250_FLOW_CONTROL bool "Enable flow control for 8250 UART" depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250 diff --git a/arch/arm/Makefile b/arch/arm/Makefile index fe254108d1d92c88bb05b90221ca314edcaceedb..8c3ce2ac44c4a675e091e8b107f1dd04f5f0b299 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -154,6 +154,7 @@ textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000 # Machine directory name. This list is sorted alphanumerically # by CONFIG_* macro name. machine-$(CONFIG_ARCH_ALPINE) += alpine +machine-$(CONFIG_ARCH_ARTPEC) += artpec machine-$(CONFIG_ARCH_AT91) += at91 machine-$(CONFIG_ARCH_AXXIA) += axxia machine-$(CONFIG_ARCH_BCM) += bcm @@ -352,7 +353,6 @@ archclean: # My testing targets (bypasses dependencies) bp:; $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/bootpImage -i zi:; $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@ define archhelp diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile index 9eca7aee927f3081975d7372a66a358565c33c56..48fab15cfc0218e1a8e7a0bab389dc766d8ce3e7 100644 --- a/arch/arm/boot/Makefile +++ b/arch/arm/boot/Makefile @@ -88,7 +88,7 @@ $(obj)/bootpImage: $(obj)/bootp/bootp FORCE $(call if_changed,objcopy) @$(kecho) ' Kernel: $@ is ready' -PHONY += initrd FORCE +PHONY += initrd initrd: @test "$(INITRD_PHYS)" != "" || \ (echo This machine does not support INITRD; exit -1) @@ -107,12 +107,4 @@ uinstall: $(CONFIG_SHELL) $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" \ $(obj)/uImage System.map "$(INSTALL_PATH)" -zi: - $(CONFIG_SHELL) $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" \ - $(obj)/zImage System.map "$(INSTALL_PATH)" - -i: - $(CONFIG_SHELL) $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" \ - $(obj)/Image System.map "$(INSTALL_PATH)" - subdir- := bootp compressed dts diff --git a/arch/arm/boot/compressed/.gitignore b/arch/arm/boot/compressed/.gitignore index 0714e0334e33c9790b221d03859574b2f4e774ad..86b2f5d28240bab4f27217daadbe7d44b64b2a1c 100644 --- a/arch/arm/boot/compressed/.gitignore +++ b/arch/arm/boot/compressed/.gitignore @@ -3,11 +3,7 @@ bswapsdi2.S font.c lib1funcs.S hyp-stub.S -piggy.gzip -piggy.lzo -piggy.lzma -piggy.xzkern -piggy.lz4 +piggy_data vmlinux vmlinux.lds diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index 43788b1a1ac5e64372e1f3d3b012ba97a2e2d6ea..d50430c40045dd3e43fe37abf63f11a011e4c687 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -66,11 +66,11 @@ endif CPPFLAGS_vmlinux.lds := -DTEXT_START="$(ZTEXTADDR)" -DBSS_START="$(ZBSSADDR)" -suffix_$(CONFIG_KERNEL_GZIP) = gzip -suffix_$(CONFIG_KERNEL_LZO) = lzo -suffix_$(CONFIG_KERNEL_LZMA) = lzma -suffix_$(CONFIG_KERNEL_XZ) = xzkern -suffix_$(CONFIG_KERNEL_LZ4) = lz4 +compress-$(CONFIG_KERNEL_GZIP) = gzip +compress-$(CONFIG_KERNEL_LZO) = lzo +compress-$(CONFIG_KERNEL_LZMA) = lzma +compress-$(CONFIG_KERNEL_XZ) = xzkern +compress-$(CONFIG_KERNEL_LZ4) = lz4 # Borrowed libfdt files for the ATAG compatibility mode @@ -89,15 +89,12 @@ ifeq ($(CONFIG_ARM_ATAG_DTB_COMPAT),y) OBJS += $(libfdt_objs) atags_to_fdt.o endif -targets := vmlinux vmlinux.lds \ - piggy.$(suffix_y) piggy.$(suffix_y).o \ - lib1funcs.o lib1funcs.S ashldi3.o ashldi3.S bswapsdi2.o \ - bswapsdi2.S font.o font.c head.o misc.o $(OBJS) +targets := vmlinux vmlinux.lds piggy_data piggy.o \ + lib1funcs.o ashldi3.o bswapsdi2.o \ + head.o $(OBJS) -# Make sure files are removed during clean -extra-y += piggy.gzip piggy.lzo piggy.lzma piggy.xzkern piggy.lz4 \ - lib1funcs.S ashldi3.S bswapsdi2.S $(libfdt) $(libfdt_hdrs) \ - hyp-stub.S +clean-files += piggy_data lib1funcs.S ashldi3.S bswapsdi2.S \ + $(libfdt) $(libfdt_hdrs) hyp-stub.S KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING @@ -178,17 +175,17 @@ fi efi-obj-$(CONFIG_EFI_STUB) := $(objtree)/drivers/firmware/efi/libstub/lib.a -$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \ +$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.o \ $(addprefix $(obj)/, $(OBJS)) $(lib1funcs) $(ashldi3) \ $(bswapsdi2) $(efi-obj-y) FORCE @$(check_for_multiple_zreladdr) $(call if_changed,ld) @$(check_for_bad_syms) -$(obj)/piggy.$(suffix_y): $(obj)/../Image FORCE - $(call if_changed,$(suffix_y)) +$(obj)/piggy_data: $(obj)/../Image FORCE + $(call if_changed,$(compress-y)) -$(obj)/piggy.$(suffix_y).o: $(obj)/piggy.$(suffix_y) FORCE +$(obj)/piggy.o: $(obj)/piggy_data CFLAGS_font.o := -Dstatic= diff --git a/arch/arm/boot/compressed/piggy.gzip.S b/arch/arm/boot/compressed/piggy.S similarity index 67% rename from arch/arm/boot/compressed/piggy.gzip.S rename to arch/arm/boot/compressed/piggy.S index a68adf91a165517ef882a3b2a45a825299dbe213..f72088495f439d7a830c096b1f935653e12c13d2 100644 --- a/arch/arm/boot/compressed/piggy.gzip.S +++ b/arch/arm/boot/compressed/piggy.S @@ -1,6 +1,6 @@ .section .piggydata,#alloc .globl input_data input_data: - .incbin "arch/arm/boot/compressed/piggy.gzip" + .incbin "arch/arm/boot/compressed/piggy_data" .globl input_data_end input_data_end: diff --git a/arch/arm/boot/compressed/piggy.lz4.S b/arch/arm/boot/compressed/piggy.lz4.S deleted file mode 100644 index 3d9a575618a3e80452b005ac43d383d3f7c439c2..0000000000000000000000000000000000000000 --- a/arch/arm/boot/compressed/piggy.lz4.S +++ /dev/null @@ -1,6 +0,0 @@ - .section .piggydata,#alloc - .globl input_data -input_data: - .incbin "arch/arm/boot/compressed/piggy.lz4" - .globl input_data_end -input_data_end: diff --git a/arch/arm/boot/compressed/piggy.lzma.S b/arch/arm/boot/compressed/piggy.lzma.S deleted file mode 100644 index d7e69cffbc0a5fa18226dd5a6223ac83d348e2e7..0000000000000000000000000000000000000000 --- a/arch/arm/boot/compressed/piggy.lzma.S +++ /dev/null @@ -1,6 +0,0 @@ - .section .piggydata,#alloc - .globl input_data -input_data: - .incbin "arch/arm/boot/compressed/piggy.lzma" - .globl input_data_end -input_data_end: diff --git a/arch/arm/boot/compressed/piggy.lzo.S b/arch/arm/boot/compressed/piggy.lzo.S deleted file mode 100644 index a425ad95959a7de2848daa5ff693f0e09a63fdcb..0000000000000000000000000000000000000000 --- a/arch/arm/boot/compressed/piggy.lzo.S +++ /dev/null @@ -1,6 +0,0 @@ - .section .piggydata,#alloc - .globl input_data -input_data: - .incbin "arch/arm/boot/compressed/piggy.lzo" - .globl input_data_end -input_data_end: diff --git a/arch/arm/boot/compressed/piggy.xzkern.S b/arch/arm/boot/compressed/piggy.xzkern.S deleted file mode 100644 index 5703f300d02782641ff8af6d2bdb54587ef860df..0000000000000000000000000000000000000000 --- a/arch/arm/boot/compressed/piggy.xzkern.S +++ /dev/null @@ -1,6 +0,0 @@ - .section .piggydata,#alloc - .globl input_data -input_data: - .incbin "arch/arm/boot/compressed/piggy.xzkern" - .globl input_data_end -input_data_end: diff --git a/arch/arm/boot/compressed/string.c b/arch/arm/boot/compressed/string.c index 36e53ef9200f236d7ad2c5e8cdcb9b7b372f0aa3..68946744873677292a32652828cd7accedd3e858 100644 --- a/arch/arm/boot/compressed/string.c +++ b/arch/arm/boot/compressed/string.c @@ -65,6 +65,15 @@ size_t strlen(const char *s) return sc - s; } +size_t strnlen(const char *s, size_t count) +{ + const char *sc; + + for (sc = s; count-- && *sc != '\0'; ++sc) + /* nothing */; + return sc - s; +} + int memcmp(const void *cs, const void *ct, size_t count) { const unsigned char *su1 = cs, *su2 = ct, *end = su1 + count; diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index a4a6d70e8b26ceaf2d9dc7b3af37e4e4bb32eba1..95c1923ce6fa3d32bdeb2e3caedf0ad48eb4d679 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -2,6 +2,8 @@ ifeq ($(CONFIG_OF),y) dtb-$(CONFIG_ARCH_ALPINE) += \ alpine-db.dtb +dtb-$(CONFIG_MACH_ARTPEC6) += \ + artpec6-devboard.dtb dtb-$(CONFIG_MACH_ASM9260) += \ alphascale-asm9260-devkit.dtb # Keep at91 dtb files sorted alphabetically for each SoC @@ -60,6 +62,7 @@ dtb-$(CONFIG_ARCH_AXXIA) += \ axm5516-amarillo.dtb dtb-$(CONFIG_ARCH_BCM2835) += \ bcm2835-rpi-b.dtb \ + bcm2835-rpi-a.dtb \ bcm2835-rpi-b-rev2.dtb \ bcm2835-rpi-b-plus.dtb \ bcm2835-rpi-a-plus.dtb \ @@ -79,6 +82,7 @@ dtb-$(CONFIG_ARCH_BCM_5301X) += \ bcm4709-buffalo-wxr-1900dhp.dtb \ bcm4709-netgear-r7000.dtb \ bcm4709-netgear-r8000.dtb \ + bcm47094-dlink-dir-885l.dtb \ bcm94708.dtb \ bcm94709.dtb \ bcm953012k.dtb @@ -156,7 +160,8 @@ dtb-$(CONFIG_ARCH_INTEGRATOR) += \ dtb-$(CONFIG_ARCH_KEYSTONE) += \ k2hk-evm.dtb \ k2l-evm.dtb \ - k2e-evm.dtb + k2e-evm.dtb \ + keystone-k2g-evm.dtb dtb-$(CONFIG_MACH_KIRKWOOD) += \ kirkwood-b3.dtb \ kirkwood-blackarmor-nas220.dtb \ @@ -189,9 +194,12 @@ dtb-$(CONFIG_MACH_KIRKWOOD) += \ kirkwood-is2.dtb \ kirkwood-km_kirkwood.dtb \ kirkwood-laplug.dtb \ + kirkwood-linkstation-lsqvl.dtb \ + kirkwood-linkstation-lsvl.dtb \ + kirkwood-linkstation-lswsxl.dtb \ + kirkwood-linkstation-lswvl.dtb \ + kirkwood-linkstation-lswxl.dtb \ kirkwood-lschlv2.dtb \ - kirkwood-lswvl.dtb \ - kirkwood-lswxl.dtb \ kirkwood-lsxhl.dtb \ kirkwood-mplcec4.dtb \ kirkwood-mv88f6281gtw-ge.dtb \ @@ -317,12 +325,17 @@ dtb-$(CONFIG_SOC_IMX6Q) += \ imx6dl-udoo.dtb \ imx6dl-wandboard.dtb \ imx6dl-wandboard-revb1.dtb \ + imx6q-apalis-ixora.dtb \ imx6q-apf6dev.dtb \ imx6q-arm2.dtb \ + imx6q-b450v3.dtb \ + imx6q-b650v3.dtb \ + imx6q-b850v3.dtb \ imx6q-cm-fx6.dtb \ imx6q-cubox-i.dtb \ imx6q-dfi-fs700-m60.dtb \ imx6q-dmo-edmqmx6.dtb \ + imx6q-evi.dtb \ imx6q-gk802.dtb \ imx6q-gw51xx.dtb \ imx6q-gw52xx.dtb \ @@ -332,6 +345,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \ imx6q-gw551x.dtb \ imx6q-gw552x.dtb \ imx6q-hummingboard.dtb \ + imx6q-icore-rqs.dtb \ imx6q-nitrogen6x.dtb \ imx6q-nitrogen6_max.dtb \ imx6q-novena.dtb \ @@ -349,7 +363,9 @@ dtb-$(CONFIG_SOC_IMX6Q) += \ imx6q-tx6q-1110.dtb \ imx6q-udoo.dtb \ imx6q-wandboard.dtb \ - imx6q-wandboard-revb1.dtb + imx6q-wandboard-revb1.dtb \ + imx6qp-sabreauto.dtb \ + imx6qp-sabresd.dtb dtb-$(CONFIG_SOC_IMX6SL) += \ imx6sl-evk.dtb \ imx6sl-warp.dtb @@ -460,6 +476,7 @@ dtb-$(CONFIG_ARCH_OMAP3) += \ omap3-sbc-t3517.dtb \ omap3-sbc-t3530.dtb \ omap3-sbc-t3730.dtb \ + omap3-sniper.dtb \ omap3-thunder.dtb \ omap3-zoom3.dtb dtb-$(CONFIG_SOC_TI81XX) += \ @@ -514,6 +531,7 @@ dtb-$(CONFIG_SOC_DRA7XX) += \ dtb-$(CONFIG_ARCH_ORION5X) += \ orion5x-lacie-d2-network.dtb \ orion5x-lacie-ethernet-disk-mini-v2.dtb \ + orion5x-linkstation-lsgl.dtb \ orion5x-linkstation-lswtgl.dtb \ orion5x-lswsgl.dtb \ orion5x-maxtor-shared-storage-2.dtb \ @@ -524,6 +542,7 @@ dtb-$(CONFIG_ARCH_QCOM) += \ qcom-apq8064-cm-qs600.dtb \ qcom-apq8064-ifc6410.dtb \ qcom-apq8064-sony-xperia-yuga.dtb \ + qcom-apq8064-asus-nexus7-flo.dtb \ qcom-apq8074-dragonboard.dtb \ qcom-apq8084-ifc6540.dtb \ qcom-apq8084-mtp.dtb \ @@ -611,6 +630,7 @@ dtb-$(CONFIG_ARCH_STI) += \ stih418-b2199.dtb dtb-$(CONFIG_ARCH_STM32)+= \ stm32f429-disco.dtb \ + stm32f469-disco.dtb \ stm32429i-eval.dtb dtb-$(CONFIG_MACH_SUN4I) += \ sun4i-a10-a1000.dtb \ @@ -666,8 +686,10 @@ dtb-$(CONFIG_MACH_SUN7I) += \ sun7i-a20-cubieboard2.dtb \ sun7i-a20-cubietruck.dtb \ sun7i-a20-hummingbird.dtb \ + sun7i-a20-itead-ibox.dtb \ sun7i-a20-i12-tvbox.dtb \ sun7i-a20-icnova-swac.dtb \ + sun7i-a20-lamobo-r1.dtb \ sun7i-a20-m3.dtb \ sun7i-a20-mk808c.dtb \ sun7i-a20-olimex-som-evb.dtb \ @@ -691,6 +713,8 @@ dtb-$(CONFIG_MACH_SUN8I) += \ sun8i-a33-ippo-q8h-v1.2.dtb \ sun8i-a33-q8-tablet.dtb \ sun8i-a33-sinlinx-sina33.dtb \ + sun8i-a83t-allwinner-h8homlet-v2.dtb \ + sun8i-a83t-cubietruck-plus.dtb \ sun8i-h3-orangepi-plus.dtb dtb-$(CONFIG_MACH_SUN9I) += \ sun9i-a80-optimus.dtb \ @@ -736,7 +760,9 @@ dtb-$(CONFIG_ARCH_U8500) += \ dtb-$(CONFIG_ARCH_UNIPHIER) += \ uniphier-ph1-ld4-ref.dtb \ uniphier-ph1-ld6b-ref.dtb \ + uniphier-ph1-pro4-ace.dtb \ uniphier-ph1-pro4-ref.dtb \ + uniphier-ph1-pro4-sanji.dtb \ uniphier-ph1-sld3-ref.dtb \ uniphier-ph1-sld8-ref.dtb \ uniphier-proxstream2-gentil.dtb \ @@ -809,6 +835,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ mt6580-evbp1.dtb \ mt6589-aquaris5.dtb \ mt6592-evb.dtb \ + mt7623-evb.dtb \ mt8127-moose.dtb \ mt8135-evbp1.dtb dtb-$(CONFIG_ARCH_ZX) += zx296702-ad1.dtb diff --git a/arch/arm/boot/dts/alpine.dtsi b/arch/arm/boot/dts/alpine.dtsi index 9af2d60e9a7f6edb33e0193b81f99d6cbefd134c..db8752fc480e7df1e34ddb96576e28e033d789d3 100644 --- a/arch/arm/boot/dts/alpine.dtsi +++ b/arch/arm/boot/dts/alpine.dtsi @@ -155,6 +155,16 @@ ranges = <0x02000000 0x0 0xfe000000 0x0 0xfe000000 0x0 0x1000000>; bus-range = <0x00 0x00>; + msi-parent = <&msix>; + }; + + msix: msix@fbe00000 { + compatible = "al,alpine-msix"; + reg = <0x0 0xfbe00000 0x0 0x100000>; + interrupt-controller; + msi-controller; + al,msi-base-spi = <96>; + al,msi-num-spis = <64>; }; }; }; diff --git a/arch/arm/boot/dts/am335x-baltos-ir5221.dts b/arch/arm/boot/dts/am335x-baltos-ir5221.dts index ded1eb64ea5216eb993f312fc2d2cbcad2e795cc..6c667fb3544923fb32704bdf4c22ff587c016f5d 100644 --- a/arch/arm/boot/dts/am335x-baltos-ir5221.dts +++ b/arch/arm/boot/dts/am335x-baltos-ir5221.dts @@ -236,7 +236,11 @@ status = "okay"; nand@0,0 { - reg = <0 0 0>; /* CS0, offset 0 */ + compatible = "ti,omap2-nand"; + reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ + interrupt-parent = <&gpmc>; + interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ + <1 IRQ_TYPE_NONE>; /* termcount */ nand-bus-width = <8>; ti,nand-ecc-opt = "bch8"; ti,nand-xfer-type = "polled"; @@ -257,12 +261,9 @@ gpmc,access-ns = <64>; gpmc,rd-cycle-ns = <82>; gpmc,wr-cycle-ns = <82>; - gpmc,wait-on-read = "true"; - gpmc,wait-on-write = "true"; gpmc,bus-turnaround-ns = <0>; gpmc,cycle2cycle-delay-ns = <0>; gpmc,clk-activation-ns = <0>; - gpmc,wait-monitoring-ns = <0>; gpmc,wr-access-ns = <40>; gpmc,wr-data-mux-bus-ns = <0>; diff --git a/arch/arm/boot/dts/am335x-chilisom.dtsi b/arch/arm/boot/dts/am335x-chilisom.dtsi index 857d9894103a9edf6a7754585b5dddd6276d74e6..95461a28bc987afb189a42333902f1f1255f14db 100644 --- a/arch/arm/boot/dts/am335x-chilisom.dtsi +++ b/arch/arm/boot/dts/am335x-chilisom.dtsi @@ -7,6 +7,7 @@ * published by the Free Software Foundation. */ #include "am33xx.dtsi" +#include / { model = "Grinn AM335x ChiliSOM"; @@ -208,7 +209,11 @@ pinctrl-0 = <&nandflash_pins>; ranges = <0 0 0x08000000 0x01000000>; /* CS0 0 @addr 0x08000000, size 0x01000000 */ nand@0,0 { + compatible = "ti,omap2-nand"; reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ + interrupt-parent = <&gpmc>; + interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ + <1 IRQ_TYPE_NONE>; /* termcount */ ti,nand-ecc-opt = "bch8"; ti,elm-id = <&elm>; nand-bus-width = <8>; @@ -227,12 +232,9 @@ gpmc,access-ns = <64>; gpmc,rd-cycle-ns = <82>; gpmc,wr-cycle-ns = <82>; - gpmc,wait-on-read = "true"; - gpmc,wait-on-write = "true"; gpmc,bus-turnaround-ns = <0>; gpmc,cycle2cycle-delay-ns = <0>; gpmc,clk-activation-ns = <0>; - gpmc,wait-monitoring-ns = <0>; gpmc,wr-access-ns = <40>; gpmc,wr-data-mux-bus-ns = <0>; }; diff --git a/arch/arm/boot/dts/am335x-cm-t335.dts b/arch/arm/boot/dts/am335x-cm-t335.dts index 42e9b665582ab2672f6b112549d4178e5dc63d38..e835644c5054df0757727daa9a3be1681cbb9ded 100644 --- a/arch/arm/boot/dts/am335x-cm-t335.dts +++ b/arch/arm/boot/dts/am335x-cm-t335.dts @@ -11,6 +11,7 @@ /dts-v1/; #include "am33xx.dtsi" +#include / { model = "CompuLab CM-T335"; @@ -40,12 +41,51 @@ regulator-max-microvolt = <3300000>; }; + /* Regulator for WiFi */ + vwlan_fixed: fixedregulator@2 { + compatible = "regulator-fixed"; + regulator-name = "vwlan_fixed"; + gpio = <&gpio0 20 GPIO_ACTIVE_HIGH>; /* gpio0_20 */ + enable-active-high; + regulator-boot-off; + }; + backlight { compatible = "pwm-backlight"; pwms = <&ecap0 0 50000 0>; brightness-levels = <0 51 53 56 62 75 101 152 255>; default-brightness-level = <8>; }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "cm-t335"; + + simple-audio-card,widgets = + "Microphone", "Mic Jack", + "Line", "Line In", + "Headphone", "Headphone Jack"; + + simple-audio-card,routing = + "Headphone Jack", "LHPOUT", + "Headphone Jack", "RHPOUT", + "LLINEIN", "Line In", + "RLINEIN", "Line In", + "MICIN", "Mic Jack"; + + simple-audio-card,format = "i2s"; + simple-audio-card,bitclock-master = <&sound_master>; + simple-audio-card,frame-master = <&sound_master>; + + simple-audio-card,cpu { + sound-dai = <&mcasp1>; + }; + + sound_master: simple-audio-card,codec { + sound-dai = <&tlv320aic23>; + system-clock-frequency = <12000000>; + }; + }; }; &am33xx_pinmux { @@ -134,6 +174,24 @@ >; }; + dcan0_pins: pinmux_dcan0_pins { + pinctrl-single,pins = < + /* uart1_ctsn.dcan0_tx */ + AM33XX_IOPAD(0x978, PIN_OUTPUT | MUX_MODE2) + /* uart1_rtsn.dcan0_rx */ + AM33XX_IOPAD(0x97C, PIN_INPUT | MUX_MODE2) + >; + }; + + dcan1_pins: pinmux_dcan1_pins { + pinctrl-single,pins = < + /* uart1_rxd.dcan1_tx */ + AM33XX_IOPAD(0x980, PIN_OUTPUT | MUX_MODE2) + /* uart1_txd.dcan1_rx */ + AM33XX_IOPAD(0x984, PIN_INPUT | MUX_MODE2) + >; + }; + ecap0_pins: pinmux_ecap0_pins { pinctrl-single,pins = < /* eCAP0_in_PWM0_out.eCAP0_in_PWM0_out MODE0 */ @@ -223,6 +281,21 @@ >; }; + spi0_pins: pinmux_spi0_pins { + pinctrl-single,pins = < + /* spi0_sclk.spi0_sclk */ + AM33XX_IOPAD(0x950, PIN_INPUT | MUX_MODE0) + /* spi0_d0.spi0_d0 */ + AM33XX_IOPAD(0x954, PIN_OUTPUT_PULLUP | MUX_MODE0) + /* spi0_d1.spi0_d1 */ + AM33XX_IOPAD(0x958, PIN_INPUT | MUX_MODE0) + /* spi0_cs0.spi0_cs0 */ + AM33XX_IOPAD(0x95C, PIN_OUTPUT | MUX_MODE0) + /* spi0_cs1.spi0_cs1 */ + AM33XX_IOPAD(0x960, PIN_OUTPUT | MUX_MODE0) + >; + }; + /* wl1271 bluetooth */ bluetooth_pins: pinmux_bluetooth_pins { pinctrl-single,pins = < @@ -230,6 +303,30 @@ AM33XX_IOPAD(0x9b0, PIN_OUTPUT_PULLUP | MUX_MODE7) >; }; + + /* TLV320AIC23B codec */ + mcasp1_pins: pinmux_mcasp1_pins { + pinctrl-single,pins = < + /* MII1_CRS.mcasp1_aclkx */ + AM33XX_IOPAD(0x90c, PIN_INPUT_PULLDOWN | MUX_MODE4) + /* MII1_RX_ER.mcasp1_fsx */ + AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE4) + /* MII1_COL.mcasp1_axr2 */ + AM33XX_IOPAD(0x908, PIN_INPUT_PULLDOWN | MUX_MODE4) + /* RMII1_REF_CLK.mcasp1_axr3 */ + AM33XX_IOPAD(0x944, PIN_INPUT_PULLDOWN | MUX_MODE4) + >; + }; + + /* wl1271 WiFi */ + wifi_pins: pinmux_wifi_pins { + pinctrl-single,pins = < + /* EMU1.gpio3_8 - WiFi IRQ */ + AM33XX_IOPAD(0x9e8, PIN_INPUT_PULLUP | MUX_MODE7) + /* XDMA_EVENT_INTR1.gpio0_20 - WiFi enable */ + AM33XX_IOPAD(0x9b4, PIN_OUTPUT | MUX_MODE7) + >; + }; }; &uart0 { @@ -264,6 +361,13 @@ status = "okay"; compatible = "emmicro,em3027"; reg = <0x56>; }; + /* Audio codec */ + tlv320aic23: codec@1a { + compatible = "ti,tlv320aic23"; + reg = <0x1a>; + #sound-dai-cells= <0>; + status = "okay"; + }; }; &usb { @@ -302,7 +406,11 @@ status = "okay"; pinctrl-0 = <&nandflash_pins>; ranges = <0 0 0x08000000 0x10000000>; /* CS0: NAND */ nand@0,0 { - reg = <0 0 0>; /* CS0, offset 0 */ + compatible = "ti,omap2-nand"; + reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ + interrupt-parent = <&gpmc>; + interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ + <1 IRQ_TYPE_NONE>; /* termcount */ ti,nand-ecc-opt = "bch8"; ti,elm-id = <&elm>; nand-bus-width = <8>; @@ -321,12 +429,9 @@ status = "okay"; gpmc,access-ns = <64>; gpmc,rd-cycle-ns = <82>; gpmc,wr-cycle-ns = <82>; - gpmc,wait-on-read = "true"; - gpmc,wait-on-write = "true"; gpmc,bus-turnaround-ns = <0>; gpmc,cycle2cycle-delay-ns = <0>; gpmc,clk-activation-ns = <0>; - gpmc,wait-monitoring-ns = <0>; gpmc,wr-access-ns = <40>; gpmc,wr-data-mux-bus-ns = <0>; /* MTD partition table */ @@ -394,3 +499,70 @@ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&mmc1_pins>; }; + +&dcan0 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&dcan0_pins>; +}; + +&dcan1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&dcan1_pins>; +}; + +/* Touschscreen and analog digital converter */ +&tscadc { + status = "okay"; + tsc { + ti,wires = <4>; + ti,x-plate-resistance = <200>; + ti,coordinate-readouts = <5>; + ti,wire-config = <0x01 0x10 0x23 0x32>; + ti,charge-delay = <0x400>; + }; + + adc { + ti,adc-channels = <4 5 6 7>; + }; +}; + +/* CPU audio */ +&mcasp1 { + pinctrl-names = "default"; + pinctrl-0 = <&mcasp1_pins>; + + op-mode = <0>; /* MCASP_IIS_MODE */ + tdm-slots = <2>; + /* 16 serializers */ + num-serializer = <16>; + serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */ + 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 + >; + tx-num-evt = <1>; + rx-num-evt = <1>; + + #sound-dai-cells= <0>; + status = "okay"; +}; + +&spi0 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&spi0_pins>; + ti,pindir-d0-out-d1-in = <1>; + /* WLS1271 WiFi */ + wlcore: wlcore@1 { + compatible = "ti,wl1271"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_pins>; + reg = <1>; + spi-max-frequency = <48000000>; + clock-xtal; + ref-clock-frequency = <38400000>; + interrupt-parent = <&gpio3>; + interrupts = <8 IRQ_TYPE_LEVEL_HIGH>; + vwlan-supply = <&vwlan_fixed>; + }; +}; diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts index 0d6a68ce434a44fa8c9cfc37eacdd72dcab818e5..28b9162102712fb9053d7434e726e0e9c6c2a4b0 100644 --- a/arch/arm/boot/dts/am335x-evm.dts +++ b/arch/arm/boot/dts/am335x-evm.dts @@ -519,7 +519,11 @@ pinctrl-0 = <&nandflash_pins_s0>; ranges = <0 0 0x08000000 0x1000000>; /* CS0: 16MB for NAND */ nand@0,0 { + compatible = "ti,omap2-nand"; reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ + interrupt-parent = <&gpmc>; + interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ + <1 IRQ_TYPE_NONE>; /* termcount */ ti,nand-ecc-opt = "bch8"; ti,elm-id = <&elm>; nand-bus-width = <8>; @@ -538,12 +542,9 @@ gpmc,access-ns = <64>; gpmc,rd-cycle-ns = <82>; gpmc,wr-cycle-ns = <82>; - gpmc,wait-on-read = "true"; - gpmc,wait-on-write = "true"; gpmc,bus-turnaround-ns = <0>; gpmc,cycle2cycle-delay-ns = <0>; gpmc,clk-activation-ns = <0>; - gpmc,wait-monitoring-ns = <0>; gpmc,wr-access-ns = <40>; gpmc,wr-data-mux-bus-ns = <0>; /* MTD partition table */ diff --git a/arch/arm/boot/dts/am335x-igep0033.dtsi b/arch/arm/boot/dts/am335x-igep0033.dtsi index 54f113546ecc0fcd6a520ff8f19b576b14bc80f1..6c3a9bf3638a181cde05789b5e8d14f0e3c228c8 100644 --- a/arch/arm/boot/dts/am335x-igep0033.dtsi +++ b/arch/arm/boot/dts/am335x-igep0033.dtsi @@ -11,6 +11,7 @@ /dts-v1/; #include "am33xx.dtsi" +#include / { cpus { @@ -129,7 +130,11 @@ ranges = <0 0 0x08000000 0x1000000>; /* CS0: 16MB for NAND */ nand@0,0 { + compatible = "ti,omap2-nand"; reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ + interrupt-parent = <&gpmc>; + interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ + <1 IRQ_TYPE_NONE>; /* termcount */ nand-bus-width = <8>; ti,nand-ecc-opt = "bch8"; gpmc,device-width = <1>; @@ -147,12 +152,9 @@ gpmc,access-ns = <64>; gpmc,rd-cycle-ns = <82>; gpmc,wr-cycle-ns = <82>; - gpmc,wait-on-read = "true"; - gpmc,wait-on-write = "true"; gpmc,bus-turnaround-ns = <0>; gpmc,cycle2cycle-delay-ns = <0>; gpmc,clk-activation-ns = <0>; - gpmc,wait-monitoring-ns = <0>; gpmc,wr-access-ns = <40>; gpmc,wr-data-mux-bus-ns = <0>; diff --git a/arch/arm/boot/dts/am335x-phycore-som.dtsi b/arch/arm/boot/dts/am335x-phycore-som.dtsi index c20ae6c6f6c7cf01ce54ac04d28e20ab40fdac20..d4b7f3bd553fdf385e84b8d086a05f5a38ab8e52 100644 --- a/arch/arm/boot/dts/am335x-phycore-som.dtsi +++ b/arch/arm/boot/dts/am335x-phycore-som.dtsi @@ -8,6 +8,7 @@ */ #include "am33xx.dtsi" +#include / { model = "Phytec AM335x phyCORE"; @@ -165,7 +166,11 @@ pinctrl-0 = <&nandflash_pins>; ranges = <0 0 0x08000000 0x1000000>; /* CS0: NAND */ nandflash: nand@0,0 { + compatible = "ti,omap2-nand"; reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ + interrupt-parent = <&gpmc>; + interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ + <1 IRQ_TYPE_NONE>; /* termcount */ nand-bus-width = <8>; ti,nand-ecc-opt = "bch8"; gpmc,device-nand = "true"; @@ -184,13 +189,10 @@ gpmc,access-ns = <30>; gpmc,rd-cycle-ns = <30>; gpmc,wr-cycle-ns = <30>; - gpmc,wait-on-read = "true"; - gpmc,wait-on-write = "true"; gpmc,bus-turnaround-ns = <0>; gpmc,cycle2cycle-delay-ns = <50>; gpmc,cycle2cycle-diffcsen; gpmc,clk-activation-ns = <0>; - gpmc,wait-monitoring-ns = <0>; gpmc,wr-access-ns = <30>; gpmc,wr-data-mux-bus-ns = <0>; diff --git a/arch/arm/boot/dts/am335x-sl50.dts b/arch/arm/boot/dts/am335x-sl50.dts index 3303c281697b017901f103aa96fee5af0a25ef8a..a6efbe6eda3b97f9dda4a74aed9e51a3b3950538 100644 --- a/arch/arm/boot/dts/am335x-sl50.dts +++ b/arch/arm/boot/dts/am335x-sl50.dts @@ -19,6 +19,10 @@ }; }; + chosen { + stdout-path = &uart0; + }; + leds { compatible = "gpio-leds"; pinctrl-names = "default"; @@ -63,12 +67,28 @@ default-brightness-level = <6>; }; + clocks { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + /* audio external oscillator */ + tlv320aic3x_mclk: oscillator@0 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24576000>; /* 24.576MHz */ + }; + }; + sound { compatible = "ti,da830-evm-audio"; ti,model = "AM335x-SL50"; ti,audio-codec = <&audio_codec>; ti,mcasp-controller = <&mcasp0>; - ti,codec-clock-rate = <12000000>; + + clocks = <&tlv320aic3x_mclk>; + clock-names = "mclk"; + ti,audio-routing = "Headphone Jack", "HPLOUT", "Headphone Jack", "HPROUT", @@ -226,7 +246,7 @@ AM33XX_IOPAD(0x994, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp0_fsx.mcasp0_fsx */ AM33XX_IOPAD(0x990, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp0_aclkx.mcasp0_aclkx */ AM33XX_IOPAD(0x998, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp0_axr0.mcasp0_axr0 */ - AM33XX_IOPAD(0x99c, PIN_INPUT_PULLDOWN | MUX_MODE2) /* mcasp0_ahclkr.mcasp0_axr2*/ + AM33XX_IOPAD(0x99c, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mcasp0_ahclkr.mcasp0_axr2 */ >; }; diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index 1fafaad516ba0481de34cc12320fb9e51c2884ce..55ca9c7dcf6aacf6f7a6702a266dc8725be3a4c7 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -866,6 +866,8 @@ gpmc,num-waitpins = <2>; #address-cells = <2>; #size-cells = <1>; + interrupt-controller; + #interrupt-cells = <2>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi index 92068fbf8b577440409c8e029d7cfba28da43cf8..6e4f5af3d8f8b607bc0bce45cd419169b0f7945d 100644 --- a/arch/arm/boot/dts/am4372.dtsi +++ b/arch/arm/boot/dts/am4372.dtsi @@ -894,21 +894,11 @@ gpmc,num-waitpins = <2>; #address-cells = <2>; #size-cells = <1>; + interrupt-controller; + #interrupt-cells = <2>; status = "disabled"; }; - am43xx_control_usb2phy1: control-phy@44e10620 { - compatible = "ti,control-phy-usb2-am437"; - reg = <0x44e10620 0x4>; - reg-names = "power"; - }; - - am43xx_control_usb2phy2: control-phy@0x44e10628 { - compatible = "ti,control-phy-usb2-am437"; - reg = <0x44e10628 0x4>; - reg-names = "power"; - }; - ocp2scp0: ocp2scp@483a8000 { compatible = "ti,am437x-ocp2scp", "ti,omap-ocp2scp"; #address-cells = <1>; @@ -919,7 +909,7 @@ usb2_phy1: phy@483a8000 { compatible = "ti,am437x-usb2"; reg = <0x483a8000 0x8000>; - ctrl-module = <&am43xx_control_usb2phy1>; + syscon-phy-power = <&scm_conf 0x620>; clocks = <&usb_phy0_always_on_clk32k>, <&usb_otg_ss0_refclk960m>; clock-names = "wkupclk", "refclk"; @@ -938,7 +928,7 @@ usb2_phy2: phy@483e8000 { compatible = "ti,am437x-usb2"; reg = <0x483e8000 0x8000>; - ctrl-module = <&am43xx_control_usb2phy2>; + syscon-phy-power = <&scm_conf 0x628>; clocks = <&usb_phy1_always_on_clk32k>, <&usb_otg_ss1_refclk960m>; clock-names = "wkupclk", "refclk"; diff --git a/arch/arm/boot/dts/am437x-cm-t43.dts b/arch/arm/boot/dts/am437x-cm-t43.dts index 8677f4cce9e9e01553c317791207bcabf88ab18d..9551c4713173b5d6c3c9de10abf484954935451f 100644 --- a/arch/arm/boot/dts/am437x-cm-t43.dts +++ b/arch/arm/boot/dts/am437x-cm-t43.dts @@ -146,7 +146,11 @@ pinctrl-0 = <&nand_flash_x8>; ranges = <0 0 0x08000000 0x1000000>; nand@0,0 { - reg = <0 0 0>; + compatible = "ti,omap2-nand"; + reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ + interrupt-parent = <&gpmc>; + interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ + <1 IRQ_TYPE_NONE>; /* termcount */ ti,nand-ecc-opt = "bch8"; ti,elm-id = <&elm>; @@ -166,17 +170,12 @@ gpmc,access-ns = <64>; gpmc,rd-cycle-ns = <82>; gpmc,wr-cycle-ns = <82>; - gpmc,wait-on-read = "true"; - gpmc,wait-on-write = "true"; gpmc,bus-turnaround-ns = <0>; gpmc,cycle2cycle-delay-ns = <0>; gpmc,clk-activation-ns = <0>; - gpmc,wait-monitoring-ns = <0>; gpmc,wr-access-ns = <40>; gpmc,wr-data-mux-bus-ns = <0>; - gpmc,wait-pin = <0>; - #address-cells = <1>; #size-cells = <1>; /* MTD partition table */ diff --git a/arch/arm/boot/dts/am437x-gp-evm.dts b/arch/arm/boot/dts/am437x-gp-evm.dts index ecd09ab6d581bf95aa0b8bee8d596c3da8b9ee22..8889be1ca1c317fb8bfb351b8a8094750b1ce52b 100644 --- a/arch/arm/boot/dts/am437x-gp-evm.dts +++ b/arch/arm/boot/dts/am437x-gp-evm.dts @@ -810,9 +810,13 @@ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&nand_flash_x8>; - ranges = <0 0 0 0x01000000>; /* minimum GPMC partition = 16MB */ + ranges = <0 0 0x08000000 0x01000000>; /* CS0 space. Min partition = 16MB */ nand@0,0 { + compatible = "ti,omap2-nand"; reg = <0 0 4>; /* device IO registers */ + interrupt-parent = <&gpmc>; + interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ + <1 IRQ_TYPE_NONE>; /* termcount */ ti,nand-ecc-opt = "bch16"; ti,elm-id = <&elm>; nand-bus-width = <8>; @@ -831,11 +835,9 @@ gpmc,access-ns = <30>; gpmc,rd-cycle-ns = <40>; gpmc,wr-cycle-ns = <40>; - gpmc,wait-pin = <0>; gpmc,bus-turnaround-ns = <0>; gpmc,cycle2cycle-delay-ns = <0>; gpmc,clk-activation-ns = <0>; - gpmc,wait-monitoring-ns = <0>; gpmc,wr-access-ns = <40>; gpmc,wr-data-mux-bus-ns = <0>; /* MTD partition table */ diff --git a/arch/arm/boot/dts/am43x-epos-evm.dts b/arch/arm/boot/dts/am43x-epos-evm.dts index d580e2b70f9a65f7dc078799add6d56628ae0169..83dfafaaba1bc019fab7432c8003930c7f8ae1e6 100644 --- a/arch/arm/boot/dts/am43x-epos-evm.dts +++ b/arch/arm/boot/dts/am43x-epos-evm.dts @@ -18,7 +18,7 @@ / { model = "TI AM43x EPOS EVM"; - compatible = "ti,am43x-epos-evm","ti,am4372","ti,am43"; + compatible = "ti,am43x-epos-evm","ti,am438x","ti,am43"; aliases { display0 = &lcd0; @@ -561,9 +561,13 @@ status = "okay"; /* Disable QSPI when enabling GPMC (NAND) */ pinctrl-names = "default"; pinctrl-0 = <&nand_flash_x8>; - ranges = <0 0 0x08000000 0x1000000>; /* CS0: 16MB for NAND */ + ranges = <0 0 0x08000000 0x01000000>; /* CS0 space. Min partition = 16MB */ nand@0,0 { + compatible = "ti,omap2-nand"; reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ + interrupt-parent = <&gpmc>; + interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ + <1 IRQ_TYPE_NONE>; /* termcount */ ti,nand-ecc-opt = "bch16"; ti,elm-id = <&elm>; nand-bus-width = <8>; @@ -582,11 +586,9 @@ gpmc,access-ns = <30>; /* tCEA + 4*/ gpmc,rd-cycle-ns = <40>; gpmc,wr-cycle-ns = <40>; - gpmc,wait-pin = <0>; gpmc,bus-turnaround-ns = <0>; gpmc,cycle2cycle-delay-ns = <0>; gpmc,clk-activation-ns = <0>; - gpmc,wait-monitoring-ns = <0>; gpmc,wr-access-ns = <40>; gpmc,wr-data-mux-bus-ns = <0>; /* MTD partition table */ diff --git a/arch/arm/boot/dts/am57xx-beagle-x15.dts b/arch/arm/boot/dts/am57xx-beagle-x15.dts index 592e65c3a4e0cd4c2116537c84afc0cabe79cd61..0a5fc5d02ce2ba9893ac30b6f9997df08d04eb65 100644 --- a/arch/arm/boot/dts/am57xx-beagle-x15.dts +++ b/arch/arm/boot/dts/am57xx-beagle-x15.dts @@ -24,7 +24,7 @@ memory { device_type = "memory"; - reg = <0x80000000 0x80000000>; + reg = <0x0 0x80000000 0x0 0x80000000>; }; vdd_3v3: fixedregulator-vdd_3v3 { @@ -592,6 +592,11 @@ DRVDD-supply = <&vdd_3v3>; DVDD-supply = <&aic_dvdd>; }; + + eeprom: eeprom@50 { + compatible = "at,24c32"; + reg = <0x50>; + }; }; &i2c3 { diff --git a/arch/arm/boot/dts/am57xx-cl-som-am57x.dts b/arch/arm/boot/dts/am57xx-cl-som-am57x.dts index 1c06cb76da07c14132e60cd29f5406dab9e9db66..14f912a1b4fd7a49889257c6709f7bced04962b7 100644 --- a/arch/arm/boot/dts/am57xx-cl-som-am57x.dts +++ b/arch/arm/boot/dts/am57xx-cl-som-am57x.dts @@ -21,7 +21,7 @@ memory { device_type = "memory"; - reg = <0x80000000 0x20000000>; /* 512 MB - minimal configuration */ + reg = <0x0 0x80000000 0x0 0x20000000>; /* 512 MB - minimal configuration */ }; leds { diff --git a/arch/arm/boot/dts/arm-realview-pb1176.dts b/arch/arm/boot/dts/arm-realview-pb1176.dts index 1bc64cda819e0b70530575ed1ec6d5c57e19b075..652d85b28aaa2f757f05c8c3f12dd0234a909284 100644 --- a/arch/arm/boot/dts/arm-realview-pb1176.dts +++ b/arch/arm/boot/dts/arm-realview-pb1176.dts @@ -53,6 +53,14 @@ regulator-boot-on; }; + veth: fixedregulator@0 { + compatible = "regulator-fixed"; + regulator-name = "veth"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + }; + xtal24mhz: xtal24mhz@24M { #clock-cells = <0>; compatible = "fixed-clock"; @@ -106,6 +114,53 @@ clock-frequency = <0>; }; + flash@30000000 { + compatible = "arm,versatile-flash", "cfi-flash"; + reg = <0x30000000 0x4000000>; + bank-width = <4>; + }; + + fpga_flash@38000000 { + compatible = "arm,versatile-flash", "cfi-flash"; + reg = <0x38000000 0x800000>; + bank-width = <4>; + }; + + /* + * The "secure flash" contains things like the boot + * monitor so we don't want people to accidentally + * screw this up. Mark the device tree node disabled + * by default. + */ + secflash@3c000000 { + compatible = "arm,versatile-flash", "cfi-flash"; + reg = <0x3c000000 0x4000000>; + bank-width = <4>; + status = "disabled"; + }; + + /* SMSC 9118 ethernet with PHY and EEPROM */ + ethernet@3a000000 { + compatible = "smsc,lan9118", "smsc,lan9115"; + reg = <0x3a000000 0x10000>; + interrupt-parent = <&intc_fpga1176>; + interrupts = <0 10 IRQ_TYPE_LEVEL_HIGH>; + phy-mode = "mii"; + reg-io-width = <4>; + smsc,irq-active-high; + smsc,irq-push-pull; + vdd33a-supply = <&veth>; + vddvario-supply = <&veth>; + }; + + usb@3b000000 { + compatible = "nxp,usb-isp1761"; + reg = <0x3b000000 0x20000>; + interrupt-parent = <&intc_fpga1176>; + interrupts = <0 11 IRQ_TYPE_LEVEL_HIGH>; + port1-otg; + }; + soc { #address-cells = <1>; #size-cells = <1>; @@ -176,6 +231,41 @@ label = "versatile:7"; default-state = "off"; }; + oscclk0: osc0@0c { + compatible = "arm,syscon-icst307"; + #clock-cells = <0>; + lock-offset = <0x20>; + vco-offset = <0x0C>; + clocks = <&xtal24mhz>; + }; + oscclk1: osc1@10 { + compatible = "arm,syscon-icst307"; + #clock-cells = <0>; + lock-offset = <0x20>; + vco-offset = <0x10>; + clocks = <&xtal24mhz>; + }; + oscclk2: osc2@14 { + compatible = "arm,syscon-icst307"; + #clock-cells = <0>; + lock-offset = <0x20>; + vco-offset = <0x14>; + clocks = <&xtal24mhz>; + }; + oscclk3: osc3@18 { + compatible = "arm,syscon-icst307"; + #clock-cells = <0>; + lock-offset = <0x20>; + vco-offset = <0x18>; + clocks = <&xtal24mhz>; + }; + oscclk4: osc4@1c { + compatible = "arm,syscon-icst307"; + #clock-cells = <0>; + lock-offset = <0x20>; + vco-offset = <0x1c>; + clocks = <&xtal24mhz>; + }; }; /* Primary DevChip GIC synthesized with the CPU */ @@ -297,6 +387,13 @@ clocks = <&uartclk>, <&pclk>; clock-names = "uartclk", "apb_pclk"; }; + + /* Direct-mapped development chip ROM */ + pb1176_rom@10200000 { + compatible = "direct-mapped"; + reg = <0x10200000 0x4000>; + bank-width = <1>; + }; }; /* These peripherals are inside the FPGA rather than the DevChip */ @@ -306,6 +403,27 @@ compatible = "simple-bus"; ranges; + i2c0: i2c@10002000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "arm,versatile-i2c"; + reg = <0x10002000 0x1000>; + + rtc@68 { + compatible = "dallas,ds1338"; + reg = <0x68>; + }; + }; + + fpga_aaci: aaci@10004000 { + compatible = "arm,pl041", "arm,primecell"; + reg = <0x10004000 0x1000>; + interrupt-parent = <&intc_fpga1176>; + interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&pclk>; + clock-names = "apb_pclk"; + }; + fpga_mci: mmcsd@10005000 { compatible = "arm,pl18x", "arm,primecell"; reg = <0x10005000 0x1000>; diff --git a/arch/arm/boot/dts/arm-realview-pb11mp.dts b/arch/arm/boot/dts/arm-realview-pb11mp.dts index da755c9851a731e825a7083bc16fbda2aa6b6640..63d6a051839f55248db749e261885a64961f6ea1 100644 --- a/arch/arm/boot/dts/arm-realview-pb11mp.dts +++ b/arch/arm/boot/dts/arm-realview-pb11mp.dts @@ -230,14 +230,14 @@ flash0@40000000 { /* 2 * 32MiB NOR Flash memory */ - compatible = "arm,vexpress-flash", "cfi-flash"; + compatible = "arm,versatile-flash", "cfi-flash"; reg = <0x40000000 0x04000000>; bank-width = <4>; }; flash1@44000000 { // 2 * 32MiB NOR Flash memory - compatible = "arm,vexpress-flash", "cfi-flash"; + compatible = "arm,versatile-flash", "cfi-flash"; reg = <0x44000000 0x04000000>; bank-width = <4>; }; diff --git a/arch/arm/boot/dts/armada-370-db.dts b/arch/arm/boot/dts/armada-370-db.dts index bb280de511dad269e2fa120f154d26c2f75f8129..2364fc56ae13904dafc50ea25c9c3aa4c4063c0d 100644 --- a/arch/arm/boot/dts/armada-370-db.dts +++ b/arch/arm/boot/dts/armada-370-db.dts @@ -168,6 +168,33 @@ spi-max-frequency = <50000000>; }; }; + + nand@d0000 { + status = "okay"; + num-cs = <1>; + marvell,nand-keep-config; + marvell,nand-enable-arbiter; + nand-on-flash-bbt; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "U-Boot"; + reg = <0 0x800000>; + }; + partition@800000 { + label = "Linux"; + reg = <0x800000 0x800000>; + }; + partition@1000000 { + label = "Filesystem"; + reg = <0x1000000 0x3f000000>; + }; + }; + }; }; pcie-controller { diff --git a/arch/arm/boot/dts/armada-370-mirabox.dts b/arch/arm/boot/dts/armada-370-mirabox.dts index 3aa980ad64f0c47f7603d5144ffa04211578b2e1..d5e19cd4d256bc1e8fd51b21201ca576278ee782 100644 --- a/arch/arm/boot/dts/armada-370-mirabox.dts +++ b/arch/arm/boot/dts/armada-370-mirabox.dts @@ -200,7 +200,7 @@ &pinctrl { pwr_led_pin: pwr-led-pin { marvell,pins = "mpp63"; - marvell,function = "gpo"; + marvell,function = "gpio"; }; stat_led_pins: stat-led-pins { diff --git a/arch/arm/boot/dts/armada-370-netgear-rn104.dts b/arch/arm/boot/dts/armada-370-netgear-rn104.dts index faa474874cb8e5c4436154cf6dcbf38f7daa60ef..11565752b9f6b7f83ea56187ebcac73deaf91a36 100644 --- a/arch/arm/boot/dts/armada-370-netgear-rn104.dts +++ b/arch/arm/boot/dts/armada-370-netgear-rn104.dts @@ -297,7 +297,7 @@ backup_led_pin: backup-led-pin { marvell,pins = "mpp63"; - marvell,function = "gpo"; + marvell,function = "gpio"; }; power_led_pin: power-led-pin { diff --git a/arch/arm/boot/dts/armada-370-synology-ds213j.dts b/arch/arm/boot/dts/armada-370-synology-ds213j.dts index 836bcc07afc5babe199baaea184b3149d6020dbd..8ca7a4340c0ff8301a80b1d6e75b52770cfdeebd 100644 --- a/arch/arm/boot/dts/armada-370-synology-ds213j.dts +++ b/arch/arm/boot/dts/armada-370-synology-ds213j.dts @@ -339,7 +339,7 @@ fan_ctrl_high_pin: fan-ctrl-high-pin { marvell,pins = "mpp63"; - marvell,function = "gpo"; + marvell,function = "gpio"; }; fan_alarm_pin: fan-alarm-pin { diff --git a/arch/arm/boot/dts/armada-375.dtsi b/arch/arm/boot/dts/armada-375.dtsi index 7ccce7529b0c8debe46f6d4d28c9d51b143738cf..cc952cf8ec3003b6339629161b40e2410ece51d4 100644 --- a/arch/arm/boot/dts/armada-375.dtsi +++ b/arch/arm/boot/dts/armada-375.dtsi @@ -529,7 +529,7 @@ }; sata@a0000 { - compatible = "marvell,orion-sata"; + compatible = "marvell,armada-370-sata"; reg = <0xa0000 0x5000>; interrupts = ; clocks = <&gateclk 14>, <&gateclk 20>; diff --git a/arch/arm/boot/dts/armada-385-db-ap.dts b/arch/arm/boot/dts/armada-385-db-ap.dts index acd5b1519edb2be2f4cd58246fba337a7059ffa1..2d3fd6e76e2c3028101d7e042bcb1e1b09c0f6c1 100644 --- a/arch/arm/boot/dts/armada-385-db-ap.dts +++ b/arch/arm/boot/dts/armada-385-db-ap.dts @@ -61,7 +61,8 @@ ranges = ; + MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000 + MBUS_ID(0x0c, 0x04) 0 0xf1200000 0x100000>; internal-regs { spi1: spi@10680 { @@ -134,18 +135,27 @@ }; }; + /* CON3 */ ethernet@30000 { status = "okay"; phy = <&phy2>; phy-mode = "sgmii"; + buffer-manager = <&bm>; + bm,pool-long = <1>; + bm,pool-short = <3>; }; + /* CON2 */ ethernet@34000 { status = "okay"; phy = <&phy1>; phy-mode = "sgmii"; + buffer-manager = <&bm>; + bm,pool-long = <2>; + bm,pool-short = <3>; }; + /* CON4 */ ethernet@70000 { pinctrl-names = "default"; @@ -157,6 +167,13 @@ status = "okay"; phy = <&phy0>; phy-mode = "rgmii-id"; + buffer-manager = <&bm>; + bm,pool-long = <0>; + bm,pool-short = <3>; + }; + + bm@c8000 { + status = "okay"; }; nfc: flash@d0000 { @@ -178,6 +195,10 @@ }; }; + bm-bppi { + status = "okay"; + }; + pcie-controller { status = "okay"; diff --git a/arch/arm/boot/dts/armada-388-clearfog.dts b/arch/arm/boot/dts/armada-388-clearfog.dts index c6e180eb3b114e060a5471c3261fe0fddf95ff6d..c60206efb583d264d254ec25f20f3c4c3905f888 100644 --- a/arch/arm/boot/dts/armada-388-clearfog.dts +++ b/arch/arm/boot/dts/armada-388-clearfog.dts @@ -78,6 +78,9 @@ internal-regs { ethernet@30000 { phy-mode = "sgmii"; + buffer-manager = <&bm>; + bm,pool-long = <2>; + bm,pool-short = <1>; status = "okay"; fixed-link { @@ -88,6 +91,9 @@ ethernet@34000 { phy-mode = "sgmii"; + buffer-manager = <&bm>; + bm,pool-long = <3>; + bm,pool-short = <1>; status = "okay"; fixed-link { diff --git a/arch/arm/boot/dts/armada-388-db.dts b/arch/arm/boot/dts/armada-388-db.dts index ff47af57f091afd342eed3987a8c40ea404fca7c..ea93ed727030883354d397609f21388a11bb48c2 100644 --- a/arch/arm/boot/dts/armada-388-db.dts +++ b/arch/arm/boot/dts/armada-388-db.dts @@ -66,7 +66,8 @@ ranges = ; + MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000 + MBUS_ID(0x0c, 0x04) 0 0xf1200000 0x100000>; internal-regs { spi@10600 { @@ -99,6 +100,9 @@ status = "okay"; phy = <&phy1>; phy-mode = "rgmii-id"; + buffer-manager = <&bm>; + bm,pool-long = <2>; + bm,pool-short = <3>; }; usb@58000 { @@ -109,6 +113,9 @@ status = "okay"; phy = <&phy0>; phy-mode = "rgmii-id"; + buffer-manager = <&bm>; + bm,pool-long = <0>; + bm,pool-short = <1>; }; mdio@72004 { @@ -129,6 +136,10 @@ status = "okay"; }; + bm@c8000 { + status = "okay"; + }; + flash@d0000 { status = "okay"; num-cs = <1>; @@ -169,6 +180,10 @@ }; }; + bm-bppi { + status = "okay"; + }; + pcie-controller { status = "okay"; /* diff --git a/arch/arm/boot/dts/armada-388-gp.dts b/arch/arm/boot/dts/armada-388-gp.dts index cd316021d6ce2b72af13fa6fc3ccb7b833d423f0..fd75e5e9550fc2bc17d63d052a0f5e2263d219fa 100644 --- a/arch/arm/boot/dts/armada-388-gp.dts +++ b/arch/arm/boot/dts/armada-388-gp.dts @@ -44,8 +44,8 @@ #include / { - model = "Marvell Armada 385 GP"; - compatible = "marvell,a385-gp", "marvell,armada388", "marvell,armada380"; + model = "Marvell Armada 388 DB-88F6820-GP"; + compatible = "marvell,a388-gp", "marvell,armada388", "marvell,armada380"; chosen { stdout-path = "serial0:115200n8"; @@ -60,7 +60,8 @@ ranges = ; + MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000 + MBUS_ID(0x0c, 0x04) 0 0xf1200000 0x100000>; internal-regs { spi@10600 { @@ -133,6 +134,9 @@ status = "okay"; phy = <&phy1>; phy-mode = "rgmii-id"; + buffer-manager = <&bm>; + bm,pool-long = <2>; + bm,pool-short = <3>; }; /* CON4 */ @@ -152,6 +156,9 @@ status = "okay"; phy = <&phy0>; phy-mode = "rgmii-id"; + buffer-manager = <&bm>; + bm,pool-long = <0>; + bm,pool-short = <1>; }; @@ -186,6 +193,10 @@ }; }; + bm@c8000 { + status = "okay"; + }; + sata@e0000 { pinctrl-names = "default"; pinctrl-0 = <&sata2_pins>, <&sata3_pins>; @@ -229,17 +240,21 @@ /* CON5 */ usb3@f0000 { - vcc-supply = <®_usb2_1_vbus>; + usb-phy = <&usb2_1_phy>; status = "okay"; }; /* CON7 */ usb3@f8000 { - vcc-supply = <®_usb3_vbus>; + usb-phy = <&usb3_phy>; status = "okay"; }; }; + bm-bppi { + status = "okay"; + }; + pcie-controller { status = "okay"; /* @@ -273,13 +288,22 @@ }; }; + usb2_1_phy: usb2_1_phy { + compatible = "usb-nop-xceiv"; + vcc-supply = <®_usb2_1_vbus>; + }; + + usb3_phy: usb3_phy { + compatible = "usb-nop-xceiv"; + vcc-supply = <®_usb3_vbus>; + }; + reg_usb3_vbus: usb3-vbus { compatible = "regulator-fixed"; regulator-name = "usb3-vbus"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; enable-active-high; - regulator-always-on; gpio = <&expander1 15 GPIO_ACTIVE_HIGH>; }; @@ -299,7 +323,6 @@ regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; enable-active-high; - regulator-always-on; gpio = <&expander0 4 GPIO_ACTIVE_HIGH>; }; @@ -309,7 +332,7 @@ regulator-min-microvolt = <12000000>; regulator-max-microvolt = <12000000>; enable-active-high; - regulator-always-on; + regulator-boot-on; gpio = <&expander0 2 GPIO_ACTIVE_HIGH>; }; @@ -318,7 +341,6 @@ regulator-name = "v5.0-sata0"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; - regulator-always-on; vin-supply = <®_sata0>; }; @@ -327,7 +349,6 @@ regulator-name = "v12.0-sata0"; regulator-min-microvolt = <12000000>; regulator-max-microvolt = <12000000>; - regulator-always-on; vin-supply = <®_sata0>; }; @@ -337,7 +358,7 @@ regulator-min-microvolt = <12000000>; regulator-max-microvolt = <12000000>; enable-active-high; - regulator-always-on; + regulator-boot-on; gpio = <&expander0 3 GPIO_ACTIVE_HIGH>; }; @@ -346,7 +367,6 @@ regulator-name = "v5.0-sata1"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; - regulator-always-on; vin-supply = <®_sata1>; }; @@ -355,7 +375,6 @@ regulator-name = "v12.0-sata1"; regulator-min-microvolt = <12000000>; regulator-max-microvolt = <12000000>; - regulator-always-on; vin-supply = <®_sata1>; }; @@ -363,7 +382,7 @@ compatible = "regulator-fixed"; regulator-name = "pwr_en_sata2"; enable-active-high; - regulator-always-on; + regulator-boot-on; gpio = <&expander0 11 GPIO_ACTIVE_HIGH>; }; @@ -372,7 +391,6 @@ regulator-name = "v5.0-sata2"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; - regulator-always-on; vin-supply = <®_sata2>; }; @@ -381,7 +399,6 @@ regulator-name = "v12.0-sata2"; regulator-min-microvolt = <12000000>; regulator-max-microvolt = <12000000>; - regulator-always-on; vin-supply = <®_sata2>; }; @@ -389,7 +406,7 @@ compatible = "regulator-fixed"; regulator-name = "pwr_en_sata3"; enable-active-high; - regulator-always-on; + regulator-boot-on; gpio = <&expander0 12 GPIO_ACTIVE_HIGH>; }; @@ -398,7 +415,6 @@ regulator-name = "v5.0-sata3"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; - regulator-always-on; vin-supply = <®_sata3>; }; @@ -407,7 +423,6 @@ regulator-name = "v12.0-sata3"; regulator-min-microvolt = <12000000>; regulator-max-microvolt = <12000000>; - regulator-always-on; vin-supply = <®_sata3>; }; }; diff --git a/arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi b/arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi index 3f792a563c0598cbc308539b1e3ada08677ffc4e..8c9842237b60058bbd1b96de2adb8e99d4e4c053 100644 --- a/arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi +++ b/arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi @@ -58,7 +58,8 @@ ranges = ; + MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000 + MBUS_ID(0x0c, 0x04) 0 0xf1200000 0x100000>; internal-regs { ethernet@70000 { @@ -66,6 +67,9 @@ pinctrl-names = "default"; phy = <&phy_dedicated>; phy-mode = "rgmii-id"; + buffer-manager = <&bm>; + bm,pool-long = <0>; + bm,pool-short = <1>; status = "okay"; }; @@ -110,6 +114,15 @@ pinctrl-names = "default"; status = "okay"; }; + + bm@c8000 { + status = "okay"; + }; }; + + bm-bppi { + status = "okay"; + }; + }; }; diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi index e8b7f67267723241730c8279902b82b8340d8118..3312be6c82cc6aac4cd98f0a1ebb03b1404c2763 100644 --- a/arch/arm/boot/dts/armada-38x.dtsi +++ b/arch/arm/boot/dts/armada-38x.dtsi @@ -429,6 +429,27 @@ reg = <0x22000 0x1000>; }; + /* + * As a special exception to the "order by + * register address" rule, the eth0 node is + * placed here to ensure that it gets + * registered as the first interface, since + * the network subsystem doesn't allow naming + * interfaces using DT aliases. Without this, + * the ordering of interfaces is different + * from the one used in U-Boot and the + * labeling of interfaces on the boards, which + * is very confusing for users. + */ + eth0: ethernet@70000 { + compatible = "marvell,armada-370-neta"; + reg = <0x70000 0x4000>; + interrupts-extended = <&mpic 8>; + clocks = <&gateclk 4>; + tx-csum-limit = <9800>; + status = "disabled"; + }; + eth1: ethernet@30000 { compatible = "marvell,armada-370-neta"; reg = <0x30000 0x4000>; @@ -493,15 +514,6 @@ }; }; - eth0: ethernet@70000 { - compatible = "marvell,armada-370-neta"; - reg = <0x70000 0x4000>; - interrupts-extended = <&mpic 8>; - clocks = <&gateclk 4>; - tx-csum-limit = <9800>; - status = "disabled"; - }; - mdio: mdio@72004 { #address-cells = <1>; #size-cells = <0>; @@ -540,6 +552,14 @@ status = "disabled"; }; + bm: bm@c8000 { + compatible = "marvell,armada-380-neta-bm"; + reg = <0xc8000 0xac>; + clocks = <&gateclk 13>; + internal-mem = <&bm_bppi>; + status = "disabled"; + }; + sata@e0000 { compatible = "marvell,armada-380-ahci"; reg = <0xe0000 0x2000>; @@ -618,6 +638,17 @@ #size-cells = <1>; ranges = <0 MBUS_ID(0x09, 0x15) 0 0x800>; }; + + bm_bppi: bm-bppi { + compatible = "mmio-sram"; + reg = ; + ranges = <0 MBUS_ID(0x0c, 0x04) 0 0x100000>; + #address-cells = <1>; + #size-cells = <1>; + clocks = <&gateclk 13>; + no-memory-wc; + status = "disabled"; + }; }; clocks { diff --git a/arch/arm/boot/dts/armada-xp-db.dts b/arch/arm/boot/dts/armada-xp-db.dts index ebe1d267406df5ab30e3a3189b669733eb8fcaa4..62422a90aeb25a640eef04c74051d664db4bb7b9 100644 --- a/arch/arm/boot/dts/armada-xp-db.dts +++ b/arch/arm/boot/dts/armada-xp-db.dts @@ -77,7 +77,8 @@ MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000 MBUS_ID(0x01, 0x2f) 0 0 0xf0000000 0x1000000 MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000 - MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000>; + MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000 + MBUS_ID(0x0c, 0x04) 0 0 0xf1200000 0x100000>; devbus-bootcs { status = "okay"; @@ -181,21 +182,33 @@ status = "okay"; phy = <&phy0>; phy-mode = "rgmii-id"; + buffer-manager = <&bm>; + bm,pool-long = <0>; }; ethernet@74000 { status = "okay"; phy = <&phy1>; phy-mode = "rgmii-id"; + buffer-manager = <&bm>; + bm,pool-long = <1>; }; ethernet@30000 { status = "okay"; phy = <&phy2>; phy-mode = "sgmii"; + buffer-manager = <&bm>; + bm,pool-long = <2>; }; ethernet@34000 { status = "okay"; phy = <&phy3>; phy-mode = "sgmii"; + buffer-manager = <&bm>; + bm,pool-long = <3>; + }; + + bm@c0000 { + status = "okay"; }; mvsdio@d4000 { @@ -229,6 +242,38 @@ spi-max-frequency = <20000000>; }; }; + + nand@d0000 { + status = "okay"; + num-cs = <1>; + marvell,nand-keep-config; + marvell,nand-enable-arbiter; + nand-on-flash-bbt; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "U-Boot"; + reg = <0 0x800000>; + }; + partition@800000 { + label = "Linux"; + reg = <0x800000 0x800000>; + }; + partition@1000000 { + label = "Filesystem"; + reg = <0x1000000 0x3f000000>; + + }; + }; + }; + }; + + bm-bppi { + status = "okay"; }; }; }; diff --git a/arch/arm/boot/dts/armada-xp-gp.dts b/arch/arm/boot/dts/armada-xp-gp.dts index 5730b875c4f51a1aa2743d8881b18d6dbc0b27cd..061f4237760e7c917d11056b97b5971bcd4680b5 100644 --- a/arch/arm/boot/dts/armada-xp-gp.dts +++ b/arch/arm/boot/dts/armada-xp-gp.dts @@ -96,7 +96,8 @@ MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000 MBUS_ID(0x01, 0x2f) 0 0 0xf0000000 0x1000000 MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000 - MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000>; + MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000 + MBUS_ID(0x0c, 0x04) 0 0 0xf1200000 0x100000>; devbus-bootcs { status = "okay"; @@ -196,21 +197,29 @@ status = "okay"; phy = <&phy0>; phy-mode = "qsgmii"; + buffer-manager = <&bm>; + bm,pool-long = <0>; }; ethernet@74000 { status = "okay"; phy = <&phy1>; phy-mode = "qsgmii"; + buffer-manager = <&bm>; + bm,pool-long = <1>; }; ethernet@30000 { status = "okay"; phy = <&phy2>; phy-mode = "qsgmii"; + buffer-manager = <&bm>; + bm,pool-long = <2>; }; ethernet@34000 { status = "okay"; phy = <&phy3>; phy-mode = "qsgmii"; + buffer-manager = <&bm>; + bm,pool-long = <3>; }; /* Front-side USB slot */ @@ -235,6 +244,10 @@ }; }; + bm@c0000 { + status = "okay"; + }; + nand@d0000 { status = "okay"; num-cs = <1>; @@ -243,5 +256,9 @@ nand-on-flash-bbt; }; }; + + bm-bppi { + status = "okay"; + }; }; }; diff --git a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts index 853bd392a4fe20155ed1469a23175213814ca9dc..ed3b889d16ce439a4e933cdcd17ff37ed6adc4c4 100644 --- a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts +++ b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts @@ -67,7 +67,8 @@ MBUS_ID(0x01, 0x1d) 0 0 0xfff00000 0x100000 MBUS_ID(0x01, 0x2f) 0 0 0xe8000000 0x8000000 MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000 - MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000>; + MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000 + MBUS_ID(0x0c, 0x04) 0 0 0xd1200000 0x100000>; devbus-bootcs { status = "okay"; @@ -176,21 +177,29 @@ status = "okay"; phy = <&phy0>; phy-mode = "sgmii"; + buffer-manager = <&bm>; + bm,pool-long = <0>; }; ethernet@74000 { status = "okay"; phy = <&phy1>; phy-mode = "sgmii"; + buffer-manager = <&bm>; + bm,pool-long = <1>; }; ethernet@30000 { status = "okay"; phy = <&phy2>; phy-mode = "sgmii"; + buffer-manager = <&bm>; + bm,pool-long = <2>; }; ethernet@34000 { status = "okay"; phy = <&phy3>; phy-mode = "sgmii"; + buffer-manager = <&bm>; + bm,pool-long = <3>; }; i2c@11000 { status = "okay"; @@ -219,6 +228,14 @@ usb@51000 { status = "okay"; }; + + bm@c0000 { + status = "okay"; + }; + }; + + bm-bppi { + status = "okay"; }; }; }; diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi index be23196829bbd7b492a192c85f3154ab26917b49..553349c07f280eadce7eb592ab93ac00497eef9c 100644 --- a/arch/arm/boot/dts/armada-xp.dtsi +++ b/arch/arm/boot/dts/armada-xp.dtsi @@ -253,6 +253,14 @@ marvell,crypto-sram-size = <0x800>; }; + bm: bm@c0000 { + compatible = "marvell,armada-380-neta-bm"; + reg = <0xc0000 0xac>; + clocks = <&gateclk 13>; + internal-mem = <&bm_bppi>; + status = "disabled"; + }; + xor@f0900 { compatible = "marvell,orion-xor"; reg = <0xF0900 0x100 @@ -291,6 +299,17 @@ #size-cells = <1>; ranges = <0 MBUS_ID(0x09, 0x05) 0 0x800>; }; + + bm_bppi: bm-bppi { + compatible = "mmio-sram"; + reg = ; + ranges = <0 MBUS_ID(0x0c, 0x04) 0 0x100000>; + #address-cells = <1>; + #size-cells = <1>; + clocks = <&gateclk 13>; + no-memory-wc; + status = "disabled"; + }; }; clocks { diff --git a/arch/arm/boot/dts/artpec6-devboard.dts b/arch/arm/boot/dts/artpec6-devboard.dts new file mode 100644 index 0000000000000000000000000000000000000000..f823ed382ac7cf5585e96ce09b35b8b6c6734705 --- /dev/null +++ b/arch/arm/boot/dts/artpec6-devboard.dts @@ -0,0 +1,64 @@ +/* + * Axis ARTPEC-6 development board. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +/dts-v1/; +#include "artpec6.dtsi" + +/ { + model = "ARTPEC-6 development board"; + compatible = "axis,artpec6-dev-board", "axis,artpec6"; + + aliases { + serial0 = &uart0; + serial1 = &uart1; + serial2 = &uart2; + serial3 = &uart3; + }; + + chosen { + stdout-path = "serial3:115200n8"; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x10000000>; + }; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&uart3 { + status = "okay"; +}; + +ðernet { + status = "okay"; + + phy-handle = <&phy1>; + phy-mode = "gmii"; + + mdio { + #address-cells = <0x1>; + #size-cells = <0x0>; + phy1: phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + device_type = "ethernet-phy"; + reg = <0x0>; + }; + }; +}; diff --git a/arch/arm/boot/dts/artpec6.dtsi b/arch/arm/boot/dts/artpec6.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..30430162b886770caca1abd9e8c170777df94396 --- /dev/null +++ b/arch/arm/boot/dts/artpec6.dtsi @@ -0,0 +1,270 @@ +/* + * Device Tree Source for the Axis ARTPEC-6 SoC + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include "skeleton.dtsi" + +/ { + compatible = "axis,artpec6"; + interrupt-parent = <&intc>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + reg = <0>; + next-level-cache = <&pl310>; + }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + reg = <1>; + next-level-cache = <&pl310>; + }; + }; + + syscon { + compatible = "axis,artpec6-syscon", "syscon"; + reg = <0xf8000000 0x48>; + }; + + psci { + compatible = "arm,psci-0.2", "arm,psci"; + method = "smc"; + psci_version = <0x84000000>; + cpu_on = <0x84000003>; + system_reset = <0x84000009>; + }; + + scu@faf00000 { + compatible = "arm,cortex-a9-scu"; + reg = <0xfaf00000 0x58>; + }; + + /* Main external clock driving CPU and peripherals */ + ext_clk: ext_clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <50000000>; + }; + + /* PLL1 is used by CPU and some peripherals */ + pll1_clk: pll1_clk@f8000000 { + #clock-cells = <0>; + compatible = "axis,artpec6-pll1-clock"; + reg = <0xf8000000 4>; + clocks = <&ext_clk>; + }; + + cpu_clk: cpu_clk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clock-div = <1>; + clock-mult = <1>; + clocks = <&pll1_clk>; + clock-output-names = "cpu_clk"; + }; + + cpu_clkdiv2: cpu_clkdiv2 { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clock-div = <2>; + clock-mult = <1>; + clocks = <&cpu_clk>; + }; + + cpu_clkdiv4: cpu_clkdiv4 { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clock-div = <4>; + clock-mult = <1>; + clocks = <&cpu_clk>; + }; + + apb_pclk: apb_pclk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clock-div = <8>; + clock-mult = <1>; + clocks = <&cpu_clk>; + clock-output-names = "apb_pclk"; + }; + + /* PLL2 is used by a number of peripherals, including UDL */ + pll2: pll2 { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clock-div = <1>; + clock-mult = <24>; + clocks = <&ext_clk>; + }; + + /* PLL2DIV2 is used by the Fractional Clock Divider, for i2s */ + pll2div2: pll2div2 { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clock-div = <2>; + clock-mult = <1>; + clocks = <&pll2>; + }; + + pll2div12: pll2div12 { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clock-div = <12>; + clock-mult = <1>; + clocks = <&pll2>; + }; + + pll2div24: pll2div24 { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clock-div = <24>; + clock-mult = <1>; + clocks = <&pll2>; + clock-output-names = "uart_clk"; + }; + + + gtimer@faf00200 { + compatible = "arm,cortex-a9-global-timer"; + reg = <0xfaf00200 0x20>; + interrupts = ; + clocks = <&cpu_clkdiv2>; + }; + + timer@faf00600 { + compatible = "arm,cortex-a9-twd-timer"; + reg = <0xfaf00600 0x20>; + interrupts = ; + clocks = <&cpu_clkdiv2>; + status = "disabled"; + }; + + intc: interrupt-controller@faf01000 { + interrupt-controller; + compatible = "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + reg = < 0xfaf01000 0x1000 >, < 0xfaf00100 0x0100 >; + }; + + pl310: cache-controller@faf10000 { + compatible = "arm,pl310-cache"; + cache-unified; + cache-level = <2>; + reg = <0xfaf10000 0x1000>; + interrupts = ; + arm,data-latency = <1 1 1>; + arm,tag-latency = <1 1 1>; + arm,filter-ranges = <0x0 0x80000000>; + }; + + pmu { + compatible = "arm,cortex-a9-pmu"; + interrupts = , + ; + interrupt-parent = <&intc>; + }; + + amba@0 { + compatible = "simple-bus"; + #address-cells = <0x1>; + #size-cells = <0x1>; + interrupt-parent = <&intc>; + ranges; + dma-ranges = <0x80000000 0x00000000 0x40000000>; + dma-coherent; + + ethernet: ethernet@f8010000 { + clock-names = "phy_ref_clk", "apb_pclk"; + clocks = <&ext_clk>, <&apb_pclk>; + compatible = "snps,dwc-qos-ethernet-4.10"; + interrupt-parent = <&intc>; + interrupts = ; + reg = <0xf8010000 0x4000>; + + snps,write-requests = <2>; + snps,read-requests = <16>; + snps,txpbl = <8>; + snps,rxpbl = <2>; + + status = "disabled"; + }; + + uart0: serial@f8036000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0xf8036000 0x1000>; + interrupts = ; + clocks = <&pll2div24>, <&apb_pclk>; + clock-names = "uart_clk", "apb_pclk"; + status = "disabled"; + }; + uart1: serial@f8037000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0xf8037000 0x1000>; + interrupts = ; + clocks = <&pll2div24>, <&apb_pclk>; + clock-names = "uart_clk", "apb_pclk"; + status = "disabled"; + }; + uart2: serial@f8038000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0xf8038000 0x1000>; + interrupts = ; + clocks = <&pll2div24>, <&apb_pclk>; + clock-names = "uart_clk", "apb_pclk"; + status = "disabled"; + }; + uart3: serial@f8039000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0xf8039000 0x1000>; + interrupts = ; + clocks = <&pll2div24>, <&apb_pclk>; + clock-names = "uart_clk", "apb_pclk"; + status = "disabled"; + }; + }; +}; diff --git a/arch/arm/boot/dts/at91-sama5d2_xplained.dts b/arch/arm/boot/dts/at91-sama5d2_xplained.dts index e683856c507c8bedacb5f8746a43cf9e4aef2207..21c780fab7612c0b5c6f1d8f047c1b85b31c5cae 100644 --- a/arch/arm/boot/dts/at91-sama5d2_xplained.dts +++ b/arch/arm/boot/dts/at91-sama5d2_xplained.dts @@ -46,6 +46,7 @@ #include "sama5d2.dtsi" #include "sama5d2-pinfunc.h" #include +#include / { model = "Atmel SAMA5D2 Xplained"; @@ -71,11 +72,20 @@ ahb { usb0: gadget@00300000 { + atmel,vbus-gpio = <&pioA 31 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usba_vbus>; status = "okay"; }; usb1: ohci@00400000 { num-ports = <3>; + atmel,vbus-gpio = <0 /* &pioA 41 GPIO_ACTIVE_HIGH */ + &pioA 42 GPIO_ACTIVE_HIGH + 0 + >; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb_default>; status = "okay"; }; @@ -267,7 +277,29 @@ }; }; + adc: adc@fc030000 { + vddana-supply = <&vdd_3v3_lp_reg>; + vref-supply = <&vdd_3v3_lp_reg>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_adc_default>; + status = "okay"; + }; + pinctrl@fc038000 { + /* + * There is no real pinmux for ADC, if the pin + * is not requested by another peripheral then + * the muxing is done when channel is enabled. + * Requesting pins for ADC is GPIO is + * encouraged to prevent conflicts and to + * disable bias in order to be in the same + * state when the pin is not muxed to the adc. + */ + pinctrl_adc_default: adc_default { + pinmux = ; + bias-disable; + }; + pinctrl_flx0_default: flx0_default { pinmux = , ; @@ -292,6 +324,18 @@ bias-disable; }; + pinctrl_key_gpio_default: key_gpio_default { + pinmux = ; + bias-pull-up; + }; + + pinctrl_led_gpio_default: led_gpio_default { + pinmux = , + , + ; + bias-pull-up; + }; + pinctrl_macb0_default: macb0_default { pinmux = , , @@ -308,6 +352,7 @@ pinctrl_macb0_phy_irq: macb0_phy_irq { pinmux = ; + bias-disable; }; pinctrl_pdmic_default: pdmic_default { @@ -375,7 +420,54 @@ ; bias-disable; }; + + pinctrl_usb_default: usb_default { + pinmux = ; + bias-disable; + }; + + pinctrl_usba_vbus: usba_vbus { + pinmux = ; + bias-disable; + }; + }; }; }; + + gpio_keys { + compatible = "gpio-keys"; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_key_gpio_default>; + + bp1 { + label = "PB_USER"; + gpios = <&pioA 41 GPIO_ACTIVE_LOW>; + linux,code = <0x104>; + }; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_led_gpio_default>; + status = "okay"; + + red { + label = "red"; + gpios = <&pioA 38 GPIO_ACTIVE_LOW>; + }; + + green { + label = "green"; + gpios = <&pioA 37 GPIO_ACTIVE_LOW>; + }; + + blue { + label = "blue"; + gpios = <&pioA 32 GPIO_ACTIVE_LOW>; + linux,default-trigger = "heartbeat"; + }; + }; }; diff --git a/arch/arm/boot/dts/at91-sama5d3_xplained.dts b/arch/arm/boot/dts/at91-sama5d3_xplained.dts index ff888d21c786a69b1f56c768ea6a2219056b98dc..f3e2b96c06a361ed01f240797f299ae4a129249c 100644 --- a/arch/arm/boot/dts/at91-sama5d3_xplained.dts +++ b/arch/arm/boot/dts/at91-sama5d3_xplained.dts @@ -303,6 +303,7 @@ regulator-name = "mmc0-card-supply"; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; + regulator-always-on; }; gpio_keys { diff --git a/arch/arm/boot/dts/at91-sama5d4_xplained.dts b/arch/arm/boot/dts/at91-sama5d4_xplained.dts index 569026e8f96cadaf25eeb10ca207c02c7f175121..da84e65b56ef15f9f56675b4f3937fe04002e627 100644 --- a/arch/arm/boot/dts/at91-sama5d4_xplained.dts +++ b/arch/arm/boot/dts/at91-sama5d4_xplained.dts @@ -268,5 +268,6 @@ regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; vin-supply = <&vcc_3v3_reg>; + regulator-always-on; }; }; diff --git a/arch/arm/boot/dts/axm55xx.dtsi b/arch/arm/boot/dts/axm55xx.dtsi index ea288f0a1d3905a51493505f41c5c261ad55f3e4..a9d6d593fc8a7d51fd654e9847f96d1657bdb07f 100644 --- a/arch/arm/boot/dts/axm55xx.dtsi +++ b/arch/arm/boot/dts/axm55xx.dtsi @@ -107,7 +107,7 @@ }; amba { - compatible = "arm,amba-bus"; + compatible = "simple-bus"; #address-cells = <2>; #size-cells = <2>; ranges; diff --git a/arch/arm/boot/dts/bcm-cygnus-clock.dtsi b/arch/arm/boot/dts/bcm-cygnus-clock.dtsi index 32bcd45ef22b36ef42038ac9a49337e686e8300b..80b6ba4ca50c96757b7bf25983e236147cc84ca8 100644 --- a/arch/arm/boot/dts/bcm-cygnus-clock.dtsi +++ b/arch/arm/boot/dts/bcm-cygnus-clock.dtsi @@ -121,4 +121,13 @@ clocks { clocks = <&osc>; clock-output-names = "keypad", "adc/touch", "pwm"; }; + + audiopll: audiopll { + #clock-cells = <1>; + compatible = "brcm,cygnus-audiopll"; + reg = <0x180aeb00 0x68>; + clocks = <&osc>; + clock-output-names = "audiopll", "ch0_audio", + "ch1_audio", "ch2_audio"; + }; }; diff --git a/arch/arm/boot/dts/bcm-nsp.dtsi b/arch/arm/boot/dts/bcm-nsp.dtsi index 10bdef557ba0505ceb05583db76fa88580188b1b..def9e783b5c694844b13986f739043fbde616242 100644 --- a/arch/arm/boot/dts/bcm-nsp.dtsi +++ b/arch/arm/boot/dts/bcm-nsp.dtsi @@ -45,14 +45,14 @@ #address-cells = <1>; #size-cells = <0>; - cpu@0 { + cpu0: cpu@0 { device_type = "cpu"; compatible = "arm,cortex-a9"; next-level-cache = <&L2>; reg = <0x0>; }; - cpu@1 { + cpu1: cpu@1 { device_type = "cpu"; compatible = "arm,cortex-a9"; next-level-cache = <&L2>; @@ -62,24 +62,19 @@ }; }; + pmu { + compatible = "arm,cortex-a9-pmu"; + interrupts = ; + interrupt-affinity = <&cpu0>, <&cpu1>; + }; + mpcore { compatible = "simple-bus"; ranges = <0x00000000 0x19000000 0x00023000>; #address-cells = <1>; #size-cells = <1>; - cpus { - #address-cells = <1>; - #size-cells = <0>; - - cpu@0 { - device_type = "cpu"; - compatible = "arm,cortex-a9"; - next-level-cache = <&L2>; - reg = <0x0>; - }; - }; - a9pll: arm_clk@00000 { #clock-cells = <0>; compatible = "brcm,nsp-armpll"; @@ -169,6 +164,18 @@ #address-cells = <1>; #size-cells = <1>; + gpioa: gpio@0020 { + compatible = "brcm,nsp-gpio-a"; + reg = <0x0020 0x70>, + <0x3f1c4 0x1c>; + #gpio-cells = <2>; + gpio-controller; + ngpios = <32>; + interrupt-controller; + interrupts = ; + gpio-ranges = <&pinctrl 0 0 32>; + }; + uart0: serial@0300 { compatible = "ns16550a"; reg = <0x0300 0x100>; @@ -185,78 +192,6 @@ status = "disabled"; }; - pcie0: pcie@12000 { - compatible = "brcm,iproc-pcie"; - reg = <0x12000 0x1000>; - - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &gic GIC_SPI 131 IRQ_TYPE_NONE>; - - linux,pci-domain = <0>; - - bus-range = <0x00 0xff>; - - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; - - /* Note: The HW does not support I/O resources. So, - * only the memory resource range is being specified. - */ - ranges = <0x82000000 0 0x08000000 0x08000000 0 0x8000000>; - - status = "disabled"; - }; - - pcie1: pcie@13000 { - compatible = "brcm,iproc-pcie"; - reg = <0x13000 0x1000>; - - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &gic GIC_SPI 137 IRQ_TYPE_NONE>; - - linux,pci-domain = <1>; - - bus-range = <0x00 0xff>; - - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; - - /* Note: The HW does not support I/O resources. So, - * only the memory resource range is being specified. - */ - ranges = <0x82000000 0 0x40000000 0x40000000 0 0x8000000>; - - status = "disabled"; - }; - - pcie2: pcie@14000 { - compatible = "brcm,iproc-pcie"; - reg = <0x14000 0x1000>; - - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &gic GIC_SPI 143 IRQ_TYPE_NONE>; - - linux,pci-domain = <2>; - - bus-range = <0x00 0xff>; - - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; - - /* Note: The HW does not support I/O resources. So, - * only the memory resource range is being specified. - */ - ranges = <0x82000000 0 0x48000000 0x48000000 0 0x8000000>; - - status = "disabled"; - }; - nand: nand@26000 { compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; reg = <0x026000 0x600>, @@ -271,6 +206,24 @@ brcm,nand-has-wp; }; + ccbtimer0: timer@34000 { + compatible = "arm,sp804"; + reg = <0x34000 0x1000>; + interrupts = , + ; + clocks = <&iprocslow>; + clock-names = "apb_pclk"; + }; + + ccbtimer1: timer@35000 { + compatible = "arm,sp804"; + reg = <0x35000 0x1000>; + interrupts = , + ; + clocks = <&iprocslow>; + clock-names = "apb_pclk"; + }; + i2c0: i2c@38000 { compatible = "brcm,iproc-i2c"; reg = <0x38000 0x50>; @@ -280,6 +233,14 @@ clock-frequency = <100000>; }; + watchdog@39000 { + compatible = "arm,sp805", "arm,primecell"; + reg = <0x39000 0x1000>; + interrupts = ; + clocks = <&iprocslow>, <&iprocslow>; + clock-names = "wdogclk", "apb_pclk"; + }; + lcpll0: lcpll0@3f100 { #clock-cells = <1>; compatible = "brcm,nsp-lcpll0"; @@ -306,4 +267,76 @@ <0x3f408 0x04>; }; }; + + pcie0: pcie@18012000 { + compatible = "brcm,iproc-pcie"; + reg = <0x18012000 0x1000>; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &gic GIC_SPI 131 IRQ_TYPE_NONE>; + + linux,pci-domain = <0>; + + bus-range = <0x00 0xff>; + + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + + /* Note: The HW does not support I/O resources. So, + * only the memory resource range is being specified. + */ + ranges = <0x82000000 0 0x08000000 0x08000000 0 0x8000000>; + + status = "disabled"; + }; + + pcie1: pcie@18013000 { + compatible = "brcm,iproc-pcie"; + reg = <0x18013000 0x1000>; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &gic GIC_SPI 137 IRQ_TYPE_NONE>; + + linux,pci-domain = <1>; + + bus-range = <0x00 0xff>; + + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + + /* Note: The HW does not support I/O resources. So, + * only the memory resource range is being specified. + */ + ranges = <0x82000000 0 0x40000000 0x40000000 0 0x8000000>; + + status = "disabled"; + }; + + pcie2: pcie@18014000 { + compatible = "brcm,iproc-pcie"; + reg = <0x18014000 0x1000>; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &gic GIC_SPI 143 IRQ_TYPE_NONE>; + + linux,pci-domain = <2>; + + bus-range = <0x00 0xff>; + + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + + /* Note: The HW does not support I/O resources. So, + * only the memory resource range is being specified. + */ + ranges = <0x82000000 0 0x48000000 0x48000000 0 0x8000000>; + + status = "disabled"; + }; }; diff --git a/arch/arm/boot/dts/bcm2835-rpi-a.dts b/arch/arm/boot/dts/bcm2835-rpi-a.dts new file mode 100644 index 0000000000000000000000000000000000000000..ddbbbbd42ddab75a0661222b452a64442065f994 --- /dev/null +++ b/arch/arm/boot/dts/bcm2835-rpi-a.dts @@ -0,0 +1,24 @@ +/dts-v1/; +#include "bcm2835.dtsi" +#include "bcm2835-rpi.dtsi" + +/ { + compatible = "raspberrypi,model-a", "brcm,bcm2835"; + model = "Raspberry Pi Model A"; + + leds { + act { + gpios = <&gpio 16 1>; + }; + }; +}; + +&gpio { + pinctrl-0 = <&gpioout &alt0 &i2s_alt2 &alt3>; + + /* I2S interface */ + i2s_alt2: i2s_alt2 { + brcm,pins = <28 29 30 31>; + brcm,function = ; + }; +}; diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi index 3afb9fefe2d1fb7cd109e54cbb47856c9d9b520a..76bdbcafab18e8ea7c4e06decd315540aac7ef33 100644 --- a/arch/arm/boot/dts/bcm2835-rpi.dtsi +++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi @@ -1,3 +1,5 @@ +#include + / { memory { reg = <0 0x10000000>; @@ -18,6 +20,12 @@ compatible = "raspberrypi,bcm2835-firmware"; mboxes = <&mailbox>; }; + + power: power { + compatible = "raspberrypi,bcm2835-power"; + firmware = <&firmware>; + #power-domain-cells = <1>; + }; }; }; @@ -58,3 +66,11 @@ status = "okay"; bus-width = <4>; }; + +&pwm { + status = "okay"; +}; + +&usb { + power-domains = <&power RPI_POWER_DOMAIN_USB>; +}; diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi index 971e741e5467b24337f712f5b85e8a4816cdaa4e..8aaf193711bfea9872673a4f2fe3ec4bcbfe494a 100644 --- a/arch/arm/boot/dts/bcm283x.dtsi +++ b/arch/arm/boot/dts/bcm283x.dtsi @@ -1,5 +1,6 @@ #include #include +#include #include "skeleton.dtsi" /* This include file covers the common peripherals and configuration between @@ -111,7 +112,7 @@ #interrupt-cells = <2>; }; - uart0: uart@7e201000 { + uart0: serial@7e201000 { compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell"; reg = <0x7e201000 0x1000>; interrupts = <2 25>; @@ -159,6 +160,44 @@ clocks = <&clocks BCM2835_CLOCK_VPU>; }; + uart1: serial@7e215040 { + compatible = "brcm,bcm2835-aux-uart"; + reg = <0x7e215040 0x40>; + interrupts = <1 29>; + clocks = <&aux BCM2835_AUX_CLOCK_UART>; + status = "disabled"; + }; + + spi1: spi@7e215080 { + compatible = "brcm,bcm2835-aux-spi"; + reg = <0x7e215080 0x40>; + interrupts = <1 29>; + clocks = <&aux BCM2835_AUX_CLOCK_SPI1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi2: spi@7e2150c0 { + compatible = "brcm,bcm2835-aux-spi"; + reg = <0x7e2150c0 0x40>; + interrupts = <1 29>; + clocks = <&aux BCM2835_AUX_CLOCK_SPI2>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + pwm: pwm@7e20c000 { + compatible = "brcm,bcm2835-pwm"; + reg = <0x7e20c000 0x28>; + clocks = <&clocks BCM2835_CLOCK_PWM>; + assigned-clocks = <&clocks BCM2835_CLOCK_PWM>; + assigned-clock-rates = <10000000>; + #pwm-cells = <2>; + status = "disabled"; + }; + sdhci: sdhci@7e300000 { compatible = "brcm,bcm2835-sdhci"; reg = <0x7e300000 0x100>; @@ -187,7 +226,7 @@ status = "disabled"; }; - usb@7e980000 { + usb: usb@7e980000 { compatible = "brcm,bcm2835-usb"; reg = <0x7e980000 0x10000>; interrupts = <1 9>; diff --git a/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts new file mode 100644 index 0000000000000000000000000000000000000000..6c83538bc2d77afd98988bba250494bf1b90d0ff --- /dev/null +++ b/arch/arm/boot/dts/bcm47094-dlink-dir-885l.dts @@ -0,0 +1,111 @@ +/* + * Broadcom BCM470X / BCM5301X ARM platform code. + * DTS for D-Link DIR-885L + * + * Copyright (C) 2016 Rafał Miłecki + * + * Licensed under the GNU/GPL. See COPYING for details. + */ + +/dts-v1/; + +#include "bcm4708.dtsi" +#include "bcm5301x-nand-cs0-bch8.dtsi" + +/ { + compatible = "dlink,dir-885l", "brcm,bcm47094", "brcm,bcm4708"; + model = "D-Link DIR-885L"; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + memory { + reg = <0x00000000 0x08000000>; + }; + + nand: nand@18028000 { + nandcs@0 { + partition@0 { + label = "firmware"; + reg = <0x00000000 0x08000000>; + }; + }; + }; + + leds { + compatible = "gpio-leds"; + + power-white { + label = "bcm53xx:white:power"; + gpios = <&chipcommon 0 GPIO_ACTIVE_LOW>; + linux,default-trigger = "default-on"; + }; + + wan-white { + label = "bcm53xx:white:wan"; + gpios = <&chipcommon 1 GPIO_ACTIVE_LOW>; + linux,default-trigger = "default-off"; + }; + + power-amber { + label = "bcm53xx:amber:power"; + gpios = <&chipcommon 2 GPIO_ACTIVE_LOW>; + linux,default-trigger = "default-off"; + }; + + wan-amber { + label = "bcm53xx:amber:wan"; + gpios = <&chipcommon 3 GPIO_ACTIVE_LOW>; + linux,default-trigger = "default-off"; + }; + + usb3-white { + label = "bcm53xx:white:usb3"; + gpios = <&chipcommon 8 GPIO_ACTIVE_LOW>; + linux,default-trigger = "default-off"; + }; + + 2ghz { + label = "bcm53xx:white:2ghz"; + gpios = <&chipcommon 13 GPIO_ACTIVE_LOW>; + linux,default-trigger = "default-off"; + }; + + 5ghz { + label = "bcm53xx:white:5ghz"; + gpios = <&chipcommon 14 GPIO_ACTIVE_LOW>; + linux,default-trigger = "default-off"; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + wps { + label = "WPS"; + linux,code = ; + gpios = <&chipcommon 7 GPIO_ACTIVE_LOW>; + }; + + /* Switch: router / extender */ + extender { + label = "Extender"; + linux,code = ; + gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>; + }; + + restart { + label = "Reset"; + linux,code = ; + gpios = <&chipcommon 17 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&uart0 { + status = "okay"; + clock-frequency = <125000000>; +}; diff --git a/arch/arm/boot/dts/cros-ec-keyboard.dtsi b/arch/arm/boot/dts/cros-ec-keyboard.dtsi index 4e42f30cb318df29a1fad4c9ef8752c769cad137..c0451051777ea234283c79c834319f43c57c8c50 100644 --- a/arch/arm/boot/dts/cros-ec-keyboard.dtsi +++ b/arch/arm/boot/dts/cros-ec-keyboard.dtsi @@ -55,6 +55,7 @@ MATRIX_KEY(0x03, 0x04, KEY_F5) MATRIX_KEY(0x03, 0x06, KEY_6) MATRIX_KEY(0x03, 0x08, KEY_MINUS) + MATRIX_KEY(0x03, 0x09, KEY_F13) MATRIX_KEY(0x03, 0x0b, KEY_BACKSLASH) MATRIX_KEY(0x03, 0x0c, KEY_MUHENKAN) diff --git a/arch/arm/boot/dts/dm8148-evm.dts b/arch/arm/boot/dts/dm8148-evm.dts index e070862b1038346c0ab984a116425bba52b01dd4..cbc17b0794b102fb2f0862958203c19c1fe79dae 100644 --- a/arch/arm/boot/dts/dm8148-evm.dts +++ b/arch/arm/boot/dts/dm8148-evm.dts @@ -6,6 +6,7 @@ /dts-v1/; #include "dm814x.dtsi" +#include / { model = "DM8148 EVM"; @@ -35,6 +36,63 @@ phy-mode = "rgmii"; }; +&gpmc { + ranges = <0 0 0x04000000 0x01000000>; /* CS0: 16MB for NAND */ + + nand@0,0 { + compatible = "ti,omap2-nand"; + reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ + interrupt-parent = <&gpmc>; + interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ + <1 IRQ_TYPE_NONE>; /* termcount */ + linux,mtd-name= "micron,mt29f2g16aadwp"; + #address-cells = <1>; + #size-cells = <1>; + ti,nand-ecc-opt = "bch8"; + nand-bus-width = <16>; + gpmc,device-width = <2>; + gpmc,sync-clk-ps = <0>; + gpmc,cs-on-ns = <0>; + gpmc,cs-rd-off-ns = <44>; + gpmc,cs-wr-off-ns = <44>; + gpmc,adv-on-ns = <6>; + gpmc,adv-rd-off-ns = <34>; + gpmc,adv-wr-off-ns = <44>; + gpmc,we-on-ns = <0>; + gpmc,we-off-ns = <40>; + gpmc,oe-on-ns = <0>; + gpmc,oe-off-ns = <54>; + gpmc,access-ns = <64>; + gpmc,rd-cycle-ns = <82>; + gpmc,wr-cycle-ns = <82>; + gpmc,bus-turnaround-ns = <0>; + gpmc,cycle2cycle-delay-ns = <0>; + gpmc,clk-activation-ns = <0>; + gpmc,wr-access-ns = <40>; + gpmc,wr-data-mux-bus-ns = <0>; + partition@0 { + label = "X-Loader"; + reg = <0 0x80000>; + }; + partition@0x80000 { + label = "U-Boot"; + reg = <0x80000 0x1c0000>; + }; + partition@0x1c0000 { + label = "Environment"; + reg = <0x240000 0x40000>; + }; + partition@0x280000 { + label = "Kernel"; + reg = <0x280000 0x500000>; + }; + partition@0x780000 { + label = "Filesystem"; + reg = <0x780000 0xf880000>; + }; + }; +}; + &mmc2 { pinctrl-names = "default"; pinctrl-0 = <&sd1_pins>; diff --git a/arch/arm/boot/dts/dm814x-clocks.dtsi b/arch/arm/boot/dts/dm814x-clocks.dtsi index 26001585673add86c25b11874d4a98c3a55ec691..e0ea6a93a22ed722392295828c21802ac54dae2d 100644 --- a/arch/arm/boot/dts/dm814x-clocks.dtsi +++ b/arch/arm/boot/dts/dm814x-clocks.dtsi @@ -41,11 +41,11 @@ reg = <0x0040>; }; - /* Optional auxosc, 20 - 30 MHz range, assume 27 MHz by default */ + /* Optional auxosc, 20 - 30 MHz range, assume 22.5729 MHz by default */ auxosc_ck: auxosc_ck { #clock-cells = <0>; compatible = "fixed-clock"; - clock-frequency = <27000000>; + clock-frequency = <22572900>; }; /* Optional 32768Hz crystal or clock on RTCOSC pins */ diff --git a/arch/arm/boot/dts/dm814x.dtsi b/arch/arm/boot/dts/dm814x.dtsi index a25cd51e39ab0d8d43f845617b2e2ef69786610e..4a6ce8c8bf8f857ca09feba084439602bc44b8ff 100644 --- a/arch/arm/boot/dts/dm814x.dtsi +++ b/arch/arm/boot/dts/dm814x.dtsi @@ -305,6 +305,13 @@ reg = <0x60000 0x1000>; }; + rtc: rtc@c0000 { + compatible = "ti,am3352-rtc", "ti,da830-rtc"; + reg = <0xc0000 0x1000>; + interrupts = <75 76>; + ti,hwmods = "rtc"; + }; + mmc2: mmc@1d8000 { compatible = "ti,omap4-hsmmc"; ti,hwmods = "mmc2"; @@ -548,6 +555,20 @@ reg-names = "gmii-sel"; }; }; + + gpmc: gpmc@50000000 { + compatible = "ti,am3352-gpmc"; + ti,hwmods = "gpmc"; + ti,no-idle-on-init; + reg = <0x50000000 0x2000>; + interrupts = <100>; + gpmc,num-cs = <7>; + gpmc,num-waitpins = <2>; + #address-cells = <2>; + #size-cells = <1>; + interrupt-controller; + #interrupt-cells = <2>; + }; }; }; diff --git a/arch/arm/boot/dts/dm8168-evm.dts b/arch/arm/boot/dts/dm8168-evm.dts index 169a85578fc93e31927c10ce381b9407a484fe38..f50348bdd8574125d53ae55b0c37ad974aff9818 100644 --- a/arch/arm/boot/dts/dm8168-evm.dts +++ b/arch/arm/boot/dts/dm8168-evm.dts @@ -6,6 +6,7 @@ /dts-v1/; #include "dm816x.dtsi" +#include / { model = "DM8168 EVM"; @@ -85,8 +86,12 @@ ranges = <0 0 0x04000000 0x01000000>; /* CS0: 16MB for NAND */ nand@0,0 { + compatible = "ti,omap2-nand"; linux,mtd-name= "micron,mt29f2g16aadwp"; reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ + interrupt-parent = <&gpmc>; + interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ + <1 IRQ_TYPE_NONE>; /* termcount */ #address-cells = <1>; #size-cells = <1>; ti,nand-ecc-opt = "bch8"; @@ -106,12 +111,9 @@ gpmc,access-ns = <64>; gpmc,rd-cycle-ns = <82>; gpmc,wr-cycle-ns = <82>; - gpmc,wait-on-read = "true"; - gpmc,wait-on-write = "true"; gpmc,bus-turnaround-ns = <0>; gpmc,cycle2cycle-delay-ns = <0>; gpmc,clk-activation-ns = <0>; - gpmc,wait-monitoring-ns = <0>; gpmc,wr-access-ns = <40>; gpmc,wr-data-mux-bus-ns = <0>; partition@0 { diff --git a/arch/arm/boot/dts/dm816x.dtsi b/arch/arm/boot/dts/dm816x.dtsi index c3b8811a3e587ff36dceff668f5f6a9f38cfe702..d9309a0161171ec1315f42c8f94b3d1bccbafd84 100644 --- a/arch/arm/boot/dts/dm816x.dtsi +++ b/arch/arm/boot/dts/dm816x.dtsi @@ -183,6 +183,8 @@ dma-names = "rxtx"; gpmc,num-cs = <6>; gpmc,num-waitpins = <2>; + interrupt-controller; + #interrupt-cells = <2>; }; i2c1: i2c@48028000 { @@ -214,6 +216,13 @@ reg = <0x48200000 0x1000>; }; + rtc: rtc@480c0000 { + compatible = "ti,am3352-rtc", "ti,da830-rtc"; + reg = <0x480c0000 0x1000>; + interrupts = <75 76>; + ti,hwmods = "rtc"; + }; + mailbox: mailbox@480c8000 { compatible = "ti,omap4-mailbox"; reg = <0x480c8000 0x2000>; diff --git a/arch/arm/boot/dts/dra62x-j5eco-evm.dts b/arch/arm/boot/dts/dra62x-j5eco-evm.dts index 79008069020da87d2cccca6530600c47850c49d5..f820573f4a4a13eabce0a214c5e746fbaab54633 100644 --- a/arch/arm/boot/dts/dra62x-j5eco-evm.dts +++ b/arch/arm/boot/dts/dra62x-j5eco-evm.dts @@ -6,6 +6,7 @@ /dts-v1/; #include "dra62x.dtsi" +#include / { model = "DRA62x J5 Eco EVM"; @@ -35,6 +36,63 @@ phy-mode = "rgmii"; }; +&gpmc { + ranges = <0 0 0x04000000 0x01000000>; /* CS0: 16MB for NAND */ + + nand@0,0 { + compatible = "ti,omap2-nand"; + reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ + interrupt-parent = <&gpmc>; + interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ + <1 IRQ_TYPE_NONE>; /* termcount */ + linux,mtd-name= "micron,mt29f2g16aadwp"; + #address-cells = <1>; + #size-cells = <1>; + ti,nand-ecc-opt = "bch8"; + nand-bus-width = <16>; + gpmc,device-width = <2>; + gpmc,sync-clk-ps = <0>; + gpmc,cs-on-ns = <0>; + gpmc,cs-rd-off-ns = <44>; + gpmc,cs-wr-off-ns = <44>; + gpmc,adv-on-ns = <6>; + gpmc,adv-rd-off-ns = <34>; + gpmc,adv-wr-off-ns = <44>; + gpmc,we-on-ns = <0>; + gpmc,we-off-ns = <40>; + gpmc,oe-on-ns = <0>; + gpmc,oe-off-ns = <54>; + gpmc,access-ns = <64>; + gpmc,rd-cycle-ns = <82>; + gpmc,wr-cycle-ns = <82>; + gpmc,bus-turnaround-ns = <0>; + gpmc,cycle2cycle-delay-ns = <0>; + gpmc,clk-activation-ns = <0>; + gpmc,wr-access-ns = <40>; + gpmc,wr-data-mux-bus-ns = <0>; + partition@0 { + label = "X-Loader"; + reg = <0 0x80000>; + }; + partition@0x80000 { + label = "U-Boot"; + reg = <0x80000 0x1c0000>; + }; + partition@0x1c0000 { + label = "Environment"; + reg = <0x240000 0x40000>; + }; + partition@0x280000 { + label = "Kernel"; + reg = <0x280000 0x500000>; + }; + partition@0x780000 { + label = "Filesystem"; + reg = <0x780000 0xf880000>; + }; + }; +}; + &mmc2 { pinctrl-names = "default"; pinctrl-0 = <&sd1_pins>; diff --git a/arch/arm/boot/dts/dra7-dspeve-thermal.dtsi b/arch/arm/boot/dts/dra7-dspeve-thermal.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..1c39a8459b39cade2795e63c91fc0e5a5418a1c3 --- /dev/null +++ b/arch/arm/boot/dts/dra7-dspeve-thermal.dtsi @@ -0,0 +1,27 @@ +/* + * Device Tree Source for DRA7x SoC DSPEVE thermal + * + * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/ + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#include + +dspeve_thermal: dspeve_thermal { + polling-delay-passive = <250>; /* milliseconds */ + polling-delay = <500>; /* milliseconds */ + + /* sensor ID */ + thermal-sensors = <&bandgap 3>; + + trips { + dspeve_crit: dspeve_crit { + temperature = <125000>; /* milliCelsius */ + hysteresis = <2000>; /* milliCelsius */ + type = "critical"; + }; + }; +}; diff --git a/arch/arm/boot/dts/dra7-evm.dts b/arch/arm/boot/dts/dra7-evm.dts index cfc24e52244e1b8b12f7d2e939458831df9173fe..d9b87236019d8d9aec502cd9235cf7f0863a8b96 100644 --- a/arch/arm/boot/dts/dra7-evm.dts +++ b/arch/arm/boot/dts/dra7-evm.dts @@ -18,7 +18,7 @@ memory { device_type = "memory"; - reg = <0x80000000 0x60000000>; /* 1536 MB */ + reg = <0x0 0x80000000 0x0 0x60000000>; /* 1536 MB */ }; evm_3v3_sd: fixedregulator-sd { @@ -741,9 +741,13 @@ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&nand_flash_x16>; - ranges = <0 0 0 0x01000000>; /* minimum GPMC partition = 16MB */ + ranges = <0 0 0x08000000 0x01000000>; /* minimum GPMC partition = 16MB */ nand@0,0 { + compatible = "ti,omap2-nand"; reg = <0 0 4>; /* device IO registers */ + interrupt-parent = <&gpmc>; + interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ + <1 IRQ_TYPE_NONE>; /* termcount */ ti,nand-ecc-opt = "bch8"; ti,elm-id = <&elm>; nand-bus-width = <16>; @@ -766,7 +770,6 @@ gpmc,bus-turnaround-ns = <0>; gpmc,cycle2cycle-delay-ns = <0>; gpmc,clk-activation-ns = <0>; - gpmc,wait-monitoring-ns = <0>; gpmc,wr-data-mux-bus-ns = <0>; /* MTD partition table */ /* All SPL-* partitions are sized to minimal length diff --git a/arch/arm/boot/dts/dra7-iva-thermal.dtsi b/arch/arm/boot/dts/dra7-iva-thermal.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..dd74a5337d1fd1b4b21b74b5b2011a88e3711482 --- /dev/null +++ b/arch/arm/boot/dts/dra7-iva-thermal.dtsi @@ -0,0 +1,27 @@ +/* + * Device Tree Source for DRA7x SoC IVA thermal + * + * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/ + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#include + +iva_thermal: iva_thermal { + polling-delay-passive = <250>; /* milliseconds */ + polling-delay = <500>; /* milliseconds */ + + /* sensor ID */ + thermal-sensors = <&bandgap 4>; + + trips { + iva_crit: iva_crit { + temperature = <125000>; /* milliCelsius */ + hysteresis = <2000>; /* milliCelsius */ + type = "critical"; + }; + }; +}; diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi index f82aa44c3ceed540fef7e291c571c2b49c5b2e1f..13ac882794270eea60abd54272480a073e3ab174 100644 --- a/arch/arm/boot/dts/dra7.dtsi +++ b/arch/arm/boot/dts/dra7.dtsi @@ -15,8 +15,8 @@ #define MAX_SOURCES 400 / { - #address-cells = <1>; - #size-cells = <1>; + #address-cells = <2>; + #size-cells = <2>; compatible = "ti,dra7xx"; interrupt-parent = <&crossbar_mpu>; @@ -57,10 +57,10 @@ compatible = "arm,cortex-a15-gic"; interrupt-controller; #interrupt-cells = <3>; - reg = <0x48211000 0x1000>, - <0x48212000 0x1000>, - <0x48214000 0x2000>, - <0x48216000 0x2000>; + reg = <0x0 0x48211000 0x0 0x1000>, + <0x0 0x48212000 0x0 0x1000>, + <0x0 0x48214000 0x0 0x2000>, + <0x0 0x48216000 0x0 0x2000>; interrupts = ; interrupt-parent = <&gic>; }; @@ -69,7 +69,7 @@ compatible = "ti,omap5-wugen-mpu", "ti,omap4-wugen-mpu"; interrupt-controller; #interrupt-cells = <3>; - reg = <0x48281000 0x1000>; + reg = <0x0 0x48281000 0x0 0x1000>; interrupt-parent = <&gic>; }; @@ -96,10 +96,10 @@ compatible = "ti,dra7-l3-noc", "simple-bus"; #address-cells = <1>; #size-cells = <1>; - ranges; + ranges = <0x0 0x0 0x0 0xc0000000>; ti,hwmods = "l3_main_1", "l3_main_2"; - reg = <0x44000000 0x1000000>, - <0x45000000 0x1000>; + reg = <0x0 0x44000000 0x0 0x1000000>, + <0x0 0x45000000 0x0 0x1000>; interrupts-extended = <&crossbar_mpu GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>, <&wakeupgen GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; @@ -156,6 +156,11 @@ compatible = "syscon"; reg = <0x1c04 0x0020>; }; + + scm_conf_pcie: scm_conf@1c24 { + compatible = "syscon"; + reg = <0x1c24 0x0024>; + }; }; cm_core_aon: cm_core_aon@5000 { @@ -1168,14 +1173,6 @@ status = "disabled"; }; - omap_control_sata: control-phy@4a002374 { - compatible = "ti,control-phy-pipe3"; - reg = <0x4a002374 0x4>; - reg-names = "power"; - clocks = <&sys_clkin1>; - clock-names = "sysclk"; - }; - /* OCP2SCP3 */ ocp2scp@4a090000 { compatible = "ti,omap-ocp2scp"; @@ -1190,7 +1187,7 @@ <0x4A096400 0x64>, /* phy_tx */ <0x4A096800 0x40>; /* pll_ctrl */ reg-names = "phy_rx", "phy_tx", "pll_ctrl"; - ctrl-module = <&omap_control_sata>; + syscon-phy-power = <&scm_conf 0x374>; clocks = <&sys_clkin1>, <&sata_ref_clk>; clock-names = "sysclk", "refclk"; syscon-pllreset = <&scm_conf 0x3fc>; @@ -1202,16 +1199,18 @@ reg = <0x4a094000 0x80>, /* phy_rx */ <0x4a094400 0x64>; /* phy_tx */ reg-names = "phy_rx", "phy_tx"; - ctrl-module = <&omap_control_pcie1phy>; + syscon-phy-power = <&scm_conf_pcie 0x1c>; + syscon-pcs = <&scm_conf_pcie 0x10>; clocks = <&dpll_pcie_ref_ck>, <&dpll_pcie_ref_m2ldo_ck>, <&optfclk_pciephy1_32khz>, <&optfclk_pciephy1_clk>, <&optfclk_pciephy1_div_clk>, - <&optfclk_pciephy_div>; + <&optfclk_pciephy_div>, + <&sys_clkin1>; clock-names = "dpll_ref", "dpll_ref_m2", "wkupclk", "refclk", - "div-clk", "phy-div"; + "div-clk", "phy-div", "sysclk"; #phy-cells = <0>; }; @@ -1220,16 +1219,18 @@ reg = <0x4a095000 0x80>, /* phy_rx */ <0x4a095400 0x64>; /* phy_tx */ reg-names = "phy_rx", "phy_tx"; - ctrl-module = <&omap_control_pcie2phy>; + syscon-phy-power = <&scm_conf_pcie 0x20>; + syscon-pcs = <&scm_conf_pcie 0x10>; clocks = <&dpll_pcie_ref_ck>, <&dpll_pcie_ref_m2ldo_ck>, <&optfclk_pciephy2_32khz>, <&optfclk_pciephy2_clk>, <&optfclk_pciephy2_div_clk>, - <&optfclk_pciephy_div>; + <&optfclk_pciephy_div>, + <&sys_clkin1>; clock-names = "dpll_ref", "dpll_ref_m2", "wkupclk", "refclk", - "div-clk", "phy-div"; + "div-clk", "phy-div", "sysclk"; #phy-cells = <0>; status = "disabled"; }; @@ -1245,23 +1246,6 @@ ti,hwmods = "sata"; }; - omap_control_pcie1phy: control-phy@0x4a003c40 { - compatible = "ti,control-phy-pcie"; - reg = <0x4a003c40 0x4>, <0x4a003c14 0x4>, <0x4a003c34 0x4>; - reg-names = "power", "control_sma", "pcie_pcs"; - clocks = <&sys_clkin1>; - clock-names = "sysclk"; - }; - - omap_control_pcie2phy: control-pcie@0x4a003c44 { - compatible = "ti,control-phy-pcie"; - reg = <0x4a003c44 0x4>, <0x4a003c14 0x4>, <0x4a003c34 0x4>; - reg-names = "power", "control_sma", "pcie_pcs"; - clocks = <&sys_clkin1>; - clock-names = "sysclk"; - status = "disabled"; - }; - rtc: rtc@48838000 { compatible = "ti,am3352-rtc"; reg = <0x48838000 0x100>; @@ -1271,24 +1255,6 @@ clocks = <&sys_32k_ck>; }; - omap_control_usb2phy1: control-phy@4a002300 { - compatible = "ti,control-phy-usb2"; - reg = <0x4a002300 0x4>; - reg-names = "power"; - }; - - omap_control_usb3phy1: control-phy@4a002370 { - compatible = "ti,control-phy-pipe3"; - reg = <0x4a002370 0x4>; - reg-names = "power"; - }; - - omap_control_usb2phy2: control-phy@0x4a002e74 { - compatible = "ti,control-phy-usb2-dra7"; - reg = <0x4a002e74 0x4>; - reg-names = "power"; - }; - /* OCP2SCP1 */ ocp2scp@4a080000 { compatible = "ti,omap-ocp2scp"; @@ -1301,7 +1267,7 @@ usb2_phy1: phy@4a084000 { compatible = "ti,omap-usb2"; reg = <0x4a084000 0x400>; - ctrl-module = <&omap_control_usb2phy1>; + syscon-phy-power = <&scm_conf 0x300>; clocks = <&usb_phy1_always_on_clk32k>, <&usb_otg_ss1_refclk960m>; clock-names = "wkupclk", @@ -1310,9 +1276,10 @@ }; usb2_phy2: phy@4a085000 { - compatible = "ti,omap-usb2"; + compatible = "ti,dra7x-usb2-phy2", + "ti,omap-usb2"; reg = <0x4a085000 0x400>; - ctrl-module = <&omap_control_usb2phy2>; + syscon-phy-power = <&scm_conf 0xe74>; clocks = <&usb_phy2_always_on_clk32k>, <&usb_otg_ss2_refclk960m>; clock-names = "wkupclk", @@ -1326,7 +1293,7 @@ <0x4a084800 0x64>, <0x4a084c00 0x40>; reg-names = "phy_rx", "phy_tx", "pll_ctrl"; - ctrl-module = <&omap_control_usb3phy1>; + syscon-phy-power = <&scm_conf 0x370>; clocks = <&usb_phy3_always_on_clk32k>, <&sys_clkin1>, <&usb_otg_ss1_refclk960m>; @@ -1357,7 +1324,6 @@ "otg"; phys = <&usb2_phy1>, <&usb3_phy1>; phy-names = "usb2-phy", "usb3-phy"; - tx-fifo-resize; maximum-speed = "super-speed"; dr_mode = "otg"; snps,dis_u3_susphy_quirk; @@ -1385,7 +1351,6 @@ "otg"; phys = <&usb2_phy2>; phy-names = "usb2-phy"; - tx-fifo-resize; maximum-speed = "high-speed"; dr_mode = "otg"; snps,dis_u3_susphy_quirk; @@ -1413,7 +1378,6 @@ interrupt-names = "peripheral", "host", "otg"; - tx-fifo-resize; maximum-speed = "high-speed"; dr_mode = "otg"; snps,dis_u3_susphy_quirk; @@ -1438,6 +1402,8 @@ gpmc,num-waitpins = <2>; #address-cells = <2>; #size-cells = <1>; + interrupt-controller; + #interrupt-cells = <2>; status = "disabled"; }; @@ -1613,6 +1579,8 @@ #include "omap4-cpu-thermal.dtsi" #include "omap5-gpu-thermal.dtsi" #include "omap5-core-thermal.dtsi" + #include "dra7-dspeve-thermal.dtsi" + #include "dra7-iva-thermal.dtsi" }; }; diff --git a/arch/arm/boot/dts/dra72-evm.dts b/arch/arm/boot/dts/dra72-evm.dts index 00b12002c07c064df61c029cfa1ab9f97ba25323..6affe2d137da882d4434b223bf0eed07d8696b45 100644 --- a/arch/arm/boot/dts/dra72-evm.dts +++ b/arch/arm/boot/dts/dra72-evm.dts @@ -17,7 +17,7 @@ memory { device_type = "memory"; - reg = <0x80000000 0x40000000>; /* 1024 MB */ + reg = <0x0 0x80000000 0x0 0x40000000>; /* 1024 MB */ }; aliases { @@ -492,13 +492,17 @@ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&nand_default>; - ranges = <0 0 0 0x01000000>; /* minimum GPMC partition = 16MB */ + ranges = <0 0 0x08000000 0x01000000>; /* minimum GPMC partition = 16MB */ nand@0,0 { /* To use NAND, DIP switch SW5 must be set like so: * SW5.1 (NAND_SELn) = ON (LOW) * SW5.9 (GPMC_WPN) = OFF (HIGH) */ + compatible = "ti,omap2-nand"; reg = <0 0 4>; /* device IO registers */ + interrupt-parent = <&gpmc>; + interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ + <1 IRQ_TYPE_NONE>; /* termcount */ ti,nand-ecc-opt = "bch8"; ti,elm-id = <&elm>; nand-bus-width = <16>; @@ -521,7 +525,6 @@ gpmc,bus-turnaround-ns = <0>; gpmc,cycle2cycle-delay-ns = <0>; gpmc,clk-activation-ns = <0>; - gpmc,wait-monitoring-ns = <0>; gpmc,wr-data-mux-bus-ns = <0>; /* MTD partition table */ /* All SPL-* partitions are sized to minimal length diff --git a/arch/arm/boot/dts/dra74x.dtsi b/arch/arm/boot/dts/dra74x.dtsi index 8bcc47db1cd180f4e175f66ddcca7ba3103728cf..4220eeffc65ae806892f353efce4eab400a9cdb9 100644 --- a/arch/arm/boot/dts/dra74x.dtsi +++ b/arch/arm/boot/dts/dra74x.dtsi @@ -76,7 +76,6 @@ interrupt-names = "peripheral", "host", "otg"; - tx-fifo-resize; maximum-speed = "high-speed"; dr_mode = "otg"; }; diff --git a/arch/arm/boot/dts/dra7xx-clocks.dtsi b/arch/arm/boot/dts/dra7xx-clocks.dtsi index 357bedeebfac45e451a57ca736cf993bd2698c24..d0bae06b7eb7e8600f75213a576b778704ecacff 100644 --- a/arch/arm/boot/dts/dra7xx-clocks.dtsi +++ b/arch/arm/boot/dts/dra7xx-clocks.dtsi @@ -2146,4 +2146,28 @@ ti,bit-shift = <0>; reg = <0x558>; }; + + ehrpwm0_tbclk: ehrpwm0_tbclk { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&l4_root_clk_div>; + ti,bit-shift = <20>; + reg = <0x0558>; + }; + + ehrpwm1_tbclk: ehrpwm1_tbclk { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&l4_root_clk_div>; + ti,bit-shift = <21>; + reg = <0x0558>; + }; + + ehrpwm2_tbclk: ehrpwm2_tbclk { + #clock-cells = <0>; + compatible = "ti,gate-clock"; + clocks = <&l4_root_clk_div>; + ti,bit-shift = <22>; + reg = <0x0558>; + }; }; diff --git a/arch/arm/boot/dts/emev2.dtsi b/arch/arm/boot/dts/emev2.dtsi index 57795da616cb40850428861c7756164ace137937..bcce6f50c93d9d2579b7e9b524f65ba8a11af40c 100644 --- a/arch/arm/boot/dts/emev2.dtsi +++ b/arch/arm/boot/dts/emev2.dtsi @@ -9,6 +9,7 @@ */ #include "skeleton.dtsi" +#include #include / { @@ -53,8 +54,8 @@ pmu { compatible = "arm,cortex-a9-pmu"; - interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>, - <0 121 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; }; clocks@e0110000 { @@ -158,7 +159,7 @@ timer@e0180000 { compatible = "renesas,em-sti"; reg = <0xe0180000 0x54>; - interrupts = <0 125 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&sti_sclk>; clock-names = "sclk"; }; @@ -166,7 +167,7 @@ uart0: serial@e1020000 { compatible = "renesas,em-uart"; reg = <0xe1020000 0x38>; - interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&usia_u0_sclk>; clock-names = "sclk"; }; @@ -174,7 +175,7 @@ uart1: serial@e1030000 { compatible = "renesas,em-uart"; reg = <0xe1030000 0x38>; - interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&usib_u1_sclk>; clock-names = "sclk"; }; @@ -182,7 +183,7 @@ uart2: serial@e1040000 { compatible = "renesas,em-uart"; reg = <0xe1040000 0x38>; - interrupts = <0 10 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&usib_u2_sclk>; clock-names = "sclk"; }; @@ -190,7 +191,7 @@ uart3: serial@e1050000 { compatible = "renesas,em-uart"; reg = <0xe1050000 0x38>; - interrupts = <0 11 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&usib_u3_sclk>; clock-names = "sclk"; }; @@ -203,8 +204,8 @@ gpio0: gpio@e0050000 { compatible = "renesas,em-gio"; reg = <0xe0050000 0x2c>, <0xe0050040 0x20>; - interrupts = <0 67 IRQ_TYPE_LEVEL_HIGH>, - <0 68 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; gpio-controller; gpio-ranges = <&pfc 0 0 32>; #gpio-cells = <2>; @@ -215,8 +216,8 @@ gpio1: gpio@e0050080 { compatible = "renesas,em-gio"; reg = <0xe0050080 0x2c>, <0xe00500c0 0x20>; - interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>, - <0 70 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; gpio-controller; gpio-ranges = <&pfc 0 32 32>; #gpio-cells = <2>; @@ -227,8 +228,8 @@ gpio2: gpio@e0050100 { compatible = "renesas,em-gio"; reg = <0xe0050100 0x2c>, <0xe0050140 0x20>; - interrupts = <0 71 IRQ_TYPE_LEVEL_HIGH>, - <0 72 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; gpio-controller; gpio-ranges = <&pfc 0 64 32>; #gpio-cells = <2>; @@ -239,8 +240,8 @@ gpio3: gpio@e0050180 { compatible = "renesas,em-gio"; reg = <0xe0050180 0x2c>, <0xe00501c0 0x20>; - interrupts = <0 73 IRQ_TYPE_LEVEL_HIGH>, - <0 74 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; gpio-controller; gpio-ranges = <&pfc 0 96 32>; #gpio-cells = <2>; @@ -251,8 +252,8 @@ gpio4: gpio@e0050200 { compatible = "renesas,em-gio"; reg = <0xe0050200 0x2c>, <0xe0050240 0x20>; - interrupts = <0 75 IRQ_TYPE_LEVEL_HIGH>, - <0 76 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; gpio-controller; gpio-ranges = <&pfc 0 128 31>; #gpio-cells = <2>; @@ -266,7 +267,7 @@ #size-cells = <0>; compatible = "renesas,iic-emev2"; reg = <0xe0070000 0x28>; - interrupts = <0 32 IRQ_TYPE_EDGE_RISING>; + interrupts = ; clocks = <&iic0_sclk>; clock-names = "sclk"; status = "disabled"; @@ -277,7 +278,7 @@ #size-cells = <0>; compatible = "renesas,iic-emev2"; reg = <0xe10a0000 0x28>; - interrupts = <0 33 IRQ_TYPE_EDGE_RISING>; + interrupts = ; clocks = <&iic1_sclk>; clock-names = "sclk"; status = "disabled"; diff --git a/arch/arm/boot/dts/exynos-syscon-restart.dtsi b/arch/arm/boot/dts/exynos-syscon-restart.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..09a2040054edc360435b378d50202ceb55144df1 --- /dev/null +++ b/arch/arm/boot/dts/exynos-syscon-restart.dtsi @@ -0,0 +1,27 @@ +/* + * Samsung's Exynos SoC syscon reboot/poweroff nodes common 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 + * published by the Free Software Foundation. + */ + +/ { + soc { + compatible = "simple-bus"; + + poweroff: syscon-poweroff { + compatible = "syscon-poweroff"; + regmap = <&pmu_system_controller>; + offset = <0x330C>; /* PS_HOLD_CONTROL */ + mask = <0x5200>; /* reset value */ + }; + + reboot: syscon-reboot { + compatible = "syscon-reboot"; + regmap = <&pmu_system_controller>; + offset = <0x0400>; /* SWRESET */ + mask = <0x1>; + }; + }; +}; diff --git a/arch/arm/boot/dts/exynos3250-monk.dts b/arch/arm/boot/dts/exynos3250-monk.dts index 443a350858460692d18bbe9f9470b0b3778d27a8..9e2840b59ae8520582717eb85369780090de7416 100644 --- a/arch/arm/boot/dts/exynos3250-monk.dts +++ b/arch/arm/boot/dts/exynos3250-monk.dts @@ -43,7 +43,7 @@ linux,code = ; label = "power key"; debounce-interval = <10>; - gpio-key,wakeup; + wakeup-source; }; }; @@ -67,7 +67,7 @@ interrupt-parent = <&gpx1>; interrupts = <5 0>; reg = <0x25>; - wakeup; + wakeup-source; muic: max77836-muic { compatible = "maxim,max77836-muic"; @@ -185,7 +185,7 @@ interrupt-parent = <&gpx0>; interrupts = <7 0>; reg = <0x66>; - wakeup; + wakeup-source; s2mps14_osc: clocks { compatible = "samsung,s2mps14-clk"; diff --git a/arch/arm/boot/dts/exynos3250-rinato.dts b/arch/arm/boot/dts/exynos3250-rinato.dts index 3e64d5dcdd60c6abfc9a0a9249f71bb54cd77eb9..1f102f3a1ab1117fd6dae8974878ca4188d03de7 100644 --- a/arch/arm/boot/dts/exynos3250-rinato.dts +++ b/arch/arm/boot/dts/exynos3250-rinato.dts @@ -43,7 +43,7 @@ linux,code = ; label = "power key"; debounce-interval = <10>; - gpio-key,wakeup; + wakeup-source; }; }; @@ -58,7 +58,7 @@ interrupt-parent = <&gpx1>; interrupts = <5 0>; reg = <0x25>; - wakeup; + wakeup-source; muic: max77836-muic { compatible = "maxim,max77836-muic"; @@ -246,7 +246,7 @@ interrupt-parent = <&gpx0>; interrupts = <7 0>; reg = <0x66>; - wakeup; + wakeup-source; s2mps14_osc: clocks { compatible = "samsung,s2mps14-clk"; diff --git a/arch/arm/boot/dts/exynos3250.dtsi b/arch/arm/boot/dts/exynos3250.dtsi index 18e3deffbf4803b2a659f4825f1df00d0674b2f3..137f9015d4e87a89ed30732a70bd5bd5c134a6cf 100644 --- a/arch/arm/boot/dts/exynos3250.dtsi +++ b/arch/arm/boot/dts/exynos3250.dtsi @@ -19,6 +19,7 @@ #include "skeleton.dtsi" #include "exynos4-cpu-thermal.dtsi" +#include "exynos-syscon-restart.dtsi" #include / { @@ -152,20 +153,6 @@ interrupt-parent = <&gic>; }; - poweroff: syscon-poweroff { - compatible = "syscon-poweroff"; - regmap = <&pmu_system_controller>; - offset = <0x330C>; /* PS_HOLD_CONTROL */ - mask = <0x5200>; /* Reset value */ - }; - - reboot: syscon-reboot { - compatible = "syscon-reboot"; - regmap = <&pmu_system_controller>; - offset = <0x0400>; /* SWRESET */ - mask = <0x1>; - }; - mipi_phy: video-phy@10020710 { compatible = "samsung,s5pv210-mipi-video-phy"; #phy-cells = <1>; @@ -381,7 +368,7 @@ }; amba { - compatible = "arm,amba-bus"; + compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges; diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi index 045785c44c048b3b15c923b07f059744c717cfa4..c679b3cc3c488d3dcb33a1533404f43f53f8d71c 100644 --- a/arch/arm/boot/dts/exynos4.dtsi +++ b/arch/arm/boot/dts/exynos4.dtsi @@ -22,6 +22,7 @@ #include #include #include "skeleton.dtsi" +#include "exynos-syscon-restart.dtsi" / { interrupt-parent = <&gic>; @@ -76,6 +77,11 @@ reg = <0x10000000 0x100>; }; + sromc@12570000 { + compatible = "samsung,exynos-srom"; + reg = <0x12570000 0x14>; + }; + mipi_phy: video-phy@10020710 { compatible = "samsung,s5pv210-mipi-video-phy"; #phy-cells = <1>; @@ -158,20 +164,6 @@ interrupt-parent = <&gic>; }; - poweroff: syscon-poweroff { - compatible = "syscon-poweroff"; - regmap = <&pmu_system_controller>; - offset = <0x330C>; /* PS_HOLD_CONTROL */ - mask = <0x5200>; /* reset value */ - }; - - reboot: syscon-reboot { - compatible = "syscon-reboot"; - regmap = <&pmu_system_controller>; - offset = <0x0400>; /* SWRESET */ - mask = <0x1>; - }; - dsi_0: dsi@11C80000 { compatible = "samsung,exynos4210-mipi-dsi"; reg = <0x11C80000 0x10000>; @@ -661,7 +653,7 @@ amba { #address-cells = <1>; #size-cells = <1>; - compatible = "arm,amba-bus"; + compatible = "simple-bus"; interrupt-parent = <&gic>; ranges; diff --git a/arch/arm/boot/dts/exynos4210-origen.dts b/arch/arm/boot/dts/exynos4210-origen.dts index 5821ad87e32c73298469493de5b6d723eb74ab16..ad7394c1d67a92acc2d64315cde287fed691884c 100644 --- a/arch/arm/boot/dts/exynos4210-origen.dts +++ b/arch/arm/boot/dts/exynos4210-origen.dts @@ -60,35 +60,35 @@ label = "Up"; gpios = <&gpx2 0 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; down { label = "Down"; gpios = <&gpx2 1 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; back { label = "Back"; gpios = <&gpx1 7 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; home { label = "Home"; gpios = <&gpx1 6 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; menu { label = "Menu"; gpios = <&gpx1 5 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/exynos4210-smdkv310.dts b/arch/arm/boot/dts/exynos4210-smdkv310.dts index 104cbb33d2bb0f088b41c943a63bc8d10a523bea..94ca7d36ab3788bd2e80b3294aeb896e20eb8d4a 100644 --- a/arch/arm/boot/dts/exynos4210-smdkv310.dts +++ b/arch/arm/boot/dts/exynos4210-smdkv310.dts @@ -66,7 +66,7 @@ samsung,keypad-num-rows = <2>; samsung,keypad-num-columns = <8>; linux,keypad-no-autorepeat; - linux,keypad-wakeup; + wakeup-source; pinctrl-names = "default"; pinctrl-0 = <&keypad_rows &keypad_cols>; status = "okay"; diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts index a50be640f1b03dd0422e6ad8556dcf60b6d5b707..1df2f0bc1d76d81022f1300b6502901df28f8c1f 100644 --- a/arch/arm/boot/dts/exynos4210-trats.dts +++ b/arch/arm/boot/dts/exynos4210-trats.dts @@ -112,7 +112,7 @@ linux,code = <116>; label = "power"; debounce-interval = <10>; - gpio-key,wakeup; + wakeup-source; }; ok-key { diff --git a/arch/arm/boot/dts/exynos4210-universal_c210.dts b/arch/arm/boot/dts/exynos4210-universal_c210.dts index 4f5d37920c8db0375fd3a8c09c8c093987037484..9a75e3effbc98acdbea66e5eedbe3ba04cd1b56b 100644 --- a/arch/arm/boot/dts/exynos4210-universal_c210.dts +++ b/arch/arm/boot/dts/exynos4210-universal_c210.dts @@ -92,7 +92,7 @@ linux,code = <171>; label = "config"; debounce-interval = <1>; - gpio-key,wakeup; + wakeup-source; }; camera-key { @@ -107,7 +107,7 @@ linux,code = <116>; label = "power"; debounce-interval = <1>; - gpio-key,wakeup; + wakeup-source; }; ok-key { diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi index 395c3ca9601eac317e8325bdf857fb6b294aeb75..5e5d3fecb04cd660d1335e9a26691787d754f51e 100644 --- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi +++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi @@ -35,7 +35,7 @@ linux,code = ; label = "power key"; debounce-interval = <10>; - gpio-key,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/exynos4412-odroidx.dts b/arch/arm/boot/dts/exynos4412-odroidx.dts index b44bb682e976705aa23824f421c7cdf419d92151..bf7b21b817e48567d164a91268f5b448d15f1a4f 100644 --- a/arch/arm/boot/dts/exynos4412-odroidx.dts +++ b/arch/arm/boot/dts/exynos4412-odroidx.dts @@ -48,7 +48,7 @@ linux,code = ; label = "home key"; debounce-interval = <10>; - gpio-key,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/exynos4412-origen.dts b/arch/arm/boot/dts/exynos4412-origen.dts index 9e2e24c6177a6bde547b28460958a254ab8c048a..8bca699b7f208366e5c25f911e9ded05bf34ac74 100644 --- a/arch/arm/boot/dts/exynos4412-origen.dts +++ b/arch/arm/boot/dts/exynos4412-origen.dts @@ -423,7 +423,7 @@ samsung,keypad-num-rows = <3>; samsung,keypad-num-columns = <2>; linux,keypad-no-autorepeat; - linux,keypad-wakeup; + wakeup-source; pinctrl-0 = <&keypad_rows &keypad_cols>; pinctrl-names = "default"; status = "okay"; diff --git a/arch/arm/boot/dts/exynos4412-smdk4412.dts b/arch/arm/boot/dts/exynos4412-smdk4412.dts index a130ab39fa7759763cdfa1d277820cdee5801c4e..a51069f3c03b7abb24a481fc714c44c3f8b3d30f 100644 --- a/arch/arm/boot/dts/exynos4412-smdk4412.dts +++ b/arch/arm/boot/dts/exynos4412-smdk4412.dts @@ -45,7 +45,7 @@ samsung,keypad-num-rows = <3>; samsung,keypad-num-columns = <8>; linux,keypad-no-autorepeat; - linux,keypad-wakeup; + wakeup-source; pinctrl-0 = <&keypad_rows &keypad_cols>; pinctrl-names = "default"; status = "okay"; diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts index a6f78c3da935023e27db331c02f1fca1a8826ee8..ed017cc7b14fcf083bd0b89094a6c250fb809e47 100644 --- a/arch/arm/boot/dts/exynos4412-trats2.dts +++ b/arch/arm/boot/dts/exynos4412-trats2.dts @@ -119,7 +119,7 @@ linux,code = <116>; label = "power"; debounce-interval = <10>; - gpio-key,wakeup; + wakeup-source; }; key-ok { @@ -127,7 +127,7 @@ linux,code = <139>; label = "ok"; debounce-inteval = <10>; - gpio-key,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/exynos4415.dtsi b/arch/arm/boot/dts/exynos4415.dtsi index ad764842fff526e8bd4160ec855d46fde9e1ea9a..28b04b6795c99c31d45acdea57e3d2e40f1815de 100644 --- a/arch/arm/boot/dts/exynos4415.dtsi +++ b/arch/arm/boot/dts/exynos4415.dtsi @@ -380,7 +380,7 @@ }; amba { - compatible = "arm,amba-bus"; + compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; interrupt-parent = <&gic>; diff --git a/arch/arm/boot/dts/exynos5.dtsi b/arch/arm/boot/dts/exynos5.dtsi index e2439e87ee4ab4b807b2692829f58a4823a73e53..92313cac035e4b9e818afad1e6ce229c468d1e2a 100644 --- a/arch/arm/boot/dts/exynos5.dtsi +++ b/arch/arm/boot/dts/exynos5.dtsi @@ -14,6 +14,7 @@ */ #include "skeleton.dtsi" +#include "exynos-syscon-restart.dtsi" / { interrupt-parent = <&gic>; @@ -30,6 +31,11 @@ reg = <0x10000000 0x100>; }; + sromc@12250000 { + compatible = "samsung,exynos-srom"; + reg = <0x12250000 0x14>; + }; + combiner: interrupt-controller@10440000 { compatible = "samsung,exynos4210-combiner"; #interrupt-cells = <2>; @@ -88,20 +94,6 @@ status = "disabled"; }; - poweroff: syscon-poweroff { - compatible = "syscon-poweroff"; - regmap = <&pmu_system_controller>; - offset = <0x330C>; /* PS_HOLD_CONTROL */ - mask = <0x5200>; /* reset value */ - }; - - reboot: syscon-reboot { - compatible = "syscon-reboot"; - regmap = <&pmu_system_controller>; - offset = <0x0400>; /* SWRESET */ - mask = <0x1>; - }; - fimd: fimd@14400000 { compatible = "samsung,exynos5250-fimd"; interrupt-parent = <&combiner>; diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts index c000532c14446db9cbcb6a942cd7c117a9d5e0aa..8b2acc74aa76fac7bcf73d28ad653e7897f8f7ee 100644 --- a/arch/arm/boot/dts/exynos5250-arndale.dts +++ b/arch/arm/boot/dts/exynos5250-arndale.dts @@ -34,42 +34,42 @@ label = "SW-TACT2"; gpios = <&gpx1 4 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; home { label = "SW-TACT3"; gpios = <&gpx1 5 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; up { label = "SW-TACT4"; gpios = <&gpx1 6 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; down { label = "SW-TACT5"; gpios = <&gpx1 7 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; back { label = "SW-TACT6"; gpios = <&gpx2 0 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; wakeup { label = "SW-TACT7"; gpios = <&gpx2 1 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/exynos5250-snow-common.dtsi b/arch/arm/boot/dts/exynos5250-snow-common.dtsi index 5cb33ba5e296258e0b5104f5f2c0284815d8b75b..95210ef6a6b51ef129cb75a0ef53fb8d5a9f46b8 100644 --- a/arch/arm/boot/dts/exynos5250-snow-common.dtsi +++ b/arch/arm/boot/dts/exynos5250-snow-common.dtsi @@ -37,7 +37,7 @@ label = "Power"; gpios = <&gpx1 3 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; lid-switch { @@ -46,7 +46,7 @@ linux,input-type = <5>; /* EV_SW */ linux,code = <0>; /* SW_LID */ debounce-interval = <1>; - gpio-key,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/exynos5250-spring.dts b/arch/arm/boot/dts/exynos5250-spring.dts index c1edd6d038a905dffd68e895cdafae25c967f160..0f500cb1eb2ddb0e1f81e2ed58323220d313c4aa 100644 --- a/arch/arm/boot/dts/exynos5250-spring.dts +++ b/arch/arm/boot/dts/exynos5250-spring.dts @@ -37,7 +37,7 @@ label = "Power"; gpios = <&gpx1 3 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; lid-switch { @@ -46,7 +46,7 @@ linux,input-type = <5>; /* EV_SW */ linux,code = <0>; /* SW_LID */ debounce-interval = <1>; - gpio-key,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index 33e2d5f7315b5265fdfc5b74b4a3e38788737f00..e653ae04015a0e4234c27415b4b82c8d2ab35cd7 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi @@ -674,7 +674,7 @@ amba { #address-cells = <1>; #size-cells = <1>; - compatible = "arm,amba-bus"; + compatible = "simple-bus"; interrupt-parent = <&gic>; ranges; @@ -807,7 +807,7 @@ sss@10830000 { compatible = "samsung,exynos4210-secss"; - reg = <0x10830000 0x10000>; + reg = <0x10830000 0x300>; interrupts = <0 112 0>; clocks = <&clock CLK_SSS>; clock-names = "secss"; diff --git a/arch/arm/boot/dts/exynos5410-pinctrl.dtsi b/arch/arm/boot/dts/exynos5410-pinctrl.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..f9aa6bb55464bf62d3c96b2cbdadc5c0857809e9 --- /dev/null +++ b/arch/arm/boot/dts/exynos5410-pinctrl.dtsi @@ -0,0 +1,406 @@ +/* + * Exynos5410 SoC pin-mux and pin-config device tree source + * + * Copyright (c) 2013 Hardkernel Co., Ltd. + * http://www.hardkernel.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +&pinctrl_0 { + gpa0: gpa0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpa1: gpa1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpa2: gpa2 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpb0: gpb0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpb1: gpb1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpb2: gpb2 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpb3: gpb3 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpc0: gpc0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpc3: gpc3 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpc1: gpc1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpc2: gpc2 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpm5: gpm5 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpd1: gpd1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpe0: gpe0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpe1: gpe1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpf0: gpf0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpf1: gpf1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpg0: gpg0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpg1: gpg1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpg2: gpg2 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gph0: gph0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gph1: gph1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpm7: gpm7 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpy0: gpy0 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpy1: gpy1 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpy2: gpy2 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpy3: gpy3 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpy4: gpy4 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpy5: gpy5 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpy6: gpy6 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpy7: gpy7 { + gpio-controller; + #gpio-cells = <2>; + }; + + gpx0: gpx0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + interrupt-parent = <&combiner>; + #interrupt-cells = <2>; + interrupts = <23 0>, + <24 0>, + <25 0>, + <25 1>, + <26 0>, + <26 1>, + <27 0>, + <27 1>; + }; + + gpx1: gpx1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + interrupt-parent = <&combiner>; + #interrupt-cells = <2>; + interrupts = <28 0>, + <28 1>, + <29 0>, + <29 1>, + <30 0>, + <30 1>, + <31 0>, + <31 1>; + }; + + gpx2: gpx2 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpx3: gpx3 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; +}; + +&pinctrl_1 { + gpj0: gpj0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpj1: gpj1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpj2: gpj2 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpj3: gpj3 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpj4: gpj4 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpk0: gpk0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpk1: gpk1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpk2: gpk2 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpk3: gpk3 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; +}; + +&pinctrl_2 { + gpv0: gpv0 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpv1: gpv1 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpv2: gpv2 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpv3: gpv3 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpv4: gpv4 { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; +}; + +&pinctrl_3 { + gpz: gpz { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; +}; diff --git a/arch/arm/boot/dts/exynos5410-smdk5410.dts b/arch/arm/boot/dts/exynos5410-smdk5410.dts index cebeaab3abecd4177566e45d614ef6da6d8405ab..a731fbe28ebc01bc816f589e46dbceb54b7bad36 100644 --- a/arch/arm/boot/dts/exynos5410-smdk5410.dts +++ b/arch/arm/boot/dts/exynos5410-smdk5410.dts @@ -11,6 +11,7 @@ /dts-v1/; #include "exynos5410.dtsi" +#include / { model = "Samsung SMDK5410 board based on EXYNOS5410"; compatible = "samsung,smdk5410", "samsung,exynos5410", "samsung,exynos5"; @@ -61,6 +62,46 @@ disable-wp; }; +&pinctrl_0 { + srom_ctl: srom-ctl { + samsung,pins = "gpy0-3", "gpy0-4", "gpy0-5", + "gpy1-0", "gpy1-1", "gpy1-2", "gpy1-3"; + samsung,pin-function = <2>; + samsung,pin-drv = <0>; + }; + + srom_ebi: srom-ebi { + samsung,pins = "gpy3-0", "gpy3-1", "gpy3-2", "gpy3-3", + "gpy3-4", "gpy3-5", "gpy3-6", "gpy3-7", + "gpy5-0", "gpy5-1", "gpy5-2", "gpy5-3", + "gpy5-4", "gpy5-5", "gpy5-6", "gpy5-7", + "gpy6-0", "gpy6-1", "gpy6-2", "gpy6-3", + "gpy6-4", "gpy6-5", "gpy6-6", "gpy6-7"; + samsung,pin-function = <2>; + samsung,pin-pud = <3>; + samsung,pin-drv = <0>; + }; +}; + +&sromc { + pinctrl-names = "default"; + pinctrl-0 = <&srom_ctl>, <&srom_ebi>; + + ethernet@3,0 { + compatible = "smsc,lan9115"; + reg = <3 0 0x10000>; + phy-mode = "mii"; + interrupt-parent = <&gpx0>; + interrupts = <5 IRQ_TYPE_LEVEL_LOW>; + reg-io-width = <2>; + smsc,irq-push-pull; + smsc,force-internal-phy; + + samsung,srom-page-mode = <1>; + samsung,srom-timing = <9 12 1 9 1 1>; + }; +}; + &uart0 { status = "okay"; }; diff --git a/arch/arm/boot/dts/exynos5410.dtsi b/arch/arm/boot/dts/exynos5410.dtsi index fad0779b1b6e86d887a926a4afdee929ca33a1d7..fa558674ac7639a7aaae36860862e7002abb659c 100644 --- a/arch/arm/boot/dts/exynos5410.dtsi +++ b/arch/arm/boot/dts/exynos5410.dtsi @@ -14,6 +14,7 @@ */ #include "skeleton.dtsi" +#include "exynos-syscon-restart.dtsi" #include / { @@ -21,6 +22,10 @@ interrupt-parent = <&gic>; aliases { + pinctrl0 = &pinctrl_0; + pinctrl1 = &pinctrl_1; + pinctrl2 = &pinctrl_2; + pinctrl3 = &pinctrl_3; serial0 = &uart0; serial1 = &uart1; serial2 = &uart2; @@ -97,25 +102,22 @@ reg = <0x10000000 0x100>; }; + sromc: sromc@12250000 { + compatible = "samsung,exynos-srom"; + reg = <0x12250000 0x14>; + #address-cells = <2>; + #size-cells = <1>; + ranges = <0 0 0x04000000 0x20000 + 1 0 0x05000000 0x20000 + 2 0 0x06000000 0x20000 + 3 0 0x07000000 0x20000>; + }; + pmu_system_controller: system-controller@10040000 { compatible = "samsung,exynos5410-pmu", "syscon"; reg = <0x10040000 0x5000>; }; - poweroff: syscon-poweroff { - compatible = "syscon-poweroff"; - regmap = <&pmu_system_controller>; - offset = <0x330C>; /* PS_HOLD_CONTROL */ - mask = <0x5200>; /* reset value */ - }; - - reboot: syscon-reboot { - compatible = "syscon-reboot"; - regmap = <&pmu_system_controller>; - offset = <0x0400>; /* SWRESET */ - mask = <0x1>; - }; - mct: mct@101C0000 { compatible = "samsung,exynos4210-mct"; reg = <0x101C0000 0xB00>; @@ -205,6 +207,36 @@ status = "disabled"; }; + pinctrl_0: pinctrl@13400000 { + compatible = "samsung,exynos5410-pinctrl"; + reg = <0x13400000 0x1000>; + interrupts = <0 45 0>; + + wakeup-interrupt-controller { + compatible = "samsung,exynos4210-wakeup-eint"; + interrupt-parent = <&gic>; + interrupts = <0 32 0>; + }; + }; + + pinctrl_1: pinctrl@14000000 { + compatible = "samsung,exynos5410-pinctrl"; + reg = <0x14000000 0x1000>; + interrupts = <0 46 0>; + }; + + pinctrl_2: pinctrl@10d10000 { + compatible = "samsung,exynos5410-pinctrl"; + reg = <0x10d10000 0x1000>; + interrupts = <0 50 0>; + }; + + pinctrl_3: pinctrl@03860000 { + compatible = "samsung,exynos5410-pinctrl"; + reg = <0x03860000 0x1000>; + interrupts = <0 47 0>; + }; + uart0: serial@12C00000 { compatible = "samsung,exynos4210-uart"; reg = <0x12C00000 0x100>; @@ -233,3 +265,5 @@ }; }; }; + +#include "exynos5410-pinctrl.dtsi" diff --git a/arch/arm/boot/dts/exynos5420-arndale-octa.dts b/arch/arm/boot/dts/exynos5420-arndale-octa.dts index 4ecef6981d5c4c7dd1332324e405fcd0d34ce4f0..a103ce8c398586f857a1c90c9696d40b357a5056 100644 --- a/arch/arm/boot/dts/exynos5420-arndale-octa.dts +++ b/arch/arm/boot/dts/exynos5420-arndale-octa.dts @@ -11,6 +11,7 @@ /dts-v1/; #include "exynos5420.dtsi" +#include "exynos5420-cpus.dtsi" #include #include #include @@ -47,11 +48,19 @@ label = "SW-TACT1"; gpios = <&gpx2 7 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; }; }; +&cpu0 { + cpu-supply = <&buck2_reg>; +}; + +&cpu4 { + cpu-supply = <&buck6_reg>; +}; + &usbdrd_dwc3_1 { dr_mode = "host"; }; diff --git a/arch/arm/boot/dts/exynos5420-cpus.dtsi b/arch/arm/boot/dts/exynos5420-cpus.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..5c052d7ff55460d2a965c5ed55e20e475ed1b24c --- /dev/null +++ b/arch/arm/boot/dts/exynos5420-cpus.dtsi @@ -0,0 +1,126 @@ +/* + * SAMSUNG EXYNOS5420 SoC cpu device tree source + * + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * This file provides desired ordering for Exynos5420 and Exynos5800 + * boards: CPU[0123] being the A15. + * + * The Exynos5420, 5422 and 5800 actually share the same CPU configuration + * but particular boards choose different booting order. + * + * Exynos5420 and Exynos5800 always boot from Cortex-A15. On Exynos5422 + * booting cluster (big or LITTLE) is chosen by IROM code by reading + * the gpg2-1 GPIO. By default all Exynos5422 based boards choose booting + * from the LITTLE: Cortex-A7. + * + * 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. + */ + +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x0>; + clocks = <&clock CLK_ARM_CLK>; + clock-frequency = <1800000000>; + cci-control-port = <&cci_control1>; + operating-points-v2 = <&cluster_a15_opp_table>; + cooling-min-level = <0>; + cooling-max-level = <11>; + #cooling-cells = <2>; /* min followed by max */ + }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x1>; + clock-frequency = <1800000000>; + cci-control-port = <&cci_control1>; + operating-points-v2 = <&cluster_a15_opp_table>; + cooling-min-level = <0>; + cooling-max-level = <11>; + #cooling-cells = <2>; /* min followed by max */ + }; + + cpu2: cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x2>; + clock-frequency = <1800000000>; + cci-control-port = <&cci_control1>; + operating-points-v2 = <&cluster_a15_opp_table>; + cooling-min-level = <0>; + cooling-max-level = <11>; + #cooling-cells = <2>; /* min followed by max */ + }; + + cpu3: cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x3>; + clock-frequency = <1800000000>; + cci-control-port = <&cci_control1>; + operating-points-v2 = <&cluster_a15_opp_table>; + cooling-min-level = <0>; + cooling-max-level = <11>; + #cooling-cells = <2>; /* min followed by max */ + }; + + cpu4: cpu@100 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x100>; + clocks = <&clock CLK_KFC_CLK>; + clock-frequency = <1000000000>; + cci-control-port = <&cci_control0>; + operating-points-v2 = <&cluster_a7_opp_table>; + cooling-min-level = <0>; + cooling-max-level = <7>; + #cooling-cells = <2>; /* min followed by max */ + }; + + cpu5: cpu@101 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x101>; + clock-frequency = <1000000000>; + cci-control-port = <&cci_control0>; + operating-points-v2 = <&cluster_a7_opp_table>; + cooling-min-level = <0>; + cooling-max-level = <7>; + #cooling-cells = <2>; /* min followed by max */ + }; + + cpu6: cpu@102 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x102>; + clock-frequency = <1000000000>; + cci-control-port = <&cci_control0>; + operating-points-v2 = <&cluster_a7_opp_table>; + cooling-min-level = <0>; + cooling-max-level = <7>; + #cooling-cells = <2>; /* min followed by max */ + }; + + cpu7: cpu@103 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x103>; + clock-frequency = <1000000000>; + cci-control-port = <&cci_control0>; + operating-points-v2 = <&cluster_a7_opp_table>; + cooling-min-level = <0>; + cooling-max-level = <7>; + #cooling-cells = <2>; /* min followed by max */ + }; + }; +}; diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts index 35cfb07dc4bb76073d0458983ad0fe95a8c430a9..3981ddb25036af95090f28d0afac7eaf59271451 100644 --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts @@ -15,6 +15,7 @@ #include #include #include "exynos5420.dtsi" +#include "exynos5420-cpus.dtsi" / { model = "Google Peach Pit Rev 6+"; @@ -64,7 +65,7 @@ label = "Power"; gpios = <&gpx1 2 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; lid-switch { @@ -73,7 +74,7 @@ linux,input-type = <5>; /* EV_SW */ linux,code = <0>; /* SW_LID */ debounce-interval = <1>; - gpio-key,wakeup; + wakeup-source; }; }; @@ -143,6 +144,14 @@ vdd-supply = <&ldo9_reg>; }; +&cpu0 { + cpu-supply = <&buck2_reg>; +}; + +&cpu4 { + cpu-supply = <&buck6_reg>; +}; + &dp { status = "okay"; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts index ac35aefd320ff0acc0998f11b96c3375dc2454c5..0785fedf441e8001aa33ea198060477c5c644836 100644 --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts @@ -11,6 +11,7 @@ /dts-v1/; #include "exynos5420.dtsi" +#include "exynos5420-cpus.dtsi" #include / { @@ -89,6 +90,14 @@ }; +&cpu0 { + cpu-supply = <&buck2_reg>; +}; + +&cpu4 { + cpu-supply = <&buck6_reg>; +}; + &dp { pinctrl-names = "default"; pinctrl-0 = <&dp_hpd>; diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi index 48a0a55314f5d184b03d36f1fb52374ef8cf794a..7b99cb58d82d3a81b65258a12defba10c420e27a 100644 --- a/arch/arm/boot/dts/exynos5420.dtsi +++ b/arch/arm/boot/dts/exynos5420.dtsi @@ -50,75 +50,121 @@ usbdrdphy1 = &usbdrd_phy1; }; - cpus { - #address-cells = <1>; - #size-cells = <0>; - - cpu0: cpu@0 { - device_type = "cpu"; - compatible = "arm,cortex-a15"; - reg = <0x0>; - clock-frequency = <1800000000>; - cci-control-port = <&cci_control1>; + cluster_a15_opp_table: opp_table0 { + compatible = "operating-points-v2"; + opp-shared; + opp@1800000000 { + opp-hz = /bits/ 64 <1800000000>; + opp-microvolt = <1250000>; + clock-latency-ns = <140000>; }; - - cpu1: cpu@1 { - device_type = "cpu"; - compatible = "arm,cortex-a15"; - reg = <0x1>; - clock-frequency = <1800000000>; - cci-control-port = <&cci_control1>; + opp@1700000000 { + opp-hz = /bits/ 64 <1700000000>; + opp-microvolt = <1212500>; + clock-latency-ns = <140000>; }; - - cpu2: cpu@2 { - device_type = "cpu"; - compatible = "arm,cortex-a15"; - reg = <0x2>; - clock-frequency = <1800000000>; - cci-control-port = <&cci_control1>; + opp@1600000000 { + opp-hz = /bits/ 64 <1600000000>; + opp-microvolt = <1175000>; + clock-latency-ns = <140000>; }; - - cpu3: cpu@3 { - device_type = "cpu"; - compatible = "arm,cortex-a15"; - reg = <0x3>; - clock-frequency = <1800000000>; - cci-control-port = <&cci_control1>; + opp@1500000000 { + opp-hz = /bits/ 64 <1500000000>; + opp-microvolt = <1137500>; + clock-latency-ns = <140000>; }; - - cpu4: cpu@100 { - device_type = "cpu"; - compatible = "arm,cortex-a7"; - reg = <0x100>; - clock-frequency = <1000000000>; - cci-control-port = <&cci_control0>; + opp@1400000000 { + opp-hz = /bits/ 64 <1400000000>; + opp-microvolt = <1112500>; + clock-latency-ns = <140000>; }; - - cpu5: cpu@101 { - device_type = "cpu"; - compatible = "arm,cortex-a7"; - reg = <0x101>; - clock-frequency = <1000000000>; - cci-control-port = <&cci_control0>; + opp@1300000000 { + opp-hz = /bits/ 64 <1300000000>; + opp-microvolt = <1062500>; + clock-latency-ns = <140000>; }; - - cpu6: cpu@102 { - device_type = "cpu"; - compatible = "arm,cortex-a7"; - reg = <0x102>; - clock-frequency = <1000000000>; - cci-control-port = <&cci_control0>; + opp@1200000000 { + opp-hz = /bits/ 64 <1200000000>; + opp-microvolt = <1037500>; + clock-latency-ns = <140000>; + }; + opp@1100000000 { + opp-hz = /bits/ 64 <1100000000>; + opp-microvolt = <1012500>; + clock-latency-ns = <140000>; + }; + opp@1000000000 { + opp-hz = /bits/ 64 <1000000000>; + opp-microvolt = < 987500>; + clock-latency-ns = <140000>; + }; + opp@900000000 { + opp-hz = /bits/ 64 <900000000>; + opp-microvolt = < 962500>; + clock-latency-ns = <140000>; }; + opp@800000000 { + opp-hz = /bits/ 64 <800000000>; + opp-microvolt = < 937500>; + clock-latency-ns = <140000>; + }; + opp@700000000 { + opp-hz = /bits/ 64 <700000000>; + opp-microvolt = < 912500>; + clock-latency-ns = <140000>; + }; + }; - cpu7: cpu@103 { - device_type = "cpu"; - compatible = "arm,cortex-a7"; - reg = <0x103>; - clock-frequency = <1000000000>; - cci-control-port = <&cci_control0>; + cluster_a7_opp_table: opp_table1 { + compatible = "operating-points-v2"; + opp-shared; + opp@1300000000 { + opp-hz = /bits/ 64 <1300000000>; + opp-microvolt = <1275000>; + clock-latency-ns = <140000>; + }; + opp@1200000000 { + opp-hz = /bits/ 64 <1200000000>; + opp-microvolt = <1212500>; + clock-latency-ns = <140000>; + }; + opp@1100000000 { + opp-hz = /bits/ 64 <1100000000>; + opp-microvolt = <1162500>; + clock-latency-ns = <140000>; + }; + opp@1000000000 { + opp-hz = /bits/ 64 <1000000000>; + opp-microvolt = <1112500>; + clock-latency-ns = <140000>; + }; + opp@900000000 { + opp-hz = /bits/ 64 <900000000>; + opp-microvolt = <1062500>; + clock-latency-ns = <140000>; + }; + opp@800000000 { + opp-hz = /bits/ 64 <800000000>; + opp-microvolt = <1025000>; + clock-latency-ns = <140000>; + }; + opp@700000000 { + opp-hz = /bits/ 64 <700000000>; + opp-microvolt = <975000>; + clock-latency-ns = <140000>; + }; + opp@600000000 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <937500>; + clock-latency-ns = <140000>; }; }; + /* + * The 'cpus' node is not present here but instead it is provided + * by exynos5420-cpus.dtsi or exynos5422-cpus.dtsi. + */ + cci: cci@10d20000 { compatible = "arm,cci-400"; #address-cells = <1>; @@ -252,8 +298,10 @@ compatible = "samsung,exynos4210-pd"; reg = <0x10044000 0x20>; #power-domain-cells = <0>; - clocks = <&clock CLK_GSCL0>, <&clock CLK_GSCL1>; - clock-names = "asb0", "asb1"; + clocks = <&clock CLK_FIN_PLL>, + <&clock CLK_MOUT_USER_ACLK300_GSCL>, + <&clock CLK_GSCL0>, <&clock CLK_GSCL1>; + clock-names = "oscclk", "clk0", "asb0", "asb1"; }; isp_pd: power-domain@10044020 { @@ -327,7 +375,7 @@ amba { #address-cells = <1>; #size-cells = <1>; - compatible = "arm,amba-bus"; + compatible = "simple-bus"; interrupt-parent = <&gic>; ranges; @@ -859,7 +907,7 @@ sss: sss@10830000 { compatible = "samsung,exynos4210-secss"; - reg = <0x10830000 0x10000>; + reg = <0x10830000 0x300>; interrupts = <0 112 0>; clocks = <&clock CLK_SSS>; clock-names = "secss"; diff --git a/arch/arm/boot/dts/exynos5422-cpu-thermal.dtsi b/arch/arm/boot/dts/exynos5422-cpu-thermal.dtsi index 2b289d7c0d13ddda8c8a19f93f1b8d14f4812ac5..3e4c4ad96d6379a733177e52d3c565f3a62d4ae7 100644 --- a/arch/arm/boot/dts/exynos5422-cpu-thermal.dtsi +++ b/arch/arm/boot/dts/exynos5422-cpu-thermal.dtsi @@ -16,7 +16,7 @@ thermal-zones { cpu0_thermal: cpu0-thermal { thermal-sensors = <&tmu_cpu0 0>; - polling-delay-passive = <0>; + polling-delay-passive = <250>; polling-delay = <0>; trips { cpu_alert0: cpu-alert-0 { @@ -39,6 +39,23 @@ hysteresis = <0>; /* millicelsius */ type = "critical"; }; + /* + * Exyunos542x support only 4 trip-points + * so for these polling mode is required. + * Start polling at temperature level of last + * interrupt-driven trip: cpu_alert2 + */ + cpu_alert3: cpu-alert-3 { + temperature = <70000>; /* millicelsius */ + hysteresis = <10000>; /* millicelsius */ + type = "passive"; + }; + cpu_alert4: cpu-alert-4 { + temperature = <85000>; /* millicelsius */ + hysteresis = <10000>; /* millicelsius */ + type = "passive"; + }; + }; cooling-maps { map0 { @@ -53,6 +70,33 @@ trip = <&cpu_alert2>; cooling-device = <&fan0 2 3>; }; + /* + * When reaching cpu_alert3, reduce CPU + * by 2 steps. On Exynos5422/5800 that would + * be: 1500 MHz and 1100 MHz. + */ + map3 { + trip = <&cpu_alert3>; + cooling-device = <&cpu0 0 2>; + }; + map4 { + trip = <&cpu_alert3>; + cooling-device = <&cpu4 0 2>; + }; + + /* + * When reaching cpu_alert4, reduce CPU + * further, down to 600 MHz (11 steps for big, + * 7 steps for LITTLE). + */ + map5 { + trip = <&cpu_alert4>; + cooling-device = <&cpu0 3 7>; + }; + map6 { + trip = <&cpu_alert4>; + cooling-device = <&cpu4 3 11>; + }; }; }; }; diff --git a/arch/arm/boot/dts/exynos5422-cpus.dtsi b/arch/arm/boot/dts/exynos5422-cpus.dtsi index b7f60c855459126bf63bb3ffe120ab6f87f37dfe..bf3c6f1ec4ee3c48b9a01a2b31ce97a87d67a00b 100644 --- a/arch/arm/boot/dts/exynos5422-cpus.dtsi +++ b/arch/arm/boot/dts/exynos5422-cpus.dtsi @@ -4,78 +4,122 @@ * Copyright (c) 2015 Samsung Electronics Co., Ltd. * http://www.samsung.com * - * The only difference between EXYNOS5422 and EXYNOS5800 is cpu ordering. The - * EXYNOS5422 is booting from Cortex-A7 core while the EXYNOS5800 is booting - * from Cortex-A15 core. + * This file provides desired ordering for Exynos5422: CPU[0123] being the A7. * - * EXYNOS5422 based board files can include this file to provide cpu ordering - * which could boot a cortex-a7 from cpu0. + * The Exynos5420, 5422 and 5800 actually share the same CPU configuration + * but particular boards choose different booting order. + * + * Exynos5420 and Exynos5800 always boot from Cortex-A15. On Exynos5422 + * booting cluster (big or LITTLE) is chosen by IROM code by reading + * the gpg2-1 GPIO. By default all Exynos5422 based boards choose booting + * from the LITTLE: Cortex-A7. * * 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. */ -&cpu0 { - device_type = "cpu"; - compatible = "arm,cortex-a7"; - reg = <0x100>; - clock-frequency = <1000000000>; - cci-control-port = <&cci_control0>; -}; +/ { + cpus { + #address-cells = <1>; + #size-cells = <0>; -&cpu1 { - device_type = "cpu"; - compatible = "arm,cortex-a7"; - reg = <0x101>; - clock-frequency = <1000000000>; - cci-control-port = <&cci_control0>; -}; + cpu0: cpu@100 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x100>; + clocks = <&clock CLK_KFC_CLK>; + clock-frequency = <1000000000>; + cci-control-port = <&cci_control0>; + operating-points-v2 = <&cluster_a7_opp_table>; + cooling-min-level = <0>; + cooling-max-level = <11>; + #cooling-cells = <2>; /* min followed by max */ + }; -&cpu2 { - device_type = "cpu"; - compatible = "arm,cortex-a7"; - reg = <0x102>; - clock-frequency = <1000000000>; - cci-control-port = <&cci_control0>; -}; + cpu1: cpu@101 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x101>; + clock-frequency = <1000000000>; + cci-control-port = <&cci_control0>; + operating-points-v2 = <&cluster_a7_opp_table>; + cooling-min-level = <0>; + cooling-max-level = <11>; + #cooling-cells = <2>; /* min followed by max */ + }; -&cpu3 { - device_type = "cpu"; - compatible = "arm,cortex-a7"; - reg = <0x103>; - clock-frequency = <1000000000>; - cci-control-port = <&cci_control0>; -}; + cpu2: cpu@102 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x102>; + clock-frequency = <1000000000>; + cci-control-port = <&cci_control0>; + operating-points-v2 = <&cluster_a7_opp_table>; + cooling-min-level = <0>; + cooling-max-level = <11>; + #cooling-cells = <2>; /* min followed by max */ + }; -&cpu4 { - device_type = "cpu"; - compatible = "arm,cortex-a15"; - reg = <0x0>; - clock-frequency = <1800000000>; - cci-control-port = <&cci_control1>; -}; + cpu3: cpu@103 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x103>; + clock-frequency = <1000000000>; + cci-control-port = <&cci_control0>; + operating-points-v2 = <&cluster_a7_opp_table>; + cooling-min-level = <0>; + cooling-max-level = <11>; + #cooling-cells = <2>; /* min followed by max */ + }; -&cpu5 { - device_type = "cpu"; - compatible = "arm,cortex-a15"; - reg = <0x1>; - clock-frequency = <1800000000>; - cci-control-port = <&cci_control1>; -}; + cpu4: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + clocks = <&clock CLK_ARM_CLK>; + reg = <0x0>; + clock-frequency = <1800000000>; + cci-control-port = <&cci_control1>; + operating-points-v2 = <&cluster_a15_opp_table>; + cooling-min-level = <0>; + cooling-max-level = <15>; + #cooling-cells = <2>; /* min followed by max */ + }; -&cpu6 { - device_type = "cpu"; - compatible = "arm,cortex-a15"; - reg = <0x2>; - clock-frequency = <1800000000>; - cci-control-port = <&cci_control1>; -}; + cpu5: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x1>; + clock-frequency = <1800000000>; + cci-control-port = <&cci_control1>; + operating-points-v2 = <&cluster_a15_opp_table>; + cooling-min-level = <0>; + cooling-max-level = <15>; + #cooling-cells = <2>; /* min followed by max */ + }; + + cpu6: cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x2>; + clock-frequency = <1800000000>; + cci-control-port = <&cci_control1>; + operating-points-v2 = <&cluster_a15_opp_table>; + cooling-min-level = <0>; + cooling-max-level = <15>; + #cooling-cells = <2>; /* min followed by max */ + }; -&cpu7 { - device_type = "cpu"; - compatible = "arm,cortex-a15"; - reg = <0x3>; - clock-frequency = <1800000000>; - cci-control-port = <&cci_control1>; + cpu7: cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0x3>; + clock-frequency = <1800000000>; + cci-control-port = <&cci_control1>; + operating-points-v2 = <&cluster_a15_opp_table>; + cooling-min-level = <0>; + cooling-max-level = <15>; + #cooling-cells = <2>; /* min followed by max */ + }; + }; }; diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi index 9134217446b8e2c321ecea78571b0cc3cdaed683..1bd507bfa750155579259b14195e08dab8adbb00 100644 --- a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi +++ b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi @@ -67,6 +67,14 @@ <19200000>; }; +&cpu0 { + cpu-supply = <&buck6_reg>; +}; + +&cpu4 { + cpu-supply = <&buck2_reg>; +}; + &hdmi { status = "okay"; hpd-gpio = <&gpx3 7 GPIO_ACTIVE_HIGH>; diff --git a/arch/arm/boot/dts/exynos5440.dtsi b/arch/arm/boot/dts/exynos5440.dtsi index f18b51f2eeaa83883d27e99e80a43611266f60e3..b9342ec5b9cff7be0bb3a5b767b066919f15dcf2 100644 --- a/arch/arm/boot/dts/exynos5440.dtsi +++ b/arch/arm/boot/dts/exynos5440.dtsi @@ -200,7 +200,7 @@ amba { #address-cells = <1>; #size-cells = <1>; - compatible = "arm,amba-bus"; + compatible = "simple-bus"; interrupt-parent = <&gic>; ranges; }; diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts index 064176f201e74da75c5f2b581602e12a7ab73b6b..6e9edc1610c4990777a516fbde1d8ef9a0a4cdab 100644 --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts @@ -15,6 +15,7 @@ #include #include #include "exynos5800.dtsi" +#include "exynos5420-cpus.dtsi" / { model = "Google Peach Pi Rev 10+"; @@ -63,7 +64,7 @@ label = "Power"; gpios = <&gpx1 2 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; lid-switch { @@ -72,7 +73,7 @@ linux,input-type = <5>; /* EV_SW */ linux,code = <0>; /* SW_LID */ debounce-interval = <1>; - gpio-key,wakeup; + wakeup-source; }; }; @@ -143,6 +144,14 @@ vdd-supply = <&ldo9_reg>; }; +&cpu0 { + cpu-supply = <&buck2_reg>; +}; + +&cpu4 { + cpu-supply = <&buck6_reg>; +}; + &dp { status = "okay"; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/exynos5800.dtsi b/arch/arm/boot/dts/exynos5800.dtsi index c0bb3563cac14cc5dd5e8c8666c3902a3068cb98..8213016803e5d4b1465e7c6742926c6734de10b8 100644 --- a/arch/arm/boot/dts/exynos5800.dtsi +++ b/arch/arm/boot/dts/exynos5800.dtsi @@ -23,6 +23,114 @@ compatible = "samsung,exynos5800-clock"; }; +&cluster_a15_opp_table { + opp@1700000000 { + opp-microvolt = <1250000>; + }; + opp@1600000000 { + opp-microvolt = <1250000>; + }; + opp@1500000000 { + opp-microvolt = <1100000>; + }; + opp@1400000000 { + opp-microvolt = <1100000>; + }; + opp@1300000000 { + opp-microvolt = <1100000>; + }; + opp@1200000000 { + opp-microvolt = <1000000>; + }; + opp@1100000000 { + opp-microvolt = <1000000>; + }; + opp@1000000000 { + opp-microvolt = <1000000>; + }; + opp@900000000 { + opp-microvolt = <1000000>; + }; + opp@800000000 { + opp-microvolt = <900000>; + }; + opp@700000000 { + opp-microvolt = <900000>; + }; + opp@600000000 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <900000>; + clock-latency-ns = <140000>; + }; + opp@500000000 { + opp-hz = /bits/ 64 <500000000>; + opp-microvolt = <900000>; + clock-latency-ns = <140000>; + }; + opp@400000000 { + opp-hz = /bits/ 64 <400000000>; + opp-microvolt = <900000>; + clock-latency-ns = <140000>; + }; + opp@300000000 { + opp-hz = /bits/ 64 <300000000>; + opp-microvolt = <900000>; + clock-latency-ns = <140000>; + }; + opp@200000000 { + opp-hz = /bits/ 64 <200000000>; + opp-microvolt = <900000>; + clock-latency-ns = <140000>; + }; +}; + +&cluster_a7_opp_table { + opp@1300000000 { + opp-microvolt = <1250000>; + }; + opp@1200000000 { + opp-microvolt = <1250000>; + }; + opp@1100000000 { + opp-microvolt = <1250000>; + }; + opp@1000000000 { + opp-microvolt = <1100000>; + }; + opp@900000000 { + opp-microvolt = <1100000>; + }; + opp@800000000 { + opp-microvolt = <1100000>; + }; + opp@700000000 { + opp-microvolt = <1000000>; + }; + opp@600000000 { + opp-microvolt = <1000000>; + }; + opp@500000000 { + opp-hz = /bits/ 64 <500000000>; + opp-microvolt = <1000000>; + clock-latency-ns = <140000>; + }; + opp@400000000 { + opp-hz = /bits/ 64 <400000000>; + opp-microvolt = <1000000>; + clock-latency-ns = <140000>; + }; + opp@300000000 { + opp-hz = /bits/ 64 <300000000>; + opp-microvolt = <900000>; + clock-latency-ns = <140000>; + }; + opp@200000000 { + opp-hz = /bits/ 64 <200000000>; + opp-microvolt = <900000>; + clock-latency-ns = <140000>; + }; +}; + &mfc { compatible = "samsung,mfc-v8"; }; diff --git a/arch/arm/boot/dts/hi3620.dtsi b/arch/arm/boot/dts/hi3620.dtsi index 6cbb62e5c6a9eb0c98042aaec8495e72c4e28640..c85d07e6db6121c39870b3bb5f07f58700975901 100644 --- a/arch/arm/boot/dts/hi3620.dtsi +++ b/arch/arm/boot/dts/hi3620.dtsi @@ -68,7 +68,7 @@ #address-cells = <1>; #size-cells = <1>; - compatible = "arm,amba-bus"; + compatible = "simple-bus"; interrupt-parent = <&gic>; ranges = <0 0xfc000000 0x2000000>; diff --git a/arch/arm/boot/dts/hip01.dtsi b/arch/arm/boot/dts/hip01.dtsi index 33130f8461c376b22cf44b724d0aaa6997cb1493..4e9562f806a2162cff8671003fe85559e8dc67a5 100644 --- a/arch/arm/boot/dts/hip01.dtsi +++ b/arch/arm/boot/dts/hip01.dtsi @@ -43,7 +43,7 @@ amba { #address-cells = <1>; #size-cells = <1>; - compatible = "arm,amba-bus"; + compatible = "simple-bus"; ranges; uart0: uart@10001000 { diff --git a/arch/arm/boot/dts/hisi-x5hd2.dtsi b/arch/arm/boot/dts/hisi-x5hd2.dtsi index c52722b14e4a01577af7768a2b840f97836afbdd..fdcc23d203e5d3f5d331b41a08f5d06b19fb6759 100644 --- a/arch/arm/boot/dts/hisi-x5hd2.dtsi +++ b/arch/arm/boot/dts/hisi-x5hd2.dtsi @@ -34,7 +34,7 @@ amba { #address-cells = <1>; #size-cells = <1>; - compatible = "arm,amba-bus"; + compatible = "simple-bus"; ranges; timer0: timer@00002000 { diff --git a/arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard.dts b/arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard.dts index ed1d0b4578ef99402f22941b818451ac366518cf..cda6907a27b9bf18da633088849398634ef07218 100644 --- a/arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard.dts +++ b/arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard.dts @@ -30,7 +30,7 @@ label = "BP1"; gpios = <&gpio3 18 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/imx25.dtsi b/arch/arm/boot/dts/imx25.dtsi index cde329e9b9e3fcf2e7a9fb477f12ca14d9818774..6b1f4bbe6ec6eedf59795b07495ee18ed35730ea 100644 --- a/arch/arm/boot/dts/imx25.dtsi +++ b/arch/arm/boot/dts/imx25.dtsi @@ -269,13 +269,36 @@ status = "disabled"; }; - tsc: tsc@50030000 { - compatible = "fsl,imx25-adc", "fsl,imx21-tsc"; - reg = <0x50030000 0x4000>; + tscadc: tscadc@50030000 { + compatible = "fsl,imx25-tsadc"; + reg = <0x50030000 0xc>; interrupts = <46>; clocks = <&clks 119>; clock-names = "ipg"; + interrupt-controller; + #interrupt-cells = <1>; + #address-cells = <1>; + #size-cells = <1>; status = "disabled"; + + adc: adc@50030800 { + compatible = "fsl,imx25-gcq"; + reg = <0x50030800 0x60>; + interrupt-parent = <&tscadc>; + interrupts = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + tsc: tcq@50030400 { + compatible = "fsl,imx25-tcq"; + reg = <0x50030400 0x60>; + interrupt-parent = <&tscadc>; + interrupts = <0>; + fsl,wires = <4>; + status = "disabled"; + }; }; ssi1: ssi@50034000 { @@ -497,7 +520,8 @@ compatible = "fsl,imx25-usb", "fsl,imx27-usb"; reg = <0x53ff4000 0x0200>; interrupts = <37>; - clocks = <&clks 70>; + clocks = <&clks 9>, <&clks 70>, <&clks 8>; + clock-names = "ipg", "ahb", "per"; fsl,usbmisc = <&usbmisc 0>; fsl,usbphy = <&usbphy0>; status = "disabled"; @@ -507,7 +531,8 @@ compatible = "fsl,imx25-usb", "fsl,imx27-usb"; reg = <0x53ff4400 0x0200>; interrupts = <35>; - clocks = <&clks 70>; + clocks = <&clks 9>, <&clks 70>, <&clks 8>; + clock-names = "ipg", "ahb", "per"; fsl,usbmisc = <&usbmisc 1>; fsl,usbphy = <&usbphy1>; status = "disabled"; @@ -516,8 +541,6 @@ usbmisc: usbmisc@53ff4600 { #index-cells = <1>; compatible = "fsl,imx25-usbmisc"; - clocks = <&clks 9>, <&clks 70>, <&clks 8>; - clock-names = "ipg", "ahb", "per"; reg = <0x53ff4600 0x00f>; }; diff --git a/arch/arm/boot/dts/imx28-apf28dev.dts b/arch/arm/boot/dts/imx28-apf28dev.dts index 7ac4f1af16ac856d243674c630b9207da71d8335..1eaa131e2d1809fb38525dc4d1105bc10c9cfef8 100644 --- a/arch/arm/boot/dts/imx28-apf28dev.dts +++ b/arch/arm/boot/dts/imx28-apf28dev.dts @@ -225,7 +225,7 @@ label = "User button"; gpios = <&gpio0 17 GPIO_ACTIVE_LOW>; linux,code = <0x100>; - gpio-key,wakeup; + wakeup-source; }; }; }; diff --git a/arch/arm/boot/dts/imx28-eukrea-mbmx28lc.dtsi b/arch/arm/boot/dts/imx28-eukrea-mbmx28lc.dtsi index 927b391d2058d588eeddc93f7c5acd4e29cafe5f..88594747f454fede06968b152c6a7da76bb3e6b7 100644 --- a/arch/arm/boot/dts/imx28-eukrea-mbmx28lc.dtsi +++ b/arch/arm/boot/dts/imx28-eukrea-mbmx28lc.dtsi @@ -36,7 +36,7 @@ label = "SW3"; gpios = <&gpio1 21 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; }; @@ -49,7 +49,7 @@ label = "SW4"; gpios = <&gpio1 20 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/imx28-tx28.dts b/arch/arm/boot/dts/imx28-tx28.dts index 4ea89344a5fff51115160fad9e34b16a4a4377eb..fd20e99c777e9764c9c1e298029ea6db0b652ad6 100644 --- a/arch/arm/boot/dts/imx28-tx28.dts +++ b/arch/arm/boot/dts/imx28-tx28.dts @@ -130,7 +130,7 @@ compatible = "fixed-clock"; reg = <0>; #clock-cells = <0>; - clock-frequency = <27000000>; + clock-frequency = <26000000>; }; }; @@ -202,7 +202,7 @@ 0x02020049 /* row 2, col 2, KEY_KP9 */ >; gpio-activelow; - linux,wakeup; + wakeup-source; debounce-delay-ms = <100>; col-scan-delay-us = <5000>; linux,no-autorepeat; diff --git a/arch/arm/boot/dts/imx35-eukrea-mbimxsd35-baseboard.dts b/arch/arm/boot/dts/imx35-eukrea-mbimxsd35-baseboard.dts index 75b036700d314cefa0040e88b92bc54e2f595a22..4727bbb804e1266a423203118dd22770a853d97f 100644 --- a/arch/arm/boot/dts/imx35-eukrea-mbimxsd35-baseboard.dts +++ b/arch/arm/boot/dts/imx35-eukrea-mbimxsd35-baseboard.dts @@ -30,7 +30,7 @@ label = "BP1"; gpios = <&gpio3 25 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; linux,input-type = <1>; }; }; diff --git a/arch/arm/boot/dts/imx35.dtsi b/arch/arm/boot/dts/imx35.dtsi index ed3dc3391d1c54e41803b32b059d06f82771aae9..14e1320d9f843a0b1baa83882694915568361301 100644 --- a/arch/arm/boot/dts/imx35.dtsi +++ b/arch/arm/boot/dts/imx35.dtsi @@ -305,7 +305,8 @@ compatible = "fsl,imx35-usb", "fsl,imx27-usb"; reg = <0x53ff4000 0x0200>; interrupts = <37>; - clocks = <&clks 73>; + clocks = <&clks 9>, <&clks 73>, <&clks 28>; + clock-names = "ipg", "ahb", "per"; fsl,usbmisc = <&usbmisc 0>; fsl,usbphy = <&usbphy0>; status = "disabled"; @@ -315,7 +316,8 @@ compatible = "fsl,imx35-usb", "fsl,imx27-usb"; reg = <0x53ff4400 0x0200>; interrupts = <35>; - clocks = <&clks 73>; + clocks = <&clks 9>, <&clks 73>, <&clks 28>; + clock-names = "ipg", "ahb", "per"; fsl,usbmisc = <&usbmisc 1>; fsl,usbphy = <&usbphy1>; dr_mode = "host"; @@ -325,8 +327,6 @@ usbmisc: usbmisc@53ff4600 { #index-cells = <1>; compatible = "fsl,imx35-usbmisc"; - clocks = <&clks 9>, <&clks 73>, <&clks 28>; - clock-names = "ipg", "ahb", "per"; reg = <0x53ff4600 0x00f>; }; }; diff --git a/arch/arm/boot/dts/imx51-babbage.dts b/arch/arm/boot/dts/imx51-babbage.dts index 649befeb2cf96ef4b968f809a98d5d718227b002..018d24eb9965f8060050555bab1e1b8663bf1f37 100644 --- a/arch/arm/boot/dts/imx51-babbage.dts +++ b/arch/arm/boot/dts/imx51-babbage.dts @@ -107,7 +107,7 @@ label = "Power Button"; gpios = <&gpio2 21 GPIO_ACTIVE_HIGH>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/imx51-digi-connectcore-som.dtsi b/arch/arm/boot/dts/imx51-digi-connectcore-som.dtsi index 321662f53e3309b835cfdc607681d8b0cc76aeb7..16fc69c69ab2e60a4cbd847aa98825fe8577e318 100644 --- a/arch/arm/boot/dts/imx51-digi-connectcore-som.dtsi +++ b/arch/arm/boot/dts/imx51-digi-connectcore-som.dtsi @@ -156,7 +156,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_esdhc2>; cap-sdio-irq; - enable-sdio-wakeup; + wakeup-source; keep-power-in-suspend; max-frequency = <50000000>; no-1-8-v; diff --git a/arch/arm/boot/dts/imx51-eukrea-mbimxsd51-baseboard.dts b/arch/arm/boot/dts/imx51-eukrea-mbimxsd51-baseboard.dts index 34599c547459a2d00756cb42bc05cca3f2fa2798..d270df3e58917aab23f21eb23ef04e667158bf4c 100644 --- a/arch/arm/boot/dts/imx51-eukrea-mbimxsd51-baseboard.dts +++ b/arch/arm/boot/dts/imx51-eukrea-mbimxsd51-baseboard.dts @@ -41,7 +41,7 @@ label = "BP1"; gpios = <&gpio3 31 GPIO_ACTIVE_LOW>; linux,code = <256>; - gpio-key,wakeup; + wakeup-source; linux,input-type = <1>; }; }; diff --git a/arch/arm/boot/dts/imx51-pinfunc.h b/arch/arm/boot/dts/imx51-pinfunc.h index 9eb92abaeb6dc42b33a597d3460833b17d6ca5f1..82eae3c8a3ce26703b4e7b99f1a021a65a07853f 100644 --- a/arch/arm/boot/dts/imx51-pinfunc.h +++ b/arch/arm/boot/dts/imx51-pinfunc.h @@ -536,7 +536,6 @@ #define MX51_PAD_DISPB2_SER_CLK__DISP1_PIN7 0x2c4 0x6c4 0x000 0x3 0x0 #define MX51_PAD_DISPB2_SER_CLK__DISPB2_SER_CLK 0x2c4 0x6c4 0x000 0x0 0x0 #define MX51_PAD_DISPB2_SER_CLK__GPIO3_7 0x2c4 0x6c4 0x990 0x4 0x1 -#define MX51_PAD_DISPB2_SER_RS__DISP1_EXT_CLK 0x2c8 0x6c8 0x000 0x2 0x0 #define MX51_PAD_DISPB2_SER_RS__DISP1_PIN16 0x2c8 0x6c8 0x000 0x2 0x0 #define MX51_PAD_DISPB2_SER_RS__DISP1_PIN8 0x2c8 0x6c8 0x000 0x3 0x0 #define MX51_PAD_DISPB2_SER_RS__DISPB2_SER_RS 0x2c8 0x6c8 0x000 0x0 0x0 diff --git a/arch/arm/boot/dts/imx53-ard.dts b/arch/arm/boot/dts/imx53-ard.dts index 3bc18835fb4bbbe0e388922689a70395bb532cd6..4486bc47d14009d96e039d33664a72204f8376c1 100644 --- a/arch/arm/boot/dts/imx53-ard.dts +++ b/arch/arm/boot/dts/imx53-ard.dts @@ -69,21 +69,21 @@ label = "Home"; gpios = <&gpio5 10 0>; linux,code = <102>; /* KEY_HOME */ - gpio-key,wakeup; + wakeup-source; }; back { label = "Back"; gpios = <&gpio5 11 0>; linux,code = <158>; /* KEY_BACK */ - gpio-key,wakeup; + wakeup-source; }; program { label = "Program"; gpios = <&gpio5 12 0>; linux,code = <362>; /* KEY_PROGRAM */ - gpio-key,wakeup; + wakeup-source; }; volume-up { diff --git a/arch/arm/boot/dts/imx53-qsb-common.dtsi b/arch/arm/boot/dts/imx53-qsb-common.dtsi index 53fd75c8ffcfd34c19f43d407bb2f8e6a4573495..c05e7cfd0cbcb2bd7b76920bc1cb0fd7913649f3 100644 --- a/arch/arm/boot/dts/imx53-qsb-common.dtsi +++ b/arch/arm/boot/dts/imx53-qsb-common.dtsi @@ -59,22 +59,22 @@ power { label = "Power Button"; - gpios = <&gpio1 8 0>; - linux,code = <116>; /* KEY_POWER */ + gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; + linux,code = ; }; volume-up { label = "Volume Up"; - gpios = <&gpio2 14 0>; - linux,code = <115>; /* KEY_VOLUMEUP */ - gpio-key,wakeup; + gpios = <&gpio2 14 GPIO_ACTIVE_LOW>; + linux,code = ; + wakeup-source; }; volume-down { label = "Volume Down"; - gpios = <&gpio2 15 0>; - linux,code = <114>; /* KEY_VOLUMEDOWN */ - gpio-key,wakeup; + gpios = <&gpio2 15 GPIO_ACTIVE_LOW>; + linux,code = ; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/imx53-tx53-x03x.dts b/arch/arm/boot/dts/imx53-tx53-x03x.dts index 13e842b0c7857b1050c73319842113d6bf08dbb3..0ecb43d88522318701304fad35e3c214cfcb276e 100644 --- a/arch/arm/boot/dts/imx53-tx53-x03x.dts +++ b/arch/arm/boot/dts/imx53-tx53-x03x.dts @@ -231,7 +231,7 @@ interrupts = <26 0>; gpios = <&gpio3 26 GPIO_ACTIVE_LOW>; ti,x-plate-ohms = <660>; - linux,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/imx53-tx53-x13x.dts b/arch/arm/boot/dts/imx53-tx53-x13x.dts index 64804719f0f442de2225613f54518f68293fc190..3cf682a681f40a986e8eb3142f3621ec5d6736b0 100644 --- a/arch/arm/boot/dts/imx53-tx53-x13x.dts +++ b/arch/arm/boot/dts/imx53-tx53-x13x.dts @@ -101,7 +101,7 @@ interrupt-parent = <&gpio3>; interrupts = <23 0>; wakeup-gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>; - linux,wakeup; + wakeup-source; }; }; @@ -126,7 +126,7 @@ interrupt-parent = <&gpio3>; interrupts = <22 0>; wakeup-gpios = <&gpio3 22 GPIO_ACTIVE_HIGH>; - linux,wakeup; + wakeup-source; }; }; @@ -183,13 +183,14 @@ status = "okay"; lvds0: lvds-channel@0 { - fsl,data-mapping = "jeida"; - fsl,data-width = <24>; + fsl,data-mapping = "spwg"; + fsl,data-width = <18>; status = "okay"; display-timings { - native-mode = <&lvds_timing0>; - lvds_timing0: hsd100pxn1 { + native-mode = <&lvds0_timing0>; + + lvds0_timing0: hsd100pxn1 { clock-frequency = <65000000>; hactive = <1024>; vactive = <768>; @@ -202,19 +203,36 @@ hsync-active = <0>; vsync-active = <0>; de-active = <1>; - pixelclk-active = <0>; + pixelclk-active = <1>; + }; + + lvds0_timing1: nl12880bc20 { + clock-frequency = <71000000>; + hactive = <1280>; + vactive = <800>; + hback-porch = <50>; + hsync-len = <60>; + hfront-porch = <50>; + vback-porch = <5>; + vsync-len = <13>; + vfront-porch = <5>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <1>; + pixelclk-active = <1>; }; }; }; lvds1: lvds-channel@1 { - fsl,data-mapping = "jeida"; - fsl,data-width = <24>; + fsl,data-mapping = "spwg"; + fsl,data-width = <18>; status = "okay"; display-timings { - native-mode = <&lvds_timing1>; - lvds_timing1: hsd100pxn1 { + native-mode = <&lvds1_timing0>; + + lvds1_timing0: hsd100pxn1 { clock-frequency = <65000000>; hactive = <1024>; vactive = <768>; @@ -227,7 +245,7 @@ hsync-active = <0>; vsync-active = <0>; de-active = <1>; - pixelclk-active = <0>; + pixelclk-active = <1>; }; }; }; diff --git a/arch/arm/boot/dts/imx53-tx53.dtsi b/arch/arm/boot/dts/imx53-tx53.dtsi index d3e50b22064f28777bbd2a3b60f512d844ff9418..bd3dfefa5778acbcc1124279f02517fc8aecaa3e 100644 --- a/arch/arm/boot/dts/imx53-tx53.dtsi +++ b/arch/arm/boot/dts/imx53-tx53.dtsi @@ -37,7 +37,7 @@ compatible = "fixed-clock"; reg = <0>; #clock-cells = <0>; - clock-frequency = <27000000>; + clock-frequency = <26000000>; }; }; @@ -50,7 +50,7 @@ label = "Power Button"; gpios = <&gpio5 2 GPIO_ACTIVE_HIGH>; linux,code = <116>; /* KEY_POWER */ - gpio-key,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/imx6dl-tx6u-811x.dts b/arch/arm/boot/dts/imx6dl-tx6u-811x.dts index c275eecc9472006de381c2a450025badea821f2c..d35a5cdc3229638445b4aacf4414da1bf90b8210 100644 --- a/arch/arm/boot/dts/imx6dl-tx6u-811x.dts +++ b/arch/arm/boot/dts/imx6dl-tx6u-811x.dts @@ -77,7 +77,7 @@ interrupt-parent = <&gpio3>; interrupts = <22 0>; wakeup-gpios = <&gpio3 22 GPIO_ACTIVE_HIGH>; - linux,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/imx6dl-wandboard-revb1.dts b/arch/arm/boot/dts/imx6dl-wandboard-revb1.dts index f607d4f1d2448069add1c8a83d8a556e4d3f52a6..8c314eee4fdd726a4826aac4aca7eceedf6df416 100644 --- a/arch/arm/boot/dts/imx6dl-wandboard-revb1.dts +++ b/arch/arm/boot/dts/imx6dl-wandboard-revb1.dts @@ -13,7 +13,7 @@ #include "imx6qdl-wandboard-revb1.dtsi" / { - model = "Wandboard i.MX6 Dual Lite Board"; + model = "Wandboard i.MX6 Dual Lite Board rev B1"; compatible = "wand,imx6dl-wandboard", "fsl,imx6dl"; memory { diff --git a/arch/arm/boot/dts/imx6q-apalis-ixora.dts b/arch/arm/boot/dts/imx6q-apalis-ixora.dts new file mode 100644 index 0000000000000000000000000000000000000000..2cba82d0d859b1a9db81ee57e81583df3a3684cc --- /dev/null +++ b/arch/arm/boot/dts/imx6q-apalis-ixora.dts @@ -0,0 +1,272 @@ +/* + * Copyright 2014-2016 Toradex AG + * Copyright 2012 Freescale Semiconductor, Inc. + * Copyright 2011 Linaro Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include +#include +#include +#include "imx6q.dtsi" +#include "imx6qdl-apalis.dtsi" + +/ { + model = "Toradex Apalis iMX6Q/D Module on Ixora Carrier Board"; + compatible = "toradex,apalis_imx6q-ixora", "toradex,apalis_imx6q", + "fsl,imx6q"; + + aliases { + i2c0 = &i2cddc; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; + }; + + aliases { + rtc0 = &rtc_i2c; + rtc1 = &snvs_rtc; + }; + + gpio-keys { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_keys>; + + wakeup { + label = "Wake-Up"; + gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; + linux,code = ; + debounce-interval = <10>; + wakeup-source; + }; + }; + + leds { + compatible = "gpio-leds"; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_leds_ixora>; + + led4-green { + label = "LED_4_GREEN"; + gpios = <&gpio1 17 GPIO_ACTIVE_HIGH>; + }; + + led4-red { + label = "LED_4_RED"; + gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>; + }; + + led5-green { + label = "LED_5_GREEN"; + gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>; + }; + + led5-red { + label = "LED_5_RED"; + gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>; + }; + }; + + pwmleds { + compatible = "pwm-leds"; + + ledpwm1 { + label = "PWM1"; + pwms = <&pwm1 0 50000>; + max-brightness = <255>; + }; + + ledpwm2 { + label = "PWM2"; + pwms = <&pwm2 0 50000>; + max-brightness = <255>; + }; + + ledpwm3 { + label = "PWM3"; + pwms = <&pwm3 0 50000>; + max-brightness = <255>; + }; + }; +}; + +&backlight { + brightness-levels = <0 127 191 223 239 247 251 255>; + default-brightness-level = <1>; + status = "okay"; +}; + +&can1 { + status = "okay"; +}; + +&can2 { + status = "okay"; +}; + +&hdmi { + ddc-i2c-bus = <&i2cddc>; + status = "okay"; +}; + +&i2cddc { + status = "okay"; +}; + +/* GEN1_I2C: I2C1_SDA/SCL on MXM3 209/211 (e.g. RTC on carrier board) */ +&i2c1 { + status = "okay"; + + eeprom@50 { + compatible = "atmel,24c02"; + reg = <0x50>; + }; + + /* M41T0M6 real time clock on carrier board */ + rtc_i2c: rtc@68 { + compatible = "st,m41t00"; + reg = <0x68>; + }; +}; + +&ldb { + status = "okay"; +}; + +&pcie { + /* active-low meaning opposite of regular PERST# active-low polarity */ + reset-gpio = <&gpio1 28 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&pwm1 { + status = "okay"; +}; + +&pwm2 { + status = "okay"; +}; + +&pwm3 { + status = "okay"; +}; + +&pwm4 { + status = "okay"; +}; + +®_usb_otg_vbus { + status = "okay"; +}; + +®_usb_host_vbus { + status = "okay"; +}; + +&sata { + status = "okay"; +}; + +&sound_spdif { + status = "okay"; +}; + +&spdif { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&uart4 { + status = "okay"; +}; + +&uart5 { + status = "okay"; +}; + +&usbh1 { + vbus-supply = <®_usb_host_vbus>; + status = "okay"; +}; + +&usbotg { + vbus-supply = <®_usb_otg_vbus>; + status = "okay"; +}; + +/* SD1 */ +&usdhc2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sd_cd>; + cd-gpios = <&gpio6 14 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&iomuxc { + /* + * Mux the Apalis GPIOs + * GPIO5, 6 used by optional fusion_F0710A kernel module + */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_apalis_gpio1 &pinctrl_apalis_gpio2 + &pinctrl_apalis_gpio3 &pinctrl_apalis_gpio4 + &pinctrl_apalis_gpio5 &pinctrl_apalis_gpio6 + &pinctrl_apalis_gpio7 &pinctrl_apalis_gpio8 + >; + + pinctrl_leds_ixora: ledsixoragrp { + fsl,pins = < + MX6QDL_PAD_SD1_DAT1__GPIO1_IO17 0x1b0b0 + MX6QDL_PAD_SD1_DAT3__GPIO1_IO21 0x1b0b0 + MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x1b0b0 + MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x1b0b0 + >; + }; +}; diff --git a/arch/arm/boot/dts/imx6q-b450v3.dts b/arch/arm/boot/dts/imx6q-b450v3.dts new file mode 100644 index 0000000000000000000000000000000000000000..3101be5bafa7d0d56070609c19201bdd65a43ae0 --- /dev/null +++ b/arch/arm/boot/dts/imx6q-b450v3.dts @@ -0,0 +1,88 @@ +/* + * Copyright 2015 Timesys Corporation. + * Copyright 2015 General Electric Company + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include "imx6q-bx50v3.dtsi" + +/ { + model = "General Electric B450v3"; + compatible = "ge,imx6q-b450v3", "advantech,imx6q-ba16", "fsl,imx6q"; + + chosen { + stdout-path = &uart3; + }; + + panel-lvds0 { + compatible = "innolux,g121x1-l03"; + backlight = <&backlight_lvds>; + power-supply = <®_lvds>; + + port { + panel_in_lvds0: endpoint { + remote-endpoint = <&lvds0_out>; + }; + }; + }; +}; + +&ldb { + assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, + <&clks IMX6QDL_CLK_LDB_DI1_SEL>; + assigned-clock-parents = <&clks IMX6QDL_CLK_PLL3_USB_OTG>, + <&clks IMX6QDL_CLK_PLL3_USB_OTG>; + status = "okay"; + + lvds0: lvds-channel@0 { + fsl,data-mapping = "spwg"; + fsl,data-width = <24>; + status = "okay"; + + port@4 { + reg = <4>; + + lvds0_out: endpoint { + remote-endpoint = <&panel_in_lvds0>; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/imx6q-b650v3.dts b/arch/arm/boot/dts/imx6q-b650v3.dts new file mode 100644 index 0000000000000000000000000000000000000000..823f55ccb60fb3ea59f1f148c340ea4575308515 --- /dev/null +++ b/arch/arm/boot/dts/imx6q-b650v3.dts @@ -0,0 +1,88 @@ +/* + * Copyright 2015 Timesys Corporation. + * Copyright 2015 General Electric Company + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include "imx6q-bx50v3.dtsi" + +/ { + model = "General Electric B650v3"; + compatible = "ge,imx6q-b650v3", "advantech,imx6q-ba16", "fsl,imx6q"; + + chosen { + stdout-path = &uart3; + }; + + panel-lvds0 { + compatible = "innolux,g121x1-l03"; + backlight = <&backlight_lvds>; + power-supply = <®_lvds>; + + port { + panel_in_lvds0: endpoint { + remote-endpoint = <&lvds0_out>; + }; + }; + }; +}; + +&ldb { + assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, + <&clks IMX6QDL_CLK_LDB_DI1_SEL>; + assigned-clock-parents = <&clks IMX6QDL_CLK_PLL3_USB_OTG>, + <&clks IMX6QDL_CLK_PLL3_USB_OTG>; + status = "okay"; + + lvds0: lvds-channel@0 { + fsl,data-mapping = "spwg"; + fsl,data-width = <24>; + status = "okay"; + + port@4 { + reg = <4>; + + lvds0_out: endpoint { + remote-endpoint = <&panel_in_lvds0>; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/imx6q-b850v3.dts b/arch/arm/boot/dts/imx6q-b850v3.dts new file mode 100644 index 0000000000000000000000000000000000000000..984d00000403d7ab5d6855111bf4edfdb7257636 --- /dev/null +++ b/arch/arm/boot/dts/imx6q-b850v3.dts @@ -0,0 +1,157 @@ +/* + * Copyright 2015 Timesys Corporation. + * Copyright 2015 General Electric Company + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include "imx6q-bx50v3.dtsi" + +/ { + model = "General Electric B850v3"; + compatible = "ge,imx6q-b850v3", "advantech,imx6q-ba16", "fsl,imx6q"; + + chosen { + stdout-path = &uart3; + }; + + panel-lvds0 { + compatible = "auo,b133htn01"; + backlight = <&backlight_lvds>; + ddc-i2c-bus = <&mux2_i2c2>; + + port { + panel_in_lvds0: endpoint { + remote-endpoint = <&lvds0_out>; + }; + }; + }; +}; + +&ldb { + assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, + <&clks IMX6QDL_CLK_LDB_DI1_SEL>; + assigned-clock-parents = <&clks IMX6QDL_CLK_PLL3_USB_OTG>, + <&clks IMX6QDL_CLK_PLL3_USB_OTG>; + fsl,dual-channel; + status = "okay"; + + lvds0: lvds-channel@0 { + fsl,data-mapping = "spwg"; + fsl,data-width = <24>; + status = "okay"; + + port@4 { + reg = <4>; + + lvds0_out: endpoint { + remote-endpoint = <&panel_in_lvds0>; + }; + }; + }; +}; + +&i2c2 { + pca9547_ddc: mux@70 { + compatible = "nxp,pca9547"; + reg = <0x70>; + #address-cells = <1>; + #size-cells = <0>; + + mux2_i2c1: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x0>; + }; + + mux2_i2c2: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x1>; + }; + + mux2_i2c3: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x2>; + }; + + mux2_i2c4: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x3>; + }; + + mux2_i2c5: i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x4>; + }; + + mux2_i2c6: i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x5>; + }; + + mux2_i2c7: i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x6>; + }; + + mux2_i2c8: i2c@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x7>; + }; + }; +}; + +&hdmi { + ddc-i2c-bus = <&mux2_i2c1>; +}; + +&mux1_i2c1 { + ads7830@4a { + compatible = "ti,ads7830"; + reg = <0x4a>; + }; +}; diff --git a/arch/arm/boot/dts/imx6q-ba16.dtsi b/arch/arm/boot/dts/imx6q-ba16.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..8f6e6035f3f7ab715ff2d787828ae84e06b2f10c --- /dev/null +++ b/arch/arm/boot/dts/imx6q-ba16.dtsi @@ -0,0 +1,632 @@ +/* + * Support for imx6 based Advantech DMS-BA16 Qseven module + * + * Copyright 2015 Timesys Corporation. + * Copyright 2015 General Electric Company + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "imx6q.dtsi" +#include + +/ { + memory { + reg = <0x10000000 0x40000000>; + }; + + backlight_lvds: backlight { + compatible = "pwm-backlight"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_display>; + pwms = <&pwm1 0 5000000>; + brightness-levels = < 0 1 2 3 4 5 6 7 8 9 + 10 11 12 13 14 15 16 17 18 19 + 20 21 22 23 24 25 26 27 28 29 + 30 31 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 48 49 + 50 51 52 53 54 55 56 57 58 59 + 60 61 62 63 64 65 66 67 68 69 + 70 71 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 88 89 + 90 91 92 93 94 95 96 97 98 99 + 100 101 102 103 104 105 106 107 108 109 + 110 111 112 113 114 115 116 117 118 119 + 120 121 122 123 124 125 126 127 128 129 + 130 131 132 133 134 135 136 137 138 139 + 140 141 142 143 144 145 146 147 148 149 + 150 151 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 168 169 + 170 171 172 173 174 175 176 177 178 179 + 180 181 182 183 184 185 186 187 188 189 + 190 191 192 193 194 195 196 197 198 199 + 200 201 202 203 204 205 206 207 208 209 + 210 211 212 213 214 215 216 217 218 219 + 220 221 222 223 224 225 226 227 228 229 + 230 231 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 248 249 + 250 251 252 253 254 255>; + default-brightness-level = <255>; + enable-gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>; + }; + + reg_1p8v: regulator-1p8v { + compatible = "regulator-fixed"; + regulator-name = "1P8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "3P3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + reg_lvds: regulator-lvds { + compatible = "regulator-fixed"; + regulator-name = "lvds_ppen"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + gpio = <&gpio3 22 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + reg_usb_h1_vbus: regulator-usbh1vbus { + compatible = "regulator-fixed"; + regulator-name = "usb_h1_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + reg_usb_otg_vbus: regulator-usbotgvbus { + compatible = "regulator-fixed"; + regulator-name = "usb_otg_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; +}; + +&audmux { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_audmux>; + status = "okay"; +}; + +&ecspi1 { + fsl,spi-num-chipselects = <1>; + cs-gpios = <&gpio2 30 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ecspi1>; + status = "okay"; + + flash: n25q032@0 { + compatible = "jedec,spi-nor"; + #address-cells = <1>; + #size-cells = <1>; + spi-max-frequency = <20000000>; + reg = <0>; + + partition@0 { + label = "U-Boot"; + reg = <0x0 0xc0000>; + }; + + partition@c0000 { + label = "env"; + reg = <0xc0000 0x10000>; + }; + + partition@d0000 { + label = "spare"; + reg = <0xd0000 0x130000>; + }; + }; +}; + +&fec { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enet>; + phy-mode = "rgmii"; + status = "okay"; +}; + +&hdmi { + ddc-i2c-bus = <&i2c2>; + status = "okay"; +}; + +&i2c1 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + status = "okay"; +}; + +&i2c2 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + status = "okay"; +}; + +&i2c3 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + status = "okay"; + + pmic@58 { + compatible = "dlg,da9063"; + reg = <0x58>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pmic>; + interrupt-parent = <&gpio7>; + interrupts = <13 IRQ_TYPE_LEVEL_LOW>; + + onkey { + compatible = "dlg,da9063-onkey"; + }; + + regulators { + vdd_bcore1: bcore1 { + regulator-min-microvolt = <1420000>; + regulator-max-microvolt = <1420000>; + regulator-always-on; + regulator-boot-on; + }; + + vdd_bcore2: bcore2 { + regulator-min-microvolt = <1420000>; + regulator-max-microvolt = <1420000>; + regulator-always-on; + regulator-boot-on; + }; + + vdd_bpro: bpro { + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-always-on; + regulator-boot-on; + }; + + vdd_bmem: bmem { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + }; + + vdd_bio: bio { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + }; + + vdd_bperi: bperi { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + }; + + vdd_ldo1: ldo1 { + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <1860000>; + }; + + vdd_ldo2: ldo2 { + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <1860000>; + }; + + vdd_ldo3: ldo3 { + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <3440000>; + }; + + vdd_ldo4: ldo4 { + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <3440000>; + }; + + vdd_ldo5: ldo5 { + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <3600000>; + }; + + vdd_ldo6: ldo6 { + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <3600000>; + }; + + vdd_ldo7: ldo7 { + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <3600000>; + }; + + vdd_ldo8: ldo8 { + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <3600000>; + }; + + vdd_ldo9: ldo9 { + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <3600000>; + }; + + vdd_ldo10: ldo10 { + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <3600000>; + }; + + vdd_ldo11: ldo11 { + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <3600000>; + regulator-always-on; + regulator-boot-on; + }; + }; + }; + + rtc@32 { + compatible = "epson,rx8010"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_rtc>; + reg = <0x32>; + interrupt-parent = <&gpio4>; + interrupts = <10 IRQ_TYPE_LEVEL_HIGH>; + }; +}; + +&pcie { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie>; + reset-gpio = <&gpio7 12 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +&pwm1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm1>; + status = "okay"; +}; + +&pwm2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm2>; + status = "okay"; +}; + +&sata { + status = "okay"; +}; + +&ssi1 { + status = "okay"; +}; + +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart3>; + fsl,uart-has-rtscts; + status = "okay"; +}; + +&uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart4>; + status = "okay"; +}; + +&usbh1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbhub>; + vbus-supply = <®_usb_h1_vbus>; + reset-gpios = <&gpio7 11 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +&usbotg { + vbus-supply = <®_usb_otg_vbus>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbotg>; + disable-over-current; + status = "okay"; +}; + +&usdhc2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc2>; + cd-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; + no-1-8-v; + keep-power-in-suspend; + wakeup-source; + status = "okay"; +}; + +&usdhc3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc3 &pinctrl_usdhc3_reset>; + bus-width = <8>; + vmmc-supply = <&vdd_bperi>; + vqmmc-supply = <&vdd_bio>; + non-removable; + keep-power-in-suspend; + status = "okay"; +}; + +&wdog1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wdog>; +}; + +&iomuxc { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hog>; + + pinctrl_audmux: audmuxgrp { + fsl,pins = < + MX6QDL_PAD_DISP0_DAT20__AUD4_TXC 0x130b0 + MX6QDL_PAD_DISP0_DAT21__AUD4_TXD 0x130b0 + MX6QDL_PAD_DISP0_DAT22__AUD4_TXFS 0x130b0 + MX6QDL_PAD_DISP0_DAT23__AUD4_RXD 0x130b0 + >; + }; + + pinctrl_display: dispgrp { + fsl,pins = < + /* BLEN_OUT */ + MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x1b0b0 + /* LVDS_PPEN_OUT */ + MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x1b0b0 + >; + }; + + pinctrl_ecspi1: ecspi1grp { + fsl,pins = < + MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1 + MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1 + MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1 + /* SPI1 CS */ + MX6QDL_PAD_EIM_EB2__GPIO2_IO30 0x1b0b0 + >; + }; + + pinctrl_ecspi5: ecspi5grp { + fsl,pins = < + MX6QDL_PAD_SD1_DAT0__ECSPI5_MISO 0x1b0b0 + MX6QDL_PAD_SD1_CMD__ECSPI5_MOSI 0x1b0b0 + MX6QDL_PAD_SD1_CLK__ECSPI5_SCLK 0x1b0b0 + MX6QDL_PAD_SD1_DAT1__GPIO1_IO17 0x1b0b0 + >; + }; + + pinctrl_enet: enetgrp { + fsl,pins = < + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x100b0 + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x100b0 + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x100b0 + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x100b0 + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x100b0 + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x100b0 + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x100b0 + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x100b0 + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x100b0 + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0 + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0 + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0 + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0 + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0 + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0 + /* FEC Reset */ + MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28 0x1b0b0 + /* AR8033 Interrupt */ + MX6QDL_PAD_GPIO_19__GPIO4_IO05 0x1b0b0 + >; + }; + + pinctrl_hog: hoggrp { + fsl,pins = < + /* GPIO 0-7 */ + MX6QDL_PAD_NANDF_D0__GPIO2_IO00 0x1b0b0 + MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x1b0b0 + MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x1b0b0 + MX6QDL_PAD_NANDF_D3__GPIO2_IO03 0x1b0b0 + MX6QDL_PAD_NANDF_D4__GPIO2_IO04 0x1b0b0 + MX6QDL_PAD_NANDF_D5__GPIO2_IO05 0x1b0b0 + MX6QDL_PAD_NANDF_D6__GPIO2_IO06 0x1b0b0 + MX6QDL_PAD_NANDF_D7__GPIO2_IO07 0x1b0b0 + /* SUS_S3_OUT to CPLD */ + MX6QDL_PAD_KEY_ROW2__GPIO4_IO11 0x1b0b0 + >; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b8b1 + MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x4001b8b1 + >; + }; + + pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1 + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1 + >; + }; + + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1 + MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1 + >; + }; + + pinctrl_pcie: pciegrp { + fsl,pins = < + /* PCIe Reset */ + MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x1b0b0 + /* PCIe Wake */ + MX6QDL_PAD_GPIO_5__GPIO1_IO05 0x1b0b0 + >; + }; + + pinctrl_pmic: pmicgrp { + fsl,pins = < + /* PMIC Interrupt */ + MX6QDL_PAD_GPIO_18__GPIO7_IO13 0x1b0b0 + >; + }; + + pinctrl_pwm1: pwm1grp { + fsl,pins = < + MX6QDL_PAD_SD1_DAT3__PWM1_OUT 0x1b0b1 + >; + }; + + pinctrl_pwm2: pwm2grp { + fsl,pins = < + MX6QDL_PAD_GPIO_1__PWM2_OUT 0x1b0b1 + >; + }; + + pinctrl_rtc: rtcgrp { + fsl,pins = < + /* RTC_INT */ + MX6QDL_PAD_KEY_COL2__GPIO4_IO10 0x1b0b0 + >; + }; + + pinctrl_uart3: uart3grp { + fsl,pins = < + MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1 + MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1 + MX6QDL_PAD_EIM_D23__UART3_CTS_B 0x1b0b1 + MX6QDL_PAD_EIM_D31__UART3_RTS_B 0x1b0b1 + >; + }; + + pinctrl_uart4: uart4grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1 + MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1 + >; + }; + + pinctrl_usbhub: usbhubgrp { + fsl,pins = < + /* HUB_RESET */ + MX6QDL_PAD_GPIO_16__GPIO7_IO11 0x1b0b0 + >; + }; + + pinctrl_usbotg: usbotggrp { + fsl,pins = < + MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x17059 + >; + }; + + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059 + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059 + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059 + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059 + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059 + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059 + /* uSDHC2 CD */ + MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x1b0b0 + >; + }; + + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059 + MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x17059 + MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x17059 + MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x17059 + MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x17059 + >; + }; + + pinctrl_usdhc3_reset: usdhc3grp-reset { + fsl,pins = < + MX6QDL_PAD_SD3_RST__SD3_RESET 0x170F9 + >; + }; + + pinctrl_usdhc4: usdhc4grp { + fsl,pins = < + MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059 + MX6QDL_PAD_SD4_CLK__SD4_CLK 0x17059 + MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059 + MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059 + MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059 + MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059 + MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059 + MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059 + MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059 + MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059 + /* uSDHC4 CD */ + MX6QDL_PAD_NANDF_CS0__GPIO6_IO11 0x1b0b0 + /* uSDHC4 SDIO PWR */ + MX6QDL_PAD_NANDF_CS1__GPIO6_IO14 0x1b0b0 + /* uSDHC4 SDIO WP */ + MX6QDL_PAD_NANDF_CS2__GPIO6_IO15 0x1b0b0 + /* uSDHC4 SDIO LED */ + MX6QDL_PAD_NANDF_CS3__GPIO6_IO16 0x1b0b0 + >; + }; + + pinctrl_wdog: wdoggrp { + fsl,pins = < + MX6QDL_PAD_GPIO_9__WDOG1_B 0x1b0b0 + >; + }; +}; diff --git a/arch/arm/boot/dts/imx6q-bx50v3.dtsi b/arch/arm/boot/dts/imx6q-bx50v3.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..bb66dfd5294c5726b0707dc76eab20bc00828d8a --- /dev/null +++ b/arch/arm/boot/dts/imx6q-bx50v3.dtsi @@ -0,0 +1,225 @@ +/* + * Copyright 2015 Timesys Corporation. + * Copyright 2015 General Electric Company + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "imx6q-ba16.dtsi" + +/ { + clocks { + mclk: clock@0 { + compatible = "fixed-clock"; + reg = <0>; + #clock-cells = <0>; + clock-frequency = <22000000>; + }; + }; + + reg_wl18xx_vmmc: regulator-wl18xx { + compatible = "regulator-fixed"; + regulator-name = "vwl1807"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&pca9539 3 GPIO_ACTIVE_HIGH>; + startup-delay-us = <70000>; + enable-active-high; + }; + + reg_wlan: regulator-wlan { + compatible = "regulator-fixed"; + regulator-name = "3P3V_wlan"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + gpio = <&gpio6 14 GPIO_ACTIVE_HIGH>; + }; + + sound { + compatible = "fsl,imx6q-ba16-sgtl5000", + "fsl,imx-audio-sgtl5000"; + model = "imx6q-ba16-sgtl5000"; + ssi-controller = <&ssi1>; + audio-codec = <&sgtl5000>; + audio-routing = + "MIC_IN", "Mic Jack", + "Mic Jack", "Mic Bias", + "LINE_IN", "Line In Jack", + "Headphone Jack", "HP_OUT"; + mux-int-port = <1>; + mux-ext-port = <4>; + }; +}; + +&ecspi5 { + fsl,spi-num-chipselects = <1>; + cs-gpios = <&gpio1 17 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ecspi5>; + status = "okay"; + + m25_eeprom: m25p80@0 { + compatible = "atmel,at25"; + spi-max-frequency = <20000000>; + size = <0x8000>; + pagesize = <64>; + reg = <0>; + address-width = <16>; + }; +}; + +&i2c1 { + pca9547: mux@70 { + compatible = "nxp,pca9547"; + reg = <0x70>; + #address-cells = <1>; + #size-cells = <0>; + + mux1_i2c1: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x0>; + + ads7830: ads7830@48 { + compatible = "ti,ads7830"; + reg = <0x48>; + }; + + mma8453: mma8453@1c { + compatible = "fsl,mma8453"; + reg = <0x1c>; + }; + }; + + mux1_i2c2: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x1>; + + eeprom: eeprom@50 { + compatible = "atmel,24c08"; + reg = <0x50>; + }; + + mpl3115: mpl3115@60 { + compatible = "fsl,mpl3115"; + reg = <0x60>; + }; + }; + + mux1_i2c3: i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x2>; + }; + + mux1_i2c4: i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x3>; + + sgtl5000: codec@0a { + compatible = "fsl,sgtl5000"; + reg = <0x0a>; + clocks = <&mclk>; + VDDA-supply = <®_1p8v>; + VDDIO-supply = <®_3p3v>; + }; + }; + + mux1_i2c5: i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x4>; + + pca9539: pca9539@74 { + compatible = "nxp,pca9539"; + reg = <0x74>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + interrupt-parent = <&gpio2>; + interrupts = <3 IRQ_TYPE_LEVEL_LOW>; + }; + }; + + mux1_i2c6: i2c@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x5>; + }; + + mux1_i2c7: i2c@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x6>; + }; + + mux1_i2c8: i2c@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x7>; + }; + }; +}; + +&usdhc4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc4>; + bus-width = <4>; + vmmc-supply = <®_wl18xx_vmmc>; + no-1-8-v; + non-removable; + wakeup-source; + keep-power-in-suspend; + cap-power-off-card; + max-frequency = <25000000>; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + wlcore: wlcore@2 { + compatible = "ti,wl1837"; + reg = <2>; + interrupt-parent = <&gpio2>; + interrupts = <6 IRQ_TYPE_LEVEL_HIGH>; + tcxo-clock-frequency = <26000000>; + }; +}; diff --git a/arch/arm/boot/dts/imx6q-evi.dts b/arch/arm/boot/dts/imx6q-evi.dts new file mode 100644 index 0000000000000000000000000000000000000000..4fa56019225e63e2f7ff5e772151ed053b4c8db1 --- /dev/null +++ b/arch/arm/boot/dts/imx6q-evi.dts @@ -0,0 +1,502 @@ +/* + * Copyright 2016 United Western Technologies. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole + * + * a) This file 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 file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +/dts-v1/; +#include "imx6q.dtsi" +#include +#include + +/ { + model = "Uniwest Evi"; + compatible = "uniwest,imx6q-evi", "fsl,imx6q"; + + memory { + reg = <0x10000000 0x40000000>; + }; + + reg_usbh1_vbus: regulator-usbhubreset { + compatible = "regulator-fixed"; + regulator-name = "usbh1_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + startup-delay-us = <2>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbh1_hubreset>; + gpio = <&gpio7 12 GPIO_ACTIVE_HIGH>; + }; + + reg_usb_otg_vbus: regulator-usbotgvbus { + compatible = "regulator-fixed"; + regulator-name = "usb_otg_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbotgvbus>; + gpio = <&gpio4 15 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-always-on; + }; + + panel { + compatible = "sharp,lq101k1ly04"; + + port { + panel_in: endpoint { + remote-endpoint = <&lvds0_out>; + }; + }; + }; +}; + +&ecspi1 { + fsl,spi-num-chipselects = <1>; + cs-gpios = <&gpio4 10 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ecspi1 &pinctrl_ecspi1cs>; + status = "okay"; +}; + +&ecspi3 { + fsl,spi-num-chipselects = <3>; + cs-gpios = <&gpio4 24 GPIO_ACTIVE_LOW>, + <&gpio4 25 GPIO_ACTIVE_LOW>, + <&gpio4 26 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ecspi3 &pinctrl_ecspi3cs>; + status = "okay"; +}; + +&ecspi5 { + fsl,spi-num-chipselects = <4>; + cs-gpios = <&gpio1 14 GPIO_ACTIVE_LOW>, + <&gpio1 13 GPIO_ACTIVE_LOW>, + <&gpio1 12 GPIO_ACTIVE_LOW>, + <&gpio2 9 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ecspi5 &pinctrl_ecspi5cs>; + status = "okay"; + + eeprom: m95m02@1 { + compatible = "st,m95m02", "atmel,at25"; + size = <262144>; + pagesize = <256>; + address-width = <24>; + spi-max-frequency = <5000000>; + reg = <1>; + }; + + pb_rtc: rtc@3 { + compatible = "nxp,rtc-pcf2123"; + spi-max-frequency = <2450000>; + spi-cs-high; + reg = <3>; + }; +}; + +&fec { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enet>; + phy-mode = "rgmii"; + phy-reset-gpios = <&gpio1 25 0>; + status = "okay"; +}; + +&gpmi { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpminand>; + status = "okay"; +}; + +&i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + clock-frequency = <100000>; + status = "okay"; +}; + +&i2c3 { + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c3>; + pinctrl-1 = <&pinctrl_i2c3_gpio>; + clock-frequency = <100000>; + scl-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>; + sda-gpios = <&gpio7 11 GPIO_ACTIVE_HIGH>; + status = "okay"; + + battery: sbs-battery@b { + compatible = "sbs,sbs-battery"; + reg = <0x0b>; + sbs,poll-retry-count = <100>; + sbs,i2c-retry-count = <100>; + }; +}; + +&ldb { + status = "okay"; + + lvds0: lvds-channel@0 { + status = "okay"; + + port@4 { + reg = <4>; + lvds0_out: endpoint { + remote-endpoint = <&panel_in>; + }; + }; + }; +}; + +&ssi1 { + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; + status = "okay"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; + status = "okay"; +}; + +&usbh1 { + vbus-supply = <®_usbh1_vbus>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbh1>; + dr_mode = "host"; + disable-over-current; + status = "okay"; +}; + +&usbotg { + vbus-supply = <®_usb_otg_vbus>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbotg>; + disable-over-current; + dr_mode = "otg"; + status = "okay"; +}; + +&usdhc1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc1>; + non-removable; + status = "okay"; +}; + +&weim { + #address-cells = <2>; + #size-cells = <1>; + ranges = <0 0 0x08000000 0x08000000>; + fsl,weim-cs-gpr = <&gpr>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_weimfpga &pinctrl_weimcs>; + status = "okay"; +}; + +&iomuxc { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hog>; + + pinctrl_hog: hoggrp { + fsl,pins = < + /* pwr mcu alert irq */ + MX6QDL_PAD_SD4_DAT2__GPIO2_IO10 0x1b0b0 + /* remainder ???? */ + MX6QDL_PAD_CSI0_MCLK__GPIO5_IO19 0x1b0b0 + >; + }; + + pinctrl_ecspi1: ecspi1grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL1__ECSPI1_MISO 0x100b1 + MX6QDL_PAD_KEY_ROW0__ECSPI1_MOSI 0x100b1 + MX6QDL_PAD_KEY_COL0__ECSPI1_SCLK 0x100b1 + >; + }; + + pinctrl_ecspi1cs: ecspi1csgrp { + fsl,pins = < + MX6QDL_PAD_KEY_COL2__GPIO4_IO10 0x1b0b0 + >; + }; + + pinctrl_ecspi3: ecspi3grp { + fsl,pins = < + MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK 0x10068 + MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI 0x10068 + MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO 0x1f068 + >; + }; + + pinctrl_ecspi3cs: ecspi3csgrp { + fsl,pins = < + MX6QDL_PAD_DISP0_DAT3__GPIO4_IO24 0x1b0b0 + MX6QDL_PAD_DISP0_DAT4__GPIO4_IO25 0x1b0b0 + MX6QDL_PAD_DISP0_DAT5__GPIO4_IO26 0x1b0b0 + MX6QDL_PAD_DISP0_DAT6__GPIO4_IO27 0x1b0b0 + >; + }; + + pinctrl_ecspi5: ecspi5grp { + fsl,pins = < + MX6QDL_PAD_SD2_CLK__ECSPI5_SCLK 0x100b1 + MX6QDL_PAD_SD2_CMD__ECSPI5_MOSI 0x100b1 + MX6QDL_PAD_SD2_DAT0__ECSPI5_MISO 0x100b1 + >; + }; + + pinctrl_ecspi5cs: ecspi5csgrp { + fsl,pins = < + MX6QDL_PAD_SD2_DAT1__GPIO1_IO14 0x1b0b0 + MX6QDL_PAD_SD2_DAT2__GPIO1_IO13 0x1b0b0 + MX6QDL_PAD_SD2_DAT3__GPIO1_IO12 0x1b0b0 + MX6QDL_PAD_SD4_DAT1__GPIO2_IO09 0x1b0b0 + >; + }; + + pinctrl_enet: enetgrp { + fsl,pins = < + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0 + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0 + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0 + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0 + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0 + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0 + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0 + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0 + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0 + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0 + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0 + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0 + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0 + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0 + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0 + MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN 0x4001b0a8 + MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x1b0b0 + >; + }; + + pinctrl_gpminand: gpminandgrp { + fsl,pins = < + MX6QDL_PAD_NANDF_CLE__NAND_CLE 0xb0b1 + MX6QDL_PAD_NANDF_ALE__NAND_ALE 0xb0b1 + MX6QDL_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1 + MX6QDL_PAD_NANDF_RB0__NAND_READY_B 0xb000 + MX6QDL_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1 + MX6QDL_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1 + MX6QDL_PAD_SD4_CMD__NAND_RE_B 0xb0b1 + MX6QDL_PAD_SD4_CLK__NAND_WE_B 0xb0b1 + MX6QDL_PAD_NANDF_D0__NAND_DATA00 0xb0b1 + MX6QDL_PAD_NANDF_D1__NAND_DATA01 0xb0b1 + MX6QDL_PAD_NANDF_D2__NAND_DATA02 0xb0b1 + MX6QDL_PAD_NANDF_D3__NAND_DATA03 0xb0b1 + MX6QDL_PAD_NANDF_D4__NAND_DATA04 0xb0b1 + MX6QDL_PAD_NANDF_D5__NAND_DATA05 0xb0b1 + MX6QDL_PAD_NANDF_D6__NAND_DATA06 0xb0b1 + MX6QDL_PAD_NANDF_D7__NAND_DATA07 0xb0b1 + MX6QDL_PAD_SD4_DAT0__NAND_DQS 0x00b1 + >; + }; + + pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1 + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1 + >; + }; + + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX6QDL_PAD_GPIO_5__I2C3_SCL 0x4001b8b1 + MX6QDL_PAD_GPIO_16__I2C3_SDA 0x4001b8b1 + >; + }; + + pinctrl_i2c3_gpio: i2c3gpiogrp { + fsl,pins = < + MX6QDL_PAD_GPIO_5__GPIO1_IO05 0x4001b8b1 + MX6QDL_PAD_GPIO_16__GPIO7_IO11 0x4001b8b1 + >; + }; + + pinctrl_weimcs: weimcsgrp { + fsl,pins = < + MX6QDL_PAD_EIM_CS0__EIM_CS0_B 0xb0b1 + MX6QDL_PAD_EIM_CS1__EIM_CS1_B 0xb0b1 + >; + }; + + pinctrl_weimfpga: weimfpgagrp { + fsl,pins = < + /* weim misc */ + MX6QDL_PAD_EIM_OE__EIM_OE_B 0xb0b1 + MX6QDL_PAD_EIM_RW__EIM_RW 0xb0b1 + MX6QDL_PAD_EIM_WAIT__EIM_WAIT_B 0xb060 + MX6QDL_PAD_EIM_BCLK__EIM_BCLK 0xb0b1 + MX6QDL_PAD_EIM_LBA__EIM_LBA_B 0xb0b1 + MX6QDL_PAD_EIM_EB0__EIM_EB0_B 0xb0b1 + MX6QDL_PAD_EIM_EB1__EIM_EB1_B 0xb0b1 + MX6QDL_PAD_EIM_EB2__EIM_EB2_B 0xb0b1 + MX6QDL_PAD_EIM_EB3__EIM_EB3_B 0xb0b1 + /* weim data */ + MX6QDL_PAD_CSI0_DATA_EN__EIM_DATA00 0x1b0b0 + MX6QDL_PAD_CSI0_VSYNC__EIM_DATA01 0x1b0b0 + MX6QDL_PAD_CSI0_DAT4__EIM_DATA02 0x1b0b0 + MX6QDL_PAD_CSI0_DAT5__EIM_DATA03 0x1b0b0 + MX6QDL_PAD_CSI0_DAT6__EIM_DATA04 0x1b0b0 + MX6QDL_PAD_CSI0_DAT7__EIM_DATA05 0x1b0b0 + MX6QDL_PAD_CSI0_DAT8__EIM_DATA06 0x1b0b0 + MX6QDL_PAD_CSI0_DAT9__EIM_DATA07 0x1b0b0 + MX6QDL_PAD_CSI0_DAT12__EIM_DATA08 0x1b0b0 + MX6QDL_PAD_CSI0_DAT13__EIM_DATA09 0x1b0b0 + MX6QDL_PAD_CSI0_DAT14__EIM_DATA10 0x1b0b0 + MX6QDL_PAD_CSI0_DAT15__EIM_DATA11 0x1b0b0 + MX6QDL_PAD_CSI0_DAT16__EIM_DATA12 0x1b0b0 + MX6QDL_PAD_CSI0_DAT17__EIM_DATA13 0x1b0b0 + MX6QDL_PAD_CSI0_DAT18__EIM_DATA14 0x1b0b0 + MX6QDL_PAD_CSI0_DAT19__EIM_DATA15 0x1b0b0 + MX6QDL_PAD_EIM_D16__EIM_DATA16 0x1b0b0 + MX6QDL_PAD_EIM_D17__EIM_DATA17 0x1b0b0 + MX6QDL_PAD_EIM_D18__EIM_DATA18 0x1b0b0 + MX6QDL_PAD_EIM_D19__EIM_DATA19 0x1b0b0 + MX6QDL_PAD_EIM_D20__EIM_DATA20 0x1b0b0 + MX6QDL_PAD_EIM_D21__EIM_DATA21 0x1b0b0 + MX6QDL_PAD_EIM_D22__EIM_DATA22 0x1b0b0 + MX6QDL_PAD_EIM_D23__EIM_DATA23 0x1b0b0 + MX6QDL_PAD_EIM_D24__EIM_DATA24 0x1b0b0 + MX6QDL_PAD_EIM_D25__EIM_DATA25 0x1b0b0 + MX6QDL_PAD_EIM_D26__EIM_DATA26 0x1b0b0 + MX6QDL_PAD_EIM_D27__EIM_DATA27 0x1b0b0 + MX6QDL_PAD_EIM_D28__EIM_DATA28 0x1b0b0 + MX6QDL_PAD_EIM_D29__EIM_DATA29 0x1b0b0 + MX6QDL_PAD_EIM_D30__EIM_DATA30 0x1b0b0 + MX6QDL_PAD_EIM_D31__EIM_DATA31 0x1b0b0 + /* weim address */ + MX6QDL_PAD_EIM_A25__EIM_ADDR25 0xb0b1 + MX6QDL_PAD_EIM_A24__EIM_ADDR24 0xb0b1 + MX6QDL_PAD_EIM_A23__EIM_ADDR23 0xb0b1 + MX6QDL_PAD_EIM_A22__EIM_ADDR22 0xb0b1 + MX6QDL_PAD_EIM_A21__EIM_ADDR21 0xb0b1 + MX6QDL_PAD_EIM_A20__EIM_ADDR20 0xb0b1 + MX6QDL_PAD_EIM_A19__EIM_ADDR19 0xb0b1 + MX6QDL_PAD_EIM_A18__EIM_ADDR18 0xb0b1 + MX6QDL_PAD_EIM_A17__EIM_ADDR17 0xb0b1 + MX6QDL_PAD_EIM_A16__EIM_ADDR16 0xb0b1 + MX6QDL_PAD_EIM_DA15__EIM_AD15 0xb0b1 + MX6QDL_PAD_EIM_DA14__EIM_AD14 0xb0b1 + MX6QDL_PAD_EIM_DA13__EIM_AD13 0xb0b1 + MX6QDL_PAD_EIM_DA12__EIM_AD12 0xb0b1 + MX6QDL_PAD_EIM_DA11__EIM_AD11 0xb0b1 + MX6QDL_PAD_EIM_DA10__EIM_AD10 0xb0b1 + MX6QDL_PAD_EIM_DA9__EIM_AD09 0xb0b1 + MX6QDL_PAD_EIM_DA8__EIM_AD08 0xb0b1 + MX6QDL_PAD_EIM_DA7__EIM_AD07 0xb0b1 + MX6QDL_PAD_EIM_DA6__EIM_AD06 0xb0b1 + MX6QDL_PAD_EIM_DA5__EIM_AD05 0xb0b1 + MX6QDL_PAD_EIM_DA4__EIM_AD04 0xb0b1 + MX6QDL_PAD_EIM_DA3__EIM_AD03 0xb0b1 + MX6QDL_PAD_EIM_DA2__EIM_AD02 0xb0b1 + MX6QDL_PAD_EIM_DA1__EIM_AD01 0xb0b1 + MX6QDL_PAD_EIM_DA0__EIM_AD00 0xb0b1 + >; + }; + + pinctrl_uart1: uart1grp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1 + MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1 + >; + }; + + pinctrl_uart2: uart2grp { + fsl,pins = < + MX6QDL_PAD_SD3_DAT5__UART2_TX_DATA 0x1b0b1 + MX6QDL_PAD_SD3_DAT4__UART2_RX_DATA 0x1b0b1 + MX6QDL_PAD_SD3_CLK__UART2_RTS_B 0x1b0b1 + MX6QDL_PAD_SD3_CMD__UART2_CTS_B 0x1b0b1 + >; + }; + + pinctrl_usbh1: usbh1grp { + fsl,pins = < + MX6QDL_PAD_GPIO_3__USB_H1_OC 0x1b0b0 + /* usbh1_b OC */ + MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x1b0b0 + >; + }; + + pinctrl_usbh1_hubreset: usbh1hubresetgrp { + fsl,pins = < + MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x1b0b0 + >; + }; + + pinctrl_usbotg: usbotggrp { + fsl,pins = < + MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059 + MX6QDL_PAD_KEY_COL4__USB_OTG_OC 0x1b0b0 + >; + }; + + pinctrl_usbotgvbus: usbotgvbusgrp { + fsl,pins = < + MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x000b0 + >; + }; + + pinctrl_usdhc1: usdhc1grp { + fsl,pins = < + MX6QDL_PAD_SD1_CMD__SD1_CMD 0x17059 + MX6QDL_PAD_SD1_CLK__SD1_CLK 0x10059 + MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x17059 + MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17059 + MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17059 + MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17059 + >; + }; +}; diff --git a/arch/arm/boot/dts/imx6q-gk802.dts b/arch/arm/boot/dts/imx6q-gk802.dts index 00bd63e63d0cdd47f4ffa012f572f10323a2d14f..b715deb4ea4666e755ddece8ce198f38187fec15 100644 --- a/arch/arm/boot/dts/imx6q-gk802.dts +++ b/arch/arm/boot/dts/imx6q-gk802.dts @@ -44,7 +44,7 @@ label = "recovery"; gpios = <&gpio3 16 1>; linux,code = <0x198>; /* KEY_RESTART */ - gpio-key,wakeup; + wakeup-source; }; }; }; diff --git a/arch/arm/boot/dts/imx6q-icore-rqs.dts b/arch/arm/boot/dts/imx6q-icore-rqs.dts new file mode 100644 index 0000000000000000000000000000000000000000..005318865f66a9bbc2de38ab77426ef6037dd458 --- /dev/null +++ b/arch/arm/boot/dts/imx6q-icore-rqs.dts @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2015 Amarula Solutions B.V. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include "imx6q.dtsi" +#include "imx6qdl-icore-rqs.dtsi" + +/ { + model = "Engicam i.CoreM6 Quad SOM"; + compatible = "engicam,imx6-icore-rqs", "fsl,imx6q"; + + sound { + compatible = "fsl,imx-audio-sgtl5000"; + model = "imx-audio-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>; + }; +}; + +&i2c3 { + codec: sgtl5000@0a { + compatible = "fsl,sgtl5000"; + reg = <0x0a>; + clocks = <&clks IMX6QDL_CLK_CKO>; + VDDA-supply = <®_2p5v>; + VDDIO-supply = <®_3p3v>; + VDDD-supply = <®_1p8v>; + }; +}; + +&sata { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/imx6q-tbs2910.dts b/arch/arm/boot/dts/imx6q-tbs2910.dts index 5645d52850a7eca0f1905f7341935ae82ce99859..0da81bc2c68a4cecb7f305a9dcbd2bfe6e8c59db 100644 --- a/arch/arm/boot/dts/imx6q-tbs2910.dts +++ b/arch/arm/boot/dts/imx6q-tbs2910.dts @@ -91,34 +91,25 @@ }; }; - regulators { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <0>; - - reg_2p5v: regulator@0 { - compatible = "regulator-fixed"; - reg = <0>; - regulator-name = "2P5V"; - regulator-min-microvolt = <2500000>; - regulator-max-microvolt = <2500000>; - }; + reg_2p5v: regulator-2p5v { + compatible = "regulator-fixed"; + regulator-name = "2P5V"; + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; + }; - reg_3p3v: regulator@1 { - compatible = "regulator-fixed"; - reg = <1>; - regulator-name = "3P3V"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - }; + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "3P3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; - reg_5p0v: regulator@2 { - compatible = "regulator-fixed"; - reg = <2>; - regulator-name = "5P0V"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - }; + reg_5p0v: regulator-5p0v { + compatible = "regulator-fixed"; + regulator-name = "5P0V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; }; sound-sgtl5000 { @@ -205,6 +196,10 @@ }; &sata { + fsl,transmit-level-mV = <1104>; + fsl,transmit-boost-mdB = <3330>; + fsl,transmit-atten-16ths = <16>; + fsl,receive-eq-mdB = <3000>; status = "okay"; }; @@ -253,6 +248,9 @@ bus-width = <4>; cd-gpios = <&gpio2 2 GPIO_ACTIVE_LOW>; vmmc-supply = <®_3p3v>; + vqmmc-supply = <®_3p3v>; + voltage-ranges = <3300 3300>; + no-1-8-v; status = "okay"; }; @@ -263,6 +261,9 @@ cd-gpios = <&gpio2 0 GPIO_ACTIVE_LOW>; wp-gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>; vmmc-supply = <®_3p3v>; + vqmmc-supply = <®_3p3v>; + voltage-ranges = <3300 3300>; + no-1-8-v; status = "okay"; }; @@ -270,163 +271,160 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usdhc4>; bus-width = <8>; + vmmc-supply = <®_3p3v>; + vqmmc-supply = <®_3p3v>; + voltage-ranges = <3300 3300>; non-removable; no-1-8-v; status = "okay"; }; &iomuxc { - imx6q-tbs2910 { - pinctrl_enet: enetgrp { - fsl,pins = < - MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0 - MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0 - MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0 - MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0 - MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0 - MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0 - MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0 - MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0 - MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0 - MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0 - MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0 - MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0 - MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0 - MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0 - MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0 - MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8 - MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x1b059 - >; - }; + pinctrl_enet: enetgrp { + fsl,pins = < + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0 + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0 + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0 + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0 + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0 + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0 + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0 + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0 + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0 + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0 + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0 + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0 + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0 + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0 + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0 + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8 + MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x1b059 + >; + }; - pinctrl_hdmi: hdmigrp { - fsl,pins = < - MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x1f8b0 - >; - }; + pinctrl_gpio_fan: gpiofangrp { + fsl,pins = < + MX6QDL_PAD_EIM_D28__GPIO3_IO28 0x130b1 + >; + }; - pinctrl_i2c1: i2c1grp { - fsl,pins = < - MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x4001b8b1 - MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b8b1 - >; - }; + pinctrl_gpio_leds: gpioledsgrp { + fsl,pins = < + MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x130b1 + >; + }; - pinctrl_i2c2: i2c2grp { - fsl,pins = < - MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1 - MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1 - >; - }; + pinctrl_hdmi: hdmigrp { + fsl,pins = < + MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x1f8b0 + >; + }; - pinctrl_i2c3: i2c3grp { - fsl,pins = < - MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1 - MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1 - >; - }; + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x4001b8b1 + MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b8b1 + >; + }; - pinctrl_ir: irgrp { - fsl,pins = < - MX6QDL_PAD_EIM_D18__GPIO3_IO18 0x17059 - >; - }; + pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1 + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1 + >; + }; - pinctrl_pcie: pciegrp { - fsl,pins = < - MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x17059 - >; - }; + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1 + MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1 + >; + }; - pinctrl_sgtl5000: sgtl5000grp { - fsl,pins = < - MX6QDL_PAD_CSI0_DAT7__AUD3_RXD 0x130b0 - MX6QDL_PAD_CSI0_DAT4__AUD3_TXC 0x130b0 - MX6QDL_PAD_CSI0_DAT5__AUD3_TXD 0x110b0 - MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x130b0 - MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x130b0 - >; - }; + pinctrl_ir: irgrp { + fsl,pins = < + MX6QDL_PAD_EIM_D18__GPIO3_IO18 0x17059 + >; + }; - pinctrl_spdif: spdifgrp { - fsl,pins = ; - }; + pinctrl_pcie: pciegrp { + fsl,pins = < + MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x17059 + >; + }; - pinctrl_uart1: uart1grp { - fsl,pins = < - MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1 - MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1 - >; - }; + pinctrl_sgtl5000: sgtl5000grp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT7__AUD3_RXD 0x130b0 + MX6QDL_PAD_CSI0_DAT4__AUD3_TXC 0x130b0 + MX6QDL_PAD_CSI0_DAT5__AUD3_TXD 0x110b0 + MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS 0x130b0 + MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x130b0 + >; + }; - pinctrl_uart2: uart2grp { - fsl,pins = < - MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1 - MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1 - >; - }; + pinctrl_spdif: spdifgrp { + fsl,pins = ; + }; - pinctrl_usbotg: usbotggrp { - fsl,pins = < - MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x17059 - >; - }; + pinctrl_uart1: uart1grp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1 + MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1 + >; + }; - pinctrl_usdhc2: usdhc2grp { - fsl,pins = < - MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059 - MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059 - MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059 - MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059 - MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059 - MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059 - MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x17059 - >; - }; + pinctrl_uart2: uart2grp { + fsl,pins = < + MX6QDL_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1 + MX6QDL_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1 + >; + }; - pinctrl_usdhc3: usdhc3grp { - fsl,pins = < - MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059 - MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059 - MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059 - MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059 - MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059 - MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059 - MX6QDL_PAD_NANDF_D0__GPIO2_IO00 0x17059 - MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x17059 - >; - }; + pinctrl_usbotg: usbotggrp { + fsl,pins = < + MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x17059 + >; + }; - pinctrl_usdhc4: usdhc4grp { - fsl,pins = < - MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059 - MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059 - MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059 - MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059 - MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059 - MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059 - MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059 - MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059 - MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059 - MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059 - >; - }; + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059 + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059 + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059 + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059 + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059 + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059 + MX6QDL_PAD_NANDF_D2__GPIO2_IO02 0x17059 + >; }; - gpio_fan { - pinctrl_gpio_fan: gpiofangrp { - fsl,pins = < - MX6QDL_PAD_EIM_D28__GPIO3_IO28 0x130b1 - >; - }; + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059 + MX6QDL_PAD_NANDF_D0__GPIO2_IO00 0x17059 + MX6QDL_PAD_NANDF_D1__GPIO2_IO01 0x17059 + >; }; - gpio_leds { - pinctrl_gpio_leds: gpioledsgrp { - fsl,pins = < - MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x130b1 - >; - }; + pinctrl_usdhc4: usdhc4grp { + fsl,pins = < + MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059 + MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059 + MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059 + MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059 + MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059 + MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059 + MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059 + MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059 + MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059 + MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059 + >; }; }; diff --git a/arch/arm/boot/dts/imx6q-tx6q-1110.dts b/arch/arm/boot/dts/imx6q-tx6q-1110.dts index 88aa1e4c792d2c2c5d56d8a819cac4640bb46369..2792da93db1fc7f86d869ac3259f3b19d4e14156 100644 --- a/arch/arm/boot/dts/imx6q-tx6q-1110.dts +++ b/arch/arm/boot/dts/imx6q-tx6q-1110.dts @@ -77,7 +77,7 @@ interrupt-parent = <&gpio3>; interrupts = <22 0>; wakeup-gpios = <&gpio3 22 GPIO_ACTIVE_HIGH>; - linux,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/imx6q-wandboard-revb1.dts b/arch/arm/boot/dts/imx6q-wandboard-revb1.dts index 20bf3c28262308ba919bf9d63c995d88f45c4ae0..9207d80f9cfb642b1ad1ac258cefb38d1c9f4683 100644 --- a/arch/arm/boot/dts/imx6q-wandboard-revb1.dts +++ b/arch/arm/boot/dts/imx6q-wandboard-revb1.dts @@ -13,7 +13,7 @@ #include "imx6qdl-wandboard-revb1.dtsi" / { - model = "Wandboard i.MX6 Quad Board"; + model = "Wandboard i.MX6 Quad Board rev B1"; compatible = "wand,imx6q-wandboard", "fsl,imx6q"; memory { diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi index 0d93c0e8f9baf24ab661c304bc12b40e757378a3..cd10c8de19048fd0e2217ddce1a286248f8010e9 100644 --- a/arch/arm/boot/dts/imx6q.dtsi +++ b/arch/arm/boot/dts/imx6q.dtsi @@ -22,7 +22,7 @@ #address-cells = <1>; #size-cells = <0>; - cpu@0 { + cpu0: cpu@0 { compatible = "arm,cortex-a9"; device_type = "cpu"; reg = <0>; @@ -162,6 +162,7 @@ }; ipu2_di0_mipi: endpoint@2 { + remote-endpoint = <&mipi_mux_2>; }; ipu2_di0_lvds0: endpoint@3 { @@ -183,6 +184,7 @@ }; ipu2_di1_mipi: endpoint@2 { + remote-endpoint = <&mipi_mux_3>; }; ipu2_di1_lvds0: endpoint@3 { diff --git a/arch/arm/boot/dts/imx6qdl-apalis.dtsi b/arch/arm/boot/dts/imx6qdl-apalis.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..b33e5a95a0f0bfaddcf432a59011327cd12f1906 --- /dev/null +++ b/arch/arm/boot/dts/imx6qdl-apalis.dtsi @@ -0,0 +1,984 @@ +/* + * Copyright 2014-2016 Toradex AG + * Copyright 2012 Freescale Semiconductor, Inc. + * Copyright 2011 Linaro Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include + +/ { + model = "Toradex Apalis iMX6Q/D Module"; + compatible = "toradex,apalis_imx6q", "fsl,imx6q"; + + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&pwm4 0 5000000>; + status = "disabled"; + }; + + /* DDC_I2C: I2C2_SDA/SCL on MXM3 205/207 */ + i2cddc: i2c@0 { + compatible = "i2c-gpio"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c_ddc>; + gpios = <&gpio3 16 GPIO_ACTIVE_HIGH /* sda */ + &gpio2 30 GPIO_ACTIVE_HIGH /* scl */ + >; + i2c-gpio,delay-us = <2>; /* ~100 kHz */ + status = "disabled"; + }; + + reg_1p8v: regulator-1p8v { + compatible = "regulator-fixed"; + regulator-name = "1P8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + reg_2p5v: regulator-2p5v { + compatible = "regulator-fixed"; + regulator-name = "2P5V"; + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; + regulator-always-on; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "3P3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + reg_usb_otg_vbus: regulator-usb-otg-vbus { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_regulator_usbotg_pwr>; + regulator-name = "usb_otg_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio3 22 GPIO_ACTIVE_HIGH>; + enable-active-high; + status = "disabled"; + }; + + /* on module USB hub */ + reg_usb_host_vbus_hub: regulator-usb-host-vbus-hub { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_regulator_usbhub_pwr>; + regulator-name = "usb_host_vbus_hub"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio3 28 GPIO_ACTIVE_HIGH>; + startup-delay-us = <2000>; + enable-active-high; + status = "okay"; + }; + + reg_usb_host_vbus: regulator-usb-host-vbus { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_regulator_usbh_pwr>; + regulator-name = "usb_host_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio1 0 GPIO_ACTIVE_HIGH>; + enable-active-high; + vin-supply = <®_usb_host_vbus_hub>; + status = "disabled"; + }; + + sound { + compatible = "fsl,imx-audio-sgtl5000"; + model = "imx6q-apalis-sgtl5000"; + ssi-controller = <&ssi1>; + audio-codec = <&codec>; + audio-routing = + "LINE_IN", "Line In Jack", + "MIC_IN", "Mic Jack", + "Mic Jack", "Mic Bias", + "Headphone Jack", "HP_OUT"; + mux-int-port = <1>; + mux-ext-port = <4>; + }; + + sound_spdif: sound-spdif { + compatible = "fsl,imx-audio-spdif"; + model = "imx-spdif"; + spdif-controller = <&spdif>; + spdif-in; + spdif-out; + status = "disabled"; + }; +}; + +&audmux { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_audmux>; + status = "okay"; +}; + +&can1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan1>; + status = "disabled"; +}; + +&can2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan2>; + status = "disabled"; +}; + +/* Apalis SPI1 */ +&ecspi1 { + fsl,spi-num-chipselects = <1>; + cs-gpios = <&gpio5 25 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ecspi1>; + status = "disabled"; +}; + +/* Apalis SPI2 */ +&ecspi2 { + fsl,spi-num-chipselects = <1>; + cs-gpios = <&gpio2 26 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ecspi2>; + status = "disabled"; +}; + +&fec { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enet>; + phy-mode = "rgmii"; + phy-handle = <ðphy>; + phy-reset-duration = <10>; + phy-reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + ethphy: ethernet-phy@7 { + interrupt-parent = <&gpio1>; + interrupts = <30 IRQ_TYPE_LEVEL_LOW>; + reg = <7>; + }; + }; +}; + +/* + * GEN1_I2C: I2C1_SDA/SCL on MXM3 209/211 (e.g. RTC on carrier + * board) + */ +&i2c1 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + status = "disabled"; +}; + +/* + * PWR_I2C: power I2C to audio codec, PMIC, temperature sensor and + * touch screen controller + */ +&i2c2 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + status = "okay"; + + pmic: pfuze100@08 { + compatible = "fsl,pfuze100"; + reg = <0x08>; + + regulators { + sw1a_reg: sw1ab { + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1875000>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <6250>; + }; + + sw1c_reg: sw1c { + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1875000>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <6250>; + }; + + sw3a_reg: sw3a { + regulator-min-microvolt = <400000>; + regulator-max-microvolt = <1975000>; + regulator-boot-on; + regulator-always-on; + }; + + swbst_reg: swbst { + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5150000>; + regulator-boot-on; + regulator-always-on; + }; + + snvs_reg: vsnvs { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <3000000>; + regulator-boot-on; + regulator-always-on; + }; + + vref_reg: vrefddr { + regulator-boot-on; + regulator-always-on; + }; + + vgen1_reg: vgen1 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1550000>; + regulator-boot-on; + regulator-always-on; + }; + + vgen2_reg: vgen2 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1550000>; + regulator-boot-on; + regulator-always-on; + }; + + vgen3_reg: vgen3 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + vgen4_reg: vgen4 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + vgen5_reg: vgen5 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + vgen6_reg: vgen6 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + }; + }; + + codec: sgtl5000@0a { + compatible = "fsl,sgtl5000"; + reg = <0x0a>; + clocks = <&clks 201>; + VDDA-supply = <®_2p5v>; + VDDIO-supply = <®_3p3v>; + }; + + /* STMPE811 touch screen controller */ + stmpe811@41 { + compatible = "st,stmpe811"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_touch_int>; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x41>; + interrupts = <10 IRQ_TYPE_LEVEL_LOW>; + interrupt-parent = <&gpio4>; + interrupt-controller; + id = <0>; + blocks = <0x5>; + irq-trigger = <0x1>; + + stmpe_touchscreen { + compatible = "st,stmpe-ts"; + reg = <0>; + /* 3.25 MHz ADC clock speed */ + st,adc-freq = <1>; + /* 8 sample average control */ + st,ave-ctrl = <3>; + /* 7 length fractional part in z */ + st,fraction-z = <7>; + /* + * 50 mA typical 80 mA max touchscreen drivers + * current limit value + */ + st,i-drive = <1>; + /* 12-bit ADC */ + st,mod-12b = <1>; + /* internal ADC reference */ + st,ref-sel = <0>; + /* ADC converstion time: 80 clocks */ + st,sample-time = <4>; + /* 1 ms panel driver settling time */ + st,settling = <3>; + /* 5 ms touch detect interrupt delay */ + st,touch-det-delay = <5>; + }; + }; +}; + +/* + * GEN2_I2C, CAM: I2C3_SDA/SCL on MXM3 201/203 (unused) + */ +&i2c3 { + clock-frequency = <100000>; + pinctrl-names = "default", "recovery"; + pinctrl-0 = <&pinctrl_i2c3>; + pinctrl-1 = <&pinctrl_i2c3_recovery>; + scl-gpios = <&gpio3 17 GPIO_ACTIVE_HIGH>; + sda-gpios = <&gpio3 18 GPIO_ACTIVE_HIGH>; + status = "disabled"; +}; + +&pwm1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm1>; + status = "disabled"; +}; + +&pwm2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm2>; + status = "disabled"; +}; + +&pwm3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm3>; + status = "disabled"; +}; + +&pwm4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm4>; + status = "disabled"; +}; + +&spdif { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spdif>; + status = "disabled"; +}; + +&ssi1 { + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1_dte &pinctrl_uart1_ctrl>; + fsl,dte-mode; + fsl,uart-has-rtscts; + status = "disabled"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2_dte>; + fsl,dte-mode; + fsl,uart-has-rtscts; + status = "disabled"; +}; + +&uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart4_dte>; + fsl,dte-mode; + status = "disabled"; +}; + +&uart5 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart5_dte>; + fsl,dte-mode; + status = "disabled"; +}; + +&usbotg { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbotg>; + disable-over-current; + status = "disabled"; +}; + +/* MMC1 */ +&usdhc1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc1>; + vqmmc-supply = <®_3p3v>; + bus-width = <8>; + voltage-ranges = <3300 3300>; + status = "disabled"; +}; + +/* SD1 */ +&usdhc2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc2>; + vqmmc-supply = <®_3p3v>; + bus-width = <4>; + voltage-ranges = <3300 3300>; + status = "disabled"; +}; + +/* eMMC */ +&usdhc3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc3>; + vqmmc-supply = <®_3p3v>; + bus-width = <8>; + voltage-ranges = <3300 3300>; + non-removable; + status = "okay"; +}; + +&weim { + status = "disabled"; +}; + +&iomuxc { + /* pins used on module */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_reset_moci>; + + pinctrl_apalis_gpio1: gpio2io04grp { + fsl,pins = < + MX6QDL_PAD_NANDF_D4__GPIO2_IO04 0x130b0 + >; + }; + + pinctrl_apalis_gpio2: gpio2io05grp { + fsl,pins = < + MX6QDL_PAD_NANDF_D5__GPIO2_IO05 0x130b0 + >; + }; + + pinctrl_apalis_gpio3: gpio2io06grp { + fsl,pins = < + MX6QDL_PAD_NANDF_D6__GPIO2_IO06 0x130b0 + >; + }; + + pinctrl_apalis_gpio4: gpio2io07grp { + fsl,pins = < + MX6QDL_PAD_NANDF_D7__GPIO2_IO07 0x130b0 + >; + }; + + pinctrl_apalis_gpio5: gpio6io10grp { + fsl,pins = < + MX6QDL_PAD_NANDF_RB0__GPIO6_IO10 0x130b0 + >; + }; + + pinctrl_apalis_gpio6: gpio6io09grp { + fsl,pins = < + MX6QDL_PAD_NANDF_WP_B__GPIO6_IO09 0x130b0 + >; + }; + + pinctrl_apalis_gpio7: gpio1io02grp { + fsl,pins = < + MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x130b0 + >; + }; + + pinctrl_apalis_gpio8: gpio1io06grp { + fsl,pins = < + MX6QDL_PAD_GPIO_6__GPIO1_IO06 0x130b0 + >; + }; + + pinctrl_audmux: audmuxgrp { + fsl,pins = < + MX6QDL_PAD_DISP0_DAT20__AUD4_TXC 0x130b0 + MX6QDL_PAD_DISP0_DAT21__AUD4_TXD 0x130b0 + MX6QDL_PAD_DISP0_DAT22__AUD4_TXFS 0x130b0 + MX6QDL_PAD_DISP0_DAT23__AUD4_RXD 0x130b0 + /* SGTL5000 sys_mclk */ + MX6QDL_PAD_GPIO_5__CCM_CLKO1 0x130b0 + >; + }; + + pinctrl_cam_mclk: cammclkgrp { + fsl,pins = < + /* CAM sys_mclk */ + MX6QDL_PAD_NANDF_CS2__CCM_CLKO2 0x00b0 + >; + }; + + pinctrl_ecspi1: ecspi1grp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT6__ECSPI1_MISO 0x100b1 + MX6QDL_PAD_CSI0_DAT5__ECSPI1_MOSI 0x100b1 + MX6QDL_PAD_CSI0_DAT4__ECSPI1_SCLK 0x100b1 + /* SPI1 cs */ + MX6QDL_PAD_CSI0_DAT7__GPIO5_IO25 0x000b1 + >; + }; + + pinctrl_ecspi2: ecspi2grp { + fsl,pins = < + MX6QDL_PAD_EIM_OE__ECSPI2_MISO 0x100b1 + MX6QDL_PAD_EIM_CS1__ECSPI2_MOSI 0x100b1 + MX6QDL_PAD_EIM_CS0__ECSPI2_SCLK 0x100b1 + /* SPI2 cs */ + MX6QDL_PAD_EIM_RW__GPIO2_IO26 0x000b1 + >; + }; + + pinctrl_enet: enetgrp { + fsl,pins = < + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x100b0 + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x100b0 + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x100b0 + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x100b0 + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x100b0 + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x100b0 + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x100b0 + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x100b0 + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x100b0 + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0 + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0 + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0 + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0 + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0 + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0 + /* Ethernet PHY reset */ + MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25 0x000b0 + /* Ethernet PHY interrupt */ + MX6QDL_PAD_ENET_TXD0__GPIO1_IO30 0x000b1 + >; + }; + + pinctrl_flexcan1: flexcan1grp { + fsl,pins = < + MX6QDL_PAD_GPIO_7__FLEXCAN1_TX 0x1b0b0 + MX6QDL_PAD_GPIO_8__FLEXCAN1_RX 0x1b0b0 + >; + }; + + pinctrl_flexcan2: flexcan2grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL4__FLEXCAN2_TX 0x1b0b0 + MX6QDL_PAD_KEY_ROW4__FLEXCAN2_RX 0x1b0b0 + >; + }; + + pinctrl_gpio_keys: gpio1io04grp { + fsl,pins = < + /* Power button */ + MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x1b0b0 + >; + }; + + pinctrl_hdmi_cec: hdmicecgrp { + fsl,pins = < + MX6QDL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x1f8b0 + >; + }; + + pinctrl_i2c_ddc: gpioi2cddcgrp { + fsl,pins = < + /* DDC bitbang */ + MX6QDL_PAD_EIM_EB2__GPIO2_IO30 0x1b0b0 + MX6QDL_PAD_EIM_D16__GPIO3_IO16 0x1b0b0 + >; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b8b1 + MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x4001b8b1 + >; + }; + + pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1 + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1 + >; + }; + + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX6QDL_PAD_EIM_D17__I2C3_SCL 0x4001b8b1 + MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1 + >; + }; + + pinctrl_i2c3_recovery: i2c3recoverygrp { + fsl,pins = < + MX6QDL_PAD_EIM_D17__GPIO3_IO17 0x4001b8b1 + MX6QDL_PAD_EIM_D18__GPIO3_IO18 0x4001b8b1 + >; + }; + + pinctrl_ipu1_csi0: ipu1csi0grp { /* parallel camera */ + fsl,pins = < + MX6QDL_PAD_CSI0_DAT12__IPU1_CSI0_DATA12 0xb0b1 + MX6QDL_PAD_CSI0_DAT13__IPU1_CSI0_DATA13 0xb0b1 + MX6QDL_PAD_CSI0_DAT14__IPU1_CSI0_DATA14 0xb0b1 + MX6QDL_PAD_CSI0_DAT15__IPU1_CSI0_DATA15 0xb0b1 + MX6QDL_PAD_CSI0_DAT16__IPU1_CSI0_DATA16 0xb0b1 + MX6QDL_PAD_CSI0_DAT17__IPU1_CSI0_DATA17 0xb0b1 + MX6QDL_PAD_CSI0_DAT18__IPU1_CSI0_DATA18 0xb0b1 + MX6QDL_PAD_CSI0_DAT19__IPU1_CSI0_DATA19 0xb0b1 + MX6QDL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK 0xb0b1 + MX6QDL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC 0xb0b1 + MX6QDL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC 0xb0b1 + >; + }; + + pinctrl_ipu1_lcdif: ipu1lcdifgrp { + fsl,pins = < + MX6QDL_PAD_EIM_A16__IPU1_DI1_DISP_CLK 0x61 + /* DE */ + MX6QDL_PAD_EIM_DA10__IPU1_DI1_PIN15 0x61 + /* HSync */ + MX6QDL_PAD_EIM_DA11__IPU1_DI1_PIN02 0x61 + /* VSync */ + MX6QDL_PAD_EIM_DA12__IPU1_DI1_PIN03 0x61 + MX6QDL_PAD_EIM_DA9__IPU1_DISP1_DATA00 0x61 + MX6QDL_PAD_EIM_DA8__IPU1_DISP1_DATA01 0x61 + MX6QDL_PAD_EIM_DA7__IPU1_DISP1_DATA02 0x61 + MX6QDL_PAD_EIM_DA6__IPU1_DISP1_DATA03 0x61 + MX6QDL_PAD_EIM_DA5__IPU1_DISP1_DATA04 0x61 + MX6QDL_PAD_EIM_DA4__IPU1_DISP1_DATA05 0x61 + MX6QDL_PAD_EIM_DA3__IPU1_DISP1_DATA06 0x61 + MX6QDL_PAD_EIM_DA2__IPU1_DISP1_DATA07 0x61 + MX6QDL_PAD_EIM_DA1__IPU1_DISP1_DATA08 0x61 + MX6QDL_PAD_EIM_DA0__IPU1_DISP1_DATA09 0x61 + MX6QDL_PAD_EIM_EB1__IPU1_DISP1_DATA10 0x61 + MX6QDL_PAD_EIM_EB0__IPU1_DISP1_DATA11 0x61 + MX6QDL_PAD_EIM_A17__IPU1_DISP1_DATA12 0x61 + MX6QDL_PAD_EIM_A18__IPU1_DISP1_DATA13 0x61 + MX6QDL_PAD_EIM_A19__IPU1_DISP1_DATA14 0x61 + MX6QDL_PAD_EIM_A20__IPU1_DISP1_DATA15 0x61 + MX6QDL_PAD_EIM_A21__IPU1_DISP1_DATA16 0x61 + MX6QDL_PAD_EIM_A22__IPU1_DISP1_DATA17 0x61 + MX6QDL_PAD_EIM_A23__IPU1_DISP1_DATA18 0x61 + MX6QDL_PAD_EIM_A24__IPU1_DISP1_DATA19 0x61 + MX6QDL_PAD_EIM_D31__IPU1_DISP1_DATA20 0x61 + MX6QDL_PAD_EIM_D30__IPU1_DISP1_DATA21 0x61 + MX6QDL_PAD_EIM_D26__IPU1_DISP1_DATA22 0x61 + MX6QDL_PAD_EIM_D27__IPU1_DISP1_DATA23 0x61 + >; + }; + + pinctrl_ipu2_vdac: ipu2vdacgrp { + fsl,pins = < + MX6QDL_PAD_DI0_DISP_CLK__IPU2_DI0_DISP_CLK 0xd1 + MX6QDL_PAD_DI0_PIN15__IPU2_DI0_PIN15 0xd1 + MX6QDL_PAD_DI0_PIN2__IPU2_DI0_PIN02 0xd1 + MX6QDL_PAD_DI0_PIN3__IPU2_DI0_PIN03 0xd1 + MX6QDL_PAD_DISP0_DAT0__IPU2_DISP0_DATA00 0xf9 + MX6QDL_PAD_DISP0_DAT1__IPU2_DISP0_DATA01 0xf9 + MX6QDL_PAD_DISP0_DAT2__IPU2_DISP0_DATA02 0xf9 + MX6QDL_PAD_DISP0_DAT3__IPU2_DISP0_DATA03 0xf9 + MX6QDL_PAD_DISP0_DAT4__IPU2_DISP0_DATA04 0xf9 + MX6QDL_PAD_DISP0_DAT5__IPU2_DISP0_DATA05 0xf9 + MX6QDL_PAD_DISP0_DAT6__IPU2_DISP0_DATA06 0xf9 + MX6QDL_PAD_DISP0_DAT7__IPU2_DISP0_DATA07 0xf9 + MX6QDL_PAD_DISP0_DAT8__IPU2_DISP0_DATA08 0xf9 + MX6QDL_PAD_DISP0_DAT9__IPU2_DISP0_DATA09 0xf9 + MX6QDL_PAD_DISP0_DAT10__IPU2_DISP0_DATA10 0xf9 + MX6QDL_PAD_DISP0_DAT11__IPU2_DISP0_DATA11 0xf9 + MX6QDL_PAD_DISP0_DAT12__IPU2_DISP0_DATA12 0xf9 + MX6QDL_PAD_DISP0_DAT13__IPU2_DISP0_DATA13 0xf9 + MX6QDL_PAD_DISP0_DAT14__IPU2_DISP0_DATA14 0xf9 + MX6QDL_PAD_DISP0_DAT15__IPU2_DISP0_DATA15 0xf9 + >; + }; + + pinctrl_mmc_cd: gpiommccdgrp { + fsl,pins = < + /* MMC1 CD */ + MX6QDL_PAD_DI0_PIN4__GPIO4_IO20 0x000b0 + >; + }; + + pinctrl_pwm1: pwm1grp { + fsl,pins = < + MX6QDL_PAD_GPIO_9__PWM1_OUT 0x1b0b1 + >; + }; + + pinctrl_pwm2: pwm2grp { + fsl,pins = < + MX6QDL_PAD_GPIO_1__PWM2_OUT 0x1b0b1 + >; + }; + + pinctrl_pwm3: pwm3grp { + fsl,pins = < + MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1 + >; + }; + + pinctrl_pwm4: pwm4grp { + fsl,pins = < + MX6QDL_PAD_SD4_DAT2__PWM4_OUT 0x1b0b1 + >; + }; + + pinctrl_regulator_usbh_pwr: gpioregusbhpwrgrp { + fsl,pins = < + /* USBH_EN */ + MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x0f058 + >; + }; + + pinctrl_regulator_usbhub_pwr: gpioregusbhubpwrgrp { + fsl,pins = < + /* USBH_HUB_EN */ + MX6QDL_PAD_EIM_D28__GPIO3_IO28 0x0f058 + >; + }; + + pinctrl_regulator_usbotg_pwr: gpioregusbotgpwrgrp { + fsl,pins = < + /* USBO1 power en */ + MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x0f058 + >; + }; + + pinctrl_reset_moci: gpioresetmocigrp { + fsl,pins = < + /* RESET_MOCI control */ + MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28 0x0f058 + >; + }; + + pinctrl_sd_cd: gpiosdcdgrp { + fsl,pins = < + /* SD1 CD */ + MX6QDL_PAD_NANDF_CS1__GPIO6_IO14 0x000b0 + >; + }; + + pinctrl_spdif: spdifgrp { + fsl,pins = < + MX6QDL_PAD_GPIO_16__SPDIF_IN 0x1b0b0 + MX6QDL_PAD_GPIO_17__SPDIF_OUT 0x1b0b0 + >; + }; + + pinctrl_touch_int: gpiotouchintgrp { + fsl,pins = < + /* STMPE811 interrupt */ + MX6QDL_PAD_KEY_COL2__GPIO4_IO10 0x1b0b0 + >; + }; + + pinctrl_uart1_dce: uart1dcegrp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1 + MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1 + >; + }; + + /* DTE mode */ + pinctrl_uart1_dte: uart1dtegrp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT10__UART1_RX_DATA 0x1b0b1 + MX6QDL_PAD_CSI0_DAT11__UART1_TX_DATA 0x1b0b1 + MX6QDL_PAD_EIM_D19__UART1_RTS_B 0x1b0b1 + MX6QDL_PAD_EIM_D20__UART1_CTS_B 0x1b0b1 + >; + }; + + /* Additional DTR, DSR, DCD */ + pinctrl_uart1_ctrl: uart1ctrlgrp { + fsl,pins = < + MX6QDL_PAD_EIM_D23__UART1_DCD_B 0x1b0b0 + MX6QDL_PAD_EIM_D24__UART1_DTR_B 0x1b0b0 + MX6QDL_PAD_EIM_D25__UART1_DSR_B 0x1b0b0 + >; + }; + + pinctrl_uart2_dce: uart2dcegrp { + fsl,pins = < + MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA 0x1b0b1 + MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA 0x1b0b1 + >; + }; + + /* DTE mode */ + pinctrl_uart2_dte: uart2dtegrp { + fsl,pins = < + MX6QDL_PAD_SD4_DAT4__UART2_TX_DATA 0x1b0b1 + MX6QDL_PAD_SD4_DAT7__UART2_RX_DATA 0x1b0b1 + MX6QDL_PAD_SD4_DAT6__UART2_RTS_B 0x1b0b1 + MX6QDL_PAD_SD4_DAT5__UART2_CTS_B 0x1b0b1 + >; + }; + + pinctrl_uart4_dce: uart4dcegrp { + fsl,pins = < + MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1 + MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1 + >; + }; + + /* DTE mode */ + pinctrl_uart4_dte: uart4dtegrp { + fsl,pins = < + MX6QDL_PAD_KEY_COL0__UART4_RX_DATA 0x1b0b1 + MX6QDL_PAD_KEY_ROW0__UART4_TX_DATA 0x1b0b1 + >; + }; + + pinctrl_uart5_dce: uart5dcegrp { + fsl,pins = < + MX6QDL_PAD_KEY_COL1__UART5_TX_DATA 0x1b0b1 + MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA 0x1b0b1 + >; + }; + + /* DTE mode */ + pinctrl_uart5_dte: uart5dtegrp { + fsl,pins = < + MX6QDL_PAD_KEY_COL1__UART5_RX_DATA 0x1b0b1 + MX6QDL_PAD_KEY_ROW1__UART5_TX_DATA 0x1b0b1 + >; + }; + + pinctrl_usbotg: usbotggrp { + fsl,pins = < + MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x17059 + >; + }; + + pinctrl_usdhc1: usdhc1grp { + fsl,pins = < + MX6QDL_PAD_SD1_CMD__SD1_CMD 0x17071 + MX6QDL_PAD_SD1_CLK__SD1_CLK 0x10071 + MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x17071 + MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17071 + MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17071 + MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17071 + MX6QDL_PAD_NANDF_D0__SD1_DATA4 0x17071 + MX6QDL_PAD_NANDF_D1__SD1_DATA5 0x17071 + MX6QDL_PAD_NANDF_D2__SD1_DATA6 0x17071 + MX6QDL_PAD_NANDF_D3__SD1_DATA7 0x17071 + >; + }; + + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17071 + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10071 + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17071 + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17071 + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17071 + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17071 + >; + }; + + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059 + MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x17059 + MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x17059 + MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x17059 + MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x17059 + /* eMMC reset */ + MX6QDL_PAD_SD3_RST__SD3_RESET 0x17059 + >; + }; + + pinctrl_usdhc3_100mhz: usdhc3100mhzgrp { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170b9 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100b9 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170b9 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170b9 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170b9 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170b9 + MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x170b9 + MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x170b9 + MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x170b9 + MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x170b9 + /* eMMC reset */ + MX6QDL_PAD_SD3_RST__SD3_RESET 0x170b9 + >; + }; + + pinctrl_usdhc3_200mhz: usdhc3200mhzgrp { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170f9 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100f9 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170f9 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170f9 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170f9 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170f9 + MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x170f9 + MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x170f9 + MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x170f9 + MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x170f9 + /* eMMC reset */ + MX6QDL_PAD_SD3_RST__SD3_RESET 0x170f9 + >; + }; +}; diff --git a/arch/arm/boot/dts/imx6qdl-apf6dev.dtsi b/arch/arm/boot/dts/imx6qdl-apf6dev.dtsi index e26ebeb5b45c055a17919cbbc7751fa4588800f8..a8f3500ee522b3999a31d3c1dff2946e1481ba5d 100644 --- a/arch/arm/boot/dts/imx6qdl-apf6dev.dtsi +++ b/arch/arm/boot/dts/imx6qdl-apf6dev.dtsi @@ -94,7 +94,7 @@ label = "User button"; gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi index 5cd16f2178b80fd955e8be48b776fb601afe606b..9d7ab6cdc9a60b3a0b4a76c853851d8b87700737 100644 --- a/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi @@ -320,13 +320,13 @@ pinctrl_pwm3: pwm3grp { fsl,pins = < - MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1 + MX6QDL_PAD_SD1_DAT1__PWM3_OUT 0x1b0b1 >; }; pinctrl_pwm4: pwm4grp { fsl,pins = < - MX6QDL_PAD_SD4_DAT2__PWM4_OUT 0x1b0b1 + MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1 >; }; diff --git a/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi index 9fa8a10c7cc8892266a87be766974b03fcfff326..8dd74e98ffd69b35f1dd8349e55231db25592148 100644 --- a/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi @@ -473,7 +473,7 @@ pinctrl_pwm3: pwm3grp { fsl,pins = < - MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1 + MX6QDL_PAD_SD1_DAT1__PWM3_OUT 0x1b0b1 >; }; diff --git a/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi index e8375e173873edc5dc39ef011321cbbac9378f00..ec3fe7444e154c4d39f28a5a4a6f8afef05eeb1f 100644 --- a/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi @@ -462,7 +462,7 @@ pinctrl_pwm3: pwm3grp { fsl,pins = < - MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1 + MX6QDL_PAD_SD1_DAT1__PWM3_OUT 0x1b0b1 >; }; diff --git a/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi index 66983dc5cbdae8868b2f20ade01b3df1be44575d..367cc49eea0d69cd63c3d3a86121f260b91f05c2 100644 --- a/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi @@ -397,8 +397,9 @@ }; &pwm4 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_pwm4>; + pinctrl-names = "default", "state_dio"; + pinctrl-0 = <&pinctrl_pwm4_backlight>; + pinctrl-1 = <&pinctrl_pwm4_dio>; status = "okay"; }; @@ -573,12 +574,20 @@ >; }; - pinctrl_pwm4: pwm4grp { + pinctrl_pwm4_backlight: pwm4grpbacklight { fsl,pins = < + /* LVDS_PWM J6.5 */ MX6QDL_PAD_SD1_CMD__PWM4_OUT 0x1b0b1 >; }; + pinctrl_pwm4_dio: pwm4grpdio { + fsl,pins = < + /* DIO3 J16.4 */ + MX6QDL_PAD_SD4_DAT2__PWM4_OUT 0x1b0b1 + >; + }; + pinctrl_uart1: uart1grp { fsl,pins = < MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1 diff --git a/arch/arm/boot/dts/imx6qdl-gw552x.dtsi b/arch/arm/boot/dts/imx6qdl-gw552x.dtsi index cca39f194017c262d6c850172f76c584a73f099f..f27f184558fb4daa43ad525afd06750eea5fd946 100644 --- a/arch/arm/boot/dts/imx6qdl-gw552x.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw552x.dtsi @@ -262,7 +262,7 @@ pinctrl_pwm3: pwm3grp { fsl,pins = < - MX6QDL_PAD_SD4_DAT1__PWM3_OUT 0x1b0b1 + MX6QDL_PAD_SD1_DAT1__PWM3_OUT 0x1b0b1 >; }; diff --git a/arch/arm/boot/dts/imx6qdl-hummingboard.dtsi b/arch/arm/boot/dts/imx6qdl-hummingboard.dtsi index 6dd0b764e036d1c51cdde3015c1a2cc56178a999..d6c2358ffad4490af869a099e1884bc3122415ac 100644 --- a/arch/arm/boot/dts/imx6qdl-hummingboard.dtsi +++ b/arch/arm/boot/dts/imx6qdl-hummingboard.dtsi @@ -48,7 +48,7 @@ ir_recv: ir-receiver { compatible = "gpio-ir-receiver"; - gpios = <&gpio3 5 1>; + gpios = <&gpio3 5 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_hummingboard_gpio3_5>; }; @@ -67,7 +67,7 @@ reg_usbh1_vbus: usb-h1-vbus { compatible = "regulator-fixed"; enable-active-high; - gpio = <&gpio1 0 0>; + gpio = <&gpio1 0 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_hummingboard_usbh1_vbus>; regulator-name = "usb_h1_vbus"; @@ -78,7 +78,7 @@ reg_usbotg_vbus: usb-otg-vbus { compatible = "regulator-fixed"; enable-active-high; - gpio = <&gpio3 22 0>; + gpio = <&gpio3 22 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_hummingboard_usbotg_vbus>; regulator-name = "usb_otg_vbus"; @@ -253,7 +253,7 @@ &pcie { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_hummingboard_pcie_reset>; - reset-gpio = <&gpio3 4 0>; + reset-gpio = <&gpio3 4 GPIO_ACTIVE_LOW>; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6qdl-icore-rqs.dtsi b/arch/arm/boot/dts/imx6qdl-icore-rqs.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..f8d945a56525799eb5b38243d7ed2da34eb76c0c --- /dev/null +++ b/arch/arm/boot/dts/imx6qdl-icore-rqs.dtsi @@ -0,0 +1,411 @@ +/* + * Copyright (C) 2015 Amarula Solutions B.V. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +/ { + memory { + reg = <0x10000000 0x80000000>; + }; + + reg_1p8v: regulator-1p8v { + compatible = "regulator-fixed"; + regulator-name = "1P8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_2p5v: regulator-2p5v { + compatible = "regulator-fixed"; + regulator-name = "2P5V"; + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "3P3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_sd3_vmmc: regulator-sd3-vmmc { + compatible = "regulator-fixed"; + regulator-name = "P3V3_SD3_SWITCHED"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio1 4 GPIO_ACTIVE_LOW>; + enable-active-high; + }; + + reg_sd4_vmmc: regulator-sd4-vmmc { + compatible = "regulator-fixed"; + regulator-name = "P3V3_SD4_SWITCHED"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_usb_h1_vbus: regulator-usb-h1-vbus { + compatible = "regulator-fixed"; + regulator-name = "usb_h1_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_usb_otg_vbus: regulator-usb-otg-vbus { + compatible = "regulator-fixed"; + regulator-name = "usb_otg_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + regulator-always-on; + }; + + usb_hub: usb-hub { + compatible = "smsc,usb3503a"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbhub>; + reset-gpios = <&gpio1 6 GPIO_ACTIVE_LOW>; + clocks = <&clks IMX6QDL_CLK_LVDS2_GATE>; + clock-names = "refclk"; + }; +}; + +&clks { + assigned-clocks = <&clks IMX6QDL_CLK_LVDS2_SEL>; + assigned-clock-parents = <&clks IMX6QDL_CLK_OSC>; +}; + +&audmux { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_audmux>; + status = "okay"; +}; + +&fec { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enet>; + phy-handle = <ð_phy>; + phy-mode = "rgmii"; + status = "okay"; + + mdio { + eth_phy: ethernet-phy { + rxc-skew-ps = <1140>; + txc-skew-ps = <1140>; + txen-skew-ps = <600>; + rxdv-skew-ps = <240>; + rxd0-skew-ps = <420>; + rxd1-skew-ps = <600>; + rxd2-skew-ps = <420>; + rxd3-skew-ps = <240>; + txd0-skew-ps = <60>; + txd1-skew-ps = <60>; + txd2-skew-ps = <60>; + txd3-skew-ps = <240>; + }; + }; +}; + +&i2c1 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + status = "okay"; +}; + +&i2c2 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + status = "okay"; +}; + +&i2c3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + status = "okay"; +}; + +&pcie { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie>; + reset-gpio = <&gpio3 29 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&ssi1 { + fsl,mode = "i2s-slave"; + status = "okay"; +}; + +&uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart4>; + status = "okay"; +}; + +&usbh1 { + vbus-supply = <®_usb_h1_vbus>; + disable-over-current; + clocks = <&clks IMX6QDL_CLK_USBOH3>; + status = "okay"; +}; + +&usbotg { + vbus-supply = <®_usb_otg_vbus>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbotg>; + disable-over-current; + status = "okay"; +}; + +&usdhc1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc1>; + no-1-8-v; + status = "okay"; +}; + +&usdhc3 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc3>; + pinctrl-1 = <&pinctrl_usdhc3_100mhz>; + pinctrl-2 = <&pinctrl_usdhc3_200mhz>; + vmcc-supply = <®_sd3_vmmc>; + cd-gpios = <&gpio1 1 GPIO_ACTIVE_LOW>; + bus-witdh=<4>; + no-1-8-v; + status = "okay"; +}; + +&usdhc4 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc4>; + pinctrl-1 = <&pinctrl_usdhc4_100mhz>; + pinctrl-2 = <&pinctrl_usdhc4_200mhz>; + vmcc-supply = <®_sd4_vmmc>; + bus-witdh=<8>; + no-1-8-v; + non-removable; + status = "okay"; +}; + +&iomuxc { + pinctrl_audmux: audmux { + fsl,pins = < + MX6QDL_PAD_DISP0_DAT20__AUD4_TXC 0x130b0 + MX6QDL_PAD_DISP0_DAT21__AUD4_TXD 0x110b0 + MX6QDL_PAD_DISP0_DAT22__AUD4_TXFS 0x130b0 + MX6QDL_PAD_DISP0_DAT23__AUD4_RXD 0x130b0 + >; + }; + + pinctrl_enet: enetgrp { + fsl,pins = < + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0 + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0 + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0 + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0 + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0 + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0 + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0 + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0 + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0 + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0 + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0 + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0 + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0 + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0 + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0 + MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN 0x1b0b0 + >; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX6QDL_PAD_EIM_D21__I2C1_SCL 0x4001b8b1 + MX6QDL_PAD_EIM_D28__I2C1_SDA 0x4001b8b1 + >; + }; + + pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1 + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1 + >; + }; + + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX6QDL_PAD_GPIO_5__I2C3_SCL 0x4001b8b1 + MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1 + MX6QDL_PAD_GPIO_0__CCM_CLKO1 0x130b0 + >; + }; + + pinctrl_pcie: pciegrp { + fsl,pins = < + MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x1f059 /* PCIe Reset */ + >; + }; + + pinctrl_uart4: uart4grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1 + MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1 + >; + }; + + pinctrl_usbhub: usbhubgrp { + fsl,pins = < + MX6QDL_PAD_GPIO_6__GPIO1_IO06 0x1f059 /* HUB USB Reset */ + >; + }; + + pinctrl_usbotg: usbotggrp { + fsl,pins = < + MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x17059 + >; + }; + + pinctrl_usdhc1: usdhc1grp { + fsl,pins = < + MX6QDL_PAD_SD1_CMD__SD1_CMD 0x17071 + MX6QDL_PAD_SD1_CLK__SD1_CLK 0x10071 + MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x17071 + MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17071 + MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17071 + MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17071 + >; + }; + + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17070 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10070 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17070 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17070 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17070 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17070 + MX6QDL_PAD_GPIO_1__GPIO1_IO01 0x1f059 /* CD */ + MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x1f059 /* PWR */ + >; + }; + + pinctrl_usdhc3_100mhz: usdhc3grp_100mhz { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170B1 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100B1 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170B1 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170B1 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170B1 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170B1 + >; + }; + + pinctrl_usdhc3_200mhz: usdhc3grp_200mhz { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x170F9 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x100F9 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x170F9 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x170F9 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x170F9 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x170F9 + >; + }; + + pinctrl_usdhc4: usdhc4grp { + fsl,pins = < + MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17070 + MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10070 + MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17070 + MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17070 + MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17070 + MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17070 + MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17070 + MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17070 + MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17070 + MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17070 + >; + }; + + pinctrl_usdhc4_100mhz: usdhc4grp_100mhz { + fsl,pins = < + MX6QDL_PAD_SD4_CMD__SD4_CMD 0x170B1 + MX6QDL_PAD_SD4_CLK__SD4_CLK 0x100B1 + MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x170B1 + MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x170B1 + MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x170B1 + MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x170B1 + MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x170B1 + MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x170B1 + MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x170B1 + MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x170B1 + >; + }; + + pinctrl_usdhc4_200mhz: usdhc4grp_200mhz { + fsl,pins = < + MX6QDL_PAD_SD4_CMD__SD4_CMD 0x170F9 + MX6QDL_PAD_SD4_CLK__SD4_CLK 0x100F9 + MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x170F9 + MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x170F9 + MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x170F9 + MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x170F9 + MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x170F9 + MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x170F9 + MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x170F9 + MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x170F9 + >; + }; +}; diff --git a/arch/arm/boot/dts/imx6qdl-microsom.dtsi b/arch/arm/boot/dts/imx6qdl-microsom.dtsi index 6d4069cc9419eae3361fece8cd52a1e29b25b853..86460e46d0559b770a16bcecfad8e2522395f226 100644 --- a/arch/arm/boot/dts/imx6qdl-microsom.dtsi +++ b/arch/arm/boot/dts/imx6qdl-microsom.dtsi @@ -154,6 +154,7 @@ bus-width = <4>; mmc-pwrseq = <&usdhc1_pwrseq>; keep-power-in-suspend; + no-1-8-v; non-removable; vmmc-supply = <®_brcm>; status = "okay"; diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi index a35d54fd9cd320eea5d5890c174161588f47e823..dc74aa395ff5473d4cbdb36f28bfef16a1adf916 100644 --- a/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi +++ b/arch/arm/boot/dts/imx6qdl-nitrogen6_max.dtsi @@ -138,7 +138,7 @@ label = "Power Button"; gpios = <&gpio2 3 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; menu { diff --git a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi index caeed56b74a391ae996b877dea9b0a325a14ff42..c6c590d1e94096e2f95e2e539d09acc10b2bce5a 100644 --- a/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi +++ b/arch/arm/boot/dts/imx6qdl-nitrogen6x.dtsi @@ -119,7 +119,7 @@ label = "Power Button"; gpios = <&gpio2 3 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; menu { diff --git a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi index 1a69a3420ac8d14a8977a7f8d862decb546f87bd..0f1aca450fe6abf931e6eb207b3f6f490e57cfc4 100644 --- a/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi +++ b/arch/arm/boot/dts/imx6qdl-sabrelite.dtsi @@ -105,7 +105,7 @@ label = "Power Button"; gpios = <&gpio2 3 GPIO_ACTIVE_LOW>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; menu { diff --git a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi index a6d445c17779cf5c39c26ff41170bb38eda31624..0b5c4de74485c00685da3fdc75b2ab3b82761be1 100644 --- a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi +++ b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi @@ -79,21 +79,21 @@ power { label = "Power Button"; gpios = <&gpio3 29 GPIO_ACTIVE_LOW>; - gpio-key,wakeup; + wakeup-source; linux,code = ; }; volume-up { label = "Volume Up"; gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; - gpio-key,wakeup; + wakeup-source; linux,code = ; }; volume-down { label = "Volume Down"; gpios = <&gpio1 5 GPIO_ACTIVE_LOW>; - gpio-key,wakeup; + wakeup-source; linux,code = ; }; }; @@ -238,6 +238,7 @@ regulator-max-microvolt = <3300000>; regulator-boot-on; regulator-always-on; + regulator-ramp-delay = <6250>; }; sw3a_reg: sw3a { diff --git a/arch/arm/boot/dts/imx6qdl-tx6.dtsi b/arch/arm/boot/dts/imx6qdl-tx6.dtsi index 13cb7ccfea44dd653e8100669d415b88699c7831..efd06b576f1da445b991a279a0af48a687a084dc 100644 --- a/arch/arm/boot/dts/imx6qdl-tx6.dtsi +++ b/arch/arm/boot/dts/imx6qdl-tx6.dtsi @@ -41,7 +41,7 @@ compatible = "fixed-clock"; reg = <0>; #clock-cells = <0>; - clock-frequency = <27000000>; + clock-frequency = <26000000>; }; }; @@ -52,7 +52,7 @@ label = "Power Button"; gpios = <&gpio5 2 GPIO_ACTIVE_HIGH>; linux,code = ; - gpio-key,wakeup; + wakeup-source; }; }; @@ -227,6 +227,11 @@ &fec { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enet>; + clocks = <&clks IMX6QDL_CLK_ENET>, + <&clks IMX6QDL_CLK_ENET>, + <&clks IMX6QDL_CLK_ENET_REF>, + <&clks IMX6QDL_CLK_ENET_REF>; + clock-names = "ipg", "ahb", "ptp", "enet_out"; phy-mode = "rmii"; phy-reset-gpios = <&gpio7 6 GPIO_ACTIVE_HIGH>; phy-supply = <®_3v3_etn>; @@ -276,7 +281,7 @@ interrupts = <15 IRQ_TYPE_EDGE_FALLING>; reset-gpios = <&gpio2 22 GPIO_ACTIVE_LOW>; wake-gpios = <&gpio2 21 GPIO_ACTIVE_HIGH>; - linux,wakeup; + wakeup-source; }; touchscreen: tsc2007@48 { @@ -288,7 +293,7 @@ interrupts = <26 0>; gpios = <&gpio3 26 GPIO_ACTIVE_LOW>; ti,x-plate-ohms = <660>; - linux,wakeup; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/imx6qdl-udoo.dtsi b/arch/arm/boot/dts/imx6qdl-udoo.dtsi index 1211da894ee9993e630aa0744e6e2478d326e5be..d3e54e40a017264400e6a787453f421e8aac2f21 100644 --- a/arch/arm/boot/dts/imx6qdl-udoo.dtsi +++ b/arch/arm/boot/dts/imx6qdl-udoo.dtsi @@ -34,6 +34,18 @@ gpio = <&gpio7 12 0>; }; }; + + sound { + compatible = "fsl,imx6q-udoo-ac97", + "fsl,imx-audio-ac97"; + model = "fsl,imx6q-udoo-ac97"; + audio-cpu = <&ssi1>; + audio-routing = + "RX", "Mic Jack", + "Headphone Jack", "TX"; + mux-int-port = <1>; + mux-ext-port = <6>; + }; }; &fec { @@ -109,6 +121,36 @@ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059 >; }; + + pinctrl_ac97_running: ac97running { + fsl,pins = < + MX6QDL_PAD_DI0_PIN2__AUD6_TXD 0x1b0b0 + MX6QDL_PAD_DI0_PIN3__AUD6_TXFS 0x1b0b0 + MX6QDL_PAD_DI0_PIN4__AUD6_RXD 0x1b0b0 + MX6QDL_PAD_DI0_PIN15__AUD6_TXC 0x1b0b0 + MX6QDL_PAD_EIM_EB2__GPIO2_IO30 0x1b0b0 + >; + }; + + pinctrl_ac97_warm_reset: ac97warmreset { + fsl,pins = < + MX6QDL_PAD_DI0_PIN2__AUD6_TXD 0x1b0b0 + MX6QDL_PAD_DI0_PIN3__GPIO4_IO19 0x1b0b0 + MX6QDL_PAD_DI0_PIN4__AUD6_RXD 0x1b0b0 + MX6QDL_PAD_DI0_PIN15__AUD6_TXC 0x1b0b0 + MX6QDL_PAD_EIM_EB2__GPIO2_IO30 0x1b0b0 + >; + }; + + pinctrl_ac97_reset: ac97reset { + fsl,pins = < + MX6QDL_PAD_DI0_PIN2__GPIO4_IO18 0x1b0b0 + MX6QDL_PAD_DI0_PIN3__GPIO4_IO19 0x1b0b0 + MX6QDL_PAD_DI0_PIN4__AUD6_RXD 0x1b0b0 + MX6QDL_PAD_DI0_PIN15__AUD6_TXC 0x1b0b0 + MX6QDL_PAD_EIM_EB2__GPIO2_IO30 0x1b0b0 + >; + }; }; }; @@ -132,3 +174,18 @@ non-removable; status = "okay"; }; + +&audmux { + status = "okay"; +}; + +&ssi1 { + cell-index = <0>; + fsl,mode = "ac97-slave"; + pinctrl-names = "ac97-running", "ac97-reset", "ac97-warm-reset"; + pinctrl-0 = <&pinctrl_ac97_running>; + pinctrl-1 = <&pinctrl_ac97_reset>; + pinctrl-2 = <&pinctrl_ac97_warm_reset>; + ac97-gpios = <&gpio4 19 0 &gpio4 18 0 &gpio2 30 0>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index f74d3db4846dacacd54b37e9cb1d35d707689368..b42822aa14f29e7d1547e469c4a82218e65c5d44 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi @@ -261,7 +261,7 @@ clocks = <&clks IMX6QDL_CLK_ECSPI1>, <&clks IMX6QDL_CLK_ECSPI1>; clock-names = "ipg", "per"; - dmas = <&sdma 3 7 1>, <&sdma 4 7 2>; + dmas = <&sdma 3 8 1>, <&sdma 4 8 2>; dma-names = "rx", "tx"; status = "disabled"; }; @@ -275,7 +275,7 @@ clocks = <&clks IMX6QDL_CLK_ECSPI2>, <&clks IMX6QDL_CLK_ECSPI2>; clock-names = "ipg", "per"; - dmas = <&sdma 5 7 1>, <&sdma 6 7 2>; + dmas = <&sdma 5 8 1>, <&sdma 6 8 2>; dma-names = "rx", "tx"; status = "disabled"; }; @@ -289,7 +289,7 @@ clocks = <&clks IMX6QDL_CLK_ECSPI3>, <&clks IMX6QDL_CLK_ECSPI3>; clock-names = "ipg", "per"; - dmas = <&sdma 7 7 1>, <&sdma 8 7 2>; + dmas = <&sdma 7 8 1>, <&sdma 8 8 2>; dma-names = "rx", "tx"; status = "disabled"; }; @@ -303,7 +303,7 @@ clocks = <&clks IMX6QDL_CLK_ECSPI4>, <&clks IMX6QDL_CLK_ECSPI4>; clock-names = "ipg", "per"; - dmas = <&sdma 9 7 1>, <&sdma 10 7 2>; + dmas = <&sdma 9 8 1>, <&sdma 10 8 2>; dma-names = "rx", "tx"; status = "disabled"; }; diff --git a/arch/arm/boot/dts/imx6qp-sabreauto.dts b/arch/arm/boot/dts/imx6qp-sabreauto.dts new file mode 100644 index 0000000000000000000000000000000000000000..5ce3840d83d3f5315b85050e67247e4b807e50a4 --- /dev/null +++ b/arch/arm/boot/dts/imx6qp-sabreauto.dts @@ -0,0 +1,93 @@ +/* + * Copyright 2016 Freescale Semiconductor, Inc. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include "imx6qp.dtsi" +#include "imx6qdl-sabreauto.dtsi" + +/ { + model = "Freescale i.MX6 Quad Plus SABRE Automotive Board"; + compatible = "fsl,imx6qp-sabreauto", "fsl,imx6qp"; +}; + +&i2c2 { + max7322: gpio@68 { + compatible = "maxim,max7322"; + reg = <0x68>; + gpio-controller; + #gpio-cells = <2>; + }; +}; + +&iomuxc { + imx6qdl-sabreauto { + pinctrl_enet: enetgrp { + fsl,pins = < + MX6QDL_PAD_KEY_COL1__ENET_MDIO 0x1b0b0 + MX6QDL_PAD_KEY_COL2__ENET_MDC 0x1b0b0 + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b018 + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b018 + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b018 + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b018 + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b018 + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b018 + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b018 + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b018 + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b018 + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b018 + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b018 + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b018 + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8 + MX6QDL_PAD_GPIO_6__ENET_IRQ 0x000b1 + >; + }; + }; +}; + +&pcie { + status = "disabled"; +}; + +&vgen3_reg { + regulator-always-on; +}; diff --git a/arch/arm/boot/dts/imx6qp-sabresd.dts b/arch/arm/boot/dts/imx6qp-sabresd.dts new file mode 100644 index 0000000000000000000000000000000000000000..b23458062f5e66f231797bf7a02833c8a4aa4792 --- /dev/null +++ b/arch/arm/boot/dts/imx6qp-sabresd.dts @@ -0,0 +1,93 @@ +/* + * Copyright 2016 Freescale Semiconductor, Inc. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include "imx6qp.dtsi" +#include "imx6qdl-sabresd.dtsi" + +/ { + model = "Freescale i.MX6 Quad Plus SABRE Smart Device Board"; + compatible = "fsl,imx6qp-sabresd", "fsl,imx6qp"; +}; + +&cpu0 { + arm-supply = <&sw2_reg>; +}; + +&iomuxc { + imx6qdl-sabresd { + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059 + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10071 + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059 + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059 + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059 + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059 + MX6QDL_PAD_NANDF_D4__SD2_DATA4 0x17059 + MX6QDL_PAD_NANDF_D5__SD2_DATA5 0x17059 + MX6QDL_PAD_NANDF_D6__SD2_DATA6 0x17059 + MX6QDL_PAD_NANDF_D7__SD2_DATA7 0x17059 + >; + }; + + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10071 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059 + MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x17059 + MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x17059 + MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x17059 + MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x17059 + >; + }; + }; +}; + +&pcie { + status = "disabled"; +}; diff --git a/arch/arm/boot/dts/imx6qp.dtsi b/arch/arm/boot/dts/imx6qp.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..1ada71437e49fd6735dc2e952e07d61ced7187cb --- /dev/null +++ b/arch/arm/boot/dts/imx6qp.dtsi @@ -0,0 +1,86 @@ +/* + * Copyright 2016 Freescale Semiconductor, Inc. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "imx6q.dtsi" + +/ { + soc { + ocram2: sram@00940000 { + compatible = "mmio-sram"; + reg = <0x00940000 0x20000>; + clocks = <&clks IMX6QDL_CLK_OCRAM>; + }; + + ocram3: sram@00960000 { + compatible = "mmio-sram"; + reg = <0x00960000 0x20000>; + clocks = <&clks IMX6QDL_CLK_OCRAM>; + }; + + ipu1: ipu@02400000 { + compatible = "fsl,imx6qp-ipu", "fsl,imx6q-ipu"; + clocks = <&clks IMX6QDL_CLK_IPU1>, + <&clks IMX6QDL_CLK_IPU1_DI0>, <&clks IMX6QDL_CLK_IPU1_DI1>, + <&clks IMX6QDL_CLK_IPU1_DI0_SEL>, <&clks IMX6QDL_CLK_IPU1_DI1_SEL>, + <&clks IMX6QDL_CLK_LDB_DI0_PODF>, <&clks IMX6QDL_CLK_LDB_DI1_PODF>, + <&clks IMX6QDL_CLK_PRG0_APB>; + clock-names = "bus", + "di0", "di1", + "di0_sel", "di1_sel", + "ldb_di0", "ldb_di1", "prg"; + }; + + ipu2: ipu@02800000 { + compatible = "fsl,imx6qp-ipu", "fsl,imx6q-ipu"; + clocks = <&clks IMX6QDL_CLK_IPU2>, + <&clks IMX6QDL_CLK_IPU2_DI0>, <&clks IMX6QDL_CLK_IPU2_DI1>, + <&clks IMX6QDL_CLK_IPU2_DI0_SEL>, <&clks IMX6QDL_CLK_IPU2_DI1_SEL>, + <&clks IMX6QDL_CLK_LDB_DI0_PODF>, <&clks IMX6QDL_CLK_LDB_DI1_PODF>, + <&clks IMX6QDL_CLK_PRG1_APB>; + clock-names = "bus", + "di0", "di1", + "di0_sel", "di1_sel", + "ldb_di0", "ldb_di1", "prg"; + }; + + }; +}; diff --git a/arch/arm/boot/dts/imx6sl-warp.dts b/arch/arm/boot/dts/imx6sl-warp.dts index 10c69963100fab7e972069a117a625175c21a72c..058bcdceb81aa1874ebbd1826d18c8a8b2743d4b 100644 --- a/arch/arm/boot/dts/imx6sl-warp.dts +++ b/arch/arm/boot/dts/imx6sl-warp.dts @@ -118,7 +118,7 @@ bus-width = <4>; non-removable; keep-power-in-suspend; - enable-sdio-wakeup; + wakeup-source; mmc-pwrseq = <&usdhc3_pwrseq>; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6sx-sabreauto.dts b/arch/arm/boot/dts/imx6sx-sabreauto.dts index 115f3fd78971868ad7025fbb0f46c17c4252e574..96ea936eeeb0a1dce450696b38893ed3b341ed48 100644 --- a/arch/arm/boot/dts/imx6sx-sabreauto.dts +++ b/arch/arm/boot/dts/imx6sx-sabreauto.dts @@ -52,7 +52,7 @@ cd-gpios = <&gpio7 10 GPIO_ACTIVE_LOW>; wp-gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>; keep-power-in-suspend; - enable-sdio-wakeup; + wakeup-source; vmmc-supply = <&vcc_sd3>; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6sx-sdb.dtsi b/arch/arm/boot/dts/imx6sx-sdb.dtsi index 94ac4005d9cd3904a9d0148d8f3e0214835fb067..f1d37306e8bf4865c40a8923d76710654e0a9b0c 100644 --- a/arch/arm/boot/dts/imx6sx-sdb.dtsi +++ b/arch/arm/boot/dts/imx6sx-sdb.dtsi @@ -184,6 +184,13 @@ status = "okay"; }; +&i2c3 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + status = "okay"; +}; + &i2c4 { clock-frequency = <100000>; pinctrl-names = "default"; @@ -283,7 +290,7 @@ non-removable; no-1-8-v; keep-power-in-suspend; - enable-sdio-wakeup; + wakeup-source; status = "okay"; }; @@ -296,7 +303,7 @@ cd-gpios = <&gpio2 10 GPIO_ACTIVE_LOW>; wp-gpios = <&gpio2 15 GPIO_ACTIVE_HIGH>; keep-power-in-suspend; - enable-sdio-wakeup; + wakeup-source; vmmc-supply = <&vcc_sd3>; status = "okay"; }; @@ -378,6 +385,13 @@ >; }; + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX6SX_PAD_KEY_ROW4__I2C3_SDA 0x4001b8b1 + MX6SX_PAD_KEY_COL4__I2C3_SCL 0x4001b8b1 + >; + }; + pinctrl_i2c4: i2c4grp { fsl,pins = < MX6SX_PAD_CSI_DATA07__I2C4_SDA 0x4001b8b1 diff --git a/arch/arm/boot/dts/imx6ul-14x14-evk.dts b/arch/arm/boot/dts/imx6ul-14x14-evk.dts index 6aaa5ec3d846eae6019e4414d4c925a5ebc2adc5..720728001d3c6949687d7fd04c2142c582563895 100644 --- a/arch/arm/boot/dts/imx6ul-14x14-evk.dts +++ b/arch/arm/boot/dts/imx6ul-14x14-evk.dts @@ -8,7 +8,6 @@ /dts-v1/; -#include #include "imx6ul.dtsi" / { @@ -131,7 +130,7 @@ pinctrl-2 = <&pinctrl_usdhc1_200mhz>; cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>; keep-power-in-suspend; - enable-sdio-wakeup; + wakeup-source; vmmc-supply = <®_sd1_vmmc>; status = "okay"; }; @@ -141,7 +140,7 @@ pinctrl-0 = <&pinctrl_usdhc2>; no-1-8-v; keep-power-in-suspend; - enable-sdio-wakeup; + wakeup-source; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx6ul-pinfunc.h b/arch/arm/boot/dts/imx6ul-pinfunc.h index 20c7da1affce0c6bb2ab851c530b5be2f96661d3..0034eeb84542ff841b53b0226144c3a14b380efc 100644 --- a/arch/arm/boot/dts/imx6ul-pinfunc.h +++ b/arch/arm/boot/dts/imx6ul-pinfunc.h @@ -14,925 +14,925 @@ * The pin function ID is a tuple of * */ -#define MX6UL_PAD_BOOT_MODE0__GPIO5_IO10 0x0014 0x02a0 0x0000 5 0 -#define MX6UL_PAD_BOOT_MODE1__GPIO5_IO11 0x0018 0x02a4 0x0000 5 0 +#define MX6UL_PAD_BOOT_MODE0__GPIO5_IO10 0x0014 0x02a0 0x0000 5 0 +#define MX6UL_PAD_BOOT_MODE1__GPIO5_IO11 0x0018 0x02a4 0x0000 5 0 -#define MX6UL_PAD_SNVS_TAMPER0__GPIO5_IO00 0x001c 0x02a8 0x0000 5 0 -#define MX6UL_PAD_SNVS_TAMPER1__GPIO5_IO01 0x0020 0x02ac 0x0000 5 0 -#define MX6UL_PAD_SNVS_TAMPER2__GPIO5_IO02 0x0024 0x02b0 0x0000 5 0 -#define MX6UL_PAD_SNVS_TAMPER3__GPIO5_IO03 0x0028 0x02b4 0x0000 5 0 -#define MX6UL_PAD_SNVS_TAMPER4__GPIO5_IO04 0x002c 0x02b8 0x0000 5 0 -#define MX6UL_PAD_SNVS_TAMPER5__GPIO5_IO05 0x0030 0x02bc 0x0000 5 0 -#define MX6UL_PAD_SNVS_TAMPER6__GPIO5_IO06 0x0034 0x02c0 0x0000 5 0 -#define MX6UL_PAD_SNVS_TAMPER7__GPIO5_IO07 0x0038 0x02c4 0x0000 5 0 -#define MX6UL_PAD_SNVS_TAMPER8__GPIO5_IO08 0x003c 0x02c8 0x0000 5 0 -#define MX6UL_PAD_SNVS_TAMPER9__GPIO5_IO09 0x0040 0x02cc 0x0000 5 0 +#define MX6UL_PAD_SNVS_TAMPER0__GPIO5_IO00 0x001c 0x02a8 0x0000 5 0 +#define MX6UL_PAD_SNVS_TAMPER1__GPIO5_IO01 0x0020 0x02ac 0x0000 5 0 +#define MX6UL_PAD_SNVS_TAMPER2__GPIO5_IO02 0x0024 0x02b0 0x0000 5 0 +#define MX6UL_PAD_SNVS_TAMPER3__GPIO5_IO03 0x0028 0x02b4 0x0000 5 0 +#define MX6UL_PAD_SNVS_TAMPER4__GPIO5_IO04 0x002c 0x02b8 0x0000 5 0 +#define MX6UL_PAD_SNVS_TAMPER5__GPIO5_IO05 0x0030 0x02bc 0x0000 5 0 +#define MX6UL_PAD_SNVS_TAMPER6__GPIO5_IO06 0x0034 0x02c0 0x0000 5 0 +#define MX6UL_PAD_SNVS_TAMPER7__GPIO5_IO07 0x0038 0x02c4 0x0000 5 0 +#define MX6UL_PAD_SNVS_TAMPER8__GPIO5_IO08 0x003c 0x02c8 0x0000 5 0 +#define MX6UL_PAD_SNVS_TAMPER9__GPIO5_IO09 0x0040 0x02cc 0x0000 5 0 -#define MX6UL_PAD_JTAG_MOD__SJC_MOD 0x0044 0x02d0 0x0000 0 0 -#define MX6UL_PAD_JTAG_MOD__GPT2_CLK 0x0044 0x02d0 0x05a0 1 0 -#define MX6UL_PAD_JTAG_MOD__SPDIF_OUT 0x0044 0x02d0 0x0000 2 0 -#define MX6UL_PAD_JTAG_MOD__ENET1_REF_CLK_25M 0x0044 0x02d0 0x0000 3 0 -#define MX6UL_PAD_JTAG_MOD__CCM_PMIC_RDY 0x0044 0x02d0 0x04c0 4 0 -#define MX6UL_PAD_JTAG_MOD__GPIO1_IO10 0x0044 0x02d0 0x0000 5 0 -#define MX6UL_PAD_JTAG_MOD__SDMA_EXT_EVENT00 0x0044 0x02d0 0x0000 6 0 -#define MX6UL_PAD_JTAG_TMS__SJC_TMS 0x0048 0x02d4 0x0000 0 0 -#define MX6UL_PAD_JTAG_TMS__GPT2_CAPTURE1 0x0048 0x02d4 0x0598 1 0 -#define MX6UL_PAD_JTAG_TMS__SAI2_MCLK 0x0048 0x02d4 0x0000 2 0 -#define MX6UL_PAD_JTAG_TMS__CCM_CLKO1 0x0048 0x02d4 0x0000 3 0 -#define MX6UL_PAD_JTAG_TMS__CCM_WAIT 0x0048 0x02d4 0x0000 4 0 -#define MX6UL_PAD_JTAG_TMS__GPIO1_IO11 0x0048 0x02d4 0x0000 5 0 -#define MX6UL_PAD_JTAG_TMS__SDMA_EXT_EVENT01 0x0048 0x02d4 0x0000 6 0 -#define MX6UL_PAD_JTAG_TMS__EPIT1_OUT 0x0048 0x02d4 0x0000 8 0 -#define MX6UL_PAD_JTAG_TDO__SJC_TDO 0x004c 0x02d8 0x0000 0 0 -#define MX6UL_PAD_JTAG_TDO__GPT2_CAPTURE2 0x004c 0x02d8 0x059c 1 0 -#define MX6UL_PAD_JTAG_TDO__SAI2_TX_SYNC 0x004c 0x02d8 0x05fc 2 0 -#define MX6UL_PAD_JTAG_TDO__CCM_CLKO2 0x004c 0x02d8 0x0000 3 0 -#define MX6UL_PAD_JTAG_TDO__CCM_STOP 0x004c 0x02d8 0x0000 4 0 -#define MX6UL_PAD_JTAG_TDO__GPIO1_IO12 0x004c 0x02d8 0x0000 5 0 -#define MX6UL_PAD_JTAG_TDO__MQS_RIGHT 0x004c 0x02d8 0x0000 6 0 -#define MX6UL_PAD_JTAG_TDO__EPIT2_OUT 0x004c 0x02d8 0x0000 8 0 -#define MX6UL_PAD_JTAG_TDI__SJC_TDI 0x0050 0x02dc 0x0000 0 0 -#define MX6UL_PAD_JTAG_TDI__GPT2_COMPARE1 0x0050 0x02dc 0x0000 1 0 -#define MX6UL_PAD_JTAG_TDI__SAI2_TX_BCLK 0x0050 0x02dc 0x05f8 2 0 -#define MX6UL_PAD_JTAG_TDI__PWM6_OUT 0x0050 0x02dc 0x0000 4 0 -#define MX6UL_PAD_JTAG_TDI__GPIO1_IO13 0x0050 0x02dc 0x0000 5 0 -#define MX6UL_PAD_JTAG_TDI__MQS_LEFT 0x0050 0x02dc 0x0000 6 0 -#define MX6UL_PAD_JTAG_TDI__SIM1_POWER_FAIL 0x0050 0x02dc 0x0000 8 0 -#define MX6UL_PAD_JTAG_TCK__SJC_TCK 0x0054 0x02e0 0x0000 0 0 -#define MX6UL_PAD_JTAG_TCK__GPT2_COMPARE2 0x0054 0x02e0 0x0000 1 0 -#define MX6UL_PAD_JTAG_TCK__SAI2_RX_DATA 0x0054 0x02e0 0x0000 2 0 -#define MX6UL_PAD_JTAG_TCK__PWM7_OUT 0x0054 0x02e0 0x0000 4 0 -#define MX6UL_PAD_JTAG_TCK__GPIO1_IO14 0x0054 0x02e0 0x0000 5 0 -#define MX6UL_PAD_JTAG_TCK__SIM2_POWER_FAIL 0x0054 0x02e0 0x0000 8 0 -#define MX6UL_PAD_JTAG_TRST_B__SJC_TRSTB 0x0058 0x02e4 0x0000 0 0 -#define MX6UL_PAD_JTAG_TRST_B__GPT2_COMPARE3 0x0058 0x02e4 0x0000 1 0 -#define MX6UL_PAD_JTAG_TRST_B__SAI2_TX_DATA 0x0058 0x02e4 0x0000 2 0 -#define MX6UL_PAD_JTAG_TRST_B__PWM8_OUT 0x0058 0x02e4 0x0000 4 0 -#define MX6UL_PAD_JTAG_TRST_B__GPIO1_IO15 0x0058 0x02e4 0x0000 5 0 -#define MX6UL_PAD_JTAG_TRST_B__CAAM_RNG_OSC_OBS 0x0058 0x02e4 0x0000 8 0 -#define MX6UL_PAD_GPIO1_IO00__I2C2_SCL 0x005c 0x02e8 0x05ac 0 1 -#define MX6UL_PAD_GPIO1_IO00__GPT1_CAPTURE1 0x005c 0x02e8 0x058c 1 0 -#define MX6UL_PAD_GPIO1_IO00__ANATOP_OTG1_ID 0x005c 0x02e8 0x04b8 2 0 -#define MX6UL_PAD_GPIO1_IO00__ENET1_REF_CLK1 0x005c 0x02e8 0x0574 3 0 -#define MX6UL_PAD_GPIO1_IO00__MQS_RIGHT 0x005c 0x02e8 0x0000 4 0 -#define MX6UL_PAD_GPIO1_IO00__GPIO1_IO00 0x005c 0x02e8 0x0000 5 0 -#define MX6UL_PAD_GPIO1_IO00__ENET1_1588_EVENT0_IN 0x005c 0x02e8 0x0000 6 0 -#define MX6UL_PAD_GPIO1_IO00__SRC_SYSTEM_RESET 0x005c 0x02e8 0x0000 7 0 -#define MX6UL_PAD_GPIO1_IO00__WDOG3_WDOG_B 0x005c 0x02e8 0x0000 8 0 -#define MX6UL_PAD_GPIO1_IO01__I2C2_SDA 0x0060 0x02ec 0x05b0 0 1 -#define MX6UL_PAD_GPIO1_IO01__GPT1_COMPARE1 0x0060 0x02ec 0x0000 1 0 -#define MX6UL_PAD_GPIO1_IO01__USB_OTG1_OC 0x0060 0x02ec 0x0664 2 0 -#define MX6UL_PAD_GPIO1_IO01__ENET2_REF_CLK2 0x0060 0x02ec 0x057c 3 0 -#define MX6UL_PAD_GPIO1_IO01__MQS_LEFT 0x0060 0x02ec 0x0000 4 0 -#define MX6UL_PAD_GPIO1_IO01__GPIO1_IO01 0x0060 0x02ec 0x0000 5 0 -#define MX6UL_PAD_GPIO1_IO01__ENET1_1588_EVENT0_OUT 0x0060 0x02ec 0x0000 6 0 -#define MX6UL_PAD_GPIO1_IO01__SRC_EARLY_RESET 0x0060 0x02ec 0x0000 7 0 -#define MX6UL_PAD_GPIO1_IO01__WDOG1_WDOG_B 0x0060 0x02ec 0x0000 8 0 -#define MX6UL_PAD_GPIO1_IO02__I2C1_SCL 0x0064 0x02f0 0x05a4 0 0 -#define MX6UL_PAD_GPIO1_IO02__GPT1_COMPARE2 0x0064 0x02f0 0x0000 1 0 -#define MX6UL_PAD_GPIO1_IO02__USB_OTG2_PWR 0x0064 0x02f0 0x0000 2 0 -#define MX6UL_PAD_GPIO1_IO02__ENET1_REF_CLK_25M 0x0064 0x02f0 0x0000 3 0 -#define MX6UL_PAD_GPIO1_IO02__USDHC1_WP 0x0064 0x02f0 0x066c 4 0 -#define MX6UL_PAD_GPIO1_IO02__GPIO1_IO02 0x0064 0x02f0 0x0000 5 0 -#define MX6UL_PAD_GPIO1_IO02__SDMA_EXT_EVENT00 0x0064 0x02f0 0x0000 6 0 -#define MX6UL_PAD_GPIO1_IO02__SRC_ANY_PU_RESET 0x0064 0x02f0 0x0000 7 0 -#define MX6UL_PAD_GPIO1_IO02__UART1_DCE_TX 0x0064 0x02f0 0x0000 8 0 -#define MX6UL_PAD_GPIO1_IO02__UART1_DTE_RX 0x0064 0x02f0 0x0624 8 0 -#define MX6UL_PAD_GPIO1_IO03__I2C1_SDA 0x0068 0x02f4 0x05a8 0 1 -#define MX6UL_PAD_GPIO1_IO03__GPT1_COMPARE3 0x0068 0x02f4 0x0000 1 0 -#define MX6UL_PAD_GPIO1_IO03__USB_OTG2_OC 0x0068 0x02f4 0x0660 2 0 -#define MX6UL_PAD_GPIO1_IO03__USDHC1_CD_B 0x0068 0x02f4 0x0668 4 0 -#define MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0x0068 0x02f4 0x0000 5 0 -#define MX6UL_PAD_GPIO1_IO03__CCM_DI0_eXT_CLK 0x0068 0x02f4 0x0000 6 0 -#define MX6UL_PAD_GPIO1_IO03__SRC_TESTER_ACK 0x0068 0x02f4 0x0000 7 0 -#define MX6UL_PAD_GPIO1_IO03__UART1_DTE_TX 0x0068 0x02f4 0x0000 8 0 -#define MX6UL_PAD_GPIO1_IO03__UART1_DCE_RX 0x0068 0x02f4 0x0624 8 1 -#define MX6UL_PAD_GPIO1_IO04__ENET1_REF_CLK1 0x006c 0x02f8 0x0574 0 1 -#define MX6UL_PAD_GPIO1_IO04__PWM3_OUT 0x006c 0x02f8 0x0000 1 0 -#define MX6UL_PAD_GPIO1_IO04__USB_OTG1_PWR 0x006c 0x02f8 0x0000 2 0 -#define MX6UL_PAD_GPIO1_IO04__USDHC1_RESET_B 0x006c 0x02f8 0x0000 4 0 -#define MX6UL_PAD_GPIO1_IO04__GPIO1_IO04 0x006c 0x02f8 0x0000 5 0 -#define MX6UL_PAD_GPIO1_IO04__ENET2_1588_EVENT0_IN 0x006c 0x02f8 0x0000 6 0 -#define MX6UL_PAD_GPIO1_IO04__UART5_DCE_TX 0x006c 0x02f8 0x0000 8 0 -#define MX6UL_PAD_GPIO1_IO04__UART5_DTE_RX 0x006c 0x02f8 0x0644 8 2 -#define MX6UL_PAD_GPIO1_IO05__ENET2_REF_CLK2 0x0070 0x02fc 0x057c 0 1 -#define MX6UL_PAD_GPIO1_IO05__PWM4_OUT 0x0070 0x02fc 0x0000 1 0 -#define MX6UL_PAD_GPIO1_IO05__ANATOP_OTG2_ID 0x0070 0x02fc 0x04bc 2 0 -#define MX6UL_PAD_GPIO1_IO05__CSI_FIELD 0x0070 0x02fc 0x0530 3 0 -#define MX6UL_PAD_GPIO1_IO05__USDHC1_VSELECT 0x0070 0x02fc 0x0000 4 0 -#define MX6UL_PAD_GPIO1_IO05__GPIO1_IO05 0x0070 0x02fc 0x0000 5 0 -#define MX6UL_PAD_GPIO1_IO05__ENET2_1588_EVENT0_OUT 0x0070 0x02fc 0x0000 6 0 -#define MX6UL_PAD_GPIO1_IO05__UART5_DCE_RX 0x0070 0x02fc 0x0644 8 3 -#define MX6UL_PAD_GPIO1_IO05__UART5_DTE_TX 0x0070 0x02fc 0x0000 8 0 -#define MX6UL_PAD_GPIO1_IO06__ENET1_MDIO 0x0074 0x0300 0x0578 0 0 -#define MX6UL_PAD_GPIO1_IO06__ENET2_MDIO 0x0074 0x0300 0x0580 1 0 -#define MX6UL_PAD_GPIO1_IO06__USB_OTG_PWR_WAKE 0x0074 0x0300 0x0000 2 0 -#define MX6UL_PAD_GPIO1_IO06__CSI_MCLK 0x0074 0x0300 0x0000 3 0 -#define MX6UL_PAD_GPIO1_IO06__USDHC2_WP 0x0074 0x0300 0x069c 4 0 -#define MX6UL_PAD_GPIO1_IO06__GPIO1_IO06 0x0074 0x0300 0x0000 5 0 -#define MX6UL_PAD_GPIO1_IO06__CCM_WAIT 0x0074 0x0300 0x0000 6 0 -#define MX6UL_PAD_GPIO1_IO06__CCM_REF_EN_B 0x0074 0x0300 0x0000 7 0 -#define MX6UL_PAD_GPIO1_IO06__UART1_DCE_CTS 0x0074 0x0300 0x0000 8 0 -#define MX6UL_PAD_GPIO1_IO06__UART1_DTE_RTS 0x0074 0x0300 0x0620 8 0 -#define MX6UL_PAD_GPIO1_IO07__ENET1_MDC 0x0078 0x0304 0x0000 0 0 -#define MX6UL_PAD_GPIO1_IO07__ENET2_MDC 0x0078 0x0304 0x0000 1 0 -#define MX6UL_PAD_GPIO1_IO07__USB_OTG_HOST_MODE 0x0078 0x0304 0x0000 2 0 -#define MX6UL_PAD_GPIO1_IO07__CSI_PIXCLK 0x0078 0x0304 0x0528 3 0 -#define MX6UL_PAD_GPIO1_IO07__USDHC2_CD_B 0x0078 0x0304 0x0674 4 1 -#define MX6UL_PAD_GPIO1_IO07__GPIO1_IO07 0x0078 0x0304 0x0000 5 0 -#define MX6UL_PAD_GPIO1_IO07__CCM_STOP 0x0078 0x0304 0x0000 6 0 -#define MX6UL_PAD_GPIO1_IO07__UART1_DCE_RTS 0x0078 0x0304 0x0620 8 1 -#define MX6UL_PAD_GPIO1_IO07__UART1_DTE_CTS 0x0078 0x0304 0x0000 8 0 -#define MX6UL_PAD_GPIO1_IO08__PWM1_OUT 0x007c 0x0308 0x0000 0 0 -#define MX6UL_PAD_GPIO1_IO08__WDOG1_WDOG_B 0x007c 0x0308 0x0000 1 0 -#define MX6UL_PAD_GPIO1_IO08__SPDIF_OUT 0x007c 0x0308 0x0000 2 0 -#define MX6UL_PAD_GPIO1_IO08__CSI_VSYNC 0x007c 0x0308 0x052c 3 1 -#define MX6UL_PAD_GPIO1_IO08__USDHC2_VSELECT 0x007c 0x0308 0x0000 4 0 -#define MX6UL_PAD_GPIO1_IO08__GPIO1_IO08 0x007c 0x0308 0x0000 5 0 -#define MX6UL_PAD_GPIO1_IO08__CCM_PMIC_RDY 0x007c 0x0308 0x04c0 6 1 -#define MX6UL_PAD_GPIO1_IO08__UART5_DCE_RTS 0x007c 0x0308 0x0640 8 1 -#define MX6UL_PAD_GPIO1_IO08__UART5_DTE_CTS 0x007c 0x0308 0x0000 8 0 -#define MX6UL_PAD_GPIO1_IO09__PWM2_OUT 0x0080 0x030c 0x0000 0 0 -#define MX6UL_PAD_GPIO1_IO09__WDOG1_WDOG_ANY 0x0080 0x030c 0x0000 1 0 -#define MX6UL_PAD_GPIO1_IO09__SPDIF_IN 0x0080 0x030c 0x0618 2 0 -#define MX6UL_PAD_GPIO1_IO09__CSI_HSYNC 0x0080 0x030c 0x0524 3 1 -#define MX6UL_PAD_GPIO1_IO09__USDHC2_RESET_B 0x0080 0x030c 0x0000 4 0 -#define MX6UL_PAD_GPIO1_IO09__GPIO1_IO09 0x0080 0x030c 0x0000 5 0 -#define MX6UL_PAD_GPIO1_IO09__USDHC1_RESET_B 0x0080 0x030c 0x0000 6 0 -#define MX6UL_PAD_GPIO1_IO09__UART5_DCE_CTS 0x0080 0x030c 0x0000 8 0 -#define MX6UL_PAD_GPIO1_IO09__UART5_DTE_RTS 0x0080 0x030c 0x0640 8 2 -#define MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX 0x0084 0x0310 0x0000 0 0 -#define MX6UL_PAD_UART1_TX_DATA__UART1_DTE_RX 0x0084 0x0310 0x0624 0 2 -#define MX6UL_PAD_UART1_TX_DATA__ENET1_RDATA02 0x0084 0x0310 0x0000 1 0 -#define MX6UL_PAD_UART1_TX_DATA__I2C3_SCL 0x0084 0x0310 0x05b4 2 0 -#define MX6UL_PAD_UART1_TX_DATA__CSI_DATA02 0x0084 0x0310 0x0000 3 0 -#define MX6UL_PAD_UART1_TX_DATA__GPT1_COMPARE1 0x0084 0x0310 0x0000 4 0 -#define MX6UL_PAD_UART1_TX_DATA__GPIO1_IO16 0x0084 0x0310 0x0000 5 0 -#define MX6UL_PAD_UART1_TX_DATA__SPDIF_OUT 0x0084 0x0310 0x0000 8 0 -#define MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX 0x0088 0x0314 0x0624 0 3 -#define MX6UL_PAD_UART1_RX_DATA__UART1_DTE_TX 0x0088 0x0314 0x0000 0 0 -#define MX6UL_PAD_UART1_RX_DATA__ENET1_RDATA03 0x0088 0x0314 0x0000 1 0 -#define MX6UL_PAD_UART1_RX_DATA__I2C3_SDA 0x0088 0x0314 0x05b8 2 0 -#define MX6UL_PAD_UART1_RX_DATA__CSI_DATA03 0x0088 0x0314 0x0000 3 0 -#define MX6UL_PAD_UART1_RX_DATA__GPT1_CLK 0x0088 0x0314 0x0594 4 0 -#define MX6UL_PAD_UART1_RX_DATA__GPIO1_IO17 0x0088 0x0314 0x0000 5 0 -#define MX6UL_PAD_UART1_RX_DATA__SPDIF_IN 0x0088 0x0314 0x0000 8 0 -#define MX6UL_PAD_UART1_CTS_B__UART1_DCE_CTS 0x008c 0x0318 0x0000 0 0 -#define MX6UL_PAD_UART1_CTS_B__UART1_DTE_RTS 0x008c 0x0318 0x0620 0 2 -#define MX6UL_PAD_UART1_CTS_B__ENET1_RX_CLK 0x008c 0x0318 0x0000 1 0 -#define MX6UL_PAD_UART1_CTS_B__USDHC1_WP 0x008c 0x0318 0x066c 2 1 -#define MX6UL_PAD_UART1_CTS_B__CSI_DATA04 0x008c 0x0318 0x0000 3 0 -#define MX6UL_PAD_UART1_CTS_B__ENET2_1588_EVENT1_IN 0x008c 0x0318 0x0000 4 0 -#define MX6UL_PAD_UART1_CTS_B__GPIO1_IO18 0x008c 0x0318 0x0000 5 0 -#define MX6UL_PAD_UART1_CTS_B__USDHC2_WP 0x008c 0x0318 0x0000 8 0 -#define MX6UL_PAD_UART1_RTS_B__UART1_DCE_RTS 0x0090 0x031c 0x0620 0 3 -#define MX6UL_PAD_UART1_RTS_B__UART1_DTE_CTS 0x0090 0x031c 0x0000 0 0 -#define MX6UL_PAD_UART1_RTS_B__ENET1_TX_ER 0x0090 0x031c 0x0000 1 0 -#define MX6UL_PAD_UART1_RTS_B__USDHC1_CD_B 0x0090 0x031c 0x0668 2 1 -#define MX6UL_PAD_UART1_RTS_B__CSI_DATA05 0x0090 0x031c 0x0000 3 0 -#define MX6UL_PAD_UART1_RTS_B__ENET2_1588_EVENT1_OUT 0x0090 0x031c 0x0000 4 0 -#define MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x0090 0x031c 0x0000 5 0 -#define MX6UL_PAD_UART1_RTS_B__USDHC2_CD_B 0x0090 0x031c 0x0000 8 0 -#define MX6UL_PAD_UART2_TX_DATA__UART2_DCE_TX 0x0094 0x0320 0x0000 0 0 -#define MX6UL_PAD_UART2_TX_DATA__UART2_DTE_RX 0x0094 0x0320 0x062c 0 0 -#define MX6UL_PAD_UART2_TX_DATA__ENET1_TDATA02 0x0094 0x0320 0x0000 1 0 -#define MX6UL_PAD_UART2_TX_DATA__I2C4_SCL 0x0094 0x0320 0x05bc 2 0 -#define MX6UL_PAD_UART2_TX_DATA__CSI_DATA06 0x0094 0x0320 0x0000 3 0 -#define MX6UL_PAD_UART2_TX_DATA__GPT1_CAPTURE1 0x0094 0x0320 0x058c 4 1 -#define MX6UL_PAD_UART2_TX_DATA__GPIO1_IO20 0x0094 0x0320 0x0000 5 0 -#define MX6UL_PAD_UART2_TX_DATA__ECSPI3_SS0 0x0094 0x0320 0x0000 8 0 -#define MX6UL_PAD_UART2_RX_DATA__UART2_DCE_RX 0x0098 0x0324 0x062c 0 1 -#define MX6UL_PAD_UART2_RX_DATA__UART2_DTE_TX 0x0098 0x0324 0x0000 0 0 -#define MX6UL_PAD_UART2_RX_DATA__ENET1_TDATA03 0x0098 0x0324 0x0000 1 0 -#define MX6UL_PAD_UART2_RX_DATA__I2C4_SDA 0x0098 0x0324 0x05c0 2 0 -#define MX6UL_PAD_UART2_RX_DATA__CSI_DATA07 0x0098 0x0324 0x0000 3 0 -#define MX6UL_PAD_UART2_RX_DATA__GPT1_CAPTURE2 0x0098 0x0324 0x0590 4 0 -#define MX6UL_PAD_UART2_RX_DATA__GPIO1_IO21 0x0098 0x0324 0x0000 5 0 -#define MX6UL_PAD_UART2_RX_DATA__SJC_DONE 0x0098 0x0324 0x0000 7 0 -#define MX6UL_PAD_UART2_RX_DATA__ECSPI3_SCLK 0x0098 0x0324 0x0000 8 0 -#define MX6UL_PAD_UART2_CTS_B__UART2_DCE_CTS 0x009c 0x0328 0x0000 0 0 -#define MX6UL_PAD_UART2_CTS_B__UART2_DTE_RTS 0x009c 0x0328 0x0628 0 0 -#define MX6UL_PAD_UART2_CTS_B__ENET1_CRS 0x009c 0x0328 0x0000 1 0 -#define MX6UL_PAD_UART2_CTS_B__FLEXCAN2_TX 0x009c 0x0328 0x0000 2 0 -#define MX6UL_PAD_UART2_CTS_B__CSI_DATA08 0x009c 0x0328 0x0000 3 0 -#define MX6UL_PAD_UART2_CTS_B__GPT1_COMPARE2 0x009c 0x0328 0x0000 4 0 -#define MX6UL_PAD_UART2_CTS_B__GPIO1_IO22 0x009c 0x0328 0x0000 5 0 -#define MX6UL_PAD_UART2_CTS_B__SJC_DE_B 0x009c 0x0328 0x0000 7 0 -#define MX6UL_PAD_UART2_CTS_B__ECSPI3_MOSI 0x009c 0x0328 0x0000 8 0 -#define MX6UL_PAD_UART2_RTS_B__UART2_DCE_RTS 0x00a0 0x032c 0x0628 0 1 -#define MX6UL_PAD_UART2_RTS_B__UART2_DTE_CTS 0x00a0 0x032c 0x0000 0 0 -#define MX6UL_PAD_UART2_RTS_B__ENET1_COL 0x00a0 0x032c 0x0000 1 0 -#define MX6UL_PAD_UART2_RTS_B__FLEXCAN2_RX 0x00a0 0x032c 0x0588 2 0 -#define MX6UL_PAD_UART2_RTS_B__CSI_DATA09 0x00a0 0x032c 0x0000 3 0 -#define MX6UL_PAD_UART2_RTS_B__GPT1_COMPARE3 0x00a0 0x032c 0x0000 4 0 -#define MX6UL_PAD_UART2_RTS_B__GPIO1_IO23 0x00a0 0x032c 0x0000 5 0 -#define MX6UL_PAD_UART2_RTS_B__SJC_FAIL 0x00a0 0x032c 0x0000 7 0 -#define MX6UL_PAD_UART2_RTS_B__ECSPI3_MISO 0x00a0 0x032c 0x0000 8 0 -#define MX6UL_PAD_UART3_TX_DATA__UART3_DCE_TX 0x00a4 0x0330 0x0000 0 0 -#define MX6UL_PAD_UART3_TX_DATA__UART3_DTE_RX 0x00a4 0x0330 0x0634 0 0 -#define MX6UL_PAD_UART3_TX_DATA__ENET2_RDATA02 0x00a4 0x0330 0x0000 1 0 -#define MX6UL_PAD_UART3_TX_DATA__SIM1_PORT0_PD 0x00a4 0x0330 0x0000 2 0 -#define MX6UL_PAD_UART3_TX_DATA__CSI_DATA01 0x00a4 0x0330 0x0000 3 0 -#define MX6UL_PAD_UART3_TX_DATA__UART2_DCE_CTS 0x00a4 0x0330 0x0000 4 0 -#define MX6UL_PAD_UART3_TX_DATA__UART2_DTE_RTS 0x00a4 0x0330 0x0628 4 2 -#define MX6UL_PAD_UART3_TX_DATA__GPIO1_IO24 0x00a4 0x0330 0x0000 5 0 -#define MX6UL_PAD_UART3_TX_DATA__SJC_JTAG_ACT 0x00a4 0x0330 0x0000 7 0 -#define MX6UL_PAD_UART3_TX_DATA__ANATOP_OTG1_ID 0x00a4 0x0330 0x0000 8 0 -#define MX6UL_PAD_UART3_RX_DATA__UART3_DCE_RX 0x00a8 0x0334 0x0634 0 1 -#define MX6UL_PAD_UART3_RX_DATA__UART3_DTE_TX 0x00a8 0x0334 0x0000 0 0 -#define MX6UL_PAD_UART3_RX_DATA__ENET2_RDATA03 0x00a8 0x0334 0x0000 1 0 -#define MX6UL_PAD_UART3_RX_DATA__SIM2_PORT0_PD 0x00a8 0x0334 0x0000 2 0 -#define MX6UL_PAD_UART3_RX_DATA__CSI_DATA00 0x00a8 0x0334 0x0000 3 0 -#define MX6UL_PAD_UART3_RX_DATA__UART2_DCE_RTS 0x00a8 0x0334 0x0628 4 3 -#define MX6UL_PAD_UART3_RX_DATA__UART2_DTE_CTS 0x00a8 0x0334 0x0000 4 0 -#define MX6UL_PAD_UART3_RX_DATA__GPIO1_IO25 0x00a8 0x0334 0x0000 5 0 -#define MX6UL_PAD_UART3_RX_DATA__EPIT1_OUT 0x00a8 0x0334 0x0000 8 0 -#define MX6UL_PAD_UART3_CTS_B__UART3_DCE_CTS 0x00ac 0x0338 0x0000 0 0 -#define MX6UL_PAD_UART3_CTS_B__UART3_DTE_RTS 0x00ac 0x0338 0x0630 0 0 -#define MX6UL_PAD_UART3_CTS_B__ENET2_RX_CLK 0x00ac 0x0338 0x0000 1 0 -#define MX6UL_PAD_UART3_CTS_B__FLEXCAN1_TX 0x00ac 0x0338 0x0000 2 0 -#define MX6UL_PAD_UART3_CTS_B__CSI_DATA10 0x00ac 0x0338 0x0000 3 0 -#define MX6UL_PAD_UART3_CTS_B__ENET1_1588_EVENT1_IN 0x00ac 0x0338 0x0000 4 0 -#define MX6UL_PAD_UART3_CTS_B__GPIO1_IO26 0x00ac 0x0338 0x0000 5 0 -#define MX6UL_PAD_UART3_CTS_B__EPIT2_OUT 0x00ac 0x0338 0x0000 8 0 -#define MX6UL_PAD_UART3_RTS_B__UART3_DCE_RTS 0x00b0 0x033c 0x0630 0 1 -#define MX6UL_PAD_UART3_RTS_B__UART3_DTE_CTS 0x00b0 0x033c 0x0000 0 0 -#define MX6UL_PAD_UART3_RTS_B__ENET2_TX_ER 0x00b0 0x033c 0x0000 1 0 -#define MX6UL_PAD_UART3_RTS_B__FLEXCAN1_RX 0x00b0 0x033c 0x0584 2 0 -#define MX6UL_PAD_UART3_RTS_B__CSI_DATA11 0x00b0 0x033c 0x0000 3 0 -#define MX6UL_PAD_UART3_RTS_B__ENET1_1588_EVENT1_OUT 0x00b0 0x033c 0x0000 4 0 -#define MX6UL_PAD_UART3_RTS_B__GPIO1_IO27 0x00b0 0x033c 0x0000 5 0 -#define MX6UL_PAD_UART3_RTS_B__WDOG1_WDOG_B 0x00b0 0x033c 0x0000 8 0 -#define MX6UL_PAD_UART4_TX_DATA__UART4_DCE_TX 0x00b4 0x0340 0x0000 0 0 -#define MX6UL_PAD_UART4_TX_DATA__UART4_DTE_RX 0x00b4 0x0340 0x063c 0 0 -#define MX6UL_PAD_UART4_TX_DATA__ENET2_TDATA02 0x00b4 0x0340 0x0000 1 0 -#define MX6UL_PAD_UART4_TX_DATA__I2C1_SCL 0x00b4 0x0340 0x05a4 2 1 -#define MX6UL_PAD_UART4_TX_DATA__CSI_DATA12 0x00b4 0x0340 0x0000 3 0 -#define MX6UL_PAD_UART4_TX_DATA__CSU_CSU_ALARM_AUT02 0x00b4 0x0340 0x0000 4 0 -#define MX6UL_PAD_UART4_TX_DATA__GPIO1_IO28 0x00b4 0x0340 0x0000 5 0 -#define MX6UL_PAD_UART4_TX_DATA__ECSPI2_SCLK 0x00b4 0x0340 0x0000 8 0 -#define MX6UL_PAD_UART4_RX_DATA__UART4_DCE_RX 0x00b8 0x0344 0x063c 0 1 -#define MX6UL_PAD_UART4_RX_DATA__UART4_DTE_TX 0x00b8 0x0344 0x0000 0 0 -#define MX6UL_PAD_UART4_RX_DATA__ENET2_TDATA03 0x00b8 0x0344 0x0000 1 0 -#define MX6UL_PAD_UART4_RX_DATA__I2C1_SDA 0x00b8 0x0344 0x05a8 2 2 -#define MX6UL_PAD_UART4_RX_DATA__CSI_DATA13 0x00b8 0x0344 0x0000 3 0 -#define MX6UL_PAD_UART4_RX_DATA__CSU_CSU_ALARM_AUT01 0x00b8 0x0344 0x0000 4 0 -#define MX6UL_PAD_UART4_RX_DATA__GPIO1_IO29 0x00b8 0x0344 0x0000 5 0 -#define MX6UL_PAD_UART4_RX_DATA__ECSPI2_SS0 0x00b8 0x0344 0x0000 8 0 -#define MX6UL_PAD_UART5_TX_DATA__GPIO1_IO30 0x00bc 0x0348 0x0000 5 0 -#define MX6UL_PAD_UART5_TX_DATA__ECSPI2_MOSI 0x00bc 0x0348 0x0000 8 0 -#define MX6UL_PAD_UART5_TX_DATA__UART5_DCE_TX 0x00bc 0x0348 0x0000 0 0 -#define MX6UL_PAD_UART5_TX_DATA__UART5_DTE_RX 0x00bc 0x0348 0x0644 0 4 -#define MX6UL_PAD_UART5_TX_DATA__ENET2_CRS 0x00bc 0x0348 0x0000 1 0 -#define MX6UL_PAD_UART5_TX_DATA__I2C2_SCL 0x00bc 0x0348 0x05ac 2 2 -#define MX6UL_PAD_UART5_TX_DATA__CSI_DATA14 0x00bc 0x0348 0x0000 3 0 -#define MX6UL_PAD_UART5_TX_DATA__CSU_CSU_ALARM_AUT00 0x00bc 0x0348 0x0000 4 0 -#define MX6UL_PAD_UART5_RX_DATA__UART5_DCE_RX 0x00c0 0x034c 0x0644 0 5 -#define MX6UL_PAD_UART5_RX_DATA__UART5_DTE_TX 0x00c0 0x034c 0x0000 0 0 -#define MX6UL_PAD_UART5_RX_DATA__ENET2_COL 0x00c0 0x034c 0x0000 1 0 -#define MX6UL_PAD_UART5_RX_DATA__I2C2_SDA 0x00c0 0x034c 0x05b0 2 2 -#define MX6UL_PAD_UART5_RX_DATA__CSI_DATA15 0x00c0 0x034c 0x0000 3 0 -#define MX6UL_PAD_UART5_RX_DATA__CSU_CSU_INT_DEB 0x00c0 0x034c 0x0000 4 0 -#define MX6UL_PAD_UART5_RX_DATA__GPIO1_IO31 0x00c0 0x034c 0x0000 5 0 -#define MX6UL_PAD_UART5_RX_DATA__ECSPI2_MISO 0x00c0 0x034c 0x0000 8 0 -#define MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00 0x00c4 0x0350 0x0000 0 0 -#define MX6UL_PAD_ENET1_RX_DATA0__UART4_DCE_RTS 0x00c4 0x0350 0x0638 1 0 -#define MX6UL_PAD_ENET1_RX_DATA0__UART4_DTE_CTS 0x00c4 0x0350 0x0000 1 0 -#define MX6UL_PAD_ENET1_RX_DATA0__PWM1_OUT 0x00c4 0x0350 0x0000 2 0 -#define MX6UL_PAD_ENET1_RX_DATA0__CSI_DATA16 0x00c4 0x0350 0x0000 3 0 -#define MX6UL_PAD_ENET1_RX_DATA0__FLEXCAN1_TX 0x00c4 0x0350 0x0000 4 0 -#define MX6UL_PAD_ENET1_RX_DATA0__GPIO2_IO00 0x00c4 0x0350 0x0000 5 0 -#define MX6UL_PAD_ENET1_RX_DATA0__KPP_ROW00 0x00c4 0x0350 0x0000 6 0 -#define MX6UL_PAD_ENET1_RX_DATA0__USDHC1_LCTL 0x00c4 0x0350 0x0000 8 0 -#define MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x00c8 0x0354 0x0000 0 0 -#define MX6UL_PAD_ENET1_RX_DATA1__UART4_DCE_CTS 0x00c8 0x0354 0x0000 1 0 -#define MX6UL_PAD_ENET1_RX_DATA1__UART4_DTE_RTS 0x00c8 0x0354 0x0638 1 1 -#define MX6UL_PAD_ENET1_RX_DATA1__PWM2_OUT 0x00c8 0x0354 0x0000 2 0 -#define MX6UL_PAD_ENET1_RX_DATA1__CSI_DATA17 0x00c8 0x0354 0x0000 3 0 -#define MX6UL_PAD_ENET1_RX_DATA1__FLEXCAN1_RX 0x00c8 0x0354 0x0584 4 1 -#define MX6UL_PAD_ENET1_RX_DATA1__GPIO2_IO01 0x00c8 0x0354 0x0000 5 0 -#define MX6UL_PAD_ENET1_RX_DATA1__KPP_COL00 0x00c8 0x0354 0x0000 6 0 -#define MX6UL_PAD_ENET1_RX_DATA1__USDHC2_LCTL 0x00c8 0x0354 0x0000 8 0 -#define MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN 0x00cc 0x0358 0x0000 0 0 -#define MX6UL_PAD_ENET1_RX_EN__UART5_DCE_RTS 0x00cc 0x0358 0x0640 1 3 -#define MX6UL_PAD_ENET1_RX_EN__UART5_DTE_CTS 0x00cc 0x0358 0x0000 1 0 -#define MX6UL_PAD_ENET1_RX_EN__CSI_DATA18 0x00cc 0x0358 0x0000 3 0 -#define MX6UL_PAD_ENET1_RX_EN__FLEXCAN2_TX 0x00cc 0x0358 0x0000 4 0 -#define MX6UL_PAD_ENET1_RX_EN__GPIO2_IO02 0x00cc 0x0358 0x0000 5 0 -#define MX6UL_PAD_ENET1_RX_EN__KPP_ROW01 0x00cc 0x0358 0x0000 6 0 -#define MX6UL_PAD_ENET1_RX_EN__USDHC1_VSELECT 0x00cc 0x0358 0x0000 8 0 -#define MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x00d0 0x035c 0x0000 0 0 -#define MX6UL_PAD_ENET1_TX_DATA0__UART5_DCE_CTS 0x00d0 0x035c 0x0000 1 0 -#define MX6UL_PAD_ENET1_TX_DATA0__UART5_DTE_RTS 0x00d0 0x035c 0x0640 1 4 -#define MX6UL_PAD_ENET1_TX_DATA0__CSI_DATA19 0x00d0 0x035c 0x0000 3 0 -#define MX6UL_PAD_ENET1_TX_DATA0__FLEXCAN2_RX 0x00d0 0x035c 0x0588 4 1 -#define MX6UL_PAD_ENET1_TX_DATA0__GPIO2_IO03 0x00d0 0x035c 0x0000 5 0 -#define MX6UL_PAD_ENET1_TX_DATA0__KPP_COL01 0x00d0 0x035c 0x0000 6 0 -#define MX6UL_PAD_ENET1_TX_DATA0__USDHC2_VSELECT 0x00d0 0x035c 0x0000 8 0 -#define MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x00d4 0x0360 0x0000 0 0 -#define MX6UL_PAD_ENET1_TX_DATA1__UART6_DCE_CTS 0x00d4 0x0360 0x0000 1 0 -#define MX6UL_PAD_ENET1_TX_DATA1__UART6_DTE_RTS 0x00d4 0x0360 0x0648 1 2 -#define MX6UL_PAD_ENET1_TX_DATA1__PWM5_OUT 0x00d4 0x0360 0x0000 2 0 -#define MX6UL_PAD_ENET1_TX_DATA1__CSI_DATA20 0x00d4 0x0360 0x0000 3 0 -#define MX6UL_PAD_ENET1_TX_DATA1__ENET2_MDIO 0x00d4 0x0360 0x0580 4 1 -#define MX6UL_PAD_ENET1_TX_DATA1__GPIO2_IO04 0x00d4 0x0360 0x0000 5 0 -#define MX6UL_PAD_ENET1_TX_DATA1__KPP_ROW02 0x00d4 0x0360 0x0000 6 0 -#define MX6UL_PAD_ENET1_TX_DATA1__WDOG1_WDOG_RST_B_DEB 0x00d4 0x0360 0x0000 8 0 -#define MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN 0x00d8 0x0364 0x0000 0 0 -#define MX6UL_PAD_ENET1_TX_EN__UART6_DCE_RTS 0x00d8 0x0364 0x0648 1 3 -#define MX6UL_PAD_ENET1_TX_EN__UART6_DTE_CTS 0x00d8 0x0364 0x0000 1 0 -#define MX6UL_PAD_ENET1_TX_EN__PWM6_OUT 0x00d8 0x0364 0x0000 2 0 -#define MX6UL_PAD_ENET1_TX_EN__CSI_DATA21 0x00d8 0x0364 0x0000 3 0 -#define MX6UL_PAD_ENET1_TX_EN__ENET2_MDC 0x00d8 0x0364 0x0000 4 0 -#define MX6UL_PAD_ENET1_TX_EN__GPIO2_IO05 0x00d8 0x0364 0x0000 5 0 -#define MX6UL_PAD_ENET1_TX_EN__KPP_COL02 0x00d8 0x0364 0x0000 6 0 -#define MX6UL_PAD_ENET1_TX_EN__WDOG2_WDOG_RST_B_DEB 0x00d8 0x0364 0x0000 8 0 -#define MX6UL_PAD_ENET1_TX_CLK__ENET1_TX_CLK 0x00dc 0x0368 0x0000 0 0 -#define MX6UL_PAD_ENET1_TX_CLK__UART7_DCE_CTS 0x00dc 0x0368 0x0000 1 0 -#define MX6UL_PAD_ENET1_TX_CLK__UART7_DTE_RTS 0x00dc 0x0368 0x0650 1 0 -#define MX6UL_PAD_ENET1_TX_CLK__PWM7_OUT 0x00dc 0x0368 0x0000 2 0 -#define MX6UL_PAD_ENET1_TX_CLK__CSI_DATA22 0x00dc 0x0368 0x0000 3 0 -#define MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 0x00dc 0x0368 0x0574 4 2 -#define MX6UL_PAD_ENET1_TX_CLK__GPIO2_IO06 0x00dc 0x0368 0x0000 5 0 -#define MX6UL_PAD_ENET1_TX_CLK__KPP_ROW03 0x00dc 0x0368 0x0000 6 0 -#define MX6UL_PAD_ENET1_TX_CLK__GPT1_CLK 0x00dc 0x0368 0x0000 8 0 -#define MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER 0x00e0 0x036c 0x0000 0 0 -#define MX6UL_PAD_ENET1_RX_ER__UART7_DCE_RTS 0x00e0 0x036c 0x0650 1 1 -#define MX6UL_PAD_ENET1_RX_ER__UART7_DTE_CTS 0x00e0 0x036c 0x0000 1 0 -#define MX6UL_PAD_ENET1_RX_ER__PWM8_OUT 0x00e0 0x036c 0x0000 2 0 -#define MX6UL_PAD_ENET1_RX_ER__CSI_DATA23 0x00e0 0x036c 0x0000 3 0 -#define MX6UL_PAD_ENET1_RX_ER__EIM_CRE 0x00e0 0x036c 0x0000 4 0 -#define MX6UL_PAD_ENET1_RX_ER__GPIO2_IO07 0x00e0 0x036c 0x0000 5 0 -#define MX6UL_PAD_ENET1_RX_ER__KPP_COL03 0x00e0 0x036c 0x0000 6 0 -#define MX6UL_PAD_ENET1_RX_ER__GPT1_CAPTURE2 0x00e0 0x036c 0x0000 8 0 -#define MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00 0x00e4 0x0370 0x0000 0 0 -#define MX6UL_PAD_ENET2_RX_DATA0__UART6_DCE_TX 0x00e4 0x0370 0x0000 1 0 -#define MX6UL_PAD_ENET2_RX_DATA0__UART6_DTE_RX 0x00e4 0x0370 0x064c 1 1 -#define MX6UL_PAD_ENET2_RX_DATA0__SIM1_PORT0_TRXD 0x00e4 0x0370 0x0000 2 0 -#define MX6UL_PAD_ENET2_RX_DATA0__I2C3_SCL 0x00e4 0x0370 0x05b4 3 1 -#define MX6UL_PAD_ENET2_RX_DATA0__ENET1_MDIO 0x00e4 0x0370 0x0578 4 1 -#define MX6UL_PAD_ENET2_RX_DATA0__GPIO2_IO08 0x00e4 0x0370 0x0000 5 0 -#define MX6UL_PAD_ENET2_RX_DATA0__KPP_ROW04 0x00e4 0x0370 0x0000 6 0 -#define MX6UL_PAD_ENET2_RX_DATA0__USB_OTG1_PWR 0x00e4 0x0370 0x0000 8 0 -#define MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x00e8 0x0374 0x0000 0 0 -#define MX6UL_PAD_ENET2_RX_DATA1__UART6_DCE_RX 0x00e8 0x0374 0x064c 1 2 -#define MX6UL_PAD_ENET2_RX_DATA1__UART6_DTE_TX 0x00e8 0x0374 0x0000 1 0 -#define MX6UL_PAD_ENET2_RX_DATA1__SIM1_PORT0_cLK 0x00e8 0x0374 0x0000 2 0 -#define MX6UL_PAD_ENET2_RX_DATA1__I2C3_SDA 0x00e8 0x0374 0x05b8 3 1 -#define MX6UL_PAD_ENET2_RX_DATA1__ENET1_MDC 0x00e8 0x0374 0x0000 4 0 -#define MX6UL_PAD_ENET2_RX_DATA1__GPIO2_IO09 0x00e8 0x0374 0x0000 5 0 -#define MX6UL_PAD_ENET2_RX_DATA1__KPP_COL04 0x00e8 0x0374 0x0000 6 0 -#define MX6UL_PAD_ENET2_RX_DATA1__USB_OTG1_OC 0x00e8 0x0374 0x0000 8 0 -#define MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN 0x00ec 0x0378 0x0000 0 0 -#define MX6UL_PAD_ENET2_RX_EN__UART7_DCE_TX 0x00ec 0x0378 0x0000 1 0 -#define MX6UL_PAD_ENET2_RX_EN__UART7_DTE_RX 0x00ec 0x0378 0x0654 1 0 -#define MX6UL_PAD_ENET2_RX_EN__SIM1_PORT0_RST_B 0x00ec 0x0378 0x0000 2 0 -#define MX6UL_PAD_ENET2_RX_EN__I2C4_SCL 0x00ec 0x0378 0x05bc 3 1 -#define MX6UL_PAD_ENET2_RX_EN__EIM_ADDR26 0x00ec 0x0378 0x0000 4 0 -#define MX6UL_PAD_ENET2_RX_EN__GPIO2_IO10 0x00ec 0x0378 0x0000 5 0 -#define MX6UL_PAD_ENET2_RX_EN__KPP_ROW05 0x00ec 0x0378 0x0000 6 0 -#define MX6UL_PAD_ENET2_RX_EN__ENET1_REF_CLK_25M 0x00ec 0x0378 0x0000 8 0 -#define MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x00f0 0x037c 0x0000 0 0 -#define MX6UL_PAD_ENET2_TX_DATA0__UART7_DCE_RX 0x00f0 0x037c 0x0654 1 1 -#define MX6UL_PAD_ENET2_TX_DATA0__UART7_DTE_TX 0x00f0 0x037c 0x0000 1 0 -#define MX6UL_PAD_ENET2_TX_DATA0__SIM1_PORT0_SVEN 0x00f0 0x037c 0x0000 2 0 -#define MX6UL_PAD_ENET2_TX_DATA0__I2C4_SDA 0x00f0 0x037c 0x05c0 3 1 -#define MX6UL_PAD_ENET2_TX_DATA0__EIM_EB_B02 0x00f0 0x037c 0x0000 4 0 -#define MX6UL_PAD_ENET2_TX_DATA0__GPIO2_IO11 0x00f0 0x037c 0x0000 5 0 -#define MX6UL_PAD_ENET2_TX_DATA0__KPP_COL05 0x00f0 0x037c 0x0000 6 0 -#define MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x00f4 0x0380 0x0000 0 0 -#define MX6UL_PAD_ENET2_TX_DATA1__UART8_DCE_TX 0x00f4 0x0380 0x0000 1 0 -#define MX6UL_PAD_ENET2_TX_DATA1__UART8_DTE_RX 0x00f4 0x0380 0x065c 1 0 -#define MX6UL_PAD_ENET2_TX_DATA1__SIM2_PORT0_TRXD 0x00f4 0x0380 0x0000 2 0 -#define MX6UL_PAD_ENET2_TX_DATA1__ECSPI4_SCLK 0x00f4 0x0380 0x0564 3 0 -#define MX6UL_PAD_ENET2_TX_DATA1__EIM_EB_B03 0x00f4 0x0380 0x0000 4 0 -#define MX6UL_PAD_ENET2_TX_DATA1__GPIO2_IO12 0x00f4 0x0380 0x0000 5 0 -#define MX6UL_PAD_ENET2_TX_DATA1__KPP_ROW06 0x00f4 0x0380 0x0000 6 0 -#define MX6UL_PAD_ENET2_TX_DATA1__USB_OTG2_PWR 0x00f4 0x0380 0x0000 8 0 -#define MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN 0x00f8 0x0384 0x0000 0 0 -#define MX6UL_PAD_ENET2_TX_EN__UART8_DCE_RX 0x00f8 0x0384 0x065c 1 1 -#define MX6UL_PAD_ENET2_TX_EN__UART8_DTE_TX 0x00f8 0x0384 0x0000 1 0 -#define MX6UL_PAD_ENET2_TX_EN__SIM2_PORT0_cLK 0x00f8 0x0384 0x0000 2 0 -#define MX6UL_PAD_ENET2_TX_EN__ECSPI4_MOSI 0x00f8 0x0384 0x056c 3 0 -#define MX6UL_PAD_ENET2_TX_EN__EIM_ACLK_FREERUN 0x00f8 0x0384 0x0000 4 0 -#define MX6UL_PAD_ENET2_TX_EN__GPIO2_IO13 0x00f8 0x0384 0x0000 5 0 -#define MX6UL_PAD_ENET2_TX_EN__KPP_COL06 0x00f8 0x0384 0x0000 6 0 -#define MX6UL_PAD_ENET2_TX_EN__USB_OTG2_OC 0x00f8 0x0384 0x0000 8 0 -#define MX6UL_PAD_ENET2_TX_CLK__ENET2_TX_CLK 0x00fc 0x0388 0x0000 0 0 -#define MX6UL_PAD_ENET2_TX_CLK__UART8_DCE_CTS 0x00fc 0x0388 0x0000 1 0 -#define MX6UL_PAD_ENET2_TX_CLK__UART8_DTE_RTS 0x00fc 0x0388 0x0658 1 0 -#define MX6UL_PAD_ENET2_TX_CLK__SIM2_PORT0_RST_B 0x00fc 0x0388 0x0000 2 0 -#define MX6UL_PAD_ENET2_TX_CLK__ECSPI4_MISO 0x00fc 0x0388 0x0568 3 0 -#define MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 0x00fc 0x0388 0x057c 4 2 -#define MX6UL_PAD_ENET2_TX_CLK__GPIO2_IO14 0x00fc 0x0388 0x0000 5 0 -#define MX6UL_PAD_ENET2_TX_CLK__KPP_ROW07 0x00fc 0x0388 0x0000 6 0 -#define MX6UL_PAD_ENET2_TX_CLK__ANATOP_OTG2_ID 0x00fc 0x0388 0x0000 8 0 -#define MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER 0x0100 0x038c 0x0000 0 0 -#define MX6UL_PAD_ENET2_RX_ER__UART8_DCE_RTS 0x0100 0x038c 0x0658 1 1 -#define MX6UL_PAD_ENET2_RX_ER__UART8_DTE_CTS 0x0100 0x038c 0x0000 1 0 -#define MX6UL_PAD_ENET2_RX_ER__SIM2_PORT0_SVEN 0x0100 0x038c 0x0000 2 0 -#define MX6UL_PAD_ENET2_RX_ER__ECSPI4_SS0 0x0100 0x038c 0x0000 3 0 -#define MX6UL_PAD_ENET2_RX_ER__EIM_ADDR25 0x0100 0x038c 0x0000 4 0 -#define MX6UL_PAD_ENET2_RX_ER__GPIO2_IO15 0x0100 0x038c 0x0000 5 0 -#define MX6UL_PAD_ENET2_RX_ER__KPP_COL07 0x0100 0x038c 0x0000 6 0 -#define MX6UL_PAD_ENET2_RX_ER__WDOG1_WDOG_ANY 0x0100 0x038c 0x0000 8 0 -#define MX6UL_PAD_LCD_CLK__LCDIF_CLK 0x0104 0x0390 0x0000 0 0 -#define MX6UL_PAD_LCD_CLK__LCDIF_WR_RWN 0x0104 0x0390 0x0000 1 0 -#define MX6UL_PAD_LCD_CLK__UART4_DCE_TX 0x0104 0x0390 0x0000 2 0 -#define MX6UL_PAD_LCD_CLK__UART4_DTE_RX 0x0104 0x0390 0x063c 2 2 -#define MX6UL_PAD_LCD_CLK__SAI3_MCLK 0x0104 0x0390 0x0000 3 0 -#define MX6UL_PAD_LCD_CLK__EIM_CS2_B 0x0104 0x0390 0x0000 4 0 -#define MX6UL_PAD_LCD_CLK__GPIO3_IO00 0x0104 0x0390 0x0000 5 0 -#define MX6UL_PAD_LCD_CLK__WDOG1_WDOG_RST_B_DEB 0x0104 0x0390 0x0000 8 0 -#define MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE 0x0108 0x0394 0x0000 0 0 -#define MX6UL_PAD_LCD_ENABLE__LCDIF_RD_E 0x0108 0x0394 0x0000 1 0 -#define MX6UL_PAD_LCD_ENABLE__UART4_DCE_RX 0x0108 0x0394 0x063c 2 3 -#define MX6UL_PAD_LCD_ENABLE__UART4_DTE_TX 0x0108 0x0394 0x0000 2 0 -#define MX6UL_PAD_LCD_ENABLE__SAI3_TX_SYNC 0x0108 0x0394 0x060c 3 0 -#define MX6UL_PAD_LCD_ENABLE__EIM_CS3_B 0x0108 0x0394 0x0000 4 0 -#define MX6UL_PAD_LCD_ENABLE__GPIO3_IO01 0x0108 0x0394 0x0000 5 0 -#define MX6UL_PAD_LCD_ENABLE__ECSPI2_RDY 0x0108 0x0394 0x0000 8 0 -#define MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC 0x010c 0x0398 0x05dc 0 0 -#define MX6UL_PAD_LCD_HSYNC__LCDIF_RS 0x010c 0x0398 0x0000 1 0 -#define MX6UL_PAD_LCD_HSYNC__UART4_DCE_CTS 0x010c 0x0398 0x0000 2 0 -#define MX6UL_PAD_LCD_HSYNC__UART4_DTE_RTS 0x010c 0x0398 0x0638 2 2 -#define MX6UL_PAD_LCD_HSYNC__SAI3_TX_BCLK 0x010c 0x0398 0x0608 3 0 -#define MX6UL_PAD_LCD_HSYNC__WDOG3_WDOG_RST_B_DEB 0x010c 0x0398 0x0000 4 0 -#define MX6UL_PAD_LCD_HSYNC__GPIO3_IO02 0x010c 0x0398 0x0000 5 0 -#define MX6UL_PAD_LCD_HSYNC__ECSPI2_SS1 0x010c 0x0398 0x0000 8 0 -#define MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC 0x0110 0x039c 0x0000 0 0 -#define MX6UL_PAD_LCD_VSYNC__LCDIF_BUSY 0x0110 0x039c 0x05dc 1 1 -#define MX6UL_PAD_LCD_VSYNC__UART4_DCE_RTS 0x0110 0x039c 0x0638 2 3 -#define MX6UL_PAD_LCD_VSYNC__UART4_DTE_CTS 0x0110 0x039c 0x0000 2 0 -#define MX6UL_PAD_LCD_VSYNC__SAI3_RX_DATA 0x0110 0x039c 0x0000 3 0 -#define MX6UL_PAD_LCD_VSYNC__WDOG2_WDOG_B 0x0110 0x039c 0x0000 4 0 -#define MX6UL_PAD_LCD_VSYNC__GPIO3_IO03 0x0110 0x039c 0x0000 5 0 -#define MX6UL_PAD_LCD_VSYNC__ECSPI2_SS2 0x0110 0x039c 0x0000 8 0 -#define MX6UL_PAD_LCD_RESET__LCDIF_RESET 0x0114 0x03a0 0x0000 0 0 -#define MX6UL_PAD_LCD_RESET__LCDIF_CS 0x0114 0x03a0 0x0000 1 0 -#define MX6UL_PAD_LCD_RESET__CA7_MX6UL_EVENTI 0x0114 0x03a0 0x0000 2 0 -#define MX6UL_PAD_LCD_RESET__SAI3_TX_DATA 0x0114 0x03a0 0x0000 3 0 -#define MX6UL_PAD_LCD_RESET__WDOG1_WDOG_ANY 0x0114 0x03a0 0x0000 4 0 -#define MX6UL_PAD_LCD_RESET__GPIO3_IO04 0x0114 0x03a0 0x0000 5 0 -#define MX6UL_PAD_LCD_RESET__ECSPI2_SS3 0x0114 0x03a0 0x0000 8 0 -#define MX6UL_PAD_LCD_DATA00__LCDIF_DATA00 0x0118 0x03a4 0x0000 0 0 -#define MX6UL_PAD_LCD_DATA00__PWM1_OUT 0x0118 0x03a4 0x0000 1 0 -#define MX6UL_PAD_LCD_DATA00__ENET1_1588_EVENT2_IN 0x0118 0x03a4 0x0000 3 0 -#define MX6UL_PAD_LCD_DATA00__I2C3_SDA 0x0118 0x03a4 0x05b8 4 2 -#define MX6UL_PAD_LCD_DATA00__GPIO3_IO05 0x0118 0x03a4 0x0000 5 0 -#define MX6UL_PAD_LCD_DATA00__SRC_BT_CFG00 0x0118 0x03a4 0x0000 6 0 -#define MX6UL_PAD_LCD_DATA00__SAI1_MCLK 0x0118 0x03a4 0x0000 8 0 -#define MX6UL_PAD_LCD_DATA01__LCDIF_DATA01 0x011c 0x03a8 0x0000 0 0 -#define MX6UL_PAD_LCD_DATA01__PWM2_OUT 0x011c 0x03a8 0x0000 1 0 -#define MX6UL_PAD_LCD_DATA01__ENET1_1588_EVENT2_OUT 0x011c 0x03a8 0x0000 3 0 -#define MX6UL_PAD_LCD_DATA01__I2C3_SCL 0x011c 0x03a8 0x05b4 4 2 -#define MX6UL_PAD_LCD_DATA01__GPIO3_IO06 0x011c 0x03a8 0x0000 5 0 -#define MX6UL_PAD_LCD_DATA01__SRC_BT_CFG01 0x011c 0x03a8 0x0000 6 0 -#define MX6UL_PAD_LCD_DATA01__SAI1_TX_SYNC 0x011c 0x03a8 0x0000 8 0 -#define MX6UL_PAD_LCD_DATA02__LCDIF_DATA02 0x0120 0x03ac 0x0000 0 0 -#define MX6UL_PAD_LCD_DATA02__PWM3_OUT 0x0120 0x03ac 0x0000 1 0 -#define MX6UL_PAD_LCD_DATA02__ENET1_1588_EVENT3_IN 0x0120 0x03ac 0x0000 3 0 -#define MX6UL_PAD_LCD_DATA02__I2C4_SDA 0x0120 0x03ac 0x05c0 4 2 -#define MX6UL_PAD_LCD_DATA02__GPIO3_IO07 0x0120 0x03ac 0x0000 5 0 -#define MX6UL_PAD_LCD_DATA02__SRC_BT_CFG02 0x0120 0x03ac 0x0000 6 0 -#define MX6UL_PAD_LCD_DATA02__SAI1_TX_BCLK 0x0120 0x03ac 0x0000 8 0 -#define MX6UL_PAD_LCD_DATA03__LCDIF_DATA03 0x0124 0x03b0 0x0000 0 0 -#define MX6UL_PAD_LCD_DATA03__PWM4_OUT 0x0124 0x03b0 0x0000 1 0 -#define MX6UL_PAD_LCD_DATA03__ENET1_1588_EVENT3_OUT 0x0124 0x03b0 0x0000 3 0 -#define MX6UL_PAD_LCD_DATA03__I2C4_SCL 0x0124 0x03b0 0x05bc 4 2 -#define MX6UL_PAD_LCD_DATA03__GPIO3_IO08 0x0124 0x03b0 0x0000 5 0 -#define MX6UL_PAD_LCD_DATA03__SRC_BT_CFG03 0x0124 0x03b0 0x0000 6 0 -#define MX6UL_PAD_LCD_DATA03__SAI1_RX_DATA 0x0124 0x03b0 0x0000 8 0 -#define MX6UL_PAD_LCD_DATA04__LCDIF_DATA04 0x0128 0x03b4 0x0000 0 0 -#define MX6UL_PAD_LCD_DATA04__UART8_DCE_CTS 0x0128 0x03b4 0x0000 1 0 -#define MX6UL_PAD_LCD_DATA04__UART8_DTE_RTS 0x0128 0x03b4 0x0658 1 2 -#define MX6UL_PAD_LCD_DATA04__ENET2_1588_EVENT2_IN 0x0128 0x03b4 0x0000 3 0 -#define MX6UL_PAD_LCD_DATA04__SPDIF_SR_CLK 0x0128 0x03b4 0x0000 4 0 -#define MX6UL_PAD_LCD_DATA04__GPIO3_IO09 0x0128 0x03b4 0x0000 5 0 -#define MX6UL_PAD_LCD_DATA04__SRC_BT_CFG04 0x0128 0x03b4 0x0000 6 0 -#define MX6UL_PAD_LCD_DATA04__SAI1_TX_DATA 0x0128 0x03b4 0x0000 8 0 -#define MX6UL_PAD_LCD_DATA05__LCDIF_DATA05 0x012c 0x03b8 0x0000 0 0 -#define MX6UL_PAD_LCD_DATA05__UART8_DCE_RTS 0x012c 0x03b8 0x0658 1 3 -#define MX6UL_PAD_LCD_DATA05__UART8_DTE_CTS 0x012c 0x03b8 0x0000 1 0 -#define MX6UL_PAD_LCD_DATA05__ENET2_1588_EVENT2_OUT 0x012c 0x03b8 0x0000 3 0 -#define MX6UL_PAD_LCD_DATA05__SPDIF_OUT 0x012c 0x03b8 0x0000 4 0 -#define MX6UL_PAD_LCD_DATA05__GPIO3_IO10 0x012c 0x03b8 0x0000 5 0 -#define MX6UL_PAD_LCD_DATA05__SRC_BT_CFG05 0x012c 0x03b8 0x0000 6 0 -#define MX6UL_PAD_LCD_DATA05__ECSPI1_SS1 0x012c 0x03b8 0x0000 8 0 -#define MX6UL_PAD_LCD_DATA06__LCDIF_DATA06 0x0130 0x03bc 0x0000 0 0 -#define MX6UL_PAD_LCD_DATA06__UART7_DCE_CTS 0x0130 0x03bc 0x0000 1 0 -#define MX6UL_PAD_LCD_DATA06__UART7_DTE_RTS 0x0130 0x03bc 0x0650 1 2 -#define MX6UL_PAD_LCD_DATA06__ENET2_1588_EVENT3_IN 0x0130 0x03bc 0x0000 3 0 -#define MX6UL_PAD_LCD_DATA06__SPDIF_LOCK 0x0130 0x03bc 0x0000 4 0 -#define MX6UL_PAD_LCD_DATA06__GPIO3_IO11 0x0130 0x03bc 0x0000 5 0 -#define MX6UL_PAD_LCD_DATA06__SRC_BT_CFG06 0x0130 0x03bc 0x0000 6 0 -#define MX6UL_PAD_LCD_DATA06__ECSPI1_SS2 0x0130 0x03bc 0x0000 8 0 -#define MX6UL_PAD_LCD_DATA07__LCDIF_DATA07 0x0134 0x03c0 0x0000 0 0 -#define MX6UL_PAD_LCD_DATA07__UART7_DCE_RTS 0x0134 0x03c0 0x0650 1 3 -#define MX6UL_PAD_LCD_DATA07__UART7_DTE_CTS 0x0134 0x03c0 0x0000 1 0 -#define MX6UL_PAD_LCD_DATA07__ENET2_1588_EVENT3_OUT 0x0134 0x03c0 0x0000 3 0 -#define MX6UL_PAD_LCD_DATA07__SPDIF_EXT_CLK 0x0134 0x03c0 0x061c 4 0 -#define MX6UL_PAD_LCD_DATA07__GPIO3_IO12 0x0134 0x03c0 0x0000 5 0 -#define MX6UL_PAD_LCD_DATA07__SRC_BT_CFG07 0x0134 0x03c0 0x0000 6 0 -#define MX6UL_PAD_LCD_DATA07__ECSPI1_SS3 0x0134 0x03c0 0x0000 8 0 -#define MX6UL_PAD_LCD_DATA08__LCDIF_DATA08 0x0138 0x03c4 0x0000 0 0 -#define MX6UL_PAD_LCD_DATA08__SPDIF_IN 0x0138 0x03c4 0x0618 1 2 -#define MX6UL_PAD_LCD_DATA08__CSI_DATA16 0x0138 0x03c4 0x0000 3 0 -#define MX6UL_PAD_LCD_DATA08__EIM_DATA00 0x0138 0x03c4 0x0000 4 0 -#define MX6UL_PAD_LCD_DATA08__GPIO3_IO13 0x0138 0x03c4 0x0000 5 0 -#define MX6UL_PAD_LCD_DATA08__SRC_BT_CFG08 0x0138 0x03c4 0x0000 6 0 -#define MX6UL_PAD_LCD_DATA08__FLEXCAN1_TX 0x0138 0x03c4 0x0000 8 0 -#define MX6UL_PAD_LCD_DATA09__LCDIF_DATA09 0x013c 0x03c8 0x0000 0 0 -#define MX6UL_PAD_LCD_DATA09__SAI3_MCLK 0x013c 0x03c8 0x0000 1 0 -#define MX6UL_PAD_LCD_DATA09__CSI_DATA17 0x013c 0x03c8 0x0000 3 0 -#define MX6UL_PAD_LCD_DATA09__EIM_DATA01 0x013c 0x03c8 0x0000 4 0 -#define MX6UL_PAD_LCD_DATA09__GPIO3_IO14 0x013c 0x03c8 0x0000 5 0 -#define MX6UL_PAD_LCD_DATA09__SRC_BT_CFG09 0x013c 0x03c8 0x0000 6 0 -#define MX6UL_PAD_LCD_DATA09__FLEXCAN1_RX 0x013c 0x03c8 0x0000 8 0 -#define MX6UL_PAD_LCD_DATA10__LCDIF_DATA10 0x0140 0x03cc 0x0000 0 0 -#define MX6UL_PAD_LCD_DATA10__SAI3_RX_SYNC 0x0140 0x03cc 0x0000 1 0 -#define MX6UL_PAD_LCD_DATA10__CSI_DATA18 0x0140 0x03cc 0x0000 3 0 -#define MX6UL_PAD_LCD_DATA10__EIM_DATA02 0x0140 0x03cc 0x0000 4 0 -#define MX6UL_PAD_LCD_DATA10__GPIO3_IO15 0x0140 0x03cc 0x0000 5 0 -#define MX6UL_PAD_LCD_DATA10__SRC_BT_CFG10 0x0140 0x03cc 0x0000 6 0 -#define MX6UL_PAD_LCD_DATA10__FLEXCAN2_TX 0x0140 0x03cc 0x0000 8 0 -#define MX6UL_PAD_LCD_DATA11__LCDIF_DATA11 0x0144 0x03d0 0x0000 0 0 -#define MX6UL_PAD_LCD_DATA11__SAI3_RX_BCLK 0x0144 0x03d0 0x0000 1 0 -#define MX6UL_PAD_LCD_DATA11__CSI_DATA19 0x0144 0x03d0 0x0000 3 0 -#define MX6UL_PAD_LCD_DATA11__EIM_DATA03 0x0144 0x03d0 0x0000 4 0 -#define MX6UL_PAD_LCD_DATA11__GPIO3_IO16 0x0144 0x03d0 0x0000 5 0 -#define MX6UL_PAD_LCD_DATA11__SRC_BT_CFG11 0x0144 0x03d0 0x0000 6 0 -#define MX6UL_PAD_LCD_DATA11__FLEXCAN2_RX 0x0144 0x03d0 0x0000 8 0 -#define MX6UL_PAD_LCD_DATA12__LCDIF_DATA12 0x0148 0x03d4 0x0000 0 0 -#define MX6UL_PAD_LCD_DATA12__SAI3_TX_SYNC 0x0148 0x03d4 0x060c 1 1 -#define MX6UL_PAD_LCD_DATA12__CSI_DATA20 0x0148 0x03d4 0x0000 3 0 -#define MX6UL_PAD_LCD_DATA12__EIM_DATA04 0x0148 0x03d4 0x0000 4 0 -#define MX6UL_PAD_LCD_DATA12__GPIO3_IO17 0x0148 0x03d4 0x0000 5 0 -#define MX6UL_PAD_LCD_DATA12__SRC_BT_CFG12 0x0148 0x03d4 0x0000 6 0 -#define MX6UL_PAD_LCD_DATA12__ECSPI1_RDY 0x0148 0x03d4 0x0000 8 0 -#define MX6UL_PAD_LCD_DATA13__LCDIF_DATA13 0x014c 0x03d8 0x0000 0 0 -#define MX6UL_PAD_LCD_DATA13__SAI3_TX_BCLK 0x014c 0x03d8 0x0608 1 1 -#define MX6UL_PAD_LCD_DATA13__CSI_DATA21 0x014c 0x03d8 0x0000 3 0 -#define MX6UL_PAD_LCD_DATA13__EIM_DATA05 0x014c 0x03d8 0x0000 4 0 -#define MX6UL_PAD_LCD_DATA13__GPIO3_IO18 0x014c 0x03d8 0x0000 5 0 -#define MX6UL_PAD_LCD_DATA13__SRC_BT_CFG13 0x014c 0x03d8 0x0000 6 0 -#define MX6UL_PAD_LCD_DATA13__USDHC2_RESET_B 0x014c 0x03d8 0x0000 8 0 -#define MX6UL_PAD_LCD_DATA14__LCDIF_DATA14 0x0150 0x03dc 0x0000 0 0 -#define MX6UL_PAD_LCD_DATA14__SAI3_RX_DATA 0x0150 0x03dc 0x0000 1 0 -#define MX6UL_PAD_LCD_DATA14__CSI_DATA22 0x0150 0x03dc 0x0000 3 0 -#define MX6UL_PAD_LCD_DATA14__EIM_DATA06 0x0150 0x03dc 0x0000 4 0 -#define MX6UL_PAD_LCD_DATA14__GPIO3_IO19 0x0150 0x03dc 0x0000 5 0 -#define MX6UL_PAD_LCD_DATA14__SRC_BT_CFG14 0x0150 0x03dc 0x0000 6 0 -#define MX6UL_PAD_LCD_DATA14__USDHC2_DATA4 0x0150 0x03dc 0x0000 8 0 -#define MX6UL_PAD_LCD_DATA15__LCDIF_DATA15 0x0154 0x03e0 0x0000 0 0 -#define MX6UL_PAD_LCD_DATA15__SAI3_TX_DATA 0x0154 0x03e0 0x0000 1 0 -#define MX6UL_PAD_LCD_DATA15__CSI_DATA23 0x0154 0x03e0 0x0000 3 0 -#define MX6UL_PAD_LCD_DATA15__EIM_DATA07 0x0154 0x03e0 0x0000 4 0 -#define MX6UL_PAD_LCD_DATA15__GPIO3_IO20 0x0154 0x03e0 0x0000 5 0 -#define MX6UL_PAD_LCD_DATA15__SRC_BT_CFG15 0x0154 0x03e0 0x0000 6 0 -#define MX6UL_PAD_LCD_DATA15__USDHC2_DATA5 0x0154 0x03e0 0x0000 8 0 -#define MX6UL_PAD_LCD_DATA16__LCDIF_DATA16 0x0158 0x03e4 0x0000 0 0 -#define MX6UL_PAD_LCD_DATA16__UART7_DCE_TX 0x0158 0x03e4 0x0000 1 0 -#define MX6UL_PAD_LCD_DATA16__UART7_DTE_RX 0x0158 0x03e4 0x0654 1 2 -#define MX6UL_PAD_LCD_DATA16__CSI_DATA01 0x0158 0x03e4 0x0000 3 0 -#define MX6UL_PAD_LCD_DATA16__EIM_DATA08 0x0158 0x03e4 0x0000 4 0 -#define MX6UL_PAD_LCD_DATA16__GPIO3_IO21 0x0158 0x03e4 0x0000 5 0 -#define MX6UL_PAD_LCD_DATA16__SRC_BT_CFG24 0x0158 0x03e4 0x0000 6 0 -#define MX6UL_PAD_LCD_DATA16__USDHC2_DATA6 0x0158 0x03e4 0x0000 8 0 -#define MX6UL_PAD_LCD_DATA17__LCDIF_DATA17 0x015c 0x03e8 0x0000 0 0 -#define MX6UL_PAD_LCD_DATA17__UART7_DCE_RX 0x015c 0x03e8 0x0654 1 3 -#define MX6UL_PAD_LCD_DATA17__UART7_DTE_TX 0x015c 0x03e8 0x0000 1 0 -#define MX6UL_PAD_LCD_DATA17__CSI_DATA00 0x015c 0x03e8 0x0000 3 0 -#define MX6UL_PAD_LCD_DATA17__EIM_DATA09 0x015c 0x03e8 0x0000 4 0 -#define MX6UL_PAD_LCD_DATA17__GPIO3_IO22 0x015c 0x03e8 0x0000 5 0 -#define MX6UL_PAD_LCD_DATA17__SRC_BT_CFG25 0x015c 0x03e8 0x0000 6 0 -#define MX6UL_PAD_LCD_DATA17__USDHC2_DATA7 0x015c 0x03e8 0x0000 8 0 -#define MX6UL_PAD_LCD_DATA18__LCDIF_DATA18 0x0160 0x03ec 0x0000 0 0 -#define MX6UL_PAD_LCD_DATA18__PWM5_OUT 0x0160 0x03ec 0x0000 1 0 -#define MX6UL_PAD_LCD_DATA18__CA7_MX6UL_EVENTO 0x0160 0x03ec 0x0000 2 0 -#define MX6UL_PAD_LCD_DATA18__CSI_DATA10 0x0160 0x03ec 0x0000 3 0 -#define MX6UL_PAD_LCD_DATA18__EIM_DATA10 0x0160 0x03ec 0x0000 4 0 -#define MX6UL_PAD_LCD_DATA18__GPIO3_IO23 0x0160 0x03ec 0x0000 5 0 -#define MX6UL_PAD_LCD_DATA18__SRC_BT_CFG26 0x0160 0x03ec 0x0000 6 0 -#define MX6UL_PAD_LCD_DATA18__USDHC2_CMD 0x0160 0x03ec 0x0000 8 0 -#define MX6UL_PAD_LCD_DATA19__EIM_DATA11 0x0164 0x03f0 0x0000 4 0 -#define MX6UL_PAD_LCD_DATA19__GPIO3_IO24 0x0164 0x03f0 0x0000 5 0 -#define MX6UL_PAD_LCD_DATA19__SRC_BT_CFG27 0x0164 0x03f0 0x0000 6 0 -#define MX6UL_PAD_LCD_DATA19__USDHC2_CLK 0x0164 0x03f0 0x0000 8 0 -#define MX6UL_PAD_LCD_DATA19__LCDIF_DATA19 0x0164 0x03f0 0x0000 0 0 -#define MX6UL_PAD_LCD_DATA19__PWM6_OUT 0x0164 0x03f0 0x0000 1 0 -#define MX6UL_PAD_LCD_DATA19__WDOG1_WDOG_ANY 0x0164 0x03f0 0x0000 2 0 -#define MX6UL_PAD_LCD_DATA19__CSI_DATA11 0x0164 0x03f0 0x0000 3 0 -#define MX6UL_PAD_LCD_DATA20__EIM_DATA12 0x0168 0x03f4 0x0000 4 0 -#define MX6UL_PAD_LCD_DATA20__GPIO3_IO25 0x0168 0x03f4 0x0000 5 0 -#define MX6UL_PAD_LCD_DATA20__SRC_BT_CFG28 0x0168 0x03f4 0x0000 6 0 -#define MX6UL_PAD_LCD_DATA20__USDHC2_DATA0 0x0168 0x03f4 0x0000 8 0 -#define MX6UL_PAD_LCD_DATA20__LCDIF_DATA20 0x0168 0x03f4 0x0000 0 0 -#define MX6UL_PAD_LCD_DATA20__UART8_DCE_TX 0x0168 0x03f4 0x0000 1 0 -#define MX6UL_PAD_LCD_DATA20__UART8_DTE_RX 0x0168 0x03f4 0x065c 1 2 -#define MX6UL_PAD_LCD_DATA20__ECSPI1_SCLK 0x0168 0x03f4 0x0534 2 0 -#define MX6UL_PAD_LCD_DATA20__CSI_DATA12 0x0168 0x03f4 0x0000 3 0 -#define MX6UL_PAD_LCD_DATA21__LCDIF_DATA21 0x016c 0x03f8 0x0000 0 0 -#define MX6UL_PAD_LCD_DATA21__UART8_DCE_RX 0x016c 0x03f8 0x065c 1 3 -#define MX6UL_PAD_LCD_DATA21__UART8_DTE_TX 0x016c 0x03f8 0x0000 1 0 -#define MX6UL_PAD_LCD_DATA21__ECSPI1_SS0 0x016c 0x03f8 0x0000 2 0 -#define MX6UL_PAD_LCD_DATA21__CSI_DATA13 0x016c 0x03f8 0x0000 3 0 -#define MX6UL_PAD_LCD_DATA21__EIM_DATA13 0x016c 0x03f8 0x0000 4 0 -#define MX6UL_PAD_LCD_DATA21__GPIO3_IO26 0x016c 0x03f8 0x0000 5 0 -#define MX6UL_PAD_LCD_DATA21__SRC_BT_CFG29 0x016c 0x03f8 0x0000 6 0 -#define MX6UL_PAD_LCD_DATA21__USDHC2_DATA1 0x016c 0x03f8 0x0000 8 0 -#define MX6UL_PAD_LCD_DATA22__LCDIF_DATA22 0x0170 0x03fc 0x0000 0 0 -#define MX6UL_PAD_LCD_DATA22__MQS_RIGHT 0x0170 0x03fc 0x0000 1 0 -#define MX6UL_PAD_LCD_DATA22__ECSPI1_MOSI 0x0170 0x03fc 0x053c 2 0 -#define MX6UL_PAD_LCD_DATA22__CSI_DATA14 0x0170 0x03fc 0x0000 3 0 -#define MX6UL_PAD_LCD_DATA22__EIM_DATA14 0x0170 0x03fc 0x0000 4 0 -#define MX6UL_PAD_LCD_DATA22__GPIO3_IO27 0x0170 0x03fc 0x0000 5 0 -#define MX6UL_PAD_LCD_DATA22__SRC_BT_CFG30 0x0170 0x03fc 0x0000 6 0 -#define MX6UL_PAD_LCD_DATA22__USDHC2_DATA2 0x0170 0x03fc 0x0000 8 0 -#define MX6UL_PAD_LCD_DATA23__LCDIF_DATA23 0x0174 0x0400 0x0000 0 0 -#define MX6UL_PAD_LCD_DATA23__MQS_LEFT 0x0174 0x0400 0x0000 1 0 -#define MX6UL_PAD_LCD_DATA23__ECSPI1_MISO 0x0174 0x0400 0x0538 2 0 -#define MX6UL_PAD_LCD_DATA23__CSI_DATA15 0x0174 0x0400 0x0000 3 0 -#define MX6UL_PAD_LCD_DATA23__EIM_DATA15 0x0174 0x0400 0x0000 4 0 -#define MX6UL_PAD_LCD_DATA23__GPIO3_IO28 0x0174 0x0400 0x0000 5 0 -#define MX6UL_PAD_LCD_DATA23__SRC_BT_CFG31 0x0174 0x0400 0x0000 6 0 -#define MX6UL_PAD_LCD_DATA23__USDHC2_DATA3 0x0174 0x0400 0x0000 8 0 -#define MX6UL_PAD_NAND_RE_B__RAWNAND_RE_B 0x0178 0x0404 0x0000 0 0 -#define MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x0178 0x0404 0x0670 1 2 -#define MX6UL_PAD_NAND_RE_B__QSPI_B_SCLK 0x0178 0x0404 0x0000 2 0 -#define MX6UL_PAD_NAND_RE_B__KPP_ROW00 0x0178 0x0404 0x0000 3 0 -#define MX6UL_PAD_NAND_RE_B__EIM_EB_B00 0x0178 0x0404 0x0000 4 0 -#define MX6UL_PAD_NAND_RE_B__GPIO4_IO00 0x0178 0x0404 0x0000 5 0 -#define MX6UL_PAD_NAND_RE_B__ECSPI3_SS2 0x0178 0x0404 0x0000 8 0 -#define MX6UL_PAD_NAND_WE_B__RAWNAND_WE_B 0x017c 0x0408 0x0000 0 0 -#define MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x017c 0x0408 0x0678 1 2 -#define MX6UL_PAD_NAND_WE_B__QSPI_B_SS0_B 0x017c 0x0408 0x0000 2 0 -#define MX6UL_PAD_NAND_WE_B__KPP_COL00 0x017c 0x0408 0x0000 3 0 -#define MX6UL_PAD_NAND_WE_B__EIM_EB_B01 0x017c 0x0408 0x0000 4 0 -#define MX6UL_PAD_NAND_WE_B__GPIO4_IO01 0x017c 0x0408 0x0000 5 0 -#define MX6UL_PAD_NAND_WE_B__ECSPI3_SS3 0x017c 0x0408 0x0000 8 0 -#define MX6UL_PAD_NAND_DATA00__RAWNAND_DATA00 0x0180 0x040c 0x0000 0 0 -#define MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x0180 0x040c 0x067c 1 2 -#define MX6UL_PAD_NAND_DATA00__QSPI_B_SS1_B 0x0180 0x040c 0x0000 2 0 -#define MX6UL_PAD_NAND_DATA00__KPP_ROW01 0x0180 0x040c 0x0000 3 0 -#define MX6UL_PAD_NAND_DATA00__EIM_AD08 0x0180 0x040c 0x0000 4 0 -#define MX6UL_PAD_NAND_DATA00__GPIO4_IO02 0x0180 0x040c 0x0000 5 0 -#define MX6UL_PAD_NAND_DATA00__ECSPI4_RDY 0x0180 0x040c 0x0000 8 0 -#define MX6UL_PAD_NAND_DATA01__RAWNAND_DATA01 0x0184 0x0410 0x0000 0 0 -#define MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x0184 0x0410 0x0680 1 2 -#define MX6UL_PAD_NAND_DATA01__QSPI_B_DQS 0x0184 0x0410 0x0000 2 0 -#define MX6UL_PAD_NAND_DATA01__KPP_COL01 0x0184 0x0410 0x0000 3 0 -#define MX6UL_PAD_NAND_DATA01__EIM_AD09 0x0184 0x0410 0x0000 4 0 -#define MX6UL_PAD_NAND_DATA01__GPIO4_IO03 0x0184 0x0410 0x0000 5 0 -#define MX6UL_PAD_NAND_DATA01__ECSPI4_SS1 0x0184 0x0410 0x0000 8 0 -#define MX6UL_PAD_NAND_DATA02__RAWNAND_DATA02 0x0188 0x0414 0x0000 0 0 -#define MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x0188 0x0414 0x0684 1 1 -#define MX6UL_PAD_NAND_DATA02__QSPI_B_DATA00 0x0188 0x0414 0x0000 2 0 -#define MX6UL_PAD_NAND_DATA02__KPP_ROW02 0x0188 0x0414 0x0000 3 0 -#define MX6UL_PAD_NAND_DATA02__EIM_AD10 0x0188 0x0414 0x0000 4 0 -#define MX6UL_PAD_NAND_DATA02__GPIO4_IO04 0x0188 0x0414 0x0000 5 0 -#define MX6UL_PAD_NAND_DATA02__ECSPI4_SS2 0x0188 0x0414 0x0000 8 0 -#define MX6UL_PAD_NAND_DATA03__RAWNAND_DATA03 0x018c 0x0418 0x0000 0 0 -#define MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x018c 0x0418 0x0688 1 2 -#define MX6UL_PAD_NAND_DATA03__QSPI_B_DATA01 0x018c 0x0418 0x0000 2 0 -#define MX6UL_PAD_NAND_DATA03__KPP_COL02 0x018c 0x0418 0x0000 3 0 -#define MX6UL_PAD_NAND_DATA03__EIM_AD11 0x018c 0x0418 0x0000 4 0 -#define MX6UL_PAD_NAND_DATA03__GPIO4_IO05 0x018c 0x0418 0x0000 5 0 -#define MX6UL_PAD_NAND_DATA03__ECSPI4_SS3 0x018c 0x0418 0x0000 8 0 -#define MX6UL_PAD_NAND_DATA04__RAWNAND_DATA04 0x0190 0x041c 0x0000 0 0 -#define MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x0190 0x041c 0x068c 1 1 -#define MX6UL_PAD_NAND_DATA04__QSPI_B_DATA02 0x0190 0x041c 0x0000 2 0 -#define MX6UL_PAD_NAND_DATA04__ECSPI4_SCLK 0x0190 0x041c 0x0564 3 1 -#define MX6UL_PAD_NAND_DATA04__EIM_AD12 0x0190 0x041c 0x0000 4 0 -#define MX6UL_PAD_NAND_DATA04__GPIO4_IO06 0x0190 0x041c 0x0000 5 0 -#define MX6UL_PAD_NAND_DATA04__UART2_DCE_TX 0x0190 0x041c 0x0000 8 0 -#define MX6UL_PAD_NAND_DATA04__UART2_DTE_RX 0x0190 0x041c 0x062c 8 2 -#define MX6UL_PAD_NAND_DATA05__RAWNAND_DATA05 0x0194 0x0420 0x0000 0 0 -#define MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x0194 0x0420 0x0690 1 1 -#define MX6UL_PAD_NAND_DATA05__QSPI_B_DATA03 0x0194 0x0420 0x0000 2 0 -#define MX6UL_PAD_NAND_DATA05__ECSPI4_MOSI 0x0194 0x0420 0x056c 3 1 -#define MX6UL_PAD_NAND_DATA05__EIM_AD13 0x0194 0x0420 0x0000 4 0 -#define MX6UL_PAD_NAND_DATA05__GPIO4_IO07 0x0194 0x0420 0x0000 5 0 -#define MX6UL_PAD_NAND_DATA05__UART2_DCE_RX 0x0194 0x0420 0x062c 8 3 -#define MX6UL_PAD_NAND_DATA05__UART2_DTE_TX 0x0194 0x0420 0x0000 8 0 -#define MX6UL_PAD_NAND_DATA06__RAWNAND_DATA06 0x0198 0x0424 0x0000 0 0 -#define MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x0198 0x0424 0x0694 1 1 -#define MX6UL_PAD_NAND_DATA06__SAI2_RX_BCLK 0x0198 0x0424 0x0000 2 0 -#define MX6UL_PAD_NAND_DATA06__ECSPI4_MISO 0x0198 0x0424 0x0568 3 1 -#define MX6UL_PAD_NAND_DATA06__EIM_AD14 0x0198 0x0424 0x0000 4 0 -#define MX6UL_PAD_NAND_DATA06__GPIO4_IO08 0x0198 0x0424 0x0000 5 0 -#define MX6UL_PAD_NAND_DATA06__UART2_DCE_CTS 0x0198 0x0424 0x0000 8 0 -#define MX6UL_PAD_NAND_DATA06__UART2_DTE_RTS 0x0198 0x0424 0x0628 8 4 -#define MX6UL_PAD_NAND_DATA07__RAWNAND_DATA07 0x019c 0x0428 0x0000 0 0 -#define MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x019c 0x0428 0x0698 1 1 -#define MX6UL_PAD_NAND_DATA07__QSPI_A_SS1_B 0x019c 0x0428 0x0000 2 0 -#define MX6UL_PAD_NAND_DATA07__ECSPI4_SS0 0x019c 0x0428 0x0000 3 0 -#define MX6UL_PAD_NAND_DATA07__EIM_AD15 0x019c 0x0428 0x0000 4 0 -#define MX6UL_PAD_NAND_DATA07__GPIO4_IO09 0x019c 0x0428 0x0000 5 0 -#define MX6UL_PAD_NAND_DATA07__UART2_DCE_RTS 0x019c 0x0428 0x0628 8 5 -#define MX6UL_PAD_NAND_DATA07__UART2_DTE_CTS 0x019c 0x0428 0x0000 8 0 -#define MX6UL_PAD_NAND_ALE__RAWNAND_ALE 0x01a0 0x042c 0x0000 0 0 -#define MX6UL_PAD_NAND_ALE__USDHC2_RESET_B 0x01a0 0x042c 0x0000 1 0 -#define MX6UL_PAD_NAND_ALE__QSPI_A_DQS 0x01a0 0x042c 0x0000 2 0 -#define MX6UL_PAD_NAND_ALE__PWM3_OUT 0x01a0 0x042c 0x0000 3 0 -#define MX6UL_PAD_NAND_ALE__EIM_ADDR17 0x01a0 0x042c 0x0000 4 0 -#define MX6UL_PAD_NAND_ALE__GPIO4_IO10 0x01a0 0x042c 0x0000 5 0 -#define MX6UL_PAD_NAND_ALE__ECSPI3_SS1 0x01a0 0x042c 0x0000 8 0 -#define MX6UL_PAD_NAND_WP_B__RAWNAND_WP_B 0x01a4 0x0430 0x0000 0 0 -#define MX6UL_PAD_NAND_WP_B__USDHC1_RESET_B 0x01a4 0x0430 0x0000 1 0 -#define MX6UL_PAD_NAND_WP_B__QSPI_A_SCLK 0x01a4 0x0430 0x0000 2 0 -#define MX6UL_PAD_NAND_WP_B__PWM4_OUT 0x01a4 0x0430 0x0000 3 0 -#define MX6UL_PAD_NAND_WP_B__EIM_BCLK 0x01a4 0x0430 0x0000 4 0 -#define MX6UL_PAD_NAND_WP_B__GPIO4_IO11 0x01a4 0x0430 0x0000 5 0 -#define MX6UL_PAD_NAND_WP_B__ECSPI3_RDY 0x01a4 0x0430 0x0000 8 0 -#define MX6UL_PAD_NAND_READY_B__RAWNAND_READY_B 0x01a8 0x0434 0x0000 0 0 -#define MX6UL_PAD_NAND_READY_B__USDHC1_DATA4 0x01a8 0x0434 0x0000 1 0 -#define MX6UL_PAD_NAND_READY_B__QSPI_A_DATA00 0x01a8 0x0434 0x0000 2 0 -#define MX6UL_PAD_NAND_READY_B__ECSPI3_SS0 0x01a8 0x0434 0x0000 3 0 -#define MX6UL_PAD_NAND_READY_B__EIM_CS1_B 0x01a8 0x0434 0x0000 4 0 -#define MX6UL_PAD_NAND_READY_B__GPIO4_IO12 0x01a8 0x0434 0x0000 5 0 -#define MX6UL_PAD_NAND_READY_B__UART3_DCE_TX 0x01a8 0x0434 0x0000 8 0 -#define MX6UL_PAD_NAND_READY_B__UART3_DTE_RX 0x01a8 0x0434 0x0634 8 2 -#define MX6UL_PAD_NAND_CE0_B__RAWNAND_CE0_B 0x01ac 0x0438 0x0000 0 0 -#define MX6UL_PAD_NAND_CE0_B__USDHC1_DATA5 0x01ac 0x0438 0x0000 1 0 -#define MX6UL_PAD_NAND_CE0_B__QSPI_A_DATA01 0x01ac 0x0438 0x0000 2 0 -#define MX6UL_PAD_NAND_CE0_B__ECSPI3_SCLK 0x01ac 0x0438 0x0554 3 1 -#define MX6UL_PAD_NAND_CE0_B__EIM_DTACK_B 0x01ac 0x0438 0x0000 4 0 -#define MX6UL_PAD_NAND_CE0_B__GPIO4_IO13 0x01ac 0x0438 0x0000 5 0 -#define MX6UL_PAD_NAND_CE0_B__UART3_DCE_RX 0x01ac 0x0438 0x0634 8 3 -#define MX6UL_PAD_NAND_CE0_B__UART3_DTE_TX 0x01ac 0x0438 0x0000 8 0 -#define MX6UL_PAD_NAND_CE1_B__RAWNAND_CE1_B 0x01b0 0x043c 0x0000 0 0 -#define MX6UL_PAD_NAND_CE1_B__USDHC1_DATA6 0x01b0 0x043c 0x0000 1 0 -#define MX6UL_PAD_NAND_CE1_B__QSPI_A_DATA02 0x01b0 0x043c 0x0000 2 0 -#define MX6UL_PAD_NAND_CE1_B__ECSPI3_MOSI 0x01b0 0x043c 0x055c 3 1 -#define MX6UL_PAD_NAND_CE1_B__EIM_ADDR18 0x01b0 0x043c 0x0000 4 0 -#define MX6UL_PAD_NAND_CE1_B__GPIO4_IO14 0x01b0 0x043c 0x0000 5 0 -#define MX6UL_PAD_NAND_CE1_B__UART3_DCE_CTS 0x01b0 0x043c 0x0000 8 0 -#define MX6UL_PAD_NAND_CE1_B__UART3_DTE_RTS 0x01b0 0x043c 0x0630 8 2 -#define MX6UL_PAD_NAND_CLE__RAWNAND_CLE 0x01b4 0x0440 0x0000 0 0 -#define MX6UL_PAD_NAND_CLE__USDHC1_DATA7 0x01b4 0x0440 0x0000 1 0 -#define MX6UL_PAD_NAND_CLE__QSPI_A_DATA03 0x01b4 0x0440 0x0000 2 0 -#define MX6UL_PAD_NAND_CLE__ECSPI3_MISO 0x01b4 0x0440 0x0558 3 1 -#define MX6UL_PAD_NAND_CLE__EIM_ADDR16 0x01b4 0x0440 0x0000 4 0 -#define MX6UL_PAD_NAND_CLE__GPIO4_IO15 0x01b4 0x0440 0x0000 5 0 -#define MX6UL_PAD_NAND_CLE__UART3_DCE_RTS 0x01b4 0x0440 0x0630 8 3 -#define MX6UL_PAD_NAND_CLE__UART3_DTE_CTS 0x01b4 0x0440 0x0000 8 0 -#define MX6UL_PAD_NAND_DQS__RAWNAND_DQS 0x01b8 0x0444 0x0000 0 0 -#define MX6UL_PAD_NAND_DQS__CSI_FIELD 0x01b8 0x0444 0x0530 1 1 -#define MX6UL_PAD_NAND_DQS__QSPI_A_SS0_B 0x01b8 0x0444 0x0000 2 0 -#define MX6UL_PAD_NAND_DQS__PWM5_OUT 0x01b8 0x0444 0x0000 3 0 -#define MX6UL_PAD_NAND_DQS__EIM_WAIT 0x01b8 0x0444 0x0000 4 0 -#define MX6UL_PAD_NAND_DQS__GPIO4_IO16 0x01b8 0x0444 0x0000 5 0 -#define MX6UL_PAD_NAND_DQS__SDMA_EXT_EVENT01 0x01b8 0x0444 0x0000 6 0 -#define MX6UL_PAD_NAND_DQS__SPDIF_EXT_CLK 0x01b8 0x0444 0x0000 8 0 -#define MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x01bc 0x0448 0x0000 0 0 -#define MX6UL_PAD_SD1_CMD__GPT2_COMPARE1 0x01bc 0x0448 0x0000 1 0 -#define MX6UL_PAD_SD1_CMD__SAI2_RX_SYNC 0x01bc 0x0448 0x0000 2 0 -#define MX6UL_PAD_SD1_CMD__SPDIF_OUT 0x01bc 0x0448 0x0000 3 0 -#define MX6UL_PAD_SD1_CMD__EIM_ADDR19 0x01bc 0x0448 0x0000 4 0 -#define MX6UL_PAD_SD1_CMD__GPIO2_IO16 0x01bc 0x0448 0x0000 5 0 -#define MX6UL_PAD_SD1_CMD__SDMA_EXT_EVENT00 0x01bc 0x0448 0x0000 6 0 -#define MX6UL_PAD_SD1_CMD__USB_OTG1_PWR 0x01bc 0x0448 0x0000 8 0 -#define MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x01c0 0x044c 0x0000 0 0 -#define MX6UL_PAD_SD1_CLK__GPT2_COMPARE2 0x01c0 0x044c 0x0000 1 0 -#define MX6UL_PAD_SD1_CLK__SAI2_MCLK 0x01c0 0x044c 0x0000 2 0 -#define MX6UL_PAD_SD1_CLK__SPDIF_IN 0x01c0 0x044c 0x0618 3 3 -#define MX6UL_PAD_SD1_CLK__EIM_ADDR20 0x01c0 0x044c 0x0000 4 0 -#define MX6UL_PAD_SD1_CLK__GPIO2_IO17 0x01c0 0x044c 0x0000 5 0 -#define MX6UL_PAD_SD1_CLK__USB_OTG1_OC 0x01c0 0x044c 0x0000 8 0 -#define MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x01c4 0x0450 0x0000 0 0 -#define MX6UL_PAD_SD1_DATA0__GPT2_COMPARE3 0x01c4 0x0450 0x0000 1 0 -#define MX6UL_PAD_SD1_DATA0__SAI2_TX_SYNC 0x01c4 0x0450 0x05fc 2 1 -#define MX6UL_PAD_SD1_DATA0__FLEXCAN1_TX 0x01c4 0x0450 0x0000 3 0 -#define MX6UL_PAD_SD1_DATA0__EIM_ADDR21 0x01c4 0x0450 0x0000 4 0 -#define MX6UL_PAD_SD1_DATA0__GPIO2_IO18 0x01c4 0x0450 0x0000 5 0 -#define MX6UL_PAD_SD1_DATA0__ANATOP_OTG1_ID 0x01c4 0x0450 0x0000 8 0 -#define MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x01c8 0x0454 0x0000 0 0 -#define MX6UL_PAD_SD1_DATA1__GPT2_CLK 0x01c8 0x0454 0x05a0 1 1 -#define MX6UL_PAD_SD1_DATA1__SAI2_TX_BCLK 0x01c8 0x0454 0x05f8 2 1 -#define MX6UL_PAD_SD1_DATA1__FLEXCAN1_RX 0x01c8 0x0454 0x0584 3 3 -#define MX6UL_PAD_SD1_DATA1__EIM_ADDR22 0x01c8 0x0454 0x0000 4 0 -#define MX6UL_PAD_SD1_DATA1__GPIO2_IO19 0x01c8 0x0454 0x0000 5 0 -#define MX6UL_PAD_SD1_DATA1__USB_OTG2_PWR 0x01c8 0x0454 0x0000 8 0 -#define MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x01cc 0x0458 0x0000 0 0 -#define MX6UL_PAD_SD1_DATA2__GPT2_CAPTURE1 0x01cc 0x0458 0x0598 1 1 -#define MX6UL_PAD_SD1_DATA2__SAI2_RX_DATA 0x01cc 0x0458 0x05f4 2 1 -#define MX6UL_PAD_SD1_DATA2__FLEXCAN2_TX 0x01cc 0x0458 0x0000 3 0 -#define MX6UL_PAD_SD1_DATA2__EIM_ADDR23 0x01cc 0x0458 0x0000 4 0 -#define MX6UL_PAD_SD1_DATA2__GPIO2_IO20 0x01cc 0x0458 0x0000 5 0 -#define MX6UL_PAD_SD1_DATA2__CCM_CLKO1 0x01cc 0x0458 0x0000 6 0 -#define MX6UL_PAD_SD1_DATA2__USB_OTG2_OC 0x01cc 0x0458 0x0000 8 0 -#define MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x01d0 0x045c 0x0000 0 0 -#define MX6UL_PAD_SD1_DATA3__GPT2_CAPTURE2 0x01d0 0x045c 0x059c 1 1 -#define MX6UL_PAD_SD1_DATA3__SAI2_TX_DATA 0x01d0 0x045c 0x0000 2 0 -#define MX6UL_PAD_SD1_DATA3__FLEXCAN2_RX 0x01d0 0x045c 0x0588 3 3 -#define MX6UL_PAD_SD1_DATA3__EIM_ADDR24 0x01d0 0x045c 0x0000 4 0 -#define MX6UL_PAD_SD1_DATA3__GPIO2_IO21 0x01d0 0x045c 0x0000 5 0 -#define MX6UL_PAD_SD1_DATA3__CCM_CLKO2 0x01d0 0x045c 0x0000 6 0 -#define MX6UL_PAD_SD1_DATA3__ANATOP_OTG2_ID 0x01d0 0x045c 0x0000 8 0 -#define MX6UL_PAD_CSI_MCLK__CSI_MCLK 0x01d4 0x0460 0x0000 0 0 -#define MX6UL_PAD_CSI_MCLK__USDHC2_CD_B 0x01d4 0x0460 0x0674 1 0 -#define MX6UL_PAD_CSI_MCLK__RAWNAND_CE2_B 0x01d4 0x0460 0x0000 2 0 -#define MX6UL_PAD_CSI_MCLK__I2C1_SDA 0x01d4 0x0460 0x05a8 3 0 -#define MX6UL_PAD_CSI_MCLK__EIM_CS0_B 0x01d4 0x0460 0x0000 4 0 -#define MX6UL_PAD_CSI_MCLK__GPIO4_IO17 0x01d4 0x0460 0x0000 5 0 -#define MX6UL_PAD_CSI_MCLK__SNVS_HP_VIO_5_CTL 0x01d4 0x0460 0x0000 6 0 -#define MX6UL_PAD_CSI_MCLK__UART6_DCE_TX 0x01d4 0x0460 0x0000 8 0 -#define MX6UL_PAD_CSI_MCLK__UART6_DTE_RX 0x01d4 0x0460 0x064c 8 0 -#define MX6UL_PAD_CSI_PIXCLK__CSI_PIXCLK 0x01d8 0x0464 0x0528 0 1 -#define MX6UL_PAD_CSI_PIXCLK__USDHC2_WP 0x01d8 0x0464 0x069c 1 2 -#define MX6UL_PAD_CSI_PIXCLK__RAWNAND_CE3_B 0x01d8 0x0464 0x0000 2 0 -#define MX6UL_PAD_CSI_PIXCLK__I2C1_SCL 0x01d8 0x0464 0x05a4 3 2 -#define MX6UL_PAD_CSI_PIXCLK__EIM_OE 0x01d8 0x0464 0x0000 4 0 -#define MX6UL_PAD_CSI_PIXCLK__GPIO4_IO18 0x01d8 0x0464 0x0000 5 0 -#define MX6UL_PAD_CSI_PIXCLK__SNVS_HP_VIO_5 0x01d8 0x0464 0x0000 6 0 -#define MX6UL_PAD_CSI_PIXCLK__UART6_DCE_RX 0x01d8 0x0464 0x064c 8 3 -#define MX6UL_PAD_CSI_PIXCLK__UART6_DTE_TX 0x01d8 0x0464 0x0000 8 0 -#define MX6UL_PAD_CSI_VSYNC__CSI_VSYNC 0x01dc 0x0468 0x052c 0 0 -#define MX6UL_PAD_CSI_VSYNC__USDHC2_CLK 0x01dc 0x0468 0x0670 1 0 -#define MX6UL_PAD_CSI_VSYNC__SIM1_PORT1_CLK 0x01dc 0x0468 0x0000 2 0 -#define MX6UL_PAD_CSI_VSYNC__I2C2_SDA 0x01dc 0x0468 0x05b0 3 0 -#define MX6UL_PAD_CSI_VSYNC__EIM_RW 0x01dc 0x0468 0x0000 4 0 -#define MX6UL_PAD_CSI_VSYNC__GPIO4_IO19 0x01dc 0x0468 0x0000 5 0 -#define MX6UL_PAD_CSI_VSYNC__PWM7_OUT 0x01dc 0x0468 0x0000 6 0 -#define MX6UL_PAD_CSI_VSYNC__UART6_DCE_RTS 0x01dc 0x0468 0x0648 8 0 -#define MX6UL_PAD_CSI_VSYNC__UART6_DTE_CTS 0x01dc 0x0468 0x0000 8 0 -#define MX6UL_PAD_CSI_HSYNC__CSI_HSYNC 0x01e0 0x046c 0x0524 0 0 -#define MX6UL_PAD_CSI_HSYNC__USDHC2_CMD 0x01e0 0x046c 0x0678 1 0 -#define MX6UL_PAD_CSI_HSYNC__SIM1_PORT1_PD 0x01e0 0x046c 0x0000 2 0 -#define MX6UL_PAD_CSI_HSYNC__I2C2_SCL 0x01e0 0x046c 0x05ac 3 0 -#define MX6UL_PAD_CSI_HSYNC__EIM_LBA_B 0x01e0 0x046c 0x0000 4 0 -#define MX6UL_PAD_CSI_HSYNC__GPIO4_IO20 0x01e0 0x046c 0x0000 5 0 -#define MX6UL_PAD_CSI_HSYNC__PWM8_OUT 0x01e0 0x046c 0x0000 6 0 -#define MX6UL_PAD_CSI_HSYNC__UART6_DCE_CTS 0x01e0 0x046c 0x0000 8 0 -#define MX6UL_PAD_CSI_HSYNC__UART6_DTE_RTS 0x01e0 0x046c 0x0648 8 1 -#define MX6UL_PAD_CSI_DATA00__CSI_DATA02 0x01e4 0x0470 0x04c4 0 0 -#define MX6UL_PAD_CSI_DATA00__USDHC2_DATA0 0x01e4 0x0470 0x067c 1 0 -#define MX6UL_PAD_CSI_DATA00__SIM1_PORT1_RST_B 0x01e4 0x0470 0x0000 2 0 -#define MX6UL_PAD_CSI_DATA00__ECSPI2_SCLK 0x01e4 0x0470 0x0544 3 0 -#define MX6UL_PAD_CSI_DATA00__EIM_AD00 0x01e4 0x0470 0x0000 4 0 -#define MX6UL_PAD_CSI_DATA00__GPIO4_IO21 0x01e4 0x0470 0x0000 5 0 -#define MX6UL_PAD_CSI_DATA00__SRC_INT_BOOT 0x01e4 0x0470 0x0000 6 0 -#define MX6UL_PAD_CSI_DATA00__UART5_DCE_TX 0x01e4 0x0470 0x0000 8 0 -#define MX6UL_PAD_CSI_DATA00__UART5_DTE_RX 0x01e4 0x0470 0x0644 8 0 -#define MX6UL_PAD_CSI_DATA01__CSI_DATA03 0x01e8 0x0474 0x04c8 0 0 -#define MX6UL_PAD_CSI_DATA01__USDHC2_DATA1 0x01e8 0x0474 0x0680 1 0 -#define MX6UL_PAD_CSI_DATA01__SIM1_PORT1_SVEN 0x01e8 0x0474 0x0000 2 0 -#define MX6UL_PAD_CSI_DATA01__ECSPI2_SS0 0x01e8 0x0474 0x0000 3 0 -#define MX6UL_PAD_CSI_DATA01__EIM_AD01 0x01e8 0x0474 0x0000 4 0 -#define MX6UL_PAD_CSI_DATA01__GPIO4_IO22 0x01e8 0x0474 0x0000 5 0 -#define MX6UL_PAD_CSI_DATA01__SAI1_MCLK 0x01e8 0x0474 0x0000 6 0 -#define MX6UL_PAD_CSI_DATA01__UART5_DCE_RX 0x01e8 0x0474 0x0644 8 1 -#define MX6UL_PAD_CSI_DATA01__UART5_DTE_TX 0x01e8 0x0474 0x0000 8 0 -#define MX6UL_PAD_CSI_DATA02__CSI_DATA04 0x01ec 0x0478 0x04d8 0 1 -#define MX6UL_PAD_CSI_DATA02__USDHC2_DATA2 0x01ec 0x0478 0x0684 1 2 -#define MX6UL_PAD_CSI_DATA02__SIM1_PORT1_TRXD 0x01ec 0x0478 0x0000 2 0 -#define MX6UL_PAD_CSI_DATA02__ECSPI2_MOSI 0x01ec 0x0478 0x054c 3 1 -#define MX6UL_PAD_CSI_DATA02__EIM_AD02 0x01ec 0x0478 0x0000 4 0 -#define MX6UL_PAD_CSI_DATA02__GPIO4_IO23 0x01ec 0x0478 0x0000 5 0 -#define MX6UL_PAD_CSI_DATA02__SAI1_RX_SYNC 0x01ec 0x0478 0x0000 6 0 -#define MX6UL_PAD_CSI_DATA02__UART5_DCE_RTS 0x01ec 0x0478 0x0640 8 5 -#define MX6UL_PAD_CSI_DATA02__UART5_DTE_CTS 0x01ec 0x0478 0x0000 8 0 -#define MX6UL_PAD_CSI_DATA03__CSI_DATA05 0x01f0 0x047c 0x04cc 0 0 -#define MX6UL_PAD_CSI_DATA03__USDHC2_DATA3 0x01f0 0x047c 0x0688 1 0 -#define MX6UL_PAD_CSI_DATA03__SIM2_PORT1_PD 0x01f0 0x047c 0x0000 2 0 -#define MX6UL_PAD_CSI_DATA03__ECSPI2_MISO 0x01f0 0x047c 0x0548 3 0 -#define MX6UL_PAD_CSI_DATA03__EIM_AD03 0x01f0 0x047c 0x0000 4 0 -#define MX6UL_PAD_CSI_DATA03__GPIO4_IO24 0x01f0 0x047c 0x0000 5 0 -#define MX6UL_PAD_CSI_DATA03__SAI1_RX_BCLK 0x01f0 0x047c 0x0000 6 0 -#define MX6UL_PAD_CSI_DATA03__UART5_DCE_CTS 0x01f0 0x047c 0x0000 8 0 -#define MX6UL_PAD_CSI_DATA03__UART5_DTE_RTS 0x01f0 0x047c 0x0640 8 0 -#define MX6UL_PAD_CSI_DATA04__CSI_DATA06 0x01f4 0x0480 0x04dc 0 1 -#define MX6UL_PAD_CSI_DATA04__USDHC2_DATA4 0x01f4 0x0480 0x068c 1 2 -#define MX6UL_PAD_CSI_DATA04__SIM2_PORT1_CLK 0x01f4 0x0480 0x0000 2 0 -#define MX6UL_PAD_CSI_DATA04__ECSPI1_SCLK 0x01f4 0x0480 0x0534 3 1 -#define MX6UL_PAD_CSI_DATA04__EIM_AD04 0x01f4 0x0480 0x0000 4 0 -#define MX6UL_PAD_CSI_DATA04__GPIO4_IO25 0x01f4 0x0480 0x0000 5 0 -#define MX6UL_PAD_CSI_DATA04__SAI1_TX_SYNC 0x01f4 0x0480 0x05ec 6 1 -#define MX6UL_PAD_CSI_DATA04__USDHC1_WP 0x01f4 0x0480 0x0000 8 0 -#define MX6UL_PAD_CSI_DATA05__CSI_DATA07 0x01f8 0x0484 0x04e0 0 1 -#define MX6UL_PAD_CSI_DATA05__USDHC2_DATA5 0x01f8 0x0484 0x0690 1 2 -#define MX6UL_PAD_CSI_DATA05__SIM2_PORT1_RST_B 0x01f8 0x0484 0x0000 2 0 -#define MX6UL_PAD_CSI_DATA05__ECSPI1_SS0 0x01f8 0x0484 0x0000 3 0 -#define MX6UL_PAD_CSI_DATA05__EIM_AD05 0x01f8 0x0484 0x0000 4 0 -#define MX6UL_PAD_CSI_DATA05__GPIO4_IO26 0x01f8 0x0484 0x0000 5 0 -#define MX6UL_PAD_CSI_DATA05__SAI1_TX_BCLK 0x01f8 0x0484 0x05e8 6 1 -#define MX6UL_PAD_CSI_DATA05__USDHC1_CD_B 0x01f8 0x0484 0x0000 8 0 -#define MX6UL_PAD_CSI_DATA06__CSI_DATA08 0x01fc 0x0488 0x04e4 0 1 -#define MX6UL_PAD_CSI_DATA06__USDHC2_DATA6 0x01fc 0x0488 0x0694 1 2 -#define MX6UL_PAD_CSI_DATA06__SIM2_PORT1_SVEN 0x01fc 0x0488 0x0000 2 0 -#define MX6UL_PAD_CSI_DATA06__ECSPI1_MOSI 0x01fc 0x0488 0x053c 3 1 -#define MX6UL_PAD_CSI_DATA06__EIM_AD06 0x01fc 0x0488 0x0000 4 0 -#define MX6UL_PAD_CSI_DATA06__GPIO4_IO27 0x01fc 0x0488 0x0000 5 0 -#define MX6UL_PAD_CSI_DATA06__SAI1_RX_DATA 0x01fc 0x0488 0x0000 6 0 -#define MX6UL_PAD_CSI_DATA06__USDHC1_RESET_B 0x01fc 0x0488 0x0000 8 0 -#define MX6UL_PAD_CSI_DATA07__CSI_DATA09 0x0200 0x048c 0x04e8 0 1 -#define MX6UL_PAD_CSI_DATA07__USDHC2_DATA7 0x0200 0x048c 0x0698 1 2 -#define MX6UL_PAD_CSI_DATA07__SIM2_PORT1_TRXD 0x0200 0x048c 0x0000 2 0 -#define MX6UL_PAD_CSI_DATA07__ECSPI1_MISO 0x0200 0x048c 0x0538 3 1 -#define MX6UL_PAD_CSI_DATA07__EIM_AD07 0x0200 0x048c 0x0000 4 0 -#define MX6UL_PAD_CSI_DATA07__GPIO4_IO28 0x0200 0x048c 0x0000 5 0 -#define MX6UL_PAD_CSI_DATA07__SAI1_TX_DATA 0x0200 0x048c 0x0000 6 0 -#define MX6UL_PAD_CSI_DATA07__USDHC1_VSELECT 0x0200 0x048c 0x0000 8 0 +#define MX6UL_PAD_JTAG_MOD__SJC_MOD 0x0044 0x02d0 0x0000 0 0 +#define MX6UL_PAD_JTAG_MOD__GPT2_CLK 0x0044 0x02d0 0x05a0 1 0 +#define MX6UL_PAD_JTAG_MOD__SPDIF_OUT 0x0044 0x02d0 0x0000 2 0 +#define MX6UL_PAD_JTAG_MOD__ENET1_REF_CLK_25M 0x0044 0x02d0 0x0000 3 0 +#define MX6UL_PAD_JTAG_MOD__CCM_PMIC_RDY 0x0044 0x02d0 0x04c0 4 0 +#define MX6UL_PAD_JTAG_MOD__GPIO1_IO10 0x0044 0x02d0 0x0000 5 0 +#define MX6UL_PAD_JTAG_MOD__SDMA_EXT_EVENT00 0x0044 0x02d0 0x0000 6 0 +#define MX6UL_PAD_JTAG_TMS__SJC_TMS 0x0048 0x02d4 0x0000 0 0 +#define MX6UL_PAD_JTAG_TMS__GPT2_CAPTURE1 0x0048 0x02d4 0x0598 1 0 +#define MX6UL_PAD_JTAG_TMS__SAI2_MCLK 0x0048 0x02d4 0x0000 2 0 +#define MX6UL_PAD_JTAG_TMS__CCM_CLKO1 0x0048 0x02d4 0x0000 3 0 +#define MX6UL_PAD_JTAG_TMS__CCM_WAIT 0x0048 0x02d4 0x0000 4 0 +#define MX6UL_PAD_JTAG_TMS__GPIO1_IO11 0x0048 0x02d4 0x0000 5 0 +#define MX6UL_PAD_JTAG_TMS__SDMA_EXT_EVENT01 0x0048 0x02d4 0x0000 6 0 +#define MX6UL_PAD_JTAG_TMS__EPIT1_OUT 0x0048 0x02d4 0x0000 8 0 +#define MX6UL_PAD_JTAG_TDO__SJC_TDO 0x004c 0x02d8 0x0000 0 0 +#define MX6UL_PAD_JTAG_TDO__GPT2_CAPTURE2 0x004c 0x02d8 0x059c 1 0 +#define MX6UL_PAD_JTAG_TDO__SAI2_TX_SYNC 0x004c 0x02d8 0x05fc 2 0 +#define MX6UL_PAD_JTAG_TDO__CCM_CLKO2 0x004c 0x02d8 0x0000 3 0 +#define MX6UL_PAD_JTAG_TDO__CCM_STOP 0x004c 0x02d8 0x0000 4 0 +#define MX6UL_PAD_JTAG_TDO__GPIO1_IO12 0x004c 0x02d8 0x0000 5 0 +#define MX6UL_PAD_JTAG_TDO__MQS_RIGHT 0x004c 0x02d8 0x0000 6 0 +#define MX6UL_PAD_JTAG_TDO__EPIT2_OUT 0x004c 0x02d8 0x0000 8 0 +#define MX6UL_PAD_JTAG_TDI__SJC_TDI 0x0050 0x02dc 0x0000 0 0 +#define MX6UL_PAD_JTAG_TDI__GPT2_COMPARE1 0x0050 0x02dc 0x0000 1 0 +#define MX6UL_PAD_JTAG_TDI__SAI2_TX_BCLK 0x0050 0x02dc 0x05f8 2 0 +#define MX6UL_PAD_JTAG_TDI__PWM6_OUT 0x0050 0x02dc 0x0000 4 0 +#define MX6UL_PAD_JTAG_TDI__GPIO1_IO13 0x0050 0x02dc 0x0000 5 0 +#define MX6UL_PAD_JTAG_TDI__MQS_LEFT 0x0050 0x02dc 0x0000 6 0 +#define MX6UL_PAD_JTAG_TDI__SIM1_POWER_FAIL 0x0050 0x02dc 0x0000 8 0 +#define MX6UL_PAD_JTAG_TCK__SJC_TCK 0x0054 0x02e0 0x0000 0 0 +#define MX6UL_PAD_JTAG_TCK__GPT2_COMPARE2 0x0054 0x02e0 0x0000 1 0 +#define MX6UL_PAD_JTAG_TCK__SAI2_RX_DATA 0x0054 0x02e0 0x05f4 2 0 +#define MX6UL_PAD_JTAG_TCK__PWM7_OUT 0x0054 0x02e0 0x0000 4 0 +#define MX6UL_PAD_JTAG_TCK__GPIO1_IO14 0x0054 0x02e0 0x0000 5 0 +#define MX6UL_PAD_JTAG_TCK__SIM2_POWER_FAIL 0x0054 0x02e0 0x0000 8 0 +#define MX6UL_PAD_JTAG_TRST_B__SJC_TRSTB 0x0058 0x02e4 0x0000 0 0 +#define MX6UL_PAD_JTAG_TRST_B__GPT2_COMPARE3 0x0058 0x02e4 0x0000 1 0 +#define MX6UL_PAD_JTAG_TRST_B__SAI2_TX_DATA 0x0058 0x02e4 0x0000 2 0 +#define MX6UL_PAD_JTAG_TRST_B__PWM8_OUT 0x0058 0x02e4 0x0000 4 0 +#define MX6UL_PAD_JTAG_TRST_B__GPIO1_IO15 0x0058 0x02e4 0x0000 5 0 +#define MX6UL_PAD_JTAG_TRST_B__CAAM_RNG_OSC_OBS 0x0058 0x02e4 0x0000 8 0 +#define MX6UL_PAD_GPIO1_IO00__I2C2_SCL 0x005c 0x02e8 0x05ac 0 1 +#define MX6UL_PAD_GPIO1_IO00__GPT1_CAPTURE1 0x005c 0x02e8 0x058c 1 0 +#define MX6UL_PAD_GPIO1_IO00__ANATOP_OTG1_ID 0x005c 0x02e8 0x04b8 2 0 +#define MX6UL_PAD_GPIO1_IO00__ENET1_REF_CLK1 0x005c 0x02e8 0x0574 3 0 +#define MX6UL_PAD_GPIO1_IO00__MQS_RIGHT 0x005c 0x02e8 0x0000 4 0 +#define MX6UL_PAD_GPIO1_IO00__GPIO1_IO00 0x005c 0x02e8 0x0000 5 0 +#define MX6UL_PAD_GPIO1_IO00__ENET1_1588_EVENT0_IN 0x005c 0x02e8 0x0000 6 0 +#define MX6UL_PAD_GPIO1_IO00__SRC_SYSTEM_RESET 0x005c 0x02e8 0x0000 7 0 +#define MX6UL_PAD_GPIO1_IO00__WDOG3_WDOG_B 0x005c 0x02e8 0x0000 8 0 +#define MX6UL_PAD_GPIO1_IO01__I2C2_SDA 0x0060 0x02ec 0x05b0 0 1 +#define MX6UL_PAD_GPIO1_IO01__GPT1_COMPARE1 0x0060 0x02ec 0x0000 1 0 +#define MX6UL_PAD_GPIO1_IO01__USB_OTG1_OC 0x0060 0x02ec 0x0664 2 0 +#define MX6UL_PAD_GPIO1_IO01__ENET2_REF_CLK2 0x0060 0x02ec 0x057c 3 0 +#define MX6UL_PAD_GPIO1_IO01__MQS_LEFT 0x0060 0x02ec 0x0000 4 0 +#define MX6UL_PAD_GPIO1_IO01__GPIO1_IO01 0x0060 0x02ec 0x0000 5 0 +#define MX6UL_PAD_GPIO1_IO01__ENET1_1588_EVENT0_OUT 0x0060 0x02ec 0x0000 6 0 +#define MX6UL_PAD_GPIO1_IO01__SRC_EARLY_RESET 0x0060 0x02ec 0x0000 7 0 +#define MX6UL_PAD_GPIO1_IO01__WDOG1_WDOG_B 0x0060 0x02ec 0x0000 8 0 +#define MX6UL_PAD_GPIO1_IO02__I2C1_SCL 0x0064 0x02f0 0x05a4 0 0 +#define MX6UL_PAD_GPIO1_IO02__GPT1_COMPARE2 0x0064 0x02f0 0x0000 1 0 +#define MX6UL_PAD_GPIO1_IO02__USB_OTG2_PWR 0x0064 0x02f0 0x0000 2 0 +#define MX6UL_PAD_GPIO1_IO02__ENET1_REF_CLK_25M 0x0064 0x02f0 0x0000 3 0 +#define MX6UL_PAD_GPIO1_IO02__USDHC1_WP 0x0064 0x02f0 0x066c 4 0 +#define MX6UL_PAD_GPIO1_IO02__GPIO1_IO02 0x0064 0x02f0 0x0000 5 0 +#define MX6UL_PAD_GPIO1_IO02__SDMA_EXT_EVENT00 0x0064 0x02f0 0x0000 6 0 +#define MX6UL_PAD_GPIO1_IO02__SRC_ANY_PU_RESET 0x0064 0x02f0 0x0000 7 0 +#define MX6UL_PAD_GPIO1_IO02__UART1_DCE_TX 0x0064 0x02f0 0x0000 8 0 +#define MX6UL_PAD_GPIO1_IO02__UART1_DTE_RX 0x0064 0x02f0 0x0624 8 0 +#define MX6UL_PAD_GPIO1_IO03__I2C1_SDA 0x0068 0x02f4 0x05a8 0 1 +#define MX6UL_PAD_GPIO1_IO03__GPT1_COMPARE3 0x0068 0x02f4 0x0000 1 0 +#define MX6UL_PAD_GPIO1_IO03__USB_OTG2_OC 0x0068 0x02f4 0x0660 2 0 +#define MX6UL_PAD_GPIO1_IO03__USDHC1_CD_B 0x0068 0x02f4 0x0668 4 0 +#define MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0x0068 0x02f4 0x0000 5 0 +#define MX6UL_PAD_GPIO1_IO03__CCM_DI0_eXT_CLK 0x0068 0x02f4 0x0000 6 0 +#define MX6UL_PAD_GPIO1_IO03__SRC_TESTER_ACK 0x0068 0x02f4 0x0000 7 0 +#define MX6UL_PAD_GPIO1_IO03__UART1_DTE_TX 0x0068 0x02f4 0x0000 8 0 +#define MX6UL_PAD_GPIO1_IO03__UART1_DCE_RX 0x0068 0x02f4 0x0624 8 1 +#define MX6UL_PAD_GPIO1_IO04__ENET1_REF_CLK1 0x006c 0x02f8 0x0574 0 1 +#define MX6UL_PAD_GPIO1_IO04__PWM3_OUT 0x006c 0x02f8 0x0000 1 0 +#define MX6UL_PAD_GPIO1_IO04__USB_OTG1_PWR 0x006c 0x02f8 0x0000 2 0 +#define MX6UL_PAD_GPIO1_IO04__USDHC1_RESET_B 0x006c 0x02f8 0x0000 4 0 +#define MX6UL_PAD_GPIO1_IO04__GPIO1_IO04 0x006c 0x02f8 0x0000 5 0 +#define MX6UL_PAD_GPIO1_IO04__ENET2_1588_EVENT0_IN 0x006c 0x02f8 0x0000 6 0 +#define MX6UL_PAD_GPIO1_IO04__UART5_DCE_TX 0x006c 0x02f8 0x0000 8 0 +#define MX6UL_PAD_GPIO1_IO04__UART5_DTE_RX 0x006c 0x02f8 0x0644 8 2 +#define MX6UL_PAD_GPIO1_IO05__ENET2_REF_CLK2 0x0070 0x02fc 0x057c 0 1 +#define MX6UL_PAD_GPIO1_IO05__PWM4_OUT 0x0070 0x02fc 0x0000 1 0 +#define MX6UL_PAD_GPIO1_IO05__ANATOP_OTG2_ID 0x0070 0x02fc 0x04bc 2 0 +#define MX6UL_PAD_GPIO1_IO05__CSI_FIELD 0x0070 0x02fc 0x0530 3 0 +#define MX6UL_PAD_GPIO1_IO05__USDHC1_VSELECT 0x0070 0x02fc 0x0000 4 0 +#define MX6UL_PAD_GPIO1_IO05__GPIO1_IO05 0x0070 0x02fc 0x0000 5 0 +#define MX6UL_PAD_GPIO1_IO05__ENET2_1588_EVENT0_OUT 0x0070 0x02fc 0x0000 6 0 +#define MX6UL_PAD_GPIO1_IO05__UART5_DCE_RX 0x0070 0x02fc 0x0644 8 3 +#define MX6UL_PAD_GPIO1_IO05__UART5_DTE_TX 0x0070 0x02fc 0x0000 8 0 +#define MX6UL_PAD_GPIO1_IO06__ENET1_MDIO 0x0074 0x0300 0x0578 0 0 +#define MX6UL_PAD_GPIO1_IO06__ENET2_MDIO 0x0074 0x0300 0x0580 1 0 +#define MX6UL_PAD_GPIO1_IO06__USB_OTG_PWR_WAKE 0x0074 0x0300 0x0000 2 0 +#define MX6UL_PAD_GPIO1_IO06__CSI_MCLK 0x0074 0x0300 0x0000 3 0 +#define MX6UL_PAD_GPIO1_IO06__USDHC2_WP 0x0074 0x0300 0x069c 4 0 +#define MX6UL_PAD_GPIO1_IO06__GPIO1_IO06 0x0074 0x0300 0x0000 5 0 +#define MX6UL_PAD_GPIO1_IO06__CCM_WAIT 0x0074 0x0300 0x0000 6 0 +#define MX6UL_PAD_GPIO1_IO06__CCM_REF_EN_B 0x0074 0x0300 0x0000 7 0 +#define MX6UL_PAD_GPIO1_IO06__UART1_DCE_CTS 0x0074 0x0300 0x0000 8 0 +#define MX6UL_PAD_GPIO1_IO06__UART1_DTE_RTS 0x0074 0x0300 0x0620 8 0 +#define MX6UL_PAD_GPIO1_IO07__ENET1_MDC 0x0078 0x0304 0x0000 0 0 +#define MX6UL_PAD_GPIO1_IO07__ENET2_MDC 0x0078 0x0304 0x0000 1 0 +#define MX6UL_PAD_GPIO1_IO07__USB_OTG_HOST_MODE 0x0078 0x0304 0x0000 2 0 +#define MX6UL_PAD_GPIO1_IO07__CSI_PIXCLK 0x0078 0x0304 0x0528 3 0 +#define MX6UL_PAD_GPIO1_IO07__USDHC2_CD_B 0x0078 0x0304 0x0674 4 1 +#define MX6UL_PAD_GPIO1_IO07__GPIO1_IO07 0x0078 0x0304 0x0000 5 0 +#define MX6UL_PAD_GPIO1_IO07__CCM_STOP 0x0078 0x0304 0x0000 6 0 +#define MX6UL_PAD_GPIO1_IO07__UART1_DCE_RTS 0x0078 0x0304 0x0620 8 1 +#define MX6UL_PAD_GPIO1_IO07__UART1_DTE_CTS 0x0078 0x0304 0x0000 8 0 +#define MX6UL_PAD_GPIO1_IO08__PWM1_OUT 0x007c 0x0308 0x0000 0 0 +#define MX6UL_PAD_GPIO1_IO08__WDOG1_WDOG_B 0x007c 0x0308 0x0000 1 0 +#define MX6UL_PAD_GPIO1_IO08__SPDIF_OUT 0x007c 0x0308 0x0000 2 0 +#define MX6UL_PAD_GPIO1_IO08__CSI_VSYNC 0x007c 0x0308 0x052c 3 1 +#define MX6UL_PAD_GPIO1_IO08__USDHC2_VSELECT 0x007c 0x0308 0x0000 4 0 +#define MX6UL_PAD_GPIO1_IO08__GPIO1_IO08 0x007c 0x0308 0x0000 5 0 +#define MX6UL_PAD_GPIO1_IO08__CCM_PMIC_RDY 0x007c 0x0308 0x04c0 6 1 +#define MX6UL_PAD_GPIO1_IO08__UART5_DCE_RTS 0x007c 0x0308 0x0640 8 1 +#define MX6UL_PAD_GPIO1_IO08__UART5_DTE_CTS 0x007c 0x0308 0x0000 8 0 +#define MX6UL_PAD_GPIO1_IO09__PWM2_OUT 0x0080 0x030c 0x0000 0 0 +#define MX6UL_PAD_GPIO1_IO09__WDOG1_WDOG_ANY 0x0080 0x030c 0x0000 1 0 +#define MX6UL_PAD_GPIO1_IO09__SPDIF_IN 0x0080 0x030c 0x0618 2 0 +#define MX6UL_PAD_GPIO1_IO09__CSI_HSYNC 0x0080 0x030c 0x0524 3 1 +#define MX6UL_PAD_GPIO1_IO09__USDHC2_RESET_B 0x0080 0x030c 0x0000 4 0 +#define MX6UL_PAD_GPIO1_IO09__GPIO1_IO09 0x0080 0x030c 0x0000 5 0 +#define MX6UL_PAD_GPIO1_IO09__USDHC1_RESET_B 0x0080 0x030c 0x0000 6 0 +#define MX6UL_PAD_GPIO1_IO09__UART5_DCE_CTS 0x0080 0x030c 0x0000 8 0 +#define MX6UL_PAD_GPIO1_IO09__UART5_DTE_RTS 0x0080 0x030c 0x0640 8 2 +#define MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX 0x0084 0x0310 0x0000 0 0 +#define MX6UL_PAD_UART1_TX_DATA__UART1_DTE_RX 0x0084 0x0310 0x0624 0 2 +#define MX6UL_PAD_UART1_TX_DATA__ENET1_RDATA02 0x0084 0x0310 0x0000 1 0 +#define MX6UL_PAD_UART1_TX_DATA__I2C3_SCL 0x0084 0x0310 0x05b4 2 0 +#define MX6UL_PAD_UART1_TX_DATA__CSI_DATA02 0x0084 0x0310 0x04c4 3 1 +#define MX6UL_PAD_UART1_TX_DATA__GPT1_COMPARE1 0x0084 0x0310 0x0000 4 0 +#define MX6UL_PAD_UART1_TX_DATA__GPIO1_IO16 0x0084 0x0310 0x0000 5 0 +#define MX6UL_PAD_UART1_TX_DATA__SPDIF_OUT 0x0084 0x0310 0x0000 8 0 +#define MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX 0x0088 0x0314 0x0624 0 3 +#define MX6UL_PAD_UART1_RX_DATA__UART1_DTE_TX 0x0088 0x0314 0x0000 0 0 +#define MX6UL_PAD_UART1_RX_DATA__ENET1_RDATA03 0x0088 0x0314 0x0000 1 0 +#define MX6UL_PAD_UART1_RX_DATA__I2C3_SDA 0x0088 0x0314 0x05b8 2 0 +#define MX6UL_PAD_UART1_RX_DATA__CSI_DATA03 0x0088 0x0314 0x04c8 3 1 +#define MX6UL_PAD_UART1_RX_DATA__GPT1_CLK 0x0088 0x0314 0x0594 4 0 +#define MX6UL_PAD_UART1_RX_DATA__GPIO1_IO17 0x0088 0x0314 0x0000 5 0 +#define MX6UL_PAD_UART1_RX_DATA__SPDIF_IN 0x0088 0x0314 0x0618 8 1 +#define MX6UL_PAD_UART1_CTS_B__UART1_DCE_CTS 0x008c 0x0318 0x0000 0 0 +#define MX6UL_PAD_UART1_CTS_B__UART1_DTE_RTS 0x008c 0x0318 0x0620 0 2 +#define MX6UL_PAD_UART1_CTS_B__ENET1_RX_CLK 0x008c 0x0318 0x0000 1 0 +#define MX6UL_PAD_UART1_CTS_B__USDHC1_WP 0x008c 0x0318 0x066c 2 1 +#define MX6UL_PAD_UART1_CTS_B__CSI_DATA04 0x008c 0x0318 0x04d8 3 0 +#define MX6UL_PAD_UART1_CTS_B__ENET2_1588_EVENT1_IN 0x008c 0x0318 0x0000 4 0 +#define MX6UL_PAD_UART1_CTS_B__GPIO1_IO18 0x008c 0x0318 0x0000 5 0 +#define MX6UL_PAD_UART1_CTS_B__USDHC2_WP 0x008c 0x0318 0x069c 8 1 +#define MX6UL_PAD_UART1_RTS_B__UART1_DCE_RTS 0x0090 0x031c 0x0620 0 3 +#define MX6UL_PAD_UART1_RTS_B__UART1_DTE_CTS 0x0090 0x031c 0x0000 0 0 +#define MX6UL_PAD_UART1_RTS_B__ENET1_TX_ER 0x0090 0x031c 0x0000 1 0 +#define MX6UL_PAD_UART1_RTS_B__USDHC1_CD_B 0x0090 0x031c 0x0668 2 1 +#define MX6UL_PAD_UART1_RTS_B__CSI_DATA05 0x0090 0x031c 0x04cc 3 1 +#define MX6UL_PAD_UART1_RTS_B__ENET2_1588_EVENT1_OUT 0x0090 0x031c 0x0000 4 0 +#define MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x0090 0x031c 0x0000 5 0 +#define MX6UL_PAD_UART1_RTS_B__USDHC2_CD_B 0x0090 0x031c 0x0674 8 2 +#define MX6UL_PAD_UART2_TX_DATA__UART2_DCE_TX 0x0094 0x0320 0x0000 0 0 +#define MX6UL_PAD_UART2_TX_DATA__UART2_DTE_RX 0x0094 0x0320 0x062c 0 0 +#define MX6UL_PAD_UART2_TX_DATA__ENET1_TDATA02 0x0094 0x0320 0x0000 1 0 +#define MX6UL_PAD_UART2_TX_DATA__I2C4_SCL 0x0094 0x0320 0x05bc 2 0 +#define MX6UL_PAD_UART2_TX_DATA__CSI_DATA06 0x0094 0x0320 0x04dc 3 0 +#define MX6UL_PAD_UART2_TX_DATA__GPT1_CAPTURE1 0x0094 0x0320 0x058c 4 1 +#define MX6UL_PAD_UART2_TX_DATA__GPIO1_IO20 0x0094 0x0320 0x0000 5 0 +#define MX6UL_PAD_UART2_TX_DATA__ECSPI3_SS0 0x0094 0x0320 0x0000 8 0 +#define MX6UL_PAD_UART2_RX_DATA__UART2_DCE_RX 0x0098 0x0324 0x062c 0 1 +#define MX6UL_PAD_UART2_RX_DATA__UART2_DTE_TX 0x0098 0x0324 0x0000 0 0 +#define MX6UL_PAD_UART2_RX_DATA__ENET1_TDATA03 0x0098 0x0324 0x0000 1 0 +#define MX6UL_PAD_UART2_RX_DATA__I2C4_SDA 0x0098 0x0324 0x05c0 2 0 +#define MX6UL_PAD_UART2_RX_DATA__CSI_DATA07 0x0098 0x0324 0x04e0 3 0 +#define MX6UL_PAD_UART2_RX_DATA__GPT1_CAPTURE2 0x0098 0x0324 0x0590 4 0 +#define MX6UL_PAD_UART2_RX_DATA__GPIO1_IO21 0x0098 0x0324 0x0000 5 0 +#define MX6UL_PAD_UART2_RX_DATA__SJC_DONE 0x0098 0x0324 0x0000 7 0 +#define MX6UL_PAD_UART2_RX_DATA__ECSPI3_SCLK 0x0098 0x0324 0x0554 8 0 +#define MX6UL_PAD_UART2_CTS_B__UART2_DCE_CTS 0x009c 0x0328 0x0000 0 0 +#define MX6UL_PAD_UART2_CTS_B__UART2_DTE_RTS 0x009c 0x0328 0x0628 0 0 +#define MX6UL_PAD_UART2_CTS_B__ENET1_CRS 0x009c 0x0328 0x0000 1 0 +#define MX6UL_PAD_UART2_CTS_B__FLEXCAN2_TX 0x009c 0x0328 0x0000 2 0 +#define MX6UL_PAD_UART2_CTS_B__CSI_DATA08 0x009c 0x0328 0x04e4 3 0 +#define MX6UL_PAD_UART2_CTS_B__GPT1_COMPARE2 0x009c 0x0328 0x0000 4 0 +#define MX6UL_PAD_UART2_CTS_B__GPIO1_IO22 0x009c 0x0328 0x0000 5 0 +#define MX6UL_PAD_UART2_CTS_B__SJC_DE_B 0x009c 0x0328 0x0000 7 0 +#define MX6UL_PAD_UART2_CTS_B__ECSPI3_MOSI 0x009c 0x0328 0x055c 8 0 +#define MX6UL_PAD_UART2_RTS_B__UART2_DCE_RTS 0x00a0 0x032c 0x0628 0 1 +#define MX6UL_PAD_UART2_RTS_B__UART2_DTE_CTS 0x00a0 0x032c 0x0000 0 0 +#define MX6UL_PAD_UART2_RTS_B__ENET1_COL 0x00a0 0x032c 0x0000 1 0 +#define MX6UL_PAD_UART2_RTS_B__FLEXCAN2_RX 0x00a0 0x032c 0x0588 2 0 +#define MX6UL_PAD_UART2_RTS_B__CSI_DATA09 0x00a0 0x032c 0x04e8 3 0 +#define MX6UL_PAD_UART2_RTS_B__GPT1_COMPARE3 0x00a0 0x032c 0x0000 4 0 +#define MX6UL_PAD_UART2_RTS_B__GPIO1_IO23 0x00a0 0x032c 0x0000 5 0 +#define MX6UL_PAD_UART2_RTS_B__SJC_FAIL 0x00a0 0x032c 0x0000 7 0 +#define MX6UL_PAD_UART2_RTS_B__ECSPI3_MISO 0x00a0 0x032c 0x0558 8 0 +#define MX6UL_PAD_UART3_TX_DATA__UART3_DCE_TX 0x00a4 0x0330 0x0000 0 0 +#define MX6UL_PAD_UART3_TX_DATA__UART3_DTE_RX 0x00a4 0x0330 0x0634 0 0 +#define MX6UL_PAD_UART3_TX_DATA__ENET2_RDATA02 0x00a4 0x0330 0x0000 1 0 +#define MX6UL_PAD_UART3_TX_DATA__SIM1_PORT0_PD 0x00a4 0x0330 0x0000 2 0 +#define MX6UL_PAD_UART3_TX_DATA__CSI_DATA01 0x00a4 0x0330 0x0000 3 0 +#define MX6UL_PAD_UART3_TX_DATA__UART2_DCE_CTS 0x00a4 0x0330 0x0000 4 0 +#define MX6UL_PAD_UART3_TX_DATA__UART2_DTE_RTS 0x00a4 0x0330 0x0628 4 2 +#define MX6UL_PAD_UART3_TX_DATA__GPIO1_IO24 0x00a4 0x0330 0x0000 5 0 +#define MX6UL_PAD_UART3_TX_DATA__SJC_JTAG_ACT 0x00a4 0x0330 0x0000 7 0 +#define MX6UL_PAD_UART3_TX_DATA__ANATOP_OTG1_ID 0x00a4 0x0330 0x04b8 8 1 +#define MX6UL_PAD_UART3_RX_DATA__UART3_DCE_RX 0x00a8 0x0334 0x0634 0 1 +#define MX6UL_PAD_UART3_RX_DATA__UART3_DTE_TX 0x00a8 0x0334 0x0000 0 0 +#define MX6UL_PAD_UART3_RX_DATA__ENET2_RDATA03 0x00a8 0x0334 0x0000 1 0 +#define MX6UL_PAD_UART3_RX_DATA__SIM2_PORT0_PD 0x00a8 0x0334 0x0000 2 0 +#define MX6UL_PAD_UART3_RX_DATA__CSI_DATA00 0x00a8 0x0334 0x0000 3 0 +#define MX6UL_PAD_UART3_RX_DATA__UART2_DCE_RTS 0x00a8 0x0334 0x0628 4 3 +#define MX6UL_PAD_UART3_RX_DATA__UART2_DTE_CTS 0x00a8 0x0334 0x0000 4 0 +#define MX6UL_PAD_UART3_RX_DATA__GPIO1_IO25 0x00a8 0x0334 0x0000 5 0 +#define MX6UL_PAD_UART3_RX_DATA__EPIT1_OUT 0x00a8 0x0334 0x0000 8 0 +#define MX6UL_PAD_UART3_CTS_B__UART3_DCE_CTS 0x00ac 0x0338 0x0000 0 0 +#define MX6UL_PAD_UART3_CTS_B__UART3_DTE_RTS 0x00ac 0x0338 0x0630 0 0 +#define MX6UL_PAD_UART3_CTS_B__ENET2_RX_CLK 0x00ac 0x0338 0x0000 1 0 +#define MX6UL_PAD_UART3_CTS_B__FLEXCAN1_TX 0x00ac 0x0338 0x0000 2 0 +#define MX6UL_PAD_UART3_CTS_B__CSI_DATA10 0x00ac 0x0338 0x0000 3 0 +#define MX6UL_PAD_UART3_CTS_B__ENET1_1588_EVENT1_IN 0x00ac 0x0338 0x0000 4 0 +#define MX6UL_PAD_UART3_CTS_B__GPIO1_IO26 0x00ac 0x0338 0x0000 5 0 +#define MX6UL_PAD_UART3_CTS_B__EPIT2_OUT 0x00ac 0x0338 0x0000 8 0 +#define MX6UL_PAD_UART3_RTS_B__UART3_DCE_RTS 0x00b0 0x033c 0x0630 0 1 +#define MX6UL_PAD_UART3_RTS_B__UART3_DTE_CTS 0x00b0 0x033c 0x0000 0 0 +#define MX6UL_PAD_UART3_RTS_B__ENET2_TX_ER 0x00b0 0x033c 0x0000 1 0 +#define MX6UL_PAD_UART3_RTS_B__FLEXCAN1_RX 0x00b0 0x033c 0x0584 2 0 +#define MX6UL_PAD_UART3_RTS_B__CSI_DATA11 0x00b0 0x033c 0x0000 3 0 +#define MX6UL_PAD_UART3_RTS_B__ENET1_1588_EVENT1_OUT 0x00b0 0x033c 0x0000 4 0 +#define MX6UL_PAD_UART3_RTS_B__GPIO1_IO27 0x00b0 0x033c 0x0000 5 0 +#define MX6UL_PAD_UART3_RTS_B__WDOG1_WDOG_B 0x00b0 0x033c 0x0000 8 0 +#define MX6UL_PAD_UART4_TX_DATA__UART4_DCE_TX 0x00b4 0x0340 0x0000 0 0 +#define MX6UL_PAD_UART4_TX_DATA__UART4_DTE_RX 0x00b4 0x0340 0x063c 0 0 +#define MX6UL_PAD_UART4_TX_DATA__ENET2_TDATA02 0x00b4 0x0340 0x0000 1 0 +#define MX6UL_PAD_UART4_TX_DATA__I2C1_SCL 0x00b4 0x0340 0x05a4 2 1 +#define MX6UL_PAD_UART4_TX_DATA__CSI_DATA12 0x00b4 0x0340 0x0000 3 0 +#define MX6UL_PAD_UART4_TX_DATA__CSU_CSU_ALARM_AUT02 0x00b4 0x0340 0x0000 4 0 +#define MX6UL_PAD_UART4_TX_DATA__GPIO1_IO28 0x00b4 0x0340 0x0000 5 0 +#define MX6UL_PAD_UART4_TX_DATA__ECSPI2_SCLK 0x00b4 0x0340 0x0544 8 1 +#define MX6UL_PAD_UART4_RX_DATA__UART4_DCE_RX 0x00b8 0x0344 0x063c 0 1 +#define MX6UL_PAD_UART4_RX_DATA__UART4_DTE_TX 0x00b8 0x0344 0x0000 0 0 +#define MX6UL_PAD_UART4_RX_DATA__ENET2_TDATA03 0x00b8 0x0344 0x0000 1 0 +#define MX6UL_PAD_UART4_RX_DATA__I2C1_SDA 0x00b8 0x0344 0x05a8 2 2 +#define MX6UL_PAD_UART4_RX_DATA__CSI_DATA13 0x00b8 0x0344 0x0000 3 0 +#define MX6UL_PAD_UART4_RX_DATA__CSU_CSU_ALARM_AUT01 0x00b8 0x0344 0x0000 4 0 +#define MX6UL_PAD_UART4_RX_DATA__GPIO1_IO29 0x00b8 0x0344 0x0000 5 0 +#define MX6UL_PAD_UART4_RX_DATA__ECSPI2_SS0 0x00b8 0x0344 0x0000 8 0 +#define MX6UL_PAD_UART5_TX_DATA__GPIO1_IO30 0x00bc 0x0348 0x0000 5 0 +#define MX6UL_PAD_UART5_TX_DATA__ECSPI2_MOSI 0x00bc 0x0348 0x054c 8 0 +#define MX6UL_PAD_UART5_TX_DATA__UART5_DCE_TX 0x00bc 0x0348 0x0000 0 0 +#define MX6UL_PAD_UART5_TX_DATA__UART5_DTE_RX 0x00bc 0x0348 0x0644 0 4 +#define MX6UL_PAD_UART5_TX_DATA__ENET2_CRS 0x00bc 0x0348 0x0000 1 0 +#define MX6UL_PAD_UART5_TX_DATA__I2C2_SCL 0x00bc 0x0348 0x05ac 2 2 +#define MX6UL_PAD_UART5_TX_DATA__CSI_DATA14 0x00bc 0x0348 0x0000 3 0 +#define MX6UL_PAD_UART5_TX_DATA__CSU_CSU_ALARM_AUT00 0x00bc 0x0348 0x0000 4 0 +#define MX6UL_PAD_UART5_RX_DATA__UART5_DCE_RX 0x00c0 0x034c 0x0644 0 5 +#define MX6UL_PAD_UART5_RX_DATA__UART5_DTE_TX 0x00c0 0x034c 0x0000 0 0 +#define MX6UL_PAD_UART5_RX_DATA__ENET2_COL 0x00c0 0x034c 0x0000 1 0 +#define MX6UL_PAD_UART5_RX_DATA__I2C2_SDA 0x00c0 0x034c 0x05b0 2 2 +#define MX6UL_PAD_UART5_RX_DATA__CSI_DATA15 0x00c0 0x034c 0x0000 3 0 +#define MX6UL_PAD_UART5_RX_DATA__CSU_CSU_INT_DEB 0x00c0 0x034c 0x0000 4 0 +#define MX6UL_PAD_UART5_RX_DATA__GPIO1_IO31 0x00c0 0x034c 0x0000 5 0 +#define MX6UL_PAD_UART5_RX_DATA__ECSPI2_MISO 0x00c0 0x034c 0x0548 8 1 +#define MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00 0x00c4 0x0350 0x0000 0 0 +#define MX6UL_PAD_ENET1_RX_DATA0__UART4_DCE_RTS 0x00c4 0x0350 0x0638 1 0 +#define MX6UL_PAD_ENET1_RX_DATA0__UART4_DTE_CTS 0x00c4 0x0350 0x0000 1 0 +#define MX6UL_PAD_ENET1_RX_DATA0__PWM1_OUT 0x00c4 0x0350 0x0000 2 0 +#define MX6UL_PAD_ENET1_RX_DATA0__CSI_DATA16 0x00c4 0x0350 0x0000 3 0 +#define MX6UL_PAD_ENET1_RX_DATA0__FLEXCAN1_TX 0x00c4 0x0350 0x0000 4 0 +#define MX6UL_PAD_ENET1_RX_DATA0__GPIO2_IO00 0x00c4 0x0350 0x0000 5 0 +#define MX6UL_PAD_ENET1_RX_DATA0__KPP_ROW00 0x00c4 0x0350 0x0000 6 0 +#define MX6UL_PAD_ENET1_RX_DATA0__USDHC1_LCTL 0x00c4 0x0350 0x0000 8 0 +#define MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x00c8 0x0354 0x0000 0 0 +#define MX6UL_PAD_ENET1_RX_DATA1__UART4_DCE_CTS 0x00c8 0x0354 0x0000 1 0 +#define MX6UL_PAD_ENET1_RX_DATA1__UART4_DTE_RTS 0x00c8 0x0354 0x0638 1 1 +#define MX6UL_PAD_ENET1_RX_DATA1__PWM2_OUT 0x00c8 0x0354 0x0000 2 0 +#define MX6UL_PAD_ENET1_RX_DATA1__CSI_DATA17 0x00c8 0x0354 0x0000 3 0 +#define MX6UL_PAD_ENET1_RX_DATA1__FLEXCAN1_RX 0x00c8 0x0354 0x0584 4 1 +#define MX6UL_PAD_ENET1_RX_DATA1__GPIO2_IO01 0x00c8 0x0354 0x0000 5 0 +#define MX6UL_PAD_ENET1_RX_DATA1__KPP_COL00 0x00c8 0x0354 0x0000 6 0 +#define MX6UL_PAD_ENET1_RX_DATA1__USDHC2_LCTL 0x00c8 0x0354 0x0000 8 0 +#define MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN 0x00cc 0x0358 0x0000 0 0 +#define MX6UL_PAD_ENET1_RX_EN__UART5_DCE_RTS 0x00cc 0x0358 0x0640 1 3 +#define MX6UL_PAD_ENET1_RX_EN__UART5_DTE_CTS 0x00cc 0x0358 0x0000 1 0 +#define MX6UL_PAD_ENET1_RX_EN__CSI_DATA18 0x00cc 0x0358 0x0000 3 0 +#define MX6UL_PAD_ENET1_RX_EN__FLEXCAN2_TX 0x00cc 0x0358 0x0000 4 0 +#define MX6UL_PAD_ENET1_RX_EN__GPIO2_IO02 0x00cc 0x0358 0x0000 5 0 +#define MX6UL_PAD_ENET1_RX_EN__KPP_ROW01 0x00cc 0x0358 0x0000 6 0 +#define MX6UL_PAD_ENET1_RX_EN__USDHC1_VSELECT 0x00cc 0x0358 0x0000 8 0 +#define MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x00d0 0x035c 0x0000 0 0 +#define MX6UL_PAD_ENET1_TX_DATA0__UART5_DCE_CTS 0x00d0 0x035c 0x0000 1 0 +#define MX6UL_PAD_ENET1_TX_DATA0__UART5_DTE_RTS 0x00d0 0x035c 0x0640 1 4 +#define MX6UL_PAD_ENET1_TX_DATA0__CSI_DATA19 0x00d0 0x035c 0x0000 3 0 +#define MX6UL_PAD_ENET1_TX_DATA0__FLEXCAN2_RX 0x00d0 0x035c 0x0588 4 1 +#define MX6UL_PAD_ENET1_TX_DATA0__GPIO2_IO03 0x00d0 0x035c 0x0000 5 0 +#define MX6UL_PAD_ENET1_TX_DATA0__KPP_COL01 0x00d0 0x035c 0x0000 6 0 +#define MX6UL_PAD_ENET1_TX_DATA0__USDHC2_VSELECT 0x00d0 0x035c 0x0000 8 0 +#define MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x00d4 0x0360 0x0000 0 0 +#define MX6UL_PAD_ENET1_TX_DATA1__UART6_DCE_CTS 0x00d4 0x0360 0x0000 1 0 +#define MX6UL_PAD_ENET1_TX_DATA1__UART6_DTE_RTS 0x00d4 0x0360 0x0648 1 2 +#define MX6UL_PAD_ENET1_TX_DATA1__PWM5_OUT 0x00d4 0x0360 0x0000 2 0 +#define MX6UL_PAD_ENET1_TX_DATA1__CSI_DATA20 0x00d4 0x0360 0x0000 3 0 +#define MX6UL_PAD_ENET1_TX_DATA1__ENET2_MDIO 0x00d4 0x0360 0x0580 4 1 +#define MX6UL_PAD_ENET1_TX_DATA1__GPIO2_IO04 0x00d4 0x0360 0x0000 5 0 +#define MX6UL_PAD_ENET1_TX_DATA1__KPP_ROW02 0x00d4 0x0360 0x0000 6 0 +#define MX6UL_PAD_ENET1_TX_DATA1__WDOG1_WDOG_RST_B_DEB 0x00d4 0x0360 0x0000 8 0 +#define MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN 0x00d8 0x0364 0x0000 0 0 +#define MX6UL_PAD_ENET1_TX_EN__UART6_DCE_RTS 0x00d8 0x0364 0x0648 1 3 +#define MX6UL_PAD_ENET1_TX_EN__UART6_DTE_CTS 0x00d8 0x0364 0x0000 1 0 +#define MX6UL_PAD_ENET1_TX_EN__PWM6_OUT 0x00d8 0x0364 0x0000 2 0 +#define MX6UL_PAD_ENET1_TX_EN__CSI_DATA21 0x00d8 0x0364 0x0000 3 0 +#define MX6UL_PAD_ENET1_TX_EN__ENET2_MDC 0x00d8 0x0364 0x0000 4 0 +#define MX6UL_PAD_ENET1_TX_EN__GPIO2_IO05 0x00d8 0x0364 0x0000 5 0 +#define MX6UL_PAD_ENET1_TX_EN__KPP_COL02 0x00d8 0x0364 0x0000 6 0 +#define MX6UL_PAD_ENET1_TX_EN__WDOG2_WDOG_RST_B_DEB 0x00d8 0x0364 0x0000 8 0 +#define MX6UL_PAD_ENET1_TX_CLK__ENET1_TX_CLK 0x00dc 0x0368 0x0000 0 0 +#define MX6UL_PAD_ENET1_TX_CLK__UART7_DCE_CTS 0x00dc 0x0368 0x0000 1 0 +#define MX6UL_PAD_ENET1_TX_CLK__UART7_DTE_RTS 0x00dc 0x0368 0x0650 1 0 +#define MX6UL_PAD_ENET1_TX_CLK__PWM7_OUT 0x00dc 0x0368 0x0000 2 0 +#define MX6UL_PAD_ENET1_TX_CLK__CSI_DATA22 0x00dc 0x0368 0x0000 3 0 +#define MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 0x00dc 0x0368 0x0574 4 2 +#define MX6UL_PAD_ENET1_TX_CLK__GPIO2_IO06 0x00dc 0x0368 0x0000 5 0 +#define MX6UL_PAD_ENET1_TX_CLK__KPP_ROW03 0x00dc 0x0368 0x0000 6 0 +#define MX6UL_PAD_ENET1_TX_CLK__GPT1_CLK 0x00dc 0x0368 0x0594 8 1 +#define MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER 0x00e0 0x036c 0x0000 0 0 +#define MX6UL_PAD_ENET1_RX_ER__UART7_DCE_RTS 0x00e0 0x036c 0x0650 1 1 +#define MX6UL_PAD_ENET1_RX_ER__UART7_DTE_CTS 0x00e0 0x036c 0x0000 1 0 +#define MX6UL_PAD_ENET1_RX_ER__PWM8_OUT 0x00e0 0x036c 0x0000 2 0 +#define MX6UL_PAD_ENET1_RX_ER__CSI_DATA23 0x00e0 0x036c 0x0000 3 0 +#define MX6UL_PAD_ENET1_RX_ER__EIM_CRE 0x00e0 0x036c 0x0000 4 0 +#define MX6UL_PAD_ENET1_RX_ER__GPIO2_IO07 0x00e0 0x036c 0x0000 5 0 +#define MX6UL_PAD_ENET1_RX_ER__KPP_COL03 0x00e0 0x036c 0x0000 6 0 +#define MX6UL_PAD_ENET1_RX_ER__GPT1_CAPTURE2 0x00e0 0x036c 0x0590 8 1 +#define MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00 0x00e4 0x0370 0x0000 0 0 +#define MX6UL_PAD_ENET2_RX_DATA0__UART6_DCE_TX 0x00e4 0x0370 0x0000 1 0 +#define MX6UL_PAD_ENET2_RX_DATA0__UART6_DTE_RX 0x00e4 0x0370 0x064c 1 1 +#define MX6UL_PAD_ENET2_RX_DATA0__SIM1_PORT0_TRXD 0x00e4 0x0370 0x0000 2 0 +#define MX6UL_PAD_ENET2_RX_DATA0__I2C3_SCL 0x00e4 0x0370 0x05b4 3 1 +#define MX6UL_PAD_ENET2_RX_DATA0__ENET1_MDIO 0x00e4 0x0370 0x0578 4 1 +#define MX6UL_PAD_ENET2_RX_DATA0__GPIO2_IO08 0x00e4 0x0370 0x0000 5 0 +#define MX6UL_PAD_ENET2_RX_DATA0__KPP_ROW04 0x00e4 0x0370 0x0000 6 0 +#define MX6UL_PAD_ENET2_RX_DATA0__USB_OTG1_PWR 0x00e4 0x0370 0x0000 8 0 +#define MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x00e8 0x0374 0x0000 0 0 +#define MX6UL_PAD_ENET2_RX_DATA1__UART6_DCE_RX 0x00e8 0x0374 0x064c 1 2 +#define MX6UL_PAD_ENET2_RX_DATA1__UART6_DTE_TX 0x00e8 0x0374 0x0000 1 0 +#define MX6UL_PAD_ENET2_RX_DATA1__SIM1_PORT0_cLK 0x00e8 0x0374 0x0000 2 0 +#define MX6UL_PAD_ENET2_RX_DATA1__I2C3_SDA 0x00e8 0x0374 0x05b8 3 1 +#define MX6UL_PAD_ENET2_RX_DATA1__ENET1_MDC 0x00e8 0x0374 0x0000 4 0 +#define MX6UL_PAD_ENET2_RX_DATA1__GPIO2_IO09 0x00e8 0x0374 0x0000 5 0 +#define MX6UL_PAD_ENET2_RX_DATA1__KPP_COL04 0x00e8 0x0374 0x0000 6 0 +#define MX6UL_PAD_ENET2_RX_DATA1__USB_OTG1_OC 0x00e8 0x0374 0x0664 8 1 +#define MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN 0x00ec 0x0378 0x0000 0 0 +#define MX6UL_PAD_ENET2_RX_EN__UART7_DCE_TX 0x00ec 0x0378 0x0000 1 0 +#define MX6UL_PAD_ENET2_RX_EN__UART7_DTE_RX 0x00ec 0x0378 0x0654 1 0 +#define MX6UL_PAD_ENET2_RX_EN__SIM1_PORT0_RST_B 0x00ec 0x0378 0x0000 2 0 +#define MX6UL_PAD_ENET2_RX_EN__I2C4_SCL 0x00ec 0x0378 0x05bc 3 1 +#define MX6UL_PAD_ENET2_RX_EN__EIM_ADDR26 0x00ec 0x0378 0x0000 4 0 +#define MX6UL_PAD_ENET2_RX_EN__GPIO2_IO10 0x00ec 0x0378 0x0000 5 0 +#define MX6UL_PAD_ENET2_RX_EN__KPP_ROW05 0x00ec 0x0378 0x0000 6 0 +#define MX6UL_PAD_ENET2_RX_EN__ENET1_REF_CLK_25M 0x00ec 0x0378 0x0000 8 0 +#define MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x00f0 0x037c 0x0000 0 0 +#define MX6UL_PAD_ENET2_TX_DATA0__UART7_DCE_RX 0x00f0 0x037c 0x0654 1 1 +#define MX6UL_PAD_ENET2_TX_DATA0__UART7_DTE_TX 0x00f0 0x037c 0x0000 1 0 +#define MX6UL_PAD_ENET2_TX_DATA0__SIM1_PORT0_SVEN 0x00f0 0x037c 0x0000 2 0 +#define MX6UL_PAD_ENET2_TX_DATA0__I2C4_SDA 0x00f0 0x037c 0x05c0 3 1 +#define MX6UL_PAD_ENET2_TX_DATA0__EIM_EB_B02 0x00f0 0x037c 0x0000 4 0 +#define MX6UL_PAD_ENET2_TX_DATA0__GPIO2_IO11 0x00f0 0x037c 0x0000 5 0 +#define MX6UL_PAD_ENET2_TX_DATA0__KPP_COL05 0x00f0 0x037c 0x0000 6 0 +#define MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x00f4 0x0380 0x0000 0 0 +#define MX6UL_PAD_ENET2_TX_DATA1__UART8_DCE_TX 0x00f4 0x0380 0x0000 1 0 +#define MX6UL_PAD_ENET2_TX_DATA1__UART8_DTE_RX 0x00f4 0x0380 0x065c 1 0 +#define MX6UL_PAD_ENET2_TX_DATA1__SIM2_PORT0_TRXD 0x00f4 0x0380 0x0000 2 0 +#define MX6UL_PAD_ENET2_TX_DATA1__ECSPI4_SCLK 0x00f4 0x0380 0x0564 3 0 +#define MX6UL_PAD_ENET2_TX_DATA1__EIM_EB_B03 0x00f4 0x0380 0x0000 4 0 +#define MX6UL_PAD_ENET2_TX_DATA1__GPIO2_IO12 0x00f4 0x0380 0x0000 5 0 +#define MX6UL_PAD_ENET2_TX_DATA1__KPP_ROW06 0x00f4 0x0380 0x0000 6 0 +#define MX6UL_PAD_ENET2_TX_DATA1__USB_OTG2_PWR 0x00f4 0x0380 0x0000 8 0 +#define MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN 0x00f8 0x0384 0x0000 0 0 +#define MX6UL_PAD_ENET2_TX_EN__UART8_DCE_RX 0x00f8 0x0384 0x065c 1 1 +#define MX6UL_PAD_ENET2_TX_EN__UART8_DTE_TX 0x00f8 0x0384 0x0000 1 0 +#define MX6UL_PAD_ENET2_TX_EN__SIM2_PORT0_cLK 0x00f8 0x0384 0x0000 2 0 +#define MX6UL_PAD_ENET2_TX_EN__ECSPI4_MOSI 0x00f8 0x0384 0x056c 3 0 +#define MX6UL_PAD_ENET2_TX_EN__EIM_ACLK_FREERUN 0x00f8 0x0384 0x0000 4 0 +#define MX6UL_PAD_ENET2_TX_EN__GPIO2_IO13 0x00f8 0x0384 0x0000 5 0 +#define MX6UL_PAD_ENET2_TX_EN__KPP_COL06 0x00f8 0x0384 0x0000 6 0 +#define MX6UL_PAD_ENET2_TX_EN__USB_OTG2_OC 0x00f8 0x0384 0x0660 8 1 +#define MX6UL_PAD_ENET2_TX_CLK__ENET2_TX_CLK 0x00fc 0x0388 0x0000 0 0 +#define MX6UL_PAD_ENET2_TX_CLK__UART8_DCE_CTS 0x00fc 0x0388 0x0000 1 0 +#define MX6UL_PAD_ENET2_TX_CLK__UART8_DTE_RTS 0x00fc 0x0388 0x0658 1 0 +#define MX6UL_PAD_ENET2_TX_CLK__SIM2_PORT0_RST_B 0x00fc 0x0388 0x0000 2 0 +#define MX6UL_PAD_ENET2_TX_CLK__ECSPI4_MISO 0x00fc 0x0388 0x0568 3 0 +#define MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 0x00fc 0x0388 0x057c 4 2 +#define MX6UL_PAD_ENET2_TX_CLK__GPIO2_IO14 0x00fc 0x0388 0x0000 5 0 +#define MX6UL_PAD_ENET2_TX_CLK__KPP_ROW07 0x00fc 0x0388 0x0000 6 0 +#define MX6UL_PAD_ENET2_TX_CLK__ANATOP_OTG2_ID 0x00fc 0x0388 0x04bc 8 1 +#define MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER 0x0100 0x038c 0x0000 0 0 +#define MX6UL_PAD_ENET2_RX_ER__UART8_DCE_RTS 0x0100 0x038c 0x0658 1 1 +#define MX6UL_PAD_ENET2_RX_ER__UART8_DTE_CTS 0x0100 0x038c 0x0000 1 0 +#define MX6UL_PAD_ENET2_RX_ER__SIM2_PORT0_SVEN 0x0100 0x038c 0x0000 2 0 +#define MX6UL_PAD_ENET2_RX_ER__ECSPI4_SS0 0x0100 0x038c 0x0000 3 0 +#define MX6UL_PAD_ENET2_RX_ER__EIM_ADDR25 0x0100 0x038c 0x0000 4 0 +#define MX6UL_PAD_ENET2_RX_ER__GPIO2_IO15 0x0100 0x038c 0x0000 5 0 +#define MX6UL_PAD_ENET2_RX_ER__KPP_COL07 0x0100 0x038c 0x0000 6 0 +#define MX6UL_PAD_ENET2_RX_ER__WDOG1_WDOG_ANY 0x0100 0x038c 0x0000 8 0 +#define MX6UL_PAD_LCD_CLK__LCDIF_CLK 0x0104 0x0390 0x0000 0 0 +#define MX6UL_PAD_LCD_CLK__LCDIF_WR_RWN 0x0104 0x0390 0x0000 1 0 +#define MX6UL_PAD_LCD_CLK__UART4_DCE_TX 0x0104 0x0390 0x0000 2 0 +#define MX6UL_PAD_LCD_CLK__UART4_DTE_RX 0x0104 0x0390 0x063c 2 2 +#define MX6UL_PAD_LCD_CLK__SAI3_MCLK 0x0104 0x0390 0x0000 3 0 +#define MX6UL_PAD_LCD_CLK__EIM_CS2_B 0x0104 0x0390 0x0000 4 0 +#define MX6UL_PAD_LCD_CLK__GPIO3_IO00 0x0104 0x0390 0x0000 5 0 +#define MX6UL_PAD_LCD_CLK__WDOG1_WDOG_RST_B_DEB 0x0104 0x0390 0x0000 8 0 +#define MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE 0x0108 0x0394 0x0000 0 0 +#define MX6UL_PAD_LCD_ENABLE__LCDIF_RD_E 0x0108 0x0394 0x0000 1 0 +#define MX6UL_PAD_LCD_ENABLE__UART4_DCE_RX 0x0108 0x0394 0x063c 2 3 +#define MX6UL_PAD_LCD_ENABLE__UART4_DTE_TX 0x0108 0x0394 0x0000 2 0 +#define MX6UL_PAD_LCD_ENABLE__SAI3_TX_SYNC 0x0108 0x0394 0x060c 3 0 +#define MX6UL_PAD_LCD_ENABLE__EIM_CS3_B 0x0108 0x0394 0x0000 4 0 +#define MX6UL_PAD_LCD_ENABLE__GPIO3_IO01 0x0108 0x0394 0x0000 5 0 +#define MX6UL_PAD_LCD_ENABLE__ECSPI2_RDY 0x0108 0x0394 0x0000 8 0 +#define MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC 0x010c 0x0398 0x05dc 0 0 +#define MX6UL_PAD_LCD_HSYNC__LCDIF_RS 0x010c 0x0398 0x0000 1 0 +#define MX6UL_PAD_LCD_HSYNC__UART4_DCE_CTS 0x010c 0x0398 0x0000 2 0 +#define MX6UL_PAD_LCD_HSYNC__UART4_DTE_RTS 0x010c 0x0398 0x0638 2 2 +#define MX6UL_PAD_LCD_HSYNC__SAI3_TX_BCLK 0x010c 0x0398 0x0608 3 0 +#define MX6UL_PAD_LCD_HSYNC__WDOG3_WDOG_RST_B_DEB 0x010c 0x0398 0x0000 4 0 +#define MX6UL_PAD_LCD_HSYNC__GPIO3_IO02 0x010c 0x0398 0x0000 5 0 +#define MX6UL_PAD_LCD_HSYNC__ECSPI2_SS1 0x010c 0x0398 0x0000 8 0 +#define MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC 0x0110 0x039c 0x0000 0 0 +#define MX6UL_PAD_LCD_VSYNC__LCDIF_BUSY 0x0110 0x039c 0x05dc 1 1 +#define MX6UL_PAD_LCD_VSYNC__UART4_DCE_RTS 0x0110 0x039c 0x0638 2 3 +#define MX6UL_PAD_LCD_VSYNC__UART4_DTE_CTS 0x0110 0x039c 0x0000 2 0 +#define MX6UL_PAD_LCD_VSYNC__SAI3_RX_DATA 0x0110 0x039c 0x0000 3 0 +#define MX6UL_PAD_LCD_VSYNC__WDOG2_WDOG_B 0x0110 0x039c 0x0000 4 0 +#define MX6UL_PAD_LCD_VSYNC__GPIO3_IO03 0x0110 0x039c 0x0000 5 0 +#define MX6UL_PAD_LCD_VSYNC__ECSPI2_SS2 0x0110 0x039c 0x0000 8 0 +#define MX6UL_PAD_LCD_RESET__LCDIF_RESET 0x0114 0x03a0 0x0000 0 0 +#define MX6UL_PAD_LCD_RESET__LCDIF_CS 0x0114 0x03a0 0x0000 1 0 +#define MX6UL_PAD_LCD_RESET__CA7_MX6UL_EVENTI 0x0114 0x03a0 0x0000 2 0 +#define MX6UL_PAD_LCD_RESET__SAI3_TX_DATA 0x0114 0x03a0 0x0000 3 0 +#define MX6UL_PAD_LCD_RESET__WDOG1_WDOG_ANY 0x0114 0x03a0 0x0000 4 0 +#define MX6UL_PAD_LCD_RESET__GPIO3_IO04 0x0114 0x03a0 0x0000 5 0 +#define MX6UL_PAD_LCD_RESET__ECSPI2_SS3 0x0114 0x03a0 0x0000 8 0 +#define MX6UL_PAD_LCD_DATA00__LCDIF_DATA00 0x0118 0x03a4 0x0000 0 0 +#define MX6UL_PAD_LCD_DATA00__PWM1_OUT 0x0118 0x03a4 0x0000 1 0 +#define MX6UL_PAD_LCD_DATA00__ENET1_1588_EVENT2_IN 0x0118 0x03a4 0x0000 3 0 +#define MX6UL_PAD_LCD_DATA00__I2C3_SDA 0x0118 0x03a4 0x05b8 4 2 +#define MX6UL_PAD_LCD_DATA00__GPIO3_IO05 0x0118 0x03a4 0x0000 5 0 +#define MX6UL_PAD_LCD_DATA00__SRC_BT_CFG00 0x0118 0x03a4 0x0000 6 0 +#define MX6UL_PAD_LCD_DATA00__SAI1_MCLK 0x0118 0x03a4 0x0000 8 0 +#define MX6UL_PAD_LCD_DATA01__LCDIF_DATA01 0x011c 0x03a8 0x0000 0 0 +#define MX6UL_PAD_LCD_DATA01__PWM2_OUT 0x011c 0x03a8 0x0000 1 0 +#define MX6UL_PAD_LCD_DATA01__ENET1_1588_EVENT2_OUT 0x011c 0x03a8 0x0000 3 0 +#define MX6UL_PAD_LCD_DATA01__I2C3_SCL 0x011c 0x03a8 0x05b4 4 2 +#define MX6UL_PAD_LCD_DATA01__GPIO3_IO06 0x011c 0x03a8 0x0000 5 0 +#define MX6UL_PAD_LCD_DATA01__SRC_BT_CFG01 0x011c 0x03a8 0x0000 6 0 +#define MX6UL_PAD_LCD_DATA01__SAI1_TX_SYNC 0x011c 0x03a8 0x05ec 8 0 +#define MX6UL_PAD_LCD_DATA02__LCDIF_DATA02 0x0120 0x03ac 0x0000 0 0 +#define MX6UL_PAD_LCD_DATA02__PWM3_OUT 0x0120 0x03ac 0x0000 1 0 +#define MX6UL_PAD_LCD_DATA02__ENET1_1588_EVENT3_IN 0x0120 0x03ac 0x0000 3 0 +#define MX6UL_PAD_LCD_DATA02__I2C4_SDA 0x0120 0x03ac 0x05c0 4 2 +#define MX6UL_PAD_LCD_DATA02__GPIO3_IO07 0x0120 0x03ac 0x0000 5 0 +#define MX6UL_PAD_LCD_DATA02__SRC_BT_CFG02 0x0120 0x03ac 0x0000 6 0 +#define MX6UL_PAD_LCD_DATA02__SAI1_TX_BCLK 0x0120 0x03ac 0x05e8 8 0 +#define MX6UL_PAD_LCD_DATA03__LCDIF_DATA03 0x0124 0x03b0 0x0000 0 0 +#define MX6UL_PAD_LCD_DATA03__PWM4_OUT 0x0124 0x03b0 0x0000 1 0 +#define MX6UL_PAD_LCD_DATA03__ENET1_1588_EVENT3_OUT 0x0124 0x03b0 0x0000 3 0 +#define MX6UL_PAD_LCD_DATA03__I2C4_SCL 0x0124 0x03b0 0x05bc 4 2 +#define MX6UL_PAD_LCD_DATA03__GPIO3_IO08 0x0124 0x03b0 0x0000 5 0 +#define MX6UL_PAD_LCD_DATA03__SRC_BT_CFG03 0x0124 0x03b0 0x0000 6 0 +#define MX6UL_PAD_LCD_DATA03__SAI1_RX_DATA 0x0124 0x03b0 0x0000 8 0 +#define MX6UL_PAD_LCD_DATA04__LCDIF_DATA04 0x0128 0x03b4 0x0000 0 0 +#define MX6UL_PAD_LCD_DATA04__UART8_DCE_CTS 0x0128 0x03b4 0x0000 1 0 +#define MX6UL_PAD_LCD_DATA04__UART8_DTE_RTS 0x0128 0x03b4 0x0658 1 2 +#define MX6UL_PAD_LCD_DATA04__ENET2_1588_EVENT2_IN 0x0128 0x03b4 0x0000 3 0 +#define MX6UL_PAD_LCD_DATA04__SPDIF_SR_CLK 0x0128 0x03b4 0x0000 4 0 +#define MX6UL_PAD_LCD_DATA04__GPIO3_IO09 0x0128 0x03b4 0x0000 5 0 +#define MX6UL_PAD_LCD_DATA04__SRC_BT_CFG04 0x0128 0x03b4 0x0000 6 0 +#define MX6UL_PAD_LCD_DATA04__SAI1_TX_DATA 0x0128 0x03b4 0x0000 8 0 +#define MX6UL_PAD_LCD_DATA05__LCDIF_DATA05 0x012c 0x03b8 0x0000 0 0 +#define MX6UL_PAD_LCD_DATA05__UART8_DCE_RTS 0x012c 0x03b8 0x0658 1 3 +#define MX6UL_PAD_LCD_DATA05__UART8_DTE_CTS 0x012c 0x03b8 0x0000 1 0 +#define MX6UL_PAD_LCD_DATA05__ENET2_1588_EVENT2_OUT 0x012c 0x03b8 0x0000 3 0 +#define MX6UL_PAD_LCD_DATA05__SPDIF_OUT 0x012c 0x03b8 0x0000 4 0 +#define MX6UL_PAD_LCD_DATA05__GPIO3_IO10 0x012c 0x03b8 0x0000 5 0 +#define MX6UL_PAD_LCD_DATA05__SRC_BT_CFG05 0x012c 0x03b8 0x0000 6 0 +#define MX6UL_PAD_LCD_DATA05__ECSPI1_SS1 0x012c 0x03b8 0x0000 8 0 +#define MX6UL_PAD_LCD_DATA06__LCDIF_DATA06 0x0130 0x03bc 0x0000 0 0 +#define MX6UL_PAD_LCD_DATA06__UART7_DCE_CTS 0x0130 0x03bc 0x0000 1 0 +#define MX6UL_PAD_LCD_DATA06__UART7_DTE_RTS 0x0130 0x03bc 0x0650 1 2 +#define MX6UL_PAD_LCD_DATA06__ENET2_1588_EVENT3_IN 0x0130 0x03bc 0x0000 3 0 +#define MX6UL_PAD_LCD_DATA06__SPDIF_LOCK 0x0130 0x03bc 0x0000 4 0 +#define MX6UL_PAD_LCD_DATA06__GPIO3_IO11 0x0130 0x03bc 0x0000 5 0 +#define MX6UL_PAD_LCD_DATA06__SRC_BT_CFG06 0x0130 0x03bc 0x0000 6 0 +#define MX6UL_PAD_LCD_DATA06__ECSPI1_SS2 0x0130 0x03bc 0x0000 8 0 +#define MX6UL_PAD_LCD_DATA07__LCDIF_DATA07 0x0134 0x03c0 0x0000 0 0 +#define MX6UL_PAD_LCD_DATA07__UART7_DCE_RTS 0x0134 0x03c0 0x0650 1 3 +#define MX6UL_PAD_LCD_DATA07__UART7_DTE_CTS 0x0134 0x03c0 0x0000 1 0 +#define MX6UL_PAD_LCD_DATA07__ENET2_1588_EVENT3_OUT 0x0134 0x03c0 0x0000 3 0 +#define MX6UL_PAD_LCD_DATA07__SPDIF_EXT_CLK 0x0134 0x03c0 0x061c 4 0 +#define MX6UL_PAD_LCD_DATA07__GPIO3_IO12 0x0134 0x03c0 0x0000 5 0 +#define MX6UL_PAD_LCD_DATA07__SRC_BT_CFG07 0x0134 0x03c0 0x0000 6 0 +#define MX6UL_PAD_LCD_DATA07__ECSPI1_SS3 0x0134 0x03c0 0x0000 8 0 +#define MX6UL_PAD_LCD_DATA08__LCDIF_DATA08 0x0138 0x03c4 0x0000 0 0 +#define MX6UL_PAD_LCD_DATA08__SPDIF_IN 0x0138 0x03c4 0x0618 1 2 +#define MX6UL_PAD_LCD_DATA08__CSI_DATA16 0x0138 0x03c4 0x0000 3 0 +#define MX6UL_PAD_LCD_DATA08__EIM_DATA00 0x0138 0x03c4 0x0000 4 0 +#define MX6UL_PAD_LCD_DATA08__GPIO3_IO13 0x0138 0x03c4 0x0000 5 0 +#define MX6UL_PAD_LCD_DATA08__SRC_BT_CFG08 0x0138 0x03c4 0x0000 6 0 +#define MX6UL_PAD_LCD_DATA08__FLEXCAN1_TX 0x0138 0x03c4 0x0000 8 0 +#define MX6UL_PAD_LCD_DATA09__LCDIF_DATA09 0x013c 0x03c8 0x0000 0 0 +#define MX6UL_PAD_LCD_DATA09__SAI3_MCLK 0x013c 0x03c8 0x0000 1 0 +#define MX6UL_PAD_LCD_DATA09__CSI_DATA17 0x013c 0x03c8 0x0000 3 0 +#define MX6UL_PAD_LCD_DATA09__EIM_DATA01 0x013c 0x03c8 0x0000 4 0 +#define MX6UL_PAD_LCD_DATA09__GPIO3_IO14 0x013c 0x03c8 0x0000 5 0 +#define MX6UL_PAD_LCD_DATA09__SRC_BT_CFG09 0x013c 0x03c8 0x0000 6 0 +#define MX6UL_PAD_LCD_DATA09__FLEXCAN1_RX 0x013c 0x03c8 0x0584 8 2 +#define MX6UL_PAD_LCD_DATA10__LCDIF_DATA10 0x0140 0x03cc 0x0000 0 0 +#define MX6UL_PAD_LCD_DATA10__SAI3_RX_SYNC 0x0140 0x03cc 0x0000 1 0 +#define MX6UL_PAD_LCD_DATA10__CSI_DATA18 0x0140 0x03cc 0x0000 3 0 +#define MX6UL_PAD_LCD_DATA10__EIM_DATA02 0x0140 0x03cc 0x0000 4 0 +#define MX6UL_PAD_LCD_DATA10__GPIO3_IO15 0x0140 0x03cc 0x0000 5 0 +#define MX6UL_PAD_LCD_DATA10__SRC_BT_CFG10 0x0140 0x03cc 0x0000 6 0 +#define MX6UL_PAD_LCD_DATA10__FLEXCAN2_TX 0x0140 0x03cc 0x0000 8 0 +#define MX6UL_PAD_LCD_DATA11__LCDIF_DATA11 0x0144 0x03d0 0x0000 0 0 +#define MX6UL_PAD_LCD_DATA11__SAI3_RX_BCLK 0x0144 0x03d0 0x0000 1 0 +#define MX6UL_PAD_LCD_DATA11__CSI_DATA19 0x0144 0x03d0 0x0000 3 0 +#define MX6UL_PAD_LCD_DATA11__EIM_DATA03 0x0144 0x03d0 0x0000 4 0 +#define MX6UL_PAD_LCD_DATA11__GPIO3_IO16 0x0144 0x03d0 0x0000 5 0 +#define MX6UL_PAD_LCD_DATA11__SRC_BT_CFG11 0x0144 0x03d0 0x0000 6 0 +#define MX6UL_PAD_LCD_DATA11__FLEXCAN2_RX 0x0144 0x03d0 0x0588 8 2 +#define MX6UL_PAD_LCD_DATA12__LCDIF_DATA12 0x0148 0x03d4 0x0000 0 0 +#define MX6UL_PAD_LCD_DATA12__SAI3_TX_SYNC 0x0148 0x03d4 0x060c 1 1 +#define MX6UL_PAD_LCD_DATA12__CSI_DATA20 0x0148 0x03d4 0x0000 3 0 +#define MX6UL_PAD_LCD_DATA12__EIM_DATA04 0x0148 0x03d4 0x0000 4 0 +#define MX6UL_PAD_LCD_DATA12__GPIO3_IO17 0x0148 0x03d4 0x0000 5 0 +#define MX6UL_PAD_LCD_DATA12__SRC_BT_CFG12 0x0148 0x03d4 0x0000 6 0 +#define MX6UL_PAD_LCD_DATA12__ECSPI1_RDY 0x0148 0x03d4 0x0000 8 0 +#define MX6UL_PAD_LCD_DATA13__LCDIF_DATA13 0x014c 0x03d8 0x0000 0 0 +#define MX6UL_PAD_LCD_DATA13__SAI3_TX_BCLK 0x014c 0x03d8 0x0608 1 1 +#define MX6UL_PAD_LCD_DATA13__CSI_DATA21 0x014c 0x03d8 0x0000 3 0 +#define MX6UL_PAD_LCD_DATA13__EIM_DATA05 0x014c 0x03d8 0x0000 4 0 +#define MX6UL_PAD_LCD_DATA13__GPIO3_IO18 0x014c 0x03d8 0x0000 5 0 +#define MX6UL_PAD_LCD_DATA13__SRC_BT_CFG13 0x014c 0x03d8 0x0000 6 0 +#define MX6UL_PAD_LCD_DATA13__USDHC2_RESET_B 0x014c 0x03d8 0x0000 8 0 +#define MX6UL_PAD_LCD_DATA14__LCDIF_DATA14 0x0150 0x03dc 0x0000 0 0 +#define MX6UL_PAD_LCD_DATA14__SAI3_RX_DATA 0x0150 0x03dc 0x0000 1 0 +#define MX6UL_PAD_LCD_DATA14__CSI_DATA22 0x0150 0x03dc 0x0000 3 0 +#define MX6UL_PAD_LCD_DATA14__EIM_DATA06 0x0150 0x03dc 0x0000 4 0 +#define MX6UL_PAD_LCD_DATA14__GPIO3_IO19 0x0150 0x03dc 0x0000 5 0 +#define MX6UL_PAD_LCD_DATA14__SRC_BT_CFG14 0x0150 0x03dc 0x0000 6 0 +#define MX6UL_PAD_LCD_DATA14__USDHC2_DATA4 0x0150 0x03dc 0x068c 8 0 +#define MX6UL_PAD_LCD_DATA15__LCDIF_DATA15 0x0154 0x03e0 0x0000 0 0 +#define MX6UL_PAD_LCD_DATA15__SAI3_TX_DATA 0x0154 0x03e0 0x0000 1 0 +#define MX6UL_PAD_LCD_DATA15__CSI_DATA23 0x0154 0x03e0 0x0000 3 0 +#define MX6UL_PAD_LCD_DATA15__EIM_DATA07 0x0154 0x03e0 0x0000 4 0 +#define MX6UL_PAD_LCD_DATA15__GPIO3_IO20 0x0154 0x03e0 0x0000 5 0 +#define MX6UL_PAD_LCD_DATA15__SRC_BT_CFG15 0x0154 0x03e0 0x0000 6 0 +#define MX6UL_PAD_LCD_DATA15__USDHC2_DATA5 0x0154 0x03e0 0x0690 8 0 +#define MX6UL_PAD_LCD_DATA16__LCDIF_DATA16 0x0158 0x03e4 0x0000 0 0 +#define MX6UL_PAD_LCD_DATA16__UART7_DCE_TX 0x0158 0x03e4 0x0000 1 0 +#define MX6UL_PAD_LCD_DATA16__UART7_DTE_RX 0x0158 0x03e4 0x0654 1 2 +#define MX6UL_PAD_LCD_DATA16__CSI_DATA01 0x0158 0x03e4 0x0000 3 0 +#define MX6UL_PAD_LCD_DATA16__EIM_DATA08 0x0158 0x03e4 0x0000 4 0 +#define MX6UL_PAD_LCD_DATA16__GPIO3_IO21 0x0158 0x03e4 0x0000 5 0 +#define MX6UL_PAD_LCD_DATA16__SRC_BT_CFG24 0x0158 0x03e4 0x0000 6 0 +#define MX6UL_PAD_LCD_DATA16__USDHC2_DATA6 0x0158 0x03e4 0x0694 8 0 +#define MX6UL_PAD_LCD_DATA17__LCDIF_DATA17 0x015c 0x03e8 0x0000 0 0 +#define MX6UL_PAD_LCD_DATA17__UART7_DCE_RX 0x015c 0x03e8 0x0654 1 3 +#define MX6UL_PAD_LCD_DATA17__UART7_DTE_TX 0x015c 0x03e8 0x0000 1 0 +#define MX6UL_PAD_LCD_DATA17__CSI_DATA00 0x015c 0x03e8 0x0000 3 0 +#define MX6UL_PAD_LCD_DATA17__EIM_DATA09 0x015c 0x03e8 0x0000 4 0 +#define MX6UL_PAD_LCD_DATA17__GPIO3_IO22 0x015c 0x03e8 0x0000 5 0 +#define MX6UL_PAD_LCD_DATA17__SRC_BT_CFG25 0x015c 0x03e8 0x0000 6 0 +#define MX6UL_PAD_LCD_DATA17__USDHC2_DATA7 0x015c 0x03e8 0x0698 8 0 +#define MX6UL_PAD_LCD_DATA18__LCDIF_DATA18 0x0160 0x03ec 0x0000 0 0 +#define MX6UL_PAD_LCD_DATA18__PWM5_OUT 0x0160 0x03ec 0x0000 1 0 +#define MX6UL_PAD_LCD_DATA18__CA7_MX6UL_EVENTO 0x0160 0x03ec 0x0000 2 0 +#define MX6UL_PAD_LCD_DATA18__CSI_DATA10 0x0160 0x03ec 0x0000 3 0 +#define MX6UL_PAD_LCD_DATA18__EIM_DATA10 0x0160 0x03ec 0x0000 4 0 +#define MX6UL_PAD_LCD_DATA18__GPIO3_IO23 0x0160 0x03ec 0x0000 5 0 +#define MX6UL_PAD_LCD_DATA18__SRC_BT_CFG26 0x0160 0x03ec 0x0000 6 0 +#define MX6UL_PAD_LCD_DATA18__USDHC2_CMD 0x0160 0x03ec 0x0678 8 1 +#define MX6UL_PAD_LCD_DATA19__EIM_DATA11 0x0164 0x03f0 0x0000 4 0 +#define MX6UL_PAD_LCD_DATA19__GPIO3_IO24 0x0164 0x03f0 0x0000 5 0 +#define MX6UL_PAD_LCD_DATA19__SRC_BT_CFG27 0x0164 0x03f0 0x0000 6 0 +#define MX6UL_PAD_LCD_DATA19__USDHC2_CLK 0x0164 0x03f0 0x0670 8 1 +#define MX6UL_PAD_LCD_DATA19__LCDIF_DATA19 0x0164 0x03f0 0x0000 0 0 +#define MX6UL_PAD_LCD_DATA19__PWM6_OUT 0x0164 0x03f0 0x0000 1 0 +#define MX6UL_PAD_LCD_DATA19__WDOG1_WDOG_ANY 0x0164 0x03f0 0x0000 2 0 +#define MX6UL_PAD_LCD_DATA19__CSI_DATA11 0x0164 0x03f0 0x0000 3 0 +#define MX6UL_PAD_LCD_DATA20__EIM_DATA12 0x0168 0x03f4 0x0000 4 0 +#define MX6UL_PAD_LCD_DATA20__GPIO3_IO25 0x0168 0x03f4 0x0000 5 0 +#define MX6UL_PAD_LCD_DATA20__SRC_BT_CFG28 0x0168 0x03f4 0x0000 6 0 +#define MX6UL_PAD_LCD_DATA20__USDHC2_DATA0 0x0168 0x03f4 0x067c 8 1 +#define MX6UL_PAD_LCD_DATA20__LCDIF_DATA20 0x0168 0x03f4 0x0000 0 0 +#define MX6UL_PAD_LCD_DATA20__UART8_DCE_TX 0x0168 0x03f4 0x0000 1 0 +#define MX6UL_PAD_LCD_DATA20__UART8_DTE_RX 0x0168 0x03f4 0x065c 1 2 +#define MX6UL_PAD_LCD_DATA20__ECSPI1_SCLK 0x0168 0x03f4 0x0534 2 0 +#define MX6UL_PAD_LCD_DATA20__CSI_DATA12 0x0168 0x03f4 0x0000 3 0 +#define MX6UL_PAD_LCD_DATA21__LCDIF_DATA21 0x016c 0x03f8 0x0000 0 0 +#define MX6UL_PAD_LCD_DATA21__UART8_DCE_RX 0x016c 0x03f8 0x065c 1 3 +#define MX6UL_PAD_LCD_DATA21__UART8_DTE_TX 0x016c 0x03f8 0x0000 1 0 +#define MX6UL_PAD_LCD_DATA21__ECSPI1_SS0 0x016c 0x03f8 0x0000 2 0 +#define MX6UL_PAD_LCD_DATA21__CSI_DATA13 0x016c 0x03f8 0x0000 3 0 +#define MX6UL_PAD_LCD_DATA21__EIM_DATA13 0x016c 0x03f8 0x0000 4 0 +#define MX6UL_PAD_LCD_DATA21__GPIO3_IO26 0x016c 0x03f8 0x0000 5 0 +#define MX6UL_PAD_LCD_DATA21__SRC_BT_CFG29 0x016c 0x03f8 0x0000 6 0 +#define MX6UL_PAD_LCD_DATA21__USDHC2_DATA1 0x016c 0x03f8 0x0680 8 1 +#define MX6UL_PAD_LCD_DATA22__LCDIF_DATA22 0x0170 0x03fc 0x0000 0 0 +#define MX6UL_PAD_LCD_DATA22__MQS_RIGHT 0x0170 0x03fc 0x0000 1 0 +#define MX6UL_PAD_LCD_DATA22__ECSPI1_MOSI 0x0170 0x03fc 0x053c 2 0 +#define MX6UL_PAD_LCD_DATA22__CSI_DATA14 0x0170 0x03fc 0x0000 3 0 +#define MX6UL_PAD_LCD_DATA22__EIM_DATA14 0x0170 0x03fc 0x0000 4 0 +#define MX6UL_PAD_LCD_DATA22__GPIO3_IO27 0x0170 0x03fc 0x0000 5 0 +#define MX6UL_PAD_LCD_DATA22__SRC_BT_CFG30 0x0170 0x03fc 0x0000 6 0 +#define MX6UL_PAD_LCD_DATA22__USDHC2_DATA2 0x0170 0x03fc 0x0684 8 0 +#define MX6UL_PAD_LCD_DATA23__LCDIF_DATA23 0x0174 0x0400 0x0000 0 0 +#define MX6UL_PAD_LCD_DATA23__MQS_LEFT 0x0174 0x0400 0x0000 1 0 +#define MX6UL_PAD_LCD_DATA23__ECSPI1_MISO 0x0174 0x0400 0x0538 2 0 +#define MX6UL_PAD_LCD_DATA23__CSI_DATA15 0x0174 0x0400 0x0000 3 0 +#define MX6UL_PAD_LCD_DATA23__EIM_DATA15 0x0174 0x0400 0x0000 4 0 +#define MX6UL_PAD_LCD_DATA23__GPIO3_IO28 0x0174 0x0400 0x0000 5 0 +#define MX6UL_PAD_LCD_DATA23__SRC_BT_CFG31 0x0174 0x0400 0x0000 6 0 +#define MX6UL_PAD_LCD_DATA23__USDHC2_DATA3 0x0174 0x0400 0x0688 8 1 +#define MX6UL_PAD_NAND_RE_B__RAWNAND_RE_B 0x0178 0x0404 0x0000 0 0 +#define MX6UL_PAD_NAND_RE_B__USDHC2_CLK 0x0178 0x0404 0x0670 1 2 +#define MX6UL_PAD_NAND_RE_B__QSPI_B_SCLK 0x0178 0x0404 0x0000 2 0 +#define MX6UL_PAD_NAND_RE_B__KPP_ROW00 0x0178 0x0404 0x0000 3 0 +#define MX6UL_PAD_NAND_RE_B__EIM_EB_B00 0x0178 0x0404 0x0000 4 0 +#define MX6UL_PAD_NAND_RE_B__GPIO4_IO00 0x0178 0x0404 0x0000 5 0 +#define MX6UL_PAD_NAND_RE_B__ECSPI3_SS2 0x0178 0x0404 0x0000 8 0 +#define MX6UL_PAD_NAND_WE_B__RAWNAND_WE_B 0x017c 0x0408 0x0000 0 0 +#define MX6UL_PAD_NAND_WE_B__USDHC2_CMD 0x017c 0x0408 0x0678 1 2 +#define MX6UL_PAD_NAND_WE_B__QSPI_B_SS0_B 0x017c 0x0408 0x0000 2 0 +#define MX6UL_PAD_NAND_WE_B__KPP_COL00 0x017c 0x0408 0x0000 3 0 +#define MX6UL_PAD_NAND_WE_B__EIM_EB_B01 0x017c 0x0408 0x0000 4 0 +#define MX6UL_PAD_NAND_WE_B__GPIO4_IO01 0x017c 0x0408 0x0000 5 0 +#define MX6UL_PAD_NAND_WE_B__ECSPI3_SS3 0x017c 0x0408 0x0000 8 0 +#define MX6UL_PAD_NAND_DATA00__RAWNAND_DATA00 0x0180 0x040c 0x0000 0 0 +#define MX6UL_PAD_NAND_DATA00__USDHC2_DATA0 0x0180 0x040c 0x067c 1 2 +#define MX6UL_PAD_NAND_DATA00__QSPI_B_SS1_B 0x0180 0x040c 0x0000 2 0 +#define MX6UL_PAD_NAND_DATA00__KPP_ROW01 0x0180 0x040c 0x0000 3 0 +#define MX6UL_PAD_NAND_DATA00__EIM_AD08 0x0180 0x040c 0x0000 4 0 +#define MX6UL_PAD_NAND_DATA00__GPIO4_IO02 0x0180 0x040c 0x0000 5 0 +#define MX6UL_PAD_NAND_DATA00__ECSPI4_RDY 0x0180 0x040c 0x0000 8 0 +#define MX6UL_PAD_NAND_DATA01__RAWNAND_DATA01 0x0184 0x0410 0x0000 0 0 +#define MX6UL_PAD_NAND_DATA01__USDHC2_DATA1 0x0184 0x0410 0x0680 1 2 +#define MX6UL_PAD_NAND_DATA01__QSPI_B_DQS 0x0184 0x0410 0x0000 2 0 +#define MX6UL_PAD_NAND_DATA01__KPP_COL01 0x0184 0x0410 0x0000 3 0 +#define MX6UL_PAD_NAND_DATA01__EIM_AD09 0x0184 0x0410 0x0000 4 0 +#define MX6UL_PAD_NAND_DATA01__GPIO4_IO03 0x0184 0x0410 0x0000 5 0 +#define MX6UL_PAD_NAND_DATA01__ECSPI4_SS1 0x0184 0x0410 0x0000 8 0 +#define MX6UL_PAD_NAND_DATA02__RAWNAND_DATA02 0x0188 0x0414 0x0000 0 0 +#define MX6UL_PAD_NAND_DATA02__USDHC2_DATA2 0x0188 0x0414 0x0684 1 1 +#define MX6UL_PAD_NAND_DATA02__QSPI_B_DATA00 0x0188 0x0414 0x0000 2 0 +#define MX6UL_PAD_NAND_DATA02__KPP_ROW02 0x0188 0x0414 0x0000 3 0 +#define MX6UL_PAD_NAND_DATA02__EIM_AD10 0x0188 0x0414 0x0000 4 0 +#define MX6UL_PAD_NAND_DATA02__GPIO4_IO04 0x0188 0x0414 0x0000 5 0 +#define MX6UL_PAD_NAND_DATA02__ECSPI4_SS2 0x0188 0x0414 0x0000 8 0 +#define MX6UL_PAD_NAND_DATA03__RAWNAND_DATA03 0x018c 0x0418 0x0000 0 0 +#define MX6UL_PAD_NAND_DATA03__USDHC2_DATA3 0x018c 0x0418 0x0688 1 2 +#define MX6UL_PAD_NAND_DATA03__QSPI_B_DATA01 0x018c 0x0418 0x0000 2 0 +#define MX6UL_PAD_NAND_DATA03__KPP_COL02 0x018c 0x0418 0x0000 3 0 +#define MX6UL_PAD_NAND_DATA03__EIM_AD11 0x018c 0x0418 0x0000 4 0 +#define MX6UL_PAD_NAND_DATA03__GPIO4_IO05 0x018c 0x0418 0x0000 5 0 +#define MX6UL_PAD_NAND_DATA03__ECSPI4_SS3 0x018c 0x0418 0x0000 8 0 +#define MX6UL_PAD_NAND_DATA04__RAWNAND_DATA04 0x0190 0x041c 0x0000 0 0 +#define MX6UL_PAD_NAND_DATA04__USDHC2_DATA4 0x0190 0x041c 0x068c 1 1 +#define MX6UL_PAD_NAND_DATA04__QSPI_B_DATA02 0x0190 0x041c 0x0000 2 0 +#define MX6UL_PAD_NAND_DATA04__ECSPI4_SCLK 0x0190 0x041c 0x0564 3 1 +#define MX6UL_PAD_NAND_DATA04__EIM_AD12 0x0190 0x041c 0x0000 4 0 +#define MX6UL_PAD_NAND_DATA04__GPIO4_IO06 0x0190 0x041c 0x0000 5 0 +#define MX6UL_PAD_NAND_DATA04__UART2_DCE_TX 0x0190 0x041c 0x0000 8 0 +#define MX6UL_PAD_NAND_DATA04__UART2_DTE_RX 0x0190 0x041c 0x062c 8 2 +#define MX6UL_PAD_NAND_DATA05__RAWNAND_DATA05 0x0194 0x0420 0x0000 0 0 +#define MX6UL_PAD_NAND_DATA05__USDHC2_DATA5 0x0194 0x0420 0x0690 1 1 +#define MX6UL_PAD_NAND_DATA05__QSPI_B_DATA03 0x0194 0x0420 0x0000 2 0 +#define MX6UL_PAD_NAND_DATA05__ECSPI4_MOSI 0x0194 0x0420 0x056c 3 1 +#define MX6UL_PAD_NAND_DATA05__EIM_AD13 0x0194 0x0420 0x0000 4 0 +#define MX6UL_PAD_NAND_DATA05__GPIO4_IO07 0x0194 0x0420 0x0000 5 0 +#define MX6UL_PAD_NAND_DATA05__UART2_DCE_RX 0x0194 0x0420 0x062c 8 3 +#define MX6UL_PAD_NAND_DATA05__UART2_DTE_TX 0x0194 0x0420 0x0000 8 0 +#define MX6UL_PAD_NAND_DATA06__RAWNAND_DATA06 0x0198 0x0424 0x0000 0 0 +#define MX6UL_PAD_NAND_DATA06__USDHC2_DATA6 0x0198 0x0424 0x0694 1 1 +#define MX6UL_PAD_NAND_DATA06__SAI2_RX_BCLK 0x0198 0x0424 0x0000 2 0 +#define MX6UL_PAD_NAND_DATA06__ECSPI4_MISO 0x0198 0x0424 0x0568 3 1 +#define MX6UL_PAD_NAND_DATA06__EIM_AD14 0x0198 0x0424 0x0000 4 0 +#define MX6UL_PAD_NAND_DATA06__GPIO4_IO08 0x0198 0x0424 0x0000 5 0 +#define MX6UL_PAD_NAND_DATA06__UART2_DCE_CTS 0x0198 0x0424 0x0000 8 0 +#define MX6UL_PAD_NAND_DATA06__UART2_DTE_RTS 0x0198 0x0424 0x0628 8 4 +#define MX6UL_PAD_NAND_DATA07__RAWNAND_DATA07 0x019c 0x0428 0x0000 0 0 +#define MX6UL_PAD_NAND_DATA07__USDHC2_DATA7 0x019c 0x0428 0x0698 1 1 +#define MX6UL_PAD_NAND_DATA07__QSPI_A_SS1_B 0x019c 0x0428 0x0000 2 0 +#define MX6UL_PAD_NAND_DATA07__ECSPI4_SS0 0x019c 0x0428 0x0000 3 0 +#define MX6UL_PAD_NAND_DATA07__EIM_AD15 0x019c 0x0428 0x0000 4 0 +#define MX6UL_PAD_NAND_DATA07__GPIO4_IO09 0x019c 0x0428 0x0000 5 0 +#define MX6UL_PAD_NAND_DATA07__UART2_DCE_RTS 0x019c 0x0428 0x0628 8 5 +#define MX6UL_PAD_NAND_DATA07__UART2_DTE_CTS 0x019c 0x0428 0x0000 8 0 +#define MX6UL_PAD_NAND_ALE__RAWNAND_ALE 0x01a0 0x042c 0x0000 0 0 +#define MX6UL_PAD_NAND_ALE__USDHC2_RESET_B 0x01a0 0x042c 0x0000 1 0 +#define MX6UL_PAD_NAND_ALE__QSPI_A_DQS 0x01a0 0x042c 0x0000 2 0 +#define MX6UL_PAD_NAND_ALE__PWM3_OUT 0x01a0 0x042c 0x0000 3 0 +#define MX6UL_PAD_NAND_ALE__EIM_ADDR17 0x01a0 0x042c 0x0000 4 0 +#define MX6UL_PAD_NAND_ALE__GPIO4_IO10 0x01a0 0x042c 0x0000 5 0 +#define MX6UL_PAD_NAND_ALE__ECSPI3_SS1 0x01a0 0x042c 0x0000 8 0 +#define MX6UL_PAD_NAND_WP_B__RAWNAND_WP_B 0x01a4 0x0430 0x0000 0 0 +#define MX6UL_PAD_NAND_WP_B__USDHC1_RESET_B 0x01a4 0x0430 0x0000 1 0 +#define MX6UL_PAD_NAND_WP_B__QSPI_A_SCLK 0x01a4 0x0430 0x0000 2 0 +#define MX6UL_PAD_NAND_WP_B__PWM4_OUT 0x01a4 0x0430 0x0000 3 0 +#define MX6UL_PAD_NAND_WP_B__EIM_BCLK 0x01a4 0x0430 0x0000 4 0 +#define MX6UL_PAD_NAND_WP_B__GPIO4_IO11 0x01a4 0x0430 0x0000 5 0 +#define MX6UL_PAD_NAND_WP_B__ECSPI3_RDY 0x01a4 0x0430 0x0000 8 0 +#define MX6UL_PAD_NAND_READY_B__RAWNAND_READY_B 0x01a8 0x0434 0x0000 0 0 +#define MX6UL_PAD_NAND_READY_B__USDHC1_DATA4 0x01a8 0x0434 0x0000 1 0 +#define MX6UL_PAD_NAND_READY_B__QSPI_A_DATA00 0x01a8 0x0434 0x0000 2 0 +#define MX6UL_PAD_NAND_READY_B__ECSPI3_SS0 0x01a8 0x0434 0x0000 3 0 +#define MX6UL_PAD_NAND_READY_B__EIM_CS1_B 0x01a8 0x0434 0x0000 4 0 +#define MX6UL_PAD_NAND_READY_B__GPIO4_IO12 0x01a8 0x0434 0x0000 5 0 +#define MX6UL_PAD_NAND_READY_B__UART3_DCE_TX 0x01a8 0x0434 0x0000 8 0 +#define MX6UL_PAD_NAND_READY_B__UART3_DTE_RX 0x01a8 0x0434 0x0634 8 2 +#define MX6UL_PAD_NAND_CE0_B__RAWNAND_CE0_B 0x01ac 0x0438 0x0000 0 0 +#define MX6UL_PAD_NAND_CE0_B__USDHC1_DATA5 0x01ac 0x0438 0x0000 1 0 +#define MX6UL_PAD_NAND_CE0_B__QSPI_A_DATA01 0x01ac 0x0438 0x0000 2 0 +#define MX6UL_PAD_NAND_CE0_B__ECSPI3_SCLK 0x01ac 0x0438 0x0554 3 1 +#define MX6UL_PAD_NAND_CE0_B__EIM_DTACK_B 0x01ac 0x0438 0x0000 4 0 +#define MX6UL_PAD_NAND_CE0_B__GPIO4_IO13 0x01ac 0x0438 0x0000 5 0 +#define MX6UL_PAD_NAND_CE0_B__UART3_DCE_RX 0x01ac 0x0438 0x0634 8 3 +#define MX6UL_PAD_NAND_CE0_B__UART3_DTE_TX 0x01ac 0x0438 0x0000 8 0 +#define MX6UL_PAD_NAND_CE1_B__RAWNAND_CE1_B 0x01b0 0x043c 0x0000 0 0 +#define MX6UL_PAD_NAND_CE1_B__USDHC1_DATA6 0x01b0 0x043c 0x0000 1 0 +#define MX6UL_PAD_NAND_CE1_B__QSPI_A_DATA02 0x01b0 0x043c 0x0000 2 0 +#define MX6UL_PAD_NAND_CE1_B__ECSPI3_MOSI 0x01b0 0x043c 0x055c 3 1 +#define MX6UL_PAD_NAND_CE1_B__EIM_ADDR18 0x01b0 0x043c 0x0000 4 0 +#define MX6UL_PAD_NAND_CE1_B__GPIO4_IO14 0x01b0 0x043c 0x0000 5 0 +#define MX6UL_PAD_NAND_CE1_B__UART3_DCE_CTS 0x01b0 0x043c 0x0000 8 0 +#define MX6UL_PAD_NAND_CE1_B__UART3_DTE_RTS 0x01b0 0x043c 0x0630 8 2 +#define MX6UL_PAD_NAND_CLE__RAWNAND_CLE 0x01b4 0x0440 0x0000 0 0 +#define MX6UL_PAD_NAND_CLE__USDHC1_DATA7 0x01b4 0x0440 0x0000 1 0 +#define MX6UL_PAD_NAND_CLE__QSPI_A_DATA03 0x01b4 0x0440 0x0000 2 0 +#define MX6UL_PAD_NAND_CLE__ECSPI3_MISO 0x01b4 0x0440 0x0558 3 1 +#define MX6UL_PAD_NAND_CLE__EIM_ADDR16 0x01b4 0x0440 0x0000 4 0 +#define MX6UL_PAD_NAND_CLE__GPIO4_IO15 0x01b4 0x0440 0x0000 5 0 +#define MX6UL_PAD_NAND_CLE__UART3_DCE_RTS 0x01b4 0x0440 0x0630 8 3 +#define MX6UL_PAD_NAND_CLE__UART3_DTE_CTS 0x01b4 0x0440 0x0000 8 0 +#define MX6UL_PAD_NAND_DQS__RAWNAND_DQS 0x01b8 0x0444 0x0000 0 0 +#define MX6UL_PAD_NAND_DQS__CSI_FIELD 0x01b8 0x0444 0x0530 1 1 +#define MX6UL_PAD_NAND_DQS__QSPI_A_SS0_B 0x01b8 0x0444 0x0000 2 0 +#define MX6UL_PAD_NAND_DQS__PWM5_OUT 0x01b8 0x0444 0x0000 3 0 +#define MX6UL_PAD_NAND_DQS__EIM_WAIT 0x01b8 0x0444 0x0000 4 0 +#define MX6UL_PAD_NAND_DQS__GPIO4_IO16 0x01b8 0x0444 0x0000 5 0 +#define MX6UL_PAD_NAND_DQS__SDMA_EXT_EVENT01 0x01b8 0x0444 0x0000 6 0 +#define MX6UL_PAD_NAND_DQS__SPDIF_EXT_CLK 0x01b8 0x0444 0x061c 8 1 +#define MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x01bc 0x0448 0x0000 0 0 +#define MX6UL_PAD_SD1_CMD__GPT2_COMPARE1 0x01bc 0x0448 0x0000 1 0 +#define MX6UL_PAD_SD1_CMD__SAI2_RX_SYNC 0x01bc 0x0448 0x0000 2 0 +#define MX6UL_PAD_SD1_CMD__SPDIF_OUT 0x01bc 0x0448 0x0000 3 0 +#define MX6UL_PAD_SD1_CMD__EIM_ADDR19 0x01bc 0x0448 0x0000 4 0 +#define MX6UL_PAD_SD1_CMD__GPIO2_IO16 0x01bc 0x0448 0x0000 5 0 +#define MX6UL_PAD_SD1_CMD__SDMA_EXT_EVENT00 0x01bc 0x0448 0x0000 6 0 +#define MX6UL_PAD_SD1_CMD__USB_OTG1_PWR 0x01bc 0x0448 0x0000 8 0 +#define MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x01c0 0x044c 0x0000 0 0 +#define MX6UL_PAD_SD1_CLK__GPT2_COMPARE2 0x01c0 0x044c 0x0000 1 0 +#define MX6UL_PAD_SD1_CLK__SAI2_MCLK 0x01c0 0x044c 0x0000 2 0 +#define MX6UL_PAD_SD1_CLK__SPDIF_IN 0x01c0 0x044c 0x0618 3 3 +#define MX6UL_PAD_SD1_CLK__EIM_ADDR20 0x01c0 0x044c 0x0000 4 0 +#define MX6UL_PAD_SD1_CLK__GPIO2_IO17 0x01c0 0x044c 0x0000 5 0 +#define MX6UL_PAD_SD1_CLK__USB_OTG1_OC 0x01c0 0x044c 0x0664 8 2 +#define MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x01c4 0x0450 0x0000 0 0 +#define MX6UL_PAD_SD1_DATA0__GPT2_COMPARE3 0x01c4 0x0450 0x0000 1 0 +#define MX6UL_PAD_SD1_DATA0__SAI2_TX_SYNC 0x01c4 0x0450 0x05fc 2 1 +#define MX6UL_PAD_SD1_DATA0__FLEXCAN1_TX 0x01c4 0x0450 0x0000 3 0 +#define MX6UL_PAD_SD1_DATA0__EIM_ADDR21 0x01c4 0x0450 0x0000 4 0 +#define MX6UL_PAD_SD1_DATA0__GPIO2_IO18 0x01c4 0x0450 0x0000 5 0 +#define MX6UL_PAD_SD1_DATA0__ANATOP_OTG1_ID 0x01c4 0x0450 0x04b8 8 2 +#define MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x01c8 0x0454 0x0000 0 0 +#define MX6UL_PAD_SD1_DATA1__GPT2_CLK 0x01c8 0x0454 0x05a0 1 1 +#define MX6UL_PAD_SD1_DATA1__SAI2_TX_BCLK 0x01c8 0x0454 0x05f8 2 1 +#define MX6UL_PAD_SD1_DATA1__FLEXCAN1_RX 0x01c8 0x0454 0x0584 3 3 +#define MX6UL_PAD_SD1_DATA1__EIM_ADDR22 0x01c8 0x0454 0x0000 4 0 +#define MX6UL_PAD_SD1_DATA1__GPIO2_IO19 0x01c8 0x0454 0x0000 5 0 +#define MX6UL_PAD_SD1_DATA1__USB_OTG2_PWR 0x01c8 0x0454 0x0000 8 0 +#define MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x01cc 0x0458 0x0000 0 0 +#define MX6UL_PAD_SD1_DATA2__GPT2_CAPTURE1 0x01cc 0x0458 0x0598 1 1 +#define MX6UL_PAD_SD1_DATA2__SAI2_RX_DATA 0x01cc 0x0458 0x05f4 2 1 +#define MX6UL_PAD_SD1_DATA2__FLEXCAN2_TX 0x01cc 0x0458 0x0000 3 0 +#define MX6UL_PAD_SD1_DATA2__EIM_ADDR23 0x01cc 0x0458 0x0000 4 0 +#define MX6UL_PAD_SD1_DATA2__GPIO2_IO20 0x01cc 0x0458 0x0000 5 0 +#define MX6UL_PAD_SD1_DATA2__CCM_CLKO1 0x01cc 0x0458 0x0000 6 0 +#define MX6UL_PAD_SD1_DATA2__USB_OTG2_OC 0x01cc 0x0458 0x0660 8 2 +#define MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x01d0 0x045c 0x0000 0 0 +#define MX6UL_PAD_SD1_DATA3__GPT2_CAPTURE2 0x01d0 0x045c 0x059c 1 1 +#define MX6UL_PAD_SD1_DATA3__SAI2_TX_DATA 0x01d0 0x045c 0x0000 2 0 +#define MX6UL_PAD_SD1_DATA3__FLEXCAN2_RX 0x01d0 0x045c 0x0588 3 3 +#define MX6UL_PAD_SD1_DATA3__EIM_ADDR24 0x01d0 0x045c 0x0000 4 0 +#define MX6UL_PAD_SD1_DATA3__GPIO2_IO21 0x01d0 0x045c 0x0000 5 0 +#define MX6UL_PAD_SD1_DATA3__CCM_CLKO2 0x01d0 0x045c 0x0000 6 0 +#define MX6UL_PAD_SD1_DATA3__ANATOP_OTG2_ID 0x01d0 0x045c 0x04bc 8 2 +#define MX6UL_PAD_CSI_MCLK__CSI_MCLK 0x01d4 0x0460 0x0000 0 0 +#define MX6UL_PAD_CSI_MCLK__USDHC2_CD_B 0x01d4 0x0460 0x0674 1 0 +#define MX6UL_PAD_CSI_MCLK__RAWNAND_CE2_B 0x01d4 0x0460 0x0000 2 0 +#define MX6UL_PAD_CSI_MCLK__I2C1_SDA 0x01d4 0x0460 0x05a8 3 0 +#define MX6UL_PAD_CSI_MCLK__EIM_CS0_B 0x01d4 0x0460 0x0000 4 0 +#define MX6UL_PAD_CSI_MCLK__GPIO4_IO17 0x01d4 0x0460 0x0000 5 0 +#define MX6UL_PAD_CSI_MCLK__SNVS_HP_VIO_5_CTL 0x01d4 0x0460 0x0000 6 0 +#define MX6UL_PAD_CSI_MCLK__UART6_DCE_TX 0x01d4 0x0460 0x0000 8 0 +#define MX6UL_PAD_CSI_MCLK__UART6_DTE_RX 0x01d4 0x0460 0x064c 8 0 +#define MX6UL_PAD_CSI_PIXCLK__CSI_PIXCLK 0x01d8 0x0464 0x0528 0 1 +#define MX6UL_PAD_CSI_PIXCLK__USDHC2_WP 0x01d8 0x0464 0x069c 1 2 +#define MX6UL_PAD_CSI_PIXCLK__RAWNAND_CE3_B 0x01d8 0x0464 0x0000 2 0 +#define MX6UL_PAD_CSI_PIXCLK__I2C1_SCL 0x01d8 0x0464 0x05a4 3 2 +#define MX6UL_PAD_CSI_PIXCLK__EIM_OE 0x01d8 0x0464 0x0000 4 0 +#define MX6UL_PAD_CSI_PIXCLK__GPIO4_IO18 0x01d8 0x0464 0x0000 5 0 +#define MX6UL_PAD_CSI_PIXCLK__SNVS_HP_VIO_5 0x01d8 0x0464 0x0000 6 0 +#define MX6UL_PAD_CSI_PIXCLK__UART6_DCE_RX 0x01d8 0x0464 0x064c 8 3 +#define MX6UL_PAD_CSI_PIXCLK__UART6_DTE_TX 0x01d8 0x0464 0x0000 8 0 +#define MX6UL_PAD_CSI_VSYNC__CSI_VSYNC 0x01dc 0x0468 0x052c 0 0 +#define MX6UL_PAD_CSI_VSYNC__USDHC2_CLK 0x01dc 0x0468 0x0670 1 0 +#define MX6UL_PAD_CSI_VSYNC__SIM1_PORT1_CLK 0x01dc 0x0468 0x0000 2 0 +#define MX6UL_PAD_CSI_VSYNC__I2C2_SDA 0x01dc 0x0468 0x05b0 3 0 +#define MX6UL_PAD_CSI_VSYNC__EIM_RW 0x01dc 0x0468 0x0000 4 0 +#define MX6UL_PAD_CSI_VSYNC__GPIO4_IO19 0x01dc 0x0468 0x0000 5 0 +#define MX6UL_PAD_CSI_VSYNC__PWM7_OUT 0x01dc 0x0468 0x0000 6 0 +#define MX6UL_PAD_CSI_VSYNC__UART6_DCE_RTS 0x01dc 0x0468 0x0648 8 0 +#define MX6UL_PAD_CSI_VSYNC__UART6_DTE_CTS 0x01dc 0x0468 0x0000 8 0 +#define MX6UL_PAD_CSI_HSYNC__CSI_HSYNC 0x01e0 0x046c 0x0524 0 0 +#define MX6UL_PAD_CSI_HSYNC__USDHC2_CMD 0x01e0 0x046c 0x0678 1 0 +#define MX6UL_PAD_CSI_HSYNC__SIM1_PORT1_PD 0x01e0 0x046c 0x0000 2 0 +#define MX6UL_PAD_CSI_HSYNC__I2C2_SCL 0x01e0 0x046c 0x05ac 3 0 +#define MX6UL_PAD_CSI_HSYNC__EIM_LBA_B 0x01e0 0x046c 0x0000 4 0 +#define MX6UL_PAD_CSI_HSYNC__GPIO4_IO20 0x01e0 0x046c 0x0000 5 0 +#define MX6UL_PAD_CSI_HSYNC__PWM8_OUT 0x01e0 0x046c 0x0000 6 0 +#define MX6UL_PAD_CSI_HSYNC__UART6_DCE_CTS 0x01e0 0x046c 0x0000 8 0 +#define MX6UL_PAD_CSI_HSYNC__UART6_DTE_RTS 0x01e0 0x046c 0x0648 8 1 +#define MX6UL_PAD_CSI_DATA00__CSI_DATA02 0x01e4 0x0470 0x04c4 0 0 +#define MX6UL_PAD_CSI_DATA00__USDHC2_DATA0 0x01e4 0x0470 0x067c 1 0 +#define MX6UL_PAD_CSI_DATA00__SIM1_PORT1_RST_B 0x01e4 0x0470 0x0000 2 0 +#define MX6UL_PAD_CSI_DATA00__ECSPI2_SCLK 0x01e4 0x0470 0x0544 3 0 +#define MX6UL_PAD_CSI_DATA00__EIM_AD00 0x01e4 0x0470 0x0000 4 0 +#define MX6UL_PAD_CSI_DATA00__GPIO4_IO21 0x01e4 0x0470 0x0000 5 0 +#define MX6UL_PAD_CSI_DATA00__SRC_INT_BOOT 0x01e4 0x0470 0x0000 6 0 +#define MX6UL_PAD_CSI_DATA00__UART5_DCE_TX 0x01e4 0x0470 0x0000 8 0 +#define MX6UL_PAD_CSI_DATA00__UART5_DTE_RX 0x01e4 0x0470 0x0644 8 0 +#define MX6UL_PAD_CSI_DATA01__CSI_DATA03 0x01e8 0x0474 0x04c8 0 0 +#define MX6UL_PAD_CSI_DATA01__USDHC2_DATA1 0x01e8 0x0474 0x0680 1 0 +#define MX6UL_PAD_CSI_DATA01__SIM1_PORT1_SVEN 0x01e8 0x0474 0x0000 2 0 +#define MX6UL_PAD_CSI_DATA01__ECSPI2_SS0 0x01e8 0x0474 0x0000 3 0 +#define MX6UL_PAD_CSI_DATA01__EIM_AD01 0x01e8 0x0474 0x0000 4 0 +#define MX6UL_PAD_CSI_DATA01__GPIO4_IO22 0x01e8 0x0474 0x0000 5 0 +#define MX6UL_PAD_CSI_DATA01__SAI1_MCLK 0x01e8 0x0474 0x0000 6 0 +#define MX6UL_PAD_CSI_DATA01__UART5_DCE_RX 0x01e8 0x0474 0x0644 8 1 +#define MX6UL_PAD_CSI_DATA01__UART5_DTE_TX 0x01e8 0x0474 0x0000 8 0 +#define MX6UL_PAD_CSI_DATA02__CSI_DATA04 0x01ec 0x0478 0x04d8 0 1 +#define MX6UL_PAD_CSI_DATA02__USDHC2_DATA2 0x01ec 0x0478 0x0684 1 2 +#define MX6UL_PAD_CSI_DATA02__SIM1_PORT1_TRXD 0x01ec 0x0478 0x0000 2 0 +#define MX6UL_PAD_CSI_DATA02__ECSPI2_MOSI 0x01ec 0x0478 0x054c 3 1 +#define MX6UL_PAD_CSI_DATA02__EIM_AD02 0x01ec 0x0478 0x0000 4 0 +#define MX6UL_PAD_CSI_DATA02__GPIO4_IO23 0x01ec 0x0478 0x0000 5 0 +#define MX6UL_PAD_CSI_DATA02__SAI1_RX_SYNC 0x01ec 0x0478 0x0000 6 0 +#define MX6UL_PAD_CSI_DATA02__UART5_DCE_RTS 0x01ec 0x0478 0x0640 8 5 +#define MX6UL_PAD_CSI_DATA02__UART5_DTE_CTS 0x01ec 0x0478 0x0000 8 0 +#define MX6UL_PAD_CSI_DATA03__CSI_DATA05 0x01f0 0x047c 0x04cc 0 0 +#define MX6UL_PAD_CSI_DATA03__USDHC2_DATA3 0x01f0 0x047c 0x0688 1 0 +#define MX6UL_PAD_CSI_DATA03__SIM2_PORT1_PD 0x01f0 0x047c 0x0000 2 0 +#define MX6UL_PAD_CSI_DATA03__ECSPI2_MISO 0x01f0 0x047c 0x0548 3 0 +#define MX6UL_PAD_CSI_DATA03__EIM_AD03 0x01f0 0x047c 0x0000 4 0 +#define MX6UL_PAD_CSI_DATA03__GPIO4_IO24 0x01f0 0x047c 0x0000 5 0 +#define MX6UL_PAD_CSI_DATA03__SAI1_RX_BCLK 0x01f0 0x047c 0x0000 6 0 +#define MX6UL_PAD_CSI_DATA03__UART5_DCE_CTS 0x01f0 0x047c 0x0000 8 0 +#define MX6UL_PAD_CSI_DATA03__UART5_DTE_RTS 0x01f0 0x047c 0x0640 8 0 +#define MX6UL_PAD_CSI_DATA04__CSI_DATA06 0x01f4 0x0480 0x04dc 0 1 +#define MX6UL_PAD_CSI_DATA04__USDHC2_DATA4 0x01f4 0x0480 0x068c 1 2 +#define MX6UL_PAD_CSI_DATA04__SIM2_PORT1_CLK 0x01f4 0x0480 0x0000 2 0 +#define MX6UL_PAD_CSI_DATA04__ECSPI1_SCLK 0x01f4 0x0480 0x0534 3 1 +#define MX6UL_PAD_CSI_DATA04__EIM_AD04 0x01f4 0x0480 0x0000 4 0 +#define MX6UL_PAD_CSI_DATA04__GPIO4_IO25 0x01f4 0x0480 0x0000 5 0 +#define MX6UL_PAD_CSI_DATA04__SAI1_TX_SYNC 0x01f4 0x0480 0x05ec 6 1 +#define MX6UL_PAD_CSI_DATA04__USDHC1_WP 0x01f4 0x0480 0x066c 8 2 +#define MX6UL_PAD_CSI_DATA05__CSI_DATA07 0x01f8 0x0484 0x04e0 0 1 +#define MX6UL_PAD_CSI_DATA05__USDHC2_DATA5 0x01f8 0x0484 0x0690 1 2 +#define MX6UL_PAD_CSI_DATA05__SIM2_PORT1_RST_B 0x01f8 0x0484 0x0000 2 0 +#define MX6UL_PAD_CSI_DATA05__ECSPI1_SS0 0x01f8 0x0484 0x0000 3 0 +#define MX6UL_PAD_CSI_DATA05__EIM_AD05 0x01f8 0x0484 0x0000 4 0 +#define MX6UL_PAD_CSI_DATA05__GPIO4_IO26 0x01f8 0x0484 0x0000 5 0 +#define MX6UL_PAD_CSI_DATA05__SAI1_TX_BCLK 0x01f8 0x0484 0x05e8 6 1 +#define MX6UL_PAD_CSI_DATA05__USDHC1_CD_B 0x01f8 0x0484 0x0668 8 2 +#define MX6UL_PAD_CSI_DATA06__CSI_DATA08 0x01fc 0x0488 0x04e4 0 1 +#define MX6UL_PAD_CSI_DATA06__USDHC2_DATA6 0x01fc 0x0488 0x0694 1 2 +#define MX6UL_PAD_CSI_DATA06__SIM2_PORT1_SVEN 0x01fc 0x0488 0x0000 2 0 +#define MX6UL_PAD_CSI_DATA06__ECSPI1_MOSI 0x01fc 0x0488 0x053c 3 1 +#define MX6UL_PAD_CSI_DATA06__EIM_AD06 0x01fc 0x0488 0x0000 4 0 +#define MX6UL_PAD_CSI_DATA06__GPIO4_IO27 0x01fc 0x0488 0x0000 5 0 +#define MX6UL_PAD_CSI_DATA06__SAI1_RX_DATA 0x01fc 0x0488 0x0000 6 0 +#define MX6UL_PAD_CSI_DATA06__USDHC1_RESET_B 0x01fc 0x0488 0x0000 8 0 +#define MX6UL_PAD_CSI_DATA07__CSI_DATA09 0x0200 0x048c 0x04e8 0 1 +#define MX6UL_PAD_CSI_DATA07__USDHC2_DATA7 0x0200 0x048c 0x0698 1 2 +#define MX6UL_PAD_CSI_DATA07__SIM2_PORT1_TRXD 0x0200 0x048c 0x0000 2 0 +#define MX6UL_PAD_CSI_DATA07__ECSPI1_MISO 0x0200 0x048c 0x0538 3 1 +#define MX6UL_PAD_CSI_DATA07__EIM_AD07 0x0200 0x048c 0x0000 4 0 +#define MX6UL_PAD_CSI_DATA07__GPIO4_IO28 0x0200 0x048c 0x0000 5 0 +#define MX6UL_PAD_CSI_DATA07__SAI1_TX_DATA 0x0200 0x048c 0x0000 6 0 +#define MX6UL_PAD_CSI_DATA07__USDHC1_VSELECT 0x0200 0x048c 0x0000 8 0 #endif /* __DTS_IMX6UL_PINFUNC_H */ diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi index 99b646506fc91d83f4648406f668ccb4294a540a..71778992f03d907b75c7936115df07ef82ee06c8 100644 --- a/arch/arm/boot/dts/imx6ul.dtsi +++ b/arch/arm/boot/dts/imx6ul.dtsi @@ -8,6 +8,7 @@ #include #include +#include #include #include "imx6ul-pinfunc.h" #include "skeleton.dtsi" @@ -140,6 +141,39 @@ reg = <0x00900000 0x20000>; }; + dma_apbh: dma-apbh@01804000 { + compatible = "fsl,imx6q-dma-apbh", "fsl,imx28-dma-apbh"; + reg = <0x01804000 0x2000>; + interrupts = <0 13 IRQ_TYPE_LEVEL_HIGH>, + <0 13 IRQ_TYPE_LEVEL_HIGH>, + <0 13 IRQ_TYPE_LEVEL_HIGH>, + <0 13 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "gpmi0", "gpmi1", "gpmi2", "gpmi3"; + #dma-cells = <1>; + dma-channels = <4>; + clocks = <&clks IMX6UL_CLK_APBHDMA>; + }; + + gpmi: gpmi-nand@01806000 { + compatible = "fsl,imx6q-gpmi-nand"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x01806000 0x2000>, <0x01808000 0x2000>; + reg-names = "gpmi-nand", "bch"; + interrupts = <0 15 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "bch"; + clocks = <&clks IMX6UL_CLK_GPMI_IO>, + <&clks IMX6UL_CLK_GPMI_APB>, + <&clks IMX6UL_CLK_GPMI_BCH>, + <&clks IMX6UL_CLK_GPMI_BCH_APB>, + <&clks IMX6UL_CLK_PER_BCH>; + clock-names = "gpmi_io", "gpmi_apb", "gpmi_bch", + "gpmi_bch_apb", "per1_bch"; + dmas = <&dma_apbh 0>; + dma-names = "rx-tx"; + status = "disabled"; + }; + aips1: aips-bus@02000000 { compatible = "fsl,aips-bus", "simple-bus"; #address-cells = <1>; @@ -234,6 +268,126 @@ clock-names = "ipg", "per"; status = "disabled"; }; + + sai1: sai@02028000 { + #sound-dai-cells = <0>; + compatible = "fsl,imx6ul-sai", "fsl,imx6sx-sai"; + reg = <0x02028000 0x4000>; + interrupts = ; + clocks = <&clks IMX6UL_CLK_SAI1_IPG>, + <&clks IMX6UL_CLK_SAI1>, + <&clks IMX6UL_CLK_DUMMY>, <&clks IMX6UL_CLK_DUMMY>; + clock-names = "bus", "mclk1", "mclk2", "mclk3"; + dmas = <&sdma 35 24 0>, + <&sdma 36 24 0>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + sai2: sai@0202c000 { + #sound-dai-cells = <0>; + compatible = "fsl,imx6ul-sai", "fsl,imx6sx-sai"; + reg = <0x0202c000 0x4000>; + interrupts = ; + clocks = <&clks IMX6UL_CLK_SAI2_IPG>, + <&clks IMX6UL_CLK_SAI2>, + <&clks IMX6UL_CLK_DUMMY>, <&clks IMX6UL_CLK_DUMMY>; + clock-names = "bus", "mclk1", "mclk2", "mclk3"; + dmas = <&sdma 37 24 0>, + <&sdma 38 24 0>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + sai3: sai@02030000 { + #sound-dai-cells = <0>; + compatible = "fsl,imx6ul-sai", "fsl,imx6sx-sai"; + reg = <0x02030000 0x4000>; + interrupts = ; + clocks = <&clks IMX6UL_CLK_SAI3_IPG>, + <&clks IMX6UL_CLK_SAI3>, + <&clks IMX6UL_CLK_DUMMY>, <&clks IMX6UL_CLK_DUMMY>; + clock-names = "bus", "mclk1", "mclk2", "mclk3"; + dmas = <&sdma 39 24 0>, + <&sdma 40 24 0>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + }; + + tsc: tsc@02040000 { + compatible = "fsl,imx6ul-tsc"; + reg = <0x02040000 0x4000>, <0x0219c000 0x4000>; + interrupts = , + ; + clocks = <&clks IMX6UL_CLK_IPG>, + <&clks IMX6UL_CLK_ADC2>; + clock-names = "tsc", "adc"; + status = "disabled"; + }; + + pwm1: pwm@02080000 { + compatible = "fsl,imx6ul-pwm", "fsl,imx27-pwm"; + reg = <0x02080000 0x4000>; + interrupts = ; + clocks = <&clks IMX6UL_CLK_PWM1>, + <&clks IMX6UL_CLK_PWM1>; + clock-names = "ipg", "per"; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm2: pwm@02084000 { + compatible = "fsl,imx6ul-pwm", "fsl,imx27-pwm"; + reg = <0x02084000 0x4000>; + interrupts = ; + clocks = <&clks IMX6UL_CLK_PWM2>, + <&clks IMX6UL_CLK_PWM2>; + clock-names = "ipg", "per"; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm3: pwm@02088000 { + compatible = "fsl,imx6ul-pwm", "fsl,imx27-pwm"; + reg = <0x02088000 0x4000>; + interrupts = ; + clocks = <&clks IMX6UL_CLK_PWM3>, + <&clks IMX6UL_CLK_PWM3>; + clock-names = "ipg", "per"; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm4: pwm@0208c000 { + compatible = "fsl,imx6ul-pwm", "fsl,imx27-pwm"; + reg = <0x0208c000 0x4000>; + interrupts = ; + clocks = <&clks IMX6UL_CLK_PWM4>, + <&clks IMX6UL_CLK_PWM4>; + clock-names = "ipg", "per"; + #pwm-cells = <2>; + status = "disabled"; + }; + + can1: flexcan@02090000 { + compatible = "fsl,imx6ul-flexcan", "fsl,imx6q-flexcan"; + reg = <0x02090000 0x4000>; + interrupts = ; + clocks = <&clks IMX6UL_CLK_CAN1_IPG>, + <&clks IMX6UL_CLK_CAN1_SERIAL>; + clock-names = "ipg", "per"; + status = "disabled"; + }; + + can2: flexcan@02094000 { + compatible = "fsl,imx6ul-flexcan", "fsl,imx6q-flexcan"; + reg = <0x02094000 0x4000>; + interrupts = ; + clocks = <&clks IMX6UL_CLK_CAN2_IPG>, + <&clks IMX6UL_CLK_CAN2_SERIAL>; + clock-names = "ipg", "per"; + status = "disabled"; }; gpt1: gpt@02098000 { @@ -317,6 +471,14 @@ status = "disabled"; }; + kpp: kpp@020b8000 { + compatible = "fsl,imx6ul-kpp", "fsl,imx6q-kpp", "fsl,imx21-kpp"; + reg = <0x020b8000 0x4000>; + interrupts = ; + clocks = <&clks IMX6UL_CLK_KPP>; + status = "disabled"; + }; + wdog1: wdog@020bc000 { compatible = "fsl,imx6ul-wdt", "fsl,imx21-wdt"; reg = <0x020bc000 0x4000>; @@ -487,49 +649,65 @@ compatible = "fsl,imx6ul-gpt", "fsl,imx6sx-gpt"; reg = <0x020e8000 0x4000>; interrupts = ; - clocks = <&clks IMX6UL_CLK_DUMMY>, - <&clks IMX6UL_CLK_DUMMY>; + clocks = <&clks IMX6UL_CLK_GPT2_BUS>, + <&clks IMX6UL_CLK_GPT2_SERIAL>; clock-names = "ipg", "per"; }; + sdma: sdma@020ec000 { + compatible = "fsl,imx6ul-sdma", "fsl,imx6q-sdma", + "fsl,imx35-sdma"; + reg = <0x020ec000 0x4000>; + interrupts = ; + clocks = <&clks IMX6UL_CLK_SDMA>, + <&clks IMX6UL_CLK_SDMA>; + clock-names = "ipg", "ahb"; + #dma-cells = <3>; + fsl,sdma-ram-script-name = "imx/sdma/sdma-imx6q.bin"; + }; + pwm5: pwm@020f0000 { compatible = "fsl,imx6ul-pwm", "fsl,imx27-pwm"; reg = <0x020f0000 0x4000>; interrupts = ; - clocks = <&clks IMX6UL_CLK_DUMMY>, - <&clks IMX6UL_CLK_DUMMY>; + clocks = <&clks IMX6UL_CLK_PWM5>, + <&clks IMX6UL_CLK_PWM5>; clock-names = "ipg", "per"; #pwm-cells = <2>; + status = "disabled"; }; pwm6: pwm@020f4000 { compatible = "fsl,imx6ul-pwm", "fsl,imx27-pwm"; reg = <0x020f4000 0x4000>; interrupts = ; - clocks = <&clks IMX6UL_CLK_DUMMY>, - <&clks IMX6UL_CLK_DUMMY>; + clocks = <&clks IMX6UL_CLK_PWM6>, + <&clks IMX6UL_CLK_PWM6>; clock-names = "ipg", "per"; #pwm-cells = <2>; + status = "disabled"; }; pwm7: pwm@020f8000 { compatible = "fsl,imx6ul-pwm", "fsl,imx27-pwm"; reg = <0x020f8000 0x4000>; interrupts = ; - clocks = <&clks IMX6UL_CLK_DUMMY>, - <&clks IMX6UL_CLK_DUMMY>; + clocks = <&clks IMX6UL_CLK_PWM7>, + <&clks IMX6UL_CLK_PWM7>; clock-names = "ipg", "per"; #pwm-cells = <2>; + status = "disabled"; }; pwm8: pwm@020fc000 { compatible = "fsl,imx6ul-pwm", "fsl,imx27-pwm"; reg = <0x020fc000 0x4000>; interrupts = ; - clocks = <&clks IMX6UL_CLK_DUMMY>, - <&clks IMX6UL_CLK_DUMMY>; + clocks = <&clks IMX6UL_CLK_PWM8>, + <&clks IMX6UL_CLK_PWM8>; clock-names = "ipg", "per"; #pwm-cells = <2>; + status = "disabled"; }; }; @@ -590,17 +768,6 @@ status = "disabled"; }; - tsc: tsc@02040000 { - compatible = "fsl,imx6ul-tsc"; - reg = <0x02040000 0x4000>, <0x0219c000 0x4000>; - interrupts = , - ; - clocks = <&clks IMX6UL_CLK_IPG>, - <&clks IMX6UL_CLK_ADC2>; - clock-names = "tsc", "adc"; - status = "disabled"; - }; - usdhc1: usdhc@02190000 { compatible = "fsl,imx6ul-usdhc", "fsl,imx6sx-usdhc"; reg = <0x02190000 0x4000>; @@ -672,6 +839,17 @@ reg = <0x021b0000 0x4000>; }; + lcdif: lcdif@021c8000 { + compatible = "fsl,imx6ul-lcdif", "fsl,imx28-lcdif"; + reg = <0x021c8000 0x4000>; + interrupts = ; + clocks = <&clks IMX6UL_CLK_LCDIF_PIX>, + <&clks IMX6UL_CLK_LCDIF_APB>, + <&clks IMX6UL_CLK_DUMMY>; + clock-names = "pix", "axi", "disp_axi"; + status = "disabled"; + }; + qspi: qspi@021e0000 { #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/imx7d-sbc-imx7.dts b/arch/arm/boot/dts/imx7d-sbc-imx7.dts index d63c597c07835595521ae00862343134f71967cf..f8a868552707124b3e1a86d074c62718927c3805 100644 --- a/arch/arm/boot/dts/imx7d-sbc-imx7.dts +++ b/arch/arm/boot/dts/imx7d-sbc-imx7.dts @@ -22,7 +22,7 @@ pinctrl-0 = <&pinctrl_usdhc1>; cd-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>; wp-gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>; - enable-sdio-wakeup; + wakeup-source; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx7d-sdb.dts b/arch/arm/boot/dts/imx7d-sdb.dts index b2c453662905e313626a79a93c1543d1bfb301ef..b267f79e30590bba28c50ab9daaaf887d4bb1d76 100644 --- a/arch/arm/boot/dts/imx7d-sdb.dts +++ b/arch/arm/boot/dts/imx7d-sdb.dts @@ -296,7 +296,7 @@ pinctrl-0 = <&pinctrl_usdhc1>; cd-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>; wp-gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>; - enable-sdio-wakeup; + wakeup-source; keep-power-in-suspend; status = "okay"; }; diff --git a/arch/arm/boot/dts/imx7d.dtsi b/arch/arm/boot/dts/imx7d.dtsi index 25ad3097874016ab3f1281e6a46d7824c7a91fc8..b5a50e0e7ff1980523e6567934135b7aad7a73d9 100644 --- a/arch/arm/boot/dts/imx7d.dtsi +++ b/arch/arm/boot/dts/imx7d.dtsi @@ -119,6 +119,15 @@ clock-output-names = "osc"; }; + timer { + compatible = "arm,armv7-timer"; + interrupts = , + , + , + ; + interrupt-parent = <&intc>; + }; + etr@30086000 { compatible = "arm,coresight-tmc", "arm,primecell"; reg = <0x30086000 0x1000>; diff --git a/arch/arm/boot/dts/integrator.dtsi b/arch/arm/boot/dts/integrator.dtsi index 3807d4f46ef7c610e102e113615dee8db1508fbc..b82f0e6d9a637936f1d6ff150a770687cfca0efb 100644 --- a/arch/arm/boot/dts/integrator.dtsi +++ b/arch/arm/boot/dts/integrator.dtsi @@ -57,7 +57,7 @@ }; fpga { - compatible = "arm,amba-bus", "simple-bus"; + compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges; diff --git a/arch/arm/boot/dts/keystone-k2g-evm.dts b/arch/arm/boot/dts/keystone-k2g-evm.dts new file mode 100644 index 0000000000000000000000000000000000000000..5bfd9e7845f2b080c1af9c08f8d8a1388d9713b7 --- /dev/null +++ b/arch/arm/boot/dts/keystone-k2g-evm.dts @@ -0,0 +1,32 @@ +/* + * Device Tree Source for K2G EVM + * + * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +/dts-v1/; + +#include "keystone-k2g.dtsi" + +/ { + compatible = "ti,k2g-evm", "ti,k2g", "ti,keystone"; + model = "Texas Instruments K2G General Purpose EVM"; + + memory { + device_type = "memory"; + reg = <0x00000008 0x00000000 0x00000000 0x80000000>; + }; + +}; + +&uart0 { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/keystone-k2g.dtsi b/arch/arm/boot/dts/keystone-k2g.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..7ff2796ae925a2cce849d080706e035c983658c0 --- /dev/null +++ b/arch/arm/boot/dts/keystone-k2g.dtsi @@ -0,0 +1,89 @@ +/* + * Device Tree Source for K2G SOC + * + * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include "skeleton.dtsi" + +/ { + compatible = "ti,k2g","ti,keystone"; + model = "Texas Instruments K2G SoC"; + #address-cells = <2>; + #size-cells = <2>; + interrupt-parent = <&gic>; + + aliases { + serial0 = &uart0; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + compatible = "arm,cortex-a15"; + device_type = "cpu"; + reg = <0>; + }; + }; + + gic: interrupt-controller@02561000 { + compatible = "arm,cortex-a15-gic"; + #interrupt-cells = <3>; + interrupt-controller; + reg = <0x0 0x02561000 0x0 0x1000>, + <0x0 0x02562000 0x0 0x2000>, + <0x0 0x02564000 0x0 0x1000>, + <0x0 0x02566000 0x0 0x2000>; + interrupts = ; + }; + + timer { + compatible = "arm,armv7-timer"; + interrupts = + , + , + , + ; + }; + + pmu { + compatible = "arm,cortex-a15-pmu"; + interrupts = ; + }; + + soc { + #address-cells = <1>; + #size-cells = <1>; + compatible = "ti,keystone","simple-bus"; + ranges = <0x0 0x0 0x0 0xc0000000>; + dma-ranges = <0x80000000 0x8 0x00000000 0x80000000>; + + uart0: serial@02530c00 { + compatible = "ns16550a"; + current-speed = <115200>; + reg-shift = <2>; + reg-io-width = <4>; + reg = <0x02530c00 0x100>; + interrupts = ; + clock-frequency = <200000000>; + status = "disabled"; + }; + }; +}; diff --git a/arch/arm/boot/dts/kirkwood-linkstation-6282.dtsi b/arch/arm/boot/dts/kirkwood-linkstation-6282.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..6548e68a20d000d75bd9f506907499066136103f --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-linkstation-6282.dtsi @@ -0,0 +1,192 @@ +/* + * Device Tree common file for kirkwood-6282 based Buffalo Linkstation + * + * Copyright (C) 2015, 2016 + * Roger Shimizu + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "kirkwood.dtsi" +#include "kirkwood-6282.dtsi" +#include "kirkwood-linkstation.dtsi" + +/ { + ocp@f1000000 { + pinctrl: pin-controller@10000 { + pmx_power_hdd0: pmx-power-hdd0 { + marvell,pins = "mpp8"; + marvell,function = "gpio"; + }; + pmx_usb_vbus: pmx-usb-vbus { + marvell,pins = "mpp12"; + marvell,function = "gpio"; + }; + pmx_fan_high: pmx-fan-high { + marvell,pins = "mpp16"; + marvell,function = "gpio"; + }; + pmx_fan_low: pmx-fan-low { + marvell,pins = "mpp17"; + marvell,function = "gpio"; + }; + pmx_led_alarm: pmx-led-alarm { + marvell,pins = "mpp36"; + marvell,function = "gpio"; + }; + pmx_led_function_red: pmx-led-function-red { + marvell,pins = "mpp37"; + marvell,function = "gpio"; + }; + pmx_led_info: pmx-led-info { + marvell,pins = "mpp38"; + marvell,function = "gpio"; + }; + pmx_led_function_blue: pmx-led-function-blue { + marvell,pins = "mpp39"; + marvell,function = "gpio"; + }; + pmx_led_power: pmx-led-power { + marvell,pins = "mpp40"; + marvell,function = "gpio"; + }; + pmx_fan_lock: pmx-fan-lock { + marvell,pins = "mpp43"; + marvell,function = "gpio"; + }; + pmx_button_function: pmx-button-function { + marvell,pins = "mpp45"; + marvell,function = "gpio"; + }; + pmx_power_switch: pmx-power-switch { + marvell,pins = "mpp46"; + marvell,function = "gpio"; + }; + pmx_power_auto_switch: pmx-power-auto-switch { + marvell,pins = "mpp47"; + marvell,function = "gpio"; + }; + }; + }; + + gpio_keys { + function-button { + gpios = <&gpio1 13 GPIO_ACTIVE_LOW>; + }; + + power-on-switch { + gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; + }; + + power-auto-switch { + gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; + }; + }; + + gpio_leds { + red-alarm-led { + label = "linkstation:red:alarm"; + gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>; + }; + + red-function-led { + label = "linkstation:red:function"; + gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>; + }; + + amber-info-led { + label = "linkstation:amber:info"; + gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>; + }; + + blue-function-led { + label = "linkstation:blue:function"; + gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; + }; + + blue-power-led { + label = "linkstation:blue:power"; + gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; + default-state = "keep"; + }; + }; + + gpio_fan { + compatible = "gpio-fan"; + pinctrl-0 = <&pmx_fan_low &pmx_fan_high &pmx_fan_lock>; + pinctrl-names = "default"; + + gpios = <&gpio0 17 GPIO_ACTIVE_LOW + &gpio0 16 GPIO_ACTIVE_LOW>; + + gpio-fan,speed-map = <0 3 + 1500 2 + 3250 1 + 5000 0>; + + alarm-gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>; + }; + + regulators { + usb_power: regulator@1 { + gpio = <&gpio0 12 GPIO_ACTIVE_HIGH>; + }; + + hdd_power0: regulator@2 { + gpio = <&gpio0 8 GPIO_ACTIVE_HIGH>; + }; + }; +}; + +&mdio { + status = "okay"; + + ethphy0: ethernet-phy@0 { + device_type = "ethernet-phy"; + reg = <0>; + }; +}; + +ð0 { + status = "okay"; + + ethernet0-port@0 { + phy-handle = <ðphy0>; + }; +}; diff --git a/arch/arm/boot/dts/kirkwood-linkstation-duo-6281.dtsi b/arch/arm/boot/dts/kirkwood-linkstation-duo-6281.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..cf2e69f0d54fffcf3deebda51a68b2b798d07687 --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-linkstation-duo-6281.dtsi @@ -0,0 +1,186 @@ +/* + * Device Tree common file for kirkwood-6281 based 2-Bay Buffalo Linkstation + * + * Copyright (C) 2015, 2016 + * Roger Shimizu + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "kirkwood.dtsi" +#include "kirkwood-6281.dtsi" +#include "kirkwood-linkstation.dtsi" + +/ { + ocp@f1000000 { + pinctrl: pin-controller@10000 { + pmx_power_hdd0: pmx-power-hdd0 { + marvell,pins = "mpp28"; + marvell,function = "gpio"; + }; + pmx_power_hdd1: pmx-power-hdd1 { + marvell,pins = "mpp29"; + marvell,function = "gpio"; + }; + pmx_usb_vbus: pmx-usb-vbus { + marvell,pins = "mpp37"; + marvell,function = "gpio"; + }; + pmx_led_alarm: pmx-led-alarm { + marvell,pins = "mpp49"; + marvell,function = "gpio"; + }; + pmx_led_function_red: pmx-led-function-red { + marvell,pins = "mpp34"; + marvell,function = "gpio"; + }; + pmx_led_function_blue: pmx-led-function-blue { + marvell,pins = "mpp36"; + marvell,function = "gpio"; + }; + pmx_led_info: pmx-led-info { + marvell,pins = "mpp38"; + marvell,function = "gpio"; + }; + pmx_led_power: pmx-led-power { + marvell,pins = "mpp39"; + marvell,function = "gpio"; + }; + pmx_button_function: pmx-button-function { + marvell,pins = "mpp41"; + marvell,function = "gpio"; + }; + pmx_power_switch: pmx-power-switch { + marvell,pins = "mpp42"; + marvell,function = "gpio"; + }; + pmx_power_auto_switch: pmx-power-auto-switch { + marvell,pins = "mpp43"; + marvell,function = "gpio"; + }; + }; + + sata@80000 { + nr-ports = <2>; + }; + }; + + gpio_keys { + function-button { + gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; + }; + + power-on-switch { + gpios = <&gpio1 10 GPIO_ACTIVE_LOW>; + }; + + power-auto-switch { + gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; + }; + }; + + gpio_leds { + red-alarm-led { + label = "linkstation:red:alarm"; + gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; + }; + + red-function-led { + label = "linkstation:red:function"; + gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>; + }; + + amber-info-led { + label = "linkstation:amber:info"; + gpios = <&gpio1 6 GPIO_ACTIVE_LOW>; + }; + + blue-function-led { + label = "linkstation:blue:function"; + gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; + }; + + blue-power-led { + label = "linkstation:blue:power"; + gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; + default-state = "keep"; + }; + }; + + regulators { + pinctrl-0 = <&pmx_power_hdd0 &pmx_power_hdd1 &pmx_usb_vbus>; + + usb_power: regulator@1 { + gpio = <&gpio1 5 GPIO_ACTIVE_HIGH>; + }; + + hdd_power0: regulator@2 { + gpio = <&gpio0 28 GPIO_ACTIVE_HIGH>; + }; + + hdd_power1: regulator@3 { + compatible = "regulator-fixed"; + reg = <3>; + regulator-name = "HDD1 Power"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + gpio = <&gpio0 29 GPIO_ACTIVE_HIGH>; + }; + }; +}; + +&mdio { + status = "okay"; + + ethphy1: ethernet-phy@8 { + device_type = "ethernet-phy"; + reg = <8>; + }; +}; + +ð1 { + status = "okay"; + + ethernet1-port@0 { + phy-handle = <ðphy1>; + }; +}; diff --git a/arch/arm/boot/dts/kirkwood-linkstation-lsqvl.dts b/arch/arm/boot/dts/kirkwood-linkstation-lsqvl.dts new file mode 100644 index 0000000000000000000000000000000000000000..6dc0df2969f04318850c9914f182d09c3e974380 --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-linkstation-lsqvl.dts @@ -0,0 +1,135 @@ +/* + * Device Tree file for Buffalo Linkstation LS-QVL + * + * Copyright (C) 2016, Mario Lange + * + * Based on kirkwood-linkstation-lswvl.dts, + * Copyright (C) 2015, 2016 + * Roger Shimizu + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "kirkwood-linkstation-6282.dtsi" + +/ { + model = "Buffalo Linkstation LS-QVL"; + compatible = "buffalo,lsqvl", "marvell,kirkwood-88f6282", "marvell,kirkwood"; + + memory { /* 256 MB */ + device_type = "memory"; + reg = <0x00000000 0x10000000>; + }; + + ocp@f1000000 { + pinctrl: pin-controller@10000 { + pmx_power_hdd1: pmx-power-hdd1 { + marvell,pins = "mpp9"; + marvell,function = "gpio"; + }; + pmx_led_hdderr0: pmx-led-hdderr0 { + marvell,pins = "mpp34"; + marvell,function = "gpio"; + }; + pmx_led_hdderr1: pmx-led-hdderr1 { + marvell,pins = "mpp35"; + marvell,function = "gpio"; + }; + pmx_led_hdderr2: pmx-led-hdderr2 { + marvell,pins = "mpp24"; + marvell,function = "gpio"; + }; + pmx_led_hdderr3: pmx-led-hdderr3 { + marvell,pins = "mpp25"; + marvell,function = "gpio"; + }; + }; + + sata@80000 { + nr-ports = <2>; + }; + }; + + gpio_leds { + pinctrl-0 = <&pmx_led_function_red &pmx_led_alarm + &pmx_led_info &pmx_led_power + &pmx_led_function_blue + &pmx_led_hdderr0 + &pmx_led_hdderr1 + &pmx_led_hdderr2 + &pmx_led_hdderr3>; + + red-hdderr0-led { + label = "linkstation:red:hdderr0"; + gpios = <&gpio1 2 GPIO_ACTIVE_LOW>; + }; + + red-hdderr1-led { + label = "linkstation:red:hdderr1"; + gpios = <&gpio1 3 GPIO_ACTIVE_LOW>; + }; + + red-hdderr2-led { + label = "linkstation:red:hdderr2"; + gpios = <&gpio0 24 GPIO_ACTIVE_LOW>; + }; + + red-hdderr3-led { + label = "linkstation:red:hdderr3"; + gpios = <&gpio0 25 GPIO_ACTIVE_LOW>; + }; + }; + + regulators { + pinctrl-0 = <&pmx_power_hdd0 &pmx_power_hdd1 &pmx_usb_vbus>; + + hdd_power1: regulator@3 { + compatible = "regulator-fixed"; + reg = <3>; + regulator-name = "HDD1 Power"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + gpio = <&gpio0 9 GPIO_ACTIVE_HIGH>; + }; + }; +}; diff --git a/arch/arm/boot/dts/kirkwood-linkstation-lsvl.dts b/arch/arm/boot/dts/kirkwood-linkstation-lsvl.dts new file mode 100644 index 0000000000000000000000000000000000000000..edcba5c44b05fe9b17c5c0b31ae4acf5633e17b6 --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-linkstation-lsvl.dts @@ -0,0 +1,57 @@ +/* + * Device Tree file for Buffalo Linkstation LS-VL + * + * Copyright (C) 2015, 2016 + * Roger Shimizu + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "kirkwood-linkstation-6282.dtsi" + +/ { + model = "Buffalo Linkstation LS-VL"; + compatible = "buffalo,lsvl", "marvell,kirkwood-88f6282", "marvell,kirkwood"; + + memory { /* 256 MB */ + device_type = "memory"; + reg = <0x00000000 0x10000000>; + }; +}; diff --git a/arch/arm/boot/dts/kirkwood-linkstation-lswsxl.dts b/arch/arm/boot/dts/kirkwood-linkstation-lswsxl.dts new file mode 100644 index 0000000000000000000000000000000000000000..4b6450186af59e0550e59f44925b86bbe4a6962a --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-linkstation-lswsxl.dts @@ -0,0 +1,57 @@ +/* + * Device Tree file for Buffalo Linkstation LS-WSXL + * + * Copyright (C) 2015, 2016 + * Roger Shimizu + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "kirkwood-linkstation-duo-6281.dtsi" + +/ { + model = "Buffalo Linkstation LS-WSXL"; + compatible = "buffalo,lswsxl", "marvell,kirkwood-88f6281", "marvell,kirkwood"; + + memory { /* 128 MB */ + device_type = "memory"; + reg = <0x00000000 0x8000000>; + }; +}; diff --git a/arch/arm/boot/dts/kirkwood-linkstation-lswvl.dts b/arch/arm/boot/dts/kirkwood-linkstation-lswvl.dts new file mode 100644 index 0000000000000000000000000000000000000000..954ec1d5b6dc24c3567df4001ae655c2026d6a88 --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-linkstation-lswvl.dts @@ -0,0 +1,112 @@ +/* + * Device Tree file for Buffalo Linkstation LS-WVL + * + * Copyright (C) 2015, 2016 + * Roger Shimizu + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "kirkwood-linkstation-6282.dtsi" + +/ { + model = "Buffalo Linkstation LS-WVL"; + compatible = "buffalo,lswvl","marvell,kirkwood-88f6282", "marvell,kirkwood"; + + memory { /* 256 MB */ + device_type = "memory"; + reg = <0x00000000 0x10000000>; + }; + + ocp@f1000000 { + pinctrl: pin-controller@10000 { + pmx_power_hdd1: pmx-power-hdd1 { + marvell,pins = "mpp9"; + marvell,function = "gpio"; + }; + pmx_led_hdderr0: pmx-led-hdderr0 { + marvell,pins = "mpp34"; + marvell,function = "gpio"; + }; + pmx_led_hdderr1: pmx-led-hdderr1 { + marvell,pins = "mpp35"; + marvell,function = "gpio"; + }; + }; + + sata@80000 { + nr-ports = <2>; + }; + }; + + gpio_leds { + pinctrl-0 = <&pmx_led_function_red &pmx_led_alarm + &pmx_led_info &pmx_led_power + &pmx_led_function_blue + &pmx_led_hdderr0 + &pmx_led_hdderr1>; + + red-hdderr0-led { + label = "linkstation:red:hdderr0"; + gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>; + }; + + red-hdderr1-led { + label = "linkstation:red:hdderr1"; + gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>; + }; + }; + + regulators { + pinctrl-0 = <&pmx_power_hdd0 &pmx_power_hdd1 &pmx_usb_vbus>; + + hdd_power1: regulator@3 { + compatible = "regulator-fixed"; + reg = <3>; + regulator-name = "HDD1 Power"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + gpio = <&gpio0 9 GPIO_ACTIVE_HIGH>; + }; + }; +}; diff --git a/arch/arm/boot/dts/kirkwood-linkstation-lswxl.dts b/arch/arm/boot/dts/kirkwood-linkstation-lswxl.dts new file mode 100644 index 0000000000000000000000000000000000000000..ecd5c12a805dbeccd7899780da5ae9e96555d156 --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-linkstation-lswxl.dts @@ -0,0 +1,116 @@ +/* + * Device Tree file for Buffalo Linkstation LS-WXL + * + * Copyright (C) 2015, 2016 + * Roger Shimizu + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "kirkwood-linkstation-duo-6281.dtsi" + +/ { + model = "Buffalo Linkstation LS-WXL"; + compatible = "buffalo,lswxl", "marvell,kirkwood-88f6281", "marvell,kirkwood"; + + memory { /* 128 MB */ + device_type = "memory"; + reg = <0x00000000 0x8000000>; + }; + + ocp@f1000000 { + pinctrl: pin-controller@10000 { + pmx_led_hdderr0: pmx-led-hdderr0 { + marvell,pins = "mpp8"; + marvell,function = "gpio"; + }; + pmx_led_hdderr1: pmx-led-hdderr1 { + marvell,pins = "mpp46"; + marvell,function = "gpio"; + }; + pmx_fan_lock: pmx-fan-lock { + marvell,pins = "mpp40"; + marvell,function = "gpio"; + }; + pmx_fan_high: pmx-fan-high { + marvell,pins = "mpp47"; + marvell,function = "gpio"; + }; + pmx_fan_low: pmx-fan-low { + marvell,pins = "mpp48"; + marvell,function = "gpio"; + }; + }; + }; + + gpio_leds { + pinctrl-0 = <&pmx_led_function_red &pmx_led_alarm + &pmx_led_info &pmx_led_power + &pmx_led_function_blue + &pmx_led_hdderr0 + &pmx_led_hdderr1>; + + red-hdderr0-led { + label = "linkstation:red:hdderr0"; + gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>; + }; + + red-hdderr1-led { + label = "linkstation:red:hdderr1"; + gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>; + }; + }; + + gpio_fan { + compatible = "gpio-fan"; + pinctrl-0 = <&pmx_fan_low &pmx_fan_high &pmx_fan_lock>; + pinctrl-names = "default"; + + gpios = <&gpio1 16 GPIO_ACTIVE_LOW + &gpio1 15 GPIO_ACTIVE_LOW>; + + gpio-fan,speed-map = <0 3 + 1500 2 + 3250 1 + 5000 0>; + + alarm-gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; + }; +}; diff --git a/arch/arm/boot/dts/kirkwood-linkstation.dtsi b/arch/arm/boot/dts/kirkwood-linkstation.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..69061b6e987b86de8adf408e3477e45457b050fb --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-linkstation.dtsi @@ -0,0 +1,202 @@ +/* + * Device Tree common file for kirkwood based Buffalo Linkstation + * + * Copyright (C) 2015, 2016 + * Roger Shimizu + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/ { + chosen { + bootargs = "console=ttyS0,115200n8 earlyprintk"; + stdout-path = &uart0; + }; + + mbus { + pcie-controller { + status = "okay"; + pcie@1,0 { + status = "okay"; + }; + }; + }; + + ocp@f1000000 { + pinctrl: pin-controller@10000 { + pmx_power_hdd0: pmx-power-hdd0 { + marvell,function = "gpio"; + }; + pmx_usb_vbus: pmx-usb-vbus { + marvell,function = "gpio"; + }; + pmx_led_alarm: pmx-led-alarm { + marvell,function = "gpio"; + }; + pmx_led_function_red: pmx-led-function-red { + marvell,function = "gpio"; + }; + pmx_led_function_blue: pmx-led-function-blue { + marvell,function = "gpio"; + }; + pmx_led_info: pmx-led-info { + marvell,function = "gpio"; + }; + pmx_led_power: pmx-led-power { + marvell,function = "gpio"; + }; + pmx_button_function: pmx-button-function { + marvell,function = "gpio"; + }; + pmx_power_switch: pmx-power-switch { + marvell,function = "gpio"; + }; + pmx_power_auto_switch: pmx-power-auto-switch { + marvell,function = "gpio"; + }; + }; + + serial@12000 { + status = "okay"; + }; + + sata@80000 { + status = "okay"; + nr-ports = <1>; + }; + + spi@10600 { + status = "okay"; + + m25p40@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "st,m25p40", "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <25000000>; + mode = <0>; + + partition@0 { + reg = <0x0 0x60000>; + label = "uboot"; + read-only; + }; + + partition@60000 { + reg = <0x60000 0x10000>; + label = "dtb"; + read-only; + }; + + partition@70000 { + reg = <0x70000 0x10000>; + label = "uboot_env"; + }; + }; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-0 = <&pmx_button_function &pmx_power_switch + &pmx_power_auto_switch>; + pinctrl-names = "default"; + + function-button { + label = "Function Button"; + linux,code = ; + }; + + power-on-switch { + label = "Power-on Switch"; + linux,code = ; + linux,input-type = <5>; + }; + + power-auto-switch { + label = "Power-auto Switch"; + linux,code = ; + linux,input-type = <5>; + }; + }; + + gpio_leds { + compatible = "gpio-leds"; + pinctrl-0 = <&pmx_led_function_red &pmx_led_alarm + &pmx_led_info &pmx_led_power + &pmx_led_function_blue>; + pinctrl-names = "default"; + }; + + restart_poweroff { + compatible = "restart-poweroff"; + }; + + regulators { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-0 = <&pmx_power_hdd0 &pmx_usb_vbus>; + pinctrl-names = "default"; + + usb_power: regulator@1 { + compatible = "regulator-fixed"; + reg = <1>; + regulator-name = "USB Power"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + }; + + hdd_power0: regulator@2 { + compatible = "regulator-fixed"; + reg = <2>; + regulator-name = "HDD0 Power"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + }; + }; +}; diff --git a/arch/arm/boot/dts/kirkwood-lswvl.dts b/arch/arm/boot/dts/kirkwood-lswvl.dts deleted file mode 100644 index 36eec7392ab491c839f86ca3299cc716af21e356..0000000000000000000000000000000000000000 --- a/arch/arm/boot/dts/kirkwood-lswvl.dts +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Device Tree file for Buffalo Linkstation LS-WVL/VL - * - * Copyright (C) 2015, 2016 - * Roger Shimizu - * - * 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. - */ - -/dts-v1/; - -#include "kirkwood.dtsi" -#include "kirkwood-6282.dtsi" - -/ { - model = "Buffalo Linkstation LS-WVL/VL"; - compatible = "buffalo,lswvl", "buffalo,lsvl", "marvell,kirkwood-88f6282", "marvell,kirkwood"; - - memory { /* 256 MB */ - device_type = "memory"; - reg = <0x00000000 0x10000000>; - }; - - chosen { - bootargs = "console=ttyS0,115200n8 earlyprintk"; - stdout-path = &uart0; - }; - - mbus { - pcie-controller { - status = "okay"; - pcie@1,0 { - status = "okay"; - }; - }; - }; - - ocp@f1000000 { - pinctrl: pin-controller@10000 { - pmx_power_hdd0: pmx-power-hdd0 { - marvell,pins = "mpp8"; - marvell,function = "gpio"; - }; - pmx_power_hdd1: pmx-power-hdd1 { - marvell,pins = "mpp9"; - marvell,function = "gpio"; - }; - pmx_usb_vbus: pmx-usb-vbus { - marvell,pins = "mpp12"; - marvell,function = "gpio"; - }; - pmx_fan_high: pmx-fan-high { - marvell,pins = "mpp16"; - marvell,function = "gpio"; - }; - pmx_fan_low: pmx-fan-low { - marvell,pins = "mpp17"; - marvell,function = "gpio"; - }; - pmx_led_hdderr0: pmx-led-hdderr0 { - marvell,pins = "mpp34"; - marvell,function = "gpio"; - }; - pmx_led_hdderr1: pmx-led-hdderr1 { - marvell,pins = "mpp35"; - marvell,function = "gpio"; - }; - pmx_led_alarm: pmx-led-alarm { - marvell,pins = "mpp36"; - marvell,function = "gpio"; - }; - pmx_led_function_red: pmx-led-function-red { - marvell,pins = "mpp37"; - marvell,function = "gpio"; - }; - pmx_led_info: pmx-led-info { - marvell,pins = "mpp38"; - marvell,function = "gpio"; - }; - pmx_led_function_blue: pmx-led-function-blue { - marvell,pins = "mpp39"; - marvell,function = "gpio"; - }; - pmx_led_power: pmx-led-power { - marvell,pins = "mpp40"; - marvell,function = "gpio"; - }; - pmx_fan_lock: pmx-fan-lock { - marvell,pins = "mpp43"; - marvell,function = "gpio"; - }; - pmx_button_function: pmx-button-function { - marvell,pins = "mpp45"; - marvell,function = "gpio"; - }; - pmx_power_switch: pmx-power-switch { - marvell,pins = "mpp46"; - marvell,function = "gpio"; - }; - pmx_power_auto_switch: pmx-power-auto-switch { - marvell,pins = "mpp47"; - marvell,function = "gpio"; - }; - }; - - serial@12000 { - status = "okay"; - }; - - sata@80000 { - status = "okay"; - nr-ports = <2>; - }; - - spi@10600 { - status = "okay"; - - m25p40@0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "st,m25p40", "jedec,spi-nor"; - reg = <0>; - spi-max-frequency = <25000000>; - mode = <0>; - - partition@0 { - reg = <0x0 0x60000>; - label = "uboot"; - read-only; - }; - - partition@60000 { - reg = <0x60000 0x10000>; - label = "dtb"; - read-only; - }; - - partition@70000 { - reg = <0x70000 0x10000>; - label = "uboot_env"; - }; - }; - }; - }; - - gpio_keys { - compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; - pinctrl-0 = <&pmx_button_function &pmx_power_switch - &pmx_power_auto_switch>; - pinctrl-names = "default"; - - button@1 { - label = "Function Button"; - linux,code = ; - gpios = <&gpio1 13 GPIO_ACTIVE_LOW>; - }; - - button@2 { - label = "Power-on Switch"; - linux,code = ; - linux,input-type = <5>; - gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; - }; - - button@3 { - label = "Power-auto Switch"; - linux,code = ; - linux,input-type = <5>; - gpios = <&gpio1 15 GPIO_ACTIVE_LOW>; - }; - }; - - gpio_leds { - compatible = "gpio-leds"; - pinctrl-0 = <&pmx_led_function_red &pmx_led_alarm - &pmx_led_info &pmx_led_power - &pmx_led_function_blue - &pmx_led_hdderr0 - &pmx_led_hdderr1>; - pinctrl-names = "default"; - - led@1 { - label = "lswvl:red:alarm"; - gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>; - }; - - led@2 { - label = "lswvl:red:func"; - gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>; - }; - - led@3 { - label = "lswvl:amber:info"; - gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>; - }; - - led@4 { - label = "lswvl:blue:func"; - gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; - }; - - led@5 { - label = "lswvl:blue:power"; - gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; - default-state = "keep"; - }; - - led@6 { - label = "lswvl:red:hdderr0"; - gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>; - }; - - led@7 { - label = "lswvl:red:hdderr1"; - gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>; - }; - }; - - gpio_fan { - compatible = "gpio-fan"; - pinctrl-0 = <&pmx_fan_low &pmx_fan_high &pmx_fan_lock>; - pinctrl-names = "default"; - - gpios = <&gpio0 17 GPIO_ACTIVE_LOW - &gpio0 16 GPIO_ACTIVE_LOW>; - - gpio-fan,speed-map = <0 3 - 1500 2 - 3250 1 - 5000 0>; - - alarm-gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>; - }; - - restart_poweroff { - compatible = "restart-poweroff"; - }; - - regulators { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <0>; - pinctrl-0 = <&pmx_power_hdd0 &pmx_power_hdd1 &pmx_usb_vbus>; - pinctrl-names = "default"; - - usb_power: regulator@1 { - compatible = "regulator-fixed"; - reg = <1>; - regulator-name = "USB Power"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - enable-active-high; - regulator-always-on; - regulator-boot-on; - gpio = <&gpio0 12 GPIO_ACTIVE_HIGH>; - }; - hdd_power0: regulator@2 { - compatible = "regulator-fixed"; - reg = <2>; - regulator-name = "HDD0 Power"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - enable-active-high; - regulator-always-on; - regulator-boot-on; - gpio = <&gpio0 8 GPIO_ACTIVE_HIGH>; - }; - hdd_power1: regulator@3 { - compatible = "regulator-fixed"; - reg = <3>; - regulator-name = "HDD1 Power"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - enable-active-high; - regulator-always-on; - regulator-boot-on; - gpio = <&gpio0 9 GPIO_ACTIVE_HIGH>; - }; - }; -}; - -&mdio { - status = "okay"; - - ethphy0: ethernet-phy@0 { - device_type = "ethernet-phy"; - reg = <0>; - }; -}; - -ð0 { - status = "okay"; - - ethernet0-port@0 { - phy-handle = <ðphy0>; - }; -}; diff --git a/arch/arm/boot/dts/kirkwood-lswxl.dts b/arch/arm/boot/dts/kirkwood-lswxl.dts deleted file mode 100644 index b13ec20a708873bb65619ccd203c3552b04bc246..0000000000000000000000000000000000000000 --- a/arch/arm/boot/dts/kirkwood-lswxl.dts +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Device Tree file for Buffalo Linkstation LS-WXL/WSXL - * - * Copyright (C) 2015, 2016 - * Roger Shimizu - * - * 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. - */ - -/dts-v1/; - -#include "kirkwood.dtsi" -#include "kirkwood-6281.dtsi" - -/ { - model = "Buffalo Linkstation LS-WXL/WSXL"; - compatible = "buffalo,lswxl", "marvell,kirkwood-88f6281", "marvell,kirkwood"; - - memory { /* 128 MB */ - device_type = "memory"; - reg = <0x00000000 0x8000000>; - }; - - chosen { - bootargs = "console=ttyS0,115200n8 earlyprintk"; - stdout-path = &uart0; - }; - - mbus { - pcie-controller { - status = "okay"; - pcie@1,0 { - status = "okay"; - }; - }; - }; - - ocp@f1000000 { - pinctrl: pin-controller@10000 { - pmx_power_hdd0: pmx-power-hdd0 { - marvell,pins = "mpp28"; - marvell,function = "gpio"; - }; - pmx_power_hdd1: pmx-power-hdd1 { - marvell,pins = "mpp29"; - marvell,function = "gpio"; - }; - pmx_usb_vbus: pmx-usb-vbus { - marvell,pins = "mpp37"; - marvell,function = "gpio"; - }; - pmx_fan_high: pmx-fan-high { - marvell,pins = "mpp47"; - marvell,function = "gpio"; - }; - pmx_fan_low: pmx-fan-low { - marvell,pins = "mpp48"; - marvell,function = "gpio"; - }; - pmx_led_hdderr0: pmx-led-hdderr0 { - marvell,pins = "mpp8"; - marvell,function = "gpio"; - }; - pmx_led_hdderr1: pmx-led-hdderr1 { - marvell,pins = "mpp46"; - marvell,function = "gpio"; - }; - pmx_led_alarm: pmx-led-alarm { - marvell,pins = "mpp49"; - marvell,function = "gpio"; - }; - pmx_led_function_red: pmx-led-function-red { - marvell,pins = "mpp34"; - marvell,function = "gpio"; - }; - pmx_led_function_blue: pmx-led-function-blue { - marvell,pins = "mpp36"; - marvell,function = "gpio"; - }; - pmx_led_info: pmx-led-info { - marvell,pins = "mpp38"; - marvell,function = "gpio"; - }; - pmx_led_power: pmx-led-power { - marvell,pins = "mpp39"; - marvell,function = "gpio"; - }; - pmx_fan_lock: pmx-fan-lock { - marvell,pins = "mpp40"; - marvell,function = "gpio"; - }; - pmx_button_function: pmx-button-function { - marvell,pins = "mpp41"; - marvell,function = "gpio"; - }; - pmx_power_switch: pmx-power-switch { - marvell,pins = "mpp42"; - marvell,function = "gpio"; - }; - pmx_power_auto_switch: pmx-power-auto-switch { - marvell,pins = "mpp43"; - marvell,function = "gpio"; - }; - }; - - serial@12000 { - status = "okay"; - }; - - sata@80000 { - status = "okay"; - nr-ports = <2>; - }; - - spi@10600 { - status = "okay"; - - m25p40@0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "st,m25p40", "jedec,spi-nor"; - reg = <0>; - spi-max-frequency = <25000000>; - mode = <0>; - - partition@0 { - reg = <0x0 0x60000>; - label = "uboot"; - read-only; - }; - - partition@60000 { - reg = <0x60000 0x10000>; - label = "dtb"; - read-only; - }; - - partition@70000 { - reg = <0x70000 0x10000>; - label = "uboot_env"; - }; - }; - }; - }; - - gpio_keys { - compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; - pinctrl-0 = <&pmx_button_function &pmx_power_switch - &pmx_power_auto_switch>; - pinctrl-names = "default"; - - button@1 { - label = "Function Button"; - linux,code = ; - gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; - }; - - button@2 { - label = "Power-on Switch"; - linux,code = ; - linux,input-type = <5>; - gpios = <&gpio1 10 GPIO_ACTIVE_LOW>; - }; - - button@3 { - label = "Power-auto Switch"; - linux,code = ; - linux,input-type = <5>; - gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; - }; - }; - - gpio_leds { - compatible = "gpio-leds"; - pinctrl-0 = <&pmx_led_function_red &pmx_led_alarm - &pmx_led_info &pmx_led_power - &pmx_led_function_blue - &pmx_led_hdderr0 - &pmx_led_hdderr1>; - pinctrl-names = "default"; - - led@1 { - label = "lswxl:blue:func"; - gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; - }; - - led@2 { - label = "lswxl:red:alarm"; - gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; - }; - - led@3 { - label = "lswxl:amber:info"; - gpios = <&gpio1 6 GPIO_ACTIVE_LOW>; - }; - - led@4 { - label = "lswxl:blue:power"; - gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; - default-state = "keep"; - }; - - led@5 { - label = "lswxl:red:func"; - gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>; - }; - - led@6 { - label = "lswxl:red:hdderr0"; - gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>; - }; - - led@7 { - label = "lswxl:red:hdderr1"; - gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>; - }; - }; - - gpio_fan { - compatible = "gpio-fan"; - pinctrl-0 = <&pmx_fan_low &pmx_fan_high &pmx_fan_lock>; - pinctrl-names = "default"; - - gpios = <&gpio1 16 GPIO_ACTIVE_LOW - &gpio1 15 GPIO_ACTIVE_LOW>; - - gpio-fan,speed-map = <0 3 - 1500 2 - 3250 1 - 5000 0>; - - alarm-gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; - }; - - restart_poweroff { - compatible = "restart-poweroff"; - }; - - regulators { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <0>; - pinctrl-0 = <&pmx_power_hdd0 &pmx_power_hdd1 &pmx_usb_vbus>; - pinctrl-names = "default"; - - usb_power: regulator@1 { - compatible = "regulator-fixed"; - reg = <1>; - regulator-name = "USB Power"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - enable-active-high; - regulator-always-on; - regulator-boot-on; - gpio = <&gpio1 5 GPIO_ACTIVE_HIGH>; - }; - hdd_power0: regulator@2 { - compatible = "regulator-fixed"; - reg = <2>; - regulator-name = "HDD0 Power"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - enable-active-high; - regulator-always-on; - regulator-boot-on; - gpio = <&gpio0 28 GPIO_ACTIVE_HIGH>; - }; - hdd_power1: regulator@3 { - compatible = "regulator-fixed"; - reg = <3>; - regulator-name = "HDD1 Power"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - enable-active-high; - regulator-always-on; - regulator-boot-on; - gpio = <&gpio0 29 GPIO_ACTIVE_HIGH>; - }; - }; -}; - -&mdio { - status = "okay"; - - ethphy1: ethernet-phy@8 { - device_type = "ethernet-phy"; - reg = <8>; - }; -}; - -ð1 { - status = "okay"; - - ethernet1-port@0 { - phy-handle = <ðphy1>; - }; -}; diff --git a/arch/arm/boot/dts/kirkwood-openrd-client.dts b/arch/arm/boot/dts/kirkwood-openrd-client.dts index 887b9c1fee43869a2b09336eb283116d3623e2af..96ff59d68f445f45a5182a12d6d42a3883ede881 100644 --- a/arch/arm/boot/dts/kirkwood-openrd-client.dts +++ b/arch/arm/boot/dts/kirkwood-openrd-client.dts @@ -20,6 +20,9 @@ compatible = "marvell,openrd-client", "marvell,openrd", "marvell,kirkwood-88f6281", "marvell,kirkwood"; ocp@f1000000 { + audio-controller@a0000 { + status = "okay"; + }; i2c@11000 { status = "okay"; clock-frequency = <400000>; @@ -27,6 +30,7 @@ cs42l51: cs42l51@4a { compatible = "cirrus,cs42l51"; reg = <0x4a>; + #sound-dai-cells = <0>; }; }; }; @@ -37,7 +41,7 @@ simple-audio-card,mclk-fs = <256>; simple-audio-card,cpu { - sound-dai = <&audio0>; + sound-dai = <&audio0 0>; }; simple-audio-card,codec { diff --git a/arch/arm/boot/dts/kirkwood-openrd.dtsi b/arch/arm/boot/dts/kirkwood-openrd.dtsi index d3330dadf7edd5da9ae9d35f10019a3b44555942..24f1d30970a0650b535bcd67395c0cea8ace7935 100644 --- a/arch/arm/boot/dts/kirkwood-openrd.dtsi +++ b/arch/arm/boot/dts/kirkwood-openrd.dtsi @@ -40,7 +40,7 @@ pinctrl-0 = <&pmx_select28 &pmx_sdio_cd &pmx_select34>; pinctrl-names = "default"; - pmx_select28: pmx-select-uart-sd { + pmx_select28: pmx-select-rs232-rs485 { marvell,pins = "mpp28"; marvell,function = "gpio"; }; @@ -48,7 +48,7 @@ marvell,pins = "mpp29"; marvell,function = "gpio"; }; - pmx_select34: pmx-select-rs232-rs484 { + pmx_select34: pmx-select-uart-sd { marvell,pins = "mpp34"; marvell,function = "gpio"; }; @@ -65,6 +65,43 @@ status = "okay"; cd-gpios = <&gpio0 29 9>; }; + gpio@10100 { + p28 { + gpio-hog; + gpios = <28 GPIO_ACTIVE_HIGH>; + /* + * SelRS232or485 selects between RS-232 or RS-485 + * mode for the second UART. + * + * Low: RS-232 + * High: RS-485 + * + * To use the second UART, you need to change also + * the SelUARTorSD. + */ + output-low; + line-name = "SelRS232or485"; + }; + }; + gpio@10140 { + p2 { + gpio-hog; + gpios = <2 GPIO_ACTIVE_HIGH>; + /* + * SelUARTorSD selects between the second UART + * (serial@12100) and SD (mvsdio@90000). + * + * Low: UART + * High: SD + * + * When changing this line make sure the newly + * selected device node is enabled and the + * previously selected device node is disabled. + */ + output-high; /* Select SD by default */ + line-name = "SelUARTorSD"; + }; + }; }; }; diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi index 7b5a4a18f49cb6981064c213805652df0911cb90..7445a15e259d05c3a51666694e2858bf3b6fb06c 100644 --- a/arch/arm/boot/dts/kirkwood.dtsi +++ b/arch/arm/boot/dts/kirkwood.dtsi @@ -381,7 +381,7 @@ audio0: audio-controller@a0000 { compatible = "marvell,kirkwood-audio"; - #sound-dai-cells = <0>; + #sound-dai-cells = <1>; reg = <0xa0000 0x2210>; interrupts = <24>; clocks = <&gate_clk 9>; diff --git a/arch/arm/boot/dts/logicpd-som-lv-37xx-devkit.dts b/arch/arm/boot/dts/logicpd-som-lv-37xx-devkit.dts new file mode 100644 index 0000000000000000000000000000000000000000..da8598402ab8b33137a74fac30a69432155fac17 --- /dev/null +++ b/arch/arm/boot/dts/logicpd-som-lv-37xx-devkit.dts @@ -0,0 +1,268 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/dts-v1/; + +#include "omap36xx.dtsi" +#include "logicpd-som-lv.dtsi" +#include "omap-gpmc-smsc9221.dtsi" + +/ { + model = "LogicPD Zoom DM3730 SOM-LV Development Kit"; + compatible = "logicpd,dm3730-som-lv-devkit", "ti,omap3630", "ti,omap3"; + + gpio_keys { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&gpio_key_pins>; + + sysboot2 { + label = "gpio3"; + gpios = <&gpio4 15 GPIO_ACTIVE_LOW>; /* gpio_111 / uP_GPIO_3 */ + linux,code = ; + wakeup-source; + }; + }; + + sound { + compatible = "ti,omap-twl4030"; + ti,model = "omap3logic"; + ti,mcbsp = <&mcbsp2>; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&led_pins &led_pins_wkup>; + + led1 { + label = "led1"; + gpios = <&gpio5 5 GPIO_ACTIVE_LOW>; /* gpio133 */ + linux,default-trigger = "cpu0"; + }; + + led2 { + label = "led2"; + gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; /* gpio11 */ + linux,default-trigger = "none"; + }; + }; +}; + +&vaux1 { + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; +}; + +&vaux4 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; +}; + +&mcbsp2 { + status = "okay"; +}; + +&charger { + ti,bb-uvolt = <3200000>; + ti,bb-uamp = <150>; +}; + +&gpmc { + ranges = <1 0 0x08000000 0x1000000>; /* CS1: 16MB for LAN9221 */ + + ethernet@gpmc { + pinctrl-names = "default"; + pinctrl-0 = <&lan9221_pins>; + interrupt-parent = <&gpio5>; + interrupts = <24 IRQ_TYPE_LEVEL_LOW>; /* gpio_152 */ + reg = <1 0 0xff>; + }; +}; + +&vpll2 { + regulator-always-on; +}; + +&dss { + status = "ok"; + vdds_dsi-supply = <&vpll2>; + vdda_video-supply = <&video_reg>; + pinctrl-names = "default"; + pinctrl-0 = <&dss_dpi_pins1>; + port { + dpi_out: endpoint { + remote-endpoint = <&lcd_in>; + data-lines = <16>; + }; + }; +}; + +/ { + aliases { + display0 = &lcd0; + }; + + video_reg: video_reg { + compatible = "regulator-fixed"; + regulator-name = "fixed-supply"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + lcd0: display@0 { + compatible = "panel-dpi"; + label = "28"; + status = "okay"; + /* default-on; */ + pinctrl-names = "default"; + pinctrl-0 = <&lcd_enable_pin>; + enable-gpios = <&gpio5 27 GPIO_ACTIVE_HIGH>; /* gpio155, lcd INI */ + port { + lcd_in: endpoint { + remote-endpoint = <&dpi_out>; + }; + }; + + panel-timing { + clock-frequency = <9000000>; + hactive = <480>; + vactive = <272>; + hfront-porch = <3>; + hback-porch = <2>; + hsync-len = <42>; + vback-porch = <3>; + vfront-porch = <2>; + vsync-len = <11>; + hsync-active = <1>; + vsync-active = <1>; + de-active = <1>; + pixelclk-active = <0>; + }; + }; + + bl: backlight { + compatible = "pwm-backlight"; + pinctrl-names = "default"; + pinctrl-0 = <&backlight_pins>; + pwms = <&twl_pwm 0 5000000>; + brightness-levels = <0 10 20 30 40 50 60 70 80 90 100>; + default-brightness-level = <7>; + enable-gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>; /* gpio_8 */ + }; +}; + +&mmc1 { + interrupts-extended = <&intc 83 &omap3_pmx_core 0x11a>; + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins &mmc1_cd>; + wp-gpios = <&gpio4 30 GPIO_ACTIVE_HIGH>; /* gpio_126 */ + cd-gpios = <&gpio4 14 IRQ_TYPE_LEVEL_LOW>; /* gpio_110 */ + vmmc-supply = <&vmmc1>; + bus-width = <4>; + cap-power-off-card; +}; + +&omap3_pmx_core { + gpio_key_pins: pinmux_gpio_key_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x212e, PIN_INPUT_PULLUP | MUX_MODE4) /* cam_xclkb.gpio_111 / uP_GPIO_3*/ + >; + }; + + led_pins: pinmux_led_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x215e, PIN_OUTPUT_PULLUP | MUX_MODE4) /* sdmmc2_dat1.gpio_133 / uP_GPIO_0 */ + >; + }; + + lan9221_pins: pinmux_lan9221_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x2184, PIN_INPUT_PULLUP | MUX_MODE4) /* mcbsp4_clkx.gpio_152 */ + >; + }; + + mmc1_pins: pinmux_mmc1_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x2144, PIN_OUTPUT | MUX_MODE0) /* sdmmc1_clk.sdmmc1_clk */ + OMAP3_CORE1_IOPAD(0x2146, PIN_INPUT | MUX_MODE0) /* sdmmc1_cmd.sdmmc1_cmd */ + OMAP3_CORE1_IOPAD(0x2148, PIN_INPUT | MUX_MODE0) /* sdmmc1_dat0.sdmmc1_dat0 */ + OMAP3_CORE1_IOPAD(0x214a, PIN_INPUT | MUX_MODE0) /* sdmmc1_dat1.sdmmc1_dat1 */ + OMAP3_CORE1_IOPAD(0x214c, PIN_INPUT | MUX_MODE0) /* sdmmc1_dat2.sdmmc1_dat2 */ + OMAP3_CORE1_IOPAD(0x214e, PIN_INPUT | MUX_MODE0) /* sdmmc1_dat3.sdmmc1_dat3 */ + OMAP3_CORE1_IOPAD(0x2132, PIN_INPUT_PULLUP | MUX_MODE4) /* cam_strobe.gpio_126 sdmmc1_wp*/ + >; + }; + + lcd_enable_pin: pinmux_lcd_enable_pin { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x218a, PIN_OUTPUT | PIN_OFF_OUTPUT_LOW | MUX_MODE4) /* mcbsp4_fs.gpio_155 */ + >; + }; + + dss_dpi_pins1: pinmux_dss_dpi_pins1 { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x20d4, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_pclk.dss_pclk */ + OMAP3_CORE1_IOPAD(0x20d6, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_hsync.dss_hsync */ + OMAP3_CORE1_IOPAD(0x20d8, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_vsync.dss_vsync */ + OMAP3_CORE1_IOPAD(0x20da, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_acbias.dss_acbias */ + + OMAP3_CORE1_IOPAD(0x20dc, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data0.dss_data0 */ + OMAP3_CORE1_IOPAD(0x20de, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data1.dss_data1 */ + OMAP3_CORE1_IOPAD(0x20e0, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data2.dss_data2 */ + OMAP3_CORE1_IOPAD(0x20e2, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data3.dss_data3 */ + OMAP3_CORE1_IOPAD(0x20e4, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data4.dss_data4 */ + OMAP3_CORE1_IOPAD(0x20e6, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data5.dss_data5 */ + OMAP3_CORE1_IOPAD(0x20e8, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data6.dss_data6 */ + OMAP3_CORE1_IOPAD(0x20ea, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data7.dss_data7 */ + OMAP3_CORE1_IOPAD(0x20ec, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data8.dss_data8 */ + OMAP3_CORE1_IOPAD(0x20ee, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data9.dss_data9 */ + OMAP3_CORE1_IOPAD(0x20f0, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data10.dss_data10 */ + OMAP3_CORE1_IOPAD(0x20f2, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data11.dss_data11 */ + OMAP3_CORE1_IOPAD(0x20f4, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data12.dss_data12 */ + OMAP3_CORE1_IOPAD(0x20f6, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data13.dss_data13 */ + OMAP3_CORE1_IOPAD(0x20f8, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data14.dss_data14 */ + OMAP3_CORE1_IOPAD(0x20fa, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data15.dss_data15 */ + >; + }; +}; + +&omap3_pmx_wkup { + led_pins_wkup: pinmux_led_pins_wkup { + pinctrl-single,pins = < + OMAP3_WKUP_IOPAD(0x2a24, PIN_OUTPUT_PULLUP | MUX_MODE4) /* jtag_emu0.gpio_11 / uP_GPIO_1 */ + >; + }; + + backlight_pins: pinmux_backlight_pins { + pinctrl-single,pins = < + OMAP3_WKUP_IOPAD(0x2a16, PIN_OUTPUT | PIN_OFF_OUTPUT_LOW | MUX_MODE4) /* sys_boot6.gpio_8 */ + >; + }; + + mmc1_cd: pinmux_mmc1_cd { + pinctrl-single,pins = < + OMAP3_WKUP_IOPAD(0x212c, PIN_INPUT_PULLUP | MUX_MODE4) /* cam_d11.gpio_110 */ + >; + }; +}; + + +&uart1 { + interrupts-extended = <&intc 72 &omap3_pmx_core OMAP3_UART1_RX>; +}; + +/* Wired to the tps65950 on the SOM, only the USB connector is on the devkit */ +&usb_otg_hs { + pinctrl-names = "default"; + pinctrl-0 = <&hsusb_otg_pins>; + interface-type = <0>; + usb-phy = <&usb2_phy>; + phys = <&usb2_phy>; + phy-names = "usb2-phy"; + mode = <3>; + power = <50>; +}; diff --git a/arch/arm/boot/dts/logicpd-som-lv.dtsi b/arch/arm/boot/dts/logicpd-som-lv.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..365f39ff58bb8a512debeaa1645fc1feb980f75b --- /dev/null +++ b/arch/arm/boot/dts/logicpd-som-lv.dtsi @@ -0,0 +1,265 @@ +/* + * 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 + +/ { + cpus { + cpu@0 { + cpu0-supply = <&vcc>; + }; + }; + + wl12xx_vmmc: wl12xx_vmmc { + compatible = "regulator-fixed"; + regulator-name = "vwl1271"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + gpio = <&gpio1 3 0>; /* gpio_3 */ + startup-delay-us = <70000>; + enable-active-high; + vin-supply = <&vmmc2>; + }; + + /* HS USB Host PHY on PORT 1 */ + hsusb2_phy: hsusb2_phy { + compatible = "usb-nop-xceiv"; + reset-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; /* gpio_4 */ + }; +}; + +&gpmc { + ranges = <0 0 0x00000000 0x1000000>; /* CS0: 16MB for NAND */ + + nand@0,0 { + linux,mtd-name = "micron,mt29f4g16abbda3w"; + reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ + nand-bus-width = <16>; + ti,nand-ecc-opt = "bch8"; + gpmc,sync-clk-ps = <0>; + gpmc,cs-on-ns = <0>; + gpmc,cs-rd-off-ns = <44>; + gpmc,cs-wr-off-ns = <44>; + gpmc,adv-on-ns = <6>; + gpmc,adv-rd-off-ns = <34>; + gpmc,adv-wr-off-ns = <44>; + gpmc,we-off-ns = <40>; + gpmc,oe-off-ns = <54>; + gpmc,access-ns = <64>; + gpmc,rd-cycle-ns = <82>; + gpmc,wr-cycle-ns = <82>; + gpmc,wr-access-ns = <40>; + gpmc,wr-data-mux-bus-ns = <0>; + gpmc,device-width = <2>; + + gpmc,page-burst-access-ns = <5>; + gpmc,cycle2cycle-delay-ns = <50>; + + #address-cells = <1>; + #size-cells = <1>; + + /* u-boot uses mtdparts=omap2-nand.0:512k(x-loader),1920k(u-boot),128k(u-boot-env),4m(kernel),-(fs) */ + + x-loader@0 { + label = "x-loader"; + reg = <0 0x80000>; + }; + + bootloaders@80000 { + label = "u-boot"; + reg = <0x80000 0x1e0000>; + }; + + bootloaders_env@260000 { + label = "u-boot-env"; + reg = <0x260000 0x20000>; + }; + + kernel@280000 { + label = "kernel"; + reg = <0x280000 0x400000>; + }; + + filesystem@680000 { + label = "fs"; + reg = <0x680000 0>; /* 0 = MTDPART_SIZ_FULL */ + }; + }; +}; + +&i2c1 { + clock-frequency = <2600000>; + + twl: twl@48 { + reg = <0x48>; + interrupts = <7>; /* SYS_NIRQ cascaded to intc */ + interrupt-parent = <&intc>; + twl_audio: audio { + compatible = "ti,twl4030-audio"; + codec { + }; + }; + }; +}; + +&i2c2 { + clock-frequency = <400000>; +}; + +&i2c3 { + clock-frequency = <400000>; +}; + +&mmc3 { + interrupts-extended = <&intc 94 &omap3_pmx_core2 0x46>; + pinctrl-0 = <&mmc3_pins>; + pinctrl-names = "default"; + vmmc-supply = <&wl12xx_vmmc>; + non-removable; + bus-width = <4>; + cap-power-off-card; + #address-cells = <1>; + #size-cells = <0>; + wlcore: wlcore@2 { + compatible = "ti,wl1273"; + reg = <2>; + interrupt-parent = <&gpio5>; + interrupts = <24 IRQ_TYPE_LEVEL_HIGH>; /* gpio 152 */ + ref-clock-frequency = <26000000>; + }; +}; + +&usbhshost { + port2-mode = "ehci-phy"; +}; + +&usbhsehci { + phys = <0 &hsusb2_phy>; +}; + + +&omap3_pmx_core { + pinctrl-names = "default"; + pinctrl-0 = <&hsusb2_pins>; + + mmc3_pins: pinmux_mm3_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x2164, PIN_INPUT_PULLUP | MUX_MODE3) /* sdmmc2_dat4.sdmmc3_dat0 */ + OMAP3_CORE1_IOPAD(0x2166, PIN_INPUT_PULLUP | MUX_MODE3) /* sdmmc2_dat5.sdmmc3_dat1 */ + OMAP3_CORE1_IOPAD(0x2168, PIN_INPUT_PULLUP | MUX_MODE3) /* sdmmc2_dat6.sdmmc3_dat2 */ + OMAP3_CORE1_IOPAD(0x216a, PIN_INPUT_PULLUP | MUX_MODE3) /* sdmmc2_dat6.sdmmc3_dat3 */ + OMAP3_CORE1_IOPAD(0x2184, PIN_INPUT_PULLUP | MUX_MODE4) /* mcbsp4_clkx.gpio_152 */ + OMAP3_CORE1_IOPAD(0x2a0c, PIN_OUTPUT | MUX_MODE4) /* sys_boot1.gpio_3 */ + OMAP3_CORE1_IOPAD(0x21d0, PIN_INPUT_PULLUP | MUX_MODE3) /* mcspi1_cs1.sdmmc3_cmd */ + OMAP3_CORE1_IOPAD(0x21d2, PIN_INPUT_PULLUP | MUX_MODE3) /* mcspi1_cs2.sdmmc_clk */ + >; + }; + mcbsp2_pins: pinmux_mcbsp2_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x213c, PIN_INPUT | MUX_MODE0) /* mcbsp2_fsx */ + OMAP3_CORE1_IOPAD(0x213e, PIN_INPUT | MUX_MODE0) /* mcbsp2_clkx */ + OMAP3_CORE1_IOPAD(0x2140, PIN_INPUT | MUX_MODE0) /* mcbsp2_dr */ + OMAP3_CORE1_IOPAD(0x2142, PIN_OUTPUT | MUX_MODE0) /* mcbsp2_dx */ + >; + }; + uart2_pins: pinmux_uart2_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x2174, PIN_INPUT | MUX_MODE0) /* uart2_cts.uart2_cts */ + OMAP3_CORE1_IOPAD(0x2176, PIN_OUTPUT | MUX_MODE0) /* uart2_rts .uart2_rts*/ + OMAP3_CORE1_IOPAD(0x2178, PIN_OUTPUT | MUX_MODE0) /* uart2_tx.uart2_tx */ + OMAP3_CORE1_IOPAD(0x217a, PIN_INPUT | MUX_MODE0) /* uart2_rx.uart2_rx */ + OMAP3_CORE1_IOPAD(0x2198, PIN_OUTPUT | MUX_MODE4) /* GPIO_162,BT_EN */ + >; + }; + mcspi1_pins: pinmux_mcspi1_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x21c8, PIN_INPUT | MUX_MODE0) /* mcspi1_clk.mcspi1_clk */ + OMAP3_CORE1_IOPAD(0x21ca, PIN_OUTPUT | MUX_MODE0) /* mcspi1_simo.mcspi1_simo */ + OMAP3_CORE1_IOPAD(0x21cc, PIN_INPUT_PULLUP | MUX_MODE0) /* mcspi1_somi.mcspi1_somi */ + OMAP3_CORE1_IOPAD(0x21ce, PIN_OUTPUT | MUX_MODE0) /* mcspi1_cs0.mcspi1_cs0 */ + >; + }; + + hsusb2_pins: pinmux_hsusb2_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x21d4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi1_cs3.hsusb2_data2 */ + OMAP3_CORE1_IOPAD(0x21d6, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_clk.hsusb2_data7 */ + OMAP3_CORE1_IOPAD(0x21d8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_simo.hsusb2_data4 */ + OMAP3_CORE1_IOPAD(0x21da, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_somi.hsusb2_data5 */ + OMAP3_CORE1_IOPAD(0x21dc, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs0.hsusb2_data6 */ + OMAP3_CORE1_IOPAD(0x21de, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs1.hsusb2_data3 */ + >; + }; + + hsusb_otg_pins: pinmux_hsusb_otg_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x21a2, PIN_INPUT | MUX_MODE0) /* hsusb0_clk.hsusb0_clk */ + OMAP3_CORE1_IOPAD(0x21a4, PIN_OUTPUT | MUX_MODE0) /* hsusb0_stp.hsusb0_stp */ + OMAP3_CORE1_IOPAD(0x21a6, PIN_INPUT | MUX_MODE0) /* hsusb0_dir.hsusb0_dir */ + OMAP3_CORE1_IOPAD(0x21a8, PIN_INPUT | MUX_MODE0) /* hsusb0_nxt.hsusb0_nxt */ + OMAP3_CORE1_IOPAD(0x21aa, PIN_INPUT | MUX_MODE0) /* hsusb0_data0.hsusb0_data0 */ + OMAP3_CORE1_IOPAD(0x21ac, PIN_INPUT | MUX_MODE0) /* hsusb0_data1.hsusb0_data1 */ + OMAP3_CORE1_IOPAD(0x21ae, PIN_INPUT | MUX_MODE0) /* hsusb0_data2.hsusb0_data2 */ + OMAP3_CORE1_IOPAD(0x21b0, PIN_INPUT | MUX_MODE0) /* hsusb0_data3.hsusb0_data3 */ + OMAP3_CORE1_IOPAD(0x21b2, PIN_INPUT | MUX_MODE0) /* hsusb0_data4.hsusb0_data4 */ + OMAP3_CORE1_IOPAD(0x21b4, PIN_INPUT | MUX_MODE0) /* hsusb0_data5.hsusb0_data5 */ + OMAP3_CORE1_IOPAD(0x21b6, PIN_INPUT | MUX_MODE0) /* hsusb0_data6.hsusb0_data6 */ + OMAP3_CORE1_IOPAD(0x21b8, PIN_INPUT | MUX_MODE0) /* hsusb0_data7.hsusb0_data7 */ + >; + }; + + +}; + +&omap3_pmx_wkup { + pinctrl-names = "default"; + pinctrl-0 = <&hsusb2_reset_pin>; + hsusb2_reset_pin: pinmux_hsusb1_reset_pin { + pinctrl-single,pins = < + OMAP3_WKUP_IOPAD(0x2a0e, PIN_OUTPUT | MUX_MODE4) /* sys_boot2.gpio_4 */ + >; + }; +}; + +&omap3_pmx_core2 { + pinctrl-names = "default"; + pinctrl-0 = <&hsusb2_2_pins>; + hsusb2_2_pins: pinmux_hsusb2_2_pins { + pinctrl-single,pins = < + OMAP3630_CORE2_IOPAD(0x25f0, PIN_OUTPUT | MUX_MODE3) /* etk_d10.hsusb2_clk */ + OMAP3630_CORE2_IOPAD(0x25f2, PIN_OUTPUT | MUX_MODE3) /* etk_d11.hsusb2_stp */ + OMAP3630_CORE2_IOPAD(0x25f4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d12.hsusb2_dir */ + OMAP3630_CORE2_IOPAD(0x25f6, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d13.hsusb2_nxt */ + OMAP3630_CORE2_IOPAD(0x25f8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d14.hsusb2_data0 */ + OMAP3630_CORE2_IOPAD(0x25fa, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d15.hsusb2_data1 */ + >; + }; +}; + +&uart2 { + interrupts-extended = <&intc 73 &omap3_pmx_core OMAP3_UART2_RX>; + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins>; +}; + +&mcspi1 { + pinctrl-names = "default"; + pinctrl-0 = <&mcspi1_pins>; +}; + +#include "twl4030.dtsi" +#include "twl4030_omap3.dtsi" + +&twl { + twl_power: power { + compatible = "ti,twl4030-power-idle-osc-off", "ti,twl4030-power-idle"; + ti,use_poweroff; + }; +}; + +&twl_gpio { + ti,use-leds; +}; diff --git a/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts b/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts index fb13f18c08cc36f4292d3c3bbe19fa74199acd85..015f795a8d19375a23ee3e21123c4da9fb1a643d 100644 --- a/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts +++ b/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts @@ -11,7 +11,7 @@ #include "omap-gpmc-smsc9221.dtsi" / { - model = "LogicPD Zoom DM3730 Torpedo Development Kit"; + model = "LogicPD Zoom DM3730 Torpedo + Wireless Development Kit"; compatible = "logicpd,dm3730-torpedo-devkit", "ti,omap3630", "ti,omap3"; gpio_keys { @@ -71,6 +71,15 @@ linux,default-trigger = "none"; }; }; + + pwm10: dmtimer-pwm@10 { + compatible = "ti,omap-dmtimer-pwm"; + pinctrl-names = "default"; + pinctrl-0 = <&pwm_pins>; + ti,timers = <&timer10>; + #pwm-cells = <3>; + }; + }; &vaux1 { @@ -93,7 +102,8 @@ }; &gpmc { - ranges = <1 0 0x08000000 0x1000000>; /* CS1: 16MB for LAN9221 */ + ranges = <0 0 0x30000000 0x1000000 /* CS0: 16MB for NAND */ + 1 0 0x2c000000 0x1000000>; /* CS1: 16MB for LAN9221 */ ethernet@gpmc { pinctrl-names = "default"; @@ -111,6 +121,7 @@ &dss { status = "ok"; vdds_dsi-supply = <&vpll2>; + vdda_video-supply = <&video_reg>; pinctrl-names = "default"; pinctrl-0 = <&dss_dpi_pins1>; port { @@ -126,13 +137,22 @@ display0 = &lcd0; }; + video_reg: video_reg { + pinctrl-names = "default"; + pinctrl-0 = <&panel_pwr_pins>; + compatible = "regulator-fixed"; + regulator-name = "fixed-supply"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio5 27 GPIO_ACTIVE_HIGH>; /* gpio155, lcd INI */ + }; + lcd0: display@0 { compatible = "panel-dpi"; label = "15"; status = "okay"; /* default-on; */ pinctrl-names = "default"; - enable-gpios = <&gpio5 27 GPIO_ACTIVE_HIGH>; /* gpio155, lcd INI */ port { lcd_in: endpoint { @@ -158,13 +178,13 @@ }; bl: backlight { - compatible = "gpio-backlight"; + compatible = "pwm-backlight"; pinctrl-names = "default"; pinctrl-0 = <&backlight_pins>; - - gpios = <&gpio2 24 GPIO_ACTIVE_HIGH>, /* gpio_56 */ - <&gpio5 26 GPIO_ACTIVE_HIGH>; /* gpio_154 */ - default-on; + pwms = <&pwm10 0 5000000 0>; + brightness-levels = <0 10 20 30 40 50 60 70 80 90 100>; + default-brightness-level = <7>; + enable-gpios = <&gpio5 26 GPIO_ACTIVE_HIGH>; /* gpio_154 */ }; }; @@ -186,6 +206,12 @@ >; }; + pwm_pins: pinmux_pwm_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x20B8, PIN_OUTPUT | PIN_OFF_OUTPUT_LOW | MUX_MODE3) /* gpmc_ncs5.gpt_10_pwm_evt */ + >; + }; + led_pins: pinmux_led_pins { pinctrl-single,pins = < OMAP3_CORE1_IOPAD(0x21d8, PIN_OUTPUT | MUX_MODE4) /* gpio_179 */ @@ -212,37 +238,60 @@ backlight_pins: pinmux_backlight_pins { pinctrl-single,pins = < - OMAP3_CORE1_IOPAD(0x20B8, PIN_OUTPUT | MUX_MODE4) /* gpmc_ncs5.gpio_56 */ - OMAP3_CORE1_IOPAD(0x2188, PIN_OUTPUT | MUX_MODE4) /* mcbsp4_dx.gpio_154 */ + OMAP3_CORE1_IOPAD(0x2188, PIN_OUTPUT | PIN_OFF_OUTPUT_LOW | MUX_MODE4) /* mcbsp4_dx.gpio_154 */ + >; + }; + + isp_pins: pinmux_isp_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x210c, PIN_INPUT | MUX_MODE0) /* cam_hs.cam_hs */ + OMAP3_CORE1_IOPAD(0x210e, PIN_INPUT | MUX_MODE0) /* cam_vs.cam_vs */ + OMAP3_CORE1_IOPAD(0x2110, PIN_INPUT | MUX_MODE0) /* cam_xclka.cam_xclka */ + OMAP3_CORE1_IOPAD(0x2112, PIN_INPUT | MUX_MODE0) /* cam_pclk.cam_pclk */ + + OMAP3_CORE1_IOPAD(0x2114, PIN_INPUT | MUX_MODE0) /* cam_d0.cam_d0 */ + OMAP3_CORE1_IOPAD(0x2116, PIN_INPUT | MUX_MODE0) /* cam_d1.cam_d1 */ + OMAP3_CORE1_IOPAD(0x2118, PIN_INPUT | MUX_MODE0) /* cam_d2.cam_d2 */ + OMAP3_CORE1_IOPAD(0x211c, PIN_INPUT | MUX_MODE0) /* cam_d3.cam_d3 */ + OMAP3_CORE1_IOPAD(0x211e, PIN_INPUT | MUX_MODE0) /* cam_d4.cam_d4 */ + OMAP3_CORE1_IOPAD(0x2120, PIN_INPUT | MUX_MODE0) /* cam_d5.cam_d5 */ + OMAP3_CORE1_IOPAD(0x2122, PIN_INPUT | MUX_MODE0) /* cam_d6.cam_d6 */ + OMAP3_CORE1_IOPAD(0x2124, PIN_INPUT | MUX_MODE0) /* cam_d7.cam_d7 */ + >; + }; + + panel_pwr_pins: pinmux_panel_pwr_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x218a, PIN_OUTPUT | PIN_OFF_OUTPUT_LOW | MUX_MODE4) /* mcbsp4_fs.gpio_155 */ >; }; dss_dpi_pins1: pinmux_dss_dpi_pins1 { pinctrl-single,pins = < - OMAP3_CORE1_IOPAD(0x20d4, PIN_OUTPUT | MUX_MODE0) /* dss_pclk.dss_pclk */ - OMAP3_CORE1_IOPAD(0x20d6, PIN_OUTPUT | MUX_MODE0) /* dss_hsync.dss_hsync */ - OMAP3_CORE1_IOPAD(0x20d8, PIN_OUTPUT | MUX_MODE0) /* dss_vsync.dss_vsync */ - OMAP3_CORE1_IOPAD(0x20da, PIN_OUTPUT | MUX_MODE0) /* dss_acbias.dss_acbias */ - - OMAP3_CORE1_IOPAD(0x20e8, PIN_OUTPUT | MUX_MODE0) /* dss_data6.dss_data6 */ - OMAP3_CORE1_IOPAD(0x20ea, PIN_OUTPUT | MUX_MODE0) /* dss_data7.dss_data7 */ - OMAP3_CORE1_IOPAD(0x20ec, PIN_OUTPUT | MUX_MODE0) /* dss_data8.dss_data8 */ - OMAP3_CORE1_IOPAD(0x20ee, PIN_OUTPUT | MUX_MODE0) /* dss_data9.dss_data9 */ - OMAP3_CORE1_IOPAD(0x20f0, PIN_OUTPUT | MUX_MODE0) /* dss_data10.dss_data10 */ - OMAP3_CORE1_IOPAD(0x20f2, PIN_OUTPUT | MUX_MODE0) /* dss_data11.dss_data11 */ - OMAP3_CORE1_IOPAD(0x20f4, PIN_OUTPUT | MUX_MODE0) /* dss_data12.dss_data12 */ - OMAP3_CORE1_IOPAD(0x20f6, PIN_OUTPUT | MUX_MODE0) /* dss_data13.dss_data13 */ - OMAP3_CORE1_IOPAD(0x20f8, PIN_OUTPUT | MUX_MODE0) /* dss_data14.dss_data14 */ - OMAP3_CORE1_IOPAD(0x20fa, PIN_OUTPUT | MUX_MODE0) /* dss_data15.dss_data15 */ - OMAP3_CORE1_IOPAD(0x20fc, PIN_OUTPUT | MUX_MODE0) /* dss_data16.dss_data16 */ - OMAP3_CORE1_IOPAD(0x20fe, PIN_OUTPUT | MUX_MODE0) /* dss_data17.dss_data17 */ - - OMAP3_CORE1_IOPAD(0x2100, PIN_OUTPUT | MUX_MODE3) /* dss_data18.dss_data0 */ - OMAP3_CORE1_IOPAD(0x2102, PIN_OUTPUT | MUX_MODE3) /* dss_data19.dss_data1 */ - OMAP3_CORE1_IOPAD(0x2104, PIN_OUTPUT | MUX_MODE3) /* dss_data20.dss_data2 */ - OMAP3_CORE1_IOPAD(0x2106, PIN_OUTPUT | MUX_MODE3) /* dss_data21.dss_data3 */ - OMAP3_CORE1_IOPAD(0x2108, PIN_OUTPUT | MUX_MODE3) /* dss_data22.dss_data4 */ - OMAP3_CORE1_IOPAD(0x210a, PIN_OUTPUT | MUX_MODE3) /* dss_data23.dss_data5 */ + OMAP3_CORE1_IOPAD(0x20d4, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_pclk.dss_pclk */ + OMAP3_CORE1_IOPAD(0x20d6, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_hsync.dss_hsync */ + OMAP3_CORE1_IOPAD(0x20d8, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_vsync.dss_vsync */ + OMAP3_CORE1_IOPAD(0x20da, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_acbias.dss_acbias */ + + OMAP3_CORE1_IOPAD(0x20e8, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data6.dss_data6 */ + OMAP3_CORE1_IOPAD(0x20ea, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data7.dss_data7 */ + OMAP3_CORE1_IOPAD(0x20ec, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data8.dss_data8 */ + OMAP3_CORE1_IOPAD(0x20ee, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data9.dss_data9 */ + OMAP3_CORE1_IOPAD(0x20f0, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data10.dss_data10 */ + OMAP3_CORE1_IOPAD(0x20f2, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data11.dss_data11 */ + OMAP3_CORE1_IOPAD(0x20f4, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data12.dss_data12 */ + OMAP3_CORE1_IOPAD(0x20f6, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data13.dss_data13 */ + OMAP3_CORE1_IOPAD(0x20f8, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data14.dss_data14 */ + OMAP3_CORE1_IOPAD(0x20fa, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data15.dss_data15 */ + OMAP3_CORE1_IOPAD(0x20fc, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data16.dss_data16 */ + OMAP3_CORE1_IOPAD(0x20fe, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE0) /* dss_data17.dss_data17 */ + + OMAP3_CORE1_IOPAD(0x2100, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE3) /* dss_data18.dss_data0 */ + OMAP3_CORE1_IOPAD(0x2102, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE3) /* dss_data19.dss_data1 */ + OMAP3_CORE1_IOPAD(0x2104, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE3) /* dss_data20.dss_data2 */ + OMAP3_CORE1_IOPAD(0x2106, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE3) /* dss_data21.dss_data3 */ + OMAP3_CORE1_IOPAD(0x2108, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE3) /* dss_data22.dss_data4 */ + OMAP3_CORE1_IOPAD(0x210a, PIN_OUTPUT_PULLDOWN | PIN_OFF_OUTPUT_LOW | MUX_MODE3) /* dss_data23.dss_data5 */ >; }; }; @@ -268,6 +317,24 @@ }; }; +&i2c2 { + mt9p031@48 { + compatible = "aptina,mt9p031"; + reg = <0x48>; + clocks = <&isp 0>; + vaa-supply = <&vaux4>; + vdd-supply = <&vaux4>; + vdd_io-supply = <&vaux4>; + port { + mt9p031_out: endpoint { + input-clock-frequency = <24000000>; + pixel-clock-frequency = <72000000>; + remote-endpoint = <&ccdc_ep>; + }; + }; + }; +}; + &i2c3 { touchscreen: tsc2004@48 { compatible = "ti,tsc2004"; @@ -289,12 +356,45 @@ }; }; +&mcspi1 { + at25@0 { + compatible = "atmel,at25"; + reg = <0>; + spi-max-frequency = <5000000>; + spi-cpha; + spi-cpol; + + pagesize = <64>; + size = <32768>; + address-width = <16>; + }; +}; + +&isp { + pinctrl-names = "default"; + pinctrl-0 = <&isp_pins>; + ports { + port@0 { + reg = <0>; + ccdc_ep: endpoint { + remote-endpoint = <&mt9p031_out>; + bus-width = <8>; + hsync-active = <1>; + vsync-active = <1>; + pclk-sample = <0>; + }; + }; + }; +}; + &uart1 { interrupts-extended = <&intc 72 &omap3_pmx_core OMAP3_UART1_RX>; }; /* Wired to the tps65950 on the SOM, only the USB connector is on the devkit */ &usb_otg_hs { + pinctrl-names = "default"; + pinctrl-0 = <&hsusb_otg_pins>; interface-type = <0>; usb-phy = <&usb2_phy>; phys = <&usb2_phy>; diff --git a/arch/arm/boot/dts/logicpd-torpedo-som.dtsi b/arch/arm/boot/dts/logicpd-torpedo-som.dtsi index 00805322367e7eb73bcc4ba5bda124eee5372467..5e9a13c0eaf7f4ca515942438cc1c8cdc331eafd 100644 --- a/arch/arm/boot/dts/logicpd-torpedo-som.dtsi +++ b/arch/arm/boot/dts/logicpd-torpedo-som.dtsi @@ -35,11 +35,15 @@ }; &gpmc { - ranges = <0 0 0x00000000 0x1000000>; /* CS0: 16MB for NAND */ + ranges = <0 0 0x30000000 0x1000000>; /* CS0: 16MB for NAND */ nand@0,0 { - linux,mtd-name = "micron,mt29f4g16abbda3w"; + compatible = "ti,omap2-nand"; reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ + interrupt-parent = <&gpmc>; + interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ + <1 IRQ_TYPE_NONE>; /* termcount */ + linux,mtd-name = "micron,mt29f4g16abbda3w"; nand-bus-width = <16>; ti,nand-ecc-opt = "bch8"; gpmc,sync-clk-ps = <0>; @@ -110,6 +114,11 @@ &i2c3 { clock-frequency = <400000>; + at24@50 { + compatible = "at24,24c02"; + readonly; + reg = <0x50>; + }; }; /* @@ -167,6 +176,31 @@ OMAP3_CORE1_IOPAD(0x2198, PIN_OUTPUT | MUX_MODE4) /* GPIO_162,BT_EN */ >; }; + mcspi1_pins: pinmux_mcspi1_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x21c8, PIN_INPUT | MUX_MODE0) /* mcspi1_clk.mcspi1_clk */ + OMAP3_CORE1_IOPAD(0x21ca, PIN_OUTPUT | MUX_MODE0) /* mcspi1_simo.mcspi1_simo */ + OMAP3_CORE1_IOPAD(0x21cc, PIN_INPUT_PULLUP | MUX_MODE0) /* mcspi1_somi.mcspi1_somi */ + OMAP3_CORE1_IOPAD(0x21ce, PIN_OUTPUT | MUX_MODE0) /* mcspi1_cs0.mcspi1_cs0 */ + >; + }; + hsusb_otg_pins: pinmux_hsusb_otg_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x21a2, PIN_INPUT | MUX_MODE0) /* hsusb0_clk.hsusb0_clk */ + OMAP3_CORE1_IOPAD(0x21a4, PIN_OUTPUT | MUX_MODE0) /* hsusb0_stp.hsusb0_stp */ + OMAP3_CORE1_IOPAD(0x21a6, PIN_INPUT | MUX_MODE0) /* hsusb0_dir.hsusb0_dir */ + OMAP3_CORE1_IOPAD(0x21a8, PIN_INPUT | MUX_MODE0) /* hsusb0_nxt.hsusb0_nxt */ + + OMAP3_CORE1_IOPAD(0x21aa, PIN_INPUT | MUX_MODE0) /* hsusb0_data0.hsusb0_data0 */ + OMAP3_CORE1_IOPAD(0x21ac, PIN_INPUT | MUX_MODE0) /* hsusb0_data1.hsusb0_data1 */ + OMAP3_CORE1_IOPAD(0x21ae, PIN_INPUT | MUX_MODE0) /* hsusb0_data2.hsusb0_data2 */ + OMAP3_CORE1_IOPAD(0x21b0, PIN_INPUT | MUX_MODE0) /* hsusb0_data3.hsusb0_data3 */ + OMAP3_CORE1_IOPAD(0x21b2, PIN_INPUT | MUX_MODE0) /* hsusb0_data4.hsusb0_data4 */ + OMAP3_CORE1_IOPAD(0x21b4, PIN_INPUT | MUX_MODE0) /* hsusb0_data5.hsusb0_data5 */ + OMAP3_CORE1_IOPAD(0x21b6, PIN_INPUT | MUX_MODE0) /* hsusb0_data6.hsusb0_data6 */ + OMAP3_CORE1_IOPAD(0x21b8, PIN_INPUT | MUX_MODE0) /* hsusb0_data7.hsusb0_data7 */ + >; + }; }; &uart2 { @@ -175,6 +209,11 @@ pinctrl-0 = <&uart2_pins>; }; +&mcspi1 { + pinctrl-names = "default"; + pinctrl-0 = <&mcspi1_pins>; +}; + &omap3_pmx_core2 { mmc3_core2_pins: pinmux_mmc3_core2_pins { pinctrl-single,pins = < diff --git a/arch/arm/boot/dts/lpc32xx.dtsi b/arch/arm/boot/dts/lpc32xx.dtsi index c85cf979725e0c5f83c2570014605cc7da4ad096..c58d8da9ea2a1356b52c8905aaeae36a61ce5f37 100644 --- a/arch/arm/boot/dts/lpc32xx.dtsi +++ b/arch/arm/boot/dts/lpc32xx.dtsi @@ -13,6 +13,9 @@ #include "skeleton.dtsi" +#include +#include + / { compatible = "nxp,lpc3220"; interrupt-parent = <&mic>; @@ -28,6 +31,22 @@ }; }; + clocks { + xtal_32k: xtal_32k { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + clock-output-names = "xtal_32k"; + }; + + xtal: xtal { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <13000000>; + clock-output-names = "xtal"; + }; + }; + ahb { #address-cells = <1>; #size-cells = <1>; @@ -41,20 +60,24 @@ slc: flash@20020000 { compatible = "nxp,lpc3220-slc"; reg = <0x20020000 0x1000>; + clocks = <&clk LPC32XX_CLK_SLC>; status = "disabled"; }; mlc: flash@200a8000 { compatible = "nxp,lpc3220-mlc"; reg = <0x200a8000 0x11000>; - interrupts = <11 0>; + interrupts = <11 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk LPC32XX_CLK_MLC>; status = "disabled"; }; dma: dma@31000000 { compatible = "arm,pl080", "arm,primecell"; reg = <0x31000000 0x1000>; - interrupts = <0x1c 0>; + interrupts = <28 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk LPC32XX_CLK_DMA>; + clock-names = "apb_pclk"; }; usb { @@ -69,43 +92,60 @@ ohci: ohci@0 { compatible = "nxp,ohci-nxp", "usb-ohci"; reg = <0x0 0x300>; - interrupts = <0x3b 0>; + interrupts = <59 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&usbclk LPC32XX_USB_CLK_HOST>; status = "disabled"; }; usbd: usbd@0 { compatible = "nxp,lpc3220-udc"; reg = <0x0 0x300>; - interrupts = <0x3d 0>, <0x3e 0>, <0x3c 0>, <0x3a 0>; + interrupts = <61 IRQ_TYPE_LEVEL_HIGH>, + <62 IRQ_TYPE_LEVEL_HIGH>, + <60 IRQ_TYPE_LEVEL_HIGH>, + <58 IRQ_TYPE_LEVEL_LOW>; + clocks = <&usbclk LPC32XX_USB_CLK_DEVICE>; status = "disabled"; }; i2cusb: i2c@300 { compatible = "nxp,pnx-i2c"; reg = <0x300 0x100>; - interrupts = <0x3f 0>; + interrupts = <63 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&usbclk LPC32XX_USB_CLK_I2C>; #address-cells = <1>; #size-cells = <0>; pnx,timeout = <0x64>; }; + + usbclk: clock-controller@f00 { + compatible = "nxp,lpc3220-usb-clk"; + reg = <0xf00 0x100>; + #clock-cells = <1>; + }; }; clcd: clcd@31040000 { compatible = "arm,pl110", "arm,primecell"; reg = <0x31040000 0x1000>; - interrupts = <0x0e 0>; + interrupts = <14 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk LPC32XX_CLK_LCD>; + clock-names = "apb_pclk"; status = "disabled"; }; mac: ethernet@31060000 { compatible = "nxp,lpc-eth"; reg = <0x31060000 0x1000>; - interrupts = <0x1d 0>; + interrupts = <29 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk LPC32XX_CLK_MAC>; }; emc: memory-controller@31080000 { compatible = "arm,pl175", "arm,primecell"; reg = <0x31080000 0x1000>; + clocks = <&clk LPC32XX_CLK_DDRAM>, <&clk LPC32XX_CLK_DDRAM>; + clock-names = "mpmcclk", "apb_pclk"; #address-cells = <1>; #size-cells = <1>; @@ -125,7 +165,9 @@ ssp0: ssp@20084000 { compatible = "arm,pl022", "arm,primecell"; reg = <0x20084000 0x1000>; - interrupts = <0x14 0>; + interrupts = <20 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk LPC32XX_CLK_SSP0>; + clock-names = "apb_pclk"; }; spi1: spi@20088000 { @@ -136,7 +178,9 @@ ssp1: ssp@2008c000 { compatible = "arm,pl022", "arm,primecell"; reg = <0x2008c000 0x1000>; - interrupts = <0x15 0>; + interrupts = <21 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk LPC32XX_CLK_SSP1>; + clock-names = "apb_pclk"; }; spi2: spi@20090000 { @@ -152,7 +196,10 @@ sd: sd@20098000 { compatible = "arm,pl18x", "arm,primecell"; reg = <0x20098000 0x1000>; - interrupts = <0x0f 0>, <0x0d 0>; + interrupts = <15 IRQ_TYPE_LEVEL_HIGH>, + <13 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk LPC32XX_CLK_SD>; + clock-names = "apb_pclk"; status = "disabled"; }; @@ -166,55 +213,57 @@ /* actually, ns16550a w/ 64 byte fifos! */ compatible = "nxp,lpc3220-uart"; reg = <0x40090000 0x1000>; - interrupts = <9 0>; - clock-frequency = <13000000>; + interrupts = <9 IRQ_TYPE_LEVEL_HIGH>; reg-shift = <2>; + clocks = <&clk LPC32XX_CLK_UART5>; status = "disabled"; }; uart3: serial@40080000 { compatible = "nxp,lpc3220-uart"; reg = <0x40080000 0x1000>; - interrupts = <7 0>; - clock-frequency = <13000000>; + interrupts = <7 IRQ_TYPE_LEVEL_HIGH>; reg-shift = <2>; + clocks = <&clk LPC32XX_CLK_UART3>; status = "disabled"; }; uart4: serial@40088000 { compatible = "nxp,lpc3220-uart"; reg = <0x40088000 0x1000>; - interrupts = <8 0>; - clock-frequency = <13000000>; + interrupts = <8 IRQ_TYPE_LEVEL_HIGH>; reg-shift = <2>; + clocks = <&clk LPC32XX_CLK_UART4>; status = "disabled"; }; uart6: serial@40098000 { compatible = "nxp,lpc3220-uart"; reg = <0x40098000 0x1000>; - interrupts = <10 0>; - clock-frequency = <13000000>; + interrupts = <10 IRQ_TYPE_LEVEL_HIGH>; reg-shift = <2>; + clocks = <&clk LPC32XX_CLK_UART6>; status = "disabled"; }; i2c1: i2c@400A0000 { compatible = "nxp,pnx-i2c"; reg = <0x400A0000 0x100>; - interrupts = <0x33 0>; + interrupts = <51 IRQ_TYPE_LEVEL_LOW>; #address-cells = <1>; #size-cells = <0>; pnx,timeout = <0x64>; + clocks = <&clk LPC32XX_CLK_I2C1>; }; i2c2: i2c@400A8000 { compatible = "nxp,pnx-i2c"; reg = <0x400A8000 0x100>; - interrupts = <0x32 0>; + interrupts = <50 IRQ_TYPE_LEVEL_LOW>; #address-cells = <1>; #size-cells = <0>; pnx,timeout = <0x64>; + clocks = <&clk LPC32XX_CLK_I2C2>; }; mpwm: mpwm@400E8000 { @@ -231,6 +280,23 @@ compatible = "simple-bus"; ranges = <0x20000000 0x20000000 0x30000000>; + /* System Control Block */ + scb { + compatible = "simple-bus"; + ranges = <0x0 0x040004000 0x00001000>; + #address-cells = <1>; + #size-cells = <1>; + + clk: clock-controller@0 { + compatible = "nxp,lpc3220-clk"; + reg = <0x00 0x114>; + #clock-cells = <1>; + + clocks = <&xtal_32k>, <&xtal>; + clock-names = "xtal_32k", "xtal"; + }; + }; + /* * MIC Interrupt controller includes: * MIC @40008000 @@ -247,28 +313,29 @@ uart1: serial@40014000 { compatible = "nxp,lpc3220-hsuart"; reg = <0x40014000 0x1000>; - interrupts = <26 0>; + interrupts = <26 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; }; uart2: serial@40018000 { compatible = "nxp,lpc3220-hsuart"; reg = <0x40018000 0x1000>; - interrupts = <25 0>; + interrupts = <25 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; }; uart7: serial@4001c000 { compatible = "nxp,lpc3220-hsuart"; reg = <0x4001c000 0x1000>; - interrupts = <24 0>; + interrupts = <24 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; }; rtc: rtc@40024000 { compatible = "nxp,lpc3220-rtc"; reg = <0x40024000 0x1000>; - interrupts = <0x34 0>; + interrupts = <52 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk LPC32XX_CLK_RTC>; }; gpio: gpio@40028000 { @@ -281,26 +348,33 @@ timer4: timer@4002C000 { compatible = "nxp,lpc3220-timer"; reg = <0x4002C000 0x1000>; - interrupts = <0x3 0>; + interrupts = <3 IRQ_TYPE_LEVEL_LOW>; + clocks = <&clk LPC32XX_CLK_TIMER4>; + clock-names = "timerclk"; status = "disabled"; }; timer5: timer@40030000 { compatible = "nxp,lpc3220-timer"; reg = <0x40030000 0x1000>; - interrupts = <0x4 0>; + interrupts = <4 IRQ_TYPE_LEVEL_LOW>; + clocks = <&clk LPC32XX_CLK_TIMER5>; + clock-names = "timerclk"; status = "disabled"; }; watchdog: watchdog@4003C000 { compatible = "nxp,pnx4008-wdt"; reg = <0x4003C000 0x1000>; + clocks = <&clk LPC32XX_CLK_WDOG>; }; timer0: timer@40044000 { compatible = "nxp,lpc3220-timer"; reg = <0x40044000 0x1000>; - interrupts = <0x10 0>; + clocks = <&clk LPC32XX_CLK_TIMER0>; + clock-names = "timerclk"; + interrupts = <16 IRQ_TYPE_LEVEL_LOW>; }; /* @@ -313,53 +387,63 @@ adc: adc@40048000 { compatible = "nxp,lpc3220-adc"; reg = <0x40048000 0x1000>; - interrupts = <0x27 0>; + interrupts = <39 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk LPC32XX_CLK_ADC>; status = "disabled"; }; tsc: tsc@40048000 { compatible = "nxp,lpc3220-tsc"; reg = <0x40048000 0x1000>; - interrupts = <0x27 0>; + interrupts = <39 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk LPC32XX_CLK_ADC>; status = "disabled"; }; timer1: timer@4004C000 { compatible = "nxp,lpc3220-timer"; reg = <0x4004C000 0x1000>; - interrupts = <0x11 0>; + interrupts = <17 IRQ_TYPE_LEVEL_LOW>; + clocks = <&clk LPC32XX_CLK_TIMER1>; + clock-names = "timerclk"; }; key: key@40050000 { compatible = "nxp,lpc3220-key"; reg = <0x40050000 0x1000>; - interrupts = <54 0>; + interrupts = <54 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; }; timer2: timer@40058000 { compatible = "nxp,lpc3220-timer"; reg = <0x40058000 0x1000>; - interrupts = <0x12 0>; + interrupts = <18 IRQ_TYPE_LEVEL_LOW>; + clocks = <&clk LPC32XX_CLK_TIMER2>; + clock-names = "timerclk"; status = "disabled"; }; pwm1: pwm@4005C000 { compatible = "nxp,lpc3220-pwm"; reg = <0x4005C000 0x4>; + clocks = <&clk LPC32XX_CLK_PWM1>; status = "disabled"; }; pwm2: pwm@4005C004 { compatible = "nxp,lpc3220-pwm"; reg = <0x4005C004 0x4>; + clocks = <&clk LPC32XX_CLK_PWM2>; status = "disabled"; }; timer3: timer@40060000 { compatible = "nxp,lpc3220-timer"; reg = <0x40060000 0x1000>; - interrupts = <0x13 0>; + interrupts = <19 IRQ_TYPE_LEVEL_LOW>; + clocks = <&clk LPC32XX_CLK_TIMER3>; + clock-names = "timerclk"; status = "disabled"; }; }; diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi index 2c84ca236473a10d8381666ef921a29a3ab395e0..726372d3adc02ec13fac9f4345ac298f479b0419 100644 --- a/arch/arm/boot/dts/ls1021a.dtsi +++ b/arch/arm/boot/dts/ls1021a.dtsi @@ -457,6 +457,18 @@ reg = <0x0 0x2d24000 0x0 0x4000>; }; + ptp_clock@2d10e00 { + compatible = "fsl,etsec-ptp"; + reg = <0x0 0x2d10e00 0x0 0xb0>; + interrupts = ; + fsl,tclk-period = <5>; + fsl,tmr-prsc = <2>; + fsl,tmr-add = <0xaaaaaaab>; + fsl,tmr-fiper1 = <999999990>; + fsl,tmr-fiper2 = <99990>; + fsl,max-adj = <499999999>; + }; + enet0: ethernet@2d10000 { compatible = "fsl,etsec2"; device_type = "network"; @@ -560,5 +572,49 @@ dr_mode = "host"; snps,quirk-frame-length-adjustment = <0x20>; }; + + pcie@3400000 { + compatible = "fsl,ls1021a-pcie", "snps,dw-pcie"; + reg = <0x00 0x03400000 0x0 0x00010000 /* controller registers */ + 0x40 0x00000000 0x0 0x00002000>; /* configuration space */ + reg-names = "regs", "config"; + interrupts = ; /* controller interrupt */ + fsl,pcie-scfg = <&scfg 0>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + num-lanes = <4>; + bus-range = <0x0 0xff>; + ranges = <0x81000000 0x0 0x00000000 0x40 0x00010000 0x0 0x00010000 /* downstream I/O */ + 0x82000000 0x0 0x40000000 0x40 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0000 0 0 1 &gic GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 2 &gic GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 3 &gic GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 4 &gic GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>; + }; + + pcie@3500000 { + compatible = "fsl,ls1021a-pcie", "snps,dw-pcie"; + reg = <0x00 0x03500000 0x0 0x00010000 /* controller registers */ + 0x48 0x00000000 0x0 0x00002000>; /* configuration space */ + reg-names = "regs", "config"; + interrupts = ; + fsl,pcie-scfg = <&scfg 1>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + num-lanes = <4>; + bus-range = <0x0 0xff>; + ranges = <0x81000000 0x0 0x00000000 0x48 0x00010000 0x0 0x00010000 /* downstream I/O */ + 0x82000000 0x0 0x40000000 0x48 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */ + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0000 0 0 1 &gic GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 2 &gic GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 3 &gic GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>, + <0000 0 0 4 &gic GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>; + }; }; }; diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi index 3766904b60f38330c622aa8436a1901af838b8d8..83437683aa60a011d7374980f529bb2d164fc11f 100644 --- a/arch/arm/boot/dts/mt2701.dtsi +++ b/arch/arm/boot/dts/mt2701.dtsi @@ -23,6 +23,7 @@ cpus { #address-cells = <1>; #size-cells = <0>; + enable-method = "mediatek,mt81xx-tz-smp"; cpu@0 { device_type = "cpu"; @@ -46,6 +47,17 @@ }; }; + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + trustzone-bootinfo@80002000 { + compatible = "mediatek,trustzone-bootinfo"; + reg = <0 0x80002000 0 0x1000>; + }; + }; + system_clk: dummy13m { compatible = "fixed-clock"; clock-frequency = <13000000>; diff --git a/arch/arm/boot/dts/mt7623-evb.dts b/arch/arm/boot/dts/mt7623-evb.dts new file mode 100644 index 0000000000000000000000000000000000000000..a9ee2d64c6f748119ffba6d6c6993cb7164f4604 --- /dev/null +++ b/arch/arm/boot/dts/mt7623-evb.dts @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2016 MediaTek Inc. + * Author: John Crispin + * + * 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. + */ + +/dts-v1/; +#include "mt7623.dtsi" + +/ { + model = "MediaTek MT7623 evaluation board"; + compatible = "mediatek,mt7623-evb", "mediatek,mt7623"; + + chosen { + stdout-path = &uart2; + }; + + memory { + reg = <0 0x80000000 0 0x40000000>; + }; +}; + +&uart2 { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..fd2b614ae6f3d034d23f2e3c54d7a00c108ed011 --- /dev/null +++ b/arch/arm/boot/dts/mt7623.dtsi @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2016 MediaTek Inc. + * Author: John Crispin + * + * 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. + */ + +#include +#include +#include "skeleton64.dtsi" + +/ { + compatible = "mediatek,mt7623"; + interrupt-parent = <&sysirq>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + enable-method = "mediatek,mt6589-smp"; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x0>; + }; + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x1>; + }; + cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x2>; + }; + cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0x3>; + }; + }; + + system_clk: dummy13m { + compatible = "fixed-clock"; + clock-frequency = <13000000>; + #clock-cells = <0>; + }; + + rtc_clk: dummy32k { + compatible = "fixed-clock"; + clock-frequency = <32000>; + #clock-cells = <0>; + }; + + uart_clk: dummy26m { + compatible = "fixed-clock"; + clock-frequency = <26000000>; + #clock-cells = <0>; + }; + + timer { + compatible = "arm,armv7-timer"; + interrupt-parent = <&gic>; + interrupts = , + , + , + ; + }; + + watchdog: watchdog@10007000 { + compatible = "mediatek,mt7623-wdt", + "mediatek,mt6589-wdt"; + reg = <0 0x10007000 0 0x100>; + }; + + timer: timer@10008000 { + compatible = "mediatek,mt7623-timer", + "mediatek,mt6577-timer"; + reg = <0 0x10008000 0 0x80>; + interrupts = ; + clocks = <&system_clk>, <&rtc_clk>; + clock-names = "system-clk", "rtc-clk"; + }; + + sysirq: interrupt-controller@10200100 { + compatible = "mediatek,mt7623-sysirq", + "mediatek,mt6577-sysirq"; + interrupt-controller; + #interrupt-cells = <3>; + interrupt-parent = <&gic>; + reg = <0 0x10200100 0 0x1c>; + }; + + gic: interrupt-controller@10211000 { + compatible = "arm,cortex-a7-gic"; + interrupt-controller; + #interrupt-cells = <3>; + interrupt-parent = <&gic>; + reg = <0 0x10211000 0 0x1000>, + <0 0x10212000 0 0x1000>, + <0 0x10214000 0 0x2000>, + <0 0x10216000 0 0x2000>; + }; + + uart0: serial@11002000 { + compatible = "mediatek,mt7623-uart", + "mediatek,mt6577-uart"; + reg = <0 0x11002000 0 0x400>; + interrupts = ; + clocks = <&uart_clk>; + status = "disabled"; + }; + + uart1: serial@11003000 { + compatible = "mediatek,mt7623-uart", + "mediatek,mt6577-uart"; + reg = <0 0x11003000 0 0x400>; + interrupts = ; + clocks = <&uart_clk>; + status = "disabled"; + }; + + uart2: serial@11004000 { + compatible = "mediatek,mt7623-uart", + "mediatek,mt6577-uart"; + reg = <0 0x11004000 0 0x400>; + interrupts = ; + clocks = <&uart_clk>; + status = "disabled"; + }; + + uart3: serial@11005000 { + compatible = "mediatek,mt7623-uart", + "mediatek,mt6577-uart"; + reg = <0 0x11005000 0 0x400>; + interrupts = ; + clocks = <&uart_clk>; + status = "disabled"; + }; +}; diff --git a/arch/arm/boot/dts/mvebu-linkstation-fan.dtsi b/arch/arm/boot/dts/mvebu-linkstation-fan.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..e211a3c47a76cd378b80b7f0c20e09dff980f629 --- /dev/null +++ b/arch/arm/boot/dts/mvebu-linkstation-fan.dtsi @@ -0,0 +1,72 @@ +/* + * Device Tree common file for gpio-fan on Buffalo Linkstation + * + * Copyright (C) 2015, 2016 + * Roger Shimizu + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/ { + gpio_fan { + compatible = "gpio-fan"; + pinctrl-0 = <&pmx_fan_low &pmx_fan_high &pmx_fan_lock>; + pinctrl-names = "default"; + + gpio-fan,speed-map = + <0 3 + 1500 2 + 3250 1 + 5000 0>; + }; +}; + +&pinctrl { + pmx_fan_low: pmx-fan-low { + marvell,function = "gpio"; + }; + + pmx_fan_high: pmx-fan-high { + marvell,function = "gpio"; + }; + + pmx_fan_lock: pmx-fan-lock { + marvell,function = "gpio"; + }; +}; diff --git a/arch/arm/boot/dts/mvebu-linkstation-gpio-simple.dtsi b/arch/arm/boot/dts/mvebu-linkstation-gpio-simple.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..68d75e79a360b219258c034ea7f028651de4d1f2 --- /dev/null +++ b/arch/arm/boot/dts/mvebu-linkstation-gpio-simple.dtsi @@ -0,0 +1,105 @@ +/* + * Device Tree common file for gpio-{keys,leds} on Buffalo Linkstation + * + * Copyright (C) 2015, 2016 + * Roger Shimizu + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include + +/ { + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-0 = <&pmx_power_switch>; + pinctrl-names = "default"; + + power-on-switch { + label = "Power-on Switch"; + linux,code = ; + linux,input-type = <5>; + }; + + power-auto-switch { + label = "Power-auto Switch"; + linux,code = ; + linux,input-type = <5>; + }; + }; + + gpio_leds { + compatible = "gpio-leds"; + pinctrl-0 = <&pmx_led_power &pmx_led_alarm &pmx_led_info>; + pinctrl-names = "default"; + + blue-power-led { + label = "linkstation:blue:power"; + default-state = "keep"; + }; + + red-alarm-led { + label = "linkstation:red:alarm"; + }; + + amber-info-led { + label = "linkstation:amber:info"; + }; + }; +}; + +&pinctrl { + pmx_power_switch: pmx-power-switch { + marvell,function = "gpio"; + }; + + pmx_led_power: pmx-leds { + marvell,function = "gpio"; + }; + + pmx_led_alarm: pmx-leds { + marvell,function = "gpio"; + }; + + pmx_led_info: pmx-leds { + marvell,function = "gpio"; + }; +}; diff --git a/arch/arm/boot/dts/omap3-beagle.dts b/arch/arm/boot/dts/omap3-beagle.dts index 8ba465d57635fb90c1e7872000ae9b93064e29a1..4602866792be3bcfbb8d9a076439276f87217af2 100644 --- a/arch/arm/boot/dts/omap3-beagle.dts +++ b/arch/arm/boot/dts/omap3-beagle.dts @@ -384,8 +384,11 @@ /* Chip select 0 */ nand@0,0 { + compatible = "ti,omap2-nand"; reg = <0 0 4>; /* NAND I/O window, 4 bytes */ - interrupts = <20>; + interrupt-parent = <&gpmc>; + interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ + <1 IRQ_TYPE_NONE>; /* termcount */ ti,nand-ecc-opt = "ham1"; nand-bus-width = <16>; #address-cells = <1>; diff --git a/arch/arm/boot/dts/omap3-cm-t3x.dtsi b/arch/arm/boot/dts/omap3-cm-t3x.dtsi index e5f7f5c92c1a9ea23068a2f2ba370780fa1d6cbd..a8127bc31fd92dbc3d91ccc9bb0f8d33d79b9677 100644 --- a/arch/arm/boot/dts/omap3-cm-t3x.dtsi +++ b/arch/arm/boot/dts/omap3-cm-t3x.dtsi @@ -261,10 +261,14 @@ }; &gpmc { - ranges = <0 0 0x00000000 0x01000000>; + ranges = <0 0 0x30000000 0x01000000>; /* CS0: 16MB for NAND */ nand@0,0 { + compatible = "ti,omap2-nand"; reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ + interrupt-parent = <&gpmc>; + interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ + <1 IRQ_TYPE_NONE>; /* termcount */ nand-bus-width = <8>; gpmc,device-width = <1>; ti,nand-ecc-opt = "sw"; diff --git a/arch/arm/boot/dts/omap3-devkit8000-common.dtsi b/arch/arm/boot/dts/omap3-devkit8000-common.dtsi index 86850bb311ebbe491ccf523c60686928882b2374..b1b8ebf90c1cc688acebe241ae68769e743a5ccc 100644 --- a/arch/arm/boot/dts/omap3-devkit8000-common.dtsi +++ b/arch/arm/boot/dts/omap3-devkit8000-common.dtsi @@ -204,7 +204,11 @@ ranges = <0 0 0x30000000 0x1000000>; /* CS0: 16MB for NAND */ nand@0,0 { + compatible = "ti,omap2-nand"; reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ + interrupt-parent = <&gpmc>; + interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ + <1 IRQ_TYPE_NONE>; /* termcount */ nand-bus-width = <16>; gpmc,device-width = <2>; ti,nand-ecc-opt = "sw"; diff --git a/arch/arm/boot/dts/omap3-evm-37xx.dts b/arch/arm/boot/dts/omap3-evm-37xx.dts index ac188657a95d150ee1ba61274d6d989d80e02079..76056ba92cedc038933a4367a55ba68af9786d4b 100644 --- a/arch/arm/boot/dts/omap3-evm-37xx.dts +++ b/arch/arm/boot/dts/omap3-evm-37xx.dts @@ -154,12 +154,16 @@ }; &gpmc { - ranges = <0 0 0x00000000 0x1000000>, /* CS0: 16MB for NAND */ + ranges = <0 0 0x30000000 0x1000000>, /* CS0: 16MB for NAND */ <5 0 0x2c000000 0x01000000>; nand@0,0 { + compatible = "ti,omap2-nand"; + reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ + interrupt-parent = <&gpmc>; + interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ + <1 IRQ_TYPE_NONE>; /* termcount */ linux,mtd-name= "hynix,h8kds0un0mer-4em"; - reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ nand-bus-width = <16>; gpmc,device-width = <2>; ti,nand-ecc-opt = "bch8"; diff --git a/arch/arm/boot/dts/omap3-gta04.dtsi b/arch/arm/boot/dts/omap3-gta04.dtsi index 5e2d6433d9394b8464b25df9d7fa189ced97e708..ab9fb8f49ff387ea4d19707e089994a5752228d0 100644 --- a/arch/arm/boot/dts/omap3-gta04.dtsi +++ b/arch/arm/boot/dts/omap3-gta04.dtsi @@ -492,7 +492,11 @@ ranges = <0 0 0x30000000 0x1000000>; /* CS0: 16MB for NAND */ nand@0,0 { + compatible = "ti,omap2-nand"; reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ + interrupt-parent = <&gpmc>; + interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ + <1 IRQ_TYPE_NONE>; /* termcount */ nand-bus-width = <16>; ti,nand-ecc-opt = "bch8"; diff --git a/arch/arm/boot/dts/omap3-igep.dtsi b/arch/arm/boot/dts/omap3-igep.dtsi index 3caf062f882c69fd3d62edcf14b85c32359b8726..41f5d386f21f31c1ac02cc091d9e318097a3e211 100644 --- a/arch/arm/boot/dts/omap3-igep.dtsi +++ b/arch/arm/boot/dts/omap3-igep.dtsi @@ -18,6 +18,10 @@ reg = <0x80000000 0x20000000>; /* 512 MB */ }; + chosen { + stdout-path = &uart3; + }; + sound { compatible = "ti,omap-twl4030"; ti,model = "igep2"; @@ -95,8 +99,12 @@ &gpmc { nand@0,0 { + compatible = "ti,omap2-nand"; + reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ + interrupt-parent = <&gpmc>; + interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ + <1 IRQ_TYPE_NONE>; /* termcount */ linux,mtd-name= "micron,mt29c4g96maz"; - reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ nand-bus-width = <16>; gpmc,device-width = <2>; ti,nand-ecc-opt = "bch8"; diff --git a/arch/arm/boot/dts/omap3-igep0020-common.dtsi b/arch/arm/boot/dts/omap3-igep0020-common.dtsi index d90f12c39307a14ba5a346ebe3b535bee9a455c7..d6f839cab6499acc72cd5b93733aa967defe9d09 100644 --- a/arch/arm/boot/dts/omap3-igep0020-common.dtsi +++ b/arch/arm/boot/dts/omap3-igep0020-common.dtsi @@ -210,8 +210,8 @@ }; &gpmc { - ranges = <0 0 0x00000000 0x20000000>, - <5 0 0x2c000000 0x01000000>; + ranges = <0 0 0x30000000 0x01000000>, /* CS0: 16MB for NAND */ + <5 0 0x2c000000 0x01000000>; /* CS5: 16MB for ethernet */ ethernet@gpmc { pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/omap3-igep0030-common.dtsi b/arch/arm/boot/dts/omap3-igep0030-common.dtsi index 640f0660396697997a877358c725b46e098116dc..e94d9427450cafa9457be8f5b50d8bfa9a07d8b5 100644 --- a/arch/arm/boot/dts/omap3-igep0030-common.dtsi +++ b/arch/arm/boot/dts/omap3-igep0030-common.dtsi @@ -33,9 +33,28 @@ default-state = "off"; }; }; + + hsusb2_phy: hsusb2_phy { + compatible = "usb-nop-xceiv"; + reset-gpios = <&gpio2 22 GPIO_ACTIVE_LOW>; /* gpio_54 */ + }; }; &omap3_pmx_core { + pinctrl-names = "default"; + pinctrl-0 = <&hsusb2_pins>; + + hsusb2_pins: pinmux_hsusb2_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x21d4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi1_cs3.hsusb2_data2 */ + OMAP3_CORE1_IOPAD(0x21d6, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_clk.hsusb2_data7 */ + OMAP3_CORE1_IOPAD(0x21d8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_simo.hsusb2_data4 */ + OMAP3_CORE1_IOPAD(0x21da, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_somi.hsusb2_data5 */ + OMAP3_CORE1_IOPAD(0x21dc, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs0.hsusb2_data6 */ + OMAP3_CORE1_IOPAD(0x21de, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs1.hsusb2_data3 */ + >; + }; + uart2_pins: pinmux_uart2_pins { pinctrl-single,pins = < OMAP3_CORE1_IOPAD(0x216c, PIN_INPUT | MUX_MODE1) /* mcbsp3_dx.uart2_cts */ @@ -47,6 +66,20 @@ }; &omap3_pmx_core2 { + pinctrl-names = "default"; + pinctrl-0 = <&hsusb2_core2_pins>; + + hsusb2_core2_pins: pinmux_hsusb2_core2_pins { + pinctrl-single,pins = < + OMAP3630_CORE2_IOPAD(0x25f0, PIN_OUTPUT | MUX_MODE3) /* etk_d10.hsusb2_clk */ + OMAP3630_CORE2_IOPAD(0x25f2, PIN_OUTPUT | MUX_MODE3) /* etk_d11.hsusb2_stp */ + OMAP3630_CORE2_IOPAD(0x25f4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d12.hsusb2_dir */ + OMAP3630_CORE2_IOPAD(0x25f6, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d13.hsusb2_nxt */ + OMAP3630_CORE2_IOPAD(0x25f8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d14.hsusb2_data0 */ + OMAP3630_CORE2_IOPAD(0x25fa, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d15.hsusb2_data1 */ + >; + }; + leds_core2_pins: pinmux_leds_core2_pins { pinctrl-single,pins = < OMAP3630_CORE2_IOPAD(0x25e0, PIN_OUTPUT | MUX_MODE4) /* etk_d2.gpio_16 */ @@ -54,7 +87,19 @@ }; }; +&usbhshost { + port2-mode = "ehci-phy"; +}; + +&usbhsehci { + phys = <0 &hsusb2_phy>; +}; + &uart2 { pinctrl-names = "default"; pinctrl-0 = <&uart2_pins>; }; + +&gpmc { + ranges = <0 0 0x30000000 0x01000000>; /* CS0: 16MB for NAND */ +}; diff --git a/arch/arm/boot/dts/omap3-ldp.dts b/arch/arm/boot/dts/omap3-ldp.dts index 540163025dd3ede47afa448e83c67f81b427dae8..2f353dadfa4004ccbc0c0b4bde351f86bf9c97fe 100644 --- a/arch/arm/boot/dts/omap3-ldp.dts +++ b/arch/arm/boot/dts/omap3-ldp.dts @@ -97,12 +97,16 @@ }; &gpmc { - ranges = <0 0 0x00000000 0x01000000>, - <1 0 0x08000000 0x01000000>; + ranges = <0 0 0x30000000 0x1000000>, /* CS0 space, 16MB */ + <1 0 0x08000000 0x1000000>; /* CS1 space, 16MB */ nand@0,0 { + compatible = "ti,omap2-nand"; + reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ + interrupt-parent = <&gpmc>; + interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ + <1 IRQ_TYPE_NONE>; /* termcount */ linux,mtd-name= "micron,nand"; - reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ nand-bus-width = <16>; gpmc,device-width = <2>; ti,nand-ecc-opt = "bch8"; diff --git a/arch/arm/boot/dts/omap3-lilly-a83x.dtsi b/arch/arm/boot/dts/omap3-lilly-a83x.dtsi index 93f8dfe20f1321c97a69e2b971275c682f631ae1..eff816e0bc0a4a8151855936072720fb7db93c9f 100644 --- a/arch/arm/boot/dts/omap3-lilly-a83x.dtsi +++ b/arch/arm/boot/dts/omap3-lilly-a83x.dtsi @@ -362,7 +362,11 @@ <7 0 0x15000000 0x01000000>; nand@0,0 { - reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ + compatible = "ti,omap2-nand"; + reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ + interrupt-parent = <&gpmc>; + interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ + <1 IRQ_TYPE_NONE>; /* termcount */ nand-bus-width = <16>; ti,nand-ecc-opt = "bch8"; /* no elm on omap3 */ diff --git a/arch/arm/boot/dts/omap3-n9.dts b/arch/arm/boot/dts/omap3-n9.dts index f2e213931e09a21ed24f7e50b28a74d50eeca735..5c67429a4da7577c46d678acabcc5d66ccac861c 100644 --- a/arch/arm/boot/dts/omap3-n9.dts +++ b/arch/arm/boot/dts/omap3-n9.dts @@ -53,3 +53,7 @@ }; }; }; + +&modem { + compatible = "nokia,n9-modem"; +}; diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts index e3bdcf819643eededad95cb6bdd76b97563d187c..b3c26a96a7262bdc2356060f900cc9b0c8bbd8eb 100644 --- a/arch/arm/boot/dts/omap3-n900.dts +++ b/arch/arm/boot/dts/omap3-n900.dts @@ -65,45 +65,46 @@ camera_lens_cover { label = "Camera Lens Cover"; gpios = <&gpio4 14 GPIO_ACTIVE_LOW>; /* 110 */ - linux,input-type = <5>; /* EV_SW */ - linux,code = <0x09>; /* SW_CAMERA_LENS_COVER */ - wakeup-source; + linux,input-type = ; + linux,code = ; + linux,can-disable; }; camera_focus { label = "Camera Focus"; gpios = <&gpio3 4 GPIO_ACTIVE_LOW>; /* 68 */ - linux,code = <0x210>; /* KEY_CAMERA_FOCUS */ - wakeup-source; + linux,code = ; + linux,can-disable; }; camera_capture { label = "Camera Capture"; gpios = <&gpio3 5 GPIO_ACTIVE_LOW>; /* 69 */ - linux,code = <0xd4>; /* KEY_CAMERA */ - wakeup-source; + linux,code = ; + linux,can-disable; }; lock_button { label = "Lock Button"; gpios = <&gpio4 17 GPIO_ACTIVE_LOW>; /* 113 */ - linux,code = <0x98>; /* KEY_SCREENLOCK */ - wakeup-source; + linux,code = ; + linux,can-disable; }; keypad_slide { label = "Keypad Slide"; gpios = <&gpio3 7 GPIO_ACTIVE_LOW>; /* 71 */ - linux,input-type = <5>; /* EV_SW */ - linux,code = <0x0a>; /* SW_KEYPAD_SLIDE */ - wakeup-source; + linux,input-type = ; + linux,code = ; + linux,can-disable; }; proximity_sensor { label = "Proximity Sensor"; gpios = <&gpio3 25 GPIO_ACTIVE_HIGH>; /* 89 */ - linux,input-type = <5>; /* EV_SW */ - linux,code = <0x0b>; /* SW_FRONT_PROXIMITY */ + linux,input-type = ; + linux,code = ; + linux,can-disable; }; }; @@ -522,6 +523,21 @@ amstaos,cover-comp-gain = <16>; }; + adp1653: led-controller@30 { + compatible = "adi,adp1653"; + reg = <0x30>; + enable-gpios = <&gpio3 24 GPIO_ACTIVE_HIGH>; /* 88 */ + + flash { + flash-timeout-us = <500000>; + flash-max-microamp = <320000>; + led-max-microamp = <50000>; + }; + indicator { + led-max-microamp = <17500>; + }; + }; + lp5523: lp5523@32 { compatible = "national,lp5523"; reg = <0x32>; diff --git a/arch/arm/boot/dts/omap3-n950-n9.dtsi b/arch/arm/boot/dts/omap3-n950-n9.dtsi index a2c2b8d8dd2c70a2ab5a8007b0cc2e24faeaafd0..858a25048102de016793d30a229aba0ae55dd5ff 100644 --- a/arch/arm/boot/dts/omap3-n950-n9.dtsi +++ b/arch/arm/boot/dts/omap3-n950-n9.dtsi @@ -31,6 +31,14 @@ startup-delay-us = <150>; enable-active-high; }; + + vwlan_fixed: fixedregulator@2 { + compatible = "regulator-fixed"; + regulator-name = "VWLAN"; + gpio = <&gpio2 3 GPIO_ACTIVE_HIGH>; /* gpio 35 */ + enable-active-high; + regulator-boot-off; + }; }; &omap3_pmx_core { @@ -44,6 +52,55 @@ OMAP3_CORE1_IOPAD(0x2162, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat3 */ >; }; + + wlan_pins: pinmux_wlan_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x207c, PIN_OUTPUT | MUX_MODE4) /* gpio 35 - wlan enable */ + OMAP3_CORE1_IOPAD(0x208a, PIN_INPUT | MUX_MODE4) /* gpio 42 - wlan irq */ + >; + }; + + ssi_pins: pinmux_ssi_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x217c, PIN_OUTPUT | MUX_MODE1) /* ssi1_dat_tx */ + OMAP3_CORE1_IOPAD(0x217e, PIN_OUTPUT | MUX_MODE1) /* ssi1_flag_tx */ + OMAP3_CORE1_IOPAD(0x2180, PIN_INPUT_PULLUP | MUX_MODE1) /* ssi1_rdy_tx */ + OMAP3_CORE1_IOPAD(0x2182, PIN_INPUT | WAKEUP_EN | MUX_MODE4) /* ssi1_wake_tx (cawake) */ + OMAP3_CORE1_IOPAD(0x2184, PIN_INPUT | MUX_MODE1) /* ssi1_dat_rx */ + OMAP3_CORE1_IOPAD(0x2186, PIN_INPUT | MUX_MODE1) /* ssi1_flag_rx */ + OMAP3_CORE1_IOPAD(0x2188, PIN_OUTPUT | MUX_MODE1) /* ssi1_rdy_rx */ + OMAP3_CORE1_IOPAD(0x218a, PIN_OUTPUT | MUX_MODE1) /* ssi1_wake */ + >; + }; + + ssi_pins_idle: pinmux_ssi_pins_idle { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x217c, PIN_OUTPUT | MUX_MODE7) /* ssi1_dat_tx */ + OMAP3_CORE1_IOPAD(0x217e, PIN_OUTPUT | MUX_MODE7) /* ssi1_flag_tx */ + OMAP3_CORE1_IOPAD(0x2180, PIN_INPUT_PULLDOWN | MUX_MODE7) /* ssi1_rdy_tx */ + OMAP3_CORE1_IOPAD(0x2182, PIN_INPUT | WAKEUP_EN | MUX_MODE4) /* ssi1_wake_tx (cawake) */ + OMAP3_CORE1_IOPAD(0x2184, PIN_INPUT | MUX_MODE7) /* ssi1_dat_rx */ + OMAP3_CORE1_IOPAD(0x2186, PIN_INPUT | MUX_MODE7) /* ssi1_flag_rx */ + OMAP3_CORE1_IOPAD(0x2188, PIN_OUTPUT | MUX_MODE4) /* ssi1_rdy_rx */ + OMAP3_CORE1_IOPAD(0x218a, PIN_OUTPUT | MUX_MODE7) /* ssi1_wake */ + >; + }; + + modem_pins1: pinmux_modem_core1_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x207a, PIN_INPUT | WAKEUP_EN | MUX_MODE4) /* gpio_34 (ape_rst_rq) */ + OMAP3_CORE1_IOPAD(0x2100, PIN_OUTPUT | MUX_MODE4) /* gpio_88 (cmt_rst_rq) */ + OMAP3_CORE1_IOPAD(0x210a, PIN_OUTPUT | MUX_MODE4) /* gpio_93 (cmt_apeslpx) */ + >; + }; +}; + +&omap3_pmx_core2 { + modem_pins2: pinmux_modem_core2_pins { + pinctrl-single,pins = < + OMAP3630_CORE2_IOPAD(0x25ec, PIN_OUTPUT | MUX_MODE4) /* gpio_23 (cmt_en) */ + >; + }; }; &i2c1 { @@ -191,3 +248,39 @@ }; }; }; + +&ssi_port1 { + pinctrl-names = "default", "idle"; + pinctrl-0 = <&ssi_pins>; + pinctrl-1 = <&ssi_pins_idle>; + + ti,ssi-cawake-gpio = <&gpio5 23 GPIO_ACTIVE_HIGH>; /* 151 */ + + modem: hsi-client { + pinctrl-names = "default"; + pinctrl-0 = <&modem_pins1 &modem_pins2>; + + hsi-channel-ids = <0>, <1>, <2>, <3>; + hsi-channel-names = "mcsaab-control", + "speech-control", + "speech-data", + "mcsaab-data"; + hsi-speed-kbps = <96000>; + hsi-mode = "frame"; + hsi-flow = "synchronized"; + hsi-arb-mode = "round-robin"; + + interrupts-extended = <&gpio2 2 IRQ_TYPE_EDGE_RISING>; /* gpio 34 */ + + gpios = <&gpio3 29 GPIO_ACTIVE_HIGH>, /* gpio 93 */ + <&gpio3 24 GPIO_ACTIVE_HIGH>, /* gpio 88 */ + <&gpio1 23 GPIO_ACTIVE_HIGH>; /* gpio 23 */ + gpio-names = "cmt_apeslpx", + "cmt_rst_rq", + "cmt_en"; + }; +}; + +&ssi_port2 { + status = "disabled"; +}; diff --git a/arch/arm/boot/dts/omap3-n950.dts b/arch/arm/boot/dts/omap3-n950.dts index 0885b34d5d7da252953c3aaef287a1e20b9dda63..7f219a9dc5be08f1dba3111d623862b03af887d2 100644 --- a/arch/arm/boot/dts/omap3-n950.dts +++ b/arch/arm/boot/dts/omap3-n950.dts @@ -17,6 +17,17 @@ compatible = "nokia,omap3-n950", "ti,omap36xx", "ti,omap3"; }; +&omap3_pmx_core { + spi4_pins: pinmux_spi4_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x218c, PIN_INPUT_PULLDOWN | MUX_MODE1) /* mcspi4_clk */ + OMAP3_CORE1_IOPAD(0x2190, PIN_OUTPUT | MUX_MODE1) /* mcspi4_simo */ + OMAP3_CORE1_IOPAD(0x2192, PIN_INPUT_PULLDOWN | MUX_MODE1) /* mcspi4_somi */ + OMAP3_CORE1_IOPAD(0x2196, PIN_OUTPUT | MUX_MODE1) /* mcspi4_cs0 */ + >; + }; +}; + &i2c2 { smia_1: camera@10 { compatible = "nokia,smia"; @@ -53,3 +64,25 @@ }; }; }; + +&mcspi4 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&spi4_pins>; + + wlcore: wlcore@0 { + compatible = "ti,wl1271"; + pinctrl-names = "default"; + pinctrl-0 = <&wlan_pins>; + reg = <0>; + spi-max-frequency = <48000000>; + clock-xtal; + ref-clock-frequency = <38400000>; + interrupts-extended = <&gpio2 10 IRQ_TYPE_LEVEL_HIGH>; /* gpio 42 */ + vwlan-supply = <&vwlan_fixed>; + }; +}; + +&modem { + compatible = "nokia,n950-modem"; +}; diff --git a/arch/arm/boot/dts/omap3-overo-base.dtsi b/arch/arm/boot/dts/omap3-overo-base.dtsi index a29ad16cc9bbddec399cef41a00106bc636a14a0..de256fa8da4870bb5325e21603b24a4b3a5583ea 100644 --- a/arch/arm/boot/dts/omap3-overo-base.dtsi +++ b/arch/arm/boot/dts/omap3-overo-base.dtsi @@ -226,8 +226,12 @@ ranges = <0 0 0x00000000 0x20000000>; nand@0,0 { + compatible = "ti,omap2-nand"; linux,mtd-name= "micron,mt29c4g96maz"; - reg = <0 0 0>; + reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ + interrupt-parent = <&gpmc>; + interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ + <1 IRQ_TYPE_NONE>; /* termcount */ nand-bus-width = <16>; gpmc,device-width = <2>; ti,nand-ecc-opt = "bch8"; diff --git a/arch/arm/boot/dts/omap3-pandora-common.dtsi b/arch/arm/boot/dts/omap3-pandora-common.dtsi index 13e9d1f987afea7ecfca699bd7bf40cf701a9327..bcf39d606b65a2c616c3db07217783b4b7977120 100644 --- a/arch/arm/boot/dts/omap3-pandora-common.dtsi +++ b/arch/arm/boot/dts/omap3-pandora-common.dtsi @@ -546,7 +546,11 @@ ranges = <0 0 0x30000000 0x1000000>; /* CS0: 16MB for NAND */ nand@0,0 { + compatible = "ti,omap2-nand"; reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ + interrupt-parent = <&gpmc>; + interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ + <1 IRQ_TYPE_NONE>; /* termcount */ nand-bus-width = <16>; ti,nand-ecc-opt = "sw"; diff --git a/arch/arm/boot/dts/omap3-sniper.dts b/arch/arm/boot/dts/omap3-sniper.dts new file mode 100644 index 0000000000000000000000000000000000000000..78a1184cb312ad5b9dc01645b5bd9117037d2c3c --- /dev/null +++ b/arch/arm/boot/dts/omap3-sniper.dts @@ -0,0 +1,254 @@ +/* + * Copyright (C) 2015-2016 Paul Kocialkowski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +/dts-v1/; + +#include "omap36xx.dtsi" +#include + +/ { + model = "LG Optimus Black"; + compatible = "lg,omap3-sniper", "ti,omap36xx", "ti,omap3"; + + cpus { + cpu@0 { + cpu0-supply = <&vcc>; + }; + }; + + memory { + device_type = "memory"; + reg = <0x80000000 0x20000000>; /* 512 MB */ + }; +}; + +&omap3_pmx_core { + pinctrl-names = "default"; + + uart3_pins: pinmux_uart3_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x219e, PIN_INPUT | MUX_MODE0) /* uart3_rx_irrx */ + OMAP3_CORE1_IOPAD(0x21a0, PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx */ + >; + }; + + dp3t_sel_pins: pinmux_dp3t_sel_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x2196, PIN_OUTPUT | MUX_MODE4) /* gpio_161 */ + OMAP3_CORE1_IOPAD(0x2198, PIN_OUTPUT | MUX_MODE4) /* gpio_162 */ + >; + }; + + i2c1_pins: pinmux_i2c1_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x21ba, PIN_INPUT | MUX_MODE0) /* i2c1_scl */ + OMAP3_CORE1_IOPAD(0x21bc, PIN_INPUT | MUX_MODE0) /* i2c1_sda */ + >; + }; + + i2c2_pins: pinmux_i2c2_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x21be, PIN_INPUT | MUX_MODE0) /* i2c2_scl */ + OMAP3_CORE1_IOPAD(0x21c0, PIN_INPUT | MUX_MODE0) /* i2c2_sda */ + >; + }; + + i2c3_pins: pinmux_i2c3_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x21c2, PIN_INPUT | MUX_MODE0) /* i2c3_scl */ + OMAP3_CORE1_IOPAD(0x21c4, PIN_INPUT | MUX_MODE0) /* i2c3_sda */ + >; + }; + + lp8720_en_pin: pinmux_lp8720_en_pin { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x2080, PIN_OUTPUT | MUX_MODE4) /* gpio_37 */ + >; + }; + + mmc1_pins: pinmux_mmc1_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x2144, PIN_INPUT | MUX_MODE0) /* sdmmc1_clk */ + OMAP3_CORE1_IOPAD(0x2146, PIN_INPUT | MUX_MODE0) /* sdmmc1_cmd */ + OMAP3_CORE1_IOPAD(0x2148, PIN_INPUT | MUX_MODE0) /* sdmmc1_dat0 */ + OMAP3_CORE1_IOPAD(0x214a, PIN_INPUT | MUX_MODE0) /* sdmmc1_dat1 */ + OMAP3_CORE1_IOPAD(0x214c, PIN_INPUT | MUX_MODE0) /* sdmmc1_dat2 */ + OMAP3_CORE1_IOPAD(0x214e, PIN_INPUT | MUX_MODE0) /* sdmmc1_dat3 */ + >; + }; + + mmc2_pins: pinmux_mmc2_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x2158, PIN_INPUT | MUX_MODE0) /* sdmmc2_clk */ + OMAP3_CORE1_IOPAD(0x215a, PIN_INPUT | MUX_MODE0) /* sdmmc2_cmd */ + OMAP3_CORE1_IOPAD(0x215c, PIN_INPUT | MUX_MODE0) /* sdmmc2_dat0 */ + OMAP3_CORE1_IOPAD(0x215e, PIN_INPUT | MUX_MODE0) /* sdmmc2_dat1 */ + OMAP3_CORE1_IOPAD(0x2160, PIN_INPUT | MUX_MODE0) /* sdmmc2_dat2 */ + OMAP3_CORE1_IOPAD(0x2162, PIN_INPUT | MUX_MODE0) /* sdmmc2_dat3 */ + OMAP3_CORE1_IOPAD(0x2164, PIN_INPUT | MUX_MODE0) /* sdmmc2_dat4 */ + OMAP3_CORE1_IOPAD(0x2166, PIN_INPUT | MUX_MODE0) /* sdmmc2_dat5 */ + OMAP3_CORE1_IOPAD(0x2168, PIN_INPUT | MUX_MODE0) /* sdmmc2_dat6 */ + OMAP3_CORE1_IOPAD(0x216a, PIN_INPUT | MUX_MODE0) /* sdmmc2_dat7 */ + >; + }; + + usb_otg_hs_pins: pinmux_usb_otg_hs_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x21a2, PIN_INPUT | MUX_MODE0) /* hsusb0_clk */ + OMAP3_CORE1_IOPAD(0x21a4, PIN_OUTPUT | MUX_MODE0) /* hsusb0_stp */ + OMAP3_CORE1_IOPAD(0x21a6, PIN_INPUT | MUX_MODE0) /* hsusb0_dir */ + OMAP3_CORE1_IOPAD(0x21a8, PIN_INPUT | MUX_MODE0) /* hsusb0_nxt */ + OMAP3_CORE1_IOPAD(0x21aa, PIN_INPUT | MUX_MODE0) /* hsusb0_data0 */ + OMAP3_CORE1_IOPAD(0x21ac, PIN_INPUT | MUX_MODE0) /* hsusb0_data1 */ + OMAP3_CORE1_IOPAD(0x21ae, PIN_INPUT | MUX_MODE0) /* hsusb0_data2 */ + OMAP3_CORE1_IOPAD(0x21b0, PIN_INPUT | MUX_MODE0) /* hsusb0_data3 */ + OMAP3_CORE1_IOPAD(0x21b2, PIN_INPUT | MUX_MODE0) /* hsusb0_data4 */ + OMAP3_CORE1_IOPAD(0x21b4, PIN_INPUT | MUX_MODE0) /* hsusb0_data5 */ + OMAP3_CORE1_IOPAD(0x21b6, PIN_INPUT | MUX_MODE0) /* hsusb0_data6 */ + OMAP3_CORE1_IOPAD(0x21b8, PIN_INPUT | MUX_MODE0) /* hsusb0_data7 */ + >; + }; +}; + +&omap3_pmx_wkup { + pinctrl-names = "default"; + + mmc1_cd_pin: pinmux_mmc1_cd_pin { + pinctrl-single,pins = < + OMAP3_WKUP_IOPAD(0x2a1a, PIN_INPUT | MUX_MODE4) /* gpio_10 */ + >; + }; +}; + +&gpio2 { + ti,no-reset-on-init; +}; + +&gpio5 { + ti,no-reset-on-init; +}; + +&gpio6 { + ti,no-reset-on-init; +}; + +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&uart3_pins &dp3t_sel_pins>; + + interrupts-extended = <&intc 74 &omap3_pmx_core OMAP3_UART3_RX>; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + + clock-frequency = <2600000>; + + twl: twl@48 { + reg = <0x48>; + interrupts = <7>; /* SYS_NIRQ cascaded to intc */ + interrupt-parent = <&intc>; + + power { + compatible = "ti,twl4030-power"; + ti,use_poweroff; + }; + }; +}; + +&i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins>; + + clock-frequency = <400000>; +}; + +&i2c3 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c3_pins>; + + clock-frequency = <400000>; + + lp8720@7d { + pinctrl-names = "default"; + pinctrl-0 = <&lp8720_en_pin>; + + compatible = "ti,lp8720"; + reg = <0x7d>; + + enable-gpios = <&gpio2 5 GPIO_ACTIVE_HIGH>; /* gpio_37 */ + + lp8720_ldo1: ldo1 { + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + }; + }; +}; + +&mmc1 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins &mmc1_cd_pin>; + + vmmc-supply = <&lp8720_ldo1>; + cd-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>; /* gpio 10 */ + bus-width = <4>; +}; + +&mmc2 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_pins>; + + vmmc-supply = <&vmmc2>; + ti,non-removable; + bus-width = <8>; +}; + +&mmc3 { + status = "disabled"; +}; + +&usb_otg_hs { + pinctrl-names = "default"; + pinctrl-0 = <&usb_otg_hs_pins>; + + interface-type = <0>; + usb-phy = <&usb2_phy>; + phys = <&usb2_phy>; + phy-names = "usb2-phy"; + mode = <3>; + power = <50>; +}; + +#include "twl4030.dtsi" +#include "twl4030_omap3.dtsi" + +&twl_keypad { + linux,keymap = < + MATRIX_KEY(0x00, 0x00, KEY_VOLUMEUP) + MATRIX_KEY(0x01, 0x00, KEY_VOLUMEDOWN) + MATRIX_KEY(0x02, 0x00, KEY_SELECT) + >; +}; + +/* + * The TWL4030 VAUX2 and VDAC regulators power sensors that are slaves on I2C3. + * When not powered, these sensors cause the I2C3 clock to stay low at all times, + * making it impossible to reach other devices on I2C3. + */ + +&vaux2 { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-always-on; +}; + +&vdac { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; +}; diff --git a/arch/arm/boot/dts/omap3-tao3530.dtsi b/arch/arm/boot/dts/omap3-tao3530.dtsi index ae5dbbd9d569269c0e9b3344b77797aee408c144..644d3c8ea66abdce6e7a18b92442e8189b81d426 100644 --- a/arch/arm/boot/dts/omap3-tao3530.dtsi +++ b/arch/arm/boot/dts/omap3-tao3530.dtsi @@ -275,10 +275,14 @@ }; &gpmc { - ranges = <0 0 0x00000000 0x01000000>; + ranges = <0 0 0x30000000 0x01000000>; /* CS0: 16MB for NAND */ nand@0,0 { + compatible = "ti,omap2-nand"; reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ + interrupt-parent = <&gpmc>; + interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ + <1 IRQ_TYPE_NONE>; /* termcount */ nand-bus-width = <16>; gpmc,device-width = <2>; /* GPMC_DEVWIDTH_16BIT */ ti,nand-ecc-opt = "sw"; diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi index d1ffabb7c74fc7dee2de91665ac92aca5c898eeb..b41d07e8e765e22131d616ed2b09d8e6cda7a341 100644 --- a/arch/arm/boot/dts/omap3.dtsi +++ b/arch/arm/boot/dts/omap3.dtsi @@ -723,6 +723,8 @@ gpmc,num-waitpins = <4>; #address-cells = <2>; #size-cells = <1>; + interrupt-controller; + #interrupt-cells = <2>; }; usb_otg_hs: usb_otg_hs@480ab000 { diff --git a/arch/arm/boot/dts/omap3430-sdp.dts b/arch/arm/boot/dts/omap3430-sdp.dts index 16b0cdfbee9cbb0368a2bdf8ddd59534ff16771e..a0dc8d854142d9415f45d8d04b601a8a35ef9de0 100644 --- a/arch/arm/boot/dts/omap3430-sdp.dts +++ b/arch/arm/boot/dts/omap3430-sdp.dts @@ -103,10 +103,14 @@ }; nand@1,0 { + compatible = "ti,omap2-nand"; + reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ + interrupt-parent = <&gpmc>; + interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */ + <1 IRQ_TYPE_NONE>; /* termcount */ linux,mtd-name= "micron,mt29f1g08abb"; #address-cells = <1>; #size-cells = <1>; - reg = <1 0 4>; /* CS1, offset 0, IO size 4 */ ti,nand-ecc-opt = "sw"; nand-bus-width = <8>; gpmc,cs-on-ns = <0>; diff --git a/arch/arm/boot/dts/omap34xx.dtsi b/arch/arm/boot/dts/omap34xx.dtsi index 4f6b2d5b1902e96114f12b1f8bd7d15ba0b9819e..387dc31822fe9c8b2729d28da389d410ffb55fe7 100644 --- a/arch/arm/boot/dts/omap34xx.dtsi +++ b/arch/arm/boot/dts/omap34xx.dtsi @@ -54,6 +54,12 @@ #size-cells = <0>; }; }; + + bandgap { + reg = <0x48002524 0x4>; + compatible = "ti,omap34xx-bandgap"; + #thermal-sensor-cells = <0>; + }; }; }; diff --git a/arch/arm/boot/dts/omap36xx.dtsi b/arch/arm/boot/dts/omap36xx.dtsi index 86253de5a97a99ddb12ea5f41c72f3c59279fced..f19c87bd6bf35b249543495810df3be423b5cd55 100644 --- a/arch/arm/boot/dts/omap36xx.dtsi +++ b/arch/arm/boot/dts/omap36xx.dtsi @@ -86,6 +86,12 @@ #size-cells = <0>; }; }; + + bandgap { + reg = <0x48002524 0x4>; + compatible = "ti,omap36xx-bandgap"; + #thermal-sensor-cells = <0>; + }; }; }; diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi index ca3c17fde5a0fb465965de579234efe9fb052e44..38805ebbe2ba49f5dcd2ee92d80cde1e324cbb56 100644 --- a/arch/arm/boot/dts/omap5.dtsi +++ b/arch/arm/boot/dts/omap5.dtsi @@ -852,18 +852,6 @@ hw-caps-temp-alert; }; - omap_control_usb2phy: control-phy@4a002300 { - compatible = "ti,control-phy-usb2"; - reg = <0x4a002300 0x4>; - reg-names = "power"; - }; - - omap_control_usb3phy: control-phy@4a002370 { - compatible = "ti,control-phy-pipe3"; - reg = <0x4a002370 0x4>; - reg-names = "power"; - }; - usb3: omap_dwc3@4a020000 { compatible = "ti,dwc3"; ti,hwmods = "usb_otg_ss"; @@ -885,7 +873,6 @@ phys = <&usb2_phy>, <&usb3_phy>; phy-names = "usb2-phy", "usb3-phy"; dr_mode = "peripheral"; - tx-fifo-resize; }; }; @@ -899,7 +886,7 @@ usb2_phy: usb2phy@4a084000 { compatible = "ti,omap-usb2"; reg = <0x4a084000 0x7c>; - ctrl-module = <&omap_control_usb2phy>; + syscon-phy-power = <&scm_conf 0x300>; clocks = <&usb_phy_cm_clk32k>, <&usb_otg_ss_refclk960m>; clock-names = "wkupclk", "refclk"; #phy-cells = <0>; @@ -911,7 +898,7 @@ <0x4a084800 0x64>, <0x4a084c00 0x40>; reg-names = "phy_rx", "phy_tx", "pll_ctrl"; - ctrl-module = <&omap_control_usb3phy>; + syscon-phy-power = <&scm_conf 0x370>; clocks = <&usb_phy_cm_clk32k>, <&sys_clkin>, <&usb_otg_ss_refclk960m>; @@ -967,14 +954,6 @@ #thermal-sensor-cells = <1>; }; - omap_control_sata: control-phy@4a002374 { - compatible = "ti,control-phy-pipe3"; - reg = <0x4a002374 0x4>; - reg-names = "power"; - clocks = <&sys_clkin>; - clock-names = "sysclk"; - }; - /* OCP2SCP3 */ ocp2scp@4a090000 { compatible = "ti,omap-ocp2scp"; @@ -989,7 +968,7 @@ <0x4A096400 0x64>, /* phy_tx */ <0x4A096800 0x40>; /* pll_ctrl */ reg-names = "phy_rx", "phy_tx", "pll_ctrl"; - ctrl-module = <&omap_control_sata>; + syscon-phy-power = <&scm_conf 0x374>; clocks = <&sys_clkin>, <&sata_ref_clk>; clock-names = "sysclk", "refclk"; #phy-cells = <0>; diff --git a/arch/arm/boot/dts/orion5x-linkstation-lsgl.dts b/arch/arm/boot/dts/orion5x-linkstation-lsgl.dts new file mode 100644 index 0000000000000000000000000000000000000000..1cf644bfd7ea13afd59f404b4825fefc9b67b2f5 --- /dev/null +++ b/arch/arm/boot/dts/orion5x-linkstation-lsgl.dts @@ -0,0 +1,87 @@ +/* + * Device Tree file for Buffalo Linkstation LS-GL + * (also known as Buffalo Linkstation Pro/Live) + * + * Copyright (C) 2016 + * Roger Shimizu + * + * Based on the board file arch/arm/mach-orion5x/kurobox_pro-setup.c + * Copyright (C) Ronen Shitrit + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include "orion5x-linkstation.dtsi" +#include + +/ { + model = "Buffalo Linkstation Pro/Live"; + compatible = "buffalo,lsgl", "marvell,orion5x-88f5182", "marvell,orion5x"; + + memory { /* 128 MB */ + device_type = "memory"; + reg = <0x00000000 0x8000000>; + }; +}; + +&pinctrl { + pmx_power_hdd: pmx-power-hdd { + marvell,pins = "mpp1"; + marvell,function = "gpio"; + }; + + pmx_power_usb: pmx-power-usb { + marvell,pins = "mpp9"; + marvell,function = "gpio"; + }; +}; + +&hdd_power { + gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; +}; + +&usb_power { + gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>; +}; + +&ehci1 { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts b/arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts index aae8a7aceab75d53f84a2eb94fc0d6e020e773a9..0eead400f42770e46f44250ef1629cdb295a1422 100644 --- a/arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts +++ b/arch/arm/boot/dts/orion5x-linkstation-lswtgl.dts @@ -45,9 +45,10 @@ /dts-v1/; +#include "orion5x-linkstation.dtsi" +#include "mvebu-linkstation-gpio-simple.dtsi" +#include "mvebu-linkstation-fan.dtsi" #include -#include -#include "orion5x-mv88f5182.dtsi" / { model = "Buffalo Linkstation LS-WTGL"; @@ -58,247 +59,93 @@ reg = <0x00000000 0x4000000>; }; - chosen { - bootargs = "console=ttyS0,115200n8 earlyprintk"; - linux,stdout-path = &uart0; - }; - - soc { - ranges = , - , - ; - - internal-regs { - pinctrl: pinctrl@10000 { - pinctrl-names = "default"; - - pmx_led_power: pmx-leds { - marvell,pins = "mpp0"; - marvell,function = "gpio"; - }; - - pmx_led_alarm: pmx-leds { - marvell,pins = "mpp2"; - marvell,function = "gpio"; - }; - - pmx_led_info: pmx-leds { - marvell,pins = "mpp3"; - marvell,function = "gpio"; - }; - - pmx_power_hdd: pmx-power-hdd { - marvell,pins = "mpp1"; - marvell,function = "gpio"; - }; - - pmx_usb_power: pmx-usb-power { - marvell,pins = "mpp9"; - marvell,function = "gpio"; - }; - - pmx_sata0: pmx-sata0 { - marvell,pins = "mpp12"; - marvell,function = "sata0"; - }; - - pmx_sata1: pmx-sata1 { - marvell,pins = "mpp13"; - marvell,function = "sata1"; - }; - - pmx_fan_high: pmx-fan-high { - marvell,pins = "mpp14"; - marvell,function = "gpio"; - }; - - pmx_fan_low: pmx-fan-low { - marvell,pins = "mpp17"; - marvell,function = "gpio"; - }; - - pmx_fan_lock: pmx-fan-lock { - marvell,pins = "mpp6"; - marvell,function = "gpio"; - }; - - pmx_power_switch: pmx-power-switch { - marvell,pins = "mpp8", "mpp10"; - marvell,function = "gpio"; - }; - }; - }; - }; - gpio_keys { - compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; - pinctrl-0 = <&pmx_power_switch>; - pinctrl-names = "default"; - - button@1 { - label = "Power-on Switch"; - linux,code = ; - linux,input-type = <5>; + power-on-switch { gpios = <&gpio0 8 GPIO_ACTIVE_LOW>; }; - button@2 { - label = "Power-auto Switch"; - linux,code = ; - linux,input-type = <5>; + power-auto-switch { gpios = <&gpio0 10 GPIO_ACTIVE_LOW>; }; }; gpio_leds { - compatible = "gpio-leds"; - pinctrl-0 = <&pmx_led_power &pmx_led_alarm - &pmx_led_info>; - pinctrl-names = "default"; - - led@1 { - label = "lswtgl:blue:power"; + blue-power-led { gpios = <&gpio0 0 GPIO_ACTIVE_LOW>; - default-state = "keep"; }; - led@2 { - label = "lswtgl:red:alarm"; + red-alarm-led { gpios = <&gpio0 2 GPIO_ACTIVE_LOW>; }; - led@3 { - label = "lswtgl:amber:info"; + amber-info-led { gpios = <&gpio0 3 GPIO_ACTIVE_LOW>; }; }; gpio_fan { - compatible = "gpio-fan"; - pinctrl-0 = <&pmx_fan_low &pmx_fan_high &pmx_fan_lock>; - pinctrl-names = "default"; - gpios = <&gpio0 14 GPIO_ACTIVE_LOW &gpio0 17 GPIO_ACTIVE_LOW>; - gpio-fan,speed-map = <0 3 - 1500 2 - 3250 1 - 5000 0>; - alarm-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>; }; +}; - restart_poweroff { - compatible = "restart-poweroff"; +&pinctrl { + pmx_led_power: pmx-leds { + marvell,pins = "mpp0"; + marvell,function = "gpio"; }; - regulators { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <0>; - pinctrl-0 = <&pmx_power_hdd &pmx_usb_power>; - pinctrl-names = "default"; - - usb_power: regulator@1 { - compatible = "regulator-fixed"; - reg = <1>; - regulator-name = "USB Power"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - enable-active-high; - regulator-always-on; - regulator-boot-on; - gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>; - }; - - hdd_power: regulator@2 { - compatible = "regulator-fixed"; - reg = <2>; - regulator-name = "HDD Power"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - enable-active-high; - regulator-always-on; - regulator-boot-on; - gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; - }; + pmx_power_hdd: pmx-power-hdd { + marvell,pins = "mpp1"; + marvell,function = "gpio"; }; -}; - -&devbus_bootcs { - status = "okay"; - devbus,keep-config; - flash@0 { - compatible = "jedec-flash"; - reg = <0 0x40000>; - bank-width = <1>; - - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - header@0 { - reg = <0 0x30000>; - read-only; - }; - - uboot@30000 { - reg = <0x30000 0xF000>; - read-only; - }; + pmx_led_alarm: pmx-leds { + marvell,pins = "mpp2"; + marvell,function = "gpio"; + }; - uboot_env@3F000 { - reg = <0x3F000 0x1000>; - }; - }; + pmx_led_info: pmx-leds { + marvell,pins = "mpp3"; + marvell,function = "gpio"; }; -}; -&mdio { - status = "okay"; + pmx_fan_lock: pmx-fan-lock { + marvell,pins = "mpp6"; + marvell,function = "gpio"; + }; - ethphy: ethernet-phy { - reg = <8>; + pmx_power_switch: pmx-power-switch { + marvell,pins = "mpp8", "mpp10"; + marvell,function = "gpio"; }; -}; -ð { - status = "okay"; + pmx_power_usb: pmx-power-usb { + marvell,pins = "mpp9"; + marvell,function = "gpio"; + }; - ethernet-port@0 { - phy-handle = <ðphy>; + pmx_fan_high: pmx-fan-high { + marvell,pins = "mpp14"; + marvell,function = "gpio"; }; -}; -&ehci0 { - status = "okay"; + pmx_fan_low: pmx-fan-low { + marvell,pins = "mpp17"; + marvell,function = "gpio"; + }; }; -&i2c { - status = "okay"; - - rtc { - compatible = "ricoh,rs5c372a"; - reg = <0x32>; - }; +&hdd_power { + gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; }; -&wdt { - status = "disabled"; +&usb_power { + gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>; }; &sata { - pinctrl-0 = <&pmx_sata0 &pmx_sata1>; - pinctrl-names = "default"; - status = "okay"; nr-ports = <2>; }; - -&uart0 { - status = "okay"; -}; diff --git a/arch/arm/boot/dts/orion5x-linkstation.dtsi b/arch/arm/boot/dts/orion5x-linkstation.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..ed456ab35fd84ae4eddd49dd9c2542bbfc5fcc0e --- /dev/null +++ b/arch/arm/boot/dts/orion5x-linkstation.dtsi @@ -0,0 +1,180 @@ +/* + * Device Tree common file for orion5x based Buffalo Linkstation + * + * Copyright (C) 2015, 2016 + * Roger Shimizu + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "orion5x-mv88f5182.dtsi" + +/ { + chosen { + bootargs = "console=ttyS0,115200n8 earlyprintk"; + linux,stdout-path = &uart0; + }; + + soc { + ranges = , + , + ; + }; + + restart_poweroff { + compatible = "restart-poweroff"; + }; + + regulators { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + pinctrl-0 = <&pmx_power_usb &pmx_power_hdd>; + pinctrl-names = "default"; + + usb_power: regulator@1 { + compatible = "regulator-fixed"; + reg = <1>; + regulator-name = "USB Power"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + }; + + hdd_power: regulator@2 { + compatible = "regulator-fixed"; + reg = <2>; + regulator-name = "HDD Power"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + }; + }; +}; + +&pinctrl { + pmx_power_hdd: pmx-power-hdd { + marvell,function = "gpio"; + }; + + pmx_power_usb: pmx-power-usb { + marvell,function = "gpio"; + }; +}; + +&devbus_bootcs { + status = "okay"; + devbus,keep-config; + + flash@0 { + compatible = "jedec-flash"; + reg = <0 0x40000>; + bank-width = <1>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + header@0 { + reg = <0 0x30000>; + read-only; + }; + + uboot@30000 { + reg = <0x30000 0xF000>; + read-only; + }; + + uboot_env@3F000 { + reg = <0x3F000 0x1000>; + }; + }; + }; +}; + +&mdio { + status = "okay"; + + ethphy: ethernet-phy { + reg = <8>; + }; +}; + +ð { + status = "okay"; + + ethernet-port@0 { + phy-handle = <ðphy>; + }; +}; + +&ehci0 { + status = "okay"; +}; + +&i2c { + status = "okay"; + + rtc { + compatible = "ricoh,rs5c372a"; + reg = <0x32>; + }; +}; + +&wdt { + status = "disabled"; +}; + +&sata { + status = "okay"; + nr-ports = <1>; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/phy3250.dts b/arch/arm/boot/dts/phy3250.dts index 7d253bb6265ac13e1e478e2f46270f2df1a63b5b..a00d7ce7802b71c7c4c6d22a73262c39771d0941 100644 --- a/arch/arm/boot/dts/phy3250.dts +++ b/arch/arm/boot/dts/phy3250.dts @@ -25,6 +25,37 @@ reg = <0x80000000 0x4000000>; }; + regulators { + backlight_reg: regulator@0 { + compatible = "regulator-fixed"; + regulator-name = "backlight_reg"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + gpio = <&gpio 5 4 0>; + enable-active-high; + regulator-boot-on; + }; + + lcd_reg: regulator@1 { + compatible = "regulator-fixed"; + regulator-name = "lcd_reg"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + gpio = <&gpio 5 0 0>; + enable-active-high; + regulator-boot-on; + }; + + sd_reg: regulator@2 { + compatible = "regulator-fixed"; + regulator-name = "sd_reg"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + gpio = <&gpio 5 5 0>; + enable-active-high; + }; + }; + ahb { mac: ethernet@31060000 { phy-mode = "rmii"; @@ -140,6 +171,7 @@ cd-gpios = <&gpio 3 1 0>; cd-inverted; bus-width = <4>; + vmmc-supply = <&sd_reg>; status = "okay"; }; }; diff --git a/arch/arm/boot/dts/pxa27x.dtsi b/arch/arm/boot/dts/pxa27x.dtsi index 7f68a1ee7073cb487eae11bbb7edbb3fc861d61e..210192c38df3cb60b7694d330f707767b377cb53 100644 --- a/arch/arm/boot/dts/pxa27x.dtsi +++ b/arch/arm/boot/dts/pxa27x.dtsi @@ -13,6 +13,7 @@ interrupts = <25>; #dma-channels = <32>; #dma-cells = <2>; + #dma-requests = <75>; status = "okay"; }; diff --git a/arch/arm/boot/dts/pxa3xx.dtsi b/arch/arm/boot/dts/pxa3xx.dtsi index cf6998a0804d418be89e476de2645fe293845bab..fec47bcd8292f5625c5e310cdcb3e79bd289fca1 100644 --- a/arch/arm/boot/dts/pxa3xx.dtsi +++ b/arch/arm/boot/dts/pxa3xx.dtsi @@ -12,6 +12,7 @@ interrupts = <25>; #dma-channels = <32>; #dma-cells = <2>; + #dma-requests = <100>; status = "okay"; }; @@ -30,7 +31,7 @@ reg = <0x43100000 90>; interrupts = <45>; clocks = <&clks CLK_NAND>; - dmas = <&pdma 97>; + dmas = <&pdma 97 3>; dma-names = "data"; #address-cells = <1>; #size-cells = <1>; diff --git a/arch/arm/boot/dts/qcom-apq8064-asus-nexus7-flo.dts b/arch/arm/boot/dts/qcom-apq8064-asus-nexus7-flo.dts new file mode 100644 index 0000000000000000000000000000000000000000..c535b3f0e5cfd161032390a93f9f90f7a8d5d034 --- /dev/null +++ b/arch/arm/boot/dts/qcom-apq8064-asus-nexus7-flo.dts @@ -0,0 +1,276 @@ +#include "qcom-apq8064-v2.0.dtsi" +#include +#include +#include +/ { + model = "Asus Nexus7(flo)"; + compatible = "asus,nexus7-flo", "qcom,apq8064"; + + aliases { + serial0 = &gsbi7_serial; + serial1 = &gsbi6_serial; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + ext_3p3v: regulator-fixed@1 { + compatible = "regulator-fixed"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "ext_3p3v"; + regulator-type = "voltage"; + startup-delay-us = <0>; + gpio = <&tlmm_pinmux 77 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-boot-on; + }; + + gpio-keys { + compatible = "gpio-keys"; + power { + label = "Power"; + gpios = <&tlmm_pinmux 26 GPIO_ACTIVE_LOW>; + linux,code = ; + gpio-key,wakeup; + }; + volume_up { + label = "Volume Up"; + gpios = <&pm8921_gpio 4 GPIO_ACTIVE_HIGH>; + linux,code = ; + }; + volume_down { + label = "Volume Down"; + gpios = <&pm8921_gpio 38 GPIO_ACTIVE_HIGH>; + linux,code = ; + }; + }; + + soc { + rpm@108000 { + regulators { + vdd_l1_l2_l12_l18-supply = <&pm8921_s4>; + vin_lvs1_3_6-supply = <&pm8921_s4>; + vin_lvs4_5_7-supply = <&pm8921_s4>; + + + vdd_l24-supply = <&pm8921_s1>; + vdd_l25-supply = <&pm8921_s1>; + vin_lvs2-supply = <&pm8921_s1>; + + vdd_l26-supply = <&pm8921_s7>; + vdd_l27-supply = <&pm8921_s7>; + vdd_l28-supply = <&pm8921_s7>; + + vdd_ncp-supply = <&pm8921_l6>; + + /* Buck SMPS */ + s1 { + regulator-always-on; + regulator-min-microvolt = <1225000>; + regulator-max-microvolt = <1225000>; + qcom,switch-mode-frequency = <3200000>; + bias-pull-down; + }; + + /* msm otg HSUSB_VDDCX */ + s3 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1150000>; + qcom,switch-mode-frequency = <4800000>; + }; + + /* + * msm_sdcc.1-sdc-vdd_io + * tabla2x-slim-CDC_VDDA_RX + * tabla2x-slim-CDC_VDDA_TX + * tabla2x-slim-CDC_VDD_CP + * tabla2x-slim-VDDIO_CDC + */ + s4 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + qcom,switch-mode-frequency = <3200000>; + regulator-always-on; + }; + + s7 { + regulator-min-microvolt = <1300000>; + regulator-max-microvolt = <1300000>; + qcom,switch-mode-frequency = <3200000>; + }; + + /* mipi_dsi.1-dsi1_pll_vdda */ + l2 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + }; + + /* msm_otg-HSUSB_3p3 */ + l3 { + regulator-min-microvolt = <3075000>; + regulator-max-microvolt = <3075000>; + bias-pull-down; + }; + + /* msm_otg-HSUSB_1p8 */ + l4 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + bias-pull-down; + }; + + /* msm_sdcc.1-sdc_vdd */ + l5 { + regulator-min-microvolt = <2950000>; + regulator-max-microvolt = <2950000>; + regulator-always-on; + bias-pull-down; + }; + + l6 { + regulator-min-microvolt = <2950000>; + regulator-max-microvolt = <2950000>; + }; + + /* mipi_dsi.1-dsi1_avdd */ + l11 { + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + bias-pull-down; + }; + + /* pwm_power for backlight */ + l17 { + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3600000>; + bias-pull-down; + }; + + /* camera, qdsp6 */ + l23 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + bias-pull-down; + }; + + /* + * tabla2x-slim-CDC_VDDA_A_1P2V + * tabla2x-slim-VDDD_CDC_D + */ + l25 { + regulator-min-microvolt = <1250000>; + regulator-max-microvolt = <1250000>; + bias-pull-down; + }; + + lvs1 { + bias-pull-down; + }; + + lvs4 { + bias-pull-down; + }; + + lvs5 { + bias-pull-down; + }; + + lvs6 { + bias-pull-down; + }; + /* + * mipi_dsi.1-dsi1_vddio + * pil_riva-pll_vdd + */ + lvs7 { + bias-pull-down; + }; + }; + }; + + gsbi@16200000 { + status = "okay"; + qcom,mode = ; + i2c@16280000 { + status = "okay"; + clock-frequency = <200000>; + pinctrl-0 = <&i2c3_pins>; + pinctrl-names = "default"; + + trackpad@10 { + compatible = "elan,ekth3500"; + reg = <0x10>; + interrupt-parent = <&tlmm_pinmux>; + interrupts = <6 IRQ_TYPE_EDGE_FALLING>; + }; + }; + }; + + + gsbi@12440000 { + status = "okay"; + qcom,mode = ; + + i2c@12460000 { + status = "okay"; + clock-frequency = <200000>; + pinctrl-0 = <&i2c1_pins>; + pinctrl-names = "default"; + + eeprom@52 { + compatible = "atmel,24c128"; + reg = <0x52>; + pagesize = <32>; + }; + }; + }; + + gsbi@16500000 { + status = "ok"; + qcom,mode = ; + + serial@16540000 { + status = "ok"; + + pinctrl-names = "default"; + pinctrl-0 = <&gsbi6_uart_4pins>; + }; + }; + + gsbi@16600000 { + status = "ok"; + qcom,mode = ; + serial@16640000 { + status = "ok"; + }; + }; + + /* OTG */ + phy@12500000 { + status = "okay"; + vddcx-supply = <&pm8921_s3>; + v3p3-supply = <&pm8921_l3>; + v1p8-supply = <&pm8921_l4>; + }; + + gadget@12500000 { + status = "okay"; + }; + + /* OTG */ + usb@12500000 { + status = "okay"; + }; + + amba { + /* eMMC */ + sdcc@12400000 { + status = "okay"; + vmmc-supply = <&pm8921_l5>; + vqmmc-supply = <&pm8921_s4>; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts b/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts index 21095dad77419afdc59e1ccebbae95fd0ccd51dd..35f1d46edded1a7e7aea86f09fb03674a0e464e7 100644 --- a/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts +++ b/arch/arm/boot/dts/qcom-apq8064-cm-qs600.dts @@ -37,6 +37,18 @@ bias-disable; }; }; + + pcie_pins: pcie_pinmux { + mux { + pins = "gpio27"; + function = "gpio"; + }; + conf { + pins = "gpio27"; + drive-strength = <12>; + bias-disable; + }; + }; }; rpm@108000 { @@ -103,6 +115,11 @@ regulator-max-microvolt = <1900000>; bias-pull-down; }; + + pm8921_lvs6: lvs6 { + bias-pull-down; + }; + }; }; @@ -195,6 +212,16 @@ }; }; + pci@1b500000 { + status = "ok"; + vdda-supply = <&pm8921_s3>; + vdda_phy-supply = <&pm8921_lvs6>; + vdda_refclk-supply = <&v3p3_fixed>; + pinctrl-0 = <&pcie_pins>; + pinctrl-names = "default"; + perst-gpio = <&tlmm_pinmux 27 GPIO_ACTIVE_LOW>; + }; + amba { /* eMMC */ sdcc1: sdcc@12400000 { diff --git a/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts b/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts index fd4d49ef9ef250f45a4b04553c633b17d6a4c8d4..2eeb0904eaa794169b756fd3a9e3a8044c5ddca2 100644 --- a/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts +++ b/arch/arm/boot/dts/qcom-apq8064-ifc6410.dts @@ -9,6 +9,11 @@ aliases { serial0 = &gsbi7_serial; serial1 = &gsbi6_serial; + i2c0 = &gsbi1_i2c; + i2c1 = &gsbi2_i2c; + i2c2 = &gsbi3_i2c; + i2c3 = &gsbi4_i2c; + spi0 = &gsbi5_spi; }; chosen { @@ -157,7 +162,16 @@ gsbi3: gsbi@16200000 { status = "okay"; qcom,mode = ; - i2c3: i2c@16280000 { + i2c@16280000 { + status = "okay"; + }; + }; + + gsbi@16300000 { + status = "okay"; + qcom,mode = ; + /* CAM I2C MIPI-CSI connector */ + i2c@16380000 { status = "okay"; }; }; @@ -178,6 +192,16 @@ }; }; + gsbi@1a200000 { + qcom,mode = ; + status = "okay"; + spi4: spi@1a280000 { + status = "okay"; + num-cs = <1>; + cs-gpios = <&tlmm_pinmux 53 0>; + }; + }; + gsbi@16500000 { status = "ok"; qcom,mode = ; diff --git a/arch/arm/boot/dts/qcom-apq8064-pins.dtsi b/arch/arm/boot/dts/qcom-apq8064-pins.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..b57c59d5bc00b6a48eaa844d630ff094fcfbc7a3 --- /dev/null +++ b/arch/arm/boot/dts/qcom-apq8064-pins.dtsi @@ -0,0 +1,208 @@ + +&tlmm_pinmux { + sdc4_gpios: sdc4-gpios { + pios { + pins = "gpio63", "gpio64", "gpio65", "gpio66", "gpio67", "gpio68"; + function = "sdc4"; + }; + }; + + ps_hold: ps_hold { + mux { + pins = "gpio78"; + function = "ps_hold"; + }; + }; + + i2c1_pins: i2c1 { + mux { + pins = "gpio20", "gpio21"; + function = "gsbi1"; + }; + + pinconf { + pins = "gpio20", "gpio21"; + drive-strength = <16>; + bias-disable; + }; + }; + + i2c1_pins_sleep: i2c1_pins_sleep { + mux { + pins = "gpio20", "gpio21"; + function = "gpio"; + }; + pinconf { + pins = "gpio20", "gpio21"; + drive-strength = <2>; + bias-disable = <0>; + }; + }; + + i2c2_pins: i2c2 { + mux { + pins = "gpio24", "gpio25"; + function = "gsbi2"; + }; + + pinconf { + pins = "gpio24", "gpio25"; + drive-strength = <16>; + bias-disable; + }; + }; + + i2c2_pins_sleep: i2c2_pins_sleep { + mux { + pins = "gpio24", "gpio25"; + function = "gpio"; + }; + + pinconf { + pins = "gpio24", "gpio25"; + drive-strength = <2>; + bias-disable = <0>; + }; + }; + + i2c3_pins: i2c3 { + mux { + pins = "gpio8", "gpio9"; + function = "gsbi3"; + }; + + pinconf { + pins = "gpio8", "gpio9"; + drive-strength = <16>; + bias-disable; + }; + }; + + i2c3_pins_sleep: i2c3_pins_sleep { + mux { + pins = "gpio8", "gpio9"; + function = "gpio"; + }; + pinconf { + pins = "gpio8", "gpio9"; + drive-strength = <2>; + bias-disable = <0>; + }; + }; + + i2c4_pins: i2c4 { + mux { + pins = "gpio12", "gpio13"; + function = "gsbi4"; + }; + + pinconf { + pins = "gpio12", "gpio13"; + drive-strength = <16>; + bias-disable; + }; + }; + + i2c4_pins_sleep: i2c4_pins_sleep { + mux { + pins = "gpio12", "gpio13"; + function = "gpio"; + }; + pinconf { + pins = "gpio12", "gpio13"; + drive-strength = <2>; + bias-disable = <0>; + }; + }; + + spi5_default: spi5_default { + pinmux { + pins = "gpio51", "gpio52", "gpio54"; + function = "gsbi5"; + }; + + pinmux_cs { + function = "gpio"; + pins = "gpio53"; + }; + + pinconf { + pins = "gpio51", "gpio52", "gpio54"; + drive-strength = <16>; + bias-disable; + }; + + pinconf_cs { + pins = "gpio53"; + drive-strength = <16>; + bias-disable; + output-high; + }; + }; + + spi5_sleep: spi5_sleep { + pinmux { + function = "gpio"; + pins = "gpio51", "gpio52", "gpio53", "gpio54"; + }; + + pinconf { + pins = "gpio51", "gpio52", "gpio53", "gpio54"; + drive-strength = <2>; + bias-pull-down; + }; + }; + + i2c6_pins: i2c6 { + mux { + pins = "gpio16", "gpio17"; + function = "gsbi6"; + }; + + pinconf { + pins = "gpio16", "gpio17"; + drive-strength = <16>; + bias-disable; + }; + }; + + i2c6_pins_sleep: i2c6_pins_sleep { + mux { + pins = "gpio16", "gpio17"; + function = "gpio"; + }; + pinconf { + pins = "gpio16", "gpio17"; + drive-strength = <2>; + bias-disable = <0>; + }; + }; + + gsbi6_uart_2pins: gsbi6_uart_2pins { + mux { + pins = "gpio14", "gpio15"; + function = "gsbi6"; + }; + }; + + gsbi6_uart_4pins: gsbi6_uart_4pins { + mux { + pins = "gpio14", "gpio15", "gpio16", "gpio17"; + function = "gsbi6"; + }; + }; + + gsbi7_uart_2pins: gsbi7_uart_2pins { + mux { + pins = "gpio82", "gpio83"; + function = "gsbi7"; + }; + }; + + gsbi7_uart_4pins: gsbi7_uart_4pins { + mux { + pins = "gpio82", "gpio83", "gpio84", "gpio85"; + function = "gsbi7"; + }; + }; +}; diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi index ed521e85e208e72bd7e7afd96ac8acb1a5ab77a3..65d0e8d9825947c68b06e53b162d10116df084c0 100644 --- a/arch/arm/boot/dts/qcom-apq8064.dtsi +++ b/arch/arm/boot/dts/qcom-apq8064.dtsi @@ -142,62 +142,6 @@ pinctrl-names = "default"; pinctrl-0 = <&ps_hold>; - - sdc4_gpios: sdc4-gpios { - pios { - pins = "gpio63", "gpio64", "gpio65", "gpio66", "gpio67", "gpio68"; - function = "sdc4"; - }; - }; - - ps_hold: ps_hold { - mux { - pins = "gpio78"; - function = "ps_hold"; - }; - }; - - i2c1_pins: i2c1 { - mux { - pins = "gpio20", "gpio21"; - function = "gsbi1"; - }; - }; - - i2c3_pins: i2c3 { - mux { - pins = "gpio8", "gpio9"; - function = "gsbi3"; - }; - }; - - gsbi6_uart_2pins: gsbi6_uart_2pins { - mux { - pins = "gpio14", "gpio15"; - function = "gsbi6"; - }; - }; - - gsbi6_uart_4pins: gsbi6_uart_4pins { - mux { - pins = "gpio14", "gpio15", "gpio16", "gpio17"; - function = "gsbi6"; - }; - }; - - gsbi7_uart_2pins: gsbi7_uart_2pins { - mux { - pins = "gpio82", "gpio83"; - function = "gsbi7"; - }; - }; - - gsbi7_uart_4pins: gsbi7_uart_4pins { - mux { - pins = "gpio82", "gpio83", "gpio84", "gpio85"; - function = "gsbi7"; - }; - }; }; sfpb_wrapper_mutex: syscon@1200000 { @@ -281,10 +225,10 @@ syscon-tcsr = <&tcsr>; - i2c1: i2c@12460000 { + gsbi1_i2c: i2c@12460000 { compatible = "qcom,i2c-qup-v1.1.1"; - pinctrl-0 = <&i2c1_pins>; - pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins &i2c1_pins_sleep>; + pinctrl-names = "default", "sleep"; reg = <0x12460000 0x1000>; interrupts = <0 194 IRQ_TYPE_NONE>; clocks = <&gcc GSBI1_QUP_CLK>, <&gcc GSBI1_H_CLK>; @@ -292,6 +236,7 @@ #address-cells = <1>; #size-cells = <0>; }; + }; gsbi2: gsbi@12480000 { @@ -307,9 +252,11 @@ syscon-tcsr = <&tcsr>; - i2c2: i2c@124a0000 { + gsbi2_i2c: i2c@124a0000 { compatible = "qcom,i2c-qup-v1.1.1"; reg = <0x124a0000 0x1000>; + pinctrl-0 = <&i2c2_pins &i2c2_pins_sleep>; + pinctrl-names = "default", "sleep"; interrupts = <0 196 IRQ_TYPE_NONE>; clocks = <&gcc GSBI2_QUP_CLK>, <&gcc GSBI2_H_CLK>; clock-names = "core", "iface"; @@ -328,15 +275,40 @@ #address-cells = <1>; #size-cells = <1>; ranges; - i2c3: i2c@16280000 { + gsbi3_i2c: i2c@16280000 { compatible = "qcom,i2c-qup-v1.1.1"; - pinctrl-0 = <&i2c3_pins>; - pinctrl-names = "default"; + pinctrl-0 = <&i2c3_pins &i2c3_pins_sleep>; + pinctrl-names = "default", "sleep"; reg = <0x16280000 0x1000>; interrupts = ; clocks = <&gcc GSBI3_QUP_CLK>, <&gcc GSBI3_H_CLK>; clock-names = "core", "iface"; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + + gsbi4: gsbi@16300000 { + status = "disabled"; + compatible = "qcom,gsbi-v1.0.0"; + cell-index = <4>; + reg = <0x16300000 0x03>; + clocks = <&gcc GSBI4_H_CLK>; + clock-names = "iface"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + gsbi4_i2c: i2c@16380000 { + compatible = "qcom,i2c-qup-v1.1.1"; + pinctrl-0 = <&i2c4_pins &i2c4_pins_sleep>; + pinctrl-names = "default", "sleep"; + reg = <0x16380000 0x1000>; + interrupts = ; + clocks = <&gcc GSBI4_QUP_CLK>, + <&gcc GSBI4_H_CLK>; + clock-names = "core", "iface"; }; }; @@ -360,6 +332,19 @@ clock-names = "core", "iface"; status = "disabled"; }; + + gsbi5_spi: spi@1a280000 { + compatible = "qcom,spi-qup-v1.1.1"; + reg = <0x1a280000 0x1000>; + interrupts = <0 155 0>; + pinctrl-0 = <&spi5_default &spi5_sleep>; + pinctrl-names = "default", "sleep"; + clocks = <&gcc GSBI5_QUP_CLK>, <&gcc GSBI5_H_CLK>; + clock-names = "core", "iface"; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; }; gsbi6: gsbi@16500000 { @@ -382,6 +367,17 @@ clock-names = "core", "iface"; status = "disabled"; }; + + gsbi6_i2c: i2c@16580000 { + compatible = "qcom,i2c-qup-v1.1.1"; + pinctrl-0 = <&i2c6_pins &i2c6_pins_sleep>; + pinctrl-names = "default", "sleep"; + reg = <0x16580000 0x1000>; + interrupts = ; + clocks = <&gcc GSBI6_QUP_CLK>, + <&gcc GSBI6_H_CLK>; + clock-names = "core", "iface"; + }; }; gsbi7: gsbi@16600000 { @@ -521,6 +517,11 @@ ; interrupt-names = "ack", "err", "wakeup"; + rpmcc: clock-controller { + compatible = "qcom,rpmcc-apq8064", "qcom,rpmcc"; + #clock-cells = <1>; + }; + regulators { compatible = "qcom,rpm-pm8921-regulators"; @@ -721,7 +722,7 @@ }; amba { - compatible = "arm,amba-bus"; + compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges; @@ -823,3 +824,4 @@ }; }; }; +#include "qcom-apq8064-pins.dtsi" diff --git a/arch/arm/boot/dts/qcom-apq8084.dtsi b/arch/arm/boot/dts/qcom-apq8084.dtsi index 08214cbae16da84c0f191661528d40bc132e09b3..a33a09f6821edb883da87e0c37d837bd9a468b8d 100644 --- a/arch/arm/boot/dts/qcom-apq8084.dtsi +++ b/arch/arm/boot/dts/qcom-apq8084.dtsi @@ -91,6 +91,20 @@ interrupts = <1 7 0xf04>; }; + clocks { + xo_board { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <19200000>; + }; + + sleep_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + }; + timer { compatible = "arm,armv7-timer"; interrupts = <1 2 0xf08>, diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi b/arch/arm/boot/dts/qcom-ipq8064.dtsi index fa698635eea0d1f859d57c766c679438a416b55d..2601a907947b97f4e58c8e07d1524afa2aad02d1 100644 --- a/arch/arm/boot/dts/qcom-ipq8064.dtsi +++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi @@ -62,6 +62,18 @@ }; clocks { + cxo_board { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <19200000>; + }; + + pxo_board { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + }; + sleep_clk: sleep_clk { compatible = "fixed-clock"; clock-frequency = <32768>; diff --git a/arch/arm/boot/dts/qcom-msm8660.dtsi b/arch/arm/boot/dts/qcom-msm8660.dtsi index e5f7f33aa4677739f9bc1e6d57d969db9b856cf9..cd214030b84a5dde3673ff0562719d3f3b73e61f 100644 --- a/arch/arm/boot/dts/qcom-msm8660.dtsi +++ b/arch/arm/boot/dts/qcom-msm8660.dtsi @@ -42,6 +42,26 @@ interrupts = <1 9 0x304>; }; + clocks { + cxo_board { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <19200000>; + }; + + pxo_board { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + }; + + sleep_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + }; + soc: soc { #address-cells = <1>; #size-cells = <1>; @@ -167,7 +187,7 @@ }; amba { - compatible = "arm,amba-bus"; + compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges; diff --git a/arch/arm/boot/dts/qcom-msm8960.dtsi b/arch/arm/boot/dts/qcom-msm8960.dtsi index 51a40d84145c51b4a206598e3344181be1442a64..da05e28a81a765e36d53682f7984c9118b8f1553 100644 --- a/arch/arm/boot/dts/qcom-msm8960.dtsi +++ b/arch/arm/boot/dts/qcom-msm8960.dtsi @@ -251,7 +251,7 @@ }; amba { - compatible = "arm,amba-bus"; + compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges; diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi index dfdafdcb8aae99711507bc4abfbbd7374ba39205..ef53305784318a40d692fa7053a631abac28e552 100644 --- a/arch/arm/boot/dts/qcom-msm8974.dtsi +++ b/arch/arm/boot/dts/qcom-msm8974.dtsi @@ -1,6 +1,6 @@ /dts-v1/; -#include +#include #include #include "skeleton.dtsi" @@ -14,10 +14,50 @@ #size-cells = <1>; ranges; + mpss@08000000 { + reg = <0x08000000 0x5100000>; + no-map; + }; + + mba@00d100000 { + reg = <0x0d100000 0x100000>; + no-map; + }; + + reserved@0d200000 { + reg = <0x0d200000 0xa00000>; + no-map; + }; + + adsp@0dc00000 { + reg = <0x0dc00000 0x1900000>; + no-map; + }; + + venus@0f500000 { + reg = <0x0f500000 0x500000>; + no-map; + }; + smem_region: smem@fa00000 { reg = <0xfa00000 0x200000>; no-map; }; + + tz@0fc00000 { + reg = <0x0fc00000 0x160000>; + no-map; + }; + + efs@0fd600000 { + reg = <0x0fd60000 0x1a0000>; + no-map; + }; + + unused@0ff00000 { + reg = <0x0ff00000 0x10100000>; + no-map; + }; }; cpus { @@ -91,6 +131,20 @@ interrupts = <1 7 0xf04>; }; + clocks { + xo_board { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <19200000>; + }; + + sleep_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + }; + timer { compatible = "arm,armv7-timer"; interrupts = <1 2 0xf08>, @@ -109,6 +163,73 @@ hwlocks = <&tcsr_mutex 3>; }; + smp2p-wcnss { + compatible = "qcom,smp2p"; + qcom,smem = <451>, <431>; + + interrupt-parent = <&intc>; + interrupts = <0 143 IRQ_TYPE_EDGE_RISING>; + + qcom,ipc = <&apcs 8 18>; + + qcom,local-pid = <0>; + qcom,remote-pid = <4>; + + wcnss_smp2p_out: master-kernel { + qcom,entry-name = "master-kernel"; + + #qcom,state-cells = <1>; + }; + + wcnss_smp2p_in: slave-kernel { + qcom,entry-name = "slave-kernel"; + + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + + smsm { + compatible = "qcom,smsm"; + + #address-cells = <1>; + #size-cells = <0>; + + qcom,ipc-1 = <&apcs 8 13>; + qcom,ipc-2 = <&apcs 8 9>; + qcom,ipc-3 = <&apcs 8 19>; + + apps_smsm: apps@0 { + reg = <0>; + + #qcom,state-cells = <1>; + }; + + modem_smsm: modem@1 { + reg = <1>; + interrupts = <0 26 IRQ_TYPE_EDGE_RISING>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + adsp_smsm: adsp@2 { + reg = <2>; + interrupts = <0 157 IRQ_TYPE_EDGE_RISING>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + wcnss_smsm: wcnss@7 { + reg = <7>; + interrupts = <0 144 IRQ_TYPE_EDGE_RISING>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + soc: soc { #address-cells = <1>; #size-cells = <1>; @@ -339,6 +460,8 @@ clock-names = "core", "iface"; #address-cells = <1>; #size-cells = <0>; + dmas = <&blsp2_dma 20>, <&blsp2_dma 21>; + dma-names = "tx", "rx"; }; spmi_bus: spmi@fc4cf000 { @@ -356,6 +479,16 @@ interrupt-controller; #interrupt-cells = <4>; }; + + blsp2_dma: dma-controller@f9944000 { + compatible = "qcom,bam-v1.4.0"; + reg = <0xf9944000 0x19000>; + interrupts = ; + clocks = <&gcc GCC_BLSP2_AHB_CLK>; + clock-names = "bam_clk"; + #dma-cells = <1>; + qcom,ee = <0>; + }; }; smd { diff --git a/arch/arm/boot/dts/qcom-pm8841.dtsi b/arch/arm/boot/dts/qcom-pm8841.dtsi index 9f357f68713c44fedd26a899303480f5cab7f09a..0512f645922e29e7b9c31067f9937724e1b041c0 100644 --- a/arch/arm/boot/dts/qcom-pm8841.dtsi +++ b/arch/arm/boot/dts/qcom-pm8841.dtsi @@ -11,7 +11,7 @@ pm8841_mpps: mpps@a000 { compatible = "qcom,pm8841-mpp", "qcom,spmi-mpp"; - reg = <0xa000 0x400>; + reg = <0xa000>; gpio-controller; #gpio-cells = <2>; interrupts = <4 0xa0 0 IRQ_TYPE_NONE>, @@ -22,7 +22,7 @@ temp-alarm@2400 { compatible = "qcom,spmi-temp-alarm"; - reg = <0x2400 0x100>; + reg = <0x2400>; interrupts = <4 0x24 0 IRQ_TYPE_EDGE_RISING>; }; }; diff --git a/arch/arm/boot/dts/qcom-pm8941.dtsi b/arch/arm/boot/dts/qcom-pm8941.dtsi index ca53a5947437525d1e706259909616c16a3d21de..d95edb6f6265394e6b3dca251098b4016aff3cc8 100644 --- a/arch/arm/boot/dts/qcom-pm8941.dtsi +++ b/arch/arm/boot/dts/qcom-pm8941.dtsi @@ -12,15 +12,15 @@ rtc@6000 { compatible = "qcom,pm8941-rtc"; - reg = <0x6000 0x100>, - <0x6100 0x100>; + reg = <0x6000>, + <0x6100>; reg-names = "rtc", "alarm"; interrupts = <0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>; }; pwrkey@800 { compatible = "qcom,pm8941-pwrkey"; - reg = <0x800 0x100>; + reg = <0x800>; interrupts = <0x0 0x8 0 IRQ_TYPE_EDGE_BOTH>; debounce = <15625>; bias-pull-up; @@ -28,7 +28,7 @@ charger@1000 { compatible = "qcom,pm8941-charger"; - reg = <0x1000 0x700>; + reg = <0x1000>; interrupts = <0x0 0x10 7 IRQ_TYPE_EDGE_BOTH>, <0x0 0x10 5 IRQ_TYPE_EDGE_BOTH>, <0x0 0x10 4 IRQ_TYPE_EDGE_BOTH>, @@ -49,7 +49,7 @@ pm8941_gpios: gpios@c000 { compatible = "qcom,pm8941-gpio", "qcom,spmi-gpio"; - reg = <0xc000 0x2400>; + reg = <0xc000>; gpio-controller; #gpio-cells = <2>; interrupts = <0 0xc0 0 IRQ_TYPE_NONE>, @@ -92,7 +92,7 @@ pm8941_mpps: mpps@a000 { compatible = "qcom,pm8941-mpp", "qcom,spmi-mpp"; - reg = <0xa000 0x800>; + reg = <0xa000>; gpio-controller; #gpio-cells = <2>; interrupts = <0 0xa0 0 IRQ_TYPE_NONE>, @@ -107,7 +107,7 @@ pm8941_temp: temp-alarm@2400 { compatible = "qcom,spmi-temp-alarm"; - reg = <0x2400 0x100>; + reg = <0x2400>; interrupts = <0 0x24 0 IRQ_TYPE_EDGE_RISING>; io-channels = <&pm8941_vadc VADC_DIE_TEMP>; io-channel-names = "thermal"; @@ -116,7 +116,7 @@ pm8941_vadc: vadc@3100 { compatible = "qcom,spmi-vadc"; - reg = <0x3100 0x100>; + reg = <0x3100>; interrupts = <0x0 0x31 0x0 IRQ_TYPE_EDGE_RISING>; #address-cells = <1>; #size-cells = <0>; @@ -141,7 +141,7 @@ pm8941_iadc: iadc@3600 { compatible = "qcom,pm8941-iadc", "qcom,spmi-iadc"; - reg = <0x3600 0x100>; + reg = <0x3600>; interrupts = <0x0 0x36 0x0 IRQ_TYPE_EDGE_RISING>; qcom,external-resistor-micro-ohms = <10000>; }; @@ -161,7 +161,7 @@ pm8941_wled: wled@d800 { compatible = "qcom,pm8941-wled"; - reg = <0xd800 0x100>; + reg = <0xd800>; label = "backlight"; status = "disabled"; diff --git a/arch/arm/boot/dts/r7s72100.dtsi b/arch/arm/boot/dts/r7s72100.dtsi index 4657d7fb5bceede5ea747359257fc68ee9b434ad..89e46ebef1bca7ce3dd02399a2a264f0a903a687 100644 --- a/arch/arm/boot/dts/r7s72100.dtsi +++ b/arch/arm/boot/dts/r7s72100.dtsi @@ -10,6 +10,7 @@ */ #include +#include #include / { @@ -152,12 +153,12 @@ scif0: serial@e8007000 { compatible = "renesas,scif-r7s72100", "renesas,scif"; reg = <0xe8007000 64>; - interrupts = <0 190 IRQ_TYPE_LEVEL_HIGH>, - <0 191 IRQ_TYPE_LEVEL_HIGH>, - <0 192 IRQ_TYPE_LEVEL_HIGH>, - <0 189 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; clocks = <&mstp4_clks R7S72100_CLK_SCIF0>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -165,12 +166,12 @@ scif1: serial@e8007800 { compatible = "renesas,scif-r7s72100", "renesas,scif"; reg = <0xe8007800 64>; - interrupts = <0 194 IRQ_TYPE_LEVEL_HIGH>, - <0 195 IRQ_TYPE_LEVEL_HIGH>, - <0 196 IRQ_TYPE_LEVEL_HIGH>, - <0 193 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; clocks = <&mstp4_clks R7S72100_CLK_SCIF1>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -178,12 +179,12 @@ scif2: serial@e8008000 { compatible = "renesas,scif-r7s72100", "renesas,scif"; reg = <0xe8008000 64>; - interrupts = <0 198 IRQ_TYPE_LEVEL_HIGH>, - <0 199 IRQ_TYPE_LEVEL_HIGH>, - <0 200 IRQ_TYPE_LEVEL_HIGH>, - <0 197 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; clocks = <&mstp4_clks R7S72100_CLK_SCIF2>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -191,12 +192,12 @@ scif3: serial@e8008800 { compatible = "renesas,scif-r7s72100", "renesas,scif"; reg = <0xe8008800 64>; - interrupts = <0 202 IRQ_TYPE_LEVEL_HIGH>, - <0 203 IRQ_TYPE_LEVEL_HIGH>, - <0 204 IRQ_TYPE_LEVEL_HIGH>, - <0 201 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; clocks = <&mstp4_clks R7S72100_CLK_SCIF3>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -204,12 +205,12 @@ scif4: serial@e8009000 { compatible = "renesas,scif-r7s72100", "renesas,scif"; reg = <0xe8009000 64>; - interrupts = <0 206 IRQ_TYPE_LEVEL_HIGH>, - <0 207 IRQ_TYPE_LEVEL_HIGH>, - <0 208 IRQ_TYPE_LEVEL_HIGH>, - <0 205 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; clocks = <&mstp4_clks R7S72100_CLK_SCIF4>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -217,12 +218,12 @@ scif5: serial@e8009800 { compatible = "renesas,scif-r7s72100", "renesas,scif"; reg = <0xe8009800 64>; - interrupts = <0 210 IRQ_TYPE_LEVEL_HIGH>, - <0 211 IRQ_TYPE_LEVEL_HIGH>, - <0 212 IRQ_TYPE_LEVEL_HIGH>, - <0 209 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; clocks = <&mstp4_clks R7S72100_CLK_SCIF5>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -230,12 +231,12 @@ scif6: serial@e800a000 { compatible = "renesas,scif-r7s72100", "renesas,scif"; reg = <0xe800a000 64>; - interrupts = <0 214 IRQ_TYPE_LEVEL_HIGH>, - <0 215 IRQ_TYPE_LEVEL_HIGH>, - <0 216 IRQ_TYPE_LEVEL_HIGH>, - <0 213 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; clocks = <&mstp4_clks R7S72100_CLK_SCIF6>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -243,12 +244,12 @@ scif7: serial@e800a800 { compatible = "renesas,scif-r7s72100", "renesas,scif"; reg = <0xe800a800 64>; - interrupts = <0 218 IRQ_TYPE_LEVEL_HIGH>, - <0 219 IRQ_TYPE_LEVEL_HIGH>, - <0 220 IRQ_TYPE_LEVEL_HIGH>, - <0 217 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; clocks = <&mstp4_clks R7S72100_CLK_SCIF7>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -256,9 +257,9 @@ spi0: spi@e800c800 { compatible = "renesas,rspi-r7s72100", "renesas,rspi-rz"; reg = <0xe800c800 0x24>; - interrupts = <0 238 IRQ_TYPE_LEVEL_HIGH>, - <0 239 IRQ_TYPE_LEVEL_HIGH>, - <0 240 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; interrupt-names = "error", "rx", "tx"; clocks = <&mstp10_clks R7S72100_CLK_SPI0>; power-domains = <&cpg_clocks>; @@ -271,9 +272,9 @@ spi1: spi@e800d000 { compatible = "renesas,rspi-r7s72100", "renesas,rspi-rz"; reg = <0xe800d000 0x24>; - interrupts = <0 241 IRQ_TYPE_LEVEL_HIGH>, - <0 242 IRQ_TYPE_LEVEL_HIGH>, - <0 243 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; interrupt-names = "error", "rx", "tx"; clocks = <&mstp10_clks R7S72100_CLK_SPI1>; power-domains = <&cpg_clocks>; @@ -286,9 +287,9 @@ spi2: spi@e800d800 { compatible = "renesas,rspi-r7s72100", "renesas,rspi-rz"; reg = <0xe800d800 0x24>; - interrupts = <0 244 IRQ_TYPE_LEVEL_HIGH>, - <0 245 IRQ_TYPE_LEVEL_HIGH>, - <0 246 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; interrupt-names = "error", "rx", "tx"; clocks = <&mstp10_clks R7S72100_CLK_SPI2>; power-domains = <&cpg_clocks>; @@ -301,9 +302,9 @@ spi3: spi@e800e000 { compatible = "renesas,rspi-r7s72100", "renesas,rspi-rz"; reg = <0xe800e000 0x24>; - interrupts = <0 247 IRQ_TYPE_LEVEL_HIGH>, - <0 248 IRQ_TYPE_LEVEL_HIGH>, - <0 249 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; interrupt-names = "error", "rx", "tx"; clocks = <&mstp10_clks R7S72100_CLK_SPI3>; power-domains = <&cpg_clocks>; @@ -316,9 +317,9 @@ spi4: spi@e800e800 { compatible = "renesas,rspi-r7s72100", "renesas,rspi-rz"; reg = <0xe800e800 0x24>; - interrupts = <0 250 IRQ_TYPE_LEVEL_HIGH>, - <0 251 IRQ_TYPE_LEVEL_HIGH>, - <0 252 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; interrupt-names = "error", "rx", "tx"; clocks = <&mstp10_clks R7S72100_CLK_SPI4>; power-domains = <&cpg_clocks>; @@ -342,14 +343,14 @@ #size-cells = <0>; compatible = "renesas,riic-r7s72100", "renesas,riic-rz"; reg = <0xfcfee000 0x44>; - interrupts = <0 157 IRQ_TYPE_LEVEL_HIGH>, - <0 158 IRQ_TYPE_EDGE_RISING>, - <0 159 IRQ_TYPE_EDGE_RISING>, - <0 160 IRQ_TYPE_LEVEL_HIGH>, - <0 161 IRQ_TYPE_LEVEL_HIGH>, - <0 162 IRQ_TYPE_LEVEL_HIGH>, - <0 163 IRQ_TYPE_LEVEL_HIGH>, - <0 164 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + ; clocks = <&mstp9_clks R7S72100_CLK_I2C0>; clock-frequency = <100000>; power-domains = <&cpg_clocks>; @@ -361,14 +362,14 @@ #size-cells = <0>; compatible = "renesas,riic-r7s72100", "renesas,riic-rz"; reg = <0xfcfee400 0x44>; - interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>, - <0 166 IRQ_TYPE_EDGE_RISING>, - <0 167 IRQ_TYPE_EDGE_RISING>, - <0 168 IRQ_TYPE_LEVEL_HIGH>, - <0 169 IRQ_TYPE_LEVEL_HIGH>, - <0 170 IRQ_TYPE_LEVEL_HIGH>, - <0 171 IRQ_TYPE_LEVEL_HIGH>, - <0 172 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + ; clocks = <&mstp9_clks R7S72100_CLK_I2C1>; clock-frequency = <100000>; power-domains = <&cpg_clocks>; @@ -380,14 +381,14 @@ #size-cells = <0>; compatible = "renesas,riic-r7s72100", "renesas,riic-rz"; reg = <0xfcfee800 0x44>; - interrupts = <0 173 IRQ_TYPE_LEVEL_HIGH>, - <0 174 IRQ_TYPE_EDGE_RISING>, - <0 175 IRQ_TYPE_EDGE_RISING>, - <0 176 IRQ_TYPE_LEVEL_HIGH>, - <0 177 IRQ_TYPE_LEVEL_HIGH>, - <0 178 IRQ_TYPE_LEVEL_HIGH>, - <0 179 IRQ_TYPE_LEVEL_HIGH>, - <0 180 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + ; clocks = <&mstp9_clks R7S72100_CLK_I2C2>; clock-frequency = <100000>; power-domains = <&cpg_clocks>; @@ -399,14 +400,14 @@ #size-cells = <0>; compatible = "renesas,riic-r7s72100", "renesas,riic-rz"; reg = <0xfcfeec00 0x44>; - interrupts = <0 181 IRQ_TYPE_LEVEL_HIGH>, - <0 182 IRQ_TYPE_EDGE_RISING>, - <0 183 IRQ_TYPE_EDGE_RISING>, - <0 184 IRQ_TYPE_LEVEL_HIGH>, - <0 185 IRQ_TYPE_LEVEL_HIGH>, - <0 186 IRQ_TYPE_LEVEL_HIGH>, - <0 187 IRQ_TYPE_LEVEL_HIGH>, - <0 188 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + ; clocks = <&mstp9_clks R7S72100_CLK_I2C3>; clock-frequency = <100000>; power-domains = <&cpg_clocks>; @@ -416,7 +417,7 @@ mtu2: timer@fcff0000 { compatible = "renesas,mtu2-r7s72100", "renesas,mtu2"; reg = <0xfcff0000 0x400>; - interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "tgi0a"; clocks = <&mstp3_clks R7S72100_CLK_MTU2>; clock-names = "fck"; diff --git a/arch/arm/boot/dts/r8a73a4.dtsi b/arch/arm/boot/dts/r8a73a4.dtsi index cb4f7b2798fe23be13facdffaef64430cf168ab1..6583a1dfca1f64c6f6482a3712908f1efc34a320 100644 --- a/arch/arm/boot/dts/r8a73a4.dtsi +++ b/arch/arm/boot/dts/r8a73a4.dtsi @@ -29,6 +29,7 @@ reg = <0>; clock-frequency = <1500000000>; power-domains = <&pd_a2sl>; + next-level-cache = <&L2_CA15>; }; }; @@ -39,10 +40,26 @@ timer { compatible = "arm,armv7-timer"; - interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, - <1 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, - <1 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, - <1 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; + }; + + L2_CA15: cache-controller@0 { + compatible = "cache"; + clocks = <&cpg_clocks R8A73A4_CLK_Z>; + power-domains = <&pd_a3sm>; + cache-unified; + cache-level = <2>; + }; + + L2_CA7: cache-controller@1 { + compatible = "cache"; + clocks = <&cpg_clocks R8A73A4_CLK_Z2>; + power-domains = <&pd_a3km>; + cache-unified; + cache-level = <2>; }; dbsc1: memory-controller@e6790000 { @@ -69,27 +86,27 @@ dma0: dma-controller@e6700020 { compatible = "renesas,shdma-r8a73a4"; reg = <0 0xe6700020 0 0x89e0>; - interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH - 0 200 IRQ_TYPE_LEVEL_HIGH - 0 201 IRQ_TYPE_LEVEL_HIGH - 0 202 IRQ_TYPE_LEVEL_HIGH - 0 203 IRQ_TYPE_LEVEL_HIGH - 0 204 IRQ_TYPE_LEVEL_HIGH - 0 205 IRQ_TYPE_LEVEL_HIGH - 0 206 IRQ_TYPE_LEVEL_HIGH - 0 207 IRQ_TYPE_LEVEL_HIGH - 0 208 IRQ_TYPE_LEVEL_HIGH - 0 209 IRQ_TYPE_LEVEL_HIGH - 0 210 IRQ_TYPE_LEVEL_HIGH - 0 211 IRQ_TYPE_LEVEL_HIGH - 0 212 IRQ_TYPE_LEVEL_HIGH - 0 213 IRQ_TYPE_LEVEL_HIGH - 0 214 IRQ_TYPE_LEVEL_HIGH - 0 215 IRQ_TYPE_LEVEL_HIGH - 0 216 IRQ_TYPE_LEVEL_HIGH - 0 217 IRQ_TYPE_LEVEL_HIGH - 0 218 IRQ_TYPE_LEVEL_HIGH - 0 219 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -106,7 +123,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic"; reg = <0 0xe60b0000 0 0x428>; - interrupts = <0 179 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp4_clks R8A73A4_CLK_IIC5>; power-domains = <&pd_a3sp>; @@ -116,7 +133,7 @@ cmt1: timer@e6130000 { compatible = "renesas,cmt-48-r8a73a4", "renesas,cmt-48-gen2"; reg = <0 0xe6130000 0 0x1004>; - interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A73A4_CLK_CMT1>; clock-names = "fck"; power-domains = <&pd_c5>; @@ -131,38 +148,38 @@ #interrupt-cells = <2>; interrupt-controller; reg = <0 0xe61c0000 0 0x200>; - interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>, - <0 1 IRQ_TYPE_LEVEL_HIGH>, - <0 2 IRQ_TYPE_LEVEL_HIGH>, - <0 3 IRQ_TYPE_LEVEL_HIGH>, - <0 4 IRQ_TYPE_LEVEL_HIGH>, - <0 5 IRQ_TYPE_LEVEL_HIGH>, - <0 6 IRQ_TYPE_LEVEL_HIGH>, - <0 7 IRQ_TYPE_LEVEL_HIGH>, - <0 8 IRQ_TYPE_LEVEL_HIGH>, - <0 9 IRQ_TYPE_LEVEL_HIGH>, - <0 10 IRQ_TYPE_LEVEL_HIGH>, - <0 11 IRQ_TYPE_LEVEL_HIGH>, - <0 12 IRQ_TYPE_LEVEL_HIGH>, - <0 13 IRQ_TYPE_LEVEL_HIGH>, - <0 14 IRQ_TYPE_LEVEL_HIGH>, - <0 15 IRQ_TYPE_LEVEL_HIGH>, - <0 16 IRQ_TYPE_LEVEL_HIGH>, - <0 17 IRQ_TYPE_LEVEL_HIGH>, - <0 18 IRQ_TYPE_LEVEL_HIGH>, - <0 19 IRQ_TYPE_LEVEL_HIGH>, - <0 20 IRQ_TYPE_LEVEL_HIGH>, - <0 21 IRQ_TYPE_LEVEL_HIGH>, - <0 22 IRQ_TYPE_LEVEL_HIGH>, - <0 23 IRQ_TYPE_LEVEL_HIGH>, - <0 24 IRQ_TYPE_LEVEL_HIGH>, - <0 25 IRQ_TYPE_LEVEL_HIGH>, - <0 26 IRQ_TYPE_LEVEL_HIGH>, - <0 27 IRQ_TYPE_LEVEL_HIGH>, - <0 28 IRQ_TYPE_LEVEL_HIGH>, - <0 29 IRQ_TYPE_LEVEL_HIGH>, - <0 30 IRQ_TYPE_LEVEL_HIGH>, - <0 31 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; clocks = <&mstp4_clks R8A73A4_CLK_IRQC>; power-domains = <&pd_c4>; }; @@ -172,32 +189,32 @@ #interrupt-cells = <2>; interrupt-controller; reg = <0 0xe61c0200 0 0x200>; - interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>, - <0 33 IRQ_TYPE_LEVEL_HIGH>, - <0 34 IRQ_TYPE_LEVEL_HIGH>, - <0 35 IRQ_TYPE_LEVEL_HIGH>, - <0 36 IRQ_TYPE_LEVEL_HIGH>, - <0 37 IRQ_TYPE_LEVEL_HIGH>, - <0 38 IRQ_TYPE_LEVEL_HIGH>, - <0 39 IRQ_TYPE_LEVEL_HIGH>, - <0 40 IRQ_TYPE_LEVEL_HIGH>, - <0 41 IRQ_TYPE_LEVEL_HIGH>, - <0 42 IRQ_TYPE_LEVEL_HIGH>, - <0 43 IRQ_TYPE_LEVEL_HIGH>, - <0 44 IRQ_TYPE_LEVEL_HIGH>, - <0 45 IRQ_TYPE_LEVEL_HIGH>, - <0 46 IRQ_TYPE_LEVEL_HIGH>, - <0 47 IRQ_TYPE_LEVEL_HIGH>, - <0 48 IRQ_TYPE_LEVEL_HIGH>, - <0 49 IRQ_TYPE_LEVEL_HIGH>, - <0 50 IRQ_TYPE_LEVEL_HIGH>, - <0 51 IRQ_TYPE_LEVEL_HIGH>, - <0 52 IRQ_TYPE_LEVEL_HIGH>, - <0 53 IRQ_TYPE_LEVEL_HIGH>, - <0 54 IRQ_TYPE_LEVEL_HIGH>, - <0 55 IRQ_TYPE_LEVEL_HIGH>, - <0 56 IRQ_TYPE_LEVEL_HIGH>, - <0 57 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; clocks = <&mstp4_clks R8A73A4_CLK_IRQC>; power-domains = <&pd_c4>; }; @@ -237,7 +254,7 @@ compatible = "renesas,thermal-r8a73a4", "renesas,rcar-thermal"; reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>, <0 0xe61f0200 0 0x38>, <0 0xe61f0300 0 0x38>; - interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp5_clks R8A73A4_CLK_THERMAL>; power-domains = <&pd_c5>; }; @@ -247,7 +264,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic"; reg = <0 0xe6500000 0 0x428>; - interrupts = <0 174 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A73A4_CLK_IIC0>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -258,7 +275,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic"; reg = <0 0xe6510000 0 0x428>; - interrupts = <0 175 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A73A4_CLK_IIC1>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -269,7 +286,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic"; reg = <0 0xe6520000 0 0x428>; - interrupts = <0 176 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A73A4_CLK_IIC2>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -280,7 +297,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic"; reg = <0 0xe6530000 0 0x428>; - interrupts = <0 177 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp4_clks R8A73A4_CLK_IIC3>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -291,7 +308,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic"; reg = <0 0xe6540000 0 0x428>; - interrupts = <0 178 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp4_clks R8A73A4_CLK_IIC4>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -302,7 +319,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic"; reg = <0 0xe6550000 0 0x428>; - interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A73A4_CLK_IIC6>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -313,7 +330,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic"; reg = <0 0xe6560000 0 0x428>; - interrupts = <0 185 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A73A4_CLK_IIC7>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -324,7 +341,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a73a4", "renesas,rmobile-iic"; reg = <0 0xe6570000 0 0x428>; - interrupts = <0 173 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp5_clks R8A73A4_CLK_IIC8>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -333,9 +350,9 @@ scifb0: serial@e6c20000 { compatible = "renesas,scifb-r8a73a4", "renesas,scifb"; reg = <0 0xe6c20000 0 0x100>; - interrupts = <0 148 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A73A4_CLK_SCIFB0>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -343,9 +360,9 @@ scifb1: serial@e6c30000 { compatible = "renesas,scifb-r8a73a4", "renesas,scifb"; reg = <0 0xe6c30000 0 0x100>; - interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A73A4_CLK_SCIFB1>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -353,9 +370,9 @@ scifa0: serial@e6c40000 { compatible = "renesas,scifa-r8a73a4", "renesas,scifa"; reg = <0 0xe6c40000 0 0x100>; - interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A73A4_CLK_SCIFA0>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -363,9 +380,9 @@ scifa1: serial@e6c50000 { compatible = "renesas,scifa-r8a73a4", "renesas,scifa"; reg = <0 0xe6c50000 0 0x100>; - interrupts = <0 145 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A73A4_CLK_SCIFA1>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -373,9 +390,9 @@ scifb2: serial@e6ce0000 { compatible = "renesas,scifb-r8a73a4", "renesas,scifb"; reg = <0 0xe6ce0000 0 0x100>; - interrupts = <0 150 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A73A4_CLK_SCIFB2>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -383,9 +400,9 @@ scifb3: serial@e6cf0000 { compatible = "renesas,scifb-r8a73a4", "renesas,scifb"; reg = <0 0xe6cf0000 0 0x100>; - interrupts = <0 151 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A73A4_CLK_SCIFB3>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_c4>; status = "disabled"; }; @@ -393,7 +410,7 @@ sdhi0: sd@ee100000 { compatible = "renesas,sdhi-r8a73a4"; reg = <0 0xee100000 0 0x100>; - interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A73A4_CLK_SDHI0>; power-domains = <&pd_a3sp>; cap-sd-highspeed; @@ -403,7 +420,7 @@ sdhi1: sd@ee120000 { compatible = "renesas,sdhi-r8a73a4"; reg = <0 0xee120000 0 0x100>; - interrupts = <0 166 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A73A4_CLK_SDHI1>; power-domains = <&pd_a3sp>; cap-sd-highspeed; @@ -413,7 +430,7 @@ sdhi2: sd@ee140000 { compatible = "renesas,sdhi-r8a73a4"; reg = <0 0xee140000 0 0x100>; - interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A73A4_CLK_SDHI2>; power-domains = <&pd_a3sp>; cap-sd-highspeed; @@ -423,7 +440,7 @@ mmcif0: mmc@ee200000 { compatible = "renesas,sh-mmcif"; reg = <0 0xee200000 0 0x80>; - interrupts = <0 169 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A73A4_CLK_MMCIF0>; power-domains = <&pd_a3sp>; reg-io-width = <4>; @@ -433,7 +450,7 @@ mmcif1: mmc@ee220000 { compatible = "renesas,sh-mmcif"; reg = <0 0xee220000 0 0x80>; - interrupts = <0 170 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A73A4_CLK_MMCIF1>; power-domains = <&pd_a3sp>; reg-io-width = <4>; @@ -449,7 +466,7 @@ <0 0xf1002000 0 0x1000>, <0 0xf1004000 0 0x2000>, <0 0xf1006000 0 0x2000>; - interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; + interrupts = ; }; bsc: bus@fec10000 { diff --git a/arch/arm/boot/dts/r8a7740.dtsi b/arch/arm/boot/dts/r8a7740.dtsi index 6ef954766eef740f7ef439103fb4e90e46030444..995fbda74b7a057e57577f3a622f6f058fe3667c 100644 --- a/arch/arm/boot/dts/r8a7740.dtsi +++ b/arch/arm/boot/dts/r8a7740.dtsi @@ -11,6 +11,7 @@ /include/ "skeleton.dtsi" #include +#include #include / { @@ -41,7 +42,7 @@ L2: cache-controller { compatible = "arm,pl310-cache"; reg = <0xf0100000 0x1000>; - interrupts = <0 84 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; power-domains = <&pd_a3sm>; arm,data-latency = <3 3 3>; arm,tag-latency = <2 2 2>; @@ -58,7 +59,7 @@ pmu { compatible = "arm,cortex-a9-pmu"; - interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; }; ptm { @@ -69,7 +70,7 @@ cmt1: timer@e6138000 { compatible = "renesas,cmt-48-r8a7740", "renesas,cmt-48"; reg = <0xe6138000 0x170>; - interrupts = <0 58 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7740_CLK_CMT1>; clock-names = "fck"; power-domains = <&pd_c5>; @@ -89,14 +90,14 @@ <0xe6900020 1>, <0xe6900040 1>, <0xe6900060 1>; - interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_INTCA>; power-domains = <&pd_a4s>; }; @@ -111,14 +112,14 @@ <0xe6900024 1>, <0xe6900044 1>, <0xe6900064 1>; - interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_INTCA>; power-domains = <&pd_a4s>; }; @@ -133,14 +134,14 @@ <0xe6900028 1>, <0xe6900048 1>, <0xe6900068 1>; - interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_INTCA>; power-domains = <&pd_a4s>; }; @@ -155,14 +156,14 @@ <0xe690002c 1>, <0xe690004c 1>, <0xe690006c 1>; - interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH - 0 149 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_INTCA>; power-domains = <&pd_a4s>; }; @@ -171,7 +172,7 @@ compatible = "renesas,gether-r8a7740"; reg = <0xe9a00000 0x800>, <0xe9a01800 0x800>; - interrupts = <0 110 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7740_CLK_GETHER>; power-domains = <&pd_a4s>; phy-mode = "mii"; @@ -185,10 +186,10 @@ #size-cells = <0>; compatible = "renesas,iic-r8a7740", "renesas,rmobile-iic"; reg = <0xfff20000 0x425>; - interrupts = <0 201 IRQ_TYPE_LEVEL_HIGH - 0 202 IRQ_TYPE_LEVEL_HIGH - 0 203 IRQ_TYPE_LEVEL_HIGH - 0 204 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7740_CLK_IIC0>; power-domains = <&pd_a4r>; status = "disabled"; @@ -199,10 +200,10 @@ #size-cells = <0>; compatible = "renesas,iic-r8a7740", "renesas,rmobile-iic"; reg = <0xe6c20000 0x425>; - interrupts = <0 70 IRQ_TYPE_LEVEL_HIGH - 0 71 IRQ_TYPE_LEVEL_HIGH - 0 72 IRQ_TYPE_LEVEL_HIGH - 0 73 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7740_CLK_IIC1>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -211,9 +212,9 @@ scifa0: serial@e6c40000 { compatible = "renesas,scifa-r8a7740", "renesas,scifa"; reg = <0xe6c40000 0x100>; - interrupts = <0 100 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFA0>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -221,9 +222,9 @@ scifa1: serial@e6c50000 { compatible = "renesas,scifa-r8a7740", "renesas,scifa"; reg = <0xe6c50000 0x100>; - interrupts = <0 101 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFA1>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -231,9 +232,9 @@ scifa2: serial@e6c60000 { compatible = "renesas,scifa-r8a7740", "renesas,scifa"; reg = <0xe6c60000 0x100>; - interrupts = <0 102 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFA2>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -241,9 +242,9 @@ scifa3: serial@e6c70000 { compatible = "renesas,scifa-r8a7740", "renesas,scifa"; reg = <0xe6c70000 0x100>; - interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFA3>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -251,9 +252,9 @@ scifa4: serial@e6c80000 { compatible = "renesas,scifa-r8a7740", "renesas,scifa"; reg = <0xe6c80000 0x100>; - interrupts = <0 104 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFA4>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -261,9 +262,9 @@ scifa5: serial@e6cb0000 { compatible = "renesas,scifa-r8a7740", "renesas,scifa"; reg = <0xe6cb0000 0x100>; - interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFA5>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -271,9 +272,9 @@ scifa6: serial@e6cc0000 { compatible = "renesas,scifa-r8a7740", "renesas,scifa"; reg = <0xe6cc0000 0x100>; - interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFA6>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -281,9 +282,9 @@ scifa7: serial@e6cd0000 { compatible = "renesas,scifa-r8a7740", "renesas,scifa"; reg = <0xe6cd0000 0x100>; - interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFA7>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -291,9 +292,9 @@ scifb: serial@e6c30000 { compatible = "renesas,scifb-r8a7740", "renesas,scifb"; reg = <0xe6c30000 0x100>; - interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7740_CLK_SCIFB>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -329,8 +330,8 @@ mmcif0: mmc@e6bd0000 { compatible = "renesas,mmcif-r8a7740", "renesas,sh-mmcif"; reg = <0xe6bd0000 0x100>; - interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH - 0 57 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7740_CLK_MMC>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -339,9 +340,9 @@ sdhi0: sd@e6850000 { compatible = "renesas,sdhi-r8a7740"; reg = <0xe6850000 0x100>; - interrupts = <0 117 IRQ_TYPE_LEVEL_HIGH - 0 118 IRQ_TYPE_LEVEL_HIGH - 0 119 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7740_CLK_SDHI0>; power-domains = <&pd_a3sp>; cap-sd-highspeed; @@ -352,9 +353,9 @@ sdhi1: sd@e6860000 { compatible = "renesas,sdhi-r8a7740"; reg = <0xe6860000 0x100>; - interrupts = <0 121 IRQ_TYPE_LEVEL_HIGH - 0 122 IRQ_TYPE_LEVEL_HIGH - 0 123 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7740_CLK_SDHI1>; power-domains = <&pd_a3sp>; cap-sd-highspeed; @@ -365,9 +366,9 @@ sdhi2: sd@e6870000 { compatible = "renesas,sdhi-r8a7740"; reg = <0xe6870000 0x100>; - interrupts = <0 125 IRQ_TYPE_LEVEL_HIGH - 0 126 IRQ_TYPE_LEVEL_HIGH - 0 127 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp4_clks R8A7740_CLK_SDHI2>; power-domains = <&pd_a3sp>; cap-sd-highspeed; @@ -379,7 +380,7 @@ #sound-dai-cells = <1>; compatible = "renesas,fsi2-r8a7740", "renesas,sh_fsi2"; reg = <0xfe1f0000 0x400>; - interrupts = <0 9 0x4>; + interrupts = ; clocks = <&mstp3_clks R8A7740_CLK_FSI>; power-domains = <&pd_a4mp>; status = "disabled"; @@ -388,9 +389,9 @@ tmu0: timer@fff80000 { compatible = "renesas,tmu-r8a7740", "renesas,tmu"; reg = <0xfff80000 0x2c>; - interrupts = <0 198 IRQ_TYPE_LEVEL_HIGH>, - <0 199 IRQ_TYPE_LEVEL_HIGH>, - <0 200 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; clocks = <&mstp1_clks R8A7740_CLK_TMU0>; clock-names = "fck"; power-domains = <&pd_a4r>; @@ -403,9 +404,9 @@ tmu1: timer@fff90000 { compatible = "renesas,tmu-r8a7740", "renesas,tmu"; reg = <0xfff90000 0x2c>; - interrupts = <0 170 IRQ_TYPE_LEVEL_HIGH>, - <0 171 IRQ_TYPE_LEVEL_HIGH>, - <0 172 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; clocks = <&mstp1_clks R8A7740_CLK_TMU1>; clock-names = "fck"; power-domains = <&pd_a4r>; diff --git a/arch/arm/boot/dts/r8a7778-bockw.dts b/arch/arm/boot/dts/r8a7778-bockw.dts index a52b359e2ae24a300e9cc5f5de946d3005ad2afe..21e3b9dda2dabf5e8d44de253b7cfaad5d11b50a 100644 --- a/arch/arm/boot/dts/r8a7778-bockw.dts +++ b/arch/arm/boot/dts/r8a7778-bockw.dts @@ -126,11 +126,19 @@ }; &pfc { + pinctrl-0 = <&scif_clk_pins>; + pinctrl-names = "default"; + scif0_pins: serial0 { renesas,groups = "scif0_data_a", "scif0_ctrl"; renesas,function = "scif0"; }; + scif_clk_pins: scif_clk { + renesas,groups = "scif_clk"; + renesas,function = "scif_clk"; + }; + mmc_pins: mmc { renesas,groups = "mmc_data8", "mmc_ctrl"; renesas,function = "mmc"; @@ -217,3 +225,8 @@ status = "okay"; }; + +&scif_clk { + clock-frequency = <14745600>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/r8a7778.dtsi b/arch/arm/boot/dts/r8a7778.dtsi index 791aafd310a5d78bf0ac92f379b7a77ef2d9a03f..f83a348fc07a49e37f6bef9cbdd33cbc76f6d192 100644 --- a/arch/arm/boot/dts/r8a7778.dtsi +++ b/arch/arm/boot/dts/r8a7778.dtsi @@ -17,6 +17,7 @@ /include/ "skeleton.dtsi" #include +#include #include / { @@ -51,7 +52,7 @@ ether: ethernet@fde00000 { compatible = "renesas,ether-r8a7778"; reg = <0xfde00000 0x400>; - interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7778_CLK_ETHER>; power-domains = <&cpg_clocks>; phy-mode = "rmii"; @@ -79,17 +80,17 @@ <0xfe780024 4>, <0xfe780044 4>, <0xfe780064 4>; - interrupts = <0 27 IRQ_TYPE_LEVEL_HIGH - 0 28 IRQ_TYPE_LEVEL_HIGH - 0 29 IRQ_TYPE_LEVEL_HIGH - 0 30 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; sense-bitfield-width = <2>; }; gpio0: gpio@ffc40000 { compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar"; reg = <0xffc40000 0x2c>; - interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 0 32>; @@ -100,7 +101,7 @@ gpio1: gpio@ffc41000 { compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar"; reg = <0xffc41000 0x2c>; - interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 32 32>; @@ -111,7 +112,7 @@ gpio2: gpio@ffc42000 { compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar"; reg = <0xffc42000 0x2c>; - interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 64 32>; @@ -122,7 +123,7 @@ gpio3: gpio@ffc43000 { compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar"; reg = <0xffc43000 0x2c>; - interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 96 32>; @@ -133,7 +134,7 @@ gpio4: gpio@ffc44000 { compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar"; reg = <0xffc44000 0x2c>; - interrupts = <0 103 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 128 27>; @@ -151,7 +152,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7778"; reg = <0xffc70000 0x1000>; - interrupts = <0 67 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_I2C0>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -162,7 +163,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7778"; reg = <0xffc71000 0x1000>; - interrupts = <0 78 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_I2C1>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -173,7 +174,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7778"; reg = <0xffc72000 0x1000>; - interrupts = <0 76 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_I2C2>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -184,7 +185,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7778"; reg = <0xffc73000 0x1000>; - interrupts = <0 77 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_I2C3>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -193,9 +194,9 @@ tmu0: timer@ffd80000 { compatible = "renesas,tmu-r8a7778", "renesas,tmu"; reg = <0xffd80000 0x30>; - interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>, - <0 33 IRQ_TYPE_LEVEL_HIGH>, - <0 34 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; clocks = <&mstp0_clks R8A7778_CLK_TMU0>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -208,9 +209,9 @@ tmu1: timer@ffd81000 { compatible = "renesas,tmu-r8a7778", "renesas,tmu"; reg = <0xffd81000 0x30>; - interrupts = <0 36 IRQ_TYPE_LEVEL_HIGH>, - <0 37 IRQ_TYPE_LEVEL_HIGH>, - <0 38 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; clocks = <&mstp0_clks R8A7778_CLK_TMU1>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -223,9 +224,9 @@ tmu2: timer@ffd82000 { compatible = "renesas,tmu-r8a7778", "renesas,tmu"; reg = <0xffd82000 0x30>; - interrupts = <0 40 IRQ_TYPE_LEVEL_HIGH>, - <0 41 IRQ_TYPE_LEVEL_HIGH>, - <0 42 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; clocks = <&mstp0_clks R8A7778_CLK_TMU2>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -285,72 +286,84 @@ }; rcar_sound,ssi { - ssi3: ssi@3 { interrupts = <0 0x85 IRQ_TYPE_LEVEL_HIGH>; }; - ssi4: ssi@4 { interrupts = <0 0x85 IRQ_TYPE_LEVEL_HIGH>; }; - ssi5: ssi@5 { interrupts = <0 0x86 IRQ_TYPE_LEVEL_HIGH>; }; - ssi6: ssi@6 { interrupts = <0 0x86 IRQ_TYPE_LEVEL_HIGH>; }; - ssi7: ssi@7 { interrupts = <0 0x86 IRQ_TYPE_LEVEL_HIGH>; }; - ssi8: ssi@8 { interrupts = <0 0x86 IRQ_TYPE_LEVEL_HIGH>; }; - ssi9: ssi@9 { interrupts = <0 0x86 IRQ_TYPE_LEVEL_HIGH>; }; + ssi3: ssi@3 { interrupts = ; }; + ssi4: ssi@4 { interrupts = ; }; + ssi5: ssi@5 { interrupts = ; }; + ssi6: ssi@6 { interrupts = ; }; + ssi7: ssi@7 { interrupts = ; }; + ssi8: ssi@8 { interrupts = ; }; + ssi9: ssi@9 { interrupts = ; }; }; }; scif0: serial@ffe40000 { - compatible = "renesas,scif-r8a7778", "renesas,scif"; + compatible = "renesas,scif-r8a7778", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe40000 0x100>; - interrupts = <0 70 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp0_clks R8A7778_CLK_SCIF0>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp0_clks R8A7778_CLK_SCIF0>, + <&cpg_clocks R8A7778_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; scif1: serial@ffe41000 { - compatible = "renesas,scif-r8a7778", "renesas,scif"; + compatible = "renesas,scif-r8a7778", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe41000 0x100>; - interrupts = <0 71 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp0_clks R8A7778_CLK_SCIF1>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp0_clks R8A7778_CLK_SCIF1>, + <&cpg_clocks R8A7778_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; scif2: serial@ffe42000 { - compatible = "renesas,scif-r8a7778", "renesas,scif"; + compatible = "renesas,scif-r8a7778", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe42000 0x100>; - interrupts = <0 72 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp0_clks R8A7778_CLK_SCIF2>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp0_clks R8A7778_CLK_SCIF2>, + <&cpg_clocks R8A7778_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; scif3: serial@ffe43000 { - compatible = "renesas,scif-r8a7778", "renesas,scif"; + compatible = "renesas,scif-r8a7778", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe43000 0x100>; - interrupts = <0 73 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp0_clks R8A7778_CLK_SCIF3>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp0_clks R8A7778_CLK_SCIF3>, + <&cpg_clocks R8A7778_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; scif4: serial@ffe44000 { - compatible = "renesas,scif-r8a7778", "renesas,scif"; + compatible = "renesas,scif-r8a7778", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe44000 0x100>; - interrupts = <0 74 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp0_clks R8A7778_CLK_SCIF4>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp0_clks R8A7778_CLK_SCIF4>, + <&cpg_clocks R8A7778_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; scif5: serial@ffe45000 { - compatible = "renesas,scif-r8a7778", "renesas,scif"; + compatible = "renesas,scif-r8a7778", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe45000 0x100>; - interrupts = <0 75 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp0_clks R8A7778_CLK_SCIF5>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp0_clks R8A7778_CLK_SCIF5>, + <&cpg_clocks R8A7778_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -358,7 +371,7 @@ mmcif: mmc@ffe4e000 { compatible = "renesas,sh-mmcif"; reg = <0xffe4e000 0x100>; - interrupts = <0 61 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7778_CLK_MMC>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -367,7 +380,7 @@ sdhi0: sd@ffe4c000 { compatible = "renesas,sdhi-r8a7778"; reg = <0xffe4c000 0x100>; - interrupts = <0 87 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7778_CLK_SDHI0>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -376,7 +389,7 @@ sdhi1: sd@ffe4d000 { compatible = "renesas,sdhi-r8a7778"; reg = <0xffe4d000 0x100>; - interrupts = <0 88 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7778_CLK_SDHI1>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -385,7 +398,7 @@ sdhi2: sd@ffe4f000 { compatible = "renesas,sdhi-r8a7778"; reg = <0xffe4f000 0x100>; - interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7778_CLK_SDHI2>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -394,7 +407,7 @@ hspi0: spi@fffc7000 { compatible = "renesas,hspi-r8a7778", "renesas,hspi"; reg = <0xfffc7000 0x18>; - interrupts = <0 63 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_HSPI>; power-domains = <&cpg_clocks>; #address-cells = <1>; @@ -405,7 +418,7 @@ hspi1: spi@fffc8000 { compatible = "renesas,hspi-r8a7778", "renesas,hspi"; reg = <0xfffc8000 0x18>; - interrupts = <0 84 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_HSPI>; power-domains = <&cpg_clocks>; #address-cells = <1>; @@ -416,7 +429,7 @@ hspi2: spi@fffc6000 { compatible = "renesas,hspi-r8a7778", "renesas,hspi"; reg = <0xfffc6000 0x18>; - interrupts = <0 85 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7778_CLK_HSPI>; power-domains = <&cpg_clocks>; #address-cells = <1>; @@ -437,6 +450,15 @@ clock-output-names = "extal"; }; + /* External SCIF clock */ + scif_clk: scif { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* This value must be overridden by the board. */ + clock-frequency = <0>; + status = "disabled"; + }; + /* Special CPG clocks */ cpg_clocks: cpg_clocks@ffc80000 { compatible = "renesas,r8a7778-cpg-clocks"; diff --git a/arch/arm/boot/dts/r8a7779-marzen.dts b/arch/arm/boot/dts/r8a7779-marzen.dts index fe396c8d58db798637a5fabaa74fe1f069c8089f..e111d35d02aebe19a8c9ae3bce5e10fc9686665b 100644 --- a/arch/arm/boot/dts/r8a7779-marzen.dts +++ b/arch/arm/boot/dts/r8a7779-marzen.dts @@ -165,6 +165,9 @@ }; &pfc { + pinctrl-0 = <&scif_clk_pins>; + pinctrl-names = "default"; + du_pins: du { du0 { renesas,groups = "du0_rgb888", "du0_sync_1", "du0_clk_out_0"; @@ -176,6 +179,11 @@ }; }; + scif_clk_pins: scif_clk { + renesas,groups = "scif_clk_b"; + renesas,function = "scif_clk"; + }; + ethernet_pins: ethernet { intc { renesas,groups = "intc_irq1_b"; @@ -222,6 +230,11 @@ status = "okay"; }; +&scif_clk { + clock-frequency = <14745600>; + status = "okay"; +}; + &sdhi0 { pinctrl-0 = <&sdhi0_pins>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/r8a7779.dtsi b/arch/arm/boot/dts/r8a7779.dtsi index 6afa909865b52b71c970087e90dc77860ea177e6..a0cc08e6295b03968b026e2f4b46e49b7c9d6f16 100644 --- a/arch/arm/boot/dts/r8a7779.dtsi +++ b/arch/arm/boot/dts/r8a7779.dtsi @@ -74,7 +74,7 @@ gpio0: gpio@ffc40000 { compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; reg = <0xffc40000 0x2c>; - interrupts = <0 141 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 0 32>; @@ -85,7 +85,7 @@ gpio1: gpio@ffc41000 { compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; reg = <0xffc41000 0x2c>; - interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 32 32>; @@ -96,7 +96,7 @@ gpio2: gpio@ffc42000 { compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; reg = <0xffc42000 0x2c>; - interrupts = <0 143 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 64 32>; @@ -107,7 +107,7 @@ gpio3: gpio@ffc43000 { compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; reg = <0xffc43000 0x2c>; - interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 96 32>; @@ -118,7 +118,7 @@ gpio4: gpio@ffc44000 { compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; reg = <0xffc44000 0x2c>; - interrupts = <0 145 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 128 32>; @@ -129,7 +129,7 @@ gpio5: gpio@ffc45000 { compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; reg = <0xffc45000 0x2c>; - interrupts = <0 146 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 160 32>; @@ -140,7 +140,7 @@ gpio6: gpio@ffc46000 { compatible = "renesas,gpio-r8a7779", "renesas,gpio-rcar"; reg = <0xffc46000 0x2c>; - interrupts = <0 147 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 192 9>; @@ -159,10 +159,10 @@ <0xfe780044 4>, <0xfe780064 4>, <0xfe780000 4>; - interrupts = <0 27 IRQ_TYPE_LEVEL_HIGH - 0 28 IRQ_TYPE_LEVEL_HIGH - 0 29 IRQ_TYPE_LEVEL_HIGH - 0 30 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; sense-bitfield-width = <2>; }; @@ -171,7 +171,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7779"; reg = <0xffc70000 0x1000>; - interrupts = <0 79 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7779_CLK_I2C0>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -182,7 +182,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7779"; reg = <0xffc71000 0x1000>; - interrupts = <0 82 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7779_CLK_I2C1>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -193,7 +193,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7779"; reg = <0xffc72000 0x1000>; - interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7779_CLK_I2C2>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -204,68 +204,80 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7779"; reg = <0xffc73000 0x1000>; - interrupts = <0 81 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7779_CLK_I2C3>; power-domains = <&cpg_clocks>; status = "disabled"; }; scif0: serial@ffe40000 { - compatible = "renesas,scif-r8a7779", "renesas,scif"; + compatible = "renesas,scif-r8a7779", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe40000 0x100>; - interrupts = <0 88 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp0_clks R8A7779_CLK_SCIF0>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp0_clks R8A7779_CLK_SCIF0>, + <&cpg_clocks R8A7779_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; scif1: serial@ffe41000 { - compatible = "renesas,scif-r8a7779", "renesas,scif"; + compatible = "renesas,scif-r8a7779", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe41000 0x100>; - interrupts = <0 89 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp0_clks R8A7779_CLK_SCIF1>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp0_clks R8A7779_CLK_SCIF1>, + <&cpg_clocks R8A7779_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; scif2: serial@ffe42000 { - compatible = "renesas,scif-r8a7779", "renesas,scif"; + compatible = "renesas,scif-r8a7779", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe42000 0x100>; - interrupts = <0 90 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp0_clks R8A7779_CLK_SCIF2>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp0_clks R8A7779_CLK_SCIF2>, + <&cpg_clocks R8A7779_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; scif3: serial@ffe43000 { - compatible = "renesas,scif-r8a7779", "renesas,scif"; + compatible = "renesas,scif-r8a7779", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe43000 0x100>; - interrupts = <0 91 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp0_clks R8A7779_CLK_SCIF3>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp0_clks R8A7779_CLK_SCIF3>, + <&cpg_clocks R8A7779_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; scif4: serial@ffe44000 { - compatible = "renesas,scif-r8a7779", "renesas,scif"; + compatible = "renesas,scif-r8a7779", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe44000 0x100>; - interrupts = <0 92 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp0_clks R8A7779_CLK_SCIF4>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp0_clks R8A7779_CLK_SCIF4>, + <&cpg_clocks R8A7779_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; scif5: serial@ffe45000 { - compatible = "renesas,scif-r8a7779", "renesas,scif"; + compatible = "renesas,scif-r8a7779", "renesas,rcar-gen1-scif", + "renesas,scif"; reg = <0xffe45000 0x100>; - interrupts = <0 93 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp0_clks R8A7779_CLK_SCIF5>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp0_clks R8A7779_CLK_SCIF5>, + <&cpg_clocks R8A7779_CLK_S1>, <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; power-domains = <&cpg_clocks>; status = "disabled"; }; @@ -283,9 +295,9 @@ tmu0: timer@ffd80000 { compatible = "renesas,tmu-r8a7779", "renesas,tmu"; reg = <0xffd80000 0x30>; - interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>, - <0 33 IRQ_TYPE_LEVEL_HIGH>, - <0 34 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; clocks = <&mstp0_clks R8A7779_CLK_TMU0>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -298,9 +310,9 @@ tmu1: timer@ffd81000 { compatible = "renesas,tmu-r8a7779", "renesas,tmu"; reg = <0xffd81000 0x30>; - interrupts = <0 36 IRQ_TYPE_LEVEL_HIGH>, - <0 37 IRQ_TYPE_LEVEL_HIGH>, - <0 38 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; clocks = <&mstp0_clks R8A7779_CLK_TMU1>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -313,9 +325,9 @@ tmu2: timer@ffd82000 { compatible = "renesas,tmu-r8a7779", "renesas,tmu"; reg = <0xffd82000 0x30>; - interrupts = <0 40 IRQ_TYPE_LEVEL_HIGH>, - <0 41 IRQ_TYPE_LEVEL_HIGH>, - <0 42 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; clocks = <&mstp0_clks R8A7779_CLK_TMU2>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -328,7 +340,7 @@ sata: sata@fc600000 { compatible = "renesas,sata-r8a7779", "renesas,rcar-sata"; reg = <0xfc600000 0x2000>; - interrupts = <0 100 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7779_CLK_SATA>; power-domains = <&cpg_clocks>; }; @@ -336,7 +348,7 @@ sdhi0: sd@ffe4c000 { compatible = "renesas,sdhi-r8a7779"; reg = <0xffe4c000 0x100>; - interrupts = <0 104 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7779_CLK_SDHI0>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -345,7 +357,7 @@ sdhi1: sd@ffe4d000 { compatible = "renesas,sdhi-r8a7779"; reg = <0xffe4d000 0x100>; - interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7779_CLK_SDHI1>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -354,7 +366,7 @@ sdhi2: sd@ffe4e000 { compatible = "renesas,sdhi-r8a7779"; reg = <0xffe4e000 0x100>; - interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7779_CLK_SDHI2>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -363,7 +375,7 @@ sdhi3: sd@ffe4f000 { compatible = "renesas,sdhi-r8a7779"; reg = <0xffe4f000 0x100>; - interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7779_CLK_SDHI3>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -372,7 +384,7 @@ hspi0: spi@fffc7000 { compatible = "renesas,hspi-r8a7779", "renesas,hspi"; reg = <0xfffc7000 0x18>; - interrupts = <0 73 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #address-cells = <1>; #size-cells = <0>; clocks = <&mstp0_clks R8A7779_CLK_HSPI>; @@ -383,7 +395,7 @@ hspi1: spi@fffc8000 { compatible = "renesas,hspi-r8a7779", "renesas,hspi"; reg = <0xfffc8000 0x18>; - interrupts = <0 74 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #address-cells = <1>; #size-cells = <0>; clocks = <&mstp0_clks R8A7779_CLK_HSPI>; @@ -394,7 +406,7 @@ hspi2: spi@fffc6000 { compatible = "renesas,hspi-r8a7779", "renesas,hspi"; reg = <0xfffc6000 0x18>; - interrupts = <0 75 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #address-cells = <1>; #size-cells = <0>; clocks = <&mstp0_clks R8A7779_CLK_HSPI>; @@ -405,7 +417,7 @@ du: display@fff80000 { compatible = "renesas,du-r8a7779"; reg = <0 0xfff80000 0 0x40000>; - interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7779_CLK_DU>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -441,6 +453,15 @@ clock-output-names = "extal"; }; + /* External SCIF clock */ + scif_clk: scif { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* This value must be overridden by the board. */ + clock-frequency = <0>; + status = "disabled"; + }; + /* Special CPG clocks */ cpg_clocks: clocks@ffc80000 { compatible = "renesas,r8a7779-cpg-clocks"; diff --git a/arch/arm/boot/dts/r8a7790-lager.dts b/arch/arm/boot/dts/r8a7790-lager.dts index 052dcee4790dd298d2c84b07b4574e2cb462b5bc..aa6ca92a9485b37278aa0c2a0a5519e5a84b0041 100644 --- a/arch/arm/boot/dts/r8a7790-lager.dts +++ b/arch/arm/boot/dts/r8a7790-lager.dts @@ -3,6 +3,7 @@ * * Copyright (C) 2013-2014 Renesas Solutions Corp. * Copyright (C) 2014 Cogent Embedded, Inc. + * Copyright (C) 2015-2016 Renesas Electronics Corporation * * This file is licensed under the terms of the GNU General Public License * version 2. This program is licensed "as is" without any warranty of any @@ -49,6 +50,7 @@ aliases { serial0 = &scif0; serial1 = &scifa1; + i2c8 = "i2cexio"; }; chosen { @@ -252,6 +254,23 @@ #clock-cells = <0>; clock-frequency = <148500000>; }; + + /* + * IIC0/I2C0 is routed to EXIO connector A, pins 114 (SCL) + 116 (SDA) only. + * We use the I2C demuxer, so the desired IP core can be selected at runtime + * depending on the use case (e.g. DMA with IIC0 or slave support with I2C0). + * Note: For testing the I2C slave feature, it is convenient to connect this + * bus with IIC3 on pins 110 (SCL) + 112 (SDA), select I2C0 at runtime, and + * instantiate the slave device at runtime according to the documentation. + * You can then communicate with the slave via IIC3. + */ + i2cexio: i2c@8 { + compatible = "i2c-demux-pinctrl"; + i2c-parent = <&iic0>, <&i2c0>; + i2c-bus-name = "i2c-exio"; + #address-cells = <1>; + #size-cells = <0>; + }; }; &du { @@ -291,6 +310,9 @@ }; &pfc { + pinctrl-0 = <&scif_clk_pins>; + pinctrl-names = "default"; + du_pins: du { renesas,groups = "du_rgb666", "du_sync_1", "du_clk_out_0"; renesas,function = "du"; @@ -301,6 +323,11 @@ renesas,function = "scif0"; }; + scif_clk_pins: scif_clk { + renesas,groups = "scif_clk"; + renesas,function = "scif_clk"; + }; + ether_pins: ether { renesas,groups = "eth_link", "eth_mdio", "eth_rmii"; renesas,function = "eth"; @@ -342,6 +369,11 @@ renesas,function = "msiof1"; }; + i2c0_pins: i2c0 { + renesas,groups = "i2c0"; + renesas,function = "i2c0"; + }; + iic0_pins: iic0 { renesas,groups = "iic0"; renesas,function = "iic0"; @@ -485,6 +517,11 @@ status = "okay"; }; +&scif_clk { + clock-frequency = <14745600>; + status = "okay"; +}; + &msiof1 { pinctrl-0 = <&msiof1_pins>; pinctrl-names = "default"; @@ -524,10 +561,14 @@ cpu0-supply = <&vdd_dvfs>; }; +&i2c0 { + pinctrl-0 = <&i2c0_pins>; + pinctrl-names = "i2c-exio"; +}; + &iic0 { - status = "okay"; pinctrl-0 = <&iic0_pins>; - pinctrl-names = "default"; + pinctrl-names = "i2c-exio"; }; &iic1 { diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index 7dfd393bfc7e7a5b52826139c9d4ad16a4de3841..38b706399a6b1ced5586c5e11820005319eddd80 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi @@ -52,6 +52,7 @@ voltage-tolerance = <1>; /* 1% */ clocks = <&cpg_clocks R8A7790_CLK_Z>; clock-latency = <300000>; /* 300 us */ + next-level-cache = <&L2_CA15>; /* kHz - uV - OPPs unknown yet */ operating-points = <1400000 1000000>, @@ -67,6 +68,7 @@ compatible = "arm,cortex-a15"; reg = <1>; clock-frequency = <1300000000>; + next-level-cache = <&L2_CA15>; }; cpu2: cpu@2 { @@ -74,6 +76,7 @@ compatible = "arm,cortex-a15"; reg = <2>; clock-frequency = <1300000000>; + next-level-cache = <&L2_CA15>; }; cpu3: cpu@3 { @@ -81,6 +84,7 @@ compatible = "arm,cortex-a15"; reg = <3>; clock-frequency = <1300000000>; + next-level-cache = <&L2_CA15>; }; cpu4: cpu@4 { @@ -88,6 +92,7 @@ compatible = "arm,cortex-a7"; reg = <0x100>; clock-frequency = <780000000>; + next-level-cache = <&L2_CA7>; }; cpu5: cpu@5 { @@ -95,6 +100,7 @@ compatible = "arm,cortex-a7"; reg = <0x101>; clock-frequency = <780000000>; + next-level-cache = <&L2_CA7>; }; cpu6: cpu@6 { @@ -102,6 +108,7 @@ compatible = "arm,cortex-a7"; reg = <0x102>; clock-frequency = <780000000>; + next-level-cache = <&L2_CA7>; }; cpu7: cpu@7 { @@ -109,9 +116,41 @@ compatible = "arm,cortex-a7"; reg = <0x103>; clock-frequency = <780000000>; + next-level-cache = <&L2_CA7>; }; }; + thermal-zones { + cpu_thermal: cpu-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + + thermal-sensors = <&thermal>; + + trips { + cpu-crit { + temperature = <115000>; + hysteresis = <0>; + type = "critical"; + }; + }; + cooling-maps { + }; + }; + }; + + L2_CA15: cache-controller@0 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + }; + + L2_CA7: cache-controller@1 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + }; + gic: interrupt-controller@f1001000 { compatible = "arm,gic-400"; #interrupt-cells = <3>; @@ -121,13 +160,13 @@ <0 0xf1002000 0 0x1000>, <0 0xf1004000 0 0x2000>, <0 0xf1006000 0 0x2000>; - interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; + interrupts = ; }; gpio0: gpio@e6050000 { compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar"; reg = <0 0xe6050000 0 0x50>; - interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 0 32>; @@ -140,7 +179,7 @@ gpio1: gpio@e6051000 { compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar"; reg = <0 0xe6051000 0 0x50>; - interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 32 30>; @@ -153,7 +192,7 @@ gpio2: gpio@e6052000 { compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar"; reg = <0 0xe6052000 0 0x50>; - interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 64 30>; @@ -166,7 +205,7 @@ gpio3: gpio@e6053000 { compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar"; reg = <0 0xe6053000 0 0x50>; - interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 96 32>; @@ -179,7 +218,7 @@ gpio4: gpio@e6054000 { compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar"; reg = <0 0xe6054000 0 0x50>; - interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 128 32>; @@ -192,7 +231,7 @@ gpio5: gpio@e6055000 { compatible = "renesas,gpio-r8a7790", "renesas,gpio-rcar"; reg = <0 0xe6055000 0 0x50>; - interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 160 32>; @@ -202,27 +241,30 @@ power-domains = <&cpg_clocks>; }; - thermal@e61f0000 { - compatible = "renesas,thermal-r8a7790", "renesas,rcar-thermal"; + thermal: thermal@e61f0000 { + compatible = "renesas,thermal-r8a7790", + "renesas,rcar-gen2-thermal", + "renesas,rcar-thermal"; reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>; - interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp5_clks R8A7790_CLK_THERMAL>; power-domains = <&cpg_clocks>; + #thermal-sensor-cells = <0>; }; timer { compatible = "arm,armv7-timer"; - interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, - <1 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, - <1 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, - <1 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; }; cmt0: timer@ffca0000 { compatible = "renesas,cmt-48-r8a7790", "renesas,cmt-48-gen2"; reg = <0 0xffca0000 0 0x1004>; - interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>, - <0 143 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; clocks = <&mstp1_clks R8A7790_CLK_CMT0>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -235,14 +277,14 @@ cmt1: timer@e6130000 { compatible = "renesas,cmt-48-r8a7790", "renesas,cmt-48-gen2"; reg = <0 0xe6130000 0 0x1004>; - interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>, - <0 121 IRQ_TYPE_LEVEL_HIGH>, - <0 122 IRQ_TYPE_LEVEL_HIGH>, - <0 123 IRQ_TYPE_LEVEL_HIGH>, - <0 124 IRQ_TYPE_LEVEL_HIGH>, - <0 125 IRQ_TYPE_LEVEL_HIGH>, - <0 126 IRQ_TYPE_LEVEL_HIGH>, - <0 127 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + ; clocks = <&mstp3_clks R8A7790_CLK_CMT1>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -257,10 +299,10 @@ #interrupt-cells = <2>; interrupt-controller; reg = <0 0xe61c0000 0 0x200>; - interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>, - <0 1 IRQ_TYPE_LEVEL_HIGH>, - <0 2 IRQ_TYPE_LEVEL_HIGH>, - <0 3 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + ; clocks = <&mstp4_clks R8A7790_CLK_IRQC>; power-domains = <&cpg_clocks>; }; @@ -268,22 +310,22 @@ dmac0: dma-controller@e6700000 { compatible = "renesas,dmac-r8a7790", "renesas,rcar-dmac"; reg = <0 0xe6700000 0 0x20000>; - interrupts = <0 197 IRQ_TYPE_LEVEL_HIGH - 0 200 IRQ_TYPE_LEVEL_HIGH - 0 201 IRQ_TYPE_LEVEL_HIGH - 0 202 IRQ_TYPE_LEVEL_HIGH - 0 203 IRQ_TYPE_LEVEL_HIGH - 0 204 IRQ_TYPE_LEVEL_HIGH - 0 205 IRQ_TYPE_LEVEL_HIGH - 0 206 IRQ_TYPE_LEVEL_HIGH - 0 207 IRQ_TYPE_LEVEL_HIGH - 0 208 IRQ_TYPE_LEVEL_HIGH - 0 209 IRQ_TYPE_LEVEL_HIGH - 0 210 IRQ_TYPE_LEVEL_HIGH - 0 211 IRQ_TYPE_LEVEL_HIGH - 0 212 IRQ_TYPE_LEVEL_HIGH - 0 213 IRQ_TYPE_LEVEL_HIGH - 0 214 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -299,22 +341,22 @@ dmac1: dma-controller@e6720000 { compatible = "renesas,dmac-r8a7790", "renesas,rcar-dmac"; reg = <0 0xe6720000 0 0x20000>; - interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH - 0 216 IRQ_TYPE_LEVEL_HIGH - 0 217 IRQ_TYPE_LEVEL_HIGH - 0 218 IRQ_TYPE_LEVEL_HIGH - 0 219 IRQ_TYPE_LEVEL_HIGH - 0 308 IRQ_TYPE_LEVEL_HIGH - 0 309 IRQ_TYPE_LEVEL_HIGH - 0 310 IRQ_TYPE_LEVEL_HIGH - 0 311 IRQ_TYPE_LEVEL_HIGH - 0 312 IRQ_TYPE_LEVEL_HIGH - 0 313 IRQ_TYPE_LEVEL_HIGH - 0 314 IRQ_TYPE_LEVEL_HIGH - 0 315 IRQ_TYPE_LEVEL_HIGH - 0 316 IRQ_TYPE_LEVEL_HIGH - 0 317 IRQ_TYPE_LEVEL_HIGH - 0 318 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -330,20 +372,20 @@ audma0: dma-controller@ec700000 { compatible = "renesas,dmac-r8a7790", "renesas,rcar-dmac"; reg = <0 0xec700000 0 0x10000>; - interrupts = <0 346 IRQ_TYPE_LEVEL_HIGH - 0 320 IRQ_TYPE_LEVEL_HIGH - 0 321 IRQ_TYPE_LEVEL_HIGH - 0 322 IRQ_TYPE_LEVEL_HIGH - 0 323 IRQ_TYPE_LEVEL_HIGH - 0 324 IRQ_TYPE_LEVEL_HIGH - 0 325 IRQ_TYPE_LEVEL_HIGH - 0 326 IRQ_TYPE_LEVEL_HIGH - 0 327 IRQ_TYPE_LEVEL_HIGH - 0 328 IRQ_TYPE_LEVEL_HIGH - 0 329 IRQ_TYPE_LEVEL_HIGH - 0 330 IRQ_TYPE_LEVEL_HIGH - 0 331 IRQ_TYPE_LEVEL_HIGH - 0 332 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -359,20 +401,20 @@ audma1: dma-controller@ec720000 { compatible = "renesas,dmac-r8a7790", "renesas,rcar-dmac"; reg = <0 0xec720000 0 0x10000>; - interrupts = <0 347 IRQ_TYPE_LEVEL_HIGH - 0 333 IRQ_TYPE_LEVEL_HIGH - 0 334 IRQ_TYPE_LEVEL_HIGH - 0 335 IRQ_TYPE_LEVEL_HIGH - 0 336 IRQ_TYPE_LEVEL_HIGH - 0 337 IRQ_TYPE_LEVEL_HIGH - 0 338 IRQ_TYPE_LEVEL_HIGH - 0 339 IRQ_TYPE_LEVEL_HIGH - 0 340 IRQ_TYPE_LEVEL_HIGH - 0 341 IRQ_TYPE_LEVEL_HIGH - 0 342 IRQ_TYPE_LEVEL_HIGH - 0 343 IRQ_TYPE_LEVEL_HIGH - 0 344 IRQ_TYPE_LEVEL_HIGH - 0 345 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -388,8 +430,8 @@ usb_dmac0: dma-controller@e65a0000 { compatible = "renesas,r8a7790-usb-dmac", "renesas,usb-dmac"; reg = <0 0xe65a0000 0 0x100>; - interrupts = <0 109 IRQ_TYPE_LEVEL_HIGH - 0 109 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "ch0", "ch1"; clocks = <&mstp3_clks R8A7790_CLK_USBDMAC0>; power-domains = <&cpg_clocks>; @@ -400,8 +442,8 @@ usb_dmac1: dma-controller@e65b0000 { compatible = "renesas,r8a7790-usb-dmac", "renesas,usb-dmac"; reg = <0 0xe65b0000 0 0x100>; - interrupts = <0 110 IRQ_TYPE_LEVEL_HIGH - 0 110 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "ch0", "ch1"; clocks = <&mstp3_clks R8A7790_CLK_USBDMAC1>; power-domains = <&cpg_clocks>; @@ -414,7 +456,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7790"; reg = <0 0xe6508000 0 0x40>; - interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7790_CLK_I2C0>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <110>; @@ -426,7 +468,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7790"; reg = <0 0xe6518000 0 0x40>; - interrupts = <0 288 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7790_CLK_I2C1>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <6>; @@ -438,7 +480,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7790"; reg = <0 0xe6530000 0 0x40>; - interrupts = <0 286 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7790_CLK_I2C2>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <6>; @@ -450,7 +492,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7790"; reg = <0 0xe6540000 0 0x40>; - interrupts = <0 290 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7790_CLK_I2C3>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <110>; @@ -462,7 +504,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a7790", "renesas,rmobile-iic"; reg = <0 0xe6500000 0 0x425>; - interrupts = <0 174 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7790_CLK_IIC0>; dmas = <&dmac0 0x61>, <&dmac0 0x62>; dma-names = "tx", "rx"; @@ -475,7 +517,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a7790", "renesas,rmobile-iic"; reg = <0 0xe6510000 0 0x425>; - interrupts = <0 175 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7790_CLK_IIC1>; dmas = <&dmac0 0x65>, <&dmac0 0x66>; dma-names = "tx", "rx"; @@ -488,7 +530,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a7790", "renesas,rmobile-iic"; reg = <0 0xe6520000 0 0x425>; - interrupts = <0 176 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7790_CLK_IIC2>; dmas = <&dmac0 0x69>, <&dmac0 0x6a>; dma-names = "tx", "rx"; @@ -501,7 +543,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a7790", "renesas,rmobile-iic"; reg = <0 0xe60b0000 0 0x425>; - interrupts = <0 173 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7790_CLK_IICDVFS>; dmas = <&dmac0 0x77>, <&dmac0 0x78>; dma-names = "tx", "rx"; @@ -512,7 +554,7 @@ mmcif0: mmc@ee200000 { compatible = "renesas,mmcif-r8a7790", "renesas,sh-mmcif"; reg = <0 0xee200000 0 0x80>; - interrupts = <0 169 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7790_CLK_MMCIF0>; dmas = <&dmac0 0xd1>, <&dmac0 0xd2>; dma-names = "tx", "rx"; @@ -525,7 +567,7 @@ mmcif1: mmc@ee220000 { compatible = "renesas,mmcif-r8a7790", "renesas,sh-mmcif"; reg = <0 0xee220000 0 0x80>; - interrupts = <0 170 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7790_CLK_MMCIF1>; dmas = <&dmac0 0xe1>, <&dmac0 0xe2>; dma-names = "tx", "rx"; @@ -543,7 +585,7 @@ sdhi0: sd@ee100000 { compatible = "renesas,sdhi-r8a7790"; reg = <0 0xee100000 0 0x328>; - interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7790_CLK_SDHI0>; dmas = <&dmac1 0xcd>, <&dmac1 0xce>; dma-names = "tx", "rx"; @@ -554,7 +596,7 @@ sdhi1: sd@ee120000 { compatible = "renesas,sdhi-r8a7790"; reg = <0 0xee120000 0 0x328>; - interrupts = <0 166 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7790_CLK_SDHI1>; dmas = <&dmac1 0xc9>, <&dmac1 0xca>; dma-names = "tx", "rx"; @@ -565,7 +607,7 @@ sdhi2: sd@ee140000 { compatible = "renesas,sdhi-r8a7790"; reg = <0 0xee140000 0 0x100>; - interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7790_CLK_SDHI2>; dmas = <&dmac1 0xc1>, <&dmac1 0xc2>; dma-names = "tx", "rx"; @@ -576,7 +618,7 @@ sdhi3: sd@ee160000 { compatible = "renesas,sdhi-r8a7790"; reg = <0 0xee160000 0 0x100>; - interrupts = <0 168 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7790_CLK_SDHI3>; dmas = <&dmac1 0xd3>, <&dmac1 0xd4>; dma-names = "tx", "rx"; @@ -585,11 +627,12 @@ }; scifa0: serial@e6c40000 { - compatible = "renesas,scifa-r8a7790", "renesas,scifa"; + compatible = "renesas,scifa-r8a7790", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c40000 0 64>; - interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_SCIFA0>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x21>, <&dmac0 0x22>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -597,11 +640,12 @@ }; scifa1: serial@e6c50000 { - compatible = "renesas,scifa-r8a7790", "renesas,scifa"; + compatible = "renesas,scifa-r8a7790", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c50000 0 64>; - interrupts = <0 145 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_SCIFA1>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x25>, <&dmac0 0x26>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -609,11 +653,12 @@ }; scifa2: serial@e6c60000 { - compatible = "renesas,scifa-r8a7790", "renesas,scifa"; + compatible = "renesas,scifa-r8a7790", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c60000 0 64>; - interrupts = <0 151 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_SCIFA2>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x27>, <&dmac0 0x28>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -621,11 +666,12 @@ }; scifb0: serial@e6c20000 { - compatible = "renesas,scifb-r8a7790", "renesas,scifb"; + compatible = "renesas,scifb-r8a7790", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6c20000 0 64>; - interrupts = <0 148 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_SCIFB0>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x3d>, <&dmac0 0x3e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -633,11 +679,12 @@ }; scifb1: serial@e6c30000 { - compatible = "renesas,scifb-r8a7790", "renesas,scifb"; + compatible = "renesas,scifb-r8a7790", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6c30000 0 64>; - interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_SCIFB1>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x19>, <&dmac0 0x1a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -645,11 +692,12 @@ }; scifb2: serial@e6ce0000 { - compatible = "renesas,scifb-r8a7790", "renesas,scifb"; + compatible = "renesas,scifb-r8a7790", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6ce0000 0 64>; - interrupts = <0 150 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_SCIFB2>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x1d>, <&dmac0 0x1e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -657,11 +705,13 @@ }; scif0: serial@e6e60000 { - compatible = "renesas,scif-r8a7790", "renesas,scif"; + compatible = "renesas,scif-r8a7790", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6e60000 0 64>; - interrupts = <0 152 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7790_CLK_SCIF0>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7790_CLK_SCIF0>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x29>, <&dmac0 0x2a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -669,11 +719,13 @@ }; scif1: serial@e6e68000 { - compatible = "renesas,scif-r8a7790", "renesas,scif"; + compatible = "renesas,scif-r8a7790", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6e68000 0 64>; - interrupts = <0 153 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7790_CLK_SCIF1>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7790_CLK_SCIF1>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x2d>, <&dmac0 0x2e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -681,11 +733,13 @@ }; hscif0: serial@e62c0000 { - compatible = "renesas,hscif-r8a7790", "renesas,hscif"; + compatible = "renesas,hscif-r8a7790", + "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62c0000 0 96>; - interrupts = <0 154 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7790_CLK_HSCIF0>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7790_CLK_HSCIF0>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x39>, <&dmac0 0x3a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -693,11 +747,13 @@ }; hscif1: serial@e62c8000 { - compatible = "renesas,hscif-r8a7790", "renesas,hscif"; + compatible = "renesas,hscif-r8a7790", + "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62c8000 0 96>; - interrupts = <0 155 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7790_CLK_HSCIF1>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7790_CLK_HSCIF1>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x4d>, <&dmac0 0x4e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -707,7 +763,7 @@ ether: ethernet@ee700000 { compatible = "renesas,ether-r8a7790"; reg = <0 0xee700000 0 0x400>; - interrupts = <0 162 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_ETHER>; power-domains = <&cpg_clocks>; phy-mode = "rmii"; @@ -717,9 +773,10 @@ }; avb: ethernet@e6800000 { - compatible = "renesas,etheravb-r8a7790"; + compatible = "renesas,etheravb-r8a7790", + "renesas,etheravb-rcar-gen2"; reg = <0 0xe6800000 0 0x800>, <0 0xee0e8000 0 0x4000>; - interrupts = <0 163 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_ETHERAVB>; power-domains = <&cpg_clocks>; #address-cells = <1>; @@ -730,7 +787,7 @@ sata0: sata@ee300000 { compatible = "renesas,sata-r8a7790"; reg = <0 0xee300000 0 0x2000>; - interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_SATA0>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -739,16 +796,16 @@ sata1: sata@ee500000 { compatible = "renesas,sata-r8a7790"; reg = <0 0xee500000 0 0x2000>; - interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_SATA1>; power-domains = <&cpg_clocks>; status = "disabled"; }; hsusb: usb@e6590000 { - compatible = "renesas,usbhs-r8a7790"; + compatible = "renesas,usbhs-r8a7790", "renesas,rcar-gen2-usbhs"; reg = <0 0xe6590000 0 0x100>; - interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7790_CLK_HSUSB>; dmas = <&usb_dmac0 0>, <&usb_dmac0 1>, <&usb_dmac1 0>, <&usb_dmac1 1>; @@ -783,7 +840,7 @@ vin0: video@e6ef0000 { compatible = "renesas,vin-r8a7790"; reg = <0 0xe6ef0000 0 0x1000>; - interrupts = <0 188 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_VIN0>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -792,7 +849,7 @@ vin1: video@e6ef1000 { compatible = "renesas,vin-r8a7790"; reg = <0 0xe6ef1000 0 0x1000>; - interrupts = <0 189 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_VIN1>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -801,7 +858,7 @@ vin2: video@e6ef2000 { compatible = "renesas,vin-r8a7790"; reg = <0 0xe6ef2000 0 0x1000>; - interrupts = <0 190 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_VIN2>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -810,7 +867,7 @@ vin3: video@e6ef3000 { compatible = "renesas,vin-r8a7790"; reg = <0 0xe6ef3000 0 0x1000>; - interrupts = <0 191 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7790_CLK_VIN3>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -819,7 +876,7 @@ vsp1@fe920000 { compatible = "renesas,vsp1"; reg = <0 0xfe920000 0 0x8000>; - interrupts = <0 266 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7790_CLK_VSP1_R>; power-domains = <&cpg_clocks>; @@ -832,7 +889,7 @@ vsp1@fe928000 { compatible = "renesas,vsp1"; reg = <0 0xfe928000 0 0x8000>; - interrupts = <0 267 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7790_CLK_VSP1_S>; power-domains = <&cpg_clocks>; @@ -846,7 +903,7 @@ vsp1@fe930000 { compatible = "renesas,vsp1"; reg = <0 0xfe930000 0 0x8000>; - interrupts = <0 246 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7790_CLK_VSP1_DU0>; power-domains = <&cpg_clocks>; @@ -860,7 +917,7 @@ vsp1@fe938000 { compatible = "renesas,vsp1"; reg = <0 0xfe938000 0 0x8000>; - interrupts = <0 247 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7790_CLK_VSP1_DU1>; power-domains = <&cpg_clocks>; @@ -877,9 +934,9 @@ <0 0xfeb90000 0 0x1c>, <0 0xfeb94000 0 0x1c>; reg-names = "du", "lvds.0", "lvds.1"; - interrupts = <0 256 IRQ_TYPE_LEVEL_HIGH>, - <0 268 IRQ_TYPE_LEVEL_HIGH>, - <0 269 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; clocks = <&mstp7_clks R8A7790_CLK_DU0>, <&mstp7_clks R8A7790_CLK_DU1>, <&mstp7_clks R8A7790_CLK_DU2>, @@ -913,7 +970,7 @@ can0: can@e6e80000 { compatible = "renesas,can-r8a7790"; reg = <0 0xe6e80000 0 0x1000>; - interrupts = <0 186 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7790_CLK_RCAN0>, <&cpg_clocks R8A7790_CLK_RCAN>, <&can_clk>; clock-names = "clkp1", "clkp2", "can_clk"; @@ -924,7 +981,7 @@ can1: can@e6e88000 { compatible = "renesas,can-r8a7790"; reg = <0 0xe6e88000 0 0x1000>; - interrupts = <0 187 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7790_CLK_RCAN1>, <&cpg_clocks R8A7790_CLK_RCAN>, <&can_clk>; clock-names = "clkp1", "clkp2", "can_clk"; @@ -935,7 +992,7 @@ jpu: jpeg-codec@fe980000 { compatible = "renesas,jpu-r8a7790"; reg = <0 0xfe980000 0 0x10300>; - interrupts = <0 272 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7790_CLK_JPU>; power-domains = <&cpg_clocks>; }; @@ -986,6 +1043,15 @@ clock-output-names = "audio_clk_c"; }; + /* External SCIF clock */ + scif_clk: scif { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* This value must be overridden by the board. */ + clock-frequency = <0>; + status = "disabled"; + }; + /* External USB clock - can be overridden by the board */ usb_extal_clk: usb_extal_clk { compatible = "fixed-clock"; @@ -1401,7 +1467,7 @@ qspi: spi@e6b10000 { compatible = "renesas,qspi-r8a7790", "renesas,qspi"; reg = <0 0xe6b10000 0 0x2c>; - interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7790_CLK_QSPI_MOD>; dmas = <&dmac0 0x17>, <&dmac0 0x18>; dma-names = "tx", "rx"; @@ -1415,7 +1481,7 @@ msiof0: spi@e6e20000 { compatible = "renesas,msiof-r8a7790"; reg = <0 0xe6e20000 0 0x0064>; - interrupts = <0 156 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7790_CLK_MSIOF0>; dmas = <&dmac0 0x51>, <&dmac0 0x52>; dma-names = "tx", "rx"; @@ -1428,7 +1494,7 @@ msiof1: spi@e6e10000 { compatible = "renesas,msiof-r8a7790"; reg = <0 0xe6e10000 0 0x0064>; - interrupts = <0 157 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_MSIOF1>; dmas = <&dmac0 0x55>, <&dmac0 0x56>; dma-names = "tx", "rx"; @@ -1441,7 +1507,7 @@ msiof2: spi@e6e00000 { compatible = "renesas,msiof-r8a7790"; reg = <0 0xe6e00000 0 0x0064>; - interrupts = <0 158 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_MSIOF2>; dmas = <&dmac0 0x41>, <&dmac0 0x42>; dma-names = "tx", "rx"; @@ -1454,7 +1520,7 @@ msiof3: spi@e6c90000 { compatible = "renesas,msiof-r8a7790"; reg = <0 0xe6c90000 0 0x0064>; - interrupts = <0 159 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7790_CLK_MSIOF3>; dmas = <&dmac0 0x45>, <&dmac0 0x46>; dma-names = "tx", "rx"; @@ -1467,7 +1533,7 @@ xhci: usb@ee000000 { compatible = "renesas,xhci-r8a7790"; reg = <0 0xee000000 0 0xc00>; - interrupts = <0 101 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7790_CLK_SSUSB>; power-domains = <&cpg_clocks>; phys = <&usb2 1>; @@ -1476,11 +1542,11 @@ }; pci0: pci@ee090000 { - compatible = "renesas,pci-r8a7790"; + compatible = "renesas,pci-r8a7790", "renesas,pci-rcar-gen2"; device_type = "pci"; reg = <0 0xee090000 0 0xc00>, <0 0xee080000 0 0x1100>; - interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7790_CLK_EHCI>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -1491,9 +1557,9 @@ #interrupt-cells = <1>; ranges = <0x02000000 0 0xee080000 0 0xee080000 0 0x00010000>; interrupt-map-mask = <0xff00 0 0 0x7>; - interrupt-map = <0x0000 0 0 1 &gic 0 108 IRQ_TYPE_LEVEL_HIGH - 0x0800 0 0 1 &gic 0 108 IRQ_TYPE_LEVEL_HIGH - 0x1000 0 0 2 &gic 0 108 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH + 0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH + 0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>; usb@0,1 { reg = <0x800 0 0 0 0>; @@ -1511,11 +1577,11 @@ }; pci1: pci@ee0b0000 { - compatible = "renesas,pci-r8a7790"; + compatible = "renesas,pci-r8a7790", "renesas,pci-rcar-gen2"; device_type = "pci"; reg = <0 0xee0b0000 0 0xc00>, <0 0xee0a0000 0 0x1100>; - interrupts = <0 112 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7790_CLK_EHCI>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -1526,19 +1592,19 @@ #interrupt-cells = <1>; ranges = <0x02000000 0 0xee0a0000 0 0xee0a0000 0 0x00010000>; interrupt-map-mask = <0xff00 0 0 0x7>; - interrupt-map = <0x0000 0 0 1 &gic 0 112 IRQ_TYPE_LEVEL_HIGH - 0x0800 0 0 1 &gic 0 112 IRQ_TYPE_LEVEL_HIGH - 0x1000 0 0 2 &gic 0 112 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH + 0x0800 0 0 1 &gic GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH + 0x1000 0 0 2 &gic GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>; }; pci2: pci@ee0d0000 { - compatible = "renesas,pci-r8a7790"; + compatible = "renesas,pci-r8a7790", "renesas,pci-rcar-gen2"; device_type = "pci"; clocks = <&mstp7_clks R8A7790_CLK_EHCI>; power-domains = <&cpg_clocks>; reg = <0 0xee0d0000 0 0xc00>, <0 0xee0c0000 0 0x1100>; - interrupts = <0 113 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; status = "disabled"; bus-range = <2 2>; @@ -1547,9 +1613,9 @@ #interrupt-cells = <1>; ranges = <0x02000000 0 0xee0c0000 0 0xee0c0000 0 0x00010000>; interrupt-map-mask = <0xff00 0 0 0x7>; - interrupt-map = <0x0000 0 0 1 &gic 0 113 IRQ_TYPE_LEVEL_HIGH - 0x0800 0 0 1 &gic 0 113 IRQ_TYPE_LEVEL_HIGH - 0x1000 0 0 2 &gic 0 113 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH + 0x0800 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH + 0x1000 0 0 2 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; usb@0,1 { reg = <0x800 0 0 0 0>; @@ -1567,7 +1633,7 @@ }; pciec: pcie@fe000000 { - compatible = "renesas,pcie-r8a7790"; + compatible = "renesas,pcie-r8a7790", "renesas,pcie-rcar-gen2"; reg = <0 0xfe000000 0 0x80000>; #address-cells = <3>; #size-cells = <2>; @@ -1580,12 +1646,12 @@ /* Map all possible DDR as inbound ranges */ dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000 0x43000000 1 0x80000000 1 0x80000000 0 0x80000000>; - interrupts = <0 116 IRQ_TYPE_LEVEL_HIGH>, - <0 117 IRQ_TYPE_LEVEL_HIGH>, - <0 118 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &gic 0 116 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0 0 0 0 &gic GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>; clocks = <&mstp3_clks R8A7790_CLK_PCIEC>, <&pcie_bus_clk>; clock-names = "pcie", "pcie_bus"; power-domains = <&cpg_clocks>; @@ -1664,52 +1730,52 @@ rcar_sound,src { src0: src@0 { - interrupts = <0 352 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x85>, <&audma1 0x9a>; dma-names = "rx", "tx"; }; src1: src@1 { - interrupts = <0 353 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x87>, <&audma1 0x9c>; dma-names = "rx", "tx"; }; src2: src@2 { - interrupts = <0 354 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x89>, <&audma1 0x9e>; dma-names = "rx", "tx"; }; src3: src@3 { - interrupts = <0 355 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x8b>, <&audma1 0xa0>; dma-names = "rx", "tx"; }; src4: src@4 { - interrupts = <0 356 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x8d>, <&audma1 0xb0>; dma-names = "rx", "tx"; }; src5: src@5 { - interrupts = <0 357 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x8f>, <&audma1 0xb2>; dma-names = "rx", "tx"; }; src6: src@6 { - interrupts = <0 358 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x91>, <&audma1 0xb4>; dma-names = "rx", "tx"; }; src7: src@7 { - interrupts = <0 359 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x93>, <&audma1 0xb6>; dma-names = "rx", "tx"; }; src8: src@8 { - interrupts = <0 360 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x95>, <&audma1 0xb8>; dma-names = "rx", "tx"; }; src9: src@9 { - interrupts = <0 361 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x97>, <&audma1 0xba>; dma-names = "rx", "tx"; }; @@ -1717,52 +1783,52 @@ rcar_sound,ssi { ssi0: ssi@0 { - interrupts = <0 370 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x01>, <&audma1 0x02>, <&audma0 0x15>, <&audma1 0x16>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi1: ssi@1 { - interrupts = <0 371 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x03>, <&audma1 0x04>, <&audma0 0x49>, <&audma1 0x4a>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi2: ssi@2 { - interrupts = <0 372 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x05>, <&audma1 0x06>, <&audma0 0x63>, <&audma1 0x64>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi3: ssi@3 { - interrupts = <0 373 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x07>, <&audma1 0x08>, <&audma0 0x6f>, <&audma1 0x70>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi4: ssi@4 { - interrupts = <0 374 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x09>, <&audma1 0x0a>, <&audma0 0x71>, <&audma1 0x72>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi5: ssi@5 { - interrupts = <0 375 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x0b>, <&audma1 0x0c>, <&audma0 0x73>, <&audma1 0x74>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi6: ssi@6 { - interrupts = <0 376 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x0d>, <&audma1 0x0e>, <&audma0 0x75>, <&audma1 0x76>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi7: ssi@7 { - interrupts = <0 377 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x0f>, <&audma1 0x10>, <&audma0 0x79>, <&audma1 0x7a>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi8: ssi@8 { - interrupts = <0 378 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x11>, <&audma1 0x12>, <&audma0 0x7b>, <&audma1 0x7c>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi9: ssi@9 { - interrupts = <0 379 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x13>, <&audma1 0x14>, <&audma0 0x7d>, <&audma1 0x7e>; dma-names = "rx", "tx", "rxu", "txu"; }; @@ -1772,8 +1838,8 @@ ipmmu_sy0: mmu@e6280000 { compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa"; reg = <0 0xe6280000 0 0x1000>; - interrupts = <0 223 IRQ_TYPE_LEVEL_HIGH>, - <0 224 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -1781,7 +1847,7 @@ ipmmu_sy1: mmu@e6290000 { compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa"; reg = <0 0xe6290000 0 0x1000>; - interrupts = <0 225 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #iommu-cells = <1>; status = "disabled"; }; @@ -1789,8 +1855,8 @@ ipmmu_ds: mmu@e6740000 { compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa"; reg = <0 0xe6740000 0 0x1000>; - interrupts = <0 198 IRQ_TYPE_LEVEL_HIGH>, - <0 199 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -1798,7 +1864,7 @@ ipmmu_mp: mmu@ec680000 { compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa"; reg = <0 0xec680000 0 0x1000>; - interrupts = <0 226 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #iommu-cells = <1>; status = "disabled"; }; @@ -1806,8 +1872,8 @@ ipmmu_mx: mmu@fe951000 { compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa"; reg = <0 0xfe951000 0 0x1000>; - interrupts = <0 222 IRQ_TYPE_LEVEL_HIGH>, - <0 221 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -1815,7 +1881,7 @@ ipmmu_rt: mmu@ffc80000 { compatible = "renesas,ipmmu-r8a7790", "renesas,ipmmu-vmsa"; reg = <0 0xffc80000 0 0x1000>; - interrupts = <0 307 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #iommu-cells = <1>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/r8a7791-koelsch.dts b/arch/arm/boot/dts/r8a7791-koelsch.dts index 45256f3cc83560a80fa91b6313b46e0bed4f5a23..0ad71b81d3a25f59aeaa3e329de0ac9f55c0cdad 100644 --- a/arch/arm/boot/dts/r8a7791-koelsch.dts +++ b/arch/arm/boot/dts/r8a7791-koelsch.dts @@ -320,6 +320,9 @@ }; &pfc { + pinctrl-0 = <&scif_clk_pins>; + pinctrl-names = "default"; + i2c2_pins: i2c2 { renesas,groups = "i2c2"; renesas,function = "i2c2"; @@ -340,6 +343,11 @@ renesas,function = "scif1"; }; + scif_clk_pins: scif_clk { + renesas,groups = "scif_clk"; + renesas,function = "scif_clk"; + }; + ether_pins: ether { renesas,groups = "eth_link", "eth_mdio", "eth_rmii"; renesas,function = "eth"; @@ -440,6 +448,11 @@ status = "okay"; }; +&scif_clk { + clock-frequency = <14745600>; + status = "okay"; +}; + &sdhi0 { pinctrl-0 = <&sdhi0_pins>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/r8a7791-porter.dts b/arch/arm/boot/dts/r8a7791-porter.dts index 01d239c3eaaaa3fe4ca8ab7854fbca9faa3e23e4..6c08314427d6aab2e54d016319d8cc532bacdbdc 100644 --- a/arch/arm/boot/dts/r8a7791-porter.dts +++ b/arch/arm/boot/dts/r8a7791-porter.dts @@ -8,6 +8,17 @@ * kind, whether express or implied. */ +/* + * SSI-AK4642 + * + * JP3: 2-1: AK4642 + * 2-3: ADV7511 + * + * This command is required before playback/capture: + * + * amixer set "LINEOUT Mixer DACL" on + */ + /dts-v1/; #include "r8a7791.dtsi" #include @@ -78,6 +89,53 @@ states = <3300000 1 1800000 0>; }; + + hdmi-out { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_con: endpoint { + remote-endpoint = <&adv7511_out>; + }; + }; + }; + + x3_clk: x3-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <148500000>; + }; + + x16_clk: x16-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <74250000>; + }; + + x14_clk: x14-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <11289600>; + clock-output-names = "audio_clock"; + }; + + sound { + compatible = "simple-audio-card"; + + simple-audio-card,format = "left_j"; + simple-audio-card,bitclock-master = <&soundcodec>; + simple-audio-card,frame-master = <&soundcodec>; + + simple-audio-card,cpu { + sound-dai = <&rcar_sound>; + }; + + soundcodec: simple-audio-card,codec { + sound-dai = <&ak4642>; + clocks = <&x14_clk>; + }; + }; }; &extal_clk { @@ -85,11 +143,19 @@ }; &pfc { + pinctrl-0 = <&scif_clk_pins>; + pinctrl-names = "default"; + scif0_pins: serial0 { renesas,groups = "scif0_data_d"; renesas,function = "scif0"; }; + scif_clk_pins: scif_clk { + renesas,groups = "scif_clk"; + renesas,function = "scif_clk"; + }; + ether_pins: ether { renesas,groups = "eth_link", "eth_mdio", "eth_rmii"; renesas,function = "eth"; @@ -139,6 +205,21 @@ renesas,groups = "can0_data"; renesas,function = "can0"; }; + + du_pins: du { + renesas,groups = "du_rgb888", "du_sync", "du_disp", "du_clk_out_0"; + renesas,function = "du"; + }; + + ssi_pins: sound { + renesas,groups = "ssi0129_ctrl", "ssi0_data", "ssi1_data"; + renesas,function = "ssi"; + }; + + audio_clk_pins: audio_clk { + renesas,groups = "audio_clk_a"; + renesas,function = "audio_clk"; + }; }; &scif0 { @@ -148,6 +229,11 @@ status = "okay"; }; +&scif_clk { + clock-frequency = <14745600>; + status = "okay"; +}; + ðer { pinctrl-0 = <ðer_pins &phy1_pins>; pinctrl-names = "default"; @@ -229,6 +315,12 @@ status = "okay"; clock-frequency = <400000>; + ak4642: codec@12 { + compatible = "asahi-kasei,ak4642"; + #sound-dai-cells = <0>; + reg = <0x12>; + }; + composite-in@20 { compatible = "adi,adv7180"; reg = <0x20>; @@ -241,6 +333,38 @@ }; }; }; + + hdmi@39 { + compatible = "adi,adv7511w"; + reg = <0x39>; + interrupt-parent = <&gpio3>; + interrupts = <29 IRQ_TYPE_LEVEL_LOW>; + + adi,input-depth = <8>; + adi,input-colorspace = "rgb"; + adi,input-clock = "1x"; + adi,input-style = <1>; + adi,input-justification = "evenly"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + adv7511_in: endpoint { + remote-endpoint = <&du_out_rgb>; + }; + }; + + port@1 { + reg = <1>; + adv7511_out: endpoint { + remote-endpoint = <&hdmi_con>; + }; + }; + }; + }; }; &sata0 { @@ -303,3 +427,44 @@ status = "okay"; }; + +&du { + pinctrl-0 = <&du_pins>; + pinctrl-names = "default"; + status = "okay"; + + clocks = <&mstp7_clks R8A7791_CLK_DU0>, + <&mstp7_clks R8A7791_CLK_DU1>, + <&mstp7_clks R8A7791_CLK_LVDS0>, + <&x3_clk>, <&x16_clk>; + clock-names = "du.0", "du.1", "lvds.0", + "dclkin.0", "dclkin.1"; + + ports { + port@1 { + endpoint { + remote-endpoint = <&adv7511_in>; + }; + }; + }; +}; + +&rcar_sound { + pinctrl-0 = <&ssi_pins &audio_clk_pins>; + pinctrl-names = "default"; + status = "okay"; + + /* Single DAI */ + #sound-dai-cells = <0>; + + rcar_sound,dai { + dai0 { + playback = <&ssi0>; + capture = <&ssi1>; + }; + }; +}; + +&ssi1 { + shared-pin; +}; diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi index 2a369ddcb6fd8dff8ce997993710d2f2592cb3f3..6439f0569fe2c578bc26e66b97947fb7cf220dd9 100644 --- a/arch/arm/boot/dts/r8a7791.dtsi +++ b/arch/arm/boot/dts/r8a7791.dtsi @@ -51,6 +51,7 @@ voltage-tolerance = <1>; /* 1% */ clocks = <&cpg_clocks R8A7791_CLK_Z>; clock-latency = <300000>; /* 300 us */ + next-level-cache = <&L2_CA15>; /* kHz - uV - OPPs unknown yet */ operating-points = <1500000 1000000>, @@ -66,9 +67,35 @@ compatible = "arm,cortex-a15"; reg = <1>; clock-frequency = <1500000000>; + next-level-cache = <&L2_CA15>; }; }; + thermal-zones { + cpu_thermal: cpu-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + + thermal-sensors = <&thermal>; + + trips { + cpu-crit { + temperature = <115000>; + hysteresis = <0>; + type = "critical"; + }; + }; + cooling-maps { + }; + }; + }; + + L2_CA15: cache-controller@0 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + }; + gic: interrupt-controller@f1001000 { compatible = "arm,gic-400"; #interrupt-cells = <3>; @@ -78,13 +105,13 @@ <0 0xf1002000 0 0x1000>, <0 0xf1004000 0 0x2000>, <0 0xf1006000 0 0x2000>; - interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>; + interrupts = ; }; gpio0: gpio@e6050000 { compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar"; reg = <0 0xe6050000 0 0x50>; - interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 0 32>; @@ -97,7 +124,7 @@ gpio1: gpio@e6051000 { compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar"; reg = <0 0xe6051000 0 0x50>; - interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 32 26>; @@ -110,7 +137,7 @@ gpio2: gpio@e6052000 { compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar"; reg = <0 0xe6052000 0 0x50>; - interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 64 32>; @@ -123,7 +150,7 @@ gpio3: gpio@e6053000 { compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar"; reg = <0 0xe6053000 0 0x50>; - interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 96 32>; @@ -136,7 +163,7 @@ gpio4: gpio@e6054000 { compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar"; reg = <0 0xe6054000 0 0x50>; - interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 128 32>; @@ -149,7 +176,7 @@ gpio5: gpio@e6055000 { compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar"; reg = <0 0xe6055000 0 0x50>; - interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 160 32>; @@ -162,7 +189,7 @@ gpio6: gpio@e6055400 { compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar"; reg = <0 0xe6055400 0 0x50>; - interrupts = <0 10 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 192 32>; @@ -175,7 +202,7 @@ gpio7: gpio@e6055800 { compatible = "renesas,gpio-r8a7791", "renesas,gpio-rcar"; reg = <0 0xe6055800 0 0x50>; - interrupts = <0 11 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 224 26>; @@ -185,27 +212,30 @@ power-domains = <&cpg_clocks>; }; - thermal@e61f0000 { - compatible = "renesas,thermal-r8a7791", "renesas,rcar-thermal"; + thermal: thermal@e61f0000 { + compatible = "renesas,thermal-r8a7791", + "renesas,rcar-gen2-thermal", + "renesas,rcar-thermal"; reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>; - interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp5_clks R8A7791_CLK_THERMAL>; power-domains = <&cpg_clocks>; + #thermal-sensor-cells = <0>; }; timer { compatible = "arm,armv7-timer"; - interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <1 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <1 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <1 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; }; cmt0: timer@ffca0000 { compatible = "renesas,cmt-48-r8a7791", "renesas,cmt-48-gen2"; reg = <0 0xffca0000 0 0x1004>; - interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>, - <0 143 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; clocks = <&mstp1_clks R8A7791_CLK_CMT0>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -218,14 +248,14 @@ cmt1: timer@e6130000 { compatible = "renesas,cmt-48-r8a7791", "renesas,cmt-48-gen2"; reg = <0 0xe6130000 0 0x1004>; - interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>, - <0 121 IRQ_TYPE_LEVEL_HIGH>, - <0 122 IRQ_TYPE_LEVEL_HIGH>, - <0 123 IRQ_TYPE_LEVEL_HIGH>, - <0 124 IRQ_TYPE_LEVEL_HIGH>, - <0 125 IRQ_TYPE_LEVEL_HIGH>, - <0 126 IRQ_TYPE_LEVEL_HIGH>, - <0 127 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + ; clocks = <&mstp3_clks R8A7791_CLK_CMT1>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -240,16 +270,16 @@ #interrupt-cells = <2>; interrupt-controller; reg = <0 0xe61c0000 0 0x200>; - interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>, - <0 1 IRQ_TYPE_LEVEL_HIGH>, - <0 2 IRQ_TYPE_LEVEL_HIGH>, - <0 3 IRQ_TYPE_LEVEL_HIGH>, - <0 12 IRQ_TYPE_LEVEL_HIGH>, - <0 13 IRQ_TYPE_LEVEL_HIGH>, - <0 14 IRQ_TYPE_LEVEL_HIGH>, - <0 15 IRQ_TYPE_LEVEL_HIGH>, - <0 16 IRQ_TYPE_LEVEL_HIGH>, - <0 17 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + , + , + ; clocks = <&mstp4_clks R8A7791_CLK_IRQC>; power-domains = <&cpg_clocks>; }; @@ -257,22 +287,22 @@ dmac0: dma-controller@e6700000 { compatible = "renesas,dmac-r8a7791", "renesas,rcar-dmac"; reg = <0 0xe6700000 0 0x20000>; - interrupts = <0 197 IRQ_TYPE_LEVEL_HIGH - 0 200 IRQ_TYPE_LEVEL_HIGH - 0 201 IRQ_TYPE_LEVEL_HIGH - 0 202 IRQ_TYPE_LEVEL_HIGH - 0 203 IRQ_TYPE_LEVEL_HIGH - 0 204 IRQ_TYPE_LEVEL_HIGH - 0 205 IRQ_TYPE_LEVEL_HIGH - 0 206 IRQ_TYPE_LEVEL_HIGH - 0 207 IRQ_TYPE_LEVEL_HIGH - 0 208 IRQ_TYPE_LEVEL_HIGH - 0 209 IRQ_TYPE_LEVEL_HIGH - 0 210 IRQ_TYPE_LEVEL_HIGH - 0 211 IRQ_TYPE_LEVEL_HIGH - 0 212 IRQ_TYPE_LEVEL_HIGH - 0 213 IRQ_TYPE_LEVEL_HIGH - 0 214 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -288,22 +318,22 @@ dmac1: dma-controller@e6720000 { compatible = "renesas,dmac-r8a7791", "renesas,rcar-dmac"; reg = <0 0xe6720000 0 0x20000>; - interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH - 0 216 IRQ_TYPE_LEVEL_HIGH - 0 217 IRQ_TYPE_LEVEL_HIGH - 0 218 IRQ_TYPE_LEVEL_HIGH - 0 219 IRQ_TYPE_LEVEL_HIGH - 0 308 IRQ_TYPE_LEVEL_HIGH - 0 309 IRQ_TYPE_LEVEL_HIGH - 0 310 IRQ_TYPE_LEVEL_HIGH - 0 311 IRQ_TYPE_LEVEL_HIGH - 0 312 IRQ_TYPE_LEVEL_HIGH - 0 313 IRQ_TYPE_LEVEL_HIGH - 0 314 IRQ_TYPE_LEVEL_HIGH - 0 315 IRQ_TYPE_LEVEL_HIGH - 0 316 IRQ_TYPE_LEVEL_HIGH - 0 317 IRQ_TYPE_LEVEL_HIGH - 0 318 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -319,20 +349,20 @@ audma0: dma-controller@ec700000 { compatible = "renesas,dmac-r8a7791", "renesas,rcar-dmac"; reg = <0 0xec700000 0 0x10000>; - interrupts = <0 346 IRQ_TYPE_LEVEL_HIGH - 0 320 IRQ_TYPE_LEVEL_HIGH - 0 321 IRQ_TYPE_LEVEL_HIGH - 0 322 IRQ_TYPE_LEVEL_HIGH - 0 323 IRQ_TYPE_LEVEL_HIGH - 0 324 IRQ_TYPE_LEVEL_HIGH - 0 325 IRQ_TYPE_LEVEL_HIGH - 0 326 IRQ_TYPE_LEVEL_HIGH - 0 327 IRQ_TYPE_LEVEL_HIGH - 0 328 IRQ_TYPE_LEVEL_HIGH - 0 329 IRQ_TYPE_LEVEL_HIGH - 0 330 IRQ_TYPE_LEVEL_HIGH - 0 331 IRQ_TYPE_LEVEL_HIGH - 0 332 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -348,20 +378,20 @@ audma1: dma-controller@ec720000 { compatible = "renesas,dmac-r8a7791", "renesas,rcar-dmac"; reg = <0 0xec720000 0 0x10000>; - interrupts = <0 347 IRQ_TYPE_LEVEL_HIGH - 0 333 IRQ_TYPE_LEVEL_HIGH - 0 334 IRQ_TYPE_LEVEL_HIGH - 0 335 IRQ_TYPE_LEVEL_HIGH - 0 336 IRQ_TYPE_LEVEL_HIGH - 0 337 IRQ_TYPE_LEVEL_HIGH - 0 338 IRQ_TYPE_LEVEL_HIGH - 0 339 IRQ_TYPE_LEVEL_HIGH - 0 340 IRQ_TYPE_LEVEL_HIGH - 0 341 IRQ_TYPE_LEVEL_HIGH - 0 342 IRQ_TYPE_LEVEL_HIGH - 0 343 IRQ_TYPE_LEVEL_HIGH - 0 344 IRQ_TYPE_LEVEL_HIGH - 0 345 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -377,8 +407,8 @@ usb_dmac0: dma-controller@e65a0000 { compatible = "renesas,r8a7791-usb-dmac", "renesas,usb-dmac"; reg = <0 0xe65a0000 0 0x100>; - interrupts = <0 109 IRQ_TYPE_LEVEL_HIGH - 0 109 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "ch0", "ch1"; clocks = <&mstp3_clks R8A7791_CLK_USBDMAC0>; power-domains = <&cpg_clocks>; @@ -389,8 +419,8 @@ usb_dmac1: dma-controller@e65b0000 { compatible = "renesas,r8a7791-usb-dmac", "renesas,usb-dmac"; reg = <0 0xe65b0000 0 0x100>; - interrupts = <0 110 IRQ_TYPE_LEVEL_HIGH - 0 110 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "ch0", "ch1"; clocks = <&mstp3_clks R8A7791_CLK_USBDMAC1>; power-domains = <&cpg_clocks>; @@ -404,7 +434,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7791"; reg = <0 0xe6508000 0 0x40>; - interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7791_CLK_I2C0>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <6>; @@ -416,7 +446,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7791"; reg = <0 0xe6518000 0 0x40>; - interrupts = <0 288 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7791_CLK_I2C1>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <6>; @@ -428,7 +458,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7791"; reg = <0 0xe6530000 0 0x40>; - interrupts = <0 286 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7791_CLK_I2C2>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <6>; @@ -440,7 +470,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7791"; reg = <0 0xe6540000 0 0x40>; - interrupts = <0 290 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7791_CLK_I2C3>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <6>; @@ -452,7 +482,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7791"; reg = <0 0xe6520000 0 0x40>; - interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7791_CLK_I2C4>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <6>; @@ -465,7 +495,7 @@ #size-cells = <0>; compatible = "renesas,i2c-r8a7791"; reg = <0 0xe6528000 0 0x40>; - interrupts = <0 20 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7791_CLK_I2C5>; power-domains = <&cpg_clocks>; i2c-scl-internal-delay-ns = <110>; @@ -478,7 +508,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a7791", "renesas,rmobile-iic"; reg = <0 0xe60b0000 0 0x425>; - interrupts = <0 173 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7791_CLK_IICDVFS>; dmas = <&dmac0 0x77>, <&dmac0 0x78>; dma-names = "tx", "rx"; @@ -491,7 +521,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a7791", "renesas,rmobile-iic"; reg = <0 0xe6500000 0 0x425>; - interrupts = <0 174 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7791_CLK_IIC0>; dmas = <&dmac0 0x61>, <&dmac0 0x62>; dma-names = "tx", "rx"; @@ -504,7 +534,7 @@ #size-cells = <0>; compatible = "renesas,iic-r8a7791", "renesas,rmobile-iic"; reg = <0 0xe6510000 0 0x425>; - interrupts = <0 175 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7791_CLK_IIC1>; dmas = <&dmac0 0x65>, <&dmac0 0x66>; dma-names = "tx", "rx"; @@ -520,7 +550,7 @@ mmcif0: mmc@ee200000 { compatible = "renesas,mmcif-r8a7791", "renesas,sh-mmcif"; reg = <0 0xee200000 0 0x80>; - interrupts = <0 169 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7791_CLK_MMCIF0>; dmas = <&dmac0 0xd1>, <&dmac0 0xd2>; dma-names = "tx", "rx"; @@ -533,7 +563,7 @@ sdhi0: sd@ee100000 { compatible = "renesas,sdhi-r8a7791"; reg = <0 0xee100000 0 0x328>; - interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7791_CLK_SDHI0>; dmas = <&dmac1 0xcd>, <&dmac1 0xce>; dma-names = "tx", "rx"; @@ -544,7 +574,7 @@ sdhi1: sd@ee140000 { compatible = "renesas,sdhi-r8a7791"; reg = <0 0xee140000 0 0x100>; - interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7791_CLK_SDHI1>; dmas = <&dmac1 0xc1>, <&dmac1 0xc2>; dma-names = "tx", "rx"; @@ -555,7 +585,7 @@ sdhi2: sd@ee160000 { compatible = "renesas,sdhi-r8a7791"; reg = <0 0xee160000 0 0x100>; - interrupts = <0 168 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7791_CLK_SDHI2>; dmas = <&dmac1 0xd3>, <&dmac1 0xd4>; dma-names = "tx", "rx"; @@ -564,11 +594,12 @@ }; scifa0: serial@e6c40000 { - compatible = "renesas,scifa-r8a7791", "renesas,scifa"; + compatible = "renesas,scifa-r8a7791", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c40000 0 64>; - interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_SCIFA0>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x21>, <&dmac0 0x22>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -576,11 +607,12 @@ }; scifa1: serial@e6c50000 { - compatible = "renesas,scifa-r8a7791", "renesas,scifa"; + compatible = "renesas,scifa-r8a7791", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c50000 0 64>; - interrupts = <0 145 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_SCIFA1>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x25>, <&dmac0 0x26>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -588,11 +620,12 @@ }; scifa2: serial@e6c60000 { - compatible = "renesas,scifa-r8a7791", "renesas,scifa"; + compatible = "renesas,scifa-r8a7791", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c60000 0 64>; - interrupts = <0 151 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_SCIFA2>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x27>, <&dmac0 0x28>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -600,11 +633,12 @@ }; scifa3: serial@e6c70000 { - compatible = "renesas,scifa-r8a7791", "renesas,scifa"; + compatible = "renesas,scifa-r8a7791", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c70000 0 64>; - interrupts = <0 29 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp11_clks R8A7791_CLK_SCIFA3>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x1b>, <&dmac0 0x1c>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -612,11 +646,12 @@ }; scifa4: serial@e6c78000 { - compatible = "renesas,scifa-r8a7791", "renesas,scifa"; + compatible = "renesas,scifa-r8a7791", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c78000 0 64>; - interrupts = <0 30 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp11_clks R8A7791_CLK_SCIFA4>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x1f>, <&dmac0 0x20>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -624,11 +659,12 @@ }; scifa5: serial@e6c80000 { - compatible = "renesas,scifa-r8a7791", "renesas,scifa"; + compatible = "renesas,scifa-r8a7791", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c80000 0 64>; - interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp11_clks R8A7791_CLK_SCIFA5>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x23>, <&dmac0 0x24>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -636,11 +672,12 @@ }; scifb0: serial@e6c20000 { - compatible = "renesas,scifb-r8a7791", "renesas,scifb"; + compatible = "renesas,scifb-r8a7791", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6c20000 0 64>; - interrupts = <0 148 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_SCIFB0>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x3d>, <&dmac0 0x3e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -648,11 +685,12 @@ }; scifb1: serial@e6c30000 { - compatible = "renesas,scifb-r8a7791", "renesas,scifb"; + compatible = "renesas,scifb-r8a7791", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6c30000 0 64>; - interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_SCIFB1>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x19>, <&dmac0 0x1a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -660,11 +698,12 @@ }; scifb2: serial@e6ce0000 { - compatible = "renesas,scifb-r8a7791", "renesas,scifb"; + compatible = "renesas,scifb-r8a7791", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6ce0000 0 64>; - interrupts = <0 150 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_SCIFB2>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x1d>, <&dmac0 0x1e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -672,11 +711,13 @@ }; scif0: serial@e6e60000 { - compatible = "renesas,scif-r8a7791", "renesas,scif"; + compatible = "renesas,scif-r8a7791", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6e60000 0 64>; - interrupts = <0 152 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7791_CLK_SCIF0>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7791_CLK_SCIF0>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x29>, <&dmac0 0x2a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -684,11 +725,13 @@ }; scif1: serial@e6e68000 { - compatible = "renesas,scif-r8a7791", "renesas,scif"; + compatible = "renesas,scif-r8a7791", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6e68000 0 64>; - interrupts = <0 153 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7791_CLK_SCIF1>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7791_CLK_SCIF1>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x2d>, <&dmac0 0x2e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -696,11 +739,13 @@ }; scif2: serial@e6e58000 { - compatible = "renesas,scif-r8a7791", "renesas,scif"; + compatible = "renesas,scif-r8a7791", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6e58000 0 64>; - interrupts = <0 22 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7791_CLK_SCIF2>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7791_CLK_SCIF2>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x2b>, <&dmac0 0x2c>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -708,11 +753,13 @@ }; scif3: serial@e6ea8000 { - compatible = "renesas,scif-r8a7791", "renesas,scif"; + compatible = "renesas,scif-r8a7791", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6ea8000 0 64>; - interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7791_CLK_SCIF3>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7791_CLK_SCIF3>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x2f>, <&dmac0 0x30>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -720,11 +767,13 @@ }; scif4: serial@e6ee0000 { - compatible = "renesas,scif-r8a7791", "renesas,scif"; + compatible = "renesas,scif-r8a7791", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6ee0000 0 64>; - interrupts = <0 24 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7791_CLK_SCIF4>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7791_CLK_SCIF4>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0xfb>, <&dmac0 0xfc>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -732,11 +781,13 @@ }; scif5: serial@e6ee8000 { - compatible = "renesas,scif-r8a7791", "renesas,scif"; + compatible = "renesas,scif-r8a7791", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6ee8000 0 64>; - interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7791_CLK_SCIF5>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7791_CLK_SCIF5>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0xfd>, <&dmac0 0xfe>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -744,11 +795,13 @@ }; hscif0: serial@e62c0000 { - compatible = "renesas,hscif-r8a7791", "renesas,hscif"; + compatible = "renesas,hscif-r8a7791", + "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62c0000 0 96>; - interrupts = <0 154 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7791_CLK_HSCIF0>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7791_CLK_HSCIF0>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x39>, <&dmac0 0x3a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -756,11 +809,13 @@ }; hscif1: serial@e62c8000 { - compatible = "renesas,hscif-r8a7791", "renesas,hscif"; + compatible = "renesas,hscif-r8a7791", + "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62c8000 0 96>; - interrupts = <0 155 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7791_CLK_HSCIF1>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7791_CLK_HSCIF1>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x4d>, <&dmac0 0x4e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -768,11 +823,13 @@ }; hscif2: serial@e62d0000 { - compatible = "renesas,hscif-r8a7791", "renesas,hscif"; + compatible = "renesas,hscif-r8a7791", + "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62d0000 0 96>; - interrupts = <0 21 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7791_CLK_HSCIF2>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7791_CLK_HSCIF2>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x3b>, <&dmac0 0x3c>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -782,7 +839,7 @@ ether: ethernet@ee700000 { compatible = "renesas,ether-r8a7791"; reg = <0 0xee700000 0 0x400>; - interrupts = <0 162 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7791_CLK_ETHER>; power-domains = <&cpg_clocks>; phy-mode = "rmii"; @@ -795,7 +852,7 @@ compatible = "renesas,etheravb-r8a7791", "renesas,etheravb-rcar-gen2"; reg = <0 0xe6800000 0 0x800>, <0 0xee0e8000 0 0x4000>; - interrupts = <0 163 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7791_CLK_ETHERAVB>; power-domains = <&cpg_clocks>; #address-cells = <1>; @@ -806,7 +863,7 @@ sata0: sata@ee300000 { compatible = "renesas,sata-r8a7791"; reg = <0 0xee300000 0 0x2000>; - interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7791_CLK_SATA0>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -815,16 +872,16 @@ sata1: sata@ee500000 { compatible = "renesas,sata-r8a7791"; reg = <0 0xee500000 0 0x2000>; - interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7791_CLK_SATA1>; power-domains = <&cpg_clocks>; status = "disabled"; }; hsusb: usb@e6590000 { - compatible = "renesas,usbhs-r8a7791"; + compatible = "renesas,usbhs-r8a7791", "renesas,rcar-gen2-usbhs"; reg = <0 0xe6590000 0 0x100>; - interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_HSUSB>; dmas = <&usb_dmac0 0>, <&usb_dmac0 1>, <&usb_dmac1 0>, <&usb_dmac1 1>; @@ -859,7 +916,7 @@ vin0: video@e6ef0000 { compatible = "renesas,vin-r8a7791"; reg = <0 0xe6ef0000 0 0x1000>; - interrupts = <0 188 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7791_CLK_VIN0>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -868,7 +925,7 @@ vin1: video@e6ef1000 { compatible = "renesas,vin-r8a7791"; reg = <0 0xe6ef1000 0 0x1000>; - interrupts = <0 189 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7791_CLK_VIN1>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -877,7 +934,7 @@ vin2: video@e6ef2000 { compatible = "renesas,vin-r8a7791"; reg = <0 0xe6ef2000 0 0x1000>; - interrupts = <0 190 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7791_CLK_VIN2>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -886,7 +943,7 @@ vsp1@fe928000 { compatible = "renesas,vsp1"; reg = <0 0xfe928000 0 0x8000>; - interrupts = <0 267 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7791_CLK_VSP1_S>; power-domains = <&cpg_clocks>; @@ -900,7 +957,7 @@ vsp1@fe930000 { compatible = "renesas,vsp1"; reg = <0 0xfe930000 0 0x8000>; - interrupts = <0 246 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7791_CLK_VSP1_DU0>; power-domains = <&cpg_clocks>; @@ -914,7 +971,7 @@ vsp1@fe938000 { compatible = "renesas,vsp1"; reg = <0 0xfe938000 0 0x8000>; - interrupts = <0 247 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7791_CLK_VSP1_DU1>; power-domains = <&cpg_clocks>; @@ -930,8 +987,8 @@ reg = <0 0xfeb00000 0 0x40000>, <0 0xfeb90000 0 0x1c>; reg-names = "du", "lvds.0"; - interrupts = <0 256 IRQ_TYPE_LEVEL_HIGH>, - <0 268 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; clocks = <&mstp7_clks R8A7791_CLK_DU0>, <&mstp7_clks R8A7791_CLK_DU1>, <&mstp7_clks R8A7791_CLK_LVDS0>; @@ -958,7 +1015,7 @@ can0: can@e6e80000 { compatible = "renesas,can-r8a7791"; reg = <0 0xe6e80000 0 0x1000>; - interrupts = <0 186 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7791_CLK_RCAN0>, <&cpg_clocks R8A7791_CLK_RCAN>, <&can_clk>; clock-names = "clkp1", "clkp2", "can_clk"; @@ -969,7 +1026,7 @@ can1: can@e6e88000 { compatible = "renesas,can-r8a7791"; reg = <0 0xe6e88000 0 0x1000>; - interrupts = <0 187 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7791_CLK_RCAN1>, <&cpg_clocks R8A7791_CLK_RCAN>, <&can_clk>; clock-names = "clkp1", "clkp2", "can_clk"; @@ -980,7 +1037,7 @@ jpu: jpeg-codec@fe980000 { compatible = "renesas,jpu-r8a7791"; reg = <0 0xfe980000 0 0x10300>; - interrupts = <0 272 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks R8A7791_CLK_JPU>; power-domains = <&cpg_clocks>; }; @@ -1031,6 +1088,15 @@ status = "disabled"; }; + /* External SCIF clock */ + scif_clk: scif { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* This value must be overridden by the board. */ + clock-frequency = <0>; + status = "disabled"; + }; + /* External USB clock - can be overridden by the board */ usb_extal_clk: usb_extal_clk { compatible = "fixed-clock"; @@ -1432,7 +1498,7 @@ qspi: spi@e6b10000 { compatible = "renesas,qspi-r8a7791", "renesas,qspi"; reg = <0 0xe6b10000 0 0x2c>; - interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7791_CLK_QSPI_MOD>; dmas = <&dmac0 0x17>, <&dmac0 0x18>; dma-names = "tx", "rx"; @@ -1446,7 +1512,7 @@ msiof0: spi@e6e20000 { compatible = "renesas,msiof-r8a7791"; reg = <0 0xe6e20000 0 0x0064>; - interrupts = <0 156 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks R8A7791_CLK_MSIOF0>; dmas = <&dmac0 0x51>, <&dmac0 0x52>; dma-names = "tx", "rx"; @@ -1459,7 +1525,7 @@ msiof1: spi@e6e10000 { compatible = "renesas,msiof-r8a7791"; reg = <0 0xe6e10000 0 0x0064>; - interrupts = <0 157 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_MSIOF1>; dmas = <&dmac0 0x55>, <&dmac0 0x56>; dma-names = "tx", "rx"; @@ -1472,7 +1538,7 @@ msiof2: spi@e6e00000 { compatible = "renesas,msiof-r8a7791"; reg = <0 0xe6e00000 0 0x0064>; - interrupts = <0 158 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7791_CLK_MSIOF2>; dmas = <&dmac0 0x41>, <&dmac0 0x42>; dma-names = "tx", "rx"; @@ -1485,7 +1551,7 @@ xhci: usb@ee000000 { compatible = "renesas,xhci-r8a7791"; reg = <0 0xee000000 0 0xc00>; - interrupts = <0 101 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7791_CLK_SSUSB>; power-domains = <&cpg_clocks>; phys = <&usb2 1>; @@ -1494,11 +1560,11 @@ }; pci0: pci@ee090000 { - compatible = "renesas,pci-r8a7791"; + compatible = "renesas,pci-r8a7791", "renesas,pci-rcar-gen2"; device_type = "pci"; reg = <0 0xee090000 0 0xc00>, <0 0xee080000 0 0x1100>; - interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_EHCI>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -1509,9 +1575,9 @@ #interrupt-cells = <1>; ranges = <0x02000000 0 0xee080000 0 0xee080000 0 0x00010000>; interrupt-map-mask = <0xff00 0 0 0x7>; - interrupt-map = <0x0000 0 0 1 &gic 0 108 IRQ_TYPE_LEVEL_HIGH - 0x0800 0 0 1 &gic 0 108 IRQ_TYPE_LEVEL_HIGH - 0x1000 0 0 2 &gic 0 108 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH + 0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH + 0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>; usb@0,1 { reg = <0x800 0 0 0 0>; @@ -1529,11 +1595,11 @@ }; pci1: pci@ee0d0000 { - compatible = "renesas,pci-r8a7791"; + compatible = "renesas,pci-r8a7791", "renesas,pci-rcar-gen2"; device_type = "pci"; reg = <0 0xee0d0000 0 0xc00>, <0 0xee0c0000 0 0x1100>; - interrupts = <0 113 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7791_CLK_EHCI>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -1544,9 +1610,9 @@ #interrupt-cells = <1>; ranges = <0x02000000 0 0xee0c0000 0 0xee0c0000 0 0x00010000>; interrupt-map-mask = <0xff00 0 0 0x7>; - interrupt-map = <0x0000 0 0 1 &gic 0 113 IRQ_TYPE_LEVEL_HIGH - 0x0800 0 0 1 &gic 0 113 IRQ_TYPE_LEVEL_HIGH - 0x1000 0 0 2 &gic 0 113 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH + 0x0800 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH + 0x1000 0 0 2 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; usb@0,1 { reg = <0x800 0 0 0 0>; @@ -1564,7 +1630,7 @@ }; pciec: pcie@fe000000 { - compatible = "renesas,pcie-r8a7791"; + compatible = "renesas,pcie-r8a7791", "renesas,pcie-rcar-gen2"; reg = <0 0xfe000000 0 0x80000>; #address-cells = <3>; #size-cells = <2>; @@ -1577,12 +1643,12 @@ /* Map all possible DDR as inbound ranges */ dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000 0x43000000 2 0x00000000 2 0x00000000 1 0x00000000>; - interrupts = <0 116 IRQ_TYPE_LEVEL_HIGH>, - <0 117 IRQ_TYPE_LEVEL_HIGH>, - <0 118 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + ; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0>; - interrupt-map = <0 0 0 0 &gic 0 116 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0 0 0 0 &gic GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>; clocks = <&mstp3_clks R8A7791_CLK_PCIEC>, <&pcie_bus_clk>; clock-names = "pcie", "pcie_bus"; power-domains = <&cpg_clocks>; @@ -1592,8 +1658,8 @@ ipmmu_sy0: mmu@e6280000 { compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa"; reg = <0 0xe6280000 0 0x1000>; - interrupts = <0 223 IRQ_TYPE_LEVEL_HIGH>, - <0 224 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -1601,7 +1667,7 @@ ipmmu_sy1: mmu@e6290000 { compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa"; reg = <0 0xe6290000 0 0x1000>; - interrupts = <0 225 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #iommu-cells = <1>; status = "disabled"; }; @@ -1609,8 +1675,8 @@ ipmmu_ds: mmu@e6740000 { compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa"; reg = <0 0xe6740000 0 0x1000>; - interrupts = <0 198 IRQ_TYPE_LEVEL_HIGH>, - <0 199 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -1618,7 +1684,7 @@ ipmmu_mp: mmu@ec680000 { compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa"; reg = <0 0xec680000 0 0x1000>; - interrupts = <0 226 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #iommu-cells = <1>; status = "disabled"; }; @@ -1626,8 +1692,8 @@ ipmmu_mx: mmu@fe951000 { compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa"; reg = <0 0xfe951000 0 0x1000>; - interrupts = <0 222 IRQ_TYPE_LEVEL_HIGH>, - <0 221 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -1635,7 +1701,7 @@ ipmmu_rt: mmu@ffc80000 { compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa"; reg = <0 0xffc80000 0 0x1000>; - interrupts = <0 307 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #iommu-cells = <1>; status = "disabled"; }; @@ -1643,8 +1709,8 @@ ipmmu_gp: mmu@e62a0000 { compatible = "renesas,ipmmu-r8a7791", "renesas,ipmmu-vmsa"; reg = <0 0xe62a0000 0 0x1000>; - interrupts = <0 260 IRQ_TYPE_LEVEL_HIGH>, - <0 261 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -1721,52 +1787,52 @@ rcar_sound,src { src0: src@0 { - interrupts = <0 352 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x85>, <&audma1 0x9a>; dma-names = "rx", "tx"; }; src1: src@1 { - interrupts = <0 353 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x87>, <&audma1 0x9c>; dma-names = "rx", "tx"; }; src2: src@2 { - interrupts = <0 354 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x89>, <&audma1 0x9e>; dma-names = "rx", "tx"; }; src3: src@3 { - interrupts = <0 355 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x8b>, <&audma1 0xa0>; dma-names = "rx", "tx"; }; src4: src@4 { - interrupts = <0 356 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x8d>, <&audma1 0xb0>; dma-names = "rx", "tx"; }; src5: src@5 { - interrupts = <0 357 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x8f>, <&audma1 0xb2>; dma-names = "rx", "tx"; }; src6: src@6 { - interrupts = <0 358 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x91>, <&audma1 0xb4>; dma-names = "rx", "tx"; }; src7: src@7 { - interrupts = <0 359 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x93>, <&audma1 0xb6>; dma-names = "rx", "tx"; }; src8: src@8 { - interrupts = <0 360 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x95>, <&audma1 0xb8>; dma-names = "rx", "tx"; }; src9: src@9 { - interrupts = <0 361 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x97>, <&audma1 0xba>; dma-names = "rx", "tx"; }; @@ -1774,52 +1840,52 @@ rcar_sound,ssi { ssi0: ssi@0 { - interrupts = <0 370 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x01>, <&audma1 0x02>, <&audma0 0x15>, <&audma1 0x16>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi1: ssi@1 { - interrupts = <0 371 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x03>, <&audma1 0x04>, <&audma0 0x49>, <&audma1 0x4a>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi2: ssi@2 { - interrupts = <0 372 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x05>, <&audma1 0x06>, <&audma0 0x63>, <&audma1 0x64>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi3: ssi@3 { - interrupts = <0 373 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x07>, <&audma1 0x08>, <&audma0 0x6f>, <&audma1 0x70>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi4: ssi@4 { - interrupts = <0 374 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x09>, <&audma1 0x0a>, <&audma0 0x71>, <&audma1 0x72>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi5: ssi@5 { - interrupts = <0 375 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x0b>, <&audma1 0x0c>, <&audma0 0x73>, <&audma1 0x74>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi6: ssi@6 { - interrupts = <0 376 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x0d>, <&audma1 0x0e>, <&audma0 0x75>, <&audma1 0x76>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi7: ssi@7 { - interrupts = <0 377 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x0f>, <&audma1 0x10>, <&audma0 0x79>, <&audma1 0x7a>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi8: ssi@8 { - interrupts = <0 378 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x11>, <&audma1 0x12>, <&audma0 0x7b>, <&audma1 0x7c>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi9: ssi@9 { - interrupts = <0 379 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x13>, <&audma1 0x14>, <&audma0 0x7d>, <&audma1 0x7e>; dma-names = "rx", "tx", "rxu", "txu"; }; diff --git a/arch/arm/boot/dts/r8a7793-gose.dts b/arch/arm/boot/dts/r8a7793-gose.dts index baa59fe8429869ac2bd975e5e7da5a443df122d6..87e89ec9dd47eef359c5b758f3b9819f2d89c092 100644 --- a/arch/arm/boot/dts/r8a7793-gose.dts +++ b/arch/arm/boot/dts/r8a7793-gose.dts @@ -8,6 +8,34 @@ * kind, whether express or implied. */ +/* + * SSI-AK4643 + * + * SW1: 1: AK4643 + * 2: CN22 + * 3: ADV7511 + * + * This command is required when Playback/Capture + * + * amixer set "LINEOUT Mixer DACL" on + * amixer set "DVC Out" 100% + * amixer set "DVC In" 100% + * + * You can use Mute + * + * amixer set "DVC Out Mute" on + * amixer set "DVC In Mute" on + * + * You can use Volume Ramp + * + * amixer set "DVC Out Ramp Up Rate" "0.125 dB/64 steps" + * amixer set "DVC Out Ramp Down Rate" "0.125 dB/512 steps" + * amixer set "DVC Out Ramp" on + * aplay xxx.wav & + * amixer set "DVC Out" 80% // Volume Down + * amixer set "DVC Out" 100% // Volume Up + */ + /dts-v1/; #include "r8a7793.dtsi" #include @@ -31,6 +59,176 @@ device_type = "memory"; reg = <0 0x40000000 0 0x40000000>; }; + + gpio-keys { + compatible = "gpio-keys"; + + key-1 { + gpios = <&gpio5 0 GPIO_ACTIVE_LOW>; + linux,code = ; + label = "SW2-1"; + wakeup-source; + debounce-interval = <20>; + }; + key-2 { + gpios = <&gpio5 1 GPIO_ACTIVE_LOW>; + linux,code = ; + label = "SW2-2"; + wakeup-source; + debounce-interval = <20>; + }; + key-3 { + gpios = <&gpio5 2 GPIO_ACTIVE_LOW>; + linux,code = ; + label = "SW2-3"; + wakeup-source; + debounce-interval = <20>; + }; + key-4 { + gpios = <&gpio5 3 GPIO_ACTIVE_LOW>; + linux,code = ; + label = "SW2-4"; + wakeup-source; + debounce-interval = <20>; + }; + key-a { + gpios = <&gpio7 0 GPIO_ACTIVE_LOW>; + linux,code = ; + label = "SW30"; + wakeup-source; + debounce-interval = <20>; + }; + key-b { + gpios = <&gpio7 1 GPIO_ACTIVE_LOW>; + linux,code = ; + label = "SW31"; + wakeup-source; + debounce-interval = <20>; + }; + key-c { + gpios = <&gpio7 2 GPIO_ACTIVE_LOW>; + linux,code = ; + label = "SW32"; + wakeup-source; + debounce-interval = <20>; + }; + key-d { + gpios = <&gpio7 3 GPIO_ACTIVE_LOW>; + linux,code = ; + label = "SW33"; + wakeup-source; + debounce-interval = <20>; + }; + key-e { + gpios = <&gpio7 4 GPIO_ACTIVE_LOW>; + linux,code = ; + label = "SW34"; + wakeup-source; + debounce-interval = <20>; + }; + key-f { + gpios = <&gpio7 5 GPIO_ACTIVE_LOW>; + linux,code = ; + label = "SW35"; + wakeup-source; + debounce-interval = <20>; + }; + key-g { + gpios = <&gpio7 6 GPIO_ACTIVE_LOW>; + linux,code = ; + label = "SW36"; + wakeup-source; + debounce-interval = <20>; + }; + }; + + leds { + compatible = "gpio-leds"; + led6 { + gpios = <&gpio2 19 GPIO_ACTIVE_HIGH>; + label = "LED6"; + }; + led7 { + gpios = <&gpio2 20 GPIO_ACTIVE_HIGH>; + label = "LED7"; + }; + led8 { + gpios = <&gpio2 21 GPIO_ACTIVE_HIGH>; + label = "LED8"; + }; + }; + + audio_clock: clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <11289600>; + clock-output-names = "audio_clock"; + }; + + rsnd_ak4643: sound { + compatible = "simple-audio-card"; + + simple-audio-card,format = "left_j"; + simple-audio-card,bitclock-master = <&sndcodec>; + simple-audio-card,frame-master = <&sndcodec>; + + sndcpu: simple-audio-card,cpu { + sound-dai = <&rcar_sound>; + }; + + sndcodec: simple-audio-card,codec { + sound-dai = <&ak4643>; + clocks = <&audio_clock>; + }; + }; + + hdmi-out { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_con: endpoint { + remote-endpoint = <&adv7511_out>; + }; + }; + }; + + x2_clk: x2-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <74250000>; + }; + + x13_clk: x13-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <148500000>; + }; +}; + +&du { + pinctrl-0 = <&du_pins>; + pinctrl-names = "default"; + status = "okay"; + + clocks = <&mstp7_clks R8A7793_CLK_DU0>, + <&mstp7_clks R8A7793_CLK_DU1>, + <&mstp7_clks R8A7793_CLK_LVDS0>, + <&x13_clk>, <&x2_clk>; + clock-names = "du.0", "du.1", "lvds.0", + "dclkin.0", "dclkin.1"; + + ports { + port@0 { + endpoint { + remote-endpoint = <&adv7511_in>; + }; + }; + port@1 { + lvds_connector: endpoint { + }; + }; + }; }; &extal_clk { @@ -38,6 +236,19 @@ }; &pfc { + pinctrl-0 = <&scif_clk_pins>; + pinctrl-names = "default"; + + i2c2_pins: i2c2 { + renesas,groups = "i2c2"; + renesas,function = "i2c2"; + }; + + du_pins: du { + renesas,groups = "du_rgb888", "du_sync", "du_disp", "du_clk_out_0"; + renesas,function = "du"; + }; + scif0_pins: serial0 { renesas,groups = "scif0_data_d"; renesas,function = "scif0"; @@ -48,6 +259,11 @@ renesas,function = "scif1"; }; + scif_clk_pins: scif_clk { + renesas,groups = "scif_clk"; + renesas,function = "scif_clk"; + }; + ether_pins: ether { renesas,groups = "eth_link", "eth_mdio", "eth_rmii"; renesas,function = "eth"; @@ -62,6 +278,16 @@ renesas,groups = "qspi_ctrl", "qspi_data4"; renesas,function = "qspi"; }; + + sound_pins: sound { + renesas,groups = "ssi0129_ctrl", "ssi0_data", "ssi1_data"; + renesas,function = "ssi"; + }; + + sound_clk_pins: sound_clk { + renesas,groups = "audio_clk_a"; + renesas,function = "audio_clk"; + }; }; ðer { @@ -98,6 +324,11 @@ status = "okay"; }; +&scif_clk { + clock-frequency = <14745600>; + status = "okay"; +}; + &qspi { pinctrl-0 = <&qspi_pins>; pinctrl-names = "default"; @@ -136,3 +367,76 @@ }; }; }; + +&i2c2 { + pinctrl-0 = <&i2c2_pins>; + pinctrl-names = "default"; + + status = "okay"; + clock-frequency = <100000>; + + ak4643: codec@12 { + compatible = "asahi-kasei,ak4643"; + #sound-dai-cells = <0>; + reg = <0x12>; + }; + + hdmi@39 { + compatible = "adi,adv7511w"; + reg = <0x39>; + interrupt-parent = <&gpio3>; + interrupts = <29 IRQ_TYPE_LEVEL_LOW>; + + adi,input-depth = <8>; + adi,input-colorspace = "rgb"; + adi,input-clock = "1x"; + adi,input-style = <1>; + adi,input-justification = "evenly"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + adv7511_in: endpoint { + remote-endpoint = <&du_out_rgb>; + }; + }; + + port@1 { + reg = <1>; + adv7511_out: endpoint { + remote-endpoint = <&hdmi_con>; + }; + }; + }; + }; + + eeprom@50 { + compatible = "renesas,r1ex24002", "atmel,24c02"; + reg = <0x50>; + pagesize = <16>; + }; +}; + +&rcar_sound { + pinctrl-0 = <&sound_pins &sound_clk_pins>; + pinctrl-names = "default"; + + /* Single DAI */ + #sound-dai-cells = <0>; + + status = "okay"; + + rcar_sound,dai { + dai0 { + playback = <&ssi0 &src2 &dvc0>; + capture = <&ssi1 &src3 &dvc1>; + }; + }; +}; + +&ssi1 { + shared-pin; +}; diff --git a/arch/arm/boot/dts/r8a7793.dtsi b/arch/arm/boot/dts/r8a7793.dtsi index aef9e69d6c26ae7cfab58fb5418e6771e0f226ba..b48215945241260102f007b9c28899d9549c240f 100644 --- a/arch/arm/boot/dts/r8a7793.dtsi +++ b/arch/arm/boot/dts/r8a7793.dtsi @@ -19,6 +19,15 @@ #size-cells = <2>; aliases { + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; + i2c4 = &i2c4; + i2c5 = &i2c5; + i2c6 = &i2c6; + i2c7 = &i2c7; + i2c8 = &i2c8; spi0 = &qspi; }; @@ -42,9 +51,35 @@ < 937500 1000000>, < 750000 1000000>, < 375000 1000000>; + next-level-cache = <&L2_CA15>; }; }; + thermal-zones { + cpu_thermal: cpu-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + + thermal-sensors = <&thermal>; + + trips { + cpu-crit { + temperature = <115000>; + hysteresis = <0>; + type = "critical"; + }; + }; + cooling-maps { + }; + }; + }; + + L2_CA15: cache-controller@0 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + }; + gic: interrupt-controller@f1001000 { compatible = "arm,gic-400"; #interrupt-cells = <3>; @@ -54,13 +89,13 @@ <0 0xf1002000 0 0x1000>, <0 0xf1004000 0 0x2000>, <0 0xf1006000 0 0x2000>; - interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>; + interrupts = ; }; gpio0: gpio@e6050000 { compatible = "renesas,gpio-r8a7793", "renesas,gpio-rcar"; reg = <0 0xe6050000 0 0x50>; - interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 0 32>; @@ -73,7 +108,7 @@ gpio1: gpio@e6051000 { compatible = "renesas,gpio-r8a7793", "renesas,gpio-rcar"; reg = <0 0xe6051000 0 0x50>; - interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 32 26>; @@ -86,7 +121,7 @@ gpio2: gpio@e6052000 { compatible = "renesas,gpio-r8a7793", "renesas,gpio-rcar"; reg = <0 0xe6052000 0 0x50>; - interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 64 32>; @@ -99,7 +134,7 @@ gpio3: gpio@e6053000 { compatible = "renesas,gpio-r8a7793", "renesas,gpio-rcar"; reg = <0 0xe6053000 0 0x50>; - interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 96 32>; @@ -112,7 +147,7 @@ gpio4: gpio@e6054000 { compatible = "renesas,gpio-r8a7793", "renesas,gpio-rcar"; reg = <0 0xe6054000 0 0x50>; - interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 128 32>; @@ -125,7 +160,7 @@ gpio5: gpio@e6055000 { compatible = "renesas,gpio-r8a7793", "renesas,gpio-rcar"; reg = <0 0xe6055000 0 0x50>; - interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 160 32>; @@ -138,7 +173,7 @@ gpio6: gpio@e6055400 { compatible = "renesas,gpio-r8a7793", "renesas,gpio-rcar"; reg = <0 0xe6055400 0 0x50>; - interrupts = <0 10 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 192 32>; @@ -151,7 +186,7 @@ gpio7: gpio@e6055800 { compatible = "renesas,gpio-r8a7793", "renesas,gpio-rcar"; reg = <0 0xe6055800 0 0x50>; - interrupts = <0 11 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 224 26>; @@ -161,27 +196,30 @@ power-domains = <&cpg_clocks>; }; - thermal@e61f0000 { - compatible = "renesas,thermal-r8a7793", "renesas,rcar-thermal"; + thermal: thermal@e61f0000 { + compatible = "renesas,thermal-r8a7793", + "renesas,rcar-gen2-thermal", + "renesas,rcar-thermal"; reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>; - interrupts = <0 69 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp5_clks R8A7793_CLK_THERMAL>; power-domains = <&cpg_clocks>; + #thermal-sensor-cells = <0>; }; timer { compatible = "arm,armv7-timer"; - interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <1 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <1 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <1 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; }; cmt0: timer@ffca0000 { compatible = "renesas,cmt-48-r8a7793", "renesas,cmt-48-gen2"; reg = <0 0xffca0000 0 0x1004>; - interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>, - <0 143 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; clocks = <&mstp1_clks R8A7793_CLK_CMT0>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -194,14 +232,14 @@ cmt1: timer@e6130000 { compatible = "renesas,cmt-48-r8a7793", "renesas,cmt-48-gen2"; reg = <0 0xe6130000 0 0x1004>; - interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>, - <0 121 IRQ_TYPE_LEVEL_HIGH>, - <0 122 IRQ_TYPE_LEVEL_HIGH>, - <0 123 IRQ_TYPE_LEVEL_HIGH>, - <0 124 IRQ_TYPE_LEVEL_HIGH>, - <0 125 IRQ_TYPE_LEVEL_HIGH>, - <0 126 IRQ_TYPE_LEVEL_HIGH>, - <0 127 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + ; clocks = <&mstp3_clks R8A7793_CLK_CMT1>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -216,44 +254,39 @@ #interrupt-cells = <2>; interrupt-controller; reg = <0 0xe61c0000 0 0x200>; - interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>, - <0 1 IRQ_TYPE_LEVEL_HIGH>, - <0 2 IRQ_TYPE_LEVEL_HIGH>, - <0 3 IRQ_TYPE_LEVEL_HIGH>, - <0 12 IRQ_TYPE_LEVEL_HIGH>, - <0 13 IRQ_TYPE_LEVEL_HIGH>, - <0 14 IRQ_TYPE_LEVEL_HIGH>, - <0 15 IRQ_TYPE_LEVEL_HIGH>, - <0 16 IRQ_TYPE_LEVEL_HIGH>, - <0 17 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + , + , + ; clocks = <&mstp4_clks R8A7793_CLK_IRQC>; power-domains = <&cpg_clocks>; }; - pfc: pfc@e6060000 { - compatible = "renesas,pfc-r8a7793"; - reg = <0 0xe6060000 0 0x250>; - }; - dmac0: dma-controller@e6700000 { compatible = "renesas,dmac-r8a7793", "renesas,rcar-dmac"; reg = <0 0xe6700000 0 0x20000>; - interrupts = <0 197 IRQ_TYPE_LEVEL_HIGH - 0 200 IRQ_TYPE_LEVEL_HIGH - 0 201 IRQ_TYPE_LEVEL_HIGH - 0 202 IRQ_TYPE_LEVEL_HIGH - 0 203 IRQ_TYPE_LEVEL_HIGH - 0 204 IRQ_TYPE_LEVEL_HIGH - 0 205 IRQ_TYPE_LEVEL_HIGH - 0 206 IRQ_TYPE_LEVEL_HIGH - 0 207 IRQ_TYPE_LEVEL_HIGH - 0 208 IRQ_TYPE_LEVEL_HIGH - 0 209 IRQ_TYPE_LEVEL_HIGH - 0 210 IRQ_TYPE_LEVEL_HIGH - 0 211 IRQ_TYPE_LEVEL_HIGH - 0 212 IRQ_TYPE_LEVEL_HIGH - 0 213 IRQ_TYPE_LEVEL_HIGH - 0 214 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -269,22 +302,22 @@ dmac1: dma-controller@e6720000 { compatible = "renesas,dmac-r8a7793", "renesas,rcar-dmac"; reg = <0 0xe6720000 0 0x20000>; - interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH - 0 216 IRQ_TYPE_LEVEL_HIGH - 0 217 IRQ_TYPE_LEVEL_HIGH - 0 218 IRQ_TYPE_LEVEL_HIGH - 0 219 IRQ_TYPE_LEVEL_HIGH - 0 308 IRQ_TYPE_LEVEL_HIGH - 0 309 IRQ_TYPE_LEVEL_HIGH - 0 310 IRQ_TYPE_LEVEL_HIGH - 0 311 IRQ_TYPE_LEVEL_HIGH - 0 312 IRQ_TYPE_LEVEL_HIGH - 0 313 IRQ_TYPE_LEVEL_HIGH - 0 314 IRQ_TYPE_LEVEL_HIGH - 0 315 IRQ_TYPE_LEVEL_HIGH - 0 316 IRQ_TYPE_LEVEL_HIGH - 0 317 IRQ_TYPE_LEVEL_HIGH - 0 318 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -297,12 +330,190 @@ dma-channels = <15>; }; + audma0: dma-controller@ec700000 { + compatible = "renesas,dmac-r8a7793", "renesas,rcar-dmac"; + reg = <0 0xec700000 0 0x10000>; + interrupts = ; + interrupt-names = "error", + "ch0", "ch1", "ch2", "ch3", + "ch4", "ch5", "ch6", "ch7", + "ch8", "ch9", "ch10", "ch11", + "ch12"; + clocks = <&mstp5_clks R8A7793_CLK_AUDIO_DMAC0>; + clock-names = "fck"; + power-domains = <&cpg_clocks>; + #dma-cells = <1>; + dma-channels = <13>; + }; + + audma1: dma-controller@ec720000 { + compatible = "renesas,dmac-r8a7793", "renesas,rcar-dmac"; + reg = <0 0xec720000 0 0x10000>; + interrupts = ; + interrupt-names = "error", + "ch0", "ch1", "ch2", "ch3", + "ch4", "ch5", "ch6", "ch7", + "ch8", "ch9", "ch10", "ch11", + "ch12"; + clocks = <&mstp5_clks R8A7793_CLK_AUDIO_DMAC1>; + clock-names = "fck"; + power-domains = <&cpg_clocks>; + #dma-cells = <1>; + dma-channels = <13>; + }; + + /* The memory map in the User's Manual maps the cores to bus numbers */ + i2c0: i2c@e6508000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7793"; + reg = <0 0xe6508000 0 0x40>; + interrupts = ; + clocks = <&mstp9_clks R8A7793_CLK_I2C0>; + power-domains = <&cpg_clocks>; + i2c-scl-internal-delay-ns = <6>; + status = "disabled"; + }; + + i2c1: i2c@e6518000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7793"; + reg = <0 0xe6518000 0 0x40>; + interrupts = ; + clocks = <&mstp9_clks R8A7793_CLK_I2C1>; + power-domains = <&cpg_clocks>; + i2c-scl-internal-delay-ns = <6>; + status = "disabled"; + }; + + i2c2: i2c@e6530000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7793"; + reg = <0 0xe6530000 0 0x40>; + interrupts = ; + clocks = <&mstp9_clks R8A7793_CLK_I2C2>; + power-domains = <&cpg_clocks>; + i2c-scl-internal-delay-ns = <6>; + status = "disabled"; + }; + + i2c3: i2c@e6540000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7793"; + reg = <0 0xe6540000 0 0x40>; + interrupts = ; + clocks = <&mstp9_clks R8A7793_CLK_I2C3>; + power-domains = <&cpg_clocks>; + i2c-scl-internal-delay-ns = <6>; + status = "disabled"; + }; + + i2c4: i2c@e6520000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7793"; + reg = <0 0xe6520000 0 0x40>; + interrupts = ; + clocks = <&mstp9_clks R8A7793_CLK_I2C4>; + power-domains = <&cpg_clocks>; + i2c-scl-internal-delay-ns = <6>; + status = "disabled"; + }; + + i2c5: i2c@e6528000 { + /* doesn't need pinmux */ + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,i2c-r8a7793"; + reg = <0 0xe6528000 0 0x40>; + interrupts = ; + clocks = <&mstp9_clks R8A7793_CLK_I2C5>; + power-domains = <&cpg_clocks>; + i2c-scl-internal-delay-ns = <110>; + status = "disabled"; + }; + + i2c6: i2c@e60b0000 { + /* doesn't need pinmux */ + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,iic-r8a7793", "renesas,rmobile-iic"; + reg = <0 0xe60b0000 0 0x425>; + interrupts = ; + clocks = <&mstp9_clks R8A7793_CLK_IICDVFS>; + dmas = <&dmac0 0x77>, <&dmac0 0x78>; + dma-names = "tx", "rx"; + power-domains = <&cpg_clocks>; + status = "disabled"; + }; + + i2c7: i2c@e6500000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,iic-r8a7793", "renesas,rmobile-iic"; + reg = <0 0xe6500000 0 0x425>; + interrupts = ; + clocks = <&mstp3_clks R8A7793_CLK_IIC0>; + dmas = <&dmac0 0x61>, <&dmac0 0x62>; + dma-names = "tx", "rx"; + power-domains = <&cpg_clocks>; + status = "disabled"; + }; + + i2c8: i2c@e6510000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,iic-r8a7793", "renesas,rmobile-iic"; + reg = <0 0xe6510000 0 0x425>; + interrupts = ; + clocks = <&mstp3_clks R8A7793_CLK_IIC1>; + dmas = <&dmac0 0x65>, <&dmac0 0x66>; + dma-names = "tx", "rx"; + power-domains = <&cpg_clocks>; + status = "disabled"; + }; + + pfc: pfc@e6060000 { + compatible = "renesas,pfc-r8a7793"; + reg = <0 0xe6060000 0 0x250>; + }; + scifa0: serial@e6c40000 { - compatible = "renesas,scifa-r8a7793", "renesas,scifa"; + compatible = "renesas,scifa-r8a7793", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c40000 0 64>; - interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7793_CLK_SCIFA0>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x21>, <&dmac0 0x22>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -310,11 +521,12 @@ }; scifa1: serial@e6c50000 { - compatible = "renesas,scifa-r8a7793", "renesas,scifa"; + compatible = "renesas,scifa-r8a7793", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c50000 0 64>; - interrupts = <0 145 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7793_CLK_SCIFA1>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x25>, <&dmac0 0x26>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -322,11 +534,12 @@ }; scifa2: serial@e6c60000 { - compatible = "renesas,scifa-r8a7793", "renesas,scifa"; + compatible = "renesas,scifa-r8a7793", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c60000 0 64>; - interrupts = <0 151 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7793_CLK_SCIFA2>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x27>, <&dmac0 0x28>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -334,11 +547,12 @@ }; scifa3: serial@e6c70000 { - compatible = "renesas,scifa-r8a7793", "renesas,scifa"; + compatible = "renesas,scifa-r8a7793", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c70000 0 64>; - interrupts = <0 29 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp11_clks R8A7793_CLK_SCIFA3>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x1b>, <&dmac0 0x1c>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -346,11 +560,12 @@ }; scifa4: serial@e6c78000 { - compatible = "renesas,scifa-r8a7793", "renesas,scifa"; + compatible = "renesas,scifa-r8a7793", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c78000 0 64>; - interrupts = <0 30 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp11_clks R8A7793_CLK_SCIFA4>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x1f>, <&dmac0 0x20>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -358,11 +573,12 @@ }; scifa5: serial@e6c80000 { - compatible = "renesas,scifa-r8a7793", "renesas,scifa"; + compatible = "renesas,scifa-r8a7793", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c80000 0 64>; - interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp11_clks R8A7793_CLK_SCIFA5>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x23>, <&dmac0 0x24>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -370,11 +586,12 @@ }; scifb0: serial@e6c20000 { - compatible = "renesas,scifb-r8a7793", "renesas,scifb"; + compatible = "renesas,scifb-r8a7793", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6c20000 0 64>; - interrupts = <0 148 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7793_CLK_SCIFB0>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x3d>, <&dmac0 0x3e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -382,11 +599,12 @@ }; scifb1: serial@e6c30000 { - compatible = "renesas,scifb-r8a7793", "renesas,scifb"; + compatible = "renesas,scifb-r8a7793", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6c30000 0 64>; - interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7793_CLK_SCIFB1>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x19>, <&dmac0 0x1a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -394,11 +612,12 @@ }; scifb2: serial@e6ce0000 { - compatible = "renesas,scifb-r8a7793", "renesas,scifb"; + compatible = "renesas,scifb-r8a7793", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6ce0000 0 64>; - interrupts = <0 150 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7793_CLK_SCIFB2>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x1d>, <&dmac0 0x1e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -406,11 +625,13 @@ }; scif0: serial@e6e60000 { - compatible = "renesas,scif-r8a7793", "renesas,scif"; + compatible = "renesas,scif-r8a7793", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6e60000 0 64>; - interrupts = <0 152 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7793_CLK_SCIF0>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7793_CLK_SCIF0>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x29>, <&dmac0 0x2a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -418,11 +639,13 @@ }; scif1: serial@e6e68000 { - compatible = "renesas,scif-r8a7793", "renesas,scif"; + compatible = "renesas,scif-r8a7793", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6e68000 0 64>; - interrupts = <0 153 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7793_CLK_SCIF1>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7793_CLK_SCIF1>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x2d>, <&dmac0 0x2e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -430,11 +653,13 @@ }; scif2: serial@e6e58000 { - compatible = "renesas,scif-r8a7793", "renesas,scif"; + compatible = "renesas,scif-r8a7793", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6e58000 0 64>; - interrupts = <0 22 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7793_CLK_SCIF2>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7793_CLK_SCIF2>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x2b>, <&dmac0 0x2c>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -442,11 +667,13 @@ }; scif3: serial@e6ea8000 { - compatible = "renesas,scif-r8a7793", "renesas,scif"; + compatible = "renesas,scif-r8a7793", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6ea8000 0 64>; - interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7793_CLK_SCIF3>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7793_CLK_SCIF3>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x2f>, <&dmac0 0x30>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -454,11 +681,13 @@ }; scif4: serial@e6ee0000 { - compatible = "renesas,scif-r8a7793", "renesas,scif"; + compatible = "renesas,scif-r8a7793", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6ee0000 0 64>; - interrupts = <0 24 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7793_CLK_SCIF4>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7793_CLK_SCIF4>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0xfb>, <&dmac0 0xfc>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -466,11 +695,13 @@ }; scif5: serial@e6ee8000 { - compatible = "renesas,scif-r8a7793", "renesas,scif"; + compatible = "renesas,scif-r8a7793", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6ee8000 0 64>; - interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7793_CLK_SCIF5>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7793_CLK_SCIF5>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0xfd>, <&dmac0 0xfe>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -478,11 +709,13 @@ }; hscif0: serial@e62c0000 { - compatible = "renesas,hscif-r8a7793", "renesas,hscif"; + compatible = "renesas,hscif-r8a7793", + "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62c0000 0 96>; - interrupts = <0 154 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7793_CLK_HSCIF0>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7793_CLK_HSCIF0>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x39>, <&dmac0 0x3a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -490,11 +723,13 @@ }; hscif1: serial@e62c8000 { - compatible = "renesas,hscif-r8a7793", "renesas,hscif"; + compatible = "renesas,hscif-r8a7793", + "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62c8000 0 96>; - interrupts = <0 155 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7793_CLK_HSCIF1>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7793_CLK_HSCIF1>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x4d>, <&dmac0 0x4e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -502,11 +737,13 @@ }; hscif2: serial@e62d0000 { - compatible = "renesas,hscif-r8a7793", "renesas,hscif"; + compatible = "renesas,hscif-r8a7793", + "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62d0000 0 96>; - interrupts = <0 21 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7793_CLK_HSCIF2>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7793_CLK_HSCIF2>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x3b>, <&dmac0 0x3c>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -516,7 +753,7 @@ ether: ethernet@ee700000 { compatible = "renesas,ether-r8a7793"; reg = <0 0xee700000 0 0x400>; - interrupts = <0 162 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7793_CLK_ETHER>; power-domains = <&cpg_clocks>; phy-mode = "rmii"; @@ -528,7 +765,7 @@ qspi: spi@e6b10000 { compatible = "renesas,qspi-r8a7793", "renesas,qspi"; reg = <0 0xe6b10000 0 0x2c>; - interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7793_CLK_QSPI_MOD>; dmas = <&dmac0 0x17>, <&dmac0 0x18>; dma-names = "tx", "rx"; @@ -544,8 +781,8 @@ reg = <0 0xfeb00000 0 0x40000>, <0 0xfeb90000 0 0x1c>; reg-names = "du", "lvds.0"; - interrupts = <0 256 IRQ_TYPE_LEVEL_HIGH>, - <0 268 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; clocks = <&mstp7_clks R8A7793_CLK_DU0>, <&mstp7_clks R8A7793_CLK_DU1>, <&mstp7_clks R8A7793_CLK_LVDS0>; @@ -583,6 +820,38 @@ clock-output-names = "extal"; }; + /* + * The external audio clocks are configured as 0 Hz fixed frequency clocks by + * default. Boards that provide audio clocks should override them. + */ + audio_clk_a: audio_clk_a { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <0>; + clock-output-names = "audio_clk_a"; + }; + audio_clk_b: audio_clk_b { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <0>; + clock-output-names = "audio_clk_b"; + }; + audio_clk_c: audio_clk_c { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <0>; + clock-output-names = "audio_clk_c"; + }; + + /* External SCIF clock */ + scif_clk: scif { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* This value must be overridden by the board. */ + clock-frequency = <0>; + status = "disabled"; + }; + /* Special CPG clocks */ cpg_clocks: cpg_clocks@e6150000 { compatible = "renesas,r8a7793-cpg-clocks", @@ -671,6 +940,14 @@ clock-mult = <1>; clock-output-names = "p"; }; + m2_clk: m2_clk { + compatible = "fixed-factor-clock"; + clocks = <&cpg_clocks R8A7793_CLK_PLL1>; + #clock-cells = <0>; + clock-div = <8>; + clock-mult = <1>; + clock-output-names = "m2"; + }; rclk_clk: rclk_clk { compatible = "fixed-factor-clock"; clocks = <&cpg_clocks R8A7793_CLK_PLL1>; @@ -770,10 +1047,11 @@ mstp5_clks: mstp5_clks@e6150144 { compatible = "renesas,r8a7793-mstp-clocks", "renesas,cpg-mstp-clocks"; reg = <0 0xe6150144 0 4>, <0 0xe615003c 0 4>; - clocks = <&extal_clk>; + clocks = <&hp_clk>, <&hp_clk>, <&extal_clk>; #clock-cells = <1>; - clock-indices = ; - clock-output-names = "thermal"; + clock-indices = ; + clock-output-names = "audmac0", "audmac1", "thermal"; }; mstp7_clks: mstp7_clks@e615014c { compatible = "renesas,r8a7793-mstp-clocks", @@ -820,19 +1098,61 @@ reg = <0 0xe6150994 0 4>, <0 0xe61509a4 0 4>; clocks = <&cp_clk>, <&cp_clk>, <&cp_clk>, <&cp_clk>, <&cp_clk>, <&cp_clk>, <&cp_clk>, <&cp_clk>, - <&cpg_clocks R8A7793_CLK_QSPI>; + <&cpg_clocks R8A7793_CLK_QSPI>, <&hp_clk>, + <&cp_clk>, <&hp_clk>, <&hp_clk>, <&hp_clk>, + <&hp_clk>, <&hp_clk>; #clock-cells = <1>; clock-indices = < R8A7793_CLK_GPIO7 R8A7793_CLK_GPIO6 R8A7793_CLK_GPIO5 R8A7793_CLK_GPIO4 R8A7793_CLK_GPIO3 R8A7793_CLK_GPIO2 R8A7793_CLK_GPIO1 R8A7793_CLK_GPIO0 - R8A7793_CLK_QSPI_MOD + R8A7793_CLK_QSPI_MOD R8A7793_CLK_I2C5 + R8A7793_CLK_IICDVFS R8A7793_CLK_I2C4 + R8A7793_CLK_I2C3 R8A7793_CLK_I2C2 + R8A7793_CLK_I2C1 R8A7793_CLK_I2C0 >; clock-output-names = "gpio7", "gpio6", "gpio5", "gpio4", "gpio3", "gpio2", "gpio1", "gpio0", - "qspi_mod"; + "qspi_mod", "i2c5", "i2c6", "i2c4", + "i2c3", "i2c2", "i2c1", "i2c0"; + }; + mstp10_clks: mstp10_clks@e6150998 { + compatible = "renesas,r8a7793-mstp-clocks", "renesas,cpg-mstp-clocks"; + reg = <0 0xe6150998 0 4>, <0 0xe61509a8 0 4>; + clocks = <&p_clk>, + <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, + <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&p_clk>, + <&p_clk>, + <&mstp10_clks R8A7793_CLK_SCU_ALL>, <&mstp10_clks R8A7793_CLK_SCU_ALL>, + <&mstp10_clks R8A7793_CLK_SCU_ALL>, <&mstp10_clks R8A7793_CLK_SCU_ALL>, + <&mstp10_clks R8A7793_CLK_SCU_ALL>, <&mstp10_clks R8A7793_CLK_SCU_ALL>, + <&mstp10_clks R8A7793_CLK_SCU_ALL>, <&mstp10_clks R8A7793_CLK_SCU_ALL>, + <&mstp10_clks R8A7793_CLK_SCU_ALL>, <&mstp10_clks R8A7793_CLK_SCU_ALL>, + <&mstp10_clks R8A7793_CLK_SCU_ALL>, <&mstp10_clks R8A7793_CLK_SCU_ALL>, + <&mstp10_clks R8A7793_CLK_SCU_ALL>, <&mstp10_clks R8A7793_CLK_SCU_ALL>; + + #clock-cells = <1>; + clock-indices = < + R8A7793_CLK_SSI_ALL + R8A7793_CLK_SSI9 R8A7793_CLK_SSI8 R8A7793_CLK_SSI7 R8A7793_CLK_SSI6 R8A7793_CLK_SSI5 + R8A7793_CLK_SSI4 R8A7793_CLK_SSI3 R8A7793_CLK_SSI2 R8A7793_CLK_SSI1 R8A7793_CLK_SSI0 + R8A7793_CLK_SCU_ALL + R8A7793_CLK_SCU_DVC1 R8A7793_CLK_SCU_DVC0 + R8A7793_CLK_SCU_CTU1_MIX1 R8A7793_CLK_SCU_CTU0_MIX0 + R8A7793_CLK_SCU_SRC9 R8A7793_CLK_SCU_SRC8 R8A7793_CLK_SCU_SRC7 R8A7793_CLK_SCU_SRC6 R8A7793_CLK_SCU_SRC5 + R8A7793_CLK_SCU_SRC4 R8A7793_CLK_SCU_SRC3 R8A7793_CLK_SCU_SRC2 R8A7793_CLK_SCU_SRC1 R8A7793_CLK_SCU_SRC0 + >; + clock-output-names = + "ssi-all", + "ssi9", "ssi8", "ssi7", "ssi6", "ssi5", + "ssi4", "ssi3", "ssi2", "ssi1", "ssi0", + "scu-all", + "scu-dvc1", "scu-dvc0", + "scu-ctu1-mix1", "scu-ctu0-mix0", + "scu-src9", "scu-src8", "scu-src7", "scu-src6", "scu-src5", + "scu-src4", "scu-src3", "scu-src2", "scu-src1", "scu-src0"; }; mstp11_clks: mstp11_clks@e615099c { compatible = "renesas,r8a7793-mstp-clocks", "renesas,cpg-mstp-clocks"; @@ -849,8 +1169,8 @@ ipmmu_sy0: mmu@e6280000 { compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa"; reg = <0 0xe6280000 0 0x1000>; - interrupts = <0 223 IRQ_TYPE_LEVEL_HIGH>, - <0 224 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -858,7 +1178,7 @@ ipmmu_sy1: mmu@e6290000 { compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa"; reg = <0 0xe6290000 0 0x1000>; - interrupts = <0 225 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #iommu-cells = <1>; status = "disabled"; }; @@ -866,8 +1186,8 @@ ipmmu_ds: mmu@e6740000 { compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa"; reg = <0 0xe6740000 0 0x1000>; - interrupts = <0 198 IRQ_TYPE_LEVEL_HIGH>, - <0 199 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -875,7 +1195,7 @@ ipmmu_mp: mmu@ec680000 { compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa"; reg = <0 0xec680000 0 0x1000>; - interrupts = <0 226 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #iommu-cells = <1>; status = "disabled"; }; @@ -883,8 +1203,8 @@ ipmmu_mx: mmu@fe951000 { compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa"; reg = <0 0xfe951000 0 0x1000>; - interrupts = <0 222 IRQ_TYPE_LEVEL_HIGH>, - <0 221 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -892,7 +1212,7 @@ ipmmu_rt: mmu@ffc80000 { compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa"; reg = <0 0xffc80000 0 0x1000>; - interrupts = <0 307 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #iommu-cells = <1>; status = "disabled"; }; @@ -900,9 +1220,166 @@ ipmmu_gp: mmu@e62a0000 { compatible = "renesas,ipmmu-r8a7793", "renesas,ipmmu-vmsa"; reg = <0 0xe62a0000 0 0x1000>; - interrupts = <0 260 IRQ_TYPE_LEVEL_HIGH>, - <0 261 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; + + rcar_sound: sound@ec500000 { + /* + * #sound-dai-cells is required + * + * Single DAI : #sound-dai-cells = <0>; <&rcar_sound>; + * Multi DAI : #sound-dai-cells = <1>; <&rcar_sound N>; + */ + compatible = "renesas,rcar_sound-r8a7793", "renesas,rcar_sound-gen2"; + reg = <0 0xec500000 0 0x1000>, /* SCU */ + <0 0xec5a0000 0 0x100>, /* ADG */ + <0 0xec540000 0 0x1000>, /* SSIU */ + <0 0xec541000 0 0x280>, /* SSI */ + <0 0xec740000 0 0x200>; /* Audio DMAC peri peri*/ + reg-names = "scu", "adg", "ssiu", "ssi", "audmapp"; + + clocks = <&mstp10_clks R8A7793_CLK_SSI_ALL>, + <&mstp10_clks R8A7793_CLK_SSI9>, <&mstp10_clks R8A7793_CLK_SSI8>, + <&mstp10_clks R8A7793_CLK_SSI7>, <&mstp10_clks R8A7793_CLK_SSI6>, + <&mstp10_clks R8A7793_CLK_SSI5>, <&mstp10_clks R8A7793_CLK_SSI4>, + <&mstp10_clks R8A7793_CLK_SSI3>, <&mstp10_clks R8A7793_CLK_SSI2>, + <&mstp10_clks R8A7793_CLK_SSI1>, <&mstp10_clks R8A7793_CLK_SSI0>, + <&mstp10_clks R8A7793_CLK_SCU_SRC9>, <&mstp10_clks R8A7793_CLK_SCU_SRC8>, + <&mstp10_clks R8A7793_CLK_SCU_SRC7>, <&mstp10_clks R8A7793_CLK_SCU_SRC6>, + <&mstp10_clks R8A7793_CLK_SCU_SRC5>, <&mstp10_clks R8A7793_CLK_SCU_SRC4>, + <&mstp10_clks R8A7793_CLK_SCU_SRC3>, <&mstp10_clks R8A7793_CLK_SCU_SRC2>, + <&mstp10_clks R8A7793_CLK_SCU_SRC1>, <&mstp10_clks R8A7793_CLK_SCU_SRC0>, + <&mstp10_clks R8A7793_CLK_SCU_DVC0>, <&mstp10_clks R8A7793_CLK_SCU_DVC1>, + <&audio_clk_a>, <&audio_clk_b>, <&audio_clk_c>, <&m2_clk>; + clock-names = "ssi-all", + "ssi.9", "ssi.8", "ssi.7", "ssi.6", "ssi.5", + "ssi.4", "ssi.3", "ssi.2", "ssi.1", "ssi.0", + "src.9", "src.8", "src.7", "src.6", "src.5", + "src.4", "src.3", "src.2", "src.1", "src.0", + "dvc.0", "dvc.1", + "clk_a", "clk_b", "clk_c", "clk_i"; + power-domains = <&cpg_clocks>; + + status = "disabled"; + + rcar_sound,dvc { + dvc0: dvc@0 { + dmas = <&audma0 0xbc>; + dma-names = "tx"; + }; + dvc1: dvc@1 { + dmas = <&audma0 0xbe>; + dma-names = "tx"; + }; + }; + + rcar_sound,src { + src0: src@0 { + interrupts = ; + dmas = <&audma0 0x85>, <&audma1 0x9a>; + dma-names = "rx", "tx"; + }; + src1: src@1 { + interrupts = ; + dmas = <&audma0 0x87>, <&audma1 0x9c>; + dma-names = "rx", "tx"; + }; + src2: src@2 { + interrupts = ; + dmas = <&audma0 0x89>, <&audma1 0x9e>; + dma-names = "rx", "tx"; + }; + src3: src@3 { + interrupts = ; + dmas = <&audma0 0x8b>, <&audma1 0xa0>; + dma-names = "rx", "tx"; + }; + src4: src@4 { + interrupts = ; + dmas = <&audma0 0x8d>, <&audma1 0xb0>; + dma-names = "rx", "tx"; + }; + src5: src@5 { + interrupts = ; + dmas = <&audma0 0x8f>, <&audma1 0xb2>; + dma-names = "rx", "tx"; + }; + src6: src@6 { + interrupts = ; + dmas = <&audma0 0x91>, <&audma1 0xb4>; + dma-names = "rx", "tx"; + }; + src7: src@7 { + interrupts = ; + dmas = <&audma0 0x93>, <&audma1 0xb6>; + dma-names = "rx", "tx"; + }; + src8: src@8 { + interrupts = ; + dmas = <&audma0 0x95>, <&audma1 0xb8>; + dma-names = "rx", "tx"; + }; + src9: src@9 { + interrupts = ; + dmas = <&audma0 0x97>, <&audma1 0xba>; + dma-names = "rx", "tx"; + }; + }; + + rcar_sound,ssi { + ssi0: ssi@0 { + interrupts = ; + dmas = <&audma0 0x01>, <&audma1 0x02>, <&audma0 0x15>, <&audma1 0x16>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi1: ssi@1 { + interrupts = ; + dmas = <&audma0 0x03>, <&audma1 0x04>, <&audma0 0x49>, <&audma1 0x4a>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi2: ssi@2 { + interrupts = ; + dmas = <&audma0 0x05>, <&audma1 0x06>, <&audma0 0x63>, <&audma1 0x64>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi3: ssi@3 { + interrupts = ; + dmas = <&audma0 0x07>, <&audma1 0x08>, <&audma0 0x6f>, <&audma1 0x70>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi4: ssi@4 { + interrupts = ; + dmas = <&audma0 0x09>, <&audma1 0x0a>, <&audma0 0x71>, <&audma1 0x72>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi5: ssi@5 { + interrupts = ; + dmas = <&audma0 0x0b>, <&audma1 0x0c>, <&audma0 0x73>, <&audma1 0x74>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi6: ssi@6 { + interrupts = ; + dmas = <&audma0 0x0d>, <&audma1 0x0e>, <&audma0 0x75>, <&audma1 0x76>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi7: ssi@7 { + interrupts = ; + dmas = <&audma0 0x0f>, <&audma1 0x10>, <&audma0 0x79>, <&audma1 0x7a>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi8: ssi@8 { + interrupts = ; + dmas = <&audma0 0x11>, <&audma1 0x12>, <&audma0 0x7b>, <&audma1 0x7c>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + ssi9: ssi@9 { + interrupts = ; + dmas = <&audma0 0x13>, <&audma1 0x14>, <&audma0 0x7d>, <&audma1 0x7e>; + dma-names = "rx", "tx", "rxu", "txu"; + }; + }; + }; }; diff --git a/arch/arm/boot/dts/r8a7794-alt.dts b/arch/arm/boot/dts/r8a7794-alt.dts index 2394e4883786f13eb0a4b005fb6a81e456f9a3f0..ca9bc4fff28751ea9e2b11b6afd23c7920449759 100644 --- a/arch/arm/boot/dts/r8a7794-alt.dts +++ b/arch/arm/boot/dts/r8a7794-alt.dts @@ -103,6 +103,9 @@ }; &pfc { + pinctrl-0 = <&scif_clk_pins>; + pinctrl-names = "default"; + du_pins: du { renesas,groups = "du1_rgb666", "du1_sync", "du1_disp", "du1_dotclkout0"; renesas,function = "du"; @@ -113,6 +116,11 @@ renesas,function = "scif2"; }; + scif_clk_pins: scif_clk { + renesas,groups = "scif_clk"; + renesas,function = "scif_clk"; + }; + ether_pins: ether { renesas,groups = "eth_link", "eth_mdio", "eth_rmii"; renesas,function = "eth"; @@ -138,6 +146,13 @@ status = "okay"; }; +&pfc { + qspi_pins: spi0 { + renesas,groups = "qspi_ctrl", "qspi_data4"; + renesas,function = "qspi"; + }; +}; + ðer { pinctrl-0 = <ðer_pins &phy1_pins>; pinctrl-names = "default"; @@ -197,3 +212,47 @@ status = "okay"; }; + +&scif_clk { + clock-frequency = <14745600>; + status = "okay"; +}; + +&qspi { + pinctrl-0 = <&qspi_pins>; + pinctrl-names = "default"; + + status = "okay"; + + flash@0 { + compatible = "spansion,s25fl512s", "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <30000000>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + spi-cpol; + spi-cpha; + m25p,fast-read; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "loader"; + reg = <0x00000000 0x00040000>; + read-only; + }; + partition@40000 { + label = "system"; + reg = <0x00040000 0x00040000>; + read-only; + }; + partition@80000 { + label = "user"; + reg = <0x00080000 0x03f80000>; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/r8a7794-silk.dts b/arch/arm/boot/dts/r8a7794-silk.dts index 5153e3af25d94c0f8f14a93b5f894fa60e217fce..66f077a3ca41d1b06a367ca265ee5aac48f71bf2 100644 --- a/arch/arm/boot/dts/r8a7794-silk.dts +++ b/arch/arm/boot/dts/r8a7794-silk.dts @@ -64,6 +64,61 @@ states = <3300000 1 1800000 0>; }; + + vga-encoder { + compatible = "adi,adv7123"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + adv7123_in: endpoint { + remote-endpoint = <&du_out_rgb1>; + }; + }; + port@1 { + reg = <1>; + adv7123_out: endpoint { + remote-endpoint = <&vga_in>; + }; + }; + }; + }; + + hdmi-out { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_con: endpoint { + remote-endpoint = <&adv7511_out>; + }; + }; + }; + + vga { + compatible = "vga-connector"; + + port { + vga_in: endpoint { + remote-endpoint = <&adv7123_out>; + }; + }; + }; + + x2_clk: x2-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <148500000>; + }; + + x3_clk: x3-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <74250000>; + }; }; &extal_clk { @@ -71,11 +126,19 @@ }; &pfc { + pinctrl-0 = <&scif_clk_pins>; + pinctrl-names = "default"; + scif2_pins: serial2 { renesas,groups = "scif2_data"; renesas,function = "scif2"; }; + scif_clk_pins: scif_clk { + renesas,groups = "scif_clk"; + renesas,function = "scif_clk"; + }; + ether_pins: ether { renesas,groups = "eth_link", "eth_mdio", "eth_rmii"; renesas,function = "eth"; @@ -129,6 +192,11 @@ status = "okay"; }; +&scif_clk { + clock-frequency = <14745600>; + status = "okay"; +}; + ðer { pinctrl-0 = <ðer_pins &phy1_pins>; pinctrl-names = "default"; @@ -164,6 +232,38 @@ }; }; }; + + hdmi@39 { + compatible = "adi,adv7511w"; + reg = <0x39>; + interrupt-parent = <&gpio5>; + interrupts = <23 IRQ_TYPE_LEVEL_LOW>; + + adi,input-depth = <8>; + adi,input-colorspace = "rgb"; + adi,input-clock = "1x"; + adi,input-style = <1>; + adi,input-justification = "evenly"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + adv7511_in: endpoint { + remote-endpoint = <&du_out_rgb0>; + }; + }; + + port@1 { + reg = <1>; + adv7511_out: endpoint { + remote-endpoint = <&hdmi_con>; + }; + }; + }; + }; }; &mmcif0 { @@ -258,3 +358,25 @@ &usbphy { status = "okay"; }; + +&du { + status = "okay"; + + clocks = <&mstp7_clks R8A7794_CLK_DU0>, + <&mstp7_clks R8A7794_CLK_DU0>, + <&x2_clk>, <&x3_clk>; + clock-names = "du.0", "du.1", "dclkin.0", "dclkin.1"; + + ports { + port@0 { + endpoint { + remote-endpoint = <&adv7511_in>; + }; + }; + port@1 { + endpoint { + remote-endpoint = <&adv7123_in>; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/r8a7794.dtsi b/arch/arm/boot/dts/r8a7794.dtsi index 6c78f1fae90f7ae43b42f6a8baea078a73fd30f4..eacb2b291361ec5cb7c5efbaa2812c316059fbee 100644 --- a/arch/arm/boot/dts/r8a7794.dtsi +++ b/arch/arm/boot/dts/r8a7794.dtsi @@ -40,6 +40,7 @@ compatible = "arm,cortex-a7"; reg = <0>; clock-frequency = <1000000000>; + next-level-cache = <&L2_CA7>; }; cpu1: cpu@1 { @@ -47,9 +48,16 @@ compatible = "arm,cortex-a7"; reg = <1>; clock-frequency = <1000000000>; + next-level-cache = <&L2_CA7>; }; }; + L2_CA7: cache-controller@1 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + }; + gic: interrupt-controller@f1001000 { compatible = "arm,gic-400"; #interrupt-cells = <3>; @@ -59,13 +67,13 @@ <0 0xf1002000 0 0x1000>, <0 0xf1004000 0 0x2000>, <0 0xf1006000 0 0x2000>; - interrupts = <1 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>; + interrupts = ; }; gpio0: gpio@e6050000 { compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar"; reg = <0 0xe6050000 0 0x50>; - interrupts = <0 4 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 0 32>; @@ -78,7 +86,7 @@ gpio1: gpio@e6051000 { compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar"; reg = <0 0xe6051000 0 0x50>; - interrupts = <0 5 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 32 26>; @@ -91,7 +99,7 @@ gpio2: gpio@e6052000 { compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar"; reg = <0 0xe6052000 0 0x50>; - interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 64 32>; @@ -104,7 +112,7 @@ gpio3: gpio@e6053000 { compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar"; reg = <0 0xe6053000 0 0x50>; - interrupts = <0 7 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 96 32>; @@ -117,7 +125,7 @@ gpio4: gpio@e6054000 { compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar"; reg = <0 0xe6054000 0 0x50>; - interrupts = <0 8 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 128 32>; @@ -130,7 +138,7 @@ gpio5: gpio@e6055000 { compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar"; reg = <0 0xe6055000 0 0x50>; - interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 160 28>; @@ -143,7 +151,7 @@ gpio6: gpio@e6055400 { compatible = "renesas,gpio-r8a7794", "renesas,gpio-rcar"; reg = <0 0xe6055400 0 0x50>; - interrupts = <0 10 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #gpio-cells = <2>; gpio-controller; gpio-ranges = <&pfc 0 192 26>; @@ -156,8 +164,8 @@ cmt0: timer@ffca0000 { compatible = "renesas,cmt-48-gen2"; reg = <0 0xffca0000 0 0x1004>; - interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>, - <0 143 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; clocks = <&mstp1_clks R8A7794_CLK_CMT0>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -170,14 +178,14 @@ cmt1: timer@e6130000 { compatible = "renesas,cmt-48-gen2"; reg = <0 0xe6130000 0 0x1004>; - interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>, - <0 121 IRQ_TYPE_LEVEL_HIGH>, - <0 122 IRQ_TYPE_LEVEL_HIGH>, - <0 123 IRQ_TYPE_LEVEL_HIGH>, - <0 124 IRQ_TYPE_LEVEL_HIGH>, - <0 125 IRQ_TYPE_LEVEL_HIGH>, - <0 126 IRQ_TYPE_LEVEL_HIGH>, - <0 127 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + ; clocks = <&mstp3_clks R8A7794_CLK_CMT1>; clock-names = "fck"; power-domains = <&cpg_clocks>; @@ -189,10 +197,10 @@ timer { compatible = "arm,armv7-timer"; - interrupts = <1 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <1 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <1 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>, - <1 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>; + interrupts = , + , + , + ; }; irqc0: interrupt-controller@e61c0000 { @@ -200,16 +208,16 @@ #interrupt-cells = <2>; interrupt-controller; reg = <0 0xe61c0000 0 0x200>; - interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>, - <0 1 IRQ_TYPE_LEVEL_HIGH>, - <0 2 IRQ_TYPE_LEVEL_HIGH>, - <0 3 IRQ_TYPE_LEVEL_HIGH>, - <0 12 IRQ_TYPE_LEVEL_HIGH>, - <0 13 IRQ_TYPE_LEVEL_HIGH>, - <0 14 IRQ_TYPE_LEVEL_HIGH>, - <0 15 IRQ_TYPE_LEVEL_HIGH>, - <0 16 IRQ_TYPE_LEVEL_HIGH>, - <0 17 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + , + , + , + , + , + , + , + , + ; clocks = <&mstp4_clks R8A7794_CLK_IRQC>; power-domains = <&cpg_clocks>; }; @@ -222,22 +230,22 @@ dmac0: dma-controller@e6700000 { compatible = "renesas,dmac-r8a7794", "renesas,rcar-dmac"; reg = <0 0xe6700000 0 0x20000>; - interrupts = <0 197 IRQ_TYPE_LEVEL_HIGH - 0 200 IRQ_TYPE_LEVEL_HIGH - 0 201 IRQ_TYPE_LEVEL_HIGH - 0 202 IRQ_TYPE_LEVEL_HIGH - 0 203 IRQ_TYPE_LEVEL_HIGH - 0 204 IRQ_TYPE_LEVEL_HIGH - 0 205 IRQ_TYPE_LEVEL_HIGH - 0 206 IRQ_TYPE_LEVEL_HIGH - 0 207 IRQ_TYPE_LEVEL_HIGH - 0 208 IRQ_TYPE_LEVEL_HIGH - 0 209 IRQ_TYPE_LEVEL_HIGH - 0 210 IRQ_TYPE_LEVEL_HIGH - 0 211 IRQ_TYPE_LEVEL_HIGH - 0 212 IRQ_TYPE_LEVEL_HIGH - 0 213 IRQ_TYPE_LEVEL_HIGH - 0 214 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -253,22 +261,22 @@ dmac1: dma-controller@e6720000 { compatible = "renesas,dmac-r8a7794", "renesas,rcar-dmac"; reg = <0 0xe6720000 0 0x20000>; - interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH - 0 216 IRQ_TYPE_LEVEL_HIGH - 0 217 IRQ_TYPE_LEVEL_HIGH - 0 218 IRQ_TYPE_LEVEL_HIGH - 0 219 IRQ_TYPE_LEVEL_HIGH - 0 308 IRQ_TYPE_LEVEL_HIGH - 0 309 IRQ_TYPE_LEVEL_HIGH - 0 310 IRQ_TYPE_LEVEL_HIGH - 0 311 IRQ_TYPE_LEVEL_HIGH - 0 312 IRQ_TYPE_LEVEL_HIGH - 0 313 IRQ_TYPE_LEVEL_HIGH - 0 314 IRQ_TYPE_LEVEL_HIGH - 0 315 IRQ_TYPE_LEVEL_HIGH - 0 316 IRQ_TYPE_LEVEL_HIGH - 0 317 IRQ_TYPE_LEVEL_HIGH - 0 318 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -282,11 +290,12 @@ }; scifa0: serial@e6c40000 { - compatible = "renesas,scifa-r8a7794", "renesas,scifa"; + compatible = "renesas,scifa-r8a7794", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c40000 0 64>; - interrupts = <0 144 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7794_CLK_SCIFA0>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x21>, <&dmac0 0x22>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -294,11 +303,12 @@ }; scifa1: serial@e6c50000 { - compatible = "renesas,scifa-r8a7794", "renesas,scifa"; + compatible = "renesas,scifa-r8a7794", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c50000 0 64>; - interrupts = <0 145 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7794_CLK_SCIFA1>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x25>, <&dmac0 0x26>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -306,11 +316,12 @@ }; scifa2: serial@e6c60000 { - compatible = "renesas,scifa-r8a7794", "renesas,scifa"; + compatible = "renesas,scifa-r8a7794", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c60000 0 64>; - interrupts = <0 151 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7794_CLK_SCIFA2>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x27>, <&dmac0 0x28>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -318,11 +329,12 @@ }; scifa3: serial@e6c70000 { - compatible = "renesas,scifa-r8a7794", "renesas,scifa"; + compatible = "renesas,scifa-r8a7794", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c70000 0 64>; - interrupts = <0 29 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp11_clks R8A7794_CLK_SCIFA3>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x1b>, <&dmac0 0x1c>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -330,11 +342,12 @@ }; scifa4: serial@e6c78000 { - compatible = "renesas,scifa-r8a7794", "renesas,scifa"; + compatible = "renesas,scifa-r8a7794", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c78000 0 64>; - interrupts = <0 30 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp11_clks R8A7794_CLK_SCIFA4>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x1f>, <&dmac0 0x20>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -342,11 +355,12 @@ }; scifa5: serial@e6c80000 { - compatible = "renesas,scifa-r8a7794", "renesas,scifa"; + compatible = "renesas,scifa-r8a7794", + "renesas,rcar-gen2-scifa", "renesas,scifa"; reg = <0 0xe6c80000 0 64>; - interrupts = <0 31 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp11_clks R8A7794_CLK_SCIFA5>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x23>, <&dmac0 0x24>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -354,11 +368,12 @@ }; scifb0: serial@e6c20000 { - compatible = "renesas,scifb-r8a7794", "renesas,scifb"; + compatible = "renesas,scifb-r8a7794", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6c20000 0 64>; - interrupts = <0 148 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7794_CLK_SCIFB0>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x3d>, <&dmac0 0x3e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -366,11 +381,12 @@ }; scifb1: serial@e6c30000 { - compatible = "renesas,scifb-r8a7794", "renesas,scifb"; + compatible = "renesas,scifb-r8a7794", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6c30000 0 64>; - interrupts = <0 149 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7794_CLK_SCIFB1>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x19>, <&dmac0 0x1a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -378,11 +394,12 @@ }; scifb2: serial@e6ce0000 { - compatible = "renesas,scifb-r8a7794", "renesas,scifb"; + compatible = "renesas,scifb-r8a7794", + "renesas,rcar-gen2-scifb", "renesas,scifb"; reg = <0 0xe6ce0000 0 64>; - interrupts = <0 150 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks R8A7794_CLK_SCIFB2>; - clock-names = "sci_ick"; + clock-names = "fck"; dmas = <&dmac0 0x1d>, <&dmac0 0x1e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -390,11 +407,13 @@ }; scif0: serial@e6e60000 { - compatible = "renesas,scif-r8a7794", "renesas,scif"; + compatible = "renesas,scif-r8a7794", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6e60000 0 64>; - interrupts = <0 152 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7794_CLK_SCIF0>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7794_CLK_SCIF0>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x29>, <&dmac0 0x2a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -402,11 +421,13 @@ }; scif1: serial@e6e68000 { - compatible = "renesas,scif-r8a7794", "renesas,scif"; + compatible = "renesas,scif-r8a7794", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6e68000 0 64>; - interrupts = <0 153 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7794_CLK_SCIF1>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7794_CLK_SCIF1>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x2d>, <&dmac0 0x2e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -414,11 +435,13 @@ }; scif2: serial@e6e58000 { - compatible = "renesas,scif-r8a7794", "renesas,scif"; + compatible = "renesas,scif-r8a7794", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6e58000 0 64>; - interrupts = <0 22 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7794_CLK_SCIF2>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7794_CLK_SCIF2>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x2b>, <&dmac0 0x2c>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -426,11 +449,13 @@ }; scif3: serial@e6ea8000 { - compatible = "renesas,scif-r8a7794", "renesas,scif"; + compatible = "renesas,scif-r8a7794", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6ea8000 0 64>; - interrupts = <0 23 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7794_CLK_SCIF3>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7794_CLK_SCIF3>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x2f>, <&dmac0 0x30>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -438,11 +463,13 @@ }; scif4: serial@e6ee0000 { - compatible = "renesas,scif-r8a7794", "renesas,scif"; + compatible = "renesas,scif-r8a7794", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6ee0000 0 64>; - interrupts = <0 24 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7794_CLK_SCIF4>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7794_CLK_SCIF4>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0xfb>, <&dmac0 0xfc>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -450,11 +477,13 @@ }; scif5: serial@e6ee8000 { - compatible = "renesas,scif-r8a7794", "renesas,scif"; + compatible = "renesas,scif-r8a7794", "renesas,rcar-gen2-scif", + "renesas,scif"; reg = <0 0xe6ee8000 0 64>; - interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7794_CLK_SCIF5>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7794_CLK_SCIF5>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0xfd>, <&dmac0 0xfe>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -462,11 +491,13 @@ }; hscif0: serial@e62c0000 { - compatible = "renesas,hscif-r8a7794", "renesas,hscif"; + compatible = "renesas,hscif-r8a7794", + "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62c0000 0 96>; - interrupts = <0 154 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7794_CLK_HSCIF0>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7794_CLK_HSCIF0>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x39>, <&dmac0 0x3a>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -474,11 +505,13 @@ }; hscif1: serial@e62c8000 { - compatible = "renesas,hscif-r8a7794", "renesas,hscif"; + compatible = "renesas,hscif-r8a7794", + "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62c8000 0 96>; - interrupts = <0 155 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7794_CLK_HSCIF1>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7794_CLK_HSCIF1>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x4d>, <&dmac0 0x4e>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -486,11 +519,13 @@ }; hscif2: serial@e62d0000 { - compatible = "renesas,hscif-r8a7794", "renesas,hscif"; + compatible = "renesas,hscif-r8a7794", + "renesas,rcar-gen2-hscif", "renesas,hscif"; reg = <0 0xe62d0000 0 96>; - interrupts = <0 21 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&mstp7_clks R8A7794_CLK_HSCIF2>; - clock-names = "sci_ick"; + interrupts = ; + clocks = <&mstp7_clks R8A7794_CLK_HSCIF2>, <&zs_clk>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x3b>, <&dmac0 0x3c>; dma-names = "tx", "rx"; power-domains = <&cpg_clocks>; @@ -500,7 +535,7 @@ ether: ethernet@ee700000 { compatible = "renesas,ether-r8a7794"; reg = <0 0xee700000 0 0x400>; - interrupts = <0 162 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7794_CLK_ETHER>; power-domains = <&cpg_clocks>; phy-mode = "rmii"; @@ -509,11 +544,23 @@ status = "disabled"; }; + avb: ethernet@e6800000 { + compatible = "renesas,etheravb-r8a7794", + "renesas,etheravb-rcar-gen2"; + reg = <0 0xe6800000 0 0x800>, <0 0xee0e8000 0 0x4000>; + interrupts = ; + clocks = <&mstp8_clks R8A7794_CLK_ETHERAVB>; + power-domains = <&cpg_clocks>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + /* The memory map in the User's Manual maps the cores to bus numbers */ i2c0: i2c@e6508000 { compatible = "renesas,i2c-r8a7794"; reg = <0 0xe6508000 0 0x40>; - interrupts = <0 287 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7794_CLK_I2C0>; power-domains = <&cpg_clocks>; #address-cells = <1>; @@ -525,7 +572,7 @@ i2c1: i2c@e6518000 { compatible = "renesas,i2c-r8a7794"; reg = <0 0xe6518000 0 0x40>; - interrupts = <0 288 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7794_CLK_I2C1>; power-domains = <&cpg_clocks>; #address-cells = <1>; @@ -537,7 +584,7 @@ i2c2: i2c@e6530000 { compatible = "renesas,i2c-r8a7794"; reg = <0 0xe6530000 0 0x40>; - interrupts = <0 286 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7794_CLK_I2C2>; power-domains = <&cpg_clocks>; #address-cells = <1>; @@ -549,7 +596,7 @@ i2c3: i2c@e6540000 { compatible = "renesas,i2c-r8a7794"; reg = <0 0xe6540000 0 0x40>; - interrupts = <0 290 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7794_CLK_I2C3>; power-domains = <&cpg_clocks>; #address-cells = <1>; @@ -561,7 +608,7 @@ i2c4: i2c@e6520000 { compatible = "renesas,i2c-r8a7794"; reg = <0 0xe6520000 0 0x40>; - interrupts = <0 19 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7794_CLK_I2C4>; power-domains = <&cpg_clocks>; #address-cells = <1>; @@ -573,7 +620,7 @@ i2c5: i2c@e6528000 { compatible = "renesas,i2c-r8a7794"; reg = <0 0xe6528000 0 0x40>; - interrupts = <0 20 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7794_CLK_I2C5>; power-domains = <&cpg_clocks>; #address-cells = <1>; @@ -585,7 +632,7 @@ mmcif0: mmc@ee200000 { compatible = "renesas,mmcif-r8a7794", "renesas,sh-mmcif"; reg = <0 0xee200000 0 0x80>; - interrupts = <0 169 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7794_CLK_MMCIF0>; dmas = <&dmac0 0xd1>, <&dmac0 0xd2>; dma-names = "tx", "rx"; @@ -597,7 +644,7 @@ sdhi0: sd@ee100000 { compatible = "renesas,sdhi-r8a7794"; reg = <0 0xee100000 0 0x200>; - interrupts = <0 165 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7794_CLK_SDHI0>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -606,7 +653,7 @@ sdhi1: sd@ee140000 { compatible = "renesas,sdhi-r8a7794"; reg = <0 0xee140000 0 0x100>; - interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7794_CLK_SDHI1>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -615,7 +662,7 @@ sdhi2: sd@ee160000 { compatible = "renesas,sdhi-r8a7794"; reg = <0 0xee160000 0 0x100>; - interrupts = <0 168 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks R8A7794_CLK_SDHI2>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -624,7 +671,7 @@ qspi: spi@e6b10000 { compatible = "renesas,qspi-r8a7794", "renesas,qspi"; reg = <0 0xe6b10000 0 0x2c>; - interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp9_clks R8A7794_CLK_QSPI_MOD>; dmas = <&dmac0 0x17>, <&dmac0 0x18>; dma-names = "tx", "rx"; @@ -638,7 +685,7 @@ vin0: video@e6ef0000 { compatible = "renesas,vin-r8a7794"; reg = <0 0xe6ef0000 0 0x1000>; - interrupts = <0 188 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7794_CLK_VIN0>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -647,18 +694,18 @@ vin1: video@e6ef1000 { compatible = "renesas,vin-r8a7794"; reg = <0 0xe6ef1000 0 0x1000>; - interrupts = <0 189 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp8_clks R8A7794_CLK_VIN1>; power-domains = <&cpg_clocks>; status = "disabled"; }; pci0: pci@ee090000 { - compatible = "renesas,pci-r8a7794"; + compatible = "renesas,pci-r8a7794", "renesas,pci-rcar-gen2"; device_type = "pci"; reg = <0 0xee090000 0 0xc00>, <0 0xee080000 0 0x1100>; - interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_EHCI>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -669,9 +716,9 @@ #interrupt-cells = <1>; ranges = <0x02000000 0 0xee080000 0 0xee080000 0 0x00010000>; interrupt-map-mask = <0xff00 0 0 0x7>; - interrupt-map = <0x0000 0 0 1 &gic 0 108 IRQ_TYPE_LEVEL_HIGH - 0x0800 0 0 1 &gic 0 108 IRQ_TYPE_LEVEL_HIGH - 0x1000 0 0 2 &gic 0 108 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH + 0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH + 0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>; usb@0,1 { reg = <0x800 0 0 0 0>; @@ -689,11 +736,11 @@ }; pci1: pci@ee0d0000 { - compatible = "renesas,pci-r8a7794"; + compatible = "renesas,pci-r8a7794", "renesas,pci-rcar-gen2"; device_type = "pci"; reg = <0 0xee0d0000 0 0xc00>, <0 0xee0c0000 0 0x1100>; - interrupts = <0 113 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_EHCI>; power-domains = <&cpg_clocks>; status = "disabled"; @@ -704,9 +751,9 @@ #interrupt-cells = <1>; ranges = <0x02000000 0 0xee0c0000 0 0xee0c0000 0 0x00010000>; interrupt-map-mask = <0xff00 0 0 0x7>; - interrupt-map = <0x0000 0 0 1 &gic 0 113 IRQ_TYPE_LEVEL_HIGH - 0x0800 0 0 1 &gic 0 113 IRQ_TYPE_LEVEL_HIGH - 0x1000 0 0 2 &gic 0 113 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH + 0x0800 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH + 0x1000 0 0 2 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; usb@0,1 { reg = <0x800 0 0 0 0>; @@ -724,9 +771,9 @@ }; hsusb: usb@e6590000 { - compatible = "renesas,usbhs-r8a7794"; + compatible = "renesas,usbhs-r8a7794", "renesas,rcar-gen2-usbhs"; reg = <0 0xe6590000 0 0x100>; - interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp7_clks R8A7794_CLK_HSUSB>; power-domains = <&cpg_clocks>; renesas,buswait = <4>; @@ -759,8 +806,8 @@ compatible = "renesas,du-r8a7794"; reg = <0 0xfeb00000 0 0x40000>; reg-names = "du"; - interrupts = <0 256 IRQ_TYPE_LEVEL_HIGH>, - <0 268 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; clocks = <&mstp7_clks R8A7794_CLK_DU0>, <&mstp7_clks R8A7794_CLK_DU0>; clock-names = "du.0", "du.1"; @@ -797,6 +844,15 @@ clock-output-names = "extal"; }; + /* External SCIF clock */ + scif_clk: scif { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* This value must be overridden by the board. */ + clock-frequency = <0>; + status = "disabled"; + }; + /* Special CPG clocks */ cpg_clocks: cpg_clocks@e6150000 { compatible = "renesas,r8a7794-cpg-clocks", @@ -1068,13 +1124,14 @@ mstp8_clks: mstp8_clks@e6150990 { compatible = "renesas,r8a7794-mstp-clocks", "renesas,cpg-mstp-clocks"; reg = <0 0xe6150990 0 4>, <0 0xe61509a0 0 4>; - clocks = <&zg_clk>, <&zg_clk>, <&p_clk>; + clocks = <&zg_clk>, <&zg_clk>, <&hp_clk>, <&p_clk>; #clock-cells = <1>; clock-indices = < - R8A7794_CLK_VIN1 R8A7794_CLK_VIN0 R8A7794_CLK_ETHER + R8A7794_CLK_VIN1 R8A7794_CLK_VIN0 + R8A7794_CLK_ETHERAVB R8A7794_CLK_ETHER >; clock-output-names = - "vin1", "vin0", "ether"; + "vin1", "vin0", "etheravb", "ether"; }; mstp9_clks: mstp9_clks@e6150994 { compatible = "renesas,r8a7794-mstp-clocks", "renesas,cpg-mstp-clocks"; @@ -1111,8 +1168,8 @@ ipmmu_sy0: mmu@e6280000 { compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa"; reg = <0 0xe6280000 0 0x1000>; - interrupts = <0 223 IRQ_TYPE_LEVEL_HIGH>, - <0 224 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -1120,7 +1177,7 @@ ipmmu_sy1: mmu@e6290000 { compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa"; reg = <0 0xe6290000 0 0x1000>; - interrupts = <0 225 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #iommu-cells = <1>; status = "disabled"; }; @@ -1128,8 +1185,8 @@ ipmmu_ds: mmu@e6740000 { compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa"; reg = <0 0xe6740000 0 0x1000>; - interrupts = <0 198 IRQ_TYPE_LEVEL_HIGH>, - <0 199 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -1137,7 +1194,7 @@ ipmmu_mp: mmu@ec680000 { compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa"; reg = <0 0xec680000 0 0x1000>; - interrupts = <0 226 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; #iommu-cells = <1>; status = "disabled"; }; @@ -1145,8 +1202,8 @@ ipmmu_mx: mmu@fe951000 { compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa"; reg = <0 0xfe951000 0 0x1000>; - interrupts = <0 222 IRQ_TYPE_LEVEL_HIGH>, - <0 221 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; @@ -1154,8 +1211,8 @@ ipmmu_gp: mmu@e62a0000 { compatible = "renesas,ipmmu-r8a7794", "renesas,ipmmu-vmsa"; reg = <0 0xe62a0000 0 0x1000>; - interrupts = <0 260 IRQ_TYPE_LEVEL_HIGH>, - <0 261 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; #iommu-cells = <1>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/rk3036-evb.dts b/arch/arm/boot/dts/rk3036-evb.dts index 28a03366601750bc9c2c5a25255e3ba433758bb3..b3d6ec87f6152b1e23c0845913990da1c19076a8 100644 --- a/arch/arm/boot/dts/rk3036-evb.dts +++ b/arch/arm/boot/dts/rk3036-evb.dts @@ -47,6 +47,20 @@ compatible = "rockchip,rk3036-evb", "rockchip,rk3036"; }; +&emac { + pinctrl-names = "default"; + pinctrl-0 = <&emac_xfer>, <&emac_mdio>; + phy = <&phy0>; + phy-reset-gpios = <&gpio2 22 GPIO_ACTIVE_LOW>; /* PHY_RST */ + phy-reset-duration = <10>; /* millisecond */ + + status = "okay"; + + phy0: ethernet-phy@0 { + reg = <0>; + }; +}; + &i2c1 { status = "okay"; diff --git a/arch/arm/boot/dts/rk3036-kylin.dts b/arch/arm/boot/dts/rk3036-kylin.dts index 992f9cadbc04e1fa5534b35c2c4966abcaff42b4..6251d109eff42de9cc5c8ec1784a003fe1eab1c0 100644 --- a/arch/arm/boot/dts/rk3036-kylin.dts +++ b/arch/arm/boot/dts/rk3036-kylin.dts @@ -46,6 +46,58 @@ model = "Rockchip RK3036 KylinBoard"; compatible = "rockchip,rk3036-kylin", "rockchip,rk3036"; + leds: gpio-leds { + compatible = "gpio-leds"; + + work { + gpios = <&gpio2 30 GPIO_ACTIVE_HIGH>; + label = "kylin:red:led"; + pinctrl-names = "default"; + pinctrl-0 = <&led_ctl>; + }; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + pinctrl-names = "default"; + pinctrl-0 = <&bt_wake_h>; + + /* + * On the module itself this is one of these (depending + * on the actual card populated): + * - SDIO_RESET_L_WL_REG_ON + * - SDIO_RESET_L_WL_RST + * - SDIO_RESET_L_BT_EN + */ + reset-gpios = <&gpio0 26 GPIO_ACTIVE_LOW>, /* WL_REG_ON */ + <&gpio0 27 GPIO_ACTIVE_LOW>, /* WL_RST */ + <&gpio2 9 GPIO_ACTIVE_LOW>; /* BT_EN */ + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,name = "rockchip,rt5616-codec"; + simple-audio-card,mclk-fs = <512>; + simple-audio-card,widgets = + "Microphone", "Microphone Jack", + "Headphone", "Headphone Jack"; + simple-audio-card,routing = + "MIC1", "Microphone Jack", + "MIC2", "Microphone Jack", + "Microphone Jack", "micbias1", + "Headphone Jack", "HPOL", + "Headphone Jack", "HPOR"; + + simple-audio-card,cpu { + sound-dai = <&i2s>; + }; + + simple-audio-card,codec { + sound-dai = <&rt5616>; + }; + }; + vcc_sys: vsys-regulator { compatible = "regulator-fixed"; regulator-name = "vcc_sys"; @@ -60,6 +112,20 @@ status = "okay"; }; +&emac { + pinctrl-names = "default"; + pinctrl-0 = <&emac_xfer>, <&emac_mdio>; + phy = <&phy0>; + phy-reset-gpios = <&gpio2 22 GPIO_ACTIVE_LOW>; /* PHY_RST */ + phy-reset-duration = <10>; /* millisecond */ + + status = "okay"; + + phy0: ethernet-phy@0 { + reg = <0>; + }; +}; + &emmc { status = "okay"; }; @@ -257,6 +323,19 @@ &i2c2 { status = "okay"; + + rt5616: rt5616@1b { + compatible = "rt5616"; + reg = <0x1b>; + clocks = <&cru SCLK_I2S_OUT>; + clock-names = "mclk"; + #sound-dai-cells = <0>; + }; +}; + +&i2s { + #sound-dai-cells = <0>; + status = "okay"; }; &sdio { @@ -264,13 +343,34 @@ broken-cd; bus-width = <4>; + cap-sd-highspeed; cap-sdio-irq; default-sample-phase = <90>; keep-power-in-suspend; + mmc-pwrseq = <&sdio_pwrseq>; non-removable; num-slots = <1>; pinctrl-names = "default"; pinctrl-0 = <&sdio_clk &sdio_cmd &sdio_bus4>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; +}; + +&sdmmc { + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + card-detect-delay = <200>; + disable-wp; + num-slots = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_clk>, <&sdmmc_cmd>, <&sdmmc_cd>, <&sdmmc_bus4>; +}; + +&uart0 { + status = "okay"; }; &uart2 { @@ -286,12 +386,30 @@ }; &pinctrl { + leds { + led_ctl: led-ctl { + rockchip,pins = <2 30 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + pmic { pmic_int: pmic-int { rockchip,pins = <2 2 RK_FUNC_GPIO &pcfg_pull_default>; }; }; + sdio { + bt_wake_h: bt-wake-h { + rockchip,pins = <2 8 RK_FUNC_GPIO &pcfg_pull_default>; + }; + }; + + sdmmc { + sdmmc_pwr: sdmmc-pwr { + rockchip,pins = <2 28 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + sleep { global_pwroff: global-pwroff { rockchip,pins = <2 7 RK_FUNC_1 &pcfg_pull_none>; diff --git a/arch/arm/boot/dts/rk3036.dtsi b/arch/arm/boot/dts/rk3036.dtsi index b9567c1e068771ba2d822d4c2fae79173a8a29e6..d0f4bb7e1e50a4d44aea72b1160c3dc8e739f641 100644 --- a/arch/arm/boot/dts/rk3036.dtsi +++ b/arch/arm/boot/dts/rk3036.dtsi @@ -60,6 +60,7 @@ serial0 = &uart0; serial1 = &uart1; serial2 = &uart2; + spi = &spi; }; memory { @@ -94,7 +95,7 @@ }; amba { - compatible = "arm,amba-bus"; + compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges; @@ -105,6 +106,7 @@ interrupts = , ; #dma-cells = <1>; + arm,pl330-broken-no-flushp; clocks = <&cru ACLK_DMAC2>; clock-names = "apb_pclk"; }; @@ -161,7 +163,7 @@ }; usb_otg: usb@10180000 { - compatible = "rockchip,rk3288-usb", "rockchip,rk3066-usb", + compatible = "rockchip,rk3036-usb", "rockchip,rk3066-usb", "snps,dwc2"; reg = <0x10180000 0x40000>; interrupts = ; @@ -176,7 +178,7 @@ }; usb_host: usb@101c0000 { - compatible = "rockchip,rk3288-usb", "rockchip,rk3066-usb", + compatible = "rockchip,rk3036-usb", "rockchip,rk3066-usb", "snps,dwc2"; reg = <0x101c0000 0x40000>; interrupts = ; @@ -186,6 +188,27 @@ status = "disabled"; }; + emac: ethernet@10200000 { + compatible = "rockchip,rk3036-emac", "snps,arc-emac"; + reg = <0x10200000 0x4000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + rockchip,grf = <&grf>; + clocks = <&cru HCLK_MAC>, <&cru SCLK_MACREF>, <&cru SCLK_MAC>; + clock-names = "hclk", "macref", "macclk"; + /* + * Fix the emac parent clock is DPLL instead of APLL. + * since that will cause some unstable things if the cpufreq + * is working. (e.g: the accurate 50MHz what mac_ref need) + */ + assigned-clocks = <&cru SCLK_MACPLL>; + assigned-clock-parents = <&cru PLL_DPLL>; + max-speed = <100>; + phy-mode = "rmii"; + status = "disabled"; + }; + sdmmc: dwmmc@10214000 { compatible = "rockchip,rk3036-dw-mshc", "rockchip,rk3288-dw-mshc"; reg = <0x10214000 0x4000>; @@ -211,7 +234,7 @@ }; emmc: dwmmc@1021c000 { - compatible = "rockchip,rk3288-dw-mshc"; + compatible = "rockchip,rk3036-dw-mshc", "rockchip,rk3288-dw-mshc"; reg = <0x1021c000 0x4000>; interrupts = ; broken-cd; @@ -241,8 +264,8 @@ interrupts = ; #address-cells = <1>; #size-cells = <0>; - clock-names = "i2s_hclk", "i2s_clk"; - clocks = <&cru HCLK_I2S>, <&cru SCLK_I2S>; + clock-names = "i2s_clk", "i2s_hclk"; + clocks = <&cru SCLK_I2S>, <&cru HCLK_I2S>; dmas = <&pdma 0>, <&pdma 1>; dma-names = "tx", "rx"; pinctrl-names = "default"; @@ -327,7 +350,7 @@ }; i2c1: i2c@20056000 { - compatible = "rockchip,rk3288-i2c"; + compatible = "rockchip,rk3036-i2c", "rockchip,rk3288-i2c"; reg = <0x20056000 0x1000>; interrupts = ; #address-cells = <1>; @@ -340,7 +363,7 @@ }; i2c2: i2c@2005a000 { - compatible = "rockchip,rk3288-i2c"; + compatible = "rockchip,rk3036-i2c", "rockchip,rk3288-i2c"; reg = <0x2005a000 0x1000>; interrupts = ; #address-cells = <1>; @@ -395,7 +418,7 @@ }; i2c0: i2c@20072000 { - compatible = "rockchip,rk3288-i2c"; + compatible = "rockchip,rk3036-i2c", "rockchip,rk3288-i2c"; reg = <0x20072000 0x1000>; interrupts = ; #address-cells = <1>; @@ -407,6 +430,21 @@ status = "disabled"; }; + spi: spi@20074000 { + compatible = "rockchip,rockchip-spi"; + reg = <0x20074000 0x1000>; + interrupts = ; + clocks =<&cru PCLK_SPI>, <&cru SCLK_SPI>; + clock-names = "apb-pclk","spi_pclk"; + dmas = <&pdma 8>, <&pdma 9>; + dma-names = "tx", "rx"; + pinctrl-names = "default"; + pinctrl-0 = <&spi_txd &spi_rxd &spi_clk &spi_cs0>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + pinctrl: pinctrl { compatible = "rockchip,rk3036-pinctrl"; rockchip,grf = <&grf>; @@ -556,6 +594,24 @@ }; }; + emac { + emac_xfer: emac-xfer { + rockchip,pins = <2 10 RK_FUNC_1 &pcfg_pull_default>, /* crs_dvalid */ + <2 13 RK_FUNC_1 &pcfg_pull_default>, /* tx_en */ + <2 14 RK_FUNC_1 &pcfg_pull_default>, /* mac_clk */ + <2 15 RK_FUNC_1 &pcfg_pull_default>, /* rx_err */ + <2 16 RK_FUNC_1 &pcfg_pull_default>, /* rxd1 */ + <2 17 RK_FUNC_1 &pcfg_pull_default>, /* rxd0 */ + <2 18 RK_FUNC_1 &pcfg_pull_default>, /* txd1 */ + <2 19 RK_FUNC_1 &pcfg_pull_default>; /* txd0 */ + }; + + emac_mdio: emac-mdio { + rockchip,pins = <2 12 RK_FUNC_1 &pcfg_pull_default>, /* mac_md */ + <2 25 RK_FUNC_1 &pcfg_pull_default>; /* mac_mdclk */ + }; + }; + i2c0 { i2c0_xfer: i2c0-xfer { rockchip,pins = <0 0 RK_FUNC_1 &pcfg_pull_none>, @@ -579,12 +635,12 @@ i2s { i2s_bus: i2s-bus { - rockchip,pins = <1 0 RK_FUNC_1 &pcfg_pull_none>, - <1 1 RK_FUNC_1 &pcfg_pull_none>, - <1 2 RK_FUNC_1 &pcfg_pull_none>, - <1 3 RK_FUNC_1 &pcfg_pull_none>, - <1 4 RK_FUNC_1 &pcfg_pull_none>, - <1 5 RK_FUNC_1 &pcfg_pull_none>; + rockchip,pins = <1 0 RK_FUNC_1 &pcfg_pull_default>, + <1 1 RK_FUNC_1 &pcfg_pull_default>, + <1 2 RK_FUNC_1 &pcfg_pull_default>, + <1 3 RK_FUNC_1 &pcfg_pull_default>, + <1 4 RK_FUNC_1 &pcfg_pull_default>, + <1 5 RK_FUNC_1 &pcfg_pull_default>; }; }; @@ -618,5 +674,29 @@ }; /* no rts / cts for uart2 */ }; + + spi { + spi_txd:spi-txd { + rockchip,pins = <1 29 RK_FUNC_3 &pcfg_pull_default>; + }; + + spi_rxd:spi-rxd { + rockchip,pins = <1 28 RK_FUNC_3 &pcfg_pull_default>; + }; + + spi_clk:spi-clk { + rockchip,pins = <2 0 RK_FUNC_2 &pcfg_pull_default>; + }; + + spi_cs0:spi-cs0 { + rockchip,pins = <1 30 RK_FUNC_3 &pcfg_pull_default>; + + }; + + spi_cs1:spi-cs1 { + rockchip,pins = <1 31 RK_FUNC_3 &pcfg_pull_default>; + + }; + }; }; }; diff --git a/arch/arm/boot/dts/rk3066a-bqcurie2.dts b/arch/arm/boot/dts/rk3066a-bqcurie2.dts index 38c91a839795f3cf77103f56fdb7bb0185ad2854..6d2a5b3a84a86635f65b8d43aae475040dc54c4e 100644 --- a/arch/arm/boot/dts/rk3066a-bqcurie2.dts +++ b/arch/arm/boot/dts/rk3066a-bqcurie2.dts @@ -53,6 +53,18 @@ reg = <0x60000000 0x40000000>; }; + vdd_log: vdd-log { + compatible = "pwm-regulator"; + pwms = <&pwm3 0 1000>; + regulator-name = "vdd_log"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + voltage-table = <1000000 100>, + <1200000 42>; + status = "okay"; + }; + vcc_sd0: fixed-regulator { compatible = "regulator-fixed"; regulator-name = "sdmmc-supply"; @@ -74,7 +86,7 @@ linux,code = <116>; label = "GPIO Key Power"; linux,input-type = <1>; - gpio-key,wakeup = <1>; + wakeup-source; debounce-interval = <100>; }; button@1 { @@ -82,7 +94,6 @@ linux,code = <104>; label = "GPIO Key Vol-"; linux,input-type = <1>; - gpio-key,wakeup = <0>; debounce-interval = <100>; }; /* VOL+ comes somehow thru the ADC */ @@ -203,6 +214,10 @@ disable-wp; }; +&pwm3 { + status = "okay"; +}; + &uart0 { status = "okay"; }; diff --git a/arch/arm/boot/dts/rk3066a-marsboard.dts b/arch/arm/boot/dts/rk3066a-marsboard.dts index 7cdc308bfac54c1ec6e286f29c4ad0c846df41aa..a2b763e949b4648f60e3929d0afba5afc711a61b 100644 --- a/arch/arm/boot/dts/rk3066a-marsboard.dts +++ b/arch/arm/boot/dts/rk3066a-marsboard.dts @@ -52,6 +52,18 @@ reg = <0x60000000 0x40000000>; }; + vdd_log: vdd-log { + compatible = "pwm-regulator"; + pwms = <&pwm3 0 1000>; + regulator-name = "vdd_log"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + voltage-table = <1000000 100>, + <1200000 42>; + status = "okay"; + }; + vcc_sd0: sdmmc-regulator { compatible = "regulator-fixed"; regulator-name = "sdmmc-supply"; @@ -194,6 +206,10 @@ }; }; +&pwm3 { + status = "okay"; +}; + &uart0 { status = "okay"; }; diff --git a/arch/arm/boot/dts/rk3066a-rayeager.dts b/arch/arm/boot/dts/rk3066a-rayeager.dts index 341c1f87936a7d20114175802e79f0a3196e9a25..05533005a809cef3d40731a2f3b4d1477a531d26 100644 --- a/arch/arm/boot/dts/rk3066a-rayeager.dts +++ b/arch/arm/boot/dts/rk3066a-rayeager.dts @@ -65,7 +65,7 @@ #size-cells = <0>; button@0 { - gpio-key,wakeup = <1>; + wakeup-source; gpios = <&gpio6 2 GPIO_ACTIVE_LOW>; label = "GPIO Power"; linux,code = <116>; @@ -74,6 +74,18 @@ }; }; + vdd_log: vdd-log { + compatible = "pwm-regulator"; + pwms = <&pwm3 0 1000>; + regulator-name = "vdd_log"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + voltage-table = <1000000 100>, + <1200000 42>; + status = "okay"; + }; + vsys: vsys-regulator { compatible = "regulator-fixed"; regulator-name = "vsys"; @@ -431,6 +443,10 @@ status = "okay"; }; +&pwm3 { + status = "okay"; +}; + &saradc { vref-supply = <&vcc_25>; status = "okay"; diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi index 58bac5053858bc95bcc8f089fd32deb9fdfa0b32..cb0a552e0b181674365aa0285ae7b92d73dc746b 100644 --- a/arch/arm/boot/dts/rk3066a.dtsi +++ b/arch/arm/boot/dts/rk3066a.dtsi @@ -61,11 +61,13 @@ reg = <0x0>; operating-points = < /* kHz uV */ - 1008000 1075000 - 816000 1025000 - 600000 1025000 - 504000 1000000 - 312000 975000 + 1416000 1300000 + 1200000 1175000 + 1008000 1125000 + 816000 1125000 + 600000 1100000 + 504000 1100000 + 312000 1075000 >; clock-latency = <40000>; clocks = <&cru ARMCLK>; @@ -188,6 +190,16 @@ clock-names = "timer", "pclk"; }; + tsadc: tsadc@20060000 { + compatible = "rockchip,rk3066-tsadc"; + reg = <0x20060000 0x100>; + clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>; + clock-names = "saradc", "apb_pclk"; + interrupts = ; + #io-channel-cells = <1>; + status = "disabled"; + }; + usbphy: phy { compatible = "rockchip,rk3066a-usb-phy", "rockchip,rk3288-usb-phy"; rockchip,grf = <&grf>; @@ -200,6 +212,7 @@ reg = <0x17c>; clocks = <&cru SCLK_OTGPHY0>; clock-names = "phyclk"; + #clock-cells = <0>; }; usbphy1: usb-phy1 { @@ -207,6 +220,7 @@ reg = <0x188>; clocks = <&cru SCLK_OTGPHY1>; clock-names = "phyclk"; + #clock-cells = <0>; }; }; diff --git a/arch/arm/boot/dts/rk3188-radxarock.dts b/arch/arm/boot/dts/rk3188-radxarock.dts index 66fa87d1e2c2492f247b703fce10d3b34f2076e9..0b6924c97b6bf0fd40e6062ac0b279e2edaea7a2 100644 --- a/arch/arm/boot/dts/rk3188-radxarock.dts +++ b/arch/arm/boot/dts/rk3188-radxarock.dts @@ -63,7 +63,7 @@ linux,code = <116>; label = "GPIO Key Power"; linux,input-type = <1>; - gpio-key,wakeup = <1>; + wakeup-source; debounce-interval = <100>; }; }; diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi index 348d46b7ada5a07ebdefe4dafc1630ddd079c0b7..9271833958f9dcd506d2b0365671414c4ec72460 100644 --- a/arch/arm/boot/dts/rk3188.dtsi +++ b/arch/arm/boot/dts/rk3188.dtsi @@ -171,6 +171,7 @@ reg = <0x10c>; clocks = <&cru SCLK_OTGPHY0>; clock-names = "phyclk"; + #clock-cells = <0>; }; usbphy1: usb-phy1 { @@ -178,6 +179,7 @@ reg = <0x11c>; clocks = <&cru SCLK_OTGPHY1>; clock-names = "phyclk"; + #clock-cells = <0>; }; }; diff --git a/arch/arm/boot/dts/rk3228.dtsi b/arch/arm/boot/dts/rk3228.dtsi index 119ff12ab440868d47e4d9a308b68fa2573f1bc0..4dae42a015098901626416fe707233d3f1872837 100644 --- a/arch/arm/boot/dts/rk3228.dtsi +++ b/arch/arm/boot/dts/rk3228.dtsi @@ -96,7 +96,7 @@ }; amba { - compatible = "arm,amba-bus"; + compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges; diff --git a/arch/arm/boot/dts/rk3288-evb.dtsi b/arch/arm/boot/dts/rk3288-evb.dtsi index 4faabdb65868e38c0e4f96143d4a3cd5370afe5e..78d47f7d2938532d435954c731ba7e99063939c2 100644 --- a/arch/arm/boot/dts/rk3288-evb.dtsi +++ b/arch/arm/boot/dts/rk3288-evb.dtsi @@ -110,7 +110,7 @@ linux,code = <116>; label = "GPIO Key Power"; linux,input-type = <1>; - gpio-key,wakeup = <1>; + wakeup-source; debounce-interval = <100>; }; }; diff --git a/arch/arm/boot/dts/rk3288-firefly.dtsi b/arch/arm/boot/dts/rk3288-firefly.dtsi index 4e3fd9aefe3497e464bc8fecdb10a688372460a6..98c586a43c73011f3aba567c784f573b8ab57dab 100644 --- a/arch/arm/boot/dts/rk3288-firefly.dtsi +++ b/arch/arm/boot/dts/rk3288-firefly.dtsi @@ -91,7 +91,7 @@ #size-cells = <0>; button@0 { - gpio-key,wakeup = <1>; + wakeup-source; gpios = <&gpio0 5 GPIO_ACTIVE_LOW>; label = "GPIO Power"; linux,code = <116>; @@ -408,6 +408,11 @@ output-low; }; + pcfg_pull_up_drv_12ma: pcfg-pull-up-drv-12ma { + bias-pull-up; + drive-strength = <12>; + }; + act8846 { pwr_hold: pwr-hold { rockchip,pins = <0 1 RK_FUNC_GPIO &pcfg_output_high>; @@ -457,6 +462,25 @@ }; sdmmc { + /* + * Default drive strength isn't enough to achieve even + * high-speed mode on firefly board so bump up to 12ma. + */ + sdmmc_bus4: sdmmc-bus4 { + rockchip,pins = <6 16 RK_FUNC_1 &pcfg_pull_up_drv_12ma>, + <6 17 RK_FUNC_1 &pcfg_pull_up_drv_12ma>, + <6 18 RK_FUNC_1 &pcfg_pull_up_drv_12ma>, + <6 19 RK_FUNC_1 &pcfg_pull_up_drv_12ma>; + }; + + sdmmc_clk: sdmmc-clk { + rockchip,pins = <6 20 RK_FUNC_1 &pcfg_pull_none_12ma>; + }; + + sdmmc_cmd: sdmmc-cmd { + rockchip,pins = <6 21 RK_FUNC_1 &pcfg_pull_up_drv_12ma>; + }; + sdmmc_pwr: sdmmc-pwr { rockchip,pins = <7 11 RK_FUNC_GPIO &pcfg_pull_none>; }; diff --git a/arch/arm/boot/dts/rk3288-popmetal.dts b/arch/arm/boot/dts/rk3288-popmetal.dts index 65c475642d5a79196925a50498a567aad75f72ef..2ff9689d2e1b831c26f8e5660ee910ad2c18e6c6 100644 --- a/arch/arm/boot/dts/rk3288-popmetal.dts +++ b/arch/arm/boot/dts/rk3288-popmetal.dts @@ -74,7 +74,7 @@ linux,code = <116>; label = "GPIO Key Power"; linux,input-type = <1>; - gpio-key,wakeup = <1>; + wakeup-source; debounce-interval = <100>; }; }; diff --git a/arch/arm/boot/dts/rk3288-r89.dts b/arch/arm/boot/dts/rk3288-r89.dts index 17f13c73fe5e078e1adebbd1932615d41b89bbcb..510a1d0d7abb5b4022c4e2b7500d9049540a1ec3 100644 --- a/arch/arm/boot/dts/rk3288-r89.dts +++ b/arch/arm/boot/dts/rk3288-r89.dts @@ -73,7 +73,7 @@ linux,code = <116>; label = "GPIO Key Power"; linux,input-type = <1>; - gpio-key,wakeup = <1>; + wakeup-source; debounce-interval = <100>; }; }; diff --git a/arch/arm/boot/dts/rk3288-rock2-som.dtsi b/arch/arm/boot/dts/rk3288-rock2-som.dtsi index 1ece66f3e162786e839c26e5ef89c04b4bc71fec..e1ee9f949035cae2a2a1b84fad09b35feebe6440 100644 --- a/arch/arm/boot/dts/rk3288-rock2-som.dtsi +++ b/arch/arm/boot/dts/rk3288-rock2-som.dtsi @@ -61,6 +61,31 @@ clock-output-names = "ext_gmac"; }; + io_domains: io-domains { + compatible = "rockchip,rk3288-io-voltage-domain"; + rockchip,grf = <&grf>; + + audio-supply = <&vcc_io>; + bb-supply = <&vcc_io>; + dvp-supply = <&vcc_18>; + flash0-supply = <&vcc_flash>; + flash1-supply = <&vccio_pmu>; + gpio30-supply = <&vccio_pmu>; + gpio1830 = <&vcc_io>; + lcdc-supply = <&vcc_io>; + sdcard-supply = <&vccio_sd>; + wifi-supply = <&vcc_18>; + }; + + vcc_flash: flash-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc_sys"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + startup-delay-us = <150>; + vin-supply = <&vcc_io>; + }; + vcc_sys: vsys-regulator { compatible = "regulator-fixed"; regulator-name = "vcc_sys"; @@ -85,6 +110,7 @@ pinctrl-names = "default"; pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; vmmc-supply = <&vcc_io>; + vqmmc-supply = <&vcc_flash>; status = "okay"; }; diff --git a/arch/arm/boot/dts/rk3288-rock2-square.dts b/arch/arm/boot/dts/rk3288-rock2-square.dts index c5453a0b07fca940227c8f24a92b838cbe43219d..dd3ad2e93a6d538dcd29c5dbc17ca2feb8d82d5d 100644 --- a/arch/arm/boot/dts/rk3288-rock2-square.dts +++ b/arch/arm/boot/dts/rk3288-rock2-square.dts @@ -49,6 +49,22 @@ stdout-path = "serial2:115200n8"; }; + gpio-leds { + compatible = "gpio-leds"; + + heartbeat { + gpios = <&gpio7 15 GPIO_ACTIVE_LOW>; + label = "rock2:green:state1"; + linux,default-trigger = "heartbeat"; + }; + + mmc { + gpios = <&gpio0 11 GPIO_ACTIVE_LOW>; + label = "rock2:blue:state2"; + linux,default-trigger = "mmc0"; + }; + }; + ir: ir-receiver { compatible = "gpio-ir-receiver"; gpios = <&gpio8 1 GPIO_ACTIVE_LOW>; @@ -70,6 +86,15 @@ #sound-dai-cells = <0>; }; + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + clocks = <&hym8563>; + clock-names = "ext_clock"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_enable>; + reset-gpios = <&gpio4 28 GPIO_ACTIVE_LOW>; + }; + vcc_usb_host: vcc-host-regulator { compatible = "regulator-fixed"; enable-active-high; @@ -95,6 +120,21 @@ }; }; +&sdio0 { + bus-width = <4>; + cap-sd-highspeed; + cap-sdio-irq; + disable-wp; + mmc-pwrseq = <&sdio_pwrseq>; + non-removable; + num-slots = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk &sdio0_int>; + vmmc-supply = <&vcc_io>; + vqmmc-supply = <&vcc_18>; + status = "okay"; +}; + &sdmmc { bus-width = <4>; cap-mmc-highspeed; @@ -119,7 +159,7 @@ }; &i2c0 { - hym8563@51 { + hym8563: hym8563@51 { compatible = "haoyu,hym8563"; reg = <0x51>; #clock-cells = <0>; @@ -161,6 +201,12 @@ rockchip,pins = <7 11 RK_FUNC_GPIO &pcfg_pull_none>; }; }; + + sdio { + wifi_enable: wifi-enable { + rockchip,pins = <4 28 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; }; &spdif { diff --git a/arch/arm/boot/dts/rk3288-veyron-chromebook.dtsi b/arch/arm/boot/dts/rk3288-veyron-chromebook.dtsi index 136d650dd05faf28b5656ea980b2b799edc06ba8..610769d99522ea47e1765282469b797d378dc5c8 100644 --- a/arch/arm/boot/dts/rk3288-veyron-chromebook.dtsi +++ b/arch/arm/boot/dts/rk3288-veyron-chromebook.dtsi @@ -108,7 +108,7 @@ lid { label = "Lid"; gpios = <&gpio0 6 GPIO_ACTIVE_LOW>; - gpio-key,wakeup; + wakeup-source; linux,code = <0>; /* SW_LID */ linux,input-type = <5>; /* EV_SW */ debounce-interval = <1>; diff --git a/arch/arm/boot/dts/rk3288-veyron.dtsi b/arch/arm/boot/dts/rk3288-veyron.dtsi index 9fce91ffff6fd89b1f39ba960dfeecd71ff8ae24..412809c60d01901087f67ed1107f2538ae3a8f1b 100644 --- a/arch/arm/boot/dts/rk3288-veyron.dtsi +++ b/arch/arm/boot/dts/rk3288-veyron.dtsi @@ -64,7 +64,7 @@ gpios = <&gpio0 5 GPIO_ACTIVE_LOW>; linux,code = ; debounce-interval = <100>; - gpio-key,wakeup; + wakeup-source; }; }; @@ -340,11 +340,6 @@ i2c-scl-rising-time-ns = <1000>; }; -&power { - assigned-clocks = <&cru SCLK_EDP_24M>; - assigned-clock-parents = <&xin24m>; -}; - &pwm1 { status = "okay"; }; @@ -421,7 +416,7 @@ status = "okay"; assigned-clocks = <&cru SCLK_USBPHY480M_SRC>; - assigned-clock-parents = <&cru SCLK_OTGPHY0>; + assigned-clock-parents = <&usbphy0>; dr_mode = "host"; }; diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index 8ac49f3efc178ddc05ead42d5fec2178280275c2..31f7e20ef418d07197d60ae6e3706b69423da385 100644 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -134,7 +134,7 @@ }; amba { - compatible = "arm,amba-bus"; + compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges; @@ -145,6 +145,7 @@ interrupts = , ; #dma-cells = <1>; + arm,pl330-broken-no-flushp; clocks = <&cru ACLK_DMAC2>; clock-names = "apb_pclk"; }; @@ -155,6 +156,7 @@ interrupts = , ; #dma-cells = <1>; + arm,pl330-broken-no-flushp; clocks = <&cru ACLK_DMAC1>; clock-names = "apb_pclk"; status = "disabled"; @@ -166,6 +168,7 @@ interrupts = , ; #dma-cells = <1>; + arm,pl330-broken-no-flushp; clocks = <&cru ACLK_DMAC1>; clock-names = "apb_pclk"; }; @@ -630,6 +633,9 @@ #address-cells = <1>; #size-cells = <0>; + assigned-clocks = <&cru SCLK_EDP_24M>; + assigned-clock-parents = <&xin24m>; + /* * Note: Although SCLK_* are the working clocks * of device without including on the NOC, needed for @@ -815,6 +821,10 @@ reg = <0>; remote-endpoint = <&hdmi_in_vopb>; }; + vopb_out_mipi: endpoint@2 { + reg = <2>; + remote-endpoint = <&mipi_in_vopb>; + }; }; }; @@ -848,6 +858,10 @@ reg = <0>; remote-endpoint = <&hdmi_in_vopl>; }; + vopl_out_mipi: endpoint@2 { + reg = <2>; + remote-endpoint = <&mipi_in_vopl>; + }; }; }; @@ -861,6 +875,37 @@ status = "disabled"; }; + mipi_dsi: mipi@ff960000 { + compatible = "rockchip,rk3288-mipi-dsi", "snps,dw-mipi-dsi"; + reg = <0xff960000 0x4000>; + interrupts = ; + clocks = <&cru SCLK_MIPIDSI_24M>, <&cru PCLK_MIPI_DSI0>; + clock-names = "ref", "pclk"; + rockchip,grf = <&grf>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + + mipi_in: port { + #address-cells = <1>; + #size-cells = <0>; + mipi_in_vopb: endpoint@0 { + reg = <0>; + remote-endpoint = <&vopb_out_mipi>; + }; + mipi_in_vopl: endpoint@1 { + reg = <1>; + remote-endpoint = <&vopl_out_mipi>; + }; + }; + }; + }; + hdmi: hdmi@ff980000 { compatible = "rockchip,rk3288-dw-hdmi"; reg = <0xff980000 0x20000>; @@ -926,6 +971,7 @@ reg = <0x320>; clocks = <&cru SCLK_OTGPHY0>; clock-names = "phyclk"; + #clock-cells = <0>; }; usbphy1: usb-phy1 { @@ -933,6 +979,7 @@ reg = <0x334>; clocks = <&cru SCLK_OTGPHY1>; clock-names = "phyclk"; + #clock-cells = <0>; }; usbphy2: usb-phy2 { @@ -940,6 +987,7 @@ reg = <0x348>; clocks = <&cru SCLK_OTGPHY2>; clock-names = "phyclk"; + #clock-cells = <0>; }; }; diff --git a/arch/arm/boot/dts/rk3xxx.dtsi b/arch/arm/boot/dts/rk3xxx.dtsi index 99eeea70223b94c9492a9df2fb8f7e4ffa373613..99bbcc2c9b8978b28be5a253f6be236a8896a315 100644 --- a/arch/arm/boot/dts/rk3xxx.dtsi +++ b/arch/arm/boot/dts/rk3xxx.dtsi @@ -67,7 +67,7 @@ }; amba { - compatible = "arm,amba-bus"; + compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges; @@ -78,6 +78,7 @@ interrupts = , ; #dma-cells = <1>; + arm,pl330-broken-no-flushp; clocks = <&cru ACLK_DMA1>; clock-names = "apb_pclk"; }; @@ -88,6 +89,7 @@ interrupts = , ; #dma-cells = <1>; + arm,pl330-broken-no-flushp; clocks = <&cru ACLK_DMA1>; clock-names = "apb_pclk"; status = "disabled"; @@ -99,6 +101,7 @@ interrupts = , ; #dma-cells = <1>; + arm,pl330-broken-no-flushp; clocks = <&cru ACLK_DMA2>; clock-names = "apb_pclk"; }; diff --git a/arch/arm/boot/dts/s5pv210-aquila.dts b/arch/arm/boot/dts/s5pv210-aquila.dts index aa64faa72970113a887c22836f9ddb5da5aa6e68..da24ab570b0e8c4b278af7d4844eec2c6e2d777b 100644 --- a/arch/arm/boot/dts/s5pv210-aquila.dts +++ b/arch/arm/boot/dts/s5pv210-aquila.dts @@ -257,7 +257,7 @@ linux,code = ; label = "power"; debounce-interval = <1>; - gpio-key,wakeup; + wakeup-source; }; }; }; @@ -268,7 +268,7 @@ &keypad { linux,input-no-autorepeat; - linux,input-wakeup; + wakeup-source; samsung,keypad-num-rows = <3>; samsung,keypad-num-columns = <3>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/s5pv210-goni.dts b/arch/arm/boot/dts/s5pv210-goni.dts index 3b76eeeb8410a66a31ff33018df38e2ba2ce990e..0a33d402138e14fb054bc32beadf748b4f9c20cd 100644 --- a/arch/arm/boot/dts/s5pv210-goni.dts +++ b/arch/arm/boot/dts/s5pv210-goni.dts @@ -239,7 +239,7 @@ linux,code = ; label = "power"; debounce-interval = <1>; - gpio-key,wakeup; + wakeup-source; }; }; }; @@ -250,7 +250,7 @@ &keypad { linux,input-no-autorepeat; - linux,input-wakeup; + wakeup-source; samsung,keypad-num-rows = <3>; samsung,keypad-num-columns = <3>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/s5pv210-smdkv210.dts b/arch/arm/boot/dts/s5pv210-smdkv210.dts index da7d210df6704d4304809e290114f3b05bb7506a..54fcc3fc82e20c2c8dba67186f92a213645dcaa6 100644 --- a/arch/arm/boot/dts/s5pv210-smdkv210.dts +++ b/arch/arm/boot/dts/s5pv210-smdkv210.dts @@ -59,7 +59,7 @@ &keypad { linux,input-no-autorepeat; - linux,input-wakeup; + wakeup-source; samsung,keypad-num-rows = <8>; samsung,keypad-num-columns = <8>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/s5pv210.dtsi b/arch/arm/boot/dts/s5pv210.dtsi index 8344a0ee2b86f554d4d674522fc0403d4edfb310..ffc36bd24d2f15c28a4792b14215bf75ffe66b5d 100644 --- a/arch/arm/boot/dts/s5pv210.dtsi +++ b/arch/arm/boot/dts/s5pv210.dtsi @@ -130,7 +130,7 @@ amba { #address-cells = <1>; #size-cells = <1>; - compatible = "arm,amba-bus"; + compatible = "simple-bus"; ranges; pdma0: dma@e0900000 { diff --git a/arch/arm/boot/dts/sama5d2.dtsi b/arch/arm/boot/dts/sama5d2.dtsi index 3f750f6170f2fc1a1913d5a67d0a4ba28d698958..78996bdbd3df38c30fb0a0051cd0db3e9a9249eb 100644 --- a/arch/arm/boot/dts/sama5d2.dtsi +++ b/arch/arm/boot/dts/sama5d2.dtsi @@ -88,12 +88,6 @@ #clock-cells = <0>; clock-frequency = <0>; }; - - adc_op_clk: adc_op_clk{ - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <1000000>; - }; }; ns_sram: sram@00200000 { @@ -263,6 +257,44 @@ cache-level = <2>; }; + nand0: nand@80000000 { + compatible = "atmel,sama5d2-nand"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + reg = < /* EBI CS3 */ + 0x80000000 0x08000000 + /* SMC PMECC regs */ + 0xf8014070 0x00000490 + /* SMC PMECC Error Location regs */ + 0xf8014500 0x00000200 + /* ROM Galois tables */ + 0x00040000 0x00018000 + >; + interrupts = <17 IRQ_TYPE_LEVEL_HIGH 6>; + atmel,nand-addr-offset = <21>; + atmel,nand-cmd-offset = <22>; + atmel,nand-has-dma; + atmel,has-pmecc; + atmel,pmecc-lookup-table-offset = <0x0 0x8000>; + status = "disabled"; + + nfc@c0000000 { + compatible = "atmel,sama5d4-nfc"; + #address-cells = <1>; + #size-cells = <1>; + reg = < /* NFC Command Registers */ + 0xc0000000 0x08000000 + /* NFC HSMC regs */ + 0xf8014000 0x00000070 + /* NFC SRAM banks */ + 0x00100000 0x00100000 + >; + clocks = <&hsmc_clk>; + atmel,write-by-sram; + }; + }; + sdmmc0: sdio-host@a0000000 { compatible = "atmel,sama5d2-sdhci"; reg = <0xa0000000 0x300>; @@ -880,6 +912,13 @@ compatible = "atmel,at91sam9260-usart"; reg = <0xf801c000 0x100>; interrupts = <24 IRQ_TYPE_LEVEL_HIGH 7>; + dmas = <&dma0 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | + AT91_XDMAC_DT_PERID(35))>, + <&dma0 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | + AT91_XDMAC_DT_PERID(36))>; + dma-names = "tx", "rx"; clocks = <&uart0_clk>; clock-names = "usart"; status = "disabled"; @@ -889,6 +928,13 @@ compatible = "atmel,at91sam9260-usart"; reg = <0xf8020000 0x100>; interrupts = <25 IRQ_TYPE_LEVEL_HIGH 7>; + dmas = <&dma0 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | + AT91_XDMAC_DT_PERID(37))>, + <&dma0 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | + AT91_XDMAC_DT_PERID(38))>; + dma-names = "tx", "rx"; clocks = <&uart1_clk>; clock-names = "usart"; status = "disabled"; @@ -898,6 +944,13 @@ compatible = "atmel,at91sam9260-usart"; reg = <0xf8024000 0x100>; interrupts = <26 IRQ_TYPE_LEVEL_HIGH 7>; + dmas = <&dma0 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | + AT91_XDMAC_DT_PERID(39))>, + <&dma0 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | + AT91_XDMAC_DT_PERID(40))>; + dma-names = "tx", "rx"; clocks = <&uart2_clk>; clock-names = "usart"; status = "disabled"; @@ -1016,6 +1069,13 @@ compatible = "atmel,at91sam9260-usart"; reg = <0xfc008000 0x100>; interrupts = <27 IRQ_TYPE_LEVEL_HIGH 7>; + dmas = <&dma0 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | + AT91_XDMAC_DT_PERID(41))>, + <&dma0 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | + AT91_XDMAC_DT_PERID(42))>; + dma-names = "tx", "rx"; clocks = <&uart3_clk>; clock-names = "usart"; status = "disabled"; @@ -1024,6 +1084,13 @@ uart4: serial@fc00c000 { compatible = "atmel,at91sam9260-usart"; reg = <0xfc00c000 0x100>; + dmas = <&dma0 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | + AT91_XDMAC_DT_PERID(43))>, + <&dma0 + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | + AT91_XDMAC_DT_PERID(44))>; + dma-names = "tx", "rx"; interrupts = <28 IRQ_TYPE_LEVEL_HIGH 7>; clocks = <&uart4_clk>; clock-names = "usart"; @@ -1085,6 +1152,18 @@ status = "disabled"; }; + adc: adc@fc030000 { + compatible = "atmel,sama5d2-adc"; + reg = <0xfc030000 0x100>; + interrupts = <40 IRQ_TYPE_LEVEL_HIGH 7>; + clocks = <&adc_clk>; + clock-names = "adc_clk"; + atmel,min-sample-rate-hz = <200000>; + atmel,max-sample-rate-hz = <20000000>; + atmel,startup-time-ms = <4>; + status = "disabled"; + }; + pioA: pinctrl@fc038000 { compatible = "atmel,sama5d2-pinctrl"; reg = <0xfc038000 0x600>; diff --git a/arch/arm/boot/dts/sh73a0.dtsi b/arch/arm/boot/dts/sh73a0.dtsi index 3a6056f9f0d23f17edb87674882e3b98f31fee49..bf825ca4f6f7912a6407abe9b3b3bc65a26e3637 100644 --- a/arch/arm/boot/dts/sh73a0.dtsi +++ b/arch/arm/boot/dts/sh73a0.dtsi @@ -58,7 +58,7 @@ L2: cache-controller { compatible = "arm,pl310-cache"; reg = <0xf0100000 0x1000>; - interrupts = <0 44 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; power-domains = <&pd_a3sm>; arm,data-latency = <3 3 3>; arm,tag-latency = <2 2 2>; @@ -70,8 +70,8 @@ sbsc2: memory-controller@fb400000 { compatible = "renesas,sbsc-sh73a0"; reg = <0xfb400000 0x400>; - interrupts = <0 37 IRQ_TYPE_LEVEL_HIGH>, - <0 38 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; interrupt-names = "sec", "temp"; power-domains = <&pd_a4bc1>; }; @@ -79,22 +79,22 @@ sbsc1: memory-controller@fe400000 { compatible = "renesas,sbsc-sh73a0"; reg = <0xfe400000 0x400>; - interrupts = <0 35 IRQ_TYPE_LEVEL_HIGH>, - <0 36 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; interrupt-names = "sec", "temp"; power-domains = <&pd_a4bc0>; }; pmu { compatible = "arm,cortex-a9-pmu"; - interrupts = <0 55 IRQ_TYPE_LEVEL_HIGH>, - <0 56 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , + ; }; cmt1: timer@e6138000 { compatible = "renesas,cmt-48-sh73a0", "renesas,cmt-48"; reg = <0xe6138000 0x200>; - interrupts = <0 65 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks SH73A0_CLK_CMT1>; clock-names = "fck"; power-domains = <&pd_c5>; @@ -113,14 +113,14 @@ <0xe6900020 1>, <0xe6900040 1>, <0xe6900060 1>; - interrupts = <0 1 IRQ_TYPE_LEVEL_HIGH - 0 2 IRQ_TYPE_LEVEL_HIGH - 0 3 IRQ_TYPE_LEVEL_HIGH - 0 4 IRQ_TYPE_LEVEL_HIGH - 0 5 IRQ_TYPE_LEVEL_HIGH - 0 6 IRQ_TYPE_LEVEL_HIGH - 0 7 IRQ_TYPE_LEVEL_HIGH - 0 8 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp5_clks SH73A0_CLK_INTCA0>; power-domains = <&pd_a4s>; control-parent; @@ -135,14 +135,14 @@ <0xe6900024 1>, <0xe6900044 1>, <0xe6900064 1>; - interrupts = <0 9 IRQ_TYPE_LEVEL_HIGH - 0 10 IRQ_TYPE_LEVEL_HIGH - 0 11 IRQ_TYPE_LEVEL_HIGH - 0 12 IRQ_TYPE_LEVEL_HIGH - 0 13 IRQ_TYPE_LEVEL_HIGH - 0 14 IRQ_TYPE_LEVEL_HIGH - 0 15 IRQ_TYPE_LEVEL_HIGH - 0 16 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp5_clks SH73A0_CLK_INTCA0>; power-domains = <&pd_a4s>; control-parent; @@ -157,14 +157,14 @@ <0xe6900028 1>, <0xe6900048 1>, <0xe6900068 1>; - interrupts = <0 17 IRQ_TYPE_LEVEL_HIGH - 0 18 IRQ_TYPE_LEVEL_HIGH - 0 19 IRQ_TYPE_LEVEL_HIGH - 0 20 IRQ_TYPE_LEVEL_HIGH - 0 21 IRQ_TYPE_LEVEL_HIGH - 0 22 IRQ_TYPE_LEVEL_HIGH - 0 23 IRQ_TYPE_LEVEL_HIGH - 0 24 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp5_clks SH73A0_CLK_INTCA0>; power-domains = <&pd_a4s>; control-parent; @@ -179,14 +179,14 @@ <0xe690002c 1>, <0xe690004c 1>, <0xe690006c 1>; - interrupts = <0 25 IRQ_TYPE_LEVEL_HIGH - 0 26 IRQ_TYPE_LEVEL_HIGH - 0 27 IRQ_TYPE_LEVEL_HIGH - 0 28 IRQ_TYPE_LEVEL_HIGH - 0 29 IRQ_TYPE_LEVEL_HIGH - 0 30 IRQ_TYPE_LEVEL_HIGH - 0 31 IRQ_TYPE_LEVEL_HIGH - 0 32 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp5_clks SH73A0_CLK_INTCA0>; power-domains = <&pd_a4s>; control-parent; @@ -197,10 +197,10 @@ #size-cells = <0>; compatible = "renesas,iic-sh73a0", "renesas,rmobile-iic"; reg = <0xe6820000 0x425>; - interrupts = <0 167 IRQ_TYPE_LEVEL_HIGH - 0 168 IRQ_TYPE_LEVEL_HIGH - 0 169 IRQ_TYPE_LEVEL_HIGH - 0 170 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp1_clks SH73A0_CLK_IIC0>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -211,10 +211,10 @@ #size-cells = <0>; compatible = "renesas,iic-sh73a0", "renesas,rmobile-iic"; reg = <0xe6822000 0x425>; - interrupts = <0 51 IRQ_TYPE_LEVEL_HIGH - 0 52 IRQ_TYPE_LEVEL_HIGH - 0 53 IRQ_TYPE_LEVEL_HIGH - 0 54 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks SH73A0_CLK_IIC1>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -225,10 +225,10 @@ #size-cells = <0>; compatible = "renesas,iic-sh73a0", "renesas,rmobile-iic"; reg = <0xe6824000 0x425>; - interrupts = <0 171 IRQ_TYPE_LEVEL_HIGH - 0 172 IRQ_TYPE_LEVEL_HIGH - 0 173 IRQ_TYPE_LEVEL_HIGH - 0 174 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks SH73A0_CLK_IIC2>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -239,10 +239,10 @@ #size-cells = <0>; compatible = "renesas,iic-sh73a0", "renesas,rmobile-iic"; reg = <0xe6826000 0x425>; - interrupts = <0 183 IRQ_TYPE_LEVEL_HIGH - 0 184 IRQ_TYPE_LEVEL_HIGH - 0 185 IRQ_TYPE_LEVEL_HIGH - 0 186 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp4_clks SH73A0_CLK_IIC3>; power-domains = <&pd_a3sp>; status = "disabled"; @@ -253,10 +253,10 @@ #size-cells = <0>; compatible = "renesas,iic-sh73a0", "renesas,rmobile-iic"; reg = <0xe6828000 0x425>; - interrupts = <0 187 IRQ_TYPE_LEVEL_HIGH - 0 188 IRQ_TYPE_LEVEL_HIGH - 0 189 IRQ_TYPE_LEVEL_HIGH - 0 190 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp4_clks SH73A0_CLK_IIC4>; power-domains = <&pd_c5>; status = "disabled"; @@ -265,8 +265,8 @@ mmcif: mmc@e6bd0000 { compatible = "renesas,sh-mmcif"; reg = <0xe6bd0000 0x100>; - interrupts = <0 140 IRQ_TYPE_LEVEL_HIGH - 0 141 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks SH73A0_CLK_MMCIF0>; power-domains = <&pd_a3sp>; reg-io-width = <4>; @@ -276,7 +276,7 @@ msiof0: spi@e6e20000 { compatible = "renesas,msiof-sh73a0", "renesas,sh-mobile-msiof"; reg = <0xe6e20000 0x0064>; - interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp0_clks SH73A0_CLK_MSIOF0>; power-domains = <&pd_a3sp>; #address-cells = <1>; @@ -287,7 +287,7 @@ msiof1: spi@e6e10000 { compatible = "renesas,msiof-sh73a0", "renesas,sh-mobile-msiof"; reg = <0xe6e10000 0x0064>; - interrupts = <0 77 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_MSIOF1>; power-domains = <&pd_a3sp>; #address-cells = <1>; @@ -298,7 +298,7 @@ msiof2: spi@e6e00000 { compatible = "renesas,msiof-sh73a0", "renesas,sh-mobile-msiof"; reg = <0xe6e00000 0x0064>; - interrupts = <0 76 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_MSIOF2>; power-domains = <&pd_a3sp>; #address-cells = <1>; @@ -309,7 +309,7 @@ msiof3: spi@e6c90000 { compatible = "renesas,msiof-sh73a0", "renesas,sh-mobile-msiof"; reg = <0xe6c90000 0x0064>; - interrupts = <0 59 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_MSIOF3>; power-domains = <&pd_a3sp>; #address-cells = <1>; @@ -320,9 +320,9 @@ sdhi0: sd@ee100000 { compatible = "renesas,sdhi-sh73a0"; reg = <0xee100000 0x100>; - interrupts = <0 83 IRQ_TYPE_LEVEL_HIGH - 0 84 IRQ_TYPE_LEVEL_HIGH - 0 85 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks SH73A0_CLK_SDHI0>; power-domains = <&pd_a3sp>; cap-sd-highspeed; @@ -333,8 +333,8 @@ sdhi1: sd@ee120000 { compatible = "renesas,sdhi-sh73a0"; reg = <0xee120000 0x100>; - interrupts = <0 88 IRQ_TYPE_LEVEL_HIGH - 0 89 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks SH73A0_CLK_SDHI1>; power-domains = <&pd_a3sp>; toshiba,mmc-wrprotect-disable; @@ -345,8 +345,8 @@ sdhi2: sd@ee140000 { compatible = "renesas,sdhi-sh73a0"; reg = <0xee140000 0x100>; - interrupts = <0 104 IRQ_TYPE_LEVEL_HIGH - 0 105 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks SH73A0_CLK_SDHI2>; power-domains = <&pd_a3sp>; toshiba,mmc-wrprotect-disable; @@ -357,9 +357,9 @@ scifa0: serial@e6c40000 { compatible = "renesas,scifa-sh73a0", "renesas,scifa"; reg = <0xe6c40000 0x100>; - interrupts = <0 72 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_SCIFA0>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -367,9 +367,9 @@ scifa1: serial@e6c50000 { compatible = "renesas,scifa-sh73a0", "renesas,scifa"; reg = <0xe6c50000 0x100>; - interrupts = <0 73 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_SCIFA1>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -377,9 +377,9 @@ scifa2: serial@e6c60000 { compatible = "renesas,scifa-sh73a0", "renesas,scifa"; reg = <0xe6c60000 0x100>; - interrupts = <0 74 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_SCIFA2>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -387,9 +387,9 @@ scifa3: serial@e6c70000 { compatible = "renesas,scifa-sh73a0", "renesas,scifa"; reg = <0xe6c70000 0x100>; - interrupts = <0 75 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_SCIFA3>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -397,9 +397,9 @@ scifa4: serial@e6c80000 { compatible = "renesas,scifa-sh73a0", "renesas,scifa"; reg = <0xe6c80000 0x100>; - interrupts = <0 78 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_SCIFA4>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -407,9 +407,9 @@ scifa5: serial@e6cb0000 { compatible = "renesas,scifa-sh73a0", "renesas,scifa"; reg = <0xe6cb0000 0x100>; - interrupts = <0 79 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_SCIFA5>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -417,9 +417,9 @@ scifa6: serial@e6cc0000 { compatible = "renesas,scifa-sh73a0", "renesas,scifa"; reg = <0xe6cc0000 0x100>; - interrupts = <0 156 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp3_clks SH73A0_CLK_SCIFA6>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -427,9 +427,9 @@ scifa7: serial@e6cd0000 { compatible = "renesas,scifa-sh73a0", "renesas,scifa"; reg = <0xe6cd0000 0x100>; - interrupts = <0 143 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_SCIFA7>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -437,9 +437,9 @@ scifb: serial@e6c30000 { compatible = "renesas,scifb-sh73a0", "renesas,scifb"; reg = <0xe6c30000 0x100>; - interrupts = <0 80 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&mstp2_clks SH73A0_CLK_SCIFB>; - clock-names = "sci_ick"; + clock-names = "fck"; power-domains = <&pd_a3sp>; status = "disabled"; }; @@ -579,7 +579,7 @@ #sound-dai-cells = <1>; compatible = "renesas,fsi2-sh73a0", "renesas,sh_fsi2"; reg = <0xec230000 0x400>; - interrupts = <0 146 0x4>; + interrupts = ; power-domains = <&pd_a4mp>; status = "disabled"; }; @@ -591,7 +591,7 @@ #size-cells = <1>; ranges = <0 0 0x20000000>; reg = <0xfec10000 0x400>; - interrupts = <0 39 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; clocks = <&zb_clk>; power-domains = <&pd_a4s>; }; diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi index 15cbc747c2425e5aa95b2c0b86aada0a14b8e46e..b89cbde3b289a807888e7cb3b293d64142b4613c 100644 --- a/arch/arm/boot/dts/socfpga.dtsi +++ b/arch/arm/boot/dts/socfpga.dtsi @@ -69,7 +69,7 @@ ranges; amba { - compatible = "arm,amba-bus"; + compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges; diff --git a/arch/arm/boot/dts/socfpga_arria10.dtsi b/arch/arm/boot/dts/socfpga_arria10.dtsi index cce9e50acf68a62274b080ee15dba03d203263fe..1c5e139e4d059f2efbc3fc02e3b0dcbe42559f7c 100644 --- a/arch/arm/boot/dts/socfpga_arria10.dtsi +++ b/arch/arm/boot/dts/socfpga_arria10.dtsi @@ -63,7 +63,7 @@ ranges; amba { - compatible = "arm,amba-bus"; + compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges; diff --git a/arch/arm/boot/dts/spear1310-evb.dts b/arch/arm/boot/dts/spear1310-evb.dts index e48857249ce7bfc8a9440fa25d80c97460436697..84101e4eebbf88bc9e112627b1abb6345e2d7e80 100644 --- a/arch/arm/boot/dts/spear1310-evb.dts +++ b/arch/arm/boot/dts/spear1310-evb.dts @@ -161,7 +161,7 @@ linux,code = <0x100>; gpios = <&gpio0 7 0x4>; debounce-interval = <20>; - gpio-key,wakeup = <1>; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/spear1340-evb.dts b/arch/arm/boot/dts/spear1340-evb.dts index c611f5606dfea5e2ba37ab5b0b57b7b73e0eed37..6565f3cb866f7d780795dacb29c727fd7c2805cf 100644 --- a/arch/arm/boot/dts/spear1340-evb.dts +++ b/arch/arm/boot/dts/spear1340-evb.dts @@ -223,7 +223,7 @@ linux,code = <0x100>; gpios = <&gpio1 1 0x4>; debounce-interval = <20>; - gpio-key,wakeup = <1>; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/spear320-hmi.dts b/arch/arm/boot/dts/spear320-hmi.dts index 0aa6fef5ce22631f33af77b7f4b6c05f91072000..0d0da1f65f0e68a23d038a11a91054f8f25022e0 100644 --- a/arch/arm/boot/dts/spear320-hmi.dts +++ b/arch/arm/boot/dts/spear320-hmi.dts @@ -141,7 +141,7 @@ linux,code = <0x100>; gpios = <&stmpegpio 3 0x4>; debounce-interval = <20>; - gpio-key,wakeup = <1>; + wakeup-source; }; button@2 { @@ -149,7 +149,7 @@ linux,code = <0x200>; gpios = <&stmpegpio 2 0x4>; debounce-interval = <20>; - gpio-key,wakeup = <1>; + wakeup-source; }; }; diff --git a/arch/arm/boot/dts/ste-href-tvk1281618.dtsi b/arch/arm/boot/dts/ste-href-tvk1281618.dtsi index b7b4211c5353ea9102e7742fc4c80afe274d8d26..55f9d0cc90f3ab2d11b0461f6aae06a4d6b442b5 100644 --- a/arch/arm/boot/dts/ste-href-tvk1281618.dtsi +++ b/arch/arm/boot/dts/ste-href-tvk1281618.dtsi @@ -37,7 +37,6 @@ }; soc { - /* Add Synaptics touch screen, TC35893 keypad etc here */ i2c@80004000 { tc35893@44 { compatible = "toshiba,tc35893"; @@ -159,6 +158,33 @@ vddio-supply = <&db8500_vsmps2_reg>; }; }; + + i2c@80110000 { + synaptics@4b { + /* Synaptics RMI4 TM1217 touchscreen */ + compatible = "syna,rmi4-i2c"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x4b>; + vdd-supply = <&ab8500_ldo_aux1_reg>; + vddio-supply = <&db8500_vsmps2_reg>; + pinctrl-names = "default"; + pinctrl-0 = <&synaptics_tvk_mode>; + interrupt-parent = <&gpio2>; + interrupts = <20 IRQ_TYPE_EDGE_FALLING>; + + rmi-f01@1 { + reg = <0x1>; + syna,nosleep = <1>; + }; + rmi-f11@11 { + reg = <0x11>; + touchscreen-inverted-x; + syna,sensor-type = <1>; + }; + }; + }; + pinctrl { /* Pull up this GPIO pin */ tc35893 { @@ -212,6 +238,15 @@ }; }; }; + synaptics { + synaptics_tvk_mode: synaptics_tvk { + /* Touchscreen uses GPIO 84 */ + tvk_cfg1 { + pins = "GPIO84_C2"; + ste,config = <&gpio_in_pu>; + }; + }; + }; }; }; }; diff --git a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi index 27a333eb89870167b82a170d3553bd5078fafdfb..e2be533430642e1a1ab3fd736db6b54d8c4cf954 100644 --- a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi +++ b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi @@ -721,7 +721,7 @@ }; amba { - compatible = "arm,amba-bus"; + compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges; diff --git a/arch/arm/boot/dts/ste-u300.dts b/arch/arm/boot/dts/ste-u300.dts index 9c73ac2842ad1605c7ec72f8a28191ffb2fdd358..2f5107ffeef047e4cce0d9925ae6d8fbc3f60079 100644 --- a/arch/arm/boot/dts/ste-u300.dts +++ b/arch/arm/boot/dts/ste-u300.dts @@ -384,7 +384,7 @@ }; amba { - compatible = "arm,amba-bus"; + compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges; diff --git a/arch/arm/boot/dts/stm32429i-eval.dts b/arch/arm/boot/dts/stm32429i-eval.dts index 6964fc9e97cfa346c0f46405382f85f62f93f8d4..6bfc5959dac3616a513f2b4017e8e3d0be75c195 100644 --- a/arch/arm/boot/dts/stm32429i-eval.dts +++ b/arch/arm/boot/dts/stm32429i-eval.dts @@ -58,18 +58,68 @@ }; memory { - reg = <0xc0000000 0x2000000>; + reg = <0x00000000 0x2000000>; }; aliases { serial0 = &usart1; }; + + leds { + compatible = "gpio-leds"; + green { + gpios = <&gpiog 6 1>; + linux,default-trigger = "heartbeat"; + }; + orange { + gpios = <&gpiog 7 1>; + }; + red { + gpios = <&gpiog 10 1>; + }; + blue { + gpios = <&gpiog 12 1>; + }; + }; + + usbotg_hs_phy: usbphy { + #phy-cells = <0>; + compatible = "usb-nop-xceiv"; + clocks = <&rcc 0 30>; + clock-names = "main_clk"; + }; }; &clk_hse { clock-frequency = <25000000>; }; +ðernet0 { + status = "okay"; + pinctrl-0 = <ðernet0_mii>; + pinctrl-names = "default"; + phy-mode = "mii-id"; + mdio0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,dwmac-mdio"; + phy1: ethernet-phy@1 { + reg = <1>; + }; + }; +}; + &usart1 { + pinctrl-0 = <&usart1_pins_a>; + pinctrl-names = "default"; + status = "okay"; +}; + +&usbotg_hs { + dr_mode = "host"; + phys = <&usbotg_hs_phy>; + phy-names = "usb2-phy"; + pinctrl-0 = <&usbotg_hs_pins_a>; + pinctrl-names = "default"; status = "okay"; }; diff --git a/arch/arm/boot/dts/stm32f429-disco.dts b/arch/arm/boot/dts/stm32f429-disco.dts index f0b731db6f530ab194deecda35fbb623cd95df10..01408073dd530671620cd75a23de7755dc3e6d0f 100644 --- a/arch/arm/boot/dts/stm32f429-disco.dts +++ b/arch/arm/boot/dts/stm32f429-disco.dts @@ -64,6 +64,17 @@ aliases { serial0 = &usart1; }; + + leds { + compatible = "gpio-leds"; + red { + gpios = <&gpiog 14 0>; + }; + green { + gpios = <&gpiog 13 0>; + linux,default-trigger = "heartbeat"; + }; + }; }; &clk_hse { @@ -71,5 +82,7 @@ }; &usart1 { + pinctrl-0 = <&usart1_pins_a>; + pinctrl-names = "default"; status = "okay"; }; diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi index 5e1e234e8c0a183fe3f7d056ff75290eb5d43933..35df462559cad3dd6aaa2fe2ecc30ce8afa28eb8 100644 --- a/arch/arm/boot/dts/stm32f429.dtsi +++ b/arch/arm/boot/dts/stm32f429.dtsi @@ -46,6 +46,7 @@ */ #include "armv7-m.dtsi" +#include / { clocks { @@ -57,6 +58,8 @@ }; soc { + dma-ranges = <0xc0000000 0x0 0x10000000>; + timer2: timer@40000000 { compatible = "st,stm32-timer"; reg = <0x40000000 0x400>; @@ -168,6 +171,160 @@ status = "disabled"; }; + syscfg: system-config@40013800 { + compatible = "syscon"; + reg = <0x40013800 0x400>; + }; + + pin-controller { + #address-cells = <1>; + #size-cells = <1>; + compatible = "st,stm32f429-pinctrl"; + ranges = <0 0x40020000 0x3000>; + pins-are-numbered; + + gpioa: gpio@40020000 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x0 0x400>; + clocks = <&rcc 0 0>; + st,bank-name = "GPIOA"; + }; + + gpiob: gpio@40020400 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x400 0x400>; + clocks = <&rcc 0 1>; + st,bank-name = "GPIOB"; + }; + + gpioc: gpio@40020800 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x800 0x400>; + clocks = <&rcc 0 2>; + st,bank-name = "GPIOC"; + }; + + gpiod: gpio@40020c00 { + gpio-controller; + #gpio-cells = <2>; + reg = <0xc00 0x400>; + clocks = <&rcc 0 3>; + st,bank-name = "GPIOD"; + }; + + gpioe: gpio@40021000 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x1000 0x400>; + clocks = <&rcc 0 4>; + st,bank-name = "GPIOE"; + }; + + gpiof: gpio@40021400 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x1400 0x400>; + clocks = <&rcc 0 5>; + st,bank-name = "GPIOF"; + }; + + gpiog: gpio@40021800 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x1800 0x400>; + clocks = <&rcc 0 6>; + st,bank-name = "GPIOG"; + }; + + gpioh: gpio@40021c00 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x1c00 0x400>; + clocks = <&rcc 0 7>; + st,bank-name = "GPIOH"; + }; + + gpioi: gpio@40022000 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x2000 0x400>; + clocks = <&rcc 0 8>; + st,bank-name = "GPIOI"; + }; + + gpioj: gpio@40022400 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x2400 0x400>; + clocks = <&rcc 0 9>; + st,bank-name = "GPIOJ"; + }; + + gpiok: gpio@40022800 { + gpio-controller; + #gpio-cells = <2>; + reg = <0x2800 0x400>; + clocks = <&rcc 0 10>; + st,bank-name = "GPIOK"; + }; + + usart1_pins_a: usart1@0 { + pins1 { + pinmux = ; + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { + pinmux = ; + bias-disable; + }; + }; + + usbotg_hs_pins_a: usbotg_hs@0 { + pins { + pinmux = , + , + , + , + , + , + , + , + , + , + , + ; + bias-disable; + drive-push-pull; + slew-rate = <2>; + }; + }; + + ethernet0_mii: mii@0 { + pins { + pinmux = , + , + , + , + , + , + , + , + , + , + , + , + , + ; + slew-rate = <2>; + }; + }; + }; + rcc: rcc@40023810 { #clock-cells = <2>; compatible = "st,stm32f42xx-rcc", "st,stm32-rcc"; @@ -175,6 +332,62 @@ clocks = <&clk_hse>; }; + dma1: dma-controller@40026000 { + compatible = "st,stm32-dma"; + reg = <0x40026000 0x400>; + interrupts = <11>, + <12>, + <13>, + <14>, + <15>, + <16>, + <17>, + <47>; + clocks = <&rcc 0 21>; + #dma-cells = <4>; + }; + + dma2: dma-controller@40026400 { + compatible = "st,stm32-dma"; + reg = <0x40026400 0x400>; + interrupts = <56>, + <57>, + <58>, + <59>, + <60>, + <68>, + <69>, + <70>; + clocks = <&rcc 0 22>; + #dma-cells = <4>; + st,mem2mem; + }; + + ethernet0: dwmac@40028000 { + compatible = "st,stm32-dwmac", "snps,dwmac-3.50a"; + reg = <0x40028000 0x8000>; + reg-names = "stmmaceth"; + interrupts = <61>, <62>; + interrupt-names = "macirq", "eth_wake_irq"; + clock-names = "stmmaceth", "tx-clk", "rx-clk"; + clocks = <&rcc 0 25>, <&rcc 0 26>, <&rcc 0 27>; + st,syscon = <&syscfg 0x4>; + snps,pbl = <8>; + snps,mixed-burst; + dma-ranges; + status = "disabled"; + }; + + usbotg_hs: usb@40040000 { + compatible = "snps,dwc2"; + dma-ranges; + reg = <0x40040000 0x40000>; + interrupts = <77>; + clocks = <&rcc 0 29>; + clock-names = "otg"; + status = "disabled"; + }; + rng: rng@50060800 { compatible = "st,stm32-rng"; reg = <0x50060800 0x400>; diff --git a/arch/arm/boot/dts/stm32f469-disco.dts b/arch/arm/boot/dts/stm32f469-disco.dts new file mode 100644 index 0000000000000000000000000000000000000000..e911af8364714c58956426c11f3624672761b1cc --- /dev/null +++ b/arch/arm/boot/dts/stm32f469-disco.dts @@ -0,0 +1,75 @@ +/* + * Copyright 2016 - Lee Jones + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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 file; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "stm32f429.dtsi" + +/ { + model = "STMicroelectronics STM32F469i-DISCO board"; + compatible = "st,stm32f469i-disco", "st,stm32f469"; + + chosen { + bootargs = "root=/dev/ram rdinit=/linuxrc"; + stdout-path = "serial0:115200n8"; + }; + + memory { + reg = <0x00000000 0x800000>; + }; + + aliases { + serial0 = &usart3; + }; +}; + +&clk_hse { + clock-frequency = <8000000>; +}; + +&usart3 { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts b/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts index 53660894ea95ebb953446caf650f43526e0f7a8a..023b03efa5fff7cd978b5820b9b8b5e3f2015052 100644 --- a/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts +++ b/arch/arm/boot/dts/sun4i-a10-chuwi-v7-cw0825.dts @@ -45,6 +45,7 @@ #include "sunxi-common-regulators.dtsi" #include #include +#include / { model = "Chuwi V7 CW0825"; @@ -88,6 +89,15 @@ pinctrl-names = "default"; pinctrl-0 = <&i2c2_pins_a>; status = "okay"; + + ft5306de4: touchscreen@38 { + compatible = "edt,edt-ft5406"; + reg = <0x38>; + interrupt-parent = <&pio>; + interrupts = <7 21 IRQ_TYPE_EDGE_FALLING>; + touchscreen-size-x = <1024>; + touchscreen-size-y = <768>; + }; }; &lradc { diff --git a/arch/arm/boot/dts/sun4i-a10-hyundai-a7hd.dts b/arch/arm/boot/dts/sun4i-a10-hyundai-a7hd.dts index 43f58fbe161ceccaa1f85469d97780ce68486270..9103864fef90a129f3f54a187721f8c7cff86673 100644 --- a/arch/arm/boot/dts/sun4i-a10-hyundai-a7hd.dts +++ b/arch/arm/boot/dts/sun4i-a10-hyundai-a7hd.dts @@ -87,6 +87,30 @@ status = "okay"; }; +&otg_sram { + status = "okay"; +}; + +&pio { + usb0_id_detect_pin: usb0_id_detect_pin@0 { + allwinner,pins = "PH4"; + allwinner,function = "gpio_in"; + allwinner,drive = ; + allwinner,pull = ; + }; + + usb0_vbus_detect_pin: usb0_vbus_detect_pin@0 { + allwinner,pins = "PH5"; + allwinner,function = "gpio_in"; + allwinner,drive = ; + allwinner,pull = ; + }; +}; + +®_usb0_vbus { + status = "okay"; +}; + ®_usb2_vbus { gpio = <&pio 7 6 GPIO_ACTIVE_HIGH>; /* PH6 */ status = "okay"; @@ -102,7 +126,17 @@ allwinner,pins = "PH6"; }; +&usb_otg { + dr_mode = "otg"; + status = "okay"; +}; + &usbphy { + pinctrl-names = "default"; + pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>; + usb0_id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */ + usb0_vbus_det-gpio = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */ + usb0_vbus-supply = <®_usb0_vbus>; usb2_vbus-supply = <®_usb2_vbus>; status = "okay"; }; diff --git a/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts b/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts index 77c31dab86b137d44fac84aec557587b0b594fe7..04b0d2d1ae6c1e2890f28abe0043f3ebcdbd9e95 100644 --- a/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts +++ b/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts @@ -48,6 +48,7 @@ #include #include +#include / { model = "INet-97F Rev 02"; @@ -93,6 +94,15 @@ pinctrl-names = "default"; pinctrl-0 = <&i2c2_pins_a>; status = "okay"; + + ft5406ee8: touchscreen@38 { + compatible = "edt,edt-ft5406"; + reg = <0x38>; + interrupt-parent = <&pio>; + interrupts = <7 21 IRQ_TYPE_EDGE_FALLING>; + touchscreen-size-x = <800>; + touchscreen-size-y = <480>; + }; }; &lradc { diff --git a/arch/arm/boot/dts/sun4i-a10-inet9f-rev03.dts b/arch/arm/boot/dts/sun4i-a10-inet9f-rev03.dts index ca49b0d0ce1e0bad3a3de2552acb04f66ee8b952..bba4f9cf9bf5d6c2f51faa05ea0ac90deb48bacc 100644 --- a/arch/arm/boot/dts/sun4i-a10-inet9f-rev03.dts +++ b/arch/arm/boot/dts/sun4i-a10-inet9f-rev03.dts @@ -253,6 +253,15 @@ pinctrl-names = "default"; pinctrl-0 = <&i2c2_pins_a>; status = "okay"; + + ft5406ee8: touchscreen@38 { + compatible = "edt,edt-ft5406"; + reg = <0x38>; + interrupt-parent = <&pio>; + interrupts = <7 21 IRQ_TYPE_EDGE_FALLING>; + touchscreen-size-x = <800>; + touchscreen-size-y = <480>; + }; }; &lradc { diff --git a/arch/arm/boot/dts/sun4i-a10-itead-iteaduino-plus.dts b/arch/arm/boot/dts/sun4i-a10-itead-iteaduino-plus.dts index 985e15503378f818299eed0110f1678fa2c016cc..4e798f014c992c949fdf186facae567c1c8b1de2 100644 --- a/arch/arm/boot/dts/sun4i-a10-itead-iteaduino-plus.dts +++ b/arch/arm/boot/dts/sun4i-a10-itead-iteaduino-plus.dts @@ -1,5 +1,6 @@ /* * Copyright 2015 Josef Gajdusek + * Copyright 2015 - Marcus Cooper * * This file is dual-licensed: you can use it either under the terms * of the GPL or the X11 license, at your option. Note that this dual @@ -42,22 +43,11 @@ /dts-v1/; #include "sun4i-a10.dtsi" -#include "sunxi-common-regulators.dtsi" - -#include -#include +#include "sunxi-itead-core-common.dtsi" / { model = "Iteaduino Plus A10"; compatible = "itead,iteaduino-plus-a10", "allwinner,sun4i-a10"; - - aliases { - serial0 = &uart0; - }; - - chosen { - stdout-path = "serial0:115200n8"; - }; }; &ahci { @@ -65,18 +55,6 @@ status = "okay"; }; -&cpu0 { - cpu-supply = <®_dcdc2>; -}; - -&ehci0 { - status = "okay"; -}; - -&ehci1 { - status = "okay"; -}; - &emac { pinctrl-names = "default"; pinctrl-0 = <&emac_pins_a>; @@ -89,12 +67,7 @@ }; &i2c0 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c0_pins_a>; - status = "okay"; - axp209: pmic@34 { - reg = <0x34>; interrupts = <0>; }; }; @@ -135,68 +108,13 @@ status = "okay"; }; -&ohci0 { - status = "okay"; -}; - -&ohci1 { - status = "okay"; -}; - ®_ahci_5v { status = "okay"; }; -#include "axp209.dtsi" - -®_dcdc2 { - regulator-always-on; - regulator-min-microvolt = <1000000>; - regulator-max-microvolt = <1450000>; - regulator-name = "vdd-cpu"; -}; - -®_dcdc3 { - regulator-always-on; - regulator-min-microvolt = <1000000>; - regulator-max-microvolt = <1400000>; - regulator-name = "vdd-int-dll"; -}; - -®_ldo1 { - regulator-name = "vdd-rtc"; -}; - -®_ldo2 { - regulator-always-on; - regulator-min-microvolt = <3000000>; - regulator-max-microvolt = <3000000>; - regulator-name = "avcc"; -}; - -®_usb1_vbus { - status = "okay"; -}; - -®_usb2_vbus { - status = "okay"; -}; - &spi0 { pinctrl-names = "default"; pinctrl-0 = <&spi0_pins_a>, <&spi0_cs0_pins_a>; status = "okay"; }; - -&uart0 { - pinctrl-names = "default"; - pinctrl-0 = <&uart0_pins_a>; - status = "okay"; -}; - -&usbphy { - usb1_vbus-supply = <®_usb1_vbus>; - usb2_vbus-supply = <®_usb2_vbus>; - status = "okay"; -}; diff --git a/arch/arm/boot/dts/sun4i-a10-mk802.dts b/arch/arm/boot/dts/sun4i-a10-mk802.dts index ddf0683cbc6a420137299ad7d688c3bce33597bc..ee46ea8548326394b45dd09aa0fc488973b2b54a 100644 --- a/arch/arm/boot/dts/sun4i-a10-mk802.dts +++ b/arch/arm/boot/dts/sun4i-a10-mk802.dts @@ -44,6 +44,7 @@ #include "sun4i-a10.dtsi" #include "sunxi-common-regulators.dtsi" #include +#include / { model = "MK802"; @@ -84,7 +85,25 @@ status = "okay"; }; +&otg_sram { + status = "okay"; +}; + &pio { + usb0_id_detect_pin: usb0_id_detect_pin@0 { + allwinner,pins = "PH4"; + allwinner,function = "gpio_in"; + allwinner,drive = ; + allwinner,pull = ; + }; + + usb0_vbus_detect_pin: usb0_vbus_detect_pin@0 { + allwinner,pins = "PH5"; + allwinner,function = "gpio_in"; + allwinner,drive = ; + allwinner,pull = ; + }; + usb2_vbus_pin_mk802: usb2_vbus_pin@0 { allwinner,pins = "PH12"; allwinner,function = "gpio_out"; @@ -93,6 +112,10 @@ }; }; +®_usb0_vbus { + status = "okay"; +}; + ®_usb1_vbus { status = "okay"; }; @@ -109,7 +132,17 @@ status = "okay"; }; +&usb_otg { + dr_mode = "otg"; + status = "okay"; +}; + &usbphy { + pinctrl-names = "default"; + pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>; + usb0_id_det-gpios = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */ + usb0_vbus_det-gpios = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */ + usb0_vbus-supply = <®_usb0_vbus>; usb1_vbus-supply = <®_usb1_vbus>; usb2_vbus-supply = <®_usb2_vbus>; status = "okay"; diff --git a/arch/arm/boot/dts/sun5i-r8-chip.dts b/arch/arm/boot/dts/sun5i-r8-chip.dts index 530ab28e9ca239b2da64d046a1c0c1da7d94b9d0..f6898c6b84d426bdf45df86495bc69cad91bb064 100644 --- a/arch/arm/boot/dts/sun5i-r8-chip.dts +++ b/arch/arm/boot/dts/sun5i-r8-chip.dts @@ -70,6 +70,10 @@ status = "okay"; }; +&cpu0 { + cpu-supply = <®_dcdc2>; +}; + &ehci0 { status = "okay"; }; diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi index b6ad7850fac6931ee1eb6f1716418c16b849eae4..1867af24ff529c2b6590e0db0dcc2f807fd72a65 100644 --- a/arch/arm/boot/dts/sun6i-a31.dtsi +++ b/arch/arm/boot/dts/sun6i-a31.dtsi @@ -709,6 +709,16 @@ allwinner,pull = ; }; + mmc3_8bit_emmc_pins: mmc3@1 { + allwinner,pins = "PC6", "PC7", "PC8", "PC9", + "PC10", "PC11", "PC12", + "PC13", "PC14", "PC15", + "PC24"; + allwinner,function = "mmc3"; + allwinner,drive = ; + allwinner,pull = ; + }; + gmac_pins_mii_a: gmac_mii@0 { allwinner,pins = "PA0", "PA1", "PA2", "PA3", "PA8", "PA9", "PA11", diff --git a/arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi b/arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi index ea69fb8ad4d80aab599c5c8e313429706a23bf87..4ec0c8679b2e20b9a15b28160639daf264abd0d6 100644 --- a/arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi +++ b/arch/arm/boot/dts/sun6i-a31s-sina31s-core.dtsi @@ -61,12 +61,14 @@ }; /* eMMC on core board */ -&mmc2 { +&mmc3 { pinctrl-names = "default"; - pinctrl-0 = <&mmc2_8bit_emmc_pins>; + pinctrl-0 = <&mmc3_8bit_emmc_pins>; vmmc-supply = <®_dcdc1>; + vqmmc-supply = <®_dcdc1>; bus-width = <8>; non-removable; + cap-mmc-hw-reset; status = "okay"; }; diff --git a/arch/arm/boot/dts/sun7i-a20-itead-ibox.dts b/arch/arm/boot/dts/sun7i-a20-itead-ibox.dts new file mode 100644 index 0000000000000000000000000000000000000000..661c21d9bdbd5a3ca39bbca7b9cebabc08632a36 --- /dev/null +++ b/arch/arm/boot/dts/sun7i-a20-itead-ibox.dts @@ -0,0 +1,125 @@ +/* + * Copyright 2015 - Marcus Cooper + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "sun7i-a20.dtsi" +#include "sunxi-itead-core-common.dtsi" + +/ { + model = "Itead Ibox A20"; + compatible = "itead,itead-ibox-a20", "allwinner,sun7i-a20"; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&led_pins_itead_core>; + + green { + label = "itead_core:green:usr"; + gpios = <&pio 7 20 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + + blue { + label = "itead_core:blue:usr"; + gpios = <&pio 7 21 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + }; +}; + +&ahci { + target-supply = <®_ahci_5v>; + status = "okay"; +}; + +&codec { + status = "okay"; +}; + +&gmac { + pinctrl-names = "default"; + pinctrl-0 = <&gmac_pins_mii_a>; + phy = <&phy1>; + phy-mode = "mii"; + status = "okay"; + + phy1: ethernet-phy@1 { + reg = <1>; + }; +}; + +&i2c0 { + axp209: pmic@34 { + interrupt-parent = <&nmi_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + }; +}; + +&ir0 { + pinctrl-names = "default"; + pinctrl-0 = <&ir0_rx_pins_a>; + status = "okay"; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + vmmc-supply = <®_vcc3v3>; + bus-width = <4>; + cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ + cd-inverted; + status = "okay"; +}; + +&pio { + led_pins_itead_core: led_pins@0 { + allwinner,pins = "PH20","PH21"; + allwinner,function = "gpio_out"; + allwinner,drive = ; + allwinner,pull = ; + }; +}; + +®_ahci_5v { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/sun7i-a20-lamobo-r1.dts b/arch/arm/boot/dts/sun7i-a20-lamobo-r1.dts new file mode 100644 index 0000000000000000000000000000000000000000..5ee43d8bf17484f386df9b62e6e878c6eb2a94cd --- /dev/null +++ b/arch/arm/boot/dts/sun7i-a20-lamobo-r1.dts @@ -0,0 +1,287 @@ +/* + * Copyright 2015 Jelle de Jong + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "sun7i-a20.dtsi" +#include "sunxi-common-regulators.dtsi" + +#include +#include +#include + +/ { + model = "Lamobo R1"; + compatible = "lamobo,lamobo-r1", "allwinner,sun7i-a20"; + + aliases { + serial0 = &uart0; + serial1 = &uart3; + serial2 = &uart7; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&led_pins_lamobo_r1>; + + green { + label = "lamobo_r1:green:usr"; + gpios = <&pio 7 24 GPIO_ACTIVE_HIGH>; + }; + }; + + reg_gmac_3v3: gmac-3v3 { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&gmac_power_pin_lamobo_r1>; + regulator-name = "gmac-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + startup-delay-us = <100000>; + enable-active-high; + gpio = <&pio 7 23 GPIO_ACTIVE_HIGH>; /* PH23 */ + }; +}; + +&ahci_pwr_pin_a { + allwinner,pins = "PB3"; +}; + +&ahci { + target-supply = <®_ahci_5v>; + status = "okay"; +}; + +&cpu0 { + cpu-supply = <®_dcdc2>; +}; + +&ehci0 { + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + +&gmac { + pinctrl-names = "default"; + pinctrl-0 = <&gmac_pins_rgmii_a>; + phy = <&phy1>; + phy-mode = "rgmii"; + phy-supply = <®_gmac_3v3>; + status = "okay"; + + phy1: ethernet-phy@1 { + reg = <1>; + }; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_a>; + status = "okay"; + + axp209: pmic@34 { + reg = <0x34>; + interrupt-parent = <&nmi_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + }; +}; + +&i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins_a>; + status = "okay"; +}; + +&ir0 { + pinctrl-names = "default"; + pinctrl-0 = <&ir0_rx_pins_a>; + status = "okay"; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_lamobo_r1>; + vmmc-supply = <®_vcc3v3>; + bus-width = <4>; + cd-gpios = <&pio 7 10 GPIO_ACTIVE_HIGH>; /* PH10 */ + cd-inverted; + status = "okay"; +}; + +&ohci0 { + status = "okay"; +}; + +&ohci1 { + status = "okay"; +}; + +&otg_sram { + status = "okay"; +}; + +&pio { + usb0_id_detect_pin: usb0_id_detect_pin@0 { + allwinner,pins = "PH4"; + allwinner,function = "gpio_in"; + allwinner,drive = ; + allwinner,pull = ; + }; + + mmc0_cd_pin_lamobo_r1: mmc0_cd_pin@0 { + allwinner,pins = "PH10"; + allwinner,function = "gpio_in"; + allwinner,drive = ; + allwinner,pull = ; + }; + + gmac_power_pin_lamobo_r1: gmac_power_pin@0 { + allwinner,pins = "PH23"; + allwinner,function = "gpio_out"; + allwinner,drive = ; + allwinner,pull = ; + }; + + led_pins_lamobo_r1: led_pins@0 { + allwinner,pins = "PH24"; + allwinner,function = "gpio_out"; + allwinner,drive = ; + allwinner,pull = ; + }; +}; + +#include "axp209.dtsi" + +®_ahci_5v { + gpio = <&pio 1 3 0>; /* PB3 */ + status = "okay"; +}; + +®_dcdc2 { + regulator-always-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1400000>; + regulator-name = "vdd-cpu"; +}; + +®_dcdc3 { + regulator-always-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1400000>; + regulator-name = "vdd-int-dll"; +}; + +®_ldo1 { + regulator-name = "vdd-rtc"; +}; + +®_ldo2 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "avcc"; +}; + +®_usb0_vbus { + status = "okay"; +}; + +®_usb1_vbus { + status = "okay"; +}; + +®_usb2_vbus { + status = "okay"; +}; + +&spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&spi0_pins_a>, + <&spi0_cs0_pins_a>, + <&spi0_cs1_pins_a>; + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins_a>; + status = "okay"; +}; + +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&uart3_pins_b>; + status = "okay"; +}; + +&uart7 { + pinctrl-names = "default"; + pinctrl-0 = <&uart7_pins_a>; + status = "okay"; +}; + +&usb_otg { + dr_mode = "otg"; + status = "okay"; +}; + +&usb_power_supply { + status = "okay"; +}; + +&usbphy { + pinctrl-names = "default"; + pinctrl-0 = <&usb0_id_detect_pin>; + usb0_id_det-gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */ + usb0_vbus_power-supply = <&usb_power_supply>; + usb0_vbus-supply = <®_usb0_vbus>; + usb1_vbus-supply = <®_usb1_vbus>; + usb2_vbus-supply = <®_usb2_vbus>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/sun7i-a20-mk808c.dts b/arch/arm/boot/dts/sun7i-a20-mk808c.dts index c9e648d17a1e80ee28e5b7c99414ad5e8923c48a..90ff4a2670259fb8ec18b2980c913a36b2ed67ac 100644 --- a/arch/arm/boot/dts/sun7i-a20-mk808c.dts +++ b/arch/arm/boot/dts/sun7i-a20-mk808c.dts @@ -53,6 +53,7 @@ #include #include +#include / { model = "mk808c"; @@ -125,6 +126,30 @@ status = "okay"; }; +&otg_sram { + status = "okay"; +}; + +&pio { + usb0_id_detect_pin: usb0_id_detect_pin@0 { + allwinner,pins = "PH4"; + allwinner,function = "gpio_in"; + allwinner,drive = ; + allwinner,pull = ; + }; + + usb0_vbus_detect_pin: usb0_vbus_detect_pin@0 { + allwinner,pins = "PH5"; + allwinner,function = "gpio_in"; + allwinner,drive = ; + allwinner,pull = ; + }; +}; + +®_usb0_vbus { + status = "okay"; +}; + ®_usb1_vbus { status = "okay"; }; @@ -145,7 +170,17 @@ status = "okay"; }; +&usb_otg { + dr_mode = "otg"; + status = "okay"; +}; + &usbphy { + pinctrl-names = "default"; + pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>; + usb0_id_det-gpios = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */ + usb0_vbus_det-gpios = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */ + usb0_vbus-supply = <®_usb0_vbus>; usb1_vbus-supply = <®_usb1_vbus>; usb2_vbus-supply = <®_usb2_vbus>; status = "okay"; diff --git a/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts b/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts index c3c626b2cfa21d547021871a3c12175bc0aafa55..23aacce4d6c7ab8e408d6591d1ab5cc58e7ae5dc 100644 --- a/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts +++ b/arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts @@ -198,6 +198,10 @@ status = "okay"; }; +&otg_sram { + status = "okay"; +}; + &pio { ahci_pwr_pin_olimex_som_evb: ahci_pwr_pin@1 { allwinner,pins = "PC3"; @@ -219,6 +223,20 @@ allwinner,drive = ; allwinner,pull = ; }; + + usb0_id_detect_pin: usb0_id_detect_pin@0 { + allwinner,pins = "PH4"; + allwinner,function = "gpio_in"; + allwinner,drive = ; + allwinner,pull = ; + }; + + usb0_vbus_detect_pin: usb0_vbus_detect_pin@0 { + allwinner,pins = "PH5"; + allwinner,function = "gpio_in"; + allwinner,drive = ; + allwinner,pull = ; + }; }; ®_ahci_5v { @@ -254,6 +272,10 @@ regulator-name = "avcc"; }; +®_usb0_vbus { + status = "okay"; +}; + ®_usb1_vbus { status = "okay"; }; @@ -268,7 +290,17 @@ status = "okay"; }; +&usb_otg { + dr_mode = "otg"; + status = "okay"; +}; + &usbphy { + pinctrl-names = "default"; + pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>; + usb0_id_det-gpios = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH04 */ + usb0_vbus_det-gpios = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH05 */ + usb0_vbus-supply = <®_usb0_vbus>; usb1_vbus-supply = <®_usb1_vbus>; usb2_vbus-supply = <®_usb2_vbus>; status = "okay"; diff --git a/arch/arm/boot/dts/sun8i-a23-a33.dtsi b/arch/arm/boot/dts/sun8i-a23-a33.dtsi index 6f88fb0ddbc7d13a1f2ee83befbdd111ee36dfb4..7e05e09e61c7e49fa78a287220047e70f0b2fa99 100644 --- a/arch/arm/boot/dts/sun8i-a23-a33.dtsi +++ b/arch/arm/boot/dts/sun8i-a23-a33.dtsi @@ -381,7 +381,7 @@ allwinner,pins = "PC5", "PC6", "PC8", "PC9", "PC10", "PC11", "PC12", "PC13", "PC14", - "PC15"; + "PC15", "PC16"; allwinner,function = "mmc2"; allwinner,drive = ; allwinner,pull = ; diff --git a/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts b/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts index 13ce68f06dd6e0ab7c7b9a5ba6e05562e4df3868..fef6abc0a7038001180f8f5bfa3d5afcfdbd3c10 100644 --- a/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts +++ b/arch/arm/boot/dts/sun8i-a33-sinlinx-sina33.dts @@ -68,7 +68,7 @@ }; &lradc { - vref-supply = <®_vcc3v0>; + vref-supply = <®_dcdc1>; status = "okay"; button@200 { @@ -96,7 +96,7 @@ &mmc0 { pinctrl-names = "default"; pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_sina33>; - vmmc-supply = <®_vcc3v0>; + vmmc-supply = <®_dcdc1>; bus-width = <4>; cd-gpios = <&pio 1 4 GPIO_ACTIVE_HIGH>; /* PB4 */ cd-inverted; @@ -106,13 +106,16 @@ &mmc2 { pinctrl-names = "default"; pinctrl-0 = <&mmc2_8bit_pins>; - vmmc-supply = <®_vcc3v0>; + vmmc-supply = <®_dcdc1>; bus-width = <8>; non-removable; + cap-mmc-hw-reset; status = "okay"; }; &mmc2_8bit_pins { + /* Increase drive strength for DDR modes */ + allwinner,drive = ; /* eMMC is missing pull-ups */ allwinner,pull = ; }; @@ -132,6 +135,76 @@ &r_rsb { status = "okay"; + + axp22x: pmic@3a3 { + compatible = "x-powers,axp223"; + reg = <0x3a3>; + interrupt-parent = <&nmi_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + eldoin-supply = <®_dcdc1>; + }; +}; + +#include "axp22x.dtsi" + +®_aldo1 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "vcc-io"; +}; + +®_aldo2 { + regulator-always-on; + regulator-min-microvolt = <2350000>; + regulator-max-microvolt = <2650000>; + regulator-name = "vdd-dll"; +}; + +®_aldo3 { + regulator-always-on; + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-pll-avcc"; +}; + +®_dc5ldo { + regulator-always-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1400000>; + regulator-name = "vdd-cpus"; +}; + +®_dcdc1 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "vcc-3v0"; +}; + +®_dcdc2 { + regulator-always-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1400000>; + regulator-name = "vdd-sys"; +}; + +®_dcdc3 { + regulator-always-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1400000>; + regulator-name = "vdd-cpu"; +}; + +®_dcdc5 { + regulator-always-on; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-name = "vcc-dram"; +}; + +®_rtc_ldo { + regulator-name = "vcc-rtc"; }; &uart0 { diff --git a/arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts b/arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts new file mode 100644 index 0000000000000000000000000000000000000000..342e1d33fa1c37df6e473e63dc45732d51689883 --- /dev/null +++ b/arch/arm/boot/dts/sun8i-a83t-allwinner-h8homlet-v2.dts @@ -0,0 +1,64 @@ +/* + * Copyright 2015 Vishnu Patekar + * Vishnu Patekar + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "sun8i-a83t.dtsi" + +/ { + model = "Allwinner A83T H8Homlet Proto Dev Board v2.0"; + compatible = "allwinner,h8homlet-v2", "allwinner,sun8i-a83t"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins_b>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts b/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts new file mode 100644 index 0000000000000000000000000000000000000000..88b1e0970b8d89c94ba6822bc34f03eeb3c0477c --- /dev/null +++ b/arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts @@ -0,0 +1,65 @@ +/* + * Copyright 2015 Chen-Yu Tsai + * + * Chen-Yu Tsai + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "sun8i-a83t.dtsi" + +/ { + model = "Cubietech Cubietruck Plus"; + compatible = "cubietech,cubietruck-plus", "allwinner,sun8i-a83t"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins_b>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..d3473f81b12f7182c953fc02abd29b26f800cc5b --- /dev/null +++ b/arch/arm/boot/dts/sun8i-a83t.dtsi @@ -0,0 +1,228 @@ +/* + * Copyright 2015 Vishnu Patekar + * + * Vishnu Patekar + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + + */ + +#include "skeleton.dtsi" + +#include + +#include + +/ { + interrupt-parent = <&gic>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <0>; + }; + + cpu@1 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <1>; + }; + + cpu@2 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <2>; + }; + + cpu@3 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <3>; + }; + + cpu@100 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <0x100>; + }; + + cpu@101 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <0x101>; + }; + + cpu@102 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <0x102>; + }; + + cpu@103 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <0x103>; + }; + }; + + timer { + compatible = "arm,armv7-timer"; + interrupts = , + , + , + ; + }; + + clocks { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + /* TODO: PRCM block has a mux for this. */ + osc24M: osc24M_clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <24000000>; + clock-output-names = "osc24M"; + }; + + /* + * This is called "internal OSC" in some places. + * It is an internal RC-based oscillator. + * TODO: Its controls are in the PRCM block. + */ + osc16M: osc16M_clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <16000000>; + clock-output-names = "osc16M"; + }; + + osc16Md512: osc16Md512_clk { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clock-div = <512>; + clock-mult = <1>; + clocks = <&osc16M>; + clock-output-names = "osc16M-d512"; + }; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + pio: pinctrl@01c20800 { + compatible = "allwinner,sun8i-a83t-pinctrl"; + interrupts = , + , + ; + reg = <0x01c20800 0x400>; + clocks = <&osc24M>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <3>; + #gpio-cells = <3>; + + mmc0_pins_a: mmc0@0 { + allwinner,pins = "PF0", "PF1", "PF2", + "PF3", "PF4", "PF5"; + allwinner,function = "mmc0"; + allwinner,drive = ; + allwinner,pull = ; + }; + + uart0_pins_a: uart0@0 { + allwinner,pins = "PF2", "PF4"; + allwinner,function = "uart0"; + allwinner,drive = ; + allwinner,pull = ; + }; + + uart0_pins_b: uart0@1 { + allwinner,pins = "PB9", "PB10"; + allwinner,function = "uart0"; + allwinner,drive = ; + allwinner,pull = ; + }; + }; + + timer@01c20c00 { + compatible = "allwinner,sun4i-a10-timer"; + reg = <0x01c20c00 0xa0>; + interrupts = , + ; + clocks = <&osc24M>; + }; + + watchdog@01c20ca0 { + compatible = "allwinner,sun6i-a31-wdt"; + reg = <0x01c20ca0 0x20>; + interrupts = ; + clocks = <&osc24M>; + }; + + uart0: serial@01c28000 { + compatible = "snps,dw-apb-uart"; + reg = <0x01c28000 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&osc24M>; + status = "disabled"; + }; + + gic: interrupt-controller@01c81000 { + compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic"; + reg = <0x01c81000 0x1000>, + <0x01c82000 0x1000>, + <0x01c84000 0x2000>, + <0x01c86000 0x2000>; + interrupt-controller; + #interrupt-cells = <3>; + interrupts = ; + }; + }; +}; diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts index e67df590535fafc35f4cb55ff6d84ac87592e3be..79f40c3e6101e5b62d1fb714b32783b03af563a5 100644 --- a/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts +++ b/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts @@ -45,6 +45,7 @@ #include "sunxi-common-regulators.dtsi" #include +#include #include / { @@ -58,6 +59,62 @@ chosen { stdout-path = "serial0:115200n8"; }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&leds_opc>, <&leds_r_opc>; + + status_led { + label = "orangepi-plus:red:status"; + gpios = <&pio 0 15 GPIO_ACTIVE_HIGH>; + }; + + pwr_led { + label = "orangepi-plus:green:pwr"; + gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + }; + + r_gpio_keys { + compatible = "gpio-keys"; + input-name = "sw4"; + + pinctrl-names = "default"; + pinctrl-0 = <&sw_r_opc>; + + sw4@0 { + label = "sw4"; + linux,code = ; + gpios = <&r_pio 0 3 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&pio { + leds_opc: led_pins@0 { + allwinner,pins = "PA15"; + allwinner,function = "gpio_out"; + allwinner,drive = ; + allwinner,pull = ; + }; +}; + +&r_pio { + leds_r_opc: led_pins@0 { + allwinner,pins = "PL10"; + allwinner,function = "gpio_out"; + allwinner,drive = ; + allwinner,pull = ; + }; + + sw_r_opc: key_pins@0 { + allwinner,pins = "PL03"; + allwinner,function = "gpio_in"; + allwinner,drive = ; + allwinner,pull = ; + }; }; &mmc0 { diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi index 1524130e43c94c97097b7389dd3951459a1af7ee..dadb7f60c06237054a22e9ec247a0d05126f75f6 100644 --- a/arch/arm/boot/dts/sun8i-h3.dtsi +++ b/arch/arm/boot/dts/sun8i-h3.dtsi @@ -276,6 +276,33 @@ clocks = <&osc24M>, <&pll6 1>, <&pll5>; clock-output-names = "mbus"; }; + + apb0: apb0_clk { + compatible = "fixed-factor-clock"; + #clock-cells = <0>; + clock-div = <1>; + clock-mult = <1>; + clocks = <&osc24M>; + clock-output-names = "apb0"; + }; + + apb0_gates: clk@01f01428 { + compatible = "allwinner,sun8i-h3-apb0-gates-clk", + "allwinner,sun4i-a10-gates-clk"; + reg = <0x01f01428 0x4>; + #clock-cells = <1>; + clocks = <&apb0>; + clock-indices = <0>, <1>; + clock-output-names = "apb0_pio", "apb0_ir"; + }; + + ir_clk: ir_clk@01f01454 { + compatible = "allwinner,sun4i-a10-mod0-clk"; + reg = <0x01f01454 0x4>; + #clock-cells = <0>; + clocks = <&osc32k>, <&osc24M>; + clock-output-names = "ir"; + }; }; soc { @@ -359,7 +386,7 @@ gpio-controller; #gpio-cells = <3>; interrupt-controller; - #interrupt-cells = <2>; + #interrupt-cells = <3>; uart0_pins_a: uart0@0 { allwinner,pins = "PA4", "PA5"; @@ -493,5 +520,40 @@ interrupts = , ; }; + + apb0_reset: reset@01f014b0 { + reg = <0x01f014b0 0x4>; + compatible = "allwinner,sun6i-a31-clock-reset"; + #reset-cells = <1>; + }; + + ir: ir@01f02000 { + compatible = "allwinner,sun5i-a13-ir"; + clocks = <&apb0_gates 1>, <&ir_clk>; + clock-names = "apb", "ir"; + resets = <&apb0_reset 1>; + interrupts = ; + reg = <0x01f02000 0x40>; + status = "disabled"; + }; + + r_pio: pinctrl@01f02c00 { + compatible = "allwinner,sun8i-h3-r-pinctrl"; + reg = <0x01f02c00 0x400>; + interrupts = ; + clocks = <&apb0_gates 0>; + resets = <&apb0_reset 0>; + gpio-controller; + #gpio-cells = <3>; + interrupt-controller; + #interrupt-cells = <3>; + + ir_pins_a: ir@0 { + allwinner,pins = "PL11"; + allwinner,function = "s_cir_rx"; + allwinner,drive = ; + allwinner,pull = ; + }; + }; }; }; diff --git a/arch/arm/boot/dts/sun8i-q8-common.dtsi b/arch/arm/boot/dts/sun8i-q8-common.dtsi index 1a69231d2da5712bc69e671cc28a84a2d6ad5a96..9d2b7e2f5975ed3dae7d9d107a5a0ed5c80369e9 100644 --- a/arch/arm/boot/dts/sun8i-q8-common.dtsi +++ b/arch/arm/boot/dts/sun8i-q8-common.dtsi @@ -56,7 +56,6 @@ brightness-levels = <0 10 20 30 40 50 60 70 80 90 100>; default-brightness-level = <8>; enable-gpios = <&pio 7 6 GPIO_ACTIVE_HIGH>; /* PH6 */ - /* backlight is powered by AXP223 DC1SW */ }; chosen { @@ -67,7 +66,7 @@ &mmc0 { pinctrl-names = "default"; pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_q8>; - vmmc-supply = <®_vcc3v0>; + vmmc-supply = <®_dcdc1>; bus-width = <4>; cd-gpios = <&pio 1 4 GPIO_ACTIVE_HIGH>; /* PB4 */ cd-inverted; @@ -92,6 +91,82 @@ &r_rsb { status = "okay"; + + axp22x: pmic@3a3 { + compatible = "x-powers,axp223"; + reg = <0x3a3>; + interrupt-parent = <&nmi_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + eldoin-supply = <®_dcdc1>; + }; +}; + +#include "axp22x.dtsi" + +®_aldo1 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "vcc-io"; +}; + +®_aldo2 { + regulator-always-on; + regulator-min-microvolt = <2350000>; + regulator-max-microvolt = <2650000>; + regulator-name = "vdd-dll"; +}; + +®_aldo3 { + regulator-always-on; + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-pll-avcc"; +}; + +®_dc1sw { + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "vcc-lcd"; +}; + +®_dc5ldo { + regulator-always-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1400000>; + regulator-name = "vdd-cpus"; +}; + +®_dcdc1 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "vcc-3v0"; +}; + +®_dcdc2 { + regulator-always-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1400000>; + regulator-name = "vdd-sys"; +}; + +®_dcdc3 { + regulator-always-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1400000>; + regulator-name = "vdd-cpu"; +}; + +®_dcdc5 { + regulator-always-on; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-name = "vcc-dram"; +}; + +®_rtc_ldo { + regulator-name = "vcc-rtc"; }; &r_uart { @@ -99,3 +174,7 @@ pinctrl-0 = <&r_uart_pins_a>; status = "okay"; }; + +&simplefb_lcd { + vcc-lcd-supply = <®_dc1sw>; +}; diff --git a/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts b/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts index 382bd9fc5647abbe4e23eb0d8ac3ed855cd1cd4d..eb2ccd0a3bd5d4217f7a2a91a7383d87594ef074 100644 --- a/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts +++ b/arch/arm/boot/dts/sun9i-a80-cubieboard4.dts @@ -111,9 +111,15 @@ vmmc-supply = <®_vcc3v0>; bus-width = <8>; non-removable; + cap-mmc-hw-reset; status = "okay"; }; +&mmc2_8bit_pins { + /* Increase drive strength for DDR modes */ + allwinner,drive = ; +}; + &r_ir { status = "okay"; }; diff --git a/arch/arm/boot/dts/sun9i-a80-optimus.dts b/arch/arm/boot/dts/sun9i-a80-optimus.dts index c0060e4f7379fe775d78f6dfb9d5db4c169f7a05..d7a20d92b1143b1a7713d998cec753a2dfada507 100644 --- a/arch/arm/boot/dts/sun9i-a80-optimus.dts +++ b/arch/arm/boot/dts/sun9i-a80-optimus.dts @@ -109,17 +109,6 @@ status = "okay"; }; -&i2c3 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c3_pins_a>; - status = "okay"; -}; - -&i2c3_pins_a { - /* Enable internal pull-up */ - allwinner,pull = ; -}; - &ohci0 { status = "okay"; }; @@ -174,9 +163,15 @@ vmmc-supply = <®_vcc3v0>; bus-width = <8>; non-removable; + cap-mmc-hw-reset; status = "okay"; }; +&mmc2_8bit_pins { + /* Increase drive strength for DDR modes */ + allwinner,drive = ; +}; + ®_usb1_vbus { pinctrl-0 = <&usb1_vbus_pin_optimus>; gpio = <&pio 7 4 GPIO_ACTIVE_HIGH>; /* PH4 */ @@ -206,17 +201,6 @@ status = "okay"; }; -&uart4 { - pinctrl-names = "default"; - pinctrl-0 = <&uart4_pins_a>; - status = "okay"; -}; - -&uart4_pins_a { - /* Enable internal pull-up */ - allwinner,pull = ; -}; - &usbphy1 { phy-supply = <®_usb1_vbus>; status = "okay"; diff --git a/arch/arm/boot/dts/sun9i-a80.dtsi b/arch/arm/boot/dts/sun9i-a80.dtsi index e838f206f2a0f34f361bf858d00a6762b4d5739c..f68b3242b33a09b0ff0c197c817b75525c9d9bb9 100644 --- a/arch/arm/boot/dts/sun9i-a80.dtsi +++ b/arch/arm/boot/dts/sun9i-a80.dtsi @@ -543,7 +543,7 @@ }; mmc0: mmc@01c0f000 { - compatible = "allwinner,sun5i-a13-mmc"; + compatible = "allwinner,sun9i-a80-mmc"; reg = <0x01c0f000 0x1000>; clocks = <&mmc_config_clk 0>, <&mmc0_clk 0>, <&mmc0_clk 1>, <&mmc0_clk 2>; @@ -557,7 +557,7 @@ }; mmc1: mmc@01c10000 { - compatible = "allwinner,sun5i-a13-mmc"; + compatible = "allwinner,sun9i-a80-mmc"; reg = <0x01c10000 0x1000>; clocks = <&mmc_config_clk 1>, <&mmc1_clk 0>, <&mmc1_clk 1>, <&mmc1_clk 2>; @@ -571,7 +571,7 @@ }; mmc2: mmc@01c11000 { - compatible = "allwinner,sun5i-a13-mmc"; + compatible = "allwinner,sun9i-a80-mmc"; reg = <0x01c11000 0x1000>; clocks = <&mmc_config_clk 2>, <&mmc2_clk 0>, <&mmc2_clk 1>, <&mmc2_clk 2>; @@ -585,7 +585,7 @@ }; mmc3: mmc@01c12000 { - compatible = "allwinner,sun5i-a13-mmc"; + compatible = "allwinner,sun9i-a80-mmc"; reg = <0x01c12000 0x1000>; clocks = <&mmc_config_clk 3>, <&mmc3_clk 0>, <&mmc3_clk 1>, <&mmc3_clk 2>; @@ -704,7 +704,8 @@ mmc2_8bit_pins: mmc2_8bit { allwinner,pins = "PC6", "PC7", "PC8", "PC9", "PC10", "PC11", "PC12", - "PC13", "PC14", "PC15"; + "PC13", "PC14", "PC15", + "PC16"; allwinner,function = "mmc2"; allwinner,drive = ; allwinner,pull = ; diff --git a/arch/arm/boot/dts/sunxi-itead-core-common.dtsi b/arch/arm/boot/dts/sunxi-itead-core-common.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..2565d5137a17e300c4f9274277303d5626e761f2 --- /dev/null +++ b/arch/arm/boot/dts/sunxi-itead-core-common.dtsi @@ -0,0 +1,136 @@ +/* + * Copyright 2015 - Marcus Cooper + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "sunxi-common-regulators.dtsi" + +/ { + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&cpu0 { + cpu-supply = <®_dcdc2>; +}; + +&ehci0 { + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_a>; + status = "okay"; + + axp209: pmic@34 { + reg = <0x34>; + }; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins_a>; + status = "okay"; +}; + +&ohci0 { + status = "okay"; +}; + +&ohci1 { + status = "okay"; +}; + +#include "axp209.dtsi" + +®_dcdc2 { + regulator-always-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1400000>; + regulator-name = "vdd-cpu"; +}; + +®_dcdc3 { + regulator-always-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1400000>; + regulator-name = "vdd-int-dll"; +}; + +®_ldo1 { + regulator-name = "vdd-rtc"; +}; + +®_ldo2 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "avcc"; +}; + +®_usb1_vbus { + status = "okay"; +}; + +®_usb2_vbus { + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins_a>; + status = "okay"; +}; + +&usbphy { + usb1_vbus-supply = <®_usb1_vbus>; + usb2_vbus-supply = <®_usb2_vbus>; + status = "okay"; +}; diff --git a/arch/arm/boot/dts/uniphier-common32.dtsi b/arch/arm/boot/dts/uniphier-common32.dtsi index ea9301aaa461b032a5431478c4638cdff5622852..61a0955982064eb8a5d216d1434ace0835631518 100644 --- a/arch/arm/boot/dts/uniphier-common32.dtsi +++ b/arch/arm/boot/dts/uniphier-common32.dtsi @@ -45,6 +45,13 @@ /include/ "skeleton.dtsi" / { + clocks { + refclk: ref { + #clock-cells = <0>; + compatible = "fixed-clock"; + }; + }; + soc: soc { compatible = "simple-bus"; #address-cells = <1>; @@ -52,12 +59,6 @@ ranges; interrupt-parent = <&intc>; - extbus: extbus { - compatible = "simple-bus"; - #address-cells = <2>; - #size-cells = <1>; - }; - serial0: serial@54006800 { compatible = "socionext,uniphier-uart"; status = "disabled"; @@ -98,9 +99,17 @@ clocks = <&uart_clk>; }; - system-bus-controller@58c00000 { - compatible = "socionext,uniphier-system-bus-controller"; - reg = <0x58c00000 0x400>, <0x59800000 0x2000>; + system_bus: system-bus@58c00000 { + compatible = "socionext,uniphier-system-bus"; + status = "disabled"; + reg = <0x58c00000 0x400>; + #address-cells = <2>; + #size-cells = <1>; + }; + + smpctrl@59800000 { + compatible = "socionext,uniphier-smpctrl"; + reg = <0x59801000 0x400>; }; timer@60000200 { diff --git a/arch/arm/boot/dts/uniphier-ph1-ld4-ref.dts b/arch/arm/boot/dts/uniphier-ph1-ld4-ref.dts index f1e9d40149ab89026e9e1035248add10b03a1e2a..ec94b7a661f2a33eca20e08ea9783971c3a7440d 100644 --- a/arch/arm/boot/dts/uniphier-ph1-ld4-ref.dts +++ b/arch/arm/boot/dts/uniphier-ph1-ld4-ref.dts @@ -72,14 +72,6 @@ }; }; -&extbus { - ranges = <1 0x00000000 0x42000000 0x02000000>; -}; - -&support_card { - ranges = <0x00000000 1 0x01f00000 0x00100000>; -}; - ðsc { interrupts = <0 49 4>; }; diff --git a/arch/arm/boot/dts/uniphier-ph1-ld4.dtsi b/arch/arm/boot/dts/uniphier-ph1-ld4.dtsi index 34f0d8dcd81470a2d60b4809a89598ac050f896e..dadd86070c98367c6bbe7c5d7892ef890f3fdb5d 100644 --- a/arch/arm/boot/dts/uniphier-ph1-ld4.dtsi +++ b/arch/arm/boot/dts/uniphier-ph1-ld4.dtsi @@ -173,6 +173,10 @@ }; +&refclk { + clock-frequency = <24576000>; +}; + &serial3 { interrupts = <0 29 4>; }; diff --git a/arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts b/arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts index 5baa9fc9c8886492b70a63e7b32e0e05b9dd4611..b8134c6e094b1ad147490a11cdace67bad793325 100644 --- a/arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts +++ b/arch/arm/boot/dts/uniphier-ph1-ld6b-ref.dts @@ -74,14 +74,6 @@ }; }; -&extbus { - ranges = <1 0x00000000 0x42000000 0x02000000>; -}; - -&support_card { - ranges = <0x00000000 1 0x01f00000 0x00100000>; -}; - ðsc { interrupts = <0 52 4>; }; diff --git a/arch/arm/boot/dts/uniphier-ph1-pro4-ace.dts b/arch/arm/boot/dts/uniphier-ph1-pro4-ace.dts new file mode 100644 index 0000000000000000000000000000000000000000..d34358632bec18ab0d3f387f023cccecf39453cf --- /dev/null +++ b/arch/arm/boot/dts/uniphier-ph1-pro4-ace.dts @@ -0,0 +1,113 @@ +/* + * Device Tree Source for UniPhier PH1-Pro4 Ace Board + * + * Copyright (C) 2016 Masahiro Yamada + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +/include/ "uniphier-ph1-pro4.dtsi" + +/ { + model = "UniPhier PH1-Pro4 Ace Board"; + compatible = "socionext,ph1-pro4-ace", "socionext,ph1-pro4"; + + memory { + device_type = "memory"; + reg = <0x80000000 0x40000000>; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + aliases { + serial0 = &serial0; + serial1 = &serial1; + serial2 = &serial2; + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; + i2c5 = &i2c5; + i2c6 = &i2c6; + }; +}; + +&serial0 { + status = "okay"; +}; + +&serial1 { + status = "okay"; +}; + +&serial2 { + status = "okay"; +}; + +&i2c0 { + status = "okay"; + + eeprom@54 { + compatible = "st,24c64"; + reg = <0x54>; + }; +}; + +&i2c1 { + status = "okay"; +}; + +&i2c2 { + status = "okay"; +}; + +&i2c3 { + status = "okay"; +}; + +&usb2 { + status = "okay"; +}; + +&usb3 { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/uniphier-ph1-pro4-ref.dts b/arch/arm/boot/dts/uniphier-ph1-pro4-ref.dts index 24626687d4df5bce1b93ba18fcef2668ec520f14..95f631a3de3558040817c7294d07f616fce99faf 100644 --- a/arch/arm/boot/dts/uniphier-ph1-pro4-ref.dts +++ b/arch/arm/boot/dts/uniphier-ph1-pro4-ref.dts @@ -74,14 +74,6 @@ }; }; -&extbus { - ranges = <1 0x00000000 0x42000000 0x02000000>; -}; - -&support_card { - ranges = <0x00000000 1 0x01f00000 0x00100000>; -}; - ðsc { interrupts = <0 50 4>; }; diff --git a/arch/arm/boot/dts/uniphier-ph1-pro4-sanji.dts b/arch/arm/boot/dts/uniphier-ph1-pro4-sanji.dts new file mode 100644 index 0000000000000000000000000000000000000000..7c3a1fcc9f3cca1051085ec563a6b6f1a73b1d72 --- /dev/null +++ b/arch/arm/boot/dts/uniphier-ph1-pro4-sanji.dts @@ -0,0 +1,108 @@ +/* + * Device Tree Source for UniPhier PH1-Pro4 Sanji Board + * + * Copyright (C) 2016 Masahiro Yamada + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +/include/ "uniphier-ph1-pro4.dtsi" + +/ { + model = "UniPhier PH1-Pro4 Sanji Board"; + compatible = "socionext,ph1-pro4-sanji", "socionext,ph1-pro4"; + + memory { + device_type = "memory"; + reg = <0x80000000 0x80000000>; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + aliases { + serial0 = &serial0; + serial1 = &serial1; + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; + i2c5 = &i2c5; + i2c6 = &i2c6; + }; +}; + +&serial0 { + status = "okay"; +}; + +&serial1 { + status = "okay"; +}; + +&i2c0 { + status = "okay"; + + eeprom@54 { + compatible = "st,24c64"; + reg = <0x54>; + }; +}; + +&i2c1 { + status = "okay"; +}; + +&i2c2 { + status = "okay"; +}; + +&i2c3 { + status = "okay"; +}; + +&usb2 { + status = "okay"; +}; + +&usb3 { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/uniphier-ph1-pro4.dtsi b/arch/arm/boot/dts/uniphier-ph1-pro4.dtsi index d78142fb35c42f847024fcc6ba66dbdffe87166a..20f3f2ae7fa419b542c2a51593d7dc5a399fc547 100644 --- a/arch/arm/boot/dts/uniphier-ph1-pro4.dtsi +++ b/arch/arm/boot/dts/uniphier-ph1-pro4.dtsi @@ -195,6 +195,10 @@ }; }; +&refclk { + clock-frequency = <25000000>; +}; + &pinctrl { compatible = "socionext,ph1-pro4-pinctrl", "syscon"; }; diff --git a/arch/arm/boot/dts/uniphier-ph1-pro5.dtsi b/arch/arm/boot/dts/uniphier-ph1-pro5.dtsi index 2f389ea75e0150b9a5127394027b277b8c99bf7d..24f6f664b2692b64acf6a19fe3d327233a759832 100644 --- a/arch/arm/boot/dts/uniphier-ph1-pro5.dtsi +++ b/arch/arm/boot/dts/uniphier-ph1-pro5.dtsi @@ -189,6 +189,10 @@ }; }; +&refclk { + clock-frequency = <20000000>; +}; + &pinctrl { compatible = "socionext,ph1-pro5-pinctrl", "syscon"; }; diff --git a/arch/arm/boot/dts/uniphier-ph1-sld3-ref.dts b/arch/arm/boot/dts/uniphier-ph1-sld3-ref.dts index b7a032156789f1d9b4b28a3d28931906a1c7c361..acb420492b36feb771e8819c9a39dbfa794ff182 100644 --- a/arch/arm/boot/dts/uniphier-ph1-sld3-ref.dts +++ b/arch/arm/boot/dts/uniphier-ph1-sld3-ref.dts @@ -73,14 +73,6 @@ }; }; -&extbus { - ranges = <1 0x00000000 0x42000000 0x02000000>; -}; - -&support_card { - ranges = <0x00000000 1 0x01f00000 0x00100000>; -}; - ðsc { interrupts = <0 49 4>; }; diff --git a/arch/arm/boot/dts/uniphier-ph1-sld3.dtsi b/arch/arm/boot/dts/uniphier-ph1-sld3.dtsi index 691a17d765c2591a7f34edcf479373daeaa6224c..03292f443305eb287826cc1ce202e0bcba224bc0 100644 --- a/arch/arm/boot/dts/uniphier-ph1-sld3.dtsi +++ b/arch/arm/boot/dts/uniphier-ph1-sld3.dtsi @@ -68,6 +68,12 @@ }; clocks { + refclk: ref { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <24576000>; + }; + arm_timer_clk: arm_timer_clk { #clock-cells = <0>; compatible = "fixed-clock"; @@ -94,12 +100,6 @@ ranges; interrupt-parent = <&intc>; - extbus: extbus { - compatible = "simple-bus"; - #address-cells = <2>; - #size-cells = <1>; - }; - timer@20000200 { compatible = "arm,cortex-a9-global-timer"; reg = <0x20000200 0x20>; @@ -216,9 +216,17 @@ clock-frequency = <400000>; }; - system-bus-controller@58c00000 { - compatible = "socionext,uniphier-system-bus-controller"; - reg = <0x58c00000 0x400>, <0x59800000 0x2000>; + system_bus: system-bus@58c00000 { + compatible = "socionext,uniphier-system-bus"; + status = "disabled"; + reg = <0x58c00000 0x400>; + #address-cells = <2>; + #size-cells = <1>; + }; + + smpctrl@59800000 { + compatible = "socionext,uniphier-smpctrl"; + reg = <0x59801000 0x400>; }; usb0: usb@5a800100 { diff --git a/arch/arm/boot/dts/uniphier-ph1-sld8-ref.dts b/arch/arm/boot/dts/uniphier-ph1-sld8-ref.dts index fc7250c61674f0e0b8a4ab0b393801790dc8c00a..d594f40e7f7626765a263c548b841b57ca213123 100644 --- a/arch/arm/boot/dts/uniphier-ph1-sld8-ref.dts +++ b/arch/arm/boot/dts/uniphier-ph1-sld8-ref.dts @@ -72,14 +72,6 @@ }; }; -&extbus { - ranges = <1 0x00000000 0x42000000 0x02000000>; -}; - -&support_card { - ranges = <0x00000000 1 0x01f00000 0x00100000>; -}; - ðsc { interrupts = <0 48 4>; }; diff --git a/arch/arm/boot/dts/uniphier-ph1-sld8.dtsi b/arch/arm/boot/dts/uniphier-ph1-sld8.dtsi index 7d06a1c487d8c8fa059983e4c97c605d15254ef4..6bfd29a05575909bb0e44f5ddcd295a054cd4032 100644 --- a/arch/arm/boot/dts/uniphier-ph1-sld8.dtsi +++ b/arch/arm/boot/dts/uniphier-ph1-sld8.dtsi @@ -172,6 +172,10 @@ }; }; +&refclk { + clock-frequency = <25000000>; +}; + &serial3 { interrupts = <0 29 4>; }; diff --git a/arch/arm/boot/dts/uniphier-pinctrl.dtsi b/arch/arm/boot/dts/uniphier-pinctrl.dtsi index f67445f4f10da20358ae5183b0c84a7b955df038..24592798a3688f0093009bd411fd486d342cfe64 100644 --- a/arch/arm/boot/dts/uniphier-pinctrl.dtsi +++ b/arch/arm/boot/dts/uniphier-pinctrl.dtsi @@ -63,6 +63,11 @@ function = "i2c3"; }; + pinctrl_i2c4: i2c4_grp { + groups = "i2c4"; + function = "i2c4"; + }; + pinctrl_uart0: uart0_grp { groups = "uart0"; function = "uart0"; diff --git a/arch/arm/boot/dts/uniphier-proxstream2-gentil.dts b/arch/arm/boot/dts/uniphier-proxstream2-gentil.dts index 9d7ec5c204dd7d747e6065834a7d090a5ef91d11..bf2619e4d4892063b9e97e33345a23aa8ddb76e4 100644 --- a/arch/arm/boot/dts/uniphier-proxstream2-gentil.dts +++ b/arch/arm/boot/dts/uniphier-proxstream2-gentil.dts @@ -63,6 +63,7 @@ serial1 = &serial1; serial2 = &serial2; i2c0 = &i2c0; + i2c2 = &i2c2; i2c4 = &i2c4; i2c5 = &i2c5; i2c6 = &i2c6; @@ -75,4 +76,13 @@ &i2c0 { status = "okay"; + + eeprom@54 { + compatible = "st,24c64"; + reg = <0x54>; + }; +}; + +&i2c2 { + status = "okay"; }; diff --git a/arch/arm/boot/dts/uniphier-proxstream2.dtsi b/arch/arm/boot/dts/uniphier-proxstream2.dtsi index 6bd353f2d77efceaeb1dd38a9991072190092f8d..4ac484c6ce4eb8208b6893b8f9bb408da7a7cdaf 100644 --- a/arch/arm/boot/dts/uniphier-proxstream2.dtsi +++ b/arch/arm/boot/dts/uniphier-proxstream2.dtsi @@ -200,6 +200,10 @@ }; }; +&refclk { + clock-frequency = <25000000>; +}; + &pinctrl { compatible = "socionext,proxstream2-pinctrl", "syscon"; }; diff --git a/arch/arm/boot/dts/uniphier-ref-daughter.dtsi b/arch/arm/boot/dts/uniphier-ref-daughter.dtsi index 3d29d2806cc0c9e9dd7d1c5d8215abafd7a9fe7e..f7df0881c5e00e32651e965118b73c7ed44d4c84 100644 --- a/arch/arm/boot/dts/uniphier-ref-daughter.dtsi +++ b/arch/arm/boot/dts/uniphier-ref-daughter.dtsi @@ -43,7 +43,7 @@ */ &i2c0 { - eeprom { + eeprom@50 { compatible = "microchip,24lc128"; reg = <0x50>; }; diff --git a/arch/arm/boot/dts/uniphier-support-card.dtsi b/arch/arm/boot/dts/uniphier-support-card.dtsi index da271e3b922ab1f0b9d688683a09233e006fae5b..51ecc9b9c0ceb6072c37173d4b9606645016344e 100644 --- a/arch/arm/boot/dts/uniphier-support-card.dtsi +++ b/arch/arm/boot/dts/uniphier-support-card.dtsi @@ -42,11 +42,15 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -&extbus { +&system_bus { + status = "okay"; + ranges = <1 0x00000000 0x42000000 0x02000000>; + support_card: support_card { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; + ranges = <0x00000000 1 0x01f00000 0x00100000>; ethsc: ethernet@00000000 { compatible = "smsc,lan9118", "smsc,lan9115"; diff --git a/arch/arm/boot/dts/versatile-ab.dts b/arch/arm/boot/dts/versatile-ab.dts index 6fd7efbead3440f339a71a1ec596253da16031ab..d23320af5ea79772fcb4f9c69cb0b6682ecddf1f 100644 --- a/arch/arm/boot/dts/versatile-ab.dts +++ b/arch/arm/boot/dts/versatile-ab.dts @@ -148,7 +148,7 @@ }; amba { - compatible = "arm,amba-bus"; + compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges; diff --git a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi index 21b02874bea3c89fb873a5be56dc5ead6d65d5db..7a556b92e55c0f1505a994a816877eccd678c16e 100644 --- a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi +++ b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi @@ -66,7 +66,7 @@ }; iofpga@3,00000000 { - compatible = "arm,amba-bus", "simple-bus"; + compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges = <0 3 0 0x200000>; diff --git a/arch/arm/boot/dts/vexpress-v2m.dtsi b/arch/arm/boot/dts/vexpress-v2m.dtsi index e712c0af149b9b8ddf1ed2323b89b3752bc89f63..47e4a115adef48a184ca6970bbe415949ee03fc2 100644 --- a/arch/arm/boot/dts/vexpress-v2m.dtsi +++ b/arch/arm/boot/dts/vexpress-v2m.dtsi @@ -65,7 +65,7 @@ }; iofpga@7,00000000 { - compatible = "arm,amba-bus", "simple-bus"; + compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges = <0 7 0 0x20000>; diff --git a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi index ed65e0f7dfc0ac96057325c8c7a2582789accb67..4d8b7f69353551b1c065d4a27d5609bf6266fff3 100644 --- a/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi +++ b/arch/arm/boot/dts/vf-colibri-eval-v3.dtsi @@ -1,10 +1,42 @@ /* * Copyright 2014 Toradex AG * - * 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 file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. */ / { @@ -18,38 +50,36 @@ clock-frequency = <16000000>; }; - regulators { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <0>; - - sys_5v0_reg: regulator@0 { - compatible = "regulator-fixed"; - reg = <0>; - regulator-name = "5v0"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - regulator-always-on; - }; + reg_3v3: regulator-3v3 { + compatible = "regulator-fixed"; + regulator-name = "3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; - /* USBH_PEN */ - usbh_vbus_reg: regulator@1 { - compatible = "regulator-fixed"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usbh1_reg>; - reg = <1>; - regulator-name = "usbh_vbus"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - gpio = <&gpio2 19 GPIO_ACTIVE_LOW>; - vin-supply = <&sys_5v0_reg>; - }; + reg_5v0: regulator-5v0 { + compatible = "regulator-fixed"; + regulator-name = "5V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + reg_usbh_vbus: regulator-usbh-vbus { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbh1_reg>; + regulator-name = "VCC_USB[1-4]"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio2 19 GPIO_ACTIVE_LOW>; /* USBH_PEN resp. USBH_P_EN */ + vin-supply = <®_5v0>; }; }; &bl { brightness-levels = <0 4 8 16 32 64 128 255>; default-brightness-level = <6>; + power-supply = <®_3v3>; status = "okay"; }; @@ -100,6 +130,10 @@ status = "okay"; }; +®_module_3v3 { + vin-supply = <®_3v3>; +}; + &uart0 { status = "okay"; }; @@ -113,7 +147,7 @@ }; &usbh1 { - vbus-supply = <&usbh_vbus_reg>; + vbus-supply = <®_usbh_vbus>; }; &iomuxc { diff --git a/arch/arm/boot/dts/vf-colibri.dtsi b/arch/arm/boot/dts/vf-colibri.dtsi index 6e556be42ccdca53e1b109d8c664bb43dbfa0635..fda7f28101e1ca547acf8c765b6e7341842fb2e1 100644 --- a/arch/arm/boot/dts/vf-colibri.dtsi +++ b/arch/arm/boot/dts/vf-colibri.dtsi @@ -1,26 +1,77 @@ /* * Copyright 2014 Toradex AG * - * 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 file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. */ / { bl: backlight { compatible = "pwm-backlight"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_bl_on>; pwms = <&pwm0 0 5000000 0>; + enable-gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>; status = "disabled"; }; + + reg_module_3v3: regulator-module-3v3 { + compatible = "regulator-fixed"; + regulator-name = "+V3.3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + reg_module_3v3_avdd: regulator-module-3v3-avdd { + compatible = "regulator-fixed"; + regulator-name = "+V3.3_AVDD_AUDIO"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; }; &adc0 { status = "okay"; + vref-supply = <®_module_3v3_avdd>; }; &adc1 { status = "okay"; + vref-supply = <®_module_3v3_avdd>; }; &can0 { @@ -35,6 +86,13 @@ status = "disabled"; }; +&clks { + assigned-clocks = <&clks VF610_CLK_ENET_SEL>, + <&clks VF610_CLK_ENET_TS_SEL>; + assigned-clock-parents = <&clks VF610_CLK_ENET_50M>, + <&clks VF610_CLK_ENET_50M>; +}; + &dspi1 { bus-num = <1>; pinctrl-names = "default"; @@ -50,10 +108,12 @@ pinctrl-0 = <&pinctrl_esdhc1>; bus-width = <4>; cd-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>; + disable-wp; }; &fec1 { phy-mode = "rmii"; + phy-supply = <®_module_3v3>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_fec1>; }; @@ -195,6 +255,12 @@ >; }; + pinctrl_gpio_bl_on: gpio_bl_on { + fsl,pins = < + VF610_PAD_PTC0__GPIO_45 0x22ef + >; + }; + pinctrl_i2c0: i2c0grp { fsl,pins = < VF610_PAD_PTB14__I2C0_SCL 0x37ff @@ -239,6 +305,8 @@ fsl,pins = < VF610_PAD_PTB10__UART0_TX 0x21a2 VF610_PAD_PTB11__UART0_RX 0x21a1 + VF610_PAD_PTB12__UART0_RTS 0x21a2 + VF610_PAD_PTB13__UART0_CTS 0x21a1 >; }; diff --git a/arch/arm/boot/dts/vf500-colibri-eval-v3.dts b/arch/arm/boot/dts/vf500-colibri-eval-v3.dts index c3173fc9e8336d97af3d60570b2d5eab7c6cad7f..b3aeab58f718d282558050334430b8d2f335ff34 100644 --- a/arch/arm/boot/dts/vf500-colibri-eval-v3.dts +++ b/arch/arm/boot/dts/vf500-colibri-eval-v3.dts @@ -1,10 +1,42 @@ /* * Copyright 2014 Toradex AG * - * 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 file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. */ /dts-v1/; diff --git a/arch/arm/boot/dts/vf500-colibri.dtsi b/arch/arm/boot/dts/vf500-colibri.dtsi index 84f091d1fcf29bb3c24ce7c8f9e8c9163f1169c1..3fe1f48c2aecd05693ef2e9a56ba623b7b6bd529 100644 --- a/arch/arm/boot/dts/vf500-colibri.dtsi +++ b/arch/arm/boot/dts/vf500-colibri.dtsi @@ -1,10 +1,42 @@ /* * Copyright 2014 Toradex AG * - * 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 file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. */ #include "vf500.dtsi" diff --git a/arch/arm/boot/dts/vf500.dtsi b/arch/arm/boot/dts/vf500.dtsi index e976d2fa15274239b9ed2b0568cb9bd9ba9b2aa6..9d372720ad3f9c73e5a00a8ec885922a63caa3f3 100644 --- a/arch/arm/boot/dts/vf500.dtsi +++ b/arch/arm/boot/dts/vf500.dtsi @@ -1,10 +1,42 @@ /* * Copyright 2013 Freescale Semiconductor, Inc. * - * 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 file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. */ #include "skeleton.dtsi" @@ -43,6 +75,15 @@ clocks = <&clks VF610_CLK_PLATFORM_BUS>; }; }; + + aips-bus@40080000 { + pmu@40089000 { + compatible = "arm,cortex-a5-pmu"; + interrupts = <7 IRQ_TYPE_LEVEL_HIGH>; + interrupt-affinity = <&a5_cpu>; + }; + }; + }; }; diff --git a/arch/arm/boot/dts/vf610-colibri-eval-v3.dts b/arch/arm/boot/dts/vf610-colibri-eval-v3.dts index 10ebe99e2751ee404ff7c4aed3a48b30e66c6c2b..dbca4f86fdbb93bd2a9fabe0c5b090535f4369cc 100644 --- a/arch/arm/boot/dts/vf610-colibri-eval-v3.dts +++ b/arch/arm/boot/dts/vf610-colibri-eval-v3.dts @@ -1,10 +1,42 @@ /* * Copyright 2014 Toradex AG * - * 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 file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. */ /dts-v1/; @@ -14,4 +46,4 @@ / { model = "Toradex Colibri VF61 on Colibri Evaluation Board"; compatible = "toradex,vf610-colibri_vf61-on-eval", "toradex,vf610-colibri_vf61", "fsl,vf610"; -}; \ No newline at end of file +}; diff --git a/arch/arm/boot/dts/vf610-colibri.dtsi b/arch/arm/boot/dts/vf610-colibri.dtsi index 2d7eab7552100225efcf2cb5d52a5443459f6a58..ab4a29f95593d0053e18a8322e2f4c9ff316334c 100644 --- a/arch/arm/boot/dts/vf610-colibri.dtsi +++ b/arch/arm/boot/dts/vf610-colibri.dtsi @@ -1,10 +1,42 @@ /* * Copyright 2014 Toradex AG * - * 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 file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. */ #include "vf610.dtsi" diff --git a/arch/arm/boot/dts/vf610-twr.dts b/arch/arm/boot/dts/vf610-twr.dts index 5438ee4be2ecf6278ac35cbf097a225b38a8a3ec..cdc1007325144195567fad08df9153ca21f2349c 100644 --- a/arch/arm/boot/dts/vf610-twr.dts +++ b/arch/arm/boot/dts/vf610-twr.dts @@ -1,10 +1,42 @@ /* * Copyright 2013 Freescale Semiconductor, Inc. * - * 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 file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. */ /dts-v1/; @@ -96,6 +128,10 @@ &clks { clocks = <&sxosc>, <&fxosc>, <&enet_ext>, <&audio_ext>; clock-names = "sxosc", "fxosc", "enet_ext", "audio_ext"; + assigned-clocks = <&clks VF610_CLK_ENET_SEL>, + <&clks VF610_CLK_ENET_TS_SEL>; + assigned-clock-parents = <&clks VF610_CLK_ENET_EXT>, + <&clks VF610_CLK_ENET_EXT>; }; &dspi0 { diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi index 58bc6e448be5601ed8d04106fbcc193793f040f1..0cfc060f94d7da2c6a1f8bc453a700e7255b5c4a 100644 --- a/arch/arm/boot/dts/vf610.dtsi +++ b/arch/arm/boot/dts/vf610.dtsi @@ -1,10 +1,42 @@ /* * Copyright 2013 Freescale Semiconductor, Inc. * - * 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 file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. */ #include "vf500.dtsi" diff --git a/arch/arm/boot/dts/vfxxx.dtsi b/arch/arm/boot/dts/vfxxx.dtsi index 4539f8d909a532121771c2259598d596c1e1971e..5c0975451d4ef48be18e183f983435d773444f2e 100644 --- a/arch/arm/boot/dts/vfxxx.dtsi +++ b/arch/arm/boot/dts/vfxxx.dtsi @@ -1,10 +1,42 @@ /* * Copyright 2013 Freescale Semiconductor, Inc. * - * 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 file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. */ #include "vf610-pinfunc.h" @@ -16,6 +48,8 @@ aliases { can0 = &can0; can1 = &can1; + ethernet0 = &fec0; + ethernet1 = &fec1; serial0 = &uart0; serial1 = &uart1; serial2 = &uart2; @@ -174,6 +208,34 @@ status = "disabled"; }; + sai0: sai@4002f000 { + compatible = "fsl,vf610-sai"; + reg = <0x4002f000 0x1000>; + interrupts = <84 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clks VF610_CLK_SAI0>, + <&clks VF610_CLK_SAI0_DIV>, + <&clks 0>, <&clks 0>; + clock-names = "bus", "mclk1", "mclk2", "mclk3"; + dma-names = "tx", "rx"; + dmas = <&edma0 0 17>, + <&edma0 0 16>; + status = "disabled"; + }; + + sai1: sai@40030000 { + compatible = "fsl,vf610-sai"; + reg = <0x40030000 0x1000>; + interrupts = <85 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clks VF610_CLK_SAI1>, + <&clks VF610_CLK_SAI1_DIV>, + <&clks 0>, <&clks 0>; + clock-names = "bus", "mclk1", "mclk2", "mclk3"; + dma-names = "tx", "rx"; + dmas = <&edma0 0 19>, + <&edma0 0 18>; + status = "disabled"; + }; + sai2: sai@40031000 { compatible = "fsl,vf610-sai"; reg = <0x40031000 0x1000>; @@ -188,6 +250,20 @@ status = "disabled"; }; + sai3: sai@40032000 { + compatible = "fsl,vf610-sai"; + reg = <0x40032000 0x1000>; + interrupts = <87 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clks VF610_CLK_SAI3>, + <&clks VF610_CLK_SAI3_DIV>, + <&clks 0>, <&clks 0>; + clock-names = "bus", "mclk1", "mclk2", "mclk3"; + dma-names = "tx", "rx"; + dmas = <&edma0 1 9>, + <&edma0 1 8>; + status = "disabled"; + }; + pit: pit@40037000 { compatible = "fsl,vf610-pit"; reg = <0x40037000 0x1000>; @@ -558,6 +634,24 @@ status = "disabled"; }; + dac0: dac@400cc000 { + compatible = "fsl,vf610-dac"; + reg = <0x400cc000 1000>; + interrupts = <55 IRQ_TYPE_LEVEL_HIGH>; + clock-names = "dac"; + clocks = <&clks VF610_CLK_DAC0>; + status = "disabled"; + }; + + dac1: dac@400cd000 { + compatible = "fsl,vf610-dac"; + reg = <0x400cd000 1000>; + interrupts = <56 IRQ_TYPE_LEVEL_HIGH>; + clock-names = "dac"; + clocks = <&clks VF610_CLK_DAC1>; + status = "disabled"; + }; + fec0: ethernet@400d0000 { compatible = "fsl,mvf600-fec"; reg = <0x400d0000 0x1000>; diff --git a/arch/arm/boot/dts/zynq-parallella.dts b/arch/arm/boot/dts/zynq-parallella.dts index 9efd16cb2859dbb25a40851516dc377a540e8edd..307ed201d6589607c1bd3ccd82f5a1f8fc390fb4 100644 --- a/arch/arm/boot/dts/zynq-parallella.dts +++ b/arch/arm/boot/dts/zynq-parallella.dts @@ -34,7 +34,7 @@ }; chosen { - bootargs = "earlyprintk root=/dev/mmcblk0p2 rootfstype=ext4 rw rootwait"; + bootargs = "earlycon root=/dev/mmcblk0p2 rootfstype=ext4 rw rootwait"; stdout-path = "serial0:115200n8"; }; }; diff --git a/arch/arm/boot/dts/zynq-zc702.dts b/arch/arm/boot/dts/zynq-zc702.dts index cb64209bca08cbb05b506a45a7b3e45b58a09142..e96959b2e67ada5c53bad2f49122556fb8f32c12 100644 --- a/arch/arm/boot/dts/zynq-zc702.dts +++ b/arch/arm/boot/dts/zynq-zc702.dts @@ -30,7 +30,7 @@ }; chosen { - bootargs = "earlyprintk"; + bootargs = "earlycon"; stdout-path = "serial0:115200n8"; }; diff --git a/arch/arm/boot/dts/zynq-zc706.dts b/arch/arm/boot/dts/zynq-zc706.dts index abf5d238ae04aa6224d5da7e0d83f67f640ec6df..be6a986bbbd80a643d612e1fad55c997194089a3 100644 --- a/arch/arm/boot/dts/zynq-zc706.dts +++ b/arch/arm/boot/dts/zynq-zc706.dts @@ -30,7 +30,7 @@ }; chosen { - bootargs = "earlyprintk"; + bootargs = "earlycon"; stdout-path = "serial0:115200n8"; }; diff --git a/arch/arm/boot/dts/zynq-zed.dts b/arch/arm/boot/dts/zynq-zed.dts index b9f2522012e8ce180b445f0d31929f32baf9be0a..7250c1eac7f9d38ec811633a41533131a2daae0f 100644 --- a/arch/arm/boot/dts/zynq-zed.dts +++ b/arch/arm/boot/dts/zynq-zed.dts @@ -29,7 +29,7 @@ }; chosen { - bootargs = "earlyprintk"; + bootargs = "earlycon"; stdout-path = "serial0:115200n8"; }; diff --git a/arch/arm/boot/dts/zynq-zybo.dts b/arch/arm/boot/dts/zynq-zybo.dts index 16c9cacd668d4af08660cc0679e1314ca6a54086..d9e0f3e7067113b771fa9c2bb1bdd2d0dbd50610 100644 --- a/arch/arm/boot/dts/zynq-zybo.dts +++ b/arch/arm/boot/dts/zynq-zybo.dts @@ -29,10 +29,15 @@ }; chosen { - bootargs = "earlyprintk"; + bootargs = "earlycon"; stdout-path = "serial0:115200n8"; }; + usb_phy0: phy0 { + #phy-cells = <0>; + compatible = "usb-nop-xceiv"; + reset-gpios = <&gpio0 46 1>; + }; }; &clkc { @@ -56,3 +61,9 @@ &uart1 { status = "okay"; }; + +&usb0 { + status = "okay"; + dr_mode = "host"; + usb-phy = <&usb_phy0>; +}; diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index 3d224941b5419e88a25aae2ae70632dba047606c..fb0a0a4dfea4da26fd635ccbad4a06de0a72ce94 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -1290,7 +1290,7 @@ static int sa1111_match(struct device *_dev, struct device_driver *_drv) struct sa1111_dev *dev = SA1111_DEV(_dev); struct sa1111_driver *drv = SA1111_DRV(_drv); - return dev->devid & drv->devid; + return !!(dev->devid & drv->devid); } static int sa1111_bus_suspend(struct device *dev, pm_message_t state) diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig index 72def201c4fd57d8aeac4c1c8454876ab4d21a82..1ef69fcbdf2e2366308da3ab1e455c7780cfd031 100644 --- a/arch/arm/configs/bcm2835_defconfig +++ b/arch/arm/configs/bcm2835_defconfig @@ -6,13 +6,13 @@ CONFIG_HIGH_RES_TIMERS=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_LOG_BUF_SHIFT=18 +CONFIG_CFS_BANDWIDTH=y +CONFIG_RT_GROUP_SCHED=y CONFIG_CGROUP_FREEZER=y -CONFIG_CGROUP_DEVICE=y CONFIG_CPUSETS=y +CONFIG_CGROUP_DEVICE=y CONFIG_CGROUP_CPUACCT=y CONFIG_CGROUP_PERF=y -CONFIG_CFS_BANDWIDTH=y -CONFIG_RT_GROUP_SCHED=y CONFIG_NAMESPACES=y CONFIG_SCHED_AUTOGROUP=y CONFIG_RELAY=y @@ -26,7 +26,6 @@ CONFIG_OPROFILE=y CONFIG_JUMP_LABEL=y CONFIG_CC_STACKPROTECTOR_REGULAR=y CONFIG_ARCH_MULTI_V6=y -# CONFIG_ARCH_MULTI_V7 is not set CONFIG_ARCH_BCM=y CONFIG_ARCH_BCM2835=y CONFIG_PREEMPT_VOLUNTARY=y @@ -107,8 +106,10 @@ CONFIG_STAGING=y CONFIG_MAILBOX=y CONFIG_BCM2835_MBOX=y # CONFIG_IOMMU_SUPPORT is not set +CONFIG_RASPBERRYPI_POWER=y CONFIG_PWM=y CONFIG_PWM_BCM2835=y +CONFIG_RASPBERRYPI_FIRMWARE=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y @@ -142,7 +143,5 @@ CONFIG_TEST_KSTRTOX=y CONFIG_KGDB=y CONFIG_KGDB_KDB=y CONFIG_STRICT_DEVMEM=y -CONFIG_DEBUG_LL=y -CONFIG_EARLY_PRINTK=y # CONFIG_XZ_DEC_ARM is not set # CONFIG_XZ_DEC_ARMTHUMB is not set diff --git a/arch/arm/configs/dram_0x00000000.config b/arch/arm/configs/dram_0x00000000.config new file mode 100644 index 0000000000000000000000000000000000000000..db96dcb420cebec5b5f4594e78506177bc3d3af3 --- /dev/null +++ b/arch/arm/configs/dram_0x00000000.config @@ -0,0 +1 @@ +CONFIG_DRAM_BASE=0x00000000 diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig index 24dcd2bb1215dd9b600fdeea5e59e5077a1de8b4..6ffd7e76f3ce0d96fc72b635d2615d4e38eaaf87 100644 --- a/arch/arm/configs/exynos_defconfig +++ b/arch/arm/configs/exynos_defconfig @@ -26,12 +26,14 @@ CONFIG_ARM_APPENDED_DTB=y CONFIG_ARM_ATAG_DTB_COMPAT=y CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc mem=256M" CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_STAT_DETAILS=y CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y CONFIG_CPUFREQ_DT=y CONFIG_CPU_IDLE=y CONFIG_ARM_EXYNOS_CPUIDLE=y CONFIG_VFP=y CONFIG_NEON=y +CONFIG_KERNEL_MODE_NEON=y CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y @@ -193,7 +195,6 @@ CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_MAX8997=y CONFIG_RTC_DRV_MAX77686=y -CONFIG_RTC_DRV_MAX77802=y CONFIG_RTC_DRV_S5M=y CONFIG_RTC_DRV_S3C=y CONFIG_DMADEVICES=y @@ -238,7 +239,12 @@ CONFIG_DEBUG_RT_MUTEXES=y CONFIG_DEBUG_SPINLOCK=y CONFIG_DEBUG_MUTEXES=y CONFIG_DEBUG_USER=y -CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_DEV_S5P=y +CONFIG_ARM_CRYPTO=y +CONFIG_CRYPTO_SHA1_ARM_NEON=m +CONFIG_CRYPTO_SHA256_ARM=m +CONFIG_CRYPTO_SHA512_ARM=m +CONFIG_CRYPTO_AES_ARM_BS=m CONFIG_CRC_CCITT=y CONFIG_FONTS=y CONFIG_FONT_7x14=y diff --git a/arch/arm/configs/imx_v4_v5_defconfig b/arch/arm/configs/imx_v4_v5_defconfig index d3a8018639de22d20e71e5de73a35bb1ab30309a..9083399a8ab155a297ca97abbd7a321da60fb03e 100644 --- a/arch/arm/configs/imx_v4_v5_defconfig +++ b/arch/arm/configs/imx_v4_v5_defconfig @@ -6,6 +6,7 @@ CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_CGROUPS=y +CONFIG_BLK_DEV_INITRD=y CONFIG_EXPERT=y # CONFIG_COMPAT_BRK is not set CONFIG_SLAB=y @@ -24,14 +25,12 @@ CONFIG_ARCH_MXC=y CONFIG_MACH_SCB9328=y CONFIG_MACH_APF9328=y CONFIG_MACH_MX21ADS=y -CONFIG_MACH_EUKREA_CPUIMX25SD=y -CONFIG_SOC_IMX25=y CONFIG_MACH_MX27ADS=y CONFIG_MACH_MX27_3DS=y CONFIG_MACH_IMX27_VISSTRIM_M10=y CONFIG_MACH_PCA100=y -CONFIG_MACH_MXT_TD60=y CONFIG_MACH_IMX27_DT=y +CONFIG_SOC_IMX25=y CONFIG_PREEMPT=y CONFIG_AEABI=y CONFIG_ZBOOT_ROM_TEXT=0x0 @@ -88,6 +87,7 @@ CONFIG_KEYBOARD_IMX=y # CONFIG_INPUT_MOUSE is not set CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_MX25=y CONFIG_TOUCHSCREEN_MC13783=y # CONFIG_LEGACY_PTYS is not set CONFIG_SERIAL_8250=m @@ -107,6 +107,7 @@ CONFIG_HWMON=m CONFIG_SENSORS_MC13783_ADC=m CONFIG_WATCHDOG=y CONFIG_IMX2_WDT=y +CONFIG_MFD_MX25_TSADC=y CONFIG_MFD_MC13XXX_SPI=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y @@ -169,11 +170,11 @@ CONFIG_RTC_DRV_IMXDI=y CONFIG_RTC_DRV_MC13XXX=y CONFIG_RTC_DRV_MXC=y CONFIG_DMADEVICES=y -CONFIG_IMX_SDMA=y CONFIG_IMX_DMA=y +CONFIG_IMX_SDMA=y # CONFIG_IOMMU_SUPPORT is not set -CONFIG_EXT2_FS=y -CONFIG_EXT3_FS=y +CONFIG_IIO=y +CONFIG_FSL_MX25_ADC=y CONFIG_EXT4_FS=y # CONFIG_DNOTIFY is not set CONFIG_VFAT_FS=y @@ -187,6 +188,5 @@ CONFIG_NLS_CODEPAGE_437=m CONFIG_NLS_CODEPAGE_850=m CONFIG_NLS_ISO8859_1=y CONFIG_NLS_ISO8859_15=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_FONTS=y CONFIG_FONT_8x8=y diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig index 2d5253dcc2266174550d709771a28fb8b4161c70..978c5deeb47c08ea78a77dfbe1c1cbdc75e1e126 100644 --- a/arch/arm/configs/imx_v6_v7_defconfig +++ b/arch/arm/configs/imx_v6_v7_defconfig @@ -47,6 +47,7 @@ CONFIG_PCI=y CONFIG_PCI_MSI=y CONFIG_PCI_IMX6=y CONFIG_SMP=y +CONFIG_ARM_PSCI=y CONFIG_PREEMPT_VOLUNTARY=y CONFIG_AEABI=y CONFIG_HIGHMEM=y @@ -56,6 +57,7 @@ CONFIG_KEXEC=y CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y CONFIG_ARM_IMX6Q_CPUFREQ=y +CONFIG_CPU_IDLE=y CONFIG_VFP=y CONFIG_NEON=y CONFIG_BINFMT_MISC=m @@ -71,7 +73,6 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set -CONFIG_IPV6=y CONFIG_NETFILTER=y CONFIG_CAN=y CONFIG_CAN_FLEXCAN=y @@ -103,10 +104,13 @@ CONFIG_MTD_M25P80=y CONFIG_MTD_SST25L=y CONFIG_MTD_NAND=y CONFIG_MTD_NAND_GPMI_NAND=y +CONFIG_MTD_NAND_VF610_NFC=y CONFIG_MTD_NAND_MXC=y CONFIG_MTD_SPI_NOR=y CONFIG_SPI_FSL_QUADSPI=y CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_FASTMAP=y +CONFIG_MTD_UBI_BLOCK=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=65536 @@ -144,7 +148,6 @@ CONFIG_USB_RTL8152=m CONFIG_USB_USBNET=m CONFIG_USB_NET_CDC_EEM=m CONFIG_BRCMFMAC=m -CONFIG_WL_TI=y CONFIG_WL12XX=m CONFIG_WLCORE_SDIO=m # CONFIG_WILINK_PLATFORM_DATA is not set @@ -163,6 +166,7 @@ CONFIG_TOUCHSCREEN_MC13783=y CONFIG_TOUCHSCREEN_TSC2007=y CONFIG_TOUCHSCREEN_STMPE=y CONFIG_TOUCHSCREEN_SX8654=y +CONFIG_TOUCHSCREEN_COLIBRI_VF50=y CONFIG_INPUT_MISC=y CONFIG_INPUT_MMA8450=y CONFIG_SERIO_SERPORT=m @@ -172,7 +176,6 @@ CONFIG_SERIAL_IMX=y CONFIG_SERIAL_IMX_CONSOLE=y CONFIG_SERIAL_FSL_LPUART=y CONFIG_SERIAL_FSL_LPUART_CONSOLE=y -CONFIG_HW_RANDOM=y # CONFIG_I2C_COMPAT is not set CONFIG_I2C_CHARDEV=y # CONFIG_I2C_HELPER_AUTO is not set @@ -181,6 +184,7 @@ CONFIG_I2C_ALGOPCA=m CONFIG_I2C_IMX=y CONFIG_SPI=y CONFIG_SPI_IMX=y +CONFIG_SPI_FSL_DSPI=y CONFIG_GPIO_SYSFS=y CONFIG_GPIO_MC9S08DZ60=y CONFIG_GPIO_PCA953X=y @@ -191,6 +195,7 @@ CONFIG_POWER_RESET_IMX=y CONFIG_POWER_RESET_SYSCON=y CONFIG_POWER_RESET_SYSCON_POWEROFF=y CONFIG_SENSORS_GPIO_FAN=y +CONFIG_SENSORS_IIO_HWMON=y CONFIG_THERMAL=y CONFIG_CPU_THERMAL=y CONFIG_IMX_THERMAL=y @@ -226,7 +231,6 @@ CONFIG_DRM=y CONFIG_DRM_PANEL_SIMPLE=y CONFIG_DRM_DW_HDMI_AHB_AUDIO=m CONFIG_DRM_IMX=y -CONFIG_DRM_IMX_FB_HELPER=y CONFIG_DRM_IMX_PARALLEL_DISPLAY=y CONFIG_DRM_IMX_TVE=y CONFIG_DRM_IMX_LDB=y @@ -270,6 +274,7 @@ CONFIG_USB_EHSET_TEST_FIXTURE=m CONFIG_NOP_USB_XCEIV=y CONFIG_USB_MXS_PHY=y CONFIG_USB_GADGET=y +CONFIG_USB_FSL_USB2=y CONFIG_USB_CONFIGFS=m CONFIG_USB_CONFIGFS_SERIAL=y CONFIG_USB_CONFIGFS_ACM=y @@ -295,6 +300,7 @@ CONFIG_MMC_SDHCI_ESDHC_IMX=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y CONFIG_LEDS_GPIO=y +CONFIG_LEDS_PWM=y CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=y CONFIG_LEDS_TRIGGER_ONESHOT=y @@ -311,15 +317,18 @@ CONFIG_RTC_DRV_MC13XXX=y CONFIG_RTC_DRV_MXC=y CONFIG_RTC_DRV_SNVS=y CONFIG_DMADEVICES=y +CONFIG_FSL_EDMA=y CONFIG_IMX_SDMA=y CONFIG_MXS_DMA=y -CONFIG_FSL_EDMA=y CONFIG_STAGING=y # CONFIG_IOMMU_SUPPORT is not set CONFIG_IIO=y CONFIG_VF610_ADC=y CONFIG_PWM=y +CONFIG_PWM_FSL_FTM=y CONFIG_PWM_IMX=y +CONFIG_NVMEM=y +CONFIG_NVMEM_IMX_OCOTP=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y @@ -327,9 +336,6 @@ CONFIG_EXT2_FS_SECURITY=y CONFIG_EXT3_FS=y CONFIG_EXT3_FS_POSIX_ACL=y CONFIG_EXT3_FS_SECURITY=y -CONFIG_EXT4_FS=y -CONFIG_EXT4_FS_POSIX_ACL=y -CONFIG_EXT4_FS_SECURITY=y CONFIG_QUOTA=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set @@ -364,6 +370,7 @@ CONFIG_PROVE_LOCKING=y # CONFIG_ARM_UNWIND is not set CONFIG_SECURITYFS=y CONFIG_CRYPTO_DEV_FSL_CAAM=y +CONFIG_CRYPTO_DEV_SAHARA=y CONFIG_CRC_CCITT=m CONFIG_CRC_T10DIF=y CONFIG_CRC7=m diff --git a/arch/arm/configs/mini2440_defconfig b/arch/arm/configs/mini2440_defconfig index 9c93f565524819278e693bbcc59435045460ac4d..0b02e4f43c6a9618859b993373b5f77ac8dcc6f2 100644 --- a/arch/arm/configs/mini2440_defconfig +++ b/arch/arm/configs/mini2440_defconfig @@ -158,6 +158,7 @@ CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_S3C2410=y CONFIG_I2C_SIMTEC=y +CONFIG_EEPROM_AT24=y CONFIG_SPI=y CONFIG_SPI_S3C24XX=y CONFIG_SPI_SPIDEV=y diff --git a/arch/arm/configs/multi_v5_defconfig b/arch/arm/configs/multi_v5_defconfig index 1f9ca4737ef66302088a5d2f913df78a3c79f135..e11d99d529ee913c589f20d3988b5a0462b3373f 100644 --- a/arch/arm/configs/multi_v5_defconfig +++ b/arch/arm/configs/multi_v5_defconfig @@ -2,6 +2,7 @@ CONFIG_SYSVIPC=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_LOG_BUF_SHIFT=19 +CONFIG_BLK_DEV_INITRD=y CONFIG_PROFILING=y CONFIG_OPROFILE=y CONFIG_KPROBES=y @@ -91,15 +92,15 @@ CONFIG_SATA_MV=y CONFIG_NETDEVICES=y CONFIG_NET_DSA_MV88E6060=y CONFIG_NET_DSA_MV88E6131=y -CONFIG_NET_DSA_MV88E6123_61_65=y +CONFIG_NET_DSA_MV88E6123=y CONFIG_NET_DSA_MV88E6171=y CONFIG_NET_DSA_MV88E6352=y CONFIG_MV643XX_ETH=y CONFIG_R8169=y CONFIG_MARVELL_PHY=y -CONFIG_MWL8K=m CONFIG_LIBERTAS=y CONFIG_LIBERTAS_SDIO=y +CONFIG_MWL8K=m CONFIG_INPUT_EVDEV=y CONFIG_KEYBOARD_GPIO=y # CONFIG_INPUT_MOUSE is not set diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig index 8e8b2ace9b7c5fb624f4e24122cf269538195f3d..28234906a0646c6bd98e796d64d5eae977743995 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig @@ -16,6 +16,8 @@ CONFIG_ARCH_MULTI_V7=y # CONFIG_ARCH_MULTI_V4 is not set CONFIG_ARCH_VIRT=y CONFIG_ARCH_ALPINE=y +CONFIG_ARCH_ARTPEC=y +CONFIG_MACH_ARTPEC6=y CONFIG_ARCH_MVEBU=y CONFIG_MACH_ARMADA_370=y CONFIG_MACH_ARMADA_375=y @@ -33,6 +35,7 @@ CONFIG_ARCH_BCM_NSP=y CONFIG_ARCH_BCM_21664=y CONFIG_ARCH_BCM_281XX=y CONFIG_ARCH_BCM_5301X=y +CONFIG_ARCH_BCM2835=y CONFIG_ARCH_BRCMSTB=y CONFIG_ARCH_BERLIN=y CONFIG_MACH_BERLIN_BG2=y @@ -182,6 +185,7 @@ CONFIG_MTD_M25P80=y CONFIG_MTD_NAND=y CONFIG_MTD_NAND_ATMEL=y CONFIG_MTD_NAND_BRCMNAND=y +CONFIG_MTD_NAND_VF610_NFC=y CONFIG_MTD_NAND_DAVINCI=y CONFIG_MTD_SPI_NOR=y CONFIG_SPI_FSL_QUADSPI=m @@ -227,6 +231,7 @@ CONFIG_R8169=y CONFIG_SH_ETH=y CONFIG_SMSC911X=y CONFIG_STMMAC_ETH=y +CONFIG_SYNOPSYS_DWC_ETH_QOS=y CONFIG_TI_CPSW=y CONFIG_XILINX_EMACLITE=y CONFIG_AT803X_PHY=y @@ -318,6 +323,7 @@ CONFIG_I2C_ARB_GPIO_CHALLENGE=m CONFIG_I2C_MUX_PCA954x=y CONFIG_I2C_MUX_PINCTRL=y CONFIG_I2C_AT91=m +CONFIG_I2C_BCM2835=y CONFIG_I2C_CADENCE=y CONFIG_I2C_DESIGNWARE_PLATFORM=y CONFIG_I2C_DIGICOLOR=m @@ -341,6 +347,8 @@ CONFIG_I2C_RCAR=y CONFIG_I2C_CROS_EC_TUNNEL=m CONFIG_SPI=y CONFIG_SPI_ATMEL=m +CONFIG_SPI_BCM2835=y +CONFIG_SPI_BCM2835AUX=y CONFIG_SPI_CADENCE=y CONFIG_SPI_DAVINCI=y CONFIG_SPI_FSL_DSPI=m @@ -363,6 +371,7 @@ CONFIG_SPI_SPIDEV=y CONFIG_SPMI=y CONFIG_PINCTRL_AS3722=y CONFIG_PINCTRL_PALMAS=y +CONFIG_PINCTRL_BCM2835=y CONFIG_PINCTRL_APQ8064=y CONFIG_PINCTRL_APQ8084=y CONFIG_PINCTRL_IPQ8064=y @@ -403,6 +412,7 @@ CONFIG_POWER_RESET_KEYSTONE=y CONFIG_POWER_RESET_RMOBILE=y CONFIG_POWER_AVS=y CONFIG_ROCKCHIP_IODOMAIN=y +CONFIG_SENSORS_IIO_HWMON=y CONFIG_SENSORS_LM90=y CONFIG_SENSORS_LM95245=y CONFIG_SENSORS_NTC_THERMISTOR=m @@ -468,6 +478,7 @@ CONFIG_REGULATOR_RK808=y CONFIG_REGULATOR_GPIO=y CONFIG_MFD_SYSCON=y CONFIG_POWER_RESET_SYSCON=y +CONFIG_REGULATOR_LP872X=y CONFIG_REGULATOR_MAX14577=m CONFIG_REGULATOR_MAX8907=y CONFIG_REGULATOR_MAX8973=y @@ -528,6 +539,7 @@ CONFIG_DRM_RCAR_LVDS=y CONFIG_DRM_TEGRA=y CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=m CONFIG_DRM_PANEL_SIMPLE=y +CONFIG_DRM_VC4=y CONFIG_FB_ARMCLCD=y CONFIG_FB_WM8505=y CONFIG_FB_SH_MOBILE_LCDC=y @@ -560,6 +572,7 @@ CONFIG_SND_SOC_ROCKCHIP_RT5645=m CONFIG_SND_SOC_SH4_FSI=m CONFIG_SND_SOC_RCAR=m CONFIG_SND_SOC_RSRC_CARD=m +CONFIG_SND_SUN4I_CODEC=m CONFIG_SND_SOC_SAMSUNG=m CONFIG_SND_SOC_SNOW=m CONFIG_SND_SOC_ODROIDX2=m @@ -578,6 +591,7 @@ CONFIG_SND_SOC_WM8978=m CONFIG_USB=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_MVEBU=y +CONFIG_USB_XHCI_RCAR=m CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_MSM=m CONFIG_USB_EHCI_EXYNOS=y @@ -592,9 +606,12 @@ CONFIG_USB_OHCI_EXYNOS=m CONFIG_USB_R8A66597_HCD=m CONFIG_USB_RENESAS_USBHS=m CONFIG_USB_STORAGE=y +CONFIG_USB_MUSB_HDRC=m +CONFIG_USB_MUSB_SUNXI=m CONFIG_USB_DWC3=y CONFIG_USB_DWC2=m CONFIG_USB_CHIPIDEA=y +CONFIG_USB_CHIPIDEA_UDC=y CONFIG_USB_CHIPIDEA_HOST=y CONFIG_AB8500_USB=y CONFIG_KEYSTONE_USB_PHY=y @@ -604,6 +621,7 @@ CONFIG_USB_ISP1301=y CONFIG_USB_MSM_OTG=m CONFIG_USB_MXS_PHY=y CONFIG_USB_GADGET=y +CONFIG_USB_FSL_USB2=y CONFIG_USB_RENESAS_USBHS_UDC=m CONFIG_USB_ETH=m CONFIG_MMC=y @@ -622,6 +640,7 @@ CONFIG_MMC_SDHCI_SPEAR=y CONFIG_MMC_SDHCI_S3C=y CONFIG_MMC_SDHCI_S3C_DMA=y CONFIG_MMC_SDHCI_BCM_KONA=y +CONFIG_MMC_SDHCI_BCM2835=y CONFIG_MMC_SDHCI_ST=y CONFIG_MMC_OMAP=y CONFIG_MMC_OMAP_HS=y @@ -665,7 +684,6 @@ CONFIG_RTC_DRV_MAX8907=y CONFIG_RTC_DRV_MAX8997=m CONFIG_RTC_DRV_MAX77686=y CONFIG_RTC_DRV_RK808=m -CONFIG_RTC_DRV_MAX77802=m CONFIG_RTC_DRV_RS5C372=m CONFIG_RTC_DRV_PALMAS=y CONFIG_RTC_DRV_ST_LPC=y @@ -691,7 +709,7 @@ CONFIG_DMADEVICES=y CONFIG_DW_DMAC=y CONFIG_AT_HDMAC=y CONFIG_AT_XDMAC=y -CONFIG_FSL_EDMA=m +CONFIG_FSL_EDMA=y CONFIG_MV_XOR=y CONFIG_TEGRA20_APB_DMA=y CONFIG_SH_DMAE=y @@ -704,6 +722,7 @@ CONFIG_PL330_DMA=y CONFIG_IMX_SDMA=y CONFIG_IMX_DMA=y CONFIG_MXS_DMA=y +CONFIG_DMA_BCM2835=y CONFIG_DMA_OMAP=y CONFIG_QCOM_BAM_DMA=y CONFIG_XILINX_VDMA=y @@ -750,8 +769,10 @@ CONFIG_IIO=y CONFIG_AT91_ADC=m CONFIG_BERLIN2_ADC=m CONFIG_EXYNOS_ADC=m +CONFIG_VF610_ADC=m CONFIG_XILINX_XADC=y CONFIG_AK8975=y +CONFIG_RASPBERRYPI_POWER=y CONFIG_PWM=y CONFIG_PWM_ATMEL=m CONFIG_PWM_ATMEL_TCB=m @@ -764,6 +785,7 @@ CONFIG_PWM_TEGRA=y CONFIG_PWM_VT8500=y CONFIG_PHY_HIX5HD2_SATA=y CONFIG_PWM_STI=m +CONFIG_PWM_BCM2835=y CONFIG_OMAP_USB2=y CONFIG_TI_PIPE3=y CONFIG_PHY_BERLIN_USB=y @@ -780,6 +802,8 @@ CONFIG_PHY_SUN9I_USB=y CONFIG_PHY_SAMSUNG_USB2=m CONFIG_NVMEM=y CONFIG_NVMEM_SUNXI_SID=y +CONFIG_BCM2835_MBOX=y +CONFIG_RASPBERRYPI_FIRMWARE=y CONFIG_EXT4_FS=y CONFIG_AUTOFS4_FS=y CONFIG_MSDOS_FS=y diff --git a/arch/arm/configs/mvebu_v5_defconfig b/arch/arm/configs/mvebu_v5_defconfig index af29780accdc680e8ba9c6d3741fb8a940d318fa..4562006aae68afc067aa96394499086d62726dfa 100644 --- a/arch/arm/configs/mvebu_v5_defconfig +++ b/arch/arm/configs/mvebu_v5_defconfig @@ -92,7 +92,7 @@ CONFIG_SATA_MV=y CONFIG_NETDEVICES=y CONFIG_NET_DSA_MV88E6060=y CONFIG_NET_DSA_MV88E6131=y -CONFIG_NET_DSA_MV88E6123_61_65=y +CONFIG_NET_DSA_MV88E6123=y CONFIG_NET_DSA_MV88E6171=y CONFIG_NET_DSA_MV88E6352=y CONFIG_MV643XX_ETH=y @@ -137,6 +137,7 @@ CONFIG_SND=y CONFIG_SND_SOC=y CONFIG_SND_KIRKWOOD_SOC=y CONFIG_SND_SOC_ALC5623=y +CONFIG_SND_SOC_CS42L51_I2C=y CONFIG_SND_SIMPLE_CARD=y CONFIG_HID_DRAGONRISE=y CONFIG_HID_GYRATION=y diff --git a/arch/arm/configs/mvebu_v7_defconfig b/arch/arm/configs/mvebu_v7_defconfig index c6729bf0a8ddb5e272ee97690cd58c68b013b5fa..dc5797a2efab52f5ad701291ce68fda9ebc55996 100644 --- a/arch/arm/configs/mvebu_v7_defconfig +++ b/arch/arm/configs/mvebu_v7_defconfig @@ -58,6 +58,7 @@ CONFIG_MTD_M25P80=y CONFIG_MTD_NAND=y CONFIG_MTD_NAND_PXA3xx=y CONFIG_MTD_SPI_NOR=y +CONFIG_SRAM=y CONFIG_EEPROM_AT24=y CONFIG_BLK_DEV_SD=y CONFIG_ATA=y @@ -109,6 +110,7 @@ CONFIG_USB_XHCI_MVEBU=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_ROOT_HUB_TT=y CONFIG_USB_STORAGE=y +CONFIG_NOP_USB_XCEIV=y CONFIG_MMC=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig index b47e7c6628c9f8883322cffba9e97c12f6963098..6e0f751be2293e57391793d31aba40a4ec7f7cc1 100644 --- a/arch/arm/configs/mxs_defconfig +++ b/arch/arm/configs/mxs_defconfig @@ -12,6 +12,7 @@ CONFIG_IKCONFIG_PROC=y # CONFIG_IPC_NS is not set # CONFIG_PID_NS is not set # CONFIG_NET_NS is not set +CONFIG_BLK_DEV_INITRD=y CONFIG_PERF_EVENTS=y # CONFIG_COMPAT_BRK is not set CONFIG_MODULES=y @@ -141,9 +142,8 @@ CONFIG_IIO=y CONFIG_IIO_SYSFS_TRIGGER=y CONFIG_PWM=y CONFIG_PWM_MXS=y -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT3_FS=y +CONFIG_NVMEM=y +CONFIG_NVMEM_MXS_OCOTP=y CONFIG_EXT4_FS=y # CONFIG_DNOTIFY is not set CONFIG_FSCACHE=m @@ -178,7 +178,6 @@ CONFIG_PROVE_LOCKING=y CONFIG_BLK_DEV_IO_TRACE=y CONFIG_STRICT_DEVMEM=y CONFIG_DEBUG_USER=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_DEV_MXS_DCP=y CONFIG_CRC_ITU_T=m CONFIG_CRC7=m diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index d18d6b42fcf52f9db076af65a0f6aad022a1173c..156bc88b8523f955fd618180ccb422182e2cfc88 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -145,6 +145,7 @@ CONFIG_BLK_DEV_RAM_SIZE=16384 CONFIG_SENSORS_TSL2550=m CONFIG_BMP085_I2C=m CONFIG_SRAM=y +CONFIG_EEPROM_AT24=m CONFIG_SENSORS_LIS3_I2C=m CONFIG_BLK_DEV_SD=y CONFIG_SCSI_SCAN_ASYNC=y @@ -278,6 +279,7 @@ CONFIG_MFD_TPS65218=y CONFIG_MFD_TPS65910=y CONFIG_MFD_TI_AM335X_TSCADC=m CONFIG_TWL6040_CORE=y +CONFIG_REGULATOR_LP872X=y CONFIG_REGULATOR_PALMAS=y CONFIG_REGULATOR_PBIAS=y CONFIG_REGULATOR_TI_ABB=y @@ -288,6 +290,14 @@ CONFIG_REGULATOR_TPS65217=y CONFIG_REGULATOR_TPS65218=y CONFIG_REGULATOR_TPS65910=y CONFIG_REGULATOR_TWL4030=y +CONFIG_MEDIA_SUPPORT=m +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_CONTROLLER=y +CONFIG_VIDEO_V4L2_SUBDEV_API=y +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_VIDEO_OMAP3=m +# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set +CONFIG_VIDEO_TVP5150=m CONFIG_FB=y CONFIG_FIRMWARE_EDID=y CONFIG_FB_MODE_HELPERS=y @@ -411,7 +421,8 @@ CONFIG_RTC_DRV_OMAP=m CONFIG_DMADEVICES=y CONFIG_TI_EDMA=y CONFIG_DMA_OMAP=y -# CONFIG_IOMMU_SUPPORT is not set +CONFIG_IOMMU_SUPPORT=y +CONFIG_OMAP_IOMMU=y CONFIG_EXTCON=m CONFIG_EXTCON_USB_GPIO=m CONFIG_EXTCON_PALMAS=m diff --git a/arch/arm/configs/orion5x_defconfig b/arch/arm/configs/orion5x_defconfig index 5876ce7af1304eb9233ff852afab30d10a2d4591..6a5bc27538f1a9aead773b6c28525482b6ebe552 100644 --- a/arch/arm/configs/orion5x_defconfig +++ b/arch/arm/configs/orion5x_defconfig @@ -86,7 +86,7 @@ CONFIG_SATA_MV=y CONFIG_NETDEVICES=y CONFIG_MII=y CONFIG_NET_DSA_MV88E6131=y -CONFIG_NET_DSA_MV88E6123_61_65=y +CONFIG_NET_DSA_MV88E6123=y CONFIG_MV643XX_ETH=y CONFIG_MARVELL_PHY=y # CONFIG_INPUT_MOUSEDEV is not set diff --git a/arch/arm/configs/pxa_defconfig b/arch/arm/configs/pxa_defconfig index 0cb724b5c639269bef9787064c610afa82166ea0..dc5517eaf09fbc878a23239a1076b941340dc338 100644 --- a/arch/arm/configs/pxa_defconfig +++ b/arch/arm/configs/pxa_defconfig @@ -378,6 +378,7 @@ CONFIG_GPIO_PALMAS=y CONFIG_GPIO_TPS6586X=y CONFIG_GPIO_TPS65910=y CONFIG_GPIO_MAX7301=m +CONFIG_GPIO_SYSFS=y CONFIG_POWER_SUPPLY_DEBUG=y CONFIG_PDA_POWER=m CONFIG_BATTERY_SBS=m diff --git a/arch/arm/configs/realview-smp_defconfig b/arch/arm/configs/realview-smp_defconfig deleted file mode 100644 index 93efdcfcf98fbfecc57ed4dceb7fea00c19fb21d..0000000000000000000000000000000000000000 --- a/arch/arm/configs/realview-smp_defconfig +++ /dev/null @@ -1,105 +0,0 @@ -# CONFIG_SWAP is not set -CONFIG_SYSVIPC=y -CONFIG_NO_HZ_FULL=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_PERF_EVENTS=y -CONFIG_SLAB=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_CFQ is not set -CONFIG_ARCH_MULTI_V6=y -CONFIG_ARCH_REALVIEW=y -CONFIG_REALVIEW_DT=y -CONFIG_MACH_REALVIEW_EB=y -CONFIG_REALVIEW_EB_ARM1136=y -CONFIG_REALVIEW_EB_ARM1176=y -CONFIG_REALVIEW_EB_A9MP=y -CONFIG_REALVIEW_EB_ARM11MP=y -CONFIG_REALVIEW_EB_ARM11MP_REVB=y -CONFIG_MACH_REALVIEW_PB11MP=y -CONFIG_MACH_REALVIEW_PB1176=y -CONFIG_MACH_REALVIEW_PBA8=y -CONFIG_MACH_REALVIEW_PBX=y -CONFIG_SMP=y -CONFIG_AEABI=y -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="root=/dev/nfs nfsroot=10.1.69.3:/work/nfsroot ip=dhcp console=ttyAMA0 mem=128M" -CONFIG_VFP=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_INET=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -# CONFIG_INET_LRO is not set -# CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_AFS_PARTS=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_ROM=y -CONFIG_MTD_PHYSMAP=y -CONFIG_ARM_CHARLCD=y -CONFIG_NETDEVICES=y -CONFIG_SMC91X=y -CONFIG_SMSC911X=y -CONFIG_SMSC_PHY=y -# CONFIG_SERIO_SERPORT is not set -CONFIG_SERIO_AMBAKMI=y -CONFIG_LEGACY_PTY_COUNT=16 -CONFIG_SERIAL_AMBA_PL011=y -CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -# CONFIG_HW_RANDOM is not set -CONFIG_I2C=y -CONFIG_I2C_VERSATILE=y -CONFIG_SPI=y -CONFIG_GPIOLIB=y -# CONFIG_HWMON is not set -CONFIG_FB=y -CONFIG_FB_ARMCLCD=y -CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_LOGO=y -# CONFIG_LOGO_LINUX_MONO is not set -# CONFIG_LOGO_LINUX_VGA16 is not set -CONFIG_SOUND=y -CONFIG_SND=y -CONFIG_SND_MIXER_OSS=y -CONFIG_SND_PCM_OSS=y -# CONFIG_SND_DRIVERS is not set -CONFIG_SND_ARMAACI=y -CONFIG_USB=y -CONFIG_USB_ISP1760=y -CONFIG_MMC=y -CONFIG_MMC_ARMMMCI=y -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -CONFIG_LEDS_VERSATILE=y -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -CONFIG_LEDS_TRIGGER_CPU=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_DS1307=y -CONFIG_RTC_DRV_PL031=y -CONFIG_VFAT_FS=y -CONFIG_TMPFS=y -CONFIG_CRAMFS=y -CONFIG_NFS_FS=y -CONFIG_ROOT_NFS=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_ISO8859_1=y -CONFIG_DEBUG_FS=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_DEBUG_KERNEL=y -# CONFIG_SCHED_DEBUG is not set -# CONFIG_FTRACE is not set -CONFIG_DEBUG_USER=y -# CONFIG_CRYPTO_HW is not set diff --git a/arch/arm/configs/realview_defconfig b/arch/arm/configs/realview_defconfig index 8f56fb3ff51db3bda55a04f91d2e2987b16bbca9..9e77dc7b828fc4bd25688a60c3e8bfae2bc4c53a 100644 --- a/arch/arm/configs/realview_defconfig +++ b/arch/arm/configs/realview_defconfig @@ -1,5 +1,6 @@ # CONFIG_SWAP is not set CONFIG_SYSVIPC=y +CONFIG_NO_HZ_FULL=y CONFIG_HIGH_RES_TIMERS=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_PERF_EVENTS=y @@ -21,6 +22,7 @@ CONFIG_MACH_REALVIEW_PB11MP=y CONFIG_MACH_REALVIEW_PB1176=y CONFIG_MACH_REALVIEW_PBA8=y CONFIG_MACH_REALVIEW_PBX=y +CONFIG_SMP=y CONFIG_AEABI=y CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 @@ -46,6 +48,8 @@ CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_ROM=y CONFIG_MTD_PHYSMAP=y CONFIG_ARM_CHARLCD=y +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y CONFIG_NETDEVICES=y CONFIG_SMC91X=y CONFIG_SMSC911X=y @@ -74,6 +78,7 @@ CONFIG_SND_PCM_OSS=y # CONFIG_SND_DRIVERS is not set CONFIG_SND_ARMAACI=y CONFIG_USB=y +CONFIG_USB_STORAGE=y CONFIG_USB_ISP1760=y CONFIG_MMC=y CONFIG_MMC_ARMMMCI=y diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig index f3142369f594aebbc0efd1066574545d3485e93d..b3ade552a2a53d4e9c03b5a5ee0c836eab24ab92 100644 --- a/arch/arm/configs/s3c2410_defconfig +++ b/arch/arm/configs/s3c2410_defconfig @@ -290,6 +290,7 @@ CONFIG_HW_RANDOM=y CONFIG_I2C_CHARDEV=m CONFIG_I2C_S3C2410=y CONFIG_I2C_SIMTEC=y +CONFIG_EEPROM_AT24=y CONFIG_SPI=y CONFIG_SPI_GPIO=m CONFIG_SPI_S3C24XX=m diff --git a/arch/arm/configs/sama5_defconfig b/arch/arm/configs/sama5_defconfig index c11bab735125f2a9165add21d339e1397da93f1c..afbda413d61aa01bd0df3a94ba6c488c8cb44f8a 100644 --- a/arch/arm/configs/sama5_defconfig +++ b/arch/arm/configs/sama5_defconfig @@ -187,6 +187,7 @@ CONFIG_AT_XDMAC=y # CONFIG_IOMMU_SUPPORT is not set CONFIG_IIO=y CONFIG_AT91_ADC=y +CONFIG_AT91_SAMA5D2_ADC=y CONFIG_PWM=y CONFIG_PWM_ATMEL=y CONFIG_PWM_ATMEL_TCB=y diff --git a/arch/arm/configs/shmobile_defconfig b/arch/arm/configs/shmobile_defconfig index 969738324a5d5f815263a12cf2f580098603cf4a..b7b714c3958c2fdad9bb8658680b7a31ee6d04e8 100644 --- a/arch/arm/configs/shmobile_defconfig +++ b/arch/arm/configs/shmobile_defconfig @@ -20,7 +20,6 @@ CONFIG_ARCH_R8A7791=y CONFIG_ARCH_R8A7793=y CONFIG_ARCH_R8A7794=y CONFIG_ARCH_SH73A0=y -CONFIG_CPU_BPREDICT_DISABLE=y CONFIG_PL310_ERRATA_588369=y CONFIG_ARM_ERRATA_754322=y CONFIG_PCI=y @@ -163,6 +162,8 @@ CONFIG_SND_SOC_RSRC_CARD=y CONFIG_SND_SOC_AK4642=y CONFIG_SND_SOC_WM8978=y CONFIG_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_RCAR=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_R8A66597_HCD=y diff --git a/arch/arm/configs/socfpga_defconfig b/arch/arm/configs/socfpga_defconfig index f7f4e2e3cc33d0a30d1dd87734ac9b2264ba0091..753f1a5defc751756a4ad4bbbb57b993d88bbb7b 100644 --- a/arch/arm/configs/socfpga_defconfig +++ b/arch/arm/configs/socfpga_defconfig @@ -7,6 +7,7 @@ CONFIG_LOG_BUF_SHIFT=14 CONFIG_CGROUPS=y CONFIG_CPUSETS=y CONFIG_NAMESPACES=y +CONFIG_BLK_DEV_INITRD=y CONFIG_EMBEDDED=y CONFIG_PROFILING=y CONFIG_OPROFILE=y @@ -107,4 +108,3 @@ CONFIG_DETECT_HUNG_TASK=y # CONFIG_SCHED_DEBUG is not set CONFIG_ENABLE_DEFAULT_TRACERS=y CONFIG_DEBUG_USER=y -CONFIG_XZ_DEC=y diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig index ec5250547d145124e3a388a4f846faabb0475ed7..1e5ec2a0e4cf4097bfb36f7c9533f1cd74a18cd8 100644 --- a/arch/arm/configs/stm32_defconfig +++ b/arch/arm/configs/stm32_defconfig @@ -52,6 +52,7 @@ CONFIG_SERIAL_STM32_CONSOLE=y # CONFIG_USB_SUPPORT is not set CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_DMADEVICES=y diff --git a/arch/arm/configs/sunxi_defconfig b/arch/arm/configs/sunxi_defconfig index a9a81a714be461ee48542ee4563feb26d88abc7e..81a1b92fd4e6aec14e949146edda411229508245 100644 --- a/arch/arm/configs/sunxi_defconfig +++ b/arch/arm/configs/sunxi_defconfig @@ -58,6 +58,7 @@ CONFIG_STMMAC_ETH=y # CONFIG_NET_VENDOR_WIZNET is not set # CONFIG_WLAN is not set # CONFIG_INPUT_MOUSEDEV is not set +CONFIG_INPUT_EVDEV=y CONFIG_KEYBOARD_SUN4I_LRADC=y # CONFIG_INPUT_MOUSE is not set CONFIG_INPUT_TOUCHSCREEN=y @@ -92,15 +93,27 @@ CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_AXP20X=y CONFIG_REGULATOR_GPIO=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_RC_SUPPORT=y +CONFIG_RC_DEVICES=y +CONFIG_IR_SUNXI=y CONFIG_FB=y CONFIG_FB_SIMPLE=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_SOC=y +CONFIG_SND_SUN4I_CODEC=y CONFIG_USB=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_HCD_PLATFORM=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_MUSB_HDRC=y +CONFIG_USB_MUSB_SUNXI=y +CONFIG_NOP_USB_XCEIV=y +CONFIG_USB_GADGET=y CONFIG_MMC=y CONFIG_MMC_SUNXI=y CONFIG_NEW_LEDS=y diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild index 16da6380eb8505a9f9b87db77ac4b56c1febd8d9..55e0e3ea9cb6bdeb19ff5c47385a571799dd71e6 100644 --- a/arch/arm/include/asm/Kbuild +++ b/arch/arm/include/asm/Kbuild @@ -1,6 +1,7 @@ generic-y += bitsperlong.h +generic-y += clkdev.h generic-y += cputime.h generic-y += current.h generic-y += early_ioremap.h @@ -23,7 +24,6 @@ generic-y += preempt.h generic-y += resource.h generic-y += rwsem.h generic-y += seccomp.h -generic-y += sections.h generic-y += segment.h generic-y += sembuf.h generic-y += serial.h diff --git a/arch/arm/include/asm/checksum.h b/arch/arm/include/asm/checksum.h index 523315115478960a2e433a66276fea007b120cda..524692f4acabf48906a9a2a4de9a053dba707068 100644 --- a/arch/arm/include/asm/checksum.h +++ b/arch/arm/include/asm/checksum.h @@ -84,10 +84,10 @@ ip_fast_csum(const void *iph, unsigned int ihl) } static inline __wsum -csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) +csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len, + __u8 proto, __wsum sum) { - u32 lenprot = len | proto << 16; + u32 lenprot = len + proto; if (__builtin_constant_p(sum) && sum == 0) { __asm__( "adds %0, %1, %2 @ csum_tcpudp_nofold0 \n\t" @@ -121,8 +121,8 @@ csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, * returns a 16-bit checksum, already complemented */ static inline __sum16 -csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) +csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len, + __u8 proto, __wsum sum) { return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum)); } @@ -144,8 +144,8 @@ __csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, __ __be32 proto, __wsum sum); static inline __sum16 -csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, __u32 len, - unsigned short proto, __wsum sum) +csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, + __u32 len, __u8 proto, __wsum sum) { return csum_fold(__csum_ipv6_magic(saddr, daddr, htonl(len), htonl(proto), sum)); diff --git a/arch/arm/include/asm/clkdev.h b/arch/arm/include/asm/clkdev.h deleted file mode 100644 index 4e8a4b27d7c7948ed1104f247e4ba5f85e0104c7..0000000000000000000000000000000000000000 --- a/arch/arm/include/asm/clkdev.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * arch/arm/include/asm/clkdev.h - * - * Copyright (C) 2008 Russell King. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Helper for the clk API to assist looking up a struct clk. - */ -#ifndef __ASM_CLKDEV_H -#define __ASM_CLKDEV_H - -#include - -#ifndef CONFIG_COMMON_CLK -#ifdef CONFIG_HAVE_MACH_CLKDEV -#include -#else -#define __clk_get(clk) ({ 1; }) -#define __clk_put(clk) do { } while (0) -#endif -#endif - -static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size) -{ - return kzalloc(size, GFP_KERNEL); -} - -#endif diff --git a/arch/arm/include/asm/div64.h b/arch/arm/include/asm/div64.h index e1f07764b0d6bf99e8ed9386a24a086fa82be1e1..7d919a9b32e5f6e251e1a42d2ccd8f7d33d62483 100644 --- a/arch/arm/include/asm/div64.h +++ b/arch/arm/include/asm/div64.h @@ -74,7 +74,7 @@ static inline uint32_t __div64_32(uint64_t *n, uint32_t base) static inline uint64_t __arch_xprod_64(uint64_t m, uint64_t n, bool bias) { unsigned long long res; - unsigned int tmp = 0; + register unsigned int tmp asm("ip") = 0; if (!bias) { asm ( "umull %Q0, %R0, %Q1, %Q2\n\t" @@ -90,12 +90,12 @@ static inline uint64_t __arch_xprod_64(uint64_t m, uint64_t n, bool bias) : "r" (m), "r" (n) : "cc"); } else { - asm ( "umull %Q0, %R0, %Q1, %Q2\n\t" - "cmn %Q0, %Q1\n\t" - "adcs %R0, %R0, %R1\n\t" - "adc %Q0, %3, #0" - : "=&r" (res) - : "r" (m), "r" (n), "r" (tmp) + asm ( "umull %Q0, %R0, %Q2, %Q3\n\t" + "cmn %Q0, %Q2\n\t" + "adcs %R0, %R0, %R2\n\t" + "adc %Q0, %1, #0" + : "=&r" (res), "+&r" (tmp) + : "r" (m), "r" (n) : "cc"); } diff --git a/arch/arm/include/asm/exception.h b/arch/arm/include/asm/exception.h index 5abaf5bbd985f1049c65e6368c3e868399bb609e..bf1991263d2df2128f4564aaee76d1c1560fe141 100644 --- a/arch/arm/include/asm/exception.h +++ b/arch/arm/include/asm/exception.h @@ -7,7 +7,7 @@ #ifndef __ASM_ARM_EXCEPTION_H #define __ASM_ARM_EXCEPTION_H -#include +#include #define __exception __attribute__((section(".exception.text"))) #ifdef CONFIG_FUNCTION_GRAPH_TRACER diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h index c79b57bf71c40d1fc2083f67b198377936e0002f..9427fd6325527e95ff9e5ad0a3f2bd973481e22a 100644 --- a/arch/arm/include/asm/memory.h +++ b/arch/arm/include/asm/memory.h @@ -134,6 +134,21 @@ */ #define PLAT_PHYS_OFFSET UL(CONFIG_PHYS_OFFSET) +#ifdef CONFIG_XIP_KERNEL +/* + * When referencing data in RAM from the XIP region in a relative manner + * with the MMU off, we need the relative offset between the two physical + * addresses. The macro below achieves this, which is: + * __pa(v_data) - __xip_pa(v_text) + */ +#define PHYS_RELATIVE(v_data, v_text) \ + (((v_data) - PAGE_OFFSET + PLAT_PHYS_OFFSET) - \ + ((v_text) - XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR) + \ + CONFIG_XIP_PHYS_ADDR)) +#else +#define PHYS_RELATIVE(v_data, v_text) ((v_data) - (v_text)) +#endif + #ifndef __ASSEMBLY__ /* @@ -273,14 +288,14 @@ static inline void *phys_to_virt(phys_addr_t x) #define __va(x) ((void *)__phys_to_virt((phys_addr_t)(x))) #define pfn_to_kaddr(pfn) __va((phys_addr_t)(pfn) << PAGE_SHIFT) -extern phys_addr_t (*arch_virt_to_idmap)(unsigned long x); +extern unsigned long (*arch_virt_to_idmap)(unsigned long x); /* * These are for systems that have a hardware interconnect supported alias of * physical memory for idmap purposes. Most cases should leave these - * untouched. + * untouched. Note: this can only return addresses less than 4GiB. */ -static inline phys_addr_t __virt_to_idmap(unsigned long x) +static inline unsigned long __virt_to_idmap(unsigned long x) { if (IS_ENABLED(CONFIG_MMU) && arch_virt_to_idmap) return arch_virt_to_idmap(x); @@ -303,20 +318,6 @@ static inline phys_addr_t __virt_to_idmap(unsigned long x) #define __bus_to_pfn(x) __phys_to_pfn(x) #endif -#ifdef CONFIG_VIRT_TO_BUS -#define virt_to_bus virt_to_bus -static inline __deprecated unsigned long virt_to_bus(void *x) -{ - return __virt_to_bus((unsigned long)x); -} - -#define bus_to_virt bus_to_virt -static inline __deprecated void *bus_to_virt(unsigned long x) -{ - return (void *)__bus_to_virt(x); -} -#endif - /* * Conversion between a struct page and a physical address. * diff --git a/arch/arm/include/asm/mmu_context.h b/arch/arm/include/asm/mmu_context.h index 432ce8176498e0a014b26689716454150278056c..fa5b42d44985fbda00595f891450c6a60c8fd48b 100644 --- a/arch/arm/include/asm/mmu_context.h +++ b/arch/arm/include/asm/mmu_context.h @@ -26,7 +26,12 @@ void __check_vmalloc_seq(struct mm_struct *mm); #ifdef CONFIG_CPU_HAS_ASID void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk); -#define init_new_context(tsk,mm) ({ atomic64_set(&(mm)->context.id, 0); 0; }) +static inline int +init_new_context(struct task_struct *tsk, struct mm_struct *mm) +{ + atomic64_set(&mm->context.id, 0); + return 0; +} #ifdef CONFIG_ARM_ERRATA_798181 void a15_erratum_get_cpumask(int this_cpu, struct mm_struct *mm, @@ -85,7 +90,12 @@ static inline void finish_arch_post_lock_switch(void) #endif /* CONFIG_MMU */ -#define init_new_context(tsk,mm) 0 +static inline int +init_new_context(struct task_struct *tsk, struct mm_struct *mm) +{ + return 0; +} + #endif /* CONFIG_CPU_HAS_ASID */ diff --git a/arch/arm/include/asm/page-nommu.h b/arch/arm/include/asm/page-nommu.h index d1b162a18dcb16402cde824488047fcd2d708a98..503f488053de6b362fd39e8dff79109fce9b1d5b 100644 --- a/arch/arm/include/asm/page-nommu.h +++ b/arch/arm/include/asm/page-nommu.h @@ -17,9 +17,6 @@ #define KTHREAD_SIZE PAGE_SIZE #endif -#define get_user_page(vaddr) __get_free_page(GFP_KERNEL) -#define free_user_page(page, addr) free_page(addr) - #define clear_page(page) memset((page), 0, PAGE_SIZE) #define copy_page(to,from) memcpy((to), (from), PAGE_SIZE) diff --git a/arch/arm/include/asm/sections.h b/arch/arm/include/asm/sections.h new file mode 100644 index 0000000000000000000000000000000000000000..803bbf2b20b87b397ee12ca0ef2f5b4eefc403d5 --- /dev/null +++ b/arch/arm/include/asm/sections.h @@ -0,0 +1,8 @@ +#ifndef _ASM_ARM_SECTIONS_H +#define _ASM_ARM_SECTIONS_H + +#include + +extern char _exiprom[]; + +#endif /* _ASM_ARM_SECTIONS_H */ diff --git a/arch/arm/include/asm/sparsemem.h b/arch/arm/include/asm/sparsemem.h index 00098615c6f0c35506f9628bb08dc81c39dca7a7..73e5e851375157513495e698a5d894617f7c86ce 100644 --- a/arch/arm/include/asm/sparsemem.h +++ b/arch/arm/include/asm/sparsemem.h @@ -15,10 +15,11 @@ * Eg, if you have 2 banks of up to 64MB at 0x80000000, 0x84000000, * then MAX_PHYSMEM_BITS is 32, SECTION_SIZE_BITS is 26. * - * Define these in your mach/memory.h. + * These can be overridden in your mach/memory.h. */ -#if !defined(SECTION_SIZE_BITS) || !defined(MAX_PHYSMEM_BITS) -#error Sparsemem is not supported on this platform +#if !defined(MAX_PHYSMEM_BITS) || !defined(SECTION_SIZE_BITS) +#define MAX_PHYSMEM_BITS 36 +#define SECTION_SIZE_BITS 28 #endif #endif diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h index 7b84657fba3577ea3d29ecf1b93e3267feecbb59..194b6992338920680c14c46326999791e33defa6 100644 --- a/arch/arm/include/asm/unistd.h +++ b/arch/arm/include/asm/unistd.h @@ -19,7 +19,7 @@ * This may need to be greater than __NR_last_syscall+1 in order to * account for the padding in the syscall table */ -#define __NR_syscalls (392) +#define __NR_syscalls (396) #define __ARCH_WANT_STAT64 #define __ARCH_WANT_SYS_GETHOSTNAME diff --git a/arch/arm/include/asm/xen/hypercall.h b/arch/arm/include/asm/xen/hypercall.h index d769972db8cbe49b232c3ac81ff10c8a958a5eee..b6b962d70db980380b526feca2370d352d26a6dc 100644 --- a/arch/arm/include/asm/xen/hypercall.h +++ b/arch/arm/include/asm/xen/hypercall.h @@ -33,6 +33,8 @@ #ifndef _ASM_ARM_XEN_HYPERCALL_H #define _ASM_ARM_XEN_HYPERCALL_H +#include + #include #include #include diff --git a/arch/arm/include/debug/at91.S b/arch/arm/include/debug/at91.S index 43243be94cfcb556d1a3a0e85f6a63089d8c89c2..d4ae3b8e2426e1ebe4cff786e01432e9b4eecbc9 100644 --- a/arch/arm/include/debug/at91.S +++ b/arch/arm/include/debug/at91.S @@ -15,7 +15,7 @@ #define AT91_IO_P2V(x) (x) #endif -#define CONFIG_DEBUG_UART_VIRT AT91_IO_P2V(CONFIG_DEBUG_UART_PHYS) +#define AT91_DEBUG_UART_VIRT AT91_IO_P2V(CONFIG_DEBUG_UART_PHYS) #define AT91_DBGU_SR (0x14) /* Status Register */ #define AT91_DBGU_THR (0x1c) /* Transmitter Holding Register */ @@ -24,7 +24,7 @@ .macro addruart, rp, rv, tmp ldr \rp, =CONFIG_DEBUG_UART_PHYS @ System peripherals (phys address) - ldr \rv, =CONFIG_DEBUG_UART_VIRT @ System peripherals (virt address) + ldr \rv, =AT91_DEBUG_UART_VIRT @ System peripherals (virt address) .endm .macro senduart,rd,rx diff --git a/arch/arm/include/debug/imx.S b/arch/arm/include/debug/imx.S index 619d8cc1ac125f6c6038daef7a814e146cebebb1..92c44760d6569181d2dd6fd191d995b453cee572 100644 --- a/arch/arm/include/debug/imx.S +++ b/arch/arm/include/debug/imx.S @@ -11,6 +11,7 @@ * */ +#include #include "imx-uart.h" /* @@ -34,6 +35,7 @@ .endm .macro senduart,rd,rx + ARM_BE8(rev \rd, \rd) str \rd, [\rx, #0x40] @ TXDATA .endm @@ -42,6 +44,7 @@ .macro busyuart,rd,rx 1002: ldr \rd, [\rx, #0x98] @ SR2 + ARM_BE8(rev \rd, \rd) tst \rd, #1 << 3 @ TXDC beq 1002b @ wait until transmit done .endm diff --git a/arch/arm/include/debug/palmchip.S b/arch/arm/include/debug/palmchip.S new file mode 100644 index 0000000000000000000000000000000000000000..6824b2d1c38e60bd0a4019e8d0450b987fa72d08 --- /dev/null +++ b/arch/arm/include/debug/palmchip.S @@ -0,0 +1,11 @@ +#include + +#undef UART_TX +#undef UART_LSR +#undef UART_MSR + +#define UART_TX 1 +#define UART_LSR 7 +#define UART_MSR 8 + +#include diff --git a/arch/arm/include/debug/zynq.S b/arch/arm/include/debug/zynq.S index de86b924756401da3189c625ef5bde99d57b1782..060cb5b49bfd84e5ccf3888d7cef0e9f5e683e87 100644 --- a/arch/arm/include/debug/zynq.S +++ b/arch/arm/include/debug/zynq.S @@ -20,9 +20,9 @@ #define UART_SR_TXEMPTY 0x00000008 /* TX FIFO empty */ #define UART0_PHYS 0xE0000000 -#define UART0_VIRT 0xF0000000 +#define UART0_VIRT 0xF0800000 #define UART1_PHYS 0xE0001000 -#define UART1_VIRT 0xF0001000 +#define UART1_VIRT 0xF0801000 #if IS_ENABLED(CONFIG_DEBUG_ZYNQ_UART1) # define LL_UART_PADDR UART1_PHYS diff --git a/arch/arm/include/uapi/asm/unistd.h b/arch/arm/include/uapi/asm/unistd.h index 5dd2528e9e45e369d0879185291e6981dbea15e4..2cb9dc770e1d41e8867f949e1ef13e028568a3d3 100644 --- a/arch/arm/include/uapi/asm/unistd.h +++ b/arch/arm/include/uapi/asm/unistd.h @@ -418,6 +418,8 @@ #define __NR_membarrier (__NR_SYSCALL_BASE+389) #define __NR_mlock2 (__NR_SYSCALL_BASE+390) #define __NR_copy_file_range (__NR_SYSCALL_BASE+391) +#define __NR_preadv2 (__NR_SYSCALL_BASE+392) +#define __NR_pwritev2 (__NR_SYSCALL_BASE+393) /* * The following SWIs are ARM private. diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index dfc7cd6851ad4bbd09b11ae94ee6056f691b1fcb..703fa0f3cd8f812907b47ac7c84646ff3e3aff94 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S @@ -399,8 +399,10 @@ CALL(sys_execveat) CALL(sys_userfaultfd) CALL(sys_membarrier) - CALL(sys_mlock2) +/* 390 */ CALL(sys_mlock2) CALL(sys_copy_file_range) + CALL(sys_preadv2) + CALL(sys_pwritev2) #ifndef syscalls_counted .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls #define syscalls_counted diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 3ce377f7251f3429668c2e2b563fcd8062c991ae..e2550500486d497c8455165b37916f2eb4974cd5 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -1064,7 +1064,6 @@ ENDPROC(vector_\name) .endm .section .stubs, "ax", %progbits -__stubs_start: @ This must be the first word .word vector_swi @@ -1202,14 +1201,13 @@ vector_addrexcptn: .long __fiq_svc @ e .long __fiq_svc @ f - .globl vector_fiq_offset - .equ vector_fiq_offset, vector_fiq + .globl vector_fiq .section .vectors, "ax", %progbits -__vectors_start: +.L__vectors_start: W(b) vector_rst W(b) vector_und - W(ldr) pc, __vectors_start + 0x1000 + W(ldr) pc, .L__vectors_start + 0x1000 W(b) vector_pabt W(b) vector_dabt W(b) vector_addrexcptn diff --git a/arch/arm/kernel/hibernate.c b/arch/arm/kernel/hibernate.c index a71501ff6f1877fc9813fd4c3e10c51ae36f04e7..b09561a6d06a00eb9029fc9916ba1f654ca7e1c2 100644 --- a/arch/arm/kernel/hibernate.c +++ b/arch/arm/kernel/hibernate.c @@ -62,7 +62,7 @@ static int notrace arch_save_image(unsigned long unused) ret = swsusp_save(); if (ret == 0) - _soft_restart(virt_to_phys(cpu_resume), false); + _soft_restart(virt_to_idmap(cpu_resume), false); return ret; } @@ -87,7 +87,7 @@ static void notrace arch_restore_image(void *unused) for (pbe = restore_pblist; pbe; pbe = pbe->next) copy_page(pbe->orig_address, pbe->address); - _soft_restart(virt_to_phys(cpu_resume), false); + _soft_restart(virt_to_idmap(cpu_resume), false); } static u64 resume_stack[PAGE_SIZE/2/sizeof(u64)] __nosavedata; diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S index 2a55373f49bfb621987ad2a548271fe51d7923b5..0b1e4a93d67edfe15899220087a4bdc53966f90c 100644 --- a/arch/arm/kernel/hyp-stub.S +++ b/arch/arm/kernel/hyp-stub.S @@ -17,6 +17,7 @@ */ #include +#include #include #include #include @@ -159,6 +160,29 @@ ARM_BE8(orr r7, r7, #(1 << 25)) @ HSCTLR.EE bic r7, #1 @ Clear ENABLE mcr p15, 0, r7, c14, c3, 1 @ CNTV_CTL 1: +#endif + +#ifdef CONFIG_ARM_GIC_V3 + @ Check whether GICv3 system registers are available + mrc p15, 0, r7, c0, c1, 1 @ ID_PFR1 + ubfx r7, r7, #28, #4 + cmp r7, #1 + bne 2f + + @ Enable system register accesses + mrc p15, 4, r7, c12, c9, 5 @ ICC_HSRE + orr r7, r7, #(ICC_SRE_EL2_ENABLE | ICC_SRE_EL2_SRE) + mcr p15, 4, r7, c12, c9, 5 @ ICC_HSRE + isb + + @ SRE bit could be forced to 0 by firmware. + @ Check whether it sticks before accessing any other sysreg + mrc p15, 4, r7, c12, c9, 5 @ ICC_HSRE + tst r7, #ICC_SRE_EL2_SRE + beq 2f + mov r7, #0 + mcr p15, 4, r7, c12, c11, 0 @ ICH_HCR +2: #endif bx lr @ The boot CPU mode is left in r4. diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 1d45320ee125d572b108d8e40bb6e0150fea8b9a..ece04a457486c5998d312bce4f3c69b97e0e7b64 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -95,7 +95,7 @@ void __init init_IRQ(void) outer_cache.write_sec = machine_desc->l2c_write_sec; ret = l2x0_of_init(machine_desc->l2c_aux_val, machine_desc->l2c_aux_mask); - if (ret) + if (ret && ret != -ENODEV) pr_err("L2C: failed to init: %d\n", ret); } diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c index 8bf3b7c098881b951df038575c6baf14e84df7b9..59fd0e24c56b150a1f22ab21983d72022fe52701 100644 --- a/arch/arm/kernel/machine_kexec.c +++ b/arch/arm/kernel/machine_kexec.c @@ -143,10 +143,8 @@ void (*kexec_reinit)(void); void machine_kexec(struct kimage *image) { - unsigned long page_list; - unsigned long reboot_code_buffer_phys; - unsigned long reboot_entry = (unsigned long)relocate_new_kernel; - unsigned long reboot_entry_phys; + unsigned long page_list, reboot_entry_phys; + void (*reboot_entry)(void); void *reboot_code_buffer; /* @@ -159,9 +157,6 @@ void machine_kexec(struct kimage *image) page_list = image->head & PAGE_MASK; - /* we need both effective and real address here */ - reboot_code_buffer_phys = - page_to_pfn(image->control_code_page) << PAGE_SHIFT; reboot_code_buffer = page_address(image->control_code_page); /* Prepare parameters for reboot_code_buffer*/ @@ -174,10 +169,11 @@ void machine_kexec(struct kimage *image) /* copy our kernel relocation code to the control code page */ reboot_entry = fncpy(reboot_code_buffer, - reboot_entry, + &relocate_new_kernel, relocate_new_kernel_size); - reboot_entry_phys = (unsigned long)reboot_entry + - (reboot_code_buffer_phys - (unsigned long)reboot_code_buffer); + + /* get the identity mapping physical address for the reboot code */ + reboot_entry_phys = virt_to_idmap(reboot_entry); pr_info("Bye!\n"); diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index efdddcb97dd14df54b0f7307acb6a57367793f6b..4f14b5ce6535f7a19215660ebb4b3e62bd6ea5ed 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c @@ -34,7 +34,7 @@ * recompiling the whole kernel when CONFIG_XIP_KERNEL is turned on/off. */ #undef MODULES_VADDR -#define MODULES_VADDR (((unsigned long)_etext + ~PMD_MASK) & PMD_MASK) +#define MODULES_VADDR (((unsigned long)_exiprom + ~PMD_MASK) & PMD_MASK) #endif #ifdef CONFIG_MMU diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c index 4152158f6e6a527eca033e0235ee5a54f0ab2d69..15063851cd10825d08468b03e88411310beb68a3 100644 --- a/arch/arm/kernel/perf_event_v7.c +++ b/arch/arm/kernel/perf_event_v7.c @@ -712,6 +712,11 @@ static const struct attribute_group *armv7_pmuv2_attr_groups[] = { #define ARMV7_EXCLUDE_USER (1 << 30) #define ARMV7_INCLUDE_HYP (1 << 27) +/* + * Secure debug enable reg + */ +#define ARMV7_SDER_SUNIDEN BIT(1) /* Permit non-invasive debug */ + static inline u32 armv7_pmnc_read(void) { u32 val; @@ -1094,7 +1099,13 @@ static int armv7pmu_set_event_filter(struct hw_perf_event *event, static void armv7pmu_reset(void *info) { struct arm_pmu *cpu_pmu = (struct arm_pmu *)info; - u32 idx, nb_cnt = cpu_pmu->num_events; + u32 idx, nb_cnt = cpu_pmu->num_events, val; + + if (cpu_pmu->secure_access) { + asm volatile("mrc p15, 0, %0, c1, c1, 1" : "=r" (val)); + val |= ARMV7_SDER_SUNIDEN; + asm volatile("mcr p15, 0, %0, c1, c1, 1" : : "r" (val)); + } /* The counter and interrupt enable registers are unknown at reset. */ for (idx = ARMV7_IDX_CYCLE_COUNTER; idx < nb_cnt; ++idx) { diff --git a/arch/arm/kernel/reboot.c b/arch/arm/kernel/reboot.c index 38269358fd252c6bb93fd58a0478319c436cdfd3..71a2ff9ec4900c58677f12114c85c82e8cfaa575 100644 --- a/arch/arm/kernel/reboot.c +++ b/arch/arm/kernel/reboot.c @@ -50,7 +50,7 @@ static void __soft_restart(void *addr) flush_cache_all(); /* Switch to the identity mapping. */ - phys_reset = (phys_reset_t)(unsigned long)virt_to_idmap(cpu_reset); + phys_reset = (phys_reset_t)virt_to_idmap(cpu_reset); phys_reset((unsigned long)addr); /* Should never get here. */ diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 139791ed473d5264682c004ea2ea7af8ddd28f5d..a28fce0bdbbe11b7a950a3a0943f8362d7124b87 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -430,11 +430,13 @@ static void __init patch_aeabi_idiv(void) pr_info("CPU: div instructions available: patching division code\n"); fn_addr = ((uintptr_t)&__aeabi_uidiv) & ~1; + asm ("" : "+g" (fn_addr)); ((u32 *)fn_addr)[0] = udiv_instruction(); ((u32 *)fn_addr)[1] = bx_lr_instruction(); flush_icache_range(fn_addr, fn_addr + 8); fn_addr = ((uintptr_t)&__aeabi_idiv) & ~1; + asm ("" : "+g" (fn_addr)); ((u32 *)fn_addr)[0] = sdiv_instruction(); ((u32 *)fn_addr)[1] = bx_lr_instruction(); flush_icache_range(fn_addr, fn_addr + 8); diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c index 08b7847bf9124f004d7214c0e9c4dae23c0fffd2..ec279d161b3287e1df5b51702c499a2ac0187054 100644 --- a/arch/arm/kernel/topology.c +++ b/arch/arm/kernel/topology.c @@ -40,7 +40,7 @@ * to run the rebalance_domains for all idle cores and the cpu_capacity can be * updated during this sequence. */ -static DEFINE_PER_CPU(unsigned long, cpu_scale); +static DEFINE_PER_CPU(unsigned long, cpu_scale) = SCHED_CAPACITY_SCALE; unsigned long arch_scale_cpu_capacity(struct sched_domain *sd, int cpu) { @@ -306,8 +306,6 @@ void __init init_cpu_topology(void) cpu_topo->socket_id = -1; cpumask_clear(&cpu_topo->core_sibling); cpumask_clear(&cpu_topo->thread_sibling); - - set_capacity_scale(cpu, SCHED_CAPACITY_SCALE); } smp_wmb(); diff --git a/arch/arm/kernel/vmlinux-xip.lds.S b/arch/arm/kernel/vmlinux-xip.lds.S new file mode 100644 index 0000000000000000000000000000000000000000..cba1ec899a693c85113659c98144c26993b8f350 --- /dev/null +++ b/arch/arm/kernel/vmlinux-xip.lds.S @@ -0,0 +1,316 @@ +/* ld script to make ARM Linux kernel + * taken from the i386 version by Russell King + * Written by Martin Mares + */ + +#include +#include +#include +#include +#include + +#define PROC_INFO \ + . = ALIGN(4); \ + VMLINUX_SYMBOL(__proc_info_begin) = .; \ + *(.proc.info.init) \ + VMLINUX_SYMBOL(__proc_info_end) = .; + +#define IDMAP_TEXT \ + ALIGN_FUNCTION(); \ + VMLINUX_SYMBOL(__idmap_text_start) = .; \ + *(.idmap.text) \ + VMLINUX_SYMBOL(__idmap_text_end) = .; \ + . = ALIGN(PAGE_SIZE); \ + VMLINUX_SYMBOL(__hyp_idmap_text_start) = .; \ + *(.hyp.idmap.text) \ + VMLINUX_SYMBOL(__hyp_idmap_text_end) = .; + +#ifdef CONFIG_HOTPLUG_CPU +#define ARM_CPU_DISCARD(x) +#define ARM_CPU_KEEP(x) x +#else +#define ARM_CPU_DISCARD(x) x +#define ARM_CPU_KEEP(x) +#endif + +#if (defined(CONFIG_SMP_ON_UP) && !defined(CONFIG_DEBUG_SPINLOCK)) || \ + defined(CONFIG_GENERIC_BUG) +#define ARM_EXIT_KEEP(x) x +#define ARM_EXIT_DISCARD(x) +#else +#define ARM_EXIT_KEEP(x) +#define ARM_EXIT_DISCARD(x) x +#endif + +OUTPUT_ARCH(arm) +ENTRY(stext) + +#ifndef __ARMEB__ +jiffies = jiffies_64; +#else +jiffies = jiffies_64 + 4; +#endif + +SECTIONS +{ + /* + * XXX: The linker does not define how output sections are + * assigned to input sections when there are multiple statements + * matching the same input section name. There is no documented + * order of matching. + * + * unwind exit sections must be discarded before the rest of the + * unwind sections get included. + */ + /DISCARD/ : { + *(.ARM.exidx.exit.text) + *(.ARM.extab.exit.text) + ARM_CPU_DISCARD(*(.ARM.exidx.cpuexit.text)) + ARM_CPU_DISCARD(*(.ARM.extab.cpuexit.text)) + ARM_EXIT_DISCARD(EXIT_TEXT) + ARM_EXIT_DISCARD(EXIT_DATA) + EXIT_CALL +#ifndef CONFIG_MMU + *(.text.fixup) + *(__ex_table) +#endif +#ifndef CONFIG_SMP_ON_UP + *(.alt.smp.init) +#endif + *(.discard) + *(.discard.*) + } + + . = XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR); + _xiprom = .; /* XIP ROM area to be mapped */ + + .head.text : { + _text = .; + HEAD_TEXT + } + + .text : { /* Real text segment */ + _stext = .; /* Text and read-only data */ + IDMAP_TEXT + __exception_text_start = .; + *(.exception.text) + __exception_text_end = .; + IRQENTRY_TEXT + TEXT_TEXT + SCHED_TEXT + LOCK_TEXT + KPROBES_TEXT + *(.gnu.warning) + *(.glue_7) + *(.glue_7t) + . = ALIGN(4); + *(.got) /* Global offset table */ + ARM_CPU_KEEP(PROC_INFO) + } + + RO_DATA(PAGE_SIZE) + + . = ALIGN(4); + __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { + __start___ex_table = .; +#ifdef CONFIG_MMU + *(__ex_table) +#endif + __stop___ex_table = .; + } + +#ifdef CONFIG_ARM_UNWIND + /* + * Stack unwinding tables + */ + . = ALIGN(8); + .ARM.unwind_idx : { + __start_unwind_idx = .; + *(.ARM.exidx*) + __stop_unwind_idx = .; + } + .ARM.unwind_tab : { + __start_unwind_tab = .; + *(.ARM.extab*) + __stop_unwind_tab = .; + } +#endif + + NOTES + + _etext = .; /* End of text and rodata section */ + + /* + * The vectors and stubs are relocatable code, and the + * only thing that matters is their relative offsets + */ + __vectors_start = .; + .vectors 0xffff0000 : AT(__vectors_start) { + *(.vectors) + } + . = __vectors_start + SIZEOF(.vectors); + __vectors_end = .; + + __stubs_start = .; + .stubs ADDR(.vectors) + 0x1000 : AT(__stubs_start) { + *(.stubs) + } + . = __stubs_start + SIZEOF(.stubs); + __stubs_end = .; + + PROVIDE(vector_fiq_offset = vector_fiq - ADDR(.vectors)); + + INIT_TEXT_SECTION(8) + .exit.text : { + ARM_EXIT_KEEP(EXIT_TEXT) + } + .init.proc.info : { + ARM_CPU_DISCARD(PROC_INFO) + } + .init.arch.info : { + __arch_info_begin = .; + *(.arch.info.init) + __arch_info_end = .; + } + .init.tagtable : { + __tagtable_begin = .; + *(.taglist.init) + __tagtable_end = .; + } +#ifdef CONFIG_SMP_ON_UP + .init.smpalt : { + __smpalt_begin = .; + *(.alt.smp.init) + __smpalt_end = .; + } +#endif + .init.pv_table : { + __pv_table_begin = .; + *(.pv_table) + __pv_table_end = .; + } + .init.data : { + INIT_SETUP(16) + INIT_CALLS + CON_INITCALL + SECURITY_INITCALL + INIT_RAM_FS + } + +#ifdef CONFIG_SMP + PERCPU_SECTION(L1_CACHE_BYTES) +#endif + + _exiprom = .; /* End of XIP ROM area */ + __data_loc = ALIGN(4); /* location in binary */ + . = PAGE_OFFSET + TEXT_OFFSET; + + .data : AT(__data_loc) { + _data = .; /* address in memory */ + _sdata = .; + + /* + * first, the init task union, aligned + * to an 8192 byte boundary. + */ + INIT_TASK_DATA(THREAD_SIZE) + + . = ALIGN(PAGE_SIZE); + __init_begin = .; + INIT_DATA + ARM_EXIT_KEEP(EXIT_DATA) + . = ALIGN(PAGE_SIZE); + __init_end = .; + + NOSAVE_DATA + CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES) + READ_MOSTLY_DATA(L1_CACHE_BYTES) + + /* + * and the usual data section + */ + DATA_DATA + CONSTRUCTORS + + _edata = .; + } + _edata_loc = __data_loc + SIZEOF(.data); + +#ifdef CONFIG_HAVE_TCM + /* + * We align everything to a page boundary so we can + * free it after init has commenced and TCM contents have + * been copied to its destination. + */ + .tcm_start : { + . = ALIGN(PAGE_SIZE); + __tcm_start = .; + __itcm_start = .; + } + + /* + * Link these to the ITCM RAM + * Put VMA to the TCM address and LMA to the common RAM + * and we'll upload the contents from RAM to TCM and free + * the used RAM after that. + */ + .text_itcm ITCM_OFFSET : AT(__itcm_start) + { + __sitcm_text = .; + *(.tcm.text) + *(.tcm.rodata) + . = ALIGN(4); + __eitcm_text = .; + } + + /* + * Reset the dot pointer, this is needed to create the + * relative __dtcm_start below (to be used as extern in code). + */ + . = ADDR(.tcm_start) + SIZEOF(.tcm_start) + SIZEOF(.text_itcm); + + .dtcm_start : { + __dtcm_start = .; + } + + /* TODO: add remainder of ITCM as well, that can be used for data! */ + .data_dtcm DTCM_OFFSET : AT(__dtcm_start) + { + . = ALIGN(4); + __sdtcm_data = .; + *(.tcm.data) + . = ALIGN(4); + __edtcm_data = .; + } + + /* Reset the dot pointer or the linker gets confused */ + . = ADDR(.dtcm_start) + SIZEOF(.data_dtcm); + + /* End marker for freeing TCM copy in linked object */ + .tcm_end : AT(ADDR(.dtcm_start) + SIZEOF(.data_dtcm)){ + . = ALIGN(PAGE_SIZE); + __tcm_end = .; + } +#endif + + BSS_SECTION(0, 0, 0) + _end = .; + + STABS_DEBUG +} + +/* + * These must never be empty + * If you have to comment these two assert statements out, your + * binutils is too old (for other reasons as well) + */ +ASSERT((__proc_info_end - __proc_info_begin), "missing CPU support") +ASSERT((__arch_info_end - __arch_info_begin), "no machine record defined") + +/* + * The HYP init code can't be more than a page long, + * and should not cross a page boundary. + * The above comment applies as well. + */ +ASSERT(__hyp_idmap_text_end - (__hyp_idmap_text_start & PAGE_MASK) <= PAGE_SIZE, + "HYP init code too big or misaligned") diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index b4139cbbbdd9830e7a4b74d9e306094bd1fe78b6..e2c6da096cefa491669ae8b4464b89f6df5f0a75 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S @@ -3,14 +3,16 @@ * Written by Martin Mares */ +#ifdef CONFIG_XIP_KERNEL +#include "vmlinux-xip.lds.S" +#else + #include #include #include #include #include -#ifdef CONFIG_ARM_KERNMEM_PERMS #include -#endif #define PROC_INFO \ . = ALIGN(4); \ @@ -89,17 +91,13 @@ SECTIONS *(.discard.*) } -#ifdef CONFIG_XIP_KERNEL - . = XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR); -#else . = PAGE_OFFSET + TEXT_OFFSET; -#endif .head.text : { _text = .; HEAD_TEXT } -#ifdef CONFIG_ARM_KERNMEM_PERMS +#ifdef CONFIG_DEBUG_RODATA . = ALIGN(1< +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define ARTPEC6_DMACFG_REGNUM 0x10 +#define ARTPEC6_DMACFG_UARTS_BURST 0xff + +#define SECURE_OP_L2C_WRITEREG 0xb4000001 + +static void __init artpec6_init_machine(void) +{ + struct regmap *regmap; + + regmap = syscon_regmap_lookup_by_compatible("axis,artpec6-syscon"); + + if (!IS_ERR(regmap)) { + /* Use PL011 DMA Burst Request signal instead of DMA + * Single Request + */ + regmap_write(regmap, ARTPEC6_DMACFG_REGNUM, + ARTPEC6_DMACFG_UARTS_BURST); + }; + + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); +} + +static void artpec6_l2c310_write_sec(unsigned long val, unsigned reg) +{ + struct arm_smccc_res res; + + arm_smccc_smc(SECURE_OP_L2C_WRITEREG, reg, val, 0, + 0, 0, 0, 0, &res); + + WARN_ON(res.a0); +} + +static const char * const artpec6_dt_match[] = { + "axis,artpec6", + NULL +}; + +DT_MACHINE_START(ARTPEC6, "Axis ARTPEC-6 Platform") + .l2c_aux_val = 0x0C000000, + .l2c_aux_mask = 0xF3FFFFFF, + .l2c_write_sec = artpec6_l2c310_write_sec, + .init_machine = artpec6_init_machine, + .dt_compat = artpec6_dt_match, +MACHINE_END diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 23be2e43309771634d7602af2a16a2f9432edd84..08047afdf38ea63b683f5d28eff4d2c472b343a5 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -104,6 +104,7 @@ config HAVE_AT91_USB_CLK config COMMON_CLK_AT91 bool select COMMON_CLK + select MFD_SYSCON config HAVE_AT91_SMD bool diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c index c1a7c6cc00e10de1fd28f76b01c399fb4de43b61..63b4fa25b48a814f1d40caeeb3be8ad9868d0d10 100644 --- a/arch/arm/mach-at91/at91rm9200.c +++ b/arch/arm/mach-at91/at91rm9200.c @@ -12,7 +12,6 @@ #include #include -#include #include "generic.h" #include "soc.h" @@ -33,7 +32,6 @@ static void __init at91rm9200_dt_device_init(void) of_platform_populate(NULL, of_default_bus_match_table, NULL, soc_dev); - arm_pm_idle = at91rm9200_idle; at91rm9200_pm_init(); } diff --git a/arch/arm/mach-at91/at91sam9.c b/arch/arm/mach-at91/at91sam9.c index 7eb64f763034fa9122ca247acddee337bb5d87e3..cada2a6412b3ba696e36a70b29568153770deea3 100644 --- a/arch/arm/mach-at91/at91sam9.c +++ b/arch/arm/mach-at91/at91sam9.c @@ -62,8 +62,6 @@ static void __init at91sam9_common_init(void) soc_dev = soc_device_to_device(soc); of_platform_populate(NULL, of_default_bus_match_table, NULL, soc_dev); - - arm_pm_idle = at91sam9_idle; } static void __init at91sam9_dt_device_init(void) diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h index b0fa7dc7286d9dc120a79c77be70fe0adb365910..28ca57a2060f060f4b86b5c5d74a82c76e4a7371 100644 --- a/arch/arm/mach-at91/generic.h +++ b/arch/arm/mach-at91/generic.h @@ -11,27 +11,18 @@ #ifndef _AT91_GENERIC_H #define _AT91_GENERIC_H -#include -#include - - /* Map io */ -extern void __init at91_map_io(void); -extern void __init at91_alt_map_io(void); - -/* idle */ -extern void at91rm9200_idle(void); -extern void at91sam9_idle(void); - #ifdef CONFIG_PM extern void __init at91rm9200_pm_init(void); extern void __init at91sam9260_pm_init(void); extern void __init at91sam9g45_pm_init(void); extern void __init at91sam9x5_pm_init(void); +extern void __init sama5_pm_init(void); #else static inline void __init at91rm9200_pm_init(void) { } static inline void __init at91sam9260_pm_init(void) { } static inline void __init at91sam9g45_pm_init(void) { } static inline void __init at91sam9x5_pm_init(void) { } +static inline void __init sama5_pm_init(void) { } #endif #endif /* _AT91_GENERIC_H */ diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 23726fb31741ea1479733ef91e88ac5585f7fe52..f06270198bf1267fbcc0f28d88a18f6b13b1ad8a 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -31,10 +31,13 @@ #include #include #include +#include #include "generic.h" #include "pm.h" +static void __iomem *pmc; + /* * FIXME: this is needed to communicate between the pinctrl driver and * the PM implementation in the machine. Possibly part of the PM @@ -87,7 +90,7 @@ static int at91_pm_verify_clocks(void) unsigned long scsr; int i; - scsr = at91_pmc_read(AT91_PMC_SCSR); + scsr = readl(pmc + AT91_PMC_SCSR); /* USB must not be using PLLB */ if ((scsr & at91_pm_data.uhp_udp_mask) != 0) { @@ -101,8 +104,7 @@ static int at91_pm_verify_clocks(void) if ((scsr & (AT91_PMC_PCK0 << i)) == 0) continue; - - css = at91_pmc_read(AT91_PMC_PCKR(i)) & AT91_PMC_CSS; + css = readl(pmc + AT91_PMC_PCKR(i)) & AT91_PMC_CSS; if (css != AT91_PMC_CSS_SLOW) { pr_err("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css); return 0; @@ -145,8 +147,8 @@ static void at91_pm_suspend(suspend_state_t state) flush_cache_all(); outer_disable(); - at91_suspend_sram_fn(at91_pmc_base, at91_ramc_base[0], - at91_ramc_base[1], pm_data); + at91_suspend_sram_fn(pmc, at91_ramc_base[0], + at91_ramc_base[1], pm_data); outer_resume(); } @@ -353,6 +355,21 @@ static __init void at91_dt_ramc(void) at91_pm_set_standby(standby); } +void at91rm9200_idle(void) +{ + /* + * Disable the processor clock. The processor will be automatically + * re-enabled by an interrupt or by a reset. + */ + writel(AT91_PMC_PCK, pmc + AT91_PMC_SCDR); +} + +void at91sam9_idle(void) +{ + writel(AT91_PMC_PCK, pmc + AT91_PMC_SCDR); + cpu_do_idle(); +} + static void __init at91_pm_sram_init(void) { struct gen_pool *sram_pool; @@ -399,13 +416,36 @@ static void __init at91_pm_sram_init(void) &at91_pm_suspend_in_sram, at91_pm_suspend_in_sram_sz); } -static void __init at91_pm_init(void) +static const struct of_device_id atmel_pmc_ids[] __initconst = { + { .compatible = "atmel,at91rm9200-pmc" }, + { .compatible = "atmel,at91sam9260-pmc" }, + { .compatible = "atmel,at91sam9g45-pmc" }, + { .compatible = "atmel,at91sam9n12-pmc" }, + { .compatible = "atmel,at91sam9x5-pmc" }, + { .compatible = "atmel,sama5d3-pmc" }, + { .compatible = "atmel,sama5d2-pmc" }, + { /* sentinel */ }, +}; + +static void __init at91_pm_init(void (*pm_idle)(void)) { - at91_pm_sram_init(); + struct device_node *pmc_np; if (at91_cpuidle_device.dev.platform_data) platform_device_register(&at91_cpuidle_device); + pmc_np = of_find_matching_node(NULL, atmel_pmc_ids); + pmc = of_iomap(pmc_np, 0); + if (!pmc) { + pr_err("AT91: PM not supported, PMC not found\n"); + return; + } + + if (pm_idle) + arm_pm_idle = pm_idle; + + at91_pm_sram_init(); + if (at91_suspend_sram_fn) suspend_set_ops(&at91_pm_ops); else @@ -424,7 +464,7 @@ void __init at91rm9200_pm_init(void) at91_pm_data.uhp_udp_mask = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP; at91_pm_data.memctrl = AT91_MEMCTRL_MC; - at91_pm_init(); + at91_pm_init(at91rm9200_idle); } void __init at91sam9260_pm_init(void) @@ -432,7 +472,7 @@ void __init at91sam9260_pm_init(void) at91_dt_ramc(); at91_pm_data.memctrl = AT91_MEMCTRL_SDRAMC; at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP; - return at91_pm_init(); + at91_pm_init(at91sam9_idle); } void __init at91sam9g45_pm_init(void) @@ -440,7 +480,7 @@ void __init at91sam9g45_pm_init(void) at91_dt_ramc(); at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP; at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR; - return at91_pm_init(); + at91_pm_init(at91sam9_idle); } void __init at91sam9x5_pm_init(void) @@ -448,5 +488,13 @@ void __init at91sam9x5_pm_init(void) at91_dt_ramc(); at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP; at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR; - return at91_pm_init(); + at91_pm_init(at91sam9_idle); +} + +void __init sama5_pm_init(void) +{ + at91_dt_ramc(); + at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP; + at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR; + at91_pm_init(NULL); } diff --git a/arch/arm/mach-at91/sama5.c b/arch/arm/mach-at91/sama5.c index d9cf6799aec00d31b4974b00fddb6a956c17f205..df8fdf1cf66d63140a4ac6acd700c3fedb3ab71f 100644 --- a/arch/arm/mach-at91/sama5.c +++ b/arch/arm/mach-at91/sama5.c @@ -51,7 +51,7 @@ static void __init sama5_dt_device_init(void) soc_dev = soc_device_to_device(soc); of_platform_populate(NULL, of_default_bus_match_table, NULL, soc_dev); - at91sam9x5_pm_init(); + sama5_pm_init(); } static const char *const sama5_dt_board_compat[] __initconst = { diff --git a/arch/arm/mach-bcm/bcm63xx_pmb.c b/arch/arm/mach-bcm/bcm63xx_pmb.c index de061ec5a47964c99cba838bac515fba48b475eb..41dcf5d65630cfe96da9480e4e0496b19b27d9ae 100644 --- a/arch/arm/mach-bcm/bcm63xx_pmb.c +++ b/arch/arm/mach-bcm/bcm63xx_pmb.c @@ -92,7 +92,6 @@ static int bcm63xx_pmb_get_resources(struct device_node *dn, unsigned int *cpu, unsigned int *addr) { - struct device_node *pmb_dn; struct of_phandle_args args; int ret; @@ -109,7 +108,6 @@ static int bcm63xx_pmb_get_resources(struct device_node *dn, return ret; } - pmb_dn = args.np; if (args.args_count != 2) { pr_err("reset-controller does not conform to reset-cells\n"); return -EINVAL; diff --git a/arch/arm/mach-bcm/platsmp.c b/arch/arm/mach-bcm/platsmp.c index 575defcc53f932f9af463805dc88cf327802df2e..cfae9c71fb7415e82e956952cf3f9d5431625982 100644 --- a/arch/arm/mach-bcm/platsmp.c +++ b/arch/arm/mach-bcm/platsmp.c @@ -283,7 +283,7 @@ static const struct smp_operations bcm_smp_ops __initconst = { CPU_METHOD_OF_DECLARE(bcm_smp_bcm281xx, "brcm,bcm11351-cpu-method", &bcm_smp_ops); -struct smp_operations nsp_smp_ops __initdata = { +static const struct smp_operations nsp_smp_ops __initconst = { .smp_prepare_cpus = bcm_smp_prepare_cpus, .smp_boot_secondary = nsp_boot_secondary, }; diff --git a/arch/arm/mach-cns3xxx/Makefile.boot b/arch/arm/mach-cns3xxx/Makefile.boot deleted file mode 100644 index d079de0b6e3b54b5e9c3ad2581690bf5320c1e9c..0000000000000000000000000000000000000000 --- a/arch/arm/mach-cns3xxx/Makefile.boot +++ /dev/null @@ -1,3 +0,0 @@ - zreladdr-y += 0x00008000 -params_phys-y := 0x00000100 -initrd_phys-y := 0x00C00000 diff --git a/arch/arm/mach-cns3xxx/cns3xxx.h b/arch/arm/mach-cns3xxx/cns3xxx.h index a0f5b60662ae50b38736674b04e7004b894cbe45..a642ba5feb6476f1cffb26a41a2946e131c69b04 100644 --- a/arch/arm/mach-cns3xxx/cns3xxx.h +++ b/arch/arm/mach-cns3xxx/cns3xxx.h @@ -162,13 +162,11 @@ #define CNS3XXX_L2C_BASE 0x92000000 /* L2 Cache Control */ #define CNS3XXX_PCIE0_MEM_BASE 0xA0000000 /* PCIe Port 0 IO/Memory Space */ -#define CNS3XXX_PCIE0_MEM_BASE_VIRT 0xE0000000 #define CNS3XXX_PCIE0_HOST_BASE 0xAB000000 /* PCIe Port 0 RC Base */ #define CNS3XXX_PCIE0_HOST_BASE_VIRT 0xE1000000 #define CNS3XXX_PCIE0_IO_BASE 0xAC000000 /* PCIe Port 0 */ -#define CNS3XXX_PCIE0_IO_BASE_VIRT 0xE2000000 #define CNS3XXX_PCIE0_CFG0_BASE 0xAD000000 /* PCIe Port 0 CFG Type 0 */ #define CNS3XXX_PCIE0_CFG0_BASE_VIRT 0xE3000000 @@ -177,16 +175,13 @@ #define CNS3XXX_PCIE0_CFG1_BASE_VIRT 0xE4000000 #define CNS3XXX_PCIE0_MSG_BASE 0xAF000000 /* PCIe Port 0 Message Space */ -#define CNS3XXX_PCIE0_MSG_BASE_VIRT 0xE5000000 #define CNS3XXX_PCIE1_MEM_BASE 0xB0000000 /* PCIe Port 1 IO/Memory Space */ -#define CNS3XXX_PCIE1_MEM_BASE_VIRT 0xE8000000 #define CNS3XXX_PCIE1_HOST_BASE 0xBB000000 /* PCIe Port 1 RC Base */ #define CNS3XXX_PCIE1_HOST_BASE_VIRT 0xE9000000 #define CNS3XXX_PCIE1_IO_BASE 0xBC000000 /* PCIe Port 1 */ -#define CNS3XXX_PCIE1_IO_BASE_VIRT 0xEA000000 #define CNS3XXX_PCIE1_CFG0_BASE 0xBD000000 /* PCIe Port 1 CFG Type 0 */ #define CNS3XXX_PCIE1_CFG0_BASE_VIRT 0xEB000000 @@ -195,7 +190,6 @@ #define CNS3XXX_PCIE1_CFG1_BASE_VIRT 0xEC000000 #define CNS3XXX_PCIE1_MSG_BASE 0xBF000000 /* PCIe Port 1 Message Space */ -#define CNS3XXX_PCIE1_MSG_BASE_VIRT 0xED000000 /* * Testchip peripheral and fpga gic regions diff --git a/arch/arm/mach-cns3xxx/pcie.c b/arch/arm/mach-cns3xxx/pcie.c index 47905a50e0757e94c1300ec98a3924d9a51b7a5b..318394ed5c7a97c2923c8c35134b88cb188ef238 100644 --- a/arch/arm/mach-cns3xxx/pcie.c +++ b/arch/arm/mach-cns3xxx/pcie.c @@ -220,13 +220,13 @@ static void cns3xxx_write_config(struct cns3xxx_pcie *cnspci, u32 mask = (0x1ull << (size * 8)) - 1; int shift = (where % 4) * 8; - v = readl_relaxed(base + (where & 0xffc)); + v = readl_relaxed(base); v &= ~(mask << shift); v |= (val & mask) << shift; - writel_relaxed(v, base + (where & 0xffc)); - readl_relaxed(base + (where & 0xffc)); + writel_relaxed(v, base); + readl_relaxed(base); } static void __init cns3xxx_pcie_hw_init(struct cns3xxx_pcie *cnspci) diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig index bcaf1d0255057ed02353b21028064001e0a1c2ef..36c8f5324e4383b270f71791a7bdafb46610fea1 100644 --- a/arch/arm/mach-davinci/Kconfig +++ b/arch/arm/mach-davinci/Kconfig @@ -9,7 +9,6 @@ config CP_INTC config ARCH_DAVINCI_DMx bool - select CPU_ARM926T menu "TI DaVinci Implementations" @@ -32,7 +31,7 @@ config ARCH_DAVINCI_DM646x config ARCH_DAVINCI_DA830 bool "DA830/OMAP-L137/AM17x based system" - depends on !ARCH_DAVINCI_DMx || AUTO_ZRELADDR + depends on !ARCH_DAVINCI_DMx || (AUTO_ZRELADDR && ARM_PATCH_PHYS_VIRT) select ARCH_DAVINCI_DA8XX # needed on silicon revs 1.0, 1.1: select CPU_DCACHE_WRITETHROUGH if !CPU_DCACHE_DISABLE @@ -40,13 +39,12 @@ config ARCH_DAVINCI_DA830 config ARCH_DAVINCI_DA850 bool "DA850/OMAP-L138/AM18x based system" - depends on !ARCH_DAVINCI_DMx || AUTO_ZRELADDR + depends on !ARCH_DAVINCI_DMx || (AUTO_ZRELADDR && ARM_PATCH_PHYS_VIRT) select ARCH_DAVINCI_DA8XX select CP_INTC config ARCH_DAVINCI_DA8XX bool - select CPU_ARM926T config ARCH_DAVINCI_DM365 bool "DaVinci 365 based system" @@ -58,7 +56,7 @@ comment "DaVinci Board Type" config MACH_DA8XX_DT bool "Support DA8XX platforms using device tree" default y - depends on ARCH_DAVINCI_DA8XX + depends on ARCH_DAVINCI_DA850 select PINCTRL help Say y here to include support for TI DaVinci DA850 based using @@ -68,8 +66,6 @@ config MACH_DAVINCI_EVM bool "TI DM644x EVM" default ARCH_DAVINCI_DM644x depends on ARCH_DAVINCI_DM644x - select EEPROM_AT24 - select I2C help Configure this option to specify the whether the board used for development is a DM644x EVM @@ -77,8 +73,6 @@ config MACH_DAVINCI_EVM config MACH_SFFSDR bool "Lyrtech SFFSDR" depends on ARCH_DAVINCI_DM644x - select EEPROM_AT24 - select I2C help Say Y here to select the Lyrtech Small Form Factor Software Defined Radio (SFFSDR) board. @@ -109,8 +103,6 @@ config MACH_DAVINCI_DM6467_EVM bool "TI DM6467 EVM" default ARCH_DAVINCI_DM646x depends on ARCH_DAVINCI_DM646x - select EEPROM_AT24 - select I2C select MACH_DAVINCI_DM6467TEVM help Configure this option to specify the whether the board used @@ -123,8 +115,6 @@ config MACH_DAVINCI_DM365_EVM bool "TI DM365 EVM" default ARCH_DAVINCI_DM365 depends on ARCH_DAVINCI_DM365 - select EEPROM_AT24 - select I2C help Configure this option to specify whether the board used for development is a DM365 EVM @@ -133,9 +123,7 @@ config MACH_DAVINCI_DA830_EVM bool "TI DA830/OMAP-L137/AM17x Reference Platform" default ARCH_DAVINCI_DA830 depends on ARCH_DAVINCI_DA830 - select EEPROM_AT24 - select GPIO_PCF857X - select I2C + select GPIO_PCF857X if I2C help Say Y here to select the TI DA830/OMAP-L137/AM17x Evaluation Module. @@ -204,8 +192,6 @@ endchoice config MACH_MITYOMAPL138 bool "Critical Link MityDSP-L138/MityARM-1808 SoM" depends on ARCH_DAVINCI_DA850 - select EEPROM_AT24 - select I2C help Say Y here to select the Critical Link MityDSP-L138/MityARM-1808 System on Module. Information on this SoM may be found at diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index 7a20507a3eefb3a6197afd1861286922184b67a2..68cc099078289262d938e974b7aa7ad77ac12ddc 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c @@ -267,7 +267,7 @@ static struct platform_device rtc_dev = { static struct snd_platform_data dm644x_evm_snd_data; /*----------------------------------------------------------------------*/ - +#ifdef CONFIG_I2C /* * I2C GPIO expanders */ @@ -612,6 +612,7 @@ static void __init evm_init_i2c(void) i2c_add_driver(&dm6446evm_msp_driver); i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info)); } +#endif #define VENC_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL) @@ -780,7 +781,9 @@ static __init void davinci_evm_init(void) pr_warn("%s: Cannot configure AEMIF\n", __func__); +#ifdef CONFIG_I2C evm_leds[7].default_trigger = "nand-disk"; +#endif if (HAS_NOR) pr_warn("WARNING: both NAND and NOR flash are enabled; disable one of them.\n"); } else if (HAS_NOR) @@ -789,9 +792,10 @@ static __init void davinci_evm_init(void) platform_add_devices(davinci_evm_devices, ARRAY_SIZE(davinci_evm_devices)); +#ifdef CONFIG_I2C evm_init_i2c(); - davinci_setup_mmc(0, &dm6446evm_mmc_config); +#endif dm644x_init_video(&dm644xevm_capture_cfg, &dm644xevm_display_cfg); davinci_serial_init(dm644x_serial_device); diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c index ee6ab7e8d3b0cdf7b54399e399550609d0e9301e..f702d4fc8eb81d47ce02ea93d5472d298723158b 100644 --- a/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/arch/arm/mach-davinci/board-dm646x-evm.c @@ -121,6 +121,7 @@ static struct platform_device davinci_nand_device = { #define HAS_ATA IS_ENABLED(CONFIG_BLK_DEV_PALMCHIP_BK3710) +#ifdef CONFIG_I2C /* CPLD Register 0 bits to control ATA */ #define DM646X_EVM_ATA_RST BIT(0) #define DM646X_EVM_ATA_PWD BIT(1) @@ -316,6 +317,7 @@ static struct at24_platform_data eeprom_info = { .setup = davinci_get_mac_addr, .context = (void *)0x7f00, }; +#endif static u8 dm646x_iis_serializer_direction[] = { TX_MODE, RX_MODE, INACTIVE_MODE, INACTIVE_MODE, @@ -346,6 +348,7 @@ static struct snd_platform_data dm646x_evm_snd_data[] = { }, }; +#ifdef CONFIG_I2C static struct i2c_client *cpld_client; static int cpld_video_probe(struct i2c_client *client, @@ -710,6 +713,7 @@ static void __init evm_init_i2c(void) evm_init_cpld(); evm_init_video(); } +#endif #define DM6467T_EVM_REF_FREQ 33000000 @@ -764,7 +768,10 @@ static __init void evm_init(void) if (ret) pr_warn("%s: GPIO init failed: %d\n", __func__, ret); +#ifdef CONFIG_I2C evm_init_i2c(); +#endif + davinci_serial_init(dm646x_serial_device); dm646x_init_mcasp0(&dm646x_evm_snd_data[0]); dm646x_init_mcasp1(&dm646x_evm_snd_data[1]); diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c index 62ebac51bab93c0d40edaf5358e46088ee5ebb9a..d97c588550ad467775dfe8b05487eb03d540c2f4 100644 --- a/arch/arm/mach-davinci/board-mityomapl138.c +++ b/arch/arm/mach-davinci/board-mityomapl138.c @@ -51,6 +51,7 @@ struct factory_config { static struct factory_config factory_config; +#ifdef CONFIG_CPU_FREQ struct part_no_info { const char *part_no; /* part number string of interest */ int max_freq; /* khz */ @@ -87,7 +88,6 @@ static struct part_no_info mityomapl138_pn_info[] = { }, }; -#ifdef CONFIG_CPU_FREQ static void mityomapl138_cpufreq_init(const char *partnum) { int i, ret; diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c index e88b7a5cde99460b92824a4881e3baaf75d9a2b5..725e693639d24a71046f63348515e3457d1347c4 100644 --- a/arch/arm/mach-davinci/devices-da8xx.c +++ b/arch/arm/mach-davinci/devices-da8xx.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -233,16 +234,54 @@ static const struct platform_device_info da850_edma1_device __initconst = { .size_data = sizeof(da850_edma1_pdata), }; +static const struct dma_slave_map da830_edma_map[] = { + { "davinci-mcasp.0", "rx", EDMA_FILTER_PARAM(0, 0) }, + { "davinci-mcasp.0", "tx", EDMA_FILTER_PARAM(0, 1) }, + { "davinci-mcasp.1", "rx", EDMA_FILTER_PARAM(0, 2) }, + { "davinci-mcasp.1", "tx", EDMA_FILTER_PARAM(0, 3) }, + { "davinci-mcasp.2", "rx", EDMA_FILTER_PARAM(0, 4) }, + { "davinci-mcasp.2", "tx", EDMA_FILTER_PARAM(0, 5) }, + { "spi_davinci.0", "rx", EDMA_FILTER_PARAM(0, 14) }, + { "spi_davinci.0", "tx", EDMA_FILTER_PARAM(0, 15) }, + { "da830-mmc.0", "rx", EDMA_FILTER_PARAM(0, 16) }, + { "da830-mmc.0", "tx", EDMA_FILTER_PARAM(0, 17) }, + { "spi_davinci.1", "rx", EDMA_FILTER_PARAM(0, 18) }, + { "spi_davinci.1", "tx", EDMA_FILTER_PARAM(0, 19) }, +}; + int __init da830_register_edma(struct edma_rsv_info *rsv) { struct platform_device *edma_pdev; da8xx_edma0_pdata.rsv = rsv; + da8xx_edma0_pdata.slave_map = da830_edma_map; + da8xx_edma0_pdata.slavecnt = ARRAY_SIZE(da830_edma_map); + edma_pdev = platform_device_register_full(&da8xx_edma0_device); return IS_ERR(edma_pdev) ? PTR_ERR(edma_pdev) : 0; } +static const struct dma_slave_map da850_edma0_map[] = { + { "davinci-mcasp.0", "rx", EDMA_FILTER_PARAM(0, 0) }, + { "davinci-mcasp.0", "tx", EDMA_FILTER_PARAM(0, 1) }, + { "davinci-mcbsp.0", "rx", EDMA_FILTER_PARAM(0, 2) }, + { "davinci-mcbsp.0", "tx", EDMA_FILTER_PARAM(0, 3) }, + { "davinci-mcbsp.1", "rx", EDMA_FILTER_PARAM(0, 4) }, + { "davinci-mcbsp.1", "tx", EDMA_FILTER_PARAM(0, 5) }, + { "spi_davinci.0", "rx", EDMA_FILTER_PARAM(0, 14) }, + { "spi_davinci.0", "tx", EDMA_FILTER_PARAM(0, 15) }, + { "da830-mmc.0", "rx", EDMA_FILTER_PARAM(0, 16) }, + { "da830-mmc.0", "tx", EDMA_FILTER_PARAM(0, 17) }, + { "spi_davinci.1", "rx", EDMA_FILTER_PARAM(0, 18) }, + { "spi_davinci.1", "tx", EDMA_FILTER_PARAM(0, 19) }, +}; + +static const struct dma_slave_map da850_edma1_map[] = { + { "da830-mmc.1", "rx", EDMA_FILTER_PARAM(1, 28) }, + { "da830-mmc.1", "tx", EDMA_FILTER_PARAM(1, 29) }, +}; + int __init da850_register_edma(struct edma_rsv_info *rsv[2]) { struct platform_device *edma_pdev; @@ -252,11 +291,18 @@ int __init da850_register_edma(struct edma_rsv_info *rsv[2]) da850_edma1_pdata.rsv = rsv[1]; } + da8xx_edma0_pdata.slave_map = da850_edma0_map; + da8xx_edma0_pdata.slavecnt = ARRAY_SIZE(da850_edma0_map); + edma_pdev = platform_device_register_full(&da8xx_edma0_device); if (IS_ERR(edma_pdev)) { pr_warn("%s: Failed to register eDMA0\n", __func__); return PTR_ERR(edma_pdev); } + + da850_edma1_pdata.slave_map = da850_edma1_map; + da850_edma1_pdata.slavecnt = ARRAY_SIZE(da850_edma1_map); + edma_pdev = platform_device_register_full(&da850_edma1_device); return IS_ERR(edma_pdev) ? PTR_ERR(edma_pdev) : 0; } diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index c7c1458df23cfbf306fffe2bfe1a0b2c5646c817..a0ecf499c2f227df04749df7cf477f5ae54a15d7 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -576,9 +577,28 @@ static s8 queue_priority_mapping[][2] = { {-1, -1}, }; +static const struct dma_slave_map dm355_edma_map[] = { + { "davinci-mcbsp.0", "tx", EDMA_FILTER_PARAM(0, 2) }, + { "davinci-mcbsp.0", "rx", EDMA_FILTER_PARAM(0, 3) }, + { "davinci-mcbsp.1", "tx", EDMA_FILTER_PARAM(0, 8) }, + { "davinci-mcbsp.1", "rx", EDMA_FILTER_PARAM(0, 9) }, + { "spi_davinci.2", "tx", EDMA_FILTER_PARAM(0, 10) }, + { "spi_davinci.2", "rx", EDMA_FILTER_PARAM(0, 11) }, + { "spi_davinci.1", "tx", EDMA_FILTER_PARAM(0, 14) }, + { "spi_davinci.1", "rx", EDMA_FILTER_PARAM(0, 15) }, + { "spi_davinci.0", "tx", EDMA_FILTER_PARAM(0, 16) }, + { "spi_davinci.0", "rx", EDMA_FILTER_PARAM(0, 17) }, + { "dm6441-mmc.0", "rx", EDMA_FILTER_PARAM(0, 26) }, + { "dm6441-mmc.0", "tx", EDMA_FILTER_PARAM(0, 27) }, + { "dm6441-mmc.1", "rx", EDMA_FILTER_PARAM(0, 30) }, + { "dm6441-mmc.1", "tx", EDMA_FILTER_PARAM(0, 31) }, +}; + static struct edma_soc_info dm355_edma_pdata = { .queue_priority_mapping = queue_priority_mapping, .default_queue = EVENTQ_1, + .slave_map = dm355_edma_map, + .slavecnt = ARRAY_SIZE(dm355_edma_map), }; static struct resource edma_resources[] = { diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index 01843fbcc9ea7d99be72e2fad6508b16e04e9ea7..384d3674dd9b196eafcdfec54d1481a36185ff86 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -862,9 +863,30 @@ static s8 dm365_queue_priority_mapping[][2] = { {-1, -1}, }; +static const struct dma_slave_map dm365_edma_map[] = { + { "davinci-mcbsp.0", "tx", EDMA_FILTER_PARAM(0, 2) }, + { "davinci-mcbsp.0", "rx", EDMA_FILTER_PARAM(0, 3) }, + { "davinci_voicecodec", "tx", EDMA_FILTER_PARAM(0, 2) }, + { "davinci_voicecodec", "rx", EDMA_FILTER_PARAM(0, 3) }, + { "spi_davinci.2", "tx", EDMA_FILTER_PARAM(0, 10) }, + { "spi_davinci.2", "rx", EDMA_FILTER_PARAM(0, 11) }, + { "spi_davinci.1", "tx", EDMA_FILTER_PARAM(0, 14) }, + { "spi_davinci.1", "rx", EDMA_FILTER_PARAM(0, 15) }, + { "spi_davinci.0", "tx", EDMA_FILTER_PARAM(0, 16) }, + { "spi_davinci.0", "rx", EDMA_FILTER_PARAM(0, 17) }, + { "spi_davinci.3", "tx", EDMA_FILTER_PARAM(0, 18) }, + { "spi_davinci.3", "rx", EDMA_FILTER_PARAM(0, 19) }, + { "dm6441-mmc.0", "rx", EDMA_FILTER_PARAM(0, 26) }, + { "dm6441-mmc.0", "tx", EDMA_FILTER_PARAM(0, 27) }, + { "dm6441-mmc.1", "rx", EDMA_FILTER_PARAM(0, 30) }, + { "dm6441-mmc.1", "tx", EDMA_FILTER_PARAM(0, 31) }, +}; + static struct edma_soc_info dm365_edma_pdata = { .queue_priority_mapping = dm365_queue_priority_mapping, .default_queue = EVENTQ_3, + .slave_map = dm365_edma_map, + .slavecnt = ARRAY_SIZE(dm365_edma_map), }; static struct resource edma_resources[] = { diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index b28071ae3a571967055bf6023c4c0590753be6a3..b4b3a8b9ca20203391eacee76bcb8aa4bcd58dd7 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -505,9 +506,20 @@ static s8 queue_priority_mapping[][2] = { {-1, -1}, }; +static const struct dma_slave_map dm644x_edma_map[] = { + { "davinci-mcbsp", "tx", EDMA_FILTER_PARAM(0, 2) }, + { "davinci-mcbsp", "rx", EDMA_FILTER_PARAM(0, 3) }, + { "spi_davinci", "tx", EDMA_FILTER_PARAM(0, 16) }, + { "spi_davinci", "rx", EDMA_FILTER_PARAM(0, 17) }, + { "dm6441-mmc.0", "rx", EDMA_FILTER_PARAM(0, 26) }, + { "dm6441-mmc.0", "tx", EDMA_FILTER_PARAM(0, 27) }, +}; + static struct edma_soc_info dm644x_edma_pdata = { .queue_priority_mapping = queue_priority_mapping, .default_queue = EVENTQ_1, + .slave_map = dm644x_edma_map, + .slavecnt = ARRAY_SIZE(dm644x_edma_map), }; static struct resource edma_resources[] = { diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index cf80786e24714a76a5eeca9fa85b3fdc7c6bd789..a43db0f5fbaa7ba33202eff406ab37a92765b48e 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -9,6 +9,7 @@ * or implied. */ #include +#include #include #include #include @@ -540,9 +541,19 @@ static s8 dm646x_queue_priority_mapping[][2] = { {-1, -1}, }; +static const struct dma_slave_map dm646x_edma_map[] = { + { "davinci-mcasp.0", "tx", EDMA_FILTER_PARAM(0, 6) }, + { "davinci-mcasp.0", "rx", EDMA_FILTER_PARAM(0, 9) }, + { "davinci-mcasp.1", "tx", EDMA_FILTER_PARAM(0, 12) }, + { "spi_davinci", "tx", EDMA_FILTER_PARAM(0, 16) }, + { "spi_davinci", "rx", EDMA_FILTER_PARAM(0, 17) }, +}; + static struct edma_soc_info dm646x_edma_pdata = { .queue_priority_mapping = dm646x_queue_priority_mapping, .default_queue = EVENTQ_1, + .slave_map = dm646x_edma_map, + .slavecnt = ARRAY_SIZE(dm646x_edma_map), }; static struct resource edma_resources[] = { diff --git a/arch/arm/mach-davinci/include/mach/uncompress.h b/arch/arm/mach-davinci/include/mach/uncompress.h index 8fb97b93b6bb3d85ab0055c444b44f5fb9612a6e..53b456a5bbe03512275e674325a0533786a3fa6b 100644 --- a/arch/arm/mach-davinci/include/mach/uncompress.h +++ b/arch/arm/mach-davinci/include/mach/uncompress.h @@ -30,7 +30,7 @@ u32 *uart; /* PORT_16C550A, in polled non-fifo mode */ -static void putc(char c) +static inline void putc(char c) { if (!uart) return; diff --git a/arch/arm/mach-dove/Kconfig b/arch/arm/mach-dove/Kconfig index d8c439c89ea93b76849965f08cbeb5149a25bbb8..0bd6d894c5970474799c92c7fca5a1512acbd54c 100644 --- a/arch/arm/mach-dove/Kconfig +++ b/arch/arm/mach-dove/Kconfig @@ -8,7 +8,7 @@ config DOVE_LEGACY config MACH_DOVE_DB bool "Marvell DB-MV88AP510 Development Board" select DOVE_LEGACY - select I2C_BOARDINFO + select I2C_BOARDINFO if I2C help Say 'Y' here if you want your kernel to support the Marvell DB-MV88AP510 Development Board. diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index 652a0bb11578927fc0bbc58983bf5aaafd7eb0d3..207fa2c737a6d3d44a8278bbfab8bbc0b5902cad 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig @@ -5,7 +5,7 @@ # # Licensed under GPLv2 -# Configuration options for the EXYNOS4 +# Configuration options for the EXYNOS menuconfig ARCH_EXYNOS bool "Samsung EXYNOS" @@ -17,6 +17,7 @@ menuconfig ARCH_EXYNOS select ARM_GIC select COMMON_CLK_SAMSUNG select EXYNOS_THERMAL + select EXYNOS_PMU select HAVE_ARM_SCU if SMP select HAVE_S3C2410_I2C if I2C select HAVE_S3C2410_WATCHDOG if WATCHDOG @@ -25,8 +26,10 @@ menuconfig ARCH_EXYNOS select PINCTRL_EXYNOS select PM_GENERIC_DOMAINS if PM select S5P_DEV_MFC + select SOC_SAMSUNG select SRAM select THERMAL + select THERMAL_OF select MFD_SYSCON select CLKSRC_EXYNOS_MCT select POWER_RESET diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile index 2f306767cdfe425b8f522a20fd756310bc5e2fad..34d29df3e0062342af5510d6a46addbe4fb21083 100644 --- a/arch/arm/mach-exynos/Makefile +++ b/arch/arm/mach-exynos/Makefile @@ -9,7 +9,7 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) += -I$(srctree)/$(src)/include -I$(srctree) # Core -obj-$(CONFIG_ARCH_EXYNOS) += exynos.o pmu.o exynos-smc.o firmware.o +obj-$(CONFIG_ARCH_EXYNOS) += exynos.o exynos-smc.o firmware.o obj-$(CONFIG_EXYNOS_CPU_SUSPEND) += pm.o sleep.o obj-$(CONFIG_PM_SLEEP) += suspend.o diff --git a/arch/arm/mach-exynos/Makefile.boot b/arch/arm/mach-exynos/Makefile.boot deleted file mode 100644 index b9862e22bf10a3ecc4ccca0c6e7ece16f3f3a2bb..0000000000000000000000000000000000000000 --- a/arch/arm/mach-exynos/Makefile.boot +++ /dev/null @@ -1,2 +0,0 @@ - zreladdr-y += 0x40008000 -params_phys-y := 0x40000100 diff --git a/arch/arm/mach-exynos/common.h b/arch/arm/mach-exynos/common.h index e349a038976d6172079af5433584803edbb3498b..5365bf1f586a7e21cb2868115a01962c6adaa59d 100644 --- a/arch/arm/mach-exynos/common.h +++ b/arch/arm/mach-exynos/common.h @@ -12,7 +12,6 @@ #ifndef __ARCH_ARM_MACH_EXYNOS_COMMON_H #define __ARCH_ARM_MACH_EXYNOS_COMMON_H -#include #include #define EXYNOS3250_SOC_ID 0xE3472000 diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c index 1c47aee31e9cc60aeabc8c504b41c76c2379a435..bbf51a46f772d3a6d2b8a0e4f1546f783ec97022 100644 --- a/arch/arm/mach-exynos/exynos.c +++ b/arch/arm/mach-exynos/exynos.c @@ -11,29 +11,23 @@ #include #include -#include -#include #include #include #include #include #include -#include #include +#include #include #include #include #include -#include #include #include "common.h" #include "mfc.h" -#include "regs-pmu.h" - -void __iomem *pmu_base_addr; static struct map_desc exynos4_iodesc[] __initdata = { { @@ -70,11 +64,6 @@ static struct map_desc exynos5_iodesc[] __initdata = { .pfn = __phys_to_pfn(EXYNOS5_PA_SROMC), .length = SZ_4K, .type = MT_DEVICE, - }, { - .virtual = (unsigned long)S5P_VA_CMU, - .pfn = __phys_to_pfn(EXYNOS5_PA_CMU), - .length = 144 * SZ_1K, - .type = MT_DEVICE, }, }; @@ -230,6 +219,10 @@ static const struct of_device_id exynos_cpufreq_matches[] = { { .compatible = "samsung,exynos4212", .data = "cpufreq-dt" }, { .compatible = "samsung,exynos4412", .data = "cpufreq-dt" }, { .compatible = "samsung,exynos5250", .data = "cpufreq-dt" }, +#ifndef CONFIG_BL_SWITCHER + { .compatible = "samsung,exynos5420", .data = "cpufreq-dt" }, + { .compatible = "samsung,exynos5800", .data = "cpufreq-dt" }, +#endif { /* sentinel */ } }; diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c index 111cfbf66fdb937829ffaac00d40ce28b777a96d..1bfd1b0bd9dca8a339329cf8d49acfa996f528aa 100644 --- a/arch/arm/mach-exynos/firmware.c +++ b/arch/arm/mach-exynos/firmware.c @@ -20,8 +20,6 @@ #include #include -#include - #include "common.h" #include "smc.h" diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h index de3ae59e1cfbbb4d4d8248224af62243cb23b548..c88325d56743e1be509fdf9c1ce72298f6e94762 100644 --- a/arch/arm/mach-exynos/include/mach/map.h +++ b/arch/arm/mach-exynos/include/mach/map.h @@ -2,7 +2,7 @@ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. * http://www.samsung.com/ * - * EXYNOS4 - Memory map definitions + * EXYNOS - Memory map definitions * * 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 @@ -14,30 +14,18 @@ #include -/* - * EXYNOS4 UART offset is 0x10000 but the older S5P SoCs are 0x400. - * So need to define it, and here is to avoid redefinition warning. - */ -#define S3C_UART_OFFSET (0x10000) - #include #define EXYNOS_PA_CHIPID 0x10000000 #define EXYNOS4_PA_CMU 0x10030000 -#define EXYNOS5_PA_CMU 0x10010000 #define EXYNOS4_PA_DMC0 0x10400000 #define EXYNOS4_PA_DMC1 0x10410000 #define EXYNOS4_PA_COREPERI 0x10500000 -#define EXYNOS4_PA_L2CC 0x10502000 #define EXYNOS4_PA_SROMC 0x12570000 #define EXYNOS5_PA_SROMC 0x12250000 -/* Compatibility UART */ - -#define EXYNOS5440_PA_UART0 0x000B0000 - #endif /* __ASM_ARCH_MAP_H */ diff --git a/arch/arm/mach-exynos/mcpm-exynos.c b/arch/arm/mach-exynos/mcpm-exynos.c index 56978199c4798fa236394c232e50d58a61e4fd3d..f086bf615b2972ee640e61256cba3438c9c9ae2a 100644 --- a/arch/arm/mach-exynos/mcpm-exynos.c +++ b/arch/arm/mach-exynos/mcpm-exynos.c @@ -16,13 +16,13 @@ #include #include #include +#include #include #include #include #include -#include "regs-pmu.h" #include "common.h" #define EXYNOS5420_CPUS_PER_CLUSTER 4 diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c index 5bd9559786ba77d2eade9c29ab1983e8746f4e54..85c3be63d644470775f95a580aab7cd9ec14ea2a 100644 --- a/arch/arm/mach-exynos/platsmp.c +++ b/arch/arm/mach-exynos/platsmp.c @@ -15,11 +15,11 @@ #include #include #include -#include #include #include #include #include +#include #include #include @@ -30,7 +30,6 @@ #include #include "common.h" -#include "regs-pmu.h" extern void exynos4_secondary_startup(void); diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c index 9c1506b499bca6f4599a20ece67494078a95d4d0..c43b776a51a30975ed475b70edd449ddd0b708d1 100644 --- a/arch/arm/mach-exynos/pm.c +++ b/arch/arm/mach-exynos/pm.c @@ -17,7 +17,9 @@ #include #include #include -#include +#include +#include +#include #include #include @@ -26,11 +28,7 @@ #include -#include - #include "common.h" -#include "exynos-pmu.h" -#include "regs-pmu.h" static inline void __iomem *exynos_boot_vector_addr(void) { diff --git a/arch/arm/mach-exynos/pmu.c b/arch/arm/mach-exynos/pmu.c deleted file mode 100644 index dbf9fe98d479a3780590507125e140b59167299f..0000000000000000000000000000000000000000 --- a/arch/arm/mach-exynos/pmu.c +++ /dev/null @@ -1,967 +0,0 @@ -/* - * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * 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 - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include - -#include - -#include "exynos-pmu.h" -#include "regs-pmu.h" - -#define PMU_TABLE_END (-1U) - -struct exynos_pmu_conf { - unsigned int offset; - u8 val[NUM_SYS_POWERDOWN]; -}; - -struct exynos_pmu_data { - const struct exynos_pmu_conf *pmu_config; - const struct exynos_pmu_conf *pmu_config_extra; - - void (*pmu_init)(void); - void (*powerdown_conf)(enum sys_powerdown); - void (*powerdown_conf_extra)(enum sys_powerdown); -}; - -struct exynos_pmu_context { - struct device *dev; - const struct exynos_pmu_data *pmu_data; -}; - -static void __iomem *pmu_base_addr; -static struct exynos_pmu_context *pmu_context; - -static inline void pmu_raw_writel(u32 val, u32 offset) -{ - writel_relaxed(val, pmu_base_addr + offset); -} - -static inline u32 pmu_raw_readl(u32 offset) -{ - return readl_relaxed(pmu_base_addr + offset); -} - -static struct exynos_pmu_conf exynos3250_pmu_config[] = { - /* { .offset = offset, .val = { AFTR, W-AFTR, SLEEP } */ - { EXYNOS3_ARM_CORE0_SYS_PWR_REG, { 0x0, 0x0, 0x2} }, - { EXYNOS3_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS3_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS3_ARM_CORE1_SYS_PWR_REG, { 0x0, 0x0, 0x2} }, - { EXYNOS3_DIS_IRQ_ARM_CORE1_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS3_DIS_IRQ_ARM_CORE1_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS3_ISP_ARM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS3_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS3_ARM_COMMON_SYS_PWR_REG, { 0x0, 0x0, 0x2} }, - { EXYNOS3_ARM_L2_SYS_PWR_REG, { 0x0, 0x0, 0x3} }, - { EXYNOS3_CMU_ACLKSTOP_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_CMU_SCLKSTOP_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_CMU_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_DRAM_FREQ_DOWN_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, - { EXYNOS3_DDRPHY_DLLOFF_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, - { EXYNOS3_LPDDR_PHY_DLL_LOCK_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, - { EXYNOS3_CMU_ACLKSTOP_COREBLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_CMU_SCLKSTOP_COREBLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_CMU_RESET_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_APLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_MPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_BPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_VPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_EPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_UPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, - { EXYNOS3_EPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_MPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_BPLLUSER_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_CMU_CLKSTOP_CAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_CMU_CLKSTOP_MFC_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_CMU_CLKSTOP_G3D_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_CMU_CLKSTOP_LCD0_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_CMU_CLKSTOP_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_CMU_CLKSTOP_MAUDIO_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_CMU_RESET_CAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_CMU_RESET_MFC_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_CMU_RESET_G3D_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_CMU_RESET_LCD0_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_CMU_RESET_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_CMU_RESET_MAUDIO_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS3_TOP_BUS_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS3_TOP_RETENTION_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, - { EXYNOS3_TOP_PWR_SYS_PWR_REG, { 0x3, 0x3, 0x3} }, - { EXYNOS3_TOP_BUS_COREBLK_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS3_TOP_RETENTION_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, - { EXYNOS3_TOP_PWR_COREBLK_SYS_PWR_REG, { 0x3, 0x3, 0x3} }, - { EXYNOS3_LOGIC_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_OSCCLK_GATE_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, - { EXYNOS3_LOGIC_RESET_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_OSCCLK_GATE_COREBLK_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, - { EXYNOS3_PAD_RETENTION_DRAM_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_PAD_RETENTION_MAUDIO_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_PAD_RETENTION_GPIO_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_PAD_RETENTION_UART_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_PAD_RETENTION_MMC0_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_PAD_RETENTION_MMC1_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_PAD_RETENTION_MMC2_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_PAD_RETENTION_SPI_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_PAD_RETENTION_EBIA_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_PAD_RETENTION_EBIB_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_PAD_RETENTION_JTAG_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_PAD_ISOLATION_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_PAD_ALV_SEL_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_XUSBXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_XXTI_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_EXT_REGULATOR_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_EXT_REGULATOR_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_GPIO_MODE_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_GPIO_MODE_MAUDIO_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_TOP_ASB_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_TOP_ASB_ISOLATION_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_TOP_ASB_RESET_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_TOP_ASB_ISOLATION_COREBLK_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS3_CAM_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS3_MFC_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS3_G3D_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS3_LCD0_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS3_ISP_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS3_MAUDIO_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS3_CMU_SYSCLK_ISP_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { PMU_TABLE_END,}, -}; - -static const struct exynos_pmu_conf exynos4210_pmu_config[] = { - /* { .offset = offset, .val = { AFTR, LPA, SLEEP } */ - { S5P_ARM_CORE0_LOWPWR, { 0x0, 0x0, 0x2 } }, - { S5P_DIS_IRQ_CORE0, { 0x0, 0x0, 0x0 } }, - { S5P_DIS_IRQ_CENTRAL0, { 0x0, 0x0, 0x0 } }, - { S5P_ARM_CORE1_LOWPWR, { 0x0, 0x0, 0x2 } }, - { S5P_DIS_IRQ_CORE1, { 0x0, 0x0, 0x0 } }, - { S5P_DIS_IRQ_CENTRAL1, { 0x0, 0x0, 0x0 } }, - { S5P_ARM_COMMON_LOWPWR, { 0x0, 0x0, 0x2 } }, - { S5P_L2_0_LOWPWR, { 0x2, 0x2, 0x3 } }, - { S5P_L2_1_LOWPWR, { 0x2, 0x2, 0x3 } }, - { S5P_CMU_ACLKSTOP_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_SCLKSTOP_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_RESET_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_APLL_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_MPLL_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_VPLL_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_EPLL_SYSCLK_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_CLKSTOP_GPS_ALIVE_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_RESET_GPSALIVE_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_CLKSTOP_CAM_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_CLKSTOP_TV_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_CLKSTOP_MFC_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_CLKSTOP_G3D_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_CLKSTOP_LCD0_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_CLKSTOP_LCD1_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_CLKSTOP_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_CLKSTOP_GPS_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_RESET_CAM_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_RESET_TV_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_RESET_MFC_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_RESET_G3D_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_RESET_LCD0_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_RESET_LCD1_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_RESET_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_RESET_GPS_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_TOP_BUS_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_TOP_RETENTION_LOWPWR, { 0x1, 0x0, 0x1 } }, - { S5P_TOP_PWR_LOWPWR, { 0x3, 0x0, 0x3 } }, - { S5P_LOGIC_RESET_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_ONENAND_MEM_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_MODIMIF_MEM_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_G2D_ACP_MEM_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_USBOTG_MEM_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_HSMMC_MEM_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_CSSYS_MEM_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_SECSS_MEM_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_PCIE_MEM_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_SATA_MEM_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_DRAM_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_PAD_RETENTION_GPIO_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_UART_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_MMCA_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_MMCB_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_EBIA_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_EBIB_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_ISOLATION_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_ALV_SEL_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_XUSBXTI_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_XXTI_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_EXT_REGULATOR_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_GPIO_MODE_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_GPIO_MODE_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CAM_LOWPWR, { 0x7, 0x0, 0x0 } }, - { S5P_TV_LOWPWR, { 0x7, 0x0, 0x0 } }, - { S5P_MFC_LOWPWR, { 0x7, 0x0, 0x0 } }, - { S5P_G3D_LOWPWR, { 0x7, 0x0, 0x0 } }, - { S5P_LCD0_LOWPWR, { 0x7, 0x0, 0x0 } }, - { S5P_LCD1_LOWPWR, { 0x7, 0x0, 0x0 } }, - { S5P_MAUDIO_LOWPWR, { 0x7, 0x7, 0x0 } }, - { S5P_GPS_LOWPWR, { 0x7, 0x0, 0x0 } }, - { S5P_GPS_ALIVE_LOWPWR, { 0x7, 0x0, 0x0 } }, - { PMU_TABLE_END,}, -}; - -static const 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 } }, - { S5P_ARM_CORE1_LOWPWR, { 0x0, 0x0, 0x2 } }, - { S5P_DIS_IRQ_CORE1, { 0x0, 0x0, 0x0 } }, - { S5P_DIS_IRQ_CENTRAL1, { 0x0, 0x0, 0x0 } }, - { S5P_ISP_ARM_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_DIS_IRQ_ISP_ARM_LOCAL_LOWPWR, { 0x0, 0x0, 0x0 } }, - { S5P_DIS_IRQ_ISP_ARM_CENTRAL_LOWPWR, { 0x0, 0x0, 0x0 } }, - { S5P_ARM_COMMON_LOWPWR, { 0x0, 0x0, 0x2 } }, - { S5P_L2_0_LOWPWR, { 0x0, 0x0, 0x3 } }, - /* XXX_OPTION register should be set other field */ - { S5P_ARM_L2_0_OPTION, { 0x10, 0x10, 0x0 } }, - { S5P_L2_1_LOWPWR, { 0x0, 0x0, 0x3 } }, - { S5P_ARM_L2_1_OPTION, { 0x10, 0x10, 0x0 } }, - { S5P_CMU_ACLKSTOP_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_SCLKSTOP_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_RESET_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_DRAM_FREQ_DOWN_LOWPWR, { 0x1, 0x1, 0x1 } }, - { S5P_DDRPHY_DLLOFF_LOWPWR, { 0x1, 0x1, 0x1 } }, - { S5P_LPDDR_PHY_DLL_LOCK_LOWPWR, { 0x1, 0x1, 0x1 } }, - { S5P_CMU_ACLKSTOP_COREBLK_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_SCLKSTOP_COREBLK_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_RESET_COREBLK_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_APLL_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_MPLL_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_VPLL_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_EPLL_SYSCLK_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_MPLLUSER_SYSCLK_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_CLKSTOP_GPS_ALIVE_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_RESET_GPSALIVE_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_CLKSTOP_CAM_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_CLKSTOP_TV_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_CLKSTOP_MFC_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_CLKSTOP_G3D_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_CLKSTOP_LCD0_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_CLKSTOP_ISP_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_CLKSTOP_MAUDIO_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_CLKSTOP_GPS_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_RESET_CAM_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_RESET_TV_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_RESET_MFC_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_RESET_G3D_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_RESET_LCD0_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_RESET_ISP_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_RESET_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_CMU_RESET_GPS_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_TOP_BUS_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_TOP_RETENTION_LOWPWR, { 0x1, 0x0, 0x1 } }, - { S5P_TOP_PWR_LOWPWR, { 0x3, 0x0, 0x3 } }, - { S5P_TOP_BUS_COREBLK_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_TOP_RETENTION_COREBLK_LOWPWR, { 0x1, 0x0, 0x1 } }, - { S5P_TOP_PWR_COREBLK_LOWPWR, { 0x3, 0x0, 0x3 } }, - { S5P_LOGIC_RESET_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_OSCCLK_GATE_LOWPWR, { 0x1, 0x0, 0x1 } }, - { S5P_LOGIC_RESET_COREBLK_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_OSCCLK_GATE_COREBLK_LOWPWR, { 0x1, 0x0, 0x1 } }, - { S5P_ONENAND_MEM_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_ONENAND_MEM_OPTION, { 0x10, 0x10, 0x0 } }, - { S5P_HSI_MEM_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_HSI_MEM_OPTION, { 0x10, 0x10, 0x0 } }, - { S5P_G2D_ACP_MEM_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_G2D_ACP_MEM_OPTION, { 0x10, 0x10, 0x0 } }, - { S5P_USBOTG_MEM_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_USBOTG_MEM_OPTION, { 0x10, 0x10, 0x0 } }, - { S5P_HSMMC_MEM_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_HSMMC_MEM_OPTION, { 0x10, 0x10, 0x0 } }, - { S5P_CSSYS_MEM_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_CSSYS_MEM_OPTION, { 0x10, 0x10, 0x0 } }, - { S5P_SECSS_MEM_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_SECSS_MEM_OPTION, { 0x10, 0x10, 0x0 } }, - { S5P_ROTATOR_MEM_LOWPWR, { 0x3, 0x0, 0x0 } }, - { S5P_ROTATOR_MEM_OPTION, { 0x10, 0x10, 0x0 } }, - { S5P_PAD_RETENTION_DRAM_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_PAD_RETENTION_GPIO_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_UART_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_MMCA_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_MMCB_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_EBIA_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_EBIB_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_GPIO_COREBLK_LOWPWR,{ 0x1, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_ISOLATION_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_PAD_ISOLATION_COREBLK_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_PAD_RETENTION_ALV_SEL_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_XUSBXTI_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_XXTI_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_EXT_REGULATOR_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_GPIO_MODE_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_GPIO_MODE_COREBLK_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_GPIO_MODE_MAUDIO_LOWPWR, { 0x1, 0x1, 0x0 } }, - { S5P_TOP_ASB_RESET_LOWPWR, { 0x1, 0x1, 0x1 } }, - { S5P_TOP_ASB_ISOLATION_LOWPWR, { 0x1, 0x0, 0x1 } }, - { S5P_CAM_LOWPWR, { 0x7, 0x0, 0x0 } }, - { S5P_TV_LOWPWR, { 0x7, 0x0, 0x0 } }, - { S5P_MFC_LOWPWR, { 0x7, 0x0, 0x0 } }, - { S5P_G3D_LOWPWR, { 0x7, 0x0, 0x0 } }, - { S5P_LCD0_LOWPWR, { 0x7, 0x0, 0x0 } }, - { S5P_ISP_LOWPWR, { 0x7, 0x0, 0x0 } }, - { S5P_MAUDIO_LOWPWR, { 0x7, 0x7, 0x0 } }, - { S5P_GPS_LOWPWR, { 0x7, 0x0, 0x0 } }, - { S5P_GPS_ALIVE_LOWPWR, { 0x7, 0x0, 0x0 } }, - { S5P_CMU_SYSCLK_ISP_LOWPWR, { 0x1, 0x0, 0x0 } }, - { S5P_CMU_SYSCLK_GPS_LOWPWR, { 0x1, 0x0, 0x0 } }, - { PMU_TABLE_END,}, -}; - -static const 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 const struct exynos_pmu_conf exynos5250_pmu_config[] = { - /* { .offset = offset, .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_ARM_L2_OPTION, { 0x10, 0x10, 0x0 } }, - { EXYNOS5_CMU_ACLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, - { EXYNOS5_CMU_SCLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x1} }, - { EXYNOS5_CMU_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { 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_JPEG_MEM_OPTION, { 0x10, 0x10, 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,}, -}; - -static struct exynos_pmu_conf exynos5420_pmu_config[] = { - /* { .offset = offset, .val = { AFTR, LPA, SLEEP } */ - { EXYNOS5_ARM_CORE0_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { 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, 0x0} }, - { EXYNOS5_DIS_IRQ_ARM_CORE1_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_DIS_IRQ_ARM_CORE1_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_ARM_CORE2_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_DIS_IRQ_ARM_CORE2_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_DIS_IRQ_ARM_CORE2_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_ARM_CORE3_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_DIS_IRQ_ARM_CORE3_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_DIS_IRQ_ARM_CORE3_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_KFC_CORE0_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_DIS_IRQ_KFC_CORE0_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_DIS_IRQ_KFC_CORE0_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_KFC_CORE1_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_DIS_IRQ_KFC_CORE1_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_DIS_IRQ_KFC_CORE1_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_KFC_CORE2_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_DIS_IRQ_KFC_CORE2_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_DIS_IRQ_KFC_CORE2_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_KFC_CORE3_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_DIS_IRQ_KFC_CORE3_LOCAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_DIS_IRQ_KFC_CORE3_CENTRAL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_ISP_ARM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_DIS_IRQ_ISP_ARM_LOCAL_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_DIS_IRQ_ISP_ARM_CENTRAL_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5420_ARM_COMMON_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_KFC_COMMON_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_ARM_L2_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_KFC_L2_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_CMU_ACLKSTOP_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { 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, 0x0} }, - { 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, 0x0, 0x1} }, - { EXYNOS5_DDRPHY_DLLOFF_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, - { EXYNOS5_DDRPHY_DLLLOCK_SYS_PWR_REG, { 0x1, 0x0, 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} }, - { EXYNOS5420_DPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5420_IPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5420_KPLL_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} }, - { EXYNOS5420_RPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5420_SPLL_SYSCLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_TOP_BUS_SYS_PWR_REG, { 0x3, 0x0, 0x0} }, - { EXYNOS5_TOP_RETENTION_SYS_PWR_REG, { 0x1, 0x1, 0x1} }, - { EXYNOS5_TOP_PWR_SYS_PWR_REG, { 0x3, 0x3, 0x0} }, - { 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, 0x0} }, - { 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, 0x0, 0x0} }, - { EXYNOS5_OSCCLK_GATE_SYSMEM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5420_INTRAM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x3} }, - { EXYNOS5420_INTROM_MEM_SYS_PWR_REG, { 0x3, 0x0, 0x3} }, - { EXYNOS5_PAD_RETENTION_DRAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_PAD_RETENTION_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5420_PAD_RETENTION_JTAG_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5420_PAD_RETENTION_DRAM_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5420_PAD_RETENTION_UART_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5420_PAD_RETENTION_MMC0_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5420_PAD_RETENTION_MMC1_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5420_PAD_RETENTION_MMC2_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5420_PAD_RETENTION_HSI_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5420_PAD_RETENTION_EBIA_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5420_PAD_RETENTION_EBIB_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5420_PAD_RETENTION_SPI_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5420_PAD_RETENTION_DRAM_COREBLK_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { EXYNOS5_PAD_ISOLATION_SYS_PWR_REG, { 0x1, 0x1, 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, 0x0} }, - { 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, 0x1, 0x0} }, - { EXYNOS5_GPIO_MODE_MAU_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_TOP_ASB_RESET_SYS_PWR_REG, { 0x1, 0x1, 0x0} }, - { EXYNOS5_TOP_ASB_ISOLATION_SYS_PWR_REG, { 0x1, 0x0, 0x0} }, - { 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} }, - { EXYNOS5420_DISP1_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS5420_MAU_SYS_PWR_REG, { 0x7, 0x7, 0x0} }, - { EXYNOS5420_G2D_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS5420_MSC_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS5420_FSYS_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS5420_FSYS2_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS5420_PSGEN_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS5420_PERIC_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS5420_WCORE_SYS_PWR_REG, { 0x7, 0x0, 0x0} }, - { EXYNOS5_CMU_CLKSTOP_GSCL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_CMU_CLKSTOP_ISP_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_CMU_CLKSTOP_MFC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_CMU_CLKSTOP_G3D_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_CLKSTOP_DISP1_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_CLKSTOP_MAU_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_CLKSTOP_G2D_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_CLKSTOP_MSC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_CLKSTOP_FSYS_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_CLKSTOP_PSGEN_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_CLKSTOP_PERIC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_CLKSTOP_WCORE_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_CMU_SYSCLK_GSCL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_CMU_SYSCLK_ISP_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_CMU_SYSCLK_MFC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_CMU_SYSCLK_G3D_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_SYSCLK_DISP1_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_SYSCLK_MAU_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_SYSCLK_G2D_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_SYSCLK_MSC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_SYSCLK_FSYS_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_SYSCLK_FSYS2_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_SYSCLK_PSGEN_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_SYSCLK_PERIC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_SYSCLK_WCORE_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_RESET_FSYS2_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_RESET_PSGEN_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_RESET_PERIC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_RESET_WCORE_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_CMU_RESET_GSCL_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_CMU_RESET_ISP_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_CMU_RESET_MFC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5_CMU_RESET_G3D_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_RESET_DISP1_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_RESET_MAU_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_RESET_G2D_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_RESET_MSC_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { EXYNOS5420_CMU_RESET_FSYS_SYS_PWR_REG, { 0x0, 0x0, 0x0} }, - { PMU_TABLE_END,}, -}; - -static unsigned int const exynos3250_list_feed[] = { - EXYNOS3_ARM_CORE_OPTION(0), - EXYNOS3_ARM_CORE_OPTION(1), - EXYNOS3_ARM_CORE_OPTION(2), - EXYNOS3_ARM_CORE_OPTION(3), - EXYNOS3_ARM_COMMON_OPTION, - EXYNOS3_TOP_PWR_OPTION, - EXYNOS3_CORE_TOP_PWR_OPTION, - S5P_CAM_OPTION, - S5P_MFC_OPTION, - S5P_G3D_OPTION, - S5P_LCD0_OPTION, - S5P_ISP_OPTION, -}; - -static void exynos3250_powerdown_conf_extra(enum sys_powerdown mode) -{ - unsigned int i; - unsigned int tmp; - - /* Enable only SC_FEEDBACK */ - for (i = 0; i < ARRAY_SIZE(exynos3250_list_feed); i++) { - tmp = pmu_raw_readl(exynos3250_list_feed[i]); - tmp &= ~(EXYNOS3_OPTION_USE_SC_COUNTER); - tmp |= EXYNOS3_OPTION_USE_SC_FEEDBACK; - pmu_raw_writel(tmp, exynos3250_list_feed[i]); - } - - if (mode != SYS_SLEEP) - return; - - pmu_raw_writel(XUSBXTI_DURATION, EXYNOS3_XUSBXTI_DURATION); - pmu_raw_writel(XXTI_DURATION, EXYNOS3_XXTI_DURATION); - pmu_raw_writel(EXT_REGULATOR_DURATION, EXYNOS3_EXT_REGULATOR_DURATION); - pmu_raw_writel(EXT_REGULATOR_COREBLK_DURATION, - EXYNOS3_EXT_REGULATOR_COREBLK_DURATION); -} - -static unsigned int const 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, -}; - -static unsigned int const exynos5_list_disable_wfi_wfe[] = { - EXYNOS5_ARM_CORE1_OPTION, - EXYNOS5_FSYS_ARM_OPTION, - EXYNOS5_ISP_ARM_OPTION, -}; - -static unsigned int const exynos5420_list_disable_pmu_reg[] = { - EXYNOS5_CMU_CLKSTOP_GSCL_SYS_PWR_REG, - EXYNOS5_CMU_CLKSTOP_ISP_SYS_PWR_REG, - EXYNOS5_CMU_CLKSTOP_G3D_SYS_PWR_REG, - EXYNOS5420_CMU_CLKSTOP_DISP1_SYS_PWR_REG, - EXYNOS5420_CMU_CLKSTOP_MAU_SYS_PWR_REG, - EXYNOS5420_CMU_CLKSTOP_G2D_SYS_PWR_REG, - EXYNOS5420_CMU_CLKSTOP_MSC_SYS_PWR_REG, - EXYNOS5420_CMU_CLKSTOP_FSYS_SYS_PWR_REG, - EXYNOS5420_CMU_CLKSTOP_PSGEN_SYS_PWR_REG, - EXYNOS5420_CMU_CLKSTOP_PERIC_SYS_PWR_REG, - EXYNOS5420_CMU_CLKSTOP_WCORE_SYS_PWR_REG, - EXYNOS5_CMU_SYSCLK_GSCL_SYS_PWR_REG, - EXYNOS5_CMU_SYSCLK_ISP_SYS_PWR_REG, - EXYNOS5_CMU_SYSCLK_G3D_SYS_PWR_REG, - EXYNOS5420_CMU_SYSCLK_DISP1_SYS_PWR_REG, - EXYNOS5420_CMU_SYSCLK_MAU_SYS_PWR_REG, - EXYNOS5420_CMU_SYSCLK_G2D_SYS_PWR_REG, - EXYNOS5420_CMU_SYSCLK_MSC_SYS_PWR_REG, - EXYNOS5420_CMU_SYSCLK_FSYS_SYS_PWR_REG, - EXYNOS5420_CMU_SYSCLK_FSYS2_SYS_PWR_REG, - EXYNOS5420_CMU_SYSCLK_PSGEN_SYS_PWR_REG, - EXYNOS5420_CMU_SYSCLK_PERIC_SYS_PWR_REG, - EXYNOS5420_CMU_SYSCLK_WCORE_SYS_PWR_REG, - EXYNOS5420_CMU_RESET_FSYS2_SYS_PWR_REG, - EXYNOS5420_CMU_RESET_PSGEN_SYS_PWR_REG, - EXYNOS5420_CMU_RESET_PERIC_SYS_PWR_REG, - EXYNOS5420_CMU_RESET_WCORE_SYS_PWR_REG, - EXYNOS5_CMU_RESET_GSCL_SYS_PWR_REG, - EXYNOS5_CMU_RESET_ISP_SYS_PWR_REG, - EXYNOS5_CMU_RESET_G3D_SYS_PWR_REG, - EXYNOS5420_CMU_RESET_DISP1_SYS_PWR_REG, - EXYNOS5420_CMU_RESET_MAU_SYS_PWR_REG, - EXYNOS5420_CMU_RESET_G2D_SYS_PWR_REG, - EXYNOS5420_CMU_RESET_MSC_SYS_PWR_REG, - EXYNOS5420_CMU_RESET_FSYS_SYS_PWR_REG, -}; - -static void exynos5420_powerdown_conf(enum sys_powerdown mode) -{ - u32 this_cluster; - - this_cluster = MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 1); - - /* - * set the cluster id to IROM register to ensure that we wake - * up with the current cluster. - */ - pmu_raw_writel(this_cluster, EXYNOS_IROM_DATA2); -} - - -static void exynos5_powerdown_conf(enum sys_powerdown mode) -{ - unsigned int i; - unsigned int tmp; - - /* - * Enable both SC_FEEDBACK and SC_COUNTER - */ - for (i = 0; i < ARRAY_SIZE(exynos5_list_both_cnt_feed); i++) { - tmp = pmu_raw_readl(exynos5_list_both_cnt_feed[i]); - tmp |= (EXYNOS5_USE_SC_FEEDBACK | - EXYNOS5_USE_SC_COUNTER); - pmu_raw_writel(tmp, exynos5_list_both_cnt_feed[i]); - } - - /* - * SKIP_DEACTIVATE_ACEACP_IN_PWDN_BITFIELD Enable - */ - tmp = pmu_raw_readl(EXYNOS5_ARM_COMMON_OPTION); - tmp |= EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN; - pmu_raw_writel(tmp, EXYNOS5_ARM_COMMON_OPTION); - - /* - * Disable WFI/WFE on XXX_OPTION - */ - for (i = 0; i < ARRAY_SIZE(exynos5_list_disable_wfi_wfe); i++) { - tmp = pmu_raw_readl(exynos5_list_disable_wfi_wfe[i]); - tmp &= ~(EXYNOS5_OPTION_USE_STANDBYWFE | - EXYNOS5_OPTION_USE_STANDBYWFI); - pmu_raw_writel(tmp, exynos5_list_disable_wfi_wfe[i]); - } -} - -void exynos_sys_powerdown_conf(enum sys_powerdown mode) -{ - unsigned int i; - const struct exynos_pmu_data *pmu_data; - - if (!pmu_context) - return; - - pmu_data = pmu_context->pmu_data; - - if (pmu_data->powerdown_conf) - pmu_data->powerdown_conf(mode); - - if (pmu_data->pmu_config) { - for (i = 0; (pmu_data->pmu_config[i].offset != PMU_TABLE_END); i++) - pmu_raw_writel(pmu_data->pmu_config[i].val[mode], - pmu_data->pmu_config[i].offset); - } - - if (pmu_data->powerdown_conf_extra) - pmu_data->powerdown_conf_extra(mode); - - if (pmu_data->pmu_config_extra) { - for (i = 0; pmu_data->pmu_config_extra[i].offset != PMU_TABLE_END; i++) - pmu_raw_writel(pmu_data->pmu_config_extra[i].val[mode], - pmu_data->pmu_config_extra[i].offset); - } -} - -static void exynos3250_pmu_init(void) -{ - unsigned int value; - - /* - * To prevent from issuing new bus request form L2 memory system - * If core status is power down, should be set '1' to L2 power down - */ - value = pmu_raw_readl(EXYNOS3_ARM_COMMON_OPTION); - value |= EXYNOS3_OPTION_SKIP_DEACTIVATE_ACEACP_IN_PWDN; - pmu_raw_writel(value, EXYNOS3_ARM_COMMON_OPTION); - - /* Enable USE_STANDBY_WFI for all CORE */ - pmu_raw_writel(S5P_USE_STANDBY_WFI_ALL, S5P_CENTRAL_SEQ_OPTION); - - /* - * Set PSHOLD port for output high - */ - value = pmu_raw_readl(S5P_PS_HOLD_CONTROL); - value |= S5P_PS_HOLD_OUTPUT_HIGH; - pmu_raw_writel(value, S5P_PS_HOLD_CONTROL); - - /* - * Enable signal for PSHOLD port - */ - value = pmu_raw_readl(S5P_PS_HOLD_CONTROL); - value |= S5P_PS_HOLD_EN; - pmu_raw_writel(value, S5P_PS_HOLD_CONTROL); -} - -static void exynos5250_pmu_init(void) -{ - unsigned int value; - /* - * When SYS_WDTRESET is set, watchdog timer reset request - * is ignored by power management unit. - */ - value = pmu_raw_readl(EXYNOS5_AUTO_WDTRESET_DISABLE); - value &= ~EXYNOS5_SYS_WDTRESET; - pmu_raw_writel(value, EXYNOS5_AUTO_WDTRESET_DISABLE); - - value = pmu_raw_readl(EXYNOS5_MASK_WDTRESET_REQUEST); - value &= ~EXYNOS5_SYS_WDTRESET; - pmu_raw_writel(value, EXYNOS5_MASK_WDTRESET_REQUEST); -} - -static void exynos5420_pmu_init(void) -{ - unsigned int value; - int i; - - /* - * Set the CMU_RESET, CMU_SYSCLK and CMU_CLKSTOP registers - * for local power blocks to Low initially as per Table 8-4: - * "System-Level Power-Down Configuration Registers". - */ - for (i = 0; i < ARRAY_SIZE(exynos5420_list_disable_pmu_reg); i++) - pmu_raw_writel(0, exynos5420_list_disable_pmu_reg[i]); - - /* Enable USE_STANDBY_WFI for all CORE */ - pmu_raw_writel(EXYNOS5420_USE_STANDBY_WFI_ALL, S5P_CENTRAL_SEQ_OPTION); - - value = pmu_raw_readl(EXYNOS_L2_OPTION(0)); - value &= ~EXYNOS5_USE_RETENTION; - pmu_raw_writel(value, EXYNOS_L2_OPTION(0)); - - value = pmu_raw_readl(EXYNOS_L2_OPTION(1)); - value &= ~EXYNOS5_USE_RETENTION; - pmu_raw_writel(value, EXYNOS_L2_OPTION(1)); - - /* - * If L2_COMMON is turned off, clocks related to ATB async - * bridge are gated. Thus, when ISP power is gated, LPI - * may get stuck. - */ - value = pmu_raw_readl(EXYNOS5420_LPI_MASK); - value |= EXYNOS5420_ATB_ISP_ARM; - pmu_raw_writel(value, EXYNOS5420_LPI_MASK); - - value = pmu_raw_readl(EXYNOS5420_LPI_MASK1); - value |= EXYNOS5420_ATB_KFC; - pmu_raw_writel(value, EXYNOS5420_LPI_MASK1); - - /* Prevent issue of new bus request from L2 memory */ - value = pmu_raw_readl(EXYNOS5420_ARM_COMMON_OPTION); - value |= EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN; - pmu_raw_writel(value, EXYNOS5420_ARM_COMMON_OPTION); - - value = pmu_raw_readl(EXYNOS5420_KFC_COMMON_OPTION); - value |= EXYNOS5_SKIP_DEACTIVATE_ACEACP_IN_PWDN; - pmu_raw_writel(value, EXYNOS5420_KFC_COMMON_OPTION); - - /* This setting is to reduce suspend/resume time */ - pmu_raw_writel(DUR_WAIT_RESET, EXYNOS5420_LOGIC_RESET_DURATION3); - - /* Serialized CPU wakeup of Eagle */ - pmu_raw_writel(SPREAD_ENABLE, EXYNOS5420_ARM_INTR_SPREAD_ENABLE); - - pmu_raw_writel(SPREAD_USE_STANDWFI, - EXYNOS5420_ARM_INTR_SPREAD_USE_STANDBYWFI); - - pmu_raw_writel(0x1, EXYNOS5420_UP_SCHEDULER); - pr_info("EXYNOS5420 PMU initialized\n"); -} - -static const struct exynos_pmu_data exynos3250_pmu_data = { - .pmu_config = exynos3250_pmu_config, - .pmu_init = exynos3250_pmu_init, - .powerdown_conf_extra = exynos3250_powerdown_conf_extra, -}; - -static const struct exynos_pmu_data exynos4210_pmu_data = { - .pmu_config = exynos4210_pmu_config, -}; - -static const struct exynos_pmu_data exynos4212_pmu_data = { - .pmu_config = exynos4x12_pmu_config, -}; - -static const struct exynos_pmu_data exynos4412_pmu_data = { - .pmu_config = exynos4x12_pmu_config, - .pmu_config_extra = exynos4412_pmu_config, -}; - -static const struct exynos_pmu_data exynos5250_pmu_data = { - .pmu_config = exynos5250_pmu_config, - .pmu_init = exynos5250_pmu_init, - .powerdown_conf = exynos5_powerdown_conf, -}; - -static const struct exynos_pmu_data exynos5420_pmu_data = { - .pmu_config = exynos5420_pmu_config, - .pmu_init = exynos5420_pmu_init, - .powerdown_conf = exynos5420_powerdown_conf, -}; - -/* - * PMU platform driver and devicetree bindings. - */ -static const struct of_device_id exynos_pmu_of_device_ids[] = { - { - .compatible = "samsung,exynos3250-pmu", - .data = &exynos3250_pmu_data, - }, { - .compatible = "samsung,exynos4210-pmu", - .data = &exynos4210_pmu_data, - }, { - .compatible = "samsung,exynos4212-pmu", - .data = &exynos4212_pmu_data, - }, { - .compatible = "samsung,exynos4412-pmu", - .data = &exynos4412_pmu_data, - }, { - .compatible = "samsung,exynos5250-pmu", - .data = &exynos5250_pmu_data, - }, { - .compatible = "samsung,exynos5420-pmu", - .data = &exynos5420_pmu_data, - }, - { /*sentinel*/ }, -}; - -static int exynos_pmu_probe(struct platform_device *pdev) -{ - const struct of_device_id *match; - struct device *dev = &pdev->dev; - struct resource *res; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - pmu_base_addr = devm_ioremap_resource(dev, res); - if (IS_ERR(pmu_base_addr)) - return PTR_ERR(pmu_base_addr); - - pmu_context = devm_kzalloc(&pdev->dev, - sizeof(struct exynos_pmu_context), - GFP_KERNEL); - if (!pmu_context) { - dev_err(dev, "Cannot allocate memory.\n"); - return -ENOMEM; - } - pmu_context->dev = dev; - - match = of_match_node(exynos_pmu_of_device_ids, dev->of_node); - - pmu_context->pmu_data = match->data; - - if (pmu_context->pmu_data->pmu_init) - pmu_context->pmu_data->pmu_init(); - - platform_set_drvdata(pdev, pmu_context); - - dev_dbg(dev, "Exynos PMU Driver probe done\n"); - return 0; -} - -static struct platform_driver exynos_pmu_driver = { - .driver = { - .name = "exynos-pmu", - .of_match_table = exynos_pmu_of_device_ids, - }, - .probe = exynos_pmu_probe, -}; - -static int __init exynos_pmu_init(void) -{ - return platform_driver_register(&exynos_pmu_driver); - -} -postcore_initcall(exynos_pmu_init); diff --git a/arch/arm/mach-exynos/s5p-dev-mfc.c b/arch/arm/mach-exynos/s5p-dev-mfc.c index 0b04b6b0fa302f97fef4996de97efe59ca572be4..8ef1f3ee4e98676ce15c9ff95cfa20c85a980962 100644 --- a/arch/arm/mach-exynos/s5p-dev-mfc.c +++ b/arch/arm/mach-exynos/s5p-dev-mfc.c @@ -9,7 +9,6 @@ */ #include -#include #include #include #include diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c index c169cc3049aa3bbe270905eea1840d1b603b125c..fee2b003e6622f3e986cc61892c48b0ad0a6929e 100644 --- a/arch/arm/mach-exynos/suspend.c +++ b/arch/arm/mach-exynos/suspend.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #include @@ -35,8 +37,6 @@ #include #include "common.h" -#include "exynos-pmu.h" -#include "regs-pmu.h" #include "regs-srom.h" #define REG_TABLE_END (-1U) diff --git a/arch/arm/mach-footbridge/Kconfig b/arch/arm/mach-footbridge/Kconfig index 07152d00fc505bc2aceac2cc9ebffae485175c8d..cbbdd84cf49ad0f70b464f79a336f07f24f5da82 100644 --- a/arch/arm/mach-footbridge/Kconfig +++ b/arch/arm/mach-footbridge/Kconfig @@ -68,7 +68,6 @@ config ARCH_NETWINDER select ISA select ISA_DMA select PCI - select VIRT_TO_BUS help Say Y here if you intend to run this kernel on the Rebel.COM NetWinder. Information about this machine can be found at: diff --git a/arch/arm/mach-imx/3ds_debugboard.c b/arch/arm/mach-imx/3ds_debugboard.c index 16496a071ecb8c3174639a15fbc3d6fe092d3e3b..cda330c93d610d35d3e82e9d9574d6611dc489d4 100644 --- a/arch/arm/mach-imx/3ds_debugboard.c +++ b/arch/arm/mach-imx/3ds_debugboard.c @@ -94,8 +94,8 @@ static void mxc_expio_irq_handler(struct irq_desc *desc) /* irq = gpio irq number */ desc->irq_data.chip->irq_mask(&desc->irq_data); - imr_val = __raw_readw(brd_io + INTR_MASK_REG); - int_valid = __raw_readw(brd_io + INTR_STATUS_REG) & ~imr_val; + imr_val = imx_readw(brd_io + INTR_MASK_REG); + int_valid = imx_readw(brd_io + INTR_STATUS_REG) & ~imr_val; expio_irq = 0; for (; int_valid != 0; int_valid >>= 1, expio_irq++) { @@ -117,17 +117,17 @@ static void expio_mask_irq(struct irq_data *d) u16 reg; u32 expio = d->hwirq; - reg = __raw_readw(brd_io + INTR_MASK_REG); + reg = imx_readw(brd_io + INTR_MASK_REG); reg |= (1 << expio); - __raw_writew(reg, brd_io + INTR_MASK_REG); + imx_writew(reg, brd_io + INTR_MASK_REG); } static void expio_ack_irq(struct irq_data *d) { u32 expio = d->hwirq; - __raw_writew(1 << expio, brd_io + INTR_RESET_REG); - __raw_writew(0, brd_io + INTR_RESET_REG); + imx_writew(1 << expio, brd_io + INTR_RESET_REG); + imx_writew(0, brd_io + INTR_RESET_REG); expio_mask_irq(d); } @@ -136,9 +136,9 @@ static void expio_unmask_irq(struct irq_data *d) u16 reg; u32 expio = d->hwirq; - reg = __raw_readw(brd_io + INTR_MASK_REG); + reg = imx_readw(brd_io + INTR_MASK_REG); reg &= ~(1 << expio); - __raw_writew(reg, brd_io + INTR_MASK_REG); + imx_writew(reg, brd_io + INTR_MASK_REG); } static struct irq_chip expio_irq_chip = { @@ -162,9 +162,9 @@ int __init mxc_expio_init(u32 base, u32 intr_gpio) if (brd_io == NULL) return -ENOMEM; - if ((__raw_readw(brd_io + MAGIC_NUMBER1_REG) != 0xAAAA) || - (__raw_readw(brd_io + MAGIC_NUMBER2_REG) != 0x5555) || - (__raw_readw(brd_io + MAGIC_NUMBER3_REG) != 0xCAFE)) { + if ((imx_readw(brd_io + MAGIC_NUMBER1_REG) != 0xAAAA) || + (imx_readw(brd_io + MAGIC_NUMBER2_REG) != 0x5555) || + (imx_readw(brd_io + MAGIC_NUMBER3_REG) != 0xCAFE)) { pr_info("3-Stack Debug board not detected\n"); iounmap(brd_io); brd_io = NULL; @@ -181,10 +181,10 @@ int __init mxc_expio_init(u32 base, u32 intr_gpio) gpio_direction_input(intr_gpio); /* disable the interrupt and clear the status */ - __raw_writew(0, brd_io + INTR_MASK_REG); - __raw_writew(0xFFFF, brd_io + INTR_RESET_REG); - __raw_writew(0, brd_io + INTR_RESET_REG); - __raw_writew(0x1F, brd_io + INTR_MASK_REG); + imx_writew(0, brd_io + INTR_MASK_REG); + imx_writew(0xFFFF, brd_io + INTR_RESET_REG); + imx_writew(0, brd_io + INTR_RESET_REG); + imx_writew(0x1F, brd_io + INTR_MASK_REG); irq_base = irq_alloc_descs(-1, 0, MXC_MAX_EXP_IO_LINES, numa_node_id()); WARN_ON(irq_base < 0); diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 15df34fbdf44c5abd4182f1c5a0514162e7fe635..8973fae25436b1fcd5424dd5c7ed994ae68ed43a 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -2,7 +2,7 @@ menuconfig ARCH_MXC bool "Freescale i.MX family" depends on ARCH_MULTI_V4_V5 || ARCH_MULTI_V6_V7 || ARM_SINGLE_ARMV7M select ARCH_REQUIRE_GPIOLIB - select ARM_CPU_SUSPEND if PM + select ARCH_SUPPORTS_BIG_ENDIAN select CLKSRC_IMX_GPT select GENERIC_IRQ_CHIP select PINCTRL @@ -511,6 +511,7 @@ config SOC_IMX53 config SOC_IMX6 bool + select ARM_CPU_SUSPEND if PM select ARM_ERRATA_754322 select ARM_ERRATA_775420 select ARM_GIC @@ -561,6 +562,7 @@ config SOC_IMX7D bool "i.MX7 Dual support" select PINCTRL_IMX7D select ARM_GIC + select HAVE_ARM_ARCH_TIMER select HAVE_IMX_ANATOP select HAVE_IMX_MMDC select HAVE_IMX_SRC diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index fb689d813b098464655d45a0cb52b1fb3d150858..9fbe624a5ef98581c5b7ed40eec84f3c7cca1fd1 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -3,7 +3,7 @@ obj-y := cpu.o system.o irq-common.o obj-$(CONFIG_SOC_IMX1) += mm-imx1.o obj-$(CONFIG_SOC_IMX21) += mm-imx21.o -obj-$(CONFIG_SOC_IMX25) += cpu-imx25.o mach-imx25.o +obj-$(CONFIG_SOC_IMX25) += cpu-imx25.o mach-imx25.o pm-imx25.o obj-$(CONFIG_SOC_IMX27) += cpu-imx27.o pm-imx27.o obj-$(CONFIG_SOC_IMX27) += mm-imx27.o ehci-imx27.o diff --git a/arch/arm/mach-imx/anatop.c b/arch/arm/mach-imx/anatop.c index 231bb250c5719d21962404a9301765cdcf499924..649a84c251ad6eebf59b4f33b4ca5a237339f7d8 100644 --- a/arch/arm/mach-imx/anatop.c +++ b/arch/arm/mach-imx/anatop.c @@ -129,7 +129,14 @@ void __init imx_init_revision_from_anatop(void) switch (digprog & 0xff) { case 0: - revision = IMX_CHIP_REVISION_1_0; + /* + * For i.MX6QP, most of the code for i.MX6Q can be resued, + * so internally, we identify it as i.MX6Q Rev 2.0 + */ + if (digprog >> 8 & 0x01) + revision = IMX_CHIP_REVISION_2_0; + else + revision = IMX_CHIP_REVISION_1_0; break; case 1: revision = IMX_CHIP_REVISION_1_1; @@ -151,7 +158,14 @@ void __init imx_init_revision_from_anatop(void) revision = IMX_CHIP_REVISION_1_5; break; default: - revision = IMX_CHIP_REVISION_UNKNOWN; + /* + * Fail back to return raw register value instead of 0xff. + * It will be easy to know version information in SOC if it + * can't be recognized by known version. And some chip's (i.MX7D) + * digprog value match linux version format, so it needn't map + * again and we can use register value directly. + */ + revision = digprog & 0xff; } mxc_set_cpu_type(digprog >> 16 & 0xff); diff --git a/arch/arm/mach-imx/avic.c b/arch/arm/mach-imx/avic.c index 1a8932335b2136b9ff941adc3d2bc35abdebb325..7fa176e792bd16fc7b71959ff0f57dcf23ec32d7 100644 --- a/arch/arm/mach-imx/avic.c +++ b/arch/arm/mach-imx/avic.c @@ -66,12 +66,12 @@ static int avic_set_irq_fiq(unsigned int irq, unsigned int type) return -EINVAL; if (irq < AVIC_NUM_IRQS / 2) { - irqt = __raw_readl(avic_base + AVIC_INTTYPEL) & ~(1 << irq); - __raw_writel(irqt | (!!type << irq), avic_base + AVIC_INTTYPEL); + irqt = imx_readl(avic_base + AVIC_INTTYPEL) & ~(1 << irq); + imx_writel(irqt | (!!type << irq), avic_base + AVIC_INTTYPEL); } else { irq -= AVIC_NUM_IRQS / 2; - irqt = __raw_readl(avic_base + AVIC_INTTYPEH) & ~(1 << irq); - __raw_writel(irqt | (!!type << irq), avic_base + AVIC_INTTYPEH); + irqt = imx_readl(avic_base + AVIC_INTTYPEH) & ~(1 << irq); + imx_writel(irqt | (!!type << irq), avic_base + AVIC_INTTYPEH); } return 0; @@ -94,8 +94,8 @@ static void avic_irq_suspend(struct irq_data *d) struct irq_chip_type *ct = gc->chip_types; int idx = d->hwirq >> 5; - avic_saved_mask_reg[idx] = __raw_readl(avic_base + ct->regs.mask); - __raw_writel(gc->wake_active, avic_base + ct->regs.mask); + avic_saved_mask_reg[idx] = imx_readl(avic_base + ct->regs.mask); + imx_writel(gc->wake_active, avic_base + ct->regs.mask); } static void avic_irq_resume(struct irq_data *d) @@ -104,7 +104,7 @@ static void avic_irq_resume(struct irq_data *d) struct irq_chip_type *ct = gc->chip_types; int idx = d->hwirq >> 5; - __raw_writel(avic_saved_mask_reg[idx], avic_base + ct->regs.mask); + imx_writel(avic_saved_mask_reg[idx], avic_base + ct->regs.mask); } #else @@ -140,7 +140,7 @@ static void __exception_irq_entry avic_handle_irq(struct pt_regs *regs) u32 nivector; do { - nivector = __raw_readl(avic_base + AVIC_NIVECSR) >> 16; + nivector = imx_readl(avic_base + AVIC_NIVECSR) >> 16; if (nivector == 0xffff) break; @@ -164,16 +164,16 @@ void __init mxc_init_irq(void __iomem *irqbase) /* put the AVIC into the reset value with * all interrupts disabled */ - __raw_writel(0, avic_base + AVIC_INTCNTL); - __raw_writel(0x1f, avic_base + AVIC_NIMASK); + imx_writel(0, avic_base + AVIC_INTCNTL); + imx_writel(0x1f, avic_base + AVIC_NIMASK); /* disable all interrupts */ - __raw_writel(0, avic_base + AVIC_INTENABLEH); - __raw_writel(0, avic_base + AVIC_INTENABLEL); + imx_writel(0, avic_base + AVIC_INTENABLEH); + imx_writel(0, avic_base + AVIC_INTENABLEL); /* all IRQ no FIQ */ - __raw_writel(0, avic_base + AVIC_INTTYPEH); - __raw_writel(0, avic_base + AVIC_INTTYPEL); + imx_writel(0, avic_base + AVIC_INTTYPEH); + imx_writel(0, avic_base + AVIC_INTTYPEL); irq_base = irq_alloc_descs(-1, 0, AVIC_NUM_IRQS, numa_node_id()); WARN_ON(irq_base < 0); @@ -188,7 +188,7 @@ void __init mxc_init_irq(void __iomem *irqbase) /* Set default priority value (0) for all IRQ's */ for (i = 0; i < 8; i++) - __raw_writel(0, avic_base + AVIC_NIPRIORITY(i)); + imx_writel(0, avic_base + AVIC_NIPRIORITY(i)); set_handle_irq(avic_handle_irq); diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index 32b83f09da18bd9e136e6db58704d526f5b105b1..58a38464480d3cf1e46302d4b010dcdeaea41638 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -66,6 +66,7 @@ void imx_gpc_check_dt(void); void imx_gpc_set_arm_power_in_lpm(bool power_off); void imx_gpc_set_arm_power_up_timing(u32 sw2iso, u32 sw); void imx_gpc_set_arm_power_down_timing(u32 sw2iso, u32 sw); +void imx25_pm_init(void); enum mxc_cpu_pwr_mode { WAIT_CLOCKED, /* wfi only */ diff --git a/arch/arm/mach-imx/cpu-imx27.c b/arch/arm/mach-imx/cpu-imx27.c index fe8d36f7e30ed95209ae218811c4420af52b5bee..8d2ae4091465b33aabdd06cfabc69954b203644f 100644 --- a/arch/arm/mach-imx/cpu-imx27.c +++ b/arch/arm/mach-imx/cpu-imx27.c @@ -39,8 +39,7 @@ static int mx27_read_cpu_rev(void) * the silicon revision very early we read it here to * avoid any further hooks */ - val = __raw_readl(MX27_IO_ADDRESS(MX27_SYSCTRL_BASE_ADDR - + SYS_CHIP_ID)); + val = imx_readl(MX27_IO_ADDRESS(MX27_SYSCTRL_BASE_ADDR + SYS_CHIP_ID)); mx27_cpu_partnumber = (int)((val >> 12) & 0xFFFF); diff --git a/arch/arm/mach-imx/cpu-imx31.c b/arch/arm/mach-imx/cpu-imx31.c index fde1860a25216ed9763fb7ba8256ed0b16757e70..3daf1959a2f0ad555e1f5c94d2cb79ca2cd2db39 100644 --- a/arch/arm/mach-imx/cpu-imx31.c +++ b/arch/arm/mach-imx/cpu-imx31.c @@ -39,7 +39,7 @@ static int mx31_read_cpu_rev(void) u32 i, srev; /* read SREV register from IIM module */ - srev = __raw_readl(MX31_IO_ADDRESS(MX31_IIM_BASE_ADDR + MXC_IIMSREV)); + srev = imx_readl(MX31_IO_ADDRESS(MX31_IIM_BASE_ADDR + MXC_IIMSREV)); srev &= 0xff; for (i = 0; i < ARRAY_SIZE(mx31_cpu_type); i++) diff --git a/arch/arm/mach-imx/cpu-imx35.c b/arch/arm/mach-imx/cpu-imx35.c index ec3aaa098c1706b3d7cf88b9c608302777419aad..8a54234df23b582b5bac78d365f2e35b4fe6cc84 100644 --- a/arch/arm/mach-imx/cpu-imx35.c +++ b/arch/arm/mach-imx/cpu-imx35.c @@ -20,7 +20,7 @@ static int mx35_read_cpu_rev(void) { u32 rev; - rev = __raw_readl(MX35_IO_ADDRESS(MX35_IIM_BASE_ADDR + MXC_IIMSREV)); + rev = imx_readl(MX35_IO_ADDRESS(MX35_IIM_BASE_ADDR + MXC_IIMSREV)); switch (rev) { case 0x00: return IMX_CHIP_REVISION_1_0; diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c index 5b0f752d5507fe337408cfb9abc3a079beb458dd..6a96b7cf468ff95b7194ce42e9e58c2b1d08261a 100644 --- a/arch/arm/mach-imx/cpu.c +++ b/arch/arm/mach-imx/cpu.c @@ -45,20 +45,20 @@ void __init imx_set_aips(void __iomem *base) * Set all MPROTx to be non-bufferable, trusted for R/W, * not forced to user-mode. */ - __raw_writel(0x77777777, base + 0x0); - __raw_writel(0x77777777, base + 0x4); + imx_writel(0x77777777, base + 0x0); + imx_writel(0x77777777, base + 0x4); /* * Set all OPACRx to be non-bufferable, to not require * supervisor privilege level for access, allow for * write access and untrusted master access. */ - __raw_writel(0x0, base + 0x40); - __raw_writel(0x0, base + 0x44); - __raw_writel(0x0, base + 0x48); - __raw_writel(0x0, base + 0x4C); - reg = __raw_readl(base + 0x50) & 0x00FFFFFF; - __raw_writel(reg, base + 0x50); + imx_writel(0x0, base + 0x40); + imx_writel(0x0, base + 0x44); + imx_writel(0x0, base + 0x48); + imx_writel(0x0, base + 0x4C); + reg = imx_readl(base + 0x50) & 0x00FFFFFF; + imx_writel(reg, base + 0x50); } void __init imx_aips_allow_unprivileged_access( diff --git a/arch/arm/mach-imx/epit.c b/arch/arm/mach-imx/epit.c index 08ce20771bb3f9e49a88294e37216d7c562edb8a..fb9a73a57d00dbf11432f1771180f3391cfdfa55 100644 --- a/arch/arm/mach-imx/epit.c +++ b/arch/arm/mach-imx/epit.c @@ -64,23 +64,23 @@ static inline void epit_irq_disable(void) { u32 val; - val = __raw_readl(timer_base + EPITCR); + val = imx_readl(timer_base + EPITCR); val &= ~EPITCR_OCIEN; - __raw_writel(val, timer_base + EPITCR); + imx_writel(val, timer_base + EPITCR); } static inline void epit_irq_enable(void) { u32 val; - val = __raw_readl(timer_base + EPITCR); + val = imx_readl(timer_base + EPITCR); val |= EPITCR_OCIEN; - __raw_writel(val, timer_base + EPITCR); + imx_writel(val, timer_base + EPITCR); } static void epit_irq_acknowledge(void) { - __raw_writel(EPITSR_OCIF, timer_base + EPITSR); + imx_writel(EPITSR_OCIF, timer_base + EPITSR); } static int __init epit_clocksource_init(struct clk *timer_clk) @@ -98,9 +98,9 @@ static int epit_set_next_event(unsigned long evt, { unsigned long tcmp; - tcmp = __raw_readl(timer_base + EPITCNR); + tcmp = imx_readl(timer_base + EPITCNR); - __raw_writel(tcmp - evt, timer_base + EPITCMPR); + imx_writel(tcmp - evt, timer_base + EPITCMPR); return 0; } @@ -213,11 +213,11 @@ void __init epit_timer_init(void __iomem *base, int irq) /* * Initialise to a known state (all timers off, and timing reset) */ - __raw_writel(0x0, timer_base + EPITCR); + imx_writel(0x0, timer_base + EPITCR); - __raw_writel(0xffffffff, timer_base + EPITLR); - __raw_writel(EPITCR_EN | EPITCR_CLKSRC_REF_HIGH | EPITCR_WAITEN, - timer_base + EPITCR); + imx_writel(0xffffffff, timer_base + EPITLR); + imx_writel(EPITCR_EN | EPITCR_CLKSRC_REF_HIGH | EPITCR_WAITEN, + timer_base + EPITCR); /* init and register the timer to the framework */ epit_clocksource_init(timer_clk); diff --git a/arch/arm/mach-imx/headsmp.S b/arch/arm/mach-imx/headsmp.S index b5e976816b63cf3cd81926dd8378036d21b2888e..6c28d28b3c647982fb25d709f2eaef570e9085e3 100644 --- a/arch/arm/mach-imx/headsmp.S +++ b/arch/arm/mach-imx/headsmp.S @@ -12,6 +12,7 @@ #include #include +#include diag_reg_offset: .word g_diag_reg - . @@ -25,6 +26,7 @@ diag_reg_offset: .endm ENTRY(v7_secondary_startup) +ARM_BE8(setend be) @ go BE8 if entered LE set_diag_reg b secondary_startup ENDPROC(v7_secondary_startup) diff --git a/arch/arm/mach-imx/iomux-imx31.c b/arch/arm/mach-imx/iomux-imx31.c index 0b5ba4bf572a252112de2d3c9d13d7cf758e3b00..3982e91b2f3ea49d993bcf2bc32472304c3dadc6 100644 --- a/arch/arm/mach-imx/iomux-imx31.c +++ b/arch/arm/mach-imx/iomux-imx31.c @@ -57,10 +57,10 @@ void mxc_iomux_mode(unsigned int pin_mode) spin_lock(&gpio_mux_lock); - l = __raw_readl(reg); + l = imx_readl(reg); l &= ~(0xff << (field * 8)); l |= mode << (field * 8); - __raw_writel(l, reg); + imx_writel(l, reg); spin_unlock(&gpio_mux_lock); } @@ -82,10 +82,10 @@ void mxc_iomux_set_pad(enum iomux_pins pin, u32 config) spin_lock(&gpio_mux_lock); - l = __raw_readl(reg); + l = imx_readl(reg); l &= ~(0x1ff << (field * 10)); l |= config << (field * 10); - __raw_writel(l, reg); + imx_writel(l, reg); spin_unlock(&gpio_mux_lock); } @@ -163,12 +163,12 @@ void mxc_iomux_set_gpr(enum iomux_gp_func gp, bool en) u32 l; spin_lock(&gpio_mux_lock); - l = __raw_readl(IOMUXGPR); + l = imx_readl(IOMUXGPR); if (en) l |= gp; else l &= ~gp; - __raw_writel(l, IOMUXGPR); + imx_writel(l, IOMUXGPR); spin_unlock(&gpio_mux_lock); } diff --git a/arch/arm/mach-imx/iomux-v1.c b/arch/arm/mach-imx/iomux-v1.c index ecd543664644135084e37d88002ecee88fa2d15a..7aa90c863ad99b21ede09f5438a70de62873c4b8 100644 --- a/arch/arm/mach-imx/iomux-v1.c +++ b/arch/arm/mach-imx/iomux-v1.c @@ -38,12 +38,12 @@ static unsigned imx_iomuxv1_numports; static inline unsigned long imx_iomuxv1_readl(unsigned offset) { - return __raw_readl(imx_iomuxv1_baseaddr + offset); + return imx_readl(imx_iomuxv1_baseaddr + offset); } static inline void imx_iomuxv1_writel(unsigned long val, unsigned offset) { - __raw_writel(val, imx_iomuxv1_baseaddr + offset); + imx_writel(val, imx_iomuxv1_baseaddr + offset); } static inline void imx_iomuxv1_rmwl(unsigned offset, diff --git a/arch/arm/mach-imx/iomux-v3.c b/arch/arm/mach-imx/iomux-v3.c index a53b2e64f98d547594243a67bf3581ac63250ea7..ca59d5f2ec92e4337e1f418ac83442ac8844806c 100644 --- a/arch/arm/mach-imx/iomux-v3.c +++ b/arch/arm/mach-imx/iomux-v3.c @@ -45,13 +45,13 @@ int mxc_iomux_v3_setup_pad(iomux_v3_cfg_t pad) u32 pad_ctrl = (pad & MUX_PAD_CTRL_MASK) >> MUX_PAD_CTRL_SHIFT; if (mux_ctrl_ofs) - __raw_writel(mux_mode, base + mux_ctrl_ofs); + imx_writel(mux_mode, base + mux_ctrl_ofs); if (sel_input_ofs) - __raw_writel(sel_input, base + sel_input_ofs); + imx_writel(sel_input, base + sel_input_ofs); if (!(pad_ctrl & NO_PAD_CTRL) && pad_ctrl_ofs) - __raw_writel(pad_ctrl, base + pad_ctrl_ofs); + imx_writel(pad_ctrl, base + pad_ctrl_ofs); return 0; } diff --git a/arch/arm/mach-imx/mach-armadillo5x0.c b/arch/arm/mach-imx/mach-armadillo5x0.c index f2060523ba489c3feca3c2083fdd28a7594a4412..eaee47a2fcc0f6d2e196af4dea2d7c3dc74edd2b 100644 --- a/arch/arm/mach-imx/mach-armadillo5x0.c +++ b/arch/arm/mach-imx/mach-armadillo5x0.c @@ -525,8 +525,8 @@ static void __init armadillo5x0_init(void) imx31_add_mxc_nand(&armadillo5x0_nand_board_info); /* set NAND page size to 2k if not configured via boot mode pins */ - __raw_writel(__raw_readl(mx3_ccm_base + MXC_CCM_RCSR) | - (1 << 30), mx3_ccm_base + MXC_CCM_RCSR); + imx_writel(imx_readl(mx3_ccm_base + MXC_CCM_RCSR) | (1 << 30), + mx3_ccm_base + MXC_CCM_RCSR); /* RTC */ /* Get RTC IRQ and register the chip */ diff --git a/arch/arm/mach-imx/mach-imx25.c b/arch/arm/mach-imx/mach-imx25.c index 9379fd0a7b4de840d3801576601a1e10bbfb0ce8..32dcb5e99e23312709231d4d8809407a654989cb 100644 --- a/arch/arm/mach-imx/mach-imx25.c +++ b/arch/arm/mach-imx/mach-imx25.c @@ -41,6 +41,7 @@ static const char * const imx25_dt_board_compat[] __initconst = { DT_MACHINE_START(IMX25_DT, "Freescale i.MX25 (Device Tree Support)") .init_early = imx25_init_early, + .init_late = imx25_pm_init, .init_irq = mx25_init_irq, .dt_compat = imx25_dt_board_compat, MACHINE_END diff --git a/arch/arm/mach-imx/mach-imx51.c b/arch/arm/mach-imx/mach-imx51.c index b015129e4045847a3e62b72fb001a71e8b80c55c..6883fbaf9484b2da00324d42ce2ada3e70cefc66 100644 --- a/arch/arm/mach-imx/mach-imx51.c +++ b/arch/arm/mach-imx/mach-imx51.c @@ -40,11 +40,10 @@ static void __init imx51_ipu_mipi_setup(void) WARN_ON(!hsc_addr); /* setup MIPI module to legacy mode */ - __raw_writel(0xf00, hsc_addr); + imx_writel(0xf00, hsc_addr); /* CSI mode: reserved; DI control mode: legacy (from Freescale BSP) */ - __raw_writel(__raw_readl(hsc_addr + 0x800) | 0x30ff, - hsc_addr + 0x800); + imx_writel(imx_readl(hsc_addr + 0x800) | 0x30ff, hsc_addr + 0x800); iounmap(hsc_addr); } diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 3878494bd11827756150235f404e86cb520a14a0..cb27d566d5abab3865fd6e0689832c933b6a8993 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -266,8 +266,11 @@ static void __init imx6q_init_machine(void) { struct device *parent; - imx_print_silicon_rev(cpu_is_imx6dl() ? "i.MX6DL" : "i.MX6Q", - imx_get_soc_revision()); + if (cpu_is_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_2_0) + imx_print_silicon_rev("i.MX6QP", IMX_CHIP_REVISION_1_0); + else + imx_print_silicon_rev(cpu_is_imx6dl() ? "i.MX6DL" : "i.MX6Q", + imx_get_soc_revision()); parent = imx_soc_device_init(); if (parent == NULL) @@ -399,6 +402,7 @@ static void __init imx6q_init_irq(void) static const char * const imx6q_dt_compat[] __initconst = { "fsl,imx6dl", "fsl,imx6q", + "fsl,imx6qp", NULL, }; diff --git a/arch/arm/mach-imx/mach-mx27ads.c b/arch/arm/mach-imx/mach-mx27ads.c index f510c43981d3a98f5ed8f9c305df329192a64ea7..a4c389eae31a2384134a5b4b31b111651ec007a6 100644 --- a/arch/arm/mach-imx/mach-mx27ads.c +++ b/arch/arm/mach-imx/mach-mx27ads.c @@ -204,9 +204,9 @@ static struct i2c_board_info mx27ads_i2c_devices[] = { static void vgpio_set(struct gpio_chip *chip, unsigned offset, int value) { if (value) - __raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_SET_REG); + imx_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_SET_REG); else - __raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_CLEAR_REG); + imx_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_CLEAR_REG); } static int vgpio_dir_out(struct gpio_chip *chip, unsigned offset, int value) @@ -366,7 +366,7 @@ static void __init mx27ads_timer_init(void) { unsigned long fref = 26000000; - if ((__raw_readw(PBC_VERSION_REG) & CKIH_27MHZ_BIT_SET) == 0) + if ((imx_readw(PBC_VERSION_REG) & CKIH_27MHZ_BIT_SET) == 0) fref = 27000000; mx27_clocks_init(fref); diff --git a/arch/arm/mach-imx/mach-mx31ads.c b/arch/arm/mach-imx/mach-mx31ads.c index 2b147e4bf9c91297deb0522bcfb14150b61f5b11..4f2c56d44ba14de19f10ccc2dc16927a4b03a545 100644 --- a/arch/arm/mach-imx/mach-mx31ads.c +++ b/arch/arm/mach-imx/mach-mx31ads.c @@ -160,8 +160,8 @@ static void mx31ads_expio_irq_handler(struct irq_desc *desc) u32 int_valid; u32 expio_irq; - imr_val = __raw_readw(PBC_INTMASK_SET_REG); - int_valid = __raw_readw(PBC_INTSTATUS_REG) & imr_val; + imr_val = imx_readw(PBC_INTMASK_SET_REG); + int_valid = imx_readw(PBC_INTSTATUS_REG) & imr_val; expio_irq = 0; for (; int_valid != 0; int_valid >>= 1, expio_irq++) { @@ -180,8 +180,8 @@ static void expio_mask_irq(struct irq_data *d) { u32 expio = d->hwirq; /* mask the interrupt */ - __raw_writew(1 << expio, PBC_INTMASK_CLEAR_REG); - __raw_readw(PBC_INTMASK_CLEAR_REG); + imx_writew(1 << expio, PBC_INTMASK_CLEAR_REG); + imx_readw(PBC_INTMASK_CLEAR_REG); } /* @@ -192,7 +192,7 @@ static void expio_ack_irq(struct irq_data *d) { u32 expio = d->hwirq; /* clear the interrupt status */ - __raw_writew(1 << expio, PBC_INTSTATUS_REG); + imx_writew(1 << expio, PBC_INTSTATUS_REG); } /* @@ -203,7 +203,7 @@ static void expio_unmask_irq(struct irq_data *d) { u32 expio = d->hwirq; /* unmask the interrupt */ - __raw_writew(1 << expio, PBC_INTMASK_SET_REG); + imx_writew(1 << expio, PBC_INTMASK_SET_REG); } static struct irq_chip expio_irq_chip = { @@ -226,8 +226,8 @@ static void __init mx31ads_init_expio(void) mxc_iomux_alloc_pin(IOMUX_MODE(MX31_PIN_GPIO1_4, IOMUX_CONFIG_GPIO), "expio"); /* disable the interrupt and clear the status */ - __raw_writew(0xFFFF, PBC_INTMASK_CLEAR_REG); - __raw_writew(0xFFFF, PBC_INTSTATUS_REG); + imx_writew(0xFFFF, PBC_INTMASK_CLEAR_REG); + imx_writew(0xFFFF, PBC_INTSTATUS_REG); irq_base = irq_alloc_descs(-1, 0, MXC_MAX_EXP_IO_LINES, numa_node_id()); WARN_ON(irq_base < 0); diff --git a/arch/arm/mach-imx/mach-mx31moboard.c b/arch/arm/mach-imx/mach-mx31moboard.c index bb6f8a52a6b8b2ebaba9b8be1dc6f9478cfc3c2c..4f2d99888afd28833044022396a6ea9582a2c994 100644 --- a/arch/arm/mach-imx/mach-mx31moboard.c +++ b/arch/arm/mach-imx/mach-mx31moboard.c @@ -509,7 +509,7 @@ static void mx31moboard_poweroff(void) mxc_iomux_mode(MX31_PIN_WATCHDOG_RST__WATCHDOG_RST); - __raw_writew(1 << 6 | 1 << 2, MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR)); + imx_writew(1 << 6 | 1 << 2, MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR)); } static int mx31moboard_baseboard; diff --git a/arch/arm/mach-imx/mach-qong.c b/arch/arm/mach-imx/mach-qong.c index 5c27646047270fc4fbcab94e689f5e533d3d9d09..34df64f133ed2f360ee57354c75a10649815bf90 100644 --- a/arch/arm/mach-imx/mach-qong.c +++ b/arch/arm/mach-imx/mach-qong.c @@ -190,9 +190,9 @@ static struct platform_device qong_nand_device = { static void __init qong_init_nand_mtd(void) { /* init CS */ - __raw_writel(0x00004f00, MX31_IO_ADDRESS(MX31_WEIM_CSCRxU(3))); - __raw_writel(0x20013b31, MX31_IO_ADDRESS(MX31_WEIM_CSCRxL(3))); - __raw_writel(0x00020800, MX31_IO_ADDRESS(MX31_WEIM_CSCRxA(3))); + imx_writel(0x00004f00, MX31_IO_ADDRESS(MX31_WEIM_CSCRxU(3))); + imx_writel(0x20013b31, MX31_IO_ADDRESS(MX31_WEIM_CSCRxL(3))); + imx_writel(0x00020800, MX31_IO_ADDRESS(MX31_WEIM_CSCRxA(3))); mxc_iomux_set_gpr(MUX_SDCTL_CSD1_SEL, true); diff --git a/arch/arm/mach-imx/mxc.h b/arch/arm/mach-imx/mxc.h index a5b1af6d7441e262a49bd19d2611adfdc3364b14..d327042567817adf27b95b9eac2a29ac4df23d98 100644 --- a/arch/arm/mach-imx/mxc.h +++ b/arch/arm/mach-imx/mxc.h @@ -193,4 +193,9 @@ extern struct cpu_op *(*get_cpu_op)(int *op); #define cpu_is_mx3() (cpu_is_mx31() || cpu_is_mx35()) #define cpu_is_mx2() (cpu_is_mx21() || cpu_is_mx27()) +#define imx_readl readl_relaxed +#define imx_readw readw_relaxed +#define imx_writel writel_relaxed +#define imx_writew writew_relaxed + #endif /* __ASM_ARCH_MXC_H__ */ diff --git a/arch/arm/mach-imx/pm-imx25.c b/arch/arm/mach-imx/pm-imx25.c new file mode 100644 index 0000000000000000000000000000000000000000..8bba9fcd96f66822b2f9de54ff458381395656bd --- /dev/null +++ b/arch/arm/mach-imx/pm-imx25.c @@ -0,0 +1,37 @@ +/* + * Copyright 2016 NXP Semiconductors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include + +static int imx25_suspend_enter(suspend_state_t state) +{ + if (!IS_ENABLED(CONFIG_PM)) + return 0; + + switch (state) { + case PM_SUSPEND_MEM: + cpu_do_idle(); + break; + default: + return -EINVAL; + } + + return 0; +} + +static const struct platform_suspend_ops imx25_suspend_ops = { + .enter = imx25_suspend_enter, + .valid = suspend_valid_only_mem, +}; + +void __init imx25_pm_init(void) +{ + suspend_set_ops(&imx25_suspend_ops); +} diff --git a/arch/arm/mach-imx/pm-imx27.c b/arch/arm/mach-imx/pm-imx27.c index 56d02d064fbf941c3b070cced2bf2f2e88a9056e..43096c8990d4cb913935b62c758107316e46a637 100644 --- a/arch/arm/mach-imx/pm-imx27.c +++ b/arch/arm/mach-imx/pm-imx27.c @@ -19,9 +19,9 @@ static int mx27_suspend_enter(suspend_state_t state) switch (state) { case PM_SUSPEND_MEM: /* Clear MPEN and SPEN to disable MPLL/SPLL */ - cscr = __raw_readl(MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR)); + cscr = imx_readl(MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR)); cscr &= 0xFFFFFFFC; - __raw_writel(cscr, MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR)); + imx_writel(cscr, MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR)); /* Executes WFI */ cpu_do_idle(); break; diff --git a/arch/arm/mach-imx/pm-imx3.c b/arch/arm/mach-imx/pm-imx3.c index 6a07006ff0f48136591ff0909636cd73b774bf08..94c0898751d8538290a258fa1cb3d4d50ba8b9f0 100644 --- a/arch/arm/mach-imx/pm-imx3.c +++ b/arch/arm/mach-imx/pm-imx3.c @@ -22,14 +22,14 @@ */ void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode) { - int reg = __raw_readl(mx3_ccm_base + MXC_CCM_CCMR); + int reg = imx_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, mx3_ccm_base + MXC_CCM_CCMR); + imx_writel(reg, mx3_ccm_base + MXC_CCM_CCMR); break; default: pr_err("Unknown cpu power mode: %d\n", mode); diff --git a/arch/arm/mach-imx/pm-imx5.c b/arch/arm/mach-imx/pm-imx5.c index 532d4b08276dc84c149b525e6fcc0a85d30a543b..868781fd460c788950ac59e6ef197bede4ab6660 100644 --- a/arch/arm/mach-imx/pm-imx5.c +++ b/arch/arm/mach-imx/pm-imx5.c @@ -153,15 +153,15 @@ static void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode) int stop_mode = 0; /* always allow platform to issue a deep sleep mode request */ - plat_lpc = __raw_readl(cortex_base + MXC_CORTEXA8_PLAT_LPC) & + plat_lpc = imx_readl(cortex_base + MXC_CORTEXA8_PLAT_LPC) & ~(MXC_CORTEXA8_PLAT_LPC_DSM); - ccm_clpcr = __raw_readl(ccm_base + MXC_CCM_CLPCR) & + ccm_clpcr = imx_readl(ccm_base + MXC_CCM_CLPCR) & ~(MXC_CCM_CLPCR_LPM_MASK); - arm_srpgcr = __raw_readl(gpc_base + MXC_SRPG_ARM_SRPGCR) & + arm_srpgcr = imx_readl(gpc_base + MXC_SRPG_ARM_SRPGCR) & ~(MXC_SRPGCR_PCR); - empgc0 = __raw_readl(gpc_base + MXC_SRPG_EMPGC0_SRPGCR) & + empgc0 = imx_readl(gpc_base + MXC_SRPG_EMPGC0_SRPGCR) & ~(MXC_SRPGCR_PCR); - empgc1 = __raw_readl(gpc_base + MXC_SRPG_EMPGC1_SRPGCR) & + empgc1 = imx_readl(gpc_base + MXC_SRPG_EMPGC1_SRPGCR) & ~(MXC_SRPGCR_PCR); switch (mode) { @@ -196,17 +196,17 @@ static void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode) return; } - __raw_writel(plat_lpc, cortex_base + MXC_CORTEXA8_PLAT_LPC); - __raw_writel(ccm_clpcr, ccm_base + MXC_CCM_CLPCR); - __raw_writel(arm_srpgcr, gpc_base + MXC_SRPG_ARM_SRPGCR); - __raw_writel(arm_srpgcr, gpc_base + MXC_SRPG_NEON_SRPGCR); + imx_writel(plat_lpc, cortex_base + MXC_CORTEXA8_PLAT_LPC); + imx_writel(ccm_clpcr, ccm_base + MXC_CCM_CLPCR); + imx_writel(arm_srpgcr, gpc_base + MXC_SRPG_ARM_SRPGCR); + imx_writel(arm_srpgcr, gpc_base + MXC_SRPG_NEON_SRPGCR); if (stop_mode) { empgc0 |= MXC_SRPGCR_PCR; empgc1 |= MXC_SRPGCR_PCR; - __raw_writel(empgc0, gpc_base + MXC_SRPG_EMPGC0_SRPGCR); - __raw_writel(empgc1, gpc_base + MXC_SRPG_EMPGC1_SRPGCR); + imx_writel(empgc0, gpc_base + MXC_SRPG_EMPGC0_SRPGCR); + imx_writel(empgc1, gpc_base + MXC_SRPG_EMPGC1_SRPGCR); } } @@ -228,8 +228,8 @@ static int mx5_suspend_enter(suspend_state_t state) flush_cache_all(); /*clear the EMPGC0/1 bits */ - __raw_writel(0, gpc_base + MXC_SRPG_EMPGC0_SRPGCR); - __raw_writel(0, gpc_base + MXC_SRPG_EMPGC1_SRPGCR); + imx_writel(0, gpc_base + MXC_SRPG_EMPGC0_SRPGCR); + imx_writel(0, gpc_base + MXC_SRPG_EMPGC1_SRPGCR); if (imx5_suspend_in_ocram_fn) imx5_suspend_in_ocram_fn(suspend_ocram_base); diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c index 4470376af5f815fd5f8f2d12c5e7d18306675bb4..58924b3844df551a270aac552b0803fb5eedf8dc 100644 --- a/arch/arm/mach-imx/pm-imx6.c +++ b/arch/arm/mach-imx/pm-imx6.c @@ -561,13 +561,13 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata) goto put_node; pl310_cache_map_failed: - iounmap(&pm_info->gpc_base.vbase); + iounmap(pm_info->gpc_base.vbase); gpc_map_failed: - iounmap(&pm_info->iomuxc_base.vbase); + iounmap(pm_info->iomuxc_base.vbase); iomuxc_map_failed: - iounmap(&pm_info->src_base.vbase); + iounmap(pm_info->src_base.vbase); src_map_failed: - iounmap(&pm_info->mmdc_base.vbase); + iounmap(pm_info->mmdc_base.vbase); put_node: of_node_put(node); diff --git a/arch/arm/mach-imx/src.c b/arch/arm/mach-imx/src.c index 45f7f4e0a447c517bb9b731eb402e33ea3083f43..70b083fe934a8f7763cd4cfc4dca0fea73f66d3d 100644 --- a/arch/arm/mach-imx/src.c +++ b/arch/arm/mach-imx/src.c @@ -73,7 +73,7 @@ static int imx_src_reset_module(struct reset_controller_dev *rcdev, return 0; } -static struct reset_control_ops imx_src_ops = { +static const struct reset_control_ops imx_src_ops = { .reset = imx_src_reset_module, }; diff --git a/arch/arm/mach-imx/system.c b/arch/arm/mach-imx/system.c index 51c35013b673b0d356c12ae8d0853557243c1f34..105d1ce4ed9d1400da09d476c03761e2de5c982e 100644 --- a/arch/arm/mach-imx/system.c +++ b/arch/arm/mach-imx/system.c @@ -54,7 +54,7 @@ void mxc_restart(enum reboot_mode mode, const char *cmd) wcr_enable = (1 << 2); /* Assert SRS signal */ - __raw_writew(wcr_enable, wdog_base); + imx_writew(wcr_enable, wdog_base); /* * Due to imx6q errata ERR004346 (WDOG: WDOG SRS bit requires to be * written twice), we add another two writes to ensure there must be at @@ -62,8 +62,8 @@ void mxc_restart(enum reboot_mode mode, const char *cmd) * the target check here, since the writes shouldn't be a huge burden * for other platforms. */ - __raw_writew(wcr_enable, wdog_base); - __raw_writew(wcr_enable, wdog_base); + imx_writew(wcr_enable, wdog_base); + imx_writew(wcr_enable, wdog_base); /* wait for reset to assert... */ mdelay(500); @@ -106,6 +106,9 @@ void __init imx_init_l2cache(void) goto out; } + if (readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN) + goto skip_if_enabled; + /* Configure the L2 PREFETCH and POWER registers */ val = readl_relaxed(l2x0_base + L310_PREFETCH_CTRL); val |= 0x70800000; @@ -122,6 +125,7 @@ void __init imx_init_l2cache(void) val &= ~(1 << 30 | 1 << 23); writel_relaxed(val, l2x0_base + L310_PREFETCH_CTRL); +skip_if_enabled: iounmap(l2x0_base); of_node_put(np); diff --git a/arch/arm/mach-imx/tzic.c b/arch/arm/mach-imx/tzic.c index 4de65eeda1eb15666e9c82557f50477e37628ec8..ae23d50f7861b4d804e38025927922f0eb5f6e1f 100644 --- a/arch/arm/mach-imx/tzic.c +++ b/arch/arm/mach-imx/tzic.c @@ -65,10 +65,10 @@ static int tzic_set_irq_fiq(unsigned int irq, unsigned int type) return -EINVAL; mask = 1U << (irq & 0x1F); - value = __raw_readl(tzic_base + TZIC_INTSEC0(index)) | mask; + value = imx_readl(tzic_base + TZIC_INTSEC0(index)) | mask; if (type) value &= ~mask; - __raw_writel(value, tzic_base + TZIC_INTSEC0(index)); + imx_writel(value, tzic_base + TZIC_INTSEC0(index)); return 0; } @@ -82,15 +82,15 @@ static void tzic_irq_suspend(struct irq_data *d) struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); int idx = d->hwirq >> 5; - __raw_writel(gc->wake_active, tzic_base + TZIC_WAKEUP0(idx)); + imx_writel(gc->wake_active, tzic_base + TZIC_WAKEUP0(idx)); } static void tzic_irq_resume(struct irq_data *d) { int idx = d->hwirq >> 5; - __raw_writel(__raw_readl(tzic_base + TZIC_ENSET0(idx)), - tzic_base + TZIC_WAKEUP0(idx)); + imx_writel(imx_readl(tzic_base + TZIC_ENSET0(idx)), + tzic_base + TZIC_WAKEUP0(idx)); } #else @@ -135,8 +135,8 @@ static void __exception_irq_entry tzic_handle_irq(struct pt_regs *regs) handled = 0; for (i = 0; i < 4; i++) { - stat = __raw_readl(tzic_base + TZIC_HIPND(i)) & - __raw_readl(tzic_base + TZIC_INTSEC0(i)); + stat = imx_readl(tzic_base + TZIC_HIPND(i)) & + imx_readl(tzic_base + TZIC_INTSEC0(i)); while (stat) { handled = 1; @@ -166,18 +166,18 @@ void __init tzic_init_irq(void) /* put the TZIC into the reset value with * all interrupts disabled */ - i = __raw_readl(tzic_base + TZIC_INTCNTL); + i = imx_readl(tzic_base + TZIC_INTCNTL); - __raw_writel(0x80010001, tzic_base + TZIC_INTCNTL); - __raw_writel(0x1f, tzic_base + TZIC_PRIOMASK); - __raw_writel(0x02, tzic_base + TZIC_SYNCCTRL); + imx_writel(0x80010001, tzic_base + TZIC_INTCNTL); + imx_writel(0x1f, tzic_base + TZIC_PRIOMASK); + imx_writel(0x02, tzic_base + TZIC_SYNCCTRL); for (i = 0; i < 4; i++) - __raw_writel(0xFFFFFFFF, tzic_base + TZIC_INTSEC0(i)); + imx_writel(0xFFFFFFFF, tzic_base + TZIC_INTSEC0(i)); /* disable all interrupts */ for (i = 0; i < 4; i++) - __raw_writel(0xFFFFFFFF, tzic_base + TZIC_ENCLEAR0(i)); + imx_writel(0xFFFFFFFF, tzic_base + TZIC_ENCLEAR0(i)); /* all IRQ no FIQ Warning :: No selection */ @@ -214,13 +214,13 @@ int tzic_enable_wake(void) { unsigned int i; - __raw_writel(1, tzic_base + TZIC_DSMINT); - if (unlikely(__raw_readl(tzic_base + TZIC_DSMINT) == 0)) + imx_writel(1, tzic_base + TZIC_DSMINT); + if (unlikely(imx_readl(tzic_base + TZIC_DSMINT) == 0)) return -EAGAIN; for (i = 0; i < 4; i++) - __raw_writel(__raw_readl(tzic_base + TZIC_ENSET0(i)), - tzic_base + TZIC_WAKEUP0(i)); + imx_writel(imx_readl(tzic_base + TZIC_ENSET0(i)), + tzic_base + TZIC_WAKEUP0(i)); return 0; } diff --git a/arch/arm/mach-integrator/Kconfig b/arch/arm/mach-integrator/Kconfig index b01bdc9baf89520096ff348ba5d20e14c4aa0b87..b2a85ba13f088fb451377fa09d800df34e926846 100644 --- a/arch/arm/mach-integrator/Kconfig +++ b/arch/arm/mach-integrator/Kconfig @@ -2,22 +2,16 @@ menuconfig ARCH_INTEGRATOR bool "ARM Ltd. Integrator family" depends on ARCH_MULTI_V4T || ARCH_MULTI_V5 || ARCH_MULTI_V6 select ARM_AMBA - select ARM_PATCH_PHYS_VIRT if MMU - select AUTO_ZRELADDR - select COMMON_CLK select COMMON_CLK_VERSATILE - select GENERIC_CLOCKEVENTS select HAVE_TCM select ICST select MFD_SYSCON - select MULTI_IRQ_HANDLER select PLAT_VERSATILE select POWER_RESET select POWER_RESET_VERSATILE select POWER_SUPPLY select SOC_INTEGRATOR_CM select SPARSE_IRQ - select USE_OF select VERSATILE_FPGA_IRQ help Support for ARM's Integrator platform. diff --git a/arch/arm/mach-integrator/Makefile.boot b/arch/arm/mach-integrator/Makefile.boot deleted file mode 100644 index ff0a4b5b0a82b5873a119ec072b3db781651ab86..0000000000000000000000000000000000000000 --- a/arch/arm/mach-integrator/Makefile.boot +++ /dev/null @@ -1,4 +0,0 @@ - zreladdr-y += 0x00008000 -params_phys-y := 0x00000100 -initrd_phys-y := 0x00800000 - diff --git a/arch/arm/mach-keystone/Makefile.boot b/arch/arm/mach-keystone/Makefile.boot deleted file mode 100644 index f3835c43af61fa92ff58a778502787bd91a9b82d..0000000000000000000000000000000000000000 --- a/arch/arm/mach-keystone/Makefile.boot +++ /dev/null @@ -1 +0,0 @@ -zreladdr-y := 0x80008000 diff --git a/arch/arm/mach-keystone/keystone.c b/arch/arm/mach-keystone/keystone.c index c279293f084cb87c2e0cc4cbf4ada1e2984e83f2..e6b9cb1e6709753b6e25166d8b9cac395d9a2c42 100644 --- a/arch/arm/mach-keystone/keystone.c +++ b/arch/arm/mach-keystone/keystone.c @@ -63,7 +63,7 @@ static void __init keystone_init(void) of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } -static phys_addr_t keystone_virt_to_idmap(unsigned long x) +static unsigned long keystone_virt_to_idmap(unsigned long x) { return (phys_addr_t)(x) - CONFIG_PAGE_OFFSET + KEYSTONE_LOW_PHYS_START; } @@ -100,6 +100,7 @@ static const char *const keystone_match[] __initconst = { "ti,k2hk", "ti,k2e", "ti,k2l", + "ti,k2g", "ti,keystone", NULL, }; diff --git a/arch/arm/mach-ks8695/board-og.c b/arch/arm/mach-ks8695/board-og.c index 1f4f2f4f25bb0b543e2a1cf5911eca6b7d438b7a..478ebd1f2b0f27ff16547e65e6cabde8289bdada 100644 --- a/arch/arm/mach-ks8695/board-og.c +++ b/arch/arm/mach-ks8695/board-og.c @@ -80,7 +80,7 @@ static void __init og_pci_bus_reset(void) #define S8250_VIRT 0xf4000000 #define S8250_SIZE 0x00100000 -static struct __initdata map_desc og_io_desc[] = { +static struct map_desc og_io_desc[] __initdata = { { .virtual = S8250_VIRT, .pfn = __phys_to_pfn(S8250_PHYS), diff --git a/arch/arm/mach-ks8695/cpu.c b/arch/arm/mach-ks8695/cpu.c index 474a050da85b91406afd85fc1efb1fc06a2695d3..7a1c4caa1ab5ae2943c7d03d18e272b5a4ee1953 100644 --- a/arch/arm/mach-ks8695/cpu.c +++ b/arch/arm/mach-ks8695/cpu.c @@ -34,7 +34,7 @@ #include -static struct __initdata map_desc ks8695_io_desc[] = { +static struct map_desc ks8695_io_desc[] __initdata = { { .virtual = (unsigned long)KS8695_IO_VA, .pfn = __phys_to_pfn(KS8695_IO_PA), diff --git a/arch/arm/mach-ks8695/include/mach/uncompress.h b/arch/arm/mach-ks8695/include/mach/uncompress.h index c089a1aea674ee58a0e217ea3ee5034b08ed9a28..a001c7c34df22ea9badd1fdb71766946a904404a 100644 --- a/arch/arm/mach-ks8695/include/mach/uncompress.h +++ b/arch/arm/mach-ks8695/include/mach/uncompress.h @@ -17,7 +17,7 @@ #include #include -static void putc(char c) +static inline void putc(char c) { while (!(__raw_readl((void __iomem*)KS8695_UART_PA + KS8695_URLS) & URLS_URTHRE)) barrier(); diff --git a/arch/arm/mach-lpc32xx/Makefile b/arch/arm/mach-lpc32xx/Makefile index f5db805ab95872bb38838a5129324ccbbedb1529..c70709ada692ed05a001131e36e63b4d15103a95 100644 --- a/arch/arm/mach-lpc32xx/Makefile +++ b/arch/arm/mach-lpc32xx/Makefile @@ -2,7 +2,6 @@ # Makefile for the linux kernel. # -obj-y := timer.o irq.o common.o serial.o clock.o +obj-y := irq.o common.o serial.o obj-y += pm.o suspend.o obj-y += phy3250.o - diff --git a/arch/arm/mach-lpc32xx/clock.c b/arch/arm/mach-lpc32xx/clock.c deleted file mode 100644 index 661c8f4b23102368e91d7420f50b36ccdaeab2a2..0000000000000000000000000000000000000000 --- a/arch/arm/mach-lpc32xx/clock.c +++ /dev/null @@ -1,1284 +0,0 @@ -/* - * arch/arm/mach-lpc32xx/clock.c - * - * Author: Kevin Wells - * - * Copyright (C) 2010 NXP Semiconductors - * - * 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. - */ - -/* - * LPC32xx clock management driver overview - * - * The LPC32XX contains a number of high level system clocks that can be - * generated from different sources. These system clocks are used to - * generate the CPU and bus rates and the individual peripheral clocks in - * the system. When Linux is started by the boot loader, the system - * clocks are already running. Stopping a system clock during normal - * Linux operation should never be attempted, as peripherals that require - * those clocks will quit working (ie, DRAM). - * - * The LPC32xx high level clock tree looks as follows. Clocks marked with - * an asterisk are always on and cannot be disabled. Clocks marked with - * an ampersand can only be disabled in CPU suspend mode. Clocks marked - * with a caret are always on if it is the selected clock for the SYSCLK - * source. The clock that isn't used for SYSCLK can be enabled and - * disabled normally. - * 32KHz oscillator* - * / | \ - * RTC* PLL397^ TOUCH - * / - * Main oscillator^ / - * | \ / - * | SYSCLK& - * | \ - * | \ - * USB_PLL HCLK_PLL& - * | | | - * USB host/device PCLK& | - * | | - * Peripherals - * - * The CPU and chip bus rates are derived from the HCLK PLL, which can - * generate various clock rates up to 266MHz and beyond. The internal bus - * rates (PCLK and HCLK) are generated from dividers based on the HCLK - * PLL rate. HCLK can be a ratio of 1:1, 1:2, or 1:4 or HCLK PLL rate, - * while PCLK can be 1:1 to 1:32 of HCLK PLL rate. Most peripherals high - * level clocks are based on either HCLK or PCLK, but have their own - * dividers as part of the IP itself. Because of this, the system clock - * rates should not be changed. - * - * The HCLK PLL is clocked from SYSCLK, which can be derived from the - * main oscillator or PLL397. PLL397 generates a rate that is 397 times - * the 32KHz oscillator rate. The main oscillator runs at the selected - * oscillator/crystal rate on the mosc_in pin of the LPC32xx. This rate - * is normally 13MHz, but depends on the selection of external crystals - * or oscillators. If USB operation is required, the main oscillator must - * be used in the system. - * - * Switching SYSCLK between sources during normal Linux operation is not - * supported. SYSCLK is preset in the bootloader. Because of the - * complexities of clock management during clock frequency changes, - * there are some limitations to the clock driver explained below: - * - The PLL397 and main oscillator can be enabled and disabled by the - * clk_enable() and clk_disable() functions unless SYSCLK is based - * on that clock. This allows the other oscillator that isn't driving - * the HCLK PLL to be used as another system clock that can be routed - * to an external pin. - * - The muxed SYSCLK input and HCLK_PLL rate cannot be changed with - * this driver. - * - HCLK and PCLK rates cannot be changed as part of this driver. - * - Most peripherals have their own dividers are part of the peripheral - * block. Changing SYSCLK, HCLK PLL, HCLK, or PCLK sources or rates - * will also impact the individual peripheral rates. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "clock.h" -#include "common.h" - -static DEFINE_SPINLOCK(global_clkregs_lock); - -static int usb_pll_enable, usb_pll_valid; - -static struct clk clk_armpll; -static struct clk clk_usbpll; - -/* - * Post divider values for PLLs based on selected register value - */ -static const u32 pll_postdivs[4] = {1, 2, 4, 8}; - -static unsigned long local_return_parent_rate(struct clk *clk) -{ - /* - * If a clock has a rate of 0, then it inherits it's parent - * clock rate - */ - while (clk->rate == 0) - clk = clk->parent; - - return clk->rate; -} - -/* 32KHz clock has a fixed rate and is not stoppable */ -static struct clk osc_32KHz = { - .rate = LPC32XX_CLOCK_OSC_FREQ, - .get_rate = local_return_parent_rate, -}; - -static int local_pll397_enable(struct clk *clk, int enable) -{ - u32 reg; - unsigned long timeout = jiffies + msecs_to_jiffies(10); - - reg = __raw_readl(LPC32XX_CLKPWR_PLL397_CTRL); - - if (enable == 0) { - reg |= LPC32XX_CLKPWR_SYSCTRL_PLL397_DIS; - __raw_writel(reg, LPC32XX_CLKPWR_PLL397_CTRL); - } else { - /* Enable PLL397 */ - reg &= ~LPC32XX_CLKPWR_SYSCTRL_PLL397_DIS; - __raw_writel(reg, LPC32XX_CLKPWR_PLL397_CTRL); - - /* Wait for PLL397 lock */ - while (((__raw_readl(LPC32XX_CLKPWR_PLL397_CTRL) & - LPC32XX_CLKPWR_SYSCTRL_PLL397_STS) == 0) && - time_before(jiffies, timeout)) - cpu_relax(); - - if ((__raw_readl(LPC32XX_CLKPWR_PLL397_CTRL) & - LPC32XX_CLKPWR_SYSCTRL_PLL397_STS) == 0) - return -ENODEV; - } - - return 0; -} - -static int local_oscmain_enable(struct clk *clk, int enable) -{ - u32 reg; - unsigned long timeout = jiffies + msecs_to_jiffies(10); - - reg = __raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL); - - if (enable == 0) { - reg |= LPC32XX_CLKPWR_MOSC_DISABLE; - __raw_writel(reg, LPC32XX_CLKPWR_MAIN_OSC_CTRL); - } else { - /* Enable main oscillator */ - reg &= ~LPC32XX_CLKPWR_MOSC_DISABLE; - __raw_writel(reg, LPC32XX_CLKPWR_MAIN_OSC_CTRL); - - /* Wait for main oscillator to start */ - while (((__raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL) & - LPC32XX_CLKPWR_MOSC_DISABLE) != 0) && - time_before(jiffies, timeout)) - cpu_relax(); - - if ((__raw_readl(LPC32XX_CLKPWR_MAIN_OSC_CTRL) & - LPC32XX_CLKPWR_MOSC_DISABLE) != 0) - return -ENODEV; - } - - return 0; -} - -static struct clk osc_pll397 = { - .parent = &osc_32KHz, - .enable = local_pll397_enable, - .rate = LPC32XX_CLOCK_OSC_FREQ * 397, - .get_rate = local_return_parent_rate, -}; - -static struct clk osc_main = { - .enable = local_oscmain_enable, - .rate = LPC32XX_MAIN_OSC_FREQ, - .get_rate = local_return_parent_rate, -}; - -static struct clk clk_sys; - -/* - * Convert a PLL register value to a PLL output frequency - */ -u32 clk_get_pllrate_from_reg(u32 inputclk, u32 regval) -{ - struct clk_pll_setup pllcfg; - - pllcfg.cco_bypass_b15 = 0; - pllcfg.direct_output_b14 = 0; - pllcfg.fdbk_div_ctrl_b13 = 0; - if ((regval & LPC32XX_CLKPWR_HCLKPLL_CCO_BYPASS) != 0) - pllcfg.cco_bypass_b15 = 1; - if ((regval & LPC32XX_CLKPWR_HCLKPLL_POSTDIV_BYPASS) != 0) - pllcfg.direct_output_b14 = 1; - if ((regval & LPC32XX_CLKPWR_HCLKPLL_FDBK_SEL_FCLK) != 0) - pllcfg.fdbk_div_ctrl_b13 = 1; - pllcfg.pll_m = 1 + ((regval >> 1) & 0xFF); - pllcfg.pll_n = 1 + ((regval >> 9) & 0x3); - pllcfg.pll_p = pll_postdivs[((regval >> 11) & 0x3)]; - - return clk_check_pll_setup(inputclk, &pllcfg); -} - -/* - * Setup the HCLK PLL with a PLL structure - */ -static u32 local_clk_pll_setup(struct clk_pll_setup *PllSetup) -{ - u32 tv, tmp = 0; - - if (PllSetup->analog_on != 0) - tmp |= LPC32XX_CLKPWR_HCLKPLL_POWER_UP; - if (PllSetup->cco_bypass_b15 != 0) - tmp |= LPC32XX_CLKPWR_HCLKPLL_CCO_BYPASS; - if (PllSetup->direct_output_b14 != 0) - tmp |= LPC32XX_CLKPWR_HCLKPLL_POSTDIV_BYPASS; - if (PllSetup->fdbk_div_ctrl_b13 != 0) - tmp |= LPC32XX_CLKPWR_HCLKPLL_FDBK_SEL_FCLK; - - tv = ffs(PllSetup->pll_p) - 1; - if ((!is_power_of_2(PllSetup->pll_p)) || (tv > 3)) - return 0; - - tmp |= LPC32XX_CLKPWR_HCLKPLL_POSTDIV_2POW(tv); - tmp |= LPC32XX_CLKPWR_HCLKPLL_PREDIV_PLUS1(PllSetup->pll_n - 1); - tmp |= LPC32XX_CLKPWR_HCLKPLL_PLLM(PllSetup->pll_m - 1); - - return tmp; -} - -/* - * Update the ARM core PLL frequency rate variable from the actual PLL setting - */ -static void local_update_armpll_rate(void) -{ - u32 clkin, pllreg; - - clkin = clk_armpll.parent->rate; - pllreg = __raw_readl(LPC32XX_CLKPWR_HCLKPLL_CTRL) & 0x1FFFF; - - clk_armpll.rate = clk_get_pllrate_from_reg(clkin, pllreg); -} - -/* - * Find a PLL configuration for the selected input frequency - */ -static u32 local_clk_find_pll_cfg(u32 pllin_freq, u32 target_freq, - struct clk_pll_setup *pllsetup) -{ - u32 ifreq, freqtol, m, n, p, fclkout; - - /* Determine frequency tolerance limits */ - freqtol = target_freq / 250; - ifreq = pllin_freq; - - /* Is direct bypass mode possible? */ - if (abs(pllin_freq - target_freq) <= freqtol) { - pllsetup->analog_on = 0; - pllsetup->cco_bypass_b15 = 1; - pllsetup->direct_output_b14 = 1; - pllsetup->fdbk_div_ctrl_b13 = 1; - pllsetup->pll_p = pll_postdivs[0]; - pllsetup->pll_n = 1; - pllsetup->pll_m = 1; - return clk_check_pll_setup(ifreq, pllsetup); - } else if (target_freq <= ifreq) { - pllsetup->analog_on = 0; - pllsetup->cco_bypass_b15 = 1; - pllsetup->direct_output_b14 = 0; - pllsetup->fdbk_div_ctrl_b13 = 1; - pllsetup->pll_n = 1; - pllsetup->pll_m = 1; - for (p = 0; p <= 3; p++) { - pllsetup->pll_p = pll_postdivs[p]; - fclkout = clk_check_pll_setup(ifreq, pllsetup); - if (abs(target_freq - fclkout) <= freqtol) - return fclkout; - } - } - - /* Is direct mode possible? */ - pllsetup->analog_on = 1; - pllsetup->cco_bypass_b15 = 0; - pllsetup->direct_output_b14 = 1; - pllsetup->fdbk_div_ctrl_b13 = 0; - pllsetup->pll_p = pll_postdivs[0]; - for (m = 1; m <= 256; m++) { - for (n = 1; n <= 4; n++) { - /* Compute output frequency for this value */ - pllsetup->pll_n = n; - pllsetup->pll_m = m; - fclkout = clk_check_pll_setup(ifreq, - pllsetup); - if (abs(target_freq - fclkout) <= - freqtol) - return fclkout; - } - } - - /* Is integer mode possible? */ - pllsetup->analog_on = 1; - pllsetup->cco_bypass_b15 = 0; - pllsetup->direct_output_b14 = 0; - pllsetup->fdbk_div_ctrl_b13 = 1; - for (m = 1; m <= 256; m++) { - for (n = 1; n <= 4; n++) { - for (p = 0; p < 4; p++) { - /* Compute output frequency */ - pllsetup->pll_p = pll_postdivs[p]; - pllsetup->pll_n = n; - pllsetup->pll_m = m; - fclkout = clk_check_pll_setup( - ifreq, pllsetup); - if (abs(target_freq - fclkout) <= freqtol) - return fclkout; - } - } - } - - /* Try non-integer mode */ - pllsetup->analog_on = 1; - pllsetup->cco_bypass_b15 = 0; - pllsetup->direct_output_b14 = 0; - pllsetup->fdbk_div_ctrl_b13 = 0; - for (m = 1; m <= 256; m++) { - for (n = 1; n <= 4; n++) { - for (p = 0; p < 4; p++) { - /* Compute output frequency */ - pllsetup->pll_p = pll_postdivs[p]; - pllsetup->pll_n = n; - pllsetup->pll_m = m; - fclkout = clk_check_pll_setup( - ifreq, pllsetup); - if (abs(target_freq - fclkout) <= freqtol) - return fclkout; - } - } - } - - return 0; -} - -static struct clk clk_armpll = { - .parent = &clk_sys, - .get_rate = local_return_parent_rate, -}; - -/* - * Setup the USB PLL with a PLL structure - */ -static u32 local_clk_usbpll_setup(struct clk_pll_setup *pHCLKPllSetup) -{ - u32 reg, tmp = local_clk_pll_setup(pHCLKPllSetup); - - reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL) & ~0x1FFFF; - reg |= tmp; - __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL); - - return clk_check_pll_setup(clk_usbpll.parent->rate, - pHCLKPllSetup); -} - -static int local_usbpll_enable(struct clk *clk, int enable) -{ - u32 reg; - int ret = 0; - unsigned long timeout = jiffies + msecs_to_jiffies(20); - - reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL); - - __raw_writel(reg & ~(LPC32XX_CLKPWR_USBCTRL_CLK_EN2 | - LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP), - LPC32XX_CLKPWR_USB_CTRL); - __raw_writel(reg & ~LPC32XX_CLKPWR_USBCTRL_CLK_EN1, - LPC32XX_CLKPWR_USB_CTRL); - - if (enable && usb_pll_valid && usb_pll_enable) { - ret = -ENODEV; - /* - * If the PLL rate has been previously set, then the rate - * in the PLL register is valid and can be enabled here. - * Otherwise, it needs to be enabled as part of setrate. - */ - - /* - * Gate clock into PLL - */ - reg |= LPC32XX_CLKPWR_USBCTRL_CLK_EN1; - __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL); - - /* - * Enable PLL - */ - reg |= LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP; - __raw_writel(reg, LPC32XX_CLKPWR_USB_CTRL); - - /* - * Wait for PLL to lock - */ - while (time_before(jiffies, timeout) && (ret == -ENODEV)) { - reg = __raw_readl(LPC32XX_CLKPWR_USB_CTRL); - if (reg & LPC32XX_CLKPWR_USBCTRL_PLL_STS) - ret = 0; - else - udelay(10); - } - - /* - * Gate clock from PLL if PLL is locked - */ - if (ret == 0) { - __raw_writel(reg | LPC32XX_CLKPWR_USBCTRL_CLK_EN2, - LPC32XX_CLKPWR_USB_CTRL); - } else { - __raw_writel(reg & ~(LPC32XX_CLKPWR_USBCTRL_CLK_EN1 | - LPC32XX_CLKPWR_USBCTRL_PLL_PWRUP), - LPC32XX_CLKPWR_USB_CTRL); - } - } else if ((enable == 0) && usb_pll_valid && usb_pll_enable) { - usb_pll_valid = 0; - usb_pll_enable = 0; - } - - return ret; -} - -static unsigned long local_usbpll_round_rate(struct clk *clk, - unsigned long rate) -{ - u32 clkin, usbdiv; - struct clk_pll_setup pllsetup; - - /* - * Unlike other clocks, this clock has a KHz input rate, so bump - * it up to work with the PLL function - */ - rate = rate * 1000; - - clkin = clk->get_rate(clk); - usbdiv = (__raw_readl(LPC32XX_CLKPWR_USBCLK_PDIV) & - LPC32XX_CLKPWR_USBPDIV_PLL_MASK) + 1; - clkin = clkin / usbdiv; - - /* Try to find a good rate setup */ - if (local_clk_find_pll_cfg(clkin, rate, &pllsetup) == 0) - return 0; - - return clk_check_pll_setup(clkin, &pllsetup); -} - -static int local_usbpll_set_rate(struct clk *clk, unsigned long rate) -{ - int ret = -ENODEV; - u32 clkin, usbdiv; - struct clk_pll_setup pllsetup; - - /* - * Unlike other clocks, this clock has a KHz input rate, so bump - * it up to work with the PLL function - */ - rate = rate * 1000; - - clkin = clk->get_rate(clk->parent); - usbdiv = (__raw_readl(LPC32XX_CLKPWR_USBCLK_PDIV) & - LPC32XX_CLKPWR_USBPDIV_PLL_MASK) + 1; - clkin = clkin / usbdiv; - - /* Try to find a good rate setup */ - if (local_clk_find_pll_cfg(clkin, rate, &pllsetup) == 0) - return -EINVAL; - - /* - * Disable PLL clocks during PLL change - */ - local_usbpll_enable(clk, 0); - pllsetup.analog_on = 0; - local_clk_usbpll_setup(&pllsetup); - - /* - * Start USB PLL and check PLL status - */ - - usb_pll_valid = 1; - usb_pll_enable = 1; - - ret = local_usbpll_enable(clk, 1); - if (ret >= 0) - clk->rate = clk_check_pll_setup(clkin, &pllsetup); - - return ret; -} - -static struct clk clk_usbpll = { - .parent = &osc_main, - .set_rate = local_usbpll_set_rate, - .enable = local_usbpll_enable, - .rate = 48000, /* In KHz */ - .get_rate = local_return_parent_rate, - .round_rate = local_usbpll_round_rate, -}; - -static u32 clk_get_hclk_div(void) -{ - static const u32 hclkdivs[4] = {1, 2, 4, 4}; - return hclkdivs[LPC32XX_CLKPWR_HCLKDIV_DIV_2POW( - __raw_readl(LPC32XX_CLKPWR_HCLK_DIV))]; -} - -static struct clk clk_hclk = { - .parent = &clk_armpll, - .get_rate = local_return_parent_rate, -}; - -static struct clk clk_pclk = { - .parent = &clk_armpll, - .get_rate = local_return_parent_rate, -}; - -static int local_onoff_enable(struct clk *clk, int enable) -{ - u32 tmp; - - tmp = __raw_readl(clk->enable_reg); - - if (enable == 0) - tmp &= ~clk->enable_mask; - else - tmp |= clk->enable_mask; - - __raw_writel(tmp, clk->enable_reg); - - return 0; -} - -/* Peripheral clock sources */ -static struct clk clk_timer0 = { - .parent = &clk_pclk, - .enable = local_onoff_enable, - .enable_reg = LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1, - .enable_mask = LPC32XX_CLKPWR_TMRPWMCLK_TIMER0_EN, - .get_rate = local_return_parent_rate, -}; -static struct clk clk_timer1 = { - .parent = &clk_pclk, - .enable = local_onoff_enable, - .enable_reg = LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1, - .enable_mask = LPC32XX_CLKPWR_TMRPWMCLK_TIMER1_EN, - .get_rate = local_return_parent_rate, -}; -static struct clk clk_timer2 = { - .parent = &clk_pclk, - .enable = local_onoff_enable, - .enable_reg = LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1, - .enable_mask = LPC32XX_CLKPWR_TMRPWMCLK_TIMER2_EN, - .get_rate = local_return_parent_rate, -}; -static struct clk clk_timer3 = { - .parent = &clk_pclk, - .enable = local_onoff_enable, - .enable_reg = LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1, - .enable_mask = LPC32XX_CLKPWR_TMRPWMCLK_TIMER3_EN, - .get_rate = local_return_parent_rate, -}; -static struct clk clk_mpwm = { - .parent = &clk_pclk, - .enable = local_onoff_enable, - .enable_reg = LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1, - .enable_mask = LPC32XX_CLKPWR_TMRPWMCLK_MPWM_EN, - .get_rate = local_return_parent_rate, -}; -static struct clk clk_wdt = { - .parent = &clk_pclk, - .enable = local_onoff_enable, - .enable_reg = LPC32XX_CLKPWR_TIMER_CLK_CTRL, - .enable_mask = LPC32XX_CLKPWR_PWMCLK_WDOG_EN, - .get_rate = local_return_parent_rate, -}; -static struct clk clk_vfp9 = { - .parent = &clk_pclk, - .enable = local_onoff_enable, - .enable_reg = LPC32XX_CLKPWR_DEBUG_CTRL, - .enable_mask = LPC32XX_CLKPWR_VFP_CLOCK_ENABLE_BIT, - .get_rate = local_return_parent_rate, -}; -static struct clk clk_dma = { - .parent = &clk_hclk, - .enable = local_onoff_enable, - .enable_reg = LPC32XX_CLKPWR_DMA_CLK_CTRL, - .enable_mask = LPC32XX_CLKPWR_DMACLKCTRL_CLK_EN, - .get_rate = local_return_parent_rate, -}; - -static struct clk clk_pwm = { - .parent = &clk_pclk, - .enable = local_onoff_enable, - .enable_reg = LPC32XX_CLKPWR_PWM_CLK_CTRL, - .enable_mask = LPC32XX_CLKPWR_PWMCLK_PWM1CLK_EN | - LPC32XX_CLKPWR_PWMCLK_PWM1SEL_PCLK | - LPC32XX_CLKPWR_PWMCLK_PWM1_DIV(1) | - LPC32XX_CLKPWR_PWMCLK_PWM2CLK_EN | - LPC32XX_CLKPWR_PWMCLK_PWM2SEL_PCLK | - LPC32XX_CLKPWR_PWMCLK_PWM2_DIV(1), - .get_rate = local_return_parent_rate, -}; - -static struct clk clk_uart3 = { - .parent = &clk_pclk, - .enable = local_onoff_enable, - .enable_reg = LPC32XX_CLKPWR_UART_CLK_CTRL, - .enable_mask = LPC32XX_CLKPWR_UARTCLKCTRL_UART3_EN, - .get_rate = local_return_parent_rate, -}; - -static struct clk clk_uart4 = { - .parent = &clk_pclk, - .enable = local_onoff_enable, - .enable_reg = LPC32XX_CLKPWR_UART_CLK_CTRL, - .enable_mask = LPC32XX_CLKPWR_UARTCLKCTRL_UART4_EN, - .get_rate = local_return_parent_rate, -}; - -static struct clk clk_uart5 = { - .parent = &clk_pclk, - .enable = local_onoff_enable, - .enable_reg = LPC32XX_CLKPWR_UART_CLK_CTRL, - .enable_mask = LPC32XX_CLKPWR_UARTCLKCTRL_UART5_EN, - .get_rate = local_return_parent_rate, -}; - -static struct clk clk_uart6 = { - .parent = &clk_pclk, - .enable = local_onoff_enable, - .enable_reg = LPC32XX_CLKPWR_UART_CLK_CTRL, - .enable_mask = LPC32XX_CLKPWR_UARTCLKCTRL_UART6_EN, - .get_rate = local_return_parent_rate, -}; - -static struct clk clk_i2c0 = { - .parent = &clk_hclk, - .enable = local_onoff_enable, - .enable_reg = LPC32XX_CLKPWR_I2C_CLK_CTRL, - .enable_mask = LPC32XX_CLKPWR_I2CCLK_I2C1CLK_EN, - .get_rate = local_return_parent_rate, -}; - -static struct clk clk_i2c1 = { - .parent = &clk_hclk, - .enable = local_onoff_enable, - .enable_reg = LPC32XX_CLKPWR_I2C_CLK_CTRL, - .enable_mask = LPC32XX_CLKPWR_I2CCLK_I2C2CLK_EN, - .get_rate = local_return_parent_rate, -}; - -static struct clk clk_i2c2 = { - .parent = &clk_pclk, - .enable = local_onoff_enable, - .enable_reg = io_p2v(LPC32XX_USB_BASE + 0xFF4), - .enable_mask = 0x4, - .get_rate = local_return_parent_rate, -}; - -static struct clk clk_ssp0 = { - .parent = &clk_hclk, - .enable = local_onoff_enable, - .enable_reg = LPC32XX_CLKPWR_SSP_CLK_CTRL, - .enable_mask = LPC32XX_CLKPWR_SSPCTRL_SSPCLK0_EN, - .get_rate = local_return_parent_rate, -}; - -static struct clk clk_ssp1 = { - .parent = &clk_hclk, - .enable = local_onoff_enable, - .enable_reg = LPC32XX_CLKPWR_SSP_CLK_CTRL, - .enable_mask = LPC32XX_CLKPWR_SSPCTRL_SSPCLK1_EN, - .get_rate = local_return_parent_rate, -}; - -static struct clk clk_kscan = { - .parent = &osc_32KHz, - .enable = local_onoff_enable, - .enable_reg = LPC32XX_CLKPWR_KEY_CLK_CTRL, - .enable_mask = LPC32XX_CLKPWR_KEYCLKCTRL_CLK_EN, - .get_rate = local_return_parent_rate, -}; - -static struct clk clk_nand = { - .parent = &clk_hclk, - .enable = local_onoff_enable, - .enable_reg = LPC32XX_CLKPWR_NAND_CLK_CTRL, - .enable_mask = LPC32XX_CLKPWR_NANDCLK_SLCCLK_EN | - LPC32XX_CLKPWR_NANDCLK_SEL_SLC, - .get_rate = local_return_parent_rate, -}; - -static struct clk clk_nand_mlc = { - .parent = &clk_hclk, - .enable = local_onoff_enable, - .enable_reg = LPC32XX_CLKPWR_NAND_CLK_CTRL, - .enable_mask = LPC32XX_CLKPWR_NANDCLK_MLCCLK_EN | - LPC32XX_CLKPWR_NANDCLK_DMA_INT | - LPC32XX_CLKPWR_NANDCLK_INTSEL_MLC, - .get_rate = local_return_parent_rate, -}; - -static struct clk clk_i2s0 = { - .parent = &clk_hclk, - .enable = local_onoff_enable, - .enable_reg = LPC32XX_CLKPWR_I2S_CLK_CTRL, - .enable_mask = LPC32XX_CLKPWR_I2SCTRL_I2SCLK0_EN, - .get_rate = local_return_parent_rate, -}; - -static struct clk clk_i2s1 = { - .parent = &clk_hclk, - .enable = local_onoff_enable, - .enable_reg = LPC32XX_CLKPWR_I2S_CLK_CTRL, - .enable_mask = LPC32XX_CLKPWR_I2SCTRL_I2SCLK1_EN | - LPC32XX_CLKPWR_I2SCTRL_I2S1_USE_DMA, - .get_rate = local_return_parent_rate, -}; - -static struct clk clk_net = { - .parent = &clk_hclk, - .enable = local_onoff_enable, - .enable_reg = LPC32XX_CLKPWR_MACCLK_CTRL, - .enable_mask = (LPC32XX_CLKPWR_MACCTRL_DMACLK_EN | - LPC32XX_CLKPWR_MACCTRL_MMIOCLK_EN | - LPC32XX_CLKPWR_MACCTRL_HRCCLK_EN), - .get_rate = local_return_parent_rate, -}; - -static struct clk clk_rtc = { - .parent = &osc_32KHz, - .rate = 1, /* 1 Hz */ - .get_rate = local_return_parent_rate, -}; - -static int local_usb_enable(struct clk *clk, int enable) -{ - u32 tmp; - - if (enable) { - /* Set up I2C pull levels */ - tmp = __raw_readl(LPC32XX_CLKPWR_I2C_CLK_CTRL); - tmp |= LPC32XX_CLKPWR_I2CCLK_USBI2CHI_DRIVE; - __raw_writel(tmp, LPC32XX_CLKPWR_I2C_CLK_CTRL); - } - - return local_onoff_enable(clk, enable); -} - -static struct clk clk_usbd = { - .parent = &clk_usbpll, - .enable = local_usb_enable, - .enable_reg = LPC32XX_CLKPWR_USB_CTRL, - .enable_mask = LPC32XX_CLKPWR_USBCTRL_HCLK_EN, - .get_rate = local_return_parent_rate, -}; - -#define OTG_ALWAYS_MASK (LPC32XX_USB_OTG_OTG_CLOCK_ON | \ - LPC32XX_USB_OTG_I2C_CLOCK_ON) - -static int local_usb_otg_enable(struct clk *clk, int enable) -{ - int to = 1000; - - if (enable) { - __raw_writel(clk->enable_mask, clk->enable_reg); - - while (((__raw_readl(LPC32XX_USB_OTG_CLK_STAT) & - clk->enable_mask) != clk->enable_mask) && (to > 0)) - to--; - } else { - __raw_writel(OTG_ALWAYS_MASK, clk->enable_reg); - - while (((__raw_readl(LPC32XX_USB_OTG_CLK_STAT) & - OTG_ALWAYS_MASK) != OTG_ALWAYS_MASK) && (to > 0)) - to--; - } - - if (to) - return 0; - else - return -1; -} - -static struct clk clk_usb_otg_dev = { - .parent = &clk_usbpll, - .enable = local_usb_otg_enable, - .enable_reg = LPC32XX_USB_OTG_CLK_CTRL, - .enable_mask = LPC32XX_USB_OTG_AHB_M_CLOCK_ON | - LPC32XX_USB_OTG_OTG_CLOCK_ON | - LPC32XX_USB_OTG_DEV_CLOCK_ON | - LPC32XX_USB_OTG_I2C_CLOCK_ON, - .get_rate = local_return_parent_rate, -}; - -static struct clk clk_usb_otg_host = { - .parent = &clk_usbpll, - .enable = local_usb_otg_enable, - .enable_reg = LPC32XX_USB_OTG_CLK_CTRL, - .enable_mask = LPC32XX_USB_OTG_AHB_M_CLOCK_ON | - LPC32XX_USB_OTG_OTG_CLOCK_ON | - LPC32XX_USB_OTG_HOST_CLOCK_ON | - LPC32XX_USB_OTG_I2C_CLOCK_ON, - .get_rate = local_return_parent_rate, -}; - -static int tsc_onoff_enable(struct clk *clk, int enable) -{ - u32 tmp; - - /* Make sure 32KHz clock is the selected clock */ - tmp = __raw_readl(LPC32XX_CLKPWR_ADC_CLK_CTRL_1); - tmp &= ~LPC32XX_CLKPWR_ADCCTRL1_PCLK_SEL; - __raw_writel(tmp, LPC32XX_CLKPWR_ADC_CLK_CTRL_1); - - if (enable == 0) - __raw_writel(0, clk->enable_reg); - else - __raw_writel(clk->enable_mask, clk->enable_reg); - - return 0; -} - -static struct clk clk_tsc = { - .parent = &osc_32KHz, - .enable = tsc_onoff_enable, - .enable_reg = LPC32XX_CLKPWR_ADC_CLK_CTRL, - .enable_mask = LPC32XX_CLKPWR_ADC32CLKCTRL_CLK_EN, - .get_rate = local_return_parent_rate, -}; - -static int adc_onoff_enable(struct clk *clk, int enable) -{ - u32 tmp; - u32 divider; - - /* Use PERIPH_CLOCK */ - tmp = __raw_readl(LPC32XX_CLKPWR_ADC_CLK_CTRL_1); - tmp |= LPC32XX_CLKPWR_ADCCTRL1_PCLK_SEL; - /* - * Set clock divider so that we have equal to or less than - * 4.5MHz clock at ADC - */ - divider = clk->get_rate(clk) / 4500000 + 1; - tmp |= divider; - __raw_writel(tmp, LPC32XX_CLKPWR_ADC_CLK_CTRL_1); - - /* synchronize rate of this clock w/ actual HW setting */ - clk->rate = clk->get_rate(clk->parent) / divider; - - if (enable == 0) - __raw_writel(0, clk->enable_reg); - else - __raw_writel(clk->enable_mask, clk->enable_reg); - - return 0; -} - -static struct clk clk_adc = { - .parent = &clk_pclk, - .enable = adc_onoff_enable, - .enable_reg = LPC32XX_CLKPWR_ADC_CLK_CTRL, - .enable_mask = LPC32XX_CLKPWR_ADC32CLKCTRL_CLK_EN, - .get_rate = local_return_parent_rate, -}; - -static int mmc_onoff_enable(struct clk *clk, int enable) -{ - u32 tmp; - - tmp = __raw_readl(LPC32XX_CLKPWR_MS_CTRL) & - ~(LPC32XX_CLKPWR_MSCARD_SDCARD_EN | - LPC32XX_CLKPWR_MSCARD_MSDIO_PU_EN | - LPC32XX_CLKPWR_MSCARD_MSDIO_PIN_DIS | - LPC32XX_CLKPWR_MSCARD_MSDIO0_DIS | - LPC32XX_CLKPWR_MSCARD_MSDIO1_DIS | - LPC32XX_CLKPWR_MSCARD_MSDIO23_DIS); - - /* If rate is 0, disable clock */ - if (enable != 0) - tmp |= LPC32XX_CLKPWR_MSCARD_SDCARD_EN | - LPC32XX_CLKPWR_MSCARD_MSDIO_PU_EN; - - __raw_writel(tmp, LPC32XX_CLKPWR_MS_CTRL); - - return 0; -} - -static unsigned long mmc_get_rate(struct clk *clk) -{ - u32 div, rate, oldclk; - - /* The MMC clock must be on when accessing an MMC register */ - oldclk = __raw_readl(LPC32XX_CLKPWR_MS_CTRL); - __raw_writel(oldclk | LPC32XX_CLKPWR_MSCARD_SDCARD_EN, - LPC32XX_CLKPWR_MS_CTRL); - div = __raw_readl(LPC32XX_CLKPWR_MS_CTRL); - __raw_writel(oldclk, LPC32XX_CLKPWR_MS_CTRL); - - /* Get the parent clock rate */ - rate = clk->parent->get_rate(clk->parent); - - /* Get the MMC controller clock divider value */ - div = div & LPC32XX_CLKPWR_MSCARD_SDCARD_DIV(0xf); - - if (!div) - div = 1; - - return rate / div; -} - -static unsigned long mmc_round_rate(struct clk *clk, unsigned long rate) -{ - unsigned long div, prate; - - /* Get the parent clock rate */ - prate = clk->parent->get_rate(clk->parent); - - if (rate >= prate) - return prate; - - div = prate / rate; - if (div > 0xf) - div = 0xf; - - return prate / div; -} - -static int mmc_set_rate(struct clk *clk, unsigned long rate) -{ - u32 tmp; - unsigned long prate, div, crate = mmc_round_rate(clk, rate); - - prate = clk->parent->get_rate(clk->parent); - - div = prate / crate; - - /* The MMC clock must be on when accessing an MMC register */ - tmp = __raw_readl(LPC32XX_CLKPWR_MS_CTRL) & - ~LPC32XX_CLKPWR_MSCARD_SDCARD_DIV(0xf); - tmp |= LPC32XX_CLKPWR_MSCARD_SDCARD_DIV(div) | - LPC32XX_CLKPWR_MSCARD_SDCARD_EN; - __raw_writel(tmp, LPC32XX_CLKPWR_MS_CTRL); - - return 0; -} - -static struct clk clk_mmc = { - .parent = &clk_armpll, - .set_rate = mmc_set_rate, - .get_rate = mmc_get_rate, - .round_rate = mmc_round_rate, - .enable = mmc_onoff_enable, - .enable_reg = LPC32XX_CLKPWR_MS_CTRL, - .enable_mask = LPC32XX_CLKPWR_MSCARD_SDCARD_EN, -}; - -static unsigned long clcd_get_rate(struct clk *clk) -{ - u32 tmp, div, rate, oldclk; - - /* The LCD clock must be on when accessing an LCD register */ - oldclk = __raw_readl(LPC32XX_CLKPWR_LCDCLK_CTRL); - __raw_writel(oldclk | LPC32XX_CLKPWR_LCDCTRL_CLK_EN, - LPC32XX_CLKPWR_LCDCLK_CTRL); - tmp = __raw_readl(io_p2v(LPC32XX_LCD_BASE + CLCD_TIM2)); - __raw_writel(oldclk, LPC32XX_CLKPWR_LCDCLK_CTRL); - - rate = clk->parent->get_rate(clk->parent); - - /* Only supports internal clocking */ - if (tmp & TIM2_BCD) - return rate; - - div = (tmp & 0x1F) | ((tmp & 0xF8) >> 22); - tmp = rate / (2 + div); - - return tmp; -} - -static int clcd_set_rate(struct clk *clk, unsigned long rate) -{ - u32 tmp, prate, div, oldclk; - - /* The LCD clock must be on when accessing an LCD register */ - oldclk = __raw_readl(LPC32XX_CLKPWR_LCDCLK_CTRL); - __raw_writel(oldclk | LPC32XX_CLKPWR_LCDCTRL_CLK_EN, - LPC32XX_CLKPWR_LCDCLK_CTRL); - - tmp = __raw_readl(io_p2v(LPC32XX_LCD_BASE + CLCD_TIM2)) | TIM2_BCD; - prate = clk->parent->get_rate(clk->parent); - - if (rate < prate) { - /* Find closest divider */ - div = prate / rate; - if (div >= 2) { - div -= 2; - tmp &= ~TIM2_BCD; - } - - tmp &= ~(0xF800001F); - tmp |= (div & 0x1F); - tmp |= (((div >> 5) & 0x1F) << 27); - } - - __raw_writel(tmp, io_p2v(LPC32XX_LCD_BASE + CLCD_TIM2)); - __raw_writel(oldclk, LPC32XX_CLKPWR_LCDCLK_CTRL); - - return 0; -} - -static unsigned long clcd_round_rate(struct clk *clk, unsigned long rate) -{ - u32 prate, div; - - prate = clk->parent->get_rate(clk->parent); - - if (rate >= prate) - rate = prate; - else { - div = prate / rate; - if (div > 0x3ff) - div = 0x3ff; - - rate = prate / div; - } - - return rate; -} - -static struct clk clk_lcd = { - .parent = &clk_hclk, - .set_rate = clcd_set_rate, - .get_rate = clcd_get_rate, - .round_rate = clcd_round_rate, - .enable = local_onoff_enable, - .enable_reg = LPC32XX_CLKPWR_LCDCLK_CTRL, - .enable_mask = LPC32XX_CLKPWR_LCDCTRL_CLK_EN, -}; - -static void local_clk_disable(struct clk *clk) -{ - /* Don't attempt to disable clock if it has no users */ - if (clk->usecount > 0) { - clk->usecount--; - - /* Only disable clock when it has no more users */ - if ((clk->usecount == 0) && (clk->enable)) - clk->enable(clk, 0); - - /* Check parent clocks, they may need to be disabled too */ - if (clk->parent) - local_clk_disable(clk->parent); - } -} - -static int local_clk_enable(struct clk *clk) -{ - int ret = 0; - - /* Enable parent clocks first and update use counts */ - if (clk->parent) - ret = local_clk_enable(clk->parent); - - if (!ret) { - /* Only enable clock if it's currently disabled */ - if ((clk->usecount == 0) && (clk->enable)) - ret = clk->enable(clk, 1); - - if (!ret) - clk->usecount++; - else if (clk->parent) - local_clk_disable(clk->parent); - } - - return ret; -} - -/* - * clk_enable - inform the system when the clock source should be running. - */ -int clk_enable(struct clk *clk) -{ - int ret; - unsigned long flags; - - spin_lock_irqsave(&global_clkregs_lock, flags); - ret = local_clk_enable(clk); - spin_unlock_irqrestore(&global_clkregs_lock, flags); - - return ret; -} -EXPORT_SYMBOL(clk_enable); - -/* - * clk_disable - inform the system when the clock source is no longer required - */ -void clk_disable(struct clk *clk) -{ - unsigned long flags; - - spin_lock_irqsave(&global_clkregs_lock, flags); - local_clk_disable(clk); - spin_unlock_irqrestore(&global_clkregs_lock, flags); -} -EXPORT_SYMBOL(clk_disable); - -/* - * clk_get_rate - obtain the current clock rate (in Hz) for a clock source - */ -unsigned long clk_get_rate(struct clk *clk) -{ - return clk->get_rate(clk); -} -EXPORT_SYMBOL(clk_get_rate); - -/* - * clk_set_rate - set the clock rate for a clock source - */ -int clk_set_rate(struct clk *clk, unsigned long rate) -{ - int ret = -EINVAL; - - /* - * Most system clocks can only be enabled or disabled, with - * the actual rate set as part of the peripheral dividers - * instead of high level clock control - */ - if (clk->set_rate) - ret = clk->set_rate(clk, rate); - - return ret; -} -EXPORT_SYMBOL(clk_set_rate); - -/* - * clk_round_rate - adjust a rate to the exact rate a clock can provide - */ -long clk_round_rate(struct clk *clk, unsigned long rate) -{ - if (clk->round_rate) - rate = clk->round_rate(clk, rate); - else - rate = clk->get_rate(clk); - - return rate; -} -EXPORT_SYMBOL(clk_round_rate); - -/* - * clk_set_parent - set the parent clock source for this clock - */ -int clk_set_parent(struct clk *clk, struct clk *parent) -{ - /* Clock re-parenting is not supported */ - return -EINVAL; -} -EXPORT_SYMBOL(clk_set_parent); - -/* - * clk_get_parent - get the parent clock source for this clock - */ -struct clk *clk_get_parent(struct clk *clk) -{ - return clk->parent; -} -EXPORT_SYMBOL(clk_get_parent); - -static struct clk_lookup lookups[] = { - CLKDEV_INIT(NULL, "osc_32KHz", &osc_32KHz), - CLKDEV_INIT(NULL, "osc_pll397", &osc_pll397), - CLKDEV_INIT(NULL, "osc_main", &osc_main), - CLKDEV_INIT(NULL, "sys_ck", &clk_sys), - CLKDEV_INIT(NULL, "arm_pll_ck", &clk_armpll), - CLKDEV_INIT(NULL, "ck_pll5", &clk_usbpll), - CLKDEV_INIT(NULL, "hclk_ck", &clk_hclk), - CLKDEV_INIT(NULL, "pclk_ck", &clk_pclk), - CLKDEV_INIT(NULL, "timer0_ck", &clk_timer0), - CLKDEV_INIT(NULL, "timer1_ck", &clk_timer1), - CLKDEV_INIT(NULL, "timer2_ck", &clk_timer2), - CLKDEV_INIT(NULL, "timer3_ck", &clk_timer3), - CLKDEV_INIT(NULL, "vfp9_ck", &clk_vfp9), - CLKDEV_INIT("pl08xdmac", NULL, &clk_dma), - CLKDEV_INIT("4003c000.watchdog", NULL, &clk_wdt), - CLKDEV_INIT("4005c000.pwm", NULL, &clk_pwm), - CLKDEV_INIT("400e8000.mpwm", NULL, &clk_mpwm), - CLKDEV_INIT(NULL, "uart3_ck", &clk_uart3), - CLKDEV_INIT(NULL, "uart4_ck", &clk_uart4), - CLKDEV_INIT(NULL, "uart5_ck", &clk_uart5), - CLKDEV_INIT(NULL, "uart6_ck", &clk_uart6), - CLKDEV_INIT("400a0000.i2c", NULL, &clk_i2c0), - CLKDEV_INIT("400a8000.i2c", NULL, &clk_i2c1), - CLKDEV_INIT("31020300.i2c", NULL, &clk_i2c2), - CLKDEV_INIT("dev:ssp0", NULL, &clk_ssp0), - CLKDEV_INIT("dev:ssp1", NULL, &clk_ssp1), - CLKDEV_INIT("40050000.key", NULL, &clk_kscan), - CLKDEV_INIT("20020000.flash", NULL, &clk_nand), - CLKDEV_INIT("200a8000.flash", NULL, &clk_nand_mlc), - CLKDEV_INIT("40048000.adc", NULL, &clk_adc), - CLKDEV_INIT(NULL, "i2s0_ck", &clk_i2s0), - CLKDEV_INIT(NULL, "i2s1_ck", &clk_i2s1), - CLKDEV_INIT("40048000.tsc", NULL, &clk_tsc), - CLKDEV_INIT("20098000.sd", NULL, &clk_mmc), - CLKDEV_INIT("31060000.ethernet", NULL, &clk_net), - CLKDEV_INIT("dev:clcd", NULL, &clk_lcd), - CLKDEV_INIT("31020000.usbd", "ck_usbd", &clk_usbd), - CLKDEV_INIT("31020000.ohci", "ck_usbd", &clk_usbd), - CLKDEV_INIT("31020000.usbd", "ck_usb_otg", &clk_usb_otg_dev), - CLKDEV_INIT("31020000.ohci", "ck_usb_otg", &clk_usb_otg_host), - CLKDEV_INIT("lpc32xx_rtc", NULL, &clk_rtc), -}; - -static int __init clk_init(void) -{ - clkdev_add_table(lookups, ARRAY_SIZE(lookups)); - - /* - * Setup muxed SYSCLK for HCLK PLL base -this selects the - * parent clock used for the ARM PLL and is used to derive - * the many system clock rates in the device. - */ - if (clk_is_sysclk_mainosc() != 0) - clk_sys.parent = &osc_main; - else - clk_sys.parent = &osc_pll397; - - clk_sys.rate = clk_sys.parent->rate; - - /* Compute the current ARM PLL and USB PLL frequencies */ - local_update_armpll_rate(); - - /* Compute HCLK and PCLK bus rates */ - clk_hclk.rate = clk_hclk.parent->rate / clk_get_hclk_div(); - clk_pclk.rate = clk_pclk.parent->rate / clk_get_pclk_div(); - - /* - * Enable system clocks - this step is somewhat formal, as the - * clocks are already running, but it does get the clock data - * inline with the actual system state. Never disable these - * clocks as they will only stop if the system is going to sleep. - * In that case, the chip/system power management functions will - * handle clock gating. - */ - if (clk_enable(&clk_hclk) || clk_enable(&clk_pclk)) - printk(KERN_ERR "Error enabling system HCLK and PCLK\n"); - - /* - * Timers 0 and 1 were enabled and are being used by the high - * resolution tick function prior to this driver being initialized. - * Tag them now as used. - */ - if (clk_enable(&clk_timer0) || clk_enable(&clk_timer1)) - printk(KERN_ERR "Error enabling timer tick clocks\n"); - - return 0; -} -core_initcall(clk_init); - diff --git a/arch/arm/mach-lpc32xx/common.c b/arch/arm/mach-lpc32xx/common.c index 716e83eb1db8ec1fe31bce19c318228ee2ce515b..5b7a1e78c3a5ed37e24506585d1d53d3551b5d82 100644 --- a/arch/arm/mach-lpc32xx/common.c +++ b/arch/arm/mach-lpc32xx/common.c @@ -194,21 +194,6 @@ void __init lpc32xx_map_io(void) iotable_init(lpc32xx_io_desc, ARRAY_SIZE(lpc32xx_io_desc)); } -void lpc23xx_restart(enum reboot_mode mode, const char *cmd) -{ - /* Make sure WDT clocks are enabled */ - __raw_writel(LPC32XX_CLKPWR_PWMCLK_WDOG_EN, - LPC32XX_CLKPWR_TIMER_CLK_CTRL); - - /* Instant assert of RESETOUT_N with pulse length 1mS */ - __raw_writel(13000, io_p2v(LPC32XX_WDTIM_BASE + 0x18)); - __raw_writel(0x70, io_p2v(LPC32XX_WDTIM_BASE + 0xC)); - - /* Wait for watchdog to reset system */ - while (1) - ; -} - static int __init lpc32xx_check_uid(void) { u32 uid[4]; diff --git a/arch/arm/mach-lpc32xx/common.h b/arch/arm/mach-lpc32xx/common.h index 1cd8853b2f9b7479a79ad54d52eb43c78cd9e511..2d90801ed1e13c19dfd8c867b535c324b1f81909 100644 --- a/arch/arm/mach-lpc32xx/common.h +++ b/arch/arm/mach-lpc32xx/common.h @@ -30,7 +30,6 @@ extern void lpc32xx_timer_init(void); extern void __init lpc32xx_init_irq(void); extern void __init lpc32xx_map_io(void); extern void __init lpc32xx_serial_init(void); -extern void lpc23xx_restart(enum reboot_mode, const char *); /* diff --git a/arch/arm/mach-lpc32xx/phy3250.c b/arch/arm/mach-lpc32xx/phy3250.c index ee06fabdf60e69e014317c9703787da5f31dc79f..b2f9e226febeee970b0594c8be030a4838735e7c 100644 --- a/arch/arm/mach-lpc32xx/phy3250.c +++ b/arch/arm/mach-lpc32xx/phy3250.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include @@ -47,13 +46,6 @@ #include #include "common.h" -/* - * Mapped GPIOLIB GPIOs - */ -#define LCD_POWER_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 0) -#define BKL_POWER_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 4) -#define MMC_PWR_ENABLE_GPIO LPC32XX_GPIO(LPC32XX_GPO_P3_GRP, 5) - /* * AMBA LCD controller */ @@ -97,20 +89,6 @@ static int lpc32xx_clcd_setup(struct clcd_fb *fb) fb->fb.fix.smem_len = PANEL_SIZE; fb->panel = &conn_lcd_panel; - if (gpio_request(LCD_POWER_GPIO, "LCD power")) - printk(KERN_ERR "Error requesting gpio %u", - LCD_POWER_GPIO); - else if (gpio_direction_output(LCD_POWER_GPIO, 1)) - printk(KERN_ERR "Error setting gpio %u to output", - LCD_POWER_GPIO); - - if (gpio_request(BKL_POWER_GPIO, "LCD backlight power")) - printk(KERN_ERR "Error requesting gpio %u", - BKL_POWER_GPIO); - else if (gpio_direction_output(BKL_POWER_GPIO, 1)) - printk(KERN_ERR "Error setting gpio %u to output", - BKL_POWER_GPIO); - return 0; } @@ -126,29 +104,10 @@ static void lpc32xx_clcd_remove(struct clcd_fb *fb) fb->fb.fix.smem_start); } -/* - * On some early LCD modules (1307.0), the backlight logic is inverted. - * For those board variants, swap the disable and enable states for - * BKL_POWER_GPIO. -*/ -static void clcd_disable(struct clcd_fb *fb) -{ - gpio_set_value(BKL_POWER_GPIO, 0); - gpio_set_value(LCD_POWER_GPIO, 0); -} - -static void clcd_enable(struct clcd_fb *fb) -{ - gpio_set_value(BKL_POWER_GPIO, 1); - gpio_set_value(LCD_POWER_GPIO, 1); -} - static struct clcd_board lpc32xx_clcd_data = { .name = "Phytec LCD", .check = clcdfb_check, .decode = clcdfb_decode, - .disable = clcd_disable, - .enable = clcd_enable, .setup = lpc32xx_clcd_setup, .mmap = lpc32xx_clcd_mmap, .remove = lpc32xx_clcd_remove, @@ -187,20 +146,9 @@ static struct pl08x_platform_data pl08x_pd = { .mem_buses = PL08X_AHB1, }; -static int mmc_handle_ios(struct device *dev, struct mmc_ios *ios) -{ - /* Only on and off are supported */ - if (ios->power_mode == MMC_POWER_OFF) - gpio_set_value(MMC_PWR_ENABLE_GPIO, 0); - else - gpio_set_value(MMC_PWR_ENABLE_GPIO, 1); - return 0; -} - static struct mmci_platform_data lpc32xx_mmci_data = { .ocr_mask = MMC_VDD_30_31 | MMC_VDD_31_32 | MMC_VDD_32_33 | MMC_VDD_33_34, - .ios_handler = mmc_handle_ios, }; static struct lpc32xx_slc_platform_data lpc32xx_slc_data = { @@ -259,8 +207,6 @@ DT_MACHINE_START(LPC32XX_DT, "LPC32XX SoC (Flattened Device Tree)") .atag_offset = 0x100, .map_io = lpc32xx_map_io, .init_irq = lpc32xx_init_irq, - .init_time = lpc32xx_timer_init, .init_machine = lpc3250_machine_init, .dt_compat = lpc32xx_dt_compat, - .restart = lpc23xx_restart, MACHINE_END diff --git a/arch/arm/mach-lpc32xx/serial.c b/arch/arm/mach-lpc32xx/serial.c index 05621a29fba22cb5a1754f525d90817c9eaf3c57..1931229a1eaa6c3ab40de07d4b1a24336f3d7548 100644 --- a/arch/arm/mach-lpc32xx/serial.c +++ b/arch/arm/mach-lpc32xx/serial.c @@ -76,9 +76,6 @@ void __init lpc32xx_serial_init(void) unsigned int puart; int i, j; - /* UART clocks are off, let clock driver manage them */ - __raw_writel(0, LPC32XX_CLKPWR_UART_CLK_CTRL); - for (i = 0; i < ARRAY_SIZE(uartinit_data); i++) { clk = clk_get(NULL, uartinit_data[i].uart_ck_name); if (!IS_ERR(clk)) { diff --git a/arch/arm/mach-lpc32xx/timer.c b/arch/arm/mach-lpc32xx/timer.c deleted file mode 100644 index ff3499d1fb1a27e5263ac3d3085daa5f9fba704d..0000000000000000000000000000000000000000 --- a/arch/arm/mach-lpc32xx/timer.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * arch/arm/mach-lpc32xx/timer.c - * - * Author: Kevin Wells - * - * Copyright (C) 2009 - 2010 NXP Semiconductors - * Copyright (C) 2009 Fontys University of Applied Sciences, Eindhoven - * Ed Schouten - * Laurens Timmermans - * - * 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. - */ - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include "common.h" - -static int lpc32xx_clkevt_next_event(unsigned long delta, - struct clock_event_device *dev) -{ - __raw_writel(LPC32XX_TIMER_CNTR_TCR_RESET, - LPC32XX_TIMER_TCR(LPC32XX_TIMER0_BASE)); - __raw_writel(delta, LPC32XX_TIMER_PR(LPC32XX_TIMER0_BASE)); - __raw_writel(LPC32XX_TIMER_CNTR_TCR_EN, - LPC32XX_TIMER_TCR(LPC32XX_TIMER0_BASE)); - - return 0; -} - -static int lpc32xx_shutdown(struct clock_event_device *evt) -{ - /* - * Disable the timer. When using oneshot, we must also - * disable the timer to wait for the first call to - * set_next_event(). - */ - __raw_writel(0, LPC32XX_TIMER_TCR(LPC32XX_TIMER0_BASE)); - return 0; -} - -static struct clock_event_device lpc32xx_clkevt = { - .name = "lpc32xx_clkevt", - .features = CLOCK_EVT_FEAT_ONESHOT, - .rating = 300, - .set_next_event = lpc32xx_clkevt_next_event, - .set_state_shutdown = lpc32xx_shutdown, - .set_state_oneshot = lpc32xx_shutdown, -}; - -static irqreturn_t lpc32xx_timer_interrupt(int irq, void *dev_id) -{ - struct clock_event_device *evt = &lpc32xx_clkevt; - - /* Clear match */ - __raw_writel(LPC32XX_TIMER_CNTR_MTCH_BIT(0), - LPC32XX_TIMER_IR(LPC32XX_TIMER0_BASE)); - - evt->event_handler(evt); - - return IRQ_HANDLED; -} - -static struct irqaction lpc32xx_timer_irq = { - .name = "LPC32XX Timer Tick", - .flags = IRQF_TIMER | IRQF_IRQPOLL, - .handler = lpc32xx_timer_interrupt, -}; - -/* - * The clock management driver isn't initialized at this point, so the - * clocks need to be enabled here manually and then tagged as used in - * the clock driver initialization - */ -void __init lpc32xx_timer_init(void) -{ - u32 clkrate, pllreg; - - /* Enable timer clock */ - __raw_writel(LPC32XX_CLKPWR_TMRPWMCLK_TIMER0_EN | - LPC32XX_CLKPWR_TMRPWMCLK_TIMER1_EN, - LPC32XX_CLKPWR_TIMERS_PWMS_CLK_CTRL_1); - - /* - * The clock driver isn't initialized at this point. So determine if - * the SYSCLK is driven from the PLL397 or main oscillator and then use - * it to compute the PLL frequency and the PCLK divider to get the base - * timer rates. This rate is needed to compute the tick rate. - */ - if (clk_is_sysclk_mainosc() != 0) - clkrate = LPC32XX_MAIN_OSC_FREQ; - else - clkrate = 397 * LPC32XX_CLOCK_OSC_FREQ; - - /* Get ARM HCLKPLL register and convert it into a frequency */ - pllreg = __raw_readl(LPC32XX_CLKPWR_HCLKPLL_CTRL) & 0x1FFFF; - clkrate = clk_get_pllrate_from_reg(clkrate, pllreg); - - /* Get PCLK divider and divide ARM PLL clock by it to get timer rate */ - clkrate = clkrate / clk_get_pclk_div(); - - /* Initial timer setup */ - __raw_writel(0, LPC32XX_TIMER_TCR(LPC32XX_TIMER0_BASE)); - __raw_writel(LPC32XX_TIMER_CNTR_MTCH_BIT(0), - LPC32XX_TIMER_IR(LPC32XX_TIMER0_BASE)); - __raw_writel(1, LPC32XX_TIMER_MR0(LPC32XX_TIMER0_BASE)); - __raw_writel(LPC32XX_TIMER_CNTR_MCR_MTCH(0) | - LPC32XX_TIMER_CNTR_MCR_STOP(0) | - LPC32XX_TIMER_CNTR_MCR_RESET(0), - LPC32XX_TIMER_MCR(LPC32XX_TIMER0_BASE)); - - /* Setup tick interrupt */ - setup_irq(IRQ_LPC32XX_TIMER0, &lpc32xx_timer_irq); - - /* Setup the clockevent structure. */ - lpc32xx_clkevt.cpumask = cpumask_of(0); - clockevents_config_and_register(&lpc32xx_clkevt, clkrate, 1, -1); - - /* Use timer1 as clock source. */ - __raw_writel(LPC32XX_TIMER_CNTR_TCR_RESET, - LPC32XX_TIMER_TCR(LPC32XX_TIMER1_BASE)); - __raw_writel(0, LPC32XX_TIMER_PR(LPC32XX_TIMER1_BASE)); - __raw_writel(0, LPC32XX_TIMER_MCR(LPC32XX_TIMER1_BASE)); - __raw_writel(LPC32XX_TIMER_CNTR_TCR_EN, - LPC32XX_TIMER_TCR(LPC32XX_TIMER1_BASE)); - - clocksource_mmio_init(LPC32XX_TIMER_TC(LPC32XX_TIMER1_BASE), - "lpc32xx_clksrc", clkrate, 300, 32, clocksource_mmio_readl_up); -} diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig index 0abcc51afff5303bce4cd054251c09be2b10a4ae..8ced4ad94af0f832495603f5cd487deb66c3042c 100644 --- a/arch/arm/mach-mediatek/Kconfig +++ b/arch/arm/mach-mediatek/Kconfig @@ -18,6 +18,10 @@ config MACH_MT6592 bool "MediaTek MT6592 SoCs support" default ARCH_MEDIATEK +config MACH_MT7623 + bool "MediaTek MT7623 SoCs support" + default ARCH_MEDIATEK + config MACH_MT8127 bool "MediaTek MT8127 SoCs support" default ARCH_MEDIATEK diff --git a/arch/arm/mach-mediatek/mediatek.c b/arch/arm/mach-mediatek/mediatek.c index 2f9f09ac51bd0b6c13915d581b08bd140398d725..9c2e38d30f47245f1dfd28eea04a36f5cb2b223b 100644 --- a/arch/arm/mach-mediatek/mediatek.c +++ b/arch/arm/mach-mediatek/mediatek.c @@ -47,6 +47,7 @@ static const char * const mediatek_board_dt_compat[] = { "mediatek,mt2701", "mediatek,mt6589", "mediatek,mt6592", + "mediatek,mt7623", "mediatek,mt8127", "mediatek,mt8135", NULL, diff --git a/arch/arm/mach-mediatek/platsmp.c b/arch/arm/mach-mediatek/platsmp.c index a1b07eeaaf5b6a42bceac6c3dd62425002c9c95d..b821e34474b6fc5a950e1739365b2442cac0a2c5 100644 --- a/arch/arm/mach-mediatek/platsmp.c +++ b/arch/arm/mach-mediatek/platsmp.c @@ -44,13 +44,21 @@ static const struct mtk_smp_boot_info mtk_mt6589_boot = { { 0x38, 0x3c, 0x40 }, }; +static const struct mtk_smp_boot_info mtk_mt7623_boot = { + 0x10202000, 0x34, + { 0x534c4131, 0x4c415332, 0x41534c33 }, + { 0x38, 0x3c, 0x40 }, +}; + static const struct of_device_id mtk_tz_smp_boot_infos[] __initconst = { { .compatible = "mediatek,mt8135", .data = &mtk_mt8135_tz_boot }, { .compatible = "mediatek,mt8127", .data = &mtk_mt8135_tz_boot }, + { .compatible = "mediatek,mt2701", .data = &mtk_mt8135_tz_boot }, }; static const struct of_device_id mtk_smp_boot_infos[] __initconst = { { .compatible = "mediatek,mt6589", .data = &mtk_mt6589_boot }, + { .compatible = "mediatek,mt7623", .data = &mtk_mt7623_boot }, }; static void __iomem *mtk_smp_base; diff --git a/arch/arm/mach-mmp/Makefile.boot b/arch/arm/mach-mmp/Makefile.boot deleted file mode 100644 index 5edf03e2beede327855eee878fc22b4f802a96a1..0000000000000000000000000000000000000000 --- a/arch/arm/mach-mmp/Makefile.boot +++ /dev/null @@ -1 +0,0 @@ - zreladdr-y += 0x00008000 diff --git a/arch/arm/mach-mv78xx0/Kconfig b/arch/arm/mach-mv78xx0/Kconfig index a32575fa3fba4d727e4584e7c169a5de09f46c48..c32f85559c6509e7f64116c351730141db16938a 100644 --- a/arch/arm/mach-mv78xx0/Kconfig +++ b/arch/arm/mach-mv78xx0/Kconfig @@ -1,5 +1,6 @@ menuconfig ARCH_MV78XX0 - bool "Marvell MV78xx0" if ARCH_MULTI_V5 + bool "Marvell MV78xx0" + depends on ARCH_MULTI_V5 select ARCH_REQUIRE_GPIOLIB select CPU_FEROCEON select MVEBU_MBUS diff --git a/arch/arm/mach-mv78xx0/Makefile.boot b/arch/arm/mach-mv78xx0/Makefile.boot deleted file mode 100644 index 760a0efe7580b0dd194ff9bfe4295624336bb806..0000000000000000000000000000000000000000 --- a/arch/arm/mach-mv78xx0/Makefile.boot +++ /dev/null @@ -1,3 +0,0 @@ - zreladdr-y += 0x00008000 -params_phys-y := 0x00000100 -initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-mv78xx0/common.c b/arch/arm/mach-mv78xx0/common.c index a1a04df9c05c57f34ea3f5a9471522113381487c..99cc93900a243df98c1af2c17f54657e61b283ee 100644 --- a/arch/arm/mach-mv78xx0/common.c +++ b/arch/arm/mach-mv78xx0/common.c @@ -405,9 +405,8 @@ void __init mv78xx0_init(void) printk("HCLK = %dMHz, ", (hclk + 499999) / 1000000); printk("TCLK = %dMHz\n", (get_tclk() + 499999) / 1000000); -#ifdef CONFIG_CACHE_FEROCEON_L2 - feroceon_l2_init(is_l2_writethrough()); -#endif + if (IS_ENABLED(CONFIG_CACHE_FEROCEON_L2)) + feroceon_l2_init(is_l2_writethrough()); /* Setup root of clk tree */ clk_init(); diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index b003e3afd693008b9023cdf58911e438ceee30ea..348044ea650c6725e07b910cc810e4e1ae566774 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -32,6 +32,7 @@ config MACH_ARMADA_370 select CPU_PJ4B select MACH_MVEBU_V7 select PINCTRL_ARMADA_370 + select MVEBU_CLK_COREDIV help Say 'Y' here if you want your kernel to support boards based on the Marvell Armada 370 SoC with device tree. @@ -49,6 +50,7 @@ config MACH_ARMADA_375 select HAVE_SMP select MACH_MVEBU_V7 select PINCTRL_ARMADA_375 + select MVEBU_CLK_COREDIV help Say 'Y' here if you want your kernel to support boards based on the Marvell Armada 375 SoC with device tree. @@ -66,6 +68,7 @@ config MACH_ARMADA_38X select HAVE_SMP select MACH_MVEBU_V7 select PINCTRL_ARMADA_38X + select MVEBU_CLK_COREDIV help Say 'Y' here if you want your kernel to support boards based on the Marvell Armada 380/385 SoC with device tree. diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c index 55348ee5a35228cf5e8cbb8f55b0b16b4d56c805..7e989d61159c384df1de62b27156ddf22d8fa44f 100644 --- a/arch/arm/mach-mvebu/coherency.c +++ b/arch/arm/mach-mvebu/coherency.c @@ -107,7 +107,7 @@ static struct notifier_block mvebu_hwcc_nb = { .notifier_call = mvebu_hwcc_notifier, }; -static struct notifier_block mvebu_hwcc_pci_nb = { +static struct notifier_block mvebu_hwcc_pci_nb __maybe_unused = { .notifier_call = mvebu_hwcc_notifier, }; diff --git a/arch/arm/mach-mvebu/platsmp.c b/arch/arm/mach-mvebu/platsmp.c index f9597b701028a107d6acc11ce481fcaddc5e0411..46c742d3bd41e65c0f0fbaa2fc5cb8d3561b0c0a 100644 --- a/arch/arm/mach-mvebu/platsmp.c +++ b/arch/arm/mach-mvebu/platsmp.c @@ -140,6 +140,7 @@ static void __init armada_xp_smp_prepare_cpus(unsigned int max_cpus) panic("Cannot find 'marvell,bootrom' compatible node"); err = of_address_to_resource(node, 0, &res); + of_node_put(node); if (err < 0) panic("Cannot get 'bootrom' node address"); diff --git a/arch/arm/mach-netx/Kconfig b/arch/arm/mach-netx/Kconfig index 3d90ef19be2b4cae09a187e5e9541154f714ed03..2da8e5dfcf24df4fca3ba9384b84726654dea4d8 100644 --- a/arch/arm/mach-netx/Kconfig +++ b/arch/arm/mach-netx/Kconfig @@ -3,20 +3,17 @@ menu "NetX Implementations" config MACH_NXDKN bool "Enable Hilscher nxdkn Eval Board support" - depends on ARCH_NETX help Board support for the Hilscher NetX Eval Board config MACH_NXDB500 bool "Enable Hilscher nxdb500 Eval Board support" - depends on ARCH_NETX select ARM_AMBA help Board support for the Hilscher nxdb500 Eval Board config MACH_NXEB500HMI bool "Enable Hilscher nxeb500hmi Eval Board support" - depends on ARCH_NETX select ARM_AMBA help Board support for the Hilscher nxeb500hmi Eval Board diff --git a/arch/arm/mach-netx/include/mach/uncompress.h b/arch/arm/mach-netx/include/mach/uncompress.h index 5cb1051b5831330beb681a78e2bc00450ff4f744..033875dbc32b8695dec4249a3494a799311b954f 100644 --- a/arch/arm/mach-netx/include/mach/uncompress.h +++ b/arch/arm/mach-netx/include/mach/uncompress.h @@ -40,7 +40,7 @@ #define FR_BUSY (1<<3) #define FR_TXFF (1<<5) -static void putc(char c) +static inline void putc(char c) { unsigned long base; diff --git a/arch/arm/mach-omap1/dma.c b/arch/arm/mach-omap1/dma.c index 7b02ed218a42f693a7347c58488d026f11b5b113..f6ba589cd312ecb257829d81f7f04c967b60e216 100644 --- a/arch/arm/mach-omap1/dma.c +++ b/arch/arm/mach-omap1/dma.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -265,6 +266,42 @@ static const struct platform_device_info omap_dma_dev_info = { .num_res = 1, }; +/* OMAP730, OMAP850 */ +static const struct dma_slave_map omap7xx_sdma_map[] = { + { "omap-mcbsp.1", "tx", SDMA_FILTER_PARAM(8) }, + { "omap-mcbsp.1", "rx", SDMA_FILTER_PARAM(9) }, + { "omap-mcbsp.2", "tx", SDMA_FILTER_PARAM(10) }, + { "omap-mcbsp.2", "rx", SDMA_FILTER_PARAM(11) }, + { "mmci-omap.0", "tx", SDMA_FILTER_PARAM(21) }, + { "mmci-omap.0", "rx", SDMA_FILTER_PARAM(22) }, + { "omap_udc", "rx0", SDMA_FILTER_PARAM(26) }, + { "omap_udc", "rx1", SDMA_FILTER_PARAM(27) }, + { "omap_udc", "rx2", SDMA_FILTER_PARAM(28) }, + { "omap_udc", "tx0", SDMA_FILTER_PARAM(29) }, + { "omap_udc", "tx1", SDMA_FILTER_PARAM(30) }, + { "omap_udc", "tx2", SDMA_FILTER_PARAM(31) }, +}; + +/* OMAP1510, OMAP1610*/ +static const struct dma_slave_map omap1xxx_sdma_map[] = { + { "omap-mcbsp.1", "tx", SDMA_FILTER_PARAM(8) }, + { "omap-mcbsp.1", "rx", SDMA_FILTER_PARAM(9) }, + { "omap-mcbsp.3", "tx", SDMA_FILTER_PARAM(10) }, + { "omap-mcbsp.3", "rx", SDMA_FILTER_PARAM(11) }, + { "omap-mcbsp.2", "tx", SDMA_FILTER_PARAM(16) }, + { "omap-mcbsp.2", "rx", SDMA_FILTER_PARAM(17) }, + { "mmci-omap.0", "tx", SDMA_FILTER_PARAM(21) }, + { "mmci-omap.0", "rx", SDMA_FILTER_PARAM(22) }, + { "omap_udc", "rx0", SDMA_FILTER_PARAM(26) }, + { "omap_udc", "rx1", SDMA_FILTER_PARAM(27) }, + { "omap_udc", "rx2", SDMA_FILTER_PARAM(28) }, + { "omap_udc", "tx0", SDMA_FILTER_PARAM(29) }, + { "omap_udc", "tx1", SDMA_FILTER_PARAM(30) }, + { "omap_udc", "tx2", SDMA_FILTER_PARAM(31) }, + { "mmci-omap.1", "tx", SDMA_FILTER_PARAM(54) }, + { "mmci-omap.1", "rx", SDMA_FILTER_PARAM(55) }, +}; + static struct omap_system_dma_plat_info dma_plat_info __initdata = { .reg_map = reg_map, .channel_stride = 0x40, @@ -342,6 +379,14 @@ static int __init omap1_system_dma_init(void) p.dma_attr = d; p.errata = configure_dma_errata(); + if (cpu_is_omap7xx()) { + p.slave_map = omap7xx_sdma_map; + p.slavecnt = ARRAY_SIZE(omap7xx_sdma_map); + } else { + p.slave_map = omap1xxx_sdma_map; + p.slavecnt = ARRAY_SIZE(omap1xxx_sdma_map); + } + ret = platform_device_add_data(pdev, &p, sizeof(p)); if (ret) { dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n", diff --git a/arch/arm/mach-omap1/include/mach/uncompress.h b/arch/arm/mach-omap1/include/mach/uncompress.h index 4869633de8cd36ab65c4ef7317cb97497013c3da..9cca6a56788fee71fa1a54a57a19610b276dbd96 100644 --- a/arch/arm/mach-omap1/include/mach/uncompress.h +++ b/arch/arm/mach-omap1/include/mach/uncompress.h @@ -45,7 +45,7 @@ static void set_omap_uart_info(unsigned char port) *uart_info = port; } -static void putc(int c) +static inline void putc(int c) { if (!uart_base) return; diff --git a/arch/arm/mach-omap2/Makefile.boot b/arch/arm/mach-omap2/Makefile.boot deleted file mode 100644 index b03e562acc60738badb856fdbd199447a55d3407..0000000000000000000000000000000000000000 --- a/arch/arm/mach-omap2/Makefile.boot +++ /dev/null @@ -1,3 +0,0 @@ - zreladdr-y += 0x80008000 -params_phys-y := 0x80000100 -initrd_phys-y := 0x80800000 diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c index cf5855174c93cbb57d3b0ccb9f2a5e417a59c7eb..1662071bb2cc8361023aa3a066ab963bbd411540 100644 --- a/arch/arm/mach-omap2/control.c +++ b/arch/arm/mach-omap2/control.c @@ -36,7 +36,6 @@ static void __iomem *omap2_ctrl_base; static s16 omap2_ctrl_offset; -static struct regmap *omap2_ctrl_syscon; #if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM) struct omap3_scratchpad { @@ -166,16 +165,9 @@ u16 omap_ctrl_readw(u16 offset) u32 omap_ctrl_readl(u16 offset) { - u32 val; - offset &= 0xfffc; - if (!omap2_ctrl_syscon) - val = readl_relaxed(omap2_ctrl_base + offset); - else - regmap_read(omap2_ctrl_syscon, omap2_ctrl_offset + offset, - &val); - return val; + return readl_relaxed(omap2_ctrl_base + offset); } void omap_ctrl_writeb(u8 val, u16 offset) @@ -207,11 +199,7 @@ void omap_ctrl_writew(u16 val, u16 offset) void omap_ctrl_writel(u32 val, u16 offset) { offset &= 0xfffc; - if (!omap2_ctrl_syscon) - writel_relaxed(val, omap2_ctrl_base + offset); - else - regmap_write(omap2_ctrl_syscon, omap2_ctrl_offset + offset, - val); + writel_relaxed(val, omap2_ctrl_base + offset); } #ifdef CONFIG_ARCH_OMAP3 @@ -715,8 +703,6 @@ int __init omap_control_init(void) if (IS_ERR(syscon)) return PTR_ERR(syscon); - omap2_ctrl_syscon = syscon; - if (of_get_child_by_name(scm_conf, "clocks")) { ret = omap2_clk_provider_init(scm_conf, data->index, @@ -724,9 +710,6 @@ int __init omap_control_init(void) if (ret) return ret; } - - iounmap(omap2_ctrl_base); - omap2_ctrl_base = NULL; } else { /* No scm_conf found, direct access */ ret = omap2_clk_provider_init(np, data->index, NULL, diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index aa7b379e266148fa8990165a8dae7ba3e09edcf7..2a3db0bd9e15c3d942199c5d4ac089868ca3e7bf 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c @@ -34,6 +34,7 @@ #include "pm.h" #include "control.h" #include "common.h" +#include "soc.h" /* Mach specific information to be recorded in the C-state driver_data */ struct omap3_idle_statedata { @@ -315,6 +316,69 @@ static struct cpuidle_driver omap3_idle_driver = { .safe_state_index = 0, }; +/* + * Numbers based on measurements made in October 2009 for PM optimized kernel + * with CPU freq enabled on device Nokia N900. Assumes OPP2 (main idle OPP, + * and worst case latencies). + */ +static struct cpuidle_driver omap3430_idle_driver = { + .name = "omap3430_idle", + .owner = THIS_MODULE, + .states = { + { + .enter = omap3_enter_idle_bm, + .exit_latency = 110 + 162, + .target_residency = 5, + .name = "C1", + .desc = "MPU ON + CORE ON", + }, + { + .enter = omap3_enter_idle_bm, + .exit_latency = 106 + 180, + .target_residency = 309, + .name = "C2", + .desc = "MPU ON + CORE ON", + }, + { + .enter = omap3_enter_idle_bm, + .exit_latency = 107 + 410, + .target_residency = 46057, + .name = "C3", + .desc = "MPU RET + CORE ON", + }, + { + .enter = omap3_enter_idle_bm, + .exit_latency = 121 + 3374, + .target_residency = 46057, + .name = "C4", + .desc = "MPU OFF + CORE ON", + }, + { + .enter = omap3_enter_idle_bm, + .exit_latency = 855 + 1146, + .target_residency = 46057, + .name = "C5", + .desc = "MPU RET + CORE RET", + }, + { + .enter = omap3_enter_idle_bm, + .exit_latency = 7580 + 4134, + .target_residency = 484329, + .name = "C6", + .desc = "MPU OFF + CORE RET", + }, + { + .enter = omap3_enter_idle_bm, + .exit_latency = 7505 + 15274, + .target_residency = 484329, + .name = "C7", + .desc = "MPU OFF + CORE OFF", + }, + }, + .state_count = ARRAY_SIZE(omap3_idle_data), + .safe_state_index = 0, +}; + /* Public functions */ /** @@ -333,5 +397,8 @@ int __init omap3_idle_init(void) if (!mpu_pd || !core_pd || !per_pd || !cam_pd) return -ENODEV; - return cpuidle_register(&omap3_idle_driver, NULL); + if (cpu_is_omap3430()) + return cpuidle_register(&omap3430_idle_driver, NULL); + else + return cpuidle_register(&omap3_idle_driver, NULL); } diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c index 1ed4be184a29b16f6f8d97a082fb80d424ca0665..e58c13a9bea5e78943e1c01fa158bea2aee31851 100644 --- a/arch/arm/mach-omap2/dma.c +++ b/arch/arm/mach-omap2/dma.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -203,6 +204,108 @@ static unsigned configure_dma_errata(void) return errata; } +static const struct dma_slave_map omap24xx_sdma_map[] = { + { "omap-gpmc", "rxtx", SDMA_FILTER_PARAM(4) }, + { "omap-aes", "tx", SDMA_FILTER_PARAM(9) }, + { "omap-aes", "rx", SDMA_FILTER_PARAM(10) }, + { "omap-sham", "rx", SDMA_FILTER_PARAM(13) }, + { "omap2_mcspi.2", "tx0", SDMA_FILTER_PARAM(15) }, + { "omap2_mcspi.2", "rx0", SDMA_FILTER_PARAM(16) }, + { "omap-mcbsp.3", "tx", SDMA_FILTER_PARAM(17) }, + { "omap-mcbsp.3", "rx", SDMA_FILTER_PARAM(18) }, + { "omap-mcbsp.4", "tx", SDMA_FILTER_PARAM(19) }, + { "omap-mcbsp.4", "rx", SDMA_FILTER_PARAM(20) }, + { "omap-mcbsp.5", "tx", SDMA_FILTER_PARAM(21) }, + { "omap-mcbsp.5", "rx", SDMA_FILTER_PARAM(22) }, + { "omap2_mcspi.2", "tx1", SDMA_FILTER_PARAM(23) }, + { "omap2_mcspi.2", "rx1", SDMA_FILTER_PARAM(24) }, + { "omap_i2c.1", "tx", SDMA_FILTER_PARAM(27) }, + { "omap_i2c.1", "rx", SDMA_FILTER_PARAM(28) }, + { "omap_i2c.2", "tx", SDMA_FILTER_PARAM(29) }, + { "omap_i2c.2", "rx", SDMA_FILTER_PARAM(30) }, + { "omap-mcbsp.1", "tx", SDMA_FILTER_PARAM(31) }, + { "omap-mcbsp.1", "rx", SDMA_FILTER_PARAM(32) }, + { "omap-mcbsp.2", "tx", SDMA_FILTER_PARAM(33) }, + { "omap-mcbsp.2", "rx", SDMA_FILTER_PARAM(34) }, + { "omap2_mcspi.0", "tx0", SDMA_FILTER_PARAM(35) }, + { "omap2_mcspi.0", "rx0", SDMA_FILTER_PARAM(36) }, + { "omap2_mcspi.0", "tx1", SDMA_FILTER_PARAM(37) }, + { "omap2_mcspi.0", "rx1", SDMA_FILTER_PARAM(38) }, + { "omap2_mcspi.0", "tx2", SDMA_FILTER_PARAM(39) }, + { "omap2_mcspi.0", "rx2", SDMA_FILTER_PARAM(40) }, + { "omap2_mcspi.0", "tx3", SDMA_FILTER_PARAM(41) }, + { "omap2_mcspi.0", "rx3", SDMA_FILTER_PARAM(42) }, + { "omap2_mcspi.1", "tx0", SDMA_FILTER_PARAM(43) }, + { "omap2_mcspi.1", "rx0", SDMA_FILTER_PARAM(44) }, + { "omap2_mcspi.1", "tx1", SDMA_FILTER_PARAM(45) }, + { "omap2_mcspi.1", "rx1", SDMA_FILTER_PARAM(46) }, + { "omap_hsmmc.1", "tx", SDMA_FILTER_PARAM(47) }, + { "omap_hsmmc.1", "rx", SDMA_FILTER_PARAM(48) }, + { "omap_uart.0", "tx", SDMA_FILTER_PARAM(49) }, + { "omap_uart.0", "rx", SDMA_FILTER_PARAM(50) }, + { "omap_uart.1", "tx", SDMA_FILTER_PARAM(51) }, + { "omap_uart.1", "rx", SDMA_FILTER_PARAM(52) }, + { "omap_uart.2", "tx", SDMA_FILTER_PARAM(53) }, + { "omap_uart.2", "rx", SDMA_FILTER_PARAM(54) }, + { "omap_hsmmc.0", "tx", SDMA_FILTER_PARAM(61) }, + { "omap_hsmmc.0", "rx", SDMA_FILTER_PARAM(62) }, +}; + +static const struct dma_slave_map omap3xxx_sdma_map[] = { + { "omap-gpmc", "rxtx", SDMA_FILTER_PARAM(4) }, + { "omap2_mcspi.2", "tx0", SDMA_FILTER_PARAM(15) }, + { "omap2_mcspi.2", "rx0", SDMA_FILTER_PARAM(16) }, + { "omap-mcbsp.3", "tx", SDMA_FILTER_PARAM(17) }, + { "omap-mcbsp.3", "rx", SDMA_FILTER_PARAM(18) }, + { "omap-mcbsp.4", "tx", SDMA_FILTER_PARAM(19) }, + { "omap-mcbsp.4", "rx", SDMA_FILTER_PARAM(20) }, + { "omap-mcbsp.5", "tx", SDMA_FILTER_PARAM(21) }, + { "omap-mcbsp.5", "rx", SDMA_FILTER_PARAM(22) }, + { "omap2_mcspi.2", "tx1", SDMA_FILTER_PARAM(23) }, + { "omap2_mcspi.2", "rx1", SDMA_FILTER_PARAM(24) }, + { "omap_i2c.3", "tx", SDMA_FILTER_PARAM(25) }, + { "omap_i2c.3", "rx", SDMA_FILTER_PARAM(26) }, + { "omap_i2c.1", "tx", SDMA_FILTER_PARAM(27) }, + { "omap_i2c.1", "rx", SDMA_FILTER_PARAM(28) }, + { "omap_i2c.2", "tx", SDMA_FILTER_PARAM(29) }, + { "omap_i2c.2", "rx", SDMA_FILTER_PARAM(30) }, + { "omap-mcbsp.1", "tx", SDMA_FILTER_PARAM(31) }, + { "omap-mcbsp.1", "rx", SDMA_FILTER_PARAM(32) }, + { "omap-mcbsp.2", "tx", SDMA_FILTER_PARAM(33) }, + { "omap-mcbsp.2", "rx", SDMA_FILTER_PARAM(34) }, + { "omap2_mcspi.0", "tx0", SDMA_FILTER_PARAM(35) }, + { "omap2_mcspi.0", "rx0", SDMA_FILTER_PARAM(36) }, + { "omap2_mcspi.0", "tx1", SDMA_FILTER_PARAM(37) }, + { "omap2_mcspi.0", "rx1", SDMA_FILTER_PARAM(38) }, + { "omap2_mcspi.0", "tx2", SDMA_FILTER_PARAM(39) }, + { "omap2_mcspi.0", "rx2", SDMA_FILTER_PARAM(40) }, + { "omap2_mcspi.0", "tx3", SDMA_FILTER_PARAM(41) }, + { "omap2_mcspi.0", "rx3", SDMA_FILTER_PARAM(42) }, + { "omap2_mcspi.1", "tx0", SDMA_FILTER_PARAM(43) }, + { "omap2_mcspi.1", "rx0", SDMA_FILTER_PARAM(44) }, + { "omap2_mcspi.1", "tx1", SDMA_FILTER_PARAM(45) }, + { "omap2_mcspi.1", "rx1", SDMA_FILTER_PARAM(46) }, + { "omap_hsmmc.1", "tx", SDMA_FILTER_PARAM(47) }, + { "omap_hsmmc.1", "rx", SDMA_FILTER_PARAM(48) }, + { "omap_uart.0", "tx", SDMA_FILTER_PARAM(49) }, + { "omap_uart.0", "rx", SDMA_FILTER_PARAM(50) }, + { "omap_uart.1", "tx", SDMA_FILTER_PARAM(51) }, + { "omap_uart.1", "rx", SDMA_FILTER_PARAM(52) }, + { "omap_uart.2", "tx", SDMA_FILTER_PARAM(53) }, + { "omap_uart.2", "rx", SDMA_FILTER_PARAM(54) }, + { "omap_hsmmc.0", "tx", SDMA_FILTER_PARAM(61) }, + { "omap_hsmmc.0", "rx", SDMA_FILTER_PARAM(62) }, + { "omap-aes", "tx", SDMA_FILTER_PARAM(65) }, + { "omap-aes", "rx", SDMA_FILTER_PARAM(66) }, + { "omap-sham", "rx", SDMA_FILTER_PARAM(69) }, + { "omap2_mcspi.3", "tx0", SDMA_FILTER_PARAM(70) }, + { "omap2_mcspi.3", "rx0", SDMA_FILTER_PARAM(71) }, + { "omap_hsmmc.2", "tx", SDMA_FILTER_PARAM(77) }, + { "omap_hsmmc.2", "rx", SDMA_FILTER_PARAM(78) }, + { "omap_uart.3", "tx", SDMA_FILTER_PARAM(81) }, + { "omap_uart.3", "rx", SDMA_FILTER_PARAM(82) }, +}; + static struct omap_system_dma_plat_info dma_plat_info __initdata = { .reg_map = reg_map, .channel_stride = 0x60, @@ -231,6 +334,20 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused) p.dma_attr = (struct omap_dma_dev_attr *)oh->dev_attr; p.errata = configure_dma_errata(); + if (!of_have_populated_dt()) { + if (soc_is_omap24xx()) { + p.slave_map = omap24xx_sdma_map; + p.slavecnt = ARRAY_SIZE(omap24xx_sdma_map); + } else if (soc_is_omap34xx() || soc_is_omap3630()) { + p.slave_map = omap3xxx_sdma_map; + p.slavecnt = ARRAY_SIZE(omap3xxx_sdma_map); + } else { + pr_err("%s: The legacy DMA map is not provided!\n", + __func__); + return -ENODEV; + } + } + pdev = omap_device_build(name, 0, oh, &p, sizeof(p)); if (IS_ERR(pdev)) { pr_err("%s: Can't build omap_device for %s:%s.\n", diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 0a985325cd645964023aadc383a757196e579282..9869a75c5d96d5647090bba102f0d736215a16ce 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -3583,14 +3583,14 @@ static struct omap_hwmod_class_sysconfig omap34xx_ssi_sysc = { .sysc_fields = &omap_hwmod_sysc_type1, }; -static struct omap_hwmod_class omap34xx_ssi_hwmod_class = { +static struct omap_hwmod_class omap3xxx_ssi_hwmod_class = { .name = "ssi", .sysc = &omap34xx_ssi_sysc, }; -static struct omap_hwmod omap34xx_ssi_hwmod = { +static struct omap_hwmod omap3xxx_ssi_hwmod = { .name = "ssi", - .class = &omap34xx_ssi_hwmod_class, + .class = &omap3xxx_ssi_hwmod_class, .clkdm_name = "core_l4_clkdm", .main_clk = "ssi_ssr_fck", .prcm = { @@ -3605,9 +3605,9 @@ static struct omap_hwmod omap34xx_ssi_hwmod = { }; /* L4 CORE -> SSI */ -static struct omap_hwmod_ocp_if omap34xx_l4_core__ssi = { +static struct omap_hwmod_ocp_if omap3xxx_l4_core__ssi = { .master = &omap3xxx_l4_core_hwmod, - .slave = &omap34xx_ssi_hwmod, + .slave = &omap3xxx_ssi_hwmod, .clk = "ssi_ick", .user = OCP_USER_MPU | OCP_USER_SDMA, }; @@ -3760,7 +3760,7 @@ static struct omap_hwmod_ocp_if *omap34xx_hwmod_ocp_ifs[] __initdata = { &omap3xxx_sad2d__l3, &omap3xxx_l4_core__mmu_isp, &omap3xxx_l3_main__mmu_iva, - &omap34xx_l4_core__ssi, + &omap3xxx_l4_core__ssi, NULL }; @@ -3784,6 +3784,7 @@ static struct omap_hwmod_ocp_if *omap36xx_hwmod_ocp_ifs[] __initdata = { &omap3xxx_sad2d__l3, &omap3xxx_l4_core__mmu_isp, &omap3xxx_l3_main__mmu_iva, + &omap3xxx_l4_core__ssi, NULL }; diff --git a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c index e97a894b5f883723c94d8ac0649346df21d4398c..97fd399202dcb6a8825e90b91e4872f452ae70e1 100644 --- a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c @@ -1020,9 +1020,21 @@ static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = { NULL, }; +static struct omap_hwmod_ocp_if *am43xx_rtc_hwmod_ocp_ifs[] __initdata = { + &am33xx_l4_wkup__rtc, + NULL, +}; + int __init am43xx_hwmod_init(void) { + int ret; + omap_hwmod_am43xx_reg(); omap_hwmod_init(); - return omap_hwmod_register_links(am43xx_hwmod_ocp_ifs); + ret = omap_hwmod_register_links(am43xx_hwmod_ocp_ifs); + + if (!ret && of_machine_is_compatible("ti,am4372")) + ret = omap_hwmod_register_links(am43xx_rtc_hwmod_ocp_ifs); + + return ret; } diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c index 848356e38b745043f872881f1e2785444fe91661..9442d89bd2292bea0c4660abca067a632a7a56dd 100644 --- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c @@ -429,6 +429,67 @@ static struct omap_hwmod dra7xx_dma_system_hwmod = { .dev_attr = &dma_dev_attr, }; +/* + * 'tpcc' class + * + */ +static struct omap_hwmod_class dra7xx_tpcc_hwmod_class = { + .name = "tpcc", +}; + +static struct omap_hwmod dra7xx_tpcc_hwmod = { + .name = "tpcc", + .class = &dra7xx_tpcc_hwmod_class, + .clkdm_name = "l3main1_clkdm", + .main_clk = "l3_iclk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L3MAIN1_TPCC_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L3MAIN1_TPCC_CONTEXT_OFFSET, + }, + }, +}; + +/* + * 'tptc' class + * + */ +static struct omap_hwmod_class dra7xx_tptc_hwmod_class = { + .name = "tptc", +}; + +/* tptc0 */ +static struct omap_hwmod dra7xx_tptc0_hwmod = { + .name = "tptc0", + .class = &dra7xx_tptc_hwmod_class, + .clkdm_name = "l3main1_clkdm", + .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, + .main_clk = "l3_iclk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L3MAIN1_TPTC1_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L3MAIN1_TPTC1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* tptc1 */ +static struct omap_hwmod dra7xx_tptc1_hwmod = { + .name = "tptc1", + .class = &dra7xx_tptc_hwmod_class, + .clkdm_name = "l3main1_clkdm", + .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, + .main_clk = "l3_iclk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = DRA7XX_CM_L3MAIN1_TPTC2_CLKCTRL_OFFSET, + .context_offs = DRA7XX_RM_L3MAIN1_TPTC2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + /* * 'dss' class * @@ -1482,8 +1543,7 @@ static struct omap_hwmod_class_sysconfig dra7xx_ocp2scp_sysc = { .syss_offs = 0x0014, .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | - SIDLE_SMART_WKUP), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), .sysc_fields = &omap_hwmod_sysc_type1, }; @@ -1527,34 +1587,72 @@ static struct omap_hwmod dra7xx_ocp2scp3_hwmod = { * */ +/* + * As noted in documentation for _reset() in omap_hwmod.c, the stock reset + * functionality of OMAP HWMOD layer does not deassert the hardreset lines + * associated with an IP automatically leaving the driver to handle that + * by itself. This does not work for PCIeSS which needs the reset lines + * deasserted for the driver to start accessing registers. + * + * We use a PCIeSS HWMOD class specific reset handler to deassert the hardreset + * lines after asserting them. + */ +static int dra7xx_pciess_reset(struct omap_hwmod *oh) +{ + int i; + + for (i = 0; i < oh->rst_lines_cnt; i++) { + omap_hwmod_assert_hardreset(oh, oh->rst_lines[i].name); + omap_hwmod_deassert_hardreset(oh, oh->rst_lines[i].name); + } + + return 0; +} + static struct omap_hwmod_class dra7xx_pciess_hwmod_class = { .name = "pcie", + .reset = dra7xx_pciess_reset, }; /* pcie1 */ +static struct omap_hwmod_rst_info dra7xx_pciess1_resets[] = { + { .name = "pcie", .rst_shift = 0 }, +}; + static struct omap_hwmod dra7xx_pciess1_hwmod = { .name = "pcie1", .class = &dra7xx_pciess_hwmod_class, .clkdm_name = "pcie_clkdm", + .rst_lines = dra7xx_pciess1_resets, + .rst_lines_cnt = ARRAY_SIZE(dra7xx_pciess1_resets), .main_clk = "l4_root_clk_div", .prcm = { .omap4 = { .clkctrl_offs = DRA7XX_CM_L3INIT_PCIESS1_CLKCTRL_OFFSET, + .rstctrl_offs = DRA7XX_RM_L3INIT_PCIESS_RSTCTRL_OFFSET, .context_offs = DRA7XX_RM_L3INIT_PCIESS1_CONTEXT_OFFSET, .modulemode = MODULEMODE_SWCTRL, }, }, }; +/* pcie2 */ +static struct omap_hwmod_rst_info dra7xx_pciess2_resets[] = { + { .name = "pcie", .rst_shift = 1 }, +}; + /* pcie2 */ static struct omap_hwmod dra7xx_pciess2_hwmod = { .name = "pcie2", .class = &dra7xx_pciess_hwmod_class, .clkdm_name = "pcie_clkdm", + .rst_lines = dra7xx_pciess2_resets, + .rst_lines_cnt = ARRAY_SIZE(dra7xx_pciess2_resets), .main_clk = "l4_root_clk_div", .prcm = { .omap4 = { .clkctrl_offs = DRA7XX_CM_L3INIT_PCIESS2_CLKCTRL_OFFSET, + .rstctrl_offs = DRA7XX_RM_L3INIT_PCIESS_RSTCTRL_OFFSET, .context_offs = DRA7XX_RM_L3INIT_PCIESS2_CONTEXT_OFFSET, .modulemode = MODULEMODE_SWCTRL, }, @@ -2549,6 +2647,30 @@ static struct omap_hwmod_ocp_if dra7xx_l4_cfg__dma_system = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +/* l3_main_1 -> tpcc */ +static struct omap_hwmod_ocp_if dra7xx_l3_main_1__tpcc = { + .master = &dra7xx_l3_main_1_hwmod, + .slave = &dra7xx_tpcc_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU, +}; + +/* l3_main_1 -> tptc0 */ +static struct omap_hwmod_ocp_if dra7xx_l3_main_1__tptc0 = { + .master = &dra7xx_l3_main_1_hwmod, + .slave = &dra7xx_tptc0_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU, +}; + +/* l3_main_1 -> tptc1 */ +static struct omap_hwmod_ocp_if dra7xx_l3_main_1__tptc1 = { + .master = &dra7xx_l3_main_1_hwmod, + .slave = &dra7xx_tptc1_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU, +}; + static struct omap_hwmod_addr_space dra7xx_dss_addrs[] = { { .name = "family", @@ -3366,6 +3488,9 @@ static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = { &dra7xx_l3_main_1__mcasp3, &dra7xx_gmac__mdio, &dra7xx_l4_cfg__dma_system, + &dra7xx_l3_main_1__tpcc, + &dra7xx_l3_main_1__tptc0, + &dra7xx_l3_main_1__tptc1, &dra7xx_l3_main_1__dss, &dra7xx_l3_main_1__dispc, &dra7xx_l3_main_1__hdmi, diff --git a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c index e493ae37291035d1e11450e62a75f47dcd4cfe0d..39736ad2a7548d41cc2ca078084c6e04e414bf56 100644 --- a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c @@ -228,6 +228,42 @@ static struct omap_hwmod_ocp_if dm816x_mpu__alwon_l3_med = { .user = OCP_USER_MPU, }; +/* RTC */ +static struct omap_hwmod_class_sysconfig ti81xx_rtc_sysc = { + .rev_offs = 0x74, + .sysc_offs = 0x78, + .sysc_flags = SYSC_HAS_SIDLEMODE, + .idlemodes = SIDLE_FORCE | SIDLE_NO | + SIDLE_SMART | SIDLE_SMART_WKUP, + .sysc_fields = &omap_hwmod_sysc_type3, +}; + +static struct omap_hwmod_class ti81xx_rtc_hwmod_class = { + .name = "rtc", + .sysc = &ti81xx_rtc_sysc, +}; + +struct omap_hwmod ti81xx_rtc_hwmod = { + .name = "rtc", + .class = &ti81xx_rtc_hwmod_class, + .clkdm_name = "alwon_l3s_clkdm", + .flags = HWMOD_NO_IDLEST, + .main_clk = "sysclk18_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = DM81XX_CM_ALWON_RTC_CLKCTRL, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod_ocp_if ti81xx_l4_ls__rtc = { + .master = &dm81xx_l4_ls_hwmod, + .slave = &ti81xx_rtc_hwmod, + .clk = "sysclk6_ck", + .user = OCP_USER_MPU, +}; + /* UART common */ static struct omap_hwmod_class_sysconfig uart_sysc = { .rev_offs = 0x50, @@ -429,6 +465,7 @@ static struct omap_hwmod dm81xx_elm_hwmod = { static struct omap_hwmod_ocp_if dm81xx_l4_ls__elm = { .master = &dm81xx_l4_ls_hwmod, .slave = &dm81xx_elm_hwmod, + .clk = "sysclk6_ck", .user = OCP_USER_MPU, }; @@ -478,6 +515,7 @@ static struct omap_hwmod dm81xx_gpio1_hwmod = { static struct omap_hwmod_ocp_if dm81xx_l4_ls__gpio1 = { .master = &dm81xx_l4_ls_hwmod, .slave = &dm81xx_gpio1_hwmod, + .clk = "sysclk6_ck", .user = OCP_USER_MPU, }; @@ -504,6 +542,7 @@ static struct omap_hwmod dm81xx_gpio2_hwmod = { static struct omap_hwmod_ocp_if dm81xx_l4_ls__gpio2 = { .master = &dm81xx_l4_ls_hwmod, .slave = &dm81xx_gpio2_hwmod, + .clk = "sysclk6_ck", .user = OCP_USER_MPU, }; @@ -628,7 +667,7 @@ static struct omap_hwmod dm814x_timer1_hwmod = { static struct omap_hwmod_ocp_if dm814x_l4_ls__timer1 = { .master = &dm81xx_l4_ls_hwmod, .slave = &dm814x_timer1_hwmod, - .clk = "timer1_fck", + .clk = "sysclk6_ck", .user = OCP_USER_MPU, }; @@ -665,7 +704,7 @@ static struct omap_hwmod dm814x_timer2_hwmod = { static struct omap_hwmod_ocp_if dm814x_l4_ls__timer2 = { .master = &dm81xx_l4_ls_hwmod, .slave = &dm814x_timer2_hwmod, - .clk = "timer2_fck", + .clk = "sysclk6_ck", .user = OCP_USER_MPU, }; @@ -1123,6 +1162,7 @@ static struct omap_hwmod dm81xx_mailbox_hwmod = { static struct omap_hwmod_ocp_if dm81xx_l4_ls__mailbox = { .master = &dm81xx_l4_ls_hwmod, .slave = &dm81xx_mailbox_hwmod, + .clk = "sysclk6_ck", .user = OCP_USER_MPU, }; @@ -1157,6 +1197,7 @@ static struct omap_hwmod dm81xx_spinbox_hwmod = { static struct omap_hwmod_ocp_if dm81xx_l4_ls__spinbox = { .master = &dm81xx_l4_ls_hwmod, .slave = &dm81xx_spinbox_hwmod, + .clk = "sysclk6_ck", .user = OCP_USER_MPU, }; @@ -1376,6 +1417,7 @@ static struct omap_hwmod_ocp_if *dm814x_hwmod_ocp_ifs[] __initdata = { &dm81xx_l4_ls__mcspi1, &dm814x_l4_ls__mmc1, &dm814x_l4_ls__mmc2, + &ti81xx_l4_ls__rtc, &dm81xx_alwon_l3_fast__tpcc, &dm81xx_alwon_l3_fast__tptc0, &dm81xx_alwon_l3_fast__tptc1, @@ -1415,6 +1457,7 @@ static struct omap_hwmod_ocp_if *dm816x_hwmod_ocp_ifs[] __initdata = { &dm81xx_l4_ls__gpio1, &dm81xx_l4_ls__gpio2, &dm81xx_l4_ls__elm, + &ti81xx_l4_ls__rtc, &dm816x_l4_ls__mmc1, &dm816x_l4_ls__timer1, &dm816x_l4_ls__timer2, diff --git a/arch/arm/mach-omap2/prm7xx.h b/arch/arm/mach-omap2/prm7xx.h index cc1e6a2b97f66af3b9ea53f0a1a57115aaac77a4..294deed956f36fb90e12d47b552455084dafe90a 100644 --- a/arch/arm/mach-omap2/prm7xx.h +++ b/arch/arm/mach-omap2/prm7xx.h @@ -360,6 +360,7 @@ /* PRM.L3INIT_PRM register offsets */ #define DRA7XX_PM_L3INIT_PWRSTCTRL_OFFSET 0x0000 #define DRA7XX_PM_L3INIT_PWRSTST_OFFSET 0x0004 +#define DRA7XX_RM_L3INIT_PCIESS_RSTCTRL_OFFSET 0x0010 #define DRA7XX_PM_L3INIT_MMC1_WKDEP_OFFSET 0x0028 #define DRA7XX_RM_L3INIT_MMC1_CONTEXT_OFFSET 0x002c #define DRA7XX_PM_L3INIT_MMC2_WKDEP_OFFSET 0x0030 diff --git a/arch/arm/mach-omap2/soc.h b/arch/arm/mach-omap2/soc.h index 79ca3c3eb2afe86c6250f5a7be74b6aef694d3cf..70df8f6cddccbf1ad7b8372eb847c2a2bdfc755c 100644 --- a/arch/arm/mach-omap2/soc.h +++ b/arch/arm/mach-omap2/soc.h @@ -181,6 +181,14 @@ static inline int is_ti ##class (void) \ return (GET_TI_CLASS == (id)) ? 1 : 0; \ } +#define GET_DRA_CLASS ((omap_rev() >> 24) & 0xff) + +#define IS_DRA_CLASS(class, id) \ +static inline int is_dra ##class (void) \ +{ \ + return (GET_DRA_CLASS == (id)) ? 1 : 0; \ +} + #define GET_OMAP_SUBCLASS ((omap_rev() >> 20) & 0x0fff) #define IS_OMAP_SUBCLASS(subclass, id) \ @@ -201,6 +209,12 @@ static inline int is_am ##subclass (void) \ return (GET_OMAP_SUBCLASS == (id)) ? 1 : 0; \ } +#define IS_DRA_SUBCLASS(subclass, id) \ +static inline int is_dra ##subclass (void) \ +{ \ + return (GET_OMAP_SUBCLASS == (id)) ? 1 : 0; \ +} + IS_OMAP_CLASS(24xx, 0x24) IS_OMAP_CLASS(34xx, 0x34) IS_OMAP_CLASS(44xx, 0x44) @@ -210,6 +224,7 @@ IS_AM_CLASS(33xx, 0x33) IS_AM_CLASS(43xx, 0x43) IS_TI_CLASS(81xx, 0x81) +IS_DRA_CLASS(7xx, 0x7) IS_OMAP_SUBCLASS(242x, 0x242) IS_OMAP_SUBCLASS(243x, 0x243) @@ -224,6 +239,8 @@ IS_TI_SUBCLASS(816x, 0x816) IS_TI_SUBCLASS(814x, 0x814) IS_AM_SUBCLASS(335x, 0x335) IS_AM_SUBCLASS(437x, 0x437) +IS_DRA_SUBCLASS(75x, 0x75) +IS_DRA_SUBCLASS(72x, 0x72) #define soc_is_omap24xx() 0 #define soc_is_omap242x() 0 @@ -397,9 +414,9 @@ IS_OMAP_TYPE(3430, 0x3430) #undef soc_is_dra7xx #undef soc_is_dra74x #undef soc_is_dra72x -#define soc_is_dra7xx() (of_machine_is_compatible("ti,dra7")) -#define soc_is_dra74x() (of_machine_is_compatible("ti,dra74")) -#define soc_is_dra72x() (of_machine_is_compatible("ti,dra72")) +#define soc_is_dra7xx() is_dra7xx() +#define soc_is_dra74x() is_dra75x() +#define soc_is_dra72x() is_dra72x() #endif /* Various silicon revisions for omap2 */ diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig index a9ad95f000a15cbad7e09710c42de0152ca27c59..a2af15822fcb85d6e9a16d0e2d9455c7df0c5dd0 100644 --- a/arch/arm/mach-orion5x/Kconfig +++ b/arch/arm/mach-orion5x/Kconfig @@ -28,14 +28,14 @@ config ARCH_ORION5X_DT config MACH_DB88F5281 bool "Marvell Orion-2 Development Board" - select I2C_BOARDINFO + select I2C_BOARDINFO if I2C help Say 'Y' here if you want your kernel to support the Marvell Orion-2 (88F5281) Development Board config MACH_RD88F5182 bool "Marvell Orion-NAS Reference Design" - select I2C_BOARDINFO + select I2C_BOARDINFO if I2C help Say 'Y' here if you want your kernel to support the Marvell Orion-NAS (88F5182) RD2 @@ -43,14 +43,14 @@ config MACH_RD88F5182 config MACH_RD88F5182_DT bool "Marvell Orion-NAS Reference Design (Flattened Device Tree)" select ARCH_ORION5X_DT - select I2C_BOARDINFO + select I2C_BOARDINFO if I2C help Say 'Y' here if you want your kernel to support the Marvell Orion-NAS (88F5182) RD2, Flattened Device Tree. config MACH_KUROBOX_PRO bool "KuroBox Pro" - select I2C_BOARDINFO + select I2C_BOARDINFO if I2C help Say 'Y' here if you want your kernel to support the KuroBox Pro platform. @@ -58,7 +58,7 @@ config MACH_KUROBOX_PRO config MACH_DNS323 bool "D-Link DNS-323" select GENERIC_NET_UTILS - select I2C_BOARDINFO + select I2C_BOARDINFO if I2C help Say 'Y' here if you want your kernel to support the D-Link DNS-323 platform. @@ -78,7 +78,7 @@ config MACH_TERASTATION_PRO2 config MACH_LINKSTATION_PRO bool "Buffalo Linkstation Pro/Live" - select I2C_BOARDINFO + select I2C_BOARDINFO if I2C help Say 'Y' here if you want your kernel to support the Buffalo Linkstation Pro/Live platform. Both v1 and @@ -86,7 +86,7 @@ config MACH_LINKSTATION_PRO config MACH_LINKSTATION_LSCHL bool "Buffalo Linkstation Live v3 (LS-CHL)" - select I2C_BOARDINFO + select I2C_BOARDINFO if I2C help Say 'Y' here if you want your kernel to support the Buffalo Linkstation Live v3 (LS-CHL) platform. @@ -100,7 +100,7 @@ config MACH_LINKSTATION_MINI config MACH_LINKSTATION_LS_HGL bool "Buffalo Linkstation LS-HGL" - select I2C_BOARDINFO + select I2C_BOARDINFO if I2C help Say 'Y' here if you want your kernel to support the Buffalo Linkstation LS-HGL platform. @@ -139,7 +139,7 @@ config MACH_D2NET_DT config MACH_NET2BIG bool "LaCie 2Big Network" - select I2C_BOARDINFO + select I2C_BOARDINFO if I2C help Say 'Y' here if you want your kernel to support the LaCie 2Big Network NAS. diff --git a/arch/arm/mach-orion5x/Makefile.boot b/arch/arm/mach-orion5x/Makefile.boot deleted file mode 100644 index 760a0efe7580b0dd194ff9bfe4295624336bb806..0000000000000000000000000000000000000000 --- a/arch/arm/mach-orion5x/Makefile.boot +++ /dev/null @@ -1,3 +0,0 @@ - zreladdr-y += 0x00008000 -params_phys-y := 0x00000100 -initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-prima2/Kconfig b/arch/arm/mach-prima2/Kconfig index f998eb1c698ec69bb18735c60ce4660f680db272..0cf4426183cff99718d63975dfcb01453b45f56b 100644 --- a/arch/arm/mach-prima2/Kconfig +++ b/arch/arm/mach-prima2/Kconfig @@ -2,6 +2,7 @@ menuconfig ARCH_SIRF bool "CSR SiRF" depends on ARCH_MULTI_V7 select ARCH_HAS_RESET_CONTROLLER + select RESET_CONTROLLER select ARCH_REQUIRE_GPIOLIB select GENERIC_IRQ_CHIP select NO_IOPORT_MAP diff --git a/arch/arm/mach-prima2/Makefile.boot b/arch/arm/mach-prima2/Makefile.boot deleted file mode 100644 index c77a4883a4eeb104578c9fb61290ebeb698a5de2..0000000000000000000000000000000000000000 --- a/arch/arm/mach-prima2/Makefile.boot +++ /dev/null @@ -1,3 +0,0 @@ -zreladdr-y += 0x00008000 -params_phys-y := 0x00000100 -initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index f096836879634fb87897574a1476e26a196fb349..7ee4652b4c61d9a3a921d52de13d3e46dd356d78 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -297,7 +297,6 @@ config MACH_MAGICIAN config MACH_MIOA701 bool "Mitac Mio A701 Support" - select GPIO_SYSFS select IWMMXT select PXA27x help @@ -529,7 +528,7 @@ config MACH_TOSA config TOSA_BT tristate "Control the state of built-in bluetooth chip on Sharp SL-6000" - depends on MACH_TOSA + depends on MACH_TOSA && NET select RFKILL help This is a simple driver that is able to control diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c index 37d8d85662f0f2c1db663c33eb8ce3b97ddb6ed4..913a319c7b005b0d1c5832ed57e2a1185b182543 100644 --- a/arch/arm/mach-pxa/devices.c +++ b/arch/arm/mach-pxa/devices.c @@ -1203,6 +1203,7 @@ void __init pxa2xx_set_spi_info(unsigned id, struct pxa2xx_spi_master *info) static struct mmp_dma_platdata pxa_dma_pdata = { .dma_channels = 0, + .nb_requestors = 0, }; static struct resource pxa_dma_resource[] = { @@ -1231,7 +1232,7 @@ static struct platform_device pxa2xx_pxa_dma = { .resource = pxa_dma_resource, }; -void __init pxa2xx_set_dmac_info(int nb_channels) +void __init pxa2xx_set_dmac_info(int nb_channels, int nb_requestors) { pxa_dma_pdata.dma_channels = nb_channels; pxa_register_device(&pxa2xx_pxa_dma, &pxa_dma_pdata); diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c index 0b00b226f54bc3eb7c343b05b133c3a4e08072ce..e838b11fb8c7d3992f88d247522064a83e2ea08f 100644 --- a/arch/arm/mach-pxa/eseries.c +++ b/arch/arm/mach-pxa/eseries.c @@ -57,7 +57,7 @@ struct gpio_vbus_mach_info e7xx_udc_info = { .gpio_pullup_inverted = 1 }; -static struct platform_device e7xx_gpio_vbus = { +static struct platform_device e7xx_gpio_vbus __maybe_unused = { .name = "gpio-vbus", .id = -1, .dev = { @@ -126,7 +126,7 @@ struct resource eseries_tmio_resources[] = { }; /* Some e-series hardware cannot control the 32K clock */ -static void __init eseries_register_clks(void) +static void __init __maybe_unused eseries_register_clks(void) { clk_register_fixed_rate(NULL, "CLK_CK32K", NULL, CLK_IS_ROOT, 32768); } diff --git a/arch/arm/mach-pxa/gumstix.c b/arch/arm/mach-pxa/gumstix.c index 6815a9357774eb445f6d24bd2640dc342d4e4dec..9c5b2fb054f96f1ff527079623597b9325d0bf1a 100644 --- a/arch/arm/mach-pxa/gumstix.c +++ b/arch/arm/mach-pxa/gumstix.c @@ -139,14 +139,14 @@ static void gumstix_setup_bt_clock(void) { int timeout = 500; - if (!(OSCC & OSCC_OOK)) + if (!(readl(OSCC) & OSCC_OOK)) pr_warn("32kHz clock was not on. Bootloader may need to be updated\n"); else return; - OSCC |= OSCC_OON; + writel(readl(OSCC) | OSCC_OON, OSCC); do { - if (OSCC & OSCC_OOK) + if (readl(OSCC) & OSCC_OOK) break; udelay(1); } while (--timeout); diff --git a/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h b/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h index f1dd62946b3699f6f25b7dd2683d98de9df141a1..5537d5601d7052ad12ead23b7b8a37c854485295 100644 --- a/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h +++ b/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h @@ -134,10 +134,10 @@ /* * PXA2xx specific Core clock definitions */ -#define CCCR __REG(0x41300000) /* Core Clock Configuration Register */ -#define CCSR __REG(0x4130000C) /* Core Clock Status Register */ -#define CKEN __REG(0x41300004) /* Clock Enable Register */ -#define OSCC __REG(0x41300008) /* Oscillator Configuration Register */ +#define CCCR io_p2v(0x41300000) /* Core Clock Configuration Register */ +#define CCSR io_p2v(0x4130000C) /* Core Clock Status Register */ +#define CKEN io_p2v(0x41300004) /* Clock Enable Register */ +#define OSCC io_p2v(0x41300008) /* Oscillator Configuration Register */ #define CCCR_N_MASK 0x0380 /* Run Mode Frequency to Turbo Mode Frequency Multiplier */ #define CCCR_M_MASK 0x0060 /* Memory Frequency to Run Mode Frequency Multiplier */ diff --git a/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h b/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h index f4d48d20754ea201d7d998740a04e843638f82b6..888bf7ade15acc7f6989b025a92b836a85c18ba4 100644 --- a/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h +++ b/arch/arm/mach-pxa/include/mach/pxa3xx-regs.h @@ -18,7 +18,7 @@ /* * Oscillator Configuration Register (OSCC) */ -#define OSCC __REG(0x41350000) /* Oscillator Configuration Register */ +#define OSCC io_p2v(0x41350000) /* Oscillator Configuration Register */ #define OSCC_PEN (1 << 11) /* 13MHz POUT */ diff --git a/arch/arm/mach-pxa/pm.h b/arch/arm/mach-pxa/pm.h index 51558bcee999e949e32500e661b0a016a34da283..3aab90d8d2b72d6682688c898e7fe555eb9ac33b 100644 --- a/arch/arm/mach-pxa/pm.h +++ b/arch/arm/mach-pxa/pm.h @@ -29,6 +29,9 @@ extern int pxa_pm_enter(suspend_state_t state); extern int pxa_pm_prepare(void); extern void pxa_pm_finish(void); +extern const char pm_enter_standby_start[], pm_enter_standby_end[]; +extern int pxa3xx_finish_suspend(unsigned long); + /* NOTE: this is for PM debugging on Lubbock, it's really a big * ugly, but let's keep the crap minimum here, instead of direct * accessing the LUBBOCK CPLD registers in arch/arm/mach-pxa/pm.c diff --git a/arch/arm/mach-pxa/pxa-dt.c b/arch/arm/mach-pxa/pxa-dt.c index 8e0e62ccdcedf45c3e17e73ffb927aaa9e6d4955..f128133a8f309f303ee20df75a45d292936bfa93 100644 --- a/arch/arm/mach-pxa/pxa-dt.c +++ b/arch/arm/mach-pxa/pxa-dt.c @@ -19,42 +19,18 @@ #include "generic.h" #ifdef CONFIG_PXA3xx -static const struct of_dev_auxdata const pxa3xx_auxdata_lookup[] __initconst = { - OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40100000, "pxa2xx-uart.0", NULL), - OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40200000, "pxa2xx-uart.1", NULL), - OF_DEV_AUXDATA("mrvl,pxa-uart", 0x40700000, "pxa2xx-uart.2", NULL), - OF_DEV_AUXDATA("mrvl,pxa-uart", 0x41600000, "pxa2xx-uart.3", NULL), - OF_DEV_AUXDATA("marvell,pxa-mmc", 0x41100000, "pxa2xx-mci.0", NULL), - OF_DEV_AUXDATA("intel,pxa3xx-gpio", 0x40e00000, "pxa3xx-gpio", NULL), - OF_DEV_AUXDATA("marvell,pxa-ohci", 0x4c000000, "pxa27x-ohci", NULL), - OF_DEV_AUXDATA("mrvl,pxa-i2c", 0x40301680, "pxa2xx-i2c.0", NULL), - OF_DEV_AUXDATA("mrvl,pwri2c", 0x40f500c0, "pxa3xx-i2c.1", NULL), - OF_DEV_AUXDATA("marvell,pxa3xx-nand", 0x43100000, "pxa3xx-nand", NULL), - {} -}; - -static void __init pxa3xx_dt_init(void) -{ - of_platform_populate(NULL, of_default_bus_match_table, - pxa3xx_auxdata_lookup, NULL); -} - static const char *const pxa3xx_dt_board_compat[] __initconst = { "marvell,pxa300", "marvell,pxa310", "marvell,pxa320", NULL, }; -#endif -#ifdef CONFIG_PXA3xx DT_MACHINE_START(PXA_DT, "Marvell PXA3xx (Device Tree Support)") .map_io = pxa3xx_map_io, .init_irq = pxa3xx_dt_init_irq, .handle_irq = pxa3xx_handle_irq, - .init_time = pxa_timer_init, .restart = pxa_restart, - .init_machine = pxa3xx_dt_init, .dt_compat = pxa3xx_dt_board_compat, MACHINE_END #endif diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index a177bf45feefa0a80be5c96a2b228ae2bfaead37..823504f48f806525d6e42b68e26010c378035470 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -206,7 +206,7 @@ static int __init pxa25x_init(void) register_syscore_ops(&pxa_irq_syscore_ops); register_syscore_ops(&pxa2xx_mfp_syscore_ops); - pxa2xx_set_dmac_info(16); + pxa2xx_set_dmac_info(16, 40); pxa_register_device(&pxa25x_device_gpio, &pxa25x_gpio_info); ret = platform_add_devices(pxa25x_devices, ARRAY_SIZE(pxa25x_devices)); diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 8dfd1755c6594894a580163413c01b2407d2816c..2eaa341dd3f82aa4b61cc7aad67a3051c82e1fc9 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -132,7 +132,8 @@ void pxa27x_cpu_pm_enter(suspend_state_t state) #ifndef CONFIG_IWMMXT u64 acc0; - asm volatile("mra %Q0, %R0, acc0" : "=r" (acc0)); + asm volatile(".arch_extension xscale\n\t" + "mra %Q0, %R0, acc0" : "=r" (acc0)); #endif /* ensure voltage-change sequencer not initiated, which hangs */ @@ -151,7 +152,8 @@ void pxa27x_cpu_pm_enter(suspend_state_t state) case PM_SUSPEND_MEM: cpu_suspend(pwrmode, pxa27x_finish_suspend); #ifndef CONFIG_IWMMXT - asm volatile("mar acc0, %Q0, %R0" : "=r" (acc0)); + asm volatile(".arch_extension xscale\n\t" + "mar acc0, %Q0, %R0" : "=r" (acc0)); #endif break; } @@ -309,7 +311,7 @@ static int __init pxa27x_init(void) if (!of_have_populated_dt()) { pxa_register_device(&pxa27x_device_gpio, &pxa27x_gpio_info); - pxa2xx_set_dmac_info(32); + pxa2xx_set_dmac_info(32, 75); ret = platform_add_devices(devices, ARRAY_SIZE(devices)); } diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index a1c4c888f246e0bc1cfc7ee8c8ff2bdb1f7758a4..3c9184d1d6b9b7ebee86157db11fe390771b950a 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -68,7 +68,6 @@ static unsigned long wakeup_src; */ static void pxa3xx_cpu_standby(unsigned int pwrmode) { - extern const char pm_enter_standby_start[], pm_enter_standby_end[]; void (*fn)(unsigned int) = (void __force *)(sram + 0x8000); memcpy_toio(sram + 0x8000, pm_enter_standby_start, @@ -103,11 +102,10 @@ static void pxa3xx_cpu_pm_suspend(void) #ifndef CONFIG_IWMMXT u64 acc0; - asm volatile("mra %Q0, %R0, acc0" : "=r" (acc0)); + asm volatile(".arch_extension xscale\n\t" + "mra %Q0, %R0, acc0" : "=r" (acc0)); #endif - extern int pxa3xx_finish_suspend(unsigned long); - /* resuming from D2 requires the HSIO2/BOOT/TPM clocks enabled */ CKENA |= (1 << CKEN_BOOT) | (1 << CKEN_TPM); CKENB |= 1 << (CKEN_HSIO2 & 0x1f); @@ -133,7 +131,8 @@ static void pxa3xx_cpu_pm_suspend(void) AD3ER = 0; #ifndef CONFIG_IWMMXT - asm volatile("mar acc0, %Q0, %R0" : "=r" (acc0)); + asm volatile(".arch_extension xscale\n\t" + "mar acc0, %Q0, %R0" : "=r" (acc0)); #endif } @@ -450,7 +449,7 @@ static int __init pxa3xx_init(void) if (of_have_populated_dt()) return 0; - pxa2xx_set_dmac_info(32); + pxa2xx_set_dmac_info(32, 100); ret = platform_add_devices(devices, ARRAY_SIZE(devices)); if (ret) return ret; diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c index 8347d87a713d858fddae79cd5fce9136112dcd12..5a941bd3dbed8ebd32c11e35ec365c5a4e58b478 100644 --- a/arch/arm/mach-pxa/raumfeld.c +++ b/arch/arm/mach-pxa/raumfeld.c @@ -18,12 +18,13 @@ #include #include +#include #include #include #include +#include #include #include -#include #include #include #include @@ -366,22 +367,31 @@ static struct pxaohci_platform_data raumfeld_ohci_info = { * Rotary encoder input device */ -static struct rotary_encoder_platform_data raumfeld_rotary_encoder_info = { - .steps = 24, - .axis = REL_X, - .relative_axis = 1, - .gpio_a = GPIO_VOLENC_A, - .gpio_b = GPIO_VOLENC_B, - .inverted_a = 1, - .inverted_b = 0, +static struct gpiod_lookup_table raumfeld_rotary_gpios_table = { + .dev_id = "rotary-encoder.0", + .table = { + GPIO_LOOKUP_IDX("gpio-0", + GPIO_VOLENC_A, NULL, 0, GPIO_ACTIVE_LOW), + GPIO_LOOKUP_IDX("gpio-0", + GPIO_VOLENC_B, NULL, 1, GPIO_ACTIVE_HIGH), + { }, + }, +}; + +static struct property_entry raumfeld_rotary_properties[] = { + PROPERTY_ENTRY_INTEGER("rotary-encoder,steps-per-period", u32, 24), + PROPERTY_ENTRY_INTEGER("linux,axis", u32, REL_X), + PROPERTY_ENTRY_INTEGER("rotary-encoder,relative_axis", u32, 1), + { }, +}; + +static struct property_set raumfeld_rotary_property_set = { + .properties = raumfeld_rotary_properties, }; static struct platform_device rotary_encoder_device = { .name = "rotary-encoder", .id = 0, - .dev = { - .platform_data = &raumfeld_rotary_encoder_info, - } }; /** @@ -1051,7 +1061,12 @@ static void __init __maybe_unused raumfeld_controller_init(void) int ret; pxa3xx_mfp_config(ARRAY_AND_SIZE(raumfeld_controller_pin_config)); + + gpiod_add_lookup_table(&raumfeld_rotary_gpios_table); + device_add_property_set(&rotary_encoder_device.dev, + &raumfeld_rotary_property_set); platform_device_register(&rotary_encoder_device); + spi_register_board_info(ARRAY_AND_SIZE(controller_spi_devices)); i2c_register_board_info(0, &raumfeld_controller_i2c_board_info, 1); @@ -1086,6 +1101,10 @@ static void __init __maybe_unused raumfeld_speaker_init(void) i2c_register_board_info(0, &raumfeld_connector_i2c_board_info, 1); platform_device_register(&smc91x_device); + + gpiod_add_lookup_table(&raumfeld_rotary_gpios_table); + device_add_property_set(&rotary_encoder_device.dev, + &raumfeld_rotary_property_set); platform_device_register(&rotary_encoder_device); raumfeld_audio_init(); diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index 825f903ab77eb462ef3d8153da4292e9dbe55e9c..d9578bc49fdc61766c430e55e1ab21857a6ebf03 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -201,7 +201,7 @@ static void __init spitz_scoop_init(void) } /* Power control is shared with between one of the CF slots and SD */ -static void spitz_card_pwr_ctrl(uint8_t enable, uint8_t new_cpr) +static void __maybe_unused spitz_card_pwr_ctrl(uint8_t enable, uint8_t new_cpr) { unsigned short cpr; unsigned long flags; diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c index 515b7ddda8aaa86f0cb85aaa49861c4680fe3de3..3b94ecfb942657b3c93337cb745c737e37046081 100644 --- a/arch/arm/mach-pxa/zeus.c +++ b/arch/arm/mach-pxa/zeus.c @@ -910,7 +910,7 @@ static void __init zeus_map_io(void) PMCR = PSPR = 0; /* enable internal 32.768Khz oscillator (ignore OSCC_OOK) */ - OSCC |= OSCC_OON; + writel(readl(OSCC) | OSCC_OON, OSCC); /* Some clock cycles later (from OSCC_ON), programme PCFR (OPDE...). * float chip selects and PCMCIA */ diff --git a/arch/arm/mach-realview/Makefile.boot b/arch/arm/mach-realview/Makefile.boot deleted file mode 100644 index d2c3d788f6880b3e765bb44574f4ceb8177bbb4c..0000000000000000000000000000000000000000 --- a/arch/arm/mach-realview/Makefile.boot +++ /dev/null @@ -1,9 +0,0 @@ -ifeq ($(CONFIG_REALVIEW_HIGH_PHYS_OFFSET),y) - zreladdr-y += 0x70008000 -params_phys-y := 0x70000100 -initrd_phys-y := 0x70800000 -else - zreladdr-y += 0x00008000 -params_phys-y := 0x00000100 -initrd_phys-y := 0x00800000 -endif diff --git a/arch/arm/mach-rpc/include/mach/uncompress.h b/arch/arm/mach-rpc/include/mach/uncompress.h index 0fd4b0b8ef22ea91b2990588a5158bc226e0f170..654a6f3f2547d25bebeb628ab603c3d1cec4de68 100644 --- a/arch/arm/mach-rpc/include/mach/uncompress.h +++ b/arch/arm/mach-rpc/include/mach/uncompress.h @@ -76,7 +76,7 @@ int white; /* * This does not append a newline */ -static void putc(int c) +static inline void putc(int c) { extern void ll_write_char(char *, char c, char white); int x,y; diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig index ef68ecb273964f7c237078752b555d326aa08056..b91aee406c74c079bc69353a7d533e22a0ee7554 100644 --- a/arch/arm/mach-s3c24xx/Kconfig +++ b/arch/arm/mach-s3c24xx/Kconfig @@ -15,6 +15,7 @@ config PLAT_S3C24XX select NO_IOPORT_MAP select S3C_DEV_NAND select IRQ_DOMAIN + select COMMON_CLK help Base platform code for any Samsung S3C24XX device @@ -405,7 +406,7 @@ config MACH_S3C2416_DT endif # CPU_S3C2416 -if CPU_S3C2440 +if CPU_S3C2440 || CPU_S3C2442 config S3C2440_XTAL_12000000 bool @@ -432,6 +433,9 @@ config S3C2440_PLL_16934400 default y if S3C24XX_PLL help PLL tables for S3C2440 or S3C2442 CPUs with 16.934MHz crystals. +endif + +if CPU_S3C2440 comment "S3C2440 Boards" @@ -460,7 +464,6 @@ config MACH_AT2440EVB config MACH_MINI2440 bool "MINI2440 development board" - select EEPROM_AT24 if I2C select LEDS_CLASS select LEDS_TRIGGERS select LEDS_TRIGGER_BACKLIGHT diff --git a/arch/arm/mach-s3c24xx/include/mach/io.h b/arch/arm/mach-s3c24xx/include/mach/io.h index 5dd1db4e267724275d90913d74246d6da122d2bc..235c53647aa49929d13779ca4c8320be75085eef 100644 --- a/arch/arm/mach-s3c24xx/include/mach/io.h +++ b/arch/arm/mach-s3c24xx/include/mach/io.h @@ -190,7 +190,7 @@ DECLARE_IO(int,l,"") result; \ }) -#define __ioaddrc(port) ((__PORT_PCIO(port) ? PCIO_BASE + (port) : (void __iomem *)(port))) +#define __ioaddrc(port) ((__PORT_PCIO(port) ? PCIO_BASE + (port) : (void __iomem *)0 + (port))) #define inb(p) (__builtin_constant_p((p)) ? __inbc(p) : __inb(p)) #define inw(p) (__builtin_constant_p((p)) ? __inwc(p) : __inw(p)) diff --git a/arch/arm/mach-s3c24xx/include/mach/map.h b/arch/arm/mach-s3c24xx/include/mach/map.h index 444793f0f5f1bb8eef5a0edab795e01eac057b78..adc39043aa218f1ddcff4496c0775a22033cabdf 100644 --- a/arch/arm/mach-s3c24xx/include/mach/map.h +++ b/arch/arm/mach-s3c24xx/include/mach/map.h @@ -14,13 +14,6 @@ #define __ASM_ARCH_MAP_H #include - -/* - * S3C2410 UART offset is 0x4000 but the other SoCs are 0x400. - * So need to define it, and here is to avoid redefinition warning. - */ -#define S3C_UART_OFFSET (0x4000) - #include /* @@ -34,9 +27,6 @@ #define S3C2410_PA_MEMCTRL (0x48000000) #define S3C24XX_SZ_MEMCTRL SZ_1M -/* UARTs */ -#define S3C_VA_UARTx(uart) (S3C_VA_UART + ((uart * S3C_UART_OFFSET))) - /* Timers */ #define S3C2410_PA_TIMER (0x51000000) #define S3C24XX_SZ_TIMER SZ_1M @@ -157,7 +147,6 @@ #define S3C_PA_FB S3C2443_PA_FB #define S3C_PA_IIC S3C2410_PA_IIC -#define S3C_PA_UART S3C24XX_PA_UART #define S3C_PA_USBHOST S3C2410_PA_USBHOST #define S3C_PA_HSMMC0 S3C2416_PA_HSMMC0 #define S3C_PA_HSMMC1 S3C2443_PA_HSMMC diff --git a/arch/arm/mach-s3c24xx/mach-gta02.c b/arch/arm/mach-s3c24xx/mach-gta02.c index 6d1e0b9c5b27cc0ece0eb3f61a69111d62dec931..27ae6877550f7b8972c288ee32fa43a7e9a3a07c 100644 --- a/arch/arm/mach-s3c24xx/mach-gta02.c +++ b/arch/arm/mach-s3c24xx/mach-gta02.c @@ -154,6 +154,7 @@ static struct s3c2410_uartcfg gta02_uartcfgs[] = { #define ADC_NOM_CHG_DETECT_1A 6 #define ADC_NOM_CHG_DETECT_USB 43 +#ifdef CONFIG_PCF50633_ADC static void gta02_configure_pmu_for_charger(struct pcf50633 *pcf, void *unused, int res) { @@ -174,6 +175,7 @@ gta02_configure_pmu_for_charger(struct pcf50633 *pcf, void *unused, int res) pcf50633_mbc_usb_curlim_set(pcf, ma); } +#endif static struct delayed_work gta02_charger_work; static int gta02_usb_vbus_draw; diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig index 7c0c420c3016acfb7dcaa74947da675ba3a1f0a7..e5c1888fc67bbfdc461c7c689f76ccf204043b25 100644 --- a/arch/arm/mach-s3c64xx/Kconfig +++ b/arch/arm/mach-s3c64xx/Kconfig @@ -3,7 +3,8 @@ # # Licensed under GPLv2 menuconfig ARCH_S3C64XX - bool "Samsung S3C64XX" if ARCH_MULTI_V6 + bool "Samsung S3C64XX" + depends on ARCH_MULTI_V6 select ARCH_REQUIRE_GPIOLIB select ARM_AMBA select ARM_VIC diff --git a/arch/arm/mach-s3c64xx/Makefile.boot b/arch/arm/mach-s3c64xx/Makefile.boot deleted file mode 100644 index c642333af3ed3358fd6f2e1f88e93589bd52edc4..0000000000000000000000000000000000000000 --- a/arch/arm/mach-s3c64xx/Makefile.boot +++ /dev/null @@ -1,2 +0,0 @@ - zreladdr-y += 0x50008000 -params_phys-y := 0x50000100 diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c index 8a894ee3ee76db63a6d06689a10174f771c26486..92ec8c3b42b9b2eb00705fbc8005b7403f64a2ec 100644 --- a/arch/arm/mach-s3c64xx/mach-smdk6410.c +++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c @@ -216,7 +216,7 @@ static struct regulator_consumer_supply smdk6410_b_pwr_5v_consumers[] = { REGULATOR_SUPPLY("AVDD", "0-001b"), }; -static struct regulator_init_data smdk6410_b_pwr_5v_data = { +static struct regulator_init_data __maybe_unused smdk6410_b_pwr_5v_data = { .constraints = { .always_on = 1, }, @@ -300,7 +300,7 @@ static struct regulator_consumer_supply smdk6410_vddarm_consumers[] = { }; /* VDDARM, BUCK1 on J5 */ -static struct regulator_init_data smdk6410_vddarm = { +static struct regulator_init_data __maybe_unused smdk6410_vddarm = { .constraints = { .name = "PVDD_ARM", .min_uV = 1000000, @@ -313,7 +313,7 @@ static struct regulator_init_data smdk6410_vddarm = { }; /* VDD_INT, BUCK2 on J5 */ -static struct regulator_init_data smdk6410_vddint = { +static struct regulator_init_data __maybe_unused smdk6410_vddint = { .constraints = { .name = "PVDD_INT", .min_uV = 1000000, @@ -324,7 +324,7 @@ static struct regulator_init_data smdk6410_vddint = { }; /* VDD_HI, LDO3 on J5 */ -static struct regulator_init_data smdk6410_vddhi = { +static struct regulator_init_data __maybe_unused smdk6410_vddhi = { .constraints = { .name = "PVDD_HI", .always_on = 1, @@ -332,7 +332,7 @@ static struct regulator_init_data smdk6410_vddhi = { }; /* VDD_PLL, LDO2 on J5 */ -static struct regulator_init_data smdk6410_vddpll = { +static struct regulator_init_data __maybe_unused smdk6410_vddpll = { .constraints = { .name = "PVDD_PLL", .always_on = 1, @@ -340,7 +340,7 @@ static struct regulator_init_data smdk6410_vddpll = { }; /* VDD_UH_MMC, LDO5 on J5 */ -static struct regulator_init_data smdk6410_vdduh_mmc = { +static struct regulator_init_data __maybe_unused smdk6410_vdduh_mmc = { .constraints = { .name = "PVDD_UH+PVDD_MMC", .always_on = 1, @@ -348,7 +348,7 @@ static struct regulator_init_data smdk6410_vdduh_mmc = { }; /* VCCM3BT, LDO8 on J5 */ -static struct regulator_init_data smdk6410_vccmc3bt = { +static struct regulator_init_data __maybe_unused smdk6410_vccmc3bt = { .constraints = { .name = "PVCCM3BT", .always_on = 1, @@ -356,7 +356,7 @@ static struct regulator_init_data smdk6410_vccmc3bt = { }; /* VCCM2MTV, LDO11 on J5 */ -static struct regulator_init_data smdk6410_vccm2mtv = { +static struct regulator_init_data __maybe_unused smdk6410_vccm2mtv = { .constraints = { .name = "PVCCM2MTV", .always_on = 1, @@ -364,7 +364,7 @@ static struct regulator_init_data smdk6410_vccm2mtv = { }; /* VDD_LCD, LDO12 on J5 */ -static struct regulator_init_data smdk6410_vddlcd = { +static struct regulator_init_data __maybe_unused smdk6410_vddlcd = { .constraints = { .name = "PVDD_LCD", .always_on = 1, @@ -372,7 +372,7 @@ static struct regulator_init_data smdk6410_vddlcd = { }; /* VDD_OTGI, LDO9 on J5 */ -static struct regulator_init_data smdk6410_vddotgi = { +static struct regulator_init_data __maybe_unused smdk6410_vddotgi = { .constraints = { .name = "PVDD_OTGI", .always_on = 1, @@ -380,7 +380,7 @@ static struct regulator_init_data smdk6410_vddotgi = { }; /* VDD_OTG, LDO14 on J5 */ -static struct regulator_init_data smdk6410_vddotg = { +static struct regulator_init_data __maybe_unused smdk6410_vddotg = { .constraints = { .name = "PVDD_OTG", .always_on = 1, @@ -388,7 +388,7 @@ static struct regulator_init_data smdk6410_vddotg = { }; /* VDD_ALIVE, LDO15 on J5 */ -static struct regulator_init_data smdk6410_vddalive = { +static struct regulator_init_data __maybe_unused smdk6410_vddalive = { .constraints = { .name = "PVDD_ALIVE", .always_on = 1, @@ -396,7 +396,7 @@ static struct regulator_init_data smdk6410_vddalive = { }; /* VDD_AUDIO, VLDO_AUDIO on J5 */ -static struct regulator_init_data smdk6410_vddaudio = { +static struct regulator_init_data __maybe_unused smdk6410_vddaudio = { .constraints = { .name = "PVDD_AUDIO", .always_on = 1, @@ -406,7 +406,7 @@ static struct regulator_init_data smdk6410_vddaudio = { #ifdef CONFIG_SMDK6410_WM1190_EV1 /* S3C64xx internal logic & PLL */ -static struct regulator_init_data wm8350_dcdc1_data = { +static struct regulator_init_data __maybe_unused wm8350_dcdc1_data = { .constraints = { .name = "PVDD_INT+PVDD_PLL", .min_uV = 1200000, @@ -417,7 +417,7 @@ static struct regulator_init_data wm8350_dcdc1_data = { }; /* Memory */ -static struct regulator_init_data wm8350_dcdc3_data = { +static struct regulator_init_data __maybe_unused wm8350_dcdc3_data = { .constraints = { .name = "PVDD_MEM", .min_uV = 1800000, @@ -437,7 +437,7 @@ static struct regulator_consumer_supply wm8350_dcdc4_consumers[] = { REGULATOR_SUPPLY("DVDD", "0-001b"), }; -static struct regulator_init_data wm8350_dcdc4_data = { +static struct regulator_init_data __maybe_unused wm8350_dcdc4_data = { .constraints = { .name = "PVDD_HI+PVDD_EXT+PVDD_SYS+PVCCM2MTV", .min_uV = 3000000, @@ -449,7 +449,7 @@ static struct regulator_init_data wm8350_dcdc4_data = { }; /* OTGi/1190-EV1 HPVDD & AVDD */ -static struct regulator_init_data wm8350_ldo4_data = { +static struct regulator_init_data __maybe_unused wm8350_ldo4_data = { .constraints = { .name = "PVDD_OTGI+HPVDD+AVDD", .min_uV = 1200000, @@ -537,7 +537,7 @@ static struct wm831x_backlight_pdata wm1192_backlight_pdata = { .max_uA = 27554, }; -static struct regulator_init_data wm1192_dcdc3 = { +static struct regulator_init_data __maybe_unused wm1192_dcdc3 = { .constraints = { .name = "PVDD_MEM+PVDD_GPS", .always_on = 1, @@ -548,7 +548,7 @@ static struct regulator_consumer_supply wm1192_ldo1_consumers[] = { REGULATOR_SUPPLY("DVDD", "0-001b"), /* WM8580 */ }; -static struct regulator_init_data wm1192_ldo1 = { +static struct regulator_init_data __maybe_unused wm1192_ldo1 = { .constraints = { .name = "PVDD_LCD+PVDD_EXT", .always_on = 1, diff --git a/arch/arm/mach-sa1100/include/mach/uncompress.h b/arch/arm/mach-sa1100/include/mach/uncompress.h index 73093dc89829989f0cfb97a748632348b0253594..a1a041b9740bc58533b420cfc4ae7446b5a7dab5 100644 --- a/arch/arm/mach-sa1100/include/mach/uncompress.h +++ b/arch/arm/mach-sa1100/include/mach/uncompress.h @@ -19,7 +19,7 @@ #define UART(x) (*(volatile unsigned long *)(serial_port + (x))) -static void putc(int c) +static inline void putc(int c) { unsigned long serial_port; diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index cd5f171f83ce64207977f82ec562b86f913e0356..f2bc5c353119e96de7fad68ff4daf43686e3f851 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig @@ -6,28 +6,30 @@ config ARCH_SHMOBILE_MULTI config PM_RCAR bool - select PM_GENERIC_DOMAINS if PM + select PM + select PM_GENERIC_DOMAINS config PM_RMOBILE bool + select PM select PM_GENERIC_DOMAINS config ARCH_RCAR_GEN1 bool - select PM_RCAR if PM || SMP + select PM_RCAR select RENESAS_INTC_IRQPIN select SYS_SUPPORTS_SH_TMU config ARCH_RCAR_GEN2 bool - select PM_RCAR if PM || SMP + select PM_RCAR select RENESAS_IRQC select SYS_SUPPORTS_SH_CMT select PCI_DOMAINS if PCI config ARCH_RMOBILE bool - select PM_RMOBILE if PM + select PM_RMOBILE select SYS_SUPPORTS_SH_CMT select SYS_SUPPORTS_SH_TMU @@ -55,7 +57,8 @@ config ARCH_EMEV2 config ARCH_R7S72100 bool "RZ/A1H (R7S72100)" - select PM_GENERIC_DOMAINS if PM + select PM + select PM_GENERIC_DOMAINS select SYS_SUPPORTS_SH_MTU2 config ARCH_R8A73A4 @@ -99,6 +102,4 @@ config ARCH_SH73A0 bool "SH-Mobile AG5 (R8A73A00)" select ARCH_RMOBILE select RENESAS_INTC_IRQPIN - -comment "Renesas ARM SoCs System Configuration" endif diff --git a/arch/arm/mach-shmobile/common.h b/arch/arm/mach-shmobile/common.h index b3a4ed5289ec7c8c35661a1b6062d4387d13d097..5464b7a75e3028a792e4718a2cc68b8dd7a1fc0b 100644 --- a/arch/arm/mach-shmobile/common.h +++ b/arch/arm/mach-shmobile/common.h @@ -11,7 +11,8 @@ extern void shmobile_smp_hook(unsigned int cpu, unsigned long fn, unsigned long arg); extern bool shmobile_smp_cpu_can_disable(unsigned int cpu); extern void shmobile_boot_scu(void); -extern void shmobile_smp_scu_prepare_cpus(unsigned int max_cpus); +extern void shmobile_smp_scu_prepare_cpus(phys_addr_t scu_base_phys, + unsigned int max_cpus); extern void shmobile_smp_scu_cpu_die(unsigned int cpu); extern int shmobile_smp_scu_cpu_kill(unsigned int cpu); extern struct platform_suspend_ops shmobile_suspend_ops; @@ -30,8 +31,6 @@ int shmobile_cpufreq_init(void); static inline int shmobile_cpufreq_init(void) { return 0; } #endif -extern void __iomem *shmobile_scu_base; - static inline void __init shmobile_init_late(void) { shmobile_suspend_init(); diff --git a/arch/arm/mach-shmobile/cpufreq.c b/arch/arm/mach-shmobile/cpufreq.c index 57fbff024dcd5dd6ccf23afb94e09d6b0ae47796..634d701c56a7463d9b93b005498362d29e14b777 100644 --- a/arch/arm/mach-shmobile/cpufreq.c +++ b/arch/arm/mach-shmobile/cpufreq.c @@ -10,6 +10,8 @@ #include +#include "common.h" + int __init shmobile_cpufreq_init(void) { platform_device_register_simple("cpufreq-dt", -1, NULL, 0); diff --git a/arch/arm/mach-shmobile/emev2.h b/arch/arm/mach-shmobile/emev2.h new file mode 100644 index 0000000000000000000000000000000000000000..916d25f6780e84a437ab37e9316a151b6a8d2743 --- /dev/null +++ b/arch/arm/mach-shmobile/emev2.h @@ -0,0 +1,6 @@ +#ifndef __ASM_EMEV2_H__ +#define __ASM_EMEV2_H__ + +extern const struct smp_operations emev2_smp_ops; + +#endif /* __ASM_EMEV2_H__ */ diff --git a/arch/arm/mach-shmobile/headsmp-scu.S b/arch/arm/mach-shmobile/headsmp-scu.S index 5e503d91ad70ddf2b8f375ffaf36a09361c9be8c..936d7011c3141b73228c923129f29f3635b0df13 100644 --- a/arch/arm/mach-shmobile/headsmp-scu.S +++ b/arch/arm/mach-shmobile/headsmp-scu.S @@ -27,7 +27,7 @@ */ ENTRY(shmobile_boot_scu) @ r0 = SCU base address - mrc p15, 0, r1, c0, c0, 5 @ read MIPDR + mrc p15, 0, r1, c0, c0, 5 @ read MPIDR and r1, r1, #3 @ mask out cpu ID lsl r1, r1, #3 @ we will shift by cpu_id * 8 bits ldr r2, [r0, #8] @ SCU Power Status Register diff --git a/arch/arm/mach-shmobile/platsmp-scu.c b/arch/arm/mach-shmobile/platsmp-scu.c index 081a097c9219f41785229c9492b95b250151c1f4..8d478f1da265d55e3a81c2bbf1dd1ba5154df7fe 100644 --- a/arch/arm/mach-shmobile/platsmp-scu.c +++ b/arch/arm/mach-shmobile/platsmp-scu.c @@ -18,7 +18,8 @@ #include "common.h" -void __iomem *shmobile_scu_base; +static phys_addr_t shmobile_scu_base_phys; +static void __iomem *shmobile_scu_base; static int shmobile_smp_scu_notifier_call(struct notifier_block *nfb, unsigned long action, void *hcpu) @@ -29,7 +30,7 @@ static int shmobile_smp_scu_notifier_call(struct notifier_block *nfb, case CPU_UP_PREPARE: /* For this particular CPU register SCU SMP boot vector */ shmobile_smp_hook(cpu, virt_to_phys(shmobile_boot_scu), - (unsigned long)shmobile_scu_base); + shmobile_scu_base_phys); break; }; @@ -40,12 +41,15 @@ static struct notifier_block shmobile_smp_scu_notifier = { .notifier_call = shmobile_smp_scu_notifier_call, }; -void __init shmobile_smp_scu_prepare_cpus(unsigned int max_cpus) +void __init shmobile_smp_scu_prepare_cpus(phys_addr_t scu_base_phys, + unsigned int max_cpus) { /* install boot code shared by all CPUs */ shmobile_boot_fn = virt_to_phys(shmobile_smp_boot); /* enable SCU and cache coherency on booting CPU */ + shmobile_scu_base_phys = scu_base_phys; + shmobile_scu_base = ioremap(scu_base_phys, PAGE_SIZE); scu_enable(shmobile_scu_base); scu_power_mode(shmobile_scu_base, SCU_PM_NORMAL); diff --git a/arch/arm/mach-shmobile/pm-rmobile.c b/arch/arm/mach-shmobile/pm-rmobile.c index 46d0a1ddce755e80ffc3f8f1bc6a510287da7906..c0b05e9e644207ddb4bf65993e804f6e121fd297 100644 --- a/arch/arm/mach-shmobile/pm-rmobile.c +++ b/arch/arm/mach-shmobile/pm-rmobile.c @@ -12,7 +12,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. */ -#include +#include #include #include #include diff --git a/arch/arm/mach-shmobile/setup-emev2.c b/arch/arm/mach-shmobile/setup-emev2.c index 10b7cb5dcb3af1e3553761eb5d2f0dbbc33d8bf4..3c99aaf65325cd19860968c24e4cf83703e84970 100644 --- a/arch/arm/mach-shmobile/setup-emev2.c +++ b/arch/arm/mach-shmobile/setup-emev2.c @@ -18,35 +18,17 @@ #include #include #include -#include "common.h" - -static struct map_desc emev2_io_desc[] __initdata = { -#ifdef CONFIG_SMP - /* 2M mapping for SCU + L2 controller */ - { - .virtual = 0xf0000000, - .pfn = __phys_to_pfn(0x1e000000), - .length = SZ_2M, - .type = MT_DEVICE - }, -#endif -}; -static void __init emev2_map_io(void) -{ - iotable_init(emev2_io_desc, ARRAY_SIZE(emev2_io_desc)); -} +#include "common.h" +#include "emev2.h" static const char *const emev2_boards_compat_dt[] __initconst = { "renesas,emev2", NULL, }; -extern const struct smp_operations emev2_smp_ops; - DT_MACHINE_START(EMEV2_DT, "Generic Emma Mobile EV2 (Flattened Device Tree)") .smp = smp_ops(emev2_smp_ops), - .map_io = emev2_map_io, .init_early = shmobile_init_delay, .init_late = shmobile_init_late, .dt_compat = emev2_boards_compat_dt, diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c index 0c8f80c5b04df34d61ed6a195769f3075fef3a56..db6dbfbaf9f10e804618556144034fa34083c7be 100644 --- a/arch/arm/mach-shmobile/setup-r8a7740.c +++ b/arch/arm/mach-shmobile/setup-r8a7740.c @@ -23,41 +23,9 @@ #include #include #include -#include #include "common.h" -static struct map_desc r8a7740_io_desc[] __initdata = { - /* - * for CPGA/INTC/PFC - * 0xe6000000-0xefffffff -> 0xe6000000-0xefffffff - */ - { - .virtual = 0xe6000000, - .pfn = __phys_to_pfn(0xe6000000), - .length = 160 << 20, - .type = MT_DEVICE_NONSHARED - }, -#ifdef CONFIG_CACHE_L2X0 - /* - * for l2x0_init() - * 0xf0100000-0xf0101000 -> 0xf0002000-0xf0003000 - */ - { - .virtual = 0xf0002000, - .pfn = __phys_to_pfn(0xf0100000), - .length = PAGE_SIZE, - .type = MT_DEVICE_NONSHARED - }, -#endif -}; - -static void __init r8a7740_map_io(void) -{ - debug_ll_io_init(); - iotable_init(r8a7740_io_desc, ARRAY_SIZE(r8a7740_io_desc)); -} - /* * r8a7740 chip has lasting errata on MERAM buffer. * this is work-around for it. @@ -110,10 +78,6 @@ static void __init r8a7740_generic_init(void) { r8a7740_meram_workaround(); -#ifdef CONFIG_CACHE_L2X0 - /* Shared attribute override enable, 32K*8way */ - l2x0_init(IOMEM(0xf0002000), 0x00400000, 0xc20f0fff); -#endif of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } @@ -123,7 +87,8 @@ static const char *const r8a7740_boards_compat_dt[] __initconst = { }; DT_MACHINE_START(R8A7740_DT, "Generic R8A7740 (Flattened Device Tree)") - .map_io = r8a7740_map_io, + .l2c_aux_val = 0, + .l2c_aux_mask = ~0, .init_early = shmobile_init_delay, .init_irq = r8a7740_init_irq_of, .init_machine = r8a7740_generic_init, diff --git a/arch/arm/mach-shmobile/setup-r8a7778.c b/arch/arm/mach-shmobile/setup-r8a7778.c index fab95d1271bc7d52b3ccbcc45be010004854abf0..cf236db686a9dd47458f96c7da9e247c1d11f0ea 100644 --- a/arch/arm/mach-shmobile/setup-r8a7778.c +++ b/arch/arm/mach-shmobile/setup-r8a7778.c @@ -15,7 +15,7 @@ * GNU General Public License for more details. */ -#include +#include #include #include diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index 1e572a903f8e470e8864738be0464b3a48b63940..0007ff51d180379ffa2f674323ea9847ed883837 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c @@ -14,7 +14,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ -#include +#include #include #include #include diff --git a/arch/arm/mach-shmobile/setup-rcar-gen2.c b/arch/arm/mach-shmobile/setup-rcar-gen2.c index 9eccde3c7b137151e3fcff5c882cb6bd62870195..1c6fd11c2f824019b4e22f657d7a5d326d38816d 100644 --- a/arch/arm/mach-shmobile/setup-rcar-gen2.c +++ b/arch/arm/mach-shmobile/setup-rcar-gen2.c @@ -15,7 +15,7 @@ * GNU General Public License for more details. */ -#include +#include #include #include #include @@ -182,8 +182,6 @@ static int __init rcar_gen2_scan_mem(unsigned long node, const char *uname, return 0; } -struct cma *rcar_gen2_dma_contiguous; - void __init rcar_gen2_reserve(void) { struct memory_reserve_config mrc; @@ -194,8 +192,11 @@ void __init rcar_gen2_reserve(void) of_scan_flat_dt(rcar_gen2_scan_mem, &mrc); #ifdef CONFIG_DMA_CMA - if (mrc.size && memblock_is_region_memory(mrc.base, mrc.size)) + if (mrc.size && memblock_is_region_memory(mrc.base, mrc.size)) { + static struct cma *rcar_gen2_dma_contiguous; + dma_contiguous_reserve_area(mrc.size, mrc.base, 0, &rcar_gen2_dma_contiguous, true); + } #endif } diff --git a/arch/arm/mach-shmobile/smp-emev2.c b/arch/arm/mach-shmobile/smp-emev2.c index adbac6963f2b962e2350ecff5638271d55cf5046..3a732199cf5e98c0f5cc625c86c75fb182631513 100644 --- a/arch/arm/mach-shmobile/smp-emev2.c +++ b/arch/arm/mach-shmobile/smp-emev2.c @@ -21,7 +21,9 @@ #include #include #include + #include "common.h" +#include "emev2.h" #define EMEV2_SCU_BASE 0x1e000000 #define EMEV2_SMU_BASE 0xe0110000 @@ -45,8 +47,7 @@ static void __init emev2_smp_prepare_cpus(unsigned int max_cpus) } /* setup EMEV2 specific SCU bits */ - shmobile_scu_base = ioremap(EMEV2_SCU_BASE, PAGE_SIZE); - shmobile_smp_scu_prepare_cpus(max_cpus); + shmobile_smp_scu_prepare_cpus(EMEV2_SCU_BASE, max_cpus); } const struct smp_operations emev2_smp_ops __initconst = { diff --git a/arch/arm/mach-shmobile/smp-r8a7779.c b/arch/arm/mach-shmobile/smp-r8a7779.c index 0b024a9dbd4397e7235827dbdaf62d65a5ad3d16..f5c31fbc10b2efbf3c341f9efbaa66f261c0f4d4 100644 --- a/arch/arm/mach-shmobile/smp-r8a7779.c +++ b/arch/arm/mach-shmobile/smp-r8a7779.c @@ -94,8 +94,7 @@ static void __init r8a7779_smp_prepare_cpus(unsigned int max_cpus) __raw_writel(__pa(shmobile_boot_vector), AVECR); /* setup r8a7779 specific SCU bits */ - shmobile_scu_base = IOMEM(R8A7779_SCU_BASE); - shmobile_smp_scu_prepare_cpus(max_cpus); + shmobile_smp_scu_prepare_cpus(R8A7779_SCU_BASE, max_cpus); r8a7779_pm_init(); diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c index ee1a4b70604bd6eaca0245c10bb6f8e6ec6391d5..41137404382e2f94c61d610988c4e442dc094800 100644 --- a/arch/arm/mach-shmobile/smp-sh73a0.c +++ b/arch/arm/mach-shmobile/smp-sh73a0.c @@ -52,8 +52,7 @@ static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus) __raw_writel(__pa(shmobile_boot_vector), SBAR); /* setup sh73a0 specific SCU bits */ - shmobile_scu_base = IOMEM(SH73A0_SCU_BASE); - shmobile_smp_scu_prepare_cpus(max_cpus); + shmobile_smp_scu_prepare_cpus(SH73A0_SCU_BASE, max_cpus); } const struct smp_operations sh73a0_smp_ops __initconst = { diff --git a/arch/arm/mach-shmobile/suspend.c b/arch/arm/mach-shmobile/suspend.c index 5d92b5dd486b0b9fd8d501aa3b69f56f96ae1ee2..74b30bade2c15c380c0d3fd721d5aa80a957ef79 100644 --- a/arch/arm/mach-shmobile/suspend.c +++ b/arch/arm/mach-shmobile/suspend.c @@ -17,6 +17,8 @@ #include #include +#include "common.h" + static int shmobile_suspend_default_enter(suspend_state_t suspend_state) { cpu_do_idle(); diff --git a/arch/arm/mach-shmobile/timer.c b/arch/arm/mach-shmobile/timer.c index c17d4d3881ffc45e5e169af4e91cf46744ac006d..ad008e4b0c49a4aa1be23992be444198d67e41d5 100644 --- a/arch/arm/mach-shmobile/timer.c +++ b/arch/arm/mach-shmobile/timer.c @@ -18,6 +18,8 @@ #include #include +#include "common.h" + static void __init shmobile_setup_delay_hz(unsigned int max_cpu_core_hz, unsigned int mult, unsigned int div) { diff --git a/arch/arm/mach-socfpga/platsmp.c b/arch/arm/mach-socfpga/platsmp.c index cbb0a54df80ac6e4eff2d463b7ae7634f363959f..07945748b57141f2c216d729a6f895d36227be7a 100644 --- a/arch/arm/mach-socfpga/platsmp.c +++ b/arch/arm/mach-socfpga/platsmp.c @@ -94,6 +94,7 @@ static void __init socfpga_smp_prepare_cpus(unsigned int max_cpus) scu_enable(socfpga_scu_base_addr); } +#ifdef CONFIG_HOTPLUG_CPU /* * platform-specific code to shutdown a CPU * @@ -116,6 +117,7 @@ static int socfpga_cpu_kill(unsigned int cpu) { return 1; } +#endif static const struct smp_operations socfpga_smp_ops __initconst = { .smp_prepare_cpus = socfpga_smp_prepare_cpus, diff --git a/arch/arm/mach-spear/Makefile.boot b/arch/arm/mach-spear/Makefile.boot deleted file mode 100644 index 4674a4c221dbcf58f9bc1b43a9fa97a0977d9489..0000000000000000000000000000000000000000 --- a/arch/arm/mach-spear/Makefile.boot +++ /dev/null @@ -1,3 +0,0 @@ -zreladdr-y += 0x00008000 -params_phys-y := 0x00000100 -initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-stm32/board-dt.c b/arch/arm/mach-stm32/board-dt.c index f2ad7723d034990dfe6e8f09baaeda4927b9e2bd..ceee47735eecc606f12764230d71576f412f96a0 100644 --- a/arch/arm/mach-stm32/board-dt.c +++ b/arch/arm/mach-stm32/board-dt.c @@ -10,6 +10,7 @@ static const char *const stm32_compat[] __initconst = { "st,stm32f429", + "st,stm32f469", NULL }; diff --git a/arch/arm/mach-sunxi/sunxi.c b/arch/arm/mach-sunxi/sunxi.c index c2be98f38e73b2006ea664b7089dc427a2575d8e..3c156190a1d44223027b4c9a37ab67550219854b 100644 --- a/arch/arm/mach-sunxi/sunxi.c +++ b/arch/arm/mach-sunxi/sunxi.c @@ -69,6 +69,7 @@ MACHINE_END static const char * const sun8i_board_dt_compat[] = { "allwinner,sun8i-a23", "allwinner,sun8i-a33", + "allwinner,sun8i-a83t", "allwinner,sun8i-h3", NULL, }; diff --git a/arch/arm/mach-tegra/board-paz00.c b/arch/arm/mach-tegra/board-paz00.c index 49d1110cff5341954e3d980d003fda4f516138f0..52db8bf7e153b09b4d7532cae4ddff12213f2921 100644 --- a/arch/arm/mach-tegra/board-paz00.c +++ b/arch/arm/mach-tegra/board-paz00.c @@ -17,23 +17,25 @@ * */ +#include #include #include -#include #include "board.h" -static struct rfkill_gpio_platform_data wifi_rfkill_platform_data = { - .name = "wifi_rfkill", - .type = RFKILL_TYPE_WLAN, +static struct property_entry __initdata wifi_rfkill_prop[] = { + PROPERTY_ENTRY_STRING("name", "wifi_rfkill"), + PROPERTY_ENTRY_STRING("type", "wlan"), + { }, +}; + +static struct property_set __initdata wifi_rfkill_pset = { + .properties = wifi_rfkill_prop, }; static struct platform_device wifi_rfkill_device = { .name = "rfkill_gpio", .id = -1, - .dev = { - .platform_data = &wifi_rfkill_platform_data, - }, }; static struct gpiod_lookup_table wifi_gpio_lookup = { @@ -47,6 +49,7 @@ static struct gpiod_lookup_table wifi_gpio_lookup = { void __init tegra_paz00_wifikill_init(void) { + platform_device_add_properties(&wifi_rfkill_device, &wifi_rfkill_pset); gpiod_add_lookup_table(&wifi_gpio_lookup); platform_device_register(&wifi_rfkill_device); } diff --git a/arch/arm/mach-u300/Makefile.boot b/arch/arm/mach-u300/Makefile.boot deleted file mode 100644 index 87811de0bd947cb4b516f54185e71b745562dc22..0000000000000000000000000000000000000000 --- a/arch/arm/mach-u300/Makefile.boot +++ /dev/null @@ -1,4 +0,0 @@ - zreladdr-y += 0x48008000 -params_phys-y := 0x48000100 -# This isn't used. -#initrd_phys-y := 0x48800000 diff --git a/arch/arm/mach-uniphier/platsmp.c b/arch/arm/mach-uniphier/platsmp.c index e1cfc1d6e2f471385bb06e9c3e6cb45a19015fb9..69141357afe81991595f81348df9f2f0964db06f 100644 --- a/arch/arm/mach-uniphier/platsmp.c +++ b/arch/arm/mach-uniphier/platsmp.c @@ -30,7 +30,7 @@ * The secondary CPUs check this register from the boot ROM for the jump * destination. After that, it can be reused as a scratch register. */ -#define UNIPHIER_SBC_ROM_BOOT_RSV2 0x1208 +#define UNIPHIER_SMPCTRL_ROM_RSV2 0x208 static void __iomem *uniphier_smp_rom_boot_rsv2; static unsigned int uniphier_smp_max_cpus; @@ -98,16 +98,24 @@ static int __init uniphier_smp_prepare_trampoline(unsigned int max_cpus) phys_addr_t rom_rsv2_phys; int ret; - np = of_find_compatible_node(NULL, NULL, - "socionext,uniphier-system-bus-controller"); - ret = of_address_to_resource(np, 1, &res); - if (ret) { - pr_err("failed to get resource of system-bus-controller\n"); - return ret; + np = of_find_compatible_node(NULL, NULL, "socionext,uniphier-smpctrl"); + of_node_put(np); + ret = of_address_to_resource(np, 0, &res); + if (!ret) { + rom_rsv2_phys = res.start + UNIPHIER_SMPCTRL_ROM_RSV2; + } else { + /* try old binding too */ + np = of_find_compatible_node(NULL, NULL, + "socionext,uniphier-system-bus-controller"); + of_node_put(np); + ret = of_address_to_resource(np, 1, &res); + if (ret) { + pr_err("failed to get resource of SMP control\n"); + return ret; + } + rom_rsv2_phys = res.start + 0x1000 + UNIPHIER_SMPCTRL_ROM_RSV2; } - rom_rsv2_phys = res.start + UNIPHIER_SBC_ROM_BOOT_RSV2; - ret = uniphier_smp_copy_trampoline(rom_rsv2_phys); if (ret) return ret; diff --git a/arch/arm/mach-ux500/Makefile.boot b/arch/arm/mach-ux500/Makefile.boot deleted file mode 100644 index 760a0efe7580b0dd194ff9bfe4295624336bb806..0000000000000000000000000000000000000000 --- a/arch/arm/mach-ux500/Makefile.boot +++ /dev/null @@ -1,3 +0,0 @@ - zreladdr-y += 0x00008000 -params_phys-y := 0x00000100 -initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index a0ffaad1fb612fe42b059c2e99313d0d30a0d9f6..a557955472ea06376e3bd2d8923bfd4e321b3043 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -76,17 +76,19 @@ static struct arm_pmu_platdata db8500_pmu_platdata = { static const char *db8500_read_soc_id(void) { void __iomem *uid; + const char *retstr; uid = ioremap(U8500_BB_UID_BASE, 0x20); if (!uid) return NULL; /* Throw these device-specific numbers into the entropy pool */ add_device_randomness(uid, 0x14); - return kasprintf(GFP_KERNEL, "%08x%08x%08x%08x%08x", + retstr = kasprintf(GFP_KERNEL, "%08x%08x%08x%08x%08x", readl((u32 *)uid+0), readl((u32 *)uid+1), readl((u32 *)uid+2), readl((u32 *)uid+3), readl((u32 *)uid+4)); iounmap(uid); + return retstr; } static struct device * __init db8500_soc_device_init(void) diff --git a/arch/arm/mach-versatile/Kconfig b/arch/arm/mach-versatile/Kconfig index e40f777ccf7d0f2a7f19942ef1d43efe618d4eb0..b0cc26284fc972bfea0433f5a66a45312e352013 100644 --- a/arch/arm/mach-versatile/Kconfig +++ b/arch/arm/mach-versatile/Kconfig @@ -8,8 +8,11 @@ config ARCH_VERSATILE select COMMON_CLK_VERSATILE select CPU_ARM926T select ICST + select MFD_SYSCON select MIGHT_HAVE_PCI select PLAT_VERSATILE + select POWER_RESET + select POWER_RESET_VERSATILE select VERSATILE_FPGA_IRQ help This enables support for ARM Ltd Versatile board. diff --git a/arch/arm/mach-versatile/versatile_dt.c b/arch/arm/mach-versatile/versatile_dt.c index c448718512552db540edd0038f980d4235bac08a..dff1c0595b67264793d9b4145287d34b20088416 100644 --- a/arch/arm/mach-versatile/versatile_dt.c +++ b/arch/arm/mach-versatile/versatile_dt.c @@ -52,8 +52,6 @@ * Versatile Registers * ------------------------------------------------------------------------ */ -#define VERSATILE_SYS_LOCK_OFFSET 0x20 -#define VERSATILE_SYS_RESETCTL_OFFSET 0x40 #define VERSATILE_SYS_PCICTL_OFFSET 0x44 #define VERSATILE_SYS_MCI_OFFSET 0x48 #define VERSATILE_SYS_FLASH_OFFSET 0x4C @@ -345,18 +343,6 @@ static void __init versatile_init_early(void) __io_address(VERSATILE_SCTL_BASE)); } -static void versatile_restart(enum reboot_mode mode, const char *cmd) -{ - u32 val; - - val = readl(versatile_sys_base + VERSATILE_SYS_RESETCTL_OFFSET); - val |= 0x105; - - writel(0xa05f, versatile_sys_base + VERSATILE_SYS_LOCK_OFFSET); - writel(val, versatile_sys_base + VERSATILE_SYS_RESETCTL_OFFSET); - writel(0, versatile_sys_base + VERSATILE_SYS_LOCK_OFFSET); -} - static void __init versatile_dt_pci_init(void) { u32 val; @@ -420,5 +406,4 @@ DT_MACHINE_START(VERSATILE_PB, "ARM-Versatile (Device Tree Support)") .init_early = versatile_init_early, .init_machine = versatile_dt_init, .dt_compat = versatile_dt_match, - .restart = versatile_restart, MACHINE_END diff --git a/arch/arm/mach-w90x900/include/mach/uncompress.h b/arch/arm/mach-w90x900/include/mach/uncompress.h index 4b7c324ff664c64752ec3b5f1118a2145b7cae2f..3855ecebda6e6ed02c375707ddd0c6217eb19edc 100644 --- a/arch/arm/mach-w90x900/include/mach/uncompress.h +++ b/arch/arm/mach-w90x900/include/mach/uncompress.h @@ -27,7 +27,7 @@ #define TX_DONE (UART_LSR_TEMT | UART_LSR_THRE) static volatile u32 * const uart_base = (u32 *)UART0_PA; -static void putc(int ch) +static inline void putc(int ch) { /* Check THRE and TEMT bits before we transmit the character. */ diff --git a/arch/arm/mach-zynq/Makefile.boot b/arch/arm/mach-zynq/Makefile.boot deleted file mode 100644 index 760a0efe7580b0dd194ff9bfe4295624336bb806..0000000000000000000000000000000000000000 --- a/arch/arm/mach-zynq/Makefile.boot +++ /dev/null @@ -1,3 +0,0 @@ - zreladdr-y += 0x00008000 -params_phys-y := 0x00000100 -initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c index 6f39d03cc27eac777a243abcb5a08ea4c35e8d7c..860ffb663f02b1c08c15c55f1c3fbf7638e610a8 100644 --- a/arch/arm/mach-zynq/common.c +++ b/arch/arm/mach-zynq/common.c @@ -150,8 +150,6 @@ static void __init zynq_init_machine(void) static void __init zynq_timer_init(void) { - zynq_early_slcr_init(); - zynq_clock_init(); of_clk_init(NULL); clocksource_probe(); @@ -186,6 +184,7 @@ static void __init zynq_map_io(void) static void __init zynq_irq_init(void) { + zynq_early_slcr_init(); irqchip_init(); } diff --git a/arch/arm/mach-zynq/slcr.c b/arch/arm/mach-zynq/slcr.c index 26320ebf349349a06c8257aa7ce87e7c7d5c46c9..f0292a30e6f696058114ac64d54c5f8720447b70 100644 --- a/arch/arm/mach-zynq/slcr.c +++ b/arch/arm/mach-zynq/slcr.c @@ -28,6 +28,7 @@ #define SLCR_A9_CPU_RST_CTRL_OFFSET 0x244 /* CPU Software Reset Control */ #define SLCR_REBOOT_STATUS_OFFSET 0x258 /* PS Reboot Status */ #define SLCR_PSS_IDCODE 0x530 /* PS IDCODE */ +#define SLCR_L2C_RAM 0xA1C /* L2C_RAM in AR#54190 */ #define SLCR_UNLOCK_MAGIC 0xDF0D #define SLCR_A9_CPU_CLKSTOP 0x10 @@ -227,6 +228,9 @@ int __init zynq_early_slcr_init(void) /* unlock the SLCR so that registers can be changed */ zynq_slcr_unlock(); + /* See AR#54190 design advisory */ + regmap_update_bits(zynq_slcr_regmap, SLCR_L2C_RAM, 0x70707, 0x20202); + register_restart_handler(&zynq_slcr_restart_nb); pr_info("%s mapped to %p\n", np->name, zynq_slcr_base); diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 549f6d3aec5b66457a948f579f04b8b5dd1021cc..55347662e5edafa0900b54987b219a5fb83a6b5a 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -1037,24 +1037,26 @@ config ARCH_SUPPORTS_BIG_ENDIAN This option specifies the architecture can support big endian operation. -config ARM_KERNMEM_PERMS - bool "Restrict kernel memory permissions" - depends on MMU - help - If this is set, kernel memory other than kernel text (and rodata) - will be made non-executable. The tradeoff is that each region is - padded to section-size (1MiB) boundaries (because their permissions - are different and splitting the 1M pages into 4K ones causes TLB - performance problems), wasting memory. - config DEBUG_RODATA bool "Make kernel text and rodata read-only" - depends on ARM_KERNMEM_PERMS + depends on MMU && !XIP_KERNEL + default y if CPU_V7 + help + If this is set, kernel text and rodata memory will be made + read-only, and non-text kernel memory will be made non-executable. + The tradeoff is that each region is padded to section-size (1MiB) + boundaries (because their permissions are different and splitting + the 1M pages into 4K ones causes TLB performance problems), which + can waste memory. + +config DEBUG_ALIGN_RODATA + bool "Make rodata strictly non-executable" + depends on DEBUG_RODATA default y help - If this is set, kernel text and rodata will be made read-only. This - is to help catch accidental or malicious attempts to change the - kernel's executable code. Additionally splits rodata from kernel - text so it can be made explicitly non-executable. This creates - another section-size padded region, so it can waste more memory - space while gaining the read-only protections. + If this is set, rodata will be made explicitly non-executable. This + provides protection on the rare chance that attackers might find and + use ROP gadgets that exist in the rodata section. This adds an + additional section-aligned split of rodata from kernel text so it + can be made explicitly non-executable. This padding may waste memory + space to gain the additional protection. diff --git a/arch/arm/mm/cache-tauros2.c b/arch/arm/mm/cache-tauros2.c index 1e373d268c04c3e3697ac40aaca1915f436a147b..88255bea65e41e61bd16ed2b12513ebcde7b04bd 100644 --- a/arch/arm/mm/cache-tauros2.c +++ b/arch/arm/mm/cache-tauros2.c @@ -22,6 +22,11 @@ #include #include +/* CP15 PJ4 Control configuration register */ +#define CCR_L2C_PREFETCH_DISABLE BIT(24) +#define CCR_L2C_ECC_ENABLE BIT(23) +#define CCR_L2C_WAY7_4_DISABLE BIT(21) +#define CCR_L2C_BURST8_ENABLE BIT(20) /* * When Tauros2 is used on a CPU that supports the v7 hierarchical @@ -182,18 +187,18 @@ static void enable_extra_feature(unsigned int features) u = read_extra_features(); if (features & CACHE_TAUROS2_PREFETCH_ON) - u &= ~0x01000000; + u &= ~CCR_L2C_PREFETCH_DISABLE; else - u |= 0x01000000; + u |= CCR_L2C_PREFETCH_DISABLE; pr_info("Tauros2: %s L2 prefetch.\n", (features & CACHE_TAUROS2_PREFETCH_ON) ? "Enabling" : "Disabling"); if (features & CACHE_TAUROS2_LINEFILL_BURST8) - u |= 0x00100000; + u |= CCR_L2C_BURST8_ENABLE; else - u &= ~0x00100000; - pr_info("Tauros2: %s line fill burt8.\n", + u &= ~CCR_L2C_BURST8_ENABLE; + pr_info("Tauros2: %s burst8 line fill.\n", (features & CACHE_TAUROS2_LINEFILL_BURST8) ? "Enabling" : "Disabling"); @@ -287,16 +292,15 @@ void __init tauros2_init(unsigned int features) node = of_find_matching_node(NULL, tauros2_ids); if (!node) { pr_info("Not found marvell,tauros2-cache, disable it\n"); - return; + } else { + ret = of_property_read_u32(node, "marvell,tauros2-cache-features", &f); + if (ret) { + pr_info("Not found marvell,tauros-cache-features property, " + "disable extra features\n"); + features = 0; + } else + features = f; } - - ret = of_property_read_u32(node, "marvell,tauros2-cache-features", &f); - if (ret) { - pr_info("Not found marvell,tauros-cache-features property, " - "disable extra features\n"); - features = 0; - } else - features = f; #endif tauros2_internal_init(features); } diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 0eca3812527e614e891113839992b4e20cf3fb8d..deac58d5f1f7cf053ca215ec718c6902961a7908 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -42,6 +42,55 @@ #include "dma.h" #include "mm.h" +struct arm_dma_alloc_args { + struct device *dev; + size_t size; + gfp_t gfp; + pgprot_t prot; + const void *caller; + bool want_vaddr; +}; + +struct arm_dma_free_args { + struct device *dev; + size_t size; + void *cpu_addr; + struct page *page; + bool want_vaddr; +}; + +struct arm_dma_allocator { + void *(*alloc)(struct arm_dma_alloc_args *args, + struct page **ret_page); + void (*free)(struct arm_dma_free_args *args); +}; + +struct arm_dma_buffer { + struct list_head list; + void *virt; + struct arm_dma_allocator *allocator; +}; + +static LIST_HEAD(arm_dma_bufs); +static DEFINE_SPINLOCK(arm_dma_bufs_lock); + +static struct arm_dma_buffer *arm_dma_buffer_find(void *virt) +{ + struct arm_dma_buffer *buf, *found = NULL; + unsigned long flags; + + spin_lock_irqsave(&arm_dma_bufs_lock, flags); + list_for_each_entry(buf, &arm_dma_bufs, list) { + if (buf->virt == virt) { + list_del(&buf->list); + found = buf; + break; + } + } + spin_unlock_irqrestore(&arm_dma_bufs_lock, flags); + return found; +} + /* * 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 @@ -592,7 +641,7 @@ static inline pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot) #define __alloc_remap_buffer(dev, size, gfp, prot, ret, c, wv) NULL #define __alloc_from_pool(size, ret_page) NULL #define __alloc_from_contiguous(dev, size, prot, ret, c, wv) NULL -#define __free_from_pool(cpu_addr, size) 0 +#define __free_from_pool(cpu_addr, size) do { } while (0) #define __free_from_contiguous(dev, page, cpu_addr, size, wv) do { } while (0) #define __dma_free_remap(cpu_addr, size) do { } while (0) @@ -610,7 +659,78 @@ static void *__alloc_simple_buffer(struct device *dev, size_t size, gfp_t gfp, return page_address(page); } +static void *simple_allocator_alloc(struct arm_dma_alloc_args *args, + struct page **ret_page) +{ + return __alloc_simple_buffer(args->dev, args->size, args->gfp, + ret_page); +} + +static void simple_allocator_free(struct arm_dma_free_args *args) +{ + __dma_free_buffer(args->page, args->size); +} +static struct arm_dma_allocator simple_allocator = { + .alloc = simple_allocator_alloc, + .free = simple_allocator_free, +}; + +static void *cma_allocator_alloc(struct arm_dma_alloc_args *args, + struct page **ret_page) +{ + return __alloc_from_contiguous(args->dev, args->size, args->prot, + ret_page, args->caller, + args->want_vaddr); +} + +static void cma_allocator_free(struct arm_dma_free_args *args) +{ + __free_from_contiguous(args->dev, args->page, args->cpu_addr, + args->size, args->want_vaddr); +} + +static struct arm_dma_allocator cma_allocator = { + .alloc = cma_allocator_alloc, + .free = cma_allocator_free, +}; + +static void *pool_allocator_alloc(struct arm_dma_alloc_args *args, + struct page **ret_page) +{ + return __alloc_from_pool(args->size, ret_page); +} + +static void pool_allocator_free(struct arm_dma_free_args *args) +{ + __free_from_pool(args->cpu_addr, args->size); +} + +static struct arm_dma_allocator pool_allocator = { + .alloc = pool_allocator_alloc, + .free = pool_allocator_free, +}; + +static void *remap_allocator_alloc(struct arm_dma_alloc_args *args, + struct page **ret_page) +{ + return __alloc_remap_buffer(args->dev, args->size, args->gfp, + args->prot, ret_page, args->caller, + args->want_vaddr); +} + +static void remap_allocator_free(struct arm_dma_free_args *args) +{ + if (args->want_vaddr) + __dma_free_remap(args->cpu_addr, args->size); + + __dma_free_buffer(args->page, args->size); +} + +static struct arm_dma_allocator remap_allocator = { + .alloc = remap_allocator_alloc, + .free = remap_allocator_free, +}; static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, pgprot_t prot, bool is_coherent, @@ -619,7 +739,16 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, u64 mask = get_coherent_dma_mask(dev); struct page *page = NULL; void *addr; - bool want_vaddr; + bool allowblock, cma; + struct arm_dma_buffer *buf; + struct arm_dma_alloc_args args = { + .dev = dev, + .size = PAGE_ALIGN(size), + .gfp = gfp, + .prot = prot, + .caller = caller, + .want_vaddr = !dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs), + }; #ifdef CONFIG_DMA_API_DEBUG u64 limit = (mask + 1) & ~mask; @@ -633,6 +762,10 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, if (!mask) return NULL; + buf = kzalloc(sizeof(*buf), gfp); + if (!buf) + return NULL; + if (mask < 0xffffffffULL) gfp |= GFP_DMA; @@ -644,28 +777,37 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, * platform; see CONFIG_HUGETLBFS. */ gfp &= ~(__GFP_COMP); + args.gfp = gfp; *handle = DMA_ERROR_CODE; - size = PAGE_ALIGN(size); - want_vaddr = !dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs); - - if (nommu()) - addr = __alloc_simple_buffer(dev, size, gfp, &page); - else if (dev_get_cma_area(dev) && (gfp & __GFP_DIRECT_RECLAIM)) - addr = __alloc_from_contiguous(dev, size, prot, &page, - caller, want_vaddr); - else if (is_coherent) - addr = __alloc_simple_buffer(dev, size, gfp, &page); - else if (!gfpflags_allow_blocking(gfp)) - addr = __alloc_from_pool(size, &page); + allowblock = gfpflags_allow_blocking(gfp); + cma = allowblock ? dev_get_cma_area(dev) : false; + + if (cma) + buf->allocator = &cma_allocator; + else if (nommu() || is_coherent) + buf->allocator = &simple_allocator; + else if (allowblock) + buf->allocator = &remap_allocator; else - addr = __alloc_remap_buffer(dev, size, gfp, prot, &page, - caller, want_vaddr); + buf->allocator = &pool_allocator; + + addr = buf->allocator->alloc(&args, &page); + + if (page) { + unsigned long flags; - if (page) *handle = pfn_to_dma(dev, page_to_pfn(page)); + buf->virt = args.want_vaddr ? addr : page; + + spin_lock_irqsave(&arm_dma_bufs_lock, flags); + list_add(&buf->list, &arm_dma_bufs); + spin_unlock_irqrestore(&arm_dma_bufs_lock, flags); + } else { + kfree(buf); + } - return want_vaddr ? addr : page; + return args.want_vaddr ? addr : page; } /* @@ -741,25 +883,21 @@ static void __arm_dma_free(struct device *dev, size_t size, void *cpu_addr, bool is_coherent) { struct page *page = pfn_to_page(dma_to_pfn(dev, handle)); - bool want_vaddr = !dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs); - - size = PAGE_ALIGN(size); - - if (nommu()) { - __dma_free_buffer(page, size); - } else if (!is_coherent && __free_from_pool(cpu_addr, size)) { + struct arm_dma_buffer *buf; + struct arm_dma_free_args args = { + .dev = dev, + .size = PAGE_ALIGN(size), + .cpu_addr = cpu_addr, + .page = page, + .want_vaddr = !dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs), + }; + + buf = arm_dma_buffer_find(cpu_addr); + if (WARN(!buf, "Freeing invalid buffer %p\n", cpu_addr)) return; - } else if (!dev_get_cma_area(dev)) { - if (want_vaddr && !is_coherent) - __dma_free_remap(cpu_addr, size); - __dma_free_buffer(page, size); - } else { - /* - * Non-atomic allocations cannot be freed with IRQs disabled - */ - WARN_ON(irqs_disabled()); - __free_from_contiguous(dev, page, cpu_addr, size, want_vaddr); - } + + buf->allocator->free(&args); + kfree(buf); } void arm_dma_free(struct device *dev, size_t size, void *cpu_addr, @@ -1122,6 +1260,9 @@ static inline void __free_iova(struct dma_iommu_mapping *mapping, spin_unlock_irqrestore(&mapping->lock, flags); } +/* We'll try 2M, 1M, 64K, and finally 4K; array must end with 0! */ +static const int iommu_order_array[] = { 9, 8, 4, 0 }; + static struct page **__iommu_alloc_buffer(struct device *dev, size_t size, gfp_t gfp, struct dma_attrs *attrs) { @@ -1129,6 +1270,7 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size, int count = size >> PAGE_SHIFT; int array_size = count * sizeof(struct page *); int i = 0; + int order_idx = 0; if (array_size <= PAGE_SIZE) pages = kzalloc(array_size, GFP_KERNEL); @@ -1154,6 +1296,10 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size, return pages; } + /* Go straight to 4K chunks if caller says it's OK. */ + if (dma_get_attr(DMA_ATTR_ALLOC_SINGLE_PAGES, attrs)) + order_idx = ARRAY_SIZE(iommu_order_array) - 1; + /* * IOMMU can map any pages, so himem can also be used here */ @@ -1162,22 +1308,24 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size, while (count) { int j, order; - for (order = __fls(count); order > 0; --order) { - /* - * We do not want OOM killer to be invoked as long - * as we can fall back to single pages, so we force - * __GFP_NORETRY for orders higher than zero. - */ - pages[i] = alloc_pages(gfp | __GFP_NORETRY, order); - if (pages[i]) - break; + order = iommu_order_array[order_idx]; + + /* Drop down when we get small */ + if (__fls(count) < order) { + order_idx++; + continue; } - if (!pages[i]) { - /* - * Fall back to single page allocation. - * Might invoke OOM killer as last resort. - */ + if (order) { + /* See if it's easy to allocate a high-order chunk */ + pages[i] = alloc_pages(gfp | __GFP_NORETRY, order); + + /* Go down a notch at first sign of pressure */ + if (!pages[i]) { + order_idx++; + continue; + } + } else { pages[i] = alloc_pages(gfp, 0); if (!pages[i]) goto error; diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index daafcf121ce082aa0a0fbb43be3e3712b2942f3e..ad5841856007a4ee0f46b6c4c40dcdfbcbf0aac1 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -346,7 +346,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) up_read(&mm->mmap_sem); /* - * Handle the "normal" case first - VM_FAULT_MAJOR / VM_FAULT_MINOR + * Handle the "normal" case first - VM_FAULT_MAJOR */ if (likely(!(fault & (VM_FAULT_ERROR | VM_FAULT_BADMAP | VM_FAULT_BADACCESS)))) return 0; diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index d0ba3551d49a4b05371db7a12c02e151be9d4eae..3cced8455727953a2525571c5a62b5ad884e8bee 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c @@ -235,7 +235,7 @@ void __flush_dcache_page(struct address_space *mapping, struct page *page) */ if (mapping && cache_is_vipt_aliasing()) flush_pfn_alias(page_to_pfn(page), - page->index << PAGE_CACHE_SHIFT); + page->index << PAGE_SHIFT); } static void __flush_dcache_aliases(struct address_space *mapping, struct page *page) @@ -250,7 +250,7 @@ static void __flush_dcache_aliases(struct address_space *mapping, struct page *p * data in the current VM view associated with this page. * - aliasing VIPT: we only need to find one mapping of this page. */ - pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT); + pgoff = page->index; flush_dcache_mmap_lock(mapping); vma_interval_tree_foreach(mpnt, &mapping->i_mmap, pgoff, pgoff) { diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c index d65909697165b20cc1936f50073bd3eea7521aec..bd274a05b8ffa9446160d1de69f777d9431c629b 100644 --- a/arch/arm/mm/idmap.c +++ b/arch/arm/mm/idmap.c @@ -15,7 +15,7 @@ * page tables. */ pgd_t *idmap_pgd; -phys_addr_t (*arch_virt_to_idmap) (unsigned long x); +unsigned long (*arch_virt_to_idmap)(unsigned long x); #ifdef CONFIG_ARM_LPAE static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end, diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 49bd08178008adc38cca29b5e50bf26aa14a07c9..370581aeb87104273df695409af37876956c639f 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -572,8 +572,9 @@ void __init mem_init(void) } } -#ifdef CONFIG_ARM_KERNMEM_PERMS +#ifdef CONFIG_DEBUG_RODATA struct section_perm { + const char *name; unsigned long start; unsigned long end; pmdval_t mask; @@ -581,9 +582,13 @@ struct section_perm { pmdval_t clear; }; +/* First section-aligned location at or after __start_rodata. */ +extern char __start_rodata_section_aligned[]; + static struct section_perm nx_perms[] = { /* Make pages tables, etc before _stext RW (set NX). */ { + .name = "pre-text NX", .start = PAGE_OFFSET, .end = (unsigned long)_stext, .mask = ~PMD_SECT_XN, @@ -591,26 +596,26 @@ static struct section_perm nx_perms[] = { }, /* Make init RW (set NX). */ { + .name = "init NX", .start = (unsigned long)__init_begin, .end = (unsigned long)_sdata, .mask = ~PMD_SECT_XN, .prot = PMD_SECT_XN, }, -#ifdef CONFIG_DEBUG_RODATA /* Make rodata NX (set RO in ro_perms below). */ { - .start = (unsigned long)__start_rodata, + .name = "rodata NX", + .start = (unsigned long)__start_rodata_section_aligned, .end = (unsigned long)__init_begin, .mask = ~PMD_SECT_XN, .prot = PMD_SECT_XN, }, -#endif }; -#ifdef CONFIG_DEBUG_RODATA static struct section_perm ro_perms[] = { /* Make kernel code and rodata RX (set RO). */ { + .name = "text/rodata RO", .start = (unsigned long)_stext, .end = (unsigned long)__init_begin, #ifdef CONFIG_ARM_LPAE @@ -623,7 +628,6 @@ static struct section_perm ro_perms[] = { #endif }, }; -#endif /* * Updates section permissions only for the current mm (sections are @@ -670,8 +674,8 @@ void set_section_perms(struct section_perm *perms, int n, bool set, for (i = 0; i < n; i++) { if (!IS_ALIGNED(perms[i].start, SECTION_SIZE) || !IS_ALIGNED(perms[i].end, SECTION_SIZE)) { - pr_err("BUG: section %lx-%lx not aligned to %lx\n", - perms[i].start, perms[i].end, + pr_err("BUG: %s section %lx-%lx not aligned to %lx\n", + perms[i].name, perms[i].start, perms[i].end, SECTION_SIZE); continue; } @@ -712,7 +716,6 @@ void fix_kernmem_perms(void) stop_machine(__fix_kernmem_perms, NULL, NULL); } -#ifdef CONFIG_DEBUG_RODATA int __mark_rodata_ro(void *unused) { update_sections_early(ro_perms, ARRAY_SIZE(ro_perms)); @@ -735,11 +738,10 @@ void set_kernel_text_ro(void) set_section_perms(ro_perms, ARRAY_SIZE(ro_perms), true, current->active_mm); } -#endif /* CONFIG_DEBUG_RODATA */ #else static inline void fix_kernmem_perms(void) { } -#endif /* CONFIG_ARM_KERNMEM_PERMS */ +#endif /* CONFIG_DEBUG_RODATA */ void free_tcmmem(void) { diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 434d76f0b36314e3731fe74376b7db5bc92483a6..62f4d01941f718bf02a6e24c19042d6c65b961d9 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -732,7 +732,7 @@ static void *__init late_alloc(unsigned long sz) return ptr; } -static pte_t * __init pte_alloc(pmd_t *pmd, unsigned long addr, +static pte_t * __init arm_pte_alloc(pmd_t *pmd, unsigned long addr, unsigned long prot, void *(*alloc)(unsigned long sz)) { @@ -747,7 +747,7 @@ static pte_t * __init pte_alloc(pmd_t *pmd, unsigned long addr, static pte_t * __init early_pte_alloc(pmd_t *pmd, unsigned long addr, unsigned long prot) { - return pte_alloc(pmd, addr, prot, early_alloc); + return arm_pte_alloc(pmd, addr, prot, early_alloc); } static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr, @@ -756,7 +756,7 @@ static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr, void *(*alloc)(unsigned long sz), bool ng) { - pte_t *pte = pte_alloc(pmd, addr, type->prot_l1, alloc); + pte_t *pte = arm_pte_alloc(pmd, addr, type->prot_l1, alloc); do { set_pte_ext(pte, pfn_pte(pfn, __pgprot(type->prot_pte)), ng ? PTE_EXT_NG : 0); @@ -1253,7 +1253,7 @@ static inline void prepare_page_table(void) #ifdef CONFIG_XIP_KERNEL /* The XIP kernel is mapped in the module area -- skip over it */ - addr = ((unsigned long)_etext + PMD_SIZE - 1) & PMD_MASK; + addr = ((unsigned long)_exiprom + PMD_SIZE - 1) & PMD_MASK; #endif for ( ; addr < PAGE_OFFSET; addr += PMD_SIZE) pmd_clear(pmd_off_k(addr)); @@ -1335,7 +1335,7 @@ static void __init devicemaps_init(const struct machine_desc *mdesc) #ifdef CONFIG_XIP_KERNEL map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & SECTION_MASK); map.virtual = MODULES_VADDR; - map.length = ((unsigned long)_etext - map.virtual + ~SECTION_MASK) & SECTION_MASK; + map.length = ((unsigned long)_exiprom - map.virtual + ~SECTION_MASK) & SECTION_MASK; map.type = MT_ROM; create_mapping(&map); #endif @@ -1426,7 +1426,11 @@ static void __init kmap_init(void) static void __init map_lowmem(void) { struct memblock_region *reg; +#ifdef CONFIG_XIP_KERNEL + phys_addr_t kernel_x_start = round_down(__pa(_sdata), SECTION_SIZE); +#else phys_addr_t kernel_x_start = round_down(__pa(_stext), SECTION_SIZE); +#endif phys_addr_t kernel_x_end = round_up(__pa(__init_end), SECTION_SIZE); /* Map all the lowmem memory banks. */ diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c index e683db1b90a3f805d1de8f92a9c0ebe544960368..b8d477321730ede65f9fdd847c164862db7bbc45 100644 --- a/arch/arm/mm/pgd.c +++ b/arch/arm/mm/pgd.c @@ -80,7 +80,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm) if (!new_pmd) goto no_pmd; - new_pte = pte_alloc_map(mm, NULL, new_pmd, 0); + new_pte = pte_alloc_map(mm, new_pmd, 0); if (!new_pte) goto no_pte; diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 0f92d575a3040b53f6584759b95a0bd1217ea3c2..6fcaac8e200f888e18207ae6cdfeca8adc000c5e 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -281,12 +281,12 @@ __v7_ca17mp_setup: bl v7_invalidate_l1 ldmia r12, {r1-r6, lr} #ifdef CONFIG_SMP + orr r10, r10, #(1 << 6) @ Enable SMP/nAMP mode ALT_SMP(mrc p15, 0, r0, c1, c0, 1) - ALT_UP(mov r0, #(1 << 6)) @ fake it for UP - tst r0, #(1 << 6) @ SMP/nAMP mode enabled? - orreq r0, r0, #(1 << 6) @ Enable SMP/nAMP mode - orreq r0, r0, r10 @ Enable CPU-specific SMP bits - mcreq p15, 0, r0, c1, c0, 1 + ALT_UP(mov r0, r10) @ fake it for UP + orr r10, r10, r0 @ Set required bits + teq r10, r0 @ Were they already set? + mcrne p15, 0, r10, c1, c0, 1 @ No, update register #endif b __v7_setup_cont @@ -487,7 +487,7 @@ __errata_finish: .align 2 __v7_setup_stack_ptr: - .word __v7_setup_stack - . + .word PHYS_RELATIVE(__v7_setup_stack, .) ENDPROC(__v7_setup) .bss diff --git a/arch/arm/plat-orion/time.c b/arch/arm/plat-orion/time.c index 8085a8aac8124839d889849d4d5877be3fa22252..ffb93db68e9c80b3003e6d93c7e93d25eb76182e 100644 --- a/arch/arm/plat-orion/time.c +++ b/arch/arm/plat-orion/time.c @@ -18,6 +18,7 @@ #include #include #include +#include /* * MBus bridge block registers. @@ -188,6 +189,15 @@ orion_time_set_base(void __iomem *_timer_base) timer_base = _timer_base; } +static unsigned long orion_delay_timer_read(void) +{ + return ~readl(timer_base + TIMER0_VAL_OFF); +} + +static struct delay_timer orion_delay_timer = { + .read_current_timer = orion_delay_timer_read, +}; + void __init orion_time_init(void __iomem *_bridge_base, u32 _bridge_timer1_clr_mask, unsigned int irq, unsigned int tclk) @@ -202,6 +212,9 @@ orion_time_init(void __iomem *_bridge_base, u32 _bridge_timer1_clr_mask, ticks_per_jiffy = (tclk + HZ/2) / HZ; + orion_delay_timer.freq = tclk; + register_current_timer_delay(&orion_delay_timer); + /* * Set scale and timer for sched_clock. */ diff --git a/arch/arm/plat-pxa/include/plat/dma.h b/arch/arm/plat-pxa/include/plat/dma.h index 28848b344e2d945e0d7b7d6bbc128d231b957b6a..ceba3e4184fc407cb8a33cc5a1f60bb5b305b114 100644 --- a/arch/arm/plat-pxa/include/plat/dma.h +++ b/arch/arm/plat-pxa/include/plat/dma.h @@ -95,6 +95,6 @@ static inline int pxad_toggle_reserved_channel(int legacy_channel) } #endif -extern void __init pxa2xx_set_dmac_info(int nb_channels); +extern void __init pxa2xx_set_dmac_info(int nb_channels, int nb_requestors); #endif /* __PLAT_DMA_H */ diff --git a/arch/arm/plat-samsung/adc.c b/arch/arm/plat-samsung/adc.c index efa6e85619ad824c2d9ea9a2bdb0b2c0eb9a3077..daf3db9f0058f6d1387f9bf5e3522c6bac0c62f0 100644 --- a/arch/arm/plat-samsung/adc.c +++ b/arch/arm/plat-samsung/adc.c @@ -422,8 +422,7 @@ static int s3c_adc_remove(struct platform_device *pdev) #ifdef CONFIG_PM static int s3c_adc_suspend(struct device *dev) { - struct platform_device *pdev = container_of(dev, - struct platform_device, dev); + struct platform_device *pdev = to_platform_device(dev); struct adc_device *adc = platform_get_drvdata(pdev); unsigned long flags; u32 con; @@ -444,8 +443,7 @@ static int s3c_adc_suspend(struct device *dev) static int s3c_adc_resume(struct device *dev) { - struct platform_device *pdev = container_of(dev, - struct platform_device, dev); + struct platform_device *pdev = to_platform_device(dev); struct adc_device *adc = platform_get_drvdata(pdev); enum s3c_cpu_type cpu = platform_get_device_id(pdev)->driver_data; int ret; diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c index b53d4ff3befb69a5e692640443674bca83129f83..84baa16f4c0b674dfe404b54bb9fe09b4fd682bf 100644 --- a/arch/arm/plat-samsung/devs.c +++ b/arch/arm/plat-samsung/devs.c @@ -727,15 +727,6 @@ static int __init s3c_nand_copy_set(struct s3c2410_nand_set *set) return -ENOMEM; } - if (set->ecc_layout) { - ptr = kmemdup(set->ecc_layout, - sizeof(struct nand_ecclayout), GFP_KERNEL); - set->ecc_layout = ptr; - - if (!ptr) - return -ENOMEM; - } - return 0; } diff --git a/arch/arm/plat-samsung/include/plat/map-s3c.h b/arch/arm/plat-samsung/include/plat/map-s3c.h index c0c70a895ca832e865f8c0b820e0fd9c85012cf2..6feedd47d87543d8cc802f9e8d8679cc9df07b55 100644 --- a/arch/arm/plat-samsung/include/plat/map-s3c.h +++ b/arch/arm/plat-samsung/include/plat/map-s3c.h @@ -27,10 +27,6 @@ #define S3C2410_PA_UART (0x50000000) #define S3C24XX_PA_UART S3C2410_PA_UART -#ifndef S3C_UART_OFFSET -#define S3C_UART_OFFSET (0x400) -#endif - /* * GPIO ports * diff --git a/arch/arm/plat-samsung/include/plat/map-s5p.h b/arch/arm/plat-samsung/include/plat/map-s5p.h index f5cf2bd208e0c1b21179c68d0ff2bab1b39eb531..4ec9a7050185f4a69fcd506c72a898d43a2be30a 100644 --- a/arch/arm/plat-samsung/include/plat/map-s5p.h +++ b/arch/arm/plat-samsung/include/plat/map-s5p.h @@ -23,7 +23,6 @@ #define S5P_VA_COREPERI_BASE S3C_ADDR(0x02800000) #define S5P_VA_COREPERI(x) (S5P_VA_COREPERI_BASE + (x)) #define S5P_VA_SCU S5P_VA_COREPERI(0x0) -#define S5P_VA_TWD S5P_VA_COREPERI(0x600) #define VA_VIC(x) (S3C_VA_IRQ + ((x) * 0x10000)) #define VA_VIC0 VA_VIC(0) @@ -31,10 +30,6 @@ #define VA_VIC2 VA_VIC(2) #define VA_VIC3 VA_VIC(3) -#ifndef S3C_UART_OFFSET -#define S3C_UART_OFFSET (0x400) -#endif - #include #endif /* __ASM_PLAT_MAP_S5P_H */ diff --git a/arch/arm/plat-versatile/Kconfig b/arch/arm/plat-versatile/Kconfig index 49b8ef91584af2945d37121d4238167b5e1cb4a8..98b9b8e9f69879656c82392c3ba4eb11e2ca4d7f 100644 --- a/arch/arm/plat-versatile/Kconfig +++ b/arch/arm/plat-versatile/Kconfig @@ -1,8 +1,5 @@ if PLAT_VERSATILE -config PLAT_VERSATILE_CLOCK - bool - config PLAT_VERSATILE_SCHED_CLOCK bool diff --git a/arch/arm/plat-versatile/Makefile b/arch/arm/plat-versatile/Makefile index 03c4900ac3f4df1000f62d014e2ac22e7ad474ab..bff3ba889882e7debd1587ed0be2f5c7563ed9a4 100644 --- a/arch/arm/plat-versatile/Makefile +++ b/arch/arm/plat-versatile/Makefile @@ -1,5 +1,4 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include -obj-$(CONFIG_PLAT_VERSATILE_CLOCK) += clock.o obj-$(CONFIG_PLAT_VERSATILE_SCHED_CLOCK) += sched-clock.o obj-$(CONFIG_SMP) += headsmp.o platsmp.o diff --git a/arch/arm/plat-versatile/clock.c b/arch/arm/plat-versatile/clock.c deleted file mode 100644 index 5c8b6564fdc225ff49970cf5768f5cc2db1a733a..0000000000000000000000000000000000000000 --- a/arch/arm/plat-versatile/clock.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * linux/arch/arm/plat-versatile/clock.c - * - * Copyright (C) 2004 ARM Limited. - * Written by Deep Blue Solutions Limited. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include -#include - -#include - -#include - -int clk_enable(struct clk *clk) -{ - return 0; -} -EXPORT_SYMBOL(clk_enable); - -void clk_disable(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_disable); - -unsigned long clk_get_rate(struct clk *clk) -{ - return clk->rate; -} -EXPORT_SYMBOL(clk_get_rate); - -long clk_round_rate(struct clk *clk, unsigned long rate) -{ - long ret = -EIO; - if (clk->ops && clk->ops->round) - ret = clk->ops->round(clk, rate); - return ret; -} -EXPORT_SYMBOL(clk_round_rate); - -int clk_set_rate(struct clk *clk, unsigned long rate) -{ - int ret = -EIO; - if (clk->ops && clk->ops->set) - ret = clk->ops->set(clk, rate); - return ret; -} -EXPORT_SYMBOL(clk_set_rate); - -long icst_clk_round(struct clk *clk, unsigned long rate) -{ - struct icst_vco vco; - vco = icst_hz_to_vco(clk->params, rate); - return icst_hz(clk->params, vco); -} -EXPORT_SYMBOL(icst_clk_round); - -int icst_clk_set(struct clk *clk, unsigned long rate) -{ - struct icst_vco vco; - - vco = icst_hz_to_vco(clk->params, rate); - clk->rate = icst_hz(clk->params, vco); - clk->ops->setvco(clk, vco); - - return 0; -} -EXPORT_SYMBOL(icst_clk_set); diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index 21074f674bdeb707c137a9b87c2a65bde4bbb25a..efa77c146415b64d774a9811d30268e690d354d1 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -1,7 +1,22 @@ menu "Platform selection" +config ARCH_SUNXI + bool "Allwinner sunxi 64-bit SoC Family" + help + This enables support for Allwinner sunxi based SoCs like the A64. + +config ARCH_ALPINE + bool "Annapurna Labs Alpine platform" + select ALPINE_MSI + help + This enables support for the Annapurna Labs Alpine + Soc family. + config ARCH_BCM_IPROC bool "Broadcom iProc SoC Family" + select COMMON_CLK_IPROC + select PINCTRL + select ARCH_REQUIRE_GPIOLIB help This enables support for Broadcom iProc based SoCs @@ -14,21 +29,14 @@ config ARCH_BERLIN This enables support for Marvell Berlin SoC Family config ARCH_EXYNOS - bool - help - This enables support for Samsung Exynos SoC family - -config ARCH_EXYNOS7 - bool "ARMv8 based Samsung Exynos7" - select ARCH_EXYNOS + bool "ARMv8 based Samsung Exynos SoC family" select COMMON_CLK_SAMSUNG select HAVE_S3C2410_WATCHDOG if WATCHDOG select HAVE_S3C_RTC if RTC_CLASS select PINCTRL select PINCTRL_EXYNOS - help - This enables support for Samsung Exynos7 SoC family + This enables support for ARMv8 based Samsung Exynos SoC family. config ARCH_LAYERSCAPE bool "ARMv8 based Freescale Layerscape SoC family" @@ -37,6 +45,7 @@ config ARCH_LAYERSCAPE config ARCH_HISI bool "Hisilicon SoC Family" + select HISILICON_IRQ_MBIGEN help This enables support for Hisilicon ARMv8 SoC family @@ -48,6 +57,22 @@ config ARCH_MEDIATEK help Support for Mediatek MT65xx & MT81xx ARMv8 SoCs +config ARCH_MESON + bool "Amlogic Platforms" + help + This enables support for the Amlogic S905 SoCs. + +config ARCH_MVEBU + bool "Marvell EBU SoC Family" + select ARMADA_AP806_CORE_CLK + select ARMADA_AP806_RING_CLK + select MVEBU_ODMI + help + This enables support for Marvell EBU familly, including: + - Armada 3700 SoC Family + - Armada 7K SoC Family + - Armada 8K SoC Family + config ARCH_QCOM bool "Qualcomm Platforms" select PINCTRL @@ -60,6 +85,7 @@ config ARCH_ROCKCHIP select ARCH_REQUIRE_GPIOLIB select PINCTRL select PINCTRL_ROCKCHIP + select ROCKCHIP_TIMER help This enables support for the ARMv8 based Rockchip chipsets, like the RK3368. @@ -76,7 +102,9 @@ config ARCH_RENESAS bool "Renesas SoC Platforms" select ARCH_SHMOBILE select PINCTRL - select PM_GENERIC_DOMAINS if PM + select PM + select PM_GENERIC_DOMAINS + select RENESAS_IRQC help This enables support for the ARMv8 based Renesas SoCs. @@ -131,6 +159,11 @@ config ARCH_VEXPRESS This enables support for the ARMv8 software model (Versatile Express). +config ARCH_VULCAN + bool "Broadcom Vulcan SOC Family" + help + This enables support for Broadcom Vulcan SoC Family + config ARCH_XGENE bool "AppliedMicro X-Gene SOC Family" help diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile index f832b8a7453a307b351273a83e320e413e27ce4a..330fae966cf3a9435ac63124342835a8cf1bd536 100644 --- a/arch/arm64/boot/dts/Makefile +++ b/arch/arm64/boot/dts/Makefile @@ -1,5 +1,7 @@ +dts-dirs += al dts-dirs += altera dts-dirs += amd +dts-dirs += amlogic dts-dirs += apm dts-dirs += arm dts-dirs += broadcom diff --git a/arch/arm64/boot/dts/al/Makefile b/arch/arm64/boot/dts/al/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..8a6cde4f9b2388ce262792925795dd0c197945a2 --- /dev/null +++ b/arch/arm64/boot/dts/al/Makefile @@ -0,0 +1,5 @@ +dtb-$(CONFIG_ARCH_ALPINE) += alpine-v2-evp.dtb + +always := $(dtb-y) +subdir-y := $(dts-dirs) +clean-files := *.dtb diff --git a/arch/arm64/boot/dts/al/alpine-v2-evp.dts b/arch/arm64/boot/dts/al/alpine-v2-evp.dts new file mode 100644 index 0000000000000000000000000000000000000000..a079d7b3063ecf8c1d29d9c3bdebc102276e2b64 --- /dev/null +++ b/arch/arm64/boot/dts/al/alpine-v2-evp.dts @@ -0,0 +1,53 @@ +/* + * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Antoine Tenart + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "alpine-v2.dtsi" + +/ { + model = "Annapurna Labs Alpine v2 EVP"; + compatible = "al,alpine-v2-evp", "al,alpine-v2"; + + aliases { + serial0 = &uart0; + serial1 = &uart1; + serial2 = &uart2; + serial3 = &uart3; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&uart0 { status = "okay"; }; diff --git a/arch/arm64/boot/dts/al/alpine-v2.dtsi b/arch/arm64/boot/dts/al/alpine-v2.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..5b7bef6842568796b35bd0915b18d0b1b00d8158 --- /dev/null +++ b/arch/arm64/boot/dts/al/alpine-v2.dtsi @@ -0,0 +1,236 @@ +/* + * Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Antoine Tenart + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/dts-v1/; + +#include + +/ { + model = "Annapurna Labs Alpine v2"; + compatible = "al,alpine-v2"; + #address-cells = <2>; + #size-cells = <2>; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu@0 { + compatible = "arm,cortex-a57", "arm,armv8"; + device_type = "cpu"; + reg = <0x0 0x0>; + enable-method = "psci"; + }; + + cpu@1 { + compatible = "arm,cortex-a57", "arm,armv8"; + device_type = "cpu"; + reg = <0x0 0x1>; + enable-method = "psci"; + }; + + cpu@2 { + compatible = "arm,cortex-a57", "arm,armv8"; + device_type = "cpu"; + reg = <0x0 0x2>; + enable-method = "psci"; + }; + + cpu@3 { + compatible = "arm,cortex-a57", "arm,armv8"; + device_type = "cpu"; + reg = <0x0 0x3>; + enable-method = "psci"; + }; + }; + + psci { + compatible = "arm,psci-0.2", "arm,psci"; + method = "smc"; + cpu_suspend = <0x84000001>; + cpu_off = <0x84000002>; + cpu_on = <0x84000003>; + }; + + sbclk: sbclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <1000000>; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <2>; + + interrupt-parent = <&gic>; + ranges; + + timer { + compatible = "arm,armv8-timer"; + interrupts = , + , + , + ; + }; + + pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = , + , + , + ; + }; + + gic: gic@f0100000 { + compatible = "arm,gic-v3"; + reg = <0x0 0xf0200000 0x0 0x10000>, /* GIC Dist */ + <0x0 0xf0280000 0x0 0x200000>, /* GICR */ + <0x0 0xf0100000 0x0 0x2000>, /* GICC */ + <0x0 0xf0110000 0x0 0x2000>, /* GICV */ + <0x0 0xf0120000 0x0 0x2000>; /* GICH */ + interrupts = ; + interrupt-controller; + #interrupt-cells = <3>; + }; + + pci@fbc00000 { + compatible = "pci-host-ecam-generic"; + device_type = "pci"; + #size-cells = <2>; + #address-cells = <3>; + #interrupt-cells = <1>; + reg = <0x0 0xfbc00000 0x0 0x100000>; + interrupt-map-mask = <0xf800 0 0 7>; + /* add legacy interrupts for SATA only */ + interrupt-map = <0x4000 0 0 1 &gic 0 53 4>, + <0x4800 0 0 1 &gic 0 54 4>; + /* 32 bit non prefetchable memory space */ + ranges = <0x2000000 0x0 0xfe000000 0x0 0xfe000000 0x0 0x1000000>; + bus-range = <0x00 0x00>; + msi-parent = <&msix>; + }; + + msix: msix@fbe00000 { + compatible = "al,alpine-msix"; + reg = <0x0 0xfbe00000 0x0 0x100000>; + interrupt-controller; + msi-controller; + al,msi-base-spi = <160>; + al,msi-num-spis = <160>; + }; + + io-fabric { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x0 0xfc000000 0x2000000>; + + uart0: serial@1883000 { + compatible = "ns16550a"; + device_type = "serial"; + reg = <0x1883000 0x1000>; + interrupts = ; + clock-frequency = <500000000>; + reg-shift = <2>; + reg-io-width = <4>; + status = "disabled"; + }; + + uart1: serial@1884000 { + compatible = "ns16550a"; + device_type = "serial"; + reg = <0x1884000 0x1000>; + interrupts = ; + clock-frequency = <500000000>; + reg-shift = <2>; + reg-io-width = <4>; + status = "disabled"; + }; + + uart2: serial@1885000 { + compatible = "ns16550a"; + device_type = "serial"; + reg = <0x1885000 0x1000>; + interrupts = ; + clock-frequency = <500000000>; + reg-shift = <2>; + reg-io-width = <4>; + status = "disabled"; + }; + + uart3: serial@1886000 { + compatible = "ns16550a"; + device_type = "serial"; + reg = <0x1886000 0x1000>; + interrupts = ; + clock-frequency = <500000000>; + reg-shift = <2>; + reg-io-width = <4>; + status = "disabled"; + }; + + timer0: timer@1890000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x1890000 0x1000>; + interrupts = ; + clocks = <&sbclk>; + }; + + timer1: timer@1891000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x1891000 0x1000>; + interrupts = ; + clocks = <&sbclk>; + status = "disabled"; + }; + + timer2: timer@1892000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x1892000 0x1000>; + interrupts = ; + clocks = <&sbclk>; + status = "disabled"; + }; + + timer3: timer@1893000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x1893000 0x1000>; + interrupts = ; + clocks = <&sbclk>; + status = "disabled"; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/amd/Makefile b/arch/arm64/boot/dts/amd/Makefile index cfdf701e05dfd6f4baf5395289086f2e486337ce..ba84770f789f5cff754fbdf2ac3b7df54ebbadc7 100644 --- a/arch/arm64/boot/dts/amd/Makefile +++ b/arch/arm64/boot/dts/amd/Makefile @@ -1,4 +1,6 @@ -dtb-$(CONFIG_ARCH_SEATTLE) += amd-overdrive.dtb +dtb-$(CONFIG_ARCH_SEATTLE) += amd-overdrive.dtb \ + amd-overdrive-rev-b0.dtb amd-overdrive-rev-b1.dtb \ + husky.dtb always := $(dtb-y) subdir-y := $(dts-dirs) diff --git a/arch/arm64/boot/dts/amd/amd-overdrive-rev-b0.dts b/arch/arm64/boot/dts/amd/amd-overdrive-rev-b0.dts new file mode 100644 index 0000000000000000000000000000000000000000..8e3074a4947d0a6dd92f2071ce6617c7d8128429 --- /dev/null +++ b/arch/arm64/boot/dts/amd/amd-overdrive-rev-b0.dts @@ -0,0 +1,87 @@ +/* + * DTS file for AMD Seattle Overdrive Development Board + * Note: For Seattle Rev.B0 + * + * Copyright (C) 2015 Advanced Micro Devices, Inc. + */ + +/dts-v1/; + +/include/ "amd-seattle-soc.dtsi" + +/ { + model = "AMD Seattle (Rev.B0) Development Board (Overdrive)"; + compatible = "amd,seattle-overdrive", "amd,seattle"; + + chosen { + stdout-path = &serial0; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; +}; + +&ccp0 { + status = "ok"; + amd,zlib-support = <1>; +}; + +/** + * NOTE: In Rev.B, gpio0 is reserved. + */ +&gpio1 { + status = "ok"; +}; + +&gpio2 { + status = "ok"; +}; + +&gpio3 { + status = "ok"; +}; + +&gpio4 { + status = "ok"; +}; + +&i2c0 { + status = "ok"; +}; + +&i2c1 { + status = "ok"; +}; + +&pcie0 { + status = "ok"; +}; + +&spi0 { + status = "ok"; +}; + +&spi1 { + status = "ok"; + sdcard0: sdcard@0 { + compatible = "mmc-spi-slot"; + reg = <0>; + spi-max-frequency = <20000000>; + voltage-ranges = <3200 3400>; + pl022,hierarchy = <0>; + pl022,interface = <0>; + pl022,com-mode = <0x0>; + pl022,rx-level-trig = <0>; + pl022,tx-level-trig = <0>; + }; +}; + +&ipmi_kcs { + status = "ok"; +}; + +&smb0 { + /include/ "amd-seattle-xgbe-b.dtsi" +}; diff --git a/arch/arm64/boot/dts/amd/amd-overdrive-rev-b1.dts b/arch/arm64/boot/dts/amd/amd-overdrive-rev-b1.dts new file mode 100644 index 0000000000000000000000000000000000000000..ed5e043f37aaff472bb8e34adda3c9957b3f762b --- /dev/null +++ b/arch/arm64/boot/dts/amd/amd-overdrive-rev-b1.dts @@ -0,0 +1,91 @@ +/* + * DTS file for AMD Seattle Overdrive Development Board + * Note: For Seattle Rev.B1 + * + * Copyright (C) 2015 Advanced Micro Devices, Inc. + */ + +/dts-v1/; + +/include/ "amd-seattle-soc.dtsi" + +/ { + model = "AMD Seattle (Rev.B1) Development Board (Overdrive)"; + compatible = "amd,seattle-overdrive", "amd,seattle"; + + chosen { + stdout-path = &serial0; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; +}; + +&ccp0 { + status = "ok"; + amd,zlib-support = <1>; +}; + +/** + * NOTE: In Rev.B, gpio0 is reserved. + */ +&gpio1 { + status = "ok"; +}; + +&gpio2 { + status = "ok"; +}; + +&gpio3 { + status = "ok"; +}; + +&gpio4 { + status = "ok"; +}; + +&i2c0 { + status = "ok"; +}; + +&i2c1 { + status = "ok"; +}; + +&pcie0 { + status = "ok"; +}; + +&sata1 { + status = "ok"; +}; + +&spi0 { + status = "ok"; +}; + +&spi1 { + status = "ok"; + sdcard0: sdcard@0 { + compatible = "mmc-spi-slot"; + reg = <0>; + spi-max-frequency = <20000000>; + voltage-ranges = <3200 3400>; + pl022,hierarchy = <0>; + pl022,interface = <0>; + pl022,com-mode = <0x0>; + pl022,rx-level-trig = <0>; + pl022,tx-level-trig = <0>; + }; +}; + +&ipmi_kcs { + status = "ok"; +}; + +&smb0 { + /include/ "amd-seattle-xgbe-b.dtsi" +}; diff --git a/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi b/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi index 2874d92881fda36c8a9fdb2a2eb2d6900225134e..bd3adeac374f4d230d74470aaf58c1be839e809a 100644 --- a/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi +++ b/arch/arm64/boot/dts/amd/amd-seattle-soc.dtsi @@ -18,8 +18,8 @@ #size-cells = <2>; reg = <0x0 0xe1110000 0 0x1000>, <0x0 0xe112f000 0 0x2000>, - <0x0 0xe1140000 0 0x10000>, - <0x0 0xe1160000 0 0x10000>; + <0x0 0xe1140000 0 0x2000>, + <0x0 0xe1160000 0 0x2000>; interrupts = <1 9 0xf04>; ranges = <0 0 0 0xe1100000 0 0x100000>; v2m0: v2m@e0080000 { @@ -55,25 +55,47 @@ #size-cells = <2>; ranges; - /* DDR range is 40-bit addressing */ - dma-ranges = <0x80 0x0 0x80 0x0 0x7f 0xffffffff>; + /* + * dma-ranges is 40-bit address space containing: + * - GICv2m MSI register is at 0xe0080000 + * - DRAM range [0x8000000000 to 0xffffffffff] + */ + dma-ranges = <0x0 0x0 0x0 0x0 0x100 0x0>; /include/ "amd-seattle-clks.dtsi" sata0: sata@e0300000 { compatible = "snps,dwc-ahci"; - reg = <0 0xe0300000 0 0x800>; + reg = <0 0xe0300000 0 0xf0000>; interrupts = <0 355 4>; clocks = <&sataclk_333mhz>; dma-coherent; }; + /* This is for Rev B only */ + sata1: sata@e0d00000 { + status = "disabled"; + compatible = "snps,dwc-ahci"; + reg = <0 0xe0d00000 0 0xf0000>; + interrupts = <0 354 4>; + clocks = <&sataclk_333mhz>; + dma-coherent; + }; + i2c0: i2c@e1000000 { status = "disabled"; compatible = "snps,designware-i2c"; reg = <0 0xe1000000 0 0x1000>; interrupts = <0 357 4>; - clocks = <&uartspiclk_100mhz>; + clocks = <&miscclk_250mhz>; + }; + + i2c1: i2c@e0050000 { + status = "disabled"; + compatible = "snps,designware-i2c"; + reg = <0 0xe0050000 0 0x1000>; + interrupts = <0 340 4>; + clocks = <&miscclk_250mhz>; }; serial0: serial@e1010000 { @@ -87,7 +109,6 @@ spi0: ssp@e1020000 { status = "disabled"; compatible = "arm,pl022", "arm,primecell"; - #gpio-cells = <2>; reg = <0 0xe1020000 0 0x1000>; spi-controller; interrupts = <0 330 4>; @@ -98,7 +119,6 @@ spi1: ssp@e1030000 { status = "disabled"; compatible = "arm,pl022", "arm,primecell"; - #gpio-cells = <2>; reg = <0 0xe1030000 0 0x1000>; spi-controller; interrupts = <0 329 4>; @@ -109,7 +129,7 @@ #size-cells = <0>; }; - gpio0: gpio@e1040000 { + gpio0: gpio@e1040000 { /* Not available to OS for B0 */ status = "disabled"; compatible = "arm,pl061", "arm,primecell"; #gpio-cells = <2>; @@ -118,18 +138,59 @@ interrupts = <0 359 4>; interrupt-controller; #interrupt-cells = <2>; - clocks = <&uartspiclk_100mhz>; + clocks = <&miscclk_250mhz>; clock-names = "apb_pclk"; }; - gpio1: gpio@e1050000 { + gpio1: gpio@e1050000 { /* [0:7] */ status = "disabled"; compatible = "arm,pl061", "arm,primecell"; #gpio-cells = <2>; reg = <0 0xe1050000 0 0x1000>; gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; interrupts = <0 358 4>; - clocks = <&uartspiclk_100mhz>; + clocks = <&miscclk_250mhz>; + clock-names = "apb_pclk"; + }; + + gpio2: gpio@e0020000 { /* [8:15] */ + status = "disabled"; + compatible = "arm,pl061", "arm,primecell"; + #gpio-cells = <2>; + reg = <0 0xe0020000 0 0x1000>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <0 366 4>; + clocks = <&miscclk_250mhz>; + clock-names = "apb_pclk"; + }; + + gpio3: gpio@e0030000 { /* [16:23] */ + status = "disabled"; + compatible = "arm,pl061", "arm,primecell"; + #gpio-cells = <2>; + reg = <0 0xe0030000 0 0x1000>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <0 365 4>; + clocks = <&miscclk_250mhz>; + clock-names = "apb_pclk"; + }; + + gpio4: gpio@e0080000 { /* [24] */ + status = "disabled"; + compatible = "arm,pl061", "arm,primecell"; + #gpio-cells = <2>; + reg = <0 0xe0080000 0 0x1000>; + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <0 361 4>; + clocks = <&miscclk_250mhz>; clock-names = "apb_pclk"; }; @@ -159,7 +220,7 @@ <0x1000 0x0 0x0 0x4 &gic0 0x0 0x0 0x0 0x123 0x1>; dma-coherent; - dma-ranges = <0x43000000 0x80 0x0 0x80 0x0 0x7f 0xffffffff>; + dma-ranges = <0x43000000 0x0 0x0 0x0 0x0 0x100 0x0>; ranges = /* I/O Memory (size=64K) */ <0x01000000 0x00 0x00000000 0x00 0xefff0000 0x00 0x00010000>, @@ -168,5 +229,22 @@ /* 64-bit MMIO (size= 124G) */ <0x03000000 0x01 0x00000000 0x01 0x00000000 0x7f 0x00000000>; }; + + /* Perf CCN504 PMU */ + ccn: ccn@e8000000 { + compatible = "arm,ccn-504"; + reg = <0x0 0xe8000000 0 0x1000000>; + interrupts = <0 380 4>; + }; + + ipmi_kcs: kcs@e0010000 { + status = "disabled"; + compatible = "ipmi-kcs"; + device_type = "ipmi"; + reg = <0x0 0xe0010000 0 0x8>; + interrupts = <0 389 4>; + reg-size = <1>; + reg-spacing = <4>; + }; }; }; diff --git a/arch/arm64/boot/dts/amd/amd-seattle-xgbe-b.dtsi b/arch/arm64/boot/dts/amd/amd-seattle-xgbe-b.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..8e8631952497f81cbf53cfd7d15e4623013b9a8f --- /dev/null +++ b/arch/arm64/boot/dts/amd/amd-seattle-xgbe-b.dtsi @@ -0,0 +1,117 @@ +/* + * DTS file for AMD Seattle XGBE (RevB) + * + * Copyright (C) 2015 Advanced Micro Devices, Inc. + */ + + xgmacclk0_dma_250mhz: clk250mhz_0 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <250000000>; + clock-output-names = "xgmacclk0_dma_250mhz"; + }; + + xgmacclk0_ptp_250mhz: clk250mhz_1 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <250000000>; + clock-output-names = "xgmacclk0_ptp_250mhz"; + }; + + xgmacclk1_dma_250mhz: clk250mhz_2 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <250000000>; + clock-output-names = "xgmacclk1_dma_250mhz"; + }; + + xgmacclk1_ptp_250mhz: clk250mhz_3 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <250000000>; + clock-output-names = "xgmacclk1_ptp_250mhz"; + }; + + xgmac0: xgmac@e0700000 { + compatible = "amd,xgbe-seattle-v1a"; + reg = <0 0xe0700000 0 0x80000>, + <0 0xe0780000 0 0x80000>, + <0 0xe1240800 0 0x00400>, /* SERDES RX/TX0 */ + <0 0xe1250000 0 0x00060>, /* SERDES IR 1/2 */ + <0 0xe12500f8 0 0x00004>; /* SERDES IR 2/2 */ + interrupts = <0 325 4>, + <0 346 1>, <0 347 1>, <0 348 1>, <0 349 1>, + <0 323 4>; + amd,per-channel-interrupt; + amd,speed-set = <0>; + amd,serdes-blwc = <1>, <1>, <0>; + amd,serdes-cdr-rate = <2>, <2>, <7>; + amd,serdes-pq-skew = <10>, <10>, <18>; + amd,serdes-tx-amp = <0>, <0>, <0>; + amd,serdes-dfe-tap-config = <3>, <3>, <3>; + amd,serdes-dfe-tap-enable = <0>, <0>, <7>; + mac-address = [ 02 A1 A2 A3 A4 A5 ]; + clocks = <&xgmacclk0_dma_250mhz>, <&xgmacclk0_ptp_250mhz>; + clock-names = "dma_clk", "ptp_clk"; + phy-mode = "xgmii"; + #stream-id-cells = <16>; + dma-coherent; + }; + + xgmac1: xgmac@e0900000 { + compatible = "amd,xgbe-seattle-v1a"; + reg = <0 0xe0900000 0 0x80000>, + <0 0xe0980000 0 0x80000>, + <0 0xe1240c00 0 0x00400>, /* SERDES RX/TX1 */ + <0 0xe1250080 0 0x00060>, /* SERDES IR 1/2 */ + <0 0xe12500fc 0 0x00004>; /* SERDES IR 2/2 */ + interrupts = <0 324 4>, + <0 341 1>, <0 342 1>, <0 343 1>, <0 344 1>, + <0 322 4>; + amd,per-channel-interrupt; + amd,speed-set = <0>; + amd,serdes-blwc = <1>, <1>, <0>; + amd,serdes-cdr-rate = <2>, <2>, <7>; + amd,serdes-pq-skew = <10>, <10>, <18>; + amd,serdes-tx-amp = <0>, <0>, <0>; + amd,serdes-dfe-tap-config = <3>, <3>, <3>; + amd,serdes-dfe-tap-enable = <0>, <0>, <7>; + mac-address = [ 02 B1 B2 B3 B4 B5 ]; + clocks = <&xgmacclk1_dma_250mhz>, <&xgmacclk1_ptp_250mhz>; + clock-names = "dma_clk", "ptp_clk"; + phy-mode = "xgmii"; + #stream-id-cells = <16>; + dma-coherent; + }; + + xgmac0_smmu: smmu@e0600000 { + compatible = "arm,mmu-401"; + reg = <0 0xe0600000 0 0x10000>; + #global-interrupts = <1>; + interrupts = /* Uses combined intr for both + * global and context + */ + <0 336 4>, + <0 336 4>; + + mmu-masters = <&xgmac0 + 0 1 2 3 4 5 6 7 + 16 17 18 19 20 21 22 23 + >; + }; + + xgmac1_smmu: smmu@e0800000 { + compatible = "arm,mmu-401"; + reg = <0 0xe0800000 0 0x10000>; + #global-interrupts = <1>; + interrupts = /* Uses combined intr for both + * global and context + */ + <0 335 4>, + <0 335 4>; + + mmu-masters = <&xgmac1 + 0 1 2 3 4 5 6 7 + 16 17 18 19 20 21 22 23 + >; + }; diff --git a/arch/arm64/boot/dts/amd/husky.dts b/arch/arm64/boot/dts/amd/husky.dts new file mode 100644 index 0000000000000000000000000000000000000000..1381d4b2bf1bbdf19d90d446f977c597ec38ad97 --- /dev/null +++ b/arch/arm64/boot/dts/amd/husky.dts @@ -0,0 +1,83 @@ +/* + * DTS file for AMD/Linaro 96Boards Enterprise Edition Server (Husky) Board + * Note: Based-on AMD Seattle Rev.B0 + * + * Copyright (C) 2015 Advanced Micro Devices, Inc. + */ + +/dts-v1/; + +/include/ "amd-seattle-soc.dtsi" + +/ { + model = "Linaro 96Boards Enterprise Edition Server (Husky) Board"; + compatible = "amd,seattle-overdrive", "amd,seattle"; + + chosen { + stdout-path = &serial0; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; +}; + +&ccp0 { + status = "ok"; + amd,zlib-support = <1>; +}; + +/** + * NOTE: In Rev.B, gpio0 is reserved. + */ +&gpio1 { + status = "ok"; +}; + +&gpio2 { + status = "ok"; +}; + +&gpio3 { + status = "ok"; +}; + +&gpio4 { + status = "ok"; +}; + +&i2c0 { + status = "ok"; +}; + +&i2c1 { + status = "ok"; +}; + +&pcie0 { + status = "ok"; +}; + +&spi0 { + status = "ok"; +}; + +&spi1 { + status = "ok"; + sdcard0: sdcard@0 { + compatible = "mmc-spi-slot"; + reg = <0>; + spi-max-frequency = <20000000>; + voltage-ranges = <3200 3400>; + pl022,hierarchy = <0>; + pl022,interface = <0>; + pl022,com-mode = <0x0>; + pl022,rx-level-trig = <0>; + pl022,tx-level-trig = <0>; + }; +}; + +&smb0 { + /include/ "amd-seattle-xgbe-b.dtsi" +}; diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..eb672f38f89ea4086c2576f6b06ea13a4a7fbd2f --- /dev/null +++ b/arch/arm64/boot/dts/amlogic/Makefile @@ -0,0 +1,7 @@ +dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-vega-s95-pro.dtb +dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-vega-s95-meta.dtb +dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-vega-s95-telos.dtb + +always := $(dtb-y) +subdir-y := $(dts-dirs) +clean-files := *.dtb diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95-meta.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95-meta.dts new file mode 100644 index 0000000000000000000000000000000000000000..399aff9e79754dd795257a6940979d97da957606 --- /dev/null +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95-meta.dts @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016 Andreas Färber + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library 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 library 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include "meson-gxbb-vega-s95.dtsi" + +/ { + compatible = "tronsmart,vega-s95-meta", "tronsmart,vega-s95", "amlogic,meson-gxbb"; + model = "Tronsmart Vega S95 Meta"; + + memory { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; + }; +}; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95-pro.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95-pro.dts new file mode 100644 index 0000000000000000000000000000000000000000..ac5a241b5ec2f4b586eb1da8f51f1242382660e8 --- /dev/null +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95-pro.dts @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016 Andreas Färber + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library 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 library 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include "meson-gxbb-vega-s95.dtsi" + +/ { + compatible = "tronsmart,vega-s95-pro", "tronsmart,vega-s95", "amlogic,meson-gxbb"; + model = "Tronsmart Vega S95 Pro"; + + memory { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x40000000>; + }; +}; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95-telos.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95-telos.dts new file mode 100644 index 0000000000000000000000000000000000000000..fff7bfa2aa39b04ef2c7a0c04068db33e642d1df --- /dev/null +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95-telos.dts @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016 Andreas Färber + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library 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 library 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include "meson-gxbb-vega-s95.dtsi" + +/ { + compatible = "tronsmart,vega-s95-telos", "tronsmart,vega-s95", "amlogic,meson-gxbb"; + model = "Tronsmart Vega S95 Telos"; + + memory { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; + }; +}; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..c1fa2667ec5c6d6753734b5f986c4a4e64c4e515 --- /dev/null +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-vega-s95.dtsi @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016 Andreas Färber + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library 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 library 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "meson-gxbb.dtsi" + +/ { + compatible = "tronsmart,vega-s95", "amlogic,meson-gxbb"; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&uart_AO { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..eaa0a455373496645bbd1ca11748d11bc11da807 --- /dev/null +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2016 Andreas Färber + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library 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 library 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include + +/ { + compatible = "amlogic,meson-gxbb"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + aliases { + serial0 = &uart_AO; + serial1 = &uart_A; + }; + + cpus { + #address-cells = <0x2>; + #size-cells = <0x0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0x0 0x0>; + enable-method = "psci"; + }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0x0 0x1>; + enable-method = "psci"; + }; + + cpu2: cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0x0 0x2>; + enable-method = "psci"; + }; + + cpu3: cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0x0 0x3>; + enable-method = "psci"; + }; + }; + + arm-pmu { + compatible = "arm,cortex-a53-pmu"; + interrupts = , + , + , + ; + interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = , + , + , + ; + }; + + xtal: xtal-clk { + compatible = "fixed-clock"; + clock-frequency = <24000000>; + clock-output-names = "xtal"; + #clock-cells = <0>; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + cbus: cbus@c1100000 { + compatible = "simple-bus"; + reg = <0x0 0xc1100000 0x0 0x100000>; + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x0 0x0 0x0 0xc1100000 0x0 0x100000>; + + uart_A: serial@84c0 { + compatible = "amlogic,meson-uart"; + reg = <0x0 0x084c0 0x0 0x14>; + interrupts = ; + clocks = <&xtal>; + status = "disabled"; + }; + }; + + gic: interrupt-controller@c4301000 { + compatible = "arm,gic-400"; + reg = <0x0 0xc4301000 0 0x1000>, + <0x0 0xc4302000 0 0x2000>, + <0x0 0xc4304000 0 0x2000>, + <0x0 0xc4306000 0 0x2000>; + interrupt-controller; + interrupts = ; + #interrupt-cells = <3>; + #address-cells = <0>; + }; + + aobus: aobus@c8100000 { + compatible = "simple-bus"; + reg = <0x0 0xc8100000 0x0 0x100000>; + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x0 0x0 0x0 0xc8100000 0x0 0x100000>; + + uart_AO: serial@4c0 { + compatible = "amlogic,meson-uart"; + reg = <0x0 0x004c0 0x0 0x14>; + interrupts = ; + clocks = <&xtal>; + status = "disabled"; + }; + }; + + apb: apb@d0000000 { + compatible = "simple-bus"; + reg = <0x0 0xd0000000 0x0 0x200000>; + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x0 0x0 0x0 0xd0000000 0x0 0x200000>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/apm/apm-merlin.dts b/arch/arm64/boot/dts/apm/apm-merlin.dts index e5ba8d5d0cae6c4b15c2e655b87c1d6abd24b7c2..387c6a8d0da9fb4d810b21066be6b5516fa88cc1 100644 --- a/arch/arm64/boot/dts/apm/apm-merlin.dts +++ b/arch/arm64/boot/dts/apm/apm-merlin.dts @@ -30,7 +30,8 @@ label = "POWER"; linux,code = <116>; linux,input-type = <0x1>; - interrupts = <0x0 0x28 0x1>; + interrupt-parent = <&sbgpio>; + interrupts = <0x0 0x1>; }; }; diff --git a/arch/arm64/boot/dts/apm/apm-mustang.dts b/arch/arm64/boot/dts/apm/apm-mustang.dts index 178aef2cdd096f63c838a35e3d1a51e9b2d7a13e..44db32ec5e9c34802c1447592f89083617c5d78a 100644 --- a/arch/arm64/boot/dts/apm/apm-mustang.dts +++ b/arch/arm64/boot/dts/apm/apm-mustang.dts @@ -30,7 +30,8 @@ label = "POWER"; linux,code = <116>; linux,input-type = <0x1>; - interrupts = <0x0 0x2d 0x1>; + interrupt-parent = <&sbgpio>; + interrupts = <0x5 0x1>; }; }; diff --git a/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi b/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi index 5d87a3dc44b86090bc2b275e0cbe14d75f75aadc..a055a5d443b76b83dde3c5f68739e54f9bb9ac2d 100644 --- a/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi +++ b/arch/arm64/boot/dts/apm/apm-shadowcat.dtsi @@ -224,7 +224,7 @@ }; socpll: socpll@17000120 { - compatible = "apm,xgene-socpll-clock"; + compatible = "apm,xgene-socpll-v2-clock"; #clock-cells = <1>; clocks = <&refclk 0>; reg = <0x0 0x17000120 0x0 0x1000>; @@ -453,6 +453,25 @@ }; }; + mailbox: mailbox@10540000 { + compatible = "apm,xgene-slimpro-mbox"; + reg = <0x0 0x10540000 0x0 0x8000>; + #mbox-cells = <1>; + interrupts = <0x0 0x0 0x4 + 0x0 0x1 0x4 + 0x0 0x2 0x4 + 0x0 0x3 0x4 + 0x0 0x4 0x4 + 0x0 0x5 0x4 + 0x0 0x6 0x4 + 0x0 0x7 0x4>; + }; + + i2cslimpro { + compatible = "apm,xgene-slimpro-i2c"; + mboxes = <&mailbox 0>; + }; + serial0: serial@10600000 { device_type = "serial"; compatible = "ns16550"; @@ -598,6 +617,12 @@ <0x0 0x2d 0x1>, <0x0 0x2e 0x1>, <0x0 0x2f 0x1>; + interrupt-parent = <&gic>; + #interrupt-cells = <2>; + interrupt-controller; + apm,nr-gpios = <22>; + apm,nr-irqs = <8>; + apm,irq-start = <8>; }; sgenet0: ethernet@1f610000 { @@ -621,7 +646,13 @@ <0x0 0x1f600000 0x0 0Xd100>, <0x0 0x20000000 0x0 0X220000>; interrupts = <0 108 4>, - <0 109 4>; + <0 109 4>, + <0 110 4>, + <0 111 4>, + <0 112 4>, + <0 113 4>, + <0 114 4>, + <0 115 4>; port-id = <1>; dma-coherent; clocks = <&xge1clk 0>; diff --git a/arch/arm64/boot/dts/apm/apm-storm.dtsi b/arch/arm64/boot/dts/apm/apm-storm.dtsi index 3e40bd469cea13c010c08c6434ae1d0aa9df81af..ae4a173df493a08c092b67a2aba4d08121ce8d55 100644 --- a/arch/arm64/boot/dts/apm/apm-storm.dtsi +++ b/arch/arm64/boot/dts/apm/apm-storm.dtsi @@ -697,6 +697,25 @@ msi-parent = <&msi>; }; + mailbox: mailbox@10540000 { + compatible = "apm,xgene-slimpro-mbox"; + reg = <0x0 0x10540000 0x0 0xa000>; + #mbox-cells = <1>; + interrupts = <0x0 0x0 0x4>, + <0x0 0x1 0x4>, + <0x0 0x2 0x4>, + <0x0 0x3 0x4>, + <0x0 0x4 0x4>, + <0x0 0x5 0x4>, + <0x0 0x6 0x4>, + <0x0 0x7 0x4>; + }; + + i2cslimpro { + compatible = "apm,xgene-slimpro-i2c"; + mboxes = <&mailbox 0>; + }; + serial0: serial@1c020000 { status = "disabled"; device_type = "serial"; @@ -889,6 +908,9 @@ <0x0 0x2b 0x1>, <0x0 0x2c 0x1>, <0x0 0x2d 0x1>; + interrupt-parent = <&gic>; + #interrupt-cells = <2>; + interrupt-controller; }; rtc: rtc@10510000 { @@ -964,7 +986,13 @@ <0x0 0x18000000 0x0 0X200>; reg-names = "enet_csr", "ring_csr", "ring_cmd"; interrupts = <0x0 0x60 0x4>, - <0x0 0x61 0x4>; + <0x0 0x61 0x4>, + <0x0 0x62 0x4>, + <0x0 0x63 0x4>, + <0x0 0x64 0x4>, + <0x0 0x65 0x4>, + <0x0 0x66 0x4>, + <0x0 0x67 0x4>; dma-coherent; clocks = <&xge0clk 0>; /* mac address will be overwritten by the bootloader */ diff --git a/arch/arm64/boot/dts/arm/Makefile b/arch/arm64/boot/dts/arm/Makefile index bb3c072096760836ad004b1e9bd485ecfaeb9b24..75cc2aa101013adbb4108738a4dc30778e834ab6 100644 --- a/arch/arm64/boot/dts/arm/Makefile +++ b/arch/arm64/boot/dts/arm/Makefile @@ -1,5 +1,5 @@ -dtb-$(CONFIG_ARCH_VEXPRESS) += foundation-v8.dtb -dtb-$(CONFIG_ARCH_VEXPRESS) += juno.dtb juno-r1.dtb +dtb-$(CONFIG_ARCH_VEXPRESS) += foundation-v8.dtb foundation-v8-gicv3.dtb +dtb-$(CONFIG_ARCH_VEXPRESS) += juno.dtb juno-r1.dtb juno-r2.dtb dtb-$(CONFIG_ARCH_VEXPRESS) += rtsm_ve-aemv8a.dtb dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2f-1xv7-ca53x2.dtb diff --git a/arch/arm64/boot/dts/arm/foundation-v8-gicv3.dts b/arch/arm64/boot/dts/arm/foundation-v8-gicv3.dts new file mode 100644 index 0000000000000000000000000000000000000000..35588dfa095c21ba19662ef015bcb583d94afb4a --- /dev/null +++ b/arch/arm64/boot/dts/arm/foundation-v8-gicv3.dts @@ -0,0 +1,30 @@ +/* + * ARM Ltd. + * + * ARMv8 Foundation model DTS (GICv3 configuration) + */ + +#include "foundation-v8.dtsi" + +/ { + gic: interrupt-controller@2f000000 { + compatible = "arm,gic-v3"; + #interrupt-cells = <3>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + interrupt-controller; + reg = <0x0 0x2f000000 0x0 0x10000>, + <0x0 0x2f100000 0x0 0x200000>, + <0x0 0x2c000000 0x0 0x2000>, + <0x0 0x2c010000 0x0 0x2000>, + <0x0 0x2c02f000 0x0 0x2000>; + interrupts = <1 9 4>; + + its: its@2f020000 { + compatible = "arm,gic-v3-its"; + msi-controller; + reg = <0x0 0x2f020000 0x0 0x20000>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/arm/foundation-v8.dts b/arch/arm64/boot/dts/arm/foundation-v8.dts index 4eac8dcea423e2ff50b0101555fa475507769c91..71168077312d5cbbb282a9a1fdfaf8eda8ae0bb3 100644 --- a/arch/arm64/boot/dts/arm/foundation-v8.dts +++ b/arch/arm64/boot/dts/arm/foundation-v8.dts @@ -1,240 +1,21 @@ /* * ARM Ltd. * - * ARMv8 Foundation model DTS + * ARMv8 Foundation model DTS (GICv2 configuration) */ -/dts-v1/; - -/memreserve/ 0x80000000 0x00010000; +#include "foundation-v8.dtsi" / { - model = "Foundation-v8A"; - compatible = "arm,foundation-aarch64", "arm,vexpress"; - interrupt-parent = <&gic>; - #address-cells = <2>; - #size-cells = <2>; - - chosen { }; - - aliases { - serial0 = &v2m_serial0; - serial1 = &v2m_serial1; - serial2 = &v2m_serial2; - serial3 = &v2m_serial3; - }; - - cpus { - #address-cells = <2>; - #size-cells = <0>; - - cpu@0 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x0>; - enable-method = "spin-table"; - cpu-release-addr = <0x0 0x8000fff8>; - next-level-cache = <&L2_0>; - }; - cpu@1 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x1>; - enable-method = "spin-table"; - cpu-release-addr = <0x0 0x8000fff8>; - next-level-cache = <&L2_0>; - }; - cpu@2 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x2>; - enable-method = "spin-table"; - cpu-release-addr = <0x0 0x8000fff8>; - next-level-cache = <&L2_0>; - }; - cpu@3 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x3>; - enable-method = "spin-table"; - cpu-release-addr = <0x0 0x8000fff8>; - next-level-cache = <&L2_0>; - }; - - L2_0: l2-cache0 { - compatible = "cache"; - }; - }; - - memory@80000000 { - device_type = "memory"; - reg = <0x00000000 0x80000000 0 0x80000000>, - <0x00000008 0x80000000 0 0x80000000>; - }; - gic: interrupt-controller@2c001000 { compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic"; #interrupt-cells = <3>; - #address-cells = <0>; + #address-cells = <2>; interrupt-controller; reg = <0x0 0x2c001000 0 0x1000>, - <0x0 0x2c002000 0 0x1000>, + <0x0 0x2c002000 0 0x2000>, <0x0 0x2c004000 0 0x2000>, <0x0 0x2c006000 0 0x2000>; interrupts = <1 9 0xf04>; }; - - timer { - compatible = "arm,armv8-timer"; - interrupts = <1 13 0xf08>, - <1 14 0xf08>, - <1 11 0xf08>, - <1 10 0xf08>; - clock-frequency = <100000000>; - }; - - pmu { - compatible = "arm,armv8-pmuv3"; - interrupts = <0 60 4>, - <0 61 4>, - <0 62 4>, - <0 63 4>; - }; - - smb { - compatible = "arm,vexpress,v2m-p1", "simple-bus"; - arm,v2m-memory-map = "rs1"; - #address-cells = <2>; /* SMB chipselect number and offset */ - #size-cells = <1>; - - ranges = <0 0 0 0x08000000 0x04000000>, - <1 0 0 0x14000000 0x04000000>, - <2 0 0 0x18000000 0x04000000>, - <3 0 0 0x1c000000 0x04000000>, - <4 0 0 0x0c000000 0x04000000>, - <5 0 0 0x10000000 0x04000000>; - - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 63>; - interrupt-map = <0 0 0 &gic 0 0 4>, - <0 0 1 &gic 0 1 4>, - <0 0 2 &gic 0 2 4>, - <0 0 3 &gic 0 3 4>, - <0 0 4 &gic 0 4 4>, - <0 0 5 &gic 0 5 4>, - <0 0 6 &gic 0 6 4>, - <0 0 7 &gic 0 7 4>, - <0 0 8 &gic 0 8 4>, - <0 0 9 &gic 0 9 4>, - <0 0 10 &gic 0 10 4>, - <0 0 11 &gic 0 11 4>, - <0 0 12 &gic 0 12 4>, - <0 0 13 &gic 0 13 4>, - <0 0 14 &gic 0 14 4>, - <0 0 15 &gic 0 15 4>, - <0 0 16 &gic 0 16 4>, - <0 0 17 &gic 0 17 4>, - <0 0 18 &gic 0 18 4>, - <0 0 19 &gic 0 19 4>, - <0 0 20 &gic 0 20 4>, - <0 0 21 &gic 0 21 4>, - <0 0 22 &gic 0 22 4>, - <0 0 23 &gic 0 23 4>, - <0 0 24 &gic 0 24 4>, - <0 0 25 &gic 0 25 4>, - <0 0 26 &gic 0 26 4>, - <0 0 27 &gic 0 27 4>, - <0 0 28 &gic 0 28 4>, - <0 0 29 &gic 0 29 4>, - <0 0 30 &gic 0 30 4>, - <0 0 31 &gic 0 31 4>, - <0 0 32 &gic 0 32 4>, - <0 0 33 &gic 0 33 4>, - <0 0 34 &gic 0 34 4>, - <0 0 35 &gic 0 35 4>, - <0 0 36 &gic 0 36 4>, - <0 0 37 &gic 0 37 4>, - <0 0 38 &gic 0 38 4>, - <0 0 39 &gic 0 39 4>, - <0 0 40 &gic 0 40 4>, - <0 0 41 &gic 0 41 4>, - <0 0 42 &gic 0 42 4>; - - ethernet@2,02000000 { - compatible = "smsc,lan91c111"; - reg = <2 0x02000000 0x10000>; - interrupts = <15>; - }; - - v2m_clk24mhz: clk24mhz { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <24000000>; - clock-output-names = "v2m:clk24mhz"; - }; - - v2m_refclk1mhz: refclk1mhz { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <1000000>; - clock-output-names = "v2m:refclk1mhz"; - }; - - v2m_refclk32khz: refclk32khz { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <32768>; - clock-output-names = "v2m:refclk32khz"; - }; - - iofpga@3,00000000 { - compatible = "arm,amba-bus", "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0 3 0 0x200000>; - - v2m_sysreg: sysreg@010000 { - compatible = "arm,vexpress-sysreg"; - reg = <0x010000 0x1000>; - }; - - v2m_serial0: uart@090000 { - compatible = "arm,pl011", "arm,primecell"; - reg = <0x090000 0x1000>; - interrupts = <5>; - clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; - clock-names = "uartclk", "apb_pclk"; - }; - - v2m_serial1: uart@0a0000 { - compatible = "arm,pl011", "arm,primecell"; - reg = <0x0a0000 0x1000>; - interrupts = <6>; - clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; - clock-names = "uartclk", "apb_pclk"; - }; - - v2m_serial2: uart@0b0000 { - compatible = "arm,pl011", "arm,primecell"; - reg = <0x0b0000 0x1000>; - interrupts = <7>; - clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; - clock-names = "uartclk", "apb_pclk"; - }; - - v2m_serial3: uart@0c0000 { - compatible = "arm,pl011", "arm,primecell"; - reg = <0x0c0000 0x1000>; - interrupts = <8>; - clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; - clock-names = "uartclk", "apb_pclk"; - }; - - virtio_block@0130000 { - compatible = "virtio,mmio"; - reg = <0x130000 0x200>; - interrupts = <42>; - }; - }; - }; }; diff --git a/arch/arm64/boot/dts/arm/foundation-v8.dtsi b/arch/arm64/boot/dts/arm/foundation-v8.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..7cfa8e414e7f5111d9c676ee3bc9c6c2fbe8941d --- /dev/null +++ b/arch/arm64/boot/dts/arm/foundation-v8.dtsi @@ -0,0 +1,236 @@ +/* + * ARM Ltd. + * + * ARMv8 Foundation model DTS + */ + +/dts-v1/; + +/memreserve/ 0x80000000 0x00010000; + +/ { + model = "Foundation-v8A"; + compatible = "arm,foundation-aarch64", "arm,vexpress"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + chosen { }; + + aliases { + serial0 = &v2m_serial0; + serial1 = &v2m_serial1; + serial2 = &v2m_serial2; + serial3 = &v2m_serial3; + }; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x0>; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0x8000fff8>; + next-level-cache = <&L2_0>; + }; + cpu@1 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x1>; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0x8000fff8>; + next-level-cache = <&L2_0>; + }; + cpu@2 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x2>; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0x8000fff8>; + next-level-cache = <&L2_0>; + }; + cpu@3 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x3>; + enable-method = "spin-table"; + cpu-release-addr = <0x0 0x8000fff8>; + next-level-cache = <&L2_0>; + }; + + L2_0: l2-cache0 { + compatible = "cache"; + }; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x00000000 0x80000000 0 0x80000000>, + <0x00000008 0x80000000 0 0x80000000>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <1 13 0xf08>, + <1 14 0xf08>, + <1 11 0xf08>, + <1 10 0xf08>; + clock-frequency = <100000000>; + }; + + pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = <0 60 4>, + <0 61 4>, + <0 62 4>, + <0 63 4>; + }; + + watchdog@2a440000 { + compatible = "arm,sbsa-gwdt"; + reg = <0x0 0x2a440000 0 0x1000>, + <0x0 0x2a450000 0 0x1000>; + interrupts = <0 27 4>; + timeout-sec = <30>; + }; + + smb@08000000 { + compatible = "arm,vexpress,v2m-p1", "simple-bus"; + arm,v2m-memory-map = "rs1"; + #address-cells = <2>; /* SMB chipselect number and offset */ + #size-cells = <1>; + + ranges = <0 0 0 0x08000000 0x04000000>, + <1 0 0 0x14000000 0x04000000>, + <2 0 0 0x18000000 0x04000000>, + <3 0 0 0x1c000000 0x04000000>, + <4 0 0 0x0c000000 0x04000000>, + <5 0 0 0x10000000 0x04000000>; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 63>; + interrupt-map = <0 0 0 &gic 0 0 0 0 4>, + <0 0 1 &gic 0 0 0 1 4>, + <0 0 2 &gic 0 0 0 2 4>, + <0 0 3 &gic 0 0 0 3 4>, + <0 0 4 &gic 0 0 0 4 4>, + <0 0 5 &gic 0 0 0 5 4>, + <0 0 6 &gic 0 0 0 6 4>, + <0 0 7 &gic 0 0 0 7 4>, + <0 0 8 &gic 0 0 0 8 4>, + <0 0 9 &gic 0 0 0 9 4>, + <0 0 10 &gic 0 0 0 10 4>, + <0 0 11 &gic 0 0 0 11 4>, + <0 0 12 &gic 0 0 0 12 4>, + <0 0 13 &gic 0 0 0 13 4>, + <0 0 14 &gic 0 0 0 14 4>, + <0 0 15 &gic 0 0 0 15 4>, + <0 0 16 &gic 0 0 0 16 4>, + <0 0 17 &gic 0 0 0 17 4>, + <0 0 18 &gic 0 0 0 18 4>, + <0 0 19 &gic 0 0 0 19 4>, + <0 0 20 &gic 0 0 0 20 4>, + <0 0 21 &gic 0 0 0 21 4>, + <0 0 22 &gic 0 0 0 22 4>, + <0 0 23 &gic 0 0 0 23 4>, + <0 0 24 &gic 0 0 0 24 4>, + <0 0 25 &gic 0 0 0 25 4>, + <0 0 26 &gic 0 0 0 26 4>, + <0 0 27 &gic 0 0 0 27 4>, + <0 0 28 &gic 0 0 0 28 4>, + <0 0 29 &gic 0 0 0 29 4>, + <0 0 30 &gic 0 0 0 30 4>, + <0 0 31 &gic 0 0 0 31 4>, + <0 0 32 &gic 0 0 0 32 4>, + <0 0 33 &gic 0 0 0 33 4>, + <0 0 34 &gic 0 0 0 34 4>, + <0 0 35 &gic 0 0 0 35 4>, + <0 0 36 &gic 0 0 0 36 4>, + <0 0 37 &gic 0 0 0 37 4>, + <0 0 38 &gic 0 0 0 38 4>, + <0 0 39 &gic 0 0 0 39 4>, + <0 0 40 &gic 0 0 0 40 4>, + <0 0 41 &gic 0 0 0 41 4>, + <0 0 42 &gic 0 0 0 42 4>; + + ethernet@2,02000000 { + compatible = "smsc,lan91c111"; + reg = <2 0x02000000 0x10000>; + interrupts = <15>; + }; + + v2m_clk24mhz: clk24mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + clock-output-names = "v2m:clk24mhz"; + }; + + v2m_refclk1mhz: refclk1mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <1000000>; + clock-output-names = "v2m:refclk1mhz"; + }; + + v2m_refclk32khz: refclk32khz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + clock-output-names = "v2m:refclk32khz"; + }; + + iofpga@3,00000000 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 3 0 0x200000>; + + v2m_sysreg: sysreg@010000 { + compatible = "arm,vexpress-sysreg"; + reg = <0x010000 0x1000>; + }; + + v2m_serial0: uart@090000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x090000 0x1000>; + interrupts = <5>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + v2m_serial1: uart@0a0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0a0000 0x1000>; + interrupts = <6>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + v2m_serial2: uart@0b0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0b0000 0x1000>; + interrupts = <7>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + v2m_serial3: uart@0c0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0c0000 0x1000>; + interrupts = <8>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + virtio_block@0130000 { + compatible = "virtio,mmio"; + reg = <0x130000 0x200>; + interrupts = <42>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi index e5b59ca9debb1916764746bb168d969572e17771..68ccc39a7a666f58f78318c48eb1b36acb814702 100644 --- a/arch/arm64/boot/dts/arm/juno-base.dtsi +++ b/arch/arm64/boot/dts/arm/juno-base.dtsi @@ -75,6 +75,28 @@ }; }; + pcie_ctlr: pcie-controller@40000000 { + compatible = "arm,juno-r1-pcie", "plda,xpressrich3-axi", "pci-host-ecam-generic"; + device_type = "pci"; + reg = <0 0x40000000 0 0x10000000>; /* ECAM config space */ + bus-range = <0 255>; + linux,pci-domain = <0>; + #address-cells = <3>; + #size-cells = <2>; + dma-coherent; + ranges = <0x01000000 0x00 0x5f800000 0x00 0x5f800000 0x0 0x00800000>, + <0x02000000 0x00 0x50000000 0x00 0x50000000 0x0 0x08000000>, + <0x42000000 0x40 0x00000000 0x40 0x00000000 0x1 0x00000000>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &gic 0 0 0 136 4>, + <0 0 0 2 &gic 0 0 0 137 4>, + <0 0 0 3 &gic 0 0 0 138 4>, + <0 0 0 4 &gic 0 0 0 139 4>; + msi-parent = <&v2m_0>; + status = "disabled"; + }; + scpi { compatible = "arm,scpi"; mboxes = <&mailbox 1>; @@ -83,17 +105,17 @@ clocks { compatible = "arm,scpi-clocks"; - scpi_dvfs: scpi_clocks@0 { + scpi_dvfs: scpi-dvfs { compatible = "arm,scpi-dvfs-clocks"; #clock-cells = <1>; clock-indices = <0>, <1>, <2>; clock-output-names = "atlclk", "aplclk","gpuclk"; }; - scpi_clk: scpi_clocks@3 { + scpi_clk: scpi-clk { compatible = "arm,scpi-variable-clocks"; #clock-cells = <1>; - clock-indices = <3>, <4>; - clock-output-names = "pxlclk0", "pxlclk1"; + clock-indices = <3>; + clock-output-names = "pxlclk"; }; }; @@ -124,6 +146,34 @@ clock-names = "apb_pclk"; }; + hdlcd@7ff50000 { + compatible = "arm,hdlcd"; + reg = <0 0x7ff50000 0 0x1000>; + interrupts = ; + clocks = <&scpi_clk 3>; + clock-names = "pxlclk"; + + port { + hdlcd1_output: hdlcd1-endpoint { + remote-endpoint = <&tda998x_1_input>; + }; + }; + }; + + hdlcd@7ff60000 { + compatible = "arm,hdlcd"; + reg = <0 0x7ff60000 0 0x1000>; + interrupts = ; + clocks = <&scpi_clk 3>; + clock-names = "pxlclk"; + + port { + hdlcd0_output: hdlcd0-endpoint { + remote-endpoint = <&tda998x_0_input>; + }; + }; + }; + soc_uart0: uart@7ff80000 { compatible = "arm,pl011", "arm,primecell"; reg = <0x0 0x7ff80000 0x0 0x1000>; @@ -142,14 +192,24 @@ i2c-sda-hold-time-ns = <500>; clocks = <&soc_smc50mhz>; - dvi0: dvi-transmitter@70 { + hdmi-transmitter@70 { compatible = "nxp,tda998x"; reg = <0x70>; + port { + tda998x_0_input: tda998x-0-endpoint { + remote-endpoint = <&hdlcd0_output>; + }; + }; }; - dvi1: dvi-transmitter@71 { + hdmi-transmitter@71 { compatible = "nxp,tda998x"; reg = <0x71>; + port { + tda998x_1_input: tda998x-1-endpoint { + remote-endpoint = <&hdlcd1_output>; + }; + }; }; }; @@ -183,7 +243,7 @@ <0x00000008 0x80000000 0x1 0x80000000>; }; - smb { + smb@08000000 { compatible = "simple-bus"; #address-cells = <2>; #size-cells = <1>; diff --git a/arch/arm64/boot/dts/arm/juno-motherboard.dtsi b/arch/arm64/boot/dts/arm/juno-motherboard.dtsi index 413f1b9ebcd45669f97def0a27d49547959f6028..3ad4c30006115c95485f5e0174d5da257f5d52ed 100644 --- a/arch/arm64/boot/dts/arm/juno-motherboard.dtsi +++ b/arch/arm64/boot/dts/arm/juno-motherboard.dtsi @@ -46,7 +46,7 @@ arm,vexpress,site = <0>; arm,v2m-memory-map = "rs1"; - mb_fixed_3v3: fixedregulator@0 { + mb_fixed_3v3: mcc-sb-3v3 { compatible = "regulator-fixed"; regulator-name = "MCC_SB_3V3"; regulator-min-microvolt = <3300000>; @@ -59,42 +59,42 @@ #address-cells = <1>; #size-cells = <0>; - button@1 { + power-button { debounce_interval = <50>; wakeup-source; linux,code = <116>; label = "POWER"; gpios = <&iofpga_gpio0 0 0x4>; }; - button@2 { + home-button { debounce_interval = <50>; wakeup-source; linux,code = <102>; label = "HOME"; gpios = <&iofpga_gpio0 1 0x4>; }; - button@3 { + rlock-button { debounce_interval = <50>; wakeup-source; linux,code = <152>; label = "RLOCK"; gpios = <&iofpga_gpio0 2 0x4>; }; - button@4 { + vol-up-button { debounce_interval = <50>; wakeup-source; linux,code = <115>; label = "VOL+"; gpios = <&iofpga_gpio0 3 0x4>; }; - button@5 { + vol-down-button { debounce_interval = <50>; wakeup-source; linux,code = <114>; label = "VOL-"; gpios = <&iofpga_gpio0 4 0x4>; }; - button@6 { + nmi-button { debounce_interval = <50>; wakeup-source; linux,code = <99>; @@ -139,7 +139,7 @@ }; iofpga@3,00000000 { - compatible = "arm,amba-bus", "simple-bus"; + compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges = <0 3 0 0x200000>; @@ -159,7 +159,7 @@ compatible = "syscon", "simple-mfd"; reg = <0x010000 0x1000>; - led@08.0 { + led0 { compatible = "register-bit-led"; offset = <0x08>; mask = <0x01>; @@ -167,7 +167,7 @@ linux,default-trigger = "heartbeat"; default-state = "on"; }; - led@08.1 { + led1 { compatible = "register-bit-led"; offset = <0x08>; mask = <0x02>; @@ -175,7 +175,7 @@ linux,default-trigger = "mmc0"; default-state = "off"; }; - led@08.2 { + led2 { compatible = "register-bit-led"; offset = <0x08>; mask = <0x04>; @@ -183,7 +183,7 @@ linux,default-trigger = "cpu0"; default-state = "off"; }; - led@08.3 { + led3 { compatible = "register-bit-led"; offset = <0x08>; mask = <0x08>; @@ -191,7 +191,7 @@ linux,default-trigger = "cpu1"; default-state = "off"; }; - led@08.4 { + led4 { compatible = "register-bit-led"; offset = <0x08>; mask = <0x10>; @@ -199,7 +199,7 @@ linux,default-trigger = "cpu2"; default-state = "off"; }; - led@08.5 { + led5 { compatible = "register-bit-led"; offset = <0x08>; mask = <0x20>; @@ -207,14 +207,14 @@ linux,default-trigger = "cpu3"; default-state = "off"; }; - led@08.6 { + led6 { compatible = "register-bit-led"; offset = <0x08>; mask = <0x40>; label = "vexpress:6"; default-state = "off"; }; - led@08.7 { + led7 { compatible = "register-bit-led"; offset = <0x08>; mask = <0x80>; diff --git a/arch/arm64/boot/dts/arm/juno-r1.dts b/arch/arm64/boot/dts/arm/juno-r1.dts index 8826f834f54f25ca1b1912e9903af68d8c37453b..d95d9e7e2dc0899eb5201c7f49316c1e26003356 100644 --- a/arch/arm64/boot/dts/arm/juno-r1.dts +++ b/arch/arm64/boot/dts/arm/juno-r1.dts @@ -172,29 +172,12 @@ }; #include "juno-base.dtsi" - - pcie-controller@40000000 { - compatible = "arm,juno-r1-pcie", "plda,xpressrich3-axi", "pci-host-ecam-generic"; - device_type = "pci"; - reg = <0 0x40000000 0 0x10000000>; /* ECAM config space */ - bus-range = <0 255>; - linux,pci-domain = <0>; - #address-cells = <3>; - #size-cells = <2>; - dma-coherent; - ranges = <0x01000000 0x00 0x5f800000 0x00 0x5f800000 0x0 0x00800000>, - <0x02000000 0x00 0x50000000 0x00 0x50000000 0x0 0x08000000>, - <0x42000000 0x40 0x00000000 0x40 0x00000000 0x1 0x00000000>; - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0 0 0 1 &gic 0 0 0 136 4>, - <0 0 0 2 &gic 0 0 0 137 4>, - <0 0 0 3 &gic 0 0 0 138 4>, - <0 0 0 4 &gic 0 0 0 139 4>; - msi-parent = <&v2m_0>; - }; }; &memtimer { status = "okay"; }; + +&pcie_ctlr { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/arm/juno-r2.dts b/arch/arm64/boot/dts/arm/juno-r2.dts new file mode 100644 index 0000000000000000000000000000000000000000..88ecd6182b67676f2b464715ced23a5397817408 --- /dev/null +++ b/arch/arm64/boot/dts/arm/juno-r2.dts @@ -0,0 +1,183 @@ +/* + * ARM Ltd. Juno Platform + * + * Copyright (c) 2015 ARM Ltd. + * + * This file is licensed under a dual GPLv2 or BSD license. + */ + +/dts-v1/; + +#include + +/ { + model = "ARM Juno development board (r2)"; + compatible = "arm,juno-r2", "arm,juno", "arm,vexpress"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + aliases { + serial0 = &soc_uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu-map { + cluster0 { + core0 { + cpu = <&A72_0>; + }; + core1 { + cpu = <&A72_1>; + }; + }; + + cluster1 { + core0 { + cpu = <&A53_0>; + }; + core1 { + cpu = <&A53_1>; + }; + core2 { + cpu = <&A53_2>; + }; + core3 { + cpu = <&A53_3>; + }; + }; + }; + + idle-states { + entry-method = "arm,psci"; + + CPU_SLEEP_0: cpu-sleep-0 { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x0010000>; + local-timer-stop; + entry-latency-us = <300>; + exit-latency-us = <1200>; + min-residency-us = <2000>; + }; + + CLUSTER_SLEEP_0: cluster-sleep-0 { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x1010000>; + local-timer-stop; + entry-latency-us = <300>; + exit-latency-us = <1200>; + min-residency-us = <2500>; + }; + }; + + A72_0: cpu@0 { + compatible = "arm,cortex-a72","arm,armv8"; + reg = <0x0 0x0>; + device_type = "cpu"; + enable-method = "psci"; + next-level-cache = <&A72_L2>; + clocks = <&scpi_dvfs 0>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + }; + + A72_1: cpu@1 { + compatible = "arm,cortex-a72","arm,armv8"; + reg = <0x0 0x1>; + device_type = "cpu"; + enable-method = "psci"; + next-level-cache = <&A72_L2>; + clocks = <&scpi_dvfs 0>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + }; + + A53_0: cpu@100 { + compatible = "arm,cortex-a53","arm,armv8"; + reg = <0x0 0x100>; + device_type = "cpu"; + enable-method = "psci"; + next-level-cache = <&A53_L2>; + clocks = <&scpi_dvfs 1>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + }; + + A53_1: cpu@101 { + compatible = "arm,cortex-a53","arm,armv8"; + reg = <0x0 0x101>; + device_type = "cpu"; + enable-method = "psci"; + next-level-cache = <&A53_L2>; + clocks = <&scpi_dvfs 1>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + }; + + A53_2: cpu@102 { + compatible = "arm,cortex-a53","arm,armv8"; + reg = <0x0 0x102>; + device_type = "cpu"; + enable-method = "psci"; + next-level-cache = <&A53_L2>; + clocks = <&scpi_dvfs 1>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + }; + + A53_3: cpu@103 { + compatible = "arm,cortex-a53","arm,armv8"; + reg = <0x0 0x103>; + device_type = "cpu"; + enable-method = "psci"; + next-level-cache = <&A53_L2>; + clocks = <&scpi_dvfs 1>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + }; + + A72_L2: l2-cache0 { + compatible = "cache"; + }; + + A53_L2: l2-cache1 { + compatible = "cache"; + }; + }; + + pmu_a72 { + compatible = "arm,cortex-a72-pmu"; + interrupts = , + ; + interrupt-affinity = <&A72_0>, + <&A72_1>; + }; + + pmu_a53 { + compatible = "arm,cortex-a53-pmu"; + interrupts = , + , + , + ; + interrupt-affinity = <&A53_0>, + <&A53_1>, + <&A53_2>, + <&A53_3>; + }; + + #include "juno-base.dtsi" +}; + +&memtimer { + status = "okay"; +}; + +&pcie_ctlr { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts b/arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts index 20addabbd127c89acf70399c5605dfedccb55203..a852e28a40e17761b5b393b21d9798eb9a80cd8b 100644 --- a/arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts +++ b/arch/arm64/boot/dts/arm/rtsm_ve-aemv8a.dts @@ -104,7 +104,7 @@ <0 63 4>; }; - smb { + smb@08000000 { compatible = "simple-bus"; #address-cells = <2>; diff --git a/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi b/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi index 88a7583ed7a72c3c8536b3c54ad356462cea0feb..161ac98418a301ef11eafb7dd3539280cad4e9d9 100644 --- a/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi +++ b/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi @@ -55,7 +55,7 @@ }; iofpga@3,00000000 { - compatible = "arm,amba-bus", "simple-bus"; + compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges = <0 3 0 0x200000>; @@ -226,7 +226,7 @@ }; }; - v2m_fixed_3v3: fixedregulator@0 { + v2m_fixed_3v3: v2m-3v3 { compatible = "regulator-fixed"; regulator-name = "3V3"; regulator-min-microvolt = <3300000>; @@ -238,7 +238,7 @@ compatible = "arm,vexpress,config-bus"; arm,vexpress,config-bridge = <&v2m_sysreg>; - v2m_oscclk1: osc@1 { + v2m_oscclk1: oscclk1 { /* CLCD clock */ compatible = "arm,vexpress-osc"; arm,vexpress-sysreg,func = <1 1>; @@ -247,27 +247,27 @@ clock-output-names = "v2m:oscclk1"; }; - reset@0 { + reset { compatible = "arm,vexpress-reset"; arm,vexpress-sysreg,func = <5 0>; }; - muxfpga@0 { + muxfpga { compatible = "arm,vexpress-muxfpga"; arm,vexpress-sysreg,func = <7 0>; }; - shutdown@0 { + shutdown { compatible = "arm,vexpress-shutdown"; arm,vexpress-sysreg,func = <8 0>; }; - reboot@0 { + reboot { compatible = "arm,vexpress-reboot"; arm,vexpress-sysreg,func = <9 0>; }; - dvimode@0 { + dvimode { compatible = "arm,vexpress-dvimode"; arm,vexpress-sysreg,func = <11 0>; }; diff --git a/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts b/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts index bb3c26d1154dab80648e7724e173bf1272617bb3..e3a171162bb4775a8aceebc54662252c18288076 100644 --- a/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts +++ b/arch/arm64/boot/dts/arm/vexpress-v2f-1xv7-ca53x2.dts @@ -93,7 +93,7 @@ compatible = "arm,vexpress,config-bus"; arm,vexpress,config-bridge = <&v2m_sysreg>; - smbclk: osc@4 { + smbclk: smclk { /* SMC clock */ compatible = "arm,vexpress-osc"; arm,vexpress-sysreg,func = <1 4>; @@ -102,7 +102,7 @@ clock-output-names = "smclk"; }; - volt@0 { + volt-vio { /* VIO to expansion board above */ compatible = "arm,vexpress-volt"; arm,vexpress-sysreg,func = <2 0>; @@ -112,7 +112,7 @@ regulator-always-on; }; - volt@1 { + volt-12v { /* 12V from power connector J6 */ compatible = "arm,vexpress-volt"; arm,vexpress-sysreg,func = <2 1>; @@ -120,7 +120,7 @@ regulator-always-on; }; - temp@0 { + temp-fpga { /* FPGA temperature */ compatible = "arm,vexpress-temp"; arm,vexpress-sysreg,func = <4 0>; @@ -128,7 +128,7 @@ }; }; - smb { + smb@08000000 { compatible = "simple-bus"; #address-cells = <2>; diff --git a/arch/arm64/boot/dts/broadcom/Makefile b/arch/arm64/boot/dts/broadcom/Makefile index e21fe66f183727321d28a3b5fa0696bc4feed6cf..bec1f8b36f60111c1530bcac23b4f00838d1fc3f 100644 --- a/arch/arm64/boot/dts/broadcom/Makefile +++ b/arch/arm64/boot/dts/broadcom/Makefile @@ -1,4 +1,5 @@ dtb-$(CONFIG_ARCH_BCM_IPROC) += ns2-svk.dtb +dtb-$(CONFIG_ARCH_VULCAN) += vulcan-eval.dtb always := $(dtb-y) subdir-y := $(dts-dirs) diff --git a/arch/arm64/boot/dts/broadcom/ns2-svk.dts b/arch/arm64/boot/dts/broadcom/ns2-svk.dts index 6bb3d4d9efa91cd534ed67c2196afdae49530699..ce0ab84e0f2da2e998c7ab210543a7e04907553c 100644 --- a/arch/arm64/boot/dts/broadcom/ns2-svk.dts +++ b/arch/arm64/boot/dts/broadcom/ns2-svk.dts @@ -52,6 +52,14 @@ }; }; +&pcie0 { + status = "ok"; +}; + +&pcie4 { + status = "ok"; +}; + &i2c0 { status = "ok"; }; @@ -64,6 +72,10 @@ status = "ok"; }; +&sdio0 { + status = "ok"; +}; + &nand { nandcs@0 { compatible = "brcm,nandcs"; diff --git a/arch/arm64/boot/dts/broadcom/ns2.dtsi b/arch/arm64/boot/dts/broadcom/ns2.dtsi index a510d3a8e6473485af20bca9ec5d1eda4f98a846..6f81c9d7fb0671ca1bf142542701182fad406faa 100644 --- a/arch/arm64/boot/dts/broadcom/ns2.dtsi +++ b/arch/arm64/boot/dts/broadcom/ns2.dtsi @@ -137,6 +137,80 @@ }; }; + pcie0: pcie@20020000 { + compatible = "brcm,iproc-pcie"; + reg = <0 0x20020000 0 0x1000>; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &gic GIC_SPI 281 IRQ_TYPE_NONE>; + + linux,pci-domain = <0>; + + bus-range = <0x00 0xff>; + + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges = <0x83000000 0 0x00000000 0 0x00000000 0 0x20000000>; + + brcm,pcie-ob; + brcm,pcie-ob-oarr-size; + brcm,pcie-ob-axi-offset = <0x00000000>; + brcm,pcie-ob-window-size = <256>; + + status = "disabled"; + + msi-parent = <&msi0>; + msi0: msi@20020000 { + compatible = "brcm,iproc-msi"; + msi-controller; + interrupt-parent = <&gic>; + interrupts = , + , + , + ; + brcm,num-eq-region = <1>; + brcm,num-msi-msg-region = <1>; + }; + }; + + pcie4: pcie@50020000 { + compatible = "brcm,iproc-pcie"; + reg = <0 0x50020000 0 0x1000>; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0>; + interrupt-map = <0 0 0 0 &gic GIC_SPI 305 IRQ_TYPE_NONE>; + + linux,pci-domain = <4>; + + bus-range = <0x00 0xff>; + + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges = <0x83000000 0 0x00000000 0 0x30000000 0 0x20000000>; + + brcm,pcie-ob; + brcm,pcie-ob-oarr-size; + brcm,pcie-ob-axi-offset = <0x30000000>; + brcm,pcie-ob-window-size = <256>; + + status = "disabled"; + + msi-parent = <&msi4>; + msi4: msi@50020000 { + compatible = "brcm,iproc-msi"; + msi-controller; + interrupt-parent = <&gic>; + interrupts = , + , + , + ; + }; + }; + soc: soc { compatible = "simple-bus"; #address-cells = <1>; @@ -256,6 +330,46 @@ <0x65260000 0x1000>; }; + timer0: timer@66030000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x66030000 0x1000>; + interrupts = ; + clocks = <&iprocslow>, + <&iprocslow>, + <&iprocslow>; + clock-names = "timer1", "timer2", "apb_pclk"; + }; + + timer1: timer@66040000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x66040000 0x1000>; + interrupts = ; + clocks = <&iprocslow>, + <&iprocslow>, + <&iprocslow>; + clock-names = "timer1", "timer2", "apb_pclk"; + }; + + timer2: timer@66050000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x66050000 0x1000>; + interrupts = ; + clocks = <&iprocslow>, + <&iprocslow>, + <&iprocslow>; + clock-names = "timer1", "timer2", "apb_pclk"; + }; + + timer3: timer@66060000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x66060000 0x1000>; + interrupts = ; + clocks = <&iprocslow>, + <&iprocslow>, + <&iprocslow>; + clock-names = "timer1", "timer2", "apb_pclk"; + }; + i2c0: i2c@66080000 { compatible = "brcm,iproc-i2c"; reg = <0x66080000 0x100>; @@ -266,6 +380,14 @@ status = "disabled"; }; + wdt0: watchdog@66090000 { + compatible = "arm,sp805", "arm,primecell"; + reg = <0x66090000 0x1000>; + interrupts = ; + clocks = <&iprocslow>, <&iprocslow>; + clock-names = "wdogclk", "apb_pclk"; + }; + i2c1: i2c@660b0000 { compatible = "brcm,iproc-i2c"; reg = <0x660b0000 0x100>; @@ -291,6 +413,24 @@ reg = <0x66220000 0x28>; }; + sdio0: sdhci@66420000 { + compatible = "brcm,sdhci-iproc-cygnus"; + reg = <0x66420000 0x100>; + interrupts = ; + bus-width = <8>; + clocks = <&genpll_sw BCM_NS2_GENPLL_SW_SDIO_CLK>; + status = "disabled"; + }; + + sdio1: sdhci@66430000 { + compatible = "brcm,sdhci-iproc-cygnus"; + reg = <0x66430000 0x100>; + interrupts = ; + bus-width = <8>; + clocks = <&genpll_sw BCM_NS2_GENPLL_SW_SDIO_CLK>; + status = "disabled"; + }; + nand: nand@66460000 { compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; reg = <0x66460000 0x600>, diff --git a/arch/arm64/boot/dts/broadcom/vulcan-eval.dts b/arch/arm64/boot/dts/broadcom/vulcan-eval.dts new file mode 100644 index 0000000000000000000000000000000000000000..9ee8d3da0e3f17923a94c381b76c65e33666c5e9 --- /dev/null +++ b/arch/arm64/boot/dts/broadcom/vulcan-eval.dts @@ -0,0 +1,33 @@ +/* + * dts file for Broadcom (BRCM) Vulcan Evaluation Platform + * + * Copyright (c) 2013-2016 Broadcom + * + * 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. + */ + +/dts-v1/; + +#include "vulcan.dtsi" + +/ { + model = "Broadcom Vulcan Eval Platform"; + compatible = "brcm,vulcan-eval", "brcm,vulcan-soc"; + + memory { + device_type = "memory"; + reg = <0x00000000 0x80000000 0x0 0x80000000>, /* 2G @ 2G */ + <0x00000008 0x80000000 0x0 0x80000000>; /* 2G @ 34G */ + }; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; diff --git a/arch/arm64/boot/dts/broadcom/vulcan.dtsi b/arch/arm64/boot/dts/broadcom/vulcan.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..c49b5a85809c5bc96d48f3b8799b965a8f96e860 --- /dev/null +++ b/arch/arm64/boot/dts/broadcom/vulcan.dtsi @@ -0,0 +1,144 @@ +/* + * dtsi file for Broadcom (BRCM) Vulcan processor + * + * Copyright (c) 2013-2016 Broadcom + * Author: Zi Shen Lim + * + * 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 + +/ { + model = "Broadcom Vulcan"; + compatible = "brcm,vulcan-soc"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + /* just 4 cpus now, 128 needed in full config */ + cpus { + #address-cells = <0x2>; + #size-cells = <0x0>; + + cpu@0 { + device_type = "cpu"; + compatible = "brcm,vulcan", "arm,armv8"; + reg = <0x0 0x0>; + enable-method = "psci"; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "brcm,vulcan", "arm,armv8"; + reg = <0x0 0x1>; + enable-method = "psci"; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "brcm,vulcan", "arm,armv8"; + reg = <0x0 0x2>; + enable-method = "psci"; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "brcm,vulcan", "arm,armv8"; + reg = <0x0 0x3>; + enable-method = "psci"; + }; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; + + gic: interrupt-controller@400080000 { + compatible = "arm,gic-v3"; + #interrupt-cells = <3>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + interrupt-controller; + #redistributor-regions = <1>; + reg = <0x04 0x00080000 0x0 0x20000>, /* GICD */ + <0x04 0x01000000 0x0 0x1000000>; /* GICR */ + interrupts = ; + + gicits: gic-its@40010000 { + compatible = "arm,gic-v3-its"; + msi-controller; + reg = <0x04 0x00100000 0x0 0x20000>; /* GIC ITS */ + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = , + , + , + ; + }; + + pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = ; /* PMU overflow */ + }; + + clk125mhz: uart_clk125mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <125000000>; + clock-output-names = "clk125mhz"; + }; + + pci { + compatible = "pci-host-ecam-generic"; + device_type = "pci"; + #interrupt-cells = <1>; + #address-cells = <3>; + #size-cells = <2>; + + /* ECAM at 0x3000_0000 - 0x4000_0000 */ + reg = <0x0 0x30000000 0x0 0x10000000>; + reg-names = "PCI ECAM"; + + /* IO 0x4000_0000 - 0x4001_0000 */ + ranges = <0x01000000 0 0x40000000 0 0x40000000 0 0x00010000 + /* MEM 0x4800_0000 - 0x5000_0000 */ + 0x02000000 0 0x48000000 0 0x48000000 0 0x08000000 + /* MEM64 pref 0x6_0000_0000 - 0x7_0000_0000 */ + 0x43000000 6 0x00000000 6 0x00000000 1 0x00000000>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = + /* addr pin ic icaddr icintr */ + <0 0 0 1 &gic 0 0 GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH + 0 0 0 2 &gic 0 0 GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH + 0 0 0 3 &gic 0 0 GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH + 0 0 0 4 &gic 0 0 GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>; + msi-parent = <&gicits>; + dma-coherent; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + uart0: serial@402020000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x04 0x02020000 0x0 0x1000>; + interrupt-parent = <&gic>; + interrupts = ; + clocks = <&clk125mhz>; + clock-names = "apb_pclk"; + }; + }; + +}; diff --git a/arch/arm64/boot/dts/cavium/thunder-88xx.dtsi b/arch/arm64/boot/dts/cavium/thunder-88xx.dtsi index 9cb7cf94284a66b07619f4b2a4ab042c803c5f03..2eb9b225f0bcc193c27520a332a7e68ff55410dc 100644 --- a/arch/arm64/boot/dts/cavium/thunder-88xx.dtsi +++ b/arch/arm64/boot/dts/cavium/thunder-88xx.dtsi @@ -360,6 +360,11 @@ <1 10 0xff01>; }; + pmu { + compatible = "cavium,thunder-pmu", "arm,armv8-pmuv3"; + interrupts = <1 7 4>; + }; + soc { compatible = "simple-bus"; #address-cells = <2>; diff --git a/arch/arm64/boot/dts/exynos/Makefile b/arch/arm64/boot/dts/exynos/Makefile index 20310e5b6d6f0226ed26c19ce1726da3dc6b8036..50c9b9383cfa6121e28f6006769983b1f33e0268 100644 --- a/arch/arm64/boot/dts/exynos/Makefile +++ b/arch/arm64/boot/dts/exynos/Makefile @@ -1,4 +1,4 @@ -dtb-$(CONFIG_ARCH_EXYNOS7) += exynos7-espresso.dtb +dtb-$(CONFIG_ARCH_EXYNOS) += exynos7-espresso.dtb always := $(dtb-y) subdir-y := $(dts-dirs) diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi index 42a61549afd45e63c33c1d8a5f402a998049a88c..be72bf5b58b5b919849f682c97001131e8f186b4 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a.dtsi @@ -407,6 +407,7 @@ reg = <0x0 0x2f00000 0x0 0x10000>; interrupts = <0 60 0x4>; dr_mode = "host"; + snps,quirk-frame-length-adjustment = <0x20>; }; usb1: usb3@3000000 { @@ -414,6 +415,7 @@ reg = <0x0 0x3000000 0x0 0x10000>; interrupts = <0 61 0x4>; dr_mode = "host"; + snps,quirk-frame-length-adjustment = <0x20>; }; usb2: usb3@3100000 { @@ -421,6 +423,7 @@ reg = <0x0 0x3100000 0x0 0x10000>; interrupts = <0 63 0x4>; dr_mode = "host"; + snps,quirk-frame-length-adjustment = <0x20>; }; sata: sata@3200000 { diff --git a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi index 2b23d03606839795c1cb3687e28fc117ffeec83f..9d746c69a789658c33ef2f3b72f72e6c48149d7f 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls2080a.dtsi @@ -456,7 +456,8 @@ }; pcie@3400000 { - compatible = "fsl,ls2080a-pcie", "snps,dw-pcie"; + compatible = "fsl,ls2080a-pcie", "fsl,ls2085a-pcie", + "snps,dw-pcie"; reg = <0x00 0x03400000 0x0 0x00100000 /* controller registers */ 0x10 0x00000000 0x0 0x00002000>; /* configuration space */ reg-names = "regs", "config"; @@ -479,7 +480,8 @@ }; pcie@3500000 { - compatible = "fsl,ls2080a-pcie", "snps,dw-pcie"; + compatible = "fsl,ls2080a-pcie", "fsl,ls2085a-pcie", + "snps,dw-pcie"; reg = <0x00 0x03500000 0x0 0x00100000 /* controller registers */ 0x12 0x00000000 0x0 0x00002000>; /* configuration space */ reg-names = "regs", "config"; @@ -502,7 +504,8 @@ }; pcie@3600000 { - compatible = "fsl,ls2080a-pcie", "snps,dw-pcie"; + compatible = "fsl,ls2080a-pcie", "fsl,ls2085a-pcie", + "snps,dw-pcie"; reg = <0x00 0x03600000 0x0 0x00100000 /* controller registers */ 0x14 0x00000000 0x0 0x00002000>; /* configuration space */ reg-names = "regs", "config"; @@ -525,7 +528,8 @@ }; pcie@3700000 { - compatible = "fsl,ls2080a-pcie", "snps,dw-pcie"; + compatible = "fsl,ls2080a-pcie", "fsl,ls2085a-pcie", + "snps,dw-pcie"; reg = <0x00 0x03700000 0x0 0x00100000 /* controller registers */ 0x16 0x00000000 0x0 0x00002000>; /* configuration space */ reg-names = "regs", "config"; @@ -569,6 +573,7 @@ reg = <0x0 0x3100000 0x0 0x10000>; interrupts = <0 80 0x4>; /* Level high type */ dr_mode = "host"; + snps,quirk-frame-length-adjustment = <0x20>; }; usb1: usb3@3110000 { @@ -577,6 +582,7 @@ reg = <0x0 0x3110000 0x0 0x10000>; interrupts = <0 81 0x4>; /* Level high type */ dr_mode = "host"; + snps,quirk-frame-length-adjustment = <0x20>; }; ccn@4000000 { diff --git a/arch/arm64/boot/dts/hisilicon/hip05-d02.dts b/arch/arm64/boot/dts/hisilicon/hip05-d02.dts index ae34e250456fe462bacfbd8daaf93ab84d71a884..e9436c0d81f7b484ef171a6c84e655a3765b0b92 100644 --- a/arch/arm64/boot/dts/hisilicon/hip05-d02.dts +++ b/arch/arm64/boot/dts/hisilicon/hip05-d02.dts @@ -11,6 +11,7 @@ /dts-v1/; +#include #include "hip05.dtsi" / { @@ -29,8 +30,25 @@ chosen { stdout-path = "serial0:115200n8"; }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + pwrbutton { + label = "Power Button"; + gpios = <&porta 8 GPIO_ACTIVE_LOW>; + linux,code = <116>; + debounce-interval = <0>; + }; + }; }; &uart0 { status = "ok"; }; + +&peri_gpio0 { + status = "ok"; +}; diff --git a/arch/arm64/boot/dts/hisilicon/hip05.dtsi b/arch/arm64/boot/dts/hisilicon/hip05.dtsi index c1ea999c7be14cf2e1bd9a42e2397ecf2ea4c793..6319ff3b03ea4d7d411d47a5fecffc4b5a18c80c 100644 --- a/arch/arm64/boot/dts/hisilicon/hip05.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hip05.dtsi @@ -90,6 +90,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x20000>; enable-method = "psci"; + next-level-cache = <&cluster0_l2>; }; cpu1: cpu@20001 { @@ -97,6 +98,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x20001>; enable-method = "psci"; + next-level-cache = <&cluster0_l2>; }; cpu2: cpu@20002 { @@ -104,6 +106,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x20002>; enable-method = "psci"; + next-level-cache = <&cluster0_l2>; }; cpu3: cpu@20003 { @@ -111,6 +114,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x20003>; enable-method = "psci"; + next-level-cache = <&cluster0_l2>; }; cpu4: cpu@20100 { @@ -118,6 +122,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x20100>; enable-method = "psci"; + next-level-cache = <&cluster1_l2>; }; cpu5: cpu@20101 { @@ -125,6 +130,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x20101>; enable-method = "psci"; + next-level-cache = <&cluster1_l2>; }; cpu6: cpu@20102 { @@ -132,6 +138,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x20102>; enable-method = "psci"; + next-level-cache = <&cluster1_l2>; }; cpu7: cpu@20103 { @@ -139,6 +146,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x20103>; enable-method = "psci"; + next-level-cache = <&cluster1_l2>; }; cpu8: cpu@20200 { @@ -146,6 +154,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x20200>; enable-method = "psci"; + next-level-cache = <&cluster2_l2>; }; cpu9: cpu@20201 { @@ -153,6 +162,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x20201>; enable-method = "psci"; + next-level-cache = <&cluster2_l2>; }; cpu10: cpu@20202 { @@ -160,6 +170,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x20202>; enable-method = "psci"; + next-level-cache = <&cluster2_l2>; }; cpu11: cpu@20203 { @@ -167,6 +178,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x20203>; enable-method = "psci"; + next-level-cache = <&cluster2_l2>; }; cpu12: cpu@20300 { @@ -174,6 +186,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x20300>; enable-method = "psci"; + next-level-cache = <&cluster3_l2>; }; cpu13: cpu@20301 { @@ -181,6 +194,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x20301>; enable-method = "psci"; + next-level-cache = <&cluster3_l2>; }; cpu14: cpu@20302 { @@ -188,6 +202,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x20302>; enable-method = "psci"; + next-level-cache = <&cluster3_l2>; }; cpu15: cpu@20303 { @@ -195,6 +210,23 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x20303>; enable-method = "psci"; + next-level-cache = <&cluster3_l2>; + }; + + cluster0_l2: l2-cache0 { + compatible = "cache"; + }; + + cluster1_l2: l2-cache1 { + compatible = "cache"; + }; + + cluster2_l2: l2-cache2 { + compatible = "cache"; + }; + + cluster3_l2: l2-cache3 { + compatible = "cache"; }; }; @@ -214,11 +246,29 @@ <0x0 0xfe020000 0 0x10000>; /* GICV */ interrupts = ; - its_totems: interrupt-controller@8c000000 { + its_peri: interrupt-controller@8c000000 { compatible = "arm,gic-v3-its"; msi-controller; reg = <0x0 0x8c000000 0x0 0x40000>; }; + + its_m3: interrupt-controller@a3000000 { + compatible = "arm,gic-v3-its"; + msi-controller; + reg = <0x0 0xa3000000 0x0 0x40000>; + }; + + its_pcie: interrupt-controller@b7000000 { + compatible = "arm,gic-v3-its"; + msi-controller; + reg = <0x0 0xb7000000 0x0 0x40000>; + }; + + its_dsa: interrupt-controller@c6000000 { + compatible = "arm,gic-v3-its"; + msi-controller; + reg = <0x0 0xc6000000 0x0 0x40000>; + }; }; timer { @@ -230,7 +280,7 @@ }; pmu { - compatible = "arm,armv8-pmuv3"; + compatible = "arm,cortex-a57-pmu"; interrupts = ; }; @@ -272,5 +322,43 @@ reg-io-width = <4>; status = "disabled"; }; + + peri_gpio0: gpio@802e0000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,dw-apb-gpio"; + reg = <0x0 0x802e0000 0x0 0x10000>; + status = "disabled"; + + porta: gpio-controller@0 { + compatible = "snps,dw-apb-gpio-port"; + gpio-controller; + #gpio-cells = <2>; + snps,nr-gpios = <32>; + reg = <0>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = ; + }; + }; + + peri_gpio1: gpio@802f0000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,dw-apb-gpio"; + reg = <0x0 0x802f0000 0x0 0x10000>; + status = "disabled"; + + portb: gpio-controller@0 { + compatible = "snps,dw-apb-gpio-port"; + gpio-controller; + #gpio-cells = <2>; + snps,nr-gpios = <32>; + reg = <0>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = ; + }; + }; }; }; diff --git a/arch/arm64/boot/dts/marvell/Makefile b/arch/arm64/boot/dts/marvell/Makefile index 348f4db4f3139f4d765253b459382f682a85697b..308468d377d05f46c78f59c33871bc2bb6f8da32 100644 --- a/arch/arm64/boot/dts/marvell/Makefile +++ b/arch/arm64/boot/dts/marvell/Makefile @@ -1,6 +1,11 @@ +# Berlin SoC Family dtb-$(CONFIG_ARCH_BERLIN) += berlin4ct-dmp.dtb dtb-$(CONFIG_ARCH_BERLIN) += berlin4ct-stb.dtb +# Mvebu SoC Family +dtb-$(CONFIG_ARCH_MVEBU) += armada-3720-db.dtb +dtb-$(CONFIG_ARCH_MVEBU) += armada-7040-db.dtb + always := $(dtb-y) subdir-y := $(dts-dirs) clean-files := *.dtb diff --git a/arch/arm64/boot/dts/marvell/armada-371x.dtsi b/arch/arm64/boot/dts/marvell/armada-371x.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..c9e5325b8ac3af0bfb190dc07301653d8da73c33 --- /dev/null +++ b/arch/arm64/boot/dts/marvell/armada-371x.dtsi @@ -0,0 +1,53 @@ +/* + * Device Tree Include file for Marvell Armada 371x family of SoCs + * (also named 88F3710) + * + * Copyright (C) 2016 Marvell + * + * Gregory CLEMENT + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "armada-37xx.dtsi" + +/ { + model = "Marvell Armada 3710 SoC"; + compatible = "marvell,armada3710", "marvell,armada3700"; +}; diff --git a/arch/arm64/boot/dts/marvell/armada-3720-db.dts b/arch/arm64/boot/dts/marvell/armada-3720-db.dts new file mode 100644 index 0000000000000000000000000000000000000000..3590501545116dfc7de3ded7bbc5899b1d571420 --- /dev/null +++ b/arch/arm64/boot/dts/marvell/armada-3720-db.dts @@ -0,0 +1,86 @@ +/* + * Device Tree file for Marvell Armada 3720 development board + * (DB-88F3720-DDR3) + * Copyright (C) 2016 Marvell + * + * Gregory CLEMENT + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; + +#include "armada-372x.dtsi" + +/ { + model = "Marvell Armada 3720 Development Board DB-88F3720-DDR3"; + compatible = "marvell,armada-3720-db", "marvell,armada3720", "marvell,armada3710"; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory { + device_type = "memory"; + reg = <0x00000000 0x00000000 0x00000000 0x20000000>; + }; + + soc { + internal-regs { + /* + * Exported on the micro USB connector CON32 + * through an FTDI + */ + uart0: serial@12000 { + status = "okay"; + }; + + /* CON31 */ + usb3@58000 { + status = "okay"; + }; + + /* CON3 */ + sata@e0000 { + status = "okay"; + }; + }; + }; +}; + diff --git a/arch/arm64/boot/dts/marvell/armada-372x.dtsi b/arch/arm64/boot/dts/marvell/armada-372x.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..f292a00ce97cb11cd01923422fd538cfef544dd4 --- /dev/null +++ b/arch/arm64/boot/dts/marvell/armada-372x.dtsi @@ -0,0 +1,63 @@ +/* + * Device Tree Include file for Marvell Armada 372x family of SoCs + * (also named 88F3720) + * + * Copyright (C) 2016 Marvell + * + * Gregory CLEMENT + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "armada-37xx.dtsi" + +/ { + model = "Marvell Armada 3720 SoC"; + compatible = "marvell,armada3720", "marvell,armada3710"; + + cpus { + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a53","arm,armv8"; + reg = <0x1>; + enable-method = "psci"; + }; + }; + +}; diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..ba9df7ff2a725a438fcd615cbf93781947120283 --- /dev/null +++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi @@ -0,0 +1,131 @@ +/* + * Device Tree Include file for Marvell Armada 37xx family of SoCs. + * + * Copyright (C) 2016 Marvell + * + * Gregory CLEMENT + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include + +/ { + model = "Marvell Armada 37xx SoC"; + compatible = "marvell,armada3700"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + aliases { + serial0 = &uart0; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a53", "arm,armv8"; + reg = <0>; + enable-method = "psci"; + }; + }; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = , + , + , + ; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + internal-regs { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + /* 32M internal register @ 0xd000_0000 */ + ranges = <0x0 0x0 0xd0000000 0x2000000>; + + uart0: serial@12000 { + compatible = "marvell,armada-3700-uart"; + reg = <0x12000 0x400>; + interrupts = ; + status = "disabled"; + }; + + usb3@58000 { + compatible = "generic-xhci"; + reg = <0x58000 0x4000>; + interrupts = ; + status = "disabled"; + }; + + sata@e0000 { + compatible = "marvell,armada-3700-ahci"; + reg = <0xe0000 0x2000>; + interrupts = ; + status = "disabled"; + }; + + gic: interrupt-controller@1d00000 { + compatible = "arm,gic-v3"; + #interrupt-cells = <3>; + interrupt-controller; + reg = <0x1d00000 0x10000>, /* GICD */ + <0x1d40000 0x40000>; /* GICR */ + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/marvell/armada-7020.dtsi b/arch/arm64/boot/dts/marvell/armada-7020.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..52575756d0be44a693e8e25cbef5a55f5f6d69a9 --- /dev/null +++ b/arch/arm64/boot/dts/marvell/armada-7020.dtsi @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2016 Marvell Technology Group Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPLv2 or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library 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 library 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Device Tree file for the Armada 7020 SoC, made of an AP806 Dual and + * one CP110. + */ + +#include "armada-ap806-dual.dtsi" + +/ { + model = "Marvell Armada 7020"; + compatible = "marvell,armada7020", "marvell,armada-ap806-dual", + "marvell,armada-ap806"; +}; diff --git a/arch/arm64/boot/dts/marvell/armada-7040-db.dts b/arch/arm64/boot/dts/marvell/armada-7040-db.dts new file mode 100644 index 0000000000000000000000000000000000000000..064a251346dd93f87d59a1c17c78de6bf7a3bfea --- /dev/null +++ b/arch/arm64/boot/dts/marvell/armada-7040-db.dts @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2016 Marvell Technology Group Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPLv2 or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library 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 library 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Device Tree file for Marvell Armada 7040 Development board platform + */ + +#include "armada-7040.dtsi" + +/ { + model = "Marvell Armada 7040 DB board"; + compatible = "marvell,armada7040-db", "marvell,armada7040", + "marvell,armada-ap806-quad", "marvell,armada-ap806"; + + memory@00000000 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; + }; + + ap806 { + config-space { + spi@510600 { + status = "okay"; + + spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "n25q128a13"; + reg = <0>; /* Chip select 0 */ + spi-max-frequency = <10000000>; + + partition@0 { + label = "U-Boot"; + reg = <0 0x200000>; + }; + partition@400000 { + label = "Filesystem"; + reg = <0x200000 0xce0000>; + }; + }; + }; + + i2c@511000 { + status = "okay"; + clock-frequency = <100000>; + }; + + serial@512000 { + status = "okay"; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/marvell/armada-7040.dtsi b/arch/arm64/boot/dts/marvell/armada-7040.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..7a2de8bf790740dc49576e362c788aa59384b86f --- /dev/null +++ b/arch/arm64/boot/dts/marvell/armada-7040.dtsi @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2016 Marvell Technology Group Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPLv2 or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library 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 library 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Device Tree file for the Armada 7040 SoC, made of an AP806 Quad and + * one CP110. + */ + +#include "armada-ap806-quad.dtsi" + +/ { + model = "Marvell Armada 7040"; + compatible = "marvell,armada7040", "marvell,armada-ap806-quad", + "marvell,armada-ap806"; +}; diff --git a/arch/arm64/boot/dts/marvell/armada-8020.dtsi b/arch/arm64/boot/dts/marvell/armada-8020.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..73d69d99513f52fc8bce8789da0b4ba516fa17a7 --- /dev/null +++ b/arch/arm64/boot/dts/marvell/armada-8020.dtsi @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2016 Marvell Technology Group Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPLv2 or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library 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 library 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Device Tree file for the Armada 8020 SoC, made of an AP806 Dual and + * two CP110. + */ + +#include "armada-ap806-dual.dtsi" + +/ { + model = "Marvell Armada 8020"; + compatible = "marvell,armada8020", "marvell,armada-ap806-dual", + "marvell,armada-ap806"; +}; diff --git a/arch/arm64/boot/dts/marvell/armada-8040.dtsi b/arch/arm64/boot/dts/marvell/armada-8040.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..a1406a40959ef705547c2473ff0c48f89a846448 --- /dev/null +++ b/arch/arm64/boot/dts/marvell/armada-8040.dtsi @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2016 Marvell Technology Group Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPLv2 or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library 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 library 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Device Tree file for the Armada 8040 SoC, made of an AP806 Quad and + * two CP110. + */ + +#include "armada-ap806-quad.dtsi" + +/ { + model = "Marvell Armada 8040"; + compatible = "marvell,armada8040", "marvell,armada-ap806-quad", + "marvell,armada-ap806"; +}; diff --git a/arch/arm64/boot/dts/marvell/armada-ap806-dual.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806-dual.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..f25c5c17fad75de71e60ade443e1f1cd5f162e33 --- /dev/null +++ b/arch/arm64/boot/dts/marvell/armada-ap806-dual.dtsi @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2016 Marvell Technology Group Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPLv2 or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library 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 library 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Device Tree file for Marvell Armada AP806. + */ + +#include "armada-ap806.dtsi" + +/ { + model = "Marvell Armada AP806 Dual"; + compatible = "marvell,armada-ap806-dual", "marvell,armada-ap806"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@000 { + device_type = "cpu"; + compatible = "arm,cortex-a72", "arm,armv8"; + reg = <0x000>; + enable-method = "psci"; + }; + cpu@001 { + device_type = "cpu"; + compatible = "arm,cortex-a72", "arm,armv8"; + reg = <0x001>; + enable-method = "psci"; + }; + }; +}; + diff --git a/arch/arm64/boot/dts/marvell/armada-ap806-quad.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806-quad.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..baa7d9a516b3cd2f76e41294142ecc3a52e55589 --- /dev/null +++ b/arch/arm64/boot/dts/marvell/armada-ap806-quad.dtsi @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2016 Marvell Technology Group Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPLv2 or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library 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 library 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Device Tree file for Marvell Armada AP806. + */ + +#include "armada-ap806.dtsi" + +/ { + model = "Marvell Armada AP806 Quad"; + compatible = "marvell,armada-ap806-quad", "marvell,armada-ap806"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@000 { + device_type = "cpu"; + compatible = "arm,cortex-a72", "arm,armv8"; + reg = <0x000>; + enable-method = "psci"; + }; + cpu@001 { + device_type = "cpu"; + compatible = "arm,cortex-a72", "arm,armv8"; + reg = <0x001>; + enable-method = "psci"; + }; + cpu@100 { + device_type = "cpu"; + compatible = "arm,cortex-a72", "arm,armv8"; + reg = <0x100>; + enable-method = "psci"; + }; + cpu@101 { + device_type = "cpu"; + compatible = "arm,cortex-a72", "arm,armv8"; + reg = <0x101>; + enable-method = "psci"; + }; + }; + +}; + diff --git a/arch/arm64/boot/dts/marvell/armada-ap806.dtsi b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..556a92bcc2f600ce0d486c597feb9493875653d1 --- /dev/null +++ b/arch/arm64/boot/dts/marvell/armada-ap806.dtsi @@ -0,0 +1,237 @@ +/* + * Copyright (C) 2016 Marvell Technology Group Ltd. + * + * This file is dual-licensed: you can use it either under the terms + * of the GPLv2 or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This library 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 library 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Device Tree file for Marvell Armada AP806. + */ + +#include + +/dts-v1/; + +/ { + model = "Marvell Armada AP806"; + compatible = "marvell,armada-ap806"; + #address-cells = <2>; + #size-cells = <2>; + + psci { + compatible = "arm,psci-0.2"; + method = "smc"; + }; + + + ap806 { + #address-cells = <2>; + #size-cells = <2>; + compatible = "simple-bus"; + interrupt-parent = <&gic>; + ranges; + + config-space { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + ranges = <0x0 0x0 0xf0000000 0x1000000>; + + gic: interrupt-controller@210000 { + compatible = "arm,gic-400"; + #interrupt-cells = <3>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + interrupt-controller; + interrupts = ; + reg = <0x210000 0x10000>, + <0x220000 0x20000>, + <0x240000 0x20000>, + <0x260000 0x20000>; + + gic_v2m0: v2m@280000 { + compatible = "arm,gic-v2m-frame"; + msi-controller; + reg = <0x280000 0x1000>; + arm,msi-base-spi = <160>; + arm,msi-num-spis = <32>; + }; + gic_v2m1: v2m@290000 { + compatible = "arm,gic-v2m-frame"; + msi-controller; + reg = <0x290000 0x1000>; + arm,msi-base-spi = <192>; + arm,msi-num-spis = <32>; + }; + gic_v2m2: v2m@2a0000 { + compatible = "arm,gic-v2m-frame"; + msi-controller; + reg = <0x2a0000 0x1000>; + arm,msi-base-spi = <224>; + arm,msi-num-spis = <32>; + }; + gic_v2m3: v2m@2b0000 { + compatible = "arm,gic-v2m-frame"; + msi-controller; + reg = <0x2b0000 0x1000>; + arm,msi-base-spi = <256>; + arm,msi-num-spis = <32>; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = , + , + , + ; + }; + + odmi: odmi@300000 { + compatible = "marvell,odmi-controller"; + interrupt-controller; + msi-controller; + marvell,odmi-frames = <4>; + reg = <0x300000 0x4000>, + <0x304000 0x4000>, + <0x308000 0x4000>, + <0x30C000 0x4000>; + marvell,spi-base = <128>, <136>, <144>, <152>; + }; + + xor0@400000 { + compatible = "marvell,mv-xor-v2"; + reg = <0x400000 0x1000>, + <0x410000 0x1000>; + msi-parent = <&gic_v2m0>; + dma-coherent; + }; + + xor1@420000 { + compatible = "marvell,mv-xor-v2"; + reg = <0x420000 0x1000>, + <0x430000 0x1000>; + msi-parent = <&gic_v2m0>; + dma-coherent; + }; + + xor2@440000 { + compatible = "marvell,mv-xor-v2"; + reg = <0x440000 0x1000>, + <0x450000 0x1000>; + msi-parent = <&gic_v2m0>; + dma-coherent; + }; + + xor3@460000 { + compatible = "marvell,mv-xor-v2"; + reg = <0x460000 0x1000>, + <0x470000 0x1000>; + msi-parent = <&gic_v2m0>; + dma-coherent; + }; + + spi0: spi@510600 { + compatible = "marvell,armada-380-spi"; + reg = <0x510600 0x50>; + #address-cells = <1>; + #size-cells = <0>; + cell-index = <0>; + interrupts = ; + clocks = <&ringclk 2>; + status = "disabled"; + }; + + i2c0: i2c@511000 { + compatible = "marvell,mv64xxx-i2c"; + reg = <0x511000 0x20>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = ; + timeout-ms = <1000>; + clocks = <&ringclk 2>; + status = "disabled"; + }; + + serial@512000 { + compatible = "snps,dw-apb-uart"; + reg = <0x512000 0x100>; + reg-shift = <2>; + interrupts = ; + reg-io-width = <1>; + clocks = <&ringclk 2>; + status = "disabled"; + }; + + serial@512100 { + compatible = "snps,dw-apb-uart"; + reg = <0x512100 0x100>; + reg-shift = <2>; + interrupts = ; + reg-io-width = <1>; + clocks = <&ringclk 2>; + status = "disabled"; + + }; + + dfx-server@6f8000 { + compatible = "simple-mfd", "syscon"; + reg = <0x6f8000 0x70000>; + + coreclk: clk@204 { + compatible = "marvell,armada-ap806-core-clock"; + #clock-cells = <1>; + clock-output-names = "ddr", "ring", "cpu"; + }; + + ringclk: clk@250 { + compatible = "marvell,armada-ap806-ring-clock"; + #clock-cells = <1>; + clock-output-names = "ring-0", "ring-2", + "ring-3", "ring-4", + "ring-5"; + clocks = <&coreclk 1>; + }; + }; + }; + }; + +}; + diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts index e427f04a9f450a3c7bf429e9ef29529f39c8baf2..7453a47b3047ef12ef6e73d12da4ed4c08babe3c 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts +++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts @@ -214,6 +214,9 @@ }; &pwrap { + /* Only MT8173 E1 needs USB power domain */ + power-domains = <&scpsys MT8173_POWER_DOMAIN_USB>; + pmic: mt6397 { compatible = "mediatek,mt6397"; interrupt-parent = <&pio>; diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi index ec135eae31f54eca2a0d7e058be3ee9414513647..eab7efc2302d135a0aaec2a529ee200d95259315 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -277,6 +278,22 @@ reg = <0 0x10200620 0 0x20>; }; + iommu: iommu@10205000 { + compatible = "mediatek,mt8173-m4u"; + reg = <0 0x10205000 0 0x1000>; + interrupts = ; + clocks = <&infracfg CLK_INFRA_M4U>; + clock-names = "bclk"; + mediatek,larbs = <&larb0 &larb1 &larb2 + &larb3 &larb4 &larb5>; + #iommu-cells = <1>; + }; + + efuse: efuse@10206000 { + compatible = "mediatek,mt8173-efuse"; + reg = <0 0x10206000 0 0x1000>; + }; + apmixedsys: clock-controller@10209000 { compatible = "mediatek,mt8173-apmixedsys"; reg = <0 0x10209000 0 0x1000>; @@ -397,6 +414,17 @@ status = "disabled"; }; + nor_flash: spi@1100d000 { + compatible = "mediatek,mt8173-nor"; + reg = <0 0x1100d000 0 0xe0>; + clocks = <&pericfg CLK_PERI_SPI>, + <&topckgen CLK_TOP_SPINFI_IFR_SEL>; + clock-names = "spi", "sf"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + i2c3: i2c@11010000 { compatible = "mediatek,mt8173-i2c"; reg = <0 0x11010000 0 0x70>, @@ -589,29 +617,98 @@ status = "disabled"; }; + larb0: larb@14021000 { + compatible = "mediatek,mt8173-smi-larb"; + reg = <0 0x14021000 0 0x1000>; + mediatek,smi = <&smi_common>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + clocks = <&mmsys CLK_MM_SMI_LARB0>, + <&mmsys CLK_MM_SMI_LARB0>; + clock-names = "apb", "smi"; + }; + + smi_common: smi@14022000 { + compatible = "mediatek,mt8173-smi-common"; + reg = <0 0x14022000 0 0x1000>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + clocks = <&mmsys CLK_MM_SMI_COMMON>, + <&mmsys CLK_MM_SMI_COMMON>; + clock-names = "apb", "smi"; + }; + + larb4: larb@14027000 { + compatible = "mediatek,mt8173-smi-larb"; + reg = <0 0x14027000 0 0x1000>; + mediatek,smi = <&smi_common>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>; + clocks = <&mmsys CLK_MM_SMI_LARB4>, + <&mmsys CLK_MM_SMI_LARB4>; + clock-names = "apb", "smi"; + }; + imgsys: clock-controller@15000000 { compatible = "mediatek,mt8173-imgsys", "syscon"; reg = <0 0x15000000 0 0x1000>; #clock-cells = <1>; }; + larb2: larb@15001000 { + compatible = "mediatek,mt8173-smi-larb"; + reg = <0 0x15001000 0 0x1000>; + mediatek,smi = <&smi_common>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_ISP>; + clocks = <&imgsys CLK_IMG_LARB2_SMI>, + <&imgsys CLK_IMG_LARB2_SMI>; + clock-names = "apb", "smi"; + }; + vdecsys: clock-controller@16000000 { compatible = "mediatek,mt8173-vdecsys", "syscon"; reg = <0 0x16000000 0 0x1000>; #clock-cells = <1>; }; + larb1: larb@16010000 { + compatible = "mediatek,mt8173-smi-larb"; + reg = <0 0x16010000 0 0x1000>; + mediatek,smi = <&smi_common>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_VDEC>; + clocks = <&vdecsys CLK_VDEC_CKEN>, + <&vdecsys CLK_VDEC_LARB_CKEN>; + clock-names = "apb", "smi"; + }; + vencsys: clock-controller@18000000 { compatible = "mediatek,mt8173-vencsys", "syscon"; reg = <0 0x18000000 0 0x1000>; #clock-cells = <1>; }; + larb3: larb@18001000 { + compatible = "mediatek,mt8173-smi-larb"; + reg = <0 0x18001000 0 0x1000>; + mediatek,smi = <&smi_common>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_VENC>; + clocks = <&vencsys CLK_VENC_CKE1>, + <&vencsys CLK_VENC_CKE0>; + clock-names = "apb", "smi"; + }; + vencltsys: clock-controller@19000000 { compatible = "mediatek,mt8173-vencltsys", "syscon"; reg = <0 0x19000000 0 0x1000>; #clock-cells = <1>; }; + + larb5: larb@19001000 { + compatible = "mediatek,mt8173-smi-larb"; + reg = <0 0x19001000 0 0x1000>; + mediatek,smi = <&smi_common>; + power-domains = <&scpsys MT8173_POWER_DOMAIN_VENC_LT>; + clocks = <&vencltsys CLK_VENCLT_CKE1>, + <&vencltsys CLK_VENCLT_CKE0>; + clock-names = "apb", "smi"; + }; }; }; diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index 8e94af64ee94516166dad513be94613f32a460aa..fa1f661ccccfb21bb71ab0d5918aee5c0742223e 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile @@ -1,4 +1,5 @@ dtb-$(CONFIG_ARCH_QCOM) += apq8016-sbc.dtb msm8916-mtp.dtb +dtb-$(CONFIG_ARCH_QCOM) += msm8996-mtp.dtb always := $(dtb-y) subdir-y := $(dts-dirs) diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi index e03c11d9d83447a524047c6e41498d7d3e4ac71c..f881437d53c5f049b5f25e37fbbee53f6a069038 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi @@ -33,7 +33,7 @@ pm8916_mpps_leds: pm8916_mpps_leds { pinconf { pins = "mpp2", "mpp3"; - function = PMIC_GPIO_FUNC_NORMAL; + function = "digital"; output-low; }; }; diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi index cbeee0bcdf5234ecbea25bb354f30d591d6e3f18..ee828a8a82361b61802dbbd5bc520b0425addb03 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc-soc-pins.dtsi @@ -10,4 +10,18 @@ output-low; }; }; + + usb_id_default: usb-id-default { + pinmux { + function = "gpio"; + pins = "gpio121"; + }; + + pinconf { + pins = "gpio121"; + drive-strength = <8>; + input-enable; + bias-pull-up; + }; + }; }; diff --git a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi index db17c5d5689c65ed83b35bc5d51ba4adc290d828..205ef89b8ca0bcc9bcaa83710f01ba5a7c324e43 100644 --- a/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi @@ -24,6 +24,8 @@ i2c0 = &blsp_i2c2; i2c1 = &blsp_i2c6; i2c3 = &blsp_i2c4; + spi0 = &blsp_spi5; + spi1 = &blsp_spi3; }; chosen { @@ -127,9 +129,173 @@ default-state = "off"; }; }; + + sdhci@07824000 { + vmmc-supply = <&pm8916_l8>; + vqmmc-supply = <&pm8916_l5>; + + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on>; + pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off>; + status = "okay"; + }; + + usb@78d9000 { + extcon = <&usb_id>, <&usb_id>; + status = "okay"; + }; + + ehci@78d9000 { + status = "okay"; + }; + + phy@78d9000 { + v1p8-supply = <&pm8916_l7>; + v3p3-supply = <&pm8916_l13>; + vddcx-supply = <&pm8916_s1>; + extcon = <&usb_id>, <&usb_id>; + dr_mode = "otg"; + status = "okay"; + switch-gpio = <&pm8916_gpios 4 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&usb_sw_sel_pm>; + }; + + lpass@07708000 { + status = "okay"; + }; + }; + + usb2513 { + compatible = "smsc,usb3503"; + reset-gpios = <&pm8916_gpios 3 GPIO_ACTIVE_LOW>; + initial-mode = <1>; + }; + + usb_id: usb-id { + compatible = "linux,extcon-usb-gpio"; + id-gpio = <&msmgpio 121 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&usb_id_default>; }; }; -&sdhc_1 { - status = "okay"; +&smd_rpm_regulators { + vdd_l1_l2_l3-supply = <&pm8916_s3>; + vdd_l5-supply = <&pm8916_s3>; + vdd_l4_l5_l6-supply = <&pm8916_s4>; + vdd_l7-supply = <&pm8916_s4>; + + s1 { + regulator-min-microvolt = <375000>; + regulator-max-microvolt = <1562000>; + }; + + s3 { + regulator-min-microvolt = <375000>; + regulator-max-microvolt = <1562000>; + }; + + s4 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-always-on; + regulator-boot-on; + }; + + l1 { + regulator-min-microvolt = <375000>; + regulator-max-microvolt = <1525000>; + }; + + l2 { + regulator-min-microvolt = <375000>; + regulator-max-microvolt = <1525000>; + }; + + l3 { + regulator-min-microvolt = <375000>; + regulator-max-microvolt = <1525000>; + }; + + l4 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l5 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l6 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l7 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l8 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l9 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l10 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l11 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l12 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l13 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l14 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + /** + * 1.8v required on LS expansion + * for mezzanine boards + */ + l15 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + regulator-always-on; + }; + + l16 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l17 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; + + l18 { + regulator-min-microvolt = <1750000>; + regulator-max-microvolt = <3337000>; + }; }; diff --git a/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi b/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi index 955c6f174d4cb16218625a6e590102a6e4a2bbf0..10c83e11c272fa7a4a86a1a33115eb988493964a 100644 --- a/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916-pins.dtsi @@ -82,7 +82,7 @@ }; pinconf_cs { pins = "gpio2"; - drive-strength = <2>; + drive-strength = <16>; bias-disable; output-high; }; @@ -110,13 +110,13 @@ pins = "gpio6"; }; pinconf { - pins = "gpio4", "gpio5", "gpio6", "gpio7"; + pins = "gpio4", "gpio5", "gpio7"; drive-strength = <12>; bias-disable; }; pinconf_cs { pins = "gpio6"; - drive-strength = <2>; + drive-strength = <16>; bias-disable; output-high; }; @@ -144,13 +144,13 @@ pins = "gpio10"; }; pinconf { - pins = "gpio8", "gpio9", "gpio10", "gpio11"; + pins = "gpio8", "gpio9", "gpio11"; drive-strength = <12>; bias-disable; }; pinconf_cs { pins = "gpio10"; - drive-strength = <2>; + drive-strength = <16>; bias-disable; output-high; }; @@ -178,13 +178,13 @@ pins = "gpio14"; }; pinconf { - pins = "gpio12", "gpio13", "gpio14", "gpio15"; + pins = "gpio12", "gpio13", "gpio15"; drive-strength = <12>; bias-disable; }; pinconf_cs { pins = "gpio14"; - drive-strength = <2>; + drive-strength = <16>; bias-disable; output-high; }; @@ -212,13 +212,13 @@ pins = "gpio18"; }; pinconf { - pins = "gpio16", "gpio17", "gpio18", "gpio19"; + pins = "gpio16", "gpio17", "gpio19"; drive-strength = <12>; bias-disable; }; pinconf_cs { pins = "gpio18"; - drive-strength = <2>; + drive-strength = <16>; bias-disable; output-high; }; @@ -246,13 +246,13 @@ pins = "gpio22"; }; pinconf { - pins = "gpio20", "gpio21", "gpio22", "gpio23"; + pins = "gpio20", "gpio21", "gpio23"; drive-strength = <12>; bias-disable; }; pinconf_cs { pins = "gpio22"; - drive-strength = <2>; + drive-strength = <16>; bias-disable; output-high; }; @@ -504,4 +504,220 @@ }; }; }; + + ext-codec-lines { + ext_codec_lines_act: lines_on { + pinmux { + function = "gpio"; + pins = "gpio67"; + }; + pinconf { + pins = "gpio67"; + drive-strength = <8>; + bias-disable; + output-high; + }; + }; + ext_codec_lines_sus: lines_off { + pinmux { + function = "gpio"; + pins = "gpio67"; + }; + pinconf { + pins = "gpio67"; + drive-strength = <2>; + bias-disable; + }; + }; + }; + + cdc-pdm-lines { + cdc_pdm_lines_act: pdm_lines_on { + pinmux { + function = "cdc_pdm0"; + pins = "gpio63", "gpio64", "gpio65", "gpio66", + "gpio67", "gpio68"; + }; + pinconf { + pins = "gpio63", "gpio64", "gpio65", "gpio66", + "gpio67", "gpio68"; + drive-strength = <8>; + bias-pull-none; + }; + }; + cdc_pdm_lines_sus: pdm_lines_off { + pinmux { + function = "cdc_pdm0"; + pins = "gpio63", "gpio64", "gpio65", "gpio66", + "gpio67", "gpio68"; + }; + pinconf { + pins = "gpio63", "gpio64", "gpio65", "gpio66", + "gpio67", "gpio68"; + drive-strength = <2>; + bias-disable; + }; + }; + }; + + ext-pri-tlmm-lines { + ext_pri_tlmm_lines_act: ext_pa_on { + pinmux { + function = "pri_mi2s"; + pins = "gpio113", "gpio114", "gpio115", + "gpio116"; + }; + pinconf { + pins = "gpio113", "gpio114", "gpio115", + "gpio116"; + drive-strength = <8>; + bias-pull-none; + }; + }; + + ext_pri_tlmm_lines_sus: ext_pa_off { + pinmux { + function = "pri_mi2s"; + pins = "gpio113", "gpio114", "gpio115", + "gpio116"; + }; + pinconf { + pins = "gpio113", "gpio114", "gpio115", + "gpio116"; + drive-strength = <2>; + bias-disable; + }; + }; + }; + + ext-pri-ws-line { + ext_pri_ws_act: ext_pa_on { + pinmux { + function = "pri_mi2s_ws"; + pins = "gpio110"; + }; + pinconf { + pins = "gpio110"; + drive-strength = <8>; + bias-pull-none; + }; + }; + + ext_pri_ws_sus: ext_pa_off { + pinmux { + function = "pri_mi2s_ws"; + pins = "gpio110"; + }; + pinconf { + pins = "gpio110"; + drive-strength = <2>; + bias-disable; + }; + }; + }; + + ext-mclk-tlmm-lines { + ext_mclk_tlmm_lines_act: mclk_lines_on { + pinmux { + function = "pri_mi2s"; + pins = "gpio116"; + }; + pinconf { + pins = "gpio116"; + drive-strength = <8>; + bias-pull-none; + }; + }; + ext_mclk_tlmm_lines_sus: mclk_lines_off { + pinmux { + function = "pri_mi2s"; + pins = "gpio116"; + }; + pinconf { + pins = "gpio116"; + drive-strength = <2>; + bias-disable; + }; + }; + }; + + /* secondary Mi2S */ + ext-sec-tlmm-lines { + ext_sec_tlmm_lines_act: tlmm_lines_on { + pinmux { + function = "sec_mi2s"; + pins = "gpio112", "gpio117", "gpio118", + "gpio119"; + }; + pinconf { + pins = "gpio112", "gpio117", "gpio118", + "gpio119"; + drive-strength = <8>; + bias-pull-none; + }; + }; + ext_sec_tlmm_lines_sus: tlmm_lines_off { + pinmux { + function = "sec_mi2s"; + pins = "gpio112", "gpio117", "gpio118", + "gpio119"; + }; + pinconf { + pins = "gpio112", "gpio117", "gpio118", + "gpio119"; + drive-strength = <2>; + bias-disable; + }; + }; + }; + + cdc-dmic-lines { + cdc_dmic_lines_act: dmic_lines_on { + pinmux_dmic0_clk { + function = "dmic0_clk"; + pins = "gpio0"; + }; + pinmux_dmic0_data { + function = "dmic0_data"; + pins = "gpio1"; + }; + pinconf { + pins = "gpio0", "gpio1"; + drive-strength = <8>; + }; + }; + cdc_dmic_lines_sus: dmic_lines_off { + pinconf { + pins = "gpio0", "gpio1"; + drive-strength = <2>; + bias-disable; + }; + }; + }; + + cross-conn-det { + cross_conn_det_act: lines_on { + pinmux { + function = "gpio"; + pins = "gpio120"; + }; + pinconf { + pins = "gpio120"; + drive-strength = <8>; + output-low; + bias-pull-down; + }; + }; + cross_conn_det_sus: lines_off { + pinmux { + function = "gpio"; + pins = "gpio120"; + }; + pinconf { + pins = "gpio120"; + drive-strength = <2>; + bias-disable; + }; + }; + }; }; diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi index 915321479998d63ff70db4c08bc3d8e1cb2cdb50..96812007850ecf0be584528dcd6bb3ca8e063866 100644 --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -61,24 +61,33 @@ device_type = "cpu"; compatible = "arm,cortex-a53", "arm,armv8"; reg = <0x0>; + next-level-cache = <&L2_0>; }; CPU1: cpu@1 { device_type = "cpu"; compatible = "arm,cortex-a53", "arm,armv8"; reg = <0x1>; + next-level-cache = <&L2_0>; }; CPU2: cpu@2 { device_type = "cpu"; compatible = "arm,cortex-a53", "arm,armv8"; reg = <0x2>; + next-level-cache = <&L2_0>; }; CPU3: cpu@3 { device_type = "cpu"; compatible = "arm,cortex-a53", "arm,armv8"; reg = <0x3>; + next-level-cache = <&L2_0>; + }; + + L2_0: l2-cache { + compatible = "cache"; + cache-level = <2>; }; }; @@ -134,7 +143,7 @@ #interrupt-cells = <2>; }; - gcc: qcom,gcc@1800000 { + gcc: clock-controller@1800000 { compatible = "qcom,gcc-msm8916"; #clock-cells = <1>; #reset-cells = <1>; @@ -343,6 +352,32 @@ status = "disabled"; }; + lpass: lpass@07708000 { + status = "disabled"; + compatible = "qcom,lpass-cpu-apq8016"; + clocks = <&gcc GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_CLK>, + <&gcc GCC_ULTAUDIO_PCNOC_MPORT_CLK>, + <&gcc GCC_ULTAUDIO_PCNOC_SWAY_CLK>, + <&gcc GCC_ULTAUDIO_LPAIF_PRI_I2S_CLK>, + <&gcc GCC_ULTAUDIO_LPAIF_SEC_I2S_CLK>, + <&gcc GCC_ULTAUDIO_LPAIF_SEC_I2S_CLK>, + <&gcc GCC_ULTAUDIO_LPAIF_AUX_I2S_CLK>; + + clock-names = "ahbix-clk", + "pcnoc-mport-clk", + "pcnoc-sway-clk", + "mi2s-bit-clk0", + "mi2s-bit-clk1", + "mi2s-bit-clk2", + "mi2s-bit-clk3"; + #sound-dai-cells = <1>; + + interrupts = <0 160 0>; + interrupt-names = "lpass-irq-lpaif"; + reg = <0x07708000 0x10000>; + reg-names = "lpass-lpaif"; + }; + sdhc_1: sdhci@07824000 { compatible = "qcom,sdhci-msm-v4"; reg = <0x07824900 0x11c>, <0x07824000 0x800>; @@ -395,10 +430,11 @@ interrupts = , ; - qcom,vdd-levels = <1 5 7>; + qcom,vdd-levels = <500000 1000000 1320000>; qcom,phy-init-sequence = <0x44 0x6B 0x24 0x13>; dr_mode = "peripheral"; qcom,otg-control = <2>; // PMIC + qcom,manual-pullup; clocks = <&gcc GCC_USB_HS_AHB_CLK>, <&gcc GCC_USB_HS_SYSTEM_CLK>, @@ -515,11 +551,15 @@ compatible = "qcom,rpm-msm8916"; qcom,smd-channels = "rpm_requests"; - pm8916-regulators { + rpmcc: qcom,rpmcc { + compatible = "qcom,rpmcc-msm8916", "qcom,rpmcc"; + #clock-cells = <1>; + }; + + smd_rpm_regulators: pm8916-regulators { compatible = "qcom,rpm-pm8916-regulators"; pm8916_s1: s1 {}; - pm8916_s2: s2 {}; pm8916_s3: s3 {}; pm8916_s4: s4 {}; diff --git a/arch/arm64/boot/dts/qcom/msm8996-mtp.dts b/arch/arm64/boot/dts/qcom/msm8996-mtp.dts new file mode 100644 index 0000000000000000000000000000000000000000..619af44a595da7ae649c238da25927b1bcd373bc --- /dev/null +++ b/arch/arm64/boot/dts/qcom/msm8996-mtp.dts @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + */ + +/dts-v1/; + +#include "msm8996-mtp.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM 8996 MTP"; + compatible = "qcom,msm8996-mtp"; +}; diff --git a/arch/arm64/boot/dts/qcom/msm8996-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8996-mtp.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..9bab5c011c070be801646fb880b197fda615336b --- /dev/null +++ b/arch/arm64/boot/dts/qcom/msm8996-mtp.dtsi @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + */ + +#include "msm8996.dtsi" + +/ { + aliases { + serial0 = &blsp2_uart1; + }; + + chosen { + stdout-path = "serial0"; + }; + + soc { + serial@75b0000 { + status = "okay"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..0506fb808c5609d64e6a042aae7e68c2848fff71 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -0,0 +1,269 @@ +/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + */ + +#include +#include +#include + +/ { + model = "Qualcomm Technologies, Inc. MSM8996"; + + interrupt-parent = <&intc>; + + #address-cells = <2>; + #size-cells = <2>; + + chosen { }; + + memory { + device_type = "memory"; + /* We expect the bootloader to fill in the reg */ + reg = <0 0 0 0>; + }; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + CPU0: cpu@0 { + device_type = "cpu"; + compatible = "qcom,kryo"; + reg = <0x0 0x0>; + enable-method = "psci"; + next-level-cache = <&L2_0>; + L2_0: l2-cache { + compatible = "cache"; + cache-level = <2>; + }; + }; + + CPU1: cpu@1 { + device_type = "cpu"; + compatible = "qcom,kryo"; + reg = <0x0 0x1>; + enable-method = "psci"; + next-level-cache = <&L2_0>; + }; + + CPU2: cpu@100 { + device_type = "cpu"; + compatible = "qcom,kryo"; + reg = <0x0 0x100>; + enable-method = "psci"; + next-level-cache = <&L2_1>; + L2_1: l2-cache { + compatible = "cache"; + cache-level = <2>; + }; + }; + + CPU3: cpu@101 { + device_type = "cpu"; + compatible = "qcom,kryo"; + reg = <0x0 0x101>; + enable-method = "psci"; + next-level-cache = <&L2_1>; + }; + + cpu-map { + cluster0 { + core0 { + cpu = <&CPU0>; + }; + + core1 { + cpu = <&CPU1>; + }; + }; + + cluster1 { + core0 { + cpu = <&CPU2>; + }; + + core1 { + cpu = <&CPU3>; + }; + }; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = , + , + , + ; + }; + + clocks { + xo_board { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <19200000>; + clock-output-names = "xo_board"; + }; + + sleep_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32764>; + clock-output-names = "sleep_clk"; + }; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + soc: soc { + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0 0xffffffff>; + compatible = "simple-bus"; + + intc: interrupt-controller@9bc0000 { + compatible = "arm,gic-v3"; + #interrupt-cells = <3>; + interrupt-controller; + #redistributor-regions = <1>; + redistributor-stride = <0x0 0x40000>; + reg = <0x09bc0000 0x10000>, + <0x09c00000 0x100000>; + interrupts = ; + }; + + gcc: clock-controller@300000 { + compatible = "qcom,gcc-msm8996"; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + reg = <0x300000 0x90000>; + }; + + blsp2_uart1: serial@75b0000 { + compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; + reg = <0x75b0000 0x1000>; + interrupts = ; + clocks = <&gcc GCC_BLSP2_UART2_APPS_CLK>, + <&gcc GCC_BLSP2_AHB_CLK>; + clock-names = "core", "iface"; + status = "disabled"; + }; + + pinctrl@1010000 { + compatible = "qcom,msm8996-pinctrl"; + reg = <0x01010000 0x300000>; + interrupts = ; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + timer@09840000 { + #address-cells = <1>; + #size-cells = <1>; + ranges; + compatible = "arm,armv7-timer-mem"; + reg = <0x09840000 0x1000>; + clock-frequency = <19200000>; + + frame@9850000 { + frame-number = <0>; + interrupts = , + ; + reg = <0x09850000 0x1000>, + <0x09860000 0x1000>; + }; + + frame@9870000 { + frame-number = <1>; + interrupts = ; + reg = <0x09870000 0x1000>; + status = "disabled"; + }; + + frame@9880000 { + frame-number = <2>; + interrupts = ; + reg = <0x09880000 0x1000>; + status = "disabled"; + }; + + frame@9890000 { + frame-number = <3>; + interrupts = ; + reg = <0x09890000 0x1000>; + status = "disabled"; + }; + + frame@98a0000 { + frame-number = <4>; + interrupts = ; + reg = <0x098a0000 0x1000>; + status = "disabled"; + }; + + frame@98b0000 { + frame-number = <5>; + interrupts = ; + reg = <0x098b0000 0x1000>; + status = "disabled"; + }; + + frame@98c0000 { + frame-number = <6>; + interrupts = ; + reg = <0x098c0000 0x1000>; + status = "disabled"; + }; + }; + + spmi_bus: qcom,spmi@400f000 { + compatible = "qcom,spmi-pmic-arb"; + reg = <0x400f000 0x1000>, + <0x4400000 0x800000>, + <0x4c00000 0x800000>, + <0x5800000 0x200000>, + <0x400a000 0x002100>; + reg-names = "core", "chnls", "obsrvr", "intr", "cnfg"; + interrupt-names = "periph_irq"; + interrupts = ; + qcom,ee = <0>; + qcom,channel = <0>; + #address-cells = <2>; + #size-cells = <0>; + interrupt-controller; + #interrupt-cells = <4>; + }; + + mmcc: clock-controller@8c0000 { + compatible = "qcom,mmcc-msm8996"; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + reg = <0x8c0000 0x40000>; + assigned-clocks = <&mmcc MMPLL9_PLL>, + <&mmcc MMPLL1_PLL>, + <&mmcc MMPLL3_PLL>, + <&mmcc MMPLL4_PLL>, + <&mmcc MMPLL5_PLL>; + assigned-clock-rates = <624000000>, + <810000000>, + <980000000>, + <960000000>, + <825000000>; + }; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/pm8004.dtsi b/arch/arm64/boot/dts/qcom/pm8004.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..ef2207afa86b4456f56503d17e45a139dcc17168 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/pm8004.dtsi @@ -0,0 +1,19 @@ +#include +#include + +&spmi_bus { + + pmic@4 { + compatible = "qcom,pm8004", "qcom,spmi-pmic"; + reg = <0x4 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + }; + + pmic@5 { + compatible = "qcom,pm8004", "qcom,spmi-pmic"; + reg = <0x5 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/pm8916.dtsi b/arch/arm64/boot/dts/qcom/pm8916.dtsi index 37432451ee4c0733040e35d90dafa166fec2630f..f71679b15d544f1ed88860fe7022e67730e00644 100644 --- a/arch/arm64/boot/dts/qcom/pm8916.dtsi +++ b/arch/arm64/boot/dts/qcom/pm8916.dtsi @@ -12,7 +12,7 @@ rtc@6000 { compatible = "qcom,pm8941-rtc"; - reg = <0x6000 0x6100>; + reg = <0x6000>; reg-names = "rtc", "alarm"; interrupts = <0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>; }; @@ -27,7 +27,7 @@ pm8916_gpios: gpios@c000 { compatible = "qcom,pm8916-gpio"; - reg = <0xc000 0x400>; + reg = <0xc000>; gpio-controller; #gpio-cells = <2>; interrupts = <0 0xc0 0 IRQ_TYPE_NONE>, @@ -38,7 +38,7 @@ pm8916_mpps: mpps@a000 { compatible = "qcom,pm8916-mpp"; - reg = <0xa000 0x400>; + reg = <0xa000>; gpio-controller; #gpio-cells = <2>; interrupts = <0 0xa0 0 IRQ_TYPE_NONE>, @@ -49,7 +49,7 @@ pm8916_temp: temp-alarm@2400 { compatible = "qcom,spmi-temp-alarm"; - reg = <0x2400 0x100>; + reg = <0x2400>; interrupts = <0 0x24 0 IRQ_TYPE_EDGE_RISING>; io-channels = <&pm8916_vadc VADC_DIE_TEMP>; io-channel-names = "thermal"; @@ -58,7 +58,7 @@ pm8916_vadc: vadc@3100 { compatible = "qcom,spmi-vadc"; - reg = <0x3100 0x100>; + reg = <0x3100>; interrupts = <0x0 0x31 0x0 IRQ_TYPE_EDGE_RISING>; #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm64/boot/dts/qcom/pm8994.dtsi b/arch/arm64/boot/dts/qcom/pm8994.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..1222d2e904f6b8cabf9bbd61437f37dc55871661 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/pm8994.dtsi @@ -0,0 +1,62 @@ +#include +#include + +&spmi_bus { + + pmic@0 { + compatible = "qcom,pm8994", "qcom,spmi-pmic"; + reg = <0x0 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + pm8994_gpios: gpios@c000 { + compatible = "qcom,pm8994-gpio"; + reg = <0xc000>; + gpio-controller; + #gpio-cells = <2>; + interrupts = <0 0xc0 0 IRQ_TYPE_NONE>, + <0 0xc1 0 IRQ_TYPE_NONE>, + <0 0xc2 0 IRQ_TYPE_NONE>, + <0 0xc3 0 IRQ_TYPE_NONE>, + <0 0xc4 0 IRQ_TYPE_NONE>, + <0 0xc5 0 IRQ_TYPE_NONE>, + <0 0xc6 0 IRQ_TYPE_NONE>, + <0 0xc7 0 IRQ_TYPE_NONE>, + <0 0xc8 0 IRQ_TYPE_NONE>, + <0 0xc9 0 IRQ_TYPE_NONE>, + <0 0xca 0 IRQ_TYPE_NONE>, + <0 0xcb 0 IRQ_TYPE_NONE>, + <0 0xcc 0 IRQ_TYPE_NONE>, + <0 0xcd 0 IRQ_TYPE_NONE>, + <0 0xce 0 IRQ_TYPE_NONE>, + <0 0xd0 0 IRQ_TYPE_NONE>, + <0 0xd1 0 IRQ_TYPE_NONE>, + <0 0xd2 0 IRQ_TYPE_NONE>, + <0 0xd3 0 IRQ_TYPE_NONE>, + <0 0xd4 0 IRQ_TYPE_NONE>, + <0 0xd5 0 IRQ_TYPE_NONE>; + }; + + pm8994_mpps: mpps@a000 { + compatible = "qcom,pm8994-mpp"; + reg = <0xa000>; + gpio-controller; + #gpio-cells = <2>; + interrupts = <0 0xa0 0 IRQ_TYPE_NONE>, + <0 0xa1 0 IRQ_TYPE_NONE>, + <0 0xa2 0 IRQ_TYPE_NONE>, + <0 0xa3 0 IRQ_TYPE_NONE>, + <0 0xa4 0 IRQ_TYPE_NONE>, + <0 0xa5 0 IRQ_TYPE_NONE>, + <0 0xa6 0 IRQ_TYPE_NONE>, + <0 0xa7 0 IRQ_TYPE_NONE>; + }; + }; + + pmic@1 { + compatible = "qcom,pm8994", "qcom,spmi-pmic"; + reg = <0x1 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/pmi8994.dtsi b/arch/arm64/boot/dts/qcom/pmi8994.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..d3879a4e8076d53a4bdcd9d2b81d343797c637a2 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/pmi8994.dtsi @@ -0,0 +1,19 @@ +#include +#include + +&spmi_bus { + + pmic@2 { + compatible = "qcom,pmi8994", "qcom,spmi-pmic"; + reg = <0x2 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + }; + + pmic@3 { + compatible = "qcom,pmi8994", "qcom,spmi-pmic"; + reg = <0x3 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + }; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts index 265d12ff6022208f94891149c065951668fd2b15..b992b1a3d95690307322e4459dfc9292d23b67ee 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts +++ b/arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts @@ -33,6 +33,7 @@ /dts-v1/; #include "r8a7795.dtsi" +#include / { model = "Renesas Salvator-X board based on r8a7795"; @@ -61,6 +62,54 @@ clock-frequency = <24576000>; }; + vcc_sdhi0: regulator@1 { + compatible = "regulator-fixed"; + + regulator-name = "SDHI0 Vcc"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&gpio5 2 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vccq_sdhi0: regulator@2 { + compatible = "regulator-gpio"; + + regulator-name = "SDHI0 VccQ"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + + gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>; + gpios-states = <1>; + states = <3300000 1 + 1800000 0>; + }; + + vcc_sdhi3: regulator@3 { + compatible = "regulator-fixed"; + + regulator-name = "SDHI3 Vcc"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&gpio3 15 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vccq_sdhi3: regulator@4 { + compatible = "regulator-gpio"; + + regulator-name = "SDHI3 VccQ"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + + gpios = <&gpio3 14 GPIO_ACTIVE_HIGH>; + gpios-states = <1>; + states = <3300000 1 + 1800000 0>; + }; + audio_clkout: audio_clkout { /* * This is same as <&rcar_sound 0> @@ -93,6 +142,9 @@ }; &pfc { + pinctrl-0 = <&scif_clk_pins>; + pinctrl-names = "default"; + scif1_pins: scif1 { renesas,groups = "scif1_data_a", "scif1_ctrl"; renesas,function = "scif1"; @@ -101,6 +153,10 @@ renesas,groups = "scif2_data_a"; renesas,function = "scif2"; }; + scif_clk_pins: scif_clk { + renesas,groups = "scif_clk_a"; + renesas,function = "scif_clk"; + }; i2c2_pins: i2c2 { renesas,groups = "i2c2_a"; @@ -112,6 +168,16 @@ renesas,function = "avb"; }; + sdhi0_pins: sd0 { + renesas,groups = "sdhi0_data4", "sdhi0_ctrl"; + renesas,function = "sdhi0"; + }; + + sdhi3_pins: sd3 { + renesas,groups = "sdhi3_data4", "sdhi3_ctrl"; + renesas,function = "sdhi3"; + }; + sound_pins: sound { renesas,groups = "ssi01239_ctrl", "ssi0_data", "ssi1_data_a"; renesas,function = "ssi"; @@ -122,6 +188,16 @@ "audio_clkout_a", "audio_clkout3_a"; renesas,function = "audio_clk"; }; + + usb1_pins: usb1 { + renesas,groups = "usb1"; + renesas,function = "usb1"; + }; + + usb2_pins: usb2 { + renesas,groups = "usb2"; + renesas,function = "usb2"; + }; }; &scif1 { @@ -138,6 +214,11 @@ status = "okay"; }; +&scif_clk { + clock-frequency = <14745600>; + status = "okay"; +}; + &i2c2 { pinctrl-0 = <&i2c2_pins>; pinctrl-names = "default"; @@ -216,6 +297,30 @@ status = "okay"; }; +&sdhi0 { + pinctrl-0 = <&sdhi0_pins>; + pinctrl-names = "default"; + + vmmc-supply = <&vcc_sdhi0>; + vqmmc-supply = <&vccq_sdhi0>; + cd-gpios = <&gpio3 12 GPIO_ACTIVE_LOW>; + wp-gpios = <&gpio3 13 GPIO_ACTIVE_HIGH>; + bus-width = <4>; + status = "okay"; +}; + +&sdhi3 { + pinctrl-0 = <&sdhi3_pins>; + pinctrl-names = "default"; + + vmmc-supply = <&vcc_sdhi3>; + vqmmc-supply = <&vccq_sdhi3>; + cd-gpios = <&gpio4 15 GPIO_ACTIVE_LOW>; + wp-gpios = <&gpio4 16 GPIO_ACTIVE_HIGH>; + bus-width = <4>; + status = "okay"; +}; + &ssi1 { shared-pin; }; @@ -249,3 +354,37 @@ interrupts = <11 IRQ_TYPE_LEVEL_LOW>; }; }; + +&xhci0 { + status = "okay"; +}; + +&usb2_phy1 { + pinctrl-0 = <&usb1_pins>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&usb2_phy2 { + pinctrl-0 = <&usb2_pins>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + +&ehci2 { + status = "okay"; +}; + +&ohci1 { + status = "okay"; +}; + +&ohci2 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi b/arch/arm64/boot/dts/renesas/r8a7795.dtsi index bb353cde125333b9f0df4dadcd817316d4ee3f08..a7315ebe3883f276456280de64d31537099cd292 100644 --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi @@ -39,6 +39,7 @@ compatible = "arm,cortex-a57", "arm,armv8"; reg = <0x0>; device_type = "cpu"; + next-level-cache = <&L2_CA57>; enable-method = "psci"; }; @@ -46,22 +47,37 @@ compatible = "arm,cortex-a57","arm,armv8"; reg = <0x1>; device_type = "cpu"; + next-level-cache = <&L2_CA57>; enable-method = "psci"; }; a57_2: cpu@2 { compatible = "arm,cortex-a57","arm,armv8"; reg = <0x2>; device_type = "cpu"; + next-level-cache = <&L2_CA57>; enable-method = "psci"; }; a57_3: cpu@3 { compatible = "arm,cortex-a57","arm,armv8"; reg = <0x3>; device_type = "cpu"; + next-level-cache = <&L2_CA57>; enable-method = "psci"; }; }; + L2_CA57: cache-controller@0 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + }; + + L2_CA53: cache-controller@1 { + compatible = "cache"; + cache-unified; + cache-level = <2>; + }; + extal_clk: extal { compatible = "fixed-clock"; #clock-cells = <0>; @@ -99,6 +115,14 @@ clock-frequency = <0>; }; + /* External SCIF clock - to be overridden by boards that provide it */ + scif_clk: scif { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <0>; + status = "disabled"; + }; + soc { compatible = "simple-bus"; interrupt-parent = <&gic>; @@ -113,7 +137,9 @@ #address-cells = <0>; interrupt-controller; reg = <0x0 0xf1010000 0 0x1000>, - <0x0 0xf1020000 0 0x2000>; + <0x0 0xf1020000 0 0x2000>, + <0x0 0xf1040000 0 0x20000>, + <0x0 0xf1060000 0 0x2000>; interrupts = ; }; @@ -230,8 +256,8 @@ power-domains = <&cpg>; }; - pmu { - compatible = "arm,armv8-pmuv3"; + pmu_a57 { + compatible = "arm,cortex-a57-pmu"; interrupts = , , , @@ -266,23 +292,23 @@ audma0: dma-controller@ec700000 { compatible = "renesas,rcar-dmac"; reg = <0 0xec700000 0 0x10000>; - interrupts = <0 350 IRQ_TYPE_LEVEL_HIGH - 0 320 IRQ_TYPE_LEVEL_HIGH - 0 321 IRQ_TYPE_LEVEL_HIGH - 0 322 IRQ_TYPE_LEVEL_HIGH - 0 323 IRQ_TYPE_LEVEL_HIGH - 0 324 IRQ_TYPE_LEVEL_HIGH - 0 325 IRQ_TYPE_LEVEL_HIGH - 0 326 IRQ_TYPE_LEVEL_HIGH - 0 327 IRQ_TYPE_LEVEL_HIGH - 0 328 IRQ_TYPE_LEVEL_HIGH - 0 329 IRQ_TYPE_LEVEL_HIGH - 0 330 IRQ_TYPE_LEVEL_HIGH - 0 331 IRQ_TYPE_LEVEL_HIGH - 0 332 IRQ_TYPE_LEVEL_HIGH - 0 333 IRQ_TYPE_LEVEL_HIGH - 0 334 IRQ_TYPE_LEVEL_HIGH - 0 335 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -298,23 +324,23 @@ audma1: dma-controller@ec720000 { compatible = "renesas,rcar-dmac"; reg = <0 0xec720000 0 0x10000>; - interrupts = <0 351 IRQ_TYPE_LEVEL_HIGH - 0 336 IRQ_TYPE_LEVEL_HIGH - 0 337 IRQ_TYPE_LEVEL_HIGH - 0 338 IRQ_TYPE_LEVEL_HIGH - 0 339 IRQ_TYPE_LEVEL_HIGH - 0 340 IRQ_TYPE_LEVEL_HIGH - 0 341 IRQ_TYPE_LEVEL_HIGH - 0 342 IRQ_TYPE_LEVEL_HIGH - 0 343 IRQ_TYPE_LEVEL_HIGH - 0 344 IRQ_TYPE_LEVEL_HIGH - 0 345 IRQ_TYPE_LEVEL_HIGH - 0 346 IRQ_TYPE_LEVEL_HIGH - 0 347 IRQ_TYPE_LEVEL_HIGH - 0 348 IRQ_TYPE_LEVEL_HIGH - 0 349 IRQ_TYPE_LEVEL_HIGH - 0 382 IRQ_TYPE_LEVEL_HIGH - 0 383 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; interrupt-names = "error", "ch0", "ch1", "ch2", "ch3", "ch4", "ch5", "ch6", "ch7", @@ -332,20 +358,123 @@ reg = <0 0xe6060000 0 0x50c>; }; + intc_ex: interrupt-controller@e61c0000 { + compatible = "renesas,intc-ex-r8a7795", "renesas,irqc"; + #interrupt-cells = <2>; + interrupt-controller; + reg = <0 0xe61c0000 0 0x200>; + interrupts = ; + clocks = <&cpg CPG_MOD 407>; + power-domains = <&cpg>; + }; + dmac0: dma-controller@e6700000 { - /* Empty node for now */ + compatible = "renesas,dmac-r8a7795", + "renesas,rcar-dmac"; + reg = <0 0xe6700000 0 0x10000>; + interrupts = ; + interrupt-names = "error", + "ch0", "ch1", "ch2", "ch3", + "ch4", "ch5", "ch6", "ch7", + "ch8", "ch9", "ch10", "ch11", + "ch12", "ch13", "ch14", "ch15"; + clocks = <&cpg CPG_MOD 219>; + clock-names = "fck"; + power-domains = <&cpg>; + #dma-cells = <1>; + dma-channels = <16>; }; dmac1: dma-controller@e7300000 { - /* Empty node for now */ + compatible = "renesas,dmac-r8a7795", + "renesas,rcar-dmac"; + reg = <0 0xe7300000 0 0x10000>; + interrupts = ; + interrupt-names = "error", + "ch0", "ch1", "ch2", "ch3", + "ch4", "ch5", "ch6", "ch7", + "ch8", "ch9", "ch10", "ch11", + "ch12", "ch13", "ch14", "ch15"; + clocks = <&cpg CPG_MOD 218>; + clock-names = "fck"; + power-domains = <&cpg>; + #dma-cells = <1>; + dma-channels = <16>; }; dmac2: dma-controller@e7310000 { - /* Empty node for now */ + compatible = "renesas,dmac-r8a7795", + "renesas,rcar-dmac"; + reg = <0 0xe7310000 0 0x10000>; + interrupts = ; + interrupt-names = "error", + "ch0", "ch1", "ch2", "ch3", + "ch4", "ch5", "ch6", "ch7", + "ch8", "ch9", "ch10", "ch11", + "ch12", "ch13", "ch14", "ch15"; + clocks = <&cpg CPG_MOD 217>; + clock-names = "fck"; + power-domains = <&cpg>; + #dma-cells = <1>; + dma-channels = <16>; }; avb: ethernet@e6800000 { - compatible = "renesas,etheravb-r8a7795"; + compatible = "renesas,etheravb-r8a7795", + "renesas,etheravb-rcar-gen3"; reg = <0 0xe6800000 0 0x800>, <0 0xe6a00000 0 0x10000>; interrupts = , , @@ -387,11 +516,15 @@ }; hscif0: serial@e6540000 { - compatible = "renesas,hscif-r8a7795", "renesas,hscif"; + compatible = "renesas,hscif-r8a7795", + "renesas,rcar-gen3-hscif", + "renesas,hscif"; reg = <0 0xe6540000 0 96>; interrupts = ; - clocks = <&cpg CPG_MOD 520>; - clock-names = "sci_ick"; + clocks = <&cpg CPG_MOD 520>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac1 0x31>, <&dmac1 0x30>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -399,11 +532,15 @@ }; hscif1: serial@e6550000 { - compatible = "renesas,hscif-r8a7795", "renesas,hscif"; + compatible = "renesas,hscif-r8a7795", + "renesas,rcar-gen3-hscif", + "renesas,hscif"; reg = <0 0xe6550000 0 96>; interrupts = ; - clocks = <&cpg CPG_MOD 519>; - clock-names = "sci_ick"; + clocks = <&cpg CPG_MOD 519>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac1 0x33>, <&dmac1 0x32>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -411,11 +548,15 @@ }; hscif2: serial@e6560000 { - compatible = "renesas,hscif-r8a7795", "renesas,hscif"; + compatible = "renesas,hscif-r8a7795", + "renesas,rcar-gen3-hscif", + "renesas,hscif"; reg = <0 0xe6560000 0 96>; interrupts = ; - clocks = <&cpg CPG_MOD 518>; - clock-names = "sci_ick"; + clocks = <&cpg CPG_MOD 518>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac1 0x35>, <&dmac1 0x34>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -423,11 +564,15 @@ }; hscif3: serial@e66a0000 { - compatible = "renesas,hscif-r8a7795", "renesas,hscif"; + compatible = "renesas,hscif-r8a7795", + "renesas,rcar-gen3-hscif", + "renesas,hscif"; reg = <0 0xe66a0000 0 96>; interrupts = ; - clocks = <&cpg CPG_MOD 517>; - clock-names = "sci_ick"; + clocks = <&cpg CPG_MOD 517>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x37>, <&dmac0 0x36>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -435,11 +580,15 @@ }; hscif4: serial@e66b0000 { - compatible = "renesas,hscif-r8a7795", "renesas,hscif"; + compatible = "renesas,hscif-r8a7795", + "renesas,rcar-gen3-hscif", + "renesas,hscif"; reg = <0 0xe66b0000 0 96>; interrupts = ; - clocks = <&cpg CPG_MOD 516>; - clock-names = "sci_ick"; + clocks = <&cpg CPG_MOD 516>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x39>, <&dmac0 0x38>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -447,11 +596,14 @@ }; scif0: serial@e6e60000 { - compatible = "renesas,scif-r8a7795", "renesas,scif"; + compatible = "renesas,scif-r8a7795", + "renesas,rcar-gen3-scif", "renesas,scif"; reg = <0 0xe6e60000 0 64>; interrupts = ; - clocks = <&cpg CPG_MOD 207>; - clock-names = "sci_ick"; + clocks = <&cpg CPG_MOD 207>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac1 0x51>, <&dmac1 0x50>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -459,11 +611,14 @@ }; scif1: serial@e6e68000 { - compatible = "renesas,scif-r8a7795", "renesas,scif"; + compatible = "renesas,scif-r8a7795", + "renesas,rcar-gen3-scif", "renesas,scif"; reg = <0 0xe6e68000 0 64>; interrupts = ; - clocks = <&cpg CPG_MOD 206>; - clock-names = "sci_ick"; + clocks = <&cpg CPG_MOD 206>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac1 0x53>, <&dmac1 0x52>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -471,11 +626,14 @@ }; scif2: serial@e6e88000 { - compatible = "renesas,scif-r8a7795", "renesas,scif"; + compatible = "renesas,scif-r8a7795", + "renesas,rcar-gen3-scif", "renesas,scif"; reg = <0 0xe6e88000 0 64>; interrupts = ; - clocks = <&cpg CPG_MOD 310>; - clock-names = "sci_ick"; + clocks = <&cpg CPG_MOD 310>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac1 0x13>, <&dmac1 0x12>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -483,11 +641,14 @@ }; scif3: serial@e6c50000 { - compatible = "renesas,scif-r8a7795", "renesas,scif"; + compatible = "renesas,scif-r8a7795", + "renesas,rcar-gen3-scif", "renesas,scif"; reg = <0 0xe6c50000 0 64>; interrupts = ; - clocks = <&cpg CPG_MOD 204>; - clock-names = "sci_ick"; + clocks = <&cpg CPG_MOD 204>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x57>, <&dmac0 0x56>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -495,11 +656,14 @@ }; scif4: serial@e6c40000 { - compatible = "renesas,scif-r8a7795", "renesas,scif"; + compatible = "renesas,scif-r8a7795", + "renesas,rcar-gen3-scif", "renesas,scif"; reg = <0 0xe6c40000 0 64>; interrupts = ; - clocks = <&cpg CPG_MOD 203>; - clock-names = "sci_ick"; + clocks = <&cpg CPG_MOD 203>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac0 0x59>, <&dmac0 0x58>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -507,11 +671,14 @@ }; scif5: serial@e6f30000 { - compatible = "renesas,scif-r8a7795", "renesas,scif"; + compatible = "renesas,scif-r8a7795", + "renesas,rcar-gen3-scif", "renesas,scif"; reg = <0 0xe6f30000 0 64>; interrupts = ; - clocks = <&cpg CPG_MOD 202>; - clock-names = "sci_ick"; + clocks = <&cpg CPG_MOD 202>, + <&cpg CPG_CORE R8A7795_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; dmas = <&dmac1 0x5b>, <&dmac1 0x5a>; dma-names = "tx", "rx"; power-domains = <&cpg>; @@ -663,52 +830,52 @@ rcar_sound,src { src0: src@0 { - interrupts = <0 352 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x85>, <&audma1 0x9a>; dma-names = "rx", "tx"; }; src1: src@1 { - interrupts = <0 353 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x87>, <&audma1 0x9c>; dma-names = "rx", "tx"; }; src2: src@2 { - interrupts = <0 354 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x89>, <&audma1 0x9e>; dma-names = "rx", "tx"; }; src3: src@3 { - interrupts = <0 355 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x8b>, <&audma1 0xa0>; dma-names = "rx", "tx"; }; src4: src@4 { - interrupts = <0 356 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x8d>, <&audma1 0xb0>; dma-names = "rx", "tx"; }; src5: src@5 { - interrupts = <0 357 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x8f>, <&audma1 0xb2>; dma-names = "rx", "tx"; }; src6: src@6 { - interrupts = <0 358 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x91>, <&audma1 0xb4>; dma-names = "rx", "tx"; }; src7: src@7 { - interrupts = <0 359 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x93>, <&audma1 0xb6>; dma-names = "rx", "tx"; }; src8: src@8 { - interrupts = <0 360 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x95>, <&audma1 0xb8>; dma-names = "rx", "tx"; }; src9: src@9 { - interrupts = <0 361 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x97>, <&audma1 0xba>; dma-names = "rx", "tx"; }; @@ -716,52 +883,52 @@ rcar_sound,ssi { ssi0: ssi@0 { - interrupts = <0 370 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x01>, <&audma1 0x02>, <&audma0 0x15>, <&audma1 0x16>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi1: ssi@1 { - interrupts = <0 371 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x03>, <&audma1 0x04>, <&audma0 0x49>, <&audma1 0x4a>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi2: ssi@2 { - interrupts = <0 372 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x05>, <&audma1 0x06>, <&audma0 0x63>, <&audma1 0x64>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi3: ssi@3 { - interrupts = <0 373 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x07>, <&audma1 0x08>, <&audma0 0x6f>, <&audma1 0x70>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi4: ssi@4 { - interrupts = <0 374 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x09>, <&audma1 0x0a>, <&audma0 0x71>, <&audma1 0x72>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi5: ssi@5 { - interrupts = <0 375 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x0b>, <&audma1 0x0c>, <&audma0 0x73>, <&audma1 0x74>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi6: ssi@6 { - interrupts = <0 376 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x0d>, <&audma1 0x0e>, <&audma0 0x75>, <&audma1 0x76>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi7: ssi@7 { - interrupts = <0 377 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x0f>, <&audma1 0x10>, <&audma0 0x79>, <&audma1 0x7a>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi8: ssi@8 { - interrupts = <0 378 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x11>, <&audma1 0x12>, <&audma0 0x7b>, <&audma1 0x7c>; dma-names = "rx", "tx", "rxu", "txu"; }; ssi9: ssi@9 { - interrupts = <0 379 IRQ_TYPE_LEVEL_HIGH>; + interrupts = ; dmas = <&audma0 0x13>, <&audma1 0x14>, <&audma0 0x7d>, <&audma1 0x7e>; dma-names = "rx", "tx", "rxu", "txu"; }; @@ -775,5 +942,181 @@ clocks = <&cpg CPG_MOD 815>; status = "disabled"; }; + + xhci0: usb@ee000000 { + compatible = "renesas,xhci-r8a7795"; + reg = <0 0xee000000 0 0xc00>; + interrupts = ; + clocks = <&cpg CPG_MOD 328>; + power-domains = <&cpg>; + status = "disabled"; + }; + + xhci1: usb@ee0400000 { + compatible = "renesas,xhci-r8a7795"; + reg = <0 0xee040000 0 0xc00>; + interrupts = ; + clocks = <&cpg CPG_MOD 327>; + power-domains = <&cpg>; + status = "disabled"; + }; + + usb_dmac0: dma-controller@e65a0000 { + compatible = "renesas,r8a7795-usb-dmac", + "renesas,usb-dmac"; + reg = <0 0xe65a0000 0 0x100>; + interrupts = ; + interrupt-names = "ch0", "ch1"; + clocks = <&cpg CPG_MOD 330>; + power-domains = <&cpg>; + #dma-cells = <1>; + dma-channels = <2>; + }; + + usb_dmac1: dma-controller@e65b0000 { + compatible = "renesas,r8a7795-usb-dmac", + "renesas,usb-dmac"; + reg = <0 0xe65b0000 0 0x100>; + interrupts = ; + interrupt-names = "ch0", "ch1"; + clocks = <&cpg CPG_MOD 331>; + power-domains = <&cpg>; + #dma-cells = <1>; + dma-channels = <2>; + }; + + sdhi0: sd@ee100000 { + compatible = "renesas,sdhi-r8a7795"; + reg = <0 0xee100000 0 0x2000>; + interrupts = ; + clocks = <&cpg CPG_MOD 314>; + power-domains = <&cpg>; + status = "disabled"; + }; + + sdhi1: sd@ee120000 { + compatible = "renesas,sdhi-r8a7795"; + reg = <0 0xee120000 0 0x2000>; + interrupts = ; + clocks = <&cpg CPG_MOD 313>; + power-domains = <&cpg>; + status = "disabled"; + }; + + sdhi2: sd@ee140000 { + compatible = "renesas,sdhi-r8a7795"; + reg = <0 0xee140000 0 0x2000>; + interrupts = ; + clocks = <&cpg CPG_MOD 312>; + power-domains = <&cpg>; + cap-mmc-highspeed; + status = "disabled"; + }; + + sdhi3: sd@ee160000 { + compatible = "renesas,sdhi-r8a7795"; + reg = <0 0xee160000 0 0x2000>; + interrupts = ; + clocks = <&cpg CPG_MOD 311>; + power-domains = <&cpg>; + cap-mmc-highspeed; + status = "disabled"; + }; + + usb2_phy0: usb-phy@ee080200 { + compatible = "renesas,usb2-phy-r8a7795"; + reg = <0 0xee080200 0 0x700>; + interrupts = ; + clocks = <&cpg CPG_MOD 703>; + power-domains = <&cpg>; + #phy-cells = <0>; + status = "disabled"; + }; + + usb2_phy1: usb-phy@ee0a0200 { + compatible = "renesas,usb2-phy-r8a7795"; + reg = <0 0xee0a0200 0 0x700>; + clocks = <&cpg CPG_MOD 702>; + power-domains = <&cpg>; + #phy-cells = <0>; + status = "disabled"; + }; + + usb2_phy2: usb-phy@ee0c0200 { + compatible = "renesas,usb2-phy-r8a7795"; + reg = <0 0xee0c0200 0 0x700>; + clocks = <&cpg CPG_MOD 701>; + power-domains = <&cpg>; + #phy-cells = <0>; + status = "disabled"; + }; + + ehci0: usb@ee080100 { + compatible = "generic-ehci"; + reg = <0 0xee080100 0 0x100>; + interrupts = ; + clocks = <&cpg CPG_MOD 703>; + phys = <&usb2_phy0>; + phy-names = "usb"; + power-domains = <&cpg>; + status = "disabled"; + }; + + ehci1: usb@ee0a0100 { + compatible = "generic-ehci"; + reg = <0 0xee0a0100 0 0x100>; + interrupts = ; + clocks = <&cpg CPG_MOD 702>; + phys = <&usb2_phy1>; + phy-names = "usb"; + power-domains = <&cpg>; + status = "disabled"; + }; + + ehci2: usb@ee0c0100 { + compatible = "generic-ehci"; + reg = <0 0xee0c0100 0 0x100>; + interrupts = ; + clocks = <&cpg CPG_MOD 701>; + phys = <&usb2_phy2>; + phy-names = "usb"; + power-domains = <&cpg>; + status = "disabled"; + }; + + ohci0: usb@ee080000 { + compatible = "generic-ohci"; + reg = <0 0xee080000 0 0x100>; + interrupts = ; + clocks = <&cpg CPG_MOD 703>; + phys = <&usb2_phy0>; + phy-names = "usb"; + power-domains = <&cpg>; + status = "disabled"; + }; + + ohci1: usb@ee0a0000 { + compatible = "generic-ohci"; + reg = <0 0xee0a0000 0 0x100>; + interrupts = ; + clocks = <&cpg CPG_MOD 702>; + phys = <&usb2_phy1>; + phy-names = "usb"; + power-domains = <&cpg>; + status = "disabled"; + }; + + ohci2: usb@ee0c0000 { + compatible = "generic-ohci"; + reg = <0 0xee0c0000 0 0x100>; + interrupts = ; + clocks = <&cpg CPG_MOD 701>; + phys = <&usb2_phy2>; + phy-names = "usb"; + power-domains = <&cpg>; + status = "disabled"; + }; }; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi b/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi index 8c219ccf67a3b4bccba2281e398d77cd450de375..6e27b22704df5630b8a3315ac14cc7032f660695 100644 --- a/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3368-evb.dtsi @@ -111,7 +111,7 @@ pinctrl-0 = <&pwr_key>; button@0 { - gpio-key,wakeup = <1>; + wakeup-source; gpios = <&gpio0 2 GPIO_ACTIVE_LOW>; label = "GPIO Power"; linux,code = <116>; diff --git a/arch/arm64/boot/dts/rockchip/rk3368-r88.dts b/arch/arm64/boot/dts/rockchip/rk3368-r88.dts index 104cbee762bb116d37d06e39ec2b2e644e3adfeb..1f2b642e794ae98219ceb49a58bc177028982dc7 100644 --- a/arch/arm64/boot/dts/rockchip/rk3368-r88.dts +++ b/arch/arm64/boot/dts/rockchip/rk3368-r88.dts @@ -71,7 +71,7 @@ pinctrl-0 = <&pwr_key>; button@0 { - gpio-key,wakeup = <1>; + wakeup-source; gpios = <&gpio0 2 GPIO_ACTIVE_LOW>; label = "GPIO Power"; linux,code = <116>; diff --git a/arch/arm64/boot/dts/rockchip/rk3368.dtsi b/arch/arm64/boot/dts/rockchip/rk3368.dtsi index 122777b1441e8b7f4f3f129659bd42ce1d0f94b9..49d119103e31fff10ce4c94698e4cc35e60d9863 100644 --- a/arch/arm64/boot/dts/rockchip/rk3368.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3368.dtsi @@ -231,8 +231,9 @@ compatible = "rockchip,rk3368-dw-mshc", "rockchip,rk3288-dw-mshc"; reg = <0x0 0xff0c0000 0x0 0x4000>; clock-freq-min-max = <400000 150000000>; - clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>; - clock-names = "biu", "ciu"; + clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>, + <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; interrupts = ; status = "disabled"; @@ -254,8 +255,9 @@ compatible = "rockchip,rk3368-dw-mshc", "rockchip,rk3288-dw-mshc"; reg = <0x0 0xff0f0000 0x0 0x4000>; clock-freq-min-max = <400000 150000000>; - clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>; - clock-names = "biu", "ciu"; + clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>, + <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; interrupts = ; status = "disabled"; diff --git a/arch/arm64/boot/dts/socionext/Makefile b/arch/arm64/boot/dts/socionext/Makefile index 8d727717c24ef87edcac1fb97606a71ccbbe654c..299b67ec4d4499d6fb4a4185caf67a722dfb5168 100644 --- a/arch/arm64/boot/dts/socionext/Makefile +++ b/arch/arm64/boot/dts/socionext/Makefile @@ -1,4 +1,4 @@ -dtb-$(CONFIG_ARCH_UNIPHIER) += uniphier-ph1-ld10-ref.dtb +dtb-$(CONFIG_ARCH_UNIPHIER) += uniphier-ph1-ld20-ref.dtb always := $(dtb-y) clean-files := *.dtb diff --git a/arch/arm64/boot/dts/socionext/uniphier-ph1-ld10-ref.dts b/arch/arm64/boot/dts/socionext/uniphier-ph1-ld20-ref.dts similarity index 88% rename from arch/arm64/boot/dts/socionext/uniphier-ph1-ld10-ref.dts rename to arch/arm64/boot/dts/socionext/uniphier-ph1-ld20-ref.dts index 3e533178ba2f24b2fd4f753d89d9a6afc669a2e7..727ae5f8c4e716178a4cda1e484b5118a16646c5 100644 --- a/arch/arm64/boot/dts/socionext/uniphier-ph1-ld10-ref.dts +++ b/arch/arm64/boot/dts/socionext/uniphier-ph1-ld20-ref.dts @@ -1,5 +1,5 @@ /* - * Device Tree Source for UniPhier PH1-LD10 Reference Board + * Device Tree Source for UniPhier PH1-LD20 Reference Board * * Copyright (C) 2015 Masahiro Yamada * @@ -43,12 +43,12 @@ */ /dts-v1/; -/include/ "uniphier-ph1-ld10.dtsi" +/include/ "uniphier-ph1-ld20.dtsi" /include/ "uniphier-support-card.dtsi" / { - model = "UniPhier PH1-LD10 Reference Board"; - compatible = "socionext,ph1-ld10-ref", "socionext,ph1-ld10"; + model = "UniPhier PH1-LD20 Reference Board"; + compatible = "socionext,ph1-ld20-ref", "socionext,ph1-ld20"; memory { device_type = "memory"; @@ -74,14 +74,6 @@ }; }; -&extbus { - ranges = <1 0x00000000 0x42000000 0x02000000>; -}; - -&support_card { - ranges = <0x00000000 1 0x01f00000 0x00100000>; -}; - ðsc { interrupts = <0 48 4>; }; diff --git a/arch/arm64/boot/dts/socionext/uniphier-ph1-ld10.dtsi b/arch/arm64/boot/dts/socionext/uniphier-ph1-ld20.dtsi similarity index 94% rename from arch/arm64/boot/dts/socionext/uniphier-ph1-ld10.dtsi rename to arch/arm64/boot/dts/socionext/uniphier-ph1-ld20.dtsi index 0296af9cbbdb64cb08054471ee725071cb4865f3..e682a3f52791b38caf45defec637e8247e64f6a3 100644 --- a/arch/arm64/boot/dts/socionext/uniphier-ph1-ld10.dtsi +++ b/arch/arm64/boot/dts/socionext/uniphier-ph1-ld20.dtsi @@ -1,5 +1,5 @@ /* - * Device Tree Source for UniPhier PH1-LD10 SoC + * Device Tree Source for UniPhier PH1-LD20 SoC * * Copyright (C) 2015 Masahiro Yamada * @@ -43,7 +43,7 @@ */ / { - compatible = "socionext,ph1-ld10"; + compatible = "socionext,ph1-ld20"; #address-cells = <2>; #size-cells = <2>; interrupt-parent = <&gic>; @@ -133,12 +133,6 @@ #size-cells = <1>; ranges = <0 0 0 0xffffffff>; - extbus: extbus { - compatible = "simple-bus"; - #address-cells = <2>; - #size-cells = <1>; - }; - serial0: serial@54006800 { compatible = "socionext,uniphier-uart"; status = "disabled"; @@ -261,8 +255,21 @@ clock-frequency = <400000>; }; + system_bus: system-bus@58c00000 { + compatible = "socionext,uniphier-system-bus"; + status = "disabled"; + reg = <0x58c00000 0x400>; + #address-cells = <2>; + #size-cells = <1>; + }; + + smpctrl@59800000 { + compatible = "socionext,uniphier-smpctrl"; + reg = <0x59801000 0x400>; + }; + pinctrl: pinctrl@5f801000 { - compatible = "socionext,ph1-ld10-pinctrl", "syscon"; + compatible = "socionext,ph1-ld20-pinctrl", "syscon"; reg = <0x5f801000 0xe00>; }; diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-ep108-clk.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp-ep108-clk.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..cdc6a437dcc73d33c0aaedb28df523cda333891a --- /dev/null +++ b/arch/arm64/boot/dts/xilinx/zynqmp-ep108-clk.dtsi @@ -0,0 +1,88 @@ +/* + * clock specification for Xilinx ZynqMP ep108 development board + * + * (C) Copyright 2015, Xilinx, Inc. + * + * Michal Simek + * + * 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. + */ + +&amba { + misc_clk: misc_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; + + i2c_clk: i2c_clk { + compatible = "fixed-clock"; + #clock-cells = <0x0>; + clock-frequency = <111111111>; + }; + + sata_clk: sata_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <75000000>; + }; +}; + +&can0 { + clocks = <&misc_clk &misc_clk>; +}; + +&gem0 { + clocks = <&misc_clk>, <&misc_clk>, <&misc_clk>; +}; + +&gpio { + clocks = <&misc_clk>; +}; + +&i2c0 { + clocks = <&i2c_clk>; +}; + +&i2c1 { + clocks = <&i2c_clk>; +}; + +&sata { + clocks = <&sata_clk>; +}; + +&sdhci0 { + clocks = <&misc_clk>, <&misc_clk>; +}; + +&sdhci1 { + clocks = <&misc_clk>, <&misc_clk>; +}; + +&spi0 { + clocks = <&misc_clk &misc_clk>; +}; + +&spi1 { + clocks = <&misc_clk &misc_clk>; +}; + +&uart0 { + clocks = <&misc_clk &misc_clk>; +}; + +&usb0 { + clocks = <&misc_clk>, <&misc_clk>; +}; + +&usb1 { + clocks = <&misc_clk>, <&misc_clk>; +}; + +&watchdog0 { + clocks= <&misc_clk>; +}; diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts b/arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts index ce5d848251fab63cf0bba9a9cb58d1681c221011..acb0527fdc4ad983a042589168d55bbcb1558efd 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts +++ b/arch/arm64/boot/dts/xilinx/zynqmp-ep108.dts @@ -14,6 +14,7 @@ /dts-v1/; /include/ "zynqmp.dtsi" +/include/ "zynqmp-ep108-clk.dtsi" / { model = "ZynqMP EP108"; diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi index 200fb588d0f544220bf5c3a0e92e35af543b6446..e595f22e7e4b67521c5e1720ea0fafeb7273a1c0 100644 --- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi +++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi @@ -90,7 +90,7 @@ }; }; - amba { + amba: amba { compatible = "simple-bus"; #address-cells = <2>; #size-cells = <1>; @@ -99,7 +99,6 @@ can0: can@ff060000 { compatible = "xlnx,zynq-can-1.0"; status = "disabled"; - clocks = <&misc_clk &misc_clk>; clock-names = "can_clk", "pclk"; reg = <0x0 0xff060000 0x1000>; interrupts = <0 23 4>; @@ -111,7 +110,6 @@ can1: can@ff070000 { compatible = "xlnx,zynq-can-1.0"; status = "disabled"; - clocks = <&misc_clk &misc_clk>; clock-names = "can_clk", "pclk"; reg = <0x0 0xff070000 0x1000>; interrupts = <0 24 4>; @@ -120,24 +118,6 @@ rx-fifo-depth = <0x40>; }; - misc_clk: misc_clk { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <25000000>; - }; - - gpio: gpio@ff0a0000 { - compatible = "xlnx,zynqmp-gpio-1.0"; - status = "disabled"; - #gpio-cells = <0x2>; - clocks = <&misc_clk>; - interrupt-parent = <&gic>; - interrupts = <0 16 4>; - interrupt-controller; - #interrupt-cells = <2>; - reg = <0x0 0xff0a0000 0x1000>; - }; - gem0: ethernet@ff0b0000 { compatible = "cdns,gem"; status = "disabled"; @@ -145,7 +125,6 @@ interrupts = <0 57 4>, <0 57 4>; reg = <0x0 0xff0b0000 0x1000>; clock-names = "pclk", "hclk", "tx_clk"; - clocks = <&misc_clk>, <&misc_clk>, <&misc_clk>; #address-cells = <1>; #size-cells = <0>; }; @@ -157,7 +136,6 @@ interrupts = <0 59 4>, <0 59 4>; reg = <0x0 0xff0c0000 0x1000>; clock-names = "pclk", "hclk", "tx_clk"; - clocks = <&misc_clk>, <&misc_clk>, <&misc_clk>; #address-cells = <1>; #size-cells = <0>; }; @@ -169,7 +147,6 @@ interrupts = <0 61 4>, <0 61 4>; reg = <0x0 0xff0d0000 0x1000>; clock-names = "pclk", "hclk", "tx_clk"; - clocks = <&misc_clk>, <&misc_clk>, <&misc_clk>; #address-cells = <1>; #size-cells = <0>; }; @@ -181,15 +158,19 @@ interrupts = <0 63 4>, <0 63 4>; reg = <0x0 0xff0e0000 0x1000>; clock-names = "pclk", "hclk", "tx_clk"; - clocks = <&misc_clk>, <&misc_clk>, <&misc_clk>; #address-cells = <1>; #size-cells = <0>; }; - i2c_clk: i2c_clk { - compatible = "fixed-clock"; - #clock-cells = <0x0>; - clock-frequency = <111111111>; + gpio: gpio@ff0a0000 { + compatible = "xlnx,zynqmp-gpio-1.0"; + status = "disabled"; + #gpio-cells = <0x2>; + interrupt-parent = <&gic>; + interrupts = <0 16 4>; + interrupt-controller; + #interrupt-cells = <2>; + reg = <0x0 0xff0a0000 0x1000>; }; i2c0: i2c@ff020000 { @@ -198,7 +179,6 @@ interrupt-parent = <&gic>; interrupts = <0 17 4>; reg = <0x0 0xff020000 0x1000>; - clocks = <&i2c_clk>; #address-cells = <1>; #size-cells = <0>; }; @@ -209,24 +189,16 @@ interrupt-parent = <&gic>; interrupts = <0 18 4>; reg = <0x0 0xff030000 0x1000>; - clocks = <&i2c_clk>; #address-cells = <1>; #size-cells = <0>; }; - sata_clk: sata_clk { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <75000000>; - }; - sata: ahci@fd0c0000 { compatible = "ceva,ahci-1v84"; status = "disabled"; reg = <0x0 0xfd0c0000 0x2000>; interrupt-parent = <&gic>; interrupts = <0 133 4>; - clocks = <&sata_clk>; }; sdhci0: sdhci@ff160000 { @@ -236,7 +208,6 @@ interrupts = <0 48 4>; reg = <0x0 0xff160000 0x1000>; clock-names = "clk_xin", "clk_ahb"; - clocks = <&misc_clk>, <&misc_clk>; }; sdhci1: sdhci@ff170000 { @@ -246,7 +217,6 @@ interrupts = <0 49 4>; reg = <0x0 0xff170000 0x1000>; clock-names = "clk_xin", "clk_ahb"; - clocks = <&misc_clk>, <&misc_clk>; }; smmu: smmu@fd800000 { @@ -268,7 +238,6 @@ interrupts = <0 19 4>; reg = <0x0 0xff040000 0x1000>; clock-names = "ref_clk", "pclk"; - clocks = <&misc_clk &misc_clk>; #address-cells = <1>; #size-cells = <0>; }; @@ -280,7 +249,6 @@ interrupts = <0 20 4>; reg = <0x0 0xff050000 0x1000>; clock-names = "ref_clk", "pclk"; - clocks = <&misc_clk &misc_clk>; #address-cells = <1>; #size-cells = <0>; }; @@ -291,7 +259,6 @@ interrupt-parent = <&gic>; interrupts = <0 36 4>, <0 37 4>, <0 38 4>; reg = <0x0 0xff110000 0x1000>; - clocks = <&misc_clk>; timer-width = <32>; }; @@ -301,7 +268,6 @@ interrupt-parent = <&gic>; interrupts = <0 39 4>, <0 40 4>, <0 41 4>; reg = <0x0 0xff120000 0x1000>; - clocks = <&misc_clk>; timer-width = <32>; }; @@ -311,7 +277,6 @@ interrupt-parent = <&gic>; interrupts = <0 42 4>, <0 43 4>, <0 44 4>; reg = <0x0 0xff130000 0x1000>; - clocks = <&misc_clk>; timer-width = <32>; }; @@ -321,7 +286,6 @@ interrupt-parent = <&gic>; interrupts = <0 45 4>, <0 46 4>, <0 47 4>; reg = <0x0 0xff140000 0x1000>; - clocks = <&misc_clk>; timer-width = <32>; }; @@ -332,7 +296,6 @@ interrupts = <0 21 4>; reg = <0x0 0xff000000 0x1000>; clock-names = "uart_clk", "pclk"; - clocks = <&misc_clk &misc_clk>; }; uart1: serial@ff010000 { @@ -342,7 +305,6 @@ interrupts = <0 22 4>; reg = <0x0 0xff010000 0x1000>; clock-names = "uart_clk", "pclk"; - clocks = <&misc_clk &misc_clk>; }; usb0: usb@fe200000 { @@ -352,7 +314,6 @@ interrupts = <0 65 4>; reg = <0x0 0xfe200000 0x40000>; clock-names = "clk_xin", "clk_ahb"; - clocks = <&misc_clk>, <&misc_clk>; }; usb1: usb@fe300000 { @@ -362,13 +323,11 @@ interrupts = <0 70 4>; reg = <0x0 0xfe300000 0x40000>; clock-names = "clk_xin", "clk_ahb"; - clocks = <&misc_clk>, <&misc_clk>; }; watchdog0: watchdog@fd4d0000 { compatible = "cdns,wdt-r1p2"; status = "disabled"; - clocks= <&misc_clk>; interrupt-parent = <&gic>; interrupts = <0 52 1>; reg = <0x0 0xfd4d0000 0x1000>; diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 86581f793e398ba29eb1e12e77498405cdeb2e6d..a44ef995d8ae86e00a11876ea04d15a68e85233d 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -30,12 +30,15 @@ CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_IOSCHED_DEADLINE is not set +CONFIG_ARCH_SUNXI=y +CONFIG_ARCH_ALPINE=y CONFIG_ARCH_BCM_IPROC=y CONFIG_ARCH_BERLIN=y -CONFIG_ARCH_EXYNOS7=y +CONFIG_ARCH_EXYNOS=y CONFIG_ARCH_LAYERSCAPE=y CONFIG_ARCH_HISI=y CONFIG_ARCH_MEDIATEK=y +CONFIG_ARCH_MVEBU=y CONFIG_ARCH_QCOM=y CONFIG_ARCH_ROCKCHIP=y CONFIG_ARCH_SEATTLE=y @@ -47,6 +50,7 @@ CONFIG_ARCH_SPRD=y CONFIG_ARCH_THUNDER=y CONFIG_ARCH_UNIPHIER=y CONFIG_ARCH_VEXPRESS=y +CONFIG_ARCH_VULCAN=y CONFIG_ARCH_XGENE=y CONFIG_ARCH_ZYNQMP=y CONFIG_PCI=y @@ -64,11 +68,13 @@ CONFIG_KSM=y CONFIG_TRANSPARENT_HUGEPAGE=y CONFIG_CMA=y CONFIG_XEN=y -CONFIG_CMDLINE="console=ttyAMA0" # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_COMPAT=y CONFIG_CPU_IDLE=y CONFIG_ARM_CPUIDLE=y +CONFIG_CPU_FREQ=y +CONFIG_ARM_BIG_LITTLE_CPUFREQ=y +CONFIG_ARM_SCPI_CPUFREQ=y CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y @@ -76,7 +82,6 @@ CONFIG_INET=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y -# CONFIG_INET_LRO is not set # CONFIG_IPV6 is not set CONFIG_BPF_JIT=y # CONFIG_WIRELESS is not set @@ -95,6 +100,7 @@ CONFIG_ATA=y CONFIG_SATA_AHCI=y CONFIG_SATA_AHCI_PLATFORM=y CONFIG_AHCI_CEVA=y +CONFIG_AHCI_MVEBU=y CONFIG_AHCI_XGENE=y CONFIG_SATA_RCAR=y CONFIG_PATA_PLATFORM=y @@ -136,24 +142,42 @@ CONFIG_SERIAL_MSM=y CONFIG_SERIAL_MSM_CONSOLE=y CONFIG_SERIAL_XILINX_PS_UART=y CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y +CONFIG_SERIAL_MVEBU_UART=y CONFIG_VIRTIO_CONSOLE=y # CONFIG_HW_RANDOM is not set +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_DESIGNWARE_PLATFORM=y +CONFIG_I2C_MV64XXX=y CONFIG_I2C_QUP=y +CONFIG_I2C_TEGRA=y CONFIG_I2C_UNIPHIER_F=y CONFIG_I2C_RCAR=y CONFIG_SPI=y CONFIG_SPI_PL022=y CONFIG_SPI_QUP=y +CONFIG_SPMI=y +CONFIG_PINCTRL_SINGLE=y CONFIG_PINCTRL_MSM8916=y +CONFIG_PINCTRL_QCOM_SPMI_PMIC=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_DWAPB=y CONFIG_GPIO_PL061=y CONFIG_GPIO_RCAR=y CONFIG_GPIO_XGENE=y +CONFIG_POWER_RESET_MSM=y CONFIG_POWER_RESET_XGENE=y CONFIG_POWER_RESET_SYSCON=y # CONFIG_HWMON is not set +CONFIG_THERMAL=y +CONFIG_THERMAL_EMULATION=y +CONFIG_EXYNOS_THERMAL=y +CONFIG_MFD_SPMI_PMIC=y +CONFIG_MFD_SEC_CORE=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_QCOM_SMD_RPM=y +CONFIG_REGULATOR_QCOM_SPMI=y +CONFIG_REGULATOR_S2MPS11=y CONFIG_FB=y CONFIG_FB_ARMCLCD=y CONFIG_FRAMEBUFFER_CONSOLE=y @@ -166,34 +190,52 @@ CONFIG_SND_SOC=y CONFIG_SND_SOC_RCAR=y CONFIG_SND_SOC_AK4613=y CONFIG_USB=y +CONFIG_USB_OTG=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_PLATFORM=y CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_MSM=y CONFIG_USB_EHCI_HCD_PLATFORM=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_HCD_PLATFORM=y CONFIG_USB_STORAGE=y +CONFIG_USB_DWC2=y +CONFIG_USB_CHIPIDEA=y +CONFIG_USB_CHIPIDEA_UDC=y +CONFIG_USB_CHIPIDEA_HOST=y CONFIG_USB_ISP1760=y +CONFIG_USB_HSIC_USB3503=y +CONFIG_USB_MSM_OTG=y CONFIG_USB_ULPI=y +CONFIG_USB_GADGET=y CONFIG_MMC=y +CONFIG_MMC_BLOCK_MINORS=32 CONFIG_MMC_ARMMMCI=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y CONFIG_MMC_SDHCI_TEGRA=y +CONFIG_MMC_SDHCI_MSM=y CONFIG_MMC_SPI=y CONFIG_MMC_DW=y CONFIG_MMC_DW_EXYNOS=y +CONFIG_MMC_DW_K3=y +CONFIG_MMC_SUNXI=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y CONFIG_LEDS_SYSCON=y CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_LEDS_TRIGGER_CPU=y CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_S5M=y CONFIG_RTC_DRV_EFI=y CONFIG_RTC_DRV_PL031=y +CONFIG_RTC_DRV_SUN6I=y CONFIG_RTC_DRV_XGENE=y CONFIG_DMADEVICES=y -CONFIG_QCOM_BAM_DMA=y CONFIG_TEGRA20_APB_DMA=y +CONFIG_QCOM_BAM_DMA=y CONFIG_RCAR_DMAC=y CONFIG_VFIO=y CONFIG_VFIO_PCI=y @@ -202,18 +244,26 @@ CONFIG_VIRTIO_BALLOON=y CONFIG_VIRTIO_MMIO=y CONFIG_XEN_GNTDEV=y CONFIG_XEN_GRANT_DEV_ALLOC=y +CONFIG_COMMON_CLK_SCPI=y CONFIG_COMMON_CLK_CS2000_CP=y CONFIG_COMMON_CLK_QCOM=y CONFIG_MSM_GCC_8916=y CONFIG_HWSPINLOCK_QCOM=y +CONFIG_MAILBOX=y +CONFIG_ARM_MHU=y +CONFIG_HI6220_MBOX=y CONFIG_ARM_SMMU=y CONFIG_QCOM_SMEM=y CONFIG_QCOM_SMD=y CONFIG_QCOM_SMD_RPM=y CONFIG_ARCH_TEGRA_132_SOC=y CONFIG_ARCH_TEGRA_210_SOC=y -CONFIG_HISILICON_IRQ_MBIGEN=y +CONFIG_EXTCON_USB_GPIO=y +CONFIG_COMMON_RESET_HI6220=y +CONFIG_PHY_RCAR_GEN3_USB2=y +CONFIG_PHY_HI6220_USB=y CONFIG_PHY_XGENE=y +CONFIG_ARM_SCPI_PROTOCOL=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y CONFIG_FANOTIFY=y @@ -225,6 +275,7 @@ CONFIG_CUSE=y CONFIG_VFAT_FS=y CONFIG_TMPFS=y CONFIG_HUGETLBFS=y +CONFIG_CONFIGFS_FS=y CONFIG_EFIVAR_FS=y CONFIG_SQUASHFS=y CONFIG_NFS_FS=y diff --git a/arch/arm64/include/asm/cacheflush.h b/arch/arm64/include/asm/cacheflush.h index 22dda613f9c91bd3bcfe3a8aad435f7384795401..c64268dbff64c0e9486c0261c0c49c9759785ba4 100644 --- a/arch/arm64/include/asm/cacheflush.h +++ b/arch/arm64/include/asm/cacheflush.h @@ -116,13 +116,6 @@ extern void copy_to_user_page(struct vm_area_struct *, struct page *, #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 extern void flush_dcache_page(struct page *); -static inline void __local_flush_icache_all(void) -{ - asm("ic iallu"); - dsb(nsh); - isb(); -} - static inline void __flush_icache_all(void) { asm("ic ialluis"); diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h index f2309a25d14c8b40741a03a2da8926887a67016f..87e1985f3be8c5912d1b1ca4fbc5d8d70024db50 100644 --- a/arch/arm64/include/asm/cputype.h +++ b/arch/arm64/include/asm/cputype.h @@ -70,6 +70,7 @@ #define ARM_CPU_IMP_ARM 0x41 #define ARM_CPU_IMP_APM 0x50 #define ARM_CPU_IMP_CAVIUM 0x43 +#define ARM_CPU_IMP_BRCM 0x42 #define ARM_CPU_PART_AEM_V8 0xD0F #define ARM_CPU_PART_FOUNDATION 0xD00 @@ -80,6 +81,8 @@ #define CAVIUM_CPU_PART_THUNDERX 0x0A1 +#define BRCM_CPU_PART_VULCAN 0x516 + #define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53) #define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57) #define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX) diff --git a/arch/arm64/include/asm/exception.h b/arch/arm64/include/asm/exception.h index 6cb7e1a6bc02a54237d7475ae20406039b14ed4b..0c2eec490abf65933b2d965270dfaf89523f3417 100644 --- a/arch/arm64/include/asm/exception.h +++ b/arch/arm64/include/asm/exception.h @@ -18,7 +18,7 @@ #ifndef __ASM_EXCEPTION_H #define __ASM_EXCEPTION_H -#include +#include #define __exception __attribute__((section(".exception.text"))) #ifdef CONFIG_FUNCTION_GRAPH_TRACER diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h index 0e391dbfc42023aad2dabf26b5e9d7b49fa8aec2..4150fd8bae0144c71e1bd956c9b56fe8e9317438 100644 --- a/arch/arm64/include/asm/kvm_arm.h +++ b/arch/arm64/include/asm/kvm_arm.h @@ -124,7 +124,9 @@ #define VTCR_EL2_SL0_LVL1 (1 << 6) #define VTCR_EL2_T0SZ_MASK 0x3f #define VTCR_EL2_T0SZ_40B 24 -#define VTCR_EL2_VS 19 +#define VTCR_EL2_VS_SHIFT 19 +#define VTCR_EL2_VS_8BIT (0 << VTCR_EL2_VS_SHIFT) +#define VTCR_EL2_VS_16BIT (1 << VTCR_EL2_VS_SHIFT) /* * We configure the Stage-2 page tables to always restrict the IPA space to be diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h index 226f49d69ea98ed0a5dac3eb9448be4f460eb548..eb7490d232a0f39328c42fd646de8b5548feb178 100644 --- a/arch/arm64/include/asm/kvm_asm.h +++ b/arch/arm64/include/asm/kvm_asm.h @@ -26,7 +26,13 @@ #define KVM_ARM64_DEBUG_DIRTY_SHIFT 0 #define KVM_ARM64_DEBUG_DIRTY (1 << KVM_ARM64_DEBUG_DIRTY_SHIFT) -#define kvm_ksym_ref(sym) phys_to_virt((u64)&sym - kimage_voffset) +#define kvm_ksym_ref(sym) \ + ({ \ + void *val = &sym; \ + if (!is_kernel_in_hyp_mode()) \ + val = phys_to_virt((u64)&sym - kimage_voffset); \ + val; \ + }) #ifndef __ASSEMBLY__ struct kvm; diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 227ed475dbd3c328abbfab391fa4d62bf953f034..b7e82a795ac9e087098c957b42e717c0fad0985c 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -27,7 +27,6 @@ #include #include #include -#include #define __KVM_HAVE_ARCH_INTC_INITIALIZED diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h index a46b019ebcf5a94c201a080e44de1cf5baceeb82..44eaff70da6ae0644fce7df9901dbd4aa71705ec 100644 --- a/arch/arm64/include/asm/kvm_hyp.h +++ b/arch/arm64/include/asm/kvm_hyp.h @@ -21,7 +21,6 @@ #include #include #include -#include #include #define __hyp_text __section(.hyp.text) notrace diff --git a/arch/arm64/include/asm/kvm_perf_event.h b/arch/arm64/include/asm/kvm_perf_event.h deleted file mode 100644 index c18fdebb8f66d0b83a9091774f2d65b5a27a0019..0000000000000000000000000000000000000000 --- a/arch/arm64/include/asm/kvm_perf_event.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2012 ARM 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __ASM_KVM_PERF_EVENT_H -#define __ASM_KVM_PERF_EVENT_H - -#define ARMV8_PMU_MAX_COUNTERS 32 -#define ARMV8_PMU_COUNTER_MASK (ARMV8_PMU_MAX_COUNTERS - 1) - -/* - * Per-CPU PMCR: config reg - */ -#define ARMV8_PMU_PMCR_E (1 << 0) /* Enable all counters */ -#define ARMV8_PMU_PMCR_P (1 << 1) /* Reset all counters */ -#define ARMV8_PMU_PMCR_C (1 << 2) /* Cycle counter reset */ -#define ARMV8_PMU_PMCR_D (1 << 3) /* CCNT counts every 64th cpu cycle */ -#define ARMV8_PMU_PMCR_X (1 << 4) /* Export to ETM */ -#define ARMV8_PMU_PMCR_DP (1 << 5) /* Disable CCNT if non-invasive debug*/ -/* Determines which bit of PMCCNTR_EL0 generates an overflow */ -#define ARMV8_PMU_PMCR_LC (1 << 6) -#define ARMV8_PMU_PMCR_N_SHIFT 11 /* Number of counters supported */ -#define ARMV8_PMU_PMCR_N_MASK 0x1f -#define ARMV8_PMU_PMCR_MASK 0x7f /* Mask for writable bits */ - -/* - * PMOVSR: counters overflow flag status reg - */ -#define ARMV8_PMU_OVSR_MASK 0xffffffff /* Mask for writable bits */ -#define ARMV8_PMU_OVERFLOWED_MASK ARMV8_PMU_OVSR_MASK - -/* - * PMXEVTYPER: Event selection reg - */ -#define ARMV8_PMU_EVTYPE_MASK 0xc80003ff /* Mask for writable bits */ -#define ARMV8_PMU_EVTYPE_EVENT 0x3ff /* Mask for EVENT bits */ - -#define ARMV8_PMU_EVTYPE_EVENT_SW_INCR 0 /* Software increment event */ - -/* - * Event filters for PMUv3 - */ -#define ARMV8_PMU_EXCLUDE_EL1 (1 << 31) -#define ARMV8_PMU_EXCLUDE_EL0 (1 << 30) -#define ARMV8_PMU_INCLUDE_EL2 (1 << 27) - -/* - * PMUSERENR: user enable reg - */ -#define ARMV8_PMU_USERENR_MASK 0xf /* Mask for writable bits */ -#define ARMV8_PMU_USERENR_EN (1 << 0) /* PMU regs can be accessed at EL0 */ -#define ARMV8_PMU_USERENR_SW (1 << 1) /* PMSWINC can be written at EL0 */ -#define ARMV8_PMU_USERENR_CR (1 << 2) /* Cycle counter can be read at EL0 */ -#define ARMV8_PMU_USERENR_ER (1 << 3) /* Event counter can be read at EL0 */ - -#endif diff --git a/arch/arm64/include/asm/opcodes.h b/arch/arm64/include/asm/opcodes.h index 4e603ea36ad3f687ab0c84fd5f127dfe7c5fd8a0..123f45d92cd1fe568a29f8e0fe421e6d953a291d 100644 --- a/arch/arm64/include/asm/opcodes.h +++ b/arch/arm64/include/asm/opcodes.h @@ -1 +1,5 @@ +#ifdef CONFIG_CPU_BIG_ENDIAN +#define CONFIG_CPU_ENDIAN_BE8 CONFIG_CPU_BIG_ENDIAN +#endif + #include <../../arm/include/asm/opcodes.h> diff --git a/arch/arm64/include/asm/perf_event.h b/arch/arm64/include/asm/perf_event.h index 7bd3cdb533ea80bd49ef6901b855e124d82cb500..2065f46fa7407deb4d43e7dc8783ca8667759500 100644 --- a/arch/arm64/include/asm/perf_event.h +++ b/arch/arm64/include/asm/perf_event.h @@ -17,6 +17,53 @@ #ifndef __ASM_PERF_EVENT_H #define __ASM_PERF_EVENT_H +#define ARMV8_PMU_MAX_COUNTERS 32 +#define ARMV8_PMU_COUNTER_MASK (ARMV8_PMU_MAX_COUNTERS - 1) + +/* + * Per-CPU PMCR: config reg + */ +#define ARMV8_PMU_PMCR_E (1 << 0) /* Enable all counters */ +#define ARMV8_PMU_PMCR_P (1 << 1) /* Reset all counters */ +#define ARMV8_PMU_PMCR_C (1 << 2) /* Cycle counter reset */ +#define ARMV8_PMU_PMCR_D (1 << 3) /* CCNT counts every 64th cpu cycle */ +#define ARMV8_PMU_PMCR_X (1 << 4) /* Export to ETM */ +#define ARMV8_PMU_PMCR_DP (1 << 5) /* Disable CCNT if non-invasive debug*/ +#define ARMV8_PMU_PMCR_LC (1 << 6) /* Overflow on 64 bit cycle counter */ +#define ARMV8_PMU_PMCR_N_SHIFT 11 /* Number of counters supported */ +#define ARMV8_PMU_PMCR_N_MASK 0x1f +#define ARMV8_PMU_PMCR_MASK 0x7f /* Mask for writable bits */ + +/* + * PMOVSR: counters overflow flag status reg + */ +#define ARMV8_PMU_OVSR_MASK 0xffffffff /* Mask for writable bits */ +#define ARMV8_PMU_OVERFLOWED_MASK ARMV8_PMU_OVSR_MASK + +/* + * PMXEVTYPER: Event selection reg + */ +#define ARMV8_PMU_EVTYPE_MASK 0xc800ffff /* Mask for writable bits */ +#define ARMV8_PMU_EVTYPE_EVENT 0xffff /* Mask for EVENT bits */ + +#define ARMV8_PMU_EVTYPE_EVENT_SW_INCR 0 /* Software increment event */ + +/* + * Event filters for PMUv3 + */ +#define ARMV8_PMU_EXCLUDE_EL1 (1 << 31) +#define ARMV8_PMU_EXCLUDE_EL0 (1 << 30) +#define ARMV8_PMU_INCLUDE_EL2 (1 << 27) + +/* + * PMUSERENR: user enable reg + */ +#define ARMV8_PMU_USERENR_MASK 0xf /* Mask for writable bits */ +#define ARMV8_PMU_USERENR_EN (1 << 0) /* PMU regs can be accessed at EL0 */ +#define ARMV8_PMU_USERENR_SW (1 << 1) /* PMSWINC can be written at EL0 */ +#define ARMV8_PMU_USERENR_CR (1 << 2) /* Cycle counter can be read at EL0 */ +#define ARMV8_PMU_USERENR_ER (1 << 3) /* Event counter can be read at EL0 */ + #ifdef CONFIG_PERF_EVENTS struct pt_regs; extern unsigned long perf_instruction_pointer(struct pt_regs *regs); diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index 1a78d6e2a78b58bf21113de3810785a81a35a29d..12874164b0ae5198cfc9d00d1721d8f58cb8ae51 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -141,6 +141,9 @@ #define ID_AA64MMFR1_VMIDBITS_SHIFT 4 #define ID_AA64MMFR1_HADBS_SHIFT 0 +#define ID_AA64MMFR1_VMIDBITS_8 0 +#define ID_AA64MMFR1_VMIDBITS_16 2 + /* id_aa64mmfr2 */ #define ID_AA64MMFR2_UAO_SHIFT 4 diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index 1f7f5a2b61bf0de999d80e6ced16bec120f716b6..12e8d2bcb3f9da4e643649442685138dea7966d1 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -277,7 +277,7 @@ END(vectors) * Invalid mode handlers */ .macro inv_entry, el, reason, regsize = 64 - kernel_entry el, \regsize + kernel_entry \el, \regsize mov x0, sp mov x1, #\reason mrs x2, esr_el1 diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index 6ebd204da16ab680fc66cf1669536170e495bc3a..4203d5f257bcf396f8cdadb4f613d7048b486f59 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -758,7 +758,7 @@ ENTRY(__early_cpu_boot_status) */ .section ".idmap.text", "ax" __enable_mmu: - mrs x18, sctlr_el1 // preserve old SCTLR_EL1 value + mrs x22, sctlr_el1 // preserve old SCTLR_EL1 value mrs x1, ID_AA64MMFR0_EL1 ubfx x2, x1, #ID_AA64MMFR0_TGRAN_SHIFT, 4 cmp x2, #ID_AA64MMFR0_TGRAN_SUPPORTED @@ -786,14 +786,15 @@ __enable_mmu: * to take into account by discarding the current kernel mapping and * creating a new one. */ - msr sctlr_el1, x18 // disable the MMU + msr sctlr_el1, x22 // disable the MMU isb bl __create_page_tables // recreate kernel mapping msr sctlr_el1, x19 // re-enable the MMU isb - ic ialluis // flush instructions fetched - isb // via old mapping + ic iallu // flush instructions fetched + dsb nsh // via old mapping + isb add x27, x27, x23 // relocated __mmap_switched #endif br x27 diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index 1b52269ffa87e00a6a6541ff5b56d573c51e60ef..f419a7c075a4754ff57d416c6397b5fc1ac49fcb 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c @@ -20,6 +20,7 @@ */ #include +#include #include #include @@ -88,16 +89,25 @@ #define ARMV8_PMUV3_PERFCTR_L2D_TLB 0x2F #define ARMV8_PMUV3_PERFCTR_L21_TLB 0x30 +/* ARMv8 implementation defined event types. */ +#define ARMV8_IMPDEF_PERFCTR_L1_DCACHE_ACCESS_LD 0x40 +#define ARMV8_IMPDEF_PERFCTR_L1_DCACHE_ACCESS_ST 0x41 +#define ARMV8_IMPDEF_PERFCTR_L1_DCACHE_REFILL_LD 0x42 +#define ARMV8_IMPDEF_PERFCTR_L1_DCACHE_REFILL_ST 0x43 +#define ARMV8_IMPDEF_PERFCTR_DTLB_REFILL_LD 0x4C +#define ARMV8_IMPDEF_PERFCTR_DTLB_REFILL_ST 0x4D +#define ARMV8_IMPDEF_PERFCTR_DTLB_ACCESS_LD 0x4E +#define ARMV8_IMPDEF_PERFCTR_DTLB_ACCESS_ST 0x4F + /* ARMv8 Cortex-A53 specific event types. */ #define ARMV8_A53_PERFCTR_PREFETCH_LINEFILL 0xC2 -/* ARMv8 Cortex-A57 and Cortex-A72 specific event types. */ -#define ARMV8_A57_PERFCTR_L1_DCACHE_ACCESS_LD 0x40 -#define ARMV8_A57_PERFCTR_L1_DCACHE_ACCESS_ST 0x41 -#define ARMV8_A57_PERFCTR_L1_DCACHE_REFILL_LD 0x42 -#define ARMV8_A57_PERFCTR_L1_DCACHE_REFILL_ST 0x43 -#define ARMV8_A57_PERFCTR_DTLB_REFILL_LD 0x4c -#define ARMV8_A57_PERFCTR_DTLB_REFILL_ST 0x4d +/* ARMv8 Cavium ThunderX specific event types. */ +#define ARMV8_THUNDER_PERFCTR_L1_DCACHE_MISS_ST 0xE9 +#define ARMV8_THUNDER_PERFCTR_L1_DCACHE_PREF_ACCESS 0xEA +#define ARMV8_THUNDER_PERFCTR_L1_DCACHE_PREF_MISS 0xEB +#define ARMV8_THUNDER_PERFCTR_L1_ICACHE_PREF_ACCESS 0xEC +#define ARMV8_THUNDER_PERFCTR_L1_ICACHE_PREF_MISS 0xED /* PMUv3 HW events mapping. */ static const unsigned armv8_pmuv3_perf_map[PERF_COUNT_HW_MAX] = { @@ -132,6 +142,18 @@ static const unsigned armv8_a57_perf_map[PERF_COUNT_HW_MAX] = { [PERF_COUNT_HW_BUS_CYCLES] = ARMV8_PMUV3_PERFCTR_BUS_CYCLES, }; +static const unsigned armv8_thunder_perf_map[PERF_COUNT_HW_MAX] = { + PERF_MAP_ALL_UNSUPPORTED, + [PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES, + [PERF_COUNT_HW_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED, + [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS, + [PERF_COUNT_HW_CACHE_MISSES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL, + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_PC_WRITE, + [PERF_COUNT_HW_BRANCH_MISSES] = ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED, + [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = ARMV8_PMUV3_PERFCTR_STALL_FRONTEND, + [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = ARMV8_PMUV3_PERFCTR_STALL_BACKEND, +}; + static const unsigned armv8_pmuv3_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] [PERF_COUNT_HW_CACHE_OP_MAX] [PERF_COUNT_HW_CACHE_RESULT_MAX] = { @@ -175,16 +197,46 @@ static const unsigned armv8_a57_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] [PERF_COUNT_HW_CACHE_RESULT_MAX] = { PERF_CACHE_MAP_ALL_UNSUPPORTED, - [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_A57_PERFCTR_L1_DCACHE_ACCESS_LD, - [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_A57_PERFCTR_L1_DCACHE_REFILL_LD, - [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_A57_PERFCTR_L1_DCACHE_ACCESS_ST, - [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_A57_PERFCTR_L1_DCACHE_REFILL_ST, + [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_L1_DCACHE_ACCESS_LD, + [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_IMPDEF_PERFCTR_L1_DCACHE_REFILL_LD, + [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_L1_DCACHE_ACCESS_ST, + [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_IMPDEF_PERFCTR_L1_DCACHE_REFILL_ST, + + [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L1_ICACHE_ACCESS, + [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1_ICACHE_REFILL, + + [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_IMPDEF_PERFCTR_DTLB_REFILL_LD, + [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_IMPDEF_PERFCTR_DTLB_REFILL_ST, + + [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_ITLB_REFILL, + + [C(BPU)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_PC_BRANCH_PRED, + [C(BPU)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED, + [C(BPU)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_PC_BRANCH_PRED, + [C(BPU)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_PC_BRANCH_MIS_PRED, +}; + +static const unsigned armv8_thunder_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] + [PERF_COUNT_HW_CACHE_OP_MAX] + [PERF_COUNT_HW_CACHE_RESULT_MAX] = { + PERF_CACHE_MAP_ALL_UNSUPPORTED, + + [C(L1D)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_L1_DCACHE_ACCESS_LD, + [C(L1D)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_IMPDEF_PERFCTR_L1_DCACHE_REFILL_LD, + [C(L1D)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_L1_DCACHE_ACCESS_ST, + [C(L1D)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_THUNDER_PERFCTR_L1_DCACHE_MISS_ST, + [C(L1D)][C(OP_PREFETCH)][C(RESULT_ACCESS)] = ARMV8_THUNDER_PERFCTR_L1_DCACHE_PREF_ACCESS, + [C(L1D)][C(OP_PREFETCH)][C(RESULT_MISS)] = ARMV8_THUNDER_PERFCTR_L1_DCACHE_PREF_MISS, [C(L1I)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_PMUV3_PERFCTR_L1_ICACHE_ACCESS, [C(L1I)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_L1_ICACHE_REFILL, + [C(L1I)][C(OP_PREFETCH)][C(RESULT_ACCESS)] = ARMV8_THUNDER_PERFCTR_L1_ICACHE_PREF_ACCESS, + [C(L1I)][C(OP_PREFETCH)][C(RESULT_MISS)] = ARMV8_THUNDER_PERFCTR_L1_ICACHE_PREF_MISS, - [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_A57_PERFCTR_DTLB_REFILL_LD, - [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_A57_PERFCTR_DTLB_REFILL_ST, + [C(DTLB)][C(OP_READ)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_DTLB_ACCESS_LD, + [C(DTLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_IMPDEF_PERFCTR_DTLB_REFILL_LD, + [C(DTLB)][C(OP_WRITE)][C(RESULT_ACCESS)] = ARMV8_IMPDEF_PERFCTR_DTLB_ACCESS_ST, + [C(DTLB)][C(OP_WRITE)][C(RESULT_MISS)] = ARMV8_IMPDEF_PERFCTR_DTLB_REFILL_ST, [C(ITLB)][C(OP_READ)][C(RESULT_MISS)] = ARMV8_PMUV3_PERFCTR_ITLB_REFILL, @@ -325,7 +377,6 @@ static const struct attribute_group *armv8_pmuv3_attr_groups[] = { NULL, }; - /* * Perf Events' indices */ @@ -334,9 +385,6 @@ static const struct attribute_group *armv8_pmuv3_attr_groups[] = { #define ARMV8_IDX_COUNTER_LAST(cpu_pmu) \ (ARMV8_IDX_CYCLE_COUNTER + cpu_pmu->num_events - 1) -#define ARMV8_MAX_COUNTERS 32 -#define ARMV8_COUNTER_MASK (ARMV8_MAX_COUNTERS - 1) - /* * ARMv8 low level PMU access */ @@ -345,39 +393,7 @@ static const struct attribute_group *armv8_pmuv3_attr_groups[] = { * Perf Event to low level counters mapping */ #define ARMV8_IDX_TO_COUNTER(x) \ - (((x) - ARMV8_IDX_COUNTER0) & ARMV8_COUNTER_MASK) - -/* - * Per-CPU PMCR: config reg - */ -#define ARMV8_PMCR_E (1 << 0) /* Enable all counters */ -#define ARMV8_PMCR_P (1 << 1) /* Reset all counters */ -#define ARMV8_PMCR_C (1 << 2) /* Cycle counter reset */ -#define ARMV8_PMCR_D (1 << 3) /* CCNT counts every 64th cpu cycle */ -#define ARMV8_PMCR_X (1 << 4) /* Export to ETM */ -#define ARMV8_PMCR_DP (1 << 5) /* Disable CCNT if non-invasive debug*/ -#define ARMV8_PMCR_N_SHIFT 11 /* Number of counters supported */ -#define ARMV8_PMCR_N_MASK 0x1f -#define ARMV8_PMCR_MASK 0x3f /* Mask for writable bits */ - -/* - * PMOVSR: counters overflow flag status reg - */ -#define ARMV8_OVSR_MASK 0xffffffff /* Mask for writable bits */ -#define ARMV8_OVERFLOWED_MASK ARMV8_OVSR_MASK - -/* - * PMXEVTYPER: Event selection reg - */ -#define ARMV8_EVTYPE_MASK 0xc80003ff /* Mask for writable bits */ -#define ARMV8_EVTYPE_EVENT 0x3ff /* Mask for EVENT bits */ - -/* - * Event filters for PMUv3 - */ -#define ARMV8_EXCLUDE_EL1 (1 << 31) -#define ARMV8_EXCLUDE_EL0 (1 << 30) -#define ARMV8_INCLUDE_EL2 (1 << 27) + (((x) - ARMV8_IDX_COUNTER0) & ARMV8_PMU_COUNTER_MASK) static inline u32 armv8pmu_pmcr_read(void) { @@ -388,14 +404,14 @@ static inline u32 armv8pmu_pmcr_read(void) static inline void armv8pmu_pmcr_write(u32 val) { - val &= ARMV8_PMCR_MASK; + val &= ARMV8_PMU_PMCR_MASK; isb(); asm volatile("msr pmcr_el0, %0" :: "r" (val)); } static inline int armv8pmu_has_overflowed(u32 pmovsr) { - return pmovsr & ARMV8_OVERFLOWED_MASK; + return pmovsr & ARMV8_PMU_OVERFLOWED_MASK; } static inline int armv8pmu_counter_valid(struct arm_pmu *cpu_pmu, int idx) @@ -445,16 +461,23 @@ static inline void armv8pmu_write_counter(struct perf_event *event, u32 value) if (!armv8pmu_counter_valid(cpu_pmu, idx)) pr_err("CPU%u writing wrong counter %d\n", smp_processor_id(), idx); - else if (idx == ARMV8_IDX_CYCLE_COUNTER) - asm volatile("msr pmccntr_el0, %0" :: "r" (value)); - else if (armv8pmu_select_counter(idx) == idx) + else if (idx == ARMV8_IDX_CYCLE_COUNTER) { + /* + * Set the upper 32bits as this is a 64bit counter but we only + * count using the lower 32bits and we want an interrupt when + * it overflows. + */ + u64 value64 = 0xffffffff00000000ULL | value; + + asm volatile("msr pmccntr_el0, %0" :: "r" (value64)); + } else if (armv8pmu_select_counter(idx) == idx) asm volatile("msr pmxevcntr_el0, %0" :: "r" (value)); } static inline void armv8pmu_write_evtype(int idx, u32 val) { if (armv8pmu_select_counter(idx) == idx) { - val &= ARMV8_EVTYPE_MASK; + val &= ARMV8_PMU_EVTYPE_MASK; asm volatile("msr pmxevtyper_el0, %0" :: "r" (val)); } } @@ -500,7 +523,7 @@ static inline u32 armv8pmu_getreset_flags(void) asm volatile("mrs %0, pmovsclr_el0" : "=r" (value)); /* Write to clear flags */ - value &= ARMV8_OVSR_MASK; + value &= ARMV8_PMU_OVSR_MASK; asm volatile("msr pmovsclr_el0, %0" :: "r" (value)); return value; @@ -638,7 +661,7 @@ static void armv8pmu_start(struct arm_pmu *cpu_pmu) raw_spin_lock_irqsave(&events->pmu_lock, flags); /* Enable all counters */ - armv8pmu_pmcr_write(armv8pmu_pmcr_read() | ARMV8_PMCR_E); + armv8pmu_pmcr_write(armv8pmu_pmcr_read() | ARMV8_PMU_PMCR_E); raw_spin_unlock_irqrestore(&events->pmu_lock, flags); } @@ -649,7 +672,7 @@ static void armv8pmu_stop(struct arm_pmu *cpu_pmu) raw_spin_lock_irqsave(&events->pmu_lock, flags); /* Disable all counters */ - armv8pmu_pmcr_write(armv8pmu_pmcr_read() & ~ARMV8_PMCR_E); + armv8pmu_pmcr_write(armv8pmu_pmcr_read() & ~ARMV8_PMU_PMCR_E); raw_spin_unlock_irqrestore(&events->pmu_lock, flags); } @@ -659,7 +682,7 @@ static int armv8pmu_get_event_idx(struct pmu_hw_events *cpuc, int idx; struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu); struct hw_perf_event *hwc = &event->hw; - unsigned long evtype = hwc->config_base & ARMV8_EVTYPE_EVENT; + unsigned long evtype = hwc->config_base & ARMV8_PMU_EVTYPE_EVENT; /* Always place a cycle counter into the cycle counter. */ if (evtype == ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES) { @@ -696,11 +719,11 @@ static int armv8pmu_set_event_filter(struct hw_perf_event *event, attr->exclude_kernel != attr->exclude_hv) return -EINVAL; if (attr->exclude_user) - config_base |= ARMV8_EXCLUDE_EL0; + config_base |= ARMV8_PMU_EXCLUDE_EL0; if (!is_kernel_in_hyp_mode() && attr->exclude_kernel) - config_base |= ARMV8_EXCLUDE_EL1; + config_base |= ARMV8_PMU_EXCLUDE_EL1; if (!attr->exclude_hv) - config_base |= ARMV8_INCLUDE_EL2; + config_base |= ARMV8_PMU_INCLUDE_EL2; /* * Install the filter into config_base as this is used to @@ -722,29 +745,40 @@ static void armv8pmu_reset(void *info) armv8pmu_disable_intens(idx); } - /* Initialize & Reset PMNC: C and P bits. */ - armv8pmu_pmcr_write(ARMV8_PMCR_P | ARMV8_PMCR_C); + /* + * Initialize & Reset PMNC. Request overflow interrupt for + * 64 bit cycle counter but cheat in armv8pmu_write_counter(). + */ + armv8pmu_pmcr_write(ARMV8_PMU_PMCR_P | ARMV8_PMU_PMCR_C | + ARMV8_PMU_PMCR_LC); } static int armv8_pmuv3_map_event(struct perf_event *event) { return armpmu_map_event(event, &armv8_pmuv3_perf_map, &armv8_pmuv3_perf_cache_map, - ARMV8_EVTYPE_EVENT); + ARMV8_PMU_EVTYPE_EVENT); } static int armv8_a53_map_event(struct perf_event *event) { return armpmu_map_event(event, &armv8_a53_perf_map, &armv8_a53_perf_cache_map, - ARMV8_EVTYPE_EVENT); + ARMV8_PMU_EVTYPE_EVENT); } static int armv8_a57_map_event(struct perf_event *event) { return armpmu_map_event(event, &armv8_a57_perf_map, &armv8_a57_perf_cache_map, - ARMV8_EVTYPE_EVENT); + ARMV8_PMU_EVTYPE_EVENT); +} + +static int armv8_thunder_map_event(struct perf_event *event) +{ + return armpmu_map_event(event, &armv8_thunder_perf_map, + &armv8_thunder_perf_cache_map, + ARMV8_PMU_EVTYPE_EVENT); } static void armv8pmu_read_num_pmnc_events(void *info) @@ -752,7 +786,7 @@ static void armv8pmu_read_num_pmnc_events(void *info) int *nb_cnt = info; /* Read the nb of CNTx counters supported from PMNC */ - *nb_cnt = (armv8pmu_pmcr_read() >> ARMV8_PMCR_N_SHIFT) & ARMV8_PMCR_N_MASK; + *nb_cnt = (armv8pmu_pmcr_read() >> ARMV8_PMU_PMCR_N_SHIFT) & ARMV8_PMU_PMCR_N_MASK; /* Add the CPU cycles counter */ *nb_cnt += 1; @@ -815,11 +849,21 @@ static int armv8_a72_pmu_init(struct arm_pmu *cpu_pmu) return armv8pmu_probe_num_events(cpu_pmu); } +static int armv8_thunder_pmu_init(struct arm_pmu *cpu_pmu) +{ + armv8_pmu_init(cpu_pmu); + cpu_pmu->name = "armv8_cavium_thunder"; + cpu_pmu->map_event = armv8_thunder_map_event; + cpu_pmu->pmu.attr_groups = armv8_pmuv3_attr_groups; + return armv8pmu_probe_num_events(cpu_pmu); +} + static const struct of_device_id armv8_pmu_of_device_ids[] = { {.compatible = "arm,armv8-pmuv3", .data = armv8_pmuv3_init}, {.compatible = "arm,cortex-a53-pmu", .data = armv8_a53_pmu_init}, {.compatible = "arm,cortex-a57-pmu", .data = armv8_a57_pmu_init}, {.compatible = "arm,cortex-a72-pmu", .data = armv8_a72_pmu_init}, + {.compatible = "cavium,thunder-pmu", .data = armv8_thunder_pmu_init}, {}, }; diff --git a/arch/arm64/kernel/psci.c b/arch/arm64/kernel/psci.c index f67f35b6edb12e4d34e1db17750b07a0bec72e39..42816bebb1e0f732d788780fde431028f202c31a 100644 --- a/arch/arm64/kernel/psci.c +++ b/arch/arm64/kernel/psci.c @@ -20,7 +20,6 @@ #include #include #include -#include #include @@ -28,73 +27,6 @@ #include #include #include -#include - -static DEFINE_PER_CPU_READ_MOSTLY(u32 *, psci_power_state); - -static int __maybe_unused cpu_psci_cpu_init_idle(unsigned int cpu) -{ - int i, ret, count = 0; - u32 *psci_states; - struct device_node *state_node, *cpu_node; - - cpu_node = of_get_cpu_node(cpu, NULL); - if (!cpu_node) - return -ENODEV; - - /* - * If the PSCI cpu_suspend function hook has not been initialized - * idle states must not be enabled, so bail out - */ - if (!psci_ops.cpu_suspend) - return -EOPNOTSUPP; - - /* Count idle states */ - while ((state_node = of_parse_phandle(cpu_node, "cpu-idle-states", - count))) { - count++; - of_node_put(state_node); - } - - if (!count) - return -ENODEV; - - psci_states = kcalloc(count, sizeof(*psci_states), GFP_KERNEL); - if (!psci_states) - return -ENOMEM; - - for (i = 0; i < count; i++) { - u32 state; - - state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i); - - ret = of_property_read_u32(state_node, - "arm,psci-suspend-param", - &state); - if (ret) { - pr_warn(" * %s missing arm,psci-suspend-param property\n", - state_node->full_name); - of_node_put(state_node); - goto free_mem; - } - - of_node_put(state_node); - pr_debug("psci-power-state %#x index %d\n", state, i); - if (!psci_power_state_is_valid(state)) { - pr_warn("Invalid PSCI power state %#x\n", state); - ret = -EINVAL; - goto free_mem; - } - psci_states[i] = state; - } - /* Idle states parsed correctly, initialize per-cpu pointer */ - per_cpu(psci_power_state, cpu) = psci_states; - return 0; - -free_mem: - kfree(psci_states); - return ret; -} static int __init cpu_psci_cpu_init(unsigned int cpu) { @@ -178,38 +110,11 @@ static int cpu_psci_cpu_kill(unsigned int cpu) } #endif -static int psci_suspend_finisher(unsigned long index) -{ - u32 *state = __this_cpu_read(psci_power_state); - - return psci_ops.cpu_suspend(state[index - 1], - virt_to_phys(cpu_resume)); -} - -static int __maybe_unused cpu_psci_cpu_suspend(unsigned long index) -{ - int ret; - u32 *state = __this_cpu_read(psci_power_state); - /* - * idle state index 0 corresponds to wfi, should never be called - * from the cpu_suspend operations - */ - if (WARN_ON_ONCE(!index)) - return -EINVAL; - - if (!psci_power_state_loses_context(state[index - 1])) - ret = psci_ops.cpu_suspend(state[index - 1], 0); - else - ret = cpu_suspend(index, psci_suspend_finisher); - - return ret; -} - const struct cpu_operations cpu_psci_ops = { .name = "psci", #ifdef CONFIG_CPU_IDLE - .cpu_init_idle = cpu_psci_cpu_init_idle, - .cpu_suspend = cpu_psci_cpu_suspend, + .cpu_init_idle = psci_cpu_init_idle, + .cpu_suspend = psci_cpu_suspend_enter, #endif .cpu_init = cpu_psci_cpu_init, .cpu_prepare = cpu_psci_cpu_prepare, diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S index 4c56e7a0621bcea078fb616487d60f9290f85214..5a1939a74ff3588bb388c73741499d6061594a5d 100644 --- a/arch/arm64/kernel/vmlinux.lds.S +++ b/arch/arm64/kernel/vmlinux.lds.S @@ -103,6 +103,7 @@ SECTIONS *(.exception.text) __exception_text_end = .; IRQENTRY_TEXT + SOFTIRQENTRY_TEXT TEXT_TEXT SCHED_TEXT LOCK_TEXT @@ -135,6 +136,7 @@ SECTIONS CON_INITCALL SECURITY_INITCALL INIT_RAM_FS + *(.init.rodata.* .init.bss) /* from the EFI stub */ } .exit.data : { ARM_EXIT_KEEP(EXIT_DATA) diff --git a/arch/arm64/kvm/hyp/Makefile b/arch/arm64/kvm/hyp/Makefile index b6a8fc5ad1afaa4b498b2d7172a78f8fcf61b541..778d0effa2afd38bd94b34b0a7a88c02ff2a79bf 100644 --- a/arch/arm64/kvm/hyp/Makefile +++ b/arch/arm64/kvm/hyp/Makefile @@ -16,3 +16,7 @@ obj-$(CONFIG_KVM_ARM_HOST) += fpsimd.o obj-$(CONFIG_KVM_ARM_HOST) += tlb.o obj-$(CONFIG_KVM_ARM_HOST) += hyp-entry.o obj-$(CONFIG_KVM_ARM_HOST) += s2-setup.o + +GCOV_PROFILE := n +KASAN_SANITIZE := n +UBSAN_SANITIZE := n diff --git a/arch/arm64/kvm/hyp/s2-setup.c b/arch/arm64/kvm/hyp/s2-setup.c index bfc54fd82797b08322b99b1cb6f553c5762b8dd4..5a9f3bf542b099ec90185446ec300812a9db64dd 100644 --- a/arch/arm64/kvm/hyp/s2-setup.c +++ b/arch/arm64/kvm/hyp/s2-setup.c @@ -36,8 +36,10 @@ void __hyp_text __init_stage2_translation(void) * Read the VMIDBits bits from ID_AA64MMFR1_EL1 and set the VS * bit in VTCR_EL2. */ - tmp = (read_sysreg(id_aa64mmfr1_el1) >> 4) & 0xf; - val |= (tmp == 2) ? VTCR_EL2_VS : 0; + tmp = (read_sysreg(id_aa64mmfr1_el1) >> ID_AA64MMFR1_VMIDBITS_SHIFT) & 0xf; + val |= (tmp == ID_AA64MMFR1_VMIDBITS_16) ? + VTCR_EL2_VS_16BIT : + VTCR_EL2_VS_8BIT; write_sysreg(val, vtcr_el2); } diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index 0077674b2b380cbccf0a718a71f04dfc5207791e..95df28bc875f3eafda13f348e7f319fdafe5cd41 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -304,7 +304,7 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr, up_read(&mm->mmap_sem); /* - * Handle the "normal" case first - VM_FAULT_MAJOR / VM_FAULT_MINOR + * Handle the "normal" case first - VM_FAULT_MAJOR */ if (likely(!(fault & (VM_FAULT_ERROR | VM_FAULT_BADMAP | VM_FAULT_BADACCESS)))) diff --git a/arch/arm64/mm/flush.c b/arch/arm64/mm/flush.c index 60585bde1264a172e4e598ce73a550272d0a40f2..dbd12ea8ce684993f1adf5c100a06d223b646073 100644 --- a/arch/arm64/mm/flush.c +++ b/arch/arm64/mm/flush.c @@ -58,17 +58,13 @@ static void flush_ptrace_access(struct vm_area_struct *vma, struct page *page, * Copy user data from/to a page which is mapped into a different processes * address space. Really, we want to allow our "user space" model to handle * this. - * - * Note that this code needs to run on the current CPU. */ void copy_to_user_page(struct vm_area_struct *vma, struct page *page, unsigned long uaddr, void *dst, const void *src, unsigned long len) { - preempt_disable(); memcpy(dst, src, len); flush_ptrace_access(vma, page, uaddr, dst, len); - preempt_enable(); } void __sync_icache_dcache(pte_t pte, unsigned long addr) diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c index da30529bb1f65c9e3d5408b2e28ab31bc2283211..589fd28e1fb5de8b923fc99ee0fa35d79b1cd6af 100644 --- a/arch/arm64/mm/hugetlbpage.c +++ b/arch/arm64/mm/hugetlbpage.c @@ -124,7 +124,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, * will be no pte_unmap() to correspond with this * pte_alloc_map(). */ - pte = pte_alloc_map(mm, NULL, pmd, addr); + pte = pte_alloc_map(mm, pmd, addr); } else if (sz == PMD_SIZE) { if (IS_ENABLED(CONFIG_ARCH_WANT_HUGE_PMD_SHARE) && pud_none(*pud)) diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index 61a38eaf0895c5db483594a6411cc9b460761cb4..ea989d83ea9ba393073fd2c5599714c57b74416e 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -362,42 +362,38 @@ void __init mem_init(void) #define MLG(b, t) b, t, ((t) - (b)) >> 30 #define MLK_ROUNDUP(b, t) b, t, DIV_ROUND_UP(((t) - (b)), SZ_1K) - pr_notice("Virtual kernel memory layout:\n" + pr_notice("Virtual kernel memory layout:\n"); #ifdef CONFIG_KASAN - " kasan : 0x%16lx - 0x%16lx (%6ld GB)\n" + pr_cont(" kasan : 0x%16lx - 0x%16lx (%6ld GB)\n", + MLG(KASAN_SHADOW_START, KASAN_SHADOW_END)); #endif - " modules : 0x%16lx - 0x%16lx (%6ld MB)\n" - " vmalloc : 0x%16lx - 0x%16lx (%6ld GB)\n" - " .text : 0x%p" " - 0x%p" " (%6ld KB)\n" - " .rodata : 0x%p" " - 0x%p" " (%6ld KB)\n" - " .init : 0x%p" " - 0x%p" " (%6ld KB)\n" - " .data : 0x%p" " - 0x%p" " (%6ld KB)\n" + pr_cont(" modules : 0x%16lx - 0x%16lx (%6ld MB)\n", + MLM(MODULES_VADDR, MODULES_END)); + pr_cont(" vmalloc : 0x%16lx - 0x%16lx (%6ld GB)\n", + MLG(VMALLOC_START, VMALLOC_END)); + pr_cont(" .text : 0x%p" " - 0x%p" " (%6ld KB)\n" + " .rodata : 0x%p" " - 0x%p" " (%6ld KB)\n" + " .init : 0x%p" " - 0x%p" " (%6ld KB)\n" + " .data : 0x%p" " - 0x%p" " (%6ld KB)\n", + MLK_ROUNDUP(_text, __start_rodata), + MLK_ROUNDUP(__start_rodata, _etext), + MLK_ROUNDUP(__init_begin, __init_end), + MLK_ROUNDUP(_sdata, _edata)); #ifdef CONFIG_SPARSEMEM_VMEMMAP - " vmemmap : 0x%16lx - 0x%16lx (%6ld GB maximum)\n" - " 0x%16lx - 0x%16lx (%6ld MB actual)\n" + pr_cont(" vmemmap : 0x%16lx - 0x%16lx (%6ld GB maximum)\n" + " 0x%16lx - 0x%16lx (%6ld MB actual)\n", + MLG(VMEMMAP_START, + VMEMMAP_START + VMEMMAP_SIZE), + MLM((unsigned long)phys_to_page(memblock_start_of_DRAM()), + (unsigned long)virt_to_page(high_memory))); #endif - " fixed : 0x%16lx - 0x%16lx (%6ld KB)\n" - " PCI I/O : 0x%16lx - 0x%16lx (%6ld MB)\n" - " memory : 0x%16lx - 0x%16lx (%6ld MB)\n", -#ifdef CONFIG_KASAN - MLG(KASAN_SHADOW_START, KASAN_SHADOW_END), -#endif - MLM(MODULES_VADDR, MODULES_END), - MLG(VMALLOC_START, VMALLOC_END), - MLK_ROUNDUP(_text, __start_rodata), - MLK_ROUNDUP(__start_rodata, _etext), - MLK_ROUNDUP(__init_begin, __init_end), - MLK_ROUNDUP(_sdata, _edata), -#ifdef CONFIG_SPARSEMEM_VMEMMAP - MLG(VMEMMAP_START, - VMEMMAP_START + VMEMMAP_SIZE), - MLM((unsigned long)phys_to_page(memblock_start_of_DRAM()), - (unsigned long)virt_to_page(high_memory)), -#endif - MLK(FIXADDR_START, FIXADDR_TOP), - MLM(PCI_IO_START, PCI_IO_END), - MLM(__phys_to_virt(memblock_start_of_DRAM()), - (unsigned long)high_memory)); + pr_cont(" fixed : 0x%16lx - 0x%16lx (%6ld KB)\n", + MLK(FIXADDR_START, FIXADDR_TOP)); + pr_cont(" PCI I/O : 0x%16lx - 0x%16lx (%6ld MB)\n", + MLM(PCI_IO_START, PCI_IO_END)); + pr_cont(" memory : 0x%16lx - 0x%16lx (%6ld MB)\n", + MLM(__phys_to_virt(memblock_start_of_DRAM()), + (unsigned long)high_memory)); #undef MLK #undef MLM diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index d2d8b8c2e17f7c41a221098cd211eb478349c87a..f3e5c74233f30cb466ec267dad8dec9cec7af9ba 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -211,8 +211,7 @@ static void alloc_init_pmd(pud_t *pud, unsigned long addr, unsigned long end, if (((addr | next | phys) & ~SECTION_MASK) == 0 && block_mappings_allowed(pgtable_alloc)) { pmd_t old_pmd =*pmd; - set_pmd(pmd, __pmd(phys | - pgprot_val(mk_sect_prot(prot)))); + pmd_set_huge(pmd, phys, prot); /* * Check for previous table entries created during * boot (__create_page_tables) and flush them. @@ -272,8 +271,7 @@ static void alloc_init_pud(pgd_t *pgd, unsigned long addr, unsigned long end, if (use_1G_block(addr, next, phys) && block_mappings_allowed(pgtable_alloc)) { pud_t old_pud = *pud; - set_pud(pud, __pud(phys | - pgprot_val(mk_sect_prot(prot)))); + pud_set_huge(pud, phys, prot); /* * If we have an old value for a pud, it will diff --git a/arch/avr32/include/asm/checksum.h b/arch/avr32/include/asm/checksum.h index 4ddbfd2486af06412b32e7cf66af54ce1942d9e8..4ab7d5bdaf53a43c33eec7072be41685e7f9edfd 100644 --- a/arch/avr32/include/asm/checksum.h +++ b/arch/avr32/include/asm/checksum.h @@ -111,9 +111,8 @@ static inline __sum16 csum_fold(__wsum sum) } static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum) + __u32 len, __u8 proto, + __wsum sum) { asm(" add %0, %1\n" " adc %0, %0, %2\n" @@ -132,9 +131,8 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, * returns a 16-bit checksum, already complemented */ static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum) + __u32 len, __u8 proto, + __wsum sum) { return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); } diff --git a/arch/avr32/include/uapi/asm/socket.h b/arch/avr32/include/uapi/asm/socket.h index 9de0796240a0015b8a315d847f8f827e389ed4e1..1fd147f09a3805d75f1e8150a825250a6e38121b 100644 --- a/arch/avr32/include/uapi/asm/socket.h +++ b/arch/avr32/include/uapi/asm/socket.h @@ -88,4 +88,6 @@ #define SO_ATTACH_REUSEPORT_CBPF 51 #define SO_ATTACH_REUSEPORT_EBPF 52 +#define SO_CNX_ADVICE 53 + #endif /* _UAPI__ASM_AVR32_SOCKET_H */ diff --git a/arch/blackfin/include/asm/checksum.h b/arch/blackfin/include/asm/checksum.h index 623cc7fb00bc0602871c905c5e14b164b726d4e2..e7134bf94e3c48502d861166dd42fabf1f2b5ee5 100644 --- a/arch/blackfin/include/asm/checksum.h +++ b/arch/blackfin/include/asm/checksum.h @@ -14,8 +14,8 @@ */ static inline __wsum -__csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) +__csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len, + __u8 proto, __wsum sum) { unsigned int carry; diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S index c9eec84aa258628d1c9d70fc545420dde30c8bc1..d920b959ff3a4b8cb3d6a28d67d40ebf6f7c457b 100644 --- a/arch/blackfin/kernel/vmlinux.lds.S +++ b/arch/blackfin/kernel/vmlinux.lds.S @@ -35,6 +35,7 @@ SECTIONS #endif LOCK_TEXT IRQENTRY_TEXT + SOFTIRQENTRY_TEXT KPROBES_TEXT #ifdef CONFIG_ROMKERNEL __sinittext = .; diff --git a/arch/blackfin/mach-bf527/boards/ezbrd.c b/arch/blackfin/mach-bf527/boards/ezbrd.c index a3a572352769f1cb46dd5d4f520c933f90fa28a3..80bcfd1d023e5846a05a7f157caa9b8558c2bb67 100644 --- a/arch/blackfin/mach-bf527/boards/ezbrd.c +++ b/arch/blackfin/mach-bf527/boards/ezbrd.c @@ -279,7 +279,7 @@ static const struct ad7877_platform_data bfin_ad7877_ts_info = { #endif #if IS_ENABLED(CONFIG_TOUCHSCREEN_AD7879) -#include +#include static const struct ad7879_platform_data bfin_ad7879_ts_info = { .model = 7879, /* Model = AD7879 */ .x_plate_ohms = 620, /* 620 Ohm from the touch datasheet */ diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c index d4219e8e5ab865fb196d4689ed315bdf2d255e85..571edfd2ecf3b3b7c64441b808c94dc452abcf9a 100644 --- a/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/arch/blackfin/mach-bf527/boards/ezkit.c @@ -477,7 +477,7 @@ static const struct ad7877_platform_data bfin_ad7877_ts_info = { #endif #if IS_ENABLED(CONFIG_TOUCHSCREEN_AD7879) -#include +#include static const struct ad7879_platform_data bfin_ad7879_ts_info = { .model = 7879, /* Model = AD7879 */ .x_plate_ohms = 620, /* 620 Ohm from the touch datasheet */ diff --git a/arch/blackfin/mach-bf527/boards/tll6527m.c b/arch/blackfin/mach-bf527/boards/tll6527m.c index a0f5856a5ff8ae402bd9c8824522dfb0a349cb70..c1acce4c2e4569883ec28f32a256df706aa43649 100644 --- a/arch/blackfin/mach-bf527/boards/tll6527m.c +++ b/arch/blackfin/mach-bf527/boards/tll6527m.c @@ -29,7 +29,7 @@ #include #if IS_ENABLED(CONFIG_TOUCHSCREEN_AD7879) -#include +#include #define LCD_BACKLIGHT_GPIO 0x40 /* TLL6527M uses TLL7UIQ35 / ADI LCD EZ Extender. AD7879 AUX GPIO is used for * LCD Backlight Enable diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index c181543a399aa2e36752f2153fe429bf89283fa9..eaec7b4832a29a5ccb219cd37810334e86bb906d 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c @@ -776,7 +776,7 @@ static const struct ad7877_platform_data bfin_ad7877_ts_info = { #endif #if IS_ENABLED(CONFIG_TOUCHSCREEN_AD7879) -#include +#include static const struct ad7879_platform_data bfin_ad7879_ts_info = { .model = 7879, /* Model = AD7879 */ .x_plate_ohms = 620, /* 620 Ohm from the touch datasheet */ diff --git a/arch/blackfin/mach-bf538/boards/ezkit.c b/arch/blackfin/mach-bf538/boards/ezkit.c index c423af36fa910835b6247e2cca53eb0bed6fb92b..1b6a52ad8a0eb66c3e623309091b8f49d360cb05 100644 --- a/arch/blackfin/mach-bf538/boards/ezkit.c +++ b/arch/blackfin/mach-bf538/boards/ezkit.c @@ -521,7 +521,7 @@ static struct bfin5xx_spi_chip spi_flash_chip_info = { #endif /* CONFIG_SPI_BFIN5XX */ #if IS_ENABLED(CONFIG_TOUCHSCREEN_AD7879) -#include +#include static const struct ad7879_platform_data bfin_ad7879_ts_info = { .model = 7879, /* Model = AD7879 */ .x_plate_ohms = 620, /* 620 Ohm from the touch datasheet */ diff --git a/arch/c6x/Kconfig b/arch/c6x/Kconfig index 79049d432d3c7808f6914376a715e34ada4c14af..5aa8ea8bad2db1cde0719d2bec9144d1c894b832 100644 --- a/arch/c6x/Kconfig +++ b/arch/c6x/Kconfig @@ -36,6 +36,7 @@ config GENERIC_HWEIGHT config GENERIC_BUG def_bool y + depends on BUG config C6X_BIG_KERNEL bool "Build a big kernel" diff --git a/arch/c6x/include/asm/checksum.h b/arch/c6x/include/asm/checksum.h index 7246816d6e4dfa997aab7179ac2505201f8531df..249b0e421ddcb1ebb9807ada0a642b9b8d1e0cae 100644 --- a/arch/c6x/include/asm/checksum.h +++ b/arch/c6x/include/asm/checksum.h @@ -10,8 +10,8 @@ #define _ASM_C6X_CHECKSUM_H static inline __wsum -csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) +csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len, + __u8 proto, __wsum sum) { unsigned long long tmp; diff --git a/arch/c6x/kernel/vmlinux.lds.S b/arch/c6x/kernel/vmlinux.lds.S index 5a6e141d1641bced3bcabc94e66849bd337cbe3d..50bc10f97bcb4a234bff525d9e120842aa663c99 100644 --- a/arch/c6x/kernel/vmlinux.lds.S +++ b/arch/c6x/kernel/vmlinux.lds.S @@ -72,6 +72,7 @@ SECTIONS SCHED_TEXT LOCK_TEXT IRQENTRY_TEXT + SOFTIRQENTRY_TEXT KPROBES_TEXT *(.fixup) *(.gnu.warning) diff --git a/arch/cris/arch-v32/drivers/cryptocop.c b/arch/cris/arch-v32/drivers/cryptocop.c index 877da1908234b7b027fa92c8476903c9b4832dae..617645d21b20c1ef5b4ff7ee61b9b662334a4c34 100644 --- a/arch/cris/arch-v32/drivers/cryptocop.c +++ b/arch/cris/arch-v32/drivers/cryptocop.c @@ -2719,9 +2719,7 @@ static int cryptocop_ioctl_process(struct inode *inode, struct file *filp, unsig /* Acquire the mm page semaphore. */ down_read(¤t->mm->mmap_sem); - err = get_user_pages(current, - current->mm, - (unsigned long int)(oper.indata + prev_ix), + err = get_user_pages((unsigned long int)(oper.indata + prev_ix), noinpages, 0, /* read access only for in data */ 0, /* no force */ @@ -2736,9 +2734,7 @@ static int cryptocop_ioctl_process(struct inode *inode, struct file *filp, unsig } noinpages = err; if (oper.do_cipher){ - err = get_user_pages(current, - current->mm, - (unsigned long int)oper.cipher_outdata, + err = get_user_pages((unsigned long int)oper.cipher_outdata, nooutpages, 1, /* write access for out data */ 0, /* no force */ diff --git a/arch/cris/include/arch-v10/arch/checksum.h b/arch/cris/include/arch-v10/arch/checksum.h index b8000c5d7fe106f0f78170f482df2c6602486a73..d1d1bd9e1090118906145490f5c6a721e3d24412 100644 --- a/arch/cris/include/arch-v10/arch/checksum.h +++ b/arch/cris/include/arch-v10/arch/checksum.h @@ -9,8 +9,8 @@ */ static inline __wsum -csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) +csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len, + __u8 proto, __wsum sum) { __wsum res; __asm__ ("add.d %2, %0\n\t" diff --git a/arch/cris/include/arch-v32/arch/checksum.h b/arch/cris/include/arch-v32/arch/checksum.h index e5dcfce6e0dc1a5267739b67d9c8bab4233fb777..65cf205b13294ba4fa0c618620233b33cebc091d 100644 --- a/arch/cris/include/arch-v32/arch/checksum.h +++ b/arch/cris/include/arch-v32/arch/checksum.h @@ -11,7 +11,7 @@ */ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, - unsigned short len, unsigned short proto, __wsum sum) + __u32 len, __u8 proto, __wsum sum) { __wsum res; diff --git a/arch/cris/include/asm/checksum.h b/arch/cris/include/asm/checksum.h index 75dcb77d6cb024c28b3c18ed3b742f74a3a3097c..ea949c60b1905df4349dc009117fa53259277cd3 100644 --- a/arch/cris/include/asm/checksum.h +++ b/arch/cris/include/asm/checksum.h @@ -63,9 +63,8 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) */ static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum) + __u32 len, __u8 proto, + __wsum sum) { return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); } diff --git a/arch/frv/include/asm/checksum.h b/arch/frv/include/asm/checksum.h index 269da09ff637f5f1a3bfb6b5ef55e8002bae3f16..b77388c5901d6f2cf1fc740e091c4ce92b57f171 100644 --- a/arch/frv/include/asm/checksum.h +++ b/arch/frv/include/asm/checksum.h @@ -105,8 +105,8 @@ static inline __sum16 csum_fold(__wsum sum) * returns a 16-bit checksum, already complemented */ static inline __wsum -csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) +csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len, + __u8 proto, __wsum sum) { asm(" addcc %1,%0,%0,icc0 \n" " addxcc %2,%0,%0,icc0 \n" @@ -120,8 +120,8 @@ csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, } static inline __sum16 -csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) +csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len, + __u8 proto, __wsum sum) { return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); } @@ -135,7 +135,7 @@ extern __sum16 ip_compute_csum(const void *buff, int len); #define _HAVE_ARCH_IPV6_CSUM static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, - __u32 len, unsigned short proto, __wsum sum) + __u32 len, __u8 proto, __wsum sum) { unsigned long tmp, tmp2; diff --git a/arch/frv/include/asm/page.h b/arch/frv/include/asm/page.h index 688d8076a43a8cbdaaa2bd5e29c816888cee5f6f..ec5eebce4fb3c127ed912bee838aa2f389d8df90 100644 --- a/arch/frv/include/asm/page.h +++ b/arch/frv/include/asm/page.h @@ -8,9 +8,6 @@ #ifndef __ASSEMBLY__ -#define get_user_page(vaddr) __get_free_page(GFP_KERNEL) -#define free_user_page(page, addr) free_page(addr) - #define clear_page(pgaddr) memset((pgaddr), 0, PAGE_SIZE) #define copy_page(to,from) memcpy((to), (from), PAGE_SIZE) diff --git a/arch/frv/include/uapi/asm/socket.h b/arch/frv/include/uapi/asm/socket.h index f02e4849ae838f0163848d7426b70cd3183685eb..afbc98f02d278d097d31add71104f5e4fe4040ea 100644 --- a/arch/frv/include/uapi/asm/socket.h +++ b/arch/frv/include/uapi/asm/socket.h @@ -88,5 +88,7 @@ #define SO_ATTACH_REUSEPORT_CBPF 51 #define SO_ATTACH_REUSEPORT_EBPF 52 +#define SO_CNX_ADVICE 53 + #endif /* _ASM_SOCKET_H */ diff --git a/arch/h8300/boot/dts/edosk2674.dts b/arch/h8300/boot/dts/edosk2674.dts index 4ce9fa874a577e559d5e916a24ddfb71eef6fcdd..6ae884bf66a5268c9dba08db6111df7dc9f40d06 100644 --- a/arch/h8300/boot/dts/edosk2674.dts +++ b/arch/h8300/boot/dts/edosk2674.dts @@ -88,20 +88,20 @@ reg = <0xffff78 8>; interrupts = <88 0>, <89 0>, <90 0>, <91 0>; clocks = <&fclk>; - clock-names = "sci_ick"; + clock-names = "fck"; }; sci1: serial@ffff80 { compatible = "renesas,sci"; reg = <0xffff80 8>; interrupts = <92 0>, <93 0>, <94 0>, <95 0>; clocks = <&fclk>; - clock-names = "sci_ick"; + clock-names = "fck"; }; sci2: serial@ffff88 { compatible = "renesas,sci"; reg = <0xffff88 8>; interrupts = <96 0>, <97 0>, <98 0>, <99 0>; clocks = <&fclk>; - clock-names = "sci_ick"; + clock-names = "fck"; }; }; diff --git a/arch/h8300/boot/dts/h8300h_sim.dts b/arch/h8300/boot/dts/h8300h_sim.dts index 545bfb57af9a9f2e8a81ff38aa46dcedf75c3757..9c733d920f1f0dc3eab70dd53e76d22a4860c3f3 100644 --- a/arch/h8300/boot/dts/h8300h_sim.dts +++ b/arch/h8300/boot/dts/h8300h_sim.dts @@ -83,7 +83,7 @@ reg = <0xffffb0 8>; interrupts = <52 0>, <53 0>, <54 0>, <55 0>; clocks = <&fclk>; - clock-names = "sci_ick"; + clock-names = "fck"; }; sci1: serial@ffffb8 { @@ -91,6 +91,6 @@ reg = <0xffffb8 8>; interrupts = <56 0>, <57 0>, <58 0>, <59 0>; clocks = <&fclk>; - clock-names = "sci_ick"; + clock-names = "fck"; }; }; diff --git a/arch/h8300/boot/dts/h8s_sim.dts b/arch/h8300/boot/dts/h8s_sim.dts index bcedba5a3ce7e8ae8fefaa195d86261b8ed8ba28..97e1f4b17ef067d5f10738e8aed5983359ce61c4 100644 --- a/arch/h8300/boot/dts/h8s_sim.dts +++ b/arch/h8300/boot/dts/h8s_sim.dts @@ -87,13 +87,13 @@ reg = <0xffff78 8>; interrupts = <88 0>, <89 0>, <90 0>, <91 0>; clocks = <&fclk>; - clock-names = "sci_ick"; + clock-names = "fck"; }; sci1: serial@ffff80 { compatible = "renesas,sci"; reg = <0xffff80 8>; interrupts = <92 0>, <93 0>, <94 0>, <95 0>; clocks = <&fclk>; - clock-names = "sci_ick"; + clock-names = "fck"; }; }; diff --git a/arch/h8300/configs/h8300h-sim_defconfig b/arch/h8300/configs/h8300h-sim_defconfig index 067bfe9c49b3a6c96fea0713a0e27837f021b1fe..80624f46b0ed4797ca1faa1f45625ae849b68713 100644 --- a/arch/h8300/configs/h8300h-sim_defconfig +++ b/arch/h8300/configs/h8300h-sim_defconfig @@ -34,7 +34,7 @@ CONFIG_BINFMT_FLAT=y # CONFIG_LEGACY_PTYS is not set # CONFIG_DEVKMEM is not set CONFIG_SERIAL_SH_SCI=y -CONFIG_SERIAL_SH_SCI_CONSOLE=y +CONFIG_SERIAL_SH_SCI_EARLYCON=y # CONFIG_HW_RANDOM is not set # CONFIG_HWMON is not set # CONFIG_USB_SUPPORT is not set diff --git a/arch/h8300/kernel/setup.c b/arch/h8300/kernel/setup.c index e4985dfa91dc853e1c227759808814b2e5e2ea97..c8c25a4e9e489eb8944d87551f55694dc6e50b8a 100644 --- a/arch/h8300/kernel/setup.c +++ b/arch/h8300/kernel/setup.c @@ -20,8 +20,6 @@ #include #include #include -#include -#include #include #include #include @@ -137,11 +135,6 @@ void __init setup_arch(char **cmdline_p) parse_early_param(); bootmem_init(); -#if defined(CONFIG_H8300H_SIM) || defined(CONFIG_H8S_SIM) - sim_console_register(); -#endif - - early_platform_driver_probe("earlyprintk", 1, 0); /* * get kmalloc into gear */ diff --git a/arch/h8300/kernel/sim-console.c b/arch/h8300/kernel/sim-console.c index a15edf0565d9e69c3ada3de938e2ac549be5e782..46138f55a9ea7eedb86eeb60e074655d863bcc69 100644 --- a/arch/h8300/kernel/sim-console.c +++ b/arch/h8300/kernel/sim-console.c @@ -1,79 +1,30 @@ /* - * arch/h8300/kernel/early_printk.c + * arch/h8300/kernel/sim-console.c * - * Copyright (C) 2009 Yoshinori Sato + * Copyright (C) 2015 Yoshinori Sato * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. */ #include -#include #include -#include -#include +#include -static void sim_write(struct console *co, const char *ptr, - unsigned len) +static void sim_write(struct console *con, const char *s, unsigned n) { register const int fd __asm__("er0") = 1; /* stdout */ - register const char *_ptr __asm__("er1") = ptr; - register const unsigned _len __asm__("er2") = len; + register const char *_ptr __asm__("er1") = s; + register const unsigned _len __asm__("er2") = n; __asm__(".byte 0x5e,0x00,0x00,0xc7\n\t" /* jsr @0xc7 (sys_write) */ : : "g"(fd), "g"(_ptr), "g"(_len)); } -static struct console sim_console = { - .name = "sim_console", - .write = sim_write, - .setup = NULL, - .flags = CON_PRINTBUFFER, - .index = -1, -}; - -static char sim_console_buf[32]; - -static int sim_probe(struct platform_device *pdev) -{ - if (sim_console.data) - return -EEXIST; - - if (!strstr(sim_console_buf, "keep")) - sim_console.flags |= CON_BOOT; - - register_console(&sim_console); - return 0; -} - -static int sim_remove(struct platform_device *pdev) +static int __init sim_setup(struct earlycon_device *device, const char *opt) { + device->con->write = sim_write; return 0; } -static struct platform_driver sim_driver = { - .probe = sim_probe, - .remove = sim_remove, - .driver = { - .name = "h8300-sim", - .owner = THIS_MODULE, - }, -}; - -early_platform_init_buffer("earlyprintk", &sim_driver, - sim_console_buf, ARRAY_SIZE(sim_console_buf)); - -static struct platform_device sim_console_device = { - .name = "h8300-sim", - .id = 0, -}; - -static struct platform_device *devices[] __initdata = { - &sim_console_device, -}; - -void __init sim_console_register(void) -{ - early_platform_add_devices(devices, - ARRAY_SIZE(devices)); -} +EARLYCON_DECLARE(h8sim, sim_setup); diff --git a/arch/hexagon/include/asm/checksum.h b/arch/hexagon/include/asm/checksum.h index 46ec8a7fd65f876a0de86d36abd5392bf505c1c2..d9f58d696238b491e3d3b0e87d76f02d89ad3963 100644 --- a/arch/hexagon/include/asm/checksum.h +++ b/arch/hexagon/include/asm/checksum.h @@ -38,12 +38,12 @@ __wsum csum_partial_copy_nocheck(const void *src, void *dst, * returns a 16-bit checksum, already complemented */ #define csum_tcpudp_nofold csum_tcpudp_nofold -__wsum csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, - unsigned short len, unsigned short proto, __wsum sum); +__wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, + __u32 len, __u8 proto, __wsum sum); #define csum_tcpudp_magic csum_tcpudp_magic -__sum16 csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, - unsigned short len, unsigned short proto, __wsum sum); +__sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, + __u32 len, __u8 proto, __wsum sum); #include diff --git a/arch/hexagon/lib/checksum.c b/arch/hexagon/lib/checksum.c index 8169f78a46a70f5bc0359b4fa006070772116d59..617506d1a5596679b19b27af252c3199e61ab1f1 100644 --- a/arch/hexagon/lib/checksum.c +++ b/arch/hexagon/lib/checksum.c @@ -60,18 +60,16 @@ static inline unsigned short from64to16(u64 x) * computes the checksum of the TCP/UDP pseudo-header * returns a 16-bit checksum, already complemented. */ -__sum16 csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, - unsigned short len, unsigned short proto, - __wsum sum) +__sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, + __u32 len, __u8 proto, __wsum sum) { return (__force __sum16)~from64to16( (__force u64)saddr + (__force u64)daddr + (__force u64)sum + ((len + proto) << 8)); } -__wsum csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, - unsigned short len, unsigned short proto, - __wsum sum) +__wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, + __u32 len, __u8 proto, __wsum sum) { u64 result; diff --git a/arch/ia64/include/asm/checksum.h b/arch/ia64/include/asm/checksum.h index 97af155057e4bcfa668eb006c935e68b1436dbca..7accf54162b2d978c4e78410f0435678a44c4ee6 100644 --- a/arch/ia64/include/asm/checksum.h +++ b/arch/ia64/include/asm/checksum.h @@ -16,15 +16,11 @@ extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl); * Computes the checksum of the TCP/UDP pseudo-header returns a 16-bit * checksum, already complemented */ -extern __sum16 csum_tcpudp_magic (__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum); +extern __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, + __u32 len, __u8 proto, __wsum sum); -extern __wsum csum_tcpudp_nofold (__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum); +extern __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, + __u32 len, __u8 proto, __wsum sum); /* * Computes the checksum of a memory block at buff, length len, @@ -73,7 +69,7 @@ static inline __sum16 csum_fold(__wsum csum) #define _HAVE_ARCH_IPV6_CSUM 1 struct in6_addr; extern __sum16 csum_ipv6_magic(const struct in6_addr *saddr, - const struct in6_addr *daddr, __u32 len, unsigned short proto, - __wsum csum); + const struct in6_addr *daddr, + __u32 len, __u8 proto, __wsum csum); #endif /* _ASM_IA64_CHECKSUM_H */ diff --git a/arch/ia64/include/asm/io.h b/arch/ia64/include/asm/io.h index a865d2a04f75bcbe92bd98e3d6e82d462e0a378b..5de673ac9cb13602dc6e8cc31d9a78b38448bbf5 100644 --- a/arch/ia64/include/asm/io.h +++ b/arch/ia64/include/asm/io.h @@ -433,6 +433,7 @@ static inline void __iomem * ioremap_cache (unsigned long phys_addr, unsigned lo return ioremap(phys_addr, size); } #define ioremap_cache ioremap_cache +#define ioremap_uc ioremap_nocache /* diff --git a/arch/ia64/include/asm/rwsem.h b/arch/ia64/include/asm/rwsem.h index 3027e7516d8502ea352afa38c6515925b5fe2d77..ce112472bdd65a10072eecf995ef5053cbae2e41 100644 --- a/arch/ia64/include/asm/rwsem.h +++ b/arch/ia64/include/asm/rwsem.h @@ -3,7 +3,7 @@ * * Copyright (C) 2003 Ken Chen * Copyright (C) 2003 Asit Mallick - * Copyright (C) 2005 Christoph Lameter + * Copyright (C) 2005 Christoph Lameter * * Based on asm-i386/rwsem.h and other architecture implementation. * diff --git a/arch/ia64/include/asm/uaccess.h b/arch/ia64/include/asm/uaccess.h index 4f3fb6ccbf2139b3e23798df6615e34ec5e4d09a..2189d5ddc1eeef552dd602875ae7d34c8baf17f7 100644 --- a/arch/ia64/include/asm/uaccess.h +++ b/arch/ia64/include/asm/uaccess.h @@ -341,13 +341,11 @@ extern unsigned long __strnlen_user (const char __user *, long); __su_ret; \ }) -/* Generic code can't deal with the location-relative format that we use for compactness. */ -#define ARCH_HAS_SORT_EXTABLE -#define ARCH_HAS_SEARCH_EXTABLE +#define ARCH_HAS_RELATIVE_EXTABLE struct exception_table_entry { - int addr; /* location-relative address of insn this fixup is for */ - int cont; /* location-relative continuation addr.; if bit 2 is set, r9 is set to 0 */ + int insn; /* location-relative address of insn this fixup is for */ + int fixup; /* location-relative continuation addr.; if bit 2 is set, r9 is set to 0 */ }; extern void ia64_handle_exception (struct pt_regs *regs, const struct exception_table_entry *e); diff --git a/arch/ia64/include/asm/unistd.h b/arch/ia64/include/asm/unistd.h index 6a8685051b676196780cab79a495fc6d906ccce7..8c85209753abc210bdcec5be8f7f9afb6abae369 100644 --- a/arch/ia64/include/asm/unistd.h +++ b/arch/ia64/include/asm/unistd.h @@ -11,7 +11,7 @@ -#define NR_syscalls 324 /* length of syscall table */ +#define NR_syscalls 326 /* length of syscall table */ /* * The following defines stop scripts/checksyscalls.sh from complaining about diff --git a/arch/ia64/include/uapi/asm/siginfo.h b/arch/ia64/include/uapi/asm/siginfo.h index bce9bc1a66c4c398e2a32babfbe9ba114aad592a..f72bf0172bb23fef180c54674b540754b7d8eb87 100644 --- a/arch/ia64/include/uapi/asm/siginfo.h +++ b/arch/ia64/include/uapi/asm/siginfo.h @@ -63,10 +63,15 @@ typedef struct siginfo { unsigned int _flags; /* see below */ unsigned long _isr; /* isr */ short _addr_lsb; /* lsb of faulting address */ - struct { - void __user *_lower; - void __user *_upper; - } _addr_bnd; + union { + /* used when si_code=SEGV_BNDERR */ + struct { + void __user *_lower; + void __user *_upper; + } _addr_bnd; + /* used when si_code=SEGV_PKUERR */ + __u32 _pkey; + }; } _sigfault; /* SIGPOLL */ diff --git a/arch/ia64/include/uapi/asm/socket.h b/arch/ia64/include/uapi/asm/socket.h index bce29166de1bfa28d5ec86b3bcaae941ce62cb21..0018fad9039f4bd9435d2b6a5976093e56d38db7 100644 --- a/arch/ia64/include/uapi/asm/socket.h +++ b/arch/ia64/include/uapi/asm/socket.h @@ -97,4 +97,6 @@ #define SO_ATTACH_REUSEPORT_CBPF 51 #define SO_ATTACH_REUSEPORT_EBPF 52 +#define SO_CNX_ADVICE 53 + #endif /* _ASM_IA64_SOCKET_H */ diff --git a/arch/ia64/include/uapi/asm/unistd.h b/arch/ia64/include/uapi/asm/unistd.h index 41369a103838a6e3d8776f550885399d9006e60e..ea5363daa7bd1e967c9f4674545e5eae0e57befa 100644 --- a/arch/ia64/include/uapi/asm/unistd.h +++ b/arch/ia64/include/uapi/asm/unistd.h @@ -337,5 +337,7 @@ #define __NR_kcmp 1345 #define __NR_mlock2 1346 #define __NR_copy_file_range 1347 +#define __NR_preadv2 1348 +#define __NR_pwritev2 1349 #endif /* _UAPI_ASM_IA64_UNISTD_H */ diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 477c55e244ecd45ce879dea27779967a16e0d13c..cfaa7b25084c5384e849af309b0245a652b34e67 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -1773,5 +1773,7 @@ sys_call_table: data8 sys_kcmp // 1345 data8 sys_mlock2 data8 sys_copy_file_range + data8 sys_preadv2 + data8 sys_pwritev2 .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls diff --git a/arch/ia64/kernel/err_inject.c b/arch/ia64/kernel/err_inject.c index 0c161ed6d18e6d77433c8bafabfdd48f904a077d..09f845793d12c1147bc767885673545a3bef88f3 100644 --- a/arch/ia64/kernel/err_inject.c +++ b/arch/ia64/kernel/err_inject.c @@ -142,8 +142,7 @@ store_virtual_to_phys(struct device *dev, struct device_attribute *attr, u64 virt_addr=simple_strtoull(buf, NULL, 16); int ret; - ret = get_user_pages(current, current->mm, virt_addr, - 1, VM_READ, 0, NULL, NULL); + ret = get_user_pages(virt_addr, 1, VM_READ, 0, NULL, NULL); if (ret<=0) { #ifdef ERR_INJ_DEBUG printk("Virtual address %lx is not existing.\n",virt_addr); diff --git a/arch/ia64/lib/checksum.c b/arch/ia64/lib/checksum.c index 9fc955026f866b5fda8fb196fb72311fbcc7f0dc..2cb23cb0c2e1d1a98bb5a4db9d6e6407555c17e7 100644 --- a/arch/ia64/lib/checksum.c +++ b/arch/ia64/lib/checksum.c @@ -34,8 +34,8 @@ from64to16 (unsigned long x) * returns a 16-bit checksum, already complemented. */ __sum16 -csum_tcpudp_magic (__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) +csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len, + __u8 proto, __wsum sum) { return (__force __sum16)~from64to16( (__force u64)saddr + (__force u64)daddr + @@ -45,8 +45,8 @@ csum_tcpudp_magic (__be32 saddr, __be32 daddr, unsigned short len, EXPORT_SYMBOL(csum_tcpudp_magic); __wsum -csum_tcpudp_nofold (__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) +csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len, + __u8 proto, __wsum sum) { unsigned long result; diff --git a/arch/ia64/mm/extable.c b/arch/ia64/mm/extable.c index c99a41e29fe81b859a9384519b9308646624f6e6..8f70bb2d0c37bc0df8bc264e5ac032e8c25e6c84 100644 --- a/arch/ia64/mm/extable.c +++ b/arch/ia64/mm/extable.c @@ -5,107 +5,12 @@ * David Mosberger-Tang */ -#include - #include -#include - -static int cmp_ex(const void *a, const void *b) -{ - const struct exception_table_entry *l = a, *r = b; - u64 lip = (u64) &l->addr + l->addr; - u64 rip = (u64) &r->addr + r->addr; - - /* avoid overflow */ - if (lip > rip) - return 1; - if (lip < rip) - return -1; - return 0; -} - -static void swap_ex(void *a, void *b, int size) -{ - struct exception_table_entry *l = a, *r = b, tmp; - u64 delta = (u64) r - (u64) l; - - tmp = *l; - l->addr = r->addr + delta; - l->cont = r->cont + delta; - r->addr = tmp.addr - delta; - r->cont = tmp.cont - delta; -} - -/* - * Sort the exception table. It's usually already sorted, but there - * may be unordered entries due to multiple text sections (such as the - * .init text section). Note that the exception-table-entries contain - * location-relative addresses, which requires a bit of care during - * sorting to avoid overflows in the offset members (e.g., it would - * not be safe to make a temporary copy of an exception-table entry on - * the stack, because the stack may be more than 2GB away from the - * exception-table). - */ -void sort_extable (struct exception_table_entry *start, - struct exception_table_entry *finish) -{ - sort(start, finish - start, sizeof(struct exception_table_entry), - cmp_ex, swap_ex); -} - -static inline unsigned long ex_to_addr(const struct exception_table_entry *x) -{ - return (unsigned long)&x->addr + x->addr; -} - -#ifdef CONFIG_MODULES -/* - * Any entry referring to the module init will be at the beginning or - * the end. - */ -void trim_init_extable(struct module *m) -{ - /*trim the beginning*/ - while (m->num_exentries && - within_module_init(ex_to_addr(&m->extable[0]), m)) { - m->extable++; - m->num_exentries--; - } - /*trim the end*/ - while (m->num_exentries && - within_module_init(ex_to_addr(&m->extable[m->num_exentries-1]), - m)) - m->num_exentries--; -} -#endif /* CONFIG_MODULES */ - -const struct exception_table_entry * -search_extable (const struct exception_table_entry *first, - const struct exception_table_entry *last, - unsigned long ip) -{ - const struct exception_table_entry *mid; - unsigned long mid_ip; - long diff; - - while (first <= last) { - mid = &first[(last - first)/2]; - mid_ip = (u64) &mid->addr + mid->addr; - diff = mid_ip - ip; - if (diff == 0) - return mid; - else if (diff < 0) - first = mid + 1; - else - last = mid - 1; - } - return NULL; -} void ia64_handle_exception (struct pt_regs *regs, const struct exception_table_entry *e) { - long fix = (u64) &e->cont + e->cont; + long fix = (u64) &e->fixup + e->fixup; regs->r8 = -EFAULT; if (fix & 4) diff --git a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c index f50d4b3f501ad6a5cd0fcf10dfd66b82500b0e54..85de86d36fdf2a71783697212e2e5cdb1e2dbc46 100644 --- a/arch/ia64/mm/hugetlbpage.c +++ b/arch/ia64/mm/hugetlbpage.c @@ -38,7 +38,7 @@ huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz) if (pud) { pmd = pmd_alloc(mm, pud, taddr); if (pmd) - pte = pte_alloc_map(mm, NULL, pmd, taddr); + pte = pte_alloc_map(mm, pmd, taddr); } return pte; } diff --git a/arch/m32r/include/asm/checksum.h b/arch/m32r/include/asm/checksum.h index a7a7c4f44abec1cbf27768d6121cb06d80ec63fe..d68e93c9bd62d99cd740aa3f9a79bc35f8fad2b4 100644 --- a/arch/m32r/include/asm/checksum.h +++ b/arch/m32r/include/asm/checksum.h @@ -114,9 +114,8 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) } static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum) + __u32 len, __u8 proto, + __wsum sum) { #if defined(__LITTLE_ENDIAN) unsigned long len_proto = (proto + len) << 8; @@ -145,9 +144,8 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, * returns a 16-bit checksum, already complemented */ static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum) + __u32 len, __u8 proto, + __wsum sum) { return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); } diff --git a/arch/m32r/include/uapi/asm/socket.h b/arch/m32r/include/uapi/asm/socket.h index 14aa4a6bccf125fc3c553dfb984e6eae3e6fd1e5..5fe42fc7b6c5dd29e15edbcfbb8ea4cb370ea25c 100644 --- a/arch/m32r/include/uapi/asm/socket.h +++ b/arch/m32r/include/uapi/asm/socket.h @@ -88,4 +88,6 @@ #define SO_ATTACH_REUSEPORT_CBPF 51 #define SO_ATTACH_REUSEPORT_EBPF 52 +#define SO_CNX_ADVICE 53 + #endif /* _ASM_M32R_SOCKET_H */ diff --git a/arch/m68k/configs/amiga_defconfig b/arch/m68k/configs/amiga_defconfig index d1fc4796025edb8769ee01195e64b91821f3625a..3ee6976f60885e5b2e0e4e2a80df6d824de14694 100644 --- a/arch/m68k/configs/amiga_defconfig +++ b/arch/m68k/configs/amiga_defconfig @@ -1,7 +1,6 @@ CONFIG_LOCALVERSION="-amiga" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_LOG_BUF_SHIFT=16 @@ -64,7 +63,6 @@ CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m -# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m CONFIG_INET_UDP_DIAG=m CONFIG_IPV6=m @@ -285,7 +283,9 @@ CONFIG_NET_MPLS_GSO=m CONFIG_MPLS_ROUTING=m CONFIG_MPLS_IPTUNNEL=m CONFIG_NET_L3_MASTER_DEV=y +CONFIG_AF_KCM=m # CONFIG_WIRELESS is not set +CONFIG_NET_DEVLINK=m # CONFIG_UEVENT_HELPER is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y @@ -359,6 +359,7 @@ CONFIG_MACVTAP=m CONFIG_IPVLAN=m CONFIG_VXLAN=m CONFIG_GENEVE=m +CONFIG_MACSEC=m CONFIG_NETCONSOLE=m CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_VETH=m @@ -452,6 +453,7 @@ CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FS_ENCRYPTION=m CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set @@ -468,6 +470,7 @@ CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_PROC_CHILDREN=y CONFIG_TMPFS=y +CONFIG_ORANGEFS_FS=m CONFIG_AFFS_FS=m CONFIG_ECRYPT_FS=m CONFIG_ECRYPT_FS_MESSAGING=y @@ -549,6 +552,7 @@ CONFIG_TEST_HEXDUMP=m CONFIG_TEST_STRING_HELPERS=m CONFIG_TEST_KSTRTOX=m CONFIG_TEST_PRINTF=m +CONFIG_TEST_BITMAP=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m @@ -557,7 +561,6 @@ CONFIG_TEST_FIRMWARE=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m CONFIG_EARLY_PRINTK=y -CONFIG_ENCRYPTED_KEYS=m CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_USER=m @@ -565,12 +568,9 @@ CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_MCRYPTD=m CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m CONFIG_CRYPTO_CHACHA20POLY1305=m -CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_XTS=m CONFIG_CRYPTO_KEYWRAP=m CONFIG_CRYPTO_XCBC=m CONFIG_CRYPTO_VMAC=m @@ -594,7 +594,6 @@ CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m CONFIG_CRYPTO_842=m CONFIG_CRYPTO_LZ4=m diff --git a/arch/m68k/configs/apollo_defconfig b/arch/m68k/configs/apollo_defconfig index 9bfe8be3658c18231ca4473d8c075a1fb2ac4d5e..e96787ffcbced33f9893d2760259177086b13c1f 100644 --- a/arch/m68k/configs/apollo_defconfig +++ b/arch/m68k/configs/apollo_defconfig @@ -1,7 +1,6 @@ CONFIG_LOCALVERSION="-apollo" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_LOG_BUF_SHIFT=16 @@ -62,7 +61,6 @@ CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m -# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m CONFIG_INET_UDP_DIAG=m CONFIG_IPV6=m @@ -283,7 +281,9 @@ CONFIG_NET_MPLS_GSO=m CONFIG_MPLS_ROUTING=m CONFIG_MPLS_IPTUNNEL=m CONFIG_NET_L3_MASTER_DEV=y +CONFIG_AF_KCM=m # CONFIG_WIRELESS is not set +CONFIG_NET_DEVLINK=m # CONFIG_UEVENT_HELPER is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y @@ -341,6 +341,7 @@ CONFIG_MACVTAP=m CONFIG_IPVLAN=m CONFIG_VXLAN=m CONFIG_GENEVE=m +CONFIG_MACSEC=m CONFIG_NETCONSOLE=m CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_VETH=m @@ -411,6 +412,7 @@ CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FS_ENCRYPTION=m CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set @@ -427,6 +429,7 @@ CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_PROC_CHILDREN=y CONFIG_TMPFS=y +CONFIG_ORANGEFS_FS=m CONFIG_AFFS_FS=m CONFIG_ECRYPT_FS=m CONFIG_ECRYPT_FS_MESSAGING=y @@ -508,6 +511,7 @@ CONFIG_TEST_HEXDUMP=m CONFIG_TEST_STRING_HELPERS=m CONFIG_TEST_KSTRTOX=m CONFIG_TEST_PRINTF=m +CONFIG_TEST_BITMAP=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m @@ -516,7 +520,6 @@ CONFIG_TEST_FIRMWARE=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m CONFIG_EARLY_PRINTK=y -CONFIG_ENCRYPTED_KEYS=m CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_USER=m @@ -524,12 +527,9 @@ CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_MCRYPTD=m CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m CONFIG_CRYPTO_CHACHA20POLY1305=m -CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_XTS=m CONFIG_CRYPTO_KEYWRAP=m CONFIG_CRYPTO_XCBC=m CONFIG_CRYPTO_VMAC=m @@ -553,7 +553,6 @@ CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m CONFIG_CRYPTO_842=m CONFIG_CRYPTO_LZ4=m diff --git a/arch/m68k/configs/atari_defconfig b/arch/m68k/configs/atari_defconfig index ebdcfae555801cd1c7367d4ca40974b3d39099cb..083fe6beac149da81250ca4fccd50798f9e4ef0d 100644 --- a/arch/m68k/configs/atari_defconfig +++ b/arch/m68k/configs/atari_defconfig @@ -1,7 +1,6 @@ CONFIG_LOCALVERSION="-atari" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_LOG_BUF_SHIFT=16 @@ -62,7 +61,6 @@ CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m -# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m CONFIG_INET_UDP_DIAG=m CONFIG_IPV6=m @@ -283,7 +281,9 @@ CONFIG_NET_MPLS_GSO=m CONFIG_MPLS_ROUTING=m CONFIG_MPLS_IPTUNNEL=m CONFIG_NET_L3_MASTER_DEV=y +CONFIG_AF_KCM=m # CONFIG_WIRELESS is not set +CONFIG_NET_DEVLINK=m # CONFIG_UEVENT_HELPER is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y @@ -350,6 +350,7 @@ CONFIG_MACVTAP=m CONFIG_IPVLAN=m CONFIG_VXLAN=m CONFIG_GENEVE=m +CONFIG_MACSEC=m CONFIG_NETCONSOLE=m CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_VETH=m @@ -432,6 +433,7 @@ CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FS_ENCRYPTION=m CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set @@ -448,6 +450,7 @@ CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_PROC_CHILDREN=y CONFIG_TMPFS=y +CONFIG_ORANGEFS_FS=m CONFIG_AFFS_FS=m CONFIG_ECRYPT_FS=m CONFIG_ECRYPT_FS_MESSAGING=y @@ -529,6 +532,7 @@ CONFIG_TEST_HEXDUMP=m CONFIG_TEST_STRING_HELPERS=m CONFIG_TEST_KSTRTOX=m CONFIG_TEST_PRINTF=m +CONFIG_TEST_BITMAP=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m @@ -537,7 +541,6 @@ CONFIG_TEST_FIRMWARE=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m CONFIG_EARLY_PRINTK=y -CONFIG_ENCRYPTED_KEYS=m CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_USER=m @@ -545,12 +548,9 @@ CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_MCRYPTD=m CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m CONFIG_CRYPTO_CHACHA20POLY1305=m -CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_XTS=m CONFIG_CRYPTO_KEYWRAP=m CONFIG_CRYPTO_XCBC=m CONFIG_CRYPTO_VMAC=m @@ -574,7 +574,6 @@ CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m CONFIG_CRYPTO_842=m CONFIG_CRYPTO_LZ4=m diff --git a/arch/m68k/configs/bvme6000_defconfig b/arch/m68k/configs/bvme6000_defconfig index 8acc65e54995388614666716febdab1dda706376..475130c06dcba04b646ec2e7c199aee7045dea7d 100644 --- a/arch/m68k/configs/bvme6000_defconfig +++ b/arch/m68k/configs/bvme6000_defconfig @@ -1,7 +1,6 @@ CONFIG_LOCALVERSION="-bvme6000" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_LOG_BUF_SHIFT=16 @@ -60,7 +59,6 @@ CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m -# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m CONFIG_INET_UDP_DIAG=m CONFIG_IPV6=m @@ -281,7 +279,9 @@ CONFIG_NET_MPLS_GSO=m CONFIG_MPLS_ROUTING=m CONFIG_MPLS_IPTUNNEL=m CONFIG_NET_L3_MASTER_DEV=y +CONFIG_AF_KCM=m # CONFIG_WIRELESS is not set +CONFIG_NET_DEVLINK=m # CONFIG_UEVENT_HELPER is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y @@ -340,6 +340,7 @@ CONFIG_MACVTAP=m CONFIG_IPVLAN=m CONFIG_VXLAN=m CONFIG_GENEVE=m +CONFIG_MACSEC=m CONFIG_NETCONSOLE=m CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_VETH=m @@ -403,6 +404,7 @@ CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FS_ENCRYPTION=m CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set @@ -419,6 +421,7 @@ CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_PROC_CHILDREN=y CONFIG_TMPFS=y +CONFIG_ORANGEFS_FS=m CONFIG_AFFS_FS=m CONFIG_ECRYPT_FS=m CONFIG_ECRYPT_FS_MESSAGING=y @@ -500,6 +503,7 @@ CONFIG_TEST_HEXDUMP=m CONFIG_TEST_STRING_HELPERS=m CONFIG_TEST_KSTRTOX=m CONFIG_TEST_PRINTF=m +CONFIG_TEST_BITMAP=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m @@ -508,7 +512,6 @@ CONFIG_TEST_FIRMWARE=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m CONFIG_EARLY_PRINTK=y -CONFIG_ENCRYPTED_KEYS=m CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_USER=m @@ -516,12 +519,9 @@ CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_MCRYPTD=m CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m CONFIG_CRYPTO_CHACHA20POLY1305=m -CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_XTS=m CONFIG_CRYPTO_KEYWRAP=m CONFIG_CRYPTO_XCBC=m CONFIG_CRYPTO_VMAC=m @@ -545,7 +545,6 @@ CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m CONFIG_CRYPTO_842=m CONFIG_CRYPTO_LZ4=m diff --git a/arch/m68k/configs/hp300_defconfig b/arch/m68k/configs/hp300_defconfig index 0c6a3d52b26e2b2559f24963040d3ba65a91ed47..4339658c200f3eb8af4bc2645836e109466055cb 100644 --- a/arch/m68k/configs/hp300_defconfig +++ b/arch/m68k/configs/hp300_defconfig @@ -1,7 +1,6 @@ CONFIG_LOCALVERSION="-hp300" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_LOG_BUF_SHIFT=16 @@ -62,7 +61,6 @@ CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m -# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m CONFIG_INET_UDP_DIAG=m CONFIG_IPV6=m @@ -283,7 +281,9 @@ CONFIG_NET_MPLS_GSO=m CONFIG_MPLS_ROUTING=m CONFIG_MPLS_IPTUNNEL=m CONFIG_NET_L3_MASTER_DEV=y +CONFIG_AF_KCM=m # CONFIG_WIRELESS is not set +CONFIG_NET_DEVLINK=m # CONFIG_UEVENT_HELPER is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y @@ -341,6 +341,7 @@ CONFIG_MACVTAP=m CONFIG_IPVLAN=m CONFIG_VXLAN=m CONFIG_GENEVE=m +CONFIG_MACSEC=m CONFIG_NETCONSOLE=m CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_VETH=m @@ -413,6 +414,7 @@ CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FS_ENCRYPTION=m CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set @@ -429,6 +431,7 @@ CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_PROC_CHILDREN=y CONFIG_TMPFS=y +CONFIG_ORANGEFS_FS=m CONFIG_AFFS_FS=m CONFIG_ECRYPT_FS=m CONFIG_ECRYPT_FS_MESSAGING=y @@ -510,6 +513,7 @@ CONFIG_TEST_HEXDUMP=m CONFIG_TEST_STRING_HELPERS=m CONFIG_TEST_KSTRTOX=m CONFIG_TEST_PRINTF=m +CONFIG_TEST_BITMAP=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m @@ -518,7 +522,6 @@ CONFIG_TEST_FIRMWARE=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m CONFIG_EARLY_PRINTK=y -CONFIG_ENCRYPTED_KEYS=m CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_USER=m @@ -526,12 +529,9 @@ CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_MCRYPTD=m CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m CONFIG_CRYPTO_CHACHA20POLY1305=m -CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_XTS=m CONFIG_CRYPTO_KEYWRAP=m CONFIG_CRYPTO_XCBC=m CONFIG_CRYPTO_VMAC=m @@ -555,7 +555,6 @@ CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m CONFIG_CRYPTO_842=m CONFIG_CRYPTO_LZ4=m diff --git a/arch/m68k/configs/mac_defconfig b/arch/m68k/configs/mac_defconfig index 12a8a6cb32f4914f06c1f5d4c8e5dd6ba31381ef..831cc8c3a2e259f67d318257e72bcab84e36b8c1 100644 --- a/arch/m68k/configs/mac_defconfig +++ b/arch/m68k/configs/mac_defconfig @@ -1,7 +1,6 @@ CONFIG_LOCALVERSION="-mac" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_LOG_BUF_SHIFT=16 @@ -61,7 +60,6 @@ CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m -# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m CONFIG_INET_UDP_DIAG=m CONFIG_IPV6=m @@ -285,7 +283,9 @@ CONFIG_NET_MPLS_GSO=m CONFIG_MPLS_ROUTING=m CONFIG_MPLS_IPTUNNEL=m CONFIG_NET_L3_MASTER_DEV=y +CONFIG_AF_KCM=m # CONFIG_WIRELESS is not set +CONFIG_NET_DEVLINK=m # CONFIG_UEVENT_HELPER is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y @@ -357,6 +357,7 @@ CONFIG_MACVTAP=m CONFIG_IPVLAN=m CONFIG_VXLAN=m CONFIG_GENEVE=m +CONFIG_MACSEC=m CONFIG_NETCONSOLE=m CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_VETH=m @@ -435,6 +436,7 @@ CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FS_ENCRYPTION=m CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set @@ -451,6 +453,7 @@ CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_PROC_CHILDREN=y CONFIG_TMPFS=y +CONFIG_ORANGEFS_FS=m CONFIG_AFFS_FS=m CONFIG_ECRYPT_FS=m CONFIG_ECRYPT_FS_MESSAGING=y @@ -532,6 +535,7 @@ CONFIG_TEST_HEXDUMP=m CONFIG_TEST_STRING_HELPERS=m CONFIG_TEST_KSTRTOX=m CONFIG_TEST_PRINTF=m +CONFIG_TEST_BITMAP=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m @@ -540,7 +544,6 @@ CONFIG_TEST_FIRMWARE=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m CONFIG_EARLY_PRINTK=y -CONFIG_ENCRYPTED_KEYS=m CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_USER=m @@ -548,12 +551,9 @@ CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_MCRYPTD=m CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m CONFIG_CRYPTO_CHACHA20POLY1305=m -CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_XTS=m CONFIG_CRYPTO_KEYWRAP=m CONFIG_CRYPTO_XCBC=m CONFIG_CRYPTO_VMAC=m @@ -577,7 +577,6 @@ CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m CONFIG_CRYPTO_842=m CONFIG_CRYPTO_LZ4=m diff --git a/arch/m68k/configs/multi_defconfig b/arch/m68k/configs/multi_defconfig index 64ff2dcb34c89a3e60e26f9c468d654ed943e97f..6377afeb522bbb9a235d1bd57f36cc14ca36ac5b 100644 --- a/arch/m68k/configs/multi_defconfig +++ b/arch/m68k/configs/multi_defconfig @@ -1,7 +1,6 @@ CONFIG_LOCALVERSION="-multi" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_LOG_BUF_SHIFT=16 @@ -71,7 +70,6 @@ CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m -# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m CONFIG_INET_UDP_DIAG=m CONFIG_IPV6=m @@ -295,7 +293,9 @@ CONFIG_NET_MPLS_GSO=m CONFIG_MPLS_ROUTING=m CONFIG_MPLS_IPTUNNEL=m CONFIG_NET_L3_MASTER_DEV=y +CONFIG_AF_KCM=m # CONFIG_WIRELESS is not set +CONFIG_NET_DEVLINK=m # CONFIG_UEVENT_HELPER is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y @@ -390,6 +390,7 @@ CONFIG_MACVTAP=m CONFIG_IPVLAN=m CONFIG_VXLAN=m CONFIG_GENEVE=m +CONFIG_MACSEC=m CONFIG_NETCONSOLE=m CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_VETH=m @@ -515,6 +516,7 @@ CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FS_ENCRYPTION=m CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set @@ -531,6 +533,7 @@ CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_PROC_CHILDREN=y CONFIG_TMPFS=y +CONFIG_ORANGEFS_FS=m CONFIG_AFFS_FS=m CONFIG_ECRYPT_FS=m CONFIG_ECRYPT_FS_MESSAGING=y @@ -612,6 +615,7 @@ CONFIG_TEST_HEXDUMP=m CONFIG_TEST_STRING_HELPERS=m CONFIG_TEST_KSTRTOX=m CONFIG_TEST_PRINTF=m +CONFIG_TEST_BITMAP=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m @@ -620,7 +624,6 @@ CONFIG_TEST_FIRMWARE=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m CONFIG_EARLY_PRINTK=y -CONFIG_ENCRYPTED_KEYS=m CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_USER=m @@ -628,12 +631,9 @@ CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_MCRYPTD=m CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m CONFIG_CRYPTO_CHACHA20POLY1305=m -CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_XTS=m CONFIG_CRYPTO_KEYWRAP=m CONFIG_CRYPTO_XCBC=m CONFIG_CRYPTO_VMAC=m @@ -657,7 +657,6 @@ CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m CONFIG_CRYPTO_842=m CONFIG_CRYPTO_LZ4=m diff --git a/arch/m68k/configs/mvme147_defconfig b/arch/m68k/configs/mvme147_defconfig index 07fc6abcfe0c50e4b656a63a9da36c728b13cec4..4304b3d56262bc677383ba4389b65d5e9a7625cd 100644 --- a/arch/m68k/configs/mvme147_defconfig +++ b/arch/m68k/configs/mvme147_defconfig @@ -1,7 +1,6 @@ CONFIG_LOCALVERSION="-mvme147" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_LOG_BUF_SHIFT=16 @@ -59,7 +58,6 @@ CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m -# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m CONFIG_INET_UDP_DIAG=m CONFIG_IPV6=m @@ -280,7 +278,9 @@ CONFIG_NET_MPLS_GSO=m CONFIG_MPLS_ROUTING=m CONFIG_MPLS_IPTUNNEL=m CONFIG_NET_L3_MASTER_DEV=y +CONFIG_AF_KCM=m # CONFIG_WIRELESS is not set +CONFIG_NET_DEVLINK=m # CONFIG_UEVENT_HELPER is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y @@ -339,6 +339,7 @@ CONFIG_MACVTAP=m CONFIG_IPVLAN=m CONFIG_VXLAN=m CONFIG_GENEVE=m +CONFIG_MACSEC=m CONFIG_NETCONSOLE=m CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_VETH=m @@ -403,6 +404,7 @@ CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FS_ENCRYPTION=m CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set @@ -419,6 +421,7 @@ CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_PROC_CHILDREN=y CONFIG_TMPFS=y +CONFIG_ORANGEFS_FS=m CONFIG_AFFS_FS=m CONFIG_ECRYPT_FS=m CONFIG_ECRYPT_FS_MESSAGING=y @@ -500,6 +503,7 @@ CONFIG_TEST_HEXDUMP=m CONFIG_TEST_STRING_HELPERS=m CONFIG_TEST_KSTRTOX=m CONFIG_TEST_PRINTF=m +CONFIG_TEST_BITMAP=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m @@ -508,7 +512,6 @@ CONFIG_TEST_FIRMWARE=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m CONFIG_EARLY_PRINTK=y -CONFIG_ENCRYPTED_KEYS=m CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_USER=m @@ -516,12 +519,9 @@ CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_MCRYPTD=m CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m CONFIG_CRYPTO_CHACHA20POLY1305=m -CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_XTS=m CONFIG_CRYPTO_KEYWRAP=m CONFIG_CRYPTO_XCBC=m CONFIG_CRYPTO_VMAC=m @@ -545,7 +545,6 @@ CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m CONFIG_CRYPTO_842=m CONFIG_CRYPTO_LZ4=m diff --git a/arch/m68k/configs/mvme16x_defconfig b/arch/m68k/configs/mvme16x_defconfig index 69903ded88f71d1d51ad4b430acbd2f745fdf867..074bda4094ffd5b0913d4411371e2597774faab2 100644 --- a/arch/m68k/configs/mvme16x_defconfig +++ b/arch/m68k/configs/mvme16x_defconfig @@ -1,7 +1,6 @@ CONFIG_LOCALVERSION="-mvme16x" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_LOG_BUF_SHIFT=16 @@ -60,7 +59,6 @@ CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m -# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m CONFIG_INET_UDP_DIAG=m CONFIG_IPV6=m @@ -281,7 +279,9 @@ CONFIG_NET_MPLS_GSO=m CONFIG_MPLS_ROUTING=m CONFIG_MPLS_IPTUNNEL=m CONFIG_NET_L3_MASTER_DEV=y +CONFIG_AF_KCM=m # CONFIG_WIRELESS is not set +CONFIG_NET_DEVLINK=m # CONFIG_UEVENT_HELPER is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y @@ -340,6 +340,7 @@ CONFIG_MACVTAP=m CONFIG_IPVLAN=m CONFIG_VXLAN=m CONFIG_GENEVE=m +CONFIG_MACSEC=m CONFIG_NETCONSOLE=m CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_VETH=m @@ -403,6 +404,7 @@ CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FS_ENCRYPTION=m CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set @@ -419,6 +421,7 @@ CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_PROC_CHILDREN=y CONFIG_TMPFS=y +CONFIG_ORANGEFS_FS=m CONFIG_AFFS_FS=m CONFIG_ECRYPT_FS=m CONFIG_ECRYPT_FS_MESSAGING=y @@ -500,6 +503,7 @@ CONFIG_TEST_HEXDUMP=m CONFIG_TEST_STRING_HELPERS=m CONFIG_TEST_KSTRTOX=m CONFIG_TEST_PRINTF=m +CONFIG_TEST_BITMAP=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m @@ -508,7 +512,6 @@ CONFIG_TEST_FIRMWARE=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m CONFIG_EARLY_PRINTK=y -CONFIG_ENCRYPTED_KEYS=m CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_USER=m @@ -516,12 +519,9 @@ CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_MCRYPTD=m CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m CONFIG_CRYPTO_CHACHA20POLY1305=m -CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_XTS=m CONFIG_CRYPTO_KEYWRAP=m CONFIG_CRYPTO_XCBC=m CONFIG_CRYPTO_VMAC=m @@ -545,7 +545,6 @@ CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m CONFIG_CRYPTO_842=m CONFIG_CRYPTO_LZ4=m diff --git a/arch/m68k/configs/q40_defconfig b/arch/m68k/configs/q40_defconfig index bd8401686ddef143bf036159cb3f4ea650772f32..07b9fa8d7f2ea71dd09a26c8d9abe4a519baa07c 100644 --- a/arch/m68k/configs/q40_defconfig +++ b/arch/m68k/configs/q40_defconfig @@ -1,7 +1,6 @@ CONFIG_LOCALVERSION="-q40" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_LOG_BUF_SHIFT=16 @@ -60,7 +59,6 @@ CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m -# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m CONFIG_INET_UDP_DIAG=m CONFIG_IPV6=m @@ -281,7 +279,9 @@ CONFIG_NET_MPLS_GSO=m CONFIG_MPLS_ROUTING=m CONFIG_MPLS_IPTUNNEL=m CONFIG_NET_L3_MASTER_DEV=y +CONFIG_AF_KCM=m # CONFIG_WIRELESS is not set +CONFIG_NET_DEVLINK=m # CONFIG_UEVENT_HELPER is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y @@ -346,6 +346,7 @@ CONFIG_MACVTAP=m CONFIG_IPVLAN=m CONFIG_VXLAN=m CONFIG_GENEVE=m +CONFIG_MACSEC=m CONFIG_NETCONSOLE=m CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_VETH=m @@ -426,6 +427,7 @@ CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FS_ENCRYPTION=m CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set @@ -442,6 +444,7 @@ CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_PROC_CHILDREN=y CONFIG_TMPFS=y +CONFIG_ORANGEFS_FS=m CONFIG_AFFS_FS=m CONFIG_ECRYPT_FS=m CONFIG_ECRYPT_FS_MESSAGING=y @@ -523,6 +526,7 @@ CONFIG_TEST_HEXDUMP=m CONFIG_TEST_STRING_HELPERS=m CONFIG_TEST_KSTRTOX=m CONFIG_TEST_PRINTF=m +CONFIG_TEST_BITMAP=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m @@ -531,7 +535,6 @@ CONFIG_TEST_FIRMWARE=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m CONFIG_EARLY_PRINTK=y -CONFIG_ENCRYPTED_KEYS=m CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_USER=m @@ -539,12 +542,9 @@ CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_MCRYPTD=m CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m CONFIG_CRYPTO_CHACHA20POLY1305=m -CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_XTS=m CONFIG_CRYPTO_KEYWRAP=m CONFIG_CRYPTO_XCBC=m CONFIG_CRYPTO_VMAC=m @@ -568,7 +568,6 @@ CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m CONFIG_CRYPTO_842=m CONFIG_CRYPTO_LZ4=m diff --git a/arch/m68k/configs/sun3_defconfig b/arch/m68k/configs/sun3_defconfig index 5f9fb3ab9636808d46b75f3696f477ab91e6dd79..36e6fae02d458e2dcb1a96c0caee68a5301f0341 100644 --- a/arch/m68k/configs/sun3_defconfig +++ b/arch/m68k/configs/sun3_defconfig @@ -1,7 +1,6 @@ CONFIG_LOCALVERSION="-sun3" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_LOG_BUF_SHIFT=16 @@ -57,7 +56,6 @@ CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m -# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m CONFIG_INET_UDP_DIAG=m CONFIG_IPV6=m @@ -278,7 +276,9 @@ CONFIG_NET_MPLS_GSO=m CONFIG_MPLS_ROUTING=m CONFIG_MPLS_IPTUNNEL=m CONFIG_NET_L3_MASTER_DEV=y +CONFIG_AF_KCM=m # CONFIG_WIRELESS is not set +CONFIG_NET_DEVLINK=m # CONFIG_UEVENT_HELPER is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y @@ -337,6 +337,7 @@ CONFIG_MACVTAP=m CONFIG_IPVLAN=m CONFIG_VXLAN=m CONFIG_GENEVE=m +CONFIG_MACSEC=m CONFIG_NETCONSOLE=m CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_VETH=m @@ -405,6 +406,7 @@ CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FS_ENCRYPTION=m CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set @@ -421,6 +423,7 @@ CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_PROC_CHILDREN=y CONFIG_TMPFS=y +CONFIG_ORANGEFS_FS=m CONFIG_AFFS_FS=m CONFIG_ECRYPT_FS=m CONFIG_ECRYPT_FS_MESSAGING=y @@ -502,6 +505,7 @@ CONFIG_TEST_HEXDUMP=m CONFIG_TEST_STRING_HELPERS=m CONFIG_TEST_KSTRTOX=m CONFIG_TEST_PRINTF=m +CONFIG_TEST_BITMAP=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m @@ -509,7 +513,6 @@ CONFIG_TEST_BPF=m CONFIG_TEST_FIRMWARE=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m -CONFIG_ENCRYPTED_KEYS=m CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_USER=m @@ -517,12 +520,9 @@ CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_MCRYPTD=m CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m CONFIG_CRYPTO_CHACHA20POLY1305=m -CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_XTS=m CONFIG_CRYPTO_KEYWRAP=m CONFIG_CRYPTO_XCBC=m CONFIG_CRYPTO_VMAC=m @@ -546,7 +546,6 @@ CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m CONFIG_CRYPTO_842=m CONFIG_CRYPTO_LZ4=m diff --git a/arch/m68k/configs/sun3x_defconfig b/arch/m68k/configs/sun3x_defconfig index 5d1c674530e2ba73ca43ffc4940f139772962152..903acf929511e5066403bfdd1c4d78bbc4084c35 100644 --- a/arch/m68k/configs/sun3x_defconfig +++ b/arch/m68k/configs/sun3x_defconfig @@ -1,7 +1,6 @@ CONFIG_LOCALVERSION="-sun3x" CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_LOG_BUF_SHIFT=16 @@ -57,7 +56,6 @@ CONFIG_INET_IPCOMP=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_XFRM_MODE_BEET=m -# CONFIG_INET_LRO is not set CONFIG_INET_DIAG=m CONFIG_INET_UDP_DIAG=m CONFIG_IPV6=m @@ -278,7 +276,9 @@ CONFIG_NET_MPLS_GSO=m CONFIG_MPLS_ROUTING=m CONFIG_MPLS_IPTUNNEL=m CONFIG_NET_L3_MASTER_DEV=y +CONFIG_AF_KCM=m # CONFIG_WIRELESS is not set +CONFIG_NET_DEVLINK=m # CONFIG_UEVENT_HELPER is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y @@ -337,6 +337,7 @@ CONFIG_MACVTAP=m CONFIG_IPVLAN=m CONFIG_VXLAN=m CONFIG_GENEVE=m +CONFIG_MACSEC=m CONFIG_NETCONSOLE=m CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_VETH=m @@ -405,6 +406,7 @@ CONFIG_JFS_FS=m CONFIG_XFS_FS=m CONFIG_OCFS2_FS=m # CONFIG_OCFS2_DEBUG_MASKLOG is not set +CONFIG_FS_ENCRYPTION=m CONFIG_FANOTIFY=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set @@ -421,6 +423,7 @@ CONFIG_VFAT_FS=m CONFIG_PROC_KCORE=y CONFIG_PROC_CHILDREN=y CONFIG_TMPFS=y +CONFIG_ORANGEFS_FS=m CONFIG_AFFS_FS=m CONFIG_ECRYPT_FS=m CONFIG_ECRYPT_FS_MESSAGING=y @@ -502,6 +505,7 @@ CONFIG_TEST_HEXDUMP=m CONFIG_TEST_STRING_HELPERS=m CONFIG_TEST_KSTRTOX=m CONFIG_TEST_PRINTF=m +CONFIG_TEST_BITMAP=m CONFIG_TEST_RHASHTABLE=m CONFIG_TEST_LKM=m CONFIG_TEST_USER_COPY=m @@ -510,7 +514,6 @@ CONFIG_TEST_FIRMWARE=m CONFIG_TEST_UDELAY=m CONFIG_TEST_STATIC_KEYS=m CONFIG_EARLY_PRINTK=y -CONFIG_ENCRYPTED_KEYS=m CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_USER=m @@ -518,12 +521,9 @@ CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_MCRYPTD=m CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_CCM=m -CONFIG_CRYPTO_GCM=m CONFIG_CRYPTO_CHACHA20POLY1305=m -CONFIG_CRYPTO_CTS=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_XTS=m CONFIG_CRYPTO_KEYWRAP=m CONFIG_CRYPTO_XCBC=m CONFIG_CRYPTO_VMAC=m @@ -547,7 +547,6 @@ CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m CONFIG_CRYPTO_842=m CONFIG_CRYPTO_LZ4=m diff --git a/arch/m68k/include/asm/checksum.h b/arch/m68k/include/asm/checksum.h index 2f88d867c711207cde22101226b11c3ff68802db..75e91f03b17825290bb5b76b07b501da86232d5c 100644 --- a/arch/m68k/include/asm/checksum.h +++ b/arch/m68k/include/asm/checksum.h @@ -117,7 +117,7 @@ static inline __sum16 ip_compute_csum(const void *buff, int len) #define _HAVE_ARCH_IPV6_CSUM static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, - __u32 len, unsigned short proto, __wsum sum) + __u32 len, __u8 proto, __wsum sum) { register unsigned long tmp; __asm__("addl %2@,%0\n\t" diff --git a/arch/m68k/include/asm/page_mm.h b/arch/m68k/include/asm/page_mm.h index 5029f73e6294763239b7f1766ad073e29b273520..e7a1946455a88a295afb4d9a7b16607e626c5943 100644 --- a/arch/m68k/include/asm/page_mm.h +++ b/arch/m68k/include/asm/page_mm.h @@ -6,9 +6,6 @@ #include #include -#define get_user_page(vaddr) __get_free_page(GFP_KERNEL) -#define free_user_page(page, addr) free_page(addr) - /* * We don't need to check for alignment etc. */ diff --git a/arch/m68k/include/asm/page_no.h b/arch/m68k/include/asm/page_no.h index ef209169579a9897aee22e1fd3cc80fa348ff7bb..fa7f32d9836b3a4e58c055ce4ea57c5f6c7e6c45 100644 --- a/arch/m68k/include/asm/page_no.h +++ b/arch/m68k/include/asm/page_no.h @@ -6,9 +6,6 @@ extern unsigned long memory_start; extern unsigned long memory_end; -#define get_user_page(vaddr) __get_free_page(GFP_KERNEL) -#define free_user_page(page, addr) free_page(addr) - #define clear_page(page) memset((page), 0, PAGE_SIZE) #define copy_page(to,from) memcpy((to), (from), PAGE_SIZE) diff --git a/arch/m68k/include/asm/unistd.h b/arch/m68k/include/asm/unistd.h index bafaff6dcd7bda8a28101f140159f9a7a76638db..a857d82ec5094abc30e353f25370365194a01194 100644 --- a/arch/m68k/include/asm/unistd.h +++ b/arch/m68k/include/asm/unistd.h @@ -4,7 +4,7 @@ #include -#define NR_syscalls 377 +#define NR_syscalls 379 #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_OLD_STAT diff --git a/arch/m68k/include/uapi/asm/unistd.h b/arch/m68k/include/uapi/asm/unistd.h index 0ca729665f29e9d67851aed2c1c52be75bbd078b..9fe674bf911fd2a4e61d7119f9b91ffbdddf44f5 100644 --- a/arch/m68k/include/uapi/asm/unistd.h +++ b/arch/m68k/include/uapi/asm/unistd.h @@ -382,5 +382,7 @@ #define __NR_membarrier 374 #define __NR_mlock2 375 #define __NR_copy_file_range 376 +#define __NR_preadv2 377 +#define __NR_pwritev2 378 #endif /* _UAPI_ASM_M68K_UNISTD_H_ */ diff --git a/arch/m68k/kernel/syscalltable.S b/arch/m68k/kernel/syscalltable.S index 8bb94261ff97d953fcfbe7c305e6a7ecfce27a97..d6fd6d9ced2474ab477b0becefbd5f695d256e96 100644 --- a/arch/m68k/kernel/syscalltable.S +++ b/arch/m68k/kernel/syscalltable.S @@ -397,3 +397,5 @@ ENTRY(sys_call_table) .long sys_membarrier .long sys_mlock2 /* 375 */ .long sys_copy_file_range + .long sys_preadv2 + .long sys_pwritev2 diff --git a/arch/metag/include/asm/checksum.h b/arch/metag/include/asm/checksum.h index 08dd1cc65799a5f9aadcb515a332ab6ec611b7d6..f65fe83b17305b4e38db043b8d00590d8db07786 100644 --- a/arch/metag/include/asm/checksum.h +++ b/arch/metag/include/asm/checksum.h @@ -59,8 +59,7 @@ extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl); * returns a 16-bit checksum, already complemented */ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, + __u32 len, __u8 proto, __wsum sum) { unsigned long len_proto = (proto + len) << 8; @@ -78,8 +77,8 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, } static inline __sum16 -csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) +csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len, + __u8 proto, __wsum sum) { return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum)); } diff --git a/arch/metag/kernel/vmlinux.lds.S b/arch/metag/kernel/vmlinux.lds.S index e12055e88bfe5e55b6092dbf3cf95dd63eb08cdd..150ace92c7ade9046c9c22b114a979356e7395ac 100644 --- a/arch/metag/kernel/vmlinux.lds.S +++ b/arch/metag/kernel/vmlinux.lds.S @@ -24,6 +24,7 @@ SECTIONS LOCK_TEXT KPROBES_TEXT IRQENTRY_TEXT + SOFTIRQENTRY_TEXT *(.text.*) *(.gnu.warning) } diff --git a/arch/metag/mm/hugetlbpage.c b/arch/metag/mm/hugetlbpage.c index 53f0f6c470273b9c7c48ad6976b3e526a929ed52..b38700ae4e8429cdd6b56226ed82d523f4153d44 100644 --- a/arch/metag/mm/hugetlbpage.c +++ b/arch/metag/mm/hugetlbpage.c @@ -67,7 +67,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, pgd = pgd_offset(mm, addr); pud = pud_offset(pgd, addr); pmd = pmd_offset(pud, addr); - pte = pte_alloc_map(mm, NULL, pmd, addr); + pte = pte_alloc_map(mm, pmd, addr); pgd->pgd &= ~_PAGE_SZ_MASK; pgd->pgd |= _PAGE_SZHUGE; diff --git a/arch/microblaze/include/asm/checksum.h b/arch/microblaze/include/asm/checksum.h index 0185cbefdda48a2770703709ed1d9701208362a0..adeecebbb0d1383506f912d7732e726c0190fe3b 100644 --- a/arch/microblaze/include/asm/checksum.h +++ b/arch/microblaze/include/asm/checksum.h @@ -16,8 +16,8 @@ */ #define csum_tcpudp_nofold csum_tcpudp_nofold static inline __wsum -csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) +csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len, + __u8 proto, __wsum sum) { __asm__("add %0, %0, %1\n\t" "addc %0, %0, %2\n\t" diff --git a/arch/microblaze/kernel/vmlinux.lds.S b/arch/microblaze/kernel/vmlinux.lds.S index be9488d697347c330f9b226d1a5a5c9ba2d97714..0a47f041055416a90d34a64be3208e3fd74b2b6c 100644 --- a/arch/microblaze/kernel/vmlinux.lds.S +++ b/arch/microblaze/kernel/vmlinux.lds.S @@ -36,6 +36,7 @@ SECTIONS { LOCK_TEXT KPROBES_TEXT IRQENTRY_TEXT + SOFTIRQENTRY_TEXT . = ALIGN (4) ; _etext = . ; } diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 7c4a4ce356033c6a2aa05fe7fe306714c44689cb..2018c2b0e078f9880bca0d2bb497e2dd271196d5 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -328,7 +328,6 @@ config LANTIQ select ARCH_REQUIRE_GPIOLIB select SWAP_IO_SPACE select BOOT_RAW - select HAVE_MACH_CLKDEV select CLKDEV_LOOKUP select USE_OF select PINCTRL @@ -590,7 +589,6 @@ config RALINK select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_SUPPORTS_MIPS16 select SYS_HAS_EARLY_PRINTK - select HAVE_MACH_CLKDEV select CLKDEV_LOOKUP select ARCH_HAS_RESET_CONTROLLER select RESET_CONTROLLER diff --git a/arch/mips/alchemy/common/dbdma.c b/arch/mips/alchemy/common/dbdma.c index 745695db5ba068d2b0416b879234e2a44174eea7..f2f264b5aafe224c2efe7bc489d34b4b7c145aad 100644 --- a/arch/mips/alchemy/common/dbdma.c +++ b/arch/mips/alchemy/common/dbdma.c @@ -261,7 +261,7 @@ u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid, au1x_dma_chan_t *cp; /* - * We do the intialization on the first channel allocation. + * We do the initialization on the first channel allocation. * We have to wait because of the interrupt handler initialization * which can't be done successfully during board set up. */ @@ -964,7 +964,7 @@ u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr) dp->dscr_source1 = dscr->dscr_source1; dp->dscr_cmd1 = dscr->dscr_cmd1; nbytes = dscr->dscr_cmd1; - /* Allow the caller to specifiy if an interrupt is generated */ + /* Allow the caller to specify if an interrupt is generated */ dp->dscr_cmd0 &= ~DSCR_CMD0_IE; dp->dscr_cmd0 |= dscr->dscr_cmd0 | DSCR_CMD0_V; ctp->chan_ptr->ddma_dbell = 0; diff --git a/arch/mips/alchemy/devboards/db1000.c b/arch/mips/alchemy/devboards/db1000.c index bdeed9d13c6fe01c0c804b695af44efd16817f46..433c4b9a9f0a92af20e31f1f16f9be5cde955b12 100644 --- a/arch/mips/alchemy/devboards/db1000.c +++ b/arch/mips/alchemy/devboards/db1000.c @@ -503,15 +503,15 @@ int __init db1000_dev_setup(void) if (board == BCSR_WHOAMI_DB1500) { c0 = AU1500_GPIO2_INT; c1 = AU1500_GPIO5_INT; - d0 = AU1500_GPIO0_INT; - d1 = AU1500_GPIO3_INT; + d0 = 0; /* GPIO number, NOT irq! */ + d1 = 3; /* GPIO number, NOT irq! */ s0 = AU1500_GPIO1_INT; s1 = AU1500_GPIO4_INT; } else if (board == BCSR_WHOAMI_DB1100) { c0 = AU1100_GPIO2_INT; c1 = AU1100_GPIO5_INT; - d0 = AU1100_GPIO0_INT; - d1 = AU1100_GPIO3_INT; + d0 = 0; /* GPIO number, NOT irq! */ + d1 = 3; /* GPIO number, NOT irq! */ s0 = AU1100_GPIO1_INT; s1 = AU1100_GPIO4_INT; @@ -545,15 +545,15 @@ int __init db1000_dev_setup(void) } else if (board == BCSR_WHOAMI_DB1000) { c0 = AU1000_GPIO2_INT; c1 = AU1000_GPIO5_INT; - d0 = AU1000_GPIO0_INT; - d1 = AU1000_GPIO3_INT; + d0 = 0; /* GPIO number, NOT irq! */ + d1 = 3; /* GPIO number, NOT irq! */ s0 = AU1000_GPIO1_INT; s1 = AU1000_GPIO4_INT; platform_add_devices(db1000_devs, ARRAY_SIZE(db1000_devs)); } else if ((board == BCSR_WHOAMI_PB1500) || (board == BCSR_WHOAMI_PB1500R2)) { c0 = AU1500_GPIO203_INT; - d0 = AU1500_GPIO201_INT; + d0 = 1; /* GPIO number, NOT irq! */ s0 = AU1500_GPIO202_INT; twosocks = 0; flashsize = 64; @@ -566,7 +566,7 @@ int __init db1000_dev_setup(void) */ } else if (board == BCSR_WHOAMI_PB1100) { c0 = AU1100_GPIO11_INT; - d0 = AU1100_GPIO9_INT; + d0 = 9; /* GPIO number, NOT irq! */ s0 = AU1100_GPIO10_INT; twosocks = 0; flashsize = 64; @@ -583,7 +583,6 @@ int __init db1000_dev_setup(void) } else return 0; /* unknown board, no further dev setup to do */ - irq_set_irq_type(d0, IRQ_TYPE_EDGE_BOTH); irq_set_irq_type(c0, IRQ_TYPE_LEVEL_LOW); irq_set_irq_type(s0, IRQ_TYPE_LEVEL_LOW); @@ -597,7 +596,6 @@ int __init db1000_dev_setup(void) c0, d0, /*s0*/0, 0, 0); if (twosocks) { - irq_set_irq_type(d1, IRQ_TYPE_EDGE_BOTH); irq_set_irq_type(c1, IRQ_TYPE_LEVEL_LOW); irq_set_irq_type(s1, IRQ_TYPE_LEVEL_LOW); diff --git a/arch/mips/alchemy/devboards/db1550.c b/arch/mips/alchemy/devboards/db1550.c index b518f029f5e7bcd97e62b5017408652fa7a111dd..1c01d6eadb08d89a56519b512cc02cb1a186704b 100644 --- a/arch/mips/alchemy/devboards/db1550.c +++ b/arch/mips/alchemy/devboards/db1550.c @@ -514,7 +514,7 @@ static void __init db1550_devices(void) AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1, AU1000_PCMCIA_IO_PHYS_ADDR, AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1, - AU1550_GPIO3_INT, AU1550_GPIO0_INT, + AU1550_GPIO3_INT, 0, /*AU1550_GPIO21_INT*/0, 0, 0); db1x_register_pcmcia_socket( @@ -524,7 +524,7 @@ static void __init db1550_devices(void) AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004400000 - 1, AU1000_PCMCIA_IO_PHYS_ADDR + 0x004000000, AU1000_PCMCIA_IO_PHYS_ADDR + 0x004010000 - 1, - AU1550_GPIO5_INT, AU1550_GPIO1_INT, + AU1550_GPIO5_INT, 1, /*AU1550_GPIO22_INT*/0, 0, 1); platform_device_register(&db1550_nand_dev); diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c index eb5117ced95ac0a49dc92a3caa1cc32b56b19022..618dfd735eede5e771061d6a42943150d19b93a6 100644 --- a/arch/mips/ath79/clock.c +++ b/arch/mips/ath79/clock.c @@ -26,8 +26,7 @@ #include "common.h" #define AR71XX_BASE_FREQ 40000000 -#define AR724X_BASE_FREQ 5000000 -#define AR913X_BASE_FREQ 5000000 +#define AR724X_BASE_FREQ 40000000 static struct clk *clks[3]; static struct clk_onecell_data clk_data = { @@ -103,8 +102,8 @@ static void __init ar724x_clocks_init(void) div = ((pll >> AR724X_PLL_FB_SHIFT) & AR724X_PLL_FB_MASK); freq = div * ref_rate; - div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK); - freq *= div; + div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK) * 2; + freq /= div; cpu_rate = freq; @@ -123,39 +122,6 @@ static void __init ar724x_clocks_init(void) clk_add_alias("uart", NULL, "ahb", NULL); } -static void __init ar913x_clocks_init(void) -{ - unsigned long ref_rate; - unsigned long cpu_rate; - unsigned long ddr_rate; - unsigned long ahb_rate; - u32 pll; - u32 freq; - u32 div; - - ref_rate = AR913X_BASE_FREQ; - pll = ath79_pll_rr(AR913X_PLL_REG_CPU_CONFIG); - - div = ((pll >> AR913X_PLL_FB_SHIFT) & AR913X_PLL_FB_MASK); - freq = div * ref_rate; - - cpu_rate = freq; - - div = ((pll >> AR913X_DDR_DIV_SHIFT) & AR913X_DDR_DIV_MASK) + 1; - ddr_rate = freq / div; - - div = (((pll >> AR913X_AHB_DIV_SHIFT) & AR913X_AHB_DIV_MASK) + 1) * 2; - ahb_rate = cpu_rate / div; - - ath79_add_sys_clkdev("ref", ref_rate); - clks[0] = ath79_add_sys_clkdev("cpu", cpu_rate); - clks[1] = ath79_add_sys_clkdev("ddr", ddr_rate); - clks[2] = ath79_add_sys_clkdev("ahb", ahb_rate); - - clk_add_alias("wdt", NULL, "ahb", NULL); - clk_add_alias("uart", NULL, "ahb", NULL); -} - static void __init ar933x_clocks_init(void) { unsigned long ref_rate; @@ -443,10 +409,8 @@ void __init ath79_clocks_init(void) { if (soc_is_ar71xx()) ar71xx_clocks_init(); - else if (soc_is_ar724x()) + else if (soc_is_ar724x() || soc_is_ar913x()) ar724x_clocks_init(); - else if (soc_is_ar913x()) - ar913x_clocks_init(); else if (soc_is_ar933x()) ar933x_clocks_init(); else if (soc_is_ar934x()) diff --git a/arch/mips/bcm47xx/sprom.c b/arch/mips/bcm47xx/sprom.c index 959c145a0a2c1654d1ac3b58a98db92ef435a713..ca7ad131d05703003ac007a6e76e8b8a358115db 100644 --- a/arch/mips/bcm47xx/sprom.c +++ b/arch/mips/bcm47xx/sprom.c @@ -714,11 +714,11 @@ void bcm47xx_sprom_register_fallbacks(void) { #if defined(CONFIG_BCM47XX_SSB) if (ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom_ssb)) - pr_warn("Failed to registered ssb SPROM handler\n"); + pr_warn("Failed to register ssb SPROM handler\n"); #endif #if defined(CONFIG_BCM47XX_BCMA) if (bcma_arch_register_fallback_sprom(&bcm47xx_get_sprom_bcma)) - pr_warn("Failed to registered bcma SPROM handler\n"); + pr_warn("Failed to register bcma SPROM handler\n"); #endif } diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile index 4eff1ef02eff9abec4ae03d4248f144ef8fa0058..309d2ad67e4d6ee3d7c8c844506b5ae8bd92b24d 100644 --- a/arch/mips/boot/compressed/Makefile +++ b/arch/mips/boot/compressed/Makefile @@ -39,10 +39,11 @@ vmlinuzobjs-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART_PROM) += $(obj)/uart-prom.o vmlinuzobjs-$(CONFIG_MIPS_ALCHEMY) += $(obj)/uart-alchemy.o endif -vmlinuzobjs-$(CONFIG_KERNEL_XZ) += $(obj)/ashldi3.o +vmlinuzobjs-$(CONFIG_KERNEL_XZ) += $(obj)/ashldi3.o $(obj)/bswapsi.o -$(obj)/ashldi3.o: KBUILD_CFLAGS += -I$(srctree)/arch/mips/lib -$(obj)/ashldi3.c: $(srctree)/arch/mips/lib/ashldi3.c +extra-y += ashldi3.c bswapsi.c +$(obj)/ashldi3.o $(obj)/bswapsi.o: KBUILD_CFLAGS += -I$(srctree)/arch/mips/lib +$(obj)/ashldi3.c $(obj)/bswapsi.c: $(obj)/%.c: $(srctree)/arch/mips/lib/%.c $(call cmd,shipped) targets := $(notdir $(vmlinuzobjs-y)) diff --git a/arch/mips/boot/dts/brcm/bcm7435.dtsi b/arch/mips/boot/dts/brcm/bcm7435.dtsi index adb33e3550430de99adb3b2e2c211310fabc65a9..56035e5b70084918a121247ace50f19d3fefdfe9 100644 --- a/arch/mips/boot/dts/brcm/bcm7435.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7435.dtsi @@ -82,7 +82,7 @@ }; gisb-arb@400000 { - compatible = "brcm,bcm7400-gisb-arb"; + compatible = "brcm,bcm7435-gisb-arb"; reg = <0x400000 0xdc>; native-endian; interrupt-parent = <&sun_l2_intc>; diff --git a/arch/mips/boot/dts/qca/ar9132.dtsi b/arch/mips/boot/dts/qca/ar9132.dtsi index 3ad4ba9b12fd6a649eb07b201414f18ba60b83a7..3c2ed9ee5b2f89d3f8b17eef1328b1dbb68702eb 100644 --- a/arch/mips/boot/dts/qca/ar9132.dtsi +++ b/arch/mips/boot/dts/qca/ar9132.dtsi @@ -83,7 +83,7 @@ }; pll: pll-controller@18050000 { - compatible = "qca,ar9132-ppl", + compatible = "qca,ar9132-pll", "qca,ar9130-pll"; reg = <0x18050000 0x20>; diff --git a/arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts b/arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts index e535ee3c26a4e8402a5da1dcc8c0f748205dacca..4f1540e5f963493201406f80e11de3e9d198d4c1 100644 --- a/arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts +++ b/arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts @@ -18,7 +18,7 @@ reg = <0x0 0x2000000>; }; - extosc: oscillator { + extosc: ref { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <40000000>; diff --git a/arch/mips/cavium-octeon/executive/cvmx-interrupt-decodes.c b/arch/mips/cavium-octeon/executive/cvmx-interrupt-decodes.c index e59d1b79f24cd54cd083d2466f091279b83110b8..2f415d9d0f3c18690690f61171df7a968e1b4a52 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-interrupt-decodes.c +++ b/arch/mips/cavium-octeon/executive/cvmx-interrupt-decodes.c @@ -68,7 +68,7 @@ void __cvmx_interrupt_gmxx_rxx_int_en_enable(int index, int block) gmx_rx_int_en.s.pause_drp = 1; /* Skipping gmx_rx_int_en.s.reserved_16_18 */ /*gmx_rx_int_en.s.ifgerr = 1; */ - /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */ + /*gmx_rx_int_en.s.coldet = 1; // Collision detect */ /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */ /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */ /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */ @@ -89,7 +89,7 @@ void __cvmx_interrupt_gmxx_rxx_int_en_enable(int index, int block) /*gmx_rx_int_en.s.phy_spd = 1; */ /*gmx_rx_int_en.s.phy_link = 1; */ /*gmx_rx_int_en.s.ifgerr = 1; */ - /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */ + /*gmx_rx_int_en.s.coldet = 1; // Collision detect */ /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */ /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */ /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */ @@ -112,7 +112,7 @@ void __cvmx_interrupt_gmxx_rxx_int_en_enable(int index, int block) /*gmx_rx_int_en.s.phy_spd = 1; */ /*gmx_rx_int_en.s.phy_link = 1; */ /*gmx_rx_int_en.s.ifgerr = 1; */ - /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */ + /*gmx_rx_int_en.s.coldet = 1; // Collision detect */ /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */ /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */ /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */ @@ -134,7 +134,7 @@ void __cvmx_interrupt_gmxx_rxx_int_en_enable(int index, int block) /*gmx_rx_int_en.s.phy_spd = 1; */ /*gmx_rx_int_en.s.phy_link = 1; */ /*gmx_rx_int_en.s.ifgerr = 1; */ - /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */ + /*gmx_rx_int_en.s.coldet = 1; // Collision detect */ /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */ /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */ /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */ @@ -156,7 +156,7 @@ void __cvmx_interrupt_gmxx_rxx_int_en_enable(int index, int block) /*gmx_rx_int_en.s.phy_spd = 1; */ /*gmx_rx_int_en.s.phy_link = 1; */ /*gmx_rx_int_en.s.ifgerr = 1; */ - /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */ + /*gmx_rx_int_en.s.coldet = 1; // Collision detect */ /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */ /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */ /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */ @@ -179,7 +179,7 @@ void __cvmx_interrupt_gmxx_rxx_int_en_enable(int index, int block) /*gmx_rx_int_en.s.phy_spd = 1; */ /*gmx_rx_int_en.s.phy_link = 1; */ /*gmx_rx_int_en.s.ifgerr = 1; */ - /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */ + /*gmx_rx_int_en.s.coldet = 1; // Collision detect */ /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */ /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */ /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */ @@ -209,7 +209,7 @@ void __cvmx_interrupt_gmxx_rxx_int_en_enable(int index, int block) gmx_rx_int_en.s.pause_drp = 1; /* Skipping gmx_rx_int_en.s.reserved_16_18 */ /*gmx_rx_int_en.s.ifgerr = 1; */ - /*gmx_rx_int_en.s.coldet = 1; // Collsion detect */ + /*gmx_rx_int_en.s.coldet = 1; // Collision detect */ /*gmx_rx_int_en.s.falerr = 1; // False carrier error or extend error after slottime */ /*gmx_rx_int_en.s.rsverr = 1; // RGMII reserved opcodes */ /*gmx_rx_int_en.s.pcterr = 1; // Bad Preamble / Protocol */ diff --git a/arch/mips/cavium-octeon/executive/cvmx-pko.c b/arch/mips/cavium-octeon/executive/cvmx-pko.c index 87be167a7a6ae07ce1b71f574d47471f5781f6ee..676fab50dd2b0e3acf31c3599bfeb2e3e2f08894 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-pko.c +++ b/arch/mips/cavium-octeon/executive/cvmx-pko.c @@ -189,7 +189,7 @@ void cvmx_pko_initialize_global(void) /* * Set the size of the PKO command buffers to an odd number of * 64bit words. This allows the normal two word send to stay - * aligned and never span a comamnd word buffer. + * aligned and never span a command word buffer. */ config.u64 = 0; config.s.pool = CVMX_FPA_OUTPUT_BUFFER_POOL; diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c index b7fa9ae28c3659dbf457aecd7cd17255cd34f5da..42412ba0f3bfd78f1f7f6f6046fd581d4641bc56 100644 --- a/arch/mips/cavium-octeon/smp.c +++ b/arch/mips/cavium-octeon/smp.c @@ -331,7 +331,7 @@ static int octeon_update_boot_vector(unsigned int cpu) } if (!(avail_coremask & (1 << coreid))) { - /* core not available, assume, that catched by simple-executive */ + /* core not available, assume, that caught by simple-executive */ cvmx_write_csr(CVMX_CIU_PP_RST, 1 << coreid); cvmx_write_csr(CVMX_CIU_PP_RST, 0); } diff --git a/arch/mips/configs/ci20_defconfig b/arch/mips/configs/ci20_defconfig index 4e36b6e1869c8b0125ef6a2ddf758d57c9d01fb2..43e0ba24470cd523c39a5ae5465d3ab2fc02f596 100644 --- a/arch/mips/configs/ci20_defconfig +++ b/arch/mips/configs/ci20_defconfig @@ -17,13 +17,12 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_CGROUPS=y +CONFIG_MEMCG=y +CONFIG_CGROUP_SCHED=y CONFIG_CGROUP_FREEZER=y -CONFIG_CGROUP_DEVICE=y CONFIG_CPUSETS=y +CONFIG_CGROUP_DEVICE=y CONFIG_CGROUP_CPUACCT=y -CONFIG_MEMCG=y -CONFIG_MEMCG_KMEM=y -CONFIG_CGROUP_SCHED=y CONFIG_NAMESPACES=y CONFIG_USER_NS=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y @@ -52,6 +51,11 @@ CONFIG_DEVTMPFS=y # CONFIG_ALLOW_DEV_COREDUMP is not set CONFIG_DMA_CMA=y CONFIG_CMA_SIZE_MBYTES=32 +CONFIG_MTD=y +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_JZ4780=y +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_FASTMAP=y CONFIG_NETDEVICES=y # CONFIG_NET_VENDOR_ARC is not set # CONFIG_NET_CADENCE is not set @@ -103,7 +107,7 @@ CONFIG_PROC_KCORE=y # CONFIG_PROC_PAGE_MONITOR is not set CONFIG_TMPFS=y CONFIG_CONFIGFS_FS=y -# CONFIG_MISC_FILESYSTEMS is not set +CONFIG_UBIFS_FS=y # CONFIG_NETWORK_FILESYSTEMS is not set CONFIG_NLS=y CONFIG_NLS_CODEPAGE_437=y diff --git a/arch/mips/dec/int-handler.S b/arch/mips/dec/int-handler.S index 8c6f508e59de144837fc781aae73987e1fe6280f..d7b99180c6e18bd2af23552629f6e96dc5b8704a 100644 --- a/arch/mips/dec/int-handler.S +++ b/arch/mips/dec/int-handler.S @@ -5,7 +5,7 @@ * Written by Ralf Baechle and Andreas Busse, modified for DECstation * support by Paul Antoine and Harald Koerfgen. * - * completly rewritten: + * completely rewritten: * Copyright (C) 1998 Harald Koerfgen * * Rewritten extensively for controller-driven IRQ support diff --git a/arch/mips/fw/arc/memory.c b/arch/mips/fw/arc/memory.c index 5537b94572b2d29f8da730d96bef202744779e32..0d75b5a0bad42c906ba5fb1b4fdad3ce4b14c02e 100644 --- a/arch/mips/fw/arc/memory.c +++ b/arch/mips/fw/arc/memory.c @@ -9,7 +9,7 @@ * PROM library functions for acquiring/using memory descriptors given to us * from the ARCS firmware. This is only used when CONFIG_ARC_MEMORY is set * because on some machines like SGI IP27 the ARC memory configuration data - * completly bogus and alternate easier to use mechanisms are available. + * completely bogus and alternate easier to use mechanisms are available. */ #include #include diff --git a/arch/mips/include/asm/checksum.h b/arch/mips/include/asm/checksum.h index 3ceacde5eb6e4fd3a7b05906ce3fe153b57c8e5c..bce1ce53149a89a574c27fb53adb9de0dcc24389 100644 --- a/arch/mips/include/asm/checksum.h +++ b/arch/mips/include/asm/checksum.h @@ -160,9 +160,9 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) } #define ip_fast_csum ip_fast_csum -static inline __wsum csum_tcpudp_nofold(__be32 saddr, - __be32 daddr, unsigned short len, unsigned short proto, - __wsum sum) +static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, + __u32 len, __u8 proto, + __wsum sum) { __asm__( " .set push # csum_tcpudp_nofold\n" @@ -215,7 +215,7 @@ static inline __sum16 ip_compute_csum(const void *buff, int len) #define _HAVE_ARCH_IPV6_CSUM static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, - __u32 len, unsigned short proto, + __u32 len, __u8 proto, __wsum sum) { __wsum tmp; diff --git a/arch/mips/include/asm/cpu-info.h b/arch/mips/include/asm/cpu-info.h index e7dc785a91ca6c2e6f64c1dc5206a06a59ba80ac..af12c1f9f1a893d8bc266035e6665bf3b36a52a0 100644 --- a/arch/mips/include/asm/cpu-info.h +++ b/arch/mips/include/asm/cpu-info.h @@ -102,7 +102,7 @@ extern void cpu_probe(void); extern void cpu_report(void); extern const char *__cpu_name[]; -#define cpu_name_string() __cpu_name[smp_processor_id()] +#define cpu_name_string() __cpu_name[raw_smp_processor_id()] struct seq_file; struct notifier_block; diff --git a/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h b/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h index cf92fe7339952b43f0a8585bc9a51d351fca0f50..c4873e8594ef126aac8257e92b35e4cb1b3d118b 100644 --- a/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h +++ b/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h @@ -141,7 +141,7 @@ .endm /* - * Do SMP slave processor setup necessary before we can savely execute C code. + * Do SMP slave processor setup necessary before we can safely execute C code. */ .macro smp_slave_setup .endm diff --git a/arch/mips/include/asm/mach-generic/kernel-entry-init.h b/arch/mips/include/asm/mach-generic/kernel-entry-init.h index 13b0751b010a71d7ac5b1c05a225220290d04f33..a229297c880b5e41dfe03a2c63c1519b34b7da58 100644 --- a/arch/mips/include/asm/mach-generic/kernel-entry-init.h +++ b/arch/mips/include/asm/mach-generic/kernel-entry-init.h @@ -16,7 +16,7 @@ .endm /* - * Do SMP slave processor setup necessary before we can savely execute C code. + * Do SMP slave processor setup necessary before we can safely execute C code. */ .macro smp_slave_setup .endm diff --git a/arch/mips/include/asm/mach-ip27/irq.h b/arch/mips/include/asm/mach-ip27/irq.h index cf4384bfa8460d64be78b787940391b083238ea5..b0b7261ff3ad26fa8c98bfcff1ae1c868f64c5ab 100644 --- a/arch/mips/include/asm/mach-ip27/irq.h +++ b/arch/mips/include/asm/mach-ip27/irq.h @@ -11,7 +11,7 @@ #define __ASM_MACH_IP27_IRQ_H /* - * A hardwired interrupt number is completly stupid for this system - a + * A hardwired interrupt number is completely stupid for this system - a * large configuration might have thousands if not tenthousands of * interrupts. */ diff --git a/arch/mips/include/asm/mach-ip27/kernel-entry-init.h b/arch/mips/include/asm/mach-ip27/kernel-entry-init.h index b087cb83da3a51fb88af8db48e51f4feb85918b1..f992c1db876b5e7b06985b80f6d3b1289b953399 100644 --- a/arch/mips/include/asm/mach-ip27/kernel-entry-init.h +++ b/arch/mips/include/asm/mach-ip27/kernel-entry-init.h @@ -81,7 +81,7 @@ .endm /* - * Do SMP slave processor setup necessary before we can savely execute C code. + * Do SMP slave processor setup necessary before we can safely execute C code. */ .macro smp_slave_setup GET_NASID_ASM t1 diff --git a/arch/mips/include/asm/mach-jz4740/gpio.h b/arch/mips/include/asm/mach-jz4740/gpio.h index bf8c3e1860e713cb548f18bdb86c0eb822229b4c..7c7708a23baa61e0a19df05d31a6a518817a4ab9 100644 --- a/arch/mips/include/asm/mach-jz4740/gpio.h +++ b/arch/mips/include/asm/mach-jz4740/gpio.h @@ -27,7 +27,7 @@ enum jz_gpio_function { /* Usually a driver for a SoC component has to request several gpio pins and - configure them as funcion pins. + configure them as function pins. jz_gpio_bulk_request can be used to ease this process. Usually one would do something like: diff --git a/arch/mips/include/asm/mach-jz4740/jz4740_nand.h b/arch/mips/include/asm/mach-jz4740/jz4740_nand.h index 79cff26d8b36f16cb333d9af2e56383db72b4222..398733e3e2cf65006541cf5c3eff6c68b06b0eb0 100644 --- a/arch/mips/include/asm/mach-jz4740/jz4740_nand.h +++ b/arch/mips/include/asm/mach-jz4740/jz4740_nand.h @@ -25,8 +25,6 @@ struct jz_nand_platform_data { int num_partitions; struct mtd_partition *partitions; - struct nand_ecclayout *ecc_layout; - unsigned char banks[JZ_NAND_NUM_BANKS]; void (*ident_callback)(struct platform_device *, struct nand_chip *, diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h index b196825a1de9ca1f3b60df1059978569c93ad8c2..d4635391c36a28240c9fbdd900d26fdf309e0ca9 100644 --- a/arch/mips/include/asm/mips-cm.h +++ b/arch/mips/include/asm/mips-cm.h @@ -28,7 +28,7 @@ extern void __iomem *mips_cm_l2sync_base; * This function returns the physical base address of the Coherence Manager * global control block, or 0 if no Coherence Manager is present. It provides * a default implementation which reads the CMGCRBase register where available, - * and may be overriden by platforms which determine this address in a + * and may be overridden by platforms which determine this address in a * different way by defining a function with the same prototype except for the * name mips_cm_phys_base (without underscores). */ diff --git a/arch/mips/include/asm/mips-r2-to-r6-emul.h b/arch/mips/include/asm/mips-r2-to-r6-emul.h index 1f6ea8352ca90408772f0a7f72f7e213bece28ba..20621e1ca2383a5a1d4154ad99e6cf16ffb9b55c 100644 --- a/arch/mips/include/asm/mips-r2-to-r6-emul.h +++ b/arch/mips/include/asm/mips-r2-to-r6-emul.h @@ -79,7 +79,7 @@ struct r2_decoder_table { }; -extern void do_trap_or_bp(struct pt_regs *regs, unsigned int code, +extern void do_trap_or_bp(struct pt_regs *regs, unsigned int code, int si_code, const char *str); #ifndef CONFIG_MIPSR2_TO_R6_EMULATOR diff --git a/arch/mips/include/asm/octeon/cvmx-config.h b/arch/mips/include/asm/octeon/cvmx-config.h index f7dd17d0dc22d600c7f42282d42d12ed4cf3b19d..f4f1996e0fac35d193374958683bbc9908685edf 100644 --- a/arch/mips/include/asm/octeon/cvmx-config.h +++ b/arch/mips/include/asm/octeon/cvmx-config.h @@ -33,7 +33,7 @@ /* Packet buffers */ #define CVMX_FPA_PACKET_POOL (0) #define CVMX_FPA_PACKET_POOL_SIZE CVMX_FPA_POOL_0_SIZE -/* Work queue entrys */ +/* Work queue entries */ #define CVMX_FPA_WQE_POOL (1) #define CVMX_FPA_WQE_POOL_SIZE CVMX_FPA_POOL_1_SIZE /* PKO queue command buffers */ diff --git a/arch/mips/include/asm/octeon/cvmx.h b/arch/mips/include/asm/octeon/cvmx.h index 774bb45834cb0714d582df55fb0bf64e1c2ceea0..3e982e0c397e8a5d77d32c592d621bd1c31650c3 100644 --- a/arch/mips/include/asm/octeon/cvmx.h +++ b/arch/mips/include/asm/octeon/cvmx.h @@ -189,7 +189,7 @@ static inline uint64_t cvmx_ptr_to_phys(void *ptr) static inline void *cvmx_phys_to_ptr(uint64_t physical_address) { if (sizeof(void *) == 8) { - /* Just set the top bit, avoiding any TLB uglyness */ + /* Just set the top bit, avoiding any TLB ugliness */ return CASTPTR(void, CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS, physical_address)); @@ -275,6 +275,11 @@ static inline void cvmx_write_csr(uint64_t csr_addr, uint64_t val) cvmx_read64(CVMX_MIO_BOOT_BIST_STAT); } +static inline void cvmx_writeq_csr(void __iomem *csr_addr, uint64_t val) +{ + cvmx_write_csr((__force uint64_t)csr_addr, val); +} + static inline void cvmx_write_io(uint64_t io_addr, uint64_t val) { cvmx_write64(io_addr, val); @@ -287,6 +292,10 @@ static inline uint64_t cvmx_read_csr(uint64_t csr_addr) return val; } +static inline uint64_t cvmx_readq_csr(void __iomem *csr_addr) +{ + return cvmx_read_csr((__force uint64_t) csr_addr); +} static inline void cvmx_send_single(uint64_t data) { diff --git a/arch/mips/include/asm/pci/bridge.h b/arch/mips/include/asm/pci/bridge.h index 8d7a63b52ac73bacfd14fcddf838e6cb2758ff6b..3206245d1ed64d94693a743ca4e14976dcb3646a 100644 --- a/arch/mips/include/asm/pci/bridge.h +++ b/arch/mips/include/asm/pci/bridge.h @@ -269,16 +269,16 @@ typedef struct bridge_err_cmdword_s { union { u32 cmd_word; struct { - u32 didn:4, /* Destination ID */ - sidn:4, /* Source ID */ - pactyp:4, /* Packet type */ - tnum:5, /* Trans Number */ - coh:1, /* Coh Transacti */ - ds:2, /* Data size */ - gbr:1, /* GBR enable */ - vbpm:1, /* VBPM message */ + u32 didn:4, /* Destination ID */ + sidn:4, /* Source ID */ + pactyp:4, /* Packet type */ + tnum:5, /* Trans Number */ + coh:1, /* Coh Transaction */ + ds:2, /* Data size */ + gbr:1, /* GBR enable */ + vbpm:1, /* VBPM message */ error:1, /* Error occurred */ - barr:1, /* Barrier op */ + barr:1, /* Barrier op */ rsvd:8; } berr_st; } berr_un; diff --git a/arch/mips/include/asm/sgi/hpc3.h b/arch/mips/include/asm/sgi/hpc3.h index 59920b3459420192b3f34185bc4293b763293418..4a9c99050c13964a62716b2f2ac81563bc6908be 100644 --- a/arch/mips/include/asm/sgi/hpc3.h +++ b/arch/mips/include/asm/sgi/hpc3.h @@ -147,7 +147,7 @@ struct hpc3_ethregs { #define HPC3_EPCFG_P1 0x000f /* Cycles to spend in P1 state for PIO */ #define HPC3_EPCFG_P2 0x00f0 /* Cycles to spend in P2 state for PIO */ #define HPC3_EPCFG_P3 0x0f00 /* Cycles to spend in P3 state for PIO */ -#define HPC3_EPCFG_TST 0x1000 /* Diagnistic ram test feature bit */ +#define HPC3_EPCFG_TST 0x1000 /* Diagnostic ram test feature bit */ u32 _unused2[0x1000/4 - 8]; /* padding */ diff --git a/arch/mips/include/asm/sgiarcs.h b/arch/mips/include/asm/sgiarcs.h index 26ddfff28c8e27cd53629e840502a771a9d0c6a5..105a9479ac5f70025f6be3c6cf6212fbb0e30076 100644 --- a/arch/mips/include/asm/sgiarcs.h +++ b/arch/mips/include/asm/sgiarcs.h @@ -144,7 +144,7 @@ struct linux_tinfo { struct linux_vdirent { ULONG namelen; unsigned char attr; - char fname[32]; /* XXX imperical, should be a define */ + char fname[32]; /* XXX empirical, should be a define */ }; /* Other stuff for files. */ @@ -179,7 +179,7 @@ struct linux_finfo { enum linux_devtypes dtype; unsigned long namelen; unsigned char attr; - char name[32]; /* XXX imperical, should be define */ + char name[32]; /* XXX empirical, should be define */ }; /* This describes the vector containing function pointers to the ARC diff --git a/arch/mips/include/asm/sn/ioc3.h b/arch/mips/include/asm/sn/ioc3.h index e33f0363235b77e57229846f34fe398078c6f7ca..feb385180f8742f0682149e13fcebfaa762e174b 100644 --- a/arch/mips/include/asm/sn/ioc3.h +++ b/arch/mips/include/asm/sn/ioc3.h @@ -355,7 +355,7 @@ struct ioc3_etxd { #define SSCR_PAUSE_STATE 0x40000000 /* sets when PAUSE takes effect */ #define SSCR_RESET 0x80000000 /* reset DMA channels */ -/* all producer/comsumer pointers are the same bitfield */ +/* all producer/consumer pointers are the same bitfield */ #define PROD_CONS_PTR_4K 0x00000ff8 /* for 4K buffers */ #define PROD_CONS_PTR_1K 0x000003f8 /* for 1K buffers */ #define PROD_CONS_PTR_OFF 3 diff --git a/arch/mips/include/asm/sn/sn0/hubio.h b/arch/mips/include/asm/sn/sn0/hubio.h index 5998b13e976498c42b32c34850115bb7388f533a..57ece90f8cf1edef77b2d58f892ae809a8ff6b48 100644 --- a/arch/mips/include/asm/sn/sn0/hubio.h +++ b/arch/mips/include/asm/sn/sn0/hubio.h @@ -628,7 +628,7 @@ typedef union h1_icrbb_u { /* * Values for field imsgtype */ -#define IIO_ICRB_IMSGT_XTALK 0 /* Incoming Meessage from Xtalk */ +#define IIO_ICRB_IMSGT_XTALK 0 /* Incoming Message from Xtalk */ #define IIO_ICRB_IMSGT_BTE 1 /* Incoming message from BTE */ #define IIO_ICRB_IMSGT_SN0NET 2 /* Incoming message from SN0 net */ #define IIO_ICRB_IMSGT_CRB 3 /* Incoming message from CRB ??? */ diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h index 095ecafe6bd3525444c27812937e2d085bf69b2a..7f109d4f64a4074d294f006def272008e8b71112 100644 --- a/arch/mips/include/asm/uaccess.h +++ b/arch/mips/include/asm/uaccess.h @@ -95,7 +95,7 @@ static inline bool eva_kernel_access(void) } /* - * Is a address valid? This does a straighforward calculation rather + * Is a address valid? This does a straightforward calculation rather * than tests. * * Address valid if: diff --git a/arch/mips/include/uapi/asm/siginfo.h b/arch/mips/include/uapi/asm/siginfo.h index 2cb7fdead5702a5c8b5f0522e0c9f3e8e4ee96ba..cc49dc240d67183f0cedb5408892ea9fdb645891 100644 --- a/arch/mips/include/uapi/asm/siginfo.h +++ b/arch/mips/include/uapi/asm/siginfo.h @@ -86,10 +86,15 @@ typedef struct siginfo { int _trapno; /* TRAP # which caused the signal */ #endif short _addr_lsb; - struct { - void __user *_lower; - void __user *_upper; - } _addr_bnd; + union { + /* used when si_code=SEGV_BNDERR */ + struct { + void __user *_lower; + void __user *_upper; + } _addr_bnd; + /* used when si_code=SEGV_PKUERR */ + __u32 _pkey; + }; } _sigfault; /* SIGPOLL, SIGXFSZ (To do ...) */ diff --git a/arch/mips/include/uapi/asm/socket.h b/arch/mips/include/uapi/asm/socket.h index 5910fe294e932d66f94cbff106ab1d4ce470c55b..2027240aafbb8432f0cc67148b70ae57f48ed2a6 100644 --- a/arch/mips/include/uapi/asm/socket.h +++ b/arch/mips/include/uapi/asm/socket.h @@ -106,4 +106,6 @@ #define SO_ATTACH_REUSEPORT_CBPF 51 #define SO_ATTACH_REUSEPORT_EBPF 52 +#define SO_CNX_ADVICE 53 + #endif /* _UAPI_ASM_SOCKET_H */ diff --git a/arch/mips/include/uapi/asm/unistd.h b/arch/mips/include/uapi/asm/unistd.h index 3129795de940b0c370c3eb6926ade8b11f878f91..24ad815c7f38d463f45e90e38417649c91a08f68 100644 --- a/arch/mips/include/uapi/asm/unistd.h +++ b/arch/mips/include/uapi/asm/unistd.h @@ -381,16 +381,18 @@ #define __NR_membarrier (__NR_Linux + 358) #define __NR_mlock2 (__NR_Linux + 359) #define __NR_copy_file_range (__NR_Linux + 360) +#define __NR_preadv2 (__NR_Linux + 361) +#define __NR_pwritev2 (__NR_Linux + 362) /* * Offset of the last Linux o32 flavoured syscall */ -#define __NR_Linux_syscalls 360 +#define __NR_Linux_syscalls 362 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ #define __NR_O32_Linux 4000 -#define __NR_O32_Linux_syscalls 360 +#define __NR_O32_Linux_syscalls 362 #if _MIPS_SIM == _MIPS_SIM_ABI64 @@ -719,16 +721,18 @@ #define __NR_membarrier (__NR_Linux + 318) #define __NR_mlock2 (__NR_Linux + 319) #define __NR_copy_file_range (__NR_Linux + 320) +#define __NR_preadv2 (__NR_Linux + 321) +#define __NR_pwritev2 (__NR_Linux + 322) /* * Offset of the last Linux 64-bit flavoured syscall */ -#define __NR_Linux_syscalls 320 +#define __NR_Linux_syscalls 322 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ #define __NR_64_Linux 5000 -#define __NR_64_Linux_syscalls 320 +#define __NR_64_Linux_syscalls 322 #if _MIPS_SIM == _MIPS_SIM_NABI32 @@ -1061,15 +1065,17 @@ #define __NR_membarrier (__NR_Linux + 322) #define __NR_mlock2 (__NR_Linux + 323) #define __NR_copy_file_range (__NR_Linux + 324) +#define __NR_preadv2 (__NR_Linux + 325) +#define __NR_pwritev2 (__NR_Linux + 326) /* * Offset of the last N32 flavoured syscall */ -#define __NR_Linux_syscalls 324 +#define __NR_Linux_syscalls 326 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ #define __NR_N32_Linux 6000 -#define __NR_N32_Linux_syscalls 324 +#define __NR_N32_Linux_syscalls 326 #endif /* _UAPI_ASM_UNISTD_H */ diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c index 1448c1f43d4e4ae6657b819a5c8ee238a7332e34..760217bbb2fa5adfc7c96fe352771ba5807bcedb 100644 --- a/arch/mips/kernel/mips-cm.c +++ b/arch/mips/kernel/mips-cm.c @@ -24,7 +24,7 @@ static char *cm2_tr[8] = { "0x04", "cpc", "0x06", "0x07" }; -/* CM3 Tag ECC transation type */ +/* CM3 Tag ECC transaction type */ static char *cm3_tr[16] = { [0x0] = "ReqNoData", [0x1] = "0x1", diff --git a/arch/mips/kernel/mips-r2-to-r6-emul.c b/arch/mips/kernel/mips-r2-to-r6-emul.c index 1f5aac7f9ec3588ec3c48a563b057351b1abfe18..3fff89ae760bac4b2a49ecbcf3877948fd4f85c6 100644 --- a/arch/mips/kernel/mips-r2-to-r6-emul.c +++ b/arch/mips/kernel/mips-r2-to-r6-emul.c @@ -940,42 +940,42 @@ int mipsr2_decoder(struct pt_regs *regs, u32 inst, unsigned long *fcr31) switch (rt) { case tgei_op: if ((long)regs->regs[rs] >= MIPSInst_SIMM(inst)) - do_trap_or_bp(regs, 0, "TGEI"); + do_trap_or_bp(regs, 0, 0, "TGEI"); MIPS_R2_STATS(traps); break; case tgeiu_op: if (regs->regs[rs] >= MIPSInst_UIMM(inst)) - do_trap_or_bp(regs, 0, "TGEIU"); + do_trap_or_bp(regs, 0, 0, "TGEIU"); MIPS_R2_STATS(traps); break; case tlti_op: if ((long)regs->regs[rs] < MIPSInst_SIMM(inst)) - do_trap_or_bp(regs, 0, "TLTI"); + do_trap_or_bp(regs, 0, 0, "TLTI"); MIPS_R2_STATS(traps); break; case tltiu_op: if (regs->regs[rs] < MIPSInst_UIMM(inst)) - do_trap_or_bp(regs, 0, "TLTIU"); + do_trap_or_bp(regs, 0, 0, "TLTIU"); MIPS_R2_STATS(traps); break; case teqi_op: if (regs->regs[rs] == MIPSInst_SIMM(inst)) - do_trap_or_bp(regs, 0, "TEQI"); + do_trap_or_bp(regs, 0, 0, "TEQI"); MIPS_R2_STATS(traps); break; case tnei_op: if (regs->regs[rs] != MIPSInst_SIMM(inst)) - do_trap_or_bp(regs, 0, "TNEI"); + do_trap_or_bp(regs, 0, 0, "TNEI"); MIPS_R2_STATS(traps); diff --git a/arch/mips/kernel/module-rela.c b/arch/mips/kernel/module-rela.c index 2b70723071c322018dbb616a0b158bae4da85d0e..9083d63b765cf9532f3a7e42f892a3b90b50811a 100644 --- a/arch/mips/kernel/module-rela.c +++ b/arch/mips/kernel/module-rela.c @@ -109,9 +109,10 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, struct module *me) { Elf_Mips_Rela *rel = (void *) sechdrs[relsec].sh_addr; + int (*handler)(struct module *me, u32 *location, Elf_Addr v); Elf_Sym *sym; u32 *location; - unsigned int i; + unsigned int i, type; Elf_Addr v; int res; @@ -134,9 +135,21 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, return -ENOENT; } - v = sym->st_value + rel[i].r_addend; + type = ELF_MIPS_R_TYPE(rel[i]); + + if (type < ARRAY_SIZE(reloc_handlers_rela)) + handler = reloc_handlers_rela[type]; + else + handler = NULL; - res = reloc_handlers_rela[ELF_MIPS_R_TYPE(rel[i])](me, location, v); + if (!handler) { + pr_err("%s: Unknown relocation type %u\n", + me->name, type); + return -EINVAL; + } + + v = sym->st_value + rel[i].r_addend; + res = handler(me, location, v); if (res) return res; } diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c index 1833f5171ccda092a74f6ac6a902d30e397fc985..f9b2936d598def20f5f9be027a4b1e1a8af758c4 100644 --- a/arch/mips/kernel/module.c +++ b/arch/mips/kernel/module.c @@ -197,9 +197,10 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *strtab, struct module *me) { Elf_Mips_Rel *rel = (void *) sechdrs[relsec].sh_addr; + int (*handler)(struct module *me, u32 *location, Elf_Addr v); Elf_Sym *sym; u32 *location; - unsigned int i; + unsigned int i, type; Elf_Addr v; int res; @@ -223,9 +224,21 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *strtab, return -ENOENT; } - v = sym->st_value; + type = ELF_MIPS_R_TYPE(rel[i]); + + if (type < ARRAY_SIZE(reloc_handlers_rel)) + handler = reloc_handlers_rel[type]; + else + handler = NULL; - res = reloc_handlers_rel[ELF_MIPS_R_TYPE(rel[i])](me, location, v); + if (!handler) { + pr_err("%s: Unknown relocation type %u\n", + me->name, type); + return -EINVAL; + } + + v = sym->st_value; + res = handler(me, location, v); if (res) return res; } diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c index d7b8dd43147a44e7a400efc4b5e2019e015f82b9..9bc1191b1ab0d32c05d7f7d15e2a6e4995262933 100644 --- a/arch/mips/kernel/perf_event_mipsxx.c +++ b/arch/mips/kernel/perf_event_mipsxx.c @@ -530,7 +530,7 @@ static void mipspmu_enable(struct pmu *pmu) /* * MIPS performance counters can be per-TC. The control registers can - * not be directly accessed accross CPUs. Hence if we want to do global + * not be directly accessed across CPUs. Hence if we want to do global * control, we need cross CPU calls. on_each_cpu() can help us, but we * can not make sure this function is called with interrupts enabled. So * here we pause local counters and then grab a rwlock and leave the diff --git a/arch/mips/kernel/pm-cps.c b/arch/mips/kernel/pm-cps.c index f63a289977cc5f34d5ee52daf61f1065153166a1..fa3f9ebad8f40503ccd6622c8c91c56c6e6188ee 100644 --- a/arch/mips/kernel/pm-cps.c +++ b/arch/mips/kernel/pm-cps.c @@ -472,7 +472,7 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) /* * Disable all but self interventions. The load from COHCTL is defined * by the interAptiv & proAptiv SUMs as ensuring that the operation - * resulting from the preceeding store is complete. + * resulting from the preceding store is complete. */ uasm_i_addiu(&p, t0, zero, 1 << cpu_data[cpu].core); uasm_i_sw(&p, t0, 0, r_pcohctl); diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index eddd5fd6fdfa2ee20f50886b8fbbad9045fd496d..92880cee449e147043f4007204f286b6cd869f88 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -615,7 +615,7 @@ int mips_set_process_fp_mode(struct task_struct *task, unsigned int value) * allows us to only worry about whether an FP mode switch is in * progress when FP is first used in a tasks time slice. Pretty much all * of the mode switch overhead can thus be confined to cases where mode - * switches are actually occuring. That is, to here. However for the + * switches are actually occurring. That is, to here. However for the * thread performing the mode switch it may take a while... */ if (num_online_cpus() > 1) { diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index a56317444bdad94c73325eb1f72d75ff46af1b82..d01fe53a663850bccbea14e30208357df5aa074b 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -596,3 +596,5 @@ EXPORT(sys_call_table) PTR sys_membarrier PTR sys_mlock2 PTR sys_copy_file_range /* 4360 */ + PTR sys_preadv2 + PTR sys_pwritev2 diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index 2b2dc14610d02b58dc704ee63de6520d45ee5156..6b73ecc02597c008c0025a89b4ebf252f73c8a38 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S @@ -434,4 +434,6 @@ EXPORT(sys_call_table) PTR sys_membarrier PTR sys_mlock2 PTR sys_copy_file_range /* 5320 */ + PTR sys_preadv2 + PTR sys_pwritev2 .size sys_call_table,.-sys_call_table diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 2bf5c8593d91daad1a9ee5ffea26eb59318854d9..71f99d5f7a068220c17c9ab4da4cd6419f356b67 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -424,4 +424,6 @@ EXPORT(sysn32_call_table) PTR sys_membarrier PTR sys_mlock2 PTR sys_copy_file_range + PTR compat_sys_preadv2 /* 6325 */ + PTR compat_sys_pwritev2 .size sysn32_call_table,.-sysn32_call_table diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index c5b759e584c758a9d56acf44d7677ff74dc7ecf8..91b43eea2d5a073026ef8f4928d74e41ca0bfb07 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -579,4 +579,6 @@ EXPORT(sys32_call_table) PTR sys_membarrier PTR sys_mlock2 PTR sys_copy_file_range /* 4360 */ + PTR compat_sys_preadv2 + PTR compat_sys_pwritev2 .size sys32_call_table,.-sys32_call_table diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 37708d9af6381f8772c190569b5d64de40c7281d..27cb638f082414048b6655eb04fc36b3b064eec1 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -243,6 +243,18 @@ static int __init mips_smp_ipi_init(void) struct irq_domain *ipidomain; struct device_node *node; + /* + * In some cases like qemu-malta, it is desired to try SMP with + * a single core. Qemu-malta has no GIC, so an attempt to set any IPIs + * would cause a BUG_ON() to be triggered since there's no ipidomain. + * + * Since for a single core system IPIs aren't required really, skip the + * initialisation which should generally keep any such configurations + * happy and only fail hard when trying to truely run SMP. + */ + if (cpumask_weight(cpu_possible_mask) == 1) + return 0; + node = of_irq_find_parent(of_root); ipidomain = irq_find_matching_host(node, DOMAIN_BUS_IPI); diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index bf14da9f3e33b74473d2a23c3b3b388456c4bdc5..ae0c89d23ad7d3e41a068f4178b69fec492e2252 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -871,7 +872,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) exception_exit(prev_state); } -void do_trap_or_bp(struct pt_regs *regs, unsigned int code, +void do_trap_or_bp(struct pt_regs *regs, unsigned int code, int si_code, const char *str) { siginfo_t info = { 0 }; @@ -928,7 +929,13 @@ void do_trap_or_bp(struct pt_regs *regs, unsigned int code, default: scnprintf(b, sizeof(b), "%s instruction in kernel code", str); die_if_kernel(b, regs); - force_sig(SIGTRAP, current); + if (si_code) { + info.si_signo = SIGTRAP; + info.si_code = si_code; + force_sig_info(SIGTRAP, &info, current); + } else { + force_sig(SIGTRAP, current); + } } } @@ -1012,7 +1019,7 @@ asmlinkage void do_bp(struct pt_regs *regs) break; } - do_trap_or_bp(regs, bcode, "Break"); + do_trap_or_bp(regs, bcode, TRAP_BRKPT, "Break"); out: set_fs(seg); @@ -1054,7 +1061,7 @@ asmlinkage void do_tr(struct pt_regs *regs) tcode = (opcode >> 6) & ((1 << 10) - 1); } - do_trap_or_bp(regs, tcode, "Trap"); + do_trap_or_bp(regs, tcode, 0, "Trap"); out: set_fs(seg); @@ -1115,19 +1122,7 @@ asmlinkage void do_ri(struct pt_regs *regs) if (unlikely(compute_return_epc(regs) < 0)) goto out; - if (get_isa16_mode(regs->cp0_epc)) { - unsigned short mmop[2] = { 0 }; - - if (unlikely(get_user(mmop[0], (u16 __user *)epc + 0) < 0)) - status = SIGSEGV; - if (unlikely(get_user(mmop[1], (u16 __user *)epc + 1) < 0)) - status = SIGSEGV; - opcode = mmop[0]; - opcode = (opcode << 16) | mmop[1]; - - if (status < 0) - status = simulate_rdhwr_mm(regs, opcode); - } else { + if (!get_isa16_mode(regs->cp0_epc)) { if (unlikely(get_user(opcode, epc) < 0)) status = SIGSEGV; @@ -1142,6 +1137,18 @@ asmlinkage void do_ri(struct pt_regs *regs) if (status < 0) status = simulate_fp(regs, opcode, old_epc, old31); + } else if (cpu_has_mmips) { + unsigned short mmop[2] = { 0 }; + + if (unlikely(get_user(mmop[0], (u16 __user *)epc + 0) < 0)) + status = SIGSEGV; + if (unlikely(get_user(mmop[1], (u16 __user *)epc + 1) < 0)) + status = SIGSEGV; + opcode = mmop[0]; + opcode = (opcode << 16) | mmop[1]; + + if (status < 0) + status = simulate_rdhwr_mm(regs, opcode); } if (status < 0) @@ -1492,6 +1499,7 @@ asmlinkage void do_mdmx(struct pt_regs *regs) */ asmlinkage void do_watch(struct pt_regs *regs) { + siginfo_t info = { .si_signo = SIGTRAP, .si_code = TRAP_HWBKPT }; enum ctx_state prev_state; u32 cause; @@ -1512,7 +1520,7 @@ asmlinkage void do_watch(struct pt_regs *regs) if (test_tsk_thread_flag(current, TIF_LOAD_WATCH)) { mips_read_watch_registers(); local_irq_enable(); - force_sig(SIGTRAP, current); + force_sig_info(SIGTRAP, &info, current); } else { mips_clear_watch_registers(); local_irq_enable(); @@ -2214,7 +2222,7 @@ void __init trap_init(void) /* * Copy the generic exception handlers to their final destination. - * This will be overriden later as suitable for a particular + * This will be overridden later as suitable for a particular * configuration. */ set_handler(0x180, &except_vec3_generic, 0x80); diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c index 490cea569d57d0088e50e241f3465c91f07bbcc7..5c62065cbf22d610323331b8d3bd56e6e53fa793 100644 --- a/arch/mips/kernel/unaligned.c +++ b/arch/mips/kernel/unaligned.c @@ -885,7 +885,7 @@ static void emulate_load_store_insn(struct pt_regs *regs, { union mips_instruction insn; unsigned long value; - unsigned int res; + unsigned int res, preempted; unsigned long origpc; unsigned long orig31; void __user *fault_addr = NULL; @@ -1226,27 +1226,36 @@ static void emulate_load_store_insn(struct pt_regs *regs, if (!access_ok(VERIFY_READ, addr, sizeof(*fpr))) goto sigbus; - /* - * Disable preemption to avoid a race between copying - * state from userland, migrating to another CPU and - * updating the hardware vector register below. - */ - preempt_disable(); - - res = __copy_from_user_inatomic(fpr, addr, - sizeof(*fpr)); - if (res) - goto fault; - - /* - * Update the hardware register if it is in use by the - * task in this quantum, in order to avoid having to - * save & restore the whole vector context. - */ - if (test_thread_flag(TIF_USEDMSA)) - write_msa_wr(wd, fpr, df); + do { + /* + * If we have live MSA context keep track of + * whether we get preempted in order to avoid + * the register context we load being clobbered + * by the live context as it's saved during + * preemption. If we don't have live context + * then it can't be saved to clobber the value + * we load. + */ + preempted = test_thread_flag(TIF_USEDMSA); + + res = __copy_from_user_inatomic(fpr, addr, + sizeof(*fpr)); + if (res) + goto fault; - preempt_enable(); + /* + * Update the hardware register if it is in use + * by the task in this quantum, in order to + * avoid having to save & restore the whole + * vector context. + */ + preempt_disable(); + if (test_thread_flag(TIF_USEDMSA)) { + write_msa_wr(wd, fpr, df); + preempted = 0; + } + preempt_enable(); + } while (preempted); break; case msa_st_op: diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 0a93e83cd01479a4abc952e2e41a853dbf4159b9..54d653ee17e1a8f3e2887bf76b1849fcaf73c27d 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S @@ -58,6 +58,7 @@ SECTIONS LOCK_TEXT KPROBES_TEXT IRQENTRY_TEXT + SOFTIRQENTRY_TEXT *(.text.*) *(.fixup) *(.gnu.warning) diff --git a/arch/mips/kvm/tlb.c b/arch/mips/kvm/tlb.c index a08c439462472e3a2e441c1238d62cdee2988ed7..e0e1d0a611fc2bd102d10ad2ecec3ae3f6951551 100644 --- a/arch/mips/kvm/tlb.c +++ b/arch/mips/kvm/tlb.c @@ -632,7 +632,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) kvm_debug("%s: vcpu %p, cpu: %d\n", __func__, vcpu, cpu); - /* Alocate new kernel and user ASIDs if needed */ + /* Allocate new kernel and user ASIDs if needed */ local_irq_save(flags); diff --git a/arch/mips/kvm/trap_emul.c b/arch/mips/kvm/trap_emul.c index ad988000563f264d443b92bd0785e40ba78fe95d..c4038d2a724c0df9746a75c67c358deb3d620071 100644 --- a/arch/mips/kvm/trap_emul.c +++ b/arch/mips/kvm/trap_emul.c @@ -500,7 +500,7 @@ static int kvm_trap_emul_vcpu_setup(struct kvm_vcpu *vcpu) kvm_write_c0_guest_config7(cop0, (MIPS_CONF7_WII) | (1 << 10)); /* - * Setup IntCtl defaults, compatibilty mode for timer interrupts (HW5) + * Setup IntCtl defaults, compatibility mode for timer interrupts (HW5) */ kvm_write_c0_guest_intctl(cop0, 0xFC000000); diff --git a/arch/mips/math-emu/ieee754dp.c b/arch/mips/math-emu/ieee754dp.c index ad3c73436777f0c3103c887827c4547d888f5941..47d26c805eac5b4f91d600eee67075ed980ab250 100644 --- a/arch/mips/math-emu/ieee754dp.c +++ b/arch/mips/math-emu/ieee754dp.c @@ -97,7 +97,7 @@ union ieee754dp ieee754dp_format(int sn, int xe, u64 xm) { assert(xm); /* we don't gen exact zeros (probably should) */ - assert((xm >> (DP_FBITS + 1 + 3)) == 0); /* no execess */ + assert((xm >> (DP_FBITS + 1 + 3)) == 0); /* no excess */ assert(xm & (DP_HIDDEN_BIT << 3)); if (xe < DP_EMIN) { @@ -165,7 +165,7 @@ union ieee754dp ieee754dp_format(int sn, int xe, u64 xm) /* strip grs bits */ xm >>= 3; - assert((xm >> (DP_FBITS + 1)) == 0); /* no execess */ + assert((xm >> (DP_FBITS + 1)) == 0); /* no excess */ assert(xe >= DP_EMIN); if (xe > DP_EMAX) { @@ -198,7 +198,7 @@ union ieee754dp ieee754dp_format(int sn, int xe, u64 xm) ieee754_setcx(IEEE754_UNDERFLOW); return builddp(sn, DP_EMIN - 1 + DP_EBIAS, xm); } else { - assert((xm >> (DP_FBITS + 1)) == 0); /* no execess */ + assert((xm >> (DP_FBITS + 1)) == 0); /* no excess */ assert(xm & DP_HIDDEN_BIT); return builddp(sn, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT); diff --git a/arch/mips/math-emu/ieee754sp.c b/arch/mips/math-emu/ieee754sp.c index def00ffc50fcc7bc4740933215cdf5872940a450..e0b2c450b9634caadcd24d5a25d3f58d4ad2f805 100644 --- a/arch/mips/math-emu/ieee754sp.c +++ b/arch/mips/math-emu/ieee754sp.c @@ -97,7 +97,7 @@ union ieee754sp ieee754sp_format(int sn, int xe, unsigned xm) { assert(xm); /* we don't gen exact zeros (probably should) */ - assert((xm >> (SP_FBITS + 1 + 3)) == 0); /* no execess */ + assert((xm >> (SP_FBITS + 1 + 3)) == 0); /* no excess */ assert(xm & (SP_HIDDEN_BIT << 3)); if (xe < SP_EMIN) { @@ -163,7 +163,7 @@ union ieee754sp ieee754sp_format(int sn, int xe, unsigned xm) /* strip grs bits */ xm >>= 3; - assert((xm >> (SP_FBITS + 1)) == 0); /* no execess */ + assert((xm >> (SP_FBITS + 1)) == 0); /* no excess */ assert(xe >= SP_EMIN); if (xe > SP_EMAX) { @@ -196,7 +196,7 @@ union ieee754sp ieee754sp_format(int sn, int xe, unsigned xm) ieee754_setcx(IEEE754_UNDERFLOW); return buildsp(sn, SP_EMIN - 1 + SP_EBIAS, xm); } else { - assert((xm >> (SP_FBITS + 1)) == 0); /* no execess */ + assert((xm >> (SP_FBITS + 1)) == 0); /* no excess */ assert(xm & SP_HIDDEN_BIT); return buildsp(sn, xe + SP_EBIAS, xm & ~SP_HIDDEN_BIT); diff --git a/arch/mips/mm/gup.c b/arch/mips/mm/gup.c index 1afd87c999b0c22f1ab08508a233126b5d6d9f2b..42d124fb6474477c896e4618713e5b6d65d6e8f3 100644 --- a/arch/mips/mm/gup.c +++ b/arch/mips/mm/gup.c @@ -64,7 +64,7 @@ static inline void get_head_page_multiple(struct page *page, int nr) { VM_BUG_ON(page != compound_head(page)); VM_BUG_ON(page_count(page) == 0); - atomic_add(nr, &page->_count); + page_ref_add(page, nr); SetPageReferenced(page); } @@ -286,8 +286,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, start += nr << PAGE_SHIFT; pages += nr; - ret = get_user_pages_unlocked(current, mm, start, - (end - start) >> PAGE_SHIFT, + ret = get_user_pages_unlocked(start, (end - start) >> PAGE_SHIFT, write, 0, pages); /* Have to be a bit careful with return values */ diff --git a/arch/mips/mm/sc-ip22.c b/arch/mips/mm/sc-ip22.c index dc7c5a5214a9e1a9fb06600ba67f55b7054e1425..026cb59a914dbc5f52a2c7200ae85f843081441c 100644 --- a/arch/mips/mm/sc-ip22.c +++ b/arch/mips/mm/sc-ip22.c @@ -158,7 +158,7 @@ static inline int __init indy_sc_probe(void) return 1; } -/* XXX Check with wje if the Indy caches can differenciate between +/* XXX Check with wje if the Indy caches can differentiate between writeback + invalidate and just invalidate. */ static struct bcache_ops indy_sc_ops = { .bc_enable = indy_sc_enable, diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index 5037d5868cef7ef47f1baaa74dc84b7da410c7d5..c17d7627f872bffd148dc093386a3cf8efd4ebd8 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -486,6 +487,10 @@ static void r4k_tlb_configure(void) * be set to fixed-size pages. */ write_c0_pagemask(PM_DEFAULT_MASK); + back_to_back_c0_hazard(); + if (read_c0_pagemask() != PM_DEFAULT_MASK) + panic("MMU doesn't support PAGE_SIZE=0x%lx", PAGE_SIZE); + write_c0_wired(0); if (current_cpu_type() == CPU_R10000 || current_cpu_type() == CPU_R12000 || diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 5a04b6f5c6fb8a2cc52d986f59042ad8cd585850..84c6e3fda84af1f87f025c63709ecd48327fb75e 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -12,7 +12,7 @@ * Copyright (C) 2011 MIPS Technologies, Inc. * * ... and the days got worse and worse and now you see - * I've gone completly out of my mind. + * I've gone completely out of my mind. * * They're coming to take me a away haha * they're coming to take me a away hoho hihi haha diff --git a/arch/mips/pic32/Kconfig b/arch/mips/pic32/Kconfig index fde56a8b85cae1dc201846948bba1ab0024e4769..1985971b98906906923a68582a242678e1c8011f 100644 --- a/arch/mips/pic32/Kconfig +++ b/arch/mips/pic32/Kconfig @@ -15,7 +15,6 @@ config PIC32MZDA select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN select ARCH_REQUIRE_GPIOLIB - select HAVE_MACH_CLKDEV select COMMON_CLK select CLKDEV_LOOKUP select LIBFDT diff --git a/arch/mips/sgi-ip27/ip27-memory.c b/arch/mips/sgi-ip27/ip27-memory.c index 8d0eb264324809b828f1463cd604e044e2e1df42..f1f88291451ec59adb4a5f28f9d19ea336669932 100644 --- a/arch/mips/sgi-ip27/ip27-memory.c +++ b/arch/mips/sgi-ip27/ip27-memory.c @@ -7,7 +7,7 @@ * Copyright (C) 2000 by Silicon Graphics, Inc. * Copyright (C) 2004 by Christoph Hellwig * - * On SGI IP27 the ARC memory configuration data is completly bogus but + * On SGI IP27 the ARC memory configuration data is completely bogus but * alternate easier to use mechanisms are available. */ #include diff --git a/arch/mips/txx9/generic/setup_tx4939.c b/arch/mips/txx9/generic/setup_tx4939.c index e3733cde50d6f5caa82fda165c7971946001a8ed..402ac2ec7e83490358f2a945247630e401acd41b 100644 --- a/arch/mips/txx9/generic/setup_tx4939.c +++ b/arch/mips/txx9/generic/setup_tx4939.c @@ -320,11 +320,12 @@ void __init tx4939_sio_init(unsigned int sclk, unsigned int cts_mask) #if IS_ENABLED(CONFIG_TC35815) static u32 tx4939_get_eth_speed(struct net_device *dev) { - struct ethtool_cmd cmd; - if (__ethtool_get_settings(dev, &cmd)) + struct ethtool_link_ksettings cmd; + + if (__ethtool_get_link_ksettings(dev, &cmd)) return 100; /* default 100Mbps */ - return ethtool_cmd_speed(&cmd); + return cmd.base.speed; } static int tx4939_netdev_event(struct notifier_block *this, diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig index 10607f0d2bcd1526f01d95cee5c519c1916224b1..06ddb5501ab1365ea6a52850cb9e203a9b5b2923 100644 --- a/arch/mn10300/Kconfig +++ b/arch/mn10300/Kconfig @@ -53,6 +53,7 @@ config GENERIC_HWEIGHT config GENERIC_BUG def_bool y + depends on BUG config QUICKLIST def_bool y diff --git a/arch/mn10300/include/asm/checksum.h b/arch/mn10300/include/asm/checksum.h index 9fb2a8d8826a78d5e507325da5cde69d412349ac..c80df5b504acabc57c2bd5529e613f54cb4c7942 100644 --- a/arch/mn10300/include/asm/checksum.h +++ b/arch/mn10300/include/asm/checksum.h @@ -37,16 +37,11 @@ static inline __sum16 csum_fold(__wsum sum) return (~sum) >> 16; } -static inline __wsum csum_tcpudp_nofold(unsigned long saddr, - unsigned long daddr, - unsigned short len, - unsigned short proto, +static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, + __u32 len, __u8 proto, __wsum sum) { - __wsum tmp; - - tmp = (__wsum) ntohs(len) << 16; - tmp += (__wsum) proto << 8; + __wsum tmp = (__wsum)((len + proto) << 8); asm( " add %1,%0 \n" @@ -64,10 +59,8 @@ static inline __wsum csum_tcpudp_nofold(unsigned long saddr, * computes the checksum of the TCP/UDP pseudo-header * returns a 16-bit checksum, already complemented */ -static inline __sum16 csum_tcpudp_magic(unsigned long saddr, - unsigned long daddr, - unsigned short len, - unsigned short proto, +static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, + __u32 len, __u8 proto, __wsum sum) { return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum)); diff --git a/arch/mn10300/include/uapi/asm/socket.h b/arch/mn10300/include/uapi/asm/socket.h index 58b1aa01ab9f140c7e910215aa727691bf7d5bcd..5129f23a9ee1008fc4b7203d2af689b0bc915a46 100644 --- a/arch/mn10300/include/uapi/asm/socket.h +++ b/arch/mn10300/include/uapi/asm/socket.h @@ -88,4 +88,6 @@ #define SO_ATTACH_REUSEPORT_CBPF 51 #define SO_ATTACH_REUSEPORT_EBPF 52 +#define SO_CNX_ADVICE 53 + #endif /* _ASM_SOCKET_H */ diff --git a/arch/mn10300/kernel/fpu-nofpu.c b/arch/mn10300/kernel/fpu-nofpu.c index 31c765b92c5dc63149088ad1611e0eb89a70a93c..8d0e041aa798ed0e9254b60eb98d1a1a6f5becca 100644 --- a/arch/mn10300/kernel/fpu-nofpu.c +++ b/arch/mn10300/kernel/fpu-nofpu.c @@ -9,6 +9,7 @@ * 2 of the Licence, or (at your option) any later version. */ #include +#include /* * handle an FPU operational exception diff --git a/arch/nios2/include/asm/checksum.h b/arch/nios2/include/asm/checksum.h index 6bc1f0d5df7be0568a1db4e66226a09e0a7f65b8..703c5ee634218914bd0fb87d7138c6a6c9d61713 100644 --- a/arch/nios2/include/asm/checksum.h +++ b/arch/nios2/include/asm/checksum.h @@ -45,8 +45,7 @@ static inline __sum16 csum_fold(__wsum sum) */ #define csum_tcpudp_nofold csum_tcpudp_nofold static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, + __u32 len, __u8 proto, __wsum sum) { __asm__ __volatile__( @@ -60,7 +59,7 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, "cmpltu r8, %0, %3\n" "add %0, %0, r8\n" /* add carry */ : "=r" (sum), "=r" (saddr) - : "r" (daddr), "r" ((ntohs(len) << 16) + (proto * 256)), + : "r" (daddr), "r" ((len + proto) << 8), "0" (sum), "1" (saddr) : "r8"); @@ -69,8 +68,8 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, } static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, __wsum sum) + __u32 len, __u8 proto, + __wsum sum) { return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum)); } diff --git a/arch/nios2/kernel/prom.c b/arch/nios2/kernel/prom.c index 718dd197909faf863069bbb085a79b7987ee26af..367c5426157ba14dfe8799664c3f11dd6eb9c8a2 100644 --- a/arch/nios2/kernel/prom.c +++ b/arch/nios2/kernel/prom.c @@ -97,8 +97,7 @@ static int __init early_init_dt_scan_serial(unsigned long node, return 0; #endif - *addr64 = fdt_translate_address((const void *)initial_boot_params, - node); + *addr64 = of_flat_dt_translate_address(node); return *addr64 == OF_BAD_ADDR ? 0 : 1; } diff --git a/arch/nios2/kernel/vmlinux.lds.S b/arch/nios2/kernel/vmlinux.lds.S index 326fab40a9de0c05cff1649b2080c4e8e493a2f4..e23e89539967713c301c4f452f802f878bb7562f 100644 --- a/arch/nios2/kernel/vmlinux.lds.S +++ b/arch/nios2/kernel/vmlinux.lds.S @@ -39,6 +39,7 @@ SECTIONS SCHED_TEXT LOCK_TEXT IRQENTRY_TEXT + SOFTIRQENTRY_TEXT KPROBES_TEXT } =0 _etext = .; diff --git a/arch/openrisc/include/asm/page.h b/arch/openrisc/include/asm/page.h index 108906f991d6766c7ec9d9dd94e3ab3da1aec07c..e613d367303412a09e2b298d2a58801f13cb6c1c 100644 --- a/arch/openrisc/include/asm/page.h +++ b/arch/openrisc/include/asm/page.h @@ -40,9 +40,6 @@ #ifndef __ASSEMBLY__ -#define get_user_page(vaddr) __get_free_page(GFP_KERNEL) -#define free_user_page(page, addr) free_page(addr) - #define clear_page(page) memset((page), 0, PAGE_SIZE) #define copy_page(to, from) memcpy((to), (from), PAGE_SIZE) diff --git a/arch/openrisc/kernel/vmlinux.lds.S b/arch/openrisc/kernel/vmlinux.lds.S index 2d69a853b742e9ff3d7608b2b5ecfda1cf780941..d936de4c07cadd73f00a0700a3781243b8f7852c 100644 --- a/arch/openrisc/kernel/vmlinux.lds.S +++ b/arch/openrisc/kernel/vmlinux.lds.S @@ -50,6 +50,7 @@ SECTIONS LOCK_TEXT KPROBES_TEXT IRQENTRY_TEXT + SOFTIRQENTRY_TEXT *(.fixup) *(.text.__*) _etext = .; diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 14f655cf542e1eff76c5584b0a603d40a330e333..bd3c873951a1ad2e890a77a57172d2ea7aedee71 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -11,6 +11,7 @@ config PARISC select RTC_DRV_GENERIC select INIT_ALL_POSSIBLE select BUG + select BUILDTIME_EXTABLE_SORT select HAVE_PERF_EVENTS select GENERIC_ATOMIC64 if !64BIT select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE @@ -29,6 +30,7 @@ config PARISC select TTY # Needed for pdc_cons.c select HAVE_DEBUG_STACKOVERFLOW select HAVE_ARCH_AUDITSYSCALL + select HAVE_ARCH_SECCOMP_FILTER select ARCH_NO_COHERENT_DMA_MMAP help diff --git a/arch/parisc/include/asm/assembly.h b/arch/parisc/include/asm/assembly.h index b3069fd83468c5972f98d19f8f17dfa9bfb5e0cf..60e6f07b7e326bc4eb306105dcae477d5aa01f0e 100644 --- a/arch/parisc/include/asm/assembly.h +++ b/arch/parisc/include/asm/assembly.h @@ -523,7 +523,7 @@ */ #define ASM_EXCEPTIONTABLE_ENTRY(fault_addr, except_addr) \ .section __ex_table,"aw" ! \ - ASM_ULONG_INSN fault_addr, except_addr ! \ + .word (fault_addr - .), (except_addr - .) ! \ .previous diff --git a/arch/parisc/include/asm/checksum.h b/arch/parisc/include/asm/checksum.h index c84b2fcb18a95ea1c643a6aea3595f2615721925..60c2c42619c986f98250c3b8a55c6e9ce97d331e 100644 --- a/arch/parisc/include/asm/checksum.h +++ b/arch/parisc/include/asm/checksum.h @@ -85,9 +85,8 @@ static inline __sum16 csum_fold(__wsum csum) } static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum) + __u32 len, __u8 proto, + __wsum sum) { __asm__( " add %1, %0, %0\n" @@ -104,9 +103,8 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, * returns a 16-bit checksum, already complemented */ static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum) + __u32 len, __u8 proto, + __wsum sum) { return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); } @@ -124,7 +122,7 @@ static inline __sum16 ip_compute_csum(const void *buf, int len) #define _HAVE_ARCH_IPV6_CSUM static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, - __u32 len, unsigned short proto, + __u32 len, __u8 proto, __wsum sum) { __asm__ __volatile__ ( diff --git a/arch/parisc/include/asm/compat.h b/arch/parisc/include/asm/compat.h index 0448a2c8eafbc34e8252240171f77173ebdb1dd3..3387307cc33e11f5e6a718a26d8781d3c9d140d2 100644 --- a/arch/parisc/include/asm/compat.h +++ b/arch/parisc/include/asm/compat.h @@ -183,6 +183,13 @@ typedef struct compat_siginfo { int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ int _fd; } _sigpoll; + + /* SIGSYS */ + struct { + compat_uptr_t _call_addr; /* calling user insn */ + int _syscall; /* triggering system call number */ + compat_uint_t _arch; /* AUDIT_ARCH_* of syscall */ + } _sigsys; } _sifields; } compat_siginfo_t; diff --git a/arch/parisc/include/asm/syscall.h b/arch/parisc/include/asm/syscall.h index a5eba95d87feb448178b095c1f9cecc707edd71c..637ce8d6f3752425371acee122b207d8e5af0b50 100644 --- a/arch/parisc/include/asm/syscall.h +++ b/arch/parisc/include/asm/syscall.h @@ -39,6 +39,19 @@ static inline void syscall_get_arguments(struct task_struct *tsk, } } +static inline void syscall_set_return_value(struct task_struct *task, + struct pt_regs *regs, + int error, long val) +{ + regs->gr[28] = error ? error : val; +} + +static inline void syscall_rollback(struct task_struct *task, + struct pt_regs *regs) +{ + /* do nothing */ +} + static inline int syscall_get_arch(void) { int arch = AUDIT_ARCH_PARISC; diff --git a/arch/parisc/include/asm/uaccess.h b/arch/parisc/include/asm/uaccess.h index 0abdd4c607ed9dc22dce8610d8f8d1d016656553..7955e43f3f3f27558da65b100b9c3f64ebe26b02 100644 --- a/arch/parisc/include/asm/uaccess.h +++ b/arch/parisc/include/asm/uaccess.h @@ -44,30 +44,29 @@ static inline long access_ok(int type, const void __user * addr, #define LDD_USER(ptr) BUILD_BUG() #define STD_KERNEL(x, ptr) __put_kernel_asm64(x, ptr) #define STD_USER(x, ptr) __put_user_asm64(x, ptr) -#define ASM_WORD_INSN ".word\t" #else #define LDD_KERNEL(ptr) __get_kernel_asm("ldd", ptr) #define LDD_USER(ptr) __get_user_asm("ldd", ptr) #define STD_KERNEL(x, ptr) __put_kernel_asm("std", x, ptr) #define STD_USER(x, ptr) __put_user_asm("std", x, ptr) -#define ASM_WORD_INSN ".dword\t" #endif /* - * The exception table contains two values: the first is an address - * for an instruction that is allowed to fault, and the second is - * the address to the fixup routine. Even on a 64bit kernel we could - * use a 32bit (unsigned int) address here. + * The exception table contains two values: the first is the relative offset to + * the address of the instruction that is allowed to fault, and the second is + * the relative offset to the address of the fixup routine. Since relative + * addresses are used, 32bit values are sufficient even on 64bit kernel. */ +#define ARCH_HAS_RELATIVE_EXTABLE struct exception_table_entry { - unsigned long insn; /* address of insn that is allowed to fault. */ - unsigned long fixup; /* fixup routine */ + int insn; /* relative address of insn that is allowed to fault. */ + int fixup; /* relative address of fixup routine */ }; #define ASM_EXCEPTIONTABLE_ENTRY( fault_addr, except_addr )\ ".section __ex_table,\"aw\"\n" \ - ASM_WORD_INSN #fault_addr ", " #except_addr "\n\t" \ + ".word (" #fault_addr " - .), (" #except_addr " - .)\n\t" \ ".previous\n" /* @@ -76,6 +75,7 @@ struct exception_table_entry { */ struct exception_data { unsigned long fault_ip; + unsigned long fault_gp; unsigned long fault_space; unsigned long fault_addr; }; diff --git a/arch/parisc/include/uapi/asm/socket.h b/arch/parisc/include/uapi/asm/socket.h index f9cf1223422ce6db81d1f144d1a2d1c709e912ab..9c935d717df94c998dce3dc66ad8eefd1b71d066 100644 --- a/arch/parisc/include/uapi/asm/socket.h +++ b/arch/parisc/include/uapi/asm/socket.h @@ -87,4 +87,6 @@ #define SO_ATTACH_REUSEPORT_CBPF 0x402C #define SO_ATTACH_REUSEPORT_EBPF 0x402D +#define SO_CNX_ADVICE 0x402E + #endif /* _UAPI_ASM_SOCKET_H */ diff --git a/arch/parisc/include/uapi/asm/unistd.h b/arch/parisc/include/uapi/asm/unistd.h index b75039f9211645becb970599deeaafe257b86001..cc0ce92c93c78905c01ce06caaed92da41588db2 100644 --- a/arch/parisc/include/uapi/asm/unistd.h +++ b/arch/parisc/include/uapi/asm/unistd.h @@ -235,8 +235,8 @@ #define __NR_io_getevents (__NR_Linux + 217) #define __NR_io_submit (__NR_Linux + 218) #define __NR_io_cancel (__NR_Linux + 219) -#define __NR_alloc_hugepages (__NR_Linux + 220) -#define __NR_free_hugepages (__NR_Linux + 221) +#define __NR_alloc_hugepages (__NR_Linux + 220) /* not used */ +#define __NR_free_hugepages (__NR_Linux + 221) /* not used */ #define __NR_exit_group (__NR_Linux + 222) #define __NR_lookup_dcookie (__NR_Linux + 223) #define __NR_epoll_create (__NR_Linux + 224) @@ -362,8 +362,10 @@ #define __NR_userfaultfd (__NR_Linux + 344) #define __NR_mlock2 (__NR_Linux + 345) #define __NR_copy_file_range (__NR_Linux + 346) +#define __NR_preadv2 (__NR_Linux + 347) +#define __NR_pwritev2 (__NR_Linux + 348) -#define __NR_Linux_syscalls (__NR_copy_file_range + 1) +#define __NR_Linux_syscalls (__NR_pwritev2 + 1) #define __IGNORE_select /* newselect */ diff --git a/arch/parisc/kernel/asm-offsets.c b/arch/parisc/kernel/asm-offsets.c index d2f62570a7b16d4f4c6321515d980f048cd278f2..78d30d2ea2d8bb24116a7639a3d4bc5f90400058 100644 --- a/arch/parisc/kernel/asm-offsets.c +++ b/arch/parisc/kernel/asm-offsets.c @@ -299,6 +299,7 @@ int main(void) #endif BLANK(); DEFINE(EXCDATA_IP, offsetof(struct exception_data, fault_ip)); + DEFINE(EXCDATA_GP, offsetof(struct exception_data, fault_gp)); DEFINE(EXCDATA_SPACE, offsetof(struct exception_data, fault_space)); DEFINE(EXCDATA_ADDR, offsetof(struct exception_data, fault_addr)); BLANK(); diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index 91c2a39cd5aab98547424685940d2b099369fbf9..67001277256c6a51c1bf67d692d29ef1d480aadf 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c @@ -319,7 +319,7 @@ void flush_dcache_page(struct page *page) if (!mapping) return; - pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT); + pgoff = page->index; /* We have carefully arranged in arch_get_unmapped_area() that * *any* mappings of a file are always congruently mapped (whether diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index b9d75d9fa9ace520e472874b5dcb0f0b0aad440e..a0ecdb4abcc878b3805d7a2d0f845272b1fc372d 100644 --- a/arch/parisc/kernel/module.c +++ b/arch/parisc/kernel/module.c @@ -660,6 +660,10 @@ int apply_relocate_add(Elf_Shdr *sechdrs, } *loc = (*loc & ~0x3ff1ffd) | reassemble_22(val); break; + case R_PARISC_PCREL32: + /* 32-bit PC relative address */ + *loc = val - dot - 8 + addend; + break; default: printk(KERN_ERR "module %s: Unknown relocation: %u\n", @@ -788,6 +792,10 @@ int apply_relocate_add(Elf_Shdr *sechdrs, CHECK_RELOC(val, 22); *loc = (*loc & ~0x3ff1ffd) | reassemble_22(val); break; + case R_PARISC_PCREL32: + /* 32-bit PC relative address */ + *loc = val - dot - 8 + addend; + break; case R_PARISC_DIR64: /* 64-bit effective address */ *loc64 = val + addend; diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c index 568b2c61ea0208de80bcd1f5fdc54f7aafa95a30..3cad8aadc69e7a1159c829a7e5e5cea9f6a1297b 100644 --- a/arch/parisc/kernel/parisc_ksyms.c +++ b/arch/parisc/kernel/parisc_ksyms.c @@ -47,11 +47,11 @@ EXPORT_SYMBOL(__cmpxchg_u64); EXPORT_SYMBOL(lclear_user); EXPORT_SYMBOL(lstrnlen_user); -/* Global fixups */ -extern void fixup_get_user_skip_1(void); -extern void fixup_get_user_skip_2(void); -extern void fixup_put_user_skip_1(void); -extern void fixup_put_user_skip_2(void); +/* Global fixups - defined as int to avoid creation of function pointers */ +extern int fixup_get_user_skip_1; +extern int fixup_get_user_skip_2; +extern int fixup_put_user_skip_1; +extern int fixup_put_user_skip_2; EXPORT_SYMBOL(fixup_get_user_skip_1); EXPORT_SYMBOL(fixup_get_user_skip_2); EXPORT_SYMBOL(fixup_put_user_skip_1); diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c index ce0b2b4075c704f9ee2006c263b1ba1cf3e9afd1..8fb81a3915990dc741324b560986895f5025a9d5 100644 --- a/arch/parisc/kernel/ptrace.c +++ b/arch/parisc/kernel/ptrace.c @@ -270,7 +270,8 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, long do_syscall_trace_enter(struct pt_regs *regs) { /* Do the secure computing check first. */ - secure_computing_strict(regs->gr[20]); + if (secure_computing() == -1) + return -1; if (test_thread_flag(TIF_SYSCALL_TRACE) && tracehook_report_syscall_entry(regs)) { @@ -296,7 +297,11 @@ long do_syscall_trace_enter(struct pt_regs *regs) regs->gr[23] & 0xffffffff); out: - return regs->gr[20]; + /* + * Sign extend the syscall number to 64bit since it may have been + * modified by a compat ptrace call + */ + return (int) ((u32) regs->gr[20]); } void do_syscall_trace_exit(struct pt_regs *regs) diff --git a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c index 984abbee71ca2b7be36cbd94a7b7a1c206191a86..c342b2e17492ebf1884c69334dd01716c1cde086 100644 --- a/arch/parisc/kernel/signal32.c +++ b/arch/parisc/kernel/signal32.c @@ -371,6 +371,11 @@ copy_siginfo_to_user32 (compat_siginfo_t __user *to, const siginfo_t *from) val = (compat_int_t)from->si_int; err |= __put_user(val, &to->si_int); break; + case __SI_SYS >> 16: + err |= __put_user(ptr_to_compat(from->si_call_addr), &to->si_call_addr); + err |= __put_user(from->si_syscall, &to->si_syscall); + err |= __put_user(from->si_arch, &to->si_arch); + break; } } return err; diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index 5aba01ac457ffc5d4823cf09c071f02f00a1d015..0a393a04e89182cba498fa64774dd32177860eb7 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c @@ -368,16 +368,6 @@ asmlinkage long parisc_fallocate(int fd, int mode, u32 offhi, u32 offlo, ((u64)lenhi << 32) | lenlo); } -asmlinkage unsigned long sys_alloc_hugepages(int key, unsigned long addr, unsigned long len, int prot, int flag) -{ - return -ENOMEM; -} - -asmlinkage int sys_free_hugepages(unsigned long addr) -{ - return -EINVAL; -} - long parisc_personality(unsigned long personality) { long err; diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index fbafa0d0e2bf865db726d15f9c4beb4817afe86c..c976ebfe2269db83e7efcc803bcd14e390695e3b 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S @@ -329,6 +329,7 @@ tracesys_next: ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */ LDREG TI_TASK(%r1), %r1 + LDREG TASK_PT_GR28(%r1), %r28 /* Restore return value */ LDREG TASK_PT_GR26(%r1), %r26 /* Restore the users args */ LDREG TASK_PT_GR25(%r1), %r25 LDREG TASK_PT_GR24(%r1), %r24 @@ -342,6 +343,7 @@ tracesys_next: stw %r21, -56(%r30) /* 6th argument */ #endif + cmpib,COND(=),n -1,%r20,tracesys_exit /* seccomp may have returned -1 */ comiclr,>>= __NR_Linux_syscalls, %r20, %r0 b,n .Ltracesys_nosys diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index 585d50fc75c0f9776cf2bca74651387790ab6c22..3cfef1de8061af183820e98ca97467d674a8c463 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S @@ -315,8 +315,8 @@ ENTRY_COMP(io_getevents) ENTRY_COMP(io_submit) ENTRY_SAME(io_cancel) - ENTRY_SAME(alloc_hugepages) /* 220 */ - ENTRY_SAME(free_hugepages) + ENTRY_SAME(ni_syscall) /* 220: was alloc_hugepages */ + ENTRY_SAME(ni_syscall) /* was free_hugepages */ ENTRY_SAME(exit_group) ENTRY_COMP(lookup_dcookie) ENTRY_SAME(epoll_create) @@ -442,6 +442,8 @@ ENTRY_SAME(userfaultfd) ENTRY_SAME(mlock2) /* 345 */ ENTRY_SAME(copy_file_range) + ENTRY_COMP(preadv2) + ENTRY_COMP(pwritev2) .ifne (. - 90b) - (__NR_Linux_syscalls * (91b - 90b)) diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index 553b09855cfd8799acde0df3d9118afcfcf5cbb0..97d6b208e1294d23f52d825ee14ca28694f7876e 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c @@ -284,11 +284,8 @@ void die_if_kernel(char *str, struct pt_regs *regs, long err) if (in_interrupt()) panic("Fatal exception in interrupt"); - if (panic_on_oops) { - printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n"); - ssleep(5); + if (panic_on_oops) panic("Fatal exception"); - } oops_exit(); do_exit(SIGSEGV); @@ -798,6 +795,9 @@ void notrace handle_interruption(int code, struct pt_regs *regs) if (fault_space == 0 && !faulthandler_disabled()) { + /* Clean up and return if in exception table. */ + if (fixup_exception(regs)) + return; pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC); parisc_terminate("Kernel Fault", regs, code, fault_address); } diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S index 308f29081d461b0a9b0a0d8eec0d54e0a1936ff3..f3ead0b6ce461501508c351fdc3246f67f18e218 100644 --- a/arch/parisc/kernel/vmlinux.lds.S +++ b/arch/parisc/kernel/vmlinux.lds.S @@ -72,6 +72,7 @@ SECTIONS LOCK_TEXT KPROBES_TEXT IRQENTRY_TEXT + SOFTIRQENTRY_TEXT *(.text.do_softirq) *(.text.sys_exit) *(.text.do_sigaltstack) diff --git a/arch/parisc/lib/fixup.S b/arch/parisc/lib/fixup.S index 536ef66bb94b5aa8c46800a968514184b5e2d85d..1052b747e011336621c6ca9f7c9eaf78af7af6df 100644 --- a/arch/parisc/lib/fixup.S +++ b/arch/parisc/lib/fixup.S @@ -26,6 +26,7 @@ #ifdef CONFIG_SMP .macro get_fault_ip t1 t2 + loadgp addil LT%__per_cpu_offset,%r27 LDREG RT%__per_cpu_offset(%r1),\t1 /* t2 = smp_processor_id() */ @@ -40,14 +41,19 @@ LDREG RT%exception_data(%r1),\t1 /* t1 = this_cpu_ptr(&exception_data) */ add,l \t1,\t2,\t1 + /* %r27 = t1->fault_gp - restore gp */ + LDREG EXCDATA_GP(\t1), %r27 /* t1 = t1->fault_ip */ LDREG EXCDATA_IP(\t1), \t1 .endm #else .macro get_fault_ip t1 t2 + loadgp /* t1 = this_cpu_ptr(&exception_data) */ addil LT%exception_data,%r27 LDREG RT%exception_data(%r1),\t2 + /* %r27 = t2->fault_gp - restore gp */ + LDREG EXCDATA_GP(\t2), %r27 /* t1 = t2->fault_ip */ LDREG EXCDATA_IP(\t2), \t1 .endm diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c index a762864ec92e9baf9bf2d2016474c21b94e026b8..16dbe81c97c9005df3cbb91045ccb6ed20878930 100644 --- a/arch/parisc/mm/fault.c +++ b/arch/parisc/mm/fault.c @@ -140,21 +140,17 @@ int fixup_exception(struct pt_regs *regs) { const struct exception_table_entry *fix; - /* If we only stored 32bit addresses in the exception table we can drop - * out if we faulted on a 64bit address. */ - if ((sizeof(regs->iaoq[0]) > sizeof(fix->insn)) - && (regs->iaoq[0] >> 32)) - return 0; - fix = search_exception_tables(regs->iaoq[0]); if (fix) { struct exception_data *d; d = this_cpu_ptr(&exception_data); d->fault_ip = regs->iaoq[0]; + d->fault_gp = regs->gr[27]; d->fault_space = regs->isr; d->fault_addr = regs->ior; - regs->iaoq[0] = ((fix->fixup) & ~3); + regs->iaoq[0] = (unsigned long)&fix->fixup + fix->fixup; + regs->iaoq[0] &= ~3; /* * NOTE: In some cases the faulting instruction * may be in the delay slot of a branch. We diff --git a/arch/parisc/mm/hugetlbpage.c b/arch/parisc/mm/hugetlbpage.c index 54ba39262b8239aba1d8e4adc267d211b9d72275..5d6eea925cf4ec979e906b118a682f318a199f01 100644 --- a/arch/parisc/mm/hugetlbpage.c +++ b/arch/parisc/mm/hugetlbpage.c @@ -63,7 +63,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, if (pud) { pmd = pmd_alloc(mm, pud, addr); if (pmd) - pte = pte_alloc_map(mm, NULL, pmd, addr); + pte = pte_alloc_map(mm, pmd, addr); } return pte; } diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index 3c07d6b968772bc6de99bada8d83578ffe172c3d..6b3e7c6ee096efb9c1df64915de09d2a29dcef13 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c @@ -22,7 +22,7 @@ #include #include #include /* for node_online_map */ -#include /* for release_pages and page_cache_release */ +#include /* for release_pages */ #include #include diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 832cc461d0afab57046ef6b7e1b68b471a9ce69c..7cd32c03828605c47f6a43949f3a246bcc4572d1 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -94,6 +94,7 @@ config PPC select OF_RESERVED_MEM select HAVE_FTRACE_MCOUNT_RECORD select HAVE_DYNAMIC_FTRACE + select HAVE_DYNAMIC_FTRACE_WITH_REGS if MPROFILE_KERNEL select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_GRAPH_TRACER select SYSCTL_EXCEPTION_TRACE @@ -158,6 +159,7 @@ config PPC select ARCH_HAS_DEVMEM_IS_ALLOWED select HAVE_ARCH_SECCOMP_FILTER select ARCH_HAS_UBSAN_SANITIZE_ALL + select ARCH_SUPPORTS_DEFERRED_STRUCT_PAGE_INIT config GENERIC_CSUM def_bool CPU_LITTLE_ENDIAN @@ -303,7 +305,7 @@ config ZONE_DMA32 config PGTABLE_LEVELS int default 2 if !PPC64 - default 3 if PPC_64K_PAGES + default 3 if PPC_64K_PAGES && !PPC_BOOK3S_64 default 4 source "init/Kconfig" @@ -373,6 +375,24 @@ config PPC_TRANSACTIONAL_MEM ---help--- Support user-mode Transactional Memory on POWERPC. +config DISABLE_MPROFILE_KERNEL + bool "Disable use of mprofile-kernel for kernel tracing" + depends on PPC64 && CPU_LITTLE_ENDIAN + default y + help + Selecting this options disables use of the mprofile-kernel ABI for + kernel tracing. That will cause options such as live patching + (CONFIG_LIVEPATCH) which depend on CONFIG_DYNAMIC_FTRACE_WITH_REGS to + be disabled also. + + If you have a toolchain which supports mprofile-kernel, then you can + enable this. Otherwise leave it disabled. If you're not sure, say + "N". + +config MPROFILE_KERNEL + depends on PPC64 && CPU_LITTLE_ENDIAN + def_bool !DISABLE_MPROFILE_KERNEL + config IOMMU_HELPER def_bool PPC64 @@ -389,7 +409,7 @@ config SWIOTLB config HOTPLUG_CPU bool "Support for enabling/disabling CPUs" depends on SMP && (PPC_PSERIES || \ - PPC_PMAC || PPC_POWERNV || (PPC_85xx && !PPC_E500MC)) + PPC_PMAC || PPC_POWERNV || FSL_SOC_BOOKE) ---help--- Say Y here to be able to disable and re-enable individual CPUs at runtime on SMP machines. diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 96efd8213c1c153f12aa0a8bb407dec2bac4a22c..709a22a3e824e334be9847d568124ef27f385703 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -133,6 +133,21 @@ else CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=powerpc64 endif +ifdef CONFIG_MPROFILE_KERNEL + ifeq ($(shell $(srctree)/arch/powerpc/scripts/gcc-check-mprofile-kernel.sh $(CC) -I$(srctree)/include -D__KERNEL__),OK) + CC_FLAGS_FTRACE := -pg -mprofile-kernel + KBUILD_CPPFLAGS += -DCC_USING_MPROFILE_KERNEL + else + # If the user asked for mprofile-kernel but the toolchain doesn't + # support it, emit a warning and deliberately break the build later + # with mprofile-kernel-not-supported. We would prefer to make this an + # error right here, but then the user would never be able to run + # oldconfig to change their configuration. + $(warning Compiler does not support mprofile-kernel, set CONFIG_DISABLE_MPROFILE_KERNEL) + CC_FLAGS_FTRACE := -mprofile-kernel-not-supported + endif +endif + CFLAGS-$(CONFIG_CELL_CPU) += $(call cc-option,-mcpu=cell) CFLAGS-$(CONFIG_POWER4_CPU) += $(call cc-option,-mcpu=power4) CFLAGS-$(CONFIG_POWER5_CPU) += $(call cc-option,-mcpu=power5) @@ -310,6 +325,16 @@ corenet64_smp_defconfig: $(call merge_into_defconfig,corenet_basic_defconfig,\ 85xx-64bit 85xx-smp altivec 85xx-hw fsl-emb-nonhw) +PHONY += mpc86xx_defconfig +mpc86xx_defconfig: + $(call merge_into_defconfig,mpc86xx_basic_defconfig,\ + 86xx-hw fsl-emb-nonhw) + +PHONY += mpc86xx_smp_defconfig +mpc86xx_smp_defconfig: + $(call merge_into_defconfig,mpc86xx_basic_defconfig,\ + 86xx-smp 86xx-hw fsl-emb-nonhw) + define archhelp @echo '* zImage - Build default images selected by kernel config' @echo ' zImage.* - Compressed kernel image (arch/$(ARCH)/boot/zImage.*)' diff --git a/arch/powerpc/boot/dts/fsl/b4860qds.dts b/arch/powerpc/boot/dts/fsl/b4860qds.dts index ba8c9bea33acbbb2c3b9f826496bbf834df8fab4..a8bc419959ca64cc99d098d6f5b40ddd5a62e2f4 100644 --- a/arch/powerpc/boot/dts/fsl/b4860qds.dts +++ b/arch/powerpc/boot/dts/fsl/b4860qds.dts @@ -1,7 +1,7 @@ /* * B4860DS Device Tree Source * - * Copyright 2012 Freescale Semiconductor Inc. + * Copyright 2012 - 2015 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -39,12 +39,69 @@ model = "fsl,B4860QDS"; compatible = "fsl,B4860QDS"; + aliases { + phy_sgmii_1e = &phy_sgmii_1e; + phy_sgmii_1f = &phy_sgmii_1f; + phy_xaui_slot1 = &phy_xaui_slot1; + phy_xaui_slot2 = &phy_xaui_slot2; + }; + ifc: localbus@ffe124000 { board-control@3,0 { compatible = "fsl,b4860qds-fpga", "fsl,fpga-qixis"; }; }; + soc@ffe000000 { + fman@400000 { + ethernet@e8000 { + phy-handle = <&phy_sgmii_1e>; + phy-connection-type = "sgmii"; + }; + + ethernet@ea000 { + phy-handle = <&phy_sgmii_1f>; + phy-connection-type = "sgmii"; + }; + + ethernet@f0000 { + phy-handle = <&phy_xaui_slot1>; + phy-connection-type = "xgmii"; + }; + + ethernet@f2000 { + phy-handle = <&phy_xaui_slot2>; + phy-connection-type = "xgmii"; + }; + + mdio@fc000 { + phy_sgmii_1e: ethernet-phy@1e { + reg = <0x1e>; + status = "disabled"; + }; + + phy_sgmii_1f: ethernet-phy@1f { + reg = <0x1f>; + status = "disabled"; + }; + }; + + mdio@fd000 { + phy_xaui_slot1: xaui-phy@slot1 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0x7>; + status = "disabled"; + }; + + phy_xaui_slot2: xaui-phy@slot2 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0x6>; + status = "disabled"; + }; + }; + }; + }; + rio: rapidio@ffe0c0000 { reg = <0xf 0xfe0c0000 0 0x11000>; @@ -55,7 +112,6 @@ ranges = <0 0 0xc 0x30000000 0 0x10000000>; }; }; - }; /include/ "b4860si-post.dtsi" diff --git a/arch/powerpc/boot/dts/fsl/b4qds.dtsi b/arch/powerpc/boot/dts/fsl/b4qds.dtsi index 64557742fb99908faaef9c78ba465fba00099d7e..3785ef826d0734a4cac3c3774d6a07c6ff8f951f 100644 --- a/arch/powerpc/boot/dts/fsl/b4qds.dtsi +++ b/arch/powerpc/boot/dts/fsl/b4qds.dtsi @@ -1,7 +1,7 @@ /* * B4420DS Device Tree Source * - * Copyright 2012 - 2014 Freescale Semiconductor, Inc. + * Copyright 2012 - 2015 Freescale Semiconductor, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -39,6 +39,13 @@ #size-cells = <2>; interrupt-parent = <&mpic>; + aliases { + phy_sgmii_10 = &phy_sgmii_10; + phy_sgmii_11 = &phy_sgmii_11; + phy_sgmii_1c = &phy_sgmii_1c; + phy_sgmii_1d = &phy_sgmii_1d; + }; + ifc: localbus@ffe124000 { reg = <0xf 0xfe124000 0 0x2000>; ranges = <0 0 0xf 0xe8000000 0x08000000 @@ -135,7 +142,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "sst,sst25wf040"; + compatible = "sst,sst25wf040", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <40000000>; /* input clock */ }; @@ -210,6 +217,47 @@ phy_type = "ulpi"; }; + fman@400000 { + ethernet@e0000 { + phy-handle = <&phy_sgmii_10>; + phy-connection-type = "sgmii"; + }; + + ethernet@e2000 { + phy-handle = <&phy_sgmii_11>; + phy-connection-type = "sgmii"; + }; + + ethernet@e4000 { + phy-handle = <&phy_sgmii_1c>; + phy-connection-type = "sgmii"; + }; + + ethernet@e6000 { + phy-handle = <&phy_sgmii_1d>; + phy-connection-type = "sgmii"; + }; + + mdio@fc000 { + phy_sgmii_10: ethernet-phy@10 { + reg = <0x10>; + }; + + phy_sgmii_11: ethernet-phy@11 { + reg = <0x11>; + }; + + phy_sgmii_1c: ethernet-phy@1c { + reg = <0x1c>; + status = "disabled"; + }; + + phy_sgmii_1d: ethernet-phy@1d { + reg = <0x1d>; + status = "disabled"; + }; + }; + }; }; pci0: pcie@ffe200000 { @@ -226,7 +274,6 @@ 0 0x00010000>; }; }; - }; /include/ "b4si-post.dtsi" diff --git a/arch/powerpc/boot/dts/fsl/bsc9131rdb.dtsi b/arch/powerpc/boot/dts/fsl/bsc9131rdb.dtsi index f4d96d277ed5b2b1492bab0db07bca33d33a30db..53f8b956340f43ab02bacad7523c97161ddab3d5 100644 --- a/arch/powerpc/boot/dts/fsl/bsc9131rdb.dtsi +++ b/arch/powerpc/boot/dts/fsl/bsc9131rdb.dtsi @@ -53,7 +53,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spansion,s25sl12801"; + compatible = "spansion,s25sl12801", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <50000000>; diff --git a/arch/powerpc/boot/dts/fsl/bsc9132qds.dtsi b/arch/powerpc/boot/dts/fsl/bsc9132qds.dtsi index 7a13bf2aa439e608b12bb3b70c6f11c7c85bc10d..fead484a8180f7f8496fbb648419fa95f1d40e92 100644 --- a/arch/powerpc/boot/dts/fsl/bsc9132qds.dtsi +++ b/arch/powerpc/boot/dts/fsl/bsc9132qds.dtsi @@ -55,7 +55,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spansion,s25sl12801"; + compatible = "spansion,s25sl12801", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <30000000>; }; diff --git a/arch/powerpc/boot/dts/fsl/c293pcie.dts b/arch/powerpc/boot/dts/fsl/c293pcie.dts index 53ab4db9e79cb2d354fe8e07aa76671498b86204..66709788429da7a103f0e41ae122fbdf21a6cfdf 100644 --- a/arch/powerpc/boot/dts/fsl/c293pcie.dts +++ b/arch/powerpc/boot/dts/fsl/c293pcie.dts @@ -167,7 +167,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spansion,s25sl12801"; + compatible = "spansion,s25sl12801", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <50000000>; diff --git a/arch/powerpc/boot/dts/fsl/gef_ppc9a.dts b/arch/powerpc/boot/dts/fsl/gef_ppc9a.dts new file mode 100644 index 0000000000000000000000000000000000000000..0424fc2bd0e0e9cbc18f6bbbd033d9d11df356c0 --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/gef_ppc9a.dts @@ -0,0 +1,216 @@ +/* + * GE PPC9A Device Tree Source + * + * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. + * + * 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. + * + * Based on: SBS CM6 Device Tree Source + * Copyright 2007 SBS Technologies GmbH & Co. KG + * And: mpc8641_hpcn.dts (MPC8641 HPCN Device Tree Source) + * Copyright 2006 Freescale Semiconductor Inc. + */ + +/* + * Compiled with dtc -I dts -O dtb -o gef_ppc9a.dtb gef_ppc9a.dts + */ + +/include/ "mpc8641si-pre.dtsi" + +/ { + model = "GEF_PPC9A"; + compatible = "gef,ppc9a"; + + memory { + device_type = "memory"; + reg = <0x0 0x40000000>; // set by uboot + }; + + lbc: localbus@fef05000 { + reg = <0xfef05000 0x1000>; + + ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash + 1 0 0xe8000000 0x08000000 // Paged Flash 0 + 2 0 0xe0000000 0x08000000 // Paged Flash 1 + 3 0 0xfc100000 0x00020000 // NVRAM + 4 0 0xfc000000 0x00008000 // FPGA + 5 0 0xfc008000 0x00008000 // AFIX FPGA + 6 0 0xfd000000 0x00800000 // IO FPGA (8-bit) + 7 0 0xfd800000 0x00800000>; // IO FPGA (32-bit) + + /* flash@0,0 is a mirror of part of the memory in flash@1,0 + flash@0,0 { + compatible = "gef,ppc9a-firmware-mirror", "cfi-flash"; + reg = <0x0 0x0 0x1000000>; + bank-width = <4>; + device-width = <2>; + #address-cells = <1>; + #size-cells = <1>; + partition@0 { + label = "firmware"; + reg = <0x0 0x1000000>; + read-only; + }; + }; + */ + + flash@1,0 { + compatible = "gef,ppc9a-paged-flash", "cfi-flash"; + reg = <0x1 0x0 0x8000000>; + bank-width = <4>; + device-width = <2>; + #address-cells = <1>; + #size-cells = <1>; + partition@0 { + label = "user"; + reg = <0x0 0x7800000>; + }; + partition@7800000 { + label = "firmware"; + reg = <0x7800000 0x800000>; + read-only; + }; + }; + + nvram@3,0 { + device_type = "nvram"; + compatible = "simtek,stk14ca8"; + reg = <0x3 0x0 0x20000>; + }; + + fpga@4,0 { + compatible = "gef,ppc9a-fpga-regs"; + reg = <0x4 0x0 0x40>; + }; + + wdt@4,2000 { + compatible = "gef,ppc9a-fpga-wdt", "gef,fpga-wdt-1.00", + "gef,fpga-wdt"; + reg = <0x4 0x2000 0x8>; + interrupts = <0x1a 0x4>; + interrupt-parent = <&gef_pic>; + }; + /* Second watchdog available, driver currently supports one. + wdt@4,2010 { + compatible = "gef,ppc9a-fpga-wdt", "gef,fpga-wdt-1.00", + "gef,fpga-wdt"; + reg = <0x4 0x2010 0x8>; + interrupts = <0x1b 0x4>; + interrupt-parent = <&gef_pic>; + }; + */ + gef_pic: pic@4,4000 { + #interrupt-cells = <1>; + interrupt-controller; + compatible = "gef,ppc9a-fpga-pic", "gef,fpga-pic-1.00"; + reg = <0x4 0x4000 0x20>; + interrupts = <0x8 0x9 0 0>; + + }; + gef_gpio: gpio@7,14000 { + #gpio-cells = <2>; + compatible = "gef,ppc9a-gpio", "gef,sbc610-gpio"; + reg = <0x7 0x14000 0x24>; + gpio-controller; + }; + }; + + soc: soc@fef00000 { + ranges = <0x0 0xfef00000 0x00100000>; + + i2c@3000 { + hwmon@48 { + compatible = "national,lm92"; + reg = <0x48>; + }; + + hwmon@4c { + compatible = "adi,adt7461"; + reg = <0x4c>; + }; + + rtc@51 { + compatible = "epson,rx8581"; + reg = <0x00000051>; + }; + + eti@6b { + compatible = "dallas,ds1682"; + reg = <0x6b>; + }; + }; + + enet0: ethernet@24000 { + tbi-handle = <&tbi0>; + phy-handle = <&phy0>; + phy-connection-type = "gmii"; + }; + + mdio@24520 { + phy0: ethernet-phy@0 { + interrupt-parent = <&gef_pic>; + interrupts = <0x9 0x4>; + reg = <1>; + }; + phy2: ethernet-phy@2 { + interrupt-parent = <&gef_pic>; + interrupts = <0x8 0x4>; + reg = <3>; + }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + enet1: ethernet@26000 { + tbi-handle = <&tbi2>; + phy-handle = <&phy2>; + phy-connection-type = "gmii"; + }; + + mdio@26520 { + tbi2: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + enet2: ethernet@25000 { + status = "disabled"; + }; + + mdio@25520 { + status = "disabled"; + }; + + enet3: ethernet@27000 { + status = "disabled"; + }; + + mdio@27520 { + status = "disabled"; + }; + }; + + pci0: pcie@fef08000 { + reg = <0xfef08000 0x1000>; + ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x40000000 + 0x01000000 0x0 0x00000000 0xfe000000 0x0 0x00400000>; + + pcie@0 { + ranges = <0x02000000 0x0 0x80000000 + 0x02000000 0x0 0x80000000 + 0x0 0x40000000 + + 0x01000000 0x0 0x00000000 + 0x01000000 0x0 0x00000000 + 0x0 0x00400000>; + }; + }; +}; + +/include/ "mpc8641si-post.dtsi" diff --git a/arch/powerpc/boot/dts/fsl/gef_sbc310.dts b/arch/powerpc/boot/dts/fsl/gef_sbc310.dts new file mode 100644 index 0000000000000000000000000000000000000000..84b3d38f880edb37a52fd03d35062de31ce23ac5 --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/gef_sbc310.dts @@ -0,0 +1,260 @@ +/* + * GE SBC310 Device Tree Source + * + * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. + * + * 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. + * + * Based on: SBS CM6 Device Tree Source + * Copyright 2007 SBS Technologies GmbH & Co. KG + * And: mpc8641_hpcn.dts (MPC8641 HPCN Device Tree Source) + * Copyright 2006 Freescale Semiconductor Inc. + */ + +/* + * Compiled with dtc -I dts -O dtb -o gef_sbc310.dtb gef_sbc310.dts + */ + +/include/ "mpc8641si-pre.dtsi" + +/ { + model = "GEF_SBC310"; + compatible = "gef,sbc310"; + + aliases { + pci1 = &pci1; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x40000000>; // set by uboot + }; + + lbc: localbus@fef05000 { + reg = <0xfef05000 0x1000>; + + ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash + 1 0 0xe0000000 0x08000000 // Paged Flash 0 + 2 0 0xe8000000 0x08000000 // Paged Flash 1 + 3 0 0xfc100000 0x00020000 // NVRAM + 4 0 0xfc000000 0x00010000>; // FPGA + + /* flash@0,0 is a mirror of part of the memory in flash@1,0 + flash@0,0 { + compatible = "gef,sbc310-firmware-mirror", "cfi-flash"; + reg = <0x0 0x0 0x01000000>; + bank-width = <2>; + device-width = <2>; + #address-cells = <1>; + #size-cells = <1>; + partition@0 { + label = "firmware"; + reg = <0x0 0x01000000>; + read-only; + }; + }; + */ + + flash@1,0 { + compatible = "gef,sbc310-paged-flash", "cfi-flash"; + reg = <0x1 0x0 0x8000000>; + bank-width = <2>; + device-width = <2>; + #address-cells = <1>; + #size-cells = <1>; + partition@0 { + label = "user"; + reg = <0x0 0x7800000>; + }; + partition@7800000 { + label = "firmware"; + reg = <0x7800000 0x800000>; + read-only; + }; + }; + + nvram@3,0 { + device_type = "nvram"; + compatible = "simtek,stk14ca8"; + reg = <0x3 0x0 0x20000>; + }; + + fpga@4,0 { + compatible = "gef,fpga-regs"; + reg = <0x4 0x0 0x40>; + }; + + wdt@4,2000 { + compatible = "gef,sbc310-fpga-wdt", "gef,fpga-wdt-1.00", + "gef,fpga-wdt"; + reg = <0x4 0x2000 0x8>; + interrupts = <0x1a 0x4>; + interrupt-parent = <&gef_pic>; + }; +/* + wdt@4,2010 { + compatible = "gef,sbc310-fpga-wdt", "gef,fpga-wdt-1.00", + "gef,fpga-wdt"; + reg = <0x4 0x2010 0x8>; + interrupts = <0x1b 0x4>; + interrupt-parent = <&gef_pic>; + }; +*/ + gef_pic: pic@4,4000 { + #interrupt-cells = <1>; + interrupt-controller; + compatible = "gef,sbc310-fpga-pic", "gef,fpga-pic"; + reg = <0x4 0x4000 0x20>; + interrupts = <0x8 0x9 0 0>; + + }; + gef_gpio: gpio@4,8000 { + #gpio-cells = <2>; + compatible = "gef,sbc310-gpio"; + reg = <0x4 0x8000 0x24>; + gpio-controller; + }; + }; + + soc: soc@fef00000 { + ranges = <0x0 0xfef00000 0x00100000>; + + i2c@3000 { + rtc@51 { + compatible = "epson,rx8581"; + reg = <0x00000051>; + }; + }; + + i2c@3100 { + hwmon@48 { + compatible = "national,lm92"; + reg = <0x48>; + }; + + hwmon@4c { + compatible = "adi,adt7461"; + reg = <0x4c>; + }; + + eti@6b { + compatible = "dallas,ds1682"; + reg = <0x6b>; + }; + }; + + enet0: ethernet@24000 { + tbi-handle = <&tbi0>; + phy-handle = <&phy0>; + phy-connection-type = "gmii"; + }; + + mdio@24520 { + phy0: ethernet-phy@0 { + interrupt-parent = <&gef_pic>; + interrupts = <0x9 0x4>; + reg = <1>; + }; + phy2: ethernet-phy@2 { + interrupt-parent = <&gef_pic>; + interrupts = <0x8 0x4>; + reg = <3>; + }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + enet1: ethernet@26000 { + tbi-handle = <&tbi2>; + phy-handle = <&phy2>; + phy-connection-type = "gmii"; + }; + + mdio@26520 { + tbi2: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + enet2: ethernet@25000 { + status = "disabled"; + }; + + mdio@25520 { + status = "disabled"; + }; + + enet3: ethernet@27000 { + status = "disabled"; + }; + + mdio@27520 { + status = "disabled"; + }; + }; + + pci0: pcie@fef08000 { + reg = <0xfef08000 0x1000>; + ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x40000000 + 0x01000000 0x0 0x00000000 0xfe000000 0x0 0x00400000>; + interrupt-map-mask = <0xff00 0x0 0x0 0x7>; + interrupt-map = < + 0x0000 0x0 0x0 0x1 &mpic 0x0 0x2 + 0x0000 0x0 0x0 0x2 &mpic 0x1 0x2 + 0x0000 0x0 0x0 0x3 &mpic 0x2 0x2 + 0x0000 0x0 0x0 0x4 &mpic 0x3 0x2 + >; + + pcie@0 { + ranges = <0x02000000 0x0 0x80000000 + 0x02000000 0x0 0x80000000 + 0x0 0x40000000 + + 0x01000000 0x0 0x00000000 + 0x01000000 0x0 0x00000000 + 0x0 0x00400000>; + }; + }; + + pci1: pcie@fef09000 { + compatible = "fsl,mpc8641-pcie"; + device_type = "pci"; + #size-cells = <2>; + #address-cells = <3>; + reg = <0xfef09000 0x1000>; + bus-range = <0x0 0xff>; + ranges = <0x02000000 0x0 0xc0000000 0xc0000000 0x0 0x20000000 + 0x01000000 0x0 0x00000000 0xfe400000 0x0 0x00400000>; + clock-frequency = <100000000>; + interrupts = <0x19 0x2 0 0>; + interrupt-map-mask = <0xf800 0x0 0x0 0x7>; + interrupt-map = < + 0x0000 0x0 0x0 0x1 &mpic 0x4 0x2 + 0x0000 0x0 0x0 0x2 &mpic 0x5 0x2 + 0x0000 0x0 0x0 0x3 &mpic 0x6 0x2 + 0x0000 0x0 0x0 0x4 &mpic 0x7 0x2 + >; + + pcie@0 { + reg = <0 0 0 0 0>; + #size-cells = <2>; + #address-cells = <3>; + device_type = "pci"; + ranges = <0x02000000 0x0 0xc0000000 + 0x02000000 0x0 0xc0000000 + 0x0 0x20000000 + + 0x01000000 0x0 0x00000000 + 0x01000000 0x0 0x00000000 + 0x0 0x00400000>; + }; + }; +}; + +/include/ "mpc8641si-post.dtsi" diff --git a/arch/powerpc/boot/dts/fsl/gef_sbc610.dts b/arch/powerpc/boot/dts/fsl/gef_sbc610.dts new file mode 100644 index 0000000000000000000000000000000000000000..974446acce23c13b5e67d19636bb251e763444f0 --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/gef_sbc610.dts @@ -0,0 +1,214 @@ +/* + * GE SBC610 Device Tree Source + * + * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. + * + * 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. + * + * Based on: SBS CM6 Device Tree Source + * Copyright 2007 SBS Technologies GmbH & Co. KG + * And: mpc8641_hpcn.dts (MPC8641 HPCN Device Tree Source) + * Copyright 2006 Freescale Semiconductor Inc. + */ + +/* + * Compiled with dtc -I dts -O dtb -o gef_sbc610.dtb gef_sbc610.dts + */ + +/include/ "mpc8641si-pre.dtsi" + +/ { + model = "GEF_SBC610"; + compatible = "gef,sbc610"; + + memory { + device_type = "memory"; + reg = <0x0 0x40000000>; // set by uboot + }; + + lbc: localbus@fef05000 { + reg = <0xfef05000 0x1000>; + + ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash + 1 0 0xe8000000 0x08000000 // Paged Flash 0 + 2 0 0xe0000000 0x08000000 // Paged Flash 1 + 3 0 0xfc100000 0x00020000 // NVRAM + 4 0 0xfc000000 0x00008000 // FPGA + 5 0 0xfc008000 0x00008000 // AFIX FPGA + 6 0 0xfd000000 0x00800000 // IO FPGA (8-bit) + 7 0 0xfd800000 0x00800000>; // IO FPGA (32-bit) + + /* flash@0,0 is a mirror of part of the memory in flash@1,0 + flash@0,0 { + compatible = "gef,sbc610-firmware-mirror", "cfi-flash"; + reg = <0x0 0x0 0x1000000>; + bank-width = <4>; + device-width = <2>; + #address-cells = <1>; + #size-cells = <1>; + partition@0 { + label = "firmware"; + reg = <0x0 0x1000000>; + read-only; + }; + }; + */ + + flash@1,0 { + compatible = "gef,sbc610-paged-flash", "cfi-flash"; + reg = <0x1 0x0 0x8000000>; + bank-width = <4>; + device-width = <2>; + #address-cells = <1>; + #size-cells = <1>; + partition@0 { + label = "user"; + reg = <0x0 0x7800000>; + }; + partition@7800000 { + label = "firmware"; + reg = <0x7800000 0x800000>; + read-only; + }; + }; + + nvram@3,0 { + device_type = "nvram"; + compatible = "simtek,stk14ca8"; + reg = <0x3 0x0 0x20000>; + }; + + fpga@4,0 { + compatible = "gef,fpga-regs"; + reg = <0x4 0x0 0x40>; + }; + + wdt@4,2000 { + compatible = "gef,fpga-wdt"; + reg = <0x4 0x2000 0x8>; + interrupts = <0x1a 0x4>; + interrupt-parent = <&gef_pic>; + }; + /* Second watchdog available, driver currently supports one. + wdt@4,2010 { + compatible = "gef,fpga-wdt"; + reg = <0x4 0x2010 0x8>; + interrupts = <0x1b 0x4>; + interrupt-parent = <&gef_pic>; + }; + */ + gef_pic: pic@4,4000 { + #interrupt-cells = <1>; + interrupt-controller; + compatible = "gef,fpga-pic"; + reg = <0x4 0x4000 0x20>; + interrupts = <0x8 0x9 0 0>; + + }; + gef_gpio: gpio@7,14000 { + #gpio-cells = <2>; + compatible = "gef,sbc610-gpio"; + reg = <0x7 0x14000 0x24>; + gpio-controller; + }; + }; + + soc: soc@fef00000 { + ranges = <0x0 0xfef00000 0x00100000>; + + i2c@3000 { + hwmon@48 { + compatible = "national,lm92"; + reg = <0x48>; + }; + + hwmon@4c { + compatible = "adi,adt7461"; + reg = <0x4c>; + }; + + rtc@51 { + compatible = "epson,rx8581"; + reg = <0x00000051>; + }; + + eti@6b { + compatible = "dallas,ds1682"; + reg = <0x6b>; + }; + }; + + enet0: ethernet@24000 { + tbi-handle = <&tbi0>; + phy-handle = <&phy0>; + phy-connection-type = "gmii"; + }; + + mdio@24520 { + phy0: ethernet-phy@0 { + interrupt-parent = <&gef_pic>; + interrupts = <0x9 0x4>; + reg = <1>; + }; + phy2: ethernet-phy@2 { + interrupt-parent = <&gef_pic>; + interrupts = <0x8 0x4>; + reg = <3>; + }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + enet1: ethernet@26000 { + tbi-handle = <&tbi2>; + phy-handle = <&phy2>; + phy-connection-type = "gmii"; + }; + + mdio@26520 { + tbi2: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + enet2: ethernet@25000 { + status = "disabled"; + }; + + mdio@25520 { + status = "disabled"; + }; + + enet3: ethernet@27000 { + status = "disabled"; + }; + + mdio@27520 { + status = "disabled"; + }; + }; + + pci0: pcie@fef08000 { + reg = <0xfef08000 0x1000>; + ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x40000000 + 0x01000000 0x0 0x00000000 0xfe000000 0x0 0x00400000>; + + pcie@0 { + ranges = <0x02000000 0x0 0x80000000 + 0x02000000 0x0 0x80000000 + 0x0 0x40000000 + + 0x01000000 0x0 0x00000000 + 0x01000000 0x0 0x00000000 + 0x0 0x00400000>; + }; + }; +}; + +/include/ "mpc8641si-post.dtsi" diff --git a/arch/powerpc/boot/dts/fsl/kmcoge4.dts b/arch/powerpc/boot/dts/fsl/kmcoge4.dts index 6858ec9ef2958c0ec4ac1820cffa16875a02a8ef..2d4b64fcee884a462fbc9ea66b4a5d73932bd683 100644 --- a/arch/powerpc/boot/dts/fsl/kmcoge4.dts +++ b/arch/powerpc/boot/dts/fsl/kmcoge4.dts @@ -63,7 +63,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spansion,s25fl256s1"; + compatible = "spansion,s25fl256s1", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <20000000>; /* input clock */ }; @@ -77,7 +77,7 @@ flash@2 { #address-cells = <1>; #size-cells = <1>; - compatible = "micron,m25p32"; + compatible = "micron,m25p32", "jedec,spi-nor"; reg = <2>; spi-max-frequency = <15000000>; }; diff --git a/arch/powerpc/boot/dts/fsl/mpc8536ds.dtsi b/arch/powerpc/boot/dts/fsl/mpc8536ds.dtsi index 937ad7e461196087a21da1f476b0b97c322e139e..a925fe49a73ec7eb1027e4e1bfbcab029f081169 100644 --- a/arch/powerpc/boot/dts/fsl/mpc8536ds.dtsi +++ b/arch/powerpc/boot/dts/fsl/mpc8536ds.dtsi @@ -142,7 +142,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spansion,s25sl12801"; + compatible = "spansion,s25sl12801", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <40000000>; partition@u-boot { @@ -166,17 +166,17 @@ }; }; flash@1 { - compatible = "spansion,s25sl12801"; + compatible = "spansion,s25sl12801", "jedec,spi-nor"; reg = <1>; spi-max-frequency = <40000000>; }; flash@2 { - compatible = "spansion,s25sl12801"; + compatible = "spansion,s25sl12801", "jedec,spi-nor"; reg = <2>; spi-max-frequency = <40000000>; }; flash@3 { - compatible = "spansion,s25sl12801"; + compatible = "spansion,s25sl12801", "jedec,spi-nor"; reg = <3>; spi-max-frequency = <40000000>; }; diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn.dts b/arch/powerpc/boot/dts/fsl/mpc8641_hpcn.dts similarity index 53% rename from arch/powerpc/boot/dts/mpc8641_hpcn.dts rename to arch/powerpc/boot/dts/fsl/mpc8641_hpcn.dts index 1c03060dd0b8559d09c2c7b7d9caad6bd7d70f7f..554001f2e96a3b8998022a0f83b3096a0ff96325 100644 --- a/arch/powerpc/boot/dts/mpc8641_hpcn.dts +++ b/arch/powerpc/boot/dts/fsl/mpc8641_hpcn.dts @@ -9,65 +9,23 @@ * option) any later version. */ -/dts-v1/; +/include/ "mpc8641si-pre.dtsi" / { model = "MPC8641HPCN"; compatible = "fsl,mpc8641hpcn"; - #address-cells = <1>; - #size-cells = <1>; aliases { - ethernet0 = &enet0; - ethernet1 = &enet1; - ethernet2 = &enet2; - ethernet3 = &enet3; - serial0 = &serial0; - serial1 = &serial1; - pci0 = &pci0; pci1 = &pci1; }; - cpus { - #address-cells = <1>; - #size-cells = <0>; - - PowerPC,8641@0 { - device_type = "cpu"; - reg = <0>; - d-cache-line-size = <32>; - i-cache-line-size = <32>; - d-cache-size = <32768>; // L1 - i-cache-size = <32768>; // L1 - timebase-frequency = <0>; // From uboot - bus-frequency = <0>; // From uboot - clock-frequency = <0>; // From uboot - }; - PowerPC,8641@1 { - device_type = "cpu"; - reg = <1>; - d-cache-line-size = <32>; - i-cache-line-size = <32>; - d-cache-size = <32768>; - i-cache-size = <32768>; - timebase-frequency = <0>; // From uboot - bus-frequency = <0>; // From uboot - clock-frequency = <0>; // From uboot - }; - }; - memory { device_type = "memory"; reg = <0x00000000 0x40000000>; // 1G at 0x0 }; - localbus@ffe05000 { - #address-cells = <2>; - #size-cells = <1>; - compatible = "fsl,mpc8641-localbus", "simple-bus"; + lbc: localbus@ffe05000 { reg = <0xffe05000 0x1000>; - interrupts = <19 2>; - interrupt-parent = <&mpic>; ranges = <0 0 0xef800000 0x00800000 2 0 0xffdf8000 0x00008000 @@ -101,253 +59,75 @@ }; }; - soc8641@ffe00000 { - #address-cells = <1>; - #size-cells = <1>; - device_type = "soc"; - compatible = "simple-bus"; + soc: soc8641@ffe00000 { ranges = <0x00000000 0xffe00000 0x00100000>; - bus-frequency = <0>; - - mcm-law@0 { - compatible = "fsl,mcm-law"; - reg = <0x0 0x1000>; - fsl,num-laws = <10>; - }; - - mcm@1000 { - compatible = "fsl,mpc8641-mcm", "fsl,mcm"; - reg = <0x1000 0x1000>; - interrupts = <17 2>; - interrupt-parent = <&mpic>; - }; - i2c@3000 { - #address-cells = <1>; - #size-cells = <0>; - cell-index = <0>; - compatible = "fsl-i2c"; - reg = <0x3000 0x100>; - interrupts = <43 2>; - interrupt-parent = <&mpic>; - dfsrr; - }; - - i2c@3100 { - #address-cells = <1>; - #size-cells = <0>; - cell-index = <1>; - compatible = "fsl-i2c"; - reg = <0x3100 0x100>; - interrupts = <43 2>; - interrupt-parent = <&mpic>; - dfsrr; + enet0: ethernet@24000 { + tbi-handle = <&tbi0>; + phy-handle = <&phy0>; + phy-connection-type = "rgmii-id"; }; - dma@21300 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma"; - reg = <0x21300 0x4>; - ranges = <0x0 0x21100 0x200>; - cell-index = <0>; - dma-channel@0 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x0 0x80>; - cell-index = <0>; - interrupt-parent = <&mpic>; - interrupts = <20 2>; + mdio@24520 { + phy0: ethernet-phy@0 { + interrupts = <10 1 0 0>; + reg = <0>; }; - dma-channel@80 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x80 0x80>; - cell-index = <1>; - interrupt-parent = <&mpic>; - interrupts = <21 2>; + phy1: ethernet-phy@1 { + interrupts = <10 1 0 0>; + reg = <1>; }; - dma-channel@100 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x100 0x80>; - cell-index = <2>; - interrupt-parent = <&mpic>; - interrupts = <22 2>; + phy2: ethernet-phy@2 { + interrupts = <10 1 0 0>; + reg = <2>; }; - dma-channel@180 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x180 0x80>; - cell-index = <3>; - interrupt-parent = <&mpic>; - interrupts = <23 2>; + phy3: ethernet-phy@3 { + interrupts = <10 1 0 0>; + reg = <3>; }; - }; - - enet0: ethernet@24000 { - #address-cells = <1>; - #size-cells = <1>; - cell-index = <0>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <29 2 30 2 34 2>; - interrupt-parent = <&mpic>; - tbi-handle = <&tbi0>; - phy-handle = <&phy0>; - phy-connection-type = "rgmii-id"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy0: ethernet-phy@0 { - interrupt-parent = <&mpic>; - interrupts = <10 1>; - reg = <0>; - }; - phy1: ethernet-phy@1 { - interrupt-parent = <&mpic>; - interrupts = <10 1>; - reg = <1>; - }; - phy2: ethernet-phy@2 { - interrupt-parent = <&mpic>; - interrupts = <10 1>; - reg = <2>; - }; - phy3: ethernet-phy@3 { - interrupt-parent = <&mpic>; - interrupts = <10 1>; - reg = <3>; - }; - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; }; }; enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; - cell-index = <1>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <35 2 36 2 40 2>; - interrupt-parent = <&mpic>; tbi-handle = <&tbi1>; phy-handle = <&phy1>; phy-connection-type = "rgmii-id"; + }; - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; + mdio@25520 { + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; }; }; enet2: ethernet@26000 { - #address-cells = <1>; - #size-cells = <1>; - cell-index = <2>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <0x26000 0x1000>; - ranges = <0x0 0x26000 0x1000>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <31 2 32 2 33 2>; - interrupt-parent = <&mpic>; tbi-handle = <&tbi2>; phy-handle = <&phy2>; phy-connection-type = "rgmii-id"; + }; - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi2: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; + mdio@26520 { + tbi2: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; }; }; enet3: ethernet@27000 { - #address-cells = <1>; - #size-cells = <1>; - cell-index = <3>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <0x27000 0x1000>; - ranges = <0x0 0x27000 0x1000>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <37 2 38 2 39 2>; - interrupt-parent = <&mpic>; tbi-handle = <&tbi3>; phy-handle = <&phy3>; phy-connection-type = "rgmii-id"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi3: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; - serial0: serial@4500 { - cell-index = <0>; - device_type = "serial"; - compatible = "fsl,ns16550", "ns16550"; - reg = <0x4500 0x100>; - clock-frequency = <0>; - interrupts = <42 2>; - interrupt-parent = <&mpic>; - }; - - serial1: serial@4600 { - cell-index = <1>; - device_type = "serial"; - compatible = "fsl,ns16550", "ns16550"; - reg = <0x4600 0x100>; - clock-frequency = <0>; - interrupts = <28 2>; - interrupt-parent = <&mpic>; - }; - - mpic: pic@40000 { - interrupt-controller; - #address-cells = <0>; - #interrupt-cells = <2>; - reg = <0x40000 0x40000>; - compatible = "chrp,open-pic"; - device_type = "open-pic"; + mdio@27520 { + tbi3: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; }; rmu: rmu@d3000 { @@ -361,50 +141,35 @@ compatible = "fsl,srio-msg-unit"; reg = <0x0 0x100>; interrupts = < - 53 2 /* msg1_tx_irq */ - 54 2>;/* msg1_rx_irq */ + 53 2 0 0 /* msg1_tx_irq */ + 54 2 0 0>;/* msg1_rx_irq */ }; message-unit@100 { compatible = "fsl,srio-msg-unit"; reg = <0x100 0x100>; interrupts = < - 55 2 /* msg2_tx_irq */ - 56 2>;/* msg2_rx_irq */ + 55 2 0 0 /* msg2_tx_irq */ + 56 2 0 0>;/* msg2_rx_irq */ }; doorbell-unit@400 { compatible = "fsl,srio-dbell-unit"; reg = <0x400 0x80>; interrupts = < - 49 2 /* bell_outb_irq */ - 50 2>;/* bell_inb_irq */ + 49 2 0 0 /* bell_outb_irq */ + 50 2 0 0>;/* bell_inb_irq */ }; port-write-unit@4e0 { compatible = "fsl,srio-port-write-unit"; reg = <0x4e0 0x20>; - interrupts = <48 2>; + interrupts = <48 2 0 0>; }; }; - - global-utilities@e0000 { - compatible = "fsl,mpc8641-guts"; - reg = <0xe0000 0x1000>; - fsl,has-rstcr; - }; }; pci0: pcie@ffe08000 { - compatible = "fsl,mpc8641-pcie"; - device_type = "pci"; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; reg = <0xffe08000 0x1000>; - bus-range = <0x0 0xff>; ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x20000000 0x01000000 0x0 0x00000000 0xffc00000 0x0 0x00010000>; - clock-frequency = <33333333>; - interrupt-parent = <&mpic>; - interrupts = <24 2>; interrupt-map-mask = <0xff00 0 0 7>; interrupt-map = < /* IDSEL 0x11 func 0 - PCI slot 1 */ @@ -522,10 +287,6 @@ >; pcie@0 { - reg = <0 0 0 0 0>; - #size-cells = <2>; - #address-cells = <3>; - device_type = "pci"; ranges = <0x02000000 0x0 0x80000000 0x02000000 0x0 0x80000000 0x0 0x20000000 @@ -545,7 +306,6 @@ 0x0 0x00010000>; isa@1e { device_type = "isa"; - #interrupt-cells = <2>; #size-cells = <1>; #address-cells = <2>; reg = <0xf000 0 0 0 0>; @@ -562,8 +322,7 @@ #address-cells = <0>; #interrupt-cells = <2>; compatible = "chrp,iic"; - interrupts = <9 2>; - interrupt-parent = <&mpic>; + interrupts = <9 2 0 0>; }; i8042@60 { @@ -571,8 +330,7 @@ #address-cells = <1>; reg = <1 0x60 1 1 0x64 1>; interrupts = <1 3 12 3>; - interrupt-parent = - <&i8259>; + interrupt-parent = <&i8259>; keyboard@0 { reg = <0>; @@ -603,16 +361,14 @@ pci1: pcie@ffe09000 { compatible = "fsl,mpc8641-pcie"; device_type = "pci"; - #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; reg = <0xffe09000 0x1000>; bus-range = <0 0xff>; ranges = <0x02000000 0x0 0xa0000000 0xa0000000 0x0 0x20000000 0x01000000 0x0 0x00000000 0xffc10000 0x0 0x00010000>; - clock-frequency = <33333333>; - interrupt-parent = <&mpic>; - interrupts = <25 2>; + clock-frequency = <100000000>; + interrupts = <25 2 0 0>; interrupt-map-mask = <0xf800 0 0 7>; interrupt-map = < /* IDSEL 0x0 */ @@ -644,8 +400,7 @@ rapidio@ffec0000 { reg = <0xffec0000 0x11000>; compatible = "fsl,srio"; - interrupt-parent = <&mpic>; - interrupts = <48 2>; + interrupts = <48 2 0 0>; #address-cells = <2>; #size-cells = <2>; fsl,srio-rmu-handle = <&rmu>; @@ -661,3 +416,5 @@ */ }; + +/include/ "mpc8641si-post.dtsi" diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts b/arch/powerpc/boot/dts/fsl/mpc8641_hpcn_36b.dts similarity index 51% rename from arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts rename to arch/powerpc/boot/dts/fsl/mpc8641_hpcn_36b.dts index bb575e28042a2aa8483f8fc97e17dd0f49190c32..fec58671a6d6ece0b8cda1e6338ed700689788a7 100644 --- a/arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts +++ b/arch/powerpc/boot/dts/fsl/mpc8641_hpcn_36b.dts @@ -9,7 +9,7 @@ * option) any later version. */ -/dts-v1/; +/include/ "mpc8641si-pre.dtsi" / { model = "MPC8641HPCN"; @@ -18,56 +18,16 @@ #size-cells = <2>; aliases { - ethernet0 = &enet0; - ethernet1 = &enet1; - ethernet2 = &enet2; - ethernet3 = &enet3; - serial0 = &serial0; - serial1 = &serial1; - pci0 = &pci0; pci1 = &pci1; }; - cpus { - #address-cells = <1>; - #size-cells = <0>; - - PowerPC,8641@0 { - device_type = "cpu"; - reg = <0>; - d-cache-line-size = <32>; // 32 bytes - i-cache-line-size = <32>; // 32 bytes - d-cache-size = <32768>; // L1, 32K - i-cache-size = <32768>; // L1, 32K - timebase-frequency = <0>; // 33 MHz, from uboot - bus-frequency = <0>; // From uboot - clock-frequency = <0>; // From uboot - }; - PowerPC,8641@1 { - device_type = "cpu"; - reg = <1>; - d-cache-line-size = <32>; // 32 bytes - i-cache-line-size = <32>; // 32 bytes - d-cache-size = <32768>; // L1, 32K - i-cache-size = <32768>; // L1, 32K - timebase-frequency = <0>; // 33 MHz, from uboot - bus-frequency = <0>; // From uboot - clock-frequency = <0>; // From uboot - }; - }; - memory { device_type = "memory"; reg = <0x0 0x00000000 0x0 0x40000000>; // 1G at 0x0 }; - localbus@fffe05000 { - #address-cells = <2>; - #size-cells = <1>; - compatible = "fsl,mpc8641-localbus", "simple-bus"; + lbc: localbus@fffe05000 { reg = <0x0f 0xffe05000 0x0 0x1000>; - interrupts = <19 2>; - interrupt-parent = <&mpic>; ranges = <0 0 0xf 0xef800000 0x00800000 2 0 0xf 0xffdf8000 0x00008000 @@ -101,276 +61,82 @@ }; }; - soc8641@fffe00000 { - #address-cells = <1>; - #size-cells = <1>; - device_type = "soc"; - compatible = "simple-bus"; + soc: soc8641@fffe00000 { ranges = <0x00000000 0x0f 0xffe00000 0x00100000>; - bus-frequency = <0>; - mcm-law@0 { - compatible = "fsl,mcm-law"; - reg = <0x0 0x1000>; - fsl,num-laws = <10>; - }; - - mcm@1000 { - compatible = "fsl,mpc8641-mcm", "fsl,mcm"; - reg = <0x1000 0x1000>; - interrupts = <17 2>; - interrupt-parent = <&mpic>; - }; - - i2c@3000 { - #address-cells = <1>; - #size-cells = <0>; - cell-index = <0>; - compatible = "fsl-i2c"; - reg = <0x3000 0x100>; - interrupts = <43 2>; - interrupt-parent = <&mpic>; - dfsrr; - }; - - i2c@3100 { - #address-cells = <1>; - #size-cells = <0>; - cell-index = <1>; - compatible = "fsl-i2c"; - reg = <0x3100 0x100>; - interrupts = <43 2>; - interrupt-parent = <&mpic>; - dfsrr; + enet0: ethernet@24000 { + tbi-handle = <&tbi0>; + phy-handle = <&phy0>; + phy-connection-type = "rgmii-id"; }; - dma@21300 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma"; - reg = <0x21300 0x4>; - ranges = <0x0 0x21100 0x200>; - cell-index = <0>; - dma-channel@0 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x0 0x80>; - cell-index = <0>; - interrupt-parent = <&mpic>; - interrupts = <20 2>; + mdio@24520 { + phy0: ethernet-phy@0 { + interrupts = <10 1 0 0>; + reg = <0>; }; - dma-channel@80 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x80 0x80>; - cell-index = <1>; - interrupt-parent = <&mpic>; - interrupts = <21 2>; + phy1: ethernet-phy@1 { + interrupts = <10 1 0 0>; + reg = <1>; }; - dma-channel@100 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x100 0x80>; - cell-index = <2>; - interrupt-parent = <&mpic>; - interrupts = <22 2>; + phy2: ethernet-phy@2 { + interrupts = <10 1 0 0>; + reg = <2>; }; - dma-channel@180 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x180 0x80>; - cell-index = <3>; - interrupt-parent = <&mpic>; - interrupts = <23 2>; + phy3: ethernet-phy@3 { + interrupts = <10 1 0 0>; + reg = <3>; }; - }; - - enet0: ethernet@24000 { - #address-cells = <1>; - #size-cells = <1>; - cell-index = <0>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <29 2 30 2 34 2>; - interrupt-parent = <&mpic>; - tbi-handle = <&tbi0>; - phy-handle = <&phy0>; - phy-connection-type = "rgmii-id"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy0: ethernet-phy@0 { - interrupt-parent = <&mpic>; - interrupts = <10 1>; - reg = <0>; - }; - phy1: ethernet-phy@1 { - interrupt-parent = <&mpic>; - interrupts = <10 1>; - reg = <1>; - }; - phy2: ethernet-phy@2 { - interrupt-parent = <&mpic>; - interrupts = <10 1>; - reg = <2>; - }; - phy3: ethernet-phy@3 { - interrupt-parent = <&mpic>; - interrupts = <10 1>; - reg = <3>; - }; - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; }; }; enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; - cell-index = <1>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <35 2 36 2 40 2>; - interrupt-parent = <&mpic>; tbi-handle = <&tbi1>; phy-handle = <&phy1>; phy-connection-type = "rgmii-id"; + }; - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; + mdio@25520 { + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; }; }; enet2: ethernet@26000 { - #address-cells = <1>; - #size-cells = <1>; - cell-index = <2>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <0x26000 0x1000>; - ranges = <0x0 0x26000 0x1000>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <31 2 32 2 33 2>; - interrupt-parent = <&mpic>; tbi-handle = <&tbi2>; phy-handle = <&phy2>; phy-connection-type = "rgmii-id"; + }; - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi2: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; + mdio@26520 { + tbi2: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; }; }; enet3: ethernet@27000 { - #address-cells = <1>; - #size-cells = <1>; - cell-index = <3>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <0x27000 0x1000>; - ranges = <0x0 0x27000 0x1000>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <37 2 38 2 39 2>; - interrupt-parent = <&mpic>; tbi-handle = <&tbi3>; phy-handle = <&phy3>; phy-connection-type = "rgmii-id"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi3: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; }; - serial0: serial@4500 { - cell-index = <0>; - device_type = "serial"; - compatible = "fsl,ns16550", "ns16550"; - reg = <0x4500 0x100>; - clock-frequency = <0>; - interrupts = <42 2>; - interrupt-parent = <&mpic>; - }; - - serial1: serial@4600 { - cell-index = <1>; - device_type = "serial"; - compatible = "fsl,ns16550", "ns16550"; - reg = <0x4600 0x100>; - clock-frequency = <0>; - interrupts = <28 2>; - interrupt-parent = <&mpic>; - }; - - mpic: pic@40000 { - interrupt-controller; - #address-cells = <0>; - #interrupt-cells = <2>; - reg = <0x40000 0x40000>; - compatible = "chrp,open-pic"; - device_type = "open-pic"; - }; - - global-utilities@e0000 { - compatible = "fsl,mpc8641-guts"; - reg = <0xe0000 0x1000>; - fsl,has-rstcr; + mdio@27520 { + tbi3: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; }; }; pci0: pcie@fffe08000 { - cell-index = <0>; - compatible = "fsl,mpc8641-pcie"; - device_type = "pci"; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; reg = <0x0f 0xffe08000 0x0 0x1000>; - bus-range = <0x0 0xff>; ranges = <0x02000000 0x0 0xe0000000 0x0c 0x00000000 0x0 0x20000000 0x01000000 0x0 0x00000000 0x0f 0xffc00000 0x0 0x00010000>; - clock-frequency = <33333333>; - interrupt-parent = <&mpic>; - interrupts = <24 2>; interrupt-map-mask = <0xff00 0 0 7>; interrupt-map = < /* IDSEL 0x11 func 0 - PCI slot 1 */ @@ -488,10 +254,6 @@ >; pcie@0 { - reg = <0 0 0 0 0>; - #size-cells = <2>; - #address-cells = <3>; - device_type = "pci"; ranges = <0x02000000 0x0 0xe0000000 0x02000000 0x0 0xe0000000 0x0 0x20000000 @@ -511,7 +273,6 @@ 0x0 0x00010000>; isa@1e { device_type = "isa"; - #interrupt-cells = <2>; #size-cells = <1>; #address-cells = <2>; reg = <0xf000 0 0 0 0>; @@ -528,8 +289,7 @@ #address-cells = <0>; #interrupt-cells = <2>; compatible = "chrp,iic"; - interrupts = <9 2>; - interrupt-parent = <&mpic>; + interrupts = <9 2 0 0>; }; i8042@60 { @@ -537,8 +297,7 @@ #address-cells = <1>; reg = <1 0x60 1 1 0x64 1>; interrupts = <1 3 12 3>; - interrupt-parent = - <&i8259>; + interrupt-parent = <&i8259>; keyboard@0 { reg = <0>; @@ -567,19 +326,16 @@ }; pci1: pcie@fffe09000 { - cell-index = <1>; compatible = "fsl,mpc8641-pcie"; device_type = "pci"; - #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; reg = <0x0f 0xffe09000 0x0 0x1000>; bus-range = <0x0 0xff>; ranges = <0x02000000 0x0 0xe0000000 0x0c 0x20000000 0x0 0x20000000 0x01000000 0x0 0x00000000 0x0f 0xffc10000 0x0 0x00010000>; - clock-frequency = <33333333>; - interrupt-parent = <&mpic>; - interrupts = <25 2>; + clock-frequency = <100000000>; + interrupts = <25 2 0 0>; interrupt-map-mask = <0xf800 0 0 7>; interrupt-map = < /* IDSEL 0x0 */ @@ -603,3 +359,5 @@ }; }; }; + +/include/ "mpc8641si-post.dtsi" diff --git a/arch/powerpc/boot/dts/fsl/mpc8641si-post.dtsi b/arch/powerpc/boot/dts/fsl/mpc8641si-post.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..70889d8e885009b1e4c20dfb14113871722c09fa --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/mpc8641si-post.dtsi @@ -0,0 +1,120 @@ +/* + * MPC8641 Silicon/SoC Device Tree Source (post include) + * + * Copyright 2016 Elettra-Sincrotrone Trieste S.C.p.A. + * + * 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. + * + */ + +&lbc { + #address-cells = <2>; + #size-cells = <1>; + compatible = "fsl,mpc8641-localbus", "simple-bus"; + interrupts = <19 2 0 0>; +}; + +&soc { + #address-cells = <1>; + #size-cells = <1>; + device_type = "soc"; + compatible = "fsl,mpc8641-soc", "simple-bus"; + bus-frequency = <0>; + + mcm-law@0 { + compatible = "fsl,mcm-law"; + reg = <0x0 0x1000>; + fsl,num-laws = <10>; + }; + + mcm@1000 { + compatible = "fsl,mpc8641-mcm", "fsl,mcm"; + reg = <0x1000 0x1000>; + interrupts = <17 2 0 0>; + }; + +/include/ "pq3-i2c-0.dtsi" +/include/ "pq3-i2c-1.dtsi" +/include/ "pq3-duart-0.dtsi" + serial@4600 { + interrupts = <28 2 0 0>; + }; +/include/ "pq3-dma-0.dtsi" + dma@21300 { + compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma"; + }; + dma-channel@0 { + compatible = "fsl,mpc8641-dma-channel", "fsl,eloplus-dma-channel"; + }; + dma-channel@80 { + compatible = "fsl,mpc8641-dma-channel", "fsl,eloplus-dma-channel"; + }; + dma-channel@100 { + compatible = "fsl,mpc8641-dma-channel", "fsl,eloplus-dma-channel"; + }; + dma-channel@180 { + compatible = "fsl,mpc8641-dma-channel", "fsl,eloplus-dma-channel"; + }; + +/include/ "pq3-etsec1-0.dtsi" + ethernet@24000 { + model = "TSEC"; + }; +/include/ "pq3-etsec1-1.dtsi" + ethernet@25000 { + model = "TSEC"; + }; +/include/ "pq3-etsec1-2.dtsi" + ethernet@26000 { + model = "TSEC"; + }; +/include/ "pq3-etsec1-3.dtsi" + ethernet@27000 { + model = "TSEC"; + }; + +/include/ "qoriq-mpic.dtsi" + msi@41600 { + compatible = "fsl,mpc8641-msi", "fsl,mpic-msi"; + }; + msi@41800 { + compatible = "fsl,mpc8641-msi", "fsl,mpic-msi"; + }; + msi@41a00 { + compatible = "fsl,mpc8641-msi", "fsl,mpic-msi"; + }; + + global-utilities@e0000 { + compatible = "fsl,mpc8641-guts"; + reg = <0xe0000 0x1000>; + fsl,has-rstcr; + }; +}; + +&pci0 { + compatible = "fsl,mpc8641-pcie"; + device_type = "pci"; + #size-cells = <2>; + #address-cells = <3>; + bus-range = <0x0 0xff>; + clock-frequency = <100000000>; + interrupts = <24 2 0 0>; + interrupt-map-mask = <0xf800 0x0 0x0 0x7>; + + interrupt-map = < + 0x0000 0x0 0x0 0x1 &mpic 0x0 0x1 + 0x0000 0x0 0x0 0x2 &mpic 0x1 0x1 + 0x0000 0x0 0x0 0x3 &mpic 0x2 0x1 + 0x0000 0x0 0x0 0x4 &mpic 0x3 0x1 + >; + + pcie@0 { + reg = <0 0 0 0 0>; + #size-cells = <2>; + #address-cells = <3>; + device_type = "pci"; + }; +}; diff --git a/arch/powerpc/boot/dts/fsl/mpc8641si-pre.dtsi b/arch/powerpc/boot/dts/fsl/mpc8641si-pre.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..9e03328561d342d7abf7b4e396280ef500cc32b2 --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/mpc8641si-pre.dtsi @@ -0,0 +1,58 @@ +/* + * MPC8641 Silicon/SoC Device Tree Source (pre include) + * + * Copyright 2016 Elettra-Sincrotrone Trieste S.C.p.A. + * + * 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. + * + */ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&mpic>; + + aliases { + ethernet0 = &enet0; + ethernet1 = &enet1; + ethernet2 = &enet2; + ethernet3 = &enet3; + serial0 = &serial0; + serial1 = &serial1; + pci0 = &pci0; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + PowerPC,8641@0 { + device_type = "cpu"; + reg = <0>; + d-cache-line-size = <32>; + i-cache-line-size = <32>; + d-cache-size = <32768>; + i-cache-size = <32768>; + timebase-frequency = <0>; + bus-frequency = <0>; + clock-frequency = <0>; + }; + + PowerPC,8641@1 { + device_type = "cpu"; + reg = <1>; + d-cache-line-size = <32>; + i-cache-line-size = <32>; + d-cache-size = <32768>; + i-cache-size = <32768>; + timebase-frequency = <0>; + bus-frequency = <0>; + clock-frequency = <0>; + }; + }; +}; diff --git a/arch/powerpc/boot/dts/fsl/mvme2500.dts b/arch/powerpc/boot/dts/fsl/mvme2500.dts index c7bc1a0c7194068d4e97ea847328297236f0814c..69559e970e998034cc30f4b639c3378b57763960 100644 --- a/arch/powerpc/boot/dts/fsl/mvme2500.dts +++ b/arch/powerpc/boot/dts/fsl/mvme2500.dts @@ -70,12 +70,12 @@ fsl,espi-num-chipselects = <2>; flash@0 { - compatible = "atmel,at25df641"; + compatible = "atmel,at25df641", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <10000000>; }; flash@1 { - compatible = "atmel,at25df641"; + compatible = "atmel,at25df641", "jedec,spi-nor"; reg = <1>; spi-max-frequency = <10000000>; }; diff --git a/arch/powerpc/boot/dts/fsl/p1010rdb.dtsi b/arch/powerpc/boot/dts/fsl/p1010rdb.dtsi index 14b62950503893dc323913be9870188c12e2115f..a8e4ba070104ebba852e7c52a4dab34c22c0202e 100644 --- a/arch/powerpc/boot/dts/fsl/p1010rdb.dtsi +++ b/arch/powerpc/boot/dts/fsl/p1010rdb.dtsi @@ -110,7 +110,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spansion,s25sl12801"; + compatible = "spansion,s25sl12801", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <40000000>; diff --git a/arch/powerpc/boot/dts/fsl/p1020rdb-pc.dtsi b/arch/powerpc/boot/dts/fsl/p1020rdb-pc.dtsi index c952cd37cf6dd3775dda54dad9401518455cc0cb..25f81eea60e09251a60e824131c48a34f90d2e55 100644 --- a/arch/powerpc/boot/dts/fsl/p1020rdb-pc.dtsi +++ b/arch/powerpc/boot/dts/fsl/p1020rdb-pc.dtsi @@ -151,7 +151,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spansion,s25sl12801"; + compatible = "spansion,s25sl12801", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <40000000>; /* input clock */ diff --git a/arch/powerpc/boot/dts/fsl/p1020rdb-pd.dts b/arch/powerpc/boot/dts/fsl/p1020rdb-pd.dts index 740553c090a374ca059476eaf89a91b24ded5966..f2dc6c09be522d3dd1cf26bff3f964e15254cb43 100644 --- a/arch/powerpc/boot/dts/fsl/p1020rdb-pd.dts +++ b/arch/powerpc/boot/dts/fsl/p1020rdb-pd.dts @@ -155,7 +155,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spansion,s25sl12801"; + compatible = "spansion,s25sl12801", "jedec,spi-nor"; reg = <0>; /* input clock */ spi-max-frequency = <40000000>; diff --git a/arch/powerpc/boot/dts/fsl/p1020rdb.dtsi b/arch/powerpc/boot/dts/fsl/p1020rdb.dtsi index 1fb7e0e0940f0cb098843b78207c6117efeffab7..703142ee66279d992a231f643e09c1eb37daa37f 100644 --- a/arch/powerpc/boot/dts/fsl/p1020rdb.dtsi +++ b/arch/powerpc/boot/dts/fsl/p1020rdb.dtsi @@ -148,7 +148,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spansion,s25sl12801"; + compatible = "spansion,s25sl12801", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <40000000>; /* input clock */ diff --git a/arch/powerpc/boot/dts/fsl/p1021mds.dts b/arch/powerpc/boot/dts/fsl/p1021mds.dts index 27fdfd7dc7c73fc8d3d17ea002e822b32fdbe659..291454c75ddad117d1d4345d992116bff7cd3cfb 100644 --- a/arch/powerpc/boot/dts/fsl/p1021mds.dts +++ b/arch/powerpc/boot/dts/fsl/p1021mds.dts @@ -123,7 +123,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spansion,s25sl12801"; + compatible = "spansion,s25sl12801", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <40000000>; /* input clock */ diff --git a/arch/powerpc/boot/dts/fsl/p1021rdb-pc.dtsi b/arch/powerpc/boot/dts/fsl/p1021rdb-pc.dtsi index e8a0f95fb24a5648f79ccfa2535e38f2bd40a5b1..18f9b31602d0b7a53f381d29810110d28e15cc7a 100644 --- a/arch/powerpc/boot/dts/fsl/p1021rdb-pc.dtsi +++ b/arch/powerpc/boot/dts/fsl/p1021rdb-pc.dtsi @@ -150,7 +150,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spansion,s25sl12801"; + compatible = "spansion,s25sl12801", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <40000000>; /* input clock */ diff --git a/arch/powerpc/boot/dts/fsl/p1022ds.dtsi b/arch/powerpc/boot/dts/fsl/p1022ds.dtsi index 149da0f123eeb9ebff4ea9b9bb1cd37e8cb85bff..ddefbf64f7f8b8c5efe6a05f27df2a3b7e873171 100644 --- a/arch/powerpc/boot/dts/fsl/p1022ds.dtsi +++ b/arch/powerpc/boot/dts/fsl/p1022ds.dtsi @@ -160,7 +160,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spansion,s25sl12801"; + compatible = "spansion,s25sl12801", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <40000000>; /* input clock */ diff --git a/arch/powerpc/boot/dts/fsl/p1022rdk.dts b/arch/powerpc/boot/dts/fsl/p1022rdk.dts index 04c16337268a7e2a4c23092581d46047cc101b1c..d505d7c51903b5879723c5b093f6e752635e2d7c 100644 --- a/arch/powerpc/boot/dts/fsl/p1022rdk.dts +++ b/arch/powerpc/boot/dts/fsl/p1022rdk.dts @@ -86,7 +86,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spansion,m25p80"; + compatible = "spansion,m25p80", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <1000000>; partition@0 { diff --git a/arch/powerpc/boot/dts/fsl/p1024rdb.dtsi b/arch/powerpc/boot/dts/fsl/p1024rdb.dtsi index b05dcb40f800225c41be95c4f594886fa59768ad..b4d05867f707c6193784a32ce46f696451d23a29 100644 --- a/arch/powerpc/boot/dts/fsl/p1024rdb.dtsi +++ b/arch/powerpc/boot/dts/fsl/p1024rdb.dtsi @@ -129,7 +129,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spansion,m25p80"; + compatible = "spansion,m25p80", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <40000000>; diff --git a/arch/powerpc/boot/dts/fsl/p1025rdb.dtsi b/arch/powerpc/boot/dts/fsl/p1025rdb.dtsi index f50256482297101c4fcda8c1093eadad638447ac..d44bb12debb01052e6d75ceaa60182c849f2101c 100644 --- a/arch/powerpc/boot/dts/fsl/p1025rdb.dtsi +++ b/arch/powerpc/boot/dts/fsl/p1025rdb.dtsi @@ -137,7 +137,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spansion,s25sl12801"; + compatible = "spansion,s25sl12801", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <40000000>; /* input clock */ diff --git a/arch/powerpc/boot/dts/fsl/p2020rdb-pc.dtsi b/arch/powerpc/boot/dts/fsl/p2020rdb-pc.dtsi index ad2e242365ccada6e32800a381da45540a7cffac..03c9afc82436cd496b6d38612d4a9b810051e9a3 100644 --- a/arch/powerpc/boot/dts/fsl/p2020rdb-pc.dtsi +++ b/arch/powerpc/boot/dts/fsl/p2020rdb-pc.dtsi @@ -151,7 +151,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spansion,m25p80"; + compatible = "spansion,m25p80", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <40000000>; diff --git a/arch/powerpc/boot/dts/fsl/p2020rdb.dts b/arch/powerpc/boot/dts/fsl/p2020rdb.dts index 70cf09019ce5486b34a38a0afdacb65750db3c0e..435a319958cb11fbf64f25f8ba952b0827755f85 100644 --- a/arch/powerpc/boot/dts/fsl/p2020rdb.dts +++ b/arch/powerpc/boot/dts/fsl/p2020rdb.dts @@ -155,7 +155,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spansion,s25sl12801"; + compatible = "spansion,s25sl12801", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <40000000>; diff --git a/arch/powerpc/boot/dts/fsl/p2041rdb.dts b/arch/powerpc/boot/dts/fsl/p2041rdb.dts index e9bd89406c4cb7cac33e59201c0271b8fd17cabd..e50fea95a853cb18239cce36c6edcec1276ee6b1 100644 --- a/arch/powerpc/boot/dts/fsl/p2041rdb.dts +++ b/arch/powerpc/boot/dts/fsl/p2041rdb.dts @@ -1,7 +1,7 @@ /* * P2041RDB Device Tree Source * - * Copyright 2011 - 2014 Freescale Semiconductor Inc. + * Copyright 2011 - 2015 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -41,6 +41,19 @@ #size-cells = <2>; interrupt-parent = <&mpic>; + aliases { + phy_rgmii_0 = &phy_rgmii_0; + phy_rgmii_1 = &phy_rgmii_1; + phy_sgmii_2 = &phy_sgmii_2; + phy_sgmii_3 = &phy_sgmii_3; + phy_sgmii_4 = &phy_sgmii_4; + phy_sgmii_1c = &phy_sgmii_1c; + phy_sgmii_1d = &phy_sgmii_1d; + phy_sgmii_1e = &phy_sgmii_1e; + phy_sgmii_1f = &phy_sgmii_1f; + phy_xgmii_2 = &phy_xgmii_2; + }; + memory { device_type = "memory"; }; @@ -83,7 +96,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spansion,s25sl12801"; + compatible = "spansion,s25sl12801", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <40000000>; /* input clock */ partition@u-boot { @@ -137,6 +150,83 @@ usb1: usb@211000 { dr_mode = "host"; }; + + fman@400000 { + ethernet@e0000 { + phy-handle = <&phy_sgmii_2>; + phy-connection-type = "sgmii"; + }; + + mdio@e1120 { + phy_rgmii_0: ethernet-phy@0 { + reg = <0x0>; + }; + + phy_rgmii_1: ethernet-phy@1 { + reg = <0x1>; + }; + + phy_sgmii_2: ethernet-phy@2 { + reg = <0x2>; + }; + + phy_sgmii_3: ethernet-phy@3 { + reg = <0x3>; + }; + + phy_sgmii_4: ethernet-phy@4 { + reg = <0x4>; + }; + + phy_sgmii_1c: ethernet-phy@1c { + reg = <0x1c>; + }; + + phy_sgmii_1d: ethernet-phy@1d { + reg = <0x1d>; + }; + + phy_sgmii_1e: ethernet-phy@1e { + reg = <0x1e>; + }; + + phy_sgmii_1f: ethernet-phy@1f { + reg = <0x1f>; + }; + }; + + ethernet@e2000 { + phy-handle = <&phy_sgmii_3>; + phy-connection-type = "sgmii"; + }; + + ethernet@e4000 { + phy-handle = <&phy_sgmii_4>; + phy-connection-type = "sgmii"; + }; + + ethernet@e6000 { + phy-handle = <&phy_rgmii_1>; + phy-connection-type = "rgmii"; + }; + + ethernet@e8000 { + phy-handle = <&phy_rgmii_0>; + phy-connection-type = "rgmii"; + }; + + ethernet@f0000 { + phy-handle = <&phy_xgmii_2>; + phy-connection-type = "xgmii"; + }; + + mdio@f1000 { + phy_xgmii_2: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0x0>; + }; + }; + }; }; rio: rapidio@ffe0c0000 { diff --git a/arch/powerpc/boot/dts/fsl/p3041ds.dts b/arch/powerpc/boot/dts/fsl/p3041ds.dts index f2b1d40334d44ffd490d114836dc945f66bca9bc..40748e415adbab4c448a4ef8cffa70f260d7d599 100644 --- a/arch/powerpc/boot/dts/fsl/p3041ds.dts +++ b/arch/powerpc/boot/dts/fsl/p3041ds.dts @@ -1,7 +1,7 @@ /* * P3041DS Device Tree Source * - * Copyright 2010 - 2014 Freescale Semiconductor Inc. + * Copyright 2010 - 2015 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -41,6 +41,20 @@ #size-cells = <2>; interrupt-parent = <&mpic>; + aliases{ + phy_rgmii_0 = &phy_rgmii_0; + phy_rgmii_1 = &phy_rgmii_1; + phy_sgmii_1c = &phy_sgmii_1c; + phy_sgmii_1d = &phy_sgmii_1d; + phy_sgmii_1e = &phy_sgmii_1e; + phy_sgmii_1f = &phy_sgmii_1f; + phy_xgmii_1 = &phy_xgmii_1; + phy_xgmii_2 = &phy_xgmii_2; + emi1_rgmii = &hydra_mdio_rgmii; + emi1_sgmii = &hydra_mdio_sgmii; + emi2_xgmii = &hydra_mdio_xgmii; + }; + memory { device_type = "memory"; }; @@ -83,7 +97,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spansion,s25sl12801"; + compatible = "spansion,s25sl12801", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <35000000>; /* input clock */ partition@u-boot { @@ -150,6 +164,52 @@ reg = <0x4c>; }; }; + + fman@400000{ + ethernet@e0000 { + phy-handle = <&phy_sgmii_1c>; + phy-connection-type = "sgmii"; + }; + + ethernet@e2000 { + phy-handle = <&phy_sgmii_1d>; + phy-connection-type = "sgmii"; + }; + + ethernet@e4000 { + phy-handle = <&phy_sgmii_1e>; + phy-connection-type = "sgmii"; + }; + + ethernet@e6000 { + phy-handle = <&phy_sgmii_1f>; + phy-connection-type = "sgmii"; + }; + + ethernet@e8000 { + phy-handle = <&phy_rgmii_1>; + phy-connection-type = "rgmii"; + }; + + ethernet@f0000 { + phy-handle = <&phy_xgmii_1>; + phy-connection-type = "xgmii"; + }; + + hydra_mdio_xgmii: mdio@f1000 { + status = "disabled"; + + phy_xgmii_1: ethernet-phy@4 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0x4>; + }; + + phy_xgmii_2: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0x0>; + }; + }; + }; }; rio: rapidio@ffe0c0000 { @@ -215,8 +275,58 @@ }; board-control@3,0 { + #address-cells = <1>; + #size-cells = <1>; compatible = "fsl,p3041ds-fpga", "fsl,fpga-ngpixis"; reg = <3 0 0x30>; + ranges = <0 3 0 0x30>; + + mdio-mux-emi1 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "mdio-mux-mmioreg", "mdio-mux"; + mdio-parent-bus = <&mdio0>; + reg = <9 1>; + mux-mask = <0x78>; + + hydra_mdio_rgmii: rgmii-mdio@8 { + #address-cells = <1>; + #size-cells = <0>; + reg = <8>; + status = "disabled"; + + phy_rgmii_0: ethernet-phy@0 { + reg = <0x0>; + }; + + phy_rgmii_1: ethernet-phy@1 { + reg = <0x1>; + }; + }; + + hydra_mdio_sgmii: sgmii-mdio@28 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x28>; + status = "disabled"; + + phy_sgmii_1c: ethernet-phy@1c { + reg = <0x1c>; + }; + + phy_sgmii_1d: ethernet-phy@1d { + reg = <0x1d>; + }; + + phy_sgmii_1e: ethernet-phy@1e { + reg = <0x1e>; + }; + + phy_sgmii_1f: ethernet-phy@1f { + reg = <0x1f>; + }; + }; + }; }; }; diff --git a/arch/powerpc/boot/dts/fsl/p4080ds.dts b/arch/powerpc/boot/dts/fsl/p4080ds.dts index 28a55c5e70998c0531cfa1db6b9bfe7c33e815f5..816b9788d5f675858cda98d25517d04181a3efe9 100644 --- a/arch/powerpc/boot/dts/fsl/p4080ds.dts +++ b/arch/powerpc/boot/dts/fsl/p4080ds.dts @@ -1,7 +1,7 @@ /* * P4080DS Device Tree Source * - * Copyright 2009 - 2014 Freescale Semiconductor Inc. + * Copyright 2009 - 2015 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -41,6 +41,20 @@ #size-cells = <2>; interrupt-parent = <&mpic>; + aliases { + phy_rgmii = &phyrgmii; + phy5_slot3 = &phy5slot3; + phy6_slot3 = &phy6slot3; + phy7_slot3 = &phy7slot3; + phy8_slot3 = &phy8slot3; + emi1_slot3 = &p4080mdio2; + emi1_slot4 = &p4080mdio1; + emi1_slot5 = &p4080mdio3; + emi1_rgmii = &p4080mdio0; + emi2_slot4 = &p4080xmdio1; + emi2_slot5 = &p4080xmdio3; + }; + memory { device_type = "memory"; }; @@ -84,7 +98,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spansion,s25sl12801"; + compatible = "spansion,s25sl12801", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <40000000>; /* input clock */ partition@u-boot { @@ -137,6 +151,60 @@ dr_mode = "host"; phy_type = "ulpi"; }; + + fman@400000 { + ethernet@e0000 { + phy-handle = <&phy0>; + phy-connection-type = "sgmii"; + }; + + ethernet@e2000 { + phy-handle = <&phy1>; + phy-connection-type = "sgmii"; + }; + + ethernet@e4000 { + phy-handle = <&phy2>; + phy-connection-type = "sgmii"; + }; + + ethernet@e6000 { + phy-handle = <&phy3>; + phy-connection-type = "sgmii"; + }; + + ethernet@f0000 { + phy-handle = <&phy10>; + phy-connection-type = "xgmii"; + }; + }; + + fman@500000 { + ethernet@e0000 { + phy-handle = <&phy5>; + phy-connection-type = "sgmii"; + }; + + ethernet@e2000 { + phy-handle = <&phy6>; + phy-connection-type = "sgmii"; + }; + + ethernet@e4000 { + phy-handle = <&phy7>; + phy-connection-type = "sgmii"; + }; + + ethernet@e6000 { + phy-handle = <&phy8>; + phy-connection-type = "sgmii"; + }; + + ethernet@f0000 { + phy-handle = <&phy11>; + phy-connection-type = "xgmii"; + }; + }; }; rio: rapidio@ffe0c0000 { @@ -213,6 +281,120 @@ }; }; + mdio-mux-emi1 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "mdio-mux-gpio", "mdio-mux"; + mdio-parent-bus = <&mdio0>; + gpios = <&gpio0 1 0>, <&gpio0 0 0>; + + p4080mdio0: mdio@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + phyrgmii: ethernet-phy@0 { + reg = <0x0>; + }; + }; + + p4080mdio1: mdio@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + + phy5: ethernet-phy@1c { + reg = <0x1c>; + }; + + phy6: ethernet-phy@1d { + reg = <0x1d>; + }; + + phy7: ethernet-phy@1e { + reg = <0x1e>; + }; + + phy8: ethernet-phy@1f { + reg = <0x1f>; + }; + }; + + p4080mdio2: mdio@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + status = "disabled"; + + phy5slot3: ethernet-phy@1c { + reg = <0x1c>; + }; + + phy6slot3: ethernet-phy@1d { + reg = <0x1d>; + }; + + phy7slot3: ethernet-phy@1e { + reg = <0x1e>; + }; + + phy8slot3: ethernet-phy@1f { + reg = <0x1f>; + }; + }; + + p4080mdio3: mdio@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + + phy0: ethernet-phy@1c { + reg = <0x1c>; + }; + + phy1: ethernet-phy@1d { + reg = <0x1d>; + }; + + phy2: ethernet-phy@1e { + reg = <0x1e>; + }; + + phy3: ethernet-phy@1f { + reg = <0x1f>; + }; + }; + }; + + mdio-mux-emi2 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "mdio-mux-gpio", "mdio-mux"; + mdio-parent-bus = <&xmdio0>; + gpios = <&gpio0 3 0>, <&gpio0 2 0>; + + p4080xmdio1: mdio@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + + phy11: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0x0>; + }; + }; + + p4080xmdio3: mdio@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + + phy10: ethernet-phy@4 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0x4>; + }; + }; + }; }; /include/ "p4080si-post.dtsi" diff --git a/arch/powerpc/boot/dts/fsl/p5020ds.dts b/arch/powerpc/boot/dts/fsl/p5020ds.dts index 920dc77b9c43f3737de3486d4e45ecedde921481..cd6f37386111a434955a398bbf848db7b727845d 100644 --- a/arch/powerpc/boot/dts/fsl/p5020ds.dts +++ b/arch/powerpc/boot/dts/fsl/p5020ds.dts @@ -1,7 +1,7 @@ /* * P5020DS Device Tree Source * - * Copyright 2010 - 2014 Freescale Semiconductor Inc. + * Copyright 2010 - 2015 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -41,6 +41,20 @@ #size-cells = <2>; interrupt-parent = <&mpic>; + aliases { + phy_rgmii_0 = &phy_rgmii_0; + phy_rgmii_1 = &phy_rgmii_1; + phy_sgmii_1c = &phy_sgmii_1c; + phy_sgmii_1d = &phy_sgmii_1d; + phy_sgmii_1e = &phy_sgmii_1e; + phy_sgmii_1f = &phy_sgmii_1f; + phy_xgmii_1 = &phy_xgmii_1; + phy_xgmii_2 = &phy_xgmii_2; + emi1_rgmii = &hydra_mdio_rgmii; + emi1_sgmii = &hydra_mdio_sgmii; + emi2_xgmii = &hydra_mdio_xgmii; + }; + memory { device_type = "memory"; }; @@ -83,7 +97,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spansion,s25sl12801"; + compatible = "spansion,s25sl12801", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <40000000>; /* input clock */ partition@u-boot { @@ -150,6 +164,52 @@ reg = <0x4c>; }; }; + + fman@400000 { + ethernet@e0000 { + phy-handle = <&phy_sgmii_1c>; + phy-connection-type = "sgmii"; + }; + + ethernet@e2000 { + phy-handle = <&phy_sgmii_1d>; + phy-connection-type = "sgmii"; + }; + + ethernet@e4000 { + phy-handle = <&phy_sgmii_1e>; + phy-connection-type = "sgmii"; + }; + + ethernet@e6000 { + phy-handle = <&phy_sgmii_1f>; + phy-connection-type = "sgmii"; + }; + + ethernet@e8000 { + phy-handle = <&phy_rgmii_1>; + phy-connection-type = "rgmii"; + }; + + ethernet@f0000 { + phy-handle = <&phy_xgmii_1>; + phy-connection-type = "xgmii"; + }; + + hydra_mdio_xgmii: mdio@f1000 { + status = "disabled"; + + phy_xgmii_1: ethernet-phy@4 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0x4>; + }; + + phy_xgmii_2: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0x0>; + }; + }; + }; }; rio: rapidio@ffe0c0000 { @@ -215,8 +275,58 @@ }; board-control@3,0 { + #address-cells = <1>; + #size-cells = <1>; compatible = "fsl,p5020ds-fpga", "fsl,fpga-ngpixis"; reg = <3 0 0x30>; + ranges = <0 3 0 0x30>; + + mdio-mux-emi1 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "mdio-mux-mmioreg", "mdio-mux"; + mdio-parent-bus = <&mdio0>; + reg = <9 1>; + mux-mask = <0x78>; + + hydra_mdio_rgmii: rgmii-mdio@8 { + #address-cells = <1>; + #size-cells = <0>; + reg = <8>; + status = "disabled"; + + phy_rgmii_0: ethernet-phy@0 { + reg = <0x0>; + }; + + phy_rgmii_1: ethernet-phy@1 { + reg = <0x1>; + }; + }; + + hydra_mdio_sgmii: sgmii-mdio@28 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x28>; + status = "disabled"; + + phy_sgmii_1c: ethernet-phy@1c { + reg = <0x1c>; + }; + + phy_sgmii_1d: ethernet-phy@1d { + reg = <0x1d>; + }; + + phy_sgmii_1e: ethernet-phy@1e { + reg = <0x1e>; + }; + + phy_sgmii_1f: ethernet-phy@1f { + reg = <0x1f>; + }; + }; + }; }; }; diff --git a/arch/powerpc/boot/dts/fsl/p5040ds.dts b/arch/powerpc/boot/dts/fsl/p5040ds.dts index e169cc297ea3e7afcf17e39f83a0896bfed7e14a..45084738cf4e5978d202b6a49606f1b7ce1d7a37 100644 --- a/arch/powerpc/boot/dts/fsl/p5040ds.dts +++ b/arch/powerpc/boot/dts/fsl/p5040ds.dts @@ -1,7 +1,7 @@ /* * P5040DS Device Tree Source * - * Copyright 2012 - 2014 Freescale Semiconductor Inc. + * Copyright 2012 - 2015 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -41,6 +41,32 @@ #size-cells = <2>; interrupt-parent = <&mpic>; + aliases{ + phy_sgmii_slot2_1c = &phy_sgmii_slot2_1c; + phy_sgmii_slot2_1d = &phy_sgmii_slot2_1d; + phy_sgmii_slot2_1e = &phy_sgmii_slot2_1e; + phy_sgmii_slot2_1f = &phy_sgmii_slot2_1f; + phy_sgmii_slot3_1c = &phy_sgmii_slot3_1c; + phy_sgmii_slot3_1d = &phy_sgmii_slot3_1d; + phy_sgmii_slot3_1e = &phy_sgmii_slot3_1e; + phy_sgmii_slot3_1f = &phy_sgmii_slot3_1f; + phy_sgmii_slot5_1c = &phy_sgmii_slot5_1c; + phy_sgmii_slot5_1d = &phy_sgmii_slot5_1d; + phy_sgmii_slot5_1e = &phy_sgmii_slot5_1e; + phy_sgmii_slot5_1f = &phy_sgmii_slot5_1f; + phy_sgmii_slot6_1c = &phy_sgmii_slot6_1c; + phy_sgmii_slot6_1d = &phy_sgmii_slot6_1d; + phy_sgmii_slot6_1e = &phy_sgmii_slot6_1e; + phy_sgmii_slot6_1f = &phy_sgmii_slot6_1f; + hydra_rg = &hydra_rg; + hydra_sg_slot2 = &hydra_sg_slot2; + hydra_sg_slot3 = &hydra_sg_slot3; + hydra_sg_slot5 = &hydra_sg_slot5; + hydra_sg_slot6 = &hydra_sg_slot6; + hydra_xg_slot1 = &hydra_xg_slot1; + hydra_xg_slot2 = &hydra_xg_slot2; + }; + memory { device_type = "memory"; }; @@ -83,7 +109,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spansion,s25sl12801"; + compatible = "spansion,s25sl12801", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <40000000>; /* input clock */ partition@u-boot { @@ -147,6 +173,62 @@ reg = <0x4c>; }; }; + + fman@400000 { + ethernet@e0000 { + phy-connection-type = "sgmii"; + }; + + ethernet@e2000 { + phy-connection-type = "sgmii"; + }; + + ethernet@e4000 { + phy-connection-type = "sgmii"; + }; + + ethernet@e6000 { + phy-connection-type = "sgmii"; + }; + + ethernet@e8000 { + phy-handle = <&phy_rgmii_0>; + phy-connection-type = "rgmii"; + }; + + ethernet@f0000 { + phy-handle = <&phy_xgmii_slot_2>; + phy-connection-type = "xgmii"; + }; + }; + + fman@500000 { + ethernet@e0000 { + phy-connection-type = "sgmii"; + }; + + ethernet@e2000 { + phy-connection-type = "sgmii"; + }; + + ethernet@e4000 { + phy-connection-type = "sgmii"; + }; + + ethernet@e6000 { + phy-connection-type = "sgmii"; + }; + + ethernet@e8000 { + phy-handle = <&phy_rgmii_1>; + phy-connection-type = "rgmii"; + }; + + ethernet@f0000 { + phy-handle = <&phy_xgmii_slot_1>; + phy-connection-type = "xgmii"; + }; + }; }; lbc: localbus@ffe124000 { @@ -200,8 +282,158 @@ }; board-control@3,0 { + #address-cells = <1>; + #size-cells = <1>; compatible = "fsl,p5040ds-fpga", "fsl,fpga-ngpixis"; reg = <3 0 0x40>; + ranges = <0 3 0 0x40>; + + mdio-mux-emi1 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "mdio-mux-mmioreg", "mdio-mux"; + mdio-parent-bus = <&mdio0>; + reg = <9 1>; + mux-mask = <0x78>; + + hydra_rg:rgmii-mdio@8 { + #address-cells = <1>; + #size-cells = <0>; + reg = <8>; + status = "disabled"; + + phy_rgmii_0: ethernet-phy@0 { + reg = <0x0>; + }; + + phy_rgmii_1: ethernet-phy@1 { + reg = <0x1>; + }; + }; + + hydra_sg_slot2: sgmii-mdio@28 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x28>; + status = "disabled"; + + phy_sgmii_slot2_1c: ethernet-phy@1c { + reg = <0x1c>; + }; + + phy_sgmii_slot2_1d: ethernet-phy@1d { + reg = <0x1d>; + }; + + phy_sgmii_slot2_1e: ethernet-phy@1e { + reg = <0x1e>; + }; + + phy_sgmii_slot2_1f: ethernet-phy@1f { + reg = <0x1f>; + }; + }; + + hydra_sg_slot3: sgmii-mdio@68 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x68>; + status = "disabled"; + + phy_sgmii_slot3_1c: ethernet-phy@1c { + reg = <0x1c>; + }; + + phy_sgmii_slot3_1d: ethernet-phy@1d { + reg = <0x1d>; + }; + + phy_sgmii_slot3_1e: ethernet-phy@1e { + reg = <0x1e>; + }; + + phy_sgmii_slot3_1f: ethernet-phy@1f { + reg = <0x1f>; + }; + }; + + hydra_sg_slot5: sgmii-mdio@38 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x38>; + status = "disabled"; + + phy_sgmii_slot5_1c: ethernet-phy@1c { + reg = <0x1c>; + }; + + phy_sgmii_slot5_1d: ethernet-phy@1d { + reg = <0x1d>; + }; + + phy_sgmii_slot5_1e: ethernet-phy@1e { + reg = <0x1e>; + }; + + phy_sgmii_slot5_1f: ethernet-phy@1f { + reg = <0x1f>; + }; + }; + hydra_sg_slot6: sgmii-mdio@48 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x48>; + status = "disabled"; + + phy_sgmii_slot6_1c: ethernet-phy@1c { + reg = <0x1c>; + }; + + phy_sgmii_slot6_1d: ethernet-phy@1d { + reg = <0x1d>; + }; + + phy_sgmii_slot6_1e: ethernet-phy@1e { + reg = <0x1e>; + }; + + phy_sgmii_slot6_1f: ethernet-phy@1f { + reg = <0x1f>; + }; + }; + }; + + mdio-mux-emi2 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "mdio-mux-mmioreg", "mdio-mux"; + mdio-parent-bus = <&xmdio0>; + reg = <9 1>; + mux-mask = <0x06>; + + hydra_xg_slot1: hydra-xg-slot1@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + status = "disabled"; + + phy_xgmii_slot_1: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <4>; + }; + }; + + hydra_xg_slot2: hydra-xg-slot2@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + + phy_xgmii_slot_2: ethernet-phy@4 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0>; + }; + }; + }; }; }; diff --git a/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi b/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi index 2f227b1345adc3190abf69aabf480e6b1ea4ac43..e2bd9313e6320bf27776759bc32e2085be599e36 100644 --- a/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi @@ -420,6 +420,7 @@ fsl,iommu-parent = <&pamu4>; }; +/include/ "qoriq-raid1.0-0.dtsi" /include/ "qoriq-qman1.dtsi" /include/ "qoriq-bman1.dtsi" diff --git a/arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi index 0659d5bb69b89ada92817ae65d43861895e588bc..dbd57750fc02d27ff7eefe6bcebe91c1c993b839 100644 --- a/arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi +++ b/arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi @@ -73,6 +73,12 @@ rtic_d = &rtic_d; sec_mon = &sec_mon; + raideng = &raideng; + raideng_jr0 = &raideng_jr0; + raideng_jr1 = &raideng_jr1; + raideng_jr2 = &raideng_jr2; + raideng_jr3 = &raideng_jr3; + fman0 = &fman0; fman1 = &fman1; ethernet0 = &enet0; diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0-best-effort.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0-best-effort.dtsi index 2e441fab6d8f5ba122735844f62ee14b1c92902c..e1a961f05dcd5b04b640827810cd198ff6fcb753 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0-best-effort.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0-best-effort.dtsi @@ -55,6 +55,7 @@ fman@400000 { reg = <0xe0000 0x1000>; fsl,fman-ports = <&fman0_rx_0x08 &fman0_tx_0x28>; ptp-timer = <&ptp_timer0>; + pcsphy-handle = <&pcsphy0>; }; mdio@e1000 { @@ -62,5 +63,9 @@ fman@400000 { #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xe1000 0x1000>; + + pcsphy0: ethernet-phy@0 { + reg = <0x0>; + }; }; }; diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0.dtsi index 0b8f87f79d1507f7d08a869d03da7c2f7560c4ad..c288f3c6c6378dc5fd3c20cf1605ecd031013c89 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-0.dtsi @@ -52,6 +52,7 @@ fman@400000 { compatible = "fsl,fman-memac"; reg = <0xf0000 0x1000>; fsl,fman-ports = <&fman0_rx_0x10 &fman0_tx_0x30>; + pcsphy-handle = <&pcsphy6>; }; mdio@f1000 { @@ -59,5 +60,9 @@ fman@400000 { #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xf1000 0x1000>; + + pcsphy6: ethernet-phy@0 { + reg = <0x0>; + }; }; }; diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1-best-effort.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1-best-effort.dtsi index ba6f2275d3f6128b55f14d28b54c6bfbd9426597..94f3e71750124b5c8a58861909d5d017b05262ca 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1-best-effort.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1-best-effort.dtsi @@ -55,6 +55,7 @@ fman@400000 { reg = <0xe2000 0x1000>; fsl,fman-ports = <&fman0_rx_0x09 &fman0_tx_0x29>; ptp-timer = <&ptp_timer0>; + pcsphy-handle = <&pcsphy1>; }; mdio@e3000 { @@ -62,5 +63,9 @@ fman@400000 { #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xe3000 0x1000>; + + pcsphy1: ethernet-phy@0 { + reg = <0x0>; + }; }; }; diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1.dtsi index 8860038055929ea8410975e3d37482f3ae0648bd..94a76982d214b7b963d4b66a9f5161793a2b8b55 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1.dtsi @@ -52,6 +52,7 @@ fman@400000 { compatible = "fsl,fman-memac"; reg = <0xf2000 0x1000>; fsl,fman-ports = <&fman0_rx_0x11 &fman0_tx_0x31>; + pcsphy-handle = <&pcsphy7>; }; mdio@f3000 { @@ -59,5 +60,9 @@ fman@400000 { #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xf3000 0x1000>; + + pcsphy7: ethernet-phy@0 { + reg = <0x0>; + }; }; }; diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-0.dtsi index ace9c13648ce3500a859c57612d7c88e30e0d45e..b5ff5f71c6b8b01874dd1b436e416409c2ac0759 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-0.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-0.dtsi @@ -51,6 +51,7 @@ fman@400000 { reg = <0xe0000 0x1000>; fsl,fman-ports = <&fman0_rx_0x08 &fman0_tx_0x28>; ptp-timer = <&ptp_timer0>; + pcsphy-handle = <&pcsphy0>; }; mdio@e1000 { @@ -58,5 +59,9 @@ fman@400000 { #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xe1000 0x1000>; + + pcsphy0: ethernet-phy@0 { + reg = <0x0>; + }; }; }; diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-1.dtsi index a4fc28654b31705da20e82681ca4d9f799707277..ee44182c634853566c9740b04631c3564e8bd020 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-1.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-1.dtsi @@ -51,6 +51,7 @@ fman@400000 { reg = <0xe2000 0x1000>; fsl,fman-ports = <&fman0_rx_0x09 &fman0_tx_0x29>; ptp-timer = <&ptp_timer0>; + pcsphy-handle = <&pcsphy1>; }; mdio@e3000 { @@ -58,5 +59,9 @@ fman@400000 { #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xe3000 0x1000>; + + pcsphy1: ethernet-phy@0 { + reg = <0x0>; + }; }; }; diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-2.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-2.dtsi index 78596faadf99335c83aedd6f89cd8e2fd10338c5..f05f0d775039b53aab57cdcd28fa8ac3ebde3490 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-2.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-2.dtsi @@ -51,6 +51,7 @@ fman@400000 { reg = <0xe4000 0x1000>; fsl,fman-ports = <&fman0_rx_0x0a &fman0_tx_0x2a>; ptp-timer = <&ptp_timer0>; + pcsphy-handle = <&pcsphy2>; }; mdio@e5000 { @@ -58,5 +59,9 @@ fman@400000 { #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xe5000 0x1000>; + + pcsphy2: ethernet-phy@0 { + reg = <0x0>; + }; }; }; diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-3.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-3.dtsi index af93abd86d78a4717ae4288b52068c943017568e..a9114ec510759e74036766b1ec1dbcaf42bcfa07 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-3.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-3.dtsi @@ -51,6 +51,7 @@ fman@400000 { reg = <0xe6000 0x1000>; fsl,fman-ports = <&fman0_rx_0x0b &fman0_tx_0x2b>; ptp-timer = <&ptp_timer0>; + pcsphy-handle = <&pcsphy3>; }; mdio@e7000 { @@ -58,5 +59,9 @@ fman@400000 { #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xe7000 0x1000>; + + pcsphy3: ethernet-phy@0 { + reg = <0x0>; + }; }; }; diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-4.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-4.dtsi index 97cffd74bf3df0186c204f5f49fdfc2e69fc7db3..44dd00ac7367fd6a100131eec3b7388741062383 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-4.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-4.dtsi @@ -51,6 +51,7 @@ fman@400000 { reg = <0xe8000 0x1000>; fsl,fman-ports = <&fman0_rx_0x0c &fman0_tx_0x2c>; ptp-timer = <&ptp_timer0>; + pcsphy-handle = <&pcsphy4>; }; mdio@e9000 { @@ -58,5 +59,9 @@ fman@400000 { #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xe9000 0x1000>; + + pcsphy4: ethernet-phy@0 { + reg = <0x0>; + }; }; }; diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-5.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-5.dtsi index 232c5c277bdbf2ea01a4d7ab13230503b49ac2f0..5b1b84b58602fa46e06cebb7be6b390d59372434 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-5.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-1g-5.dtsi @@ -51,6 +51,7 @@ fman@400000 { reg = <0xea000 0x1000>; fsl,fman-ports = <&fman0_rx_0x0d &fman0_tx_0x2d>; ptp-timer = <&ptp_timer0>; + pcsphy-handle = <&pcsphy5>; }; mdio@eb000 { @@ -58,5 +59,9 @@ fman@400000 { #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xeb000 0x1000>; + + pcsphy5: ethernet-phy@0 { + reg = <0x0>; + }; }; }; diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-0.dtsi index 89d64ee282b0916fd678900b8758f5b1ef7d4089..0e1daaef9e74b8fe2b6f51369a11c66b238e7dfd 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-0.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-0.dtsi @@ -52,6 +52,7 @@ fman@500000 { compatible = "fsl,fman-memac"; reg = <0xf0000 0x1000>; fsl,fman-ports = <&fman1_rx_0x10 &fman1_tx_0x30>; + pcsphy-handle = <&pcsphy14>; }; mdio@f1000 { @@ -59,5 +60,9 @@ fman@500000 { #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xf1000 0x1000>; + + pcsphy14: ethernet-phy@0 { + reg = <0x0>; + }; }; }; diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-1.dtsi index 7fa9260889c6249faeec6bd167190789ceaf77ac..68c5ef779266a8692e712a0ddcfa51db0822d945 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-1.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-10g-1.dtsi @@ -52,6 +52,7 @@ fman@500000 { compatible = "fsl,fman-memac"; reg = <0xf2000 0x1000>; fsl,fman-ports = <&fman1_rx_0x11 &fman1_tx_0x31>; + pcsphy-handle = <&pcsphy15>; }; mdio@f3000 { @@ -59,5 +60,9 @@ fman@500000 { #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xf3000 0x1000>; + + pcsphy15: ethernet-phy@0 { + reg = <0x0>; + }; }; }; diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-0.dtsi index 3d236662bf07479211860851536ab6e1e7dd3d42..605363cc1117fbf38b334e68a9b21815325cfe74 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-0.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-0.dtsi @@ -51,6 +51,7 @@ fman@500000 { reg = <0xe0000 0x1000>; fsl,fman-ports = <&fman1_rx_0x08 &fman1_tx_0x28>; ptp-timer = <&ptp_timer1>; + pcsphy-handle = <&pcsphy8>; }; mdio@e1000 { @@ -58,5 +59,9 @@ fman@500000 { #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xe1000 0x1000>; + + pcsphy8: ethernet-phy@0 { + reg = <0x0>; + }; }; }; diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-1.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-1.dtsi index 97dc2eedd462ea8112d5cab594aaeb918d8f45da..1955dfa136348f12ea29e0c4fdd3abb7438784fe 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-1.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-1.dtsi @@ -51,6 +51,7 @@ fman@500000 { reg = <0xe2000 0x1000>; fsl,fman-ports = <&fman1_rx_0x09 &fman1_tx_0x29>; ptp-timer = <&ptp_timer1>; + pcsphy-handle = <&pcsphy9>; }; mdio@e3000 { @@ -58,5 +59,9 @@ fman@500000 { #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xe3000 0x1000>; + + pcsphy9: ethernet-phy@0 { + reg = <0x0>; + }; }; }; diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-2.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-2.dtsi index f084dd2f0bec770b9ea127df1d79803fe46a259a..2c1476454ee01bb81069c325ed7c02c20f70963d 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-2.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-2.dtsi @@ -51,6 +51,7 @@ fman@500000 { reg = <0xe4000 0x1000>; fsl,fman-ports = <&fman1_rx_0x0a &fman1_tx_0x2a>; ptp-timer = <&ptp_timer1>; + pcsphy-handle = <&pcsphy10>; }; mdio@e5000 { @@ -58,5 +59,9 @@ fman@500000 { #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xe5000 0x1000>; + + pcsphy10: ethernet-phy@0 { + reg = <0x0>; + }; }; }; diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-3.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-3.dtsi index bb627b3bf3db2ba4408142e8cb6d22597c82cc22..b8b541ff5fb034e597c427431e15b4e01ed0de26 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-3.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-3.dtsi @@ -51,6 +51,7 @@ fman@500000 { reg = <0xe6000 0x1000>; fsl,fman-ports = <&fman1_rx_0x0b &fman1_tx_0x2b>; ptp-timer = <&ptp_timer1>; + pcsphy-handle = <&pcsphy11>; }; mdio@e7000 { @@ -58,5 +59,9 @@ fman@500000 { #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xe7000 0x1000>; + + pcsphy11: ethernet-phy@0 { + reg = <0x0>; + }; }; }; diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-4.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-4.dtsi index 821ed12225d4e99c8612c94dbb76f2de31097ab6..4b2cfddd1b1553bbb34d53a236cd399fb96441b1 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-4.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-4.dtsi @@ -51,6 +51,7 @@ fman@500000 { reg = <0xe8000 0x1000>; fsl,fman-ports = <&fman1_rx_0x0c &fman1_tx_0x2c>; ptp-timer = <&ptp_timer1>; + pcsphy-handle = <&pcsphy12>; }; mdio@e9000 { @@ -58,5 +59,9 @@ fman@500000 { #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xe9000 0x1000>; + + pcsphy12: ethernet-phy@0 { + reg = <0x0>; + }; }; }; diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-5.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-5.dtsi index e245f1a1e42a8665fb53001d1eae96d0a619251d..0a52ddf7cc171e6b830bc2707bc0be9d8ac26ee0 100644 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-5.dtsi +++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3-1-1g-5.dtsi @@ -51,6 +51,7 @@ fman@500000 { reg = <0xea000 0x1000>; fsl,fman-ports = <&fman1_rx_0x0d &fman1_tx_0x2d>; ptp-timer = <&ptp_timer1>; + pcsphy-handle = <&pcsphy13>; }; mdio@eb000 { @@ -58,5 +59,9 @@ fman@500000 { #size-cells = <0>; compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; reg = <0xeb000 0x1000>; + + pcsphy13: ethernet-phy@0 { + reg = <0x0>; + }; }; }; diff --git a/arch/powerpc/boot/dts/fsl/sbc8641d.dts b/arch/powerpc/boot/dts/fsl/sbc8641d.dts new file mode 100644 index 0000000000000000000000000000000000000000..0a9733cd418db8540deaf4af5d4856c94e604d31 --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/sbc8641d.dts @@ -0,0 +1,203 @@ +/* + * SBC8641D Device Tree Source + * + * Copyright 2008 Wind River Systems Inc. + * + * Paul Gortmaker (see MAINTAINERS for contact information) + * + * Based largely on the mpc8641_hpcn.dts by Freescale Semiconductor Inc. + * + * 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/ "mpc8641si-pre.dtsi" + +/ { + model = "SBC8641D"; + compatible = "wind,sbc8641"; + + aliases { + pci1 = &pci1; + }; + + memory { + device_type = "memory"; + reg = <0x00000000 0x20000000>; // 512M at 0x0 + }; + + lbc: localbus@f8005000 { + reg = <0xf8005000 0x1000>; + + ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash + 1 0 0xf0000000 0x00010000 // 64KB EEPROM + 2 0 0xf1000000 0x00100000 // EPLD (1MB) + 3 0 0xe0000000 0x04000000 // 64MB LB SDRAM (CS3) + 4 0 0xe4000000 0x04000000 // 64MB LB SDRAM (CS4) + 6 0 0xf4000000 0x00100000 // LCD display (1MB) + 7 0 0xe8000000 0x04000000>; // 64MB OneNAND + + flash@0,0 { + compatible = "cfi-flash"; + reg = <0 0 0x01000000>; + bank-width = <2>; + device-width = <2>; + #address-cells = <1>; + #size-cells = <1>; + partition@0 { + label = "dtb"; + reg = <0x00000000 0x00100000>; + read-only; + }; + partition@300000 { + label = "kernel"; + reg = <0x00100000 0x00400000>; + read-only; + }; + partition@400000 { + label = "fs"; + reg = <0x00500000 0x00a00000>; + }; + partition@700000 { + label = "firmware"; + reg = <0x00f00000 0x00100000>; + read-only; + }; + }; + + epld@2,0 { + compatible = "wrs,epld-localbus"; + #address-cells = <2>; + #size-cells = <1>; + reg = <2 0 0x100000>; + ranges = <0 0 5 0 1 // User switches + 1 0 5 1 1 // Board ID/Rev + 3 0 5 3 1>; // LEDs + }; + }; + + soc: soc@f8000000 { + ranges = <0x00000000 0xf8000000 0x00100000>; + + enet0: ethernet@24000 { + tbi-handle = <&tbi0>; + phy-handle = <&phy0>; + phy-connection-type = "rgmii-id"; + }; + + mdio@24520 { + phy0: ethernet-phy@1f { + reg = <0x1f>; + }; + phy1: ethernet-phy@0 { + reg = <0>; + }; + phy2: ethernet-phy@1 { + reg = <1>; + }; + phy3: ethernet-phy@2 { + reg = <2>; + }; + tbi0: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + enet1: ethernet@25000 { + tbi-handle = <&tbi1>; + phy-handle = <&phy1>; + phy-connection-type = "rgmii-id"; + }; + + mdio@25520 { + tbi1: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + enet2: ethernet@26000 { + tbi-handle = <&tbi2>; + phy-handle = <&phy2>; + phy-connection-type = "rgmii-id"; + }; + + mdio@26520 { + tbi2: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + + enet3: ethernet@27000 { + tbi-handle = <&tbi3>; + phy-handle = <&phy3>; + phy-connection-type = "rgmii-id"; + }; + + mdio@27520 { + tbi3: tbi-phy@11 { + reg = <0x11>; + device_type = "tbi-phy"; + }; + }; + }; + + pci0: pcie@f8008000 { + reg = <0xf8008000 0x1000>; + ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x20000000 + 0x01000000 0x0 0x00000000 0xe2000000 0x0 0x00100000>; + interrupt-map-mask = <0xff00 0 0 7>; + + pcie@0 { + ranges = <0x02000000 0x0 0x80000000 + 0x02000000 0x0 0x80000000 + 0x0 0x20000000 + + 0x01000000 0x0 0x00000000 + 0x01000000 0x0 0x00000000 + 0x0 0x00100000>; + }; + + }; + + pci1: pcie@f8009000 { + compatible = "fsl,mpc8641-pcie"; + device_type = "pci"; + #size-cells = <2>; + #address-cells = <3>; + reg = <0xf8009000 0x1000>; + bus-range = <0 0xff>; + ranges = <0x02000000 0x0 0xa0000000 0xa0000000 0x0 0x20000000 + 0x01000000 0x0 0x00000000 0xe3000000 0x0 0x00100000>; + clock-frequency = <100000000>; + interrupts = <25 2 0 0>; + interrupt-map-mask = <0xf800 0 0 7>; + interrupt-map = < + /* IDSEL 0x0 */ + 0x0000 0 0 1 &mpic 4 1 + 0x0000 0 0 2 &mpic 5 1 + 0x0000 0 0 3 &mpic 6 1 + 0x0000 0 0 4 &mpic 7 1 + >; + + pcie@0 { + reg = <0 0 0 0 0>; + #size-cells = <2>; + #address-cells = <3>; + device_type = "pci"; + ranges = <0x02000000 0x0 0xa0000000 + 0x02000000 0x0 0xa0000000 + 0x0 0x20000000 + + 0x01000000 0x0 0x00000000 + 0x01000000 0x0 0x00000000 + 0x0 0x00100000>; + }; + }; +}; + +/include/ "mpc8641si-post.dtsi" diff --git a/arch/powerpc/boot/dts/fsl/t1023rdb.dts b/arch/powerpc/boot/dts/fsl/t1023rdb.dts index 6bd842beb1dcfbb019a6d033079ccb530048f43c..29757623e5bafe8e29b47244275dbce25ff444a0 100644 --- a/arch/powerpc/boot/dts/fsl/t1023rdb.dts +++ b/arch/powerpc/boot/dts/fsl/t1023rdb.dts @@ -79,7 +79,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "spansion,s25fl512s"; + compatible = "spansion,s25fl512s", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <10000000>; /* input clk */ }; @@ -111,6 +111,47 @@ shunt-resistor = <1000>; }; }; + + fman@400000 { + fm1mac1: ethernet@e0000 { + phy-handle = <&sgmii_rtk_phy2>; + phy-connection-type = "sgmii"; + sleep = <&rcpm 0x80000000>; + }; + + fm1mac2: ethernet@e2000 { + sleep = <&rcpm 0x40000000>; + }; + + fm1mac3: ethernet@e4000 { + phy-handle = <&sgmii_aqr_phy3>; + phy-connection-type = "sgmii-2500"; + sleep = <&rcpm 0x20000000>; + }; + + fm1mac4: ethernet@e6000 { + phy-handle = <&rgmii_rtk_phy1>; + phy-connection-type = "rgmii"; + sleep = <&rcpm 0x10000000>; + }; + + + mdio0: mdio@fc000 { + rgmii_rtk_phy1: ethernet-phy@1 { + reg = <0x1>; + }; + sgmii_rtk_phy2: ethernet-phy@3 { + reg = <0x3>; + }; + }; + + xmdio0: mdio@fd000 { + sgmii_aqr_phy3: ethernet-phy@2 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0x2>; + }; + }; + }; }; pci0: pcie@ffe240000 { diff --git a/arch/powerpc/boot/dts/fsl/t1024qds.dts b/arch/powerpc/boot/dts/fsl/t1024qds.dts index 6a3581b8e1f85e235b995ed831aa08861a5081e1..772143da367ff0c0fb20c7fa1eb8b02cdeed6b61 100644 --- a/arch/powerpc/boot/dts/fsl/t1024qds.dts +++ b/arch/powerpc/boot/dts/fsl/t1024qds.dts @@ -87,7 +87,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "micron,n25q128a11"; /* 16MB */ + compatible = "micron,n25q128a11", "jedec,spi-nor"; /* 16MB */ reg = <0>; spi-max-frequency = <10000000>; }; @@ -95,7 +95,7 @@ flash@1 { #address-cells = <1>; #size-cells = <1>; - compatible = "sst,sst25wf040"; /* 512KB */ + compatible = "sst,sst25wf040", "jedec,spi-nor"; /* 512KB */ reg = <1>; spi-max-frequency = <10000000>; }; @@ -103,7 +103,7 @@ flash@2 { #address-cells = <1>; #size-cells = <1>; - compatible = "eon,en25s64"; /* 8MB */ + compatible = "eon,en25s64", "jedec,spi-nor"; /* 8MB */ reg = <2>; spi-max-frequency = <10000000>; }; diff --git a/arch/powerpc/boot/dts/fsl/t1024rdb.dts b/arch/powerpc/boot/dts/fsl/t1024rdb.dts index 0ccc7d03335eb7e3ca1ba1e280cf2f523ecddd53..302cdd22b4bbbeba487190c6433fddcce91899c8 100644 --- a/arch/powerpc/boot/dts/fsl/t1024rdb.dts +++ b/arch/powerpc/boot/dts/fsl/t1024rdb.dts @@ -89,7 +89,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "micron,n25q512ax3"; + compatible = "micron,n25q512ax3", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <10000000>; /* input clk */ }; @@ -140,6 +140,51 @@ #size-cells = <0>; }; }; + + fman@400000 { + fm1mac1: ethernet@e0000 { + phy-handle = <&xg_aqr105_phy3>; + phy-connection-type = "xgmii"; + sleep = <&rcpm 0x80000000>; + }; + + fm1mac2: ethernet@e2000 { + sleep = <&rcpm 0x40000000>; + }; + + fm1mac3: ethernet@e4000 { + phy-handle = <&rgmii_phy2>; + phy-connection-type = "rgmii"; + sleep = <&rcpm 0x20000000>; + }; + + fm1mac4: ethernet@e6000 { + phy-handle = <&rgmii_phy1>; + phy-connection-type = "rgmii"; + sleep = <&rcpm 0x10000000>; + }; + + + mdio0: mdio@fc000 { + rgmii_phy1: ethernet-phy@2 { + reg = <0x2>; + }; + rgmii_phy2: ethernet-phy@6 { + reg = <0x6>; + }; + }; + + xmdio0: mdio@fd000 { + xg_aqr105_phy3: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0x1>; + }; + sg_2500_aqr105_phy4: ethernet-phy@2 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0x2>; + }; + }; + }; }; pci0: pcie@ffe240000 { diff --git a/arch/powerpc/boot/dts/fsl/t1040rdb.dts b/arch/powerpc/boot/dts/fsl/t1040rdb.dts index cf194154bbdce37151403052608a29514dace66c..621f2c6ee6ad51829f764f103e9f177079c46ed4 100644 --- a/arch/powerpc/boot/dts/fsl/t1040rdb.dts +++ b/arch/powerpc/boot/dts/fsl/t1040rdb.dts @@ -1,7 +1,7 @@ /* * T1040RDB Device Tree Source * - * Copyright 2014 Freescale Semiconductor Inc. + * Copyright 2014 - 2015 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -38,6 +38,36 @@ / { model = "fsl,T1040RDB"; compatible = "fsl,T1040RDB"; + + aliases { + phy_sgmii_2 = &phy_sgmii_2; + }; + + soc@ffe000000 { + fman@400000 { + ethernet@e0000 { + fixed-link = <0 1 1000 0 0>; + phy-connection-type = "sgmii"; + }; + + ethernet@e2000 { + fixed-link = <1 1 1000 0 0>; + phy-connection-type = "sgmii"; + }; + + ethernet@e4000 { + phy-handle = <&phy_sgmii_2>; + phy-connection-type = "sgmii"; + }; + + mdio@fc000 { + phy_sgmii_2: ethernet-phy@03 { + reg = <0x03>; + }; + }; + }; + }; + ifc: localbus@ffe124000 { cpld@3,0 { compatible = "fsl,t1040rdb-cpld"; diff --git a/arch/powerpc/boot/dts/fsl/t1042rdb.dts b/arch/powerpc/boot/dts/fsl/t1042rdb.dts index 8d908e795e4db42c71d5b12d067ae3cbb7b062e7..2c138627b1b4344a7292e18144252363848fcb1e 100644 --- a/arch/powerpc/boot/dts/fsl/t1042rdb.dts +++ b/arch/powerpc/boot/dts/fsl/t1042rdb.dts @@ -1,7 +1,7 @@ /* * T1042RDB Device Tree Source * - * Copyright 2014 Freescale Semiconductor Inc. + * Copyright 2014 - 2015 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -38,6 +38,34 @@ / { model = "fsl,T1042RDB"; compatible = "fsl,T1042RDB"; + + aliases { + phy_sgmii_2 = &phy_sgmii_2; + }; + + soc@ffe000000 { + fman@400000 { + ethernet@e0000 { + status = "disabled"; + }; + + ethernet@e2000 { + status = "disabled"; + }; + + ethernet@e4000 { + phy-handle = <&phy_sgmii_2>; + phy-connection-type = "sgmii"; + }; + + mdio@fc000 { + phy_sgmii_2: ethernet-phy@03 { + reg = <0x03>; + }; + }; + }; + }; + ifc: localbus@ffe124000 { cpld@3,0 { compatible = "fsl,t1042rdb-cpld"; diff --git a/arch/powerpc/boot/dts/fsl/t1042rdb_pi.dts b/arch/powerpc/boot/dts/fsl/t1042rdb_pi.dts index 98c001019d6a39c8e06cceaabea68687341c579d..8ec3ff45e6fc70a93b8afbe17dddb73dd12a7077 100644 --- a/arch/powerpc/boot/dts/fsl/t1042rdb_pi.dts +++ b/arch/powerpc/boot/dts/fsl/t1042rdb_pi.dts @@ -1,7 +1,7 @@ /* * T1042RDB_PI Device Tree Source * - * Copyright 2014 Freescale Semiconductor Inc. + * Copyright 2014 - 2015 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -38,11 +38,13 @@ / { model = "fsl,T1042RDB_PI"; compatible = "fsl,T1042RDB_PI"; + ifc: localbus@ffe124000 { cpld@3,0 { compatible = "fsl,t1042rdb_pi-cpld"; }; }; + soc: soc@ffe000000 { i2c@118000 { rtc@68 { @@ -51,6 +53,20 @@ interrupts = <0x2 0x1 0 0>; }; }; + + fman@400000 { + ethernet@e0000 { + status = "disabled"; + }; + + ethernet@e2000 { + status = "disabled"; + }; + + ethernet@e4000 { + status = "disabled"; + }; + }; }; }; diff --git a/arch/powerpc/boot/dts/fsl/t104xd4rdb.dtsi b/arch/powerpc/boot/dts/fsl/t104xd4rdb.dtsi index 3f6d7c6a106b7d18fe52afe6cc3cbb6dbf450fc9..8c7ea6c05de93e38508976405c936d0cc2f10fbe 100644 --- a/arch/powerpc/boot/dts/fsl/t104xd4rdb.dtsi +++ b/arch/powerpc/boot/dts/fsl/t104xd4rdb.dtsi @@ -104,7 +104,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "micron,n25q512ax3"; + compatible = "micron,n25q512ax3", "jedec,spi-nor"; reg = <0>; /* input clock */ spi-max-frequency = <10000000>; diff --git a/arch/powerpc/boot/dts/fsl/t104xqds.dtsi b/arch/powerpc/boot/dts/fsl/t104xqds.dtsi index 1498d1e4aecf6338244e71b0b4f9c35b05d9883f..977af355b388104be13fe26b1f9b899772e72daa 100644 --- a/arch/powerpc/boot/dts/fsl/t104xqds.dtsi +++ b/arch/powerpc/boot/dts/fsl/t104xqds.dtsi @@ -1,7 +1,7 @@ /* * T104xQDS Device Tree Source * - * Copyright 2013 - 2014 Freescale Semiconductor Inc. + * Copyright 2013 - 2015 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -38,6 +38,33 @@ #size-cells = <2>; interrupt-parent = <&mpic>; + aliases { + emi1_rgmii0 = &t1040mdio0; + emi1_rgmii1 = &t1040mdio1; + emi1_slot3 = &t1040mdio3; + emi1_slot5 = &t1040mdio5; + emi1_slot6 = &t1040mdio6; + emi1_slot7 = &t1040mdio7; + rgmii_phy1 = &rgmii_phy1; + rgmii_phy2 = &rgmii_phy2; + phy_s3_01 = &phy_s3_01; + phy_s3_02 = &phy_s3_02; + phy_s3_03 = &phy_s3_03; + phy_s3_04 = &phy_s3_04; + phy_s5_01 = &phy_s5_01; + phy_s5_02 = &phy_s5_02; + phy_s5_03 = &phy_s5_03; + phy_s5_04 = &phy_s5_04; + phy_s6_01 = &phy_s6_01; + phy_s6_02 = &phy_s6_02; + phy_s6_03 = &phy_s6_03; + phy_s6_04 = &phy_s6_04; + phy_s7_01 = &phy_s7_01; + phy_s7_02 = &phy_s7_02; + phy_s7_03 = &phy_s7_03; + phy_s7_04 = &phy_s7_04; + }; + reserved-memory { #address-cells = <2>; #size-cells = <2>; @@ -85,6 +112,128 @@ #size-cells = <1>; compatible = "fsl,fpga-qixis"; reg = <3 0 0x300>; + ranges = <0 3 0 0x300>; + + mdio-mux-emi1 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "mdio-mux-mmioreg", "mdio-mux"; + mdio-parent-bus = <&mdio0>; + reg = <0x54 1>; + mux-mask = <0xe0>; + + t1040mdio0: mdio@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x00>; + status = "disabled"; + + rgmii_phy1: ethernet-phy@1 { + reg = <0x1>; + }; + }; + + t1040mdio1: mdio@20 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x20>; + status = "disabled"; + + rgmii_phy2: ethernet-phy@2 { + reg = <0x2>; + }; + }; + + t1040mdio3: mdio@60 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x60>; + status = "disabled"; + + phy_s3_01: ethernet-phy@1c { + reg = <0x1c>; + }; + + phy_s3_02: ethernet-phy@1d { + reg = <0x1d>; + }; + + phy_s3_03: ethernet-phy@1e { + reg = <0x1e>; + }; + + phy_s3_04: ethernet-phy@1f { + reg = <0x1f>; + }; + }; + + t1040mdio5: mdio@a0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0xa0>; + + phy_s5_01: ethernet-phy@1c { + reg = <0x14>; + }; + + phy_s5_02: ethernet-phy@1d { + reg = <0x15>; + }; + + phy_s5_03: ethernet-phy@1e { + reg = <0x16>; + }; + + phy_s5_04: ethernet-phy@1f { + reg = <0x17>; + }; + }; + + t1040mdio6: mdio@c0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0xc0>; + + phy_s6_01: ethernet-phy@1c { + reg = <0x18>; + }; + + phy_s6_02: ethernet-phy@1d { + reg = <0x19>; + }; + + phy_s6_03: ethernet-phy@1e { + reg = <0x1a>; + }; + + phy_s6_04: ethernet-phy@1f { + reg = <0x1b>; + }; + }; + + t1040mdio7: mdio@e0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0xe0>; + status = "disabled"; + + phy_s7_01: ethernet-phy@1c { + reg = <0x1c>; + }; + + phy_s7_02: ethernet-phy@1d { + reg = <0x1d>; + }; + + phy_s7_03: ethernet-phy@1e { + reg = <0x1e>; + }; + + phy_s7_04: ethernet-phy@1f { + reg = <0x1f>; + }; + }; + }; }; }; @@ -112,7 +261,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "micron,n25q128a11"; + compatible = "micron,n25q128a11", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <10000000>; /* input clock */ }; @@ -129,6 +278,33 @@ interrupts = <0x1 0x1 0 0>; }; }; + + fman@400000 { + ethernet@e0000 { + fixed-link = <0 1 1000 0 0>; + phy-connection-type = "sgmii"; + }; + + ethernet@e2000 { + fixed-link = <1 1 1000 0 0>; + phy-connection-type = "sgmii"; + }; + + ethernet@e4000 { + phy-handle = <&phy_s7_03>; + phy-connection-type = "sgmii"; + }; + + ethernet@e6000 { + phy-handle = <&rgmii_phy1>; + phy-connection-type = "rgmii"; + }; + + ethernet@e8000 { + phy-handle = <&rgmii_phy2>; + phy-connection-type = "rgmii"; + }; + }; }; pci0: pcie@ffe240000 { diff --git a/arch/powerpc/boot/dts/fsl/t104xrdb.dtsi b/arch/powerpc/boot/dts/fsl/t104xrdb.dtsi index 830ea484295b846e5b07f1b05998f07760f7fa80..72691ef102ee75141d45bb6fee300127b4cf2e74 100644 --- a/arch/powerpc/boot/dts/fsl/t104xrdb.dtsi +++ b/arch/powerpc/boot/dts/fsl/t104xrdb.dtsi @@ -1,7 +1,7 @@ /* * T1040RDB/T1042RDB Device Tree Source * - * Copyright 2014 Freescale Semiconductor Inc. + * Copyright 2014 - 2015 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -33,6 +33,12 @@ */ / { + aliases { + phy_rgmii_0 = &phy_rgmii_0; + phy_rgmii_1 = &phy_rgmii_1; + phy_sgmii_2 = &phy_sgmii_2; + }; + reserved-memory { #address-cells = <2>; #size-cells = <2>; @@ -103,10 +109,15 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "micron,n25q512a"; + compatible = "micron,n25q512a", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <10000000>; /* input clock */ }; + slic@3 { + compatible = "maxim,ds26522"; + reg = <3>; + spi-max-frequency = <2000000>; /* input clock */ + }; }; i2c@118000 { @@ -125,6 +136,31 @@ }; }; + fman@400000 { + ethernet@e6000 { + phy-handle = <&phy_rgmii_0>; + phy-connection-type = "rgmii"; + }; + + ethernet@e8000 { + phy-handle = <&phy_rgmii_1>; + phy-connection-type = "rgmii"; + }; + + mdio0: mdio@fc000 { + phy_sgmii_2: ethernet-phy@03 { + reg = <0x03>; + }; + + phy_rgmii_0: ethernet-phy@01 { + reg = <0x01>; + }; + + phy_rgmii_1: ethernet-phy@02 { + reg = <0x02>; + }; + }; + }; }; pci0: pcie@ffe240000 { diff --git a/arch/powerpc/boot/dts/fsl/t2080qds.dts b/arch/powerpc/boot/dts/fsl/t2080qds.dts index 9c8e10fe04cbbf55ac6111a749f7a2a959238abf..8d190e8c62cefecbdd959aa16b9999b57672f08b 100644 --- a/arch/powerpc/boot/dts/fsl/t2080qds.dts +++ b/arch/powerpc/boot/dts/fsl/t2080qds.dts @@ -1,7 +1,7 @@ /* * T2080QDS Device Tree Source * - * Copyright 2013 Freescale Semiconductor Inc. + * Copyright 2013 - 2015 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -42,6 +42,12 @@ #size-cells = <2>; interrupt-parent = <&mpic>; + aliases { + emi1_slot1 = &t2080mdio2; + emi1_slot2 = &t2080mdio3; + emi1_slot3 = &t2080mdio4; + }; + rio: rapidio@ffe0c0000 { reg = <0xf 0xfe0c0000 0 0x11000>; @@ -54,4 +60,154 @@ }; }; +&soc { + fman@400000 { + ethernet@e0000 { + phy-handle = <&phy_sgmii_s3_1e>; + phy-connection-type = "xgmii"; + }; + + ethernet@e2000 { + phy-handle = <&phy_sgmii_s3_1f>; + phy-connection-type = "xgmii"; + }; + + ethernet@e4000 { + phy-handle = <&rgmii_phy1>; + phy-connection-type = "rgmii"; + }; + + ethernet@e6000 { + phy-handle = <&rgmii_phy2>; + phy-connection-type = "rgmii"; + }; + + ethernet@e8000 { + phy-handle = <&phy_sgmii_s2_1e>; + phy-connection-type = "sgmii"; + }; + + ethernet@ea000 { + phy-handle = <&phy_sgmii_s2_1d>; + phy-connection-type = "sgmii"; + }; + + ethernet@f0000 { + phy-handle = <&phy_xaui_slot3>; + phy-connection-type = "xgmii"; + }; + + ethernet@f2000 { + phy-handle = <&phy_sgmii_s3_1f>; + phy-connection-type = "xgmii"; + }; + + mdio@fd000 { + phy_xaui_slot3: ethernet-phy@3 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0x3>; + }; + }; + }; +}; + +&boardctrl { + mdio-mux-emi1 { + compatible = "mdio-mux-mmioreg", "mdio-mux"; + mdio-parent-bus = <&mdio0>; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x54 1>; + mux-mask = <0xe0>; + + t2080mdio0: mdio@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + rgmii_phy1: ethernet-phy@1 { + reg = <0x1>; + }; + }; + + t2080mdio1: mdio@20 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x20>; + + rgmii_phy2: ethernet-phy@2 { + reg = <0x2>; + }; + }; + + t2080mdio2: mdio@40 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40>; + status = "disabled"; + + phy_sgmii_s1_1c: ethernet-phy@1c { + reg = <0x1c>; + }; + + phy_sgmii_s1_1d: ethernet-phy@1d { + reg = <0x1d>; + }; + + phy_sgmii_s1_1e: ethernet-phy@1e { + reg = <0x1e>; + }; + + phy_sgmii_s1_1f: ethernet-phy@1f { + reg = <0x1f>; + }; + }; + + t2080mdio3: mdio@c0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0xc0>; + + phy_sgmii_s2_1c: ethernet-phy@1c { + reg = <0x1c>; + }; + + phy_sgmii_s2_1d: ethernet-phy@1d { + reg = <0x1d>; + }; + + phy_sgmii_s2_1e: ethernet-phy@1e { + reg = <0x1e>; + }; + + phy_sgmii_s2_1f: ethernet-phy@1f { + reg = <0x1f>; + }; + }; + + t2080mdio4: mdio@60 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x60>; + status = "disabled"; + + phy_sgmii_s3_1c: ethernet-phy@1c { + reg = <0x1c>; + }; + + phy_sgmii_s3_1d: ethernet-phy@1d { + reg = <0x1d>; + }; + + phy_sgmii_s3_1e: ethernet-phy@1e { + reg = <0x1e>; + }; + + phy_sgmii_s3_1f: ethernet-phy@1f { + reg = <0x1f>; + }; + }; + }; +}; + /include/ "t2080si-post.dtsi" diff --git a/arch/powerpc/boot/dts/fsl/t2080rdb.dts b/arch/powerpc/boot/dts/fsl/t2080rdb.dts index 33205bf08919f49e9a8434c39c78cd798a86eaa1..836e4c965b227387c6b0c42c7932ea5a4585a9f7 100644 --- a/arch/powerpc/boot/dts/fsl/t2080rdb.dts +++ b/arch/powerpc/boot/dts/fsl/t2080rdb.dts @@ -1,7 +1,7 @@ /* * T2080PCIe-RDB Board Device Tree Source * - * Copyright 2014 Freescale Semiconductor Inc. + * Copyright 2014 - 2015 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -54,4 +54,69 @@ }; }; +&soc { + fman@400000 { + ethernet@e0000 { + phy-handle = <&xg_aq1202_phy3>; + phy-connection-type = "xgmii"; + }; + + ethernet@e2000 { + phy-handle = <&xg_aq1202_phy4>; + phy-connection-type = "xgmii"; + }; + + ethernet@e4000 { + phy-handle = <&rgmii_phy1>; + phy-connection-type = "rgmii"; + }; + + ethernet@e6000 { + phy-handle = <&rgmii_phy2>; + phy-connection-type = "rgmii"; + }; + + ethernet@f0000 { + phy-handle = <&xg_cs4315_phy1>; + phy-connection-type = "xgmii"; + }; + + ethernet@f2000 { + phy-handle = <&xg_cs4315_phy2>; + phy-connection-type = "xgmii"; + }; + + mdio@fc000 { + rgmii_phy1: ethernet-phy@1 { + reg = <0x1>; + }; + rgmii_phy2: ethernet-phy@2 { + reg = <0x2>; + }; + }; + + mdio@fd000 { + xg_cs4315_phy1: ethernet-phy@c { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0xc>; + }; + + xg_cs4315_phy2: ethernet-phy@d { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0xd>; + }; + + xg_aq1202_phy3: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0x0>; + }; + + xg_aq1202_phy4: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0x1>; + }; + }; + }; +}; + /include/ "t2080si-post.dtsi" diff --git a/arch/powerpc/boot/dts/fsl/t2081qds.dts b/arch/powerpc/boot/dts/fsl/t2081qds.dts index b81213596dbfabdb3038413e28bdb18449e65a7f..fc5c4a30f7ad7907b4728ec66bb24e120a704799 100644 --- a/arch/powerpc/boot/dts/fsl/t2081qds.dts +++ b/arch/powerpc/boot/dts/fsl/t2081qds.dts @@ -1,7 +1,7 @@ /* * T2081QDS Device Tree Source * - * Copyright 2013 Freescale Semiconductor Inc. + * Copyright 2013 - 2015 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -41,6 +41,225 @@ #address-cells = <2>; #size-cells = <2>; interrupt-parent = <&mpic>; + + aliases { + emi1_slot1 = &t2081mdio2; + emi1_slot2 = &t2081mdio3; + emi1_slot3 = &t2081mdio4; + emi1_slot5 = &t2081mdio5; + emi1_slot6 = &t2081mdio6; + emi1_slot7 = &t2081mdio7; + }; +}; + +&soc { + fman@400000 { + ethernet@e0000 { + phy-handle = <&phy_sgmii_s7_1c>; + phy-connection-type = "sgmii"; + }; + + ethernet@e2000 { + phy-handle = <&phy_sgmii_s7_1d>; + phy-connection-type = "sgmii"; + }; + + ethernet@e4000 { + phy-handle = <&rgmii_phy1>; + phy-connection-type = "rgmii"; + }; + + ethernet@e6000 { + phy-handle = <&rgmii_phy2>; + phy-connection-type = "rgmii"; + }; + + ethernet@e8000 { + phy-handle = <&phy_sgmii_s3_1c>; + phy-connection-type = "sgmii"; + }; + + ethernet@ea000 { + phy-handle = <&phy_sgmii_s7_1f>; + phy-connection-type = "sgmii"; + }; + + ethernet@f0000 { + phy-handle = <&phy_sgmii_s2_1c>; + phy-connection-type = "xgmii"; + }; + + ethernet@f2000 { + phy-handle = <&phy_sgmii_s7_1e>; + phy-connection-type = "xgmii"; + }; + }; +}; + +&boardctrl { + mdio-mux-emi1 { + compatible = "mdio-mux-mmioreg", "mdio-mux"; + mdio-parent-bus = <&mdio0>; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x54 1>; + mux-mask = <0xe0>; + + t2081mdio0: mdio@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + rgmii_phy1: ethernet-phy@1 { + reg = <0x1>; + }; + }; + + t2081mdio1: mdio@20 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x20>; + + rgmii_phy2: ethernet-phy@2 { + reg = <0x2>; + }; + }; + + t2081mdio2: mdio@40 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40>; + + phy_sgmii_s1_1c: ethernet-phy@1c { + reg = <0x1c>; + }; + + phy_sgmii_s1_1d: ethernet-phy@1d { + reg = <0x1d>; + }; + + phy_sgmii_s1_1e: ethernet-phy@1e { + reg = <0x1e>; + }; + + phy_sgmii_s1_1f: ethernet-phy@1f { + reg = <0x1f>; + }; + }; + + t2081mdio3: mdio@60 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x60>; + + phy_sgmii_s2_1c: ethernet-phy@1c { + reg = <0x1c>; + }; + + phy_sgmii_s2_1d: ethernet-phy@1d { + reg = <0x1d>; + }; + + phy_sgmii_s2_1e: ethernet-phy@1e { + reg = <0x1e>; + }; + + phy_sgmii_s2_1f: ethernet-phy@1f { + reg = <0x1f>; + }; + }; + + t2081mdio4: mdio@80 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x80>; + status = "disabled"; + + phy_sgmii_s3_1c: ethernet-phy@1c { + reg = <0x1c>; + }; + + phy_sgmii_s3_1d: ethernet-phy@1d { + reg = <0x1d>; + }; + + phy_sgmii_s3_1e: ethernet-phy@1e { + reg = <0x1e>; + }; + + phy_sgmii_s3_1f: ethernet-phy@1f { + reg = <0x1f>; + }; + }; + + t2081mdio5: mdio@a0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0xa0>; + status = "disabled"; + + phy_sgmii_s5_1c: ethernet-phy@1c { + reg = <0x1c>; + }; + + phy_sgmii_s5_1d: ethernet-phy@1d { + reg = <0x1d>; + }; + + phy_sgmii_s5_1e: ethernet-phy@1e { + reg = <0x1e>; + }; + + phy_sgmii_s5_1f: ethernet-phy@1f { + reg = <0x1f>; + }; + }; + + t2081mdio6: mdio@c0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0xc0>; + status = "disabled"; + + phy_sgmii_s6_1c: ethernet-phy@1c { + reg = <0x1c>; + }; + + phy_sgmii_s6_1d: ethernet-phy@1d { + reg = <0x1d>; + }; + + phy_sgmii_s6_1e: ethernet-phy@1e { + reg = <0x1e>; + }; + + phy_sgmii_s6_1f: ethernet-phy@1f { + reg = <0x1f>; + }; + }; + + t2081mdio7: mdio@e0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0xe0>; + + phy_sgmii_s7_1c: ethernet-phy@1c { + reg = <0x1c>; + }; + + phy_sgmii_s7_1d: ethernet-phy@1d { + reg = <0x1d>; + }; + + phy_sgmii_s7_1e: ethernet-phy@1e { + reg = <0x1e>; + }; + + phy_sgmii_s7_1f: ethernet-phy@1f { + reg = <0x1f>; + }; + }; + }; }; /include/ "t2081si-post.dtsi" diff --git a/arch/powerpc/boot/dts/fsl/t208xqds.dtsi b/arch/powerpc/boot/dts/fsl/t208xqds.dtsi index 869f9159b4d14ff9ed775c41f8dd2f17b8df0259..ec080bd01b0979b55f932c8d107c0d26212ace1b 100644 --- a/arch/powerpc/boot/dts/fsl/t208xqds.dtsi +++ b/arch/powerpc/boot/dts/fsl/t208xqds.dtsi @@ -112,7 +112,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "micron,n25q128a11"; /* 16MB */ + compatible = "micron,n25q128a11", "jedec,spi-nor"; /* 16MB */ reg = <0>; spi-max-frequency = <40000000>; /* input clock */ }; @@ -120,7 +120,7 @@ flash@1 { #address-cells = <1>; #size-cells = <1>; - compatible = "sst,sst25wf040"; + compatible = "sst,sst25wf040", "jedec,spi-nor"; reg = <1>; spi-max-frequency = <35000000>; }; @@ -128,7 +128,7 @@ flash@2 { #address-cells = <1>; #size-cells = <1>; - compatible = "eon,en25s64"; + compatible = "eon,en25s64", "jedec,spi-nor"; reg = <2>; spi-max-frequency = <35000000>; }; diff --git a/arch/powerpc/boot/dts/fsl/t208xrdb.dtsi b/arch/powerpc/boot/dts/fsl/t208xrdb.dtsi index 693d2a8fa01cde3b78e2717af34bca06a737fa72..dc9326875778c19fb2dd75f56744a2ae2f43db0f 100644 --- a/arch/powerpc/boot/dts/fsl/t208xrdb.dtsi +++ b/arch/powerpc/boot/dts/fsl/t208xrdb.dtsi @@ -113,7 +113,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "micron,n25q512a"; + compatible = "micron,n25q512a", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <10000000>; /* input clock */ }; diff --git a/arch/powerpc/boot/dts/fsl/t4240qds.dts b/arch/powerpc/boot/dts/fsl/t4240qds.dts index c067a6533809fea8cff70e3e57380b3acc7edc1a..9573ceada07c2c79f394ee2c7275bb12b6e51a44 100644 --- a/arch/powerpc/boot/dts/fsl/t4240qds.dts +++ b/arch/powerpc/boot/dts/fsl/t4240qds.dts @@ -1,7 +1,7 @@ /* * T4240QDS Device Tree Source * - * Copyright 2012 - 2014 Freescale Semiconductor Inc. + * Copyright 2012 - 2015 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -41,6 +41,44 @@ #size-cells = <2>; interrupt-parent = <&mpic>; + aliases{ + phy_rgmii1 = &phyrgmii1; + phy_rgmii2 = &phyrgmii2; + phy_sgmii3 = &phy3; + phy_sgmii4 = &phy4; + phy_sgmii11 = &phy11; + phy_sgmii12 = &phy12; + sgmii_phy11 = &sgmiiphy11; + sgmii_phy12 = &sgmiiphy12; + sgmii_phy13 = &sgmiiphy13; + sgmii_phy14 = &sgmiiphy14; + sgmii_phy21 = &sgmiiphy21; + sgmii_phy22 = &sgmiiphy22; + sgmii_phy23 = &sgmiiphy23; + sgmii_phy24 = &sgmiiphy24; + sgmii_phy31 = &sgmiiphy31; + sgmii_phy32 = &sgmiiphy32; + sgmii_phy33 = &sgmiiphy33; + sgmii_phy34 = &sgmiiphy34; + sgmii_phy41 = &sgmiiphy41; + sgmii_phy42 = &sgmiiphy42; + sgmii_phy43 = &sgmiiphy43; + sgmii_phy44 = &sgmiiphy44; + phy_xfi1 = &xfiphy1; + phy_xfi2 = &xfiphy2; + phy_xfi3 = &xfiphy3; + phy_xfi4 = &xfiphy4; + xfi_pcs_mdio1 = &xfimdio0; + xfi_pcs_mdio2 = &xfimdio1; + xfi_pcs_mdio3 = &xfimdio2; + xfi_pcs_mdio4 = &xfimdio3; + emi1_rgmii = &t4240mdio0; + emi1_slot1 = &t4240mdio1; + emi1_slot2 = &t4240mdio2; + emi1_slot3 = &t4240mdio3; + emi1_slot4 = &t4240mdio4; + }; + ifc: localbus@ffe124000 { reg = <0xf 0xfe124000 0 0x2000>; ranges = <0 0 0xf 0xe8000000 0x08000000 @@ -91,8 +129,190 @@ }; board-control@3,0 { + #address-cells = <1>; + #size-cells = <1>; compatible = "fsl,t4240qds-fpga", "fsl,fpga-qixis"; reg = <3 0 0x300>; + ranges = <0 3 0 0x300>; + + mdio-mux-emi1 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "mdio-mux-mmioreg", "mdio-mux"; + mdio-parent-bus = <&mdio1>; + reg = <0x54 1>; + mux-mask = <0xe0>; + + t4240mdio0: mdio@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + phyrgmii1: ethernet-phy@1 { + reg = <0x1>; + }; + + phyrgmii2: ethernet-phy@2 { + reg = <0x2>; + }; + }; + + t4240mdio1: mdio@20 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x20>; + status = "disabled"; + + phy1: ethernet-phy@0 { + reg = <0x0>; + }; + + phy2: ethernet-phy@1 { + reg = <0x1>; + }; + + phy3: ethernet-phy@2 { + reg = <0x2>; + }; + + phy4: ethernet-phy@3 { + reg = <0x3>; + }; + + sgmiiphy11: ethernet-phy@1c { + reg = <0x1c>; + }; + + sgmiiphy12: ethernet-phy@1d { + reg = <0x1d>; + }; + + sgmiiphy13: ethernet-phy@1e { + reg = <0x1e>; + }; + + sgmiiphy14: ethernet-phy@1f { + reg = <0x1f>; + }; + }; + + t4240mdio2: mdio@40 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40>; + status = "disabled"; + + phy5: ethernet-phy@4 { + reg = <0x4>; + }; + + phy6: ethernet-phy@5 { + reg = <0x5>; + }; + + phy7: ethernet-phy@6 { + reg = <0x6>; + }; + + phy8: ethernet-phy@7 { + reg = <0x7>; + }; + + sgmiiphy21: ethernet-phy@1c { + reg = <0x1c>; + }; + + sgmiiphy22: ethernet-phy@1d { + reg = <0x1d>; + }; + + sgmiiphy23: ethernet-phy@1e { + reg = <0x1e>; + }; + + sgmiiphy24: ethernet-phy@1f { + reg = <0x1f>; + }; + }; + + t4240mdio3: mdio@60 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x60>; + status = "disabled"; + + phy9: ethernet-phy@8 { + reg = <0x8>; + }; + + phy10: ethernet-phy@9 { + reg = <0x9>; + }; + + phy11: ethernet-phy@a { + reg = <0xa>; + }; + + phy12: ethernet-phy@b { + reg = <0xb>; + }; + + sgmiiphy31: ethernet-phy@1c { + reg = <0x1c>; + }; + + sgmiiphy32: ethernet-phy@1d { + reg = <0x1d>; + }; + + sgmiiphy33: ethernet-phy@1e { + reg = <0x1e>; + }; + + sgmiiphy34: ethernet-phy@1f { + reg = <0x1f>; + }; + }; + + t4240mdio4: mdio@80 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x80>; + status = "disabled"; + + phy13: ethernet-phy@c { + reg = <0xc>; + }; + + phy14: ethernet-phy@d { + reg = <0xd>; + }; + + phy15: ethernet-phy@e { + reg = <0xe>; + }; + + phy16: ethernet-phy@f { + reg = <0xf>; + }; + + sgmiiphy41: ethernet-phy@1c { + reg = <0x1c>; + }; + + sgmiiphy42: ethernet-phy@1d { + reg = <0x1d>; + }; + + sgmiiphy43: ethernet-phy@1e { + reg = <0x1e>; + }; + + sgmiiphy44: ethernet-phy@1f { + reg = <0x1f>; + }; + }; + }; }; }; @@ -138,7 +358,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "sst,sst25wf040"; + compatible = "sst,sst25wf040", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <40000000>; /* input clock */ }; @@ -234,6 +454,184 @@ sdhc@114000 { voltage-ranges = <1800 1800 3300 3300>; }; + + fman@400000 { + port@83000 { + status = "disabled"; + }; + + port@84000 { + status = "disabled"; + }; + + port@85000 { + status = "disabled"; + }; + + port@86000 { + status = "disabled"; + }; + + port@87000 { + status = "disabled"; + }; + + ethernet@e0000 { + phy-handle = <&phy5>; + phy-connection-type = "sgmii"; + }; + + ethernet@e2000 { + phy-handle = <&phy6>; + phy-connection-type = "sgmii"; + }; + + ethernet@e4000 { + phy-handle = <&phy7>; + phy-connection-type = "sgmii"; + }; + + ethernet@e6000 { + phy-handle = <&phy8>; + phy-connection-type = "sgmii"; + }; + + ethernet@e8000 { + phy-handle = <&phyrgmii2>; + phy-connection-type = "rgmii"; + }; + + ethernet@ea000 { + phy-handle = <&phy2>; + phy-connection-type = "sgmii"; + }; + + ethernet@f0000 { + phy-handle = <&xauiphy1>; + phy-connection-type = "xgmii"; + }; + + ethernet@f2000 { + phy-handle = <&xauiphy2>; + phy-connection-type = "xgmii"; + }; + + xfimdio0: mdio@f1000 { + status = "disabled"; + + xfiphy1: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0x0>; + }; + }; + + xfimdio1: mdio@f3000 { + status = "disabled"; + + xfiphy2: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0x0>; + }; + }; + }; + + fman@500000 { + port@84000 { + status = "disabled"; + }; + + port@85000 { + status = "disabled"; + }; + + port@86000 { + status = "disabled"; + }; + + port@87000 { + status = "disabled"; + }; + + ethernet@e0000 { + phy-handle = <&phy13>; + phy-connection-type = "sgmii"; + }; + + ethernet@e2000 { + phy-handle = <&phy14>; + phy-connection-type = "sgmii"; + }; + + ethernet@e4000 { + phy-handle = <&phy15>; + phy-connection-type = "sgmii"; + }; + + ethernet@e6000 { + phy-handle = <&phy16>; + phy-connection-type = "sgmii"; + }; + + ethernet@e8000 { + phy-handle = <&phyrgmii1>; + phy-connection-type = "rgmii"; + }; + + ethernet@ea000 { + phy-handle = <&phy10>; + phy-connection-type = "sgmii"; + }; + + ethernet@f0000 { + phy-handle = <&xauiphy3>; + phy-connection-type = "xgmii"; + }; + + ethernet@f2000 { + phy-handle = <&xauiphy4>; + phy-connection-type = "xgmii"; + }; + + xfimdio2: mdio@f1000 { + status = "disabled"; + + xfiphy3: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0x0>; + }; + }; + + xfimdio3: mdio@f3000 { + status = "disabled"; + + xfiphy4: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0x0>; + }; + }; + + mdio@fd000 { + xauiphy1: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0x0>; + }; + + xauiphy2: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0x1>; + }; + + xauiphy3: ethernet-phy@2 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0x2>; + }; + + xauiphy4: ethernet-phy@3 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0x3>; + }; + }; + }; }; pci0: pcie@ffe240000 { diff --git a/arch/powerpc/boot/dts/fsl/t4240rdb.dts b/arch/powerpc/boot/dts/fsl/t4240rdb.dts index 6e820a875621a752e0475c3cd9e57079676dc30c..cc0a264b8acb3bb234d2a4e73ed5477d2d55c948 100644 --- a/arch/powerpc/boot/dts/fsl/t4240rdb.dts +++ b/arch/powerpc/boot/dts/fsl/t4240rdb.dts @@ -1,7 +1,7 @@ /* * T4240RDB Device Tree Source * - * Copyright 2014 Freescale Semiconductor Inc. + * Copyright 2014 - 2015 Freescale Semiconductor Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -41,6 +41,17 @@ #size-cells = <2>; interrupt-parent = <&mpic>; + aliases { + sgmii_phy21 = &sgmiiphy21; + sgmii_phy22 = &sgmiiphy22; + sgmii_phy23 = &sgmiiphy23; + sgmii_phy24 = &sgmiiphy24; + sgmii_phy41 = &sgmiiphy41; + sgmii_phy42 = &sgmiiphy42; + sgmii_phy43 = &sgmiiphy43; + sgmii_phy44 = &sgmiiphy44; + }; + ifc: localbus@ffe124000 { reg = <0xf 0xfe124000 0 0x2000>; ranges = <0 0 0xf 0xe8000000 0x08000000 @@ -107,7 +118,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "sst,sst25wf040"; + compatible = "sst,sst25wf040", "jedec,spi-nor"; reg = <0>; spi-max-frequency = <40000000>; /* input clock */ }; @@ -136,6 +147,142 @@ sdhc@114000 { voltage-ranges = <1800 1800 3300 3300>; }; + + fman@400000 { + ethernet@e0000 { + phy-handle = <&sgmiiphy21>; + phy-connection-type = "sgmii"; + }; + + ethernet@e2000 { + phy-handle = <&sgmiiphy22>; + phy-connection-type = "sgmii"; + }; + + ethernet@e4000 { + phy-handle = <&sgmiiphy23>; + phy-connection-type = "sgmii"; + }; + + ethernet@e6000 { + phy-handle = <&sgmiiphy24>; + phy-connection-type = "sgmii"; + }; + + ethernet@e8000 { + status = "disabled"; + }; + + ethernet@ea000 { + status = "disabled"; + }; + + ethernet@f0000 { + phy-handle = <&xfiphy1>; + phy-connection-type = "xgmii"; + }; + + ethernet@f2000 { + phy-handle = <&xfiphy2>; + phy-connection-type = "xgmii"; + }; + }; + + fman@500000 { + ethernet@e0000 { + phy-handle = <&sgmiiphy41>; + phy-connection-type = "sgmii"; + }; + + ethernet@e2000 { + phy-handle = <&sgmiiphy42>; + phy-connection-type = "sgmii"; + }; + + ethernet@e4000 { + phy-handle = <&sgmiiphy43>; + phy-connection-type = "sgmii"; + }; + + ethernet@e6000 { + phy-handle = <&sgmiiphy44>; + phy-connection-type = "sgmii"; + }; + + ethernet@e8000 { + status = "disabled"; + }; + + ethernet@ea000 { + status = "disabled"; + }; + + ethernet@f0000 { + phy-handle = <&xfiphy3>; + phy-connection-type = "xgmii"; + }; + + ethernet@f2000 { + phy-handle = <&xfiphy4>; + phy-connection-type = "xgmii"; + }; + + mdio@fc000 { + sgmiiphy21: ethernet-phy@0 { + reg = <0x0>; + }; + + sgmiiphy22: ethernet-phy@1 { + reg = <0x1>; + }; + + sgmiiphy23: ethernet-phy@2 { + reg = <0x2>; + }; + + sgmiiphy24: ethernet-phy@3 { + reg = <0x3>; + }; + + sgmiiphy41: ethernet-phy@4 { + reg = <0x4>; + }; + + sgmiiphy42: ethernet-phy@5 { + reg = <0x5>; + }; + + sgmiiphy43: ethernet-phy@6 { + reg = <0x6>; + }; + + sgmiiphy44: ethernet-phy@7 { + reg = <0x7>; + }; + }; + + mdio@fd000 { + xfiphy1: ethernet-phy@10 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0x10>; + }; + + xfiphy2: ethernet-phy@11 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0x11>; + }; + + xfiphy3: ethernet-phy@13 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0x13>; + }; + + xfiphy4: ethernet-phy@12 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <0x12>; + }; + }; + }; }; pci0: pcie@ffe240000 { diff --git a/arch/powerpc/boot/dts/gef_ppc9a.dts b/arch/powerpc/boot/dts/gef_ppc9a.dts deleted file mode 100644 index 83eb0fda2666079c73d67e0db37c7ee24f0a5c34..0000000000000000000000000000000000000000 --- a/arch/powerpc/boot/dts/gef_ppc9a.dts +++ /dev/null @@ -1,425 +0,0 @@ -/* - * GE PPC9A Device Tree Source - * - * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. - * - * 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. - * - * Based on: SBS CM6 Device Tree Source - * Copyright 2007 SBS Technologies GmbH & Co. KG - * And: mpc8641_hpcn.dts (MPC8641 HPCN Device Tree Source) - * Copyright 2006 Freescale Semiconductor Inc. - */ - -/* - * Compiled with dtc -I dts -O dtb -o gef_ppc9a.dtb gef_ppc9a.dts - */ - -/dts-v1/; - -/ { - model = "GEF_PPC9A"; - compatible = "gef,ppc9a"; - #address-cells = <1>; - #size-cells = <1>; - - aliases { - ethernet0 = &enet0; - ethernet1 = &enet1; - serial0 = &serial0; - serial1 = &serial1; - pci0 = &pci0; - }; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - PowerPC,8641@0 { - device_type = "cpu"; - reg = <0>; - d-cache-line-size = <32>; // 32 bytes - i-cache-line-size = <32>; // 32 bytes - d-cache-size = <32768>; // L1, 32K - i-cache-size = <32768>; // L1, 32K - timebase-frequency = <0>; // From uboot - bus-frequency = <0>; // From uboot - clock-frequency = <0>; // From uboot - }; - PowerPC,8641@1 { - device_type = "cpu"; - reg = <1>; - d-cache-line-size = <32>; // 32 bytes - i-cache-line-size = <32>; // 32 bytes - d-cache-size = <32768>; // L1, 32K - i-cache-size = <32768>; // L1, 32K - timebase-frequency = <0>; // From uboot - bus-frequency = <0>; // From uboot - clock-frequency = <0>; // From uboot - }; - }; - - memory { - device_type = "memory"; - reg = <0x0 0x40000000>; // set by uboot - }; - - localbus@fef05000 { - #address-cells = <2>; - #size-cells = <1>; - compatible = "fsl,mpc8641-localbus", "simple-bus"; - reg = <0xfef05000 0x1000>; - interrupts = <19 2>; - interrupt-parent = <&mpic>; - - ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash - 1 0 0xe8000000 0x08000000 // Paged Flash 0 - 2 0 0xe0000000 0x08000000 // Paged Flash 1 - 3 0 0xfc100000 0x00020000 // NVRAM - 4 0 0xfc000000 0x00008000 // FPGA - 5 0 0xfc008000 0x00008000 // AFIX FPGA - 6 0 0xfd000000 0x00800000 // IO FPGA (8-bit) - 7 0 0xfd800000 0x00800000>; // IO FPGA (32-bit) - - /* flash@0,0 is a mirror of part of the memory in flash@1,0 - flash@0,0 { - compatible = "gef,ppc9a-firmware-mirror", "cfi-flash"; - reg = <0x0 0x0 0x1000000>; - bank-width = <4>; - device-width = <2>; - #address-cells = <1>; - #size-cells = <1>; - partition@0 { - label = "firmware"; - reg = <0x0 0x1000000>; - read-only; - }; - }; - */ - - flash@1,0 { - compatible = "gef,ppc9a-paged-flash", "cfi-flash"; - reg = <0x1 0x0 0x8000000>; - bank-width = <4>; - device-width = <2>; - #address-cells = <1>; - #size-cells = <1>; - partition@0 { - label = "user"; - reg = <0x0 0x7800000>; - }; - partition@7800000 { - label = "firmware"; - reg = <0x7800000 0x800000>; - read-only; - }; - }; - - nvram@3,0 { - device_type = "nvram"; - compatible = "simtek,stk14ca8"; - reg = <0x3 0x0 0x20000>; - }; - - fpga@4,0 { - compatible = "gef,ppc9a-fpga-regs"; - reg = <0x4 0x0 0x40>; - }; - - wdt@4,2000 { - compatible = "gef,ppc9a-fpga-wdt", "gef,fpga-wdt-1.00", - "gef,fpga-wdt"; - reg = <0x4 0x2000 0x8>; - interrupts = <0x1a 0x4>; - interrupt-parent = <&gef_pic>; - }; - /* Second watchdog available, driver currently supports one. - wdt@4,2010 { - compatible = "gef,ppc9a-fpga-wdt", "gef,fpga-wdt-1.00", - "gef,fpga-wdt"; - reg = <0x4 0x2010 0x8>; - interrupts = <0x1b 0x4>; - interrupt-parent = <&gef_pic>; - }; - */ - gef_pic: pic@4,4000 { - #interrupt-cells = <1>; - interrupt-controller; - compatible = "gef,ppc9a-fpga-pic", "gef,fpga-pic-1.00"; - reg = <0x4 0x4000 0x20>; - interrupts = <0x8 - 0x9>; - interrupt-parent = <&mpic>; - - }; - gef_gpio: gpio@7,14000 { - #gpio-cells = <2>; - compatible = "gef,ppc9a-gpio", "gef,sbc610-gpio"; - reg = <0x7 0x14000 0x24>; - gpio-controller; - }; - }; - - soc@fef00000 { - #address-cells = <1>; - #size-cells = <1>; - #interrupt-cells = <2>; - device_type = "soc"; - compatible = "fsl,mpc8641-soc", "simple-bus"; - ranges = <0x0 0xfef00000 0x00100000>; - bus-frequency = <33333333>; - - mcm-law@0 { - compatible = "fsl,mcm-law"; - reg = <0x0 0x1000>; - fsl,num-laws = <10>; - }; - - mcm@1000 { - compatible = "fsl,mpc8641-mcm", "fsl,mcm"; - reg = <0x1000 0x1000>; - interrupts = <17 2>; - interrupt-parent = <&mpic>; - }; - - i2c1: i2c@3000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl-i2c"; - reg = <0x3000 0x100>; - interrupts = <0x2b 0x2>; - interrupt-parent = <&mpic>; - dfsrr; - - hwmon@48 { - compatible = "national,lm92"; - reg = <0x48>; - }; - - hwmon@4c { - compatible = "adi,adt7461"; - reg = <0x4c>; - }; - - rtc@51 { - compatible = "epson,rx8581"; - reg = <0x00000051>; - }; - - eti@6b { - compatible = "dallas,ds1682"; - reg = <0x6b>; - }; - }; - - i2c2: i2c@3100 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl-i2c"; - reg = <0x3100 0x100>; - interrupts = <0x2b 0x2>; - interrupt-parent = <&mpic>; - dfsrr; - }; - - dma@21300 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma"; - reg = <0x21300 0x4>; - ranges = <0x0 0x21100 0x200>; - cell-index = <0>; - dma-channel@0 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x0 0x80>; - cell-index = <0>; - interrupt-parent = <&mpic>; - interrupts = <20 2>; - }; - dma-channel@80 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x80 0x80>; - cell-index = <1>; - interrupt-parent = <&mpic>; - interrupts = <21 2>; - }; - dma-channel@100 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x100 0x80>; - cell-index = <2>; - interrupt-parent = <&mpic>; - interrupts = <22 2>; - }; - dma-channel@180 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x180 0x80>; - cell-index = <3>; - interrupt-parent = <&mpic>; - interrupts = <23 2>; - }; - }; - - enet0: ethernet@24000 { - #address-cells = <1>; - #size-cells = <1>; - cell-index = <0>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <29 2 30 2 34 2>; - interrupt-parent = <&mpic>; - tbi-handle = <&tbi0>; - phy-handle = <&phy0>; - phy-connection-type = "gmii"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy0: ethernet-phy@0 { - interrupt-parent = <&gef_pic>; - interrupts = <0x9 0x4>; - reg = <1>; - }; - phy2: ethernet-phy@2 { - interrupt-parent = <&gef_pic>; - interrupts = <0x8 0x4>; - reg = <3>; - }; - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; - }; - - enet1: ethernet@26000 { - #address-cells = <1>; - #size-cells = <1>; - cell-index = <2>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <0x26000 0x1000>; - ranges = <0x0 0x26000 0x1000>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <31 2 32 2 33 2>; - interrupt-parent = <&mpic>; - tbi-handle = <&tbi2>; - phy-handle = <&phy2>; - phy-connection-type = "gmii"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi2: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; - }; - - serial0: serial@4500 { - cell-index = <0>; - device_type = "serial"; - compatible = "fsl,ns16550", "ns16550"; - reg = <0x4500 0x100>; - clock-frequency = <0>; - interrupts = <0x2a 0x2>; - interrupt-parent = <&mpic>; - }; - - serial1: serial@4600 { - cell-index = <1>; - device_type = "serial"; - compatible = "fsl,ns16550", "ns16550"; - reg = <0x4600 0x100>; - clock-frequency = <0>; - interrupts = <0x1c 0x2>; - interrupt-parent = <&mpic>; - }; - - mpic: pic@40000 { - clock-frequency = <0>; - interrupt-controller; - #address-cells = <0>; - #interrupt-cells = <2>; - reg = <0x40000 0x40000>; - compatible = "chrp,open-pic"; - device_type = "open-pic"; - }; - - msi@41600 { - compatible = "fsl,mpc8641-msi", "fsl,mpic-msi"; - reg = <0x41600 0x80>; - msi-available-ranges = <0 0x100>; - interrupts = < - 0xe0 0 - 0xe1 0 - 0xe2 0 - 0xe3 0 - 0xe4 0 - 0xe5 0 - 0xe6 0 - 0xe7 0>; - interrupt-parent = <&mpic>; - }; - - global-utilities@e0000 { - compatible = "fsl,mpc8641-guts"; - reg = <0xe0000 0x1000>; - fsl,has-rstcr; - }; - }; - - pci0: pcie@fef08000 { - compatible = "fsl,mpc8641-pcie"; - device_type = "pci"; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - reg = <0xfef08000 0x1000>; - bus-range = <0x0 0xff>; - ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x40000000 - 0x01000000 0x0 0x00000000 0xfe000000 0x0 0x00400000>; - clock-frequency = <33333333>; - interrupt-parent = <&mpic>; - interrupts = <0x18 0x2>; - interrupt-map-mask = <0xf800 0x0 0x0 0x7>; - interrupt-map = < - 0x0000 0x0 0x0 0x1 &mpic 0x0 0x1 - 0x0000 0x0 0x0 0x2 &mpic 0x1 0x1 - 0x0000 0x0 0x0 0x3 &mpic 0x2 0x1 - 0x0000 0x0 0x0 0x4 &mpic 0x3 0x1 - >; - - pcie@0 { - reg = <0 0 0 0 0>; - #size-cells = <2>; - #address-cells = <3>; - device_type = "pci"; - ranges = <0x02000000 0x0 0x80000000 - 0x02000000 0x0 0x80000000 - 0x0 0x40000000 - - 0x01000000 0x0 0x00000000 - 0x01000000 0x0 0x00000000 - 0x0 0x00400000>; - }; - }; -}; diff --git a/arch/powerpc/boot/dts/gef_sbc310.dts b/arch/powerpc/boot/dts/gef_sbc310.dts deleted file mode 100644 index d426dd3de9ef7f4af36e75dd1b9bfcb33109e91f..0000000000000000000000000000000000000000 --- a/arch/powerpc/boot/dts/gef_sbc310.dts +++ /dev/null @@ -1,459 +0,0 @@ -/* - * GE SBC310 Device Tree Source - * - * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. - * - * 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. - * - * Based on: SBS CM6 Device Tree Source - * Copyright 2007 SBS Technologies GmbH & Co. KG - * And: mpc8641_hpcn.dts (MPC8641 HPCN Device Tree Source) - * Copyright 2006 Freescale Semiconductor Inc. - */ - -/* - * Compiled with dtc -I dts -O dtb -o gef_sbc310.dtb gef_sbc310.dts - */ - -/dts-v1/; - -/ { - model = "GEF_SBC310"; - compatible = "gef,sbc310"; - #address-cells = <1>; - #size-cells = <1>; - - aliases { - ethernet0 = &enet0; - ethernet1 = &enet1; - serial0 = &serial0; - serial1 = &serial1; - pci0 = &pci0; - pci1 = &pci1; - }; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - PowerPC,8641@0 { - device_type = "cpu"; - reg = <0>; - d-cache-line-size = <32>; // 32 bytes - i-cache-line-size = <32>; // 32 bytes - d-cache-size = <32768>; // L1, 32K - i-cache-size = <32768>; // L1, 32K - timebase-frequency = <0>; // From uboot - bus-frequency = <0>; // From uboot - clock-frequency = <0>; // From uboot - }; - PowerPC,8641@1 { - device_type = "cpu"; - reg = <1>; - d-cache-line-size = <32>; // 32 bytes - i-cache-line-size = <32>; // 32 bytes - d-cache-size = <32768>; // L1, 32K - i-cache-size = <32768>; // L1, 32K - timebase-frequency = <0>; // From uboot - bus-frequency = <0>; // From uboot - clock-frequency = <0>; // From uboot - }; - }; - - memory { - device_type = "memory"; - reg = <0x0 0x40000000>; // set by uboot - }; - - localbus@fef05000 { - #address-cells = <2>; - #size-cells = <1>; - compatible = "fsl,mpc8641-localbus", "simple-bus"; - reg = <0xfef05000 0x1000>; - interrupts = <19 2>; - interrupt-parent = <&mpic>; - - ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash - 1 0 0xe0000000 0x08000000 // Paged Flash 0 - 2 0 0xe8000000 0x08000000 // Paged Flash 1 - 3 0 0xfc100000 0x00020000 // NVRAM - 4 0 0xfc000000 0x00010000>; // FPGA - - /* flash@0,0 is a mirror of part of the memory in flash@1,0 - flash@0,0 { - compatible = "gef,sbc310-firmware-mirror", "cfi-flash"; - reg = <0x0 0x0 0x01000000>; - bank-width = <2>; - device-width = <2>; - #address-cells = <1>; - #size-cells = <1>; - partition@0 { - label = "firmware"; - reg = <0x0 0x01000000>; - read-only; - }; - }; - */ - - flash@1,0 { - compatible = "gef,sbc310-paged-flash", "cfi-flash"; - reg = <0x1 0x0 0x8000000>; - bank-width = <2>; - device-width = <2>; - #address-cells = <1>; - #size-cells = <1>; - partition@0 { - label = "user"; - reg = <0x0 0x7800000>; - }; - partition@7800000 { - label = "firmware"; - reg = <0x7800000 0x800000>; - read-only; - }; - }; - - nvram@3,0 { - device_type = "nvram"; - compatible = "simtek,stk14ca8"; - reg = <0x3 0x0 0x20000>; - }; - - fpga@4,0 { - compatible = "gef,fpga-regs"; - reg = <0x4 0x0 0x40>; - }; - - wdt@4,2000 { - compatible = "gef,sbc310-fpga-wdt", "gef,fpga-wdt-1.00", - "gef,fpga-wdt"; - reg = <0x4 0x2000 0x8>; - interrupts = <0x1a 0x4>; - interrupt-parent = <&gef_pic>; - }; -/* - wdt@4,2010 { - compatible = "gef,sbc310-fpga-wdt", "gef,fpga-wdt-1.00", - "gef,fpga-wdt"; - reg = <0x4 0x2010 0x8>; - interrupts = <0x1b 0x4>; - interrupt-parent = <&gef_pic>; - }; -*/ - gef_pic: pic@4,4000 { - #interrupt-cells = <1>; - interrupt-controller; - compatible = "gef,sbc310-fpga-pic", "gef,fpga-pic"; - reg = <0x4 0x4000 0x20>; - interrupts = <0x8 - 0x9>; - interrupt-parent = <&mpic>; - - }; - gef_gpio: gpio@4,8000 { - #gpio-cells = <2>; - compatible = "gef,sbc310-gpio"; - reg = <0x4 0x8000 0x24>; - gpio-controller; - }; - }; - - soc@fef00000 { - #address-cells = <1>; - #size-cells = <1>; - #interrupt-cells = <2>; - device_type = "soc"; - compatible = "fsl,mpc8641-soc", "simple-bus"; - ranges = <0x0 0xfef00000 0x00100000>; - bus-frequency = <33333333>; - - mcm-law@0 { - compatible = "fsl,mcm-law"; - reg = <0x0 0x1000>; - fsl,num-laws = <10>; - }; - - mcm@1000 { - compatible = "fsl,mpc8641-mcm", "fsl,mcm"; - reg = <0x1000 0x1000>; - interrupts = <17 2>; - interrupt-parent = <&mpic>; - }; - - i2c1: i2c@3000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl-i2c"; - reg = <0x3000 0x100>; - interrupts = <0x2b 0x2>; - interrupt-parent = <&mpic>; - dfsrr; - - rtc@51 { - compatible = "epson,rx8581"; - reg = <0x00000051>; - }; - }; - - i2c2: i2c@3100 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl-i2c"; - reg = <0x3100 0x100>; - interrupts = <0x2b 0x2>; - interrupt-parent = <&mpic>; - dfsrr; - - hwmon@48 { - compatible = "national,lm92"; - reg = <0x48>; - }; - - hwmon@4c { - compatible = "adi,adt7461"; - reg = <0x4c>; - }; - - eti@6b { - compatible = "dallas,ds1682"; - reg = <0x6b>; - }; - }; - - dma@21300 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma"; - reg = <0x21300 0x4>; - ranges = <0x0 0x21100 0x200>; - cell-index = <0>; - dma-channel@0 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x0 0x80>; - cell-index = <0>; - interrupt-parent = <&mpic>; - interrupts = <20 2>; - }; - dma-channel@80 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x80 0x80>; - cell-index = <1>; - interrupt-parent = <&mpic>; - interrupts = <21 2>; - }; - dma-channel@100 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x100 0x80>; - cell-index = <2>; - interrupt-parent = <&mpic>; - interrupts = <22 2>; - }; - dma-channel@180 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x180 0x80>; - cell-index = <3>; - interrupt-parent = <&mpic>; - interrupts = <23 2>; - }; - }; - - enet0: ethernet@24000 { - #address-cells = <1>; - #size-cells = <1>; - cell-index = <0>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <29 2 30 2 34 2>; - interrupt-parent = <&mpic>; - tbi-handle = <&tbi0>; - phy-handle = <&phy0>; - phy-connection-type = "gmii"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy0: ethernet-phy@0 { - interrupt-parent = <&gef_pic>; - interrupts = <0x9 0x4>; - reg = <1>; - }; - phy2: ethernet-phy@2 { - interrupt-parent = <&gef_pic>; - interrupts = <0x8 0x4>; - reg = <3>; - }; - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; - }; - - enet1: ethernet@26000 { - #address-cells = <1>; - #size-cells = <1>; - cell-index = <2>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <0x26000 0x1000>; - ranges = <0x0 0x26000 0x1000>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <31 2 32 2 33 2>; - interrupt-parent = <&mpic>; - tbi-handle = <&tbi2>; - phy-handle = <&phy2>; - phy-connection-type = "gmii"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi2: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; - }; - - serial0: serial@4500 { - cell-index = <0>; - device_type = "serial"; - compatible = "fsl,ns16550", "ns16550"; - reg = <0x4500 0x100>; - clock-frequency = <0>; - interrupts = <0x2a 0x2>; - interrupt-parent = <&mpic>; - }; - - serial1: serial@4600 { - cell-index = <1>; - device_type = "serial"; - compatible = "fsl,ns16550", "ns16550"; - reg = <0x4600 0x100>; - clock-frequency = <0>; - interrupts = <0x1c 0x2>; - interrupt-parent = <&mpic>; - }; - - mpic: pic@40000 { - clock-frequency = <0>; - interrupt-controller; - #address-cells = <0>; - #interrupt-cells = <2>; - reg = <0x40000 0x40000>; - compatible = "chrp,open-pic"; - device_type = "open-pic"; - }; - - msi@41600 { - compatible = "fsl,mpc8641-msi", "fsl,mpic-msi"; - reg = <0x41600 0x80>; - msi-available-ranges = <0 0x100>; - interrupts = < - 0xe0 0 - 0xe1 0 - 0xe2 0 - 0xe3 0 - 0xe4 0 - 0xe5 0 - 0xe6 0 - 0xe7 0>; - interrupt-parent = <&mpic>; - }; - - global-utilities@e0000 { - compatible = "fsl,mpc8641-guts"; - reg = <0xe0000 0x1000>; - fsl,has-rstcr; - }; - }; - - pci0: pcie@fef08000 { - compatible = "fsl,mpc8641-pcie"; - device_type = "pci"; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - reg = <0xfef08000 0x1000>; - bus-range = <0x0 0xff>; - ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x40000000 - 0x01000000 0x0 0x00000000 0xfe000000 0x0 0x00400000>; - clock-frequency = <33333333>; - interrupt-parent = <&mpic>; - interrupts = <0x18 0x2>; - interrupt-map-mask = <0xff00 0x0 0x0 0x7>; - interrupt-map = < - 0x0000 0x0 0x0 0x1 &mpic 0x0 0x2 - 0x0000 0x0 0x0 0x2 &mpic 0x1 0x2 - 0x0000 0x0 0x0 0x3 &mpic 0x2 0x2 - 0x0000 0x0 0x0 0x4 &mpic 0x3 0x2 - >; - - pcie@0 { - reg = <0 0 0 0 0>; - #size-cells = <2>; - #address-cells = <3>; - device_type = "pci"; - ranges = <0x02000000 0x0 0x80000000 - 0x02000000 0x0 0x80000000 - 0x0 0x40000000 - - 0x01000000 0x0 0x00000000 - 0x01000000 0x0 0x00000000 - 0x0 0x00400000>; - }; - }; - - pci1: pcie@fef09000 { - compatible = "fsl,mpc8641-pcie"; - device_type = "pci"; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - reg = <0xfef09000 0x1000>; - bus-range = <0x0 0xff>; - ranges = <0x02000000 0x0 0xc0000000 0xc0000000 0x0 0x20000000 - 0x01000000 0x0 0x00000000 0xfe400000 0x0 0x00400000>; - clock-frequency = <33333333>; - interrupt-parent = <&mpic>; - interrupts = <0x19 0x2>; - interrupt-map-mask = <0xf800 0x0 0x0 0x7>; - interrupt-map = < - 0x0000 0x0 0x0 0x1 &mpic 0x4 0x2 - 0x0000 0x0 0x0 0x2 &mpic 0x5 0x2 - 0x0000 0x0 0x0 0x3 &mpic 0x6 0x2 - 0x0000 0x0 0x0 0x4 &mpic 0x7 0x2 - >; - - pcie@0 { - reg = <0 0 0 0 0>; - #size-cells = <2>; - #address-cells = <3>; - device_type = "pci"; - ranges = <0x02000000 0x0 0xc0000000 - 0x02000000 0x0 0xc0000000 - 0x0 0x20000000 - - 0x01000000 0x0 0x00000000 - 0x01000000 0x0 0x00000000 - 0x0 0x00400000>; - }; - }; -}; diff --git a/arch/powerpc/boot/dts/gef_sbc610.dts b/arch/powerpc/boot/dts/gef_sbc610.dts deleted file mode 100644 index 5db3399b76b747cd3e0b7b1027e41beb965f4965..0000000000000000000000000000000000000000 --- a/arch/powerpc/boot/dts/gef_sbc610.dts +++ /dev/null @@ -1,423 +0,0 @@ -/* - * GE SBC610 Device Tree Source - * - * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. - * - * 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. - * - * Based on: SBS CM6 Device Tree Source - * Copyright 2007 SBS Technologies GmbH & Co. KG - * And: mpc8641_hpcn.dts (MPC8641 HPCN Device Tree Source) - * Copyright 2006 Freescale Semiconductor Inc. - */ - -/* - * Compiled with dtc -I dts -O dtb -o gef_sbc610.dtb gef_sbc610.dts - */ - -/dts-v1/; - -/ { - model = "GEF_SBC610"; - compatible = "gef,sbc610"; - #address-cells = <1>; - #size-cells = <1>; - - aliases { - ethernet0 = &enet0; - ethernet1 = &enet1; - serial0 = &serial0; - serial1 = &serial1; - pci0 = &pci0; - }; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - PowerPC,8641@0 { - device_type = "cpu"; - reg = <0>; - d-cache-line-size = <32>; // 32 bytes - i-cache-line-size = <32>; // 32 bytes - d-cache-size = <32768>; // L1, 32K - i-cache-size = <32768>; // L1, 32K - timebase-frequency = <0>; // From uboot - bus-frequency = <0>; // From uboot - clock-frequency = <0>; // From uboot - }; - PowerPC,8641@1 { - device_type = "cpu"; - reg = <1>; - d-cache-line-size = <32>; // 32 bytes - i-cache-line-size = <32>; // 32 bytes - d-cache-size = <32768>; // L1, 32K - i-cache-size = <32768>; // L1, 32K - timebase-frequency = <0>; // From uboot - bus-frequency = <0>; // From uboot - clock-frequency = <0>; // From uboot - }; - }; - - memory { - device_type = "memory"; - reg = <0x0 0x40000000>; // set by uboot - }; - - localbus@fef05000 { - #address-cells = <2>; - #size-cells = <1>; - compatible = "fsl,mpc8641-localbus", "simple-bus"; - reg = <0xfef05000 0x1000>; - interrupts = <19 2>; - interrupt-parent = <&mpic>; - - ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash - 1 0 0xe8000000 0x08000000 // Paged Flash 0 - 2 0 0xe0000000 0x08000000 // Paged Flash 1 - 3 0 0xfc100000 0x00020000 // NVRAM - 4 0 0xfc000000 0x00008000 // FPGA - 5 0 0xfc008000 0x00008000 // AFIX FPGA - 6 0 0xfd000000 0x00800000 // IO FPGA (8-bit) - 7 0 0xfd800000 0x00800000>; // IO FPGA (32-bit) - - /* flash@0,0 is a mirror of part of the memory in flash@1,0 - flash@0,0 { - compatible = "gef,sbc610-firmware-mirror", "cfi-flash"; - reg = <0x0 0x0 0x1000000>; - bank-width = <4>; - device-width = <2>; - #address-cells = <1>; - #size-cells = <1>; - partition@0 { - label = "firmware"; - reg = <0x0 0x1000000>; - read-only; - }; - }; - */ - - flash@1,0 { - compatible = "gef,sbc610-paged-flash", "cfi-flash"; - reg = <0x1 0x0 0x8000000>; - bank-width = <4>; - device-width = <2>; - #address-cells = <1>; - #size-cells = <1>; - partition@0 { - label = "user"; - reg = <0x0 0x7800000>; - }; - partition@7800000 { - label = "firmware"; - reg = <0x7800000 0x800000>; - read-only; - }; - }; - - nvram@3,0 { - device_type = "nvram"; - compatible = "simtek,stk14ca8"; - reg = <0x3 0x0 0x20000>; - }; - - fpga@4,0 { - compatible = "gef,fpga-regs"; - reg = <0x4 0x0 0x40>; - }; - - wdt@4,2000 { - compatible = "gef,fpga-wdt"; - reg = <0x4 0x2000 0x8>; - interrupts = <0x1a 0x4>; - interrupt-parent = <&gef_pic>; - }; - /* Second watchdog available, driver currently supports one. - wdt@4,2010 { - compatible = "gef,fpga-wdt"; - reg = <0x4 0x2010 0x8>; - interrupts = <0x1b 0x4>; - interrupt-parent = <&gef_pic>; - }; - */ - gef_pic: pic@4,4000 { - #interrupt-cells = <1>; - interrupt-controller; - compatible = "gef,fpga-pic"; - reg = <0x4 0x4000 0x20>; - interrupts = <0x8 - 0x9>; - interrupt-parent = <&mpic>; - - }; - gef_gpio: gpio@7,14000 { - #gpio-cells = <2>; - compatible = "gef,sbc610-gpio"; - reg = <0x7 0x14000 0x24>; - gpio-controller; - }; - }; - - soc@fef00000 { - #address-cells = <1>; - #size-cells = <1>; - #interrupt-cells = <2>; - device_type = "soc"; - compatible = "simple-bus"; - ranges = <0x0 0xfef00000 0x00100000>; - bus-frequency = <33333333>; - - mcm-law@0 { - compatible = "fsl,mcm-law"; - reg = <0x0 0x1000>; - fsl,num-laws = <10>; - }; - - mcm@1000 { - compatible = "fsl,mpc8641-mcm", "fsl,mcm"; - reg = <0x1000 0x1000>; - interrupts = <17 2>; - interrupt-parent = <&mpic>; - }; - - i2c1: i2c@3000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl-i2c"; - reg = <0x3000 0x100>; - interrupts = <0x2b 0x2>; - interrupt-parent = <&mpic>; - dfsrr; - - hwmon@48 { - compatible = "national,lm92"; - reg = <0x48>; - }; - - hwmon@4c { - compatible = "adi,adt7461"; - reg = <0x4c>; - }; - - rtc@51 { - compatible = "epson,rx8581"; - reg = <0x00000051>; - }; - - eti@6b { - compatible = "dallas,ds1682"; - reg = <0x6b>; - }; - }; - - i2c2: i2c@3100 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl-i2c"; - reg = <0x3100 0x100>; - interrupts = <0x2b 0x2>; - interrupt-parent = <&mpic>; - dfsrr; - }; - - dma@21300 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma"; - reg = <0x21300 0x4>; - ranges = <0x0 0x21100 0x200>; - cell-index = <0>; - dma-channel@0 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x0 0x80>; - cell-index = <0>; - interrupt-parent = <&mpic>; - interrupts = <20 2>; - }; - dma-channel@80 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x80 0x80>; - cell-index = <1>; - interrupt-parent = <&mpic>; - interrupts = <21 2>; - }; - dma-channel@100 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x100 0x80>; - cell-index = <2>; - interrupt-parent = <&mpic>; - interrupts = <22 2>; - }; - dma-channel@180 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x180 0x80>; - cell-index = <3>; - interrupt-parent = <&mpic>; - interrupts = <23 2>; - }; - }; - - enet0: ethernet@24000 { - #address-cells = <1>; - #size-cells = <1>; - cell-index = <0>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <29 2 30 2 34 2>; - interrupt-parent = <&mpic>; - tbi-handle = <&tbi0>; - phy-handle = <&phy0>; - phy-connection-type = "gmii"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy0: ethernet-phy@0 { - interrupt-parent = <&gef_pic>; - interrupts = <0x9 0x4>; - reg = <1>; - }; - phy2: ethernet-phy@2 { - interrupt-parent = <&gef_pic>; - interrupts = <0x8 0x4>; - reg = <3>; - }; - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; - }; - - enet1: ethernet@26000 { - #address-cells = <1>; - #size-cells = <1>; - cell-index = <2>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <0x26000 0x1000>; - ranges = <0x0 0x26000 0x1000>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <31 2 32 2 33 2>; - interrupt-parent = <&mpic>; - tbi-handle = <&tbi2>; - phy-handle = <&phy2>; - phy-connection-type = "gmii"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi2: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; - }; - - serial0: serial@4500 { - cell-index = <0>; - device_type = "serial"; - compatible = "fsl,ns16550", "ns16550"; - reg = <0x4500 0x100>; - clock-frequency = <0>; - interrupts = <0x2a 0x2>; - interrupt-parent = <&mpic>; - }; - - serial1: serial@4600 { - cell-index = <1>; - device_type = "serial"; - compatible = "fsl,ns16550", "ns16550"; - reg = <0x4600 0x100>; - clock-frequency = <0>; - interrupts = <0x1c 0x2>; - interrupt-parent = <&mpic>; - }; - - mpic: pic@40000 { - clock-frequency = <0>; - interrupt-controller; - #address-cells = <0>; - #interrupt-cells = <2>; - reg = <0x40000 0x40000>; - compatible = "chrp,open-pic"; - device_type = "open-pic"; - }; - - msi@41600 { - compatible = "fsl,mpc8641-msi", "fsl,mpic-msi"; - reg = <0x41600 0x80>; - msi-available-ranges = <0 0x100>; - interrupts = < - 0xe0 0 - 0xe1 0 - 0xe2 0 - 0xe3 0 - 0xe4 0 - 0xe5 0 - 0xe6 0 - 0xe7 0>; - interrupt-parent = <&mpic>; - }; - - global-utilities@e0000 { - compatible = "fsl,mpc8641-guts"; - reg = <0xe0000 0x1000>; - fsl,has-rstcr; - }; - }; - - pci0: pcie@fef08000 { - compatible = "fsl,mpc8641-pcie"; - device_type = "pci"; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - reg = <0xfef08000 0x1000>; - bus-range = <0x0 0xff>; - ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x40000000 - 0x01000000 0x0 0x00000000 0xfe000000 0x0 0x00400000>; - clock-frequency = <33333333>; - interrupt-parent = <&mpic>; - interrupts = <0x18 0x2>; - interrupt-map-mask = <0xf800 0x0 0x0 0x7>; - interrupt-map = < - 0x0000 0x0 0x0 0x1 &mpic 0x0 0x1 - 0x0000 0x0 0x0 0x2 &mpic 0x1 0x1 - 0x0000 0x0 0x0 0x3 &mpic 0x2 0x1 - 0x0000 0x0 0x0 0x4 &mpic 0x3 0x1 - >; - - pcie@0 { - reg = <0 0 0 0 0>; - #size-cells = <2>; - #address-cells = <3>; - device_type = "pci"; - ranges = <0x02000000 0x0 0x80000000 - 0x02000000 0x0 0x80000000 - 0x0 0x40000000 - - 0x01000000 0x0 0x00000000 - 0x01000000 0x0 0x00000000 - 0x0 0x00400000>; - }; - }; -}; diff --git a/arch/powerpc/boot/dts/sbc8641d.dts b/arch/powerpc/boot/dts/sbc8641d.dts deleted file mode 100644 index 68f0ed7626bd96252f768c7dcca12e8e0294ef69..0000000000000000000000000000000000000000 --- a/arch/powerpc/boot/dts/sbc8641d.dts +++ /dev/null @@ -1,447 +0,0 @@ -/* - * SBC8641D Device Tree Source - * - * Copyright 2008 Wind River Systems Inc. - * - * Paul Gortmaker (see MAINTAINERS for contact information) - * - * Based largely on the mpc8641_hpcn.dts by Freescale Semiconductor Inc. - * - * 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. - */ - -/dts-v1/; - -/ { - model = "SBC8641D"; - compatible = "wind,sbc8641"; - #address-cells = <1>; - #size-cells = <1>; - - aliases { - ethernet0 = &enet0; - ethernet1 = &enet1; - ethernet2 = &enet2; - ethernet3 = &enet3; - serial0 = &serial0; - serial1 = &serial1; - pci0 = &pci0; - pci1 = &pci1; - }; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - PowerPC,8641@0 { - device_type = "cpu"; - reg = <0>; - d-cache-line-size = <32>; - i-cache-line-size = <32>; - d-cache-size = <32768>; // L1 - i-cache-size = <32768>; // L1 - timebase-frequency = <0>; // From uboot - bus-frequency = <0>; // From uboot - clock-frequency = <0>; // From uboot - }; - PowerPC,8641@1 { - device_type = "cpu"; - reg = <1>; - d-cache-line-size = <32>; - i-cache-line-size = <32>; - d-cache-size = <32768>; - i-cache-size = <32768>; - timebase-frequency = <0>; // From uboot - bus-frequency = <0>; // From uboot - clock-frequency = <0>; // From uboot - }; - }; - - memory { - device_type = "memory"; - reg = <0x00000000 0x20000000>; // 512M at 0x0 - }; - - localbus@f8005000 { - #address-cells = <2>; - #size-cells = <1>; - compatible = "fsl,mpc8641-localbus", "simple-bus"; - reg = <0xf8005000 0x1000>; - interrupts = <19 2>; - interrupt-parent = <&mpic>; - - ranges = <0 0 0xff000000 0x01000000 // 16MB Boot flash - 1 0 0xf0000000 0x00010000 // 64KB EEPROM - 2 0 0xf1000000 0x00100000 // EPLD (1MB) - 3 0 0xe0000000 0x04000000 // 64MB LB SDRAM (CS3) - 4 0 0xe4000000 0x04000000 // 64MB LB SDRAM (CS4) - 6 0 0xf4000000 0x00100000 // LCD display (1MB) - 7 0 0xe8000000 0x04000000>; // 64MB OneNAND - - flash@0,0 { - compatible = "cfi-flash"; - reg = <0 0 0x01000000>; - bank-width = <2>; - device-width = <2>; - #address-cells = <1>; - #size-cells = <1>; - partition@0 { - label = "dtb"; - reg = <0x00000000 0x00100000>; - read-only; - }; - partition@300000 { - label = "kernel"; - reg = <0x00100000 0x00400000>; - read-only; - }; - partition@400000 { - label = "fs"; - reg = <0x00500000 0x00a00000>; - }; - partition@700000 { - label = "firmware"; - reg = <0x00f00000 0x00100000>; - read-only; - }; - }; - - epld@2,0 { - compatible = "wrs,epld-localbus"; - #address-cells = <2>; - #size-cells = <1>; - reg = <2 0 0x100000>; - ranges = <0 0 5 0 1 // User switches - 1 0 5 1 1 // Board ID/Rev - 3 0 5 3 1>; // LEDs - }; - }; - - soc@f8000000 { - #address-cells = <1>; - #size-cells = <1>; - device_type = "soc"; - compatible = "simple-bus"; - ranges = <0x00000000 0xf8000000 0x00100000>; - bus-frequency = <0>; - - mcm-law@0 { - compatible = "fsl,mcm-law"; - reg = <0x0 0x1000>; - fsl,num-laws = <10>; - }; - - mcm@1000 { - compatible = "fsl,mpc8641-mcm", "fsl,mcm"; - reg = <0x1000 0x1000>; - interrupts = <17 2>; - interrupt-parent = <&mpic>; - }; - - i2c@3000 { - #address-cells = <1>; - #size-cells = <0>; - cell-index = <0>; - compatible = "fsl-i2c"; - reg = <0x3000 0x100>; - interrupts = <43 2>; - interrupt-parent = <&mpic>; - dfsrr; - }; - - i2c@3100 { - #address-cells = <1>; - #size-cells = <0>; - cell-index = <1>; - compatible = "fsl-i2c"; - reg = <0x3100 0x100>; - interrupts = <43 2>; - interrupt-parent = <&mpic>; - dfsrr; - }; - - dma@21300 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma"; - reg = <0x21300 0x4>; - ranges = <0x0 0x21100 0x200>; - cell-index = <0>; - dma-channel@0 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x0 0x80>; - cell-index = <0>; - interrupt-parent = <&mpic>; - interrupts = <20 2>; - }; - dma-channel@80 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x80 0x80>; - cell-index = <1>; - interrupt-parent = <&mpic>; - interrupts = <21 2>; - }; - dma-channel@100 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x100 0x80>; - cell-index = <2>; - interrupt-parent = <&mpic>; - interrupts = <22 2>; - }; - dma-channel@180 { - compatible = "fsl,mpc8641-dma-channel", - "fsl,eloplus-dma-channel"; - reg = <0x180 0x80>; - cell-index = <3>; - interrupt-parent = <&mpic>; - interrupts = <23 2>; - }; - }; - - enet0: ethernet@24000 { - #address-cells = <1>; - #size-cells = <1>; - cell-index = <0>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <0x24000 0x1000>; - ranges = <0x0 0x24000 0x1000>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <29 2 30 2 34 2>; - interrupt-parent = <&mpic>; - tbi-handle = <&tbi0>; - phy-handle = <&phy0>; - phy-connection-type = "rgmii-id"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-mdio"; - reg = <0x520 0x20>; - - phy0: ethernet-phy@1f { - reg = <0x1f>; - }; - phy1: ethernet-phy@0 { - reg = <0>; - }; - phy2: ethernet-phy@1 { - reg = <1>; - }; - phy3: ethernet-phy@2 { - reg = <2>; - }; - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; - }; - - enet1: ethernet@25000 { - #address-cells = <1>; - #size-cells = <1>; - cell-index = <1>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <0x25000 0x1000>; - ranges = <0x0 0x25000 0x1000>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <35 2 36 2 40 2>; - interrupt-parent = <&mpic>; - tbi-handle = <&tbi1>; - phy-handle = <&phy1>; - phy-connection-type = "rgmii-id"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi1: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; - }; - - enet2: ethernet@26000 { - #address-cells = <1>; - #size-cells = <1>; - cell-index = <2>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <0x26000 0x1000>; - ranges = <0x0 0x26000 0x1000>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <31 2 32 2 33 2>; - interrupt-parent = <&mpic>; - tbi-handle = <&tbi2>; - phy-handle = <&phy2>; - phy-connection-type = "rgmii-id"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi2: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; - }; - - enet3: ethernet@27000 { - #address-cells = <1>; - #size-cells = <1>; - cell-index = <3>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <0x27000 0x1000>; - ranges = <0x0 0x27000 0x1000>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <37 2 38 2 39 2>; - interrupt-parent = <&mpic>; - tbi-handle = <&tbi3>; - phy-handle = <&phy3>; - phy-connection-type = "rgmii-id"; - - mdio@520 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,gianfar-tbi"; - reg = <0x520 0x20>; - - tbi3: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; - }; - - serial0: serial@4500 { - cell-index = <0>; - device_type = "serial"; - compatible = "fsl,ns16550", "ns16550"; - reg = <0x4500 0x100>; - clock-frequency = <0>; - interrupts = <42 2>; - interrupt-parent = <&mpic>; - }; - - serial1: serial@4600 { - cell-index = <1>; - device_type = "serial"; - compatible = "fsl,ns16550", "ns16550"; - reg = <0x4600 0x100>; - clock-frequency = <0>; - interrupts = <28 2>; - interrupt-parent = <&mpic>; - }; - - mpic: pic@40000 { - clock-frequency = <0>; - interrupt-controller; - #address-cells = <0>; - #interrupt-cells = <2>; - reg = <0x40000 0x40000>; - compatible = "chrp,open-pic"; - device_type = "open-pic"; - big-endian; - }; - - global-utilities@e0000 { - compatible = "fsl,mpc8641-guts"; - reg = <0xe0000 0x1000>; - fsl,has-rstcr; - }; - }; - - pci0: pcie@f8008000 { - compatible = "fsl,mpc8641-pcie"; - device_type = "pci"; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - reg = <0xf8008000 0x1000>; - bus-range = <0x0 0xff>; - ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x20000000 - 0x01000000 0x0 0x00000000 0xe2000000 0x0 0x00100000>; - clock-frequency = <33333333>; - interrupt-parent = <&mpic>; - interrupts = <24 2>; - interrupt-map-mask = <0xff00 0 0 7>; - interrupt-map = < - /* IDSEL 0x0 */ - 0x0000 0 0 1 &mpic 0 1 - 0x0000 0 0 2 &mpic 1 1 - 0x0000 0 0 3 &mpic 2 1 - 0x0000 0 0 4 &mpic 3 1 - >; - - pcie@0 { - reg = <0 0 0 0 0>; - #size-cells = <2>; - #address-cells = <3>; - device_type = "pci"; - ranges = <0x02000000 0x0 0x80000000 - 0x02000000 0x0 0x80000000 - 0x0 0x20000000 - - 0x01000000 0x0 0x00000000 - 0x01000000 0x0 0x00000000 - 0x0 0x00100000>; - }; - - }; - - pci1: pcie@f8009000 { - compatible = "fsl,mpc8641-pcie"; - device_type = "pci"; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - reg = <0xf8009000 0x1000>; - bus-range = <0 0xff>; - ranges = <0x02000000 0x0 0xa0000000 0xa0000000 0x0 0x20000000 - 0x01000000 0x0 0x00000000 0xe3000000 0x0 0x00100000>; - clock-frequency = <33333333>; - interrupt-parent = <&mpic>; - interrupts = <25 2>; - interrupt-map-mask = <0xf800 0 0 7>; - interrupt-map = < - /* IDSEL 0x0 */ - 0x0000 0 0 1 &mpic 4 1 - 0x0000 0 0 2 &mpic 5 1 - 0x0000 0 0 3 &mpic 6 1 - 0x0000 0 0 4 &mpic 7 1 - >; - - pcie@0 { - reg = <0 0 0 0 0>; - #size-cells = <2>; - #address-cells = <3>; - device_type = "pci"; - ranges = <0x02000000 0x0 0xa0000000 - 0x02000000 0x0 0xa0000000 - 0x0 0x20000000 - - 0x01000000 0x0 0x00000000 - 0x01000000 0x0 0x00000000 - 0x0 0x00100000>; - }; - }; -}; diff --git a/arch/powerpc/boot/rs6000.h b/arch/powerpc/boot/rs6000.h index 433f45084e416a3f1e094ed8e58d7c50f6b883fa..d70517ccc0f79a6196419e64c5d2b2754d678c62 100644 --- a/arch/powerpc/boot/rs6000.h +++ b/arch/powerpc/boot/rs6000.h @@ -239,5 +239,5 @@ struct external_reloc { #define DEFAULT_DATA_SECTION_ALIGNMENT 4 #define DEFAULT_BSS_SECTION_ALIGNMENT 4 #define DEFAULT_TEXT_SECTION_ALIGNMENT 4 -/* For new sections we havn't heard of before */ +/* For new sections we haven't heard of before */ #define DEFAULT_SECTION_ALIGNMENT 4 diff --git a/arch/powerpc/boot/treeboot-akebono.c b/arch/powerpc/boot/treeboot-akebono.c index b73174c34fe45f236ae2c6604c9f82f49ba697e2..bcc5902f8462a669115aa4bfcf332b2dd4637b0a 100644 --- a/arch/powerpc/boot/treeboot-akebono.c +++ b/arch/powerpc/boot/treeboot-akebono.c @@ -38,7 +38,7 @@ BSS_STACK(4096); -#define SPRN_PIR 0x11E /* Processor Indentification Register */ +#define SPRN_PIR 0x11E /* Processor Identification Register */ #define USERDATA_LEN 256 /* Length of userdata passed in by PIBS */ #define MAX_RANKS 0x4 #define DDR3_MR0CF 0x80010011U diff --git a/arch/powerpc/boot/treeboot-currituck.c b/arch/powerpc/boot/treeboot-currituck.c index 925ae43b746710fdc75a7dc90673e579d775d1f3..303d2074ee56314aad56415301c5524a9e954e84 100644 --- a/arch/powerpc/boot/treeboot-currituck.c +++ b/arch/powerpc/boot/treeboot-currituck.c @@ -80,7 +80,7 @@ static void ibm_currituck_fixups(void) } } -#define SPRN_PIR 0x11E /* Processor Indentification Register */ +#define SPRN_PIR 0x11E /* Processor Identification Register */ void platform_init(void) { unsigned long end_of_ram, avail_ram; diff --git a/arch/powerpc/boot/treeboot-iss4xx.c b/arch/powerpc/boot/treeboot-iss4xx.c index 329e710feda26d99f731c38a1eee0aeb15edc6d4..733f8bf25184f94f73cc0b5d14b56938fa1f2cd8 100644 --- a/arch/powerpc/boot/treeboot-iss4xx.c +++ b/arch/powerpc/boot/treeboot-iss4xx.c @@ -59,7 +59,7 @@ static void *iss_4xx_vmlinux_alloc(unsigned long size) return (void *)ibm4xx_memstart; } -#define SPRN_PIR 0x11E /* Processor Indentification Register */ +#define SPRN_PIR 0x11E /* Processor Identification Register */ void platform_init(void) { unsigned long end_of_ram = 0x08000000; diff --git a/arch/powerpc/configs/83xx/mpc834x_itx_defconfig b/arch/powerpc/configs/83xx/mpc834x_itx_defconfig index 2a5fdcbabcddb236dd0add614c1b3a3155e36996..87fc15bce407721ea70c476deb46009609a2d560 100644 --- a/arch/powerpc/configs/83xx/mpc834x_itx_defconfig +++ b/arch/powerpc/configs/83xx/mpc834x_itx_defconfig @@ -35,7 +35,6 @@ CONFIG_MTD_PHYSMAP=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=32768 -CONFIG_IDE=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_SG=y CONFIG_SCSI_SPI_ATTRS=y diff --git a/arch/powerpc/configs/85xx/ksi8560_defconfig b/arch/powerpc/configs/85xx/ksi8560_defconfig index 3be85c5f1a2a14c89fb56abe888732319c527914..6f753a71fe5d967da105dca6df4890a61cdc1c0c 100644 --- a/arch/powerpc/configs/85xx/ksi8560_defconfig +++ b/arch/powerpc/configs/85xx/ksi8560_defconfig @@ -34,7 +34,6 @@ CONFIG_MTD_PHYSMAP_OF=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=32768 -CONFIG_IDE=y CONFIG_NETDEVICES=y CONFIG_FS_ENET=y # CONFIG_FS_ENET_HAS_SCC is not set diff --git a/arch/powerpc/configs/85xx/stx_gp3_defconfig b/arch/powerpc/configs/85xx/stx_gp3_defconfig index f66d16ba8c5893eda9b6b4b79f1b28c8d57ae301..b45190556c0ca78f21d16c88b6724886d52a8d16 100644 --- a/arch/powerpc/configs/85xx/stx_gp3_defconfig +++ b/arch/powerpc/configs/85xx/stx_gp3_defconfig @@ -31,8 +31,6 @@ CONFIG_BLK_DEV_LOOP=m CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=32768 -CONFIG_IDE=y -CONFIG_BLK_DEV_IDECD=m CONFIG_SCSI=m CONFIG_BLK_DEV_SD=m CONFIG_CHR_DEV_ST=m diff --git a/arch/powerpc/configs/86xx-hw.config b/arch/powerpc/configs/86xx-hw.config new file mode 100644 index 0000000000000000000000000000000000000000..f91f8895fc930baff7db312a47b89a8f04aece5a --- /dev/null +++ b/arch/powerpc/configs/86xx-hw.config @@ -0,0 +1,104 @@ +CONFIG_ATA=y +CONFIG_BLK_DEV_SD=y +CONFIG_BLK_DEV_SR=y +CONFIG_BROADCOM_PHY=y +# CONFIG_CARDBUS is not set +CONFIG_CHR_DEV_SG=y +CONFIG_CHR_DEV_ST=y +CONFIG_CRC_T10DIF=y +CONFIG_CRYPTO_HMAC=y +CONFIG_DS1682=y +CONFIG_EEPROM_LEGACY=y +CONFIG_GEF_WDT=y +CONFIG_GIANFAR=y +CONFIG_GPIO_GE_FPGA=y +CONFIG_GPIO_SYSFS=y +CONFIG_HID_A4TECH=y +CONFIG_HID_APPLE=y +CONFIG_HID_BELKIN=y +CONFIG_HID_CHERRY=y +CONFIG_HID_CHICONY=y +CONFIG_HID_CYPRESS=y +CONFIG_HID_EZKEY=y +CONFIG_HID_GYRATION=y +CONFIG_HID_LOGITECH=y +CONFIG_HID_MICROSOFT=y +CONFIG_HID_MONTEREY=y +CONFIG_HID_PANTHERLORD=y +CONFIG_HID_PETALYNX=y +CONFIG_HID_SAMSUNG=y +CONFIG_HID_SUNPLUS=y +CONFIG_HW_RANDOM=y +CONFIG_HZ_1000=y +CONFIG_I2C_MPC=y +CONFIG_I2C=y +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +CONFIG_INPUT_FF_MEMLESS=m +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_MOUSE is not set +CONFIG_MTD_BLOCK=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_LE_BYTE_SWAP=y +CONFIG_MTD_CFI=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_NAND_FSL_ELBC=y +CONFIG_MTD_NAND=y +CONFIG_MTD_PHYSMAP_OF=y +CONFIG_NETDEVICES=y +CONFIG_NET_TULIP=y +CONFIG_NVRAM=y +CONFIG_PATA_ALI=y +CONFIG_PCCARD=y +CONFIG_PCI_DEBUG=y +# CONFIG_PCIEASPM is not set +CONFIG_PCIEPORTBUS=y +CONFIG_PCI=y +# CONFIG_PCMCIA_LOAD_CIS is not set +# CONFIG_PPC_CHRP is not set +# CONFIG_PPC_PMAC is not set +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_CMOS=y +CONFIG_RTC_DRV_RX8581=y +CONFIG_SATA_AHCI=y +CONFIG_SATA_SIL24=y +CONFIG_SATA_SIL=y +CONFIG_SCSI_LOGGING=y +CONFIG_SENSORS_LM90=y +CONFIG_SENSORS_LM92=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_DETECT_IRQ=y +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_NR_UARTS=2 +CONFIG_SERIAL_8250_RSA=y +CONFIG_SERIAL_8250_RUNTIME_UARTS=2 +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250=y +CONFIG_SERIO_LIBPS2=y +CONFIG_SND_INTEL8X0=y +CONFIG_SND_MIXER_OSS=y +CONFIG_SND_PCM_OSS=y +# CONFIG_SND_SUPPORT_OLD_API is not set +CONFIG_SND=y +CONFIG_SOUND=y +CONFIG_ULI526X=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_MON=y +CONFIG_USB_OHCI_HCD_PPC_OF_BE=y +CONFIG_USB_OHCI_HCD_PPC_OF_LE=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_STORAGE=y +CONFIG_USB=y +CONFIG_VITESSE_PHY=y +CONFIG_VME_BUS=y +CONFIG_VME_TSI148=y +CONFIG_WATCHDOG=y +# CONFIG_YENTA_O2 is not set +# CONFIG_YENTA_RICOH is not set +# CONFIG_YENTA_TOSHIBA is not set +CONFIG_YENTA=y diff --git a/arch/powerpc/configs/86xx-smp.config b/arch/powerpc/configs/86xx-smp.config new file mode 100644 index 0000000000000000000000000000000000000000..40ac38d3038c113216f4bc8464fc2ee2ac57b6fd --- /dev/null +++ b/arch/powerpc/configs/86xx-smp.config @@ -0,0 +1,2 @@ +CONFIG_NR_CPUS=2 +CONFIG_SMP=y diff --git a/arch/powerpc/configs/86xx/gef_ppc9a_defconfig b/arch/powerpc/configs/86xx/gef_ppc9a_defconfig deleted file mode 100644 index 9792a2cb9b207bc645377e80170d47f28d50db7b..0000000000000000000000000000000000000000 --- a/arch/powerpc/configs/86xx/gef_ppc9a_defconfig +++ /dev/null @@ -1,216 +0,0 @@ -CONFIG_SMP=y -CONFIG_NR_CPUS=2 -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_BSD_PROCESS_ACCT_V3=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_RELAY=y -CONFIG_BLK_DEV_INITRD=y -CONFIG_EXPERT=y -CONFIG_SLAB=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_PPC_CHRP is not set -# CONFIG_PPC_PMAC is not set -CONFIG_PPC_86xx=y -CONFIG_GEF_PPC9A=y -CONFIG_HIGHMEM=y -CONFIG_HZ_1000=y -CONFIG_PREEMPT=y -CONFIG_BINFMT_MISC=m -CONFIG_PCI=y -CONFIG_PCIEPORTBUS=y -# CONFIG_PCIEASPM is not set -CONFIG_PCCARD=y -# CONFIG_PCMCIA_LOAD_CIS is not set -# CONFIG_CARDBUS is not set -CONFIG_YENTA=y -# CONFIG_YENTA_O2 is not set -# CONFIG_YENTA_RICOH is not set -# CONFIG_YENTA_TOSHIBA is not set -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_XFRM_USER=m -CONFIG_NET_KEY=m -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_VERBOSE=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -CONFIG_NET_IPIP=m -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -CONFIG_SYN_COOKIES=y -CONFIG_INET_AH=m -CONFIG_INET_ESP=m -CONFIG_INET_IPCOMP=m -# CONFIG_INET_XFRM_MODE_BEET is not set -CONFIG_INET6_AH=m -CONFIG_INET6_ESP=m -CONFIG_INET6_IPCOMP=m -CONFIG_IPV6_TUNNEL=m -CONFIG_NET_PKTGEN=m -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_MTD=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_JEDECPROBE=y -CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_PHYSMAP_OF=y -CONFIG_BLK_DEV_LOOP=m -CONFIG_BLK_DEV_CRYPTOLOOP=m -CONFIG_BLK_DEV_NBD=m -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=131072 -CONFIG_DS1682=y -CONFIG_IDE=y -CONFIG_BLK_DEV_IDECS=y -CONFIG_BLK_DEV_SD=y -CONFIG_CHR_DEV_ST=y -CONFIG_BLK_DEV_SR=y -CONFIG_ATA=y -CONFIG_SATA_SIL=y -CONFIG_NETDEVICES=y -CONFIG_BONDING=m -CONFIG_DUMMY=m -CONFIG_NETCONSOLE=y -CONFIG_TUN=m -CONFIG_GIANFAR=y -CONFIG_PPP=m -CONFIG_PPP_BSDCOMP=m -CONFIG_PPP_DEFLATE=m -CONFIG_PPP_FILTER=y -CONFIG_PPP_MULTILINK=y -CONFIG_PPPOE=m -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_SLIP=m -CONFIG_SLIP_COMPRESSED=y -CONFIG_SLIP_SMART=y -CONFIG_SLIP_MODE_SLIP6=y -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_SERIO is not set -# CONFIG_LEGACY_PTYS is not set -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -# CONFIG_SERIAL_8250_PCI is not set -CONFIG_SERIAL_8250_NR_UARTS=2 -CONFIG_SERIAL_8250_RUNTIME_UARTS=2 -CONFIG_HW_RANDOM=y -CONFIG_NVRAM=y -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_MPC=y -CONFIG_GPIO_SYSFS=y -CONFIG_GPIO_GE_FPGA=y -CONFIG_SENSORS_LM90=y -CONFIG_SENSORS_LM92=y -CONFIG_WATCHDOG=y -CONFIG_GEF_WDT=y -CONFIG_HID_A4TECH=y -CONFIG_HID_APPLE=y -CONFIG_HID_BELKIN=y -CONFIG_HID_CHERRY=y -CONFIG_HID_CHICONY=y -CONFIG_HID_CYPRESS=y -CONFIG_HID_EZKEY=y -CONFIG_HID_GYRATION=y -CONFIG_HID_LOGITECH=y -CONFIG_HID_MICROSOFT=y -CONFIG_HID_MONTEREY=y -CONFIG_HID_PANTHERLORD=y -CONFIG_HID_PETALYNX=y -CONFIG_HID_SAMSUNG=y -CONFIG_HID_SUNPLUS=y -CONFIG_USB=y -CONFIG_USB_EHCI_HCD=y -# CONFIG_USB_EHCI_HCD_PPC_OF is not set -CONFIG_USB_OHCI_HCD=y -CONFIG_USB_STORAGE=y -CONFIG_RTC_CLASS=y -# CONFIG_RTC_INTF_PROC is not set -CONFIG_RTC_DRV_RX8581=y -CONFIG_STAGING=y -CONFIG_VME_BUS=y -CONFIG_VME_TSI148=y -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT2_FS_POSIX_ACL=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -CONFIG_EXT3_FS_POSIX_ACL=y -CONFIG_ISO9660_FS=y -CONFIG_JOLIET=y -CONFIG_ZISOFS=y -CONFIG_UDF_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=850 -CONFIG_FAT_DEFAULT_IOCHARSET="ascii" -CONFIG_PROC_KCORE=y -CONFIG_TMPFS=y -CONFIG_JFFS2_FS=y -CONFIG_NFS_FS=y -CONFIG_NFS_V4=y -CONFIG_ROOT_NFS=y -CONFIG_CIFS=m -CONFIG_CIFS_XATTR=y -CONFIG_CIFS_POSIX=y -CONFIG_NLS_CODEPAGE_437=m -CONFIG_NLS_CODEPAGE_737=m -CONFIG_NLS_CODEPAGE_775=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_CODEPAGE_852=m -CONFIG_NLS_CODEPAGE_855=m -CONFIG_NLS_CODEPAGE_857=m -CONFIG_NLS_CODEPAGE_860=m -CONFIG_NLS_CODEPAGE_861=m -CONFIG_NLS_CODEPAGE_862=m -CONFIG_NLS_CODEPAGE_863=m -CONFIG_NLS_CODEPAGE_864=m -CONFIG_NLS_CODEPAGE_865=m -CONFIG_NLS_CODEPAGE_866=m -CONFIG_NLS_CODEPAGE_869=m -CONFIG_NLS_CODEPAGE_936=m -CONFIG_NLS_CODEPAGE_950=m -CONFIG_NLS_CODEPAGE_932=m -CONFIG_NLS_CODEPAGE_949=m -CONFIG_NLS_CODEPAGE_874=m -CONFIG_NLS_ISO8859_8=m -CONFIG_NLS_CODEPAGE_1250=m -CONFIG_NLS_CODEPAGE_1251=m -CONFIG_NLS_ASCII=m -CONFIG_NLS_ISO8859_1=m -CONFIG_NLS_ISO8859_2=m -CONFIG_NLS_ISO8859_3=m -CONFIG_NLS_ISO8859_4=m -CONFIG_NLS_ISO8859_5=m -CONFIG_NLS_ISO8859_6=m -CONFIG_NLS_ISO8859_7=m -CONFIG_NLS_ISO8859_9=m -CONFIG_NLS_ISO8859_13=m -CONFIG_NLS_ISO8859_14=m -CONFIG_NLS_ISO8859_15=m -CONFIG_NLS_KOI8_R=m -CONFIG_NLS_KOI8_U=m -CONFIG_NLS_UTF8=m -CONFIG_CRC_CCITT=y -CONFIG_CRC_T10DIF=y -CONFIG_LIBCRC32C=y -CONFIG_MAGIC_SYSRQ=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set -# CONFIG_CRYPTO_HW is not set diff --git a/arch/powerpc/configs/86xx/gef_sbc310_defconfig b/arch/powerpc/configs/86xx/gef_sbc310_defconfig deleted file mode 100644 index cadc36682bb4f2c19e77135956a36ba3eecf7a22..0000000000000000000000000000000000000000 --- a/arch/powerpc/configs/86xx/gef_sbc310_defconfig +++ /dev/null @@ -1,214 +0,0 @@ -CONFIG_SMP=y -CONFIG_NR_CPUS=2 -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_BSD_PROCESS_ACCT_V3=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_RELAY=y -CONFIG_BLK_DEV_INITRD=y -CONFIG_EXPERT=y -CONFIG_SLAB=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_PPC_CHRP is not set -# CONFIG_PPC_PMAC is not set -CONFIG_PPC_86xx=y -CONFIG_GEF_SBC310=y -CONFIG_HIGHMEM=y -CONFIG_HZ_1000=y -CONFIG_PREEMPT=y -CONFIG_BINFMT_MISC=y -CONFIG_PCI=y -CONFIG_PCIEPORTBUS=y -# CONFIG_PCIEASPM is not set -CONFIG_PCCARD=y -# CONFIG_PCMCIA_LOAD_CIS is not set -# CONFIG_CARDBUS is not set -CONFIG_YENTA=y -# CONFIG_YENTA_O2 is not set -# CONFIG_YENTA_RICOH is not set -# CONFIG_YENTA_TOSHIBA is not set -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_XFRM_USER=m -CONFIG_NET_KEY=m -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_VERBOSE=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -CONFIG_NET_IPIP=m -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -CONFIG_SYN_COOKIES=y -CONFIG_INET_AH=m -CONFIG_INET_ESP=m -CONFIG_INET_IPCOMP=m -# CONFIG_INET_XFRM_MODE_BEET is not set -CONFIG_INET6_AH=m -CONFIG_INET6_ESP=m -CONFIG_INET6_IPCOMP=m -CONFIG_IPV6_TUNNEL=m -CONFIG_NET_PKTGEN=m -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_MTD=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_JEDECPROBE=y -CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_PHYSMAP_OF=y -CONFIG_BLK_DEV_LOOP=m -CONFIG_BLK_DEV_CRYPTOLOOP=m -CONFIG_BLK_DEV_NBD=m -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=131072 -CONFIG_DS1682=y -CONFIG_IDE=y -CONFIG_BLK_DEV_IDECS=y -CONFIG_BLK_DEV_SD=y -CONFIG_CHR_DEV_ST=y -CONFIG_BLK_DEV_SR=y -CONFIG_ATA=y -CONFIG_SATA_SIL24=y -# CONFIG_ATA_SFF is not set -CONFIG_NETDEVICES=y -CONFIG_BONDING=m -CONFIG_DUMMY=m -CONFIG_NETCONSOLE=y -CONFIG_TUN=m -CONFIG_GIANFAR=y -CONFIG_PPP=m -CONFIG_PPP_BSDCOMP=m -CONFIG_PPP_DEFLATE=m -CONFIG_PPP_FILTER=y -CONFIG_PPP_MULTILINK=y -CONFIG_PPPOE=m -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_SLIP=m -CONFIG_SLIP_COMPRESSED=y -CONFIG_SLIP_SMART=y -CONFIG_SLIP_MODE_SLIP6=y -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_SERIO is not set -# CONFIG_LEGACY_PTYS is not set -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -# CONFIG_SERIAL_8250_PCI is not set -CONFIG_SERIAL_8250_NR_UARTS=2 -CONFIG_SERIAL_8250_RUNTIME_UARTS=2 -CONFIG_HW_RANDOM=y -CONFIG_NVRAM=y -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_MPC=y -CONFIG_GPIO_SYSFS=y -CONFIG_GPIO_GE_FPGA=y -CONFIG_SENSORS_LM90=y -CONFIG_SENSORS_LM92=y -CONFIG_WATCHDOG=y -CONFIG_GEF_WDT=y -CONFIG_HID_A4TECH=y -CONFIG_HID_APPLE=y -CONFIG_HID_BELKIN=y -CONFIG_HID_CHERRY=y -CONFIG_HID_CHICONY=y -CONFIG_HID_CYPRESS=y -CONFIG_HID_EZKEY=y -CONFIG_HID_GYRATION=y -CONFIG_HID_LOGITECH=y -CONFIG_HID_MICROSOFT=y -CONFIG_HID_MONTEREY=y -CONFIG_HID_PANTHERLORD=y -CONFIG_HID_PETALYNX=y -CONFIG_HID_SAMSUNG=y -CONFIG_HID_SUNPLUS=y -CONFIG_USB=y -CONFIG_USB_EHCI_HCD=y -# CONFIG_USB_EHCI_HCD_PPC_OF is not set -CONFIG_USB_OHCI_HCD=y -CONFIG_USB_STORAGE=y -CONFIG_RTC_CLASS=y -# CONFIG_RTC_INTF_PROC is not set -CONFIG_RTC_DRV_RX8581=y -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT2_FS_POSIX_ACL=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -CONFIG_EXT3_FS_POSIX_ACL=y -CONFIG_ISO9660_FS=y -CONFIG_JOLIET=y -CONFIG_ZISOFS=y -CONFIG_UDF_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=850 -CONFIG_FAT_DEFAULT_IOCHARSET="ascii" -CONFIG_PROC_KCORE=y -CONFIG_TMPFS=y -CONFIG_JFFS2_FS=y -CONFIG_NFS_FS=y -CONFIG_NFS_V4=y -CONFIG_ROOT_NFS=y -CONFIG_CIFS=m -CONFIG_CIFS_XATTR=y -CONFIG_CIFS_POSIX=y -CONFIG_NLS_CODEPAGE_437=m -CONFIG_NLS_CODEPAGE_737=m -CONFIG_NLS_CODEPAGE_775=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_CODEPAGE_852=m -CONFIG_NLS_CODEPAGE_855=m -CONFIG_NLS_CODEPAGE_857=m -CONFIG_NLS_CODEPAGE_860=m -CONFIG_NLS_CODEPAGE_861=m -CONFIG_NLS_CODEPAGE_862=m -CONFIG_NLS_CODEPAGE_863=m -CONFIG_NLS_CODEPAGE_864=m -CONFIG_NLS_CODEPAGE_865=m -CONFIG_NLS_CODEPAGE_866=m -CONFIG_NLS_CODEPAGE_869=m -CONFIG_NLS_CODEPAGE_936=m -CONFIG_NLS_CODEPAGE_950=m -CONFIG_NLS_CODEPAGE_932=m -CONFIG_NLS_CODEPAGE_949=m -CONFIG_NLS_CODEPAGE_874=m -CONFIG_NLS_ISO8859_8=m -CONFIG_NLS_CODEPAGE_1250=m -CONFIG_NLS_CODEPAGE_1251=m -CONFIG_NLS_ASCII=m -CONFIG_NLS_ISO8859_1=m -CONFIG_NLS_ISO8859_2=m -CONFIG_NLS_ISO8859_3=m -CONFIG_NLS_ISO8859_4=m -CONFIG_NLS_ISO8859_5=m -CONFIG_NLS_ISO8859_6=m -CONFIG_NLS_ISO8859_7=m -CONFIG_NLS_ISO8859_9=m -CONFIG_NLS_ISO8859_13=m -CONFIG_NLS_ISO8859_14=m -CONFIG_NLS_ISO8859_15=m -CONFIG_NLS_KOI8_R=m -CONFIG_NLS_KOI8_U=m -CONFIG_NLS_UTF8=m -CONFIG_CRC_CCITT=y -CONFIG_CRC_T10DIF=y -CONFIG_LIBCRC32C=y -CONFIG_MAGIC_SYSRQ=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set -# CONFIG_CRYPTO_HW is not set diff --git a/arch/powerpc/configs/86xx/gef_sbc610_defconfig b/arch/powerpc/configs/86xx/gef_sbc610_defconfig deleted file mode 100644 index 2aa7d9737e43cb142b860dee96dfb591769aaee2..0000000000000000000000000000000000000000 --- a/arch/powerpc/configs/86xx/gef_sbc610_defconfig +++ /dev/null @@ -1,273 +0,0 @@ -CONFIG_SMP=y -CONFIG_NR_CPUS=2 -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_BSD_PROCESS_ACCT_V3=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_RELAY=y -CONFIG_BLK_DEV_INITRD=y -CONFIG_EXPERT=y -CONFIG_SLAB=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_PPC_CHRP is not set -# CONFIG_PPC_PMAC is not set -CONFIG_PPC_86xx=y -CONFIG_GEF_SBC610=y -CONFIG_HIGHMEM=y -CONFIG_HZ_1000=y -CONFIG_PREEMPT=y -CONFIG_BINFMT_MISC=m -CONFIG_PCI=y -CONFIG_PCIEPORTBUS=y -# CONFIG_PCIEASPM is not set -CONFIG_PCI_DEBUG=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_XFRM_USER=m -CONFIG_NET_KEY=m -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_VERBOSE=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -CONFIG_NET_IPIP=m -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -CONFIG_SYN_COOKIES=y -CONFIG_INET_AH=m -CONFIG_INET_ESP=m -CONFIG_INET_IPCOMP=m -# CONFIG_INET_LRO is not set -CONFIG_INET6_AH=m -CONFIG_INET6_ESP=m -CONFIG_INET6_IPCOMP=m -CONFIG_IPV6_TUNNEL=m -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_XT_MATCH_SCTP is not set -CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_ECN=m -CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_FILTER=m -CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_MANGLE=m -CONFIG_IP_NF_TARGET_ECN=m -CONFIG_IP_NF_RAW=m -CONFIG_IP_NF_ARPTABLES=m -CONFIG_IP_NF_ARPFILTER=m -CONFIG_IP_NF_ARP_MANGLE=m -CONFIG_IP6_NF_IPTABLES=m -CONFIG_IP6_NF_MATCH_EUI64=m -CONFIG_IP6_NF_MATCH_FRAG=m -CONFIG_IP6_NF_MATCH_OPTS=m -CONFIG_IP6_NF_MATCH_HL=m -CONFIG_IP6_NF_MATCH_IPV6HEADER=m -CONFIG_IP6_NF_MATCH_RT=m -CONFIG_IP6_NF_FILTER=m -CONFIG_IP6_NF_MANGLE=m -CONFIG_IP6_NF_RAW=m -CONFIG_IP_SCTP=m -CONFIG_TIPC=m -CONFIG_ATM=m -CONFIG_ATM_CLIP=m -CONFIG_ATM_LANE=m -CONFIG_ATM_MPOA=m -CONFIG_ATM_BR2684=m -CONFIG_BRIDGE=m -CONFIG_VLAN_8021Q=m -CONFIG_NET_SCHED=y -CONFIG_NET_SCH_CBQ=m -CONFIG_NET_SCH_HTB=m -CONFIG_NET_SCH_HFSC=m -CONFIG_NET_SCH_ATM=m -CONFIG_NET_SCH_PRIO=m -CONFIG_NET_SCH_RED=m -CONFIG_NET_SCH_SFQ=m -CONFIG_NET_SCH_TEQL=m -CONFIG_NET_SCH_TBF=m -CONFIG_NET_SCH_GRED=m -CONFIG_NET_SCH_DSMARK=m -CONFIG_NET_SCH_NETEM=m -CONFIG_NET_CLS_TCINDEX=m -CONFIG_NET_CLS_ROUTE4=m -CONFIG_NET_CLS_FW=m -CONFIG_NET_CLS_U32=m -CONFIG_NET_CLS_RSVP=m -CONFIG_NET_CLS_RSVP6=m -CONFIG_NET_PKTGEN=m -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -# CONFIG_FW_LOADER is not set -CONFIG_MTD=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_JEDECPROBE=y -CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_PHYSMAP_OF=y -CONFIG_BLK_DEV_LOOP=m -CONFIG_BLK_DEV_CRYPTOLOOP=m -CONFIG_BLK_DEV_NBD=m -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=131072 -CONFIG_DS1682=y -CONFIG_BLK_DEV_SD=y -CONFIG_CHR_DEV_ST=y -CONFIG_BLK_DEV_SR=y -CONFIG_ATA=y -CONFIG_SATA_SIL=y -CONFIG_NETDEVICES=y -CONFIG_BONDING=m -CONFIG_DUMMY=m -CONFIG_NETCONSOLE=y -CONFIG_TUN=m -CONFIG_GIANFAR=y -CONFIG_PPP=m -CONFIG_PPP_BSDCOMP=m -CONFIG_PPP_DEFLATE=m -CONFIG_PPP_FILTER=y -CONFIG_PPP_MULTILINK=y -CONFIG_PPPOATM=m -CONFIG_PPPOE=m -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_SLIP=m -CONFIG_SLIP_COMPRESSED=y -CONFIG_SLIP_SMART=y -CONFIG_SLIP_MODE_SLIP6=y -CONFIG_INPUT_FF_MEMLESS=m -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_SERIO is not set -# CONFIG_LEGACY_PTYS is not set -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -# CONFIG_SERIAL_8250_PCI is not set -CONFIG_SERIAL_8250_NR_UARTS=2 -CONFIG_SERIAL_8250_RUNTIME_UARTS=2 -CONFIG_HW_RANDOM=y -CONFIG_NVRAM=y -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_MPC=y -CONFIG_GPIO_SYSFS=y -CONFIG_GPIO_GE_FPGA=y -CONFIG_SENSORS_LM90=y -CONFIG_SENSORS_LM92=y -CONFIG_WATCHDOG=y -CONFIG_GEF_WDT=y -CONFIG_HID_A4TECH=y -CONFIG_HID_APPLE=y -CONFIG_HID_BELKIN=y -CONFIG_HID_CHERRY=y -CONFIG_HID_CHICONY=y -CONFIG_HID_CYPRESS=y -CONFIG_HID_EZKEY=y -CONFIG_HID_GYRATION=y -CONFIG_HID_LOGITECH=y -CONFIG_HID_MICROSOFT=y -CONFIG_HID_MONTEREY=y -CONFIG_HID_PANTHERLORD=y -CONFIG_HID_PETALYNX=y -CONFIG_HID_SAMSUNG=y -CONFIG_HID_SUNPLUS=y -CONFIG_USB=y -CONFIG_USB_EHCI_HCD=y -# CONFIG_USB_EHCI_HCD_PPC_OF is not set -CONFIG_USB_OHCI_HCD=y -CONFIG_USB_STORAGE=y -CONFIG_RTC_CLASS=y -# CONFIG_RTC_INTF_PROC is not set -CONFIG_RTC_DRV_RX8581=y -CONFIG_STAGING=y -CONFIG_VME_BUS=y -CONFIG_VME_TSI148=y -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT2_FS_POSIX_ACL=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -CONFIG_EXT3_FS_POSIX_ACL=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_PROC_KCORE=y -CONFIG_TMPFS=y -CONFIG_JFFS2_FS=y -CONFIG_NFS_FS=y -CONFIG_NFS_V4=y -CONFIG_ROOT_NFS=y -CONFIG_CIFS=m -CONFIG_CIFS_XATTR=y -CONFIG_CIFS_POSIX=y -CONFIG_NLS_CODEPAGE_437=m -CONFIG_NLS_CODEPAGE_737=m -CONFIG_NLS_CODEPAGE_775=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_CODEPAGE_852=m -CONFIG_NLS_CODEPAGE_855=m -CONFIG_NLS_CODEPAGE_857=m -CONFIG_NLS_CODEPAGE_860=m -CONFIG_NLS_CODEPAGE_861=m -CONFIG_NLS_CODEPAGE_862=m -CONFIG_NLS_CODEPAGE_863=m -CONFIG_NLS_CODEPAGE_864=m -CONFIG_NLS_CODEPAGE_865=m -CONFIG_NLS_CODEPAGE_866=m -CONFIG_NLS_CODEPAGE_869=m -CONFIG_NLS_CODEPAGE_936=m -CONFIG_NLS_CODEPAGE_950=m -CONFIG_NLS_CODEPAGE_932=m -CONFIG_NLS_CODEPAGE_949=m -CONFIG_NLS_CODEPAGE_874=m -CONFIG_NLS_ISO8859_8=m -CONFIG_NLS_CODEPAGE_1250=m -CONFIG_NLS_CODEPAGE_1251=m -CONFIG_NLS_ASCII=m -CONFIG_NLS_ISO8859_1=m -CONFIG_NLS_ISO8859_2=m -CONFIG_NLS_ISO8859_3=m -CONFIG_NLS_ISO8859_4=m -CONFIG_NLS_ISO8859_5=m -CONFIG_NLS_ISO8859_6=m -CONFIG_NLS_ISO8859_7=m -CONFIG_NLS_ISO8859_9=m -CONFIG_NLS_ISO8859_13=m -CONFIG_NLS_ISO8859_14=m -CONFIG_NLS_ISO8859_15=m -CONFIG_NLS_KOI8_R=m -CONFIG_NLS_KOI8_U=m -CONFIG_NLS_UTF8=m -CONFIG_DEBUG_INFO=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_DETECT_HUNG_TASK=y -# CONFIG_DEBUG_BUGVERBOSE is not set -CONFIG_SECURITY=y -CONFIG_SECURITY_NETWORK=y -CONFIG_CRYPTO_NULL=m -CONFIG_CRYPTO_TEST=m -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_HMAC=y -CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_WP512=m -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_CAST5=m -CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_SERPENT=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_TWOFISH=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set -# CONFIG_CRYPTO_HW is not set diff --git a/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig b/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig deleted file mode 100644 index e32207de2b77d9201924a4db668fac74e899fc21..0000000000000000000000000000000000000000 --- a/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig +++ /dev/null @@ -1,110 +0,0 @@ -# CONFIG_SWAP is not set -CONFIG_SYSVIPC=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_BLK_DEV_INITRD=y -CONFIG_EXPERT=y -# CONFIG_ELF_CORE is not set -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -CONFIG_PARTITION_ADVANCED=y -CONFIG_LDM_PARTITION=y -# CONFIG_IOSCHED_CFQ is not set -# CONFIG_PPC_CHRP is not set -# CONFIG_PPC_PMAC is not set -CONFIG_PPC_86xx=y -CONFIG_MPC8610_HPCD=y -CONFIG_HIGHMEM=y -CONFIG_HZ_1000=y -CONFIG_FORCE_MAX_ZONEORDER=12 -# CONFIG_SECCOMP is not set -CONFIG_PCI=y -CONFIG_PCIEPORTBUS=y -# CONFIG_PCIEASPM is not set -CONFIG_PCI_DEBUG=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_XFRM_USER=y -CONFIG_INET=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -# CONFIG_INET_LRO is not set -CONFIG_IPV6=y -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_PHYSMAP_OF=y -CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_FSL_ELBC=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=131072 -CONFIG_IDE=y -CONFIG_BLK_DEV_SD=y -CONFIG_CHR_DEV_SG=y -CONFIG_ATA=y -CONFIG_SATA_AHCI=y -CONFIG_PATA_ALI=y -CONFIG_NETDEVICES=y -CONFIG_DUMMY=y -CONFIG_NET_TULIP=y -CONFIG_ULI526X=y -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -CONFIG_SERIO_LIBPS2=y -# CONFIG_LEGACY_PTYS is not set -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=2 -CONFIG_SERIAL_8250_RUNTIME_UARTS=2 -CONFIG_SERIAL_8250_EXTENDED=y -CONFIG_SERIAL_8250_MANY_PORTS=y -CONFIG_SERIAL_8250_SHARE_IRQ=y -CONFIG_SERIAL_8250_DETECT_IRQ=y -CONFIG_SERIAL_8250_RSA=y -# CONFIG_HW_RANDOM is not set -CONFIG_I2C=y -CONFIG_I2C_MPC=y -# CONFIG_HWMON is not set -CONFIG_FB=y -CONFIG_FB_FSL_DIU=y -CONFIG_VGACON_SOFT_SCROLLBACK=y -CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_SOUND=y -CONFIG_SND=y -CONFIG_SND_MIXER_OSS=y -CONFIG_SND_PCM_OSS=y -# CONFIG_SND_SUPPORT_OLD_API is not set -CONFIG_SND_SOC=y -CONFIG_SND_POWERPC_SOC=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_CMOS=y -CONFIG_EXT2_FS=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -# CONFIG_DNOTIFY is not set -CONFIG_PROC_KCORE=y -CONFIG_TMPFS=y -CONFIG_NFS_FS=y -CONFIG_ROOT_NFS=y -CONFIG_NFSD=y -CONFIG_NLS=y -CONFIG_CRC_T10DIF=y -CONFIG_FONTS=y -CONFIG_FONT_8x8=y -CONFIG_FONT_8x16=y -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_SHIRQ=y -CONFIG_DETECT_HUNG_TASK=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig b/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig deleted file mode 100644 index a36e11ddaebd5d5c2612803be552b6c20254c606..0000000000000000000000000000000000000000 --- a/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig +++ /dev/null @@ -1,156 +0,0 @@ -CONFIG_SMP=y -CONFIG_NR_CPUS=2 -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -CONFIG_AUDIT=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_BLK_DEV_INITRD=y -CONFIG_EXPERT=y -CONFIG_KALLSYMS_ALL=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -CONFIG_MODVERSIONS=y -# CONFIG_BLK_DEV_BSG is not set -CONFIG_PARTITION_ADVANCED=y -CONFIG_MAC_PARTITION=y -# CONFIG_PPC_CHRP is not set -# CONFIG_PPC_PMAC is not set -CONFIG_PPC_86xx=y -CONFIG_MPC8641_HPCN=y -CONFIG_HIGHMEM=y -CONFIG_HZ_1000=y -CONFIG_BINFMT_MISC=m -CONFIG_PCI=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_XFRM_USER=y -CONFIG_NET_KEY=m -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_VERBOSE=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -CONFIG_NET_IPIP=y -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set -CONFIG_IPV6=y -CONFIG_IP_SCTP=m -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_NBD=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=131072 -CONFIG_EEPROM_LEGACY=y -CONFIG_BLK_DEV_SD=y -CONFIG_CHR_DEV_ST=y -CONFIG_BLK_DEV_SR=y -CONFIG_CHR_DEV_SG=y -CONFIG_SCSI_LOGGING=y -CONFIG_ATA=y -CONFIG_SATA_AHCI=y -CONFIG_PATA_ALI=y -CONFIG_NETDEVICES=y -CONFIG_DUMMY=y -CONFIG_GIANFAR=y -CONFIG_VITESSE_PHY=y -CONFIG_INPUT_FF_MEMLESS=m -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -CONFIG_SERIO_LIBPS2=y -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=2 -CONFIG_SERIAL_8250_RUNTIME_UARTS=2 -CONFIG_SERIAL_8250_EXTENDED=y -CONFIG_SERIAL_8250_MANY_PORTS=y -CONFIG_SERIAL_8250_SHARE_IRQ=y -CONFIG_SERIAL_8250_DETECT_IRQ=y -CONFIG_SERIAL_8250_RSA=y -# CONFIG_HW_RANDOM is not set -CONFIG_NVRAM=y -CONFIG_I2C=y -CONFIG_I2C_MPC=y -# CONFIG_HWMON is not set -CONFIG_SOUND=y -CONFIG_SND=y -CONFIG_SND_MIXER_OSS=y -CONFIG_SND_PCM_OSS=y -# CONFIG_SND_SUPPORT_OLD_API is not set -CONFIG_SND_INTEL8X0=y -CONFIG_HID_A4TECH=y -CONFIG_HID_APPLE=y -CONFIG_HID_BELKIN=y -CONFIG_HID_CHERRY=y -CONFIG_HID_CHICONY=y -CONFIG_HID_CYPRESS=y -CONFIG_HID_EZKEY=y -CONFIG_HID_GYRATION=y -CONFIG_HID_LOGITECH=y -CONFIG_HID_MICROSOFT=y -CONFIG_HID_MONTEREY=y -CONFIG_HID_PANTHERLORD=y -CONFIG_HID_PETALYNX=y -CONFIG_HID_SAMSUNG=y -CONFIG_HID_SUNPLUS=y -CONFIG_USB=y -CONFIG_USB_MON=y -CONFIG_USB_EHCI_HCD=y -CONFIG_USB_OHCI_HCD=y -CONFIG_USB_OHCI_HCD_PPC_OF_BE=y -CONFIG_USB_OHCI_HCD_PPC_OF_LE=y -CONFIG_USB_STORAGE=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_CMOS=y -CONFIG_EXT2_FS=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -CONFIG_ISO9660_FS=m -CONFIG_JOLIET=y -CONFIG_ZISOFS=y -CONFIG_UDF_FS=m -CONFIG_MSDOS_FS=m -CONFIG_VFAT_FS=y -CONFIG_NTFS_FS=y -CONFIG_PROC_KCORE=y -CONFIG_TMPFS=y -CONFIG_ADFS_FS=m -CONFIG_AFFS_FS=m -CONFIG_HFS_FS=m -CONFIG_HFSPLUS_FS=m -CONFIG_BEFS_FS=m -CONFIG_BFS_FS=m -CONFIG_EFS_FS=m -CONFIG_CRAMFS=y -CONFIG_VXFS_FS=m -CONFIG_HPFS_FS=m -CONFIG_QNX4FS_FS=m -CONFIG_SYSV_FS=m -CONFIG_UFS_FS=m -CONFIG_NFS_FS=y -CONFIG_NFS_V4=y -CONFIG_ROOT_NFS=y -CONFIG_NFSD=y -CONFIG_CRC_T10DIF=y -CONFIG_DEBUG_INFO=y -CONFIG_DETECT_HUNG_TASK=y -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_HMAC=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/86xx/sbc8641d_defconfig b/arch/powerpc/configs/86xx/sbc8641d_defconfig deleted file mode 100644 index db79bdee844b9a046471edb92e3d28dd64bf24d2..0000000000000000000000000000000000000000 --- a/arch/powerpc/configs/86xx/sbc8641d_defconfig +++ /dev/null @@ -1,246 +0,0 @@ -CONFIG_SMP=y -CONFIG_NR_CPUS=2 -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_BSD_PROCESS_ACCT_V3=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_RELAY=y -CONFIG_BLK_DEV_INITRD=y -CONFIG_EXPERT=y -CONFIG_SLAB=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_PPC_CHRP is not set -# CONFIG_PPC_PMAC is not set -CONFIG_PPC_86xx=y -CONFIG_SBC8641D=y -CONFIG_PREEMPT=y -CONFIG_BINFMT_MISC=m -CONFIG_PCI=y -CONFIG_PCIEPORTBUS=y -# CONFIG_PCIEASPM is not set -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_XFRM_USER=m -CONFIG_NET_KEY=m -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_VERBOSE=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -CONFIG_NET_IPIP=m -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -CONFIG_SYN_COOKIES=y -CONFIG_INET_AH=m -CONFIG_INET_ESP=m -CONFIG_INET_IPCOMP=m -# CONFIG_INET_LRO is not set -CONFIG_INET6_AH=m -CONFIG_INET6_ESP=m -CONFIG_INET6_IPCOMP=m -CONFIG_IPV6_TUNNEL=m -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_XT_MATCH_SCTP is not set -CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_ECN=m -CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_FILTER=m -CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_MANGLE=m -CONFIG_IP_NF_TARGET_ECN=m -CONFIG_IP_NF_RAW=m -CONFIG_IP_NF_ARPTABLES=m -CONFIG_IP_NF_ARPFILTER=m -CONFIG_IP_NF_ARP_MANGLE=m -CONFIG_IP6_NF_IPTABLES=m -CONFIG_IP6_NF_MATCH_EUI64=m -CONFIG_IP6_NF_MATCH_FRAG=m -CONFIG_IP6_NF_MATCH_OPTS=m -CONFIG_IP6_NF_MATCH_HL=m -CONFIG_IP6_NF_MATCH_IPV6HEADER=m -CONFIG_IP6_NF_MATCH_RT=m -CONFIG_IP6_NF_FILTER=m -CONFIG_IP6_NF_MANGLE=m -CONFIG_IP6_NF_RAW=m -CONFIG_IP_SCTP=m -CONFIG_TIPC=m -CONFIG_ATM=m -CONFIG_ATM_CLIP=m -CONFIG_ATM_LANE=m -CONFIG_ATM_MPOA=m -CONFIG_ATM_BR2684=m -CONFIG_BRIDGE=m -CONFIG_VLAN_8021Q=m -CONFIG_NET_SCHED=y -CONFIG_NET_SCH_CBQ=m -CONFIG_NET_SCH_HTB=m -CONFIG_NET_SCH_HFSC=m -CONFIG_NET_SCH_ATM=m -CONFIG_NET_SCH_PRIO=m -CONFIG_NET_SCH_RED=m -CONFIG_NET_SCH_SFQ=m -CONFIG_NET_SCH_TEQL=m -CONFIG_NET_SCH_TBF=m -CONFIG_NET_SCH_GRED=m -CONFIG_NET_SCH_DSMARK=m -CONFIG_NET_SCH_NETEM=m -CONFIG_NET_CLS_TCINDEX=m -CONFIG_NET_CLS_ROUTE4=m -CONFIG_NET_CLS_FW=m -CONFIG_NET_CLS_U32=m -CONFIG_NET_CLS_RSVP=m -CONFIG_NET_CLS_RSVP6=m -CONFIG_NET_PKTGEN=m -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -# CONFIG_FW_LOADER is not set -CONFIG_MTD=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_CFI_ADV_OPTIONS=y -CONFIG_MTD_CFI_LE_BYTE_SWAP=y -CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_PHYSMAP_OF=y -CONFIG_BLK_DEV_LOOP=m -CONFIG_BLK_DEV_CRYPTOLOOP=m -CONFIG_BLK_DEV_NBD=m -CONFIG_BLK_DEV_RAM=y -CONFIG_MD=y -CONFIG_BLK_DEV_MD=y -CONFIG_MD_LINEAR=y -CONFIG_MD_RAID0=y -CONFIG_MD_RAID1=y -CONFIG_MD_RAID10=y -CONFIG_MD_MULTIPATH=y -CONFIG_MD_FAULTY=y -CONFIG_BLK_DEV_DM=y -CONFIG_DM_CRYPT=y -CONFIG_DM_SNAPSHOT=y -CONFIG_DM_MIRROR=y -CONFIG_DM_ZERO=y -CONFIG_NETDEVICES=y -CONFIG_BONDING=m -CONFIG_DUMMY=m -CONFIG_NETCONSOLE=y -CONFIG_TUN=m -CONFIG_GIANFAR=y -CONFIG_BROADCOM_PHY=y -CONFIG_PPP=m -CONFIG_PPP_BSDCOMP=m -CONFIG_PPP_DEFLATE=m -CONFIG_PPP_FILTER=y -CONFIG_PPP_MULTILINK=y -CONFIG_PPPOATM=m -CONFIG_PPPOE=m -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_SLIP=m -CONFIG_SLIP_COMPRESSED=y -CONFIG_SLIP_SMART=y -CONFIG_SLIP_MODE_SLIP6=y -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_SERIO is not set -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -# CONFIG_SERIAL_8250_PCI is not set -CONFIG_SERIAL_8250_NR_UARTS=2 -CONFIG_SERIAL_8250_RUNTIME_UARTS=2 -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_MPC=y -CONFIG_WATCHDOG=y -CONFIG_SOFT_WATCHDOG=m -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT2_FS_POSIX_ACL=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -CONFIG_EXT3_FS_POSIX_ACL=y -CONFIG_REISERFS_FS=m -CONFIG_REISERFS_FS_XATTR=y -CONFIG_REISERFS_FS_POSIX_ACL=y -CONFIG_AUTOFS4_FS=m -CONFIG_PROC_KCORE=y -CONFIG_TMPFS=y -CONFIG_MINIX_FS=m -CONFIG_ROMFS_FS=m -CONFIG_NFS_FS=y -CONFIG_NFS_V4=y -CONFIG_ROOT_NFS=y -CONFIG_CIFS=m -CONFIG_CIFS_XATTR=y -CONFIG_CIFS_POSIX=y -CONFIG_NLS_CODEPAGE_437=m -CONFIG_NLS_CODEPAGE_737=m -CONFIG_NLS_CODEPAGE_775=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_CODEPAGE_852=m -CONFIG_NLS_CODEPAGE_855=m -CONFIG_NLS_CODEPAGE_857=m -CONFIG_NLS_CODEPAGE_860=m -CONFIG_NLS_CODEPAGE_861=m -CONFIG_NLS_CODEPAGE_862=m -CONFIG_NLS_CODEPAGE_863=m -CONFIG_NLS_CODEPAGE_864=m -CONFIG_NLS_CODEPAGE_865=m -CONFIG_NLS_CODEPAGE_866=m -CONFIG_NLS_CODEPAGE_869=m -CONFIG_NLS_CODEPAGE_936=m -CONFIG_NLS_CODEPAGE_950=m -CONFIG_NLS_CODEPAGE_932=m -CONFIG_NLS_CODEPAGE_949=m -CONFIG_NLS_CODEPAGE_874=m -CONFIG_NLS_ISO8859_8=m -CONFIG_NLS_CODEPAGE_1250=m -CONFIG_NLS_CODEPAGE_1251=m -CONFIG_NLS_ASCII=m -CONFIG_NLS_ISO8859_1=m -CONFIG_NLS_ISO8859_2=m -CONFIG_NLS_ISO8859_3=m -CONFIG_NLS_ISO8859_4=m -CONFIG_NLS_ISO8859_5=m -CONFIG_NLS_ISO8859_6=m -CONFIG_NLS_ISO8859_7=m -CONFIG_NLS_ISO8859_9=m -CONFIG_NLS_ISO8859_13=m -CONFIG_NLS_ISO8859_14=m -CONFIG_NLS_ISO8859_15=m -CONFIG_NLS_KOI8_R=m -CONFIG_NLS_KOI8_U=m -CONFIG_NLS_UTF8=m -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_FS=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_DETECT_HUNG_TASK=y -# CONFIG_DEBUG_BUGVERBOSE is not set -CONFIG_SECURITY=y -CONFIG_SECURITY_NETWORK=y -CONFIG_CRYPTO_NULL=m -CONFIG_CRYPTO_TEST=m -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_HMAC=y -CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_WP512=m -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_CAST5=m -CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_SERPENT=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_TWOFISH=m -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/mpc86xx_basic_defconfig b/arch/powerpc/configs/mpc86xx_basic_defconfig new file mode 100644 index 0000000000000000000000000000000000000000..33af5c5de105d731248436e307fe71fc3b90ef70 --- /dev/null +++ b/arch/powerpc/configs/mpc86xx_basic_defconfig @@ -0,0 +1,10 @@ +CONFIG_HIGHMEM=y +CONFIG_KEXEC=y +CONFIG_PPC_86xx=y +CONFIG_PROC_KCORE=y +CONFIG_GEF_PPC9A=y +CONFIG_GEF_SBC310=y +CONFIG_GEF_SBC610=y +CONFIG_MPC8610_HPCD=y +CONFIG_MPC8641_HPCN=y +CONFIG_SBC8641D=y diff --git a/arch/powerpc/configs/mpc86xx_defconfig b/arch/powerpc/configs/mpc86xx_defconfig deleted file mode 100644 index a4572563681c7da509c1d922be3537e1874b631b..0000000000000000000000000000000000000000 --- a/arch/powerpc/configs/mpc86xx_defconfig +++ /dev/null @@ -1,162 +0,0 @@ -CONFIG_SMP=y -CONFIG_NR_CPUS=2 -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -CONFIG_AUDIT=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_BLK_DEV_INITRD=y -CONFIG_EXPERT=y -CONFIG_KALLSYMS_ALL=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -CONFIG_MODVERSIONS=y -# CONFIG_BLK_DEV_BSG is not set -CONFIG_PARTITION_ADVANCED=y -CONFIG_MAC_PARTITION=y -# CONFIG_PPC_CHRP is not set -# CONFIG_PPC_PMAC is not set -CONFIG_PPC_86xx=y -CONFIG_MPC8641_HPCN=y -CONFIG_SBC8641D=y -CONFIG_MPC8610_HPCD=y -CONFIG_GEF_SBC610=y -CONFIG_HIGHMEM=y -CONFIG_HZ_1000=y -CONFIG_BINFMT_MISC=m -CONFIG_PCI=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_XFRM_USER=y -CONFIG_NET_KEY=m -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_VERBOSE=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -CONFIG_NET_IPIP=y -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set -CONFIG_IPV6=y -CONFIG_IP_SCTP=m -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_NBD=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=131072 -CONFIG_EEPROM_LEGACY=y -CONFIG_BLK_DEV_SD=y -CONFIG_CHR_DEV_ST=y -CONFIG_BLK_DEV_SR=y -CONFIG_CHR_DEV_SG=y -CONFIG_SCSI_LOGGING=y -CONFIG_ATA=y -CONFIG_SATA_AHCI=y -CONFIG_PATA_ALI=y -CONFIG_NETDEVICES=y -CONFIG_DUMMY=y -CONFIG_GIANFAR=y -CONFIG_VITESSE_PHY=y -CONFIG_INPUT_FF_MEMLESS=m -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -CONFIG_SERIO_LIBPS2=y -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=2 -CONFIG_SERIAL_8250_RUNTIME_UARTS=2 -CONFIG_SERIAL_8250_EXTENDED=y -CONFIG_SERIAL_8250_MANY_PORTS=y -CONFIG_SERIAL_8250_SHARE_IRQ=y -CONFIG_SERIAL_8250_DETECT_IRQ=y -CONFIG_SERIAL_8250_RSA=y -# CONFIG_HW_RANDOM is not set -CONFIG_NVRAM=y -CONFIG_I2C=y -CONFIG_I2C_MPC=y -# CONFIG_HWMON is not set -CONFIG_SOUND=y -CONFIG_SND=y -CONFIG_SND_MIXER_OSS=y -CONFIG_SND_PCM_OSS=y -# CONFIG_SND_SUPPORT_OLD_API is not set -CONFIG_SND_INTEL8X0=y -CONFIG_HID_A4TECH=y -CONFIG_HID_APPLE=y -CONFIG_HID_BELKIN=y -CONFIG_HID_CHERRY=y -CONFIG_HID_CHICONY=y -CONFIG_HID_CYPRESS=y -CONFIG_HID_EZKEY=y -CONFIG_HID_GYRATION=y -CONFIG_HID_LOGITECH=y -CONFIG_HID_MICROSOFT=y -CONFIG_HID_MONTEREY=y -CONFIG_HID_PANTHERLORD=y -CONFIG_HID_PETALYNX=y -CONFIG_HID_SAMSUNG=y -CONFIG_HID_SUNPLUS=y -CONFIG_USB=y -CONFIG_USB_MON=y -CONFIG_USB_EHCI_HCD=y -CONFIG_USB_OHCI_HCD=y -CONFIG_USB_OHCI_HCD_PPC_OF_BE=y -CONFIG_USB_OHCI_HCD_PPC_OF_LE=y -CONFIG_USB_STORAGE=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_CMOS=y -CONFIG_EXT2_FS=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -CONFIG_ISO9660_FS=m -CONFIG_JOLIET=y -CONFIG_ZISOFS=y -CONFIG_UDF_FS=m -CONFIG_MSDOS_FS=m -CONFIG_VFAT_FS=y -CONFIG_NTFS_FS=y -CONFIG_PROC_KCORE=y -CONFIG_TMPFS=y -CONFIG_ADFS_FS=m -CONFIG_AFFS_FS=m -CONFIG_HFS_FS=m -CONFIG_HFSPLUS_FS=m -CONFIG_BEFS_FS=m -CONFIG_BFS_FS=m -CONFIG_EFS_FS=m -CONFIG_CRAMFS=y -CONFIG_VXFS_FS=m -CONFIG_HPFS_FS=m -CONFIG_QNX4FS_FS=m -CONFIG_SYSV_FS=m -CONFIG_UFS_FS=m -CONFIG_NFS_FS=y -CONFIG_NFS_V4=y -CONFIG_ROOT_NFS=y -CONFIG_NFSD=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_CODEPAGE_850=y -CONFIG_NLS_ISO8859_1=y -CONFIG_CRC_T10DIF=y -CONFIG_DEBUG_INFO=y -CONFIG_DETECT_HUNG_TASK=y -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_HMAC=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set diff --git a/arch/powerpc/configs/powernv_defconfig b/arch/powerpc/configs/powernv_defconfig new file mode 100644 index 0000000000000000000000000000000000000000..045031048f8d40a205ca5b663a1ab7e08cfbcb18 --- /dev/null +++ b/arch/powerpc/configs/powernv_defconfig @@ -0,0 +1,313 @@ +CONFIG_PPC64=y +CONFIG_SMP=y +CONFIG_NR_CPUS=2048 +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_FHANDLE=y +CONFIG_AUDIT=y +CONFIG_IRQ_DOMAIN_DEBUG=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +CONFIG_TASK_XACCT=y +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_NUMA_BALANCING=y +CONFIG_CGROUPS=y +CONFIG_MEMCG=y +CONFIG_MEMCG_SWAP=y +CONFIG_CGROUP_SCHED=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CPUSETS=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_CGROUP_PERF=y +CONFIG_USER_NS=y +CONFIG_BLK_DEV_INITRD=y +# CONFIG_COMPAT_BRK is not set +CONFIG_PROFILING=y +CONFIG_OPROFILE=y +CONFIG_KPROBES=y +CONFIG_JUMP_LABEL=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_OPAL_PRD=y +# CONFIG_PPC_PSERIES is not set +# CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +CONFIG_CPU_IDLE=y +CONFIG_HZ_100=y +CONFIG_BINFMT_MISC=m +CONFIG_PPC_TRANSACTIONAL_MEM=y +CONFIG_HOTPLUG_CPU=y +CONFIG_KEXEC=y +CONFIG_IRQ_ALL_CPUS=y +CONFIG_NUMA=y +CONFIG_MEMORY_HOTPLUG=y +CONFIG_MEMORY_HOTREMOVE=y +CONFIG_KSM=y +CONFIG_TRANSPARENT_HUGEPAGE=y +CONFIG_PPC_64K_PAGES=y +CONFIG_PPC_SUBPAGE_PROT=y +CONFIG_SCHED_SMT=y +CONFIG_PM=y +CONFIG_PCI_MSI=y +CONFIG_HOTPLUG_PCI=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_XFRM_USER=m +CONFIG_NET_KEY=m +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_NET_IPIP=y +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +# CONFIG_IPV6 is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_ADVANCED is not set +CONFIG_BRIDGE=m +CONFIG_VLAN_8021Q=m +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_MTD=y +CONFIG_MTD_POWERNV_FLASH=y +CONFIG_PARPORT=m +CONFIG_PARPORT_PC=m +CONFIG_BLK_DEV_FD=m +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_VIRTIO_BLK=m +CONFIG_IDE=y +CONFIG_BLK_DEV_IDECD=y +CONFIG_BLK_DEV_GENERIC=y +CONFIG_BLK_DEV_AMD74XX=y +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=y +CONFIG_BLK_DEV_SR=y +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_CHR_DEV_SG=y +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_FC_ATTRS=y +CONFIG_SCSI_SRP_ATTRS=y +CONFIG_SCSI_CXGB3_ISCSI=m +CONFIG_SCSI_CXGB4_ISCSI=m +CONFIG_SCSI_BNX2_ISCSI=m +CONFIG_BE2ISCSI=m +CONFIG_SCSI_MPT2SAS=m +CONFIG_SCSI_SYM53C8XX_2=y +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 +CONFIG_SCSI_IPR=y +CONFIG_SCSI_QLA_FC=m +CONFIG_SCSI_QLA_ISCSI=m +CONFIG_SCSI_LPFC=m +CONFIG_SCSI_VIRTIO=m +CONFIG_SCSI_DH=y +CONFIG_SCSI_DH_RDAC=m +CONFIG_SCSI_DH_ALUA=m +CONFIG_ATA=y +CONFIG_SATA_AHCI=y +# CONFIG_ATA_SFF is not set +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +CONFIG_MD_LINEAR=y +CONFIG_MD_RAID0=y +CONFIG_MD_RAID1=y +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_FAULTY=m +CONFIG_BLK_DEV_DM=y +CONFIG_DM_CRYPT=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_THIN_PROVISIONING=m +CONFIG_DM_MIRROR=m +CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_QL=m +CONFIG_DM_MULTIPATH_ST=m +CONFIG_DM_UEVENT=y +CONFIG_BONDING=m +CONFIG_DUMMY=m +CONFIG_MACVLAN=m +CONFIG_MACVTAP=m +CONFIG_VXLAN=m +CONFIG_NETCONSOLE=y +CONFIG_TUN=m +CONFIG_VETH=m +CONFIG_VIRTIO_NET=m +CONFIG_VHOST_NET=m +CONFIG_VORTEX=y +CONFIG_ACENIC=m +CONFIG_ACENIC_OMIT_TIGON_I=y +CONFIG_PCNET32=y +CONFIG_TIGON3=y +CONFIG_BNX2X=m +CONFIG_CHELSIO_T1=m +CONFIG_BE2NET=m +CONFIG_S2IO=m +CONFIG_E100=y +CONFIG_E1000=y +CONFIG_E1000E=y +CONFIG_IXGB=m +CONFIG_IXGBE=m +CONFIG_MLX4_EN=m +CONFIG_MYRI10GE=m +CONFIG_QLGE=m +CONFIG_NETXEN_NIC=m +CONFIG_PPP=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPPOE=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_EVDEV=m +CONFIG_INPUT_MISC=y +# CONFIG_SERIO_SERPORT is not set +CONFIG_DEVPTS_MULTIPLE_INSTANCES=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_JSM=m +CONFIG_VIRTIO_CONSOLE=m +CONFIG_IPMI_HANDLER=y +CONFIG_IPMI_DEVICE_INTERFACE=y +CONFIG_IPMI_POWERNV=y +CONFIG_RAW_DRIVER=y +CONFIG_MAX_RAW_DEVS=1024 +CONFIG_DRM=y +CONFIG_DRM_AST=y +CONFIG_FIRMWARE_EDID=y +CONFIG_FB_OF=y +CONFIG_FB_MATROX=y +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_MATROX_G=y +CONFIG_FB_RADEON=y +CONFIG_FB_IBM_GXT4500=y +CONFIG_LCD_PLATFORM=m +# CONFIG_VGA_CONSOLE is not set +CONFIG_LOGO=y +CONFIG_HID_GYRATION=y +CONFIG_HID_PANTHERLORD=y +CONFIG_HID_PETALYNX=y +CONFIG_HID_SAMSUNG=y +CONFIG_HID_SUNPLUS=y +CONFIG_USB_HIDDEV=y +CONFIG_USB=y +CONFIG_USB_MON=m +CONFIG_USB_EHCI_HCD=y +# CONFIG_USB_EHCI_HCD_PPC_OF is not set +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_STORAGE=m +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=m +CONFIG_LEDS_POWERNV=m +CONFIG_INFINIBAND=m +CONFIG_INFINIBAND_USER_MAD=m +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_INFINIBAND_MTHCA=m +CONFIG_INFINIBAND_CXGB3=m +CONFIG_INFINIBAND_CXGB4=m +CONFIG_MLX4_INFINIBAND=m +CONFIG_INFINIBAND_IPOIB=m +CONFIG_INFINIBAND_IPOIB_CM=y +CONFIG_INFINIBAND_SRP=m +CONFIG_INFINIBAND_ISER=m +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_GENERIC=y +CONFIG_VIRTIO_PCI=m +CONFIG_VIRTIO_BALLOON=m +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_REISERFS_FS=y +CONFIG_REISERFS_FS_XATTR=y +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +CONFIG_XFS_FS=m +CONFIG_XFS_POSIX_ACL=y +CONFIG_BTRFS_FS=m +CONFIG_BTRFS_FS_POSIX_ACL=y +CONFIG_NILFS2_FS=m +CONFIG_AUTOFS4_FS=m +CONFIG_FUSE_FS=m +CONFIG_OVERLAY_FS=m +CONFIG_ISO9660_FS=y +CONFIG_UDF_FS=m +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_PROC_KCORE=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_HUGETLBFS=y +CONFIG_CRAMFS=m +CONFIG_SQUASHFS=m +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_PSTORE=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFSD=m +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_CIFS=m +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_UTF8=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_KERNEL=y +CONFIG_DEBUG_STACK_USAGE=y +CONFIG_DEBUG_STACKOVERFLOW=y +CONFIG_LOCKUP_DETECTOR=y +CONFIG_LATENCYTOP=y +CONFIG_SCHED_TRACER=y +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_CODE_PATCHING_SELFTEST=y +CONFIG_FTR_FIXUP_SELFTEST=y +CONFIG_MSI_BITMAP_SELFTEST=y +CONFIG_XMON=y +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_LZO=m +CONFIG_CRYPTO_DEV_NX=y +CONFIG_VIRTUALIZATION=y +CONFIG_KVM_BOOK3S_64=m +CONFIG_KVM_BOOK3S_64_HV=m diff --git a/arch/powerpc/crypto/aes-spe-core.S b/arch/powerpc/crypto/aes-spe-core.S index 5dc6bce90a77db2c3021cda19e9e3e0d710f4013..bc6ff43a9889eedd635dc1638bd97d4263fa2269 100644 --- a/arch/powerpc/crypto/aes-spe-core.S +++ b/arch/powerpc/crypto/aes-spe-core.S @@ -61,7 +61,7 @@ * via bl/blr. It expects that caller has pre-xored input data with first * 4 words of encryption key into rD0-rD3. Pointer/counter registers must * have also been set up before (rT0, rKP, CTR). Output is stored in rD0-rD3 - * and rW0-rW3 and caller must execute a final xor on the ouput registers. + * and rW0-rW3 and caller must execute a final xor on the output registers. * All working registers rD0-rD3 & rW0-rW7 are overwritten during processing. * */ @@ -209,7 +209,7 @@ ppc_encrypt_block_loop: * via bl/blr. It expects that caller has pre-xored input data with first * 4 words of encryption key into rD0-rD3. Pointer/counter registers must * have also been set up before (rT0, rKP, CTR). Output is stored in rD0-rD3 - * and rW0-rW3 and caller must execute a final xor on the ouput registers. + * and rW0-rW3 and caller must execute a final xor on the output registers. * All working registers rD0-rD3 & rW0-rW7 are overwritten during processing. * */ diff --git a/arch/powerpc/crypto/aes-spe-glue.c b/arch/powerpc/crypto/aes-spe-glue.c index ab113198ed20da020a36ab16ee1790d2c43a0307..748fc00c5e19c3f29c326bb107bf898f0ed8ae48 100644 --- a/arch/powerpc/crypto/aes-spe-glue.c +++ b/arch/powerpc/crypto/aes-spe-glue.c @@ -33,7 +33,7 @@ * 16 byte block block or 25 cycles per byte. Thus 768 bytes of input data * will need an estimated maximum of 20,000 cycles. Headroom for cache misses * included. Even with the low end model clocked at 667 MHz this equals to a - * critical time window of less than 30us. The value has been choosen to + * critical time window of less than 30us. The value has been chosen to * process a 512 byte disk block in one or a large 1400 bytes IPsec network * packet in two runs. * diff --git a/arch/powerpc/include/asm/atomic.h b/arch/powerpc/include/asm/atomic.h index 55f106ed12bf2e719f6f555c868cc5ba2a38da6a..ae0751ef8788fd55f7c4d6b37a8fbb73d82d317f 100644 --- a/arch/powerpc/include/asm/atomic.h +++ b/arch/powerpc/include/asm/atomic.h @@ -12,6 +12,24 @@ #define ATOMIC_INIT(i) { (i) } +/* + * Since *_return_relaxed and {cmp}xchg_relaxed are implemented with + * a "bne-" instruction at the end, so an isync is enough as a acquire barrier + * on the platform without lwsync. + */ +#define __atomic_op_acquire(op, args...) \ +({ \ + typeof(op##_relaxed(args)) __ret = op##_relaxed(args); \ + __asm__ __volatile__(PPC_ACQUIRE_BARRIER "" : : : "memory"); \ + __ret; \ +}) + +#define __atomic_op_release(op, args...) \ +({ \ + __asm__ __volatile__(PPC_RELEASE_BARRIER "" : : : "memory"); \ + op##_relaxed(args); \ +}) + static __inline__ int atomic_read(const atomic_t *v) { int t; @@ -42,27 +60,27 @@ static __inline__ void atomic_##op(int a, atomic_t *v) \ : "cc"); \ } \ -#define ATOMIC_OP_RETURN(op, asm_op) \ -static __inline__ int atomic_##op##_return(int a, atomic_t *v) \ +#define ATOMIC_OP_RETURN_RELAXED(op, asm_op) \ +static inline int atomic_##op##_return_relaxed(int a, atomic_t *v) \ { \ int t; \ \ __asm__ __volatile__( \ - PPC_ATOMIC_ENTRY_BARRIER \ -"1: lwarx %0,0,%2 # atomic_" #op "_return\n" \ - #asm_op " %0,%1,%0\n" \ - PPC405_ERR77(0,%2) \ -" stwcx. %0,0,%2 \n" \ +"1: lwarx %0,0,%3 # atomic_" #op "_return_relaxed\n" \ + #asm_op " %0,%2,%0\n" \ + PPC405_ERR77(0, %3) \ +" stwcx. %0,0,%3\n" \ " bne- 1b\n" \ - PPC_ATOMIC_EXIT_BARRIER \ - : "=&r" (t) \ + : "=&r" (t), "+m" (v->counter) \ : "r" (a), "r" (&v->counter) \ - : "cc", "memory"); \ + : "cc"); \ \ return t; \ } -#define ATOMIC_OPS(op, asm_op) ATOMIC_OP(op, asm_op) ATOMIC_OP_RETURN(op, asm_op) +#define ATOMIC_OPS(op, asm_op) \ + ATOMIC_OP(op, asm_op) \ + ATOMIC_OP_RETURN_RELAXED(op, asm_op) ATOMIC_OPS(add, add) ATOMIC_OPS(sub, subf) @@ -71,8 +89,11 @@ ATOMIC_OP(and, and) ATOMIC_OP(or, or) ATOMIC_OP(xor, xor) +#define atomic_add_return_relaxed atomic_add_return_relaxed +#define atomic_sub_return_relaxed atomic_sub_return_relaxed + #undef ATOMIC_OPS -#undef ATOMIC_OP_RETURN +#undef ATOMIC_OP_RETURN_RELAXED #undef ATOMIC_OP #define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0) @@ -92,21 +113,19 @@ static __inline__ void atomic_inc(atomic_t *v) : "cc", "xer"); } -static __inline__ int atomic_inc_return(atomic_t *v) +static __inline__ int atomic_inc_return_relaxed(atomic_t *v) { int t; __asm__ __volatile__( - PPC_ATOMIC_ENTRY_BARRIER -"1: lwarx %0,0,%1 # atomic_inc_return\n\ - addic %0,%0,1\n" - PPC405_ERR77(0,%1) -" stwcx. %0,0,%1 \n\ - bne- 1b" - PPC_ATOMIC_EXIT_BARRIER - : "=&r" (t) +"1: lwarx %0,0,%2 # atomic_inc_return_relaxed\n" +" addic %0,%0,1\n" + PPC405_ERR77(0, %2) +" stwcx. %0,0,%2\n" +" bne- 1b" + : "=&r" (t), "+m" (v->counter) : "r" (&v->counter) - : "cc", "xer", "memory"); + : "cc", "xer"); return t; } @@ -136,27 +155,34 @@ static __inline__ void atomic_dec(atomic_t *v) : "cc", "xer"); } -static __inline__ int atomic_dec_return(atomic_t *v) +static __inline__ int atomic_dec_return_relaxed(atomic_t *v) { int t; __asm__ __volatile__( - PPC_ATOMIC_ENTRY_BARRIER -"1: lwarx %0,0,%1 # atomic_dec_return\n\ - addic %0,%0,-1\n" - PPC405_ERR77(0,%1) -" stwcx. %0,0,%1\n\ - bne- 1b" - PPC_ATOMIC_EXIT_BARRIER - : "=&r" (t) +"1: lwarx %0,0,%2 # atomic_dec_return_relaxed\n" +" addic %0,%0,-1\n" + PPC405_ERR77(0, %2) +" stwcx. %0,0,%2\n" +" bne- 1b" + : "=&r" (t), "+m" (v->counter) : "r" (&v->counter) - : "cc", "xer", "memory"); + : "cc", "xer"); return t; } +#define atomic_inc_return_relaxed atomic_inc_return_relaxed +#define atomic_dec_return_relaxed atomic_dec_return_relaxed + #define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n))) +#define atomic_cmpxchg_relaxed(v, o, n) \ + cmpxchg_relaxed(&((v)->counter), (o), (n)) +#define atomic_cmpxchg_acquire(v, o, n) \ + cmpxchg_acquire(&((v)->counter), (o), (n)) + #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) +#define atomic_xchg_relaxed(v, new) xchg_relaxed(&((v)->counter), (new)) /** * __atomic_add_unless - add unless the number is a given value @@ -285,26 +311,27 @@ static __inline__ void atomic64_##op(long a, atomic64_t *v) \ : "cc"); \ } -#define ATOMIC64_OP_RETURN(op, asm_op) \ -static __inline__ long atomic64_##op##_return(long a, atomic64_t *v) \ +#define ATOMIC64_OP_RETURN_RELAXED(op, asm_op) \ +static inline long \ +atomic64_##op##_return_relaxed(long a, atomic64_t *v) \ { \ long t; \ \ __asm__ __volatile__( \ - PPC_ATOMIC_ENTRY_BARRIER \ -"1: ldarx %0,0,%2 # atomic64_" #op "_return\n" \ - #asm_op " %0,%1,%0\n" \ -" stdcx. %0,0,%2 \n" \ +"1: ldarx %0,0,%3 # atomic64_" #op "_return_relaxed\n" \ + #asm_op " %0,%2,%0\n" \ +" stdcx. %0,0,%3\n" \ " bne- 1b\n" \ - PPC_ATOMIC_EXIT_BARRIER \ - : "=&r" (t) \ + : "=&r" (t), "+m" (v->counter) \ : "r" (a), "r" (&v->counter) \ - : "cc", "memory"); \ + : "cc"); \ \ return t; \ } -#define ATOMIC64_OPS(op, asm_op) ATOMIC64_OP(op, asm_op) ATOMIC64_OP_RETURN(op, asm_op) +#define ATOMIC64_OPS(op, asm_op) \ + ATOMIC64_OP(op, asm_op) \ + ATOMIC64_OP_RETURN_RELAXED(op, asm_op) ATOMIC64_OPS(add, add) ATOMIC64_OPS(sub, subf) @@ -312,8 +339,11 @@ ATOMIC64_OP(and, and) ATOMIC64_OP(or, or) ATOMIC64_OP(xor, xor) -#undef ATOMIC64_OPS -#undef ATOMIC64_OP_RETURN +#define atomic64_add_return_relaxed atomic64_add_return_relaxed +#define atomic64_sub_return_relaxed atomic64_sub_return_relaxed + +#undef ATOPIC64_OPS +#undef ATOMIC64_OP_RETURN_RELAXED #undef ATOMIC64_OP #define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0) @@ -332,20 +362,18 @@ static __inline__ void atomic64_inc(atomic64_t *v) : "cc", "xer"); } -static __inline__ long atomic64_inc_return(atomic64_t *v) +static __inline__ long atomic64_inc_return_relaxed(atomic64_t *v) { long t; __asm__ __volatile__( - PPC_ATOMIC_ENTRY_BARRIER -"1: ldarx %0,0,%1 # atomic64_inc_return\n\ - addic %0,%0,1\n\ - stdcx. %0,0,%1 \n\ - bne- 1b" - PPC_ATOMIC_EXIT_BARRIER - : "=&r" (t) +"1: ldarx %0,0,%2 # atomic64_inc_return_relaxed\n" +" addic %0,%0,1\n" +" stdcx. %0,0,%2\n" +" bne- 1b" + : "=&r" (t), "+m" (v->counter) : "r" (&v->counter) - : "cc", "xer", "memory"); + : "cc", "xer"); return t; } @@ -374,24 +402,25 @@ static __inline__ void atomic64_dec(atomic64_t *v) : "cc", "xer"); } -static __inline__ long atomic64_dec_return(atomic64_t *v) +static __inline__ long atomic64_dec_return_relaxed(atomic64_t *v) { long t; __asm__ __volatile__( - PPC_ATOMIC_ENTRY_BARRIER -"1: ldarx %0,0,%1 # atomic64_dec_return\n\ - addic %0,%0,-1\n\ - stdcx. %0,0,%1\n\ - bne- 1b" - PPC_ATOMIC_EXIT_BARRIER - : "=&r" (t) +"1: ldarx %0,0,%2 # atomic64_dec_return_relaxed\n" +" addic %0,%0,-1\n" +" stdcx. %0,0,%2\n" +" bne- 1b" + : "=&r" (t), "+m" (v->counter) : "r" (&v->counter) - : "cc", "xer", "memory"); + : "cc", "xer"); return t; } +#define atomic64_inc_return_relaxed atomic64_inc_return_relaxed +#define atomic64_dec_return_relaxed atomic64_dec_return_relaxed + #define atomic64_sub_and_test(a, v) (atomic64_sub_return((a), (v)) == 0) #define atomic64_dec_and_test(v) (atomic64_dec_return((v)) == 0) @@ -420,7 +449,13 @@ static __inline__ long atomic64_dec_if_positive(atomic64_t *v) } #define atomic64_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n))) +#define atomic64_cmpxchg_relaxed(v, o, n) \ + cmpxchg_relaxed(&((v)->counter), (o), (n)) +#define atomic64_cmpxchg_acquire(v, o, n) \ + cmpxchg_acquire(&((v)->counter), (o), (n)) + #define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) +#define atomic64_xchg_relaxed(v, new) xchg_relaxed(&((v)->counter), (new)) /** * atomic64_add_unless - add unless the number is a given value diff --git a/arch/powerpc/include/asm/mmu-hash32.h b/arch/powerpc/include/asm/book3s/32/mmu-hash.h similarity index 100% rename from arch/powerpc/include/asm/mmu-hash32.h rename to arch/powerpc/include/asm/book3s/32/mmu-hash.h diff --git a/arch/powerpc/include/asm/book3s/64/hash-4k.h b/arch/powerpc/include/asm/book3s/64/hash-4k.h index ea0414d6659e0e515ce82d8ecde796cacff8b6c2..5f08a08322385d8285851d07e82ff0917a72ebc8 100644 --- a/arch/powerpc/include/asm/book3s/64/hash-4k.h +++ b/arch/powerpc/include/asm/book3s/64/hash-4k.h @@ -52,44 +52,14 @@ _PAGE_F_SECOND | _PAGE_F_GIX) /* shift to put page number into pte */ -#define PTE_RPN_SHIFT (18) +#define PTE_RPN_SHIFT (12) +#define PTE_RPN_SIZE (45) /* gives 57-bit real addresses */ #define _PAGE_4K_PFN 0 #ifndef __ASSEMBLY__ /* - * 4-level page tables related bits + * On all 4K setups, remap_4k_pfn() equates to remap_pfn_range() */ - -#define pgd_none(pgd) (!pgd_val(pgd)) -#define pgd_bad(pgd) (pgd_val(pgd) == 0) -#define pgd_present(pgd) (pgd_val(pgd) != 0) -#define pgd_page_vaddr(pgd) (pgd_val(pgd) & ~PGD_MASKED_BITS) - -static inline void pgd_clear(pgd_t *pgdp) -{ - *pgdp = __pgd(0); -} - -static inline pte_t pgd_pte(pgd_t pgd) -{ - return __pte(pgd_val(pgd)); -} - -static inline pgd_t pte_pgd(pte_t pte) -{ - return __pgd(pte_val(pte)); -} -extern struct page *pgd_page(pgd_t pgd); - -#define pud_offset(pgdp, addr) \ - (((pud_t *) pgd_page_vaddr(*(pgdp))) + \ - (((addr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1))) - -#define pud_ERROR(e) \ - pr_err("%s:%d: bad pud %08lx.\n", __FILE__, __LINE__, pud_val(e)) - -/* - * On all 4K setups, remap_4k_pfn() equates to remap_pfn_range() */ #define remap_4k_pfn(vma, addr, pfn, prot) \ remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, (prot)) diff --git a/arch/powerpc/include/asm/book3s/64/hash-64k.h b/arch/powerpc/include/asm/book3s/64/hash-64k.h index 849bbec80f7bb1afd2a8622f75801fe2f7a67cb1..0a7956a80a08196433471f4d8703ebf5a2ee6c6f 100644 --- a/arch/powerpc/include/asm/book3s/64/hash-64k.h +++ b/arch/powerpc/include/asm/book3s/64/hash-64k.h @@ -1,15 +1,14 @@ #ifndef _ASM_POWERPC_BOOK3S_64_HASH_64K_H #define _ASM_POWERPC_BOOK3S_64_HASH_64K_H -#include - #define PTE_INDEX_SIZE 8 -#define PMD_INDEX_SIZE 10 -#define PUD_INDEX_SIZE 0 +#define PMD_INDEX_SIZE 5 +#define PUD_INDEX_SIZE 5 #define PGD_INDEX_SIZE 12 #define PTRS_PER_PTE (1 << PTE_INDEX_SIZE) #define PTRS_PER_PMD (1 << PMD_INDEX_SIZE) +#define PTRS_PER_PUD (1 << PUD_INDEX_SIZE) #define PTRS_PER_PGD (1 << PGD_INDEX_SIZE) /* With 4k base page size, hugepage PTEs go at the PMD level */ @@ -20,13 +19,18 @@ #define PMD_SIZE (1UL << PMD_SHIFT) #define PMD_MASK (~(PMD_SIZE-1)) -/* PGDIR_SHIFT determines what a third-level page table entry can map */ -#define PGDIR_SHIFT (PMD_SHIFT + PMD_INDEX_SIZE) +/* PUD_SHIFT determines what a third-level page table entry can map */ +#define PUD_SHIFT (PMD_SHIFT + PMD_INDEX_SIZE) +#define PUD_SIZE (1UL << PUD_SHIFT) +#define PUD_MASK (~(PUD_SIZE-1)) + +/* PGDIR_SHIFT determines what a fourth-level page table entry can map */ +#define PGDIR_SHIFT (PUD_SHIFT + PUD_INDEX_SIZE) #define PGDIR_SIZE (1UL << PGDIR_SHIFT) #define PGDIR_MASK (~(PGDIR_SIZE-1)) -#define _PAGE_COMBO 0x00040000 /* this is a combo 4k page */ -#define _PAGE_4K_PFN 0x00080000 /* PFN is for a single 4k page */ +#define _PAGE_COMBO 0x00001000 /* this is a combo 4k page */ +#define _PAGE_4K_PFN 0x00002000 /* PFN is for a single 4k page */ /* * Used to track subpage group valid if _PAGE_COMBO is set * This overloads _PAGE_F_GIX and _PAGE_F_SECOND @@ -39,10 +43,12 @@ /* Shift to put page number into pte. * - * That gives us a max RPN of 34 bits, which means a max of 50 bits - * of addressable physical space, or 46 bits for the special 4k PFNs. + * That gives us a max RPN of 41 bits, which means a max of 57 bits + * of addressable physical space, or 53 bits for the special 4k PFNs. */ -#define PTE_RPN_SHIFT (30) +#define PTE_RPN_SHIFT (16) +#define PTE_RPN_SIZE (41) + /* * we support 16 fragments per PTE page of 64K size. */ @@ -54,13 +60,12 @@ #define PTE_FRAG_SIZE_SHIFT 12 #define PTE_FRAG_SIZE (1UL << PTE_FRAG_SIZE_SHIFT) -/* - * Bits to mask out from a PMD to get to the PTE page - * PMDs point to PTE table fragments which are PTE_FRAG_SIZE aligned. - */ -#define PMD_MASKED_BITS (PTE_FRAG_SIZE - 1) -/* Bits to mask out from a PGD/PUD to get to the PMD page */ -#define PUD_MASKED_BITS 0x1ff +/* Bits to mask out from a PMD to get to the PTE page */ +#define PMD_MASKED_BITS 0xc0000000000000ffUL +/* Bits to mask out from a PUD to get to the PMD page */ +#define PUD_MASKED_BITS 0xc0000000000000ffUL +/* Bits to mask out from a PGD to get to the PUD page */ +#define PGD_MASKED_BITS 0xc0000000000000ffUL #ifndef __ASSEMBLY__ @@ -120,7 +125,7 @@ extern bool __rpte_sub_valid(real_pte_t rpte, unsigned long index); (((pte) & _PAGE_COMBO)? MMU_PAGE_4K: MMU_PAGE_64K) #define remap_4k_pfn(vma, addr, pfn, prot) \ - (WARN_ON(((pfn) >= (1UL << (64 - PTE_RPN_SHIFT)))) ? -EINVAL : \ + (WARN_ON(((pfn) >= (1UL << PTE_RPN_SIZE))) ? -EINVAL : \ remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, \ __pgprot(pgprot_val((prot)) | _PAGE_4K_PFN))) @@ -130,11 +135,9 @@ extern bool __rpte_sub_valid(real_pte_t rpte, unsigned long index); #else #define PMD_TABLE_SIZE (sizeof(pmd_t) << PMD_INDEX_SIZE) #endif +#define PUD_TABLE_SIZE (sizeof(pud_t) << PUD_INDEX_SIZE) #define PGD_TABLE_SIZE (sizeof(pgd_t) << PGD_INDEX_SIZE) -#define pgd_pte(pgd) (pud_pte(((pud_t){ pgd }))) -#define pte_pgd(pte) ((pgd_t)pte_pud(pte)) - #ifdef CONFIG_HUGETLB_PAGE /* * We have PGD_INDEX_SIZ = 12 and PTE_INDEX_SIZE = 8, so that we can have @@ -208,30 +211,30 @@ static inline char *get_hpte_slot_array(pmd_t *pmdp) /* * The linux hugepage PMD now include the pmd entries followed by the address * to the stashed pgtable_t. The stashed pgtable_t contains the hpte bits. - * [ 1 bit secondary | 3 bit hidx | 1 bit valid | 000]. We use one byte per + * [ 000 | 1 bit secondary | 3 bit hidx | 1 bit valid]. We use one byte per * each HPTE entry. With 16MB hugepage and 64K HPTE we need 256 entries and * with 4K HPTE we need 4096 entries. Both will fit in a 4K pgtable_t. * - * The last three bits are intentionally left to zero. This memory location + * The top three bits are intentionally left as zero. This memory location * are also used as normal page PTE pointers. So if we have any pointers * left around while we collapse a hugepage, we need to make sure * _PAGE_PRESENT bit of that is zero when we look at them */ static inline unsigned int hpte_valid(unsigned char *hpte_slot_array, int index) { - return (hpte_slot_array[index] >> 3) & 0x1; + return hpte_slot_array[index] & 0x1; } static inline unsigned int hpte_hash_index(unsigned char *hpte_slot_array, int index) { - return hpte_slot_array[index] >> 4; + return hpte_slot_array[index] >> 1; } static inline void mark_hpte_slot_valid(unsigned char *hpte_slot_array, unsigned int index, unsigned int hidx) { - hpte_slot_array[index] = hidx << 4 | 0x1 << 3; + hpte_slot_array[index] = (hidx << 1) | 0x1; } /* diff --git a/arch/powerpc/include/asm/book3s/64/hash.h b/arch/powerpc/include/asm/book3s/64/hash.h index 8d1c8162f0c1078d1842d754b64a078be8e1ea0e..d0ee6fcef823045dd5e98340d65cdbfcdb298243 100644 --- a/arch/powerpc/include/asm/book3s/64/hash.h +++ b/arch/powerpc/include/asm/book3s/64/hash.h @@ -4,8 +4,7 @@ /* * Common bits between 4K and 64K pages in a linux-style PTE. - * These match the bits in the (hardware-defined) PowerPC PTE as closely - * as possible. Additional bits may be defined in pgtable-hash64-*.h + * Additional bits may be defined in pgtable-hash64-*.h * * Note: We only support user read/write permissions. Supervisor always * have full read/write to pages above PAGE_OFFSET (pages below that @@ -14,32 +13,35 @@ * We could create separate kernel read-only if we used the 3 PP bits * combinations that newer processors provide but we currently don't. */ -#define _PAGE_PTE 0x00001 -#define _PAGE_PRESENT 0x00002 /* software: pte contains a translation */ -#define _PAGE_BIT_SWAP_TYPE 2 -#define _PAGE_USER 0x00004 /* matches one of the PP bits */ -#define _PAGE_EXEC 0x00008 /* No execute on POWER4 and newer (we invert) */ -#define _PAGE_GUARDED 0x00010 -/* We can derive Memory coherence from _PAGE_NO_CACHE */ +#define _PAGE_BIT_SWAP_TYPE 0 + +#define _PAGE_EXEC 0x00001 /* execute permission */ +#define _PAGE_RW 0x00002 /* read & write access allowed */ +#define _PAGE_READ 0x00004 /* read access allowed */ +#define _PAGE_USER 0x00008 /* page may be accessed by userspace */ +#define _PAGE_GUARDED 0x00010 /* G: guarded (side-effect) page */ +/* M (memory coherence) is always set in the HPTE, so we don't need it here */ #define _PAGE_COHERENT 0x0 #define _PAGE_NO_CACHE 0x00020 /* I: cache inhibit */ #define _PAGE_WRITETHRU 0x00040 /* W: cache write-through */ #define _PAGE_DIRTY 0x00080 /* C: page changed */ #define _PAGE_ACCESSED 0x00100 /* R: page referenced */ -#define _PAGE_RW 0x00200 /* software: user write access allowed */ -#define _PAGE_HASHPTE 0x00400 /* software: pte has an associated HPTE */ +#define _PAGE_SPECIAL 0x00400 /* software: special page */ #define _PAGE_BUSY 0x00800 /* software: PTE & hash are busy */ -#define _PAGE_F_GIX 0x07000 /* full page: hidx bits */ -#define _PAGE_F_GIX_SHIFT 12 -#define _PAGE_F_SECOND 0x08000 /* Whether to use secondary hash or not */ -#define _PAGE_SPECIAL 0x10000 /* software: special page */ #ifdef CONFIG_MEM_SOFT_DIRTY -#define _PAGE_SOFT_DIRTY 0x20000 /* software: software dirty tracking */ +#define _PAGE_SOFT_DIRTY 0x200 /* software: software dirty tracking */ #else -#define _PAGE_SOFT_DIRTY 0x00000 +#define _PAGE_SOFT_DIRTY 0x000 #endif +#define _PAGE_F_GIX_SHIFT 57 +#define _PAGE_F_GIX (7ul << 57) /* HPTE index within HPTEG */ +#define _PAGE_F_SECOND (1ul << 60) /* HPTE is in 2ndary HPTEG */ +#define _PAGE_HASHPTE (1ul << 61) /* PTE has associated HPTE */ +#define _PAGE_PTE (1ul << 62) /* distinguishes PTEs from pointers */ +#define _PAGE_PRESENT (1ul << 63) /* pte contains a translation */ + /* * We need to differentiate between explicit huge page and THP huge * page, since THP huge page also need to track real subpage details @@ -132,7 +134,7 @@ * The mask convered by the RPN must be a ULL on 32-bit platforms with * 64-bit PTEs */ -#define PTE_RPN_MASK (~((1UL << PTE_RPN_SHIFT) - 1)) +#define PTE_RPN_MASK (((1UL << PTE_RPN_SIZE) - 1) << PTE_RPN_SHIFT) /* * _PAGE_CHG_MASK masks of bits that are to be preserved across * pgprot changes @@ -223,15 +225,17 @@ #define PUD_BAD_BITS (PMD_TABLE_SIZE-1) #ifndef __ASSEMBLY__ -#define pmd_bad(pmd) (!is_kernel_addr(pmd_val(pmd)) \ - || (pmd_val(pmd) & PMD_BAD_BITS)) -#define pmd_page_vaddr(pmd) (pmd_val(pmd) & ~PMD_MASKED_BITS) +#define pmd_bad(pmd) (pmd_val(pmd) & PMD_BAD_BITS) +#define pmd_page_vaddr(pmd) __va(pmd_val(pmd) & ~PMD_MASKED_BITS) + +#define pud_bad(pud) (pud_val(pud) & PUD_BAD_BITS) +#define pud_page_vaddr(pud) __va(pud_val(pud) & ~PUD_MASKED_BITS) -#define pud_bad(pud) (!is_kernel_addr(pud_val(pud)) \ - || (pud_val(pud) & PUD_BAD_BITS)) -#define pud_page_vaddr(pud) (pud_val(pud) & ~PUD_MASKED_BITS) +/* Pointers in the page table tree are physical addresses */ +#define __pgtable_ptr_val(ptr) __pa(ptr) #define pgd_index(address) (((address) >> (PGDIR_SHIFT)) & (PTRS_PER_PGD - 1)) +#define pud_index(address) (((address) >> (PUD_SHIFT)) & (PTRS_PER_PUD - 1)) #define pmd_index(address) (((address) >> (PMD_SHIFT)) & (PTRS_PER_PMD - 1)) #define pte_index(address) (((address) >> (PAGE_SHIFT)) & (PTRS_PER_PTE - 1)) @@ -360,8 +364,18 @@ static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry) :"cc"); } +static inline int pgd_bad(pgd_t pgd) +{ + return (pgd_val(pgd) == 0); +} + #define __HAVE_ARCH_PTE_SAME #define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0) +static inline unsigned long pgd_page_vaddr(pgd_t pgd) +{ + return (unsigned long)__va(pgd_val(pgd) & ~PGD_MASKED_BITS); +} + /* Generic accessors to PTE bits */ static inline int pte_write(pte_t pte) { return !!(pte_val(pte) & _PAGE_RW);} @@ -402,7 +416,7 @@ static inline int pte_protnone(pte_t pte) static inline int pte_present(pte_t pte) { - return pte_val(pte) & _PAGE_PRESENT; + return !!(pte_val(pte) & _PAGE_PRESENT); } /* Conversion functions: convert a page and protection to a page entry, @@ -413,13 +427,13 @@ static inline int pte_present(pte_t pte) */ static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot) { - return __pte(((pte_basic_t)(pfn) << PTE_RPN_SHIFT) | + return __pte((((pte_basic_t)(pfn) << PTE_RPN_SHIFT) & PTE_RPN_MASK) | pgprot_val(pgprot)); } static inline unsigned long pte_pfn(pte_t pte) { - return pte_val(pte) >> PTE_RPN_SHIFT; + return (pte_val(pte) & PTE_RPN_MASK) >> PTE_RPN_SHIFT; } /* Generic modifiers for PTE bits */ diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/book3s/64/mmu-hash.h similarity index 99% rename from arch/powerpc/include/asm/mmu-hash64.h rename to arch/powerpc/include/asm/book3s/64/mmu-hash.h index 7352d3f212df9f392cdf35a9293aab8dd20628fe..0cea4807e26fd2fe5a7c4a834c50637bd70ec157 100644 --- a/arch/powerpc/include/asm/mmu-hash64.h +++ b/arch/powerpc/include/asm/book3s/64/mmu-hash.h @@ -114,6 +114,7 @@ #define POWER7_TLB_SETS 128 /* # sets in POWER7 TLB */ #define POWER8_TLB_SETS 512 /* # sets in POWER8 TLB */ +#define POWER9_TLB_SETS_HASH 256 /* # sets in POWER9 TLB Hash mode */ #ifndef __ASSEMBLY__ @@ -607,6 +608,9 @@ static inline unsigned long get_kernel_vsid(unsigned long ea, int ssize) context = (MAX_USER_CONTEXT) + ((ea >> 60) - 0xc) + 1; return get_vsid(context, ea, ssize); } + +unsigned htab_shift_for_mem_size(unsigned long mem_size); + #endif /* __ASSEMBLY__ */ #endif /* _ASM_POWERPC_MMU_HASH64_H_ */ diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h index ac07a30a7934265ed98706efb9f2c82ac8db85ce..77d3ce05798e34e9a9e7ab8bdbca1d90ae5174a7 100644 --- a/arch/powerpc/include/asm/book3s/64/pgtable.h +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h @@ -43,13 +43,8 @@ */ #ifndef __real_pte -#ifdef CONFIG_STRICT_MM_TYPECHECKS #define __real_pte(e,p) ((real_pte_t){(e)}) #define __rpte_to_pte(r) ((r).pte) -#else -#define __real_pte(e,p) (e) -#define __rpte_to_pte(r) (__pte(r)) -#endif #define __rpte_to_hidx(r,index) (pte_val(__rpte_to_pte(r)) >>_PAGE_F_GIX_SHIFT) #define pte_iterate_hashed_subpages(rpte, psize, va, index, shift) \ @@ -111,6 +106,26 @@ static inline void pgd_set(pgd_t *pgdp, unsigned long val) *pgdp = __pgd(val); } +static inline void pgd_clear(pgd_t *pgdp) +{ + *pgdp = __pgd(0); +} + +#define pgd_none(pgd) (!pgd_val(pgd)) +#define pgd_present(pgd) (!pgd_none(pgd)) + +static inline pte_t pgd_pte(pgd_t pgd) +{ + return __pte(pgd_val(pgd)); +} + +static inline pgd_t pte_pgd(pte_t pte) +{ + return __pgd(pte_val(pte)); +} + +extern struct page *pgd_page(pgd_t pgd); + /* * Find an entry in a page-table-directory. We combine the address region * (the high order N bits) and the pgd portion of the address. @@ -118,9 +133,10 @@ static inline void pgd_set(pgd_t *pgdp, unsigned long val) #define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) +#define pud_offset(pgdp, addr) \ + (((pud_t *) pgd_page_vaddr(*(pgdp))) + pud_index(addr)) #define pmd_offset(pudp,addr) \ (((pmd_t *) pud_page_vaddr(*(pudp))) + pmd_index(addr)) - #define pte_offset_kernel(dir,addr) \ (((pte_t *) pmd_page_vaddr(*(dir))) + pte_index(addr)) @@ -135,6 +151,8 @@ static inline void pgd_set(pgd_t *pgdp, unsigned long val) pr_err("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) #define pmd_ERROR(e) \ pr_err("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e)) +#define pud_ERROR(e) \ + pr_err("%s:%d: bad pud %08lx.\n", __FILE__, __LINE__, pud_val(e)) #define pgd_ERROR(e) \ pr_err("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) @@ -154,10 +172,10 @@ static inline void pgd_set(pgd_t *pgdp, unsigned long val) #define SWP_TYPE_BITS 5 #define __swp_type(x) (((x).val >> _PAGE_BIT_SWAP_TYPE) \ & ((1UL << SWP_TYPE_BITS) - 1)) -#define __swp_offset(x) ((x).val >> PTE_RPN_SHIFT) +#define __swp_offset(x) (((x).val & PTE_RPN_MASK) >> PTE_RPN_SHIFT) #define __swp_entry(type, offset) ((swp_entry_t) { \ - ((type) << _PAGE_BIT_SWAP_TYPE) \ - | ((offset) << PTE_RPN_SHIFT) }) + ((type) << _PAGE_BIT_SWAP_TYPE) \ + | (((offset) << PTE_RPN_SHIFT) & PTE_RPN_MASK)}) /* * swp_entry_t must be independent of pte bits. We build a swp_entry_t from * swap type and offset we get from swap and convert that to pte to find a diff --git a/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h b/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h new file mode 100644 index 0000000000000000000000000000000000000000..1b753f96b3744c85efe0947a4f40d3612f7966b8 --- /dev/null +++ b/arch/powerpc/include/asm/book3s/64/tlbflush-hash.h @@ -0,0 +1,94 @@ +#ifndef _ASM_POWERPC_BOOK3S_64_TLBFLUSH_HASH_H +#define _ASM_POWERPC_BOOK3S_64_TLBFLUSH_HASH_H + +#define MMU_NO_CONTEXT 0 + +/* + * TLB flushing for 64-bit hash-MMU CPUs + */ + +#include +#include + +#define PPC64_TLB_BATCH_NR 192 + +struct ppc64_tlb_batch { + int active; + unsigned long index; + struct mm_struct *mm; + real_pte_t pte[PPC64_TLB_BATCH_NR]; + unsigned long vpn[PPC64_TLB_BATCH_NR]; + unsigned int psize; + int ssize; +}; +DECLARE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch); + +extern void __flush_tlb_pending(struct ppc64_tlb_batch *batch); + +#define __HAVE_ARCH_ENTER_LAZY_MMU_MODE + +static inline void arch_enter_lazy_mmu_mode(void) +{ + struct ppc64_tlb_batch *batch = this_cpu_ptr(&ppc64_tlb_batch); + + batch->active = 1; +} + +static inline void arch_leave_lazy_mmu_mode(void) +{ + struct ppc64_tlb_batch *batch = this_cpu_ptr(&ppc64_tlb_batch); + + if (batch->index) + __flush_tlb_pending(batch); + batch->active = 0; +} + +#define arch_flush_lazy_mmu_mode() do {} while (0) + + +extern void flush_hash_page(unsigned long vpn, real_pte_t pte, int psize, + int ssize, unsigned long flags); +extern void flush_hash_range(unsigned long number, int local); +extern void flush_hash_hugepage(unsigned long vsid, unsigned long addr, + pmd_t *pmdp, unsigned int psize, int ssize, + unsigned long flags); + +static inline void local_flush_tlb_mm(struct mm_struct *mm) +{ +} + +static inline void flush_tlb_mm(struct mm_struct *mm) +{ +} + +static inline void local_flush_tlb_page(struct vm_area_struct *vma, + unsigned long vmaddr) +{ +} + +static inline void flush_tlb_page(struct vm_area_struct *vma, + unsigned long vmaddr) +{ +} + +static inline void flush_tlb_page_nohash(struct vm_area_struct *vma, + unsigned long vmaddr) +{ +} + +static inline void flush_tlb_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end) +{ +} + +static inline void flush_tlb_kernel_range(unsigned long start, + unsigned long end) +{ +} + +/* Private function for use by PCI IO mapping code */ +extern void __flush_hash_table_range(struct mm_struct *mm, unsigned long start, + unsigned long end); +extern void flush_tlb_pmd_range(struct mm_struct *mm, pmd_t *pmd, + unsigned long addr); +#endif /* _ASM_POWERPC_BOOK3S_64_TLBFLUSH_HASH_H */ diff --git a/arch/powerpc/include/asm/cache.h b/arch/powerpc/include/asm/cache.h index 5f8229e24fe6523a73ef2335a5f480e5f3983911..ffbafbf76b193a28338d8721e22c63644c55ec35 100644 --- a/arch/powerpc/include/asm/cache.h +++ b/arch/powerpc/include/asm/cache.h @@ -69,6 +69,25 @@ extern void _set_L3CR(unsigned long); #define _set_L3CR(val) do { } while(0) #endif +static inline void dcbz(void *addr) +{ + __asm__ __volatile__ ("dcbz 0, %0" : : "r"(addr) : "memory"); +} + +static inline void dcbi(void *addr) +{ + __asm__ __volatile__ ("dcbi 0, %0" : : "r"(addr) : "memory"); +} + +static inline void dcbf(void *addr) +{ + __asm__ __volatile__ ("dcbf 0, %0" : : "r"(addr) : "memory"); +} + +static inline void dcbst(void *addr) +{ + __asm__ __volatile__ ("dcbst 0, %0" : : "r"(addr) : "memory"); +} #endif /* !__ASSEMBLY__ */ #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_CACHE_H */ diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h index 6229e6b6037b97fe7d43862945a8c7806d602128..69fb16d7a8117a9509120ba81991075e19de104d 100644 --- a/arch/powerpc/include/asm/cacheflush.h +++ b/arch/powerpc/include/asm/cacheflush.h @@ -30,8 +30,6 @@ extern void flush_dcache_page(struct page *page); #define flush_dcache_mmap_lock(mapping) do { } while (0) #define flush_dcache_mmap_unlock(mapping) do { } while (0) -extern void __flush_disable_L1(void); - extern void flush_icache_range(unsigned long, unsigned long); extern void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, unsigned long addr, @@ -47,12 +45,58 @@ static inline void __flush_dcache_icache_phys(unsigned long physaddr) } #endif -extern void flush_dcache_range(unsigned long start, unsigned long stop); #ifdef CONFIG_PPC32 -extern void clean_dcache_range(unsigned long start, unsigned long stop); -extern void invalidate_dcache_range(unsigned long start, unsigned long stop); +/* + * Write any modified data cache blocks out to memory and invalidate them. + * Does not invalidate the corresponding instruction cache blocks. + */ +static inline void flush_dcache_range(unsigned long start, unsigned long stop) +{ + void *addr = (void *)(start & ~(L1_CACHE_BYTES - 1)); + unsigned long size = stop - (unsigned long)addr + (L1_CACHE_BYTES - 1); + unsigned long i; + + for (i = 0; i < size >> L1_CACHE_SHIFT; i++, addr += L1_CACHE_BYTES) + dcbf(addr); + mb(); /* sync */ +} + +/* + * Write any modified data cache blocks out to memory. + * Does not invalidate the corresponding cache lines (especially for + * any corresponding instruction cache). + */ +static inline void clean_dcache_range(unsigned long start, unsigned long stop) +{ + void *addr = (void *)(start & ~(L1_CACHE_BYTES - 1)); + unsigned long size = stop - (unsigned long)addr + (L1_CACHE_BYTES - 1); + unsigned long i; + + for (i = 0; i < size >> L1_CACHE_SHIFT; i++, addr += L1_CACHE_BYTES) + dcbst(addr); + mb(); /* sync */ +} + +/* + * Like above, but invalidate the D-cache. This is used by the 8xx + * to invalidate the cache so the PPC core doesn't get stale data + * from the CPM (no cache snooping here :-). + */ +static inline void invalidate_dcache_range(unsigned long start, + unsigned long stop) +{ + void *addr = (void *)(start & ~(L1_CACHE_BYTES - 1)); + unsigned long size = stop - (unsigned long)addr + (L1_CACHE_BYTES - 1); + unsigned long i; + + for (i = 0; i < size >> L1_CACHE_SHIFT; i++, addr += L1_CACHE_BYTES) + dcbi(addr); + mb(); /* sync */ +} + #endif /* CONFIG_PPC32 */ #ifdef CONFIG_PPC64 +extern void flush_dcache_range(unsigned long start, unsigned long stop); extern void flush_inval_dcache_range(unsigned long start, unsigned long stop); extern void flush_dcache_phys_range(unsigned long start, unsigned long stop); #endif diff --git a/arch/powerpc/include/asm/checksum.h b/arch/powerpc/include/asm/checksum.h index e8d9ef4755a499bae606caa80e2edd14899c0a0d..ee655ed1ff1bc7eae352be8887936e168f7ab58f 100644 --- a/arch/powerpc/include/asm/checksum.h +++ b/arch/powerpc/include/asm/checksum.h @@ -9,30 +9,9 @@ * 2 of the License, or (at your option) any later version. */ -/* - * This is a version of ip_compute_csum() optimized for IP headers, - * which always checksum on 4 octet boundaries. ihl is the number - * of 32-bit words and is always >= 5. - */ #ifdef CONFIG_GENERIC_CSUM #include #else -extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl); - -/* - * computes the checksum of a memory block at buff, length len, - * and adds in "sum" (32-bit) - * - * returns a 32-bit number suitable for feeding into itself - * or csum_tcpudp_magic - * - * this function must be called with even lengths, except - * for the last fragment, which may be odd - * - * it's best to have buff aligned on a 32-bit boundary - */ -extern __wsum csum_partial(const void *buff, int len, __wsum sum); - /* * Computes the checksum of a memory block at src, length len, * and adds in "sum" (32-bit), while copying the block to dst. @@ -47,21 +26,12 @@ extern __wsum csum_partial_copy_generic(const void *src, void *dst, int len, __wsum sum, int *src_err, int *dst_err); -#ifdef __powerpc64__ #define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER extern __wsum csum_and_copy_from_user(const void __user *src, void *dst, int len, __wsum sum, int *err_ptr); #define HAVE_CSUM_COPY_USER extern __wsum csum_and_copy_to_user(const void *src, void __user *dst, int len, __wsum sum, int *err_ptr); -#else -/* - * the same as csum_partial, but copies from src to dst while it - * checksums. - */ -#define csum_partial_copy_from_user(src, dst, len, sum, errp) \ - csum_partial_copy_generic((__force const void *)(src), (dst), (len), (sum), (errp), NULL) -#endif #define csum_partial_copy_nocheck(src, dst, len, sum) \ csum_partial_copy_generic((src), (dst), (len), (sum), NULL, NULL) @@ -83,15 +53,6 @@ static inline __sum16 csum_fold(__wsum sum) return (__force __sum16)(~((__force u32)sum + tmp) >> 16); } -/* - * this routine is used for miscellaneous IP-like checksums, mainly - * in icmp.c - */ -static inline __sum16 ip_compute_csum(const void *buff, int len) -{ - return csum_fold(csum_partial(buff, len, 0)); -} - static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, unsigned short proto, @@ -135,17 +96,117 @@ static inline __wsum csum_add(__wsum csum, __wsum addend) { #ifdef __powerpc64__ u64 res = (__force u64)csum; +#endif + if (__builtin_constant_p(csum) && csum == 0) + return addend; + if (__builtin_constant_p(addend) && addend == 0) + return csum; +#ifdef __powerpc64__ res += (__force u64)addend; return (__force __wsum)((u32)res + (res >> 32)); #else asm("addc %0,%0,%1;" "addze %0,%0;" - : "+r" (csum) : "r" (addend)); + : "+r" (csum) : "r" (addend) : "xer"); return csum; #endif } +/* + * This is a version of ip_compute_csum() optimized for IP headers, + * which always checksum on 4 octet boundaries. ihl is the number + * of 32-bit words and is always >= 5. + */ +static inline __wsum ip_fast_csum_nofold(const void *iph, unsigned int ihl) +{ + const u32 *ptr = (const u32 *)iph + 1; +#ifdef __powerpc64__ + unsigned int i; + u64 s = *(const u32 *)iph; + + for (i = 0; i < ihl - 1; i++, ptr++) + s += *ptr; + s += (s >> 32); + return (__force __wsum)s; +#else + __wsum sum, tmp; + + asm("mtctr %3;" + "addc %0,%4,%5;" + "1: lwzu %1, 4(%2);" + "adde %0,%0,%1;" + "bdnz 1b;" + "addze %0,%0;" + : "=r" (sum), "=r" (tmp), "+b" (ptr) + : "r" (ihl - 2), "r" (*(const u32 *)iph), "r" (*ptr) + : "ctr", "xer", "memory"); + + return sum; +#endif +} + +static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) +{ + return csum_fold(ip_fast_csum_nofold(iph, ihl)); +} + +/* + * computes the checksum of a memory block at buff, length len, + * and adds in "sum" (32-bit) + * + * returns a 32-bit number suitable for feeding into itself + * or csum_tcpudp_magic + * + * this function must be called with even lengths, except + * for the last fragment, which may be odd + * + * it's best to have buff aligned on a 32-bit boundary + */ +__wsum __csum_partial(const void *buff, int len, __wsum sum); + +static inline __wsum csum_partial(const void *buff, int len, __wsum sum) +{ + if (__builtin_constant_p(len) && len <= 16 && (len & 1) == 0) { + if (len == 2) + sum = csum_add(sum, (__force __wsum)*(const u16 *)buff); + if (len >= 4) + sum = csum_add(sum, (__force __wsum)*(const u32 *)buff); + if (len == 6) + sum = csum_add(sum, (__force __wsum) + *(const u16 *)(buff + 4)); + if (len >= 8) + sum = csum_add(sum, (__force __wsum) + *(const u32 *)(buff + 4)); + if (len == 10) + sum = csum_add(sum, (__force __wsum) + *(const u16 *)(buff + 8)); + if (len >= 12) + sum = csum_add(sum, (__force __wsum) + *(const u32 *)(buff + 8)); + if (len == 14) + sum = csum_add(sum, (__force __wsum) + *(const u16 *)(buff + 12)); + if (len >= 16) + sum = csum_add(sum, (__force __wsum) + *(const u32 *)(buff + 12)); + } else if (__builtin_constant_p(len) && (len & 3) == 0) { + sum = csum_add(sum, ip_fast_csum_nofold(buff, len >> 2)); + } else { + sum = __csum_partial(buff, len, sum); + } + return sum; +} + +/* + * this routine is used for miscellaneous IP-like checksums, mainly + * in icmp.c + */ +static inline __sum16 ip_compute_csum(const void *buff, int len) +{ + return csum_fold(csum_partial(buff, len, 0)); +} + #endif #endif /* __KERNEL__ */ #endif diff --git a/arch/powerpc/include/asm/cmpxchg.h b/arch/powerpc/include/asm/cmpxchg.h index d1a8d93cccfd483b8181046434ebc3ef55d8704a..44efe739b6b9b4979f95b3a26d8abf52dcda3c26 100644 --- a/arch/powerpc/include/asm/cmpxchg.h +++ b/arch/powerpc/include/asm/cmpxchg.h @@ -5,25 +5,25 @@ #include #include #include +#include /* * Atomic exchange * - * Changes the memory location '*ptr' to be val and returns + * Changes the memory location '*p' to be val and returns * the previous value stored there. */ + static __always_inline unsigned long -__xchg_u32(volatile void *p, unsigned long val) +__xchg_u32_local(volatile void *p, unsigned long val) { unsigned long prev; __asm__ __volatile__( - PPC_ATOMIC_ENTRY_BARRIER "1: lwarx %0,0,%2 \n" PPC405_ERR77(0,%2) " stwcx. %3,0,%2 \n\ bne- 1b" - PPC_ATOMIC_EXIT_BARRIER : "=&r" (prev), "+m" (*(volatile unsigned int *)p) : "r" (p), "r" (val) : "cc", "memory"); @@ -31,42 +31,34 @@ __xchg_u32(volatile void *p, unsigned long val) return prev; } -/* - * Atomic exchange - * - * Changes the memory location '*ptr' to be val and returns - * the previous value stored there. - */ static __always_inline unsigned long -__xchg_u32_local(volatile void *p, unsigned long val) +__xchg_u32_relaxed(u32 *p, unsigned long val) { unsigned long prev; __asm__ __volatile__( -"1: lwarx %0,0,%2 \n" - PPC405_ERR77(0,%2) -" stwcx. %3,0,%2 \n\ - bne- 1b" - : "=&r" (prev), "+m" (*(volatile unsigned int *)p) +"1: lwarx %0,0,%2\n" + PPC405_ERR77(0, %2) +" stwcx. %3,0,%2\n" +" bne- 1b" + : "=&r" (prev), "+m" (*p) : "r" (p), "r" (val) - : "cc", "memory"); + : "cc"); return prev; } #ifdef CONFIG_PPC64 static __always_inline unsigned long -__xchg_u64(volatile void *p, unsigned long val) +__xchg_u64_local(volatile void *p, unsigned long val) { unsigned long prev; __asm__ __volatile__( - PPC_ATOMIC_ENTRY_BARRIER "1: ldarx %0,0,%2 \n" PPC405_ERR77(0,%2) " stdcx. %3,0,%2 \n\ bne- 1b" - PPC_ATOMIC_EXIT_BARRIER : "=&r" (prev), "+m" (*(volatile unsigned long *)p) : "r" (p), "r" (val) : "cc", "memory"); @@ -75,64 +67,52 @@ __xchg_u64(volatile void *p, unsigned long val) } static __always_inline unsigned long -__xchg_u64_local(volatile void *p, unsigned long val) +__xchg_u64_relaxed(u64 *p, unsigned long val) { unsigned long prev; __asm__ __volatile__( -"1: ldarx %0,0,%2 \n" - PPC405_ERR77(0,%2) -" stdcx. %3,0,%2 \n\ - bne- 1b" - : "=&r" (prev), "+m" (*(volatile unsigned long *)p) +"1: ldarx %0,0,%2\n" + PPC405_ERR77(0, %2) +" stdcx. %3,0,%2\n" +" bne- 1b" + : "=&r" (prev), "+m" (*p) : "r" (p), "r" (val) - : "cc", "memory"); + : "cc"); return prev; } #endif -/* - * This function doesn't exist, so you'll get a linker error - * if something tries to do an invalid xchg(). - */ -extern void __xchg_called_with_bad_pointer(void); - static __always_inline unsigned long -__xchg(volatile void *ptr, unsigned long x, unsigned int size) +__xchg_local(volatile void *ptr, unsigned long x, unsigned int size) { switch (size) { case 4: - return __xchg_u32(ptr, x); + return __xchg_u32_local(ptr, x); #ifdef CONFIG_PPC64 case 8: - return __xchg_u64(ptr, x); + return __xchg_u64_local(ptr, x); #endif } - __xchg_called_with_bad_pointer(); + BUILD_BUG_ON_MSG(1, "Unsupported size for __xchg"); return x; } static __always_inline unsigned long -__xchg_local(volatile void *ptr, unsigned long x, unsigned int size) +__xchg_relaxed(void *ptr, unsigned long x, unsigned int size) { switch (size) { case 4: - return __xchg_u32_local(ptr, x); + return __xchg_u32_relaxed(ptr, x); #ifdef CONFIG_PPC64 case 8: - return __xchg_u64_local(ptr, x); + return __xchg_u64_relaxed(ptr, x); #endif } - __xchg_called_with_bad_pointer(); + BUILD_BUG_ON_MSG(1, "Unsupported size for __xchg_local"); return x; } -#define xchg(ptr,x) \ - ({ \ - __typeof__(*(ptr)) _x_ = (x); \ - (__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, sizeof(*(ptr))); \ - }) - #define xchg_local(ptr,x) \ ({ \ __typeof__(*(ptr)) _x_ = (x); \ @@ -140,6 +120,12 @@ __xchg_local(volatile void *ptr, unsigned long x, unsigned int size) (unsigned long)_x_, sizeof(*(ptr))); \ }) +#define xchg_relaxed(ptr, x) \ +({ \ + __typeof__(*(ptr)) _x_ = (x); \ + (__typeof__(*(ptr))) __xchg_relaxed((ptr), \ + (unsigned long)_x_, sizeof(*(ptr))); \ +}) /* * Compare and exchange - if *p == old, set it to new, * and return the old value of *p. @@ -190,6 +176,56 @@ __cmpxchg_u32_local(volatile unsigned int *p, unsigned long old, return prev; } +static __always_inline unsigned long +__cmpxchg_u32_relaxed(u32 *p, unsigned long old, unsigned long new) +{ + unsigned long prev; + + __asm__ __volatile__ ( +"1: lwarx %0,0,%2 # __cmpxchg_u32_relaxed\n" +" cmpw 0,%0,%3\n" +" bne- 2f\n" + PPC405_ERR77(0, %2) +" stwcx. %4,0,%2\n" +" bne- 1b\n" +"2:" + : "=&r" (prev), "+m" (*p) + : "r" (p), "r" (old), "r" (new) + : "cc"); + + return prev; +} + +/* + * cmpxchg family don't have order guarantee if cmp part fails, therefore we + * can avoid superfluous barriers if we use assembly code to implement + * cmpxchg() and cmpxchg_acquire(), however we don't do the similar for + * cmpxchg_release() because that will result in putting a barrier in the + * middle of a ll/sc loop, which is probably a bad idea. For example, this + * might cause the conditional store more likely to fail. + */ +static __always_inline unsigned long +__cmpxchg_u32_acquire(u32 *p, unsigned long old, unsigned long new) +{ + unsigned long prev; + + __asm__ __volatile__ ( +"1: lwarx %0,0,%2 # __cmpxchg_u32_acquire\n" +" cmpw 0,%0,%3\n" +" bne- 2f\n" + PPC405_ERR77(0, %2) +" stwcx. %4,0,%2\n" +" bne- 1b\n" + PPC_ACQUIRE_BARRIER + "\n" +"2:" + : "=&r" (prev), "+m" (*p) + : "r" (p), "r" (old), "r" (new) + : "cc", "memory"); + + return prev; +} + #ifdef CONFIG_PPC64 static __always_inline unsigned long __cmpxchg_u64(volatile unsigned long *p, unsigned long old, unsigned long new) @@ -233,11 +269,47 @@ __cmpxchg_u64_local(volatile unsigned long *p, unsigned long old, return prev; } -#endif -/* This function doesn't exist, so you'll get a linker error - if something tries to do an invalid cmpxchg(). */ -extern void __cmpxchg_called_with_bad_pointer(void); +static __always_inline unsigned long +__cmpxchg_u64_relaxed(u64 *p, unsigned long old, unsigned long new) +{ + unsigned long prev; + + __asm__ __volatile__ ( +"1: ldarx %0,0,%2 # __cmpxchg_u64_relaxed\n" +" cmpd 0,%0,%3\n" +" bne- 2f\n" +" stdcx. %4,0,%2\n" +" bne- 1b\n" +"2:" + : "=&r" (prev), "+m" (*p) + : "r" (p), "r" (old), "r" (new) + : "cc"); + + return prev; +} + +static __always_inline unsigned long +__cmpxchg_u64_acquire(u64 *p, unsigned long old, unsigned long new) +{ + unsigned long prev; + + __asm__ __volatile__ ( +"1: ldarx %0,0,%2 # __cmpxchg_u64_acquire\n" +" cmpd 0,%0,%3\n" +" bne- 2f\n" +" stdcx. %4,0,%2\n" +" bne- 1b\n" + PPC_ACQUIRE_BARRIER + "\n" +"2:" + : "=&r" (prev), "+m" (*p) + : "r" (p), "r" (old), "r" (new) + : "cc", "memory"); + + return prev; +} +#endif static __always_inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, @@ -251,7 +323,7 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, return __cmpxchg_u64(ptr, old, new); #endif } - __cmpxchg_called_with_bad_pointer(); + BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg"); return old; } @@ -267,10 +339,41 @@ __cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new, return __cmpxchg_u64_local(ptr, old, new); #endif } - __cmpxchg_called_with_bad_pointer(); + BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg_local"); + return old; +} + +static __always_inline unsigned long +__cmpxchg_relaxed(void *ptr, unsigned long old, unsigned long new, + unsigned int size) +{ + switch (size) { + case 4: + return __cmpxchg_u32_relaxed(ptr, old, new); +#ifdef CONFIG_PPC64 + case 8: + return __cmpxchg_u64_relaxed(ptr, old, new); +#endif + } + BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg_relaxed"); return old; } +static __always_inline unsigned long +__cmpxchg_acquire(void *ptr, unsigned long old, unsigned long new, + unsigned int size) +{ + switch (size) { + case 4: + return __cmpxchg_u32_acquire(ptr, old, new); +#ifdef CONFIG_PPC64 + case 8: + return __cmpxchg_u64_acquire(ptr, old, new); +#endif + } + BUILD_BUG_ON_MSG(1, "Unsupported size for __cmpxchg_acquire"); + return old; +} #define cmpxchg(ptr, o, n) \ ({ \ __typeof__(*(ptr)) _o_ = (o); \ @@ -288,6 +391,23 @@ __cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new, (unsigned long)_n_, sizeof(*(ptr))); \ }) +#define cmpxchg_relaxed(ptr, o, n) \ +({ \ + __typeof__(*(ptr)) _o_ = (o); \ + __typeof__(*(ptr)) _n_ = (n); \ + (__typeof__(*(ptr))) __cmpxchg_relaxed((ptr), \ + (unsigned long)_o_, (unsigned long)_n_, \ + sizeof(*(ptr))); \ +}) + +#define cmpxchg_acquire(ptr, o, n) \ +({ \ + __typeof__(*(ptr)) _o_ = (o); \ + __typeof__(*(ptr)) _n_ = (n); \ + (__typeof__(*(ptr))) __cmpxchg_acquire((ptr), \ + (unsigned long)_o_, (unsigned long)_n_, \ + sizeof(*(ptr))); \ +}) #ifdef CONFIG_PPC64 #define cmpxchg64(ptr, o, n) \ ({ \ @@ -299,7 +419,16 @@ __cmpxchg_local(volatile void *ptr, unsigned long old, unsigned long new, BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ cmpxchg_local((ptr), (o), (n)); \ }) -#define cmpxchg64_relaxed cmpxchg64_local +#define cmpxchg64_relaxed(ptr, o, n) \ +({ \ + BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ + cmpxchg_relaxed((ptr), (o), (n)); \ +}) +#define cmpxchg64_acquire(ptr, o, n) \ +({ \ + BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ + cmpxchg_acquire((ptr), (o), (n)); \ +}) #else #include #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h index 840a5509b3f19b37f5dd1d92f43718c568d49453..994c60a857cef048b66976272e258de865d7d49f 100644 --- a/arch/powerpc/include/asm/code-patching.h +++ b/arch/powerpc/include/asm/code-patching.h @@ -99,4 +99,25 @@ static inline unsigned long ppc_global_function_entry(void *func) #endif } +#ifdef CONFIG_PPC64 +/* + * Some instruction encodings commonly used in dynamic ftracing + * and function live patching. + */ + +/* This must match the definition of STK_GOT in */ +#if defined(_CALL_ELF) && _CALL_ELF == 2 +#define R2_STACK_OFFSET 24 +#else +#define R2_STACK_OFFSET 40 +#endif + +#define PPC_INST_LD_TOC (PPC_INST_LD | ___PPC_RT(__REG_R2) | \ + ___PPC_RA(__REG_R1) | R2_STACK_OFFSET) + +/* usually preceded by a mflr r0 */ +#define PPC_INST_STD_LR (PPC_INST_STD | ___PPC_RS(__REG_R0) | \ + ___PPC_RA(__REG_R1) | PPC_LR_STKOFF) +#endif /* CONFIG_PPC64 */ + #endif /* _ASM_POWERPC_CODE_PATCHING_H */ diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index b118072670fb15ceac83fce37967f1b07e4cffec..df4fb5faba436e1922ef1bd774b0d17ed814b274 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h @@ -43,6 +43,11 @@ extern int machine_check_e500(struct pt_regs *regs); extern int machine_check_e200(struct pt_regs *regs); extern int machine_check_47x(struct pt_regs *regs); +extern void cpu_down_flush_e500v2(void); +extern void cpu_down_flush_e500mc(void); +extern void cpu_down_flush_e5500(void); +extern void cpu_down_flush_e6500(void); + /* NOTE WELL: Update identify_cpu() if fields are added or removed! */ struct cpu_spec { /* CPU is matched via (PVR & pvr_mask) == pvr_value */ @@ -59,6 +64,9 @@ struct cpu_spec { unsigned int icache_bsize; unsigned int dcache_bsize; + /* flush caches inside the current cpu */ + void (*cpu_down_flush)(void); + /* number of performance monitor counters */ unsigned int num_pmcs; enum powerpc_pmc_type pmc_type; @@ -171,7 +179,7 @@ enum { #define CPU_FTR_ARCH_201 LONG_ASM_CONST(0x0000000200000000) #define CPU_FTR_ARCH_206 LONG_ASM_CONST(0x0000000400000000) #define CPU_FTR_ARCH_207S LONG_ASM_CONST(0x0000000800000000) -/* Free LONG_ASM_CONST(0x0000001000000000) */ +#define CPU_FTR_ARCH_300 LONG_ASM_CONST(0x0000001000000000) #define CPU_FTR_MMCRA LONG_ASM_CONST(0x0000002000000000) #define CPU_FTR_CTRL LONG_ASM_CONST(0x0000004000000000) #define CPU_FTR_SMT LONG_ASM_CONST(0x0000008000000000) @@ -196,6 +204,7 @@ enum { #define CPU_FTR_DAWR LONG_ASM_CONST(0x0400000000000000) #define CPU_FTR_DABRX LONG_ASM_CONST(0x0800000000000000) #define CPU_FTR_PMAO_BUG LONG_ASM_CONST(0x1000000000000000) +#define CPU_FTR_SUBCORE LONG_ASM_CONST(0x2000000000000000) #ifndef __ASSEMBLY__ @@ -443,9 +452,19 @@ enum { CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \ CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \ - CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP) + CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP | CPU_FTR_SUBCORE) #define CPU_FTRS_POWER8E (CPU_FTRS_POWER8 | CPU_FTR_PMAO_BUG) #define CPU_FTRS_POWER8_DD1 (CPU_FTRS_POWER8 & ~CPU_FTR_DBELL) +#define CPU_FTRS_POWER9 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ + CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_ARCH_206 |\ + CPU_FTR_MMCRA | CPU_FTR_SMT | \ + CPU_FTR_COHERENT_ICACHE | \ + CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \ + CPU_FTR_DSCR | CPU_FTR_SAO | \ + CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ + CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \ + CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \ + CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP | CPU_FTR_ARCH_300) #define CPU_FTRS_CELL (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \ @@ -464,7 +483,7 @@ enum { (CPU_FTRS_POWER4 | CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | \ CPU_FTRS_POWER6 | CPU_FTRS_POWER7 | CPU_FTRS_POWER8E | \ CPU_FTRS_POWER8 | CPU_FTRS_POWER8_DD1 | CPU_FTRS_CELL | \ - CPU_FTRS_PA6T | CPU_FTR_VSX) + CPU_FTRS_PA6T | CPU_FTR_VSX | CPU_FTRS_POWER9) #endif #else enum { @@ -515,7 +534,8 @@ enum { (CPU_FTRS_POWER4 & CPU_FTRS_PPC970 & CPU_FTRS_POWER5 & \ CPU_FTRS_POWER6 & CPU_FTRS_POWER7 & CPU_FTRS_CELL & \ CPU_FTRS_PA6T & CPU_FTRS_POWER8 & CPU_FTRS_POWER8E & \ - CPU_FTRS_POWER8_DD1 & ~CPU_FTR_HVMODE & CPU_FTRS_POSSIBLE) + CPU_FTRS_POWER8_DD1 & ~CPU_FTR_HVMODE & CPU_FTRS_POSSIBLE & \ + CPU_FTRS_POWER9) #endif #else enum { diff --git a/arch/powerpc/include/asm/cputhreads.h b/arch/powerpc/include/asm/cputhreads.h index ba42e46ea58eeed448d3d7abb5c67f5570e96bca..666bef4ebfae72a88c4bceebacbc18a7bfa7b390 100644 --- a/arch/powerpc/include/asm/cputhreads.h +++ b/arch/powerpc/include/asm/cputhreads.h @@ -1,6 +1,7 @@ #ifndef _ASM_POWERPC_CPUTHREADS_H #define _ASM_POWERPC_CPUTHREADS_H +#ifndef __ASSEMBLY__ #include /* @@ -94,7 +95,21 @@ static inline int cpu_last_thread_sibling(int cpu) return cpu | (threads_per_core - 1); } +static inline u32 get_tensr(void) +{ +#ifdef CONFIG_BOOKE + if (cpu_has_feature(CPU_FTR_SMT)) + return mfspr(SPRN_TENSR); +#endif + return 1; +} + +void book3e_start_thread(int thread, unsigned long addr); +void book3e_stop_thread(int thread); + +#endif /* __ASSEMBLY__ */ +#define INVALID_THREAD_HWID 0x0fff #endif /* _ASM_POWERPC_CPUTHREADS_H */ diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h index 867c39b45df6ce4c1bd5a342ca314a888bb185bf..fb9f376ae27bf09098c92e7f7687dcbd8178950f 100644 --- a/arch/powerpc/include/asm/eeh.h +++ b/arch/powerpc/include/asm/eeh.h @@ -72,6 +72,7 @@ struct pci_dn; #define EEH_PE_PHB (1 << 1) /* PHB PE */ #define EEH_PE_DEVICE (1 << 2) /* Device PE */ #define EEH_PE_BUS (1 << 3) /* Bus PE */ +#define EEH_PE_VF (1 << 4) /* VF PE */ #define EEH_PE_ISOLATED (1 << 0) /* Isolated PE */ #define EEH_PE_RECOVERING (1 << 1) /* Recovering PE */ @@ -136,11 +137,15 @@ struct eeh_dev { int pcix_cap; /* Saved PCIx capability */ int pcie_cap; /* Saved PCIe capability */ int aer_cap; /* Saved AER capability */ + int af_cap; /* Saved AF capability */ struct eeh_pe *pe; /* Associated PE */ struct list_head list; /* Form link list in the PE */ + struct list_head rmv_list; /* Record the removed edevs */ struct pci_controller *phb; /* Associated PHB */ struct pci_dn *pdn; /* Associated PCI device node */ struct pci_dev *pdev; /* Associated PCI device */ + bool in_error; /* Error flag for edev */ + struct pci_dev *physfn; /* Associated SRIOV PF */ struct pci_bus *bus; /* PCI bus for partial hotplug */ }; diff --git a/arch/powerpc/include/asm/fsl_pm.h b/arch/powerpc/include/asm/fsl_pm.h new file mode 100644 index 0000000000000000000000000000000000000000..47df55e36d4fb593e462c439f6beec919f56cc7f --- /dev/null +++ b/arch/powerpc/include/asm/fsl_pm.h @@ -0,0 +1,51 @@ +/* + * Support Power Management + * + * Copyright 2014-2015 Freescale Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#ifndef __PPC_FSL_PM_H +#define __PPC_FSL_PM_H + +#define E500_PM_PH10 1 +#define E500_PM_PH15 2 +#define E500_PM_PH20 3 +#define E500_PM_PH30 4 +#define E500_PM_DOZE E500_PM_PH10 +#define E500_PM_NAP E500_PM_PH15 + +#define PLAT_PM_SLEEP 20 +#define PLAT_PM_LPM20 30 + +#define FSL_PM_SLEEP (1 << 0) +#define FSL_PM_DEEP_SLEEP (1 << 1) + +struct fsl_pm_ops { + /* mask pending interrupts to the RCPM from MPIC */ + void (*irq_mask)(int cpu); + + /* unmask pending interrupts to the RCPM from MPIC */ + void (*irq_unmask)(int cpu); + void (*cpu_enter_state)(int cpu, int state); + void (*cpu_exit_state)(int cpu, int state); + void (*cpu_up_prepare)(int cpu); + void (*cpu_die)(int cpu); + int (*plat_enter_sleep)(void); + void (*freeze_time_base)(bool freeze); + + /* keep the power of IP blocks during sleep/deep sleep */ + void (*set_ip_power)(bool enable, u32 mask); + + /* get platform supported power management modes */ + unsigned int (*get_pm_modes)(void); +}; + +extern const struct fsl_pm_ops *qoriq_pm_ops; + +int __init fsl_rcpm_init(void); + +#endif /* __PPC_FSL_PM_H */ diff --git a/arch/powerpc/include/asm/ftrace.h b/arch/powerpc/include/asm/ftrace.h index ef89b14655731006c7adac49afbe26a073782868..50ca7585abe2563af6e9c421d8050d2df5f82411 100644 --- a/arch/powerpc/include/asm/ftrace.h +++ b/arch/powerpc/include/asm/ftrace.h @@ -46,6 +46,8 @@ extern void _mcount(void); #ifdef CONFIG_DYNAMIC_FTRACE +# define FTRACE_ADDR ((unsigned long)ftrace_caller) +# define FTRACE_REGS_ADDR FTRACE_ADDR static inline unsigned long ftrace_call_adjust(unsigned long addr) { /* reloction of mcount call site is the same as the address */ @@ -58,6 +60,9 @@ struct dyn_arch_ftrace { #endif /* CONFIG_DYNAMIC_FTRACE */ #endif /* __ASSEMBLY__ */ +#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS +#define ARCH_SUPPORTS_FTRACE_OPS 1 +#endif #endif #if defined(CONFIG_FTRACE_SYSCALLS) && defined(CONFIG_PPC64) && !defined(__ASSEMBLY__) diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h index 7eac89b9f02e5f2a97ceeb6d12fa4cffc3abf4b9..42814f0567cc49db7328258676801f8c739da12c 100644 --- a/arch/powerpc/include/asm/hugetlb.h +++ b/arch/powerpc/include/asm/hugetlb.h @@ -19,7 +19,7 @@ static inline pte_t *hugepd_page(hugepd_t hpd) * We have only four bits to encode, MMU page size */ BUILD_BUG_ON((MMU_PAGE_COUNT - 1) > 0xf); - return (pte_t *)(hpd.pd & ~HUGEPD_SHIFT_MASK); + return __va(hpd.pd & HUGEPD_ADDR_MASK); } static inline unsigned int hugepd_mmu_psize(hugepd_t hpd) diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h index e3b54dd4f73073cad8dc34270d5f2a09b7ba1351..0bc9c284aa105332aafa408a1750183c1ae36174 100644 --- a/arch/powerpc/include/asm/hvcall.h +++ b/arch/powerpc/include/asm/hvcall.h @@ -94,6 +94,7 @@ #define H_SG_LIST -72 #define H_OP_MODE -73 #define H_COP_HW -74 +#define H_STATE -75 #define H_UNSUPPORTED_FLAG_START -256 #define H_UNSUPPORTED_FLAG_END -511 #define H_MULTI_THREADS_ACTIVE -9005 diff --git a/arch/powerpc/include/asm/hydra.h b/arch/powerpc/include/asm/hydra.h index 1cb39c96d1558fcded9b86d7aa5e3a5512f929cc..b3b0f2d020f0ce91f244c213ab2e051e7cdd2233 100644 --- a/arch/powerpc/include/asm/hydra.h +++ b/arch/powerpc/include/asm/hydra.h @@ -89,7 +89,7 @@ extern volatile struct Hydra __iomem *Hydra; #define HYDRA_INT_EXT2 13 /* PCI IRQX */ #define HYDRA_INT_EXT3 14 /* PCI IRQY */ #define HYDRA_INT_EXT4 15 /* PCI IRQZ */ -#define HYDRA_INT_EXT5 16 /* IDE Primay/Secondary */ +#define HYDRA_INT_EXT5 16 /* IDE Primary/Secondary */ #define HYDRA_INT_EXT6 17 /* IDE Secondary */ #define HYDRA_INT_EXT7 18 /* Power Off Request */ #define HYDRA_INT_SPARE 19 diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h index 6c1297ec374cc720f456e2c34f78299f8aa6468f..2fd1690b79d210702c123d6e54d7828ce521be9a 100644 --- a/arch/powerpc/include/asm/io.h +++ b/arch/powerpc/include/asm/io.h @@ -300,7 +300,7 @@ extern void _memcpy_toio(volatile void __iomem *dest, const void *src, * When CONFIG_PPC_INDIRECT_MMIO is set, the platform can provide hooks * on all MMIOs. (Note that this is all 64 bits only for now) * - * To help platforms who may need to differenciate MMIO addresses in + * To help platforms who may need to differentiate MMIO addresses in * their hooks, a bitfield is reserved for use by the platform near the * top of MMIO addresses (not PIO, those have to cope the hard way). * diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h index 3f191f573d4f1f487b5e417ddd55eaed8d49951d..fd22442d30a9732eae0489c4e062cfe41628884c 100644 --- a/arch/powerpc/include/asm/machdep.h +++ b/arch/powerpc/include/asm/machdep.h @@ -54,7 +54,7 @@ struct machdep_calls { int psize, int apsize, int ssize); long (*hpte_remove)(unsigned long hpte_group); - void (*hpte_removebolted)(unsigned long ea, + int (*hpte_removebolted)(unsigned long ea, int psize, int ssize); void (*flush_hash_range)(unsigned long number, int local); void (*hugepage_invalidate)(unsigned long vsid, @@ -174,11 +174,11 @@ struct machdep_calls { platform, called once per cpu. */ void (*enable_pmcs)(void); - /* Set DABR for this platform, leave empty for default implemenation */ + /* Set DABR for this platform, leave empty for default implementation */ int (*set_dabr)(unsigned long dabr, unsigned long dabrx); - /* Set DAWR for this platform, leave empty for default implemenation */ + /* Set DAWR for this platform, leave empty for default implementation */ int (*set_dawr)(unsigned long dawr, unsigned long dawrx); diff --git a/arch/powerpc/include/asm/mman.h b/arch/powerpc/include/asm/mman.h index 8565c254151abed6bd3b698551c86035201c28b4..2563c435a4b166593e71812086baa791a01de43b 100644 --- a/arch/powerpc/include/asm/mman.h +++ b/arch/powerpc/include/asm/mman.h @@ -18,11 +18,12 @@ * This file is included by linux/mman.h, so we can't use cacl_vm_prot_bits() * here. How important is the optimization? */ -static inline unsigned long arch_calc_vm_prot_bits(unsigned long prot) +static inline unsigned long arch_calc_vm_prot_bits(unsigned long prot, + unsigned long pkey) { return (prot & PROT_SAO) ? VM_SAO : 0; } -#define arch_calc_vm_prot_bits(prot) arch_calc_vm_prot_bits(prot) +#define arch_calc_vm_prot_bits(prot, pkey) arch_calc_vm_prot_bits(prot, pkey) static inline pgprot_t arch_vm_get_page_prot(unsigned long vm_flags) { diff --git a/arch/powerpc/include/asm/mmu-8xx.h b/arch/powerpc/include/asm/mmu-8xx.h index f05500a29a60d6f23f4e23de99821995511ccae0..0a566f15f9850ad891b60abab8130de92eb12ecd 100644 --- a/arch/powerpc/include/asm/mmu-8xx.h +++ b/arch/powerpc/include/asm/mmu-8xx.h @@ -171,9 +171,9 @@ typedef struct { } mm_context_t; #endif /* !__ASSEMBLY__ */ -#if (PAGE_SHIFT == 12) +#if defined(CONFIG_PPC_4K_PAGES) #define mmu_virtual_psize MMU_PAGE_4K -#elif (PAGE_SHIFT == 14) +#elif defined(CONFIG_PPC_16K_PAGES) #define mmu_virtual_psize MMU_PAGE_16K #else #error "Unsupported PAGE_SIZE" diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h index 3d5abfe6ba6756324b71cfae8d69a9ba865da75c..8ca1c983bf6c3443c9d1a47cec058833383986b6 100644 --- a/arch/powerpc/include/asm/mmu.h +++ b/arch/powerpc/include/asm/mmu.h @@ -97,6 +97,7 @@ #define MMU_FTRS_POWER6 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE #define MMU_FTRS_POWER7 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE #define MMU_FTRS_POWER8 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE +#define MMU_FTRS_POWER9 MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE #define MMU_FTRS_CELL MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \ MMU_FTR_CI_LARGE_PAGE #define MMU_FTRS_PA6T MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \ @@ -182,10 +183,10 @@ static inline void assert_pte_locked(struct mm_struct *mm, unsigned long addr) #if defined(CONFIG_PPC_STD_MMU_64) /* 64-bit classic hash table MMU */ -# include +#include #elif defined(CONFIG_PPC_STD_MMU_32) /* 32-bit classic hash table MMU */ -# include +#include #elif defined(CONFIG_40x) /* 40x-style software loaded TLB */ # include diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h index 878c27771717260cb1bc5590ad4c6138b2b096f7..4eaab40e3ade3663b13dcd155ed9258d276534a0 100644 --- a/arch/powerpc/include/asm/mmu_context.h +++ b/arch/powerpc/include/asm/mmu_context.h @@ -148,5 +148,17 @@ static inline void arch_bprm_mm_init(struct mm_struct *mm, { } +static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, + bool write, bool execute, bool foreign) +{ + /* by default, allow everything */ + return true; +} + +static inline bool arch_pte_access_permitted(pte_t pte, bool write) +{ + /* by default, allow everything */ + return true; +} #endif /* __KERNEL__ */ #endif /* __ASM_POWERPC_MMU_CONTEXT_H */ diff --git a/arch/powerpc/include/asm/module.h b/arch/powerpc/include/asm/module.h index dcfcad139bccc0765e3dc6a5f17cd5566258910b..cd4ffd86765f35eeac01f0103307aa5ef174d0e5 100644 --- a/arch/powerpc/include/asm/module.h +++ b/arch/powerpc/include/asm/module.h @@ -19,7 +19,7 @@ * Thanks to Paul M for explaining this. * * PPC can only do rel jumps += 32MB, and often the kernel and other - * modules are furthur away than this. So, we jump to a table of + * modules are further away than this. So, we jump to a table of * trampolines attached to the module (the Procedure Linkage Table) * whenever that happens. */ @@ -78,10 +78,18 @@ struct mod_arch_specific { # endif /* MODULE */ #endif -bool is_module_trampoline(u32 *insns); -int module_trampoline_target(struct module *mod, u32 *trampoline, +int module_trampoline_target(struct module *mod, unsigned long trampoline, unsigned long *target); +#ifdef CONFIG_DYNAMIC_FTRACE +int module_finalize_ftrace(struct module *mod, const Elf_Shdr *sechdrs); +#else +static inline int module_finalize_ftrace(struct module *mod, const Elf_Shdr *sechdrs) +{ + return 0; +} +#endif + struct exception_table_entry; void sort_ex_table(struct exception_table_entry *start, struct exception_table_entry *finish); diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h index c82cbf52d19ea07cef31629c75b6502ea9955dcd..78084759751412c3a28e87ed2982899b19595037 100644 --- a/arch/powerpc/include/asm/nohash/32/pgtable.h +++ b/arch/powerpc/include/asm/nohash/32/pgtable.h @@ -86,7 +86,7 @@ extern int icache_44x_need_flush; * We no longer map larger than phys RAM with the BATs so we don't have * to worry about the VMALLOC_OFFSET causing problems. We do have to worry * about clashes between our early calls to ioremap() that start growing down - * from ioremap_base being run into the VM area allocations (growing upwards + * from IOREMAP_TOP being run into the VM area allocations (growing upwards * from VMALLOC_START). For this reason we have ioremap_bot to check when * we actually run into our mappings setup in the early boot with the VM * system. This really does become a problem for machines with good amounts @@ -309,7 +309,8 @@ static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry) #define pte_index(address) \ (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) #define pte_offset_kernel(dir, addr) \ - ((pte_t *) pmd_page_vaddr(*(dir)) + pte_index(addr)) + (pmd_bad(*(dir)) ? NULL : (pte_t *)pmd_page_vaddr(*(dir)) + \ + pte_index(addr)) #define pte_offset_map(dir, addr) \ ((pte_t *) kmap_atomic(pmd_page(*(dir))) + pte_index(addr)) #define pte_unmap(pte) kunmap_atomic(pte) diff --git a/arch/powerpc/include/asm/nohash/64/pgtable.h b/arch/powerpc/include/asm/nohash/64/pgtable.h index b9f734dd5b81c24a8c2ae00c0cd1c6956d2e08b8..10debb93c4a4835a8ccaa758cb850237d7a6f200 100644 --- a/arch/powerpc/include/asm/nohash/64/pgtable.h +++ b/arch/powerpc/include/asm/nohash/64/pgtable.h @@ -108,6 +108,9 @@ #ifndef __ASSEMBLY__ /* pte_clear moved to later in this file */ +/* Pointers in the page table tree are virtual addresses */ +#define __pgtable_ptr_val(ptr) ((unsigned long)(ptr)) + #define PMD_BAD_BITS (PTE_TABLE_SIZE-1) #define PUD_BAD_BITS (PMD_TABLE_SIZE-1) diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index 07a99e638449acdbbcb9817919d3ce62f0d2b0a9..9d86c665171693da90767981beb5b0755ad6c76d 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h @@ -248,6 +248,7 @@ extern int opal_elog_init(void); extern void opal_platform_dump_init(void); extern void opal_sys_param_init(void); extern void opal_msglog_init(void); +extern void opal_msglog_sysfs_init(void); extern int opal_async_comp_init(void); extern int opal_sensor_init(void); extern int opal_hmi_handler_init(void); @@ -273,6 +274,8 @@ void opal_free_sg_list(struct opal_sg_list *sg); extern int opal_error_code(int rc); +ssize_t opal_msglog_copy(char *to, loff_t pos, size_t count); + #endif /* __ASSEMBLY__ */ #endif /* _ASM_POWERPC_OPAL_H */ diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h index e34124f6fbf27fd9af63d7da99c61e978b9da65e..ab3d8977bacd6488fafe662c61d893be1c1bd22b 100644 --- a/arch/powerpc/include/asm/page.h +++ b/arch/powerpc/include/asm/page.h @@ -271,6 +271,13 @@ extern long long virt_phys_offset; #else #define PD_HUGE 0x80000000 #endif + +#else /* CONFIG_PPC_BOOK3S_64 */ +/* + * Book3S 64 stores real addresses in the hugepd entries to + * avoid overlaps with _PAGE_PRESENT and _PAGE_PTE. + */ +#define HUGEPD_ADDR_MASK (0x0ffffffffffffffful & ~HUGEPD_SHIFT_MASK) #endif /* CONFIG_PPC_BOOK3S_64 */ /* @@ -281,109 +288,7 @@ extern long long virt_phys_offset; #ifndef __ASSEMBLY__ -#ifdef CONFIG_STRICT_MM_TYPECHECKS -/* These are used to make use of C type-checking. */ - -/* PTE level */ -typedef struct { pte_basic_t pte; } pte_t; -#define __pte(x) ((pte_t) { (x) }) -static inline pte_basic_t pte_val(pte_t x) -{ - return x.pte; -} - -/* 64k pages additionally define a bigger "real PTE" type that gathers - * the "second half" part of the PTE for pseudo 64k pages - */ -#if defined(CONFIG_PPC_64K_PAGES) && defined(CONFIG_PPC_STD_MMU_64) -typedef struct { pte_t pte; unsigned long hidx; } real_pte_t; -#else -typedef struct { pte_t pte; } real_pte_t; -#endif - -/* PMD level */ -#ifdef CONFIG_PPC64 -typedef struct { unsigned long pmd; } pmd_t; -#define __pmd(x) ((pmd_t) { (x) }) -static inline unsigned long pmd_val(pmd_t x) -{ - return x.pmd; -} - -/* PUD level exusts only on 4k pages */ -#ifndef CONFIG_PPC_64K_PAGES -typedef struct { unsigned long pud; } pud_t; -#define __pud(x) ((pud_t) { (x) }) -static inline unsigned long pud_val(pud_t x) -{ - return x.pud; -} -#endif /* !CONFIG_PPC_64K_PAGES */ -#endif /* CONFIG_PPC64 */ - -/* PGD level */ -typedef struct { unsigned long pgd; } pgd_t; -#define __pgd(x) ((pgd_t) { (x) }) -static inline unsigned long pgd_val(pgd_t x) -{ - return x.pgd; -} - -/* Page protection bits */ -typedef struct { unsigned long pgprot; } pgprot_t; -#define pgprot_val(x) ((x).pgprot) -#define __pgprot(x) ((pgprot_t) { (x) }) - -#else - -/* - * .. while these make it easier on the compiler - */ - -typedef pte_basic_t pte_t; -#define __pte(x) (x) -static inline pte_basic_t pte_val(pte_t pte) -{ - return pte; -} - -#if defined(CONFIG_PPC_64K_PAGES) && defined(CONFIG_PPC_STD_MMU_64) -typedef struct { pte_t pte; unsigned long hidx; } real_pte_t; -#else -typedef pte_t real_pte_t; -#endif - - -#ifdef CONFIG_PPC64 -typedef unsigned long pmd_t; -#define __pmd(x) (x) -static inline unsigned long pmd_val(pmd_t pmd) -{ - return pmd; -} - -#ifndef CONFIG_PPC_64K_PAGES -typedef unsigned long pud_t; -#define __pud(x) (x) -static inline unsigned long pud_val(pud_t pud) -{ - return pud; -} -#endif /* !CONFIG_PPC_64K_PAGES */ -#endif /* CONFIG_PPC64 */ - -typedef unsigned long pgd_t; -#define __pgd(x) (x) -static inline unsigned long pgd_val(pgd_t pgd) -{ - return pgd; -} - -typedef unsigned long pgprot_t; -#define pgprot_val(x) (x) -#define __pgprot(x) (x) - -#endif +#include typedef struct { signed long pd; } hugepd_t; diff --git a/arch/powerpc/include/asm/page_32.h b/arch/powerpc/include/asm/page_32.h index 68d73b2a7bfc93b70d6479384937197d433b6c76..6a8e1797f22320c528bc28e369fb39816eda311f 100644 --- a/arch/powerpc/include/asm/page_32.h +++ b/arch/powerpc/include/asm/page_32.h @@ -1,6 +1,8 @@ #ifndef _ASM_POWERPC_PAGE_32_H #define _ASM_POWERPC_PAGE_32_H +#include + #if defined(CONFIG_PHYSICAL_ALIGN) && (CONFIG_PHYSICAL_START != 0) #if (CONFIG_PHYSICAL_START % CONFIG_PHYSICAL_ALIGN) != 0 #error "CONFIG_PHYSICAL_START must be a multiple of CONFIG_PHYSICAL_ALIGN" @@ -36,9 +38,18 @@ typedef unsigned long long pte_basic_t; typedef unsigned long pte_basic_t; #endif -struct page; -extern void clear_pages(void *page, int order); -static inline void clear_page(void *page) { clear_pages(page, 0); } +/* + * Clear page using the dcbz instruction, which doesn't cause any + * memory traffic (except to write out any cache lines which get + * displaced). This only works on cacheable memory. + */ +static inline void clear_page(void *addr) +{ + unsigned int i; + + for (i = 0; i < PAGE_SIZE / L1_CACHE_BYTES; i++, addr += L1_CACHE_BYTES) + dcbz(addr); +} extern void copy_page(void *to, void *from); #include diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index 78968c1ff931941d8244364cedd7f664f352e763..f5056e3394b466e20544818d1c431ee8e18cc5f8 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h @@ -211,15 +211,16 @@ struct pci_dn { #define IODA_INVALID_PE (-1) #ifdef CONFIG_PPC_POWERNV int pe_number; + int vf_index; /* VF index in the PF */ #ifdef CONFIG_PCI_IOV u16 vfs_expanded; /* number of VFs IOV BAR expanded */ u16 num_vfs; /* number of VFs enabled*/ - int offset; /* PE# for the first VF PE */ -#define M64_PER_IOV 4 - int m64_per_iov; + int *pe_num_map; /* PE# for the first VF PE or array */ + bool m64_single_mode; /* Use M64 BAR in Single Mode */ #define IODA_INVALID_M64 (-1) - int m64_wins[PCI_SRIOV_NUM_BARS][M64_PER_IOV]; + int (*m64_map)[PCI_SRIOV_NUM_BARS]; #endif /* CONFIG_PCI_IOV */ + int mps; /* Maximum Payload Size */ #endif struct list_head child_list; struct list_head list; diff --git a/arch/powerpc/include/asm/perf_event_server.h b/arch/powerpc/include/asm/perf_event_server.h index 814622146d5a11b53b39eff36d308b6a5ec9b643..e157489ee7a1220156868099903d45509bedd7e6 100644 --- a/arch/powerpc/include/asm/perf_event_server.h +++ b/arch/powerpc/include/asm/perf_event_server.h @@ -136,16 +136,24 @@ extern ssize_t power_events_sysfs_show(struct device *dev, * event 'cpu-cycles' can have two entries in sysfs: 'cpu-cycles' and * 'PM_CYC' where the latter is the name by which the event is known in * POWER CPU specification. + * + * Similarly, some hardware and cache events use the same event code. Eg. + * on POWER8, both "cache-references" and "L1-dcache-loads" events refer + * to the same event, PM_LD_REF_L1. The suffix, allows us to have two + * sysfs objects for the same event and thus two entries/aliases in sysfs. */ #define EVENT_VAR(_id, _suffix) event_attr_##_id##_suffix #define EVENT_PTR(_id, _suffix) &EVENT_VAR(_id, _suffix).attr.attr #define EVENT_ATTR(_name, _id, _suffix) \ - PMU_EVENT_ATTR(_name, EVENT_VAR(_id, _suffix), PME_##_id, \ + PMU_EVENT_ATTR(_name, EVENT_VAR(_id, _suffix), _id, \ power_events_sysfs_show) #define GENERIC_EVENT_ATTR(_name, _id) EVENT_ATTR(_name, _id, _g) #define GENERIC_EVENT_PTR(_id) EVENT_PTR(_id, _g) +#define CACHE_EVENT_ATTR(_name, _id) EVENT_ATTR(_name, _id, _c) +#define CACHE_EVENT_PTR(_id) EVENT_PTR(_id, _c) + #define POWER_EVENT_ATTR(_name, _id) EVENT_ATTR(_name, _id, _p) #define POWER_EVENT_PTR(_id) EVENT_PTR(_id, _p) diff --git a/arch/powerpc/include/asm/pgalloc-64.h b/arch/powerpc/include/asm/pgalloc-64.h index 69ef28a817335717602ca5dfd654f731e259a3dd..8d5fc3ac43da5ae71c3b7d6ca5ec27793974bfa4 100644 --- a/arch/powerpc/include/asm/pgalloc-64.h +++ b/arch/powerpc/include/asm/pgalloc-64.h @@ -53,7 +53,7 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) #ifndef CONFIG_PPC_64K_PAGES -#define pgd_populate(MM, PGD, PUD) pgd_set(PGD, (unsigned long)PUD) +#define pgd_populate(MM, PGD, PUD) pgd_set(PGD, __pgtable_ptr_val(PUD)) static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr) { @@ -68,19 +68,19 @@ static inline void pud_free(struct mm_struct *mm, pud_t *pud) static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) { - pud_set(pud, (unsigned long)pmd); + pud_set(pud, __pgtable_ptr_val(pmd)); } static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte) { - pmd_set(pmd, (unsigned long)pte); + pmd_set(pmd, __pgtable_ptr_val(pte)); } static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, pgtable_t pte_page) { - pmd_set(pmd, (unsigned long)page_address(pte_page)); + pmd_set(pmd, __pgtable_ptr_val(page_address(pte_page))); } #define pmd_pgtable(pmd) pmd_page(pmd) @@ -171,23 +171,45 @@ extern void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int shift); extern void __tlb_remove_table(void *_table); #endif -#define pud_populate(mm, pud, pmd) pud_set(pud, (unsigned long)pmd) +#ifndef __PAGETABLE_PUD_FOLDED +/* book3s 64 is 4 level page table */ +static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud) +{ + pgd_set(pgd, __pgtable_ptr_val(pud)); +} + +static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr) +{ + return kmem_cache_alloc(PGT_CACHE(PUD_INDEX_SIZE), + GFP_KERNEL|__GFP_REPEAT); +} + +static inline void pud_free(struct mm_struct *mm, pud_t *pud) +{ + kmem_cache_free(PGT_CACHE(PUD_INDEX_SIZE), pud); +} +#endif + +static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) +{ + pud_set(pud, __pgtable_ptr_val(pmd)); +} static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte) { - pmd_set(pmd, (unsigned long)pte); + pmd_set(pmd, __pgtable_ptr_val(pte)); } static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, pgtable_t pte_page) { - pmd_set(pmd, (unsigned long)pte_page); + pmd_set(pmd, __pgtable_ptr_val(pte_page)); } static inline pgtable_t pmd_pgtable(pmd_t pmd) { - return (pgtable_t)(pmd_val(pmd) & ~PMD_MASKED_BITS); + return (pgtable_t)pmd_page_vaddr(pmd); } static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, @@ -233,11 +255,11 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) #define __pmd_free_tlb(tlb, pmd, addr) \ pgtable_free_tlb(tlb, pmd, PMD_CACHE_INDEX) -#ifndef CONFIG_PPC_64K_PAGES +#ifndef __PAGETABLE_PUD_FOLDED #define __pud_free_tlb(tlb, pud, addr) \ pgtable_free_tlb(tlb, pud, PUD_INDEX_SIZE) -#endif /* CONFIG_PPC_64K_PAGES */ +#endif /* __PAGETABLE_PUD_FOLDED */ #define check_pgt_cache() do { } while (0) diff --git a/arch/powerpc/include/asm/pgtable-types.h b/arch/powerpc/include/asm/pgtable-types.h new file mode 100644 index 0000000000000000000000000000000000000000..43140f8b059236946a49b0f15635ddd6e8a3c235 --- /dev/null +++ b/arch/powerpc/include/asm/pgtable-types.h @@ -0,0 +1,103 @@ +#ifndef _ASM_POWERPC_PGTABLE_TYPES_H +#define _ASM_POWERPC_PGTABLE_TYPES_H + +#ifdef CONFIG_STRICT_MM_TYPECHECKS +/* These are used to make use of C type-checking. */ + +/* PTE level */ +typedef struct { pte_basic_t pte; } pte_t; +#define __pte(x) ((pte_t) { (x) }) +static inline pte_basic_t pte_val(pte_t x) +{ + return x.pte; +} + +/* PMD level */ +#ifdef CONFIG_PPC64 +typedef struct { unsigned long pmd; } pmd_t; +#define __pmd(x) ((pmd_t) { (x) }) +static inline unsigned long pmd_val(pmd_t x) +{ + return x.pmd; +} + +/* + * 64 bit hash always use 4 level table. Everybody else use 4 level + * only for 4K page size. + */ +#if defined(CONFIG_PPC_BOOK3S_64) || !defined(CONFIG_PPC_64K_PAGES) +typedef struct { unsigned long pud; } pud_t; +#define __pud(x) ((pud_t) { (x) }) +static inline unsigned long pud_val(pud_t x) +{ + return x.pud; +} +#endif /* CONFIG_PPC_BOOK3S_64 || !CONFIG_PPC_64K_PAGES */ +#endif /* CONFIG_PPC64 */ + +/* PGD level */ +typedef struct { unsigned long pgd; } pgd_t; +#define __pgd(x) ((pgd_t) { (x) }) +static inline unsigned long pgd_val(pgd_t x) +{ + return x.pgd; +} + +/* Page protection bits */ +typedef struct { unsigned long pgprot; } pgprot_t; +#define pgprot_val(x) ((x).pgprot) +#define __pgprot(x) ((pgprot_t) { (x) }) + +#else + +/* + * .. while these make it easier on the compiler + */ + +typedef pte_basic_t pte_t; +#define __pte(x) (x) +static inline pte_basic_t pte_val(pte_t pte) +{ + return pte; +} + +#ifdef CONFIG_PPC64 +typedef unsigned long pmd_t; +#define __pmd(x) (x) +static inline unsigned long pmd_val(pmd_t pmd) +{ + return pmd; +} + +#if defined(CONFIG_PPC_BOOK3S_64) || !defined(CONFIG_PPC_64K_PAGES) +typedef unsigned long pud_t; +#define __pud(x) (x) +static inline unsigned long pud_val(pud_t pud) +{ + return pud; +} +#endif /* CONFIG_PPC_BOOK3S_64 || !CONFIG_PPC_64K_PAGES */ +#endif /* CONFIG_PPC64 */ + +typedef unsigned long pgd_t; +#define __pgd(x) (x) +static inline unsigned long pgd_val(pgd_t pgd) +{ + return pgd; +} + +typedef unsigned long pgprot_t; +#define pgprot_val(x) (x) +#define __pgprot(x) (x) + +#endif /* CONFIG_STRICT_MM_TYPECHECKS */ +/* + * With hash config 64k pages additionally define a bigger "real PTE" type that + * gathers the "second half" part of the PTE for pseudo 64k pages + */ +#if defined(CONFIG_PPC_64K_PAGES) && defined(CONFIG_PPC_STD_MMU_64) +typedef struct { pte_t pte; unsigned long hidx; } real_pte_t; +#else +typedef struct { pte_t pte; } real_pte_t; +#endif +#endif /* _ASM_POWERPC_PGTABLE_TYPES_H */ diff --git a/arch/powerpc/include/asm/pmac_feature.h b/arch/powerpc/include/asm/pmac_feature.h index 10902c9375d09b9bf25454db1baf8c9c2c9f55a9..92569796894691eb946aa68b52d8e8f67112f823 100644 --- a/arch/powerpc/include/asm/pmac_feature.h +++ b/arch/powerpc/include/asm/pmac_feature.h @@ -46,7 +46,7 @@ /* PowerSurge are the first generation of PCI Pmacs. This include * all of the Grand-Central based machines. We currently don't - * differenciate most of them. + * differentiate most of them. */ #define PMAC_TYPE_PSURGE 0x10 /* PowerSurge */ #define PMAC_TYPE_ANS 0x11 /* Apple Network Server */ diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index ac2330820b9ae2de3c8fedfe4ffc47987f6ed992..009fab130cd8507ad6c571ae8843066aea462319 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -236,7 +236,9 @@ struct thread_struct { #endif struct arch_hw_breakpoint hw_brk; /* info on the hardware breakpoint */ unsigned long trap_nr; /* last trap # on this thread */ + u8 load_fp; #ifdef CONFIG_ALTIVEC + u8 load_vec; struct thread_vr_state vr_state; struct thread_vr_state *vr_save_area; unsigned long vrsave; @@ -244,7 +246,7 @@ struct thread_struct { #endif /* CONFIG_ALTIVEC */ #ifdef CONFIG_VSX /* VSR status */ - int used_vsr; /* set if process has used altivec */ + int used_vsr; /* set if process has used VSX */ #endif /* CONFIG_VSX */ #ifdef CONFIG_SPE unsigned long evr[32]; /* upper 32-bits of SPE regs */ diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index c4cb2ffc624ea5b442aec8c83c86e3a1710d9411..f5f4c66bbbc91331cb82fc731f353eb01bb0a02f 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -75,6 +75,14 @@ #define MSR_HV 0 #endif +/* + * To be used in shared book E/book S, this avoids needing to worry about + * book S/book E in shared code + */ +#ifndef MSR_SPE +#define MSR_SPE 0 +#endif + #define MSR_VEC __MASK(MSR_VEC_LG) /* Enable AltiVec */ #define MSR_VSX __MASK(MSR_VSX_LG) /* Enable VSX */ #define MSR_POW __MASK(MSR_POW_LG) /* Enable Power Management */ @@ -376,7 +384,7 @@ #define SPRN_TSCR 0x399 /* Thread Switch Control Register */ #define SPRN_DEC 0x016 /* Decrement Register */ -#define SPRN_DER 0x095 /* Debug Enable Regsiter */ +#define SPRN_DER 0x095 /* Debug Enable Register */ #define DER_RSTE 0x40000000 /* Reset Interrupt */ #define DER_CHSTPE 0x20000000 /* Check Stop */ #define DER_MCIE 0x10000000 /* Machine Check Interrupt */ @@ -401,7 +409,7 @@ #define SPRN_DPDES 0x0B0 /* Directed Priv. Doorbell Exc. State */ #define SPRN_EAR 0x11A /* External Address Register */ #define SPRN_HASH1 0x3D2 /* Primary Hash Address Register */ -#define SPRN_HASH2 0x3D3 /* Secondary Hash Address Resgister */ +#define SPRN_HASH2 0x3D3 /* Secondary Hash Address Register */ #define SPRN_HID0 0x3F0 /* Hardware Implementation Register 0 */ #define HID0_HDICE_SH (63 - 23) /* 970 HDEC interrupt enable */ #define HID0_EMCP (1<<31) /* Enable Machine Check pin */ @@ -514,7 +522,7 @@ #define ICTRL_EICP 0x00000100 /* enable icache par. check */ #define SPRN_IMISS 0x3D4 /* Instruction TLB Miss Register */ #define SPRN_IMMR 0x27E /* Internal Memory Map Register */ -#define SPRN_L2CR 0x3F9 /* Level 2 Cache Control Regsiter */ +#define SPRN_L2CR 0x3F9 /* Level 2 Cache Control Register */ #define SPRN_L2CR2 0x3f8 #define L2CR_L2E 0x80000000 /* L2 enable */ #define L2CR_L2PE 0x40000000 /* L2 parity enable */ @@ -549,7 +557,7 @@ #define L2CR_L2DO_745x 0x00010000 /* L2 data only (745x) */ #define L2CR_L2REP_745x 0x00001000 /* L2 repl. algorithm (745x) */ #define L2CR_L2HWF_745x 0x00000800 /* L2 hardware flush (745x) */ -#define SPRN_L3CR 0x3FA /* Level 3 Cache Control Regsiter */ +#define SPRN_L3CR 0x3FA /* Level 3 Cache Control Register */ #define L3CR_L3E 0x80000000 /* L3 enable */ #define L3CR_L3PE 0x40000000 /* L3 data parity enable */ #define L3CR_L3APE 0x20000000 /* L3 addr parity enable */ @@ -1211,9 +1219,11 @@ static inline void mtmsr_isync(unsigned long val) #define mfspr(rn) ({unsigned long rval; \ asm volatile("mfspr %0," __stringify(rn) \ : "=r" (rval)); rval;}) +#ifndef mtspr #define mtspr(rn, v) asm volatile("mtspr " __stringify(rn) ",%0" : \ : "r" ((unsigned long)(v)) \ : "memory") +#endif extern void msr_check_and_set(unsigned long bits); extern bool strict_msr_control; diff --git a/arch/powerpc/include/asm/reg_8xx.h b/arch/powerpc/include/asm/reg_8xx.h index e8ea346b21d38af5b5d327e00f8b28ac9baf22ba..94d01f81e66877646faba091187ae981bfa0a457 100644 --- a/arch/powerpc/include/asm/reg_8xx.h +++ b/arch/powerpc/include/asm/reg_8xx.h @@ -4,6 +4,8 @@ #ifndef _ASM_POWERPC_REG_8xx_H #define _ASM_POWERPC_REG_8xx_H +#include + /* Cache control on the MPC8xx is provided through some additional * special purpose registers. */ @@ -14,6 +16,15 @@ #define SPRN_DC_ADR 569 /* Address needed for some commands */ #define SPRN_DC_DAT 570 /* Read-only data register */ +/* Misc Debug */ +#define SPRN_DPDR 630 +#define SPRN_MI_CAM 816 +#define SPRN_MI_RAM0 817 +#define SPRN_MI_RAM1 818 +#define SPRN_MD_CAM 824 +#define SPRN_MD_RAM0 825 +#define SPRN_MD_RAM1 826 + /* Commands. Only the first few are available to the instruction cache. */ #define IDC_ENABLE 0x02000000 /* Cache enable */ @@ -39,4 +50,86 @@ #define DC_DFWT 0x40000000 /* Data cache is forced write through */ #define DC_LES 0x20000000 /* Caches are little endian mode */ +#ifdef CONFIG_8xx_CPU6 +#define do_mtspr_cpu6(rn, rn_addr, v) \ + do { \ + int _reg_cpu6 = rn_addr, _tmp_cpu6; \ + asm volatile("stw %0, %1;" \ + "lwz %0, %1;" \ + "mtspr " __stringify(rn) ",%2" : \ + : "r" (_reg_cpu6), "m"(_tmp_cpu6), \ + "r" ((unsigned long)(v)) \ + : "memory"); \ + } while (0) + +#define do_mtspr(rn, v) asm volatile("mtspr " __stringify(rn) ",%0" : \ + : "r" ((unsigned long)(v)) \ + : "memory") +#define mtspr(rn, v) \ + do { \ + if (rn == SPRN_IMMR) \ + do_mtspr_cpu6(rn, 0x3d30, v); \ + else if (rn == SPRN_IC_CST) \ + do_mtspr_cpu6(rn, 0x2110, v); \ + else if (rn == SPRN_IC_ADR) \ + do_mtspr_cpu6(rn, 0x2310, v); \ + else if (rn == SPRN_IC_DAT) \ + do_mtspr_cpu6(rn, 0x2510, v); \ + else if (rn == SPRN_DC_CST) \ + do_mtspr_cpu6(rn, 0x3110, v); \ + else if (rn == SPRN_DC_ADR) \ + do_mtspr_cpu6(rn, 0x3310, v); \ + else if (rn == SPRN_DC_DAT) \ + do_mtspr_cpu6(rn, 0x3510, v); \ + else if (rn == SPRN_MI_CTR) \ + do_mtspr_cpu6(rn, 0x2180, v); \ + else if (rn == SPRN_MI_AP) \ + do_mtspr_cpu6(rn, 0x2580, v); \ + else if (rn == SPRN_MI_EPN) \ + do_mtspr_cpu6(rn, 0x2780, v); \ + else if (rn == SPRN_MI_TWC) \ + do_mtspr_cpu6(rn, 0x2b80, v); \ + else if (rn == SPRN_MI_RPN) \ + do_mtspr_cpu6(rn, 0x2d80, v); \ + else if (rn == SPRN_MI_CAM) \ + do_mtspr_cpu6(rn, 0x2190, v); \ + else if (rn == SPRN_MI_RAM0) \ + do_mtspr_cpu6(rn, 0x2390, v); \ + else if (rn == SPRN_MI_RAM1) \ + do_mtspr_cpu6(rn, 0x2590, v); \ + else if (rn == SPRN_MD_CTR) \ + do_mtspr_cpu6(rn, 0x3180, v); \ + else if (rn == SPRN_M_CASID) \ + do_mtspr_cpu6(rn, 0x3380, v); \ + else if (rn == SPRN_MD_AP) \ + do_mtspr_cpu6(rn, 0x3580, v); \ + else if (rn == SPRN_MD_EPN) \ + do_mtspr_cpu6(rn, 0x3780, v); \ + else if (rn == SPRN_M_TWB) \ + do_mtspr_cpu6(rn, 0x3980, v); \ + else if (rn == SPRN_MD_TWC) \ + do_mtspr_cpu6(rn, 0x3b80, v); \ + else if (rn == SPRN_MD_RPN) \ + do_mtspr_cpu6(rn, 0x3d80, v); \ + else if (rn == SPRN_M_TW) \ + do_mtspr_cpu6(rn, 0x3f80, v); \ + else if (rn == SPRN_MD_CAM) \ + do_mtspr_cpu6(rn, 0x3190, v); \ + else if (rn == SPRN_MD_RAM0) \ + do_mtspr_cpu6(rn, 0x3390, v); \ + else if (rn == SPRN_MD_RAM1) \ + do_mtspr_cpu6(rn, 0x3590, v); \ + else if (rn == SPRN_DEC) \ + do_mtspr_cpu6(rn, 0x2c00, v); \ + else if (rn == SPRN_TBWL) \ + do_mtspr_cpu6(rn, 0x3880, v); \ + else if (rn == SPRN_TBWU) \ + do_mtspr_cpu6(rn, 0x3a80, v); \ + else if (rn == SPRN_DPDR) \ + do_mtspr_cpu6(rn, 0x2d30, v); \ + else \ + do_mtspr(rn, v); \ + } while (0) +#endif + #endif /* _ASM_POWERPC_REG_8xx_H */ diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h index 2fef74b474f0a239b0c4aa29607dde1cbc93f64b..737e012ef56e124807d885f05dc6bc0d0a54cd9f 100644 --- a/arch/powerpc/include/asm/reg_booke.h +++ b/arch/powerpc/include/asm/reg_booke.h @@ -681,7 +681,7 @@ #define SPRN_CDBCR 0x3D7 /* Cache Debug Control Register */ #define SPRN_TBHI 0x3DC /* Time Base High */ #define SPRN_TBLO 0x3DD /* Time Base Low */ -#define SPRN_DBCR 0x3F2 /* Debug Control Regsiter */ +#define SPRN_DBCR 0x3F2 /* Debug Control Register */ #define SPRN_PBL1 0x3FC /* Protection Bound Lower 1 */ #define SPRN_PBL2 0x3FE /* Protection Bound Lower 2 */ #define SPRN_PBU1 0x3FD /* Protection Bound Upper 1 */ diff --git a/arch/powerpc/include/asm/sections.h b/arch/powerpc/include/asm/sections.h index a5e930aca804341a21cd90a0c8f2b4367de18e3f..abf5866e08c644e6054c1b8148531d41c0c340bb 100644 --- a/arch/powerpc/include/asm/sections.h +++ b/arch/powerpc/include/asm/sections.h @@ -22,6 +22,18 @@ static inline int in_kernel_text(unsigned long addr) return 0; } +static inline unsigned long kernel_toc_addr(void) +{ + /* Defined by the linker, see vmlinux.lds.S */ + extern unsigned long __toc_start; + + /* + * The TOC register (r2) points 32kB into the TOC, so that 64kB of + * the TOC can be addressed using a single machine instruction. + */ + return (unsigned long)(&__toc_start) + 0x8000UL; +} + static inline int overlaps_interrupt_vector_text(unsigned long start, unsigned long end) { diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h index 78083ed20792f63844ad82941168c1f9d005f1b5..e1afd4c4f695f37037dfe3eac8c3730a87dfbc9d 100644 --- a/arch/powerpc/include/asm/smp.h +++ b/arch/powerpc/include/asm/smp.h @@ -67,6 +67,9 @@ void generic_cpu_die(unsigned int cpu); void generic_set_cpu_dead(unsigned int cpu); void generic_set_cpu_up(unsigned int cpu); int generic_check_cpu_restart(unsigned int cpu); +int is_cpu_dead(unsigned int cpu); +#else +#define generic_set_cpu_up(i) do { } while (0) #endif #ifdef CONFIG_PPC64 @@ -201,6 +204,7 @@ extern void generic_secondary_thread_init(void); extern unsigned long __secondary_hold_spinloop; extern unsigned long __secondary_hold_acknowledge; extern char __secondary_hold; +extern unsigned int booting_thread_hwid; extern void __early_start(void); #endif /* __ASSEMBLY__ */ diff --git a/arch/powerpc/include/asm/smu.h b/arch/powerpc/include/asm/smu.h index 37d2da6feabf7208bc659512e88214cd943d4b32..f280dd11243fe3324007258e8a923317329864fe 100644 --- a/arch/powerpc/include/asm/smu.h +++ b/arch/powerpc/include/asm/smu.h @@ -154,7 +154,7 @@ * * The Darwin I2C driver is less subtle though. On any non-success status * from the response command, it waits 5ms and tries again up to 20 times, - * it doesn't differenciate between fatal errors or "busy" status. + * it doesn't differentiate between fatal errors or "busy" status. * * This driver provides an asynchronous paramblock based i2c command * interface to be used either directly by low level code or by a higher diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h index 5b268b6be74c791cadfa2ea8575e298104bd529a..17c8380673a60637c61fec5772162bf0ae5523cb 100644 --- a/arch/powerpc/include/asm/switch_to.h +++ b/arch/powerpc/include/asm/switch_to.h @@ -28,12 +28,14 @@ extern void giveup_all(struct task_struct *); extern void enable_kernel_fp(void); extern void flush_fp_to_thread(struct task_struct *); extern void giveup_fpu(struct task_struct *); -extern void __giveup_fpu(struct task_struct *); +extern void save_fpu(struct task_struct *); static inline void disable_kernel_fp(void) { msr_check_and_clear(MSR_FP); } #else +static inline void __giveup_fpu(struct task_struct *t) { } +static inline void save_fpu(struct task_struct *t) { } static inline void flush_fp_to_thread(struct task_struct *t) { } #endif @@ -41,18 +43,19 @@ static inline void flush_fp_to_thread(struct task_struct *t) { } extern void enable_kernel_altivec(void); extern void flush_altivec_to_thread(struct task_struct *); extern void giveup_altivec(struct task_struct *); -extern void __giveup_altivec(struct task_struct *); +extern void save_altivec(struct task_struct *); static inline void disable_kernel_altivec(void) { msr_check_and_clear(MSR_VEC); } +#else +static inline void save_altivec(struct task_struct *t) { } +static inline void __giveup_altivec(struct task_struct *t) { } #endif #ifdef CONFIG_VSX extern void enable_kernel_vsx(void); extern void flush_vsx_to_thread(struct task_struct *); -extern void giveup_vsx(struct task_struct *); -extern void __giveup_vsx(struct task_struct *); static inline void disable_kernel_vsx(void) { msr_check_and_clear(MSR_FP|MSR_VEC|MSR_VSX); @@ -68,6 +71,8 @@ static inline void disable_kernel_spe(void) { msr_check_and_clear(MSR_SPE); } +#else +static inline void __giveup_spe(struct task_struct *t) { } #endif static inline void clear_task_ebb(struct task_struct *t) diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h index 2d7109a8d2961f440193e47ecc2602a5729e018e..1092fdd7e73728f88c38193800f19b5ae06a1679 100644 --- a/arch/powerpc/include/asm/time.h +++ b/arch/powerpc/include/asm/time.h @@ -31,8 +31,6 @@ extern void tick_broadcast_ipi_handler(void); extern void generic_calibrate_decr(void); -extern void set_dec_cpu6(unsigned int val); - /* Some sane defaults: 125 MHz timebase, 1GHz processor */ extern unsigned long ppc_proc_freq; #define DEFAULT_PROC_FREQ (DEFAULT_TB_FREQ * 8) @@ -166,14 +164,12 @@ static inline void set_dec(int val) { #if defined(CONFIG_40x) mtspr(SPRN_PIT, val); -#elif defined(CONFIG_8xx_CPU6) - set_dec_cpu6(val - 1); #else #ifndef CONFIG_BOOKE --val; #endif mtspr(SPRN_DEC, val); -#endif /* not 40x or 8xx_CPU6 */ +#endif /* not 40x */ } static inline unsigned long tb_ticks_since(unsigned long tstamp) diff --git a/arch/powerpc/include/asm/tlbflush.h b/arch/powerpc/include/asm/tlbflush.h index 23d351ca0303492f699f5e630668339a6b28effb..9f77f85e3e99be60ff514ee21c3708c857c3dda0 100644 --- a/arch/powerpc/include/asm/tlbflush.h +++ b/arch/powerpc/include/asm/tlbflush.h @@ -78,97 +78,7 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm) } #elif defined(CONFIG_PPC_STD_MMU_64) - -#define MMU_NO_CONTEXT 0 - -/* - * TLB flushing for 64-bit hash-MMU CPUs - */ - -#include -#include - -#define PPC64_TLB_BATCH_NR 192 - -struct ppc64_tlb_batch { - int active; - unsigned long index; - struct mm_struct *mm; - real_pte_t pte[PPC64_TLB_BATCH_NR]; - unsigned long vpn[PPC64_TLB_BATCH_NR]; - unsigned int psize; - int ssize; -}; -DECLARE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch); - -extern void __flush_tlb_pending(struct ppc64_tlb_batch *batch); - -#define __HAVE_ARCH_ENTER_LAZY_MMU_MODE - -static inline void arch_enter_lazy_mmu_mode(void) -{ - struct ppc64_tlb_batch *batch = this_cpu_ptr(&ppc64_tlb_batch); - - batch->active = 1; -} - -static inline void arch_leave_lazy_mmu_mode(void) -{ - struct ppc64_tlb_batch *batch = this_cpu_ptr(&ppc64_tlb_batch); - - if (batch->index) - __flush_tlb_pending(batch); - batch->active = 0; -} - -#define arch_flush_lazy_mmu_mode() do {} while (0) - - -extern void flush_hash_page(unsigned long vpn, real_pte_t pte, int psize, - int ssize, unsigned long flags); -extern void flush_hash_range(unsigned long number, int local); -extern void flush_hash_hugepage(unsigned long vsid, unsigned long addr, - pmd_t *pmdp, unsigned int psize, int ssize, - unsigned long flags); - -static inline void local_flush_tlb_mm(struct mm_struct *mm) -{ -} - -static inline void flush_tlb_mm(struct mm_struct *mm) -{ -} - -static inline void local_flush_tlb_page(struct vm_area_struct *vma, - unsigned long vmaddr) -{ -} - -static inline void flush_tlb_page(struct vm_area_struct *vma, - unsigned long vmaddr) -{ -} - -static inline void flush_tlb_page_nohash(struct vm_area_struct *vma, - unsigned long vmaddr) -{ -} - -static inline void flush_tlb_range(struct vm_area_struct *vma, - unsigned long start, unsigned long end) -{ -} - -static inline void flush_tlb_kernel_range(unsigned long start, - unsigned long end) -{ -} - -/* Private function for use by PCI IO mapping code */ -extern void __flush_hash_table_range(struct mm_struct *mm, unsigned long start, - unsigned long end); -extern void flush_tlb_pmd_range(struct mm_struct *mm, pmd_t *pmd, - unsigned long addr); +#include #else #error Unsupported MMU type #endif diff --git a/arch/powerpc/include/asm/uninorth.h b/arch/powerpc/include/asm/uninorth.h index d12b11d7641e662286d3ef1d2a3e306a352388b0..a1d112979fd2880c2b6b8e80e0b738d1f2c36250 100644 --- a/arch/powerpc/include/asm/uninorth.h +++ b/arch/powerpc/include/asm/uninorth.h @@ -132,7 +132,7 @@ /* This one _might_ return the CPU number of the CPU reading it; * the bootROM decides whether to boot or to sleep/spinloop depending - * on this register beeing 0 or not + * on this register being 0 or not */ #define UNI_N_CPU_NUMBER 0x0050 diff --git a/arch/powerpc/include/asm/xics.h b/arch/powerpc/include/asm/xics.h index 254604856e69e1cb1ced217b4191b21b664834ba..04ef3ae511da85104ba01570deb9050c5f2f4dd0 100644 --- a/arch/powerpc/include/asm/xics.h +++ b/arch/powerpc/include/asm/xics.h @@ -1,5 +1,5 @@ /* - * Common definitions accross all variants of ICP and ICS interrupt + * Common definitions across all variants of ICP and ICS interrupt * controllers. */ diff --git a/arch/powerpc/include/uapi/asm/epapr_hcalls.h b/arch/powerpc/include/uapi/asm/epapr_hcalls.h index 7f9c74b46704eecc67658c97d62ef85c5e006d78..b4504f3944278cc408b8e8cf0591ee67fc541716 100644 --- a/arch/powerpc/include/uapi/asm/epapr_hcalls.h +++ b/arch/powerpc/include/uapi/asm/epapr_hcalls.h @@ -78,7 +78,7 @@ #define EV_SUCCESS 0 #define EV_EPERM 1 /* Operation not permitted */ #define EV_ENOENT 2 /* Entry Not Found */ -#define EV_EIO 3 /* I/O error occured */ +#define EV_EIO 3 /* I/O error occurred */ #define EV_EAGAIN 4 /* The operation had insufficient * resources to complete and should be * retried @@ -89,7 +89,7 @@ #define EV_ENODEV 7 /* No such device */ #define EV_EINVAL 8 /* An argument supplied to the hcall was out of range or invalid */ -#define EV_INTERNAL 9 /* An internal error occured */ +#define EV_INTERNAL 9 /* An internal error occurred */ #define EV_CONFIG 10 /* A configuration error was detected */ #define EV_INVALID_STATE 11 /* The object is in an invalid state */ #define EV_UNIMPLEMENTED 12 /* Unimplemented hypercall */ diff --git a/arch/powerpc/include/uapi/asm/socket.h b/arch/powerpc/include/uapi/asm/socket.h index dd54f28ecdeca2cf82bdddb2c8e2570862d3b46e..1672e3398270bf50a740895c6ad534689eb84cf5 100644 --- a/arch/powerpc/include/uapi/asm/socket.h +++ b/arch/powerpc/include/uapi/asm/socket.h @@ -95,4 +95,6 @@ #define SO_ATTACH_REUSEPORT_CBPF 51 #define SO_ATTACH_REUSEPORT_EBPF 52 +#define SO_CNX_ADVICE 53 + #endif /* _ASM_POWERPC_SOCKET_H */ diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 794f22adf99d4819c15de9f1ecc316eaafb491c0..2da380fcc34c699c34851696cae2899a18d9c8bd 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -16,14 +16,14 @@ endif ifdef CONFIG_FUNCTION_TRACER # Do not trace early boot code -CFLAGS_REMOVE_cputable.o = -pg -mno-sched-epilog -CFLAGS_REMOVE_prom_init.o = -pg -mno-sched-epilog -CFLAGS_REMOVE_btext.o = -pg -mno-sched-epilog -CFLAGS_REMOVE_prom.o = -pg -mno-sched-epilog +CFLAGS_REMOVE_cputable.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) +CFLAGS_REMOVE_prom_init.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) +CFLAGS_REMOVE_btext.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) +CFLAGS_REMOVE_prom.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) # do not trace tracer code -CFLAGS_REMOVE_ftrace.o = -pg -mno-sched-epilog +CFLAGS_REMOVE_ftrace.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) # timers used by tracing -CFLAGS_REMOVE_time.o = -pg -mno-sched-epilog +CFLAGS_REMOVE_time.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) endif obj-y := cputable.o ptrace.o syscalls.o \ diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 07cebc3514f34337b734153b02f836e28c402d4f..0d0183d3180a434beb5b4772bb0469e370f17940 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -95,12 +95,14 @@ int main(void) DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fp_state)); DEFINE(THREAD_FPSAVEAREA, offsetof(struct thread_struct, fp_save_area)); DEFINE(FPSTATE_FPSCR, offsetof(struct thread_fp_state, fpscr)); + DEFINE(THREAD_LOAD_FP, offsetof(struct thread_struct, load_fp)); #ifdef CONFIG_ALTIVEC DEFINE(THREAD_VRSTATE, offsetof(struct thread_struct, vr_state)); DEFINE(THREAD_VRSAVEAREA, offsetof(struct thread_struct, vr_save_area)); DEFINE(THREAD_VRSAVE, offsetof(struct thread_struct, vrsave)); DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr)); DEFINE(VRSTATE_VSCR, offsetof(struct thread_vr_state, vscr)); + DEFINE(THREAD_LOAD_VEC, offsetof(struct thread_struct, load_vec)); #endif /* CONFIG_ALTIVEC */ #ifdef CONFIG_VSX DEFINE(THREAD_USED_VSR, offsetof(struct thread_struct, used_vsr)); @@ -374,6 +376,7 @@ int main(void) DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features)); DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup)); DEFINE(CPU_SPEC_RESTORE, offsetof(struct cpu_spec, cpu_restore)); + DEFINE(CPU_DOWN_FLUSH, offsetof(struct cpu_spec, cpu_down_flush)); DEFINE(pbe_address, offsetof(struct pbe, address)); DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address)); diff --git a/arch/powerpc/kernel/cpu_setup_fsl_booke.S b/arch/powerpc/kernel/cpu_setup_fsl_booke.S index dddba3e942606e138a467c3de8bd3841d482cb30..462aed9bcf512fa38856aad905ba9003b2b6c8f5 100644 --- a/arch/powerpc/kernel/cpu_setup_fsl_booke.S +++ b/arch/powerpc/kernel/cpu_setup_fsl_booke.S @@ -13,11 +13,13 @@ * */ +#include #include #include #include #include #include +#include _GLOBAL(__e500_icache_setup) mfspr r0, SPRN_L1CSR1 @@ -233,3 +235,113 @@ _GLOBAL(__setup_cpu_e5500) mtlr r5 blr #endif + +/* flush L1 date cache, it can apply to e500v2, e500mc and e5500 */ +_GLOBAL(flush_dcache_L1) + mfmsr r10 + wrteei 0 + + mfspr r3,SPRN_L1CFG0 + rlwinm r5,r3,9,3 /* Extract cache block size */ + twlgti r5,1 /* Only 32 and 64 byte cache blocks + * are currently defined. + */ + li r4,32 + subfic r6,r5,2 /* r6 = log2(1KiB / cache block size) - + * log2(number of ways) + */ + slw r5,r4,r5 /* r5 = cache block size */ + + rlwinm r7,r3,0,0xff /* Extract number of KiB in the cache */ + mulli r7,r7,13 /* An 8-way cache will require 13 + * loads per set. + */ + slw r7,r7,r6 + + /* save off HID0 and set DCFA */ + mfspr r8,SPRN_HID0 + ori r9,r8,HID0_DCFA@l + mtspr SPRN_HID0,r9 + isync + + LOAD_REG_IMMEDIATE(r6, KERNELBASE) + mr r4, r6 + mtctr r7 + +1: lwz r3,0(r4) /* Load... */ + add r4,r4,r5 + bdnz 1b + + msync + mr r4, r6 + mtctr r7 + +1: dcbf 0,r4 /* ...and flush. */ + add r4,r4,r5 + bdnz 1b + + /* restore HID0 */ + mtspr SPRN_HID0,r8 + isync + + wrtee r10 + + blr + +has_L2_cache: + /* skip L2 cache on P2040/P2040E as they have no L2 cache */ + mfspr r3, SPRN_SVR + /* shift right by 8 bits and clear E bit of SVR */ + rlwinm r4, r3, 24, ~0x800 + + lis r3, SVR_P2040@h + ori r3, r3, SVR_P2040@l + cmpw r4, r3 + beq 1f + + li r3, 1 + blr +1: + li r3, 0 + blr + +/* flush backside L2 cache */ +flush_backside_L2_cache: + mflr r10 + bl has_L2_cache + mtlr r10 + cmpwi r3, 0 + beq 2f + + /* Flush the L2 cache */ + mfspr r3, SPRN_L2CSR0 + ori r3, r3, L2CSR0_L2FL@l + msync + isync + mtspr SPRN_L2CSR0,r3 + isync + + /* check if it is complete */ +1: mfspr r3,SPRN_L2CSR0 + andi. r3, r3, L2CSR0_L2FL@l + bne 1b +2: + blr + +_GLOBAL(cpu_down_flush_e500v2) + mflr r0 + bl flush_dcache_L1 + mtlr r0 + blr + +_GLOBAL(cpu_down_flush_e500mc) +_GLOBAL(cpu_down_flush_e5500) + mflr r0 + bl flush_dcache_L1 + bl flush_backside_L2_cache + mtlr r0 + blr + +/* L1 Data Cache of e6500 contains no modified data, no flush is required */ +_GLOBAL(cpu_down_flush_e6500) + blr diff --git a/arch/powerpc/kernel/cpu_setup_power.S b/arch/powerpc/kernel/cpu_setup_power.S index 9c9b7411b28bbc5c8c5c0d0b79752b605e80b116..584e119fa8b0133ed7ff1acd81ad4cac254f6dd0 100644 --- a/arch/powerpc/kernel/cpu_setup_power.S +++ b/arch/powerpc/kernel/cpu_setup_power.S @@ -15,6 +15,7 @@ #include #include #include +#include /* Entry: r3 = crap, r4 = ptr to cputable entry * @@ -83,6 +84,39 @@ _GLOBAL(__restore_cpu_power8) mtlr r11 blr +_GLOBAL(__setup_cpu_power9) + mflr r11 + bl __init_FSCR + bl __init_hvmode_206 + mtlr r11 + beqlr + li r0,0 + mtspr SPRN_LPID,r0 + mfspr r3,SPRN_LPCR + ori r3, r3, LPCR_PECEDH + bl __init_LPCR + bl __init_HFSCR + bl __init_tlb_power9 + mtlr r11 + blr + +_GLOBAL(__restore_cpu_power9) + mflr r11 + bl __init_FSCR + mfmsr r3 + rldicl. r0,r3,4,63 + mtlr r11 + beqlr + li r0,0 + mtspr SPRN_LPID,r0 + mfspr r3,SPRN_LPCR + ori r3, r3, LPCR_PECEDH + bl __init_LPCR + bl __init_HFSCR + bl __init_tlb_power9 + mtlr r11 + blr + __init_hvmode_206: /* Disable CPU_FTR_HVMODE and exit if MSR:HV is not set */ mfmsr r3 @@ -139,7 +173,7 @@ __init_HFSCR: * (invalidate by congruence class). P7 has 128 CCs., P8 has 512. */ __init_tlb_power7: - li r6,128 + li r6,POWER7_TLB_SETS mtctr r6 li r7,0xc00 /* IS field = 0b11 */ ptesync @@ -150,7 +184,18 @@ __init_tlb_power7: 1: blr __init_tlb_power8: - li r6,512 + li r6,POWER8_TLB_SETS + mtctr r6 + li r7,0xc00 /* IS field = 0b11 */ + ptesync +2: tlbiel r7 + addi r7,r7,0x1000 + bdnz 2b + ptesync +1: blr + +__init_tlb_power9: + li r6,POWER9_TLB_SETS_HASH mtctr r6 li r7,0xc00 /* IS field = 0b11 */ ptesync diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 7d80bfdfb15eef4fb4abf8390d0724b688e8f6f8..6c662b8de90d6430a15e4c7f903ccffe74727f58 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -70,9 +70,12 @@ extern void __setup_cpu_power7(unsigned long offset, struct cpu_spec* spec); extern void __restore_cpu_power7(void); extern void __setup_cpu_power8(unsigned long offset, struct cpu_spec* spec); extern void __restore_cpu_power8(void); +extern void __setup_cpu_power9(unsigned long offset, struct cpu_spec* spec); +extern void __restore_cpu_power9(void); extern void __restore_cpu_a2(void); extern void __flush_tlb_power7(unsigned int action); extern void __flush_tlb_power8(unsigned int action); +extern void __flush_tlb_power9(unsigned int action); extern long __machine_check_early_realmode_p7(struct pt_regs *regs); extern long __machine_check_early_realmode_p8(struct pt_regs *regs); #endif /* CONFIG_PPC64 */ @@ -116,6 +119,11 @@ extern void __restore_cpu_e6500(void); #define COMMON_USER_PA6T (COMMON_USER_PPC64 | PPC_FEATURE_PA6T |\ PPC_FEATURE_TRUE_LE | \ PPC_FEATURE_HAS_ALTIVEC_COMP) +#define COMMON_USER_POWER9 COMMON_USER_POWER8 +#define COMMON_USER2_POWER9 (COMMON_USER2_POWER8 | \ + PPC_FEATURE2_ARCH_3_00 | \ + PPC_FEATURE2_HAS_IEEE128) + #ifdef CONFIG_PPC_BOOK3E_64 #define COMMON_USER_BOOKE (COMMON_USER_PPC64 | PPC_FEATURE_BOOKE) #else @@ -499,6 +507,25 @@ static struct cpu_spec __initdata cpu_specs[] = { .machine_check_early = __machine_check_early_realmode_p8, .platform = "power8", }, + { /* Power9 */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x004e0000, + .cpu_name = "POWER9 (raw)", + .cpu_features = CPU_FTRS_POWER9, + .cpu_user_features = COMMON_USER_POWER9, + .cpu_user_features2 = COMMON_USER2_POWER9, + .mmu_features = MMU_FTRS_POWER9, + .icache_bsize = 128, + .dcache_bsize = 128, + .num_pmcs = 6, + .pmc_type = PPC_PMC_IBM, + .oprofile_cpu_type = "ppc64/power9", + .oprofile_type = PPC_OPROFILE_INVALID, + .cpu_setup = __setup_cpu_power9, + .cpu_restore = __restore_cpu_power9, + .flush_tlb = __flush_tlb_power9, + .platform = "power9", + }, { /* Cell Broadband Engine */ .pvr_mask = 0xffff0000, .pvr_value = 0x00700000, @@ -2023,6 +2050,7 @@ static struct cpu_spec __initdata cpu_specs[] = { .cpu_setup = __setup_cpu_e500v2, .machine_check = machine_check_e500, .platform = "ppc8548", + .cpu_down_flush = cpu_down_flush_e500v2, }, #else { /* e500mc */ @@ -2042,6 +2070,7 @@ static struct cpu_spec __initdata cpu_specs[] = { .cpu_setup = __setup_cpu_e500mc, .machine_check = machine_check_e500mc, .platform = "ppce500mc", + .cpu_down_flush = cpu_down_flush_e500mc, }, #endif /* CONFIG_PPC_E500MC */ #endif /* CONFIG_PPC32 */ @@ -2066,6 +2095,7 @@ static struct cpu_spec __initdata cpu_specs[] = { #endif .machine_check = machine_check_e500mc, .platform = "ppce5500", + .cpu_down_flush = cpu_down_flush_e5500, }, { /* e6500 */ .pvr_mask = 0xffff0000, @@ -2088,6 +2118,7 @@ static struct cpu_spec __initdata cpu_specs[] = { #endif .machine_check = machine_check_e500mc, .platform = "ppce6500", + .cpu_down_flush = cpu_down_flush_e6500, }, #endif /* CONFIG_PPC_E500MC */ #ifdef CONFIG_PPC32 diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index 40e4d4a276635c304db839c5eb88002a386d712b..6544017eb90b837f99e78681b9c149d0c3a9f74d 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c @@ -268,13 +268,6 @@ static void *eeh_dump_pe_log(void *data, void *flag) struct eeh_dev *edev, *tmp; size_t *plen = flag; - /* If the PE's config space is blocked, 0xFF's will be - * returned. It's pointless to collect the log in this - * case. - */ - if (pe->state & EEH_PE_CFG_BLOCKED) - return NULL; - eeh_pe_for_each_dev(pe, edev, tmp) *plen += eeh_dump_dev_log(edev, pci_regs_buf + *plen, EEH_PCI_REGS_LOG_LEN - *plen); @@ -677,7 +670,7 @@ int eeh_pci_enable(struct eeh_pe *pe, int function) /* Check if the request is finished successfully */ if (active_flag) { rc = eeh_ops->wait_state(pe, PCI_BUS_RESET_WAIT_MSEC); - if (rc <= 0) + if (rc < 0) return rc; if (rc & active_flag) @@ -739,7 +732,7 @@ static void *eeh_restore_dev_state(void *data, void *userdata) } /** - * pcibios_set_pcie_slot_reset - Set PCI-E reset state + * pcibios_set_pcie_reset_state - Set PCI-E reset state * @dev: pci device struct * @state: reset state to enter * @@ -761,7 +754,8 @@ int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state stat case pcie_deassert_reset: eeh_ops->reset(pe, EEH_RESET_DEACTIVATE); eeh_unfreeze_pe(pe, false); - eeh_pe_state_clear(pe, EEH_PE_CFG_BLOCKED); + if (!(pe->type & EEH_PE_VF)) + eeh_pe_state_clear(pe, EEH_PE_CFG_BLOCKED); eeh_pe_dev_traverse(pe, eeh_restore_dev_state, dev); eeh_pe_state_clear(pe, EEH_PE_ISOLATED); break; @@ -769,14 +763,16 @@ int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state stat eeh_pe_state_mark_with_cfg(pe, EEH_PE_ISOLATED); eeh_ops->set_option(pe, EEH_OPT_FREEZE_PE); eeh_pe_dev_traverse(pe, eeh_disable_and_save_dev_state, dev); - eeh_pe_state_mark(pe, EEH_PE_CFG_BLOCKED); + if (!(pe->type & EEH_PE_VF)) + eeh_pe_state_mark(pe, EEH_PE_CFG_BLOCKED); eeh_ops->reset(pe, EEH_RESET_HOT); break; case pcie_warm_reset: eeh_pe_state_mark_with_cfg(pe, EEH_PE_ISOLATED); eeh_ops->set_option(pe, EEH_OPT_FREEZE_PE); eeh_pe_dev_traverse(pe, eeh_disable_and_save_dev_state, dev); - eeh_pe_state_mark(pe, EEH_PE_CFG_BLOCKED); + if (!(pe->type & EEH_PE_VF)) + eeh_pe_state_mark(pe, EEH_PE_CFG_BLOCKED); eeh_ops->reset(pe, EEH_RESET_FUNDAMENTAL); break; default: @@ -1243,6 +1239,14 @@ void eeh_remove_device(struct pci_dev *dev) * from the parent PE during the BAR resotre. */ edev->pdev = NULL; + + /* + * The flag "in_error" is used to trace EEH devices for VFs + * in error state or not. It's set in eeh_report_error(). If + * it's not set, eeh_report_{reset,resume}() won't be called + * for the VF EEH device. + */ + edev->in_error = false; dev->dev.archdata.edev = NULL; if (!(edev->pe->state & EEH_PE_KEEP)) eeh_rmv_from_parent_pe(edev); @@ -1537,6 +1541,17 @@ int eeh_pe_get_state(struct eeh_pe *pe) if (!eeh_ops || !eeh_ops->get_state) return -ENOENT; + /* + * If the parent PE is owned by the host kernel and is undergoing + * error recovery, we should return the PE state as temporarily + * unavailable so that the error recovery on the guest is suspended + * until the recovery completes on the host. + */ + if (pe->parent && + !(pe->state & EEH_PE_REMOVED) && + (pe->parent->state & (EEH_PE_ISOLATED | EEH_PE_RECOVERING))) + return EEH_PE_STATE_UNAVAIL; + result = eeh_ops->get_state(pe, NULL); rst_active = !!(result & EEH_STATE_RESET_ACTIVE); dma_en = !!(result & EEH_STATE_DMA_ENABLED); diff --git a/arch/powerpc/kernel/eeh_cache.c b/arch/powerpc/kernel/eeh_cache.c index a1e86e172e3cca3b24cf74ecc503248ddcd5e3d2..ddbcfab7efdfbe4f03136427f517f9f0ce4d2046 100644 --- a/arch/powerpc/kernel/eeh_cache.c +++ b/arch/powerpc/kernel/eeh_cache.c @@ -195,8 +195,11 @@ static void __eeh_addr_cache_insert_dev(struct pci_dev *dev) return; } - /* Walk resources on this device, poke them into the tree */ - for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { + /* + * Walk resources on this device, poke the first 7 (6 normal BAR and 1 + * ROM BAR) into the tree. + */ + for (i = 0; i <= PCI_ROM_RESOURCE; i++) { resource_size_t start = pci_resource_start(dev,i); resource_size_t end = pci_resource_end(dev,i); unsigned long flags = pci_resource_flags(dev,i); @@ -222,10 +225,6 @@ void eeh_addr_cache_insert_dev(struct pci_dev *dev) { unsigned long flags; - /* Ignore PCI bridges */ - if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE) - return; - spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags); __eeh_addr_cache_insert_dev(dev); spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags); diff --git a/arch/powerpc/kernel/eeh_dev.c b/arch/powerpc/kernel/eeh_dev.c index aabba94ff9cbd702d9026b2b12ba8e1ba5fc2798..7815095fe3d8a0f9f82436f452e0789b33e17ba2 100644 --- a/arch/powerpc/kernel/eeh_dev.c +++ b/arch/powerpc/kernel/eeh_dev.c @@ -67,6 +67,7 @@ void *eeh_dev_init(struct pci_dn *pdn, void *data) edev->pdn = pdn; edev->phb = phb; INIT_LIST_HEAD(&edev->list); + INIT_LIST_HEAD(&edev->rmv_list); return NULL; } diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c index 650cfb31ea3d9b3cee0301948bd85e54400cb951..fb6207d2c604b4bd9b24d35c57454c080383775a 100644 --- a/arch/powerpc/kernel/eeh_driver.c +++ b/arch/powerpc/kernel/eeh_driver.c @@ -34,6 +34,11 @@ #include #include +struct eeh_rmv_data { + struct list_head edev_list; + int removed; +}; + /** * eeh_pcid_name - Retrieve name of PCI device driver * @pdev: PCI device @@ -190,7 +195,7 @@ static void *eeh_report_error(void *data, void *userdata) enum pci_ers_result rc, *res = userdata; struct pci_driver *driver; - if (!dev || eeh_dev_removed(edev)) + if (!dev || eeh_dev_removed(edev) || eeh_pe_passed(edev->pe)) return NULL; dev->error_state = pci_channel_io_frozen; @@ -211,6 +216,7 @@ static void *eeh_report_error(void *data, void *userdata) if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; if (*res == PCI_ERS_RESULT_NONE) *res = rc; + edev->in_error = true; eeh_pcid_put(dev); return NULL; } @@ -231,7 +237,7 @@ static void *eeh_report_mmio_enabled(void *data, void *userdata) enum pci_ers_result rc, *res = userdata; struct pci_driver *driver; - if (!dev || eeh_dev_removed(edev)) + if (!dev || eeh_dev_removed(edev) || eeh_pe_passed(edev->pe)) return NULL; driver = eeh_pcid_get(dev); @@ -271,7 +277,7 @@ static void *eeh_report_reset(void *data, void *userdata) enum pci_ers_result rc, *res = userdata; struct pci_driver *driver; - if (!dev || eeh_dev_removed(edev)) + if (!dev || eeh_dev_removed(edev) || eeh_pe_passed(edev->pe)) return NULL; dev->error_state = pci_channel_io_normal; @@ -282,7 +288,8 @@ static void *eeh_report_reset(void *data, void *userdata) if (!driver->err_handler || !driver->err_handler->slot_reset || - (edev->mode & EEH_DEV_NO_HANDLER)) { + (edev->mode & EEH_DEV_NO_HANDLER) || + (!edev->in_error)) { eeh_pcid_put(dev); return NULL; } @@ -326,20 +333,23 @@ static void *eeh_report_resume(void *data, void *userdata) { struct eeh_dev *edev = (struct eeh_dev *)data; struct pci_dev *dev = eeh_dev_to_pci_dev(edev); + bool was_in_error; struct pci_driver *driver; - if (!dev || eeh_dev_removed(edev)) + if (!dev || eeh_dev_removed(edev) || eeh_pe_passed(edev->pe)) return NULL; dev->error_state = pci_channel_io_normal; driver = eeh_pcid_get(dev); if (!driver) return NULL; + was_in_error = edev->in_error; + edev->in_error = false; eeh_enable_irq(dev); if (!driver->err_handler || !driver->err_handler->resume || - (edev->mode & EEH_DEV_NO_HANDLER)) { + (edev->mode & EEH_DEV_NO_HANDLER) || !was_in_error) { edev->mode &= ~EEH_DEV_NO_HANDLER; eeh_pcid_put(dev); return NULL; @@ -365,7 +375,7 @@ static void *eeh_report_failure(void *data, void *userdata) struct pci_dev *dev = eeh_dev_to_pci_dev(edev); struct pci_driver *driver; - if (!dev || eeh_dev_removed(edev)) + if (!dev || eeh_dev_removed(edev) || eeh_pe_passed(edev->pe)) return NULL; dev->error_state = pci_channel_io_perm_failure; @@ -386,12 +396,40 @@ static void *eeh_report_failure(void *data, void *userdata) return NULL; } +static void *eeh_add_virt_device(void *data, void *userdata) +{ + struct pci_driver *driver; + struct eeh_dev *edev = (struct eeh_dev *)data; + struct pci_dev *dev = eeh_dev_to_pci_dev(edev); + struct pci_dn *pdn = eeh_dev_to_pdn(edev); + + if (!(edev->physfn)) { + pr_warn("%s: EEH dev %04x:%02x:%02x.%01x not for VF\n", + __func__, edev->phb->global_number, pdn->busno, + PCI_SLOT(pdn->devfn), PCI_FUNC(pdn->devfn)); + return NULL; + } + + driver = eeh_pcid_get(dev); + if (driver) { + eeh_pcid_put(dev); + if (driver->err_handler) + return NULL; + } + +#ifdef CONFIG_PPC_POWERNV + pci_iov_add_virtfn(edev->physfn, pdn->vf_index, 0); +#endif + return NULL; +} + static void *eeh_rmv_device(void *data, void *userdata) { struct pci_driver *driver; struct eeh_dev *edev = (struct eeh_dev *)data; struct pci_dev *dev = eeh_dev_to_pci_dev(edev); - int *removed = (int *)userdata; + struct eeh_rmv_data *rmv_data = (struct eeh_rmv_data *)userdata; + int *removed = rmv_data ? &rmv_data->removed : NULL; /* * Actually, we should remove the PCI bridges as well. @@ -416,7 +454,11 @@ static void *eeh_rmv_device(void *data, void *userdata) driver = eeh_pcid_get(dev); if (driver) { eeh_pcid_put(dev); - if (driver->err_handler && + if (removed && + eeh_pe_passed(edev->pe)) + return NULL; + if (removed && + driver->err_handler && driver->err_handler->error_detected && driver->err_handler->slot_reset) return NULL; @@ -427,11 +469,29 @@ static void *eeh_rmv_device(void *data, void *userdata) pci_name(dev)); edev->bus = dev->bus; edev->mode |= EEH_DEV_DISCONNECTED; - (*removed)++; + if (removed) + (*removed)++; - pci_lock_rescan_remove(); - pci_stop_and_remove_bus_device(dev); - pci_unlock_rescan_remove(); + if (edev->physfn) { +#ifdef CONFIG_PPC_POWERNV + struct pci_dn *pdn = eeh_dev_to_pdn(edev); + + pci_iov_remove_virtfn(edev->physfn, pdn->vf_index, 0); + edev->pdev = NULL; + + /* + * We have to set the VF PE number to invalid one, which is + * required to plug the VF successfully. + */ + pdn->pe_number = IODA_INVALID_PE; +#endif + if (rmv_data) + list_add(&edev->rmv_list, &rmv_data->edev_list); + } else { + pci_lock_rescan_remove(); + pci_stop_and_remove_bus_device(dev); + pci_unlock_rescan_remove(); + } return NULL; } @@ -545,11 +605,13 @@ int eeh_pe_reset_and_recover(struct eeh_pe *pe) * During the reset, udev might be invoked because those affected * PCI devices will be removed and then added. */ -static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus) +static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus, + struct eeh_rmv_data *rmv_data) { struct pci_bus *frozen_bus = eeh_pe_bus_get(pe); struct timeval tstamp; - int cnt, rc, removed = 0; + int cnt, rc; + struct eeh_dev *edev; /* pcibios will clear the counter; save the value */ cnt = pe->freeze_count; @@ -563,12 +625,16 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus) */ eeh_pe_state_mark(pe, EEH_PE_KEEP); if (bus) { - eeh_pe_state_clear(pe, EEH_PE_PRI_BUS); - pci_lock_rescan_remove(); - pcibios_remove_pci_devices(bus); - pci_unlock_rescan_remove(); + if (pe->type & EEH_PE_VF) { + eeh_pe_dev_traverse(pe, eeh_rmv_device, NULL); + } else { + eeh_pe_state_clear(pe, EEH_PE_PRI_BUS); + pci_lock_rescan_remove(); + pcibios_remove_pci_devices(bus); + pci_unlock_rescan_remove(); + } } else if (frozen_bus) { - eeh_pe_dev_traverse(pe, eeh_rmv_device, &removed); + eeh_pe_dev_traverse(pe, eeh_rmv_device, &rmv_data); } /* @@ -610,14 +676,22 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus) * PE. We should disconnect it so the binding can be * rebuilt when adding PCI devices. */ + edev = list_first_entry(&pe->edevs, struct eeh_dev, list); eeh_pe_traverse(pe, eeh_pe_detach_dev, NULL); - pcibios_add_pci_devices(bus); - } else if (frozen_bus && removed) { + if (pe->type & EEH_PE_VF) + eeh_add_virt_device(edev, NULL); + else + pcibios_add_pci_devices(bus); + } else if (frozen_bus && rmv_data->removed) { pr_info("EEH: Sleep 5s ahead of partial hotplug\n"); ssleep(5); + edev = list_first_entry(&pe->edevs, struct eeh_dev, list); eeh_pe_traverse(pe, eeh_pe_detach_dev, NULL); - pcibios_add_pci_devices(frozen_bus); + if (pe->type & EEH_PE_VF) + eeh_add_virt_device(edev, NULL); + else + pcibios_add_pci_devices(frozen_bus); } eeh_pe_state_clear(pe, EEH_PE_KEEP); @@ -636,8 +710,10 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus) static void eeh_handle_normal_event(struct eeh_pe *pe) { struct pci_bus *frozen_bus; + struct eeh_dev *edev, *tmp; int rc = 0; enum pci_ers_result result = PCI_ERS_RESULT_NONE; + struct eeh_rmv_data rmv_data = {LIST_HEAD_INIT(rmv_data.edev_list), 0}; frozen_bus = eeh_pe_bus_get(pe); if (!frozen_bus) { @@ -692,7 +768,7 @@ static void eeh_handle_normal_event(struct eeh_pe *pe) */ if (result == PCI_ERS_RESULT_NONE) { pr_info("EEH: Reset with hotplug activity\n"); - rc = eeh_reset_device(pe, frozen_bus); + rc = eeh_reset_device(pe, frozen_bus, NULL); if (rc) { pr_warn("%s: Unable to reset, err=%d\n", __func__, rc); @@ -744,7 +820,7 @@ static void eeh_handle_normal_event(struct eeh_pe *pe) /* If any device called out for a reset, then reset the slot */ if (result == PCI_ERS_RESULT_NEED_RESET) { pr_info("EEH: Reset without hotplug activity\n"); - rc = eeh_reset_device(pe, NULL); + rc = eeh_reset_device(pe, NULL, &rmv_data); if (rc) { pr_warn("%s: Cannot reset, err=%d\n", __func__, rc); @@ -764,6 +840,15 @@ static void eeh_handle_normal_event(struct eeh_pe *pe) goto hard_fail; } + /* + * For those hot removed VFs, we should add back them after PF get + * recovered properly. + */ + list_for_each_entry_safe(edev, tmp, &rmv_data.edev_list, rmv_list) { + eeh_add_virt_device(edev, NULL); + list_del(&edev->rmv_list); + } + /* Tell all device drivers that they can resume operations */ pr_info("EEH: Notify device driver to resume\n"); eeh_pe_dev_traverse(pe, eeh_report_resume, NULL); @@ -803,12 +888,17 @@ static void eeh_handle_normal_event(struct eeh_pe *pe) * the their PCI config any more. */ if (frozen_bus) { - eeh_pe_state_clear(pe, EEH_PE_PRI_BUS); - eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED); + if (pe->type & EEH_PE_VF) { + eeh_pe_dev_traverse(pe, eeh_rmv_device, NULL); + eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED); + } else { + eeh_pe_state_clear(pe, EEH_PE_PRI_BUS); + eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED); - pci_lock_rescan_remove(); - pcibios_remove_pci_devices(frozen_bus); - pci_unlock_rescan_remove(); + pci_lock_rescan_remove(); + pcibios_remove_pci_devices(frozen_bus); + pci_unlock_rescan_remove(); + } } } diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c index 98f81800e00c1030b69c80d79eb8d43edbda9728..eea48d8baf4944ac053b0a34ba706afa6ad4b43c 100644 --- a/arch/powerpc/kernel/eeh_pe.c +++ b/arch/powerpc/kernel/eeh_pe.c @@ -299,7 +299,10 @@ static struct eeh_pe *eeh_pe_get_parent(struct eeh_dev *edev) * EEH device already having associated PE, but * the direct parent EEH device doesn't have yet. */ - pdn = pdn ? pdn->parent : NULL; + if (edev->physfn) + pdn = pci_get_pdn(edev->physfn); + else + pdn = pdn ? pdn->parent : NULL; while (pdn) { /* We're poking out of PCI territory */ parent = pdn_to_eeh_dev(pdn); @@ -382,7 +385,10 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev) } /* Create a new EEH PE */ - pe = eeh_pe_alloc(edev->phb, EEH_PE_DEVICE); + if (edev->physfn) + pe = eeh_pe_alloc(edev->phb, EEH_PE_VF); + else + pe = eeh_pe_alloc(edev->phb, EEH_PE_DEVICE); if (!pe) { pr_err("%s: out of memory!\n", __func__); return -ENOMEM; @@ -920,25 +926,21 @@ const char *eeh_pe_loc_get(struct eeh_pe *pe) */ struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe) { - struct pci_bus *bus = NULL; struct eeh_dev *edev; struct pci_dev *pdev; - if (pe->type & EEH_PE_PHB) { - bus = pe->phb->bus; - } else if (pe->type & EEH_PE_BUS || - pe->type & EEH_PE_DEVICE) { - if (pe->state & EEH_PE_PRI_BUS) { - bus = pe->bus; - goto out; - } + if (pe->type & EEH_PE_PHB) + return pe->phb->bus; - edev = list_first_entry(&pe->edevs, struct eeh_dev, list); - pdev = eeh_dev_to_pci_dev(edev); - if (pdev) - bus = pdev->bus; - } + /* The primary bus might be cached during probe time */ + if (pe->state & EEH_PE_PRI_BUS) + return pe->bus; -out: - return bus; + /* Retrieve the parent PCI bus of first (top) PCI device */ + edev = list_first_entry_or_null(&pe->edevs, struct eeh_dev, list); + pdev = eeh_dev_to_pci_dev(edev); + if (pdev) + return pdev->bus; + + return NULL; } diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 0d525ce3717fb4a3587af904d8450ed2100a56d4..9916d150b28c151bac0920aeb822545a41c40738 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -210,7 +210,29 @@ system_call: /* label this so stack traces look sane */ li r11,-MAX_ERRNO andi. r0,r9,(_TIF_SYSCALL_DOTRACE|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK) bne- syscall_exit_work - cmpld r3,r11 + + andi. r0,r8,MSR_FP + beq 2f +#ifdef CONFIG_ALTIVEC + andis. r0,r8,MSR_VEC@h + bne 3f +#endif +2: addi r3,r1,STACK_FRAME_OVERHEAD +#ifdef CONFIG_PPC_BOOK3S + mtmsrd r10,1 /* Restore RI */ +#endif + bl restore_math +#ifdef CONFIG_PPC_BOOK3S + ld r10,PACAKMSR(r13) + li r9,MSR_RI + andc r11,r10,r9 /* Re-clear RI */ + mtmsrd r11,1 +#endif + ld r8,_MSR(r1) + ld r3,RESULT(r1) + li r11,-MAX_ERRNO + +3: cmpld r3,r11 ld r5,_CCR(r1) bge- syscall_error .Lsyscall_error_cont: @@ -602,8 +624,8 @@ _GLOBAL(ret_from_except_lite) /* Check current_thread_info()->flags */ andi. r0,r4,_TIF_USER_WORK_MASK -#ifdef CONFIG_PPC_BOOK3E bne 1f +#ifdef CONFIG_PPC_BOOK3E /* * Check to see if the dbcr0 register is set up to debug. * Use the internal debug mode bit to do this. @@ -618,7 +640,9 @@ _GLOBAL(ret_from_except_lite) mtspr SPRN_DBSR,r10 b restore #else - beq restore + addi r3,r1,STACK_FRAME_OVERHEAD + bl restore_math + b restore #endif 1: andi. r0,r4,_TIF_NEED_RESCHED beq 2f @@ -1143,8 +1167,12 @@ _GLOBAL(enter_prom) #ifdef CONFIG_DYNAMIC_FTRACE _GLOBAL(mcount) _GLOBAL(_mcount) - blr + mflr r12 + mtctr r12 + mtlr r0 + bctr +#ifndef CC_USING_MPROFILE_KERNEL _GLOBAL_TOC(ftrace_caller) /* Taken from output of objdump from lib64/glibc */ mflr r3 @@ -1166,6 +1194,115 @@ _GLOBAL(ftrace_graph_stub) ld r0, 128(r1) mtlr r0 addi r1, r1, 112 + +#else /* CC_USING_MPROFILE_KERNEL */ +/* + * + * ftrace_caller() is the function that replaces _mcount() when ftrace is + * active. + * + * We arrive here after a function A calls function B, and we are the trace + * function for B. When we enter r1 points to A's stack frame, B has not yet + * had a chance to allocate one yet. + * + * Additionally r2 may point either to the TOC for A, or B, depending on + * whether B did a TOC setup sequence before calling us. + * + * On entry the LR points back to the _mcount() call site, and r0 holds the + * saved LR as it was on entry to B, ie. the original return address at the + * call site in A. + * + * Our job is to save the register state into a struct pt_regs (on the stack) + * and then arrange for the ftrace function to be called. + */ +_GLOBAL(ftrace_caller) + /* Save the original return address in A's stack frame */ + std r0,LRSAVE(r1) + + /* Create our stack frame + pt_regs */ + stdu r1,-SWITCH_FRAME_SIZE(r1) + + /* Save all gprs to pt_regs */ + SAVE_8GPRS(0,r1) + SAVE_8GPRS(8,r1) + SAVE_8GPRS(16,r1) + SAVE_8GPRS(24,r1) + + /* Load special regs for save below */ + mfmsr r8 + mfctr r9 + mfxer r10 + mfcr r11 + + /* Get the _mcount() call site out of LR */ + mflr r7 + /* Save it as pt_regs->nip & pt_regs->link */ + std r7, _NIP(r1) + std r7, _LINK(r1) + + /* Save callee's TOC in the ABI compliant location */ + std r2, 24(r1) + ld r2,PACATOC(r13) /* get kernel TOC in r2 */ + + addis r3,r2,function_trace_op@toc@ha + addi r3,r3,function_trace_op@toc@l + ld r5,0(r3) + + /* Calculate ip from nip-4 into r3 for call below */ + subi r3, r7, MCOUNT_INSN_SIZE + + /* Put the original return address in r4 as parent_ip */ + mr r4, r0 + + /* Save special regs */ + std r8, _MSR(r1) + std r9, _CTR(r1) + std r10, _XER(r1) + std r11, _CCR(r1) + + /* Load &pt_regs in r6 for call below */ + addi r6, r1 ,STACK_FRAME_OVERHEAD + + /* ftrace_call(r3, r4, r5, r6) */ +.globl ftrace_call +ftrace_call: + bl ftrace_stub + nop + + /* Load ctr with the possibly modified NIP */ + ld r3, _NIP(r1) + mtctr r3 + + /* Restore gprs */ + REST_8GPRS(0,r1) + REST_8GPRS(8,r1) + REST_8GPRS(16,r1) + REST_8GPRS(24,r1) + + /* Restore callee's TOC */ + ld r2, 24(r1) + + /* Pop our stack frame */ + addi r1, r1, SWITCH_FRAME_SIZE + + /* Restore original LR for return to B */ + ld r0, LRSAVE(r1) + mtlr r0 + +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + stdu r1, -112(r1) +.globl ftrace_graph_call +ftrace_graph_call: + b ftrace_graph_stub +_GLOBAL(ftrace_graph_stub) + addi r1, r1, 112 +#endif + + ld r0,LRSAVE(r1) /* restore callee's lr at _mcount site */ + mtlr r0 + bctr /* jump after _mcount site */ +#endif /* CC_USING_MPROFILE_KERNEL */ + _GLOBAL(ftrace_stub) blr #else @@ -1198,6 +1335,7 @@ _GLOBAL(ftrace_stub) #endif /* CONFIG_DYNAMIC_FTRACE */ #ifdef CONFIG_FUNCTION_GRAPH_TRACER +#ifndef CC_USING_MPROFILE_KERNEL _GLOBAL(ftrace_graph_caller) /* load r4 with local address */ ld r4, 128(r1) @@ -1222,6 +1360,56 @@ _GLOBAL(ftrace_graph_caller) addi r1, r1, 112 blr +#else /* CC_USING_MPROFILE_KERNEL */ +_GLOBAL(ftrace_graph_caller) + /* with -mprofile-kernel, parameter regs are still alive at _mcount */ + std r10, 104(r1) + std r9, 96(r1) + std r8, 88(r1) + std r7, 80(r1) + std r6, 72(r1) + std r5, 64(r1) + std r4, 56(r1) + std r3, 48(r1) + + /* Save callee's TOC in the ABI compliant location */ + std r2, 24(r1) + ld r2, PACATOC(r13) /* get kernel TOC in r2 */ + + mfctr r4 /* ftrace_caller has moved local addr here */ + std r4, 40(r1) + mflr r3 /* ftrace_caller has restored LR from stack */ + subi r4, r4, MCOUNT_INSN_SIZE + + bl prepare_ftrace_return + nop + + /* + * prepare_ftrace_return gives us the address we divert to. + * Change the LR to this. + */ + mtlr r3 + + ld r0, 40(r1) + mtctr r0 + ld r10, 104(r1) + ld r9, 96(r1) + ld r8, 88(r1) + ld r7, 80(r1) + ld r6, 72(r1) + ld r5, 64(r1) + ld r4, 56(r1) + ld r3, 48(r1) + + /* Restore callee's TOC */ + ld r2, 24(r1) + + addi r1, r1, 112 + mflr r0 + std r0, LRSAVE(r1) + bctr +#endif /* CC_USING_MPROFILE_KERNEL */ + _GLOBAL(return_to_handler) /* need to save return values */ std r4, -32(r1) diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S index 2117eaca3d288232a735325f2a31bd2a3c80e4cf..15da2b5df85e6775ede9834a6620c8abb7c0be02 100644 --- a/arch/powerpc/kernel/fpu.S +++ b/arch/powerpc/kernel/fpu.S @@ -130,6 +130,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX) or r12,r12,r4 std r12,_MSR(r1) #endif + /* Don't care if r4 overflows, this is desired behaviour */ + lbz r4,THREAD_LOAD_FP(r5) + addi r4,r4,1 + stb r4,THREAD_LOAD_FP(r5) addi r10,r5,THREAD_FPSTATE lfd fr0,FPSTATE_FPSCR(r10) MTFSF_L(fr0) @@ -139,33 +143,20 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX) blr /* - * __giveup_fpu(tsk) - * Disable FP for the task given as the argument, - * and save the floating-point registers in its thread_struct. + * save_fpu(tsk) + * Save the floating-point registers in its thread_struct. * Enables the FPU for use in the kernel on return. */ -_GLOBAL(__giveup_fpu) +_GLOBAL(save_fpu) addi r3,r3,THREAD /* want THREAD of task */ PPC_LL r6,THREAD_FPSAVEAREA(r3) PPC_LL r5,PT_REGS(r3) PPC_LCMPI 0,r6,0 bne 2f addi r6,r3,THREAD_FPSTATE -2: PPC_LCMPI 0,r5,0 - SAVE_32FPVSRS(0, R4, R6) +2: SAVE_32FPVSRS(0, R4, R6) mffs fr0 stfd fr0,FPSTATE_FPSCR(r6) - beq 1f - PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5) - li r3,MSR_FP|MSR_FE0|MSR_FE1 -#ifdef CONFIG_VSX -BEGIN_FTR_SECTION - oris r3,r3,MSR_VSX@h -END_FTR_SECTION_IFSET(CPU_FTR_VSX) -#endif - andc r4,r4,r3 /* disable FP for previous task */ - PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5) -1: blr /* diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c index 44d4d8eb3c85c6a8e845b9048e0276842122a3f0..9dac18dabd03c5a5f2135aee190a463212393fee 100644 --- a/arch/powerpc/kernel/ftrace.c +++ b/arch/powerpc/kernel/ftrace.c @@ -61,8 +61,11 @@ ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new) return -EFAULT; /* Make sure it is what we expect it to be */ - if (replaced != old) + if (replaced != old) { + pr_err("%p: replaced (%#x) != old (%#x)", + (void *)ip, replaced, old); return -EINVAL; + } /* replace the text with the new text */ if (patch_instruction((unsigned int *)ip, new)) @@ -106,14 +109,15 @@ static int __ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, unsigned long addr) { - unsigned int op; - unsigned long entry, ptr; + unsigned long entry, ptr, tramp; unsigned long ip = rec->ip; - void *tramp; + unsigned int op, pop; /* read where this goes */ - if (probe_kernel_read(&op, (void *)ip, sizeof(int))) + if (probe_kernel_read(&op, (void *)ip, sizeof(int))) { + pr_err("Fetching opcode failed.\n"); return -EFAULT; + } /* Make sure that that this is still a 24bit jump */ if (!is_bl_op(op)) { @@ -122,14 +126,9 @@ __ftrace_make_nop(struct module *mod, } /* lets find where the pointer goes */ - tramp = (void *)find_bl_target(ip, op); - - pr_devel("ip:%lx jumps to %p", ip, tramp); + tramp = find_bl_target(ip, op); - if (!is_module_trampoline(tramp)) { - pr_err("Not a trampoline\n"); - return -EINVAL; - } + pr_devel("ip:%lx jumps to %lx", ip, tramp); if (module_trampoline_target(mod, tramp, &ptr)) { pr_err("Failed to get trampoline target\n"); @@ -158,10 +157,42 @@ __ftrace_make_nop(struct module *mod, * * Use a b +8 to jump over the load. */ - op = 0x48000008; /* b +8 */ - if (patch_instruction((unsigned int *)ip, op)) + pop = PPC_INST_BRANCH | 8; /* b +8 */ + + /* + * Check what is in the next instruction. We can see ld r2,40(r1), but + * on first pass after boot we will see mflr r0. + */ + if (probe_kernel_read(&op, (void *)(ip+4), MCOUNT_INSN_SIZE)) { + pr_err("Fetching op failed.\n"); + return -EFAULT; + } + + if (op != PPC_INST_LD_TOC) { + unsigned int inst; + + if (probe_kernel_read(&inst, (void *)(ip - 4), 4)) { + pr_err("Fetching instruction at %lx failed.\n", ip - 4); + return -EFAULT; + } + + /* We expect either a mlfr r0, or a std r0, LRSAVE(r1) */ + if (inst != PPC_INST_MFLR && inst != PPC_INST_STD_LR) { + pr_err("Unexpected instructions around bl _mcount\n" + "when enabling dynamic ftrace!\t" + "(%08x,bl,%08x)\n", inst, op); + return -EINVAL; + } + + /* When using -mkernel_profile there is no load to jump over */ + pop = PPC_INST_NOP; + } + + if (patch_instruction((unsigned int *)ip, pop)) { + pr_err("Patching NOP failed.\n"); return -EPERM; + } return 0; } @@ -287,16 +318,15 @@ int ftrace_make_nop(struct module *mod, #ifdef CONFIG_MODULES #ifdef CONFIG_PPC64 +/* + * Examine the existing instructions for __ftrace_make_call. + * They should effectively be a NOP, and follow formal constraints, + * depending on the ABI. Return false if they don't. + */ +#ifndef CC_USING_MPROFILE_KERNEL static int -__ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) +expected_nop_sequence(void *ip, unsigned int op0, unsigned int op1) { - unsigned int op[2]; - void *ip = (void *)rec->ip; - - /* read where this goes */ - if (probe_kernel_read(op, ip, sizeof(op))) - return -EFAULT; - /* * We expect to see: * @@ -306,8 +336,34 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) * The load offset is different depending on the ABI. For simplicity * just mask it out when doing the compare. */ - if ((op[0] != 0x48000008) || ((op[1] & 0xffff0000) != 0xe8410000)) { - pr_err("Unexpected call sequence: %x %x\n", op[0], op[1]); + if ((op0 != 0x48000008) || ((op1 & 0xffff0000) != 0xe8410000)) + return 0; + return 1; +} +#else +static int +expected_nop_sequence(void *ip, unsigned int op0, unsigned int op1) +{ + /* look for patched "NOP" on ppc64 with -mprofile-kernel */ + if (op0 != PPC_INST_NOP) + return 0; + return 1; +} +#endif + +static int +__ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) +{ + unsigned int op[2]; + void *ip = (void *)rec->ip; + + /* read where this goes */ + if (probe_kernel_read(op, ip, sizeof(op))) + return -EFAULT; + + if (!expected_nop_sequence(ip, op[0], op[1])) { + pr_err("Unexpected call sequence at %p: %x %x\n", + ip, op[0], op[1]); return -EINVAL; } @@ -330,7 +386,16 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) return 0; } -#else + +#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS +int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, + unsigned long addr) +{ + return ftrace_make_call(rec, addr); +} +#endif + +#else /* !CONFIG_PPC64: */ static int __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) { @@ -455,20 +520,13 @@ void ftrace_replace_code(int enable) } } +/* + * Use the default ftrace_modify_all_code, but without + * stop_machine(). + */ void arch_ftrace_update_code(int command) { - if (command & FTRACE_UPDATE_CALLS) - ftrace_replace_code(1); - else if (command & FTRACE_DISABLE_CALLS) - ftrace_replace_code(0); - - if (command & FTRACE_UPDATE_TRACE_FUNC) - ftrace_update_ftrace_func(ftrace_trace_function); - - if (command & FTRACE_START_FUNC_RET) - ftrace_enable_ftrace_graph_caller(); - else if (command & FTRACE_STOP_FUNC_RET) - ftrace_disable_ftrace_graph_caller(); + ftrace_modify_all_code(command); } int __init ftrace_dyn_arch_init(void) diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S index b5061abbd2e0c1df269f424905f56c5e429167b1..9cdf5c71e4263c102a2294ffb251f991f98a8c03 100644 --- a/arch/powerpc/kernel/head_44x.S +++ b/arch/powerpc/kernel/head_44x.S @@ -806,7 +806,7 @@ _GLOBAL(set_context) _GLOBAL(init_cpu_state) mflr r22 #ifdef CONFIG_PPC_47x - /* We use the PVR to differenciate 44x cores from 476 */ + /* We use the PVR to differentiate 44x cores from 476 */ mfspr r3,SPRN_PVR srwi r3,r3,16 cmplwi cr0,r3,PVR_476FPE@h diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 1b779560728f964635039db913c81c83e0fd1358..4286775cbde9c36b67b6188615f8c93d41efdb5b 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -40,6 +40,8 @@ #include #include #include +#include +#include /* The physical memory is laid out such that the secondary processor * spin code sits at 0x0000...0x00ff. On server, the vectors follow @@ -181,6 +183,64 @@ exception_marker: #endif #ifdef CONFIG_PPC_BOOK3E +/* + * The booting_thread_hwid holds the thread id we want to boot in cpu + * hotplug case. It is set by cpu hotplug code, and is invalid by default. + * The thread id is the same as the initial value of SPRN_PIR[THREAD_ID] + * bit field. + */ + .globl booting_thread_hwid +booting_thread_hwid: + .long INVALID_THREAD_HWID + .align 3 +/* + * start a thread in the same core + * input parameters: + * r3 = the thread physical id + * r4 = the entry point where thread starts + */ +_GLOBAL(book3e_start_thread) + LOAD_REG_IMMEDIATE(r5, MSR_KERNEL) + cmpi 0, r3, 0 + beq 10f + cmpi 0, r3, 1 + beq 11f + /* If the thread id is invalid, just exit. */ + b 13f +10: + MTTMR(TMRN_IMSR0, 5) + MTTMR(TMRN_INIA0, 4) + b 12f +11: + MTTMR(TMRN_IMSR1, 5) + MTTMR(TMRN_INIA1, 4) +12: + isync + li r6, 1 + sld r6, r6, r3 + mtspr SPRN_TENS, r6 +13: + blr + +/* + * stop a thread in the same core + * input parameter: + * r3 = the thread physical id + */ +_GLOBAL(book3e_stop_thread) + cmpi 0, r3, 0 + beq 10f + cmpi 0, r3, 1 + beq 10f + /* If the thread id is invalid, just exit. */ + b 13f +10: + li r4, 1 + sld r4, r4, r3 + mtspr SPRN_TENC, r4 +13: + blr + _GLOBAL(fsl_secondary_thread_init) mfspr r4,SPRN_BUCSR @@ -261,6 +321,44 @@ _GLOBAL(generic_secondary_smp_init) mr r3,r24 mr r4,r25 bl book3e_secondary_core_init + +/* + * After common core init has finished, check if the current thread is the + * one we wanted to boot. If not, start the specified thread and stop the + * current thread. + */ + LOAD_REG_ADDR(r4, booting_thread_hwid) + lwz r3, 0(r4) + li r5, INVALID_THREAD_HWID + cmpw r3, r5 + beq 20f + + /* + * The value of booting_thread_hwid has been stored in r3, + * so make it invalid. + */ + stw r5, 0(r4) + + /* + * Get the current thread id and check if it is the one we wanted. + * If not, start the one specified in booting_thread_hwid and stop + * the current thread. + */ + mfspr r8, SPRN_TIR + cmpw r3, r8 + beq 20f + + /* start the specified thread */ + LOAD_REG_ADDR(r5, fsl_secondary_thread_init) + ld r4, 0(r5) + bl book3e_start_thread + + /* stop the current thread */ + mr r3, r8 + bl book3e_stop_thread +10: + b 10b +20: #endif generic_secondary_common_init: diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index 78c1eba4c04a432ea233983e81d9da7a87071834..80c69472314ea9a2d104be987c4fb1f030b11130 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -329,7 +329,7 @@ InstructionTLBMiss: /* If we are faulting a kernel address, we have to use the * kernel page tables. */ -#ifdef CONFIG_MODULES +#if defined(CONFIG_MODULES) || defined (CONFIG_DEBUG_PAGEALLOC) /* Only modules will cause ITLB Misses as we always * pin the first 8MB of kernel memory */ mfspr r11, SPRN_SRR0 /* Get effective address of fault */ @@ -385,27 +385,26 @@ InstructionTLBMiss: . = 0x1200 DataStoreTLBMiss: -#ifdef CONFIG_8xx_CPU6 mtspr SPRN_SPRG_SCRATCH2, r3 -#endif EXCEPTION_PROLOG_0 - mfcr r10 + mfcr r3 /* If we are faulting a kernel address, we have to use the * kernel page tables. */ - mfspr r11, SPRN_MD_EPN - IS_KERNEL(r11, r11) + mfspr r10, SPRN_MD_EPN + IS_KERNEL(r11, r10) mfspr r11, SPRN_M_TW /* Get level 1 table */ BRANCH_UNLESS_KERNEL(3f) lis r11, (swapper_pg_dir-PAGE_OFFSET)@ha 3: - mtcr r10 - mfspr r10, SPRN_MD_EPN /* Insert level 1 index */ rlwimi r11, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29 lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r11) /* Get the level 1 entry */ + mtcr r11 + bt- 28,DTLBMiss8M /* bit 28 = Large page (8M) */ + mtcr r3 /* We have a pte table, so load fetch the pte from the table. */ @@ -453,13 +452,34 @@ DataStoreTLBMiss: MTSPR_CPU6(SPRN_MD_RPN, r10, r3) /* Update TLB entry */ /* Restore registers */ -#ifdef CONFIG_8xx_CPU6 mfspr r3, SPRN_SPRG_SCRATCH2 + mtspr SPRN_DAR, r11 /* Tag DAR */ + EXCEPTION_EPILOG_0 + rfi + +DTLBMiss8M: + mtcr r3 + ori r11, r11, MD_SVALID + MTSPR_CPU6(SPRN_MD_TWC, r11, r3) +#ifdef CONFIG_PPC_16K_PAGES + /* + * In 16k pages mode, each PGD entry defines a 64M block. + * Here we select the 8M page within the block. + */ + rlwimi r11, r10, 0, 0x03800000 #endif + rlwinm r10, r11, 0, 0xff800000 + ori r10, r10, 0xf0 | MD_SPS16K | _PAGE_SHARED | _PAGE_DIRTY | \ + _PAGE_PRESENT + MTSPR_CPU6(SPRN_MD_RPN, r10, r3) /* Update TLB entry */ + + li r11, RPN_PATTERN + mfspr r3, SPRN_SPRG_SCRATCH2 mtspr SPRN_DAR, r11 /* Tag DAR */ EXCEPTION_EPILOG_0 rfi + /* This is an instruction TLB error on the MPC8xx. This could be due * to many reasons, such as executing guarded memory or illegal instruction * addresses. There is nothing to do but handle a big time error fault. @@ -537,13 +557,15 @@ FixupDAR:/* Entry point for dcbx workaround. */ /* Insert level 1 index */ 3: rlwimi r11, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29 lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r11) /* Get the level 1 entry */ + mtcr r11 + bt 28,200f /* bit 28 = Large page (8M) */ rlwinm r11, r11,0,0,19 /* Extract page descriptor page address */ /* Insert level 2 index */ rlwimi r11, r10, 32 - (PAGE_SHIFT - 2), 32 - PAGE_SHIFT, 29 lwz r11, 0(r11) /* Get the pte */ /* concat physical page address(r11) and page offset(r10) */ rlwimi r11, r10, 0, 32 - PAGE_SHIFT, 31 - lwz r11,0(r11) +201: lwz r11,0(r11) /* Check if it really is a dcbx instruction. */ /* dcbt and dcbtst does not generate DTLB Misses/Errors, * no need to include them here */ @@ -562,6 +584,10 @@ FixupDAR:/* Entry point for dcbx workaround. */ 141: mfspr r10,SPRN_SPRG_SCRATCH2 b DARFixed /* Nope, go back to normal TLB processing */ + /* concat physical page address(r11) and page offset(r10) */ +200: rlwimi r11, r10, 0, 32 - (PAGE_SHIFT << 1), 31 + b 201b + 144: mfspr r10, SPRN_DSISR rlwinm r10, r10,0,7,5 /* Clear store bit for buggy dcbst insn */ mtspr SPRN_DSISR, r10 @@ -856,68 +882,6 @@ initial_mmu: blr -/* - * Set up to use a given MMU context. - * r3 is context number, r4 is PGD pointer. - * - * We place the physical address of the new task page directory loaded - * into the MMU base register, and set the ASID compare register with - * the new "context." - */ -_GLOBAL(set_context) - -#ifdef CONFIG_BDI_SWITCH - /* Context switch the PTE pointer for the Abatron BDI2000. - * The PGDIR is passed as second argument. - */ - lis r5, KERNELBASE@h - lwz r5, 0xf0(r5) - stw r4, 0x4(r5) -#endif - - /* Register M_TW will contain base address of level 1 table minus the - * lower part of the kernel PGDIR base address, so that all accesses to - * level 1 table are done relative to lower part of kernel PGDIR base - * address. - */ - li r5, (swapper_pg_dir-PAGE_OFFSET)@l - sub r4, r4, r5 - tophys (r4, r4) -#ifdef CONFIG_8xx_CPU6 - lis r6, cpu6_errata_word@h - ori r6, r6, cpu6_errata_word@l - li r7, 0x3f80 - stw r7, 12(r6) - lwz r7, 12(r6) -#endif - mtspr SPRN_M_TW, r4 /* Update pointeur to level 1 table */ -#ifdef CONFIG_8xx_CPU6 - li r7, 0x3380 - stw r7, 12(r6) - lwz r7, 12(r6) -#endif - mtspr SPRN_M_CASID, r3 /* Update context */ - SYNC - blr - -#ifdef CONFIG_8xx_CPU6 -/* It's here because it is unique to the 8xx. - * It is important we get called with interrupts disabled. I used to - * do that, but it appears that all code that calls this already had - * interrupt disabled. - */ - .globl set_dec_cpu6 -set_dec_cpu6: - lis r7, cpu6_errata_word@h - ori r7, r7, cpu6_errata_word@l - li r4, 0x2c00 - stw r4, 8(r7) - lwz r4, 8(r7) - mtspr 22, r3 /* Update Decrementer */ - SYNC - blr -#endif - /* * We put a few things here that have to be page-aligned. * This stuff goes at the beginning of the data segment, diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index f705171b924b9389c5b16979ce52fd90171ecffa..3bfa3150911f7b42f20b7bfb7e7715be6c10871e 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -1037,80 +1037,6 @@ _GLOBAL(set_context) isync /* Force context change */ blr -_GLOBAL(flush_dcache_L1) - mfspr r3,SPRN_L1CFG0 - - rlwinm r5,r3,9,3 /* Extract cache block size */ - twlgti r5,1 /* Only 32 and 64 byte cache blocks - * are currently defined. - */ - li r4,32 - subfic r6,r5,2 /* r6 = log2(1KiB / cache block size) - - * log2(number of ways) - */ - slw r5,r4,r5 /* r5 = cache block size */ - - rlwinm r7,r3,0,0xff /* Extract number of KiB in the cache */ - mulli r7,r7,13 /* An 8-way cache will require 13 - * loads per set. - */ - slw r7,r7,r6 - - /* save off HID0 and set DCFA */ - mfspr r8,SPRN_HID0 - ori r9,r8,HID0_DCFA@l - mtspr SPRN_HID0,r9 - isync - - lis r4,KERNELBASE@h - mtctr r7 - -1: lwz r3,0(r4) /* Load... */ - add r4,r4,r5 - bdnz 1b - - msync - lis r4,KERNELBASE@h - mtctr r7 - -1: dcbf 0,r4 /* ...and flush. */ - add r4,r4,r5 - bdnz 1b - - /* restore HID0 */ - mtspr SPRN_HID0,r8 - isync - - blr - -/* Flush L1 d-cache, invalidate and disable d-cache and i-cache */ -_GLOBAL(__flush_disable_L1) - mflr r10 - bl flush_dcache_L1 /* Flush L1 d-cache */ - mtlr r10 - - mfspr r4, SPRN_L1CSR0 /* Invalidate and disable d-cache */ - li r5, 2 - rlwimi r4, r5, 0, 3 - - msync - isync - mtspr SPRN_L1CSR0, r4 - isync - -1: mfspr r4, SPRN_L1CSR0 /* Wait for the invalidate to finish */ - andi. r4, r4, 2 - bne 1b - - mfspr r4, SPRN_L1CSR1 /* Invalidate and disable i-cache */ - li r5, 2 - rlwimi r4, r5, 0, 3 - - mtspr SPRN_L1CSR1, r4 - isync - - blr - #ifdef CONFIG_SMP /* When we get here, r24 needs to hold the CPU # */ .globl __secondary_start diff --git a/arch/powerpc/kernel/idle_power7.S b/arch/powerpc/kernel/idle_power7.S index cf4fb5429cf12fe097590d570d7c9a6b0bce2571..470ceebd2d237c565eea24467b071440f177d149 100644 --- a/arch/powerpc/kernel/idle_power7.S +++ b/arch/powerpc/kernel/idle_power7.S @@ -19,7 +19,7 @@ #include #include #include -#include +#include #undef DEBUG diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c index e77c3ccf8dcfe432c6f7e7b761cb64a67afa3bed..dbf098121ce638fcbb2c6c91e1426014b2b28f3d 100644 --- a/arch/powerpc/kernel/kgdb.c +++ b/arch/powerpc/kernel/kgdb.c @@ -445,7 +445,11 @@ int kgdb_arch_handle_exception(int vector, int signo, int err_code, * Global data */ struct kgdb_arch arch_kgdb_ops = { +#ifdef __LITTLE_ENDIAN__ + .gdb_bpt_instr = {0x08, 0x10, 0x82, 0x7d}, +#else .gdb_bpt_instr = {0x7d, 0x82, 0x10, 0x08}, +#endif }; static int kgdb_not_implemented(struct pt_regs *regs) diff --git a/arch/powerpc/kernel/mce_power.c b/arch/powerpc/kernel/mce_power.c index 2c647b1e62e4b82d1157b39ef4086e29e066667a..ee62b197502d77e93ac860ab9e495db38eedc11e 100644 --- a/arch/powerpc/kernel/mce_power.c +++ b/arch/powerpc/kernel/mce_power.c @@ -54,8 +54,8 @@ static void flush_tlb_206(unsigned int num_sets, unsigned int action) } /* - * Generic routine to flush TLB on power7. This routine is used as - * flush_tlb hook in cpu_spec for Power7 processor. + * Generic routines to flush TLB on POWER processors. These routines + * are used as flush_tlb hook in the cpu_spec. * * action => TLB_INVAL_SCOPE_GLOBAL: Invalidate all TLBs. * TLB_INVAL_SCOPE_LPID: Invalidate TLB for current LPID. @@ -65,18 +65,17 @@ void __flush_tlb_power7(unsigned int action) flush_tlb_206(POWER7_TLB_SETS, action); } -/* - * Generic routine to flush TLB on power8. This routine is used as - * flush_tlb hook in cpu_spec for power8 processor. - * - * action => TLB_INVAL_SCOPE_GLOBAL: Invalidate all TLBs. - * TLB_INVAL_SCOPE_LPID: Invalidate TLB for current LPID. - */ void __flush_tlb_power8(unsigned int action) { flush_tlb_206(POWER8_TLB_SETS, action); } +void __flush_tlb_power9(unsigned int action) +{ + flush_tlb_206(POWER9_TLB_SETS_HASH, action); +} + + /* flush SLBs and reload */ static void flush_and_reload_slb(void) { diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index be8edd67f05be889d971d714e4ef53a40d410081..bf5160fbf9d8437c11afae2b75a5b3d29bab79ff 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S @@ -91,17 +91,16 @@ _GLOBAL(mulhdu) addc r7,r0,r7 addze r4,r4 1: beqlr cr1 /* all done if high part of A is 0 */ - mr r10,r3 mullw r9,r3,r5 - mulhwu r3,r3,r5 + mulhwu r10,r3,r5 beq 2f - mullw r0,r10,r6 - mulhwu r8,r10,r6 + mullw r0,r3,r6 + mulhwu r8,r3,r6 addc r7,r0,r7 adde r4,r4,r8 - addze r3,r3 + addze r10,r10 2: addc r4,r4,r9 - addze r3,r3 + addze r3,r10 blr /* @@ -296,12 +295,9 @@ _GLOBAL(real_writeb) * Flush instruction cache. * This is a no-op on the 601. */ +#ifndef CONFIG_PPC_8xx _GLOBAL(flush_instruction_cache) -#if defined(CONFIG_8xx) - isync - lis r5, IDC_INVALL@h - mtspr SPRN_IC_CST, r5 -#elif defined(CONFIG_4xx) +#if defined(CONFIG_4xx) #ifdef CONFIG_403GCX li r3, 512 mtctr r3 @@ -334,9 +330,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_UNIFIED_ID_CACHE) mfspr r3,SPRN_HID0 ori r3,r3,HID0_ICFI mtspr SPRN_HID0,r3 -#endif /* CONFIG_8xx/4xx */ +#endif /* CONFIG_4xx */ isync blr +#endif /* CONFIG_PPC_8xx */ /* * Write any modified data cache blocks out to memory @@ -350,10 +347,9 @@ BEGIN_FTR_SECTION PURGE_PREFETCHED_INS blr /* for 601, do nothing */ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) - li r5,L1_CACHE_BYTES-1 - andc r3,r3,r5 + rlwinm r3,r3,0,0,31 - L1_CACHE_SHIFT subf r4,r3,r4 - add r4,r4,r5 + addi r4,r4,L1_CACHE_BYTES - 1 srwi. r4,r4,L1_CACHE_SHIFT beqlr mtctr r4 @@ -376,71 +372,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) sync /* additional sync needed on g4 */ isync blr -/* - * Write any modified data cache blocks out to memory. - * Does not invalidate the corresponding cache lines (especially for - * any corresponding instruction cache). - * - * clean_dcache_range(unsigned long start, unsigned long stop) - */ -_GLOBAL(clean_dcache_range) - li r5,L1_CACHE_BYTES-1 - andc r3,r3,r5 - subf r4,r3,r4 - add r4,r4,r5 - srwi. r4,r4,L1_CACHE_SHIFT - beqlr - mtctr r4 - -1: dcbst 0,r3 - addi r3,r3,L1_CACHE_BYTES - bdnz 1b - sync /* wait for dcbst's to get to ram */ - blr - -/* - * Write any modified data cache blocks out to memory and invalidate them. - * Does not invalidate the corresponding instruction cache blocks. - * - * flush_dcache_range(unsigned long start, unsigned long stop) - */ -_GLOBAL(flush_dcache_range) - li r5,L1_CACHE_BYTES-1 - andc r3,r3,r5 - subf r4,r3,r4 - add r4,r4,r5 - srwi. r4,r4,L1_CACHE_SHIFT - beqlr - mtctr r4 - -1: dcbf 0,r3 - addi r3,r3,L1_CACHE_BYTES - bdnz 1b - sync /* wait for dcbst's to get to ram */ - blr - -/* - * Like above, but invalidate the D-cache. This is used by the 8xx - * to invalidate the cache so the PPC core doesn't get stale data - * from the CPM (no cache snooping here :-). - * - * invalidate_dcache_range(unsigned long start, unsigned long stop) - */ -_GLOBAL(invalidate_dcache_range) - li r5,L1_CACHE_BYTES-1 - andc r3,r3,r5 - subf r4,r3,r4 - add r4,r4,r5 - srwi. r4,r4,L1_CACHE_SHIFT - beqlr - mtctr r4 - -1: dcbi 0,r3 - addi r3,r3,L1_CACHE_BYTES - bdnz 1b - sync /* wait for dcbi's to get to ram */ - blr - /* * Flush a particular page from the data cache to RAM. * Note: this is necessary because the instruction cache does *not* @@ -518,22 +449,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) blr #endif /* CONFIG_BOOKE */ -/* - * Clear pages using the dcbz instruction, which doesn't cause any - * memory traffic (except to write out any cache lines which get - * displaced). This only works on cacheable memory. - * - * void clear_pages(void *page, int order) ; - */ -_GLOBAL(clear_pages) - li r0,PAGE_SIZE/L1_CACHE_BYTES - slw r0,r0,r4 - mtctr r0 -1: dcbz 0,r3 - addi r3,r3,L1_CACHE_BYTES - bdnz 1b - blr - /* * Copy a whole page. We use the dcbz instruction on the destination * to reduce memory traffic (it eliminates the unnecessary reads of diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c index 9547381b631a587b6d520b22f414039d6d458525..d1f1b35bf0c72b098b45c83e9cbf3480db03f01e 100644 --- a/arch/powerpc/kernel/module.c +++ b/arch/powerpc/kernel/module.c @@ -47,6 +47,11 @@ int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *me) { const Elf_Shdr *sect; + int rc; + + rc = module_finalize_ftrace(me, sechdrs); + if (rc) + return rc; /* Apply feature fixups */ sect = find_section(hdr, sechdrs, "__ftr_fixup"); diff --git a/arch/powerpc/kernel/module_32.c b/arch/powerpc/kernel/module_32.c index 2c01665eb410afe448eb15c533da1af921af331d..5a7a78f12562969d8db892d4ab63be131530e62e 100644 --- a/arch/powerpc/kernel/module_32.c +++ b/arch/powerpc/kernel/module_32.c @@ -181,7 +181,7 @@ static inline int entry_matches(struct ppc_plt_entry *entry, Elf32_Addr val) /* Set up a trampoline in the PLT to bounce us to the distant function */ static uint32_t do_plt_call(void *location, Elf32_Addr val, - Elf32_Shdr *sechdrs, + const Elf32_Shdr *sechdrs, struct module *mod) { struct ppc_plt_entry *entry; @@ -294,11 +294,19 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, return -ENOEXEC; } } + + return 0; +} + #ifdef CONFIG_DYNAMIC_FTRACE - module->arch.tramp = - do_plt_call(module->core_layout.base, - (unsigned long)ftrace_caller, - sechdrs, module); -#endif +int module_finalize_ftrace(struct module *module, const Elf_Shdr *sechdrs) +{ + module->arch.tramp = do_plt_call(module->core_layout.base, + (unsigned long)ftrace_caller, + sechdrs, module); + if (!module->arch.tramp) + return -ENOENT; + return 0; } +#endif diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c index 08b7a40de5f85ab1c6f7e5ed205ca52edd5ab12c..9ce9a25f58b556c139ff14a616021180a846dff0 100644 --- a/arch/powerpc/kernel/module_64.c +++ b/arch/powerpc/kernel/module_64.c @@ -31,6 +31,7 @@ #include #include #include +#include /* FIXME: We don't do .init separately. To do this, we'd need to have a separate r2 value in the init and core section, and stub between @@ -41,7 +42,6 @@ --RR. */ #if defined(_CALL_ELF) && _CALL_ELF == 2 -#define R2_STACK_OFFSET 24 /* An address is simply the address of the function. */ typedef unsigned long func_desc_t; @@ -73,7 +73,6 @@ static unsigned int local_entry_offset(const Elf64_Sym *sym) return PPC64_LOCAL_ENTRY_OFFSET(sym->st_other); } #else -#define R2_STACK_OFFSET 40 /* An address is address of the OPD entry, which contains address of fn. */ typedef struct ppc64_opd_entry func_desc_t; @@ -96,6 +95,8 @@ static unsigned int local_entry_offset(const Elf64_Sym *sym) } #endif +#define STUB_MAGIC 0x73747562 /* stub */ + /* Like PPC32, we need little trampolines to do > 24-bit jumps (into the kernel itself). But on PPC64, these need to be used for every jump, actually, to reset r2 (TOC+0x8000). */ @@ -105,7 +106,8 @@ struct ppc64_stub_entry * need 6 instructions on ABIv2 but we always allocate 7 so * so we don't have to modify the trampoline load instruction. */ u32 jump[7]; - u32 unused; + /* Used by ftrace to identify stubs */ + u32 magic; /* Data for the above code */ func_desc_t funcdata; }; @@ -139,70 +141,39 @@ static u32 ppc64_stub_insns[] = { }; #ifdef CONFIG_DYNAMIC_FTRACE - -static u32 ppc64_stub_mask[] = { - 0xffff0000, - 0xffff0000, - 0xffffffff, - 0xffffffff, -#if !defined(_CALL_ELF) || _CALL_ELF != 2 - 0xffffffff, -#endif - 0xffffffff, - 0xffffffff -}; - -bool is_module_trampoline(u32 *p) +int module_trampoline_target(struct module *mod, unsigned long addr, + unsigned long *target) { - unsigned int i; - u32 insns[ARRAY_SIZE(ppc64_stub_insns)]; - - BUILD_BUG_ON(sizeof(ppc64_stub_insns) != sizeof(ppc64_stub_mask)); + struct ppc64_stub_entry *stub; + func_desc_t funcdata; + u32 magic; - if (probe_kernel_read(insns, p, sizeof(insns))) + if (!within_module_core(addr, mod)) { + pr_err("%s: stub %lx not in module %s\n", __func__, addr, mod->name); return -EFAULT; - - for (i = 0; i < ARRAY_SIZE(ppc64_stub_insns); i++) { - u32 insna = insns[i]; - u32 insnb = ppc64_stub_insns[i]; - u32 mask = ppc64_stub_mask[i]; - - if ((insna & mask) != (insnb & mask)) - return false; } - return true; -} - -int module_trampoline_target(struct module *mod, u32 *trampoline, - unsigned long *target) -{ - u32 buf[2]; - u16 upper, lower; - long offset; - void *toc_entry; + stub = (struct ppc64_stub_entry *)addr; - if (probe_kernel_read(buf, trampoline, sizeof(buf))) + if (probe_kernel_read(&magic, &stub->magic, sizeof(magic))) { + pr_err("%s: fault reading magic for stub %lx for %s\n", __func__, addr, mod->name); return -EFAULT; + } - upper = buf[0] & 0xffff; - lower = buf[1] & 0xffff; - - /* perform the addis/addi, both signed */ - offset = ((short)upper << 16) + (short)lower; + if (magic != STUB_MAGIC) { + pr_err("%s: bad magic for stub %lx for %s\n", __func__, addr, mod->name); + return -EFAULT; + } - /* - * Now get the address this trampoline jumps to. This - * is always 32 bytes into our trampoline stub. - */ - toc_entry = (void *)mod->arch.toc + offset + 32; + if (probe_kernel_read(&funcdata, &stub->funcdata, sizeof(funcdata))) { + pr_err("%s: fault reading funcdata for stub %lx for %s\n", __func__, addr, mod->name); + return -EFAULT; + } - if (probe_kernel_read(target, toc_entry, sizeof(*target))) - return -EFAULT; + *target = stub_func_addr(funcdata); return 0; } - #endif /* Count how many different 24-bit relocations (different symbol, @@ -413,7 +384,7 @@ int module_frob_arch_sections(Elf64_Ehdr *hdr, /* r2 is the TOC pointer: it actually points 0x8000 into the TOC (this gives the value maximum span in an instruction which uses a signed offset) */ -static inline unsigned long my_r2(Elf64_Shdr *sechdrs, struct module *me) +static inline unsigned long my_r2(const Elf64_Shdr *sechdrs, struct module *me) { return sechdrs[me->arch.toc_section].sh_addr + 0x8000; } @@ -426,7 +397,7 @@ static inline unsigned long my_r2(Elf64_Shdr *sechdrs, struct module *me) #define PPC_HA(v) PPC_HI ((v) + 0x8000) /* Patch stub to reference function and correct r2 value. */ -static inline int create_stub(Elf64_Shdr *sechdrs, +static inline int create_stub(const Elf64_Shdr *sechdrs, struct ppc64_stub_entry *entry, unsigned long addr, struct module *me) @@ -447,12 +418,14 @@ static inline int create_stub(Elf64_Shdr *sechdrs, entry->jump[0] |= PPC_HA(reladdr); entry->jump[1] |= PPC_LO(reladdr); entry->funcdata = func_desc(addr); + entry->magic = STUB_MAGIC; + return 1; } /* Create stub to jump to function described in this OPD/ptr: we need the stub to set up the TOC ptr (r2) for the function. */ -static unsigned long stub_for_addr(Elf64_Shdr *sechdrs, +static unsigned long stub_for_addr(const Elf64_Shdr *sechdrs, unsigned long addr, struct module *me) { @@ -476,17 +449,60 @@ static unsigned long stub_for_addr(Elf64_Shdr *sechdrs, return (unsigned long)&stubs[i]; } +#ifdef CC_USING_MPROFILE_KERNEL +static bool is_early_mcount_callsite(u32 *instruction) +{ + /* + * Check if this is one of the -mprofile-kernel sequences. + */ + if (instruction[-1] == PPC_INST_STD_LR && + instruction[-2] == PPC_INST_MFLR) + return true; + + if (instruction[-1] == PPC_INST_MFLR) + return true; + + return false; +} + +/* + * In case of _mcount calls, do not save the current callee's TOC (in r2) into + * the original caller's stack frame. If we did we would clobber the saved TOC + * value of the original caller. + */ +static void squash_toc_save_inst(const char *name, unsigned long addr) +{ + struct ppc64_stub_entry *stub = (struct ppc64_stub_entry *)addr; + + /* Only for calls to _mcount */ + if (strcmp("_mcount", name) != 0) + return; + + stub->jump[2] = PPC_INST_NOP; +} +#else +static void squash_toc_save_inst(const char *name, unsigned long addr) { } + +/* without -mprofile-kernel, mcount calls are never early */ +static bool is_early_mcount_callsite(u32 *instruction) +{ + return false; +} +#endif + /* We expect a noop next: if it is, replace it with instruction to restore r2. */ static int restore_r2(u32 *instruction, struct module *me) { if (*instruction != PPC_INST_NOP) { + if (is_early_mcount_callsite(instruction - 1)) + return 1; pr_err("%s: Expect noop after relocate, got %08x\n", me->name, *instruction); return 0; } /* ld r2,R2_STACK_OFFSET(r1) */ - *instruction = 0xe8410000 | R2_STACK_OFFSET; + *instruction = PPC_INST_LD_TOC; return 1; } @@ -611,6 +627,8 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, return -ENOENT; if (!restore_r2((u32 *)location + 1, me)) return -ENOEXEC; + + squash_toc_save_inst(strtab + sym->st_name, value); } else value += local_entry_offset(sym); @@ -693,12 +711,84 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, } } + return 0; +} + #ifdef CONFIG_DYNAMIC_FTRACE - me->arch.toc = my_r2(sechdrs, me); - me->arch.tramp = stub_for_addr(sechdrs, - (unsigned long)ftrace_caller, - me); + +#ifdef CC_USING_MPROFILE_KERNEL + +#define PACATOC offsetof(struct paca_struct, kernel_toc) + +/* + * For mprofile-kernel we use a special stub for ftrace_caller() because we + * can't rely on r2 containing this module's TOC when we enter the stub. + * + * That can happen if the function calling us didn't need to use the toc. In + * that case it won't have setup r2, and the r2 value will be either the + * kernel's toc, or possibly another modules toc. + * + * To deal with that this stub uses the kernel toc, which is always accessible + * via the paca (in r13). The target (ftrace_caller()) is responsible for + * saving and restoring the toc before returning. + */ +static unsigned long create_ftrace_stub(const Elf64_Shdr *sechdrs, struct module *me) +{ + struct ppc64_stub_entry *entry; + unsigned int i, num_stubs; + static u32 stub_insns[] = { + 0xe98d0000 | PACATOC, /* ld r12,PACATOC(r13) */ + 0x3d8c0000, /* addis r12,r12, */ + 0x398c0000, /* addi r12,r12, */ + 0x7d8903a6, /* mtctr r12 */ + 0x4e800420, /* bctr */ + }; + long reladdr; + + num_stubs = sechdrs[me->arch.stubs_section].sh_size / sizeof(*entry); + + /* Find the next available stub entry */ + entry = (void *)sechdrs[me->arch.stubs_section].sh_addr; + for (i = 0; i < num_stubs && stub_func_addr(entry->funcdata); i++, entry++); + + if (i >= num_stubs) { + pr_err("%s: Unable to find a free slot for ftrace stub.\n", me->name); + return 0; + } + + memcpy(entry->jump, stub_insns, sizeof(stub_insns)); + + /* Stub uses address relative to kernel toc (from the paca) */ + reladdr = (unsigned long)ftrace_caller - kernel_toc_addr(); + if (reladdr > 0x7FFFFFFF || reladdr < -(0x80000000L)) { + pr_err("%s: Address of ftrace_caller out of range of kernel_toc.\n", me->name); + return 0; + } + + entry->jump[1] |= PPC_HA(reladdr); + entry->jump[2] |= PPC_LO(reladdr); + + /* Eventhough we don't use funcdata in the stub, it's needed elsewhere. */ + entry->funcdata = func_desc((unsigned long)ftrace_caller); + entry->magic = STUB_MAGIC; + + return (unsigned long)entry; +} +#else +static unsigned long create_ftrace_stub(const Elf64_Shdr *sechdrs, struct module *me) +{ + return stub_for_addr(sechdrs, (unsigned long)ftrace_caller, me); +} #endif +int module_finalize_ftrace(struct module *mod, const Elf_Shdr *sechdrs) +{ + mod->arch.toc = my_r2(sechdrs, mod); + mod->arch.tramp = create_ftrace_stub(sechdrs, mod); + + if (!mod->arch.tramp) + return -ENOENT; + return 0; } +#endif diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c index 01ea0edf0579a3eefb67c65dcb535797a1e4ac63..93dae296b6be693d635a56cf2b894c3dc20f8433 100644 --- a/arch/powerpc/kernel/paca.c +++ b/arch/powerpc/kernel/paca.c @@ -17,10 +17,6 @@ #include #include -/* This symbol is provided by the linker - let it fill in the paca - * field correctly */ -extern unsigned long __toc_start; - #ifdef CONFIG_PPC_BOOK3S /* @@ -149,11 +145,6 @@ EXPORT_SYMBOL(paca); void __init initialise_paca(struct paca_struct *new_paca, int cpu) { - /* The TOC register (GPR2) points 32kB into the TOC, so that 64kB - * of the TOC can be addressed using a single machine instruction. - */ - unsigned long kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL; - #ifdef CONFIG_PPC_BOOK3S new_paca->lppaca_ptr = new_lppaca(cpu); #else @@ -161,7 +152,7 @@ void __init initialise_paca(struct paca_struct *new_paca, int cpu) #endif new_paca->lock_token = 0x8000; new_paca->paca_index = cpu; - new_paca->kernel_toc = kernel_toc; + new_paca->kernel_toc = kernel_toc_addr(); new_paca->kernelbase = (unsigned long) _stext; /* Only set MSR:IR/DR when MMU is initialized */ new_paca->kernel_msr = MSR_KERNEL & ~(MSR_IR | MSR_DR); diff --git a/arch/powerpc/kernel/pci-hotplug.c b/arch/powerpc/kernel/pci-hotplug.c index 7f9ed0c1f6b93d88dc4b3d8e815b7e1c099b1f82..59c436189f466fbef0119378028184198ca5a863 100644 --- a/arch/powerpc/kernel/pci-hotplug.c +++ b/arch/powerpc/kernel/pci-hotplug.c @@ -55,7 +55,7 @@ void pcibios_remove_pci_devices(struct pci_bus *bus) pr_debug("PCI: Removing devices on bus %04x:%02x\n", pci_domain_nr(bus), bus->number); - list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { + list_for_each_entry_safe_reverse(dev, tmp, &bus->devices, bus_list) { pr_debug(" Removing %s...\n", pci_name(dev)); pci_stop_and_remove_bus_device(dev); } diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c index b3b4df91b792cc59e533c7465b7543da37756de6..38102cb9baa968223dd4bfb353c544928e91984c 100644 --- a/arch/powerpc/kernel/pci_dn.c +++ b/arch/powerpc/kernel/pci_dn.c @@ -139,6 +139,7 @@ struct pci_dn *pci_get_pdn(struct pci_dev *pdev) #ifdef CONFIG_PCI_IOV static struct pci_dn *add_one_dev_pci_data(struct pci_dn *parent, struct pci_dev *pdev, + int vf_index, int busno, int devfn) { struct pci_dn *pdn; @@ -158,6 +159,7 @@ static struct pci_dn *add_one_dev_pci_data(struct pci_dn *parent, pdn->busno = busno; pdn->devfn = devfn; #ifdef CONFIG_PPC_POWERNV + pdn->vf_index = vf_index; pdn->pe_number = IODA_INVALID_PE; #endif INIT_LIST_HEAD(&pdn->child_list); @@ -179,6 +181,7 @@ struct pci_dn *add_dev_pci_data(struct pci_dev *pdev) { #ifdef CONFIG_PCI_IOV struct pci_dn *parent, *pdn; + struct eeh_dev *edev; int i; /* Only support IOV for now */ @@ -196,7 +199,7 @@ struct pci_dn *add_dev_pci_data(struct pci_dev *pdev) return NULL; for (i = 0; i < pci_sriov_get_totalvfs(pdev); i++) { - pdn = add_one_dev_pci_data(parent, NULL, + pdn = add_one_dev_pci_data(parent, NULL, i, pci_iov_virtfn_bus(pdev, i), pci_iov_virtfn_devfn(pdev, i)); if (!pdn) { @@ -204,6 +207,12 @@ struct pci_dn *add_dev_pci_data(struct pci_dev *pdev) __func__, i); return NULL; } + + /* Create the EEH device for the VF */ + eeh_dev_init(pdn, pci_bus_to_host(pdev->bus)); + edev = pdn_to_eeh_dev(pdn); + BUG_ON(!edev); + edev->physfn = pdev; } #endif /* CONFIG_PCI_IOV */ @@ -215,6 +224,7 @@ void remove_dev_pci_data(struct pci_dev *pdev) #ifdef CONFIG_PCI_IOV struct pci_dn *parent; struct pci_dn *pdn, *tmp; + struct eeh_dev *edev; int i; /* @@ -256,6 +266,13 @@ void remove_dev_pci_data(struct pci_dev *pdev) pdn->devfn != pci_iov_virtfn_devfn(pdev, i)) continue; + /* Release EEH device for the VF */ + edev = pdn_to_eeh_dev(pdn); + if (edev) { + pdn->edev = NULL; + kfree(edev); + } + if (!list_empty(&pdn->list)) list_del(&pdn->list); diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 41e1607e800caf9ff5277f08609dab49566123e6..9f01e28ecef35f465bd1e868ab7652d022ac4ff3 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c @@ -6,7 +6,9 @@ #include #include +#ifdef CONFIG_PPC64 EXPORT_SYMBOL(flush_dcache_range); +#endif EXPORT_SYMBOL(flush_icache_range); EXPORT_SYMBOL(empty_zero_page); @@ -28,10 +30,6 @@ EXPORT_SYMBOL(load_vr_state); EXPORT_SYMBOL(store_vr_state); #endif -#ifdef CONFIG_VSX -EXPORT_SYMBOL_GPL(__giveup_vsx); -#endif - #ifdef CONFIG_EPAPR_PARAVIRT EXPORT_SYMBOL(epapr_hypercall_start); #endif diff --git a/arch/powerpc/kernel/ppc_ksyms_32.c b/arch/powerpc/kernel/ppc_ksyms_32.c index 30ddd8a24eee9708977fa85e1192ac89697ed1f2..2bfaafe5be99e23433432ab418e92a315f2e1b7f 100644 --- a/arch/powerpc/kernel/ppc_ksyms_32.c +++ b/arch/powerpc/kernel/ppc_ksyms_32.c @@ -10,7 +10,6 @@ #include #include -EXPORT_SYMBOL(clear_pages); EXPORT_SYMBOL(ISA_DMA_THRESHOLD); EXPORT_SYMBOL(DMA_MODE_READ); EXPORT_SYMBOL(DMA_MODE_WRITE); diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 3c5736e52a14b7d42dd0c28425e709b0a7147c3c..b8500b4ac7fead4c78bc6478d109e3b0a6a50c76 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -133,6 +133,16 @@ void __msr_check_and_clear(unsigned long bits) EXPORT_SYMBOL(__msr_check_and_clear); #ifdef CONFIG_PPC_FPU +void __giveup_fpu(struct task_struct *tsk) +{ + save_fpu(tsk); + tsk->thread.regs->msr &= ~MSR_FP; +#ifdef CONFIG_VSX + if (cpu_has_feature(CPU_FTR_VSX)) + tsk->thread.regs->msr &= ~MSR_VSX; +#endif +} + void giveup_fpu(struct task_struct *tsk) { check_if_tm_restore_required(tsk); @@ -187,9 +197,32 @@ void enable_kernel_fp(void) } } EXPORT_SYMBOL(enable_kernel_fp); + +static int restore_fp(struct task_struct *tsk) { + if (tsk->thread.load_fp) { + load_fp_state(¤t->thread.fp_state); + current->thread.load_fp++; + return 1; + } + return 0; +} +#else +static int restore_fp(struct task_struct *tsk) { return 0; } #endif /* CONFIG_PPC_FPU */ #ifdef CONFIG_ALTIVEC +#define loadvec(thr) ((thr).load_vec) + +static void __giveup_altivec(struct task_struct *tsk) +{ + save_altivec(tsk); + tsk->thread.regs->msr &= ~MSR_VEC; +#ifdef CONFIG_VSX + if (cpu_has_feature(CPU_FTR_VSX)) + tsk->thread.regs->msr &= ~MSR_VSX; +#endif +} + void giveup_altivec(struct task_struct *tsk) { check_if_tm_restore_required(tsk); @@ -229,22 +262,49 @@ void flush_altivec_to_thread(struct task_struct *tsk) } } EXPORT_SYMBOL_GPL(flush_altivec_to_thread); + +static int restore_altivec(struct task_struct *tsk) +{ + if (cpu_has_feature(CPU_FTR_ALTIVEC) && tsk->thread.load_vec) { + load_vr_state(&tsk->thread.vr_state); + tsk->thread.used_vr = 1; + tsk->thread.load_vec++; + + return 1; + } + return 0; +} +#else +#define loadvec(thr) 0 +static inline int restore_altivec(struct task_struct *tsk) { return 0; } #endif /* CONFIG_ALTIVEC */ #ifdef CONFIG_VSX -void giveup_vsx(struct task_struct *tsk) +static void __giveup_vsx(struct task_struct *tsk) { - check_if_tm_restore_required(tsk); - - msr_check_and_set(MSR_FP|MSR_VEC|MSR_VSX); if (tsk->thread.regs->msr & MSR_FP) __giveup_fpu(tsk); if (tsk->thread.regs->msr & MSR_VEC) __giveup_altivec(tsk); + tsk->thread.regs->msr &= ~MSR_VSX; +} + +static void giveup_vsx(struct task_struct *tsk) +{ + check_if_tm_restore_required(tsk); + + msr_check_and_set(MSR_FP|MSR_VEC|MSR_VSX); __giveup_vsx(tsk); msr_check_and_clear(MSR_FP|MSR_VEC|MSR_VSX); } -EXPORT_SYMBOL(giveup_vsx); + +static void save_vsx(struct task_struct *tsk) +{ + if (tsk->thread.regs->msr & MSR_FP) + save_fpu(tsk); + if (tsk->thread.regs->msr & MSR_VEC) + save_altivec(tsk); +} void enable_kernel_vsx(void) { @@ -275,6 +335,19 @@ void flush_vsx_to_thread(struct task_struct *tsk) } } EXPORT_SYMBOL_GPL(flush_vsx_to_thread); + +static int restore_vsx(struct task_struct *tsk) +{ + if (cpu_has_feature(CPU_FTR_VSX)) { + tsk->thread.used_vsr = 1; + return 1; + } + + return 0; +} +#else +static inline int restore_vsx(struct task_struct *tsk) { return 0; } +static inline void save_vsx(struct task_struct *tsk) { } #endif /* CONFIG_VSX */ #ifdef CONFIG_SPE @@ -374,12 +447,76 @@ void giveup_all(struct task_struct *tsk) } EXPORT_SYMBOL(giveup_all); +void restore_math(struct pt_regs *regs) +{ + unsigned long msr; + + if (!current->thread.load_fp && !loadvec(current->thread)) + return; + + msr = regs->msr; + msr_check_and_set(msr_all_available); + + /* + * Only reload if the bit is not set in the user MSR, the bit BEING set + * indicates that the registers are hot + */ + if ((!(msr & MSR_FP)) && restore_fp(current)) + msr |= MSR_FP | current->thread.fpexc_mode; + + if ((!(msr & MSR_VEC)) && restore_altivec(current)) + msr |= MSR_VEC; + + if ((msr & (MSR_FP | MSR_VEC)) == (MSR_FP | MSR_VEC) && + restore_vsx(current)) { + msr |= MSR_VSX; + } + + msr_check_and_clear(msr_all_available); + + regs->msr = msr; +} + +void save_all(struct task_struct *tsk) +{ + unsigned long usermsr; + + if (!tsk->thread.regs) + return; + + usermsr = tsk->thread.regs->msr; + + if ((usermsr & msr_all_available) == 0) + return; + + msr_check_and_set(msr_all_available); + + /* + * Saving the way the register space is in hardware, save_vsx boils + * down to a save_fpu() and save_altivec() + */ + if (usermsr & MSR_VSX) { + save_vsx(tsk); + } else { + if (usermsr & MSR_FP) + save_fpu(tsk); + + if (usermsr & MSR_VEC) + save_altivec(tsk); + } + + if (usermsr & MSR_SPE) + __giveup_spe(tsk); + + msr_check_and_clear(msr_all_available); +} + void flush_all_to_thread(struct task_struct *tsk) { if (tsk->thread.regs) { preempt_disable(); BUG_ON(tsk != current); - giveup_all(tsk); + save_all(tsk); #ifdef CONFIG_SPE if (tsk->thread.regs->msr & MSR_SPE) @@ -832,17 +969,9 @@ void restore_tm_state(struct pt_regs *regs) msr_diff = current->thread.ckpt_regs.msr & ~regs->msr; msr_diff &= MSR_FP | MSR_VEC | MSR_VSX; - if (msr_diff & MSR_FP) { - msr_check_and_set(MSR_FP); - load_fp_state(¤t->thread.fp_state); - msr_check_and_clear(MSR_FP); - regs->msr |= current->thread.fpexc_mode; - } - if (msr_diff & MSR_VEC) { - msr_check_and_set(MSR_VEC); - load_vr_state(¤t->thread.vr_state); - msr_check_and_clear(MSR_VEC); - } + + restore_math(regs); + regs->msr |= msr_diff; } @@ -854,7 +983,7 @@ void restore_tm_state(struct pt_regs *regs) static inline void save_sprs(struct thread_struct *t) { #ifdef CONFIG_ALTIVEC - if (cpu_has_feature(cpu_has_feature(CPU_FTR_ALTIVEC))) + if (cpu_has_feature(CPU_FTR_ALTIVEC)) t->vrsave = mfspr(SPRN_VRSAVE); #endif #ifdef CONFIG_PPC_BOOK3S_64 @@ -1006,6 +1135,10 @@ struct task_struct *__switch_to(struct task_struct *prev, batch = this_cpu_ptr(&ppc64_tlb_batch); batch->active = 1; } + + if (current_thread_info()->task->thread.regs) + restore_math(current_thread_info()->task->thread.regs); + #endif /* CONFIG_PPC_BOOK3S_64 */ return last; @@ -1307,6 +1440,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, f = ret_from_fork; } + childregs->msr &= ~(MSR_FP|MSR_VEC|MSR_VSX); sp -= STACK_FRAME_OVERHEAD; /* diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c index 5a2c049c1c61461a50546a05082338158bdd7d08..aa610ce8742fe6bb0d3875e0a1d69c37d6741e63 100644 --- a/arch/powerpc/kernel/rtasd.c +++ b/arch/powerpc/kernel/rtasd.c @@ -49,7 +49,7 @@ static unsigned int rtas_error_log_buffer_max; static unsigned int event_scan; static unsigned int rtas_event_scan_rate; -static int full_rtas_msgs = 0; +static bool full_rtas_msgs; /* Stop logging to nvram after first fatal error */ static int logging_enabled; /* Until we initialize everything, @@ -592,11 +592,6 @@ __setup("surveillance=", surveillance_setup); static int __init rtasmsgs_setup(char *str) { - if (strcmp(str, "on") == 0) - full_rtas_msgs = 1; - else if (strcmp(str, "off") == 0) - full_rtas_msgs = 0; - - return 1; + return (kstrtobool(str, &full_rtas_msgs) == 0); } __setup("rtasmsgs=", rtasmsgs_setup); diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c index cf8c7e4e0b21bb519f0098bd5a72622233dcd358..cb64d6feb45ac188de852a26a877d9454ba178df 100644 --- a/arch/powerpc/kernel/signal.c +++ b/arch/powerpc/kernel/signal.c @@ -1,7 +1,7 @@ /* * Common signal handling code for both 32 and 64 bits * - * Copyright (c) 2007 Benjamin Herrenschmidt, IBM Coproration + * Copyright (c) 2007 Benjamin Herrenschmidt, IBM Corporation * Extracted from signal_32.c and signal_64.c * * This file is subject to the terms and conditions of the GNU General @@ -178,7 +178,7 @@ unsigned long get_tm_stackpointer(struct pt_regs *regs) * need to use the stack pointer from the checkpointed state, rather * than the speculated state. This ensures that the signal context * (written tm suspended) will be written below the stack required for - * the rollback. The transaction is aborted becuase of the treclaim, + * the rollback. The transaction is aborted because of the treclaim, * so any memory written between the tbegin and the signal will be * rolled back anyway. * diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h index 51b274199dd9f318c4adf6e6a2a122acb6caa054..be305c858e5136ff99cd791774cabd8ff758124a 100644 --- a/arch/powerpc/kernel/signal.h +++ b/arch/powerpc/kernel/signal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 Benjamin Herrenschmidt, IBM Coproration + * Copyright (c) 2007 Benjamin Herrenschmidt, IBM Corporation * Extracted from signal_32.c and signal_64.c * * This file is subject to the terms and conditions of the GNU General diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index b7dea05f07259558089205cebef69f40a7985a2f..8cac1eb414661ad6e3340a8469361fe9a885d117 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -445,7 +445,7 @@ void generic_cpu_die(unsigned int cpu) for (i = 0; i < 100; i++) { smp_rmb(); - if (per_cpu(cpu_state, cpu) == CPU_DEAD) + if (is_cpu_dead(cpu)) return; msleep(100); } @@ -472,6 +472,11 @@ int generic_check_cpu_restart(unsigned int cpu) return per_cpu(cpu_state, cpu) == CPU_UP_PREPARE; } +int is_cpu_dead(unsigned int cpu) +{ + return per_cpu(cpu_state, cpu) == CPU_DEAD; +} + static bool secondaries_inhibited(void) { return kvm_hv_mode_active(); diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index b6becc795bb559399d1a9d300e2251600a8c5aba..9229ba63c37086a86af0a4b17dcde17012eff732 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -203,9 +203,8 @@ static int __kprobes __die(const char *str, struct pt_regs *regs, long err) #ifdef CONFIG_SMP printk("SMP NR_CPUS=%d ", NR_CPUS); #endif -#ifdef CONFIG_DEBUG_PAGEALLOC - printk("DEBUG_PAGEALLOC "); -#endif + if (debug_pagealloc_enabled()) + printk("DEBUG_PAGEALLOC "); #ifdef CONFIG_NUMA printk("NUMA "); #endif @@ -1148,6 +1147,7 @@ void __kprobes program_check_exception(struct pt_regs *regs) goto bail; } if (reason & REASON_TRAP) { + unsigned long bugaddr; /* Debugger is first in line to stop recursive faults in * rcu_lock, notify_die, or atomic_notifier_call_chain */ if (debugger_bpt(regs)) @@ -1158,8 +1158,15 @@ void __kprobes program_check_exception(struct pt_regs *regs) == NOTIFY_STOP) goto bail; + bugaddr = regs->nip; + /* + * Fixup bugaddr for BUG_ON() in real mode + */ + if (!is_kernel_addr(bugaddr) && !(regs->msr & MSR_IR)) + bugaddr += PAGE_OFFSET; + if (!(regs->msr & MSR_PR) && /* not user-mode */ - report_bug(regs->nip, regs) == BUG_TRAP_TYPE_WARN) { + report_bug(bugaddr, regs) == BUG_TRAP_TYPE_WARN) { regs->nip += 4; goto bail; } @@ -1394,7 +1401,7 @@ void facility_unavailable_exception(struct pt_regs *regs) * is a read DSCR attempt through a mfspr instruction, we * just emulate the instruction instead. This code path will * always emulate all the mfspr instructions till the user - * has attempted atleast one mtspr instruction. This way it + * has attempted at least one mtspr instruction. This way it * preserves the same behaviour when the user is accessing * the DSCR through privilege level only SPR number (0x11) * which is emulated through illegal instruction exception. diff --git a/arch/powerpc/kernel/vector.S b/arch/powerpc/kernel/vector.S index 162d0f7149419f50a7324e8e02086ab03bee993b..1c2e7a343bf5f195cfe4b53c37171056b0554a38 100644 --- a/arch/powerpc/kernel/vector.S +++ b/arch/powerpc/kernel/vector.S @@ -91,6 +91,10 @@ _GLOBAL(load_up_altivec) oris r12,r12,MSR_VEC@h std r12,_MSR(r1) #endif + /* Don't care if r4 overflows, this is desired behaviour */ + lbz r4,THREAD_LOAD_VEC(r5) + addi r4,r4,1 + stb r4,THREAD_LOAD_VEC(r5) addi r6,r5,THREAD_VRSTATE li r4,1 li r10,VRSTATE_VSCR @@ -102,36 +106,20 @@ _GLOBAL(load_up_altivec) blr /* - * __giveup_altivec(tsk) - * Disable VMX for the task given as the argument, - * and save the vector registers in its thread_struct. + * save_altivec(tsk) + * Save the vector registers to its thread_struct */ -_GLOBAL(__giveup_altivec) +_GLOBAL(save_altivec) addi r3,r3,THREAD /* want THREAD of task */ PPC_LL r7,THREAD_VRSAVEAREA(r3) PPC_LL r5,PT_REGS(r3) PPC_LCMPI 0,r7,0 bne 2f addi r7,r3,THREAD_VRSTATE -2: PPC_LCMPI 0,r5,0 - SAVE_32VRS(0,r4,r7) +2: SAVE_32VRS(0,r4,r7) mfvscr v0 li r4,VRSTATE_VSCR stvx v0,r4,r7 - beq 1f - PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5) -#ifdef CONFIG_VSX -BEGIN_FTR_SECTION - lis r3,(MSR_VEC|MSR_VSX)@h -FTR_SECTION_ELSE - lis r3,MSR_VEC@h -ALT_FTR_SECTION_END_IFSET(CPU_FTR_VSX) -#else - lis r3,MSR_VEC@h -#endif - andc r4,r4,r3 /* disable FP for previous task */ - PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5) -1: blr #ifdef CONFIG_VSX @@ -163,23 +151,6 @@ _GLOBAL(load_up_vsx) std r12,_MSR(r1) b fast_exception_return -/* - * __giveup_vsx(tsk) - * Disable VSX for the task given as the argument. - * Does NOT save vsx registers. - */ -_GLOBAL(__giveup_vsx) - addi r3,r3,THREAD /* want THREAD of task */ - ld r5,PT_REGS(r3) - cmpdi 0,r5,0 - beq 1f - ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) - lis r3,MSR_VSX@h - andc r4,r4,r3 /* disable VSX for previous task */ - std r4,_MSR-STACK_FRAME_OVERHEAD(r5) -1: - blr - #endif /* CONFIG_VSX */ diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index d41fd0af89807c5b3b5bb4e3e713bd09d4b94eaf..2dd91f79de05a729f2aca86f4467365dba4d35de 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -55,6 +55,7 @@ SECTIONS LOCK_TEXT KPROBES_TEXT IRQENTRY_TEXT + SOFTIRQENTRY_TEXT #ifdef CONFIG_PPC32 *(.got1) diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile index 7f7b6d86ac731af7241e4ce343a4ed6a8e0542c8..eba0bea6e032b67968771341dcaa1c0eb9624863 100644 --- a/arch/powerpc/kvm/Makefile +++ b/arch/powerpc/kvm/Makefile @@ -8,7 +8,8 @@ ccflags-y := -Ivirt/kvm -Iarch/powerpc/kvm KVM := ../../../virt/kvm common-objs-y = $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o \ - $(KVM)/eventfd.o $(KVM)/vfio.o + $(KVM)/eventfd.o +common-objs-$(CONFIG_KVM_VFIO) += $(KVM)/vfio.o CFLAGS_e500_mmu.o := -I. CFLAGS_e500_mmu_host.o := -I. diff --git a/arch/powerpc/kvm/book3s_32_mmu_host.c b/arch/powerpc/kvm/book3s_32_mmu_host.c index 55c4d51ea3e2bbbad7305b2ab0eca65d4b27bad9..999106991a76d5f5be4ea2a026b163ab572eab74 100644 --- a/arch/powerpc/kvm/book3s_32_mmu_host.c +++ b/arch/powerpc/kvm/book3s_32_mmu_host.c @@ -22,7 +22,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/powerpc/kvm/book3s_64_mmu.c b/arch/powerpc/kvm/book3s_64_mmu.c index 9bf7031a67ffc0aedf742e7a9da6afebeb8fe64b..b9131aa1aedf0d9430a80867582f19aa2dc941f0 100644 --- a/arch/powerpc/kvm/book3s_64_mmu.c +++ b/arch/powerpc/kvm/book3s_64_mmu.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include /* #define DEBUG_MMU */ diff --git a/arch/powerpc/kvm/book3s_64_mmu_host.c b/arch/powerpc/kvm/book3s_64_mmu_host.c index 913cd2198fa6df6f96daceda2f92958123c3a5dd..114edace6cddf380ba4099b259f64ff1895973ff 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_host.c +++ b/arch/powerpc/kvm/book3s_64_mmu_host.c @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c index fb37290a57b410eaede72333dceff3f677ace967..c7b78d8336b26d18873231225a1ed6c0bcdde3bc 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c index 2c2d1030843acf5736e4ac0dd08c87b3522f2b17..18cf6d1f81748ef4d4c0f32f4f21f69736e8e651 100644 --- a/arch/powerpc/kvm/book3s_64_vio.c +++ b/arch/powerpc/kvm/book3s_64_vio.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include #include @@ -209,6 +209,32 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm, return ret; } +long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn, + unsigned long ioba, unsigned long tce) +{ + struct kvmppc_spapr_tce_table *stt = kvmppc_find_table(vcpu, liobn); + long ret; + + /* udbg_printf("H_PUT_TCE(): liobn=0x%lx ioba=0x%lx, tce=0x%lx\n", */ + /* liobn, ioba, tce); */ + + if (!stt) + return H_TOO_HARD; + + ret = kvmppc_ioba_validate(stt, ioba, 1); + if (ret != H_SUCCESS) + return ret; + + ret = kvmppc_tce_validate(stt, tce); + if (ret != H_SUCCESS) + return ret; + + kvmppc_tce_put(stt, ioba >> stt->page_shift, tce); + + return H_SUCCESS; +} +EXPORT_SYMBOL_GPL(kvmppc_h_put_tce); + long kvmppc_h_put_tce_indirect(struct kvm_vcpu *vcpu, unsigned long liobn, unsigned long ioba, unsigned long tce_list, unsigned long npages) @@ -264,3 +290,29 @@ long kvmppc_h_put_tce_indirect(struct kvm_vcpu *vcpu, return ret; } EXPORT_SYMBOL_GPL(kvmppc_h_put_tce_indirect); + +long kvmppc_h_stuff_tce(struct kvm_vcpu *vcpu, + unsigned long liobn, unsigned long ioba, + unsigned long tce_value, unsigned long npages) +{ + struct kvmppc_spapr_tce_table *stt; + long i, ret; + + stt = kvmppc_find_table(vcpu, liobn); + if (!stt) + return H_TOO_HARD; + + ret = kvmppc_ioba_validate(stt, ioba, npages); + if (ret != H_SUCCESS) + return ret; + + /* Check permission bits only to allow userspace poison TCE for debug */ + if (tce_value & (TCE_PCI_WRITE | TCE_PCI_READ)) + return H_PARAMETER; + + for (i = 0; i < npages; ++i, ioba += (1ULL << stt->page_shift)) + kvmppc_tce_put(stt, ioba >> stt->page_shift, tce_value); + + return H_SUCCESS; +} +EXPORT_SYMBOL_GPL(kvmppc_h_stuff_tce); diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c index 44be73e6aa26b6563d1cc4cc91e1a332a84271c3..d461c440889aa1882d9fd68f46d98d94e3afed16 100644 --- a/arch/powerpc/kvm/book3s_64_vio_hv.c +++ b/arch/powerpc/kvm/book3s_64_vio_hv.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include #include @@ -180,8 +180,8 @@ long kvmppc_gpa_to_ua(struct kvm *kvm, unsigned long gpa, EXPORT_SYMBOL_GPL(kvmppc_gpa_to_ua); #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE -long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn, - unsigned long ioba, unsigned long tce) +long kvmppc_rm_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn, + unsigned long ioba, unsigned long tce) { struct kvmppc_spapr_tce_table *stt = kvmppc_find_table(vcpu, liobn); long ret; @@ -204,7 +204,6 @@ long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn, return H_SUCCESS; } -EXPORT_SYMBOL_GPL(kvmppc_h_put_tce); static long kvmppc_rm_ua_to_hpa(struct kvm_vcpu *vcpu, unsigned long ua, unsigned long *phpa) @@ -296,7 +295,7 @@ long kvmppc_rm_h_put_tce_indirect(struct kvm_vcpu *vcpu, return ret; } -long kvmppc_h_stuff_tce(struct kvm_vcpu *vcpu, +long kvmppc_rm_h_stuff_tce(struct kvm_vcpu *vcpu, unsigned long liobn, unsigned long ioba, unsigned long tce_value, unsigned long npages) { @@ -320,7 +319,6 @@ long kvmppc_h_stuff_tce(struct kvm_vcpu *vcpu, return H_SUCCESS; } -EXPORT_SYMBOL_GPL(kvmppc_h_stuff_tce); long kvmppc_h_get_tce(struct kvm_vcpu *vcpu, unsigned long liobn, unsigned long ioba) diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c index 91700518bbf30491be41c8feebeb0d9df1329529..4cb8db05f3e55007a1ee54feaf6864d841020e9c 100644 --- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c +++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index 85b32f16fa74e02a2fa753a62ecaf2c728e3eb2a..e571ad277398fd6625499c05ae03cde47a46d20a 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #define VCPU_GPRS_TM(reg) (((reg) * ULONG_SIZE) + VCPU_GPR_TM) @@ -1942,7 +1942,7 @@ hcall_real_table: .long DOTSYM(kvmppc_h_clear_ref) - hcall_real_table .long DOTSYM(kvmppc_h_protect) - hcall_real_table .long DOTSYM(kvmppc_h_get_tce) - hcall_real_table - .long DOTSYM(kvmppc_h_put_tce) - hcall_real_table + .long DOTSYM(kvmppc_rm_h_put_tce) - hcall_real_table .long 0 /* 0x24 - H_SET_SPRG0 */ .long DOTSYM(kvmppc_h_set_dabr) - hcall_real_table .long 0 /* 0x2c */ @@ -2020,7 +2020,7 @@ hcall_real_table: .long 0 /* 0x12c */ .long 0 /* 0x130 */ .long DOTSYM(kvmppc_h_set_xdabr) - hcall_real_table - .long DOTSYM(kvmppc_h_stuff_tce) - hcall_real_table + .long DOTSYM(kvmppc_rm_h_stuff_tce) - hcall_real_table .long DOTSYM(kvmppc_rm_h_put_tce_indirect) - hcall_real_table .long 0 /* 0x140 */ .long 0 /* 0x144 */ diff --git a/arch/powerpc/kvm/book3s_xics.c b/arch/powerpc/kvm/book3s_xics.c index 905e94a1370f4982060b4d917e6fb5b8202d4fd3..46871d554057a7e841af248d09e05779513b9506 100644 --- a/arch/powerpc/kvm/book3s_xics.c +++ b/arch/powerpc/kvm/book3s_xics.c @@ -432,7 +432,7 @@ static void icp_deliver_irq(struct kvmppc_xics *xics, struct kvmppc_icp *icp, * the whole masked_pending business which is about not * losing interrupts that occur while masked. * - * I don't differenciate normal deliveries and resends, this + * I don't differentiate normal deliveries and resends, this * implementation will differ from PAPR and not lose such * interrupts. */ diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index 778ef86e187eca40d63585a54b3d0ff4161ba613..4d66f44a165789df702242c622024a269da745a2 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -992,7 +992,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, kvmppc_restart_interrupt(vcpu, exit_nr); /* - * get last instruction before beeing preempted + * get last instruction before being preempted * TODO: for e6500 check also BOOKE_INTERRUPT_LRAT_ERROR & ESR_DATA */ switch (exit_nr) { diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c index cda695de8aa7b336266543cb1c560a02dddbc7b0..f48a0c22e8f9024e87965df7b0821596d43c926a 100644 --- a/arch/powerpc/kvm/e500mc.c +++ b/arch/powerpc/kvm/e500mc.c @@ -182,7 +182,7 @@ int kvmppc_core_check_processor_compat(void) r = 0; #ifdef CONFIG_ALTIVEC /* - * Since guests have the priviledge to enable AltiVec, we need AltiVec + * Since guests have the privilege to enable AltiVec, we need AltiVec * support in the host to save/restore their context. * Don't use CPU_FTR_ALTIVEC to identify cores with AltiVec unit * because it's cleared in the absence of CONFIG_ALTIVEC! diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 19aa59b0850cf73489d5f61623794da607a6fc41..6a68730774ee7dd701358cbc6cfce36c37db4009 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -96,6 +96,9 @@ int kvmppc_prepare_to_enter(struct kvm_vcpu *vcpu) * so we don't miss a request because the requester sees * OUTSIDE_GUEST_MODE and assumes we'll be checking requests * before next entering the guest (and thus doesn't IPI). + * This also orders the write to mode from any reads + * to the page tables done while the VCPU is running. + * Please see the comment in kvm_flush_remote_tlbs. */ smp_mb(); diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index a47e14277fd8a91d1d4a255592db73a979a94f1b..ba21be15310f3ebd877ad5bf15e8858323932f96 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -6,8 +6,8 @@ subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC) -CFLAGS_REMOVE_code-patching.o = -pg -CFLAGS_REMOVE_feature-fixups.o = -pg +CFLAGS_REMOVE_code-patching.o = $(CC_FLAGS_FTRACE) +CFLAGS_REMOVE_feature-fixups.o = $(CC_FLAGS_FTRACE) obj-y += string.o alloc.o crtsavres.o ppc_ksyms.o code-patching.o \ feature-fixups.o @@ -22,8 +22,7 @@ obj64-$(CONFIG_SMP) += locks.o obj64-$(CONFIG_ALTIVEC) += vmx-helper.o ifeq ($(CONFIG_GENERIC_CSUM),) -obj-y += checksum_$(CONFIG_WORD_SIZE).o -obj-$(CONFIG_PPC64) += checksum_wrappers_64.o +obj-y += checksum_$(CONFIG_WORD_SIZE).o checksum_wrappers.o endif obj-$(CONFIG_PPC_EMULATE_SSTEP) += sstep.o ldstfp.o diff --git a/arch/powerpc/lib/checksum_32.S b/arch/powerpc/lib/checksum_32.S index 6d67e057f15ecd342e1b4d6cd7050a144325bd40..d90870a66b60b4b0820a3044466f70716e1ed610 100644 --- a/arch/powerpc/lib/checksum_32.S +++ b/arch/powerpc/lib/checksum_32.S @@ -14,68 +14,59 @@ #include #include +#include #include #include .text -/* - * ip_fast_csum(buf, len) -- Optimized for IP header - * len is in words and is always >= 5. - */ -_GLOBAL(ip_fast_csum) - lwz r0,0(r3) - lwzu r5,4(r3) - addic. r4,r4,-2 - addc r0,r0,r5 - mtctr r4 - blelr- -1: lwzu r4,4(r3) - adde r0,r0,r4 - bdnz 1b - addze r0,r0 /* add in final carry */ - rlwinm r3,r0,16,0,31 /* fold two halves together */ - add r3,r0,r3 - not r3,r3 - srwi r3,r3,16 - blr - /* * computes the checksum of a memory block at buff, length len, * and adds in "sum" (32-bit) * - * csum_partial(buff, len, sum) + * __csum_partial(buff, len, sum) */ -_GLOBAL(csum_partial) - addic r0,r5,0 +_GLOBAL(__csum_partial) subi r3,r3,4 - srwi. r6,r4,2 + srawi. r6,r4,2 /* Divide len by 4 and also clear carry */ beq 3f /* if we're doing < 4 bytes */ - andi. r5,r3,2 /* Align buffer to longword boundary */ + andi. r0,r3,2 /* Align buffer to longword boundary */ beq+ 1f - lhz r5,4(r3) /* do 2 bytes to get aligned */ - addi r3,r3,2 + lhz r0,4(r3) /* do 2 bytes to get aligned */ subi r4,r4,2 - addc r0,r0,r5 + addi r3,r3,2 srwi. r6,r4,2 /* # words to do */ + adde r5,r5,r0 beq 3f -1: mtctr r6 -2: lwzu r5,4(r3) /* the bdnz has zero overhead, so it should */ - adde r0,r0,r5 /* be unnecessary to unroll this loop */ +1: andi. r6,r6,3 /* Prepare to handle words 4 by 4 */ + beq 21f + mtctr r6 +2: lwzu r0,4(r3) + adde r5,r5,r0 bdnz 2b - andi. r4,r4,3 -3: cmpwi 0,r4,2 - blt+ 4f - lhz r5,4(r3) +21: srwi. r6,r4,4 /* # blocks of 4 words to do */ + beq 3f + mtctr r6 +22: lwz r0,4(r3) + lwz r6,8(r3) + lwz r7,12(r3) + lwzu r8,16(r3) + adde r5,r5,r0 + adde r5,r5,r6 + adde r5,r5,r7 + adde r5,r5,r8 + bdnz 22b +3: andi. r0,r4,2 + beq+ 4f + lhz r0,4(r3) addi r3,r3,2 - subi r4,r4,2 - adde r0,r0,r5 -4: cmpwi 0,r4,1 - bne+ 5f - lbz r5,4(r3) - slwi r5,r5,8 /* Upper byte of word */ - adde r0,r0,r5 -5: addze r3,r0 /* add in final carry */ + adde r5,r5,r0 +4: andi. r0,r4,1 + beq+ 5f + lbz r0,4(r3) + slwi r0,r0,8 /* Upper byte of word */ + adde r5,r5,r0 +5: addze r3,r5 /* add in final carry */ blr /* @@ -87,123 +78,220 @@ _GLOBAL(csum_partial) * * csum_partial_copy_generic(src, dst, len, sum, src_err, dst_err) */ +#define CSUM_COPY_16_BYTES_WITHEX(n) \ +8 ## n ## 0: \ + lwz r7,4(r4); \ +8 ## n ## 1: \ + lwz r8,8(r4); \ +8 ## n ## 2: \ + lwz r9,12(r4); \ +8 ## n ## 3: \ + lwzu r10,16(r4); \ +8 ## n ## 4: \ + stw r7,4(r6); \ + adde r12,r12,r7; \ +8 ## n ## 5: \ + stw r8,8(r6); \ + adde r12,r12,r8; \ +8 ## n ## 6: \ + stw r9,12(r6); \ + adde r12,r12,r9; \ +8 ## n ## 7: \ + stwu r10,16(r6); \ + adde r12,r12,r10 + +#define CSUM_COPY_16_BYTES_EXCODE(n) \ +.section __ex_table,"a"; \ + .align 2; \ + .long 8 ## n ## 0b,src_error; \ + .long 8 ## n ## 1b,src_error; \ + .long 8 ## n ## 2b,src_error; \ + .long 8 ## n ## 3b,src_error; \ + .long 8 ## n ## 4b,dst_error; \ + .long 8 ## n ## 5b,dst_error; \ + .long 8 ## n ## 6b,dst_error; \ + .long 8 ## n ## 7b,dst_error; \ + .text + + .text + .stabs "arch/powerpc/lib/",N_SO,0,0,0f + .stabs "checksum_32.S",N_SO,0,0,0f +0: + +CACHELINE_BYTES = L1_CACHE_BYTES +LG_CACHELINE_BYTES = L1_CACHE_SHIFT +CACHELINE_MASK = (L1_CACHE_BYTES-1) + _GLOBAL(csum_partial_copy_generic) - addic r0,r6,0 - subi r3,r3,4 - subi r4,r4,4 - srwi. r6,r5,2 - beq 3f /* if we're doing < 4 bytes */ - andi. r9,r4,2 /* Align dst to longword boundary */ - beq+ 1f -81: lhz r6,4(r3) /* do 2 bytes to get aligned */ - addi r3,r3,2 - subi r5,r5,2 -91: sth r6,4(r4) - addi r4,r4,2 - addc r0,r0,r6 - srwi. r6,r5,2 /* # words to do */ - beq 3f -1: srwi. r6,r5,4 /* # groups of 4 words to do */ - beq 10f - mtctr r6 -71: lwz r6,4(r3) -72: lwz r9,8(r3) -73: lwz r10,12(r3) -74: lwzu r11,16(r3) - adde r0,r0,r6 -75: stw r6,4(r4) - adde r0,r0,r9 -76: stw r9,8(r4) - adde r0,r0,r10 -77: stw r10,12(r4) - adde r0,r0,r11 -78: stwu r11,16(r4) - bdnz 71b -10: rlwinm. r6,r5,30,30,31 /* # words left to do */ - beq 13f - mtctr r6 -82: lwzu r9,4(r3) -92: stwu r9,4(r4) - adde r0,r0,r9 - bdnz 82b -13: andi. r5,r5,3 -3: cmpwi 0,r5,2 - blt+ 4f -83: lhz r6,4(r3) - addi r3,r3,2 - subi r5,r5,2 -93: sth r6,4(r4) + stwu r1,-16(r1) + stw r7,12(r1) + stw r8,8(r1) + + andi. r0,r4,1 /* is destination address even ? */ + cmplwi cr7,r0,0 + addic r12,r6,0 + addi r6,r4,-4 + neg r0,r4 + addi r4,r3,-4 + andi. r0,r0,CACHELINE_MASK /* # bytes to start of cache line */ + beq 58f + + cmplw 0,r5,r0 /* is this more than total to do? */ + blt 63f /* if not much to do */ + andi. r8,r0,3 /* get it word-aligned first */ + mtctr r8 + beq+ 61f + li r3,0 +70: lbz r9,4(r4) /* do some bytes */ + addi r4,r4,1 + slwi r3,r3,8 + rlwimi r3,r9,0,24,31 +71: stb r9,4(r6) + addi r6,r6,1 + bdnz 70b + adde r12,r12,r3 +61: subf r5,r0,r5 + srwi. r0,r0,2 + mtctr r0 + beq 58f +72: lwzu r9,4(r4) /* do some words */ + adde r12,r12,r9 +73: stwu r9,4(r6) + bdnz 72b + +58: srwi. r0,r5,LG_CACHELINE_BYTES /* # complete cachelines */ + clrlwi r5,r5,32-LG_CACHELINE_BYTES + li r11,4 + beq 63f + + /* Here we decide how far ahead to prefetch the source */ + li r3,4 + cmpwi r0,1 + li r7,0 + ble 114f + li r7,1 +#if MAX_COPY_PREFETCH > 1 + /* Heuristically, for large transfers we prefetch + MAX_COPY_PREFETCH cachelines ahead. For small transfers + we prefetch 1 cacheline ahead. */ + cmpwi r0,MAX_COPY_PREFETCH + ble 112f + li r7,MAX_COPY_PREFETCH +112: mtctr r7 +111: dcbt r3,r4 + addi r3,r3,CACHELINE_BYTES + bdnz 111b +#else + dcbt r3,r4 + addi r3,r3,CACHELINE_BYTES +#endif /* MAX_COPY_PREFETCH > 1 */ + +114: subf r8,r7,r0 + mr r0,r7 + mtctr r8 + +53: dcbt r3,r4 +54: dcbz r11,r6 +/* the main body of the cacheline loop */ + CSUM_COPY_16_BYTES_WITHEX(0) +#if L1_CACHE_BYTES >= 32 + CSUM_COPY_16_BYTES_WITHEX(1) +#if L1_CACHE_BYTES >= 64 + CSUM_COPY_16_BYTES_WITHEX(2) + CSUM_COPY_16_BYTES_WITHEX(3) +#if L1_CACHE_BYTES >= 128 + CSUM_COPY_16_BYTES_WITHEX(4) + CSUM_COPY_16_BYTES_WITHEX(5) + CSUM_COPY_16_BYTES_WITHEX(6) + CSUM_COPY_16_BYTES_WITHEX(7) +#endif +#endif +#endif + bdnz 53b + cmpwi r0,0 + li r3,4 + li r7,0 + bne 114b + +63: srwi. r0,r5,2 + mtctr r0 + beq 64f +30: lwzu r0,4(r4) + adde r12,r12,r0 +31: stwu r0,4(r6) + bdnz 30b + +64: andi. r0,r5,2 + beq+ 65f +40: lhz r0,4(r4) addi r4,r4,2 - adde r0,r0,r6 -4: cmpwi 0,r5,1 - bne+ 5f -84: lbz r6,4(r3) -94: stb r6,4(r4) - slwi r6,r6,8 /* Upper byte of word */ - adde r0,r0,r6 -5: addze r3,r0 /* add in final carry */ +41: sth r0,4(r6) + adde r12,r12,r0 + addi r6,r6,2 +65: andi. r0,r5,1 + beq+ 66f +50: lbz r0,4(r4) +51: stb r0,4(r6) + slwi r0,r0,8 + adde r12,r12,r0 +66: addze r3,r12 + addi r1,r1,16 + beqlr+ cr7 + rlwinm r3,r3,8,0,31 /* swap bytes for odd destination */ blr -/* These shouldn't go in the fixup section, since that would - cause the ex_table addresses to get out of order. */ - -src_error_4: - mfctr r6 /* update # bytes remaining from ctr */ - rlwimi r5,r6,4,0,27 - b 79f -src_error_1: - li r6,0 - subi r5,r5,2 -95: sth r6,4(r4) - addi r4,r4,2 -79: srwi. r6,r5,2 - beq 3f - mtctr r6 -src_error_2: - li r6,0 -96: stwu r6,4(r4) - bdnz 96b -3: andi. r5,r5,3 - beq src_error -src_error_3: - li r6,0 - mtctr r5 - addi r4,r4,3 -97: stbu r6,1(r4) - bdnz 97b +/* read fault */ src_error: - cmpwi 0,r7,0 - beq 1f - li r6,-EFAULT - stw r6,0(r7) -1: addze r3,r0 + lwz r7,12(r1) + addi r1,r1,16 + cmpwi cr0,r7,0 + beqlr + li r0,-EFAULT + stw r0,0(r7) blr - +/* write fault */ dst_error: - cmpwi 0,r8,0 - beq 1f - li r6,-EFAULT - stw r6,0(r8) -1: addze r3,r0 + lwz r8,8(r1) + addi r1,r1,16 + cmpwi cr0,r8,0 + beqlr + li r0,-EFAULT + stw r0,0(r8) blr -.section __ex_table,"a" - .long 81b,src_error_1 - .long 91b,dst_error - .long 71b,src_error_4 - .long 72b,src_error_4 - .long 73b,src_error_4 - .long 74b,src_error_4 - .long 75b,dst_error - .long 76b,dst_error - .long 77b,dst_error - .long 78b,dst_error - .long 82b,src_error_2 - .long 92b,dst_error - .long 83b,src_error_3 - .long 93b,dst_error - .long 84b,src_error_3 - .long 94b,dst_error - .long 95b,dst_error - .long 96b,dst_error - .long 97b,dst_error + .section __ex_table,"a" + .align 2 + .long 70b,src_error + .long 71b,dst_error + .long 72b,src_error + .long 73b,dst_error + .long 54b,dst_error + .text + +/* + * this stuff handles faults in the cacheline loop and branches to either + * src_error (if in read part) or dst_error (if in write part) + */ + CSUM_COPY_16_BYTES_EXCODE(0) +#if L1_CACHE_BYTES >= 32 + CSUM_COPY_16_BYTES_EXCODE(1) +#if L1_CACHE_BYTES >= 64 + CSUM_COPY_16_BYTES_EXCODE(2) + CSUM_COPY_16_BYTES_EXCODE(3) +#if L1_CACHE_BYTES >= 128 + CSUM_COPY_16_BYTES_EXCODE(4) + CSUM_COPY_16_BYTES_EXCODE(5) + CSUM_COPY_16_BYTES_EXCODE(6) + CSUM_COPY_16_BYTES_EXCODE(7) +#endif +#endif +#endif + + .section __ex_table,"a" + .align 2 + .long 30b,src_error + .long 31b,dst_error + .long 40b,src_error + .long 41b,dst_error + .long 50b,src_error + .long 51b,dst_error diff --git a/arch/powerpc/lib/checksum_64.S b/arch/powerpc/lib/checksum_64.S index f3ef35436612b75505bfabe5cf5b6761208c3d70..8e6e51016cc51e33ce28399541425c12a6c0da0f 100644 --- a/arch/powerpc/lib/checksum_64.S +++ b/arch/powerpc/lib/checksum_64.S @@ -17,40 +17,13 @@ #include #include -/* - * ip_fast_csum(r3=buf, r4=len) -- Optimized for IP header - * len is in words and is always >= 5. - * - * In practice len == 5, but this is not guaranteed. So this code does not - * attempt to use doubleword instructions. - */ -_GLOBAL(ip_fast_csum) - lwz r0,0(r3) - lwzu r5,4(r3) - addic. r4,r4,-2 - addc r0,r0,r5 - mtctr r4 - blelr- -1: lwzu r4,4(r3) - adde r0,r0,r4 - bdnz 1b - addze r0,r0 /* add in final carry */ - rldicl r4,r0,32,0 /* fold two 32-bit halves together */ - add r0,r0,r4 - srdi r0,r0,32 - rlwinm r3,r0,16,0,31 /* fold two halves together */ - add r3,r0,r3 - not r3,r3 - srwi r3,r3,16 - blr - /* * Computes the checksum of a memory block at buff, length len, * and adds in "sum" (32-bit). * - * csum_partial(r3=buff, r4=len, r5=sum) + * __csum_partial(r3=buff, r4=len, r5=sum) */ -_GLOBAL(csum_partial) +_GLOBAL(__csum_partial) addic r0,r5,0 /* clear carry */ srdi. r6,r4,3 /* less than 8 bytes? */ diff --git a/arch/powerpc/lib/checksum_wrappers_64.c b/arch/powerpc/lib/checksum_wrappers.c similarity index 100% rename from arch/powerpc/lib/checksum_wrappers_64.c rename to arch/powerpc/lib/checksum_wrappers.c diff --git a/arch/powerpc/lib/ppc_ksyms.c b/arch/powerpc/lib/ppc_ksyms.c index c7f8e9586316181e48079258aedc39abe381b6ae..c422812f74054e7e20442160eb65f77bf29bffa6 100644 --- a/arch/powerpc/lib/ppc_ksyms.c +++ b/arch/powerpc/lib/ppc_ksyms.c @@ -17,10 +17,8 @@ EXPORT_SYMBOL(strcmp); EXPORT_SYMBOL(strncmp); #ifndef CONFIG_GENERIC_CSUM -EXPORT_SYMBOL(csum_partial); +EXPORT_SYMBOL(__csum_partial); EXPORT_SYMBOL(csum_partial_copy_generic); -EXPORT_SYMBOL(ip_fast_csum); -EXPORT_SYMBOL(csum_tcpudp_magic); #endif EXPORT_SYMBOL(__copy_tofrom_user); diff --git a/arch/powerpc/mm/8xx_mmu.c b/arch/powerpc/mm/8xx_mmu.c new file mode 100644 index 0000000000000000000000000000000000000000..949100577db536f389cbff597d21a5742e107715 --- /dev/null +++ b/arch/powerpc/mm/8xx_mmu.c @@ -0,0 +1,141 @@ +/* + * This file contains the routines for initializing the MMU + * on the 8xx series of chips. + * -- christophe + * + * Derived from arch/powerpc/mm/40x_mmu.c: + * + * 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 "mmu_decl.h" + +extern int __map_without_ltlbs; +/* + * MMU_init_hw does the chip-specific initialization of the MMU hardware. + */ +void __init MMU_init_hw(void) +{ + /* Nothing to do for the time being but keep it similar to other PPC */ +} + +#define LARGE_PAGE_SIZE_4M (1<<22) +#define LARGE_PAGE_SIZE_8M (1<<23) +#define LARGE_PAGE_SIZE_64M (1<<26) + +unsigned long __init mmu_mapin_ram(unsigned long top) +{ + unsigned long v, s, mapped; + phys_addr_t p; + + v = KERNELBASE; + p = 0; + s = top; + + if (__map_without_ltlbs) + return 0; + +#ifdef CONFIG_PPC_4K_PAGES + while (s >= LARGE_PAGE_SIZE_8M) { + pmd_t *pmdp; + unsigned long val = p | MD_PS8MEG; + + pmdp = pmd_offset(pud_offset(pgd_offset_k(v), v), v); + *pmdp++ = __pmd(val); + *pmdp++ = __pmd(val + LARGE_PAGE_SIZE_4M); + + v += LARGE_PAGE_SIZE_8M; + p += LARGE_PAGE_SIZE_8M; + s -= LARGE_PAGE_SIZE_8M; + } +#else /* CONFIG_PPC_16K_PAGES */ + while (s >= LARGE_PAGE_SIZE_64M) { + pmd_t *pmdp; + unsigned long val = p | MD_PS8MEG; + + pmdp = pmd_offset(pud_offset(pgd_offset_k(v), v), v); + *pmdp++ = __pmd(val); + + v += LARGE_PAGE_SIZE_64M; + p += LARGE_PAGE_SIZE_64M; + s -= LARGE_PAGE_SIZE_64M; + } +#endif + + mapped = top - s; + + /* If the size of RAM is not an exact power of two, we may not + * have covered RAM in its entirety with 8 MiB + * pages. Consequently, restrict the top end of RAM currently + * allocable so that calls to the MEMBLOCK to allocate PTEs for "tail" + * coverage with normal-sized pages (or other reasons) do not + * attempt to allocate outside the allowed range. + */ + memblock_set_current_limit(mapped); + + return mapped; +} + +void setup_initial_memory_limit(phys_addr_t first_memblock_base, + phys_addr_t first_memblock_size) +{ + /* We don't currently support the first MEMBLOCK not mapping 0 + * physical on those processors + */ + BUG_ON(first_memblock_base != 0); + +#ifdef CONFIG_PIN_TLB + /* 8xx can only access 24MB at the moment */ + memblock_set_current_limit(min_t(u64, first_memblock_size, 0x01800000)); +#else + /* 8xx can only access 8MB at the moment */ + memblock_set_current_limit(min_t(u64, first_memblock_size, 0x00800000)); +#endif +} + +/* + * Set up to use a given MMU context. + * id is context number, pgd is PGD pointer. + * + * We place the physical address of the new task page directory loaded + * into the MMU base register, and set the ASID compare register with + * the new "context." + */ +void set_context(unsigned long id, pgd_t *pgd) +{ + s16 offset = (s16)(__pa(swapper_pg_dir)); + +#ifdef CONFIG_BDI_SWITCH + pgd_t **ptr = *(pgd_t ***)(KERNELBASE + 0xf0); + + /* Context switch the PTE pointer for the Abatron BDI2000. + * The PGDIR is passed as second argument. + */ + *(ptr + 1) = pgd; +#endif + + /* Register M_TW will contain base address of level 1 table minus the + * lower part of the kernel PGDIR base address, so that all accesses to + * level 1 table are done relative to lower part of kernel PGDIR base + * address. + */ + mtspr(SPRN_M_TW, __pa(pgd) - offset); + + /* Update context */ + mtspr(SPRN_M_CASID, id); + /* sync */ + mb(); +} + +void flush_instruction_cache(void) +{ + isync(); + mtspr(SPRN_IC_CST, IDC_INVALL); + isync(); +} diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile index 1ffeda85c08615f6f1583995608892f1058fb284..adfee3f1aeb9e7d7b8c47a4366a3a1dc05a5224f 100644 --- a/arch/powerpc/mm/Makefile +++ b/arch/powerpc/mm/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_PPC_ICSWX) += icswx.o obj-$(CONFIG_PPC_ICSWX_PID) += icswx_pid.o obj-$(CONFIG_40x) += 40x_mmu.o obj-$(CONFIG_44x) += 44x_mmu.o +obj-$(CONFIG_PPC_8xx) += 8xx_mmu.o obj-$(CONFIG_PPC_FSL_BOOK3E) += fsl_booke_mmu.o obj-$(CONFIG_NEED_MULTIPLE_NODES) += numa.o obj-$(CONFIG_PPC_SPLPAR) += vphn.o diff --git a/arch/powerpc/mm/dma-noncoherent.c b/arch/powerpc/mm/dma-noncoherent.c index 169aba446a7403d390717bfc57d621b16a455bfa..2dc74e5c64584e237a854be90f317d3f2d52c1da 100644 --- a/arch/powerpc/mm/dma-noncoherent.c +++ b/arch/powerpc/mm/dma-noncoherent.c @@ -327,7 +327,7 @@ void __dma_sync(void *vaddr, size_t size, int direction) * invalidate only when cache-line aligned otherwise there is * the potential for discarding uncommitted data from the cache */ - if ((start & (L1_CACHE_BYTES - 1)) || (size & (L1_CACHE_BYTES - 1))) + if ((start | end) & (L1_CACHE_BYTES - 1)) flush_dcache_range(start, end); else invalidate_dcache_range(start, end); diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c index f3afe3d97f6b3bd26ef344e44611a2e2cd0d5460..a1b2713f6e96aa96424519d9fe3d109c160154bd 100644 --- a/arch/powerpc/mm/fsl_booke_mmu.c +++ b/arch/powerpc/mm/fsl_booke_mmu.c @@ -72,10 +72,11 @@ unsigned long tlbcam_sz(int idx) return tlbcam_addrs[idx].limit - tlbcam_addrs[idx].start + 1; } +#ifdef CONFIG_FSL_BOOKE /* * Return PA for this VA if it is mapped by a CAM, or 0 */ -phys_addr_t v_mapped_by_tlbcam(unsigned long va) +phys_addr_t v_block_mapped(unsigned long va) { int b; for (b = 0; b < tlbcam_index; ++b) @@ -87,7 +88,7 @@ phys_addr_t v_mapped_by_tlbcam(unsigned long va) /* * Return VA for a given PA or 0 if not mapped */ -unsigned long p_mapped_by_tlbcam(phys_addr_t pa) +unsigned long p_block_mapped(phys_addr_t pa) { int b; for (b = 0; b < tlbcam_index; ++b) @@ -97,6 +98,7 @@ unsigned long p_mapped_by_tlbcam(phys_addr_t pa) return tlbcam_addrs[b].start+(pa-tlbcam_addrs[b].phys); return 0; } +#endif /* * Set up a variable-size TLB entry (tlbcam). The parameters are not checked; diff --git a/arch/powerpc/mm/hash64_4k.c b/arch/powerpc/mm/hash64_4k.c index e7c04542ba62255d7547f5e204724c5d85e46c4a..47d1b26effc6a71115d371599590496fc2dd5b96 100644 --- a/arch/powerpc/mm/hash64_4k.c +++ b/arch/powerpc/mm/hash64_4k.c @@ -44,7 +44,7 @@ int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid, * a write access. Since this is 4K insert of 64K page size * also add _PAGE_COMBO */ - new_pte = old_pte | _PAGE_BUSY | _PAGE_ACCESSED | _PAGE_HASHPTE; + new_pte = old_pte | _PAGE_BUSY | _PAGE_ACCESSED; if (access & _PAGE_RW) new_pte |= _PAGE_DIRTY; } while (old_pte != __cmpxchg_u64((unsigned long *)ptep, @@ -106,7 +106,7 @@ int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid, } } /* - * Hypervisor failure. Restore old pmd and return -1 + * Hypervisor failure. Restore old pte and return -1 * similar to __hash_page_* */ if (unlikely(slot == -2)) { diff --git a/arch/powerpc/mm/hash64_64k.c b/arch/powerpc/mm/hash64_64k.c index edb09912f0c9b5ca316216bf3d912c7efe8d920a..b2d659cf51c664f1379b8748feaa72146a146590 100644 --- a/arch/powerpc/mm/hash64_64k.c +++ b/arch/powerpc/mm/hash64_64k.c @@ -188,7 +188,7 @@ int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid, } } /* - * Hypervisor failure. Restore old pmd and return -1 + * Hypervisor failure. Restore old pte and return -1 * similar to __hash_page_* */ if (unlikely(slot == -2)) { @@ -249,8 +249,7 @@ int __hash_page_64K(unsigned long ea, unsigned long access, return 0; /* * Try to lock the PTE, add ACCESSED and DIRTY if it was - * a write access. Since this is 4K insert of 64K page size - * also add _PAGE_COMBO + * a write access. */ new_pte = old_pte | _PAGE_BUSY | _PAGE_ACCESSED; if (access & _PAGE_RW) @@ -311,7 +310,7 @@ int __hash_page_64K(unsigned long ea, unsigned long access, } } /* - * Hypervisor failure. Restore old pmd and return -1 + * Hypervisor failure. Restore old pte and return -1 * similar to __hash_page_* */ if (unlikely(slot == -2)) { diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index ba59d5977f3498d4c9c4e42faeff5111f925d2a5..7635b1c6b5dacfd04793315c31069a42a425e402 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -168,11 +168,11 @@ unsigned long htab_convert_pte_flags(unsigned long pteflags) rflags |= HPTE_R_N; /* * PP bits: - * Linux use slb key 0 for kernel and 1 for user. - * kernel areas are mapped by PP bits 00 - * and and there is no kernel RO (_PAGE_KERNEL_RO). - * User area mapped by 0x2 and read only use by - * 0x3. + * Linux uses slb key 0 for kernel and 1 for user. + * kernel areas are mapped with PP=00 + * and there is no kernel RO (_PAGE_KERNEL_RO). + * User area is mapped with PP=0x2 for read/write + * or PP=0x3 for read-only (including writeable but clean pages). */ if (pteflags & _PAGE_USER) { rflags |= 0x2; @@ -255,36 +255,42 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend, if (ret < 0) break; + #ifdef CONFIG_DEBUG_PAGEALLOC - if ((paddr >> PAGE_SHIFT) < linear_map_hash_count) + if (debug_pagealloc_enabled() && + (paddr >> PAGE_SHIFT) < linear_map_hash_count) linear_map_hash_slots[paddr >> PAGE_SHIFT] = ret | 0x80; #endif /* CONFIG_DEBUG_PAGEALLOC */ } return ret < 0 ? ret : 0; } -#ifdef CONFIG_MEMORY_HOTPLUG int htab_remove_mapping(unsigned long vstart, unsigned long vend, int psize, int ssize) { unsigned long vaddr; unsigned int step, shift; + int rc; + int ret = 0; shift = mmu_psize_defs[psize].shift; step = 1 << shift; - if (!ppc_md.hpte_removebolted) { - printk(KERN_WARNING "Platform doesn't implement " - "hpte_removebolted\n"); - return -EINVAL; - } + if (!ppc_md.hpte_removebolted) + return -ENODEV; - for (vaddr = vstart; vaddr < vend; vaddr += step) - ppc_md.hpte_removebolted(vaddr, psize, ssize); + for (vaddr = vstart; vaddr < vend; vaddr += step) { + rc = ppc_md.hpte_removebolted(vaddr, psize, ssize); + if (rc == -ENOENT) { + ret = -ENOENT; + continue; + } + if (rc < 0) + return rc; + } - return 0; + return ret; } -#endif /* CONFIG_MEMORY_HOTPLUG */ static int __init htab_dt_scan_seg_sizes(unsigned long node, const char *uname, int depth, @@ -512,17 +518,17 @@ static void __init htab_init_page_sizes(void) if (mmu_has_feature(MMU_FTR_16M_PAGE)) memcpy(mmu_psize_defs, mmu_psize_defaults_gp, sizeof(mmu_psize_defaults_gp)); - found: -#ifndef CONFIG_DEBUG_PAGEALLOC - /* - * Pick a size for the linear mapping. Currently, we only support - * 16M, 1M and 4K which is the default - */ - if (mmu_psize_defs[MMU_PAGE_16M].shift) - mmu_linear_psize = MMU_PAGE_16M; - else if (mmu_psize_defs[MMU_PAGE_1M].shift) - mmu_linear_psize = MMU_PAGE_1M; -#endif /* CONFIG_DEBUG_PAGEALLOC */ +found: + if (!debug_pagealloc_enabled()) { + /* + * Pick a size for the linear mapping. Currently, we only + * support 16M, 1M and 4K which is the default + */ + if (mmu_psize_defs[MMU_PAGE_16M].shift) + mmu_linear_psize = MMU_PAGE_16M; + else if (mmu_psize_defs[MMU_PAGE_1M].shift) + mmu_linear_psize = MMU_PAGE_1M; + } #ifdef CONFIG_PPC_64K_PAGES /* @@ -605,10 +611,28 @@ static int __init htab_dt_scan_pftsize(unsigned long node, return 0; } -static unsigned long __init htab_get_table_size(void) +unsigned htab_shift_for_mem_size(unsigned long mem_size) { - unsigned long mem_size, rnd_mem_size, pteg_count, psize; + unsigned memshift = __ilog2(mem_size); + unsigned pshift = mmu_psize_defs[mmu_virtual_psize].shift; + unsigned pteg_shift; + /* round mem_size up to next power of 2 */ + if ((1UL << memshift) < mem_size) + memshift += 1; + + /* aim for 2 pages / pteg */ + pteg_shift = memshift - (pshift + 1); + + /* + * 2^11 PTEGS of 128 bytes each, ie. 2^18 bytes is the minimum htab + * size permitted by the architecture. + */ + return max(pteg_shift + 7, 18U); +} + +static unsigned long __init htab_get_table_size(void) +{ /* If hash size isn't already provided by the platform, we try to * retrieve it from the device-tree. If it's not there neither, we * calculate it now based on the total RAM size @@ -618,31 +642,30 @@ static unsigned long __init htab_get_table_size(void) if (ppc64_pft_size) return 1UL << ppc64_pft_size; - /* round mem_size up to next power of 2 */ - mem_size = memblock_phys_mem_size(); - rnd_mem_size = 1UL << __ilog2(mem_size); - if (rnd_mem_size < mem_size) - rnd_mem_size <<= 1; - - /* # pages / 2 */ - psize = mmu_psize_defs[mmu_virtual_psize].shift; - pteg_count = max(rnd_mem_size >> (psize + 1), 1UL << 11); - - return pteg_count << 7; + return 1UL << htab_shift_for_mem_size(memblock_phys_mem_size()); } #ifdef CONFIG_MEMORY_HOTPLUG int create_section_mapping(unsigned long start, unsigned long end) { - return htab_bolt_mapping(start, end, __pa(start), - pgprot_val(PAGE_KERNEL), mmu_linear_psize, - mmu_kernel_ssize); + int rc = htab_bolt_mapping(start, end, __pa(start), + pgprot_val(PAGE_KERNEL), mmu_linear_psize, + mmu_kernel_ssize); + + if (rc < 0) { + int rc2 = htab_remove_mapping(start, end, mmu_linear_psize, + mmu_kernel_ssize); + BUG_ON(rc2 && (rc2 != -ENOENT)); + } + return rc; } int remove_section_mapping(unsigned long start, unsigned long end) { - return htab_remove_mapping(start, end, mmu_linear_psize, - mmu_kernel_ssize); + int rc = htab_remove_mapping(start, end, mmu_linear_psize, + mmu_kernel_ssize); + WARN_ON(rc < 0); + return rc; } #endif /* CONFIG_MEMORY_HOTPLUG */ @@ -721,10 +744,12 @@ static void __init htab_initialize(void) prot = pgprot_val(PAGE_KERNEL); #ifdef CONFIG_DEBUG_PAGEALLOC - linear_map_hash_count = memblock_end_of_DRAM() >> PAGE_SHIFT; - linear_map_hash_slots = __va(memblock_alloc_base(linear_map_hash_count, - 1, ppc64_rma_size)); - memset(linear_map_hash_slots, 0, linear_map_hash_count); + if (debug_pagealloc_enabled()) { + linear_map_hash_count = memblock_end_of_DRAM() >> PAGE_SHIFT; + linear_map_hash_slots = __va(memblock_alloc_base( + linear_map_hash_count, 1, ppc64_rma_size)); + memset(linear_map_hash_slots, 0, linear_map_hash_count); + } #endif /* CONFIG_DEBUG_PAGEALLOC */ /* On U3 based machines, we need to reserve the DART area and diff --git a/arch/powerpc/mm/hugetlbpage-hash64.c b/arch/powerpc/mm/hugetlbpage-hash64.c index e2138c7ae70fed97740cd74a84ce41b5ac29baa9..8555fce902fea574608b42d2bb240009e3fe8371 100644 --- a/arch/powerpc/mm/hugetlbpage-hash64.c +++ b/arch/powerpc/mm/hugetlbpage-hash64.c @@ -76,7 +76,7 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, if (old_pte & _PAGE_F_SECOND) hash = ~hash; slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; - slot += (old_pte & _PAGE_F_GIX) >> 12; + slot += (old_pte & _PAGE_F_GIX) >> _PAGE_F_GIX_SHIFT; if (ppc_md.hpte_updatepp(slot, rflags, vpn, mmu_psize, mmu_psize, ssize, flags) == -1) @@ -105,7 +105,8 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, return -1; } - new_pte |= (slot << 12) & (_PAGE_F_SECOND | _PAGE_F_GIX); + new_pte |= (slot << _PAGE_F_GIX_SHIFT) & + (_PAGE_F_SECOND | _PAGE_F_GIX); } /* diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 744e24bcb85c4445dcaf58b8d3334ef0a2702cbb..d991b9e80dbbc75ef955c78c924c2e273228b70f 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -107,8 +107,7 @@ static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp, kmem_cache_free(cachep, new); else { #ifdef CONFIG_PPC_BOOK3S_64 - hpdp->pd = (unsigned long)new | - (shift_to_mmu_psize(pshift) << 2); + hpdp->pd = __pa(new) | (shift_to_mmu_psize(pshift) << 2); #else hpdp->pd = ((unsigned long)new & ~PD_HUGE) | pshift; #endif @@ -414,13 +413,13 @@ static void hugepd_free(struct mmu_gather *tlb, void *hugepte) { struct hugepd_freelist **batchp; - batchp = this_cpu_ptr(&hugepd_freelist_cur); + batchp = &get_cpu_var(hugepd_freelist_cur); if (atomic_read(&tlb->mm->mm_users) < 2 || cpumask_equal(mm_cpumask(tlb->mm), cpumask_of(smp_processor_id()))) { kmem_cache_free(hugepte_cache, hugepte); - put_cpu_var(hugepd_freelist_cur); + put_cpu_var(hugepd_freelist_cur); return; } diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c index a10be665b645fc3e85a4e3ee3bbcfb69a67ddc5a..c899fe340bbd2cc85f596fb137a2008973b04f30 100644 --- a/arch/powerpc/mm/init_32.c +++ b/arch/powerpc/mm/init_32.c @@ -112,10 +112,10 @@ void __init MMU_setup(void) if (strstr(boot_command_line, "noltlbs")) { __map_without_ltlbs = 1; } -#ifdef CONFIG_DEBUG_PAGEALLOC - __map_without_bats = 1; - __map_without_ltlbs = 1; -#endif + if (debug_pagealloc_enabled()) { + __map_without_bats = 1; + __map_without_ltlbs = 1; + } } /* @@ -178,10 +178,6 @@ void __init MMU_init(void) /* Initialize early top-down ioremap allocator */ ioremap_bot = IOREMAP_TOP; - /* Map in I/O resources */ - if (ppc_md.progress) - ppc_md.progress("MMU:setio", 0x302); - if (ppc_md.progress) ppc_md.progress("MMU:exit", 0x211); @@ -193,22 +189,3 @@ void __init MMU_init(void) /* Shortly after that, the entire linear mapping will be available */ memblock_set_current_limit(lowmem_end_addr); } - -#ifdef CONFIG_8xx /* No 8xx specific .c file to put that in ... */ -void setup_initial_memory_limit(phys_addr_t first_memblock_base, - phys_addr_t first_memblock_size) -{ - /* We don't currently support the first MEMBLOCK not mapping 0 - * physical on those processors - */ - BUG_ON(first_memblock_base != 0); - -#ifdef CONFIG_PIN_TLB - /* 8xx can only access 24MB at the moment */ - memblock_set_current_limit(min_t(u64, first_memblock_size, 0x01800000)); -#else - /* 8xx can only access 8MB at the moment */ - memblock_set_current_limit(min_t(u64, first_memblock_size, 0x00800000)); -#endif -} -#endif /* CONFIG_8xx */ diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c index 379a6a90644be155483e76ddd45a2bcdfdb28c2a..ba655666186d9caab2cd2c68c2570e8e9f8f1d45 100644 --- a/arch/powerpc/mm/init_64.c +++ b/arch/powerpc/mm/init_64.c @@ -85,6 +85,11 @@ static void pgd_ctor(void *addr) memset(addr, 0, PGD_TABLE_SIZE); } +static void pud_ctor(void *addr) +{ + memset(addr, 0, PUD_TABLE_SIZE); +} + static void pmd_ctor(void *addr) { memset(addr, 0, PMD_TABLE_SIZE); @@ -138,14 +143,18 @@ void pgtable_cache_init(void) { pgtable_cache_add(PGD_INDEX_SIZE, pgd_ctor); pgtable_cache_add(PMD_CACHE_INDEX, pmd_ctor); + /* + * In all current configs, when the PUD index exists it's the + * same size as either the pgd or pmd index except with THP enabled + * on book3s 64 + */ + if (PUD_INDEX_SIZE && !PGT_CACHE(PUD_INDEX_SIZE)) + pgtable_cache_add(PUD_INDEX_SIZE, pud_ctor); + if (!PGT_CACHE(PGD_INDEX_SIZE) || !PGT_CACHE(PMD_CACHE_INDEX)) panic("Couldn't allocate pgtable caches"); - /* In all current configs, when the PUD index exists it's the - * same size as either the pgd or pmd index. Verify that the - * initialization above has also created a PUD cache. This - * will need re-examiniation if we add new possibilities for - * the pagetable layout. */ - BUG_ON(PUD_INDEX_SIZE && !PGT_CACHE(PUD_INDEX_SIZE)); + if (PUD_INDEX_SIZE && !PGT_CACHE(PUD_INDEX_SIZE)) + panic("Couldn't allocate pud pgtable caches"); } #ifdef CONFIG_SPARSEMEM_VMEMMAP @@ -188,9 +197,9 @@ static int __meminit vmemmap_populated(unsigned long start, int page_size) */ #ifdef CONFIG_PPC_BOOK3E -static void __meminit vmemmap_create_mapping(unsigned long start, - unsigned long page_size, - unsigned long phys) +static int __meminit vmemmap_create_mapping(unsigned long start, + unsigned long page_size, + unsigned long phys) { /* Create a PTE encoding without page size */ unsigned long i, flags = _PAGE_PRESENT | _PAGE_ACCESSED | @@ -208,6 +217,8 @@ static void __meminit vmemmap_create_mapping(unsigned long start, */ for (i = 0; i < page_size; i += PAGE_SIZE) BUG_ON(map_kernel_page(start + i, phys, flags)); + + return 0; } #ifdef CONFIG_MEMORY_HOTPLUG @@ -217,25 +228,31 @@ static void vmemmap_remove_mapping(unsigned long start, } #endif #else /* CONFIG_PPC_BOOK3E */ -static void __meminit vmemmap_create_mapping(unsigned long start, - unsigned long page_size, - unsigned long phys) +static int __meminit vmemmap_create_mapping(unsigned long start, + unsigned long page_size, + unsigned long phys) { - int mapped = htab_bolt_mapping(start, start + page_size, phys, - pgprot_val(PAGE_KERNEL), - mmu_vmemmap_psize, - mmu_kernel_ssize); - BUG_ON(mapped < 0); + int rc = htab_bolt_mapping(start, start + page_size, phys, + pgprot_val(PAGE_KERNEL), + mmu_vmemmap_psize, mmu_kernel_ssize); + if (rc < 0) { + int rc2 = htab_remove_mapping(start, start + page_size, + mmu_vmemmap_psize, + mmu_kernel_ssize); + BUG_ON(rc2 && (rc2 != -ENOENT)); + } + return rc; } #ifdef CONFIG_MEMORY_HOTPLUG static void vmemmap_remove_mapping(unsigned long start, unsigned long page_size) { - int mapped = htab_remove_mapping(start, start + page_size, - mmu_vmemmap_psize, - mmu_kernel_ssize); - BUG_ON(mapped < 0); + int rc = htab_remove_mapping(start, start + page_size, + mmu_vmemmap_psize, + mmu_kernel_ssize); + BUG_ON((rc < 0) && (rc != -ENOENT)); + WARN_ON(rc == -ENOENT); } #endif @@ -303,6 +320,7 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node) for (; start < end; start += page_size) { void *p; + int rc; if (vmemmap_populated(start, page_size)) continue; @@ -316,7 +334,13 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node) pr_debug(" * %016lx..%016lx allocated at %p\n", start, start + page_size, p); - vmemmap_create_mapping(start, page_size, __pa(p)); + rc = vmemmap_create_mapping(start, page_size, __pa(p)); + if (rc < 0) { + pr_warning( + "vmemmap_populate: Unable to create vmemmap mapping: %d\n", + rc); + return -EFAULT; + } } return 0; diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index f078a1f94fc267de0e4de530cd413608c2d93e5f..ac79dbde1015ba090e30718c77759c4ec10498ed 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -119,12 +119,18 @@ int arch_add_memory(int nid, u64 start, u64 size, bool for_device) struct zone *zone; unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; + int rc; pgdata = NODE_DATA(nid); start = (unsigned long)__va(start); - if (create_section_mapping(start, start + size)) - return -EINVAL; + rc = create_section_mapping(start, start + size); + if (rc) { + pr_warning( + "Unable to create mapping for hot added memory 0x%llx..0x%llx: %d\n", + start, start + size, rc); + return -EFAULT; + } /* this should work for most non-highmem platforms */ zone = pgdata->node_zones + diff --git a/arch/powerpc/mm/mmu_context_hash64.c b/arch/powerpc/mm/mmu_context_hash64.c index 4e4efbc2658e3500c1a2f0eb3fb2a036a5d284cc..9ca6fe16cb29440ca6293a9d02f8d3d8a51096d7 100644 --- a/arch/powerpc/mm/mmu_context_hash64.c +++ b/arch/powerpc/mm/mmu_context_hash64.c @@ -118,8 +118,7 @@ static void destroy_pagetable_page(struct mm_struct *mm) /* drop all the pending references */ count = ((unsigned long)pte_frag & ~PAGE_MASK) >> PTE_FRAG_SIZE_SHIFT; /* We allow PTE_FRAG_NR fragments from a PTE page */ - count = atomic_sub_return(PTE_FRAG_NR - count, &page->_count); - if (!count) { + if (page_ref_sub_and_test(page, PTE_FRAG_NR - count)) { pgtable_page_dtor(page); free_hot_cold_page(page, 0); } diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h index 9f58ff44a07500870717ea5668e60f3ec7c64793..bfb7c0bcabd57a6dd12f87ca1e41f7bacdfe4f28 100644 --- a/arch/powerpc/mm/mmu_decl.h +++ b/arch/powerpc/mm/mmu_decl.h @@ -100,7 +100,6 @@ extern void setbat(int index, unsigned long virt, phys_addr_t phys, extern int __map_without_bats; extern int __allow_ioremap_reserved; -extern unsigned long ioremap_base; extern unsigned int rtas_data, rtas_size; struct hash_pte; @@ -110,7 +109,8 @@ extern unsigned long Hash_size, Hash_mask; #endif /* CONFIG_PPC32 */ #ifdef CONFIG_PPC64 -extern int map_kernel_page(unsigned long ea, unsigned long pa, int flags); +extern int map_kernel_page(unsigned long ea, unsigned long pa, + unsigned long flags); #endif /* CONFIG_PPC64 */ extern unsigned long ioremap_bot; @@ -132,22 +132,17 @@ extern void wii_memory_fixups(void); /* ...and now those things that may be slightly different between processor * architectures. -- Dan */ -#if defined(CONFIG_8xx) -#define MMU_init_hw() do { } while(0) -#define mmu_mapin_ram(top) (0UL) - -#elif defined(CONFIG_4xx) +#ifdef CONFIG_PPC32 extern void MMU_init_hw(void); extern unsigned long mmu_mapin_ram(unsigned long top); +#endif -#elif defined(CONFIG_PPC_FSL_BOOK3E) +#ifdef CONFIG_PPC_FSL_BOOK3E extern unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx, bool dryrun); extern unsigned long calc_cam_sz(unsigned long ram, unsigned long virt, phys_addr_t phys); #ifdef CONFIG_PPC32 -extern void MMU_init_hw(void); -extern unsigned long mmu_mapin_ram(unsigned long top); extern void adjust_total_lowmem(void); extern int switch_to_as1(void); extern void restore_to_as0(int esel, int offset, void *dt_ptr, int bootcpu); @@ -162,8 +157,14 @@ struct tlbcam { u32 MAS3; u32 MAS7; }; -#elif defined(CONFIG_PPC32) -/* anything 32-bit except 4xx or 8xx */ -extern void MMU_init_hw(void); -extern unsigned long mmu_mapin_ram(unsigned long top); +#endif + +#if defined(CONFIG_6xx) || defined(CONFIG_FSL_BOOKE) +/* 6xx have BATS */ +/* FSL_BOOKE have TLBCAM */ +phys_addr_t v_block_mapped(unsigned long va); +unsigned long p_block_mapped(phys_addr_t pa); +#else +static inline phys_addr_t v_block_mapped(unsigned long va) { return 0; } +static inline unsigned long p_block_mapped(phys_addr_t pa) { return 0; } #endif diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c index 7692d1bb1bc6aa0b9184cb87eb67d958751fc9bc..bf7bf32b54f8a7ca025c06ca7e74e3f0d78f1d70 100644 --- a/arch/powerpc/mm/pgtable_32.c +++ b/arch/powerpc/mm/pgtable_32.c @@ -37,35 +37,10 @@ #include "mmu_decl.h" -unsigned long ioremap_base; unsigned long ioremap_bot; EXPORT_SYMBOL(ioremap_bot); /* aka VMALLOC_END */ -#ifdef CONFIG_6xx -#define HAVE_BATS 1 -#endif - -#if defined(CONFIG_FSL_BOOKE) -#define HAVE_TLBCAM 1 -#endif - -extern char etext[], _stext[]; - -#ifdef HAVE_BATS -extern phys_addr_t v_mapped_by_bats(unsigned long va); -extern unsigned long p_mapped_by_bats(phys_addr_t pa); -#else /* !HAVE_BATS */ -#define v_mapped_by_bats(x) (0UL) -#define p_mapped_by_bats(x) (0UL) -#endif /* HAVE_BATS */ - -#ifdef HAVE_TLBCAM -extern phys_addr_t v_mapped_by_tlbcam(unsigned long va); -extern unsigned long p_mapped_by_tlbcam(phys_addr_t pa); -#else /* !HAVE_TLBCAM */ -#define v_mapped_by_tlbcam(x) (0UL) -#define p_mapped_by_tlbcam(x) (0UL) -#endif /* HAVE_TLBCAM */ +extern char etext[], _stext[], _sinittext[], _einittext[]; #define PGDIR_ORDER (32 + PGD_T_LOG2 - PGDIR_SHIFT) @@ -197,7 +172,7 @@ __ioremap_caller(phys_addr_t addr, unsigned long size, unsigned long flags, /* * Choose an address to map it to. * Once the vmalloc system is running, we use it. - * Before then, we use space going down from ioremap_base + * Before then, we use space going down from IOREMAP_TOP * (ioremap_bot records where we're up to). */ p = addr & PAGE_MASK; @@ -228,19 +203,10 @@ __ioremap_caller(phys_addr_t addr, unsigned long size, unsigned long flags, /* * Is it already mapped? Perhaps overlapped by a previous - * BAT mapping. If the whole area is mapped then we're done, - * otherwise remap it since we want to keep the virt addrs for - * each request contiguous. - * - * We make the assumption here that if the bottom and top - * of the range we want are mapped then it's mapped to the - * same virt address (and this is contiguous). - * -- Cort + * mapping. */ - if ((v = p_mapped_by_bats(p)) /*&& p_mapped_by_bats(p+size-1)*/ ) - goto out; - - if ((v = p_mapped_by_tlbcam(p))) + v = p_block_mapped(p); + if (v) goto out; if (slab_is_available()) { @@ -278,7 +244,8 @@ void iounmap(volatile void __iomem *addr) * If mapped by BATs then there is nothing to do. * Calling vfree() generates a benign warning. */ - if (v_mapped_by_bats((unsigned long)addr)) return; + if (v_block_mapped((unsigned long)addr)) + return; if (addr > high_memory && (unsigned long) addr < ioremap_bot) vunmap((void *) (PAGE_MASK & (unsigned long)addr)); @@ -322,7 +289,8 @@ void __init __mapin_ram_chunk(unsigned long offset, unsigned long top) v = PAGE_OFFSET + s; p = memstart_addr + s; for (; s < top; s += PAGE_SIZE) { - ktext = ((char *) v >= _stext && (char *) v < etext); + ktext = ((char *)v >= _stext && (char *)v < etext) || + ((char *)v >= _sinittext && (char *)v < _einittext); f = ktext ? pgprot_val(PAGE_KERNEL_TEXT) : pgprot_val(PAGE_KERNEL); map_page(v, p, f); #ifdef CONFIG_PPC_STD_MMU_32 @@ -403,7 +371,7 @@ static int __change_page_attr(struct page *page, pgprot_t prot) BUG_ON(PageHighMem(page)); address = (unsigned long)page_address(page); - if (v_mapped_by_bats(address) || v_mapped_by_tlbcam(address)) + if (v_block_mapped(address)) return 0; if (!get_pteptr(&init_mm, address, &kpte, &kpmd)) return -EINVAL; diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index cdf2123d46db4813a4e87f30d29f8da359c313d9..347106080bb1e64b87d28477db24e47f3ab3ef77 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c @@ -88,7 +88,7 @@ static __ref void *early_alloc_pgtable(unsigned long size) * map_kernel_page adds an entry to the ioremap page table * and adds an entry to the HPT, possibly bolting it */ -int map_kernel_page(unsigned long ea, unsigned long pa, int flags) +int map_kernel_page(unsigned long ea, unsigned long pa, unsigned long flags) { pgd_t *pgdp; pud_t *pudp; @@ -403,7 +403,7 @@ static pte_t *__alloc_for_cache(struct mm_struct *mm, int kernel) * count. */ if (likely(!mm->context.pte_frag)) { - atomic_set(&page->_count, PTE_FRAG_NR); + set_page_count(page, PTE_FRAG_NR); mm->context.pte_frag = ret + PTE_FRAG_SIZE; } spin_unlock(&mm->page_table_lock); @@ -749,7 +749,7 @@ pmd_t pfn_pmd(unsigned long pfn, pgprot_t pgprot) { unsigned long pmdv; - pmdv = pfn << PTE_RPN_SHIFT; + pmdv = (pfn << PTE_RPN_SHIFT) & PTE_RPN_MASK; return pmd_set_protbits(__pmd(pmdv), pgprot); } @@ -817,6 +817,13 @@ pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm, int has_transparent_hugepage(void) { + + BUILD_BUG_ON_MSG((PMD_SHIFT - PAGE_SHIFT) >= MAX_ORDER, + "hugepages can't be allocated by the buddy allocator"); + + BUILD_BUG_ON_MSG((PMD_SHIFT - PAGE_SHIFT) < 2, + "We need more than 2 pages to do deferred thp split"); + if (!mmu_has_feature(MMU_FTR_16M_PAGE)) return 0; /* diff --git a/arch/powerpc/mm/ppc_mmu_32.c b/arch/powerpc/mm/ppc_mmu_32.c index 6b2f3e457171a1f5347494f69aea6fa2c5cc4d03..2a049fb8523d57d51311e31fe54bebb04f31f1bb 100644 --- a/arch/powerpc/mm/ppc_mmu_32.c +++ b/arch/powerpc/mm/ppc_mmu_32.c @@ -49,7 +49,7 @@ struct batrange { /* stores address ranges mapped by BATs */ /* * Return PA for this VA if it is mapped by a BAT, or 0 */ -phys_addr_t v_mapped_by_bats(unsigned long va) +phys_addr_t v_block_mapped(unsigned long va) { int b; for (b = 0; b < 4; ++b) @@ -61,7 +61,7 @@ phys_addr_t v_mapped_by_bats(unsigned long va) /* * Return VA for a given PA or 0 if not mapped */ -unsigned long p_mapped_by_bats(phys_addr_t pa) +unsigned long p_block_mapped(phys_addr_t pa) { int b; for (b = 0; b < 4; ++b) diff --git a/arch/powerpc/mm/tlb_low_64e.S b/arch/powerpc/mm/tlb_low_64e.S index 29d6987c37ba4c8079d834eb09a0ae8f91a34399..eb82d787d99a1140e660b4e5675a241ee2b92a5c 100644 --- a/arch/powerpc/mm/tlb_low_64e.S +++ b/arch/powerpc/mm/tlb_low_64e.S @@ -895,7 +895,7 @@ ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_USE_PAIRED_MAS) BEGIN_MMU_FTR_SECTION virt_page_table_tlb_miss_done: - /* We have overriden MAS2:EPN but currently our primary TLB miss + /* We have overridden MAS2:EPN but currently our primary TLB miss * handler will always restore it so that should not be an issue, * if we ever optimize the primary handler to not write MAS2 on * some cases, we'll have to restore MAS2:EPN here based on the diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c index bb04e4df31008089e5390619dc52a7c6c26d5f7b..f4668488512c46d278cc1742672e741a9016639b 100644 --- a/arch/powerpc/mm/tlb_nohash.c +++ b/arch/powerpc/mm/tlb_nohash.c @@ -640,9 +640,7 @@ static void early_init_this_mmu(void) * transient mapping would cause problems. */ #ifdef CONFIG_SMP - if (cpu != boot_cpuid && - (cpu != cpu_first_thread_sibling(cpu) || - cpu == cpu_first_thread_sibling(boot_cpuid))) + if (hweight32(get_tensr()) > 1) map = false; #endif diff --git a/arch/powerpc/mm/tlb_nohash_low.S b/arch/powerpc/mm/tlb_nohash_low.S index 68c477592e43694677fd92c2bf58b3ae9ab0a3c9..eabecfcaef7cf0503c125535619a9fcc6acbcf86 100644 --- a/arch/powerpc/mm/tlb_nohash_low.S +++ b/arch/powerpc/mm/tlb_nohash_low.S @@ -108,7 +108,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_47x) blr 2: #ifdef CONFIG_PPC_47x - oris r7,r6,0x8000 /* specify way explicitely */ + oris r7,r6,0x8000 /* specify way explicitly */ clrrwi r4,r3,12 /* get an EPN for the hashing with V = 0 */ ori r4,r4,PPC47x_TLBE_SIZE tlbwe r4,r7,0 /* write it */ @@ -149,7 +149,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_47x) li r3,-1 /* Current set */ lis r10,tlb_47x_boltmap@h ori r10,r10,tlb_47x_boltmap@l - lis r7,0x8000 /* Specify way explicitely */ + lis r7,0x8000 /* Specify way explicitly */ b 9f /* For each set */ diff --git a/arch/powerpc/oprofile/op_model_cell.c b/arch/powerpc/oprofile/op_model_cell.c index 863d89386f607dd86a3edb08d594448b3b5fe260..c82497a31c54f981d243b9b056c85b604a664abe 100644 --- a/arch/powerpc/oprofile/op_model_cell.c +++ b/arch/powerpc/oprofile/op_model_cell.c @@ -208,7 +208,7 @@ static void pm_rtas_reset_signals(u32 node) /* * The debug bus is being set to the passthru disable state. - * However, the FW still expects atleast one legal signal routing + * However, the FW still expects at least one legal signal routing * entry or it will return an error on the arguments. If we don't * supply a valid entry, we must ignore all return values. Ignoring * all return values means we might miss an error we should be @@ -1008,7 +1008,7 @@ static int initial_lfsr[] = { * * To avoid the time to compute the LFSR, a lookup table is used. The 24 bit * LFSR sequence is broken into four ranges. The spacing of the precomputed - * values is adjusted in each range so the error between the user specifed + * values is adjusted in each range so the error between the user specified * number (N) of events between samples and the actual number of events based * on the precomputed value will be les then about 6.2%. Note, if the user * specifies N < 2^16, the LFSR value that is 2^16 from the end will be used. diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c index d1e65ce545b31f427629853a3803a6b0b4af0d9b..97a1d40d8696cac34452725081bbf6a5027f96ed 100644 --- a/arch/powerpc/perf/core-book3s.c +++ b/arch/powerpc/perf/core-book3s.c @@ -651,7 +651,7 @@ static void pmao_restore_workaround(bool ebb) /* * We are already soft-disabled in power_pmu_enable(). We need to hard - * enable to actually prevent the PMU exception from firing. + * disable to actually prevent the PMU exception from firing. */ hard_irq_disable(); diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c index 3b09ecfd0aee20861ae7c2d5f48a19965a21953f..2da41b78cb6da64d99762502f389830aa07a221a 100644 --- a/arch/powerpc/perf/hv-24x7.c +++ b/arch/powerpc/perf/hv-24x7.c @@ -27,20 +27,6 @@ #include "hv-24x7-catalog.h" #include "hv-common.h" -static const char *event_domain_suffix(unsigned domain) -{ - switch (domain) { -#define DOMAIN(n, v, x, c) \ - case HV_PERF_DOMAIN_##n: \ - return "__" #n; -#include "hv-24x7-domains.h" -#undef DOMAIN - default: - WARN(1, "unknown domain %d\n", domain); - return "__UNKNOWN_DOMAIN_SUFFIX"; - } -} - static bool domain_is_valid(unsigned domain) { switch (domain) { @@ -68,6 +54,24 @@ static bool is_physical_domain(unsigned domain) } } +static const char *domain_name(unsigned domain) +{ + if (!domain_is_valid(domain)) + return NULL; + + switch (domain) { + case HV_PERF_DOMAIN_PHYS_CHIP: return "Physical Chip"; + case HV_PERF_DOMAIN_PHYS_CORE: return "Physical Core"; + case HV_PERF_DOMAIN_VCPU_HOME_CORE: return "VCPU Home Core"; + case HV_PERF_DOMAIN_VCPU_HOME_CHIP: return "VCPU Home Chip"; + case HV_PERF_DOMAIN_VCPU_HOME_NODE: return "VCPU Home Node"; + case HV_PERF_DOMAIN_VCPU_REMOTE_NODE: return "VCPU Remote Node"; + } + + WARN_ON_ONCE(domain); + return NULL; +} + static bool catalog_entry_domain_is_valid(unsigned domain) { return is_physical_domain(domain); @@ -101,6 +105,7 @@ static bool catalog_entry_domain_is_valid(unsigned domain) EVENT_DEFINE_RANGE_FORMAT(domain, config, 0, 3); /* u16 */ EVENT_DEFINE_RANGE_FORMAT(core, config, 16, 31); +EVENT_DEFINE_RANGE_FORMAT(chip, config, 16, 31); EVENT_DEFINE_RANGE_FORMAT(vcpu, config, 16, 31); /* u32, see "data_offset" */ EVENT_DEFINE_RANGE_FORMAT(offset, config, 32, 63); @@ -115,6 +120,7 @@ static struct attribute *format_attrs[] = { &format_attr_domain.attr, &format_attr_offset.attr, &format_attr_core.attr, + &format_attr_chip.attr, &format_attr_vcpu.attr, &format_attr_lpar.attr, NULL, @@ -274,32 +280,70 @@ static unsigned long h_get_24x7_catalog_page(char page[], version, index); } -static unsigned core_domains[] = { - HV_PERF_DOMAIN_PHYS_CORE, - HV_PERF_DOMAIN_VCPU_HOME_CORE, - HV_PERF_DOMAIN_VCPU_HOME_CHIP, - HV_PERF_DOMAIN_VCPU_HOME_NODE, - HV_PERF_DOMAIN_VCPU_REMOTE_NODE, -}; -/* chip event data always yeilds a single event, core yeilds multiple */ -#define MAX_EVENTS_PER_EVENT_DATA ARRAY_SIZE(core_domains) - +/* + * Each event we find in the catalog, will have a sysfs entry. Format the + * data for this sysfs entry based on the event's domain. + * + * Events belonging to the Chip domain can only be monitored in that domain. + * i.e the domain for these events is a fixed/knwon value. + * + * Events belonging to the Core domain can be monitored either in the physical + * core or in one of the virtual CPU domains. So the domain value for these + * events must be specified by the user (i.e is a required parameter). Format + * the Core events with 'domain=?' so the perf-tool can error check required + * parameters. + * + * NOTE: For the Core domain events, rather than making domain a required + * parameter we could default it to PHYS_CORE and allowe users to + * override the domain to one of the VCPU domains. + * + * However, this can make the interface a little inconsistent. + * + * If we set domain=2 (PHYS_CHIP) and allow user to override this field + * the user may be tempted to also modify the "offset=x" field in which + * can lead to confusing usage. Consider the HPM_PCYC (offset=0x18) and + * HPM_INST (offset=0x20) events. With: + * + * perf stat -e hv_24x7/HPM_PCYC,offset=0x20/ + * + * we end up monitoring HPM_INST, while the command line has HPM_PCYC. + * + * By not assigning a default value to the domain for the Core events, + * we can have simple guidelines: + * + * - Specifying values for parameters with "=?" is required. + * + * - Specifying (i.e overriding) values for other parameters + * is undefined. + */ static char *event_fmt(struct hv_24x7_event_data *event, unsigned domain) { const char *sindex; const char *lpar; + const char *domain_str; + char buf[8]; - if (is_physical_domain(domain)) { + switch (domain) { + case HV_PERF_DOMAIN_PHYS_CHIP: + snprintf(buf, sizeof(buf), "%d", domain); + domain_str = buf; + lpar = "0x0"; + sindex = "chip"; + break; + case HV_PERF_DOMAIN_PHYS_CORE: + domain_str = "?"; lpar = "0x0"; sindex = "core"; - } else { + break; + default: + domain_str = "?"; lpar = "?"; sindex = "vcpu"; } return kasprintf(GFP_KERNEL, - "domain=0x%x,offset=0x%x,%s=?,lpar=%s", - domain, + "domain=%s,offset=0x%x,%s=?,lpar=%s", + domain_str, be16_to_cpu(event->event_counter_offs) + be16_to_cpu(event->event_group_record_offs), sindex, @@ -339,6 +383,15 @@ static struct attribute *device_str_attr_create_(char *name, char *str) return &attr->attr.attr; } +/* + * Allocate and initialize strings representing event attributes. + * + * NOTE: The strings allocated here are never destroyed and continue to + * exist till shutdown. This is to allow us to create as many events + * from the catalog as possible, even if we encounter errors with some. + * In case of changes to error paths in future, these may need to be + * freed by the caller. + */ static struct attribute *device_str_attr_create(char *name, int name_max, int name_nonce, char *str, size_t str_max) @@ -370,16 +423,6 @@ static struct attribute *device_str_attr_create(char *name, int name_max, return NULL; } -static void device_str_attr_destroy(struct attribute *attr) -{ - struct dev_ext_attribute *d; - - d = container_of(attr, struct dev_ext_attribute, attr.attr); - kfree(d->var); - kfree(d->attr.attr.name); - kfree(d); -} - static struct attribute *event_to_attr(unsigned ix, struct hv_24x7_event_data *event, unsigned domain, @@ -387,7 +430,6 @@ static struct attribute *event_to_attr(unsigned ix, { int event_name_len; char *ev_name, *a_ev_name, *val; - const char *ev_suffix; struct attribute *attr; if (!domain_is_valid(domain)) { @@ -400,14 +442,13 @@ static struct attribute *event_to_attr(unsigned ix, if (!val) return NULL; - ev_suffix = event_domain_suffix(domain); ev_name = event_name(event, &event_name_len); if (!nonce) - a_ev_name = kasprintf(GFP_KERNEL, "%.*s%s", - (int)event_name_len, ev_name, ev_suffix); + a_ev_name = kasprintf(GFP_KERNEL, "%.*s", + (int)event_name_len, ev_name); else - a_ev_name = kasprintf(GFP_KERNEL, "%.*s%s__%d", - (int)event_name_len, ev_name, ev_suffix, nonce); + a_ev_name = kasprintf(GFP_KERNEL, "%.*s__%d", + (int)event_name_len, ev_name, nonce); if (!a_ev_name) goto out_val; @@ -452,45 +493,14 @@ event_to_long_desc_attr(struct hv_24x7_event_data *event, int nonce) return device_str_attr_create(name, nl, nonce, desc, dl); } -static ssize_t event_data_to_attrs(unsigned ix, struct attribute **attrs, +static int event_data_to_attrs(unsigned ix, struct attribute **attrs, struct hv_24x7_event_data *event, int nonce) { - unsigned i; - - switch (event->domain) { - case HV_PERF_DOMAIN_PHYS_CHIP: - *attrs = event_to_attr(ix, event, event->domain, nonce); - return 1; - case HV_PERF_DOMAIN_PHYS_CORE: - for (i = 0; i < ARRAY_SIZE(core_domains); i++) { - attrs[i] = event_to_attr(ix, event, core_domains[i], - nonce); - if (!attrs[i]) { - pr_warn("catalog event %u: individual attr %u " - "creation failure\n", ix, i); - for (; i; i--) - device_str_attr_destroy(attrs[i - 1]); - return -1; - } - } - return i; - default: - pr_warn("catalog event %u: domain %u is not allowed in the " - "catalog\n", ix, event->domain); + *attrs = event_to_attr(ix, event, event->domain, nonce); + if (!*attrs) return -1; - } -} -static size_t event_to_attr_ct(struct hv_24x7_event_data *event) -{ - switch (event->domain) { - case HV_PERF_DOMAIN_PHYS_CHIP: - return 1; - case HV_PERF_DOMAIN_PHYS_CORE: - return ARRAY_SIZE(core_domains); - default: - return 0; - } + return 0; } /* */ @@ -718,9 +728,8 @@ static int create_events_from_catalog(struct attribute ***events_, goto e_free; } - if (SIZE_MAX / MAX_EVENTS_PER_EVENT_DATA - 1 < event_entry_count) { - pr_err("event_entry_count %zu is invalid\n", - event_entry_count); + if (SIZE_MAX - 1 < event_entry_count) { + pr_err("event_entry_count %zu is invalid\n", event_entry_count); ret = -EIO; goto e_free; } @@ -793,7 +802,7 @@ static int create_events_from_catalog(struct attribute ***events_, continue; } - attr_max += event_to_attr_ct(event); + attr_max++; } event_idx_last = event_idx; @@ -843,12 +852,12 @@ static int create_events_from_catalog(struct attribute ***events_, nonce = event_uniq_add(&ev_uniq, name, nl, event->domain); ct = event_data_to_attrs(event_idx, events + event_attr_ct, event, nonce); - if (ct <= 0) { + if (ct < 0) { pr_warn("event %zu (%.*s) creation failure, skipping\n", event_idx, nl, name); junk_events++; } else { - event_attr_ct += ct; + event_attr_ct++; event_descs[desc_ct] = event_to_desc_attr(event, nonce); if (event_descs[desc_ct]) desc_ct++; @@ -953,6 +962,27 @@ static ssize_t catalog_read(struct file *filp, struct kobject *kobj, return ret; } +static ssize_t domains_show(struct device *dev, struct device_attribute *attr, + char *page) +{ + int d, n, count = 0; + const char *str; + + for (d = 0; d < HV_PERF_DOMAIN_MAX; d++) { + str = domain_name(d); + if (!str) + continue; + + n = sprintf(page, "%d: %s\n", d, str); + if (n < 0) + break; + + count += n; + page += n; + } + return count; +} + #define PAGE_0_ATTR(_name, _fmt, _expr) \ static ssize_t _name##_show(struct device *dev, \ struct device_attribute *dev_attr, \ @@ -981,6 +1011,7 @@ PAGE_0_ATTR(catalog_version, "%lld\n", PAGE_0_ATTR(catalog_len, "%lld\n", (unsigned long long)be32_to_cpu(page_0->length) * 4096); static BIN_ATTR_RO(catalog, 0/* real length varies */); +static DEVICE_ATTR_RO(domains); static struct bin_attribute *if_bin_attrs[] = { &bin_attr_catalog, @@ -990,6 +1021,7 @@ static struct bin_attribute *if_bin_attrs[] = { static struct attribute *if_attrs[] = { &dev_attr_catalog_len.attr, &dev_attr_catalog_version.attr, + &dev_attr_domains.attr, NULL, }; @@ -1081,10 +1113,16 @@ static int add_event_to_24x7_request(struct perf_event *event, return -EINVAL; } - if (is_physical_domain(event_get_domain(event))) + switch (event_get_domain(event)) { + case HV_PERF_DOMAIN_PHYS_CHIP: + idx = event_get_chip(event); + break; + case HV_PERF_DOMAIN_PHYS_CORE: idx = event_get_core(event); - else + break; + default: idx = event_get_vcpu(event); + } i = request_buffer->num_requests++; req = &request_buffer->requests[i]; @@ -1200,11 +1238,12 @@ static int h_24x7_event_init(struct perf_event *event) return -EACCES; } - /* see if the event complains */ + /* Get the initial value of the counter for this event */ if (single_24x7_request(event, &ct)) { pr_devel("test hcall failed\n"); return -EIO; } + (void)local64_xchg(&event->hw.prev_count, ct); return 0; } @@ -1267,6 +1306,16 @@ static void h_24x7_event_read(struct perf_event *event) h24x7hw = &get_cpu_var(hv_24x7_hw); h24x7hw->events[i] = event; put_cpu_var(h24x7hw); + /* + * Clear the event count so we can compute the _change_ + * in the 24x7 raw counter value at the end of the txn. + * + * Note that we could alternatively read the 24x7 value + * now and save its value in event->hw.prev_count. But + * that would require issuing a hcall, which would then + * defeat the purpose of using the txn interface. + */ + local64_set(&event->count, 0); } put_cpu_var(hv_24x7_reqb); diff --git a/arch/powerpc/perf/hv-24x7.h b/arch/powerpc/perf/hv-24x7.h index 0f9fa21a29f23bddd5d367b0fc20daef71b53002..791455e7f5cf7a93cd38f6ab6afddb3dfba82eab 100644 --- a/arch/powerpc/perf/hv-24x7.h +++ b/arch/powerpc/perf/hv-24x7.h @@ -7,6 +7,7 @@ enum hv_perf_domains { #define DOMAIN(n, v, x, c) HV_PERF_DOMAIN_##n = v, #include "hv-24x7-domains.h" #undef DOMAIN + HV_PERF_DOMAIN_MAX, }; struct hv_24x7_request { @@ -80,7 +81,7 @@ struct hv_24x7_result { __u8 results_complete; __be16 num_elements_returned; - /* This is a copy of @data_size from the coresponding hv_24x7_request */ + /* This is a copy of @data_size from the corresponding hv_24x7_request */ __be16 result_element_data_size; __u8 reserved[0x2]; diff --git a/arch/powerpc/perf/hv-gpci.c b/arch/powerpc/perf/hv-gpci.c index 856fe6e03c2a84a122456fd001f30834c4253940..7aa37236bb70bf38ae4d4bb2cc5e9e118d1ad5da 100644 --- a/arch/powerpc/perf/hv-gpci.c +++ b/arch/powerpc/perf/hv-gpci.c @@ -127,8 +127,16 @@ static const struct attribute_group *attr_groups[] = { NULL, }; -#define GPCI_MAX_DATA_BYTES \ - (1024 - sizeof(struct hv_get_perf_counter_info_params)) +#define HGPCI_REQ_BUFFER_SIZE 4096 +#define HGPCI_MAX_DATA_BYTES \ + (HGPCI_REQ_BUFFER_SIZE - sizeof(struct hv_get_perf_counter_info_params)) + +DEFINE_PER_CPU(char, hv_gpci_reqb[HGPCI_REQ_BUFFER_SIZE]) __aligned(sizeof(uint64_t)); + +struct hv_gpci_request_buffer { + struct hv_get_perf_counter_info_params params; + uint8_t bytes[HGPCI_MAX_DATA_BYTES]; +} __packed; static unsigned long single_gpci_request(u32 req, u32 starting_index, u16 secondary_index, u8 version_in, u32 offset, u8 length, @@ -137,24 +145,21 @@ static unsigned long single_gpci_request(u32 req, u32 starting_index, unsigned long ret; size_t i; u64 count; + struct hv_gpci_request_buffer *arg; + + arg = (void *)get_cpu_var(hv_gpci_reqb); + memset(arg, 0, HGPCI_REQ_BUFFER_SIZE); - struct { - struct hv_get_perf_counter_info_params params; - uint8_t bytes[GPCI_MAX_DATA_BYTES]; - } __packed __aligned(sizeof(uint64_t)) arg = { - .params = { - .counter_request = cpu_to_be32(req), - .starting_index = cpu_to_be32(starting_index), - .secondary_index = cpu_to_be16(secondary_index), - .counter_info_version_in = version_in, - } - }; + arg->params.counter_request = cpu_to_be32(req); + arg->params.starting_index = cpu_to_be32(starting_index); + arg->params.secondary_index = cpu_to_be16(secondary_index); + arg->params.counter_info_version_in = version_in; ret = plpar_hcall_norets(H_GET_PERF_COUNTER_INFO, - virt_to_phys(&arg), sizeof(arg)); + virt_to_phys(arg), HGPCI_REQ_BUFFER_SIZE); if (ret) { pr_devel("hcall failed: 0x%lx\n", ret); - return ret; + goto out; } /* @@ -163,9 +168,11 @@ static unsigned long single_gpci_request(u32 req, u32 starting_index, */ count = 0; for (i = offset; i < offset + length; i++) - count |= arg.bytes[i] << (i - offset); + count |= arg->bytes[i] << (i - offset); *value = count; +out: + put_cpu_var(hv_gpci_reqb); return ret; } @@ -245,10 +252,10 @@ static int h_gpci_event_init(struct perf_event *event) } /* last byte within the buffer? */ - if ((event_get_offset(event) + length) > GPCI_MAX_DATA_BYTES) { + if ((event_get_offset(event) + length) > HGPCI_MAX_DATA_BYTES) { pr_devel("request outside of buffer: %zu > %zu\n", (size_t)event_get_offset(event) + length, - GPCI_MAX_DATA_BYTES); + HGPCI_MAX_DATA_BYTES); return -EINVAL; } diff --git a/arch/powerpc/perf/power7-pmu.c b/arch/powerpc/perf/power7-pmu.c index 5b62f238929003a0deade3e8a2a63203df06337b..a383c23a907048df6b3c3dee72704179b9cba584 100644 --- a/arch/powerpc/perf/power7-pmu.c +++ b/arch/powerpc/perf/power7-pmu.c @@ -54,7 +54,7 @@ * Power7 event codes. */ #define EVENT(_name, _code) \ - PME_##_name = _code, + _name = _code, enum { #include "power7-events-list.h" @@ -318,14 +318,14 @@ static void power7_disable_pmc(unsigned int pmc, unsigned long mmcr[]) } static int power7_generic_events[] = { - [PERF_COUNT_HW_CPU_CYCLES] = PME_PM_CYC, - [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = PME_PM_GCT_NOSLOT_CYC, - [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = PME_PM_CMPLU_STALL, - [PERF_COUNT_HW_INSTRUCTIONS] = PME_PM_INST_CMPL, - [PERF_COUNT_HW_CACHE_REFERENCES] = PME_PM_LD_REF_L1, - [PERF_COUNT_HW_CACHE_MISSES] = PME_PM_LD_MISS_L1, - [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = PME_PM_BRU_FIN, - [PERF_COUNT_HW_BRANCH_MISSES] = PME_PM_BR_MPRED, + [PERF_COUNT_HW_CPU_CYCLES] = PM_CYC, + [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = PM_GCT_NOSLOT_CYC, + [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = PM_CMPLU_STALL, + [PERF_COUNT_HW_INSTRUCTIONS] = PM_INST_CMPL, + [PERF_COUNT_HW_CACHE_REFERENCES] = PM_LD_REF_L1, + [PERF_COUNT_HW_CACHE_MISSES] = PM_LD_MISS_L1, + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = PM_BRU_FIN, + [PERF_COUNT_HW_BRANCH_MISSES] = PM_BR_MPRED, }; #define C(x) PERF_COUNT_HW_CACHE_##x diff --git a/arch/powerpc/perf/power8-events-list.h b/arch/powerpc/perf/power8-events-list.h new file mode 100644 index 0000000000000000000000000000000000000000..741b77edd03e739ac54296bd441c5e5b09c98d9b --- /dev/null +++ b/arch/powerpc/perf/power8-events-list.h @@ -0,0 +1,51 @@ +/* + * Performance counter support for POWER8 processors. + * + * Copyright 2014 Sukadev Bhattiprolu, IBM Corporation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +/* + * Power8 event codes. + */ +EVENT(PM_CYC, 0x0001e) +EVENT(PM_GCT_NOSLOT_CYC, 0x100f8) +EVENT(PM_CMPLU_STALL, 0x4000a) +EVENT(PM_INST_CMPL, 0x00002) +EVENT(PM_BRU_FIN, 0x10068) +EVENT(PM_BR_MPRED_CMPL, 0x400f6) + +/* All L1 D cache load references counted at finish, gated by reject */ +EVENT(PM_LD_REF_L1, 0x100ee) +/* Load Missed L1 */ +EVENT(PM_LD_MISS_L1, 0x3e054) +/* Store Missed L1 */ +EVENT(PM_ST_MISS_L1, 0x300f0) +/* L1 cache data prefetches */ +EVENT(PM_L1_PREF, 0x0d8b8) +/* Instruction fetches from L1 */ +EVENT(PM_INST_FROM_L1, 0x04080) +/* Demand iCache Miss */ +EVENT(PM_L1_ICACHE_MISS, 0x200fd) +/* Instruction Demand sectors wriittent into IL1 */ +EVENT(PM_L1_DEMAND_WRITE, 0x0408c) +/* Instruction prefetch written into IL1 */ +EVENT(PM_IC_PREF_WRITE, 0x0408e) +/* The data cache was reloaded from local core's L3 due to a demand load */ +EVENT(PM_DATA_FROM_L3, 0x4c042) +/* Demand LD - L3 Miss (not L2 hit and not L3 hit) */ +EVENT(PM_DATA_FROM_L3MISS, 0x300fe) +/* All successful D-side store dispatches for this thread */ +EVENT(PM_L2_ST, 0x17080) +/* All successful D-side store dispatches for this thread that were L2 Miss */ +EVENT(PM_L2_ST_MISS, 0x17082) +/* Total HW L3 prefetches(Load+store) */ +EVENT(PM_L3_PREF_ALL, 0x4e052) +/* Data PTEG reload */ +EVENT(PM_DTLB_MISS, 0x300fc) +/* ITLB Reloaded */ +EVENT(PM_ITLB_MISS, 0x400fc) diff --git a/arch/powerpc/perf/power8-pmu.c b/arch/powerpc/perf/power8-pmu.c index 9958ba8bf0d27fca74a182546170a487edb88346..690d9186a85520d41ddc38c2089d0ced017061d4 100644 --- a/arch/powerpc/perf/power8-pmu.c +++ b/arch/powerpc/perf/power8-pmu.c @@ -17,48 +17,16 @@ #include #include - /* * Some power8 event codes. */ -#define PM_CYC 0x0001e -#define PM_GCT_NOSLOT_CYC 0x100f8 -#define PM_CMPLU_STALL 0x4000a -#define PM_INST_CMPL 0x00002 -#define PM_BRU_FIN 0x10068 -#define PM_BR_MPRED_CMPL 0x400f6 - -/* All L1 D cache load references counted at finish, gated by reject */ -#define PM_LD_REF_L1 0x100ee -/* Load Missed L1 */ -#define PM_LD_MISS_L1 0x3e054 -/* Store Missed L1 */ -#define PM_ST_MISS_L1 0x300f0 -/* L1 cache data prefetches */ -#define PM_L1_PREF 0x0d8b8 -/* Instruction fetches from L1 */ -#define PM_INST_FROM_L1 0x04080 -/* Demand iCache Miss */ -#define PM_L1_ICACHE_MISS 0x200fd -/* Instruction Demand sectors wriittent into IL1 */ -#define PM_L1_DEMAND_WRITE 0x0408c -/* Instruction prefetch written into IL1 */ -#define PM_IC_PREF_WRITE 0x0408e -/* The data cache was reloaded from local core's L3 due to a demand load */ -#define PM_DATA_FROM_L3 0x4c042 -/* Demand LD - L3 Miss (not L2 hit and not L3 hit) */ -#define PM_DATA_FROM_L3MISS 0x300fe -/* All successful D-side store dispatches for this thread */ -#define PM_L2_ST 0x17080 -/* All successful D-side store dispatches for this thread that were L2 Miss */ -#define PM_L2_ST_MISS 0x17082 -/* Total HW L3 prefetches(Load+store) */ -#define PM_L3_PREF_ALL 0x4e052 -/* Data PTEG reload */ -#define PM_DTLB_MISS 0x300fc -/* ITLB Reloaded */ -#define PM_ITLB_MISS 0x400fc +#define EVENT(_name, _code) _name = _code, + +enum { +#include "power8-events-list.h" +}; +#undef EVENT /* * Raw event encoding for POWER8: @@ -415,7 +383,7 @@ static int power8_compute_mmcr(u64 event[], int n_ev, pmc_inuse |= 1 << pmc; } - /* In continous sampling mode, update SDAR on TLB miss */ + /* In continuous sampling mode, update SDAR on TLB miss */ mmcra = MMCRA_SDAR_MODE_TLB; mmcr1 = mmcr2 = 0; @@ -604,6 +572,71 @@ static void power8_disable_pmc(unsigned int pmc, unsigned long mmcr[]) mmcr[1] &= ~(0xffUL << MMCR1_PMCSEL_SHIFT(pmc + 1)); } +GENERIC_EVENT_ATTR(cpu-cycles, PM_CYC); +GENERIC_EVENT_ATTR(stalled-cycles-frontend, PM_GCT_NOSLOT_CYC); +GENERIC_EVENT_ATTR(stalled-cycles-backend, PM_CMPLU_STALL); +GENERIC_EVENT_ATTR(instructions, PM_INST_CMPL); +GENERIC_EVENT_ATTR(branch-instructions, PM_BRU_FIN); +GENERIC_EVENT_ATTR(branch-misses, PM_BR_MPRED_CMPL); +GENERIC_EVENT_ATTR(cache-references, PM_LD_REF_L1); +GENERIC_EVENT_ATTR(cache-misses, PM_LD_MISS_L1); + +CACHE_EVENT_ATTR(L1-dcache-load-misses, PM_LD_MISS_L1); +CACHE_EVENT_ATTR(L1-dcache-loads, PM_LD_REF_L1); + +CACHE_EVENT_ATTR(L1-dcache-prefetches, PM_L1_PREF); +CACHE_EVENT_ATTR(L1-dcache-store-misses, PM_ST_MISS_L1); +CACHE_EVENT_ATTR(L1-icache-load-misses, PM_L1_ICACHE_MISS); +CACHE_EVENT_ATTR(L1-icache-loads, PM_INST_FROM_L1); +CACHE_EVENT_ATTR(L1-icache-prefetches, PM_IC_PREF_WRITE); + +CACHE_EVENT_ATTR(LLC-load-misses, PM_DATA_FROM_L3MISS); +CACHE_EVENT_ATTR(LLC-loads, PM_DATA_FROM_L3); +CACHE_EVENT_ATTR(LLC-prefetches, PM_L3_PREF_ALL); +CACHE_EVENT_ATTR(LLC-store-misses, PM_L2_ST_MISS); +CACHE_EVENT_ATTR(LLC-stores, PM_L2_ST); + +CACHE_EVENT_ATTR(branch-load-misses, PM_BR_MPRED_CMPL); +CACHE_EVENT_ATTR(branch-loads, PM_BRU_FIN); +CACHE_EVENT_ATTR(dTLB-load-misses, PM_DTLB_MISS); +CACHE_EVENT_ATTR(iTLB-load-misses, PM_ITLB_MISS); + +static struct attribute *power8_events_attr[] = { + GENERIC_EVENT_PTR(PM_CYC), + GENERIC_EVENT_PTR(PM_GCT_NOSLOT_CYC), + GENERIC_EVENT_PTR(PM_CMPLU_STALL), + GENERIC_EVENT_PTR(PM_INST_CMPL), + GENERIC_EVENT_PTR(PM_BRU_FIN), + GENERIC_EVENT_PTR(PM_BR_MPRED_CMPL), + GENERIC_EVENT_PTR(PM_LD_REF_L1), + GENERIC_EVENT_PTR(PM_LD_MISS_L1), + + CACHE_EVENT_PTR(PM_LD_MISS_L1), + CACHE_EVENT_PTR(PM_LD_REF_L1), + CACHE_EVENT_PTR(PM_L1_PREF), + CACHE_EVENT_PTR(PM_ST_MISS_L1), + CACHE_EVENT_PTR(PM_L1_ICACHE_MISS), + CACHE_EVENT_PTR(PM_INST_FROM_L1), + CACHE_EVENT_PTR(PM_IC_PREF_WRITE), + CACHE_EVENT_PTR(PM_DATA_FROM_L3MISS), + CACHE_EVENT_PTR(PM_DATA_FROM_L3), + CACHE_EVENT_PTR(PM_L3_PREF_ALL), + CACHE_EVENT_PTR(PM_L2_ST_MISS), + CACHE_EVENT_PTR(PM_L2_ST), + + CACHE_EVENT_PTR(PM_BR_MPRED_CMPL), + CACHE_EVENT_PTR(PM_BRU_FIN), + + CACHE_EVENT_PTR(PM_DTLB_MISS), + CACHE_EVENT_PTR(PM_ITLB_MISS), + NULL +}; + +static struct attribute_group power8_pmu_events_group = { + .name = "events", + .attrs = power8_events_attr, +}; + PMU_FORMAT_ATTR(event, "config:0-49"); PMU_FORMAT_ATTR(pmcxsel, "config:0-7"); PMU_FORMAT_ATTR(mark, "config:8"); @@ -640,6 +673,7 @@ struct attribute_group power8_pmu_format_group = { static const struct attribute_group *power8_pmu_attr_groups[] = { &power8_pmu_format_group, + &power8_pmu_events_group, NULL, }; diff --git a/arch/powerpc/platforms/512x/mpc512x_shared.c b/arch/powerpc/platforms/512x/mpc512x_shared.c index 711f3d352af7b45e6ca7786f065963dbde3eb747..452da2391153aef4ffb132a65d440ccfa8fe0e45 100644 --- a/arch/powerpc/platforms/512x/mpc512x_shared.c +++ b/arch/powerpc/platforms/512x/mpc512x_shared.c @@ -188,7 +188,7 @@ static struct fsl_diu_shared_fb __attribute__ ((__aligned__(8))) diu_shared_fb; static inline void mpc512x_free_bootmem(struct page *page) { BUG_ON(PageTail(page)); - BUG_ON(atomic_read(&page->_count) > 1); + BUG_ON(page_ref_count(page) > 1); free_reserved_page(page); } diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/arch/powerpc/platforms/52xx/mpc52xx_pci.c index 6eb3b2abae9088a653705010741cff60b90261a2..00282c2b0cae9bee9d8cef2be40128e02b65f563 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_pci.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_pci.c @@ -319,7 +319,7 @@ mpc52xx_pci_setup(struct pci_controller *hose, tmp = in_be32(&pci_regs->gscr); #if 0 - /* Reset the exteral bus ( internal PCI controller is NOT resetted ) */ + /* Reset the exteral bus ( internal PCI controller is NOT reset ) */ /* Not necessary and can be a bad thing if for example the bootloader is displaying a splash screen or ... Just left here for documentation purpose if anyone need it */ diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig index 97915feffd42d35be230f3d4b58883b938b4eaae..e626461a63bd1ab04a6c0fc63cafb02c9d2139db 100644 --- a/arch/powerpc/platforms/85xx/Kconfig +++ b/arch/powerpc/platforms/85xx/Kconfig @@ -8,6 +8,7 @@ menuconfig FSL_SOC_BOOKE select FSL_PCI if PCI select SERIAL_8250_EXTENDED if SERIAL_8250 select SERIAL_8250_SHARE_IRQ if SERIAL_8250 + select FSL_CORENET_RCPM if PPC_E500MC default y if FSL_SOC_BOOKE diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile index 1fe7fb95175a50ebec0576fac897ae077f7b5a8e..7bc86dae9517654cc14a379c6022f56b05f00f9f 100644 --- a/arch/powerpc/platforms/85xx/Makefile +++ b/arch/powerpc/platforms/85xx/Makefile @@ -2,6 +2,7 @@ # Makefile for the PowerPC 85xx linux kernel. # obj-$(CONFIG_SMP) += smp.o +obj-$(CONFIG_FSL_PMC) += mpc85xx_pm_ops.o obj-y += common.o diff --git a/arch/powerpc/platforms/85xx/common.c b/arch/powerpc/platforms/85xx/common.c index 949f22c86e61c97bce0e9dd0eaab64c4be24d8da..28720a4ded7ba974eeccb944b5a5eca143ade75b 100644 --- a/arch/powerpc/platforms/85xx/common.c +++ b/arch/powerpc/platforms/85xx/common.c @@ -9,11 +9,14 @@ #include #include +#include #include #include #include "mpc85xx.h" +const struct fsl_pm_ops *qoriq_pm_ops; + static const struct of_device_id mpc85xx_common_ids[] __initconst = { { .type = "soc", }, { .compatible = "soc", }, diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c index 5ac70de3e48ace4d756f4f84157f909fa4f9aa7c..d7e87ff912d7d9df3e18c7e7357d39f313880d2b 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c @@ -99,7 +99,7 @@ static void mpc85xx_cds_restart(char *cmd) pci_read_config_byte(dev, 0x47, &tmp); /* - * At this point, the harware reset should have triggered. + * At this point, the hardware reset should have triggered. * However, if it doesn't work for some mysterious reason, * just fall through to the default reset below. */ diff --git a/arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c b/arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c new file mode 100644 index 0000000000000000000000000000000000000000..f05325f0cc03bd39f27eac46af45b772e3d6926f --- /dev/null +++ b/arch/powerpc/platforms/85xx/mpc85xx_pm_ops.c @@ -0,0 +1,106 @@ +/* + * MPC85xx PM operators + * + * Copyright 2015 Freescale Semiconductor Inc. + * + * 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. + */ + +#define pr_fmt(fmt) "%s: " fmt, __func__ + +#include +#include +#include +#include + +#include +#include + +static struct ccsr_guts __iomem *guts; + +static void mpc85xx_irq_mask(int cpu) +{ + +} + +static void mpc85xx_irq_unmask(int cpu) +{ + +} + +static void mpc85xx_cpu_die(int cpu) +{ + u32 tmp; + + tmp = (mfspr(SPRN_HID0) & ~(HID0_DOZE|HID0_SLEEP)) | HID0_NAP; + mtspr(SPRN_HID0, tmp); + + /* Enter NAP mode. */ + tmp = mfmsr(); + tmp |= MSR_WE; + asm volatile( + "msync\n" + "mtmsr %0\n" + "isync\n" + : + : "r" (tmp)); +} + +static void mpc85xx_cpu_up_prepare(int cpu) +{ + +} + +static void mpc85xx_freeze_time_base(bool freeze) +{ + uint32_t mask; + + mask = CCSR_GUTS_DEVDISR_TB0 | CCSR_GUTS_DEVDISR_TB1; + if (freeze) + setbits32(&guts->devdisr, mask); + else + clrbits32(&guts->devdisr, mask); + + in_be32(&guts->devdisr); +} + +static const struct of_device_id mpc85xx_smp_guts_ids[] = { + { .compatible = "fsl,mpc8572-guts", }, + { .compatible = "fsl,p1020-guts", }, + { .compatible = "fsl,p1021-guts", }, + { .compatible = "fsl,p1022-guts", }, + { .compatible = "fsl,p1023-guts", }, + { .compatible = "fsl,p2020-guts", }, + { .compatible = "fsl,bsc9132-guts", }, + {}, +}; + +static const struct fsl_pm_ops mpc85xx_pm_ops = { + .freeze_time_base = mpc85xx_freeze_time_base, + .irq_mask = mpc85xx_irq_mask, + .irq_unmask = mpc85xx_irq_unmask, + .cpu_die = mpc85xx_cpu_die, + .cpu_up_prepare = mpc85xx_cpu_up_prepare, +}; + +int __init mpc85xx_setup_pmc(void) +{ + struct device_node *np; + + np = of_find_matching_node(NULL, mpc85xx_smp_guts_ids); + if (np) { + guts = of_iomap(np, 0); + of_node_put(np); + if (!guts) { + pr_err("Could not map guts node address\n"); + return -ENOMEM; + } + } + + qoriq_pm_ops = &mpc85xx_pm_ops; + + return 0; +} diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 6b107cea1c08e0b9e2f5a9807ba64ff9cbe94d0d..fe9f19e5e935f538dec748c40390e41d2313ff09 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -2,7 +2,7 @@ * Author: Andy Fleming * Kumar Gala * - * Copyright 2006-2008, 2011-2012 Freescale Semiconductor Inc. + * Copyright 2006-2008, 2011-2012, 2015 Freescale Semiconductor Inc. * * 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 @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -29,6 +28,7 @@ #include #include #include +#include #include #include @@ -43,35 +43,23 @@ struct epapr_spin_table { u32 pir; }; -static struct ccsr_guts __iomem *guts; +#ifdef CONFIG_HOTPLUG_CPU static u64 timebase; static int tb_req; static int tb_valid; -static void mpc85xx_timebase_freeze(int freeze) -{ - uint32_t mask; - - mask = CCSR_GUTS_DEVDISR_TB0 | CCSR_GUTS_DEVDISR_TB1; - if (freeze) - setbits32(&guts->devdisr, mask); - else - clrbits32(&guts->devdisr, mask); - - in_be32(&guts->devdisr); -} - static void mpc85xx_give_timebase(void) { unsigned long flags; local_irq_save(flags); + hard_irq_disable(); while (!tb_req) barrier(); tb_req = 0; - mpc85xx_timebase_freeze(1); + qoriq_pm_ops->freeze_time_base(true); #ifdef CONFIG_PPC64 /* * e5500/e6500 have a workaround for erratum A-006958 in place @@ -104,7 +92,7 @@ static void mpc85xx_give_timebase(void) while (tb_valid) barrier(); - mpc85xx_timebase_freeze(0); + qoriq_pm_ops->freeze_time_base(false); local_irq_restore(flags); } @@ -114,6 +102,7 @@ static void mpc85xx_take_timebase(void) unsigned long flags; local_irq_save(flags); + hard_irq_disable(); tb_req = 1; while (!tb_valid) @@ -126,36 +115,54 @@ static void mpc85xx_take_timebase(void) local_irq_restore(flags); } -#ifdef CONFIG_HOTPLUG_CPU static void smp_85xx_mach_cpu_die(void) { unsigned int cpu = smp_processor_id(); - u32 tmp; local_irq_disable(); + hard_irq_disable(); + /* mask all irqs to prevent cpu wakeup */ + qoriq_pm_ops->irq_mask(cpu); + idle_task_exit(); - generic_set_cpu_dead(cpu); - mb(); mtspr(SPRN_TCR, 0); + mtspr(SPRN_TSR, mfspr(SPRN_TSR)); - __flush_disable_L1(); - tmp = (mfspr(SPRN_HID0) & ~(HID0_DOZE|HID0_SLEEP)) | HID0_NAP; - mtspr(SPRN_HID0, tmp); - isync(); + generic_set_cpu_dead(cpu); - /* Enter NAP mode. */ - tmp = mfmsr(); - tmp |= MSR_WE; - mb(); - mtmsr(tmp); - isync(); + cur_cpu_spec->cpu_down_flush(); + + qoriq_pm_ops->cpu_die(cpu); while (1) ; } + +static void qoriq_cpu_kill(unsigned int cpu) +{ + int i; + + for (i = 0; i < 500; i++) { + if (is_cpu_dead(cpu)) { +#ifdef CONFIG_PPC64 + paca[cpu].cpu_start = 0; +#endif + return; + } + msleep(20); + } + pr_err("CPU%d didn't die...\n", cpu); +} #endif +/* + * To keep it compatible with old boot program which uses + * cache-inhibit spin table, we need to flush the cache + * before accessing spin table to invalidate any staled data. + * We also need to flush the cache after writing to spin + * table to push data out. + */ static inline void flush_spin_table(void *spin_table) { flush_dcache_range((ulong)spin_table, @@ -173,78 +180,28 @@ static inline u32 read_spin_table_addr_l(void *spin_table) static void wake_hw_thread(void *info) { void fsl_secondary_thread_init(void); - unsigned long imsr, inia; - int nr = *(const int *)info; + unsigned long inia; + int cpu = *(const int *)info; - imsr = MSR_KERNEL; inia = *(unsigned long *)fsl_secondary_thread_init; - - if (cpu_thread_in_core(nr) == 0) { - /* For when we boot on a secondary thread with kdump */ - mttmr(TMRN_IMSR0, imsr); - mttmr(TMRN_INIA0, inia); - mtspr(SPRN_TENS, TEN_THREAD(0)); - } else { - mttmr(TMRN_IMSR1, imsr); - mttmr(TMRN_INIA1, inia); - mtspr(SPRN_TENS, TEN_THREAD(1)); - } - - smp_generic_kick_cpu(nr); + book3e_start_thread(cpu_thread_in_core(cpu), inia); } #endif -static int smp_85xx_kick_cpu(int nr) +static int smp_85xx_start_cpu(int cpu) { - unsigned long flags; - const u64 *cpu_rel_addr; - __iomem struct epapr_spin_table *spin_table; + int ret = 0; struct device_node *np; - int hw_cpu = get_hard_smp_processor_id(nr); + const u64 *cpu_rel_addr; + unsigned long flags; int ioremappable; - int ret = 0; - - WARN_ON(nr < 0 || nr >= NR_CPUS); - WARN_ON(hw_cpu < 0 || hw_cpu >= NR_CPUS); - - pr_debug("smp_85xx_kick_cpu: kick CPU #%d\n", nr); - -#ifdef CONFIG_PPC64 - /* Threads don't use the spin table */ - if (cpu_thread_in_core(nr) != 0) { - int primary = cpu_first_thread_sibling(nr); - - if (WARN_ON_ONCE(!cpu_has_feature(CPU_FTR_SMT))) - return -ENOENT; - - if (cpu_thread_in_core(nr) != 1) { - pr_err("%s: cpu %d: invalid hw thread %d\n", - __func__, nr, cpu_thread_in_core(nr)); - return -ENOENT; - } + int hw_cpu = get_hard_smp_processor_id(cpu); + struct epapr_spin_table __iomem *spin_table; - if (!cpu_online(primary)) { - pr_err("%s: cpu %d: primary %d not online\n", - __func__, nr, primary); - return -ENOENT; - } - - smp_call_function_single(primary, wake_hw_thread, &nr, 0); - return 0; - } else if (cpu_thread_in_core(boot_cpuid) != 0 && - cpu_first_thread_sibling(boot_cpuid) == nr) { - if (WARN_ON_ONCE(!cpu_has_feature(CPU_FTR_SMT))) - return -ENOENT; - - smp_call_function_single(boot_cpuid, wake_hw_thread, &nr, 0); - } -#endif - - np = of_get_cpu_node(nr, NULL); + np = of_get_cpu_node(cpu, NULL); cpu_rel_addr = of_get_property(np, "cpu-release-addr", NULL); - - if (cpu_rel_addr == NULL) { - printk(KERN_ERR "No cpu-release-addr for cpu %d\n", nr); + if (!cpu_rel_addr) { + pr_err("No cpu-release-addr for cpu %d\n", cpu); return -ENOENT; } @@ -264,28 +221,18 @@ static int smp_85xx_kick_cpu(int nr) spin_table = phys_to_virt(*cpu_rel_addr); local_irq_save(flags); -#ifdef CONFIG_PPC32 -#ifdef CONFIG_HOTPLUG_CPU - /* Corresponding to generic_set_cpu_dead() */ - generic_set_cpu_up(nr); + hard_irq_disable(); - if (system_state == SYSTEM_RUNNING) { - /* - * To keep it compatible with old boot program which uses - * cache-inhibit spin table, we need to flush the cache - * before accessing spin table to invalidate any staled data. - * We also need to flush the cache after writing to spin - * table to push data out. - */ - flush_spin_table(spin_table); - out_be32(&spin_table->addr_l, 0); - flush_spin_table(spin_table); + if (qoriq_pm_ops) + qoriq_pm_ops->cpu_up_prepare(cpu); + /* if cpu is not spinning, reset it */ + if (read_spin_table_addr_l(spin_table) != 1) { /* * We don't set the BPTR register here since it already points * to the boot page properly. */ - mpic_reset_core(nr); + mpic_reset_core(cpu); /* * wait until core is ready... @@ -295,40 +242,23 @@ static int smp_85xx_kick_cpu(int nr) if (!spin_event_timeout( read_spin_table_addr_l(spin_table) == 1, 10000, 100)) { - pr_err("%s: timeout waiting for core %d to reset\n", - __func__, hw_cpu); - ret = -ENOENT; - goto out; + pr_err("timeout waiting for cpu %d to reset\n", + hw_cpu); + ret = -EAGAIN; + goto err; } - - /* clear the acknowledge status */ - __secondary_hold_acknowledge = -1; } -#endif - flush_spin_table(spin_table); - out_be32(&spin_table->pir, hw_cpu); - out_be32(&spin_table->addr_l, __pa(__early_start)); - flush_spin_table(spin_table); - - /* Wait a bit for the CPU to ack. */ - if (!spin_event_timeout(__secondary_hold_acknowledge == hw_cpu, - 10000, 100)) { - pr_err("%s: timeout waiting for core %d to ack\n", - __func__, hw_cpu); - ret = -ENOENT; - goto out; - } -out: -#else - smp_generic_kick_cpu(nr); flush_spin_table(spin_table); out_be32(&spin_table->pir, hw_cpu); +#ifdef CONFIG_PPC64 out_be64((u64 *)(&spin_table->addr_h), __pa(ppc_function_entry(generic_secondary_smp_init))); - flush_spin_table(spin_table); +#else + out_be32(&spin_table->addr_l, __pa(__early_start)); #endif - + flush_spin_table(spin_table); +err: local_irq_restore(flags); if (ioremappable) @@ -337,6 +267,81 @@ static int smp_85xx_kick_cpu(int nr) return ret; } +static int smp_85xx_kick_cpu(int nr) +{ + int ret = 0; +#ifdef CONFIG_PPC64 + int primary = nr; +#endif + + WARN_ON(nr < 0 || nr >= num_possible_cpus()); + + pr_debug("kick CPU #%d\n", nr); + +#ifdef CONFIG_PPC64 + if (threads_per_core == 2) { + if (WARN_ON_ONCE(!cpu_has_feature(CPU_FTR_SMT))) + return -ENOENT; + + booting_thread_hwid = cpu_thread_in_core(nr); + primary = cpu_first_thread_sibling(nr); + + if (qoriq_pm_ops) + qoriq_pm_ops->cpu_up_prepare(nr); + + /* + * If either thread in the core is online, use it to start + * the other. + */ + if (cpu_online(primary)) { + smp_call_function_single(primary, + wake_hw_thread, &nr, 1); + goto done; + } else if (cpu_online(primary + 1)) { + smp_call_function_single(primary + 1, + wake_hw_thread, &nr, 1); + goto done; + } + + /* + * If getting here, it means both threads in the core are + * offline. So start the primary thread, then it will start + * the thread specified in booting_thread_hwid, the one + * corresponding to nr. + */ + + } else if (threads_per_core == 1) { + /* + * If one core has only one thread, set booting_thread_hwid to + * an invalid value. + */ + booting_thread_hwid = INVALID_THREAD_HWID; + + } else if (threads_per_core > 2) { + pr_err("Do not support more than 2 threads per CPU."); + return -EINVAL; + } + + ret = smp_85xx_start_cpu(primary); + if (ret) + return ret; + +done: + paca[nr].cpu_start = 1; + generic_set_cpu_up(nr); + + return ret; +#else + ret = smp_85xx_start_cpu(nr); + if (ret) + return ret; + + generic_set_cpu_up(nr); + + return ret; +#endif +} + struct smp_ops_t smp_85xx_ops = { .kick_cpu = smp_85xx_kick_cpu, .cpu_bootable = smp_generic_cpu_bootable, @@ -359,7 +364,7 @@ void mpc85xx_smp_kexec_cpu_down(int crash_shutdown, int secondary) local_irq_disable(); if (secondary) { - __flush_disable_L1(); + cur_cpu_spec->cpu_down_flush(); atomic_inc(&kexec_down_cpus); /* loop forever */ while (1); @@ -467,16 +472,6 @@ static void smp_85xx_setup_cpu(int cpu_nr) smp_85xx_basic_setup(cpu_nr); } -static const struct of_device_id mpc85xx_smp_guts_ids[] = { - { .compatible = "fsl,mpc8572-guts", }, - { .compatible = "fsl,p1020-guts", }, - { .compatible = "fsl,p1021-guts", }, - { .compatible = "fsl,p1022-guts", }, - { .compatible = "fsl,p1023-guts", }, - { .compatible = "fsl,p2020-guts", }, - {}, -}; - void __init mpc85xx_smp_init(void) { struct device_node *np; @@ -500,22 +495,21 @@ void __init mpc85xx_smp_init(void) smp_85xx_ops.probe = NULL; } - np = of_find_matching_node(NULL, mpc85xx_smp_guts_ids); - if (np) { - guts = of_iomap(np, 0); - of_node_put(np); - if (!guts) { - pr_err("%s: Could not map guts node address\n", - __func__); - return; - } +#ifdef CONFIG_HOTPLUG_CPU +#ifdef CONFIG_FSL_CORENET_RCPM + fsl_rcpm_init(); +#endif + +#ifdef CONFIG_FSL_PMC + mpc85xx_setup_pmc(); +#endif + if (qoriq_pm_ops) { smp_85xx_ops.give_timebase = mpc85xx_give_timebase; smp_85xx_ops.take_timebase = mpc85xx_take_timebase; -#ifdef CONFIG_HOTPLUG_CPU ppc_md.cpu_die = smp_85xx_mach_cpu_die; -#endif + smp_85xx_ops.cpu_die = qoriq_cpu_kill; } - +#endif smp_ops = &smp_85xx_ops; #ifdef CONFIG_KEXEC diff --git a/arch/powerpc/platforms/85xx/smp.h b/arch/powerpc/platforms/85xx/smp.h index e2b44933ff197bcb5aed6a895de6f18056bf91f2..0b20ae315c539116a05fee644a487d593911a163 100644 --- a/arch/powerpc/platforms/85xx/smp.h +++ b/arch/powerpc/platforms/85xx/smp.h @@ -5,6 +5,7 @@ #ifdef CONFIG_SMP void __init mpc85xx_smp_init(void); +int __init mpc85xx_setup_pmc(void); #else static inline void mpc85xx_smp_init(void) { diff --git a/arch/powerpc/platforms/86xx/Makefile b/arch/powerpc/platforms/86xx/Makefile index ede815d6489dbc8fbce9bea2b08fe05549737db7..2d889ad7dc89dee81ee6fcc79f8877845843e55d 100644 --- a/arch/powerpc/platforms/86xx/Makefile +++ b/arch/powerpc/platforms/86xx/Makefile @@ -2,7 +2,7 @@ # Makefile for the PowerPC 86xx linux kernel. # -obj-y := pic.o +obj-y := pic.o common.o obj-$(CONFIG_SMP) += mpc86xx_smp.o obj-$(CONFIG_MPC8641_HPCN) += mpc86xx_hpcn.o obj-$(CONFIG_SBC8641D) += sbc8641d.o diff --git a/arch/powerpc/platforms/86xx/common.c b/arch/powerpc/platforms/86xx/common.c new file mode 100644 index 0000000000000000000000000000000000000000..0f7b7fcf1ba266b30f7521102100a202b3de6415 --- /dev/null +++ b/arch/powerpc/platforms/86xx/common.c @@ -0,0 +1,43 @@ +/* + * Routines common to most mpc86xx-based boards. + * + * This 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 "mpc86xx.h" + +static const struct of_device_id mpc86xx_common_ids[] __initconst = { + { .type = "soc", }, + { .compatible = "soc", }, + { .compatible = "simple-bus", }, + { .name = "localbus", }, + { .compatible = "gianfar", }, + { .compatible = "fsl,mpc8641-pcie", }, + {}, +}; + +int __init mpc86xx_common_publish_devices(void) +{ + return of_platform_bus_probe(NULL, mpc86xx_common_ids, NULL); +} + +long __init mpc86xx_time_init(void) +{ + unsigned int temp; + + /* Set the time base to zero */ + mtspr(SPRN_TBWL, 0); + mtspr(SPRN_TBWU, 0); + + temp = mfspr(SPRN_HID0); + temp |= HID0_TBEN; + mtspr(SPRN_HID0, temp); + isync(); + + return 0; +} diff --git a/arch/powerpc/platforms/86xx/gef_ppc9a.c b/arch/powerpc/platforms/86xx/gef_ppc9a.c index bf17933b20f32c315caf1393d0e666c88cf8876a..8e63b752712c8cce2f876bc82cee140c82651bad 100644 --- a/arch/powerpc/platforms/86xx/gef_ppc9a.c +++ b/arch/powerpc/platforms/86xx/gef_ppc9a.c @@ -197,37 +197,7 @@ static int __init gef_ppc9a_probe(void) return 0; } -static long __init mpc86xx_time_init(void) -{ - unsigned int temp; - - /* Set the time base to zero */ - mtspr(SPRN_TBWL, 0); - mtspr(SPRN_TBWU, 0); - - temp = mfspr(SPRN_HID0); - temp |= HID0_TBEN; - mtspr(SPRN_HID0, temp); - asm volatile("isync"); - - return 0; -} - -static const struct of_device_id of_bus_ids[] __initconst = { - { .compatible = "simple-bus", }, - { .compatible = "gianfar", }, - { .compatible = "fsl,mpc8641-pcie", }, - {}, -}; - -static int __init declare_of_platform_devices(void) -{ - printk(KERN_DEBUG "Probe platform devices\n"); - of_platform_bus_probe(NULL, of_bus_ids, NULL); - - return 0; -} -machine_arch_initcall(gef_ppc9a, declare_of_platform_devices); +machine_arch_initcall(gef_ppc9a, mpc86xx_common_publish_devices); define_machine(gef_ppc9a) { .name = "GE PPC9A", diff --git a/arch/powerpc/platforms/86xx/gef_sbc310.c b/arch/powerpc/platforms/86xx/gef_sbc310.c index 8facf5873866ad94e583cdae37ad42b6573a4d3a..0e0be94f551fb2f9c0e67b7de6f734cb093855c1 100644 --- a/arch/powerpc/platforms/86xx/gef_sbc310.c +++ b/arch/powerpc/platforms/86xx/gef_sbc310.c @@ -184,37 +184,7 @@ static int __init gef_sbc310_probe(void) return 0; } -static long __init mpc86xx_time_init(void) -{ - unsigned int temp; - - /* Set the time base to zero */ - mtspr(SPRN_TBWL, 0); - mtspr(SPRN_TBWU, 0); - - temp = mfspr(SPRN_HID0); - temp |= HID0_TBEN; - mtspr(SPRN_HID0, temp); - asm volatile("isync"); - - return 0; -} - -static const struct of_device_id of_bus_ids[] __initconst = { - { .compatible = "simple-bus", }, - { .compatible = "gianfar", }, - { .compatible = "fsl,mpc8641-pcie", }, - {}, -}; - -static int __init declare_of_platform_devices(void) -{ - printk(KERN_DEBUG "Probe platform devices\n"); - of_platform_bus_probe(NULL, of_bus_ids, NULL); - - return 0; -} -machine_arch_initcall(gef_sbc310, declare_of_platform_devices); +machine_arch_initcall(gef_sbc310, mpc86xx_common_publish_devices); define_machine(gef_sbc310) { .name = "GE SBC310", diff --git a/arch/powerpc/platforms/86xx/gef_sbc610.c b/arch/powerpc/platforms/86xx/gef_sbc610.c index 8c9058df5642d13eb30e8e6c66e14523c2dd3d4e..e8292b492d7e650aeec86e06792c336446ea4524 100644 --- a/arch/powerpc/platforms/86xx/gef_sbc610.c +++ b/arch/powerpc/platforms/86xx/gef_sbc610.c @@ -174,37 +174,7 @@ static int __init gef_sbc610_probe(void) return 0; } -static long __init mpc86xx_time_init(void) -{ - unsigned int temp; - - /* Set the time base to zero */ - mtspr(SPRN_TBWL, 0); - mtspr(SPRN_TBWU, 0); - - temp = mfspr(SPRN_HID0); - temp |= HID0_TBEN; - mtspr(SPRN_HID0, temp); - asm volatile("isync"); - - return 0; -} - -static const struct of_device_id of_bus_ids[] __initconst = { - { .compatible = "simple-bus", }, - { .compatible = "gianfar", }, - { .compatible = "fsl,mpc8641-pcie", }, - {}, -}; - -static int __init declare_of_platform_devices(void) -{ - printk(KERN_DEBUG "Probe platform devices\n"); - of_platform_bus_probe(NULL, of_bus_ids, NULL); - - return 0; -} -machine_arch_initcall(gef_sbc610, declare_of_platform_devices); +machine_arch_initcall(gef_sbc610, mpc86xx_common_publish_devices); define_machine(gef_sbc610) { .name = "GE SBC610", diff --git a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c index 437a9c372ae1ef405c081db17a8cf0bc76951cef..957473e5c8e5109cccf962791bc2508cfbdd0047 100644 --- a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c +++ b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c @@ -88,12 +88,10 @@ static inline void mpc8610_suspend_init(void) { } static const struct of_device_id mpc8610_ids[] __initconst = { { .compatible = "fsl,mpc8610-immr", }, { .compatible = "fsl,mpc8610-guts", }, - { .compatible = "simple-bus", }, /* So that the DMA channel nodes can be probed individually: */ { .compatible = "fsl,eloplus-dma", }, /* PCI controllers */ { .compatible = "fsl,mpc8610-pci", }, - { .compatible = "fsl,mpc8641-pcie", }, {} }; @@ -105,6 +103,8 @@ static int __init mpc8610_declare_of_platform_devices(void) /* Enable wakeup on PIXIS' event IRQ. */ mpc8610_suspend_init(); + mpc86xx_common_publish_devices(); + /* Without this call, the SSI device driver won't get probed. */ of_platform_bus_probe(NULL, mpc8610_ids, NULL); @@ -327,22 +327,6 @@ static int __init mpc86xx_hpcd_probe(void) return 0; } -static long __init mpc86xx_time_init(void) -{ - unsigned int temp; - - /* Set the time base to zero */ - mtspr(SPRN_TBWL, 0); - mtspr(SPRN_TBWU, 0); - - temp = mfspr(SPRN_HID0); - temp |= HID0_TBEN; - mtspr(SPRN_HID0, temp); - asm volatile("isync"); - - return 0; -} - define_machine(mpc86xx_hpcd) { .name = "MPC86xx HPCD", .probe = mpc86xx_hpcd_probe, diff --git a/arch/powerpc/platforms/86xx/mpc86xx.h b/arch/powerpc/platforms/86xx/mpc86xx.h index 08efb57559d1ceaa7c230e7eddaf10c31dcfc23b..53500db6b644301ff3aaa9414a7cb04952b2402b 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx.h +++ b/arch/powerpc/platforms/86xx/mpc86xx.h @@ -17,5 +17,7 @@ extern void mpc86xx_smp_init(void); extern void mpc86xx_init_irq(void); +extern long mpc86xx_time_init(void); +extern int mpc86xx_common_publish_devices(void); #endif /* __MPC86XX_H__ */ diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c index 07ccb1b0cc7de168cc46eec53c8723a8c43491d1..e5084811b9c62b5c45383051bd2deaf8b54b59b1 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c +++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c @@ -110,33 +110,14 @@ static int __init mpc86xx_hpcn_probe(void) return 0; } -static long __init -mpc86xx_time_init(void) -{ - unsigned int temp; - - /* Set the time base to zero */ - mtspr(SPRN_TBWL, 0); - mtspr(SPRN_TBWU, 0); - - temp = mfspr(SPRN_HID0); - temp |= HID0_TBEN; - mtspr(SPRN_HID0, temp); - asm volatile("isync"); - - return 0; -} - static const struct of_device_id of_bus_ids[] __initconst = { - { .compatible = "simple-bus", }, { .compatible = "fsl,srio", }, - { .compatible = "gianfar", }, - { .compatible = "fsl,mpc8641-pcie", }, {}, }; static int __init declare_of_platform_devices(void) { + mpc86xx_common_publish_devices(); of_platform_bus_probe(NULL, of_bus_ids, NULL); return 0; diff --git a/arch/powerpc/platforms/86xx/sbc8641d.c b/arch/powerpc/platforms/86xx/sbc8641d.c index 6810b71d54a795803a6a8cdc6d021af84ebf4b21..2a9cf278c12a7af4367710d180eca90c157622b0 100644 --- a/arch/powerpc/platforms/86xx/sbc8641d.c +++ b/arch/powerpc/platforms/86xx/sbc8641d.c @@ -75,37 +75,7 @@ static int __init sbc8641_probe(void) return 0; } -static long __init -mpc86xx_time_init(void) -{ - unsigned int temp; - - /* Set the time base to zero */ - mtspr(SPRN_TBWL, 0); - mtspr(SPRN_TBWU, 0); - - temp = mfspr(SPRN_HID0); - temp |= HID0_TBEN; - mtspr(SPRN_HID0, temp); - asm volatile("isync"); - - return 0; -} - -static const struct of_device_id of_bus_ids[] __initconst = { - { .compatible = "simple-bus", }, - { .compatible = "gianfar", }, - { .compatible = "fsl,mpc8641-pcie", }, - {}, -}; - -static int __init declare_of_platform_devices(void) -{ - of_platform_bus_probe(NULL, of_bus_ids, NULL); - - return 0; -} -machine_arch_initcall(sbc8641, declare_of_platform_devices); +machine_arch_initcall(sbc8641, mpc86xx_common_publish_devices); define_machine(sbc8641) { .name = "SBC8641D", diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index dfa863876778144baa5cb99ac65e61c4ca60ec70..6ca5f0525e5701518b5ebba4cc4b40d387b3a68b 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c @@ -732,8 +732,8 @@ spufs_fill_super(struct super_block *sb, void *data, int silent) return -ENOMEM; sb->s_maxbytes = MAX_LFS_FILESIZE; - sb->s_blocksize = PAGE_CACHE_SIZE; - sb->s_blocksize_bits = PAGE_CACHE_SHIFT; + sb->s_blocksize = PAGE_SIZE; + sb->s_blocksize_bits = PAGE_SHIFT; sb->s_magic = SPUFS_MAGIC; sb->s_op = &s_ops; sb->s_fs_info = info; diff --git a/arch/powerpc/platforms/embedded6xx/mpc10x.h b/arch/powerpc/platforms/embedded6xx/mpc10x.h index b290b63661f17b8f8afd950c0b5723c1ed225362..5ad12023e56280171238e13cf5136f67df1cc0bc 100644 --- a/arch/powerpc/platforms/embedded6xx/mpc10x.h +++ b/arch/powerpc/platforms/embedded6xx/mpc10x.h @@ -24,13 +24,11 @@ * Processor: 0x80000000 - 0x807fffff -> PCI I/O: 0x00000000 - 0x007fffff * Processor: 0xc0000000 - 0xdfffffff -> PCI MEM: 0x00000000 - 0x1fffffff * PCI MEM: 0x80000000 -> Processor System Memory: 0x00000000 - * EUMB mapped to: ioremap_base - 0x00100000 (ioremap_base - 1 MB) * * MAP B (CHRP Map) * Processor: 0xfe000000 - 0xfebfffff -> PCI I/O: 0x00000000 - 0x00bfffff * Processor: 0x80000000 - 0xbfffffff -> PCI MEM: 0x80000000 - 0xbfffffff * PCI MEM: 0x00000000 -> Processor System Memory: 0x00000000 - * EUMB mapped to: ioremap_base - 0x00100000 (ioremap_base - 1 MB) */ /* @@ -138,14 +136,6 @@ #define MPC10X_EUMB_WP_OFFSET 0x000ff000 /* Data path diagnostic, watchpoint reg offset */ #define MPC10X_EUMB_WP_SIZE 0x00001000 /* Data path diagnostic, watchpoint reg size */ -/* - * Define some recommended places to put the EUMB regs. - * For both maps, recommend putting the EUMB from 0xeff00000 to 0xefffffff. - */ -extern unsigned long ioremap_base; -#define MPC10X_MAPA_EUMB_BASE (ioremap_base - MPC10X_EUMB_SIZE) -#define MPC10X_MAPB_EUMB_BASE MPC10X_MAPA_EUMB_BASE - enum ppc_sys_devices { MPC10X_IIC1, MPC10X_DMA0, diff --git a/arch/powerpc/platforms/powermac/Makefile b/arch/powerpc/platforms/powermac/Makefile index 52c6ce1cc985ba33c93a9afc35572b5dc9457d8c..1eb7b45e017d14e8df7440f7b5d34af0f05f65b3 100644 --- a/arch/powerpc/platforms/powermac/Makefile +++ b/arch/powerpc/platforms/powermac/Makefile @@ -2,7 +2,7 @@ CFLAGS_bootx_init.o += -fPIC ifdef CONFIG_FUNCTION_TRACER # Do not trace early boot code -CFLAGS_REMOVE_bootx_init.o = -pg -mno-sched-epilog +CFLAGS_REMOVE_bootx_init.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) endif obj-y += pic.o setup.o time.o feature.o pci.o \ diff --git a/arch/powerpc/platforms/powermac/cache.S b/arch/powerpc/platforms/powermac/cache.S index 6be1a4af335973cc057cec26bdb9bc6080e93cae..cc5347eb1662281fb7796b41c9ec78373135da2b 100644 --- a/arch/powerpc/platforms/powermac/cache.S +++ b/arch/powerpc/platforms/powermac/cache.S @@ -23,7 +23,7 @@ * when going to sleep, when doing a PMU based cpufreq transition, * or when "offlining" a CPU on SMP machines. This code is over * paranoid, but I've had enough issues with various CPU revs and - * bugs that I decided it was worth beeing over cautious + * bugs that I decided it was worth being over cautious */ _GLOBAL(flush_disable_caches) diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c index 4882bfd90e27c820b42db5307a08d4c271f48ded..1e02328c3f2d4d8c1bd45c7b5f074dc59f9641bd 100644 --- a/arch/powerpc/platforms/powermac/feature.c +++ b/arch/powerpc/platforms/powermac/feature.c @@ -198,7 +198,7 @@ static long ohare_htw_scc_enable(struct device_node *node, long param, if (htw) { /* Side effect: this will also power up the * modem, but it's too messy to figure out on which - * ports this controls the tranceiver and on which + * ports this controls the transceiver and on which * it controls the modem */ if (trans) @@ -463,7 +463,7 @@ static long heathrow_sound_enable(struct device_node *node, long param, unsigned long flags; /* B&W G3 and Yikes don't support that properly (the - * sound appear to never come back after beeing shut down). + * sound appear to never come back after being shut down). */ if (pmac_mb.model_id == PMAC_TYPE_YOSEMITE || pmac_mb.model_id == PMAC_TYPE_YIKES) @@ -2770,7 +2770,7 @@ set_initial_features(void) * but I'm not too sure it was audited for side-effects on other * ohare based machines... * Since I still have difficulties figuring the right way to - * differenciate them all and since that hack was there for a long + * differentiate them all and since that hack was there for a long * time, I'll keep it around */ if (macio_chips[0].type == macio_ohare) { diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile index f1516b5ecec94c04740256396b293b53157923df..cd9711e72df685751792ba9b7f027fc1a98b062b 100644 --- a/arch/powerpc/platforms/powernv/Makefile +++ b/arch/powerpc/platforms/powernv/Makefile @@ -5,7 +5,7 @@ obj-y += opal-msglog.o opal-hmi.o opal-power.o opal-irqchip.o obj-y += opal-kmsg.o obj-$(CONFIG_SMP) += smp.o subcore.o subcore-asm.o -obj-$(CONFIG_PCI) += pci.o pci-p5ioc2.o pci-ioda.o npu-dma.o +obj-$(CONFIG_PCI) += pci.o pci-ioda.o npu-dma.o obj-$(CONFIG_EEH) += eeh-powernv.o obj-$(CONFIG_PPC_SCOM) += opal-xscom.o obj-$(CONFIG_MEMORY_FAILURE) += opal-memory-errors.o diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c index 87f47e55aab65ac234df1d67c926ca17b1517f06..950b3e539057a9f7affed493e49d17979e43b95f 100644 --- a/arch/powerpc/platforms/powernv/eeh-powernv.c +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c @@ -167,42 +167,26 @@ static int pnv_eeh_dbgfs_get(void *data, int offset, u64 *val) return 0; } -static int pnv_eeh_outb_dbgfs_set(void *data, u64 val) -{ - return pnv_eeh_dbgfs_set(data, 0xD10, val); -} - -static int pnv_eeh_outb_dbgfs_get(void *data, u64 *val) -{ - return pnv_eeh_dbgfs_get(data, 0xD10, val); -} - -static int pnv_eeh_inbA_dbgfs_set(void *data, u64 val) -{ - return pnv_eeh_dbgfs_set(data, 0xD90, val); -} - -static int pnv_eeh_inbA_dbgfs_get(void *data, u64 *val) -{ - return pnv_eeh_dbgfs_get(data, 0xD90, val); -} - -static int pnv_eeh_inbB_dbgfs_set(void *data, u64 val) -{ - return pnv_eeh_dbgfs_set(data, 0xE10, val); -} +#define PNV_EEH_DBGFS_ENTRY(name, reg) \ +static int pnv_eeh_dbgfs_set_##name(void *data, u64 val) \ +{ \ + return pnv_eeh_dbgfs_set(data, reg, val); \ +} \ + \ +static int pnv_eeh_dbgfs_get_##name(void *data, u64 *val) \ +{ \ + return pnv_eeh_dbgfs_get(data, reg, val); \ +} \ + \ +DEFINE_SIMPLE_ATTRIBUTE(pnv_eeh_dbgfs_ops_##name, \ + pnv_eeh_dbgfs_get_##name, \ + pnv_eeh_dbgfs_set_##name, \ + "0x%llx\n") + +PNV_EEH_DBGFS_ENTRY(outb, 0xD10); +PNV_EEH_DBGFS_ENTRY(inbA, 0xD90); +PNV_EEH_DBGFS_ENTRY(inbB, 0xE10); -static int pnv_eeh_inbB_dbgfs_get(void *data, u64 *val) -{ - return pnv_eeh_dbgfs_get(data, 0xE10, val); -} - -DEFINE_SIMPLE_ATTRIBUTE(pnv_eeh_outb_dbgfs_ops, pnv_eeh_outb_dbgfs_get, - pnv_eeh_outb_dbgfs_set, "0x%llx\n"); -DEFINE_SIMPLE_ATTRIBUTE(pnv_eeh_inbA_dbgfs_ops, pnv_eeh_inbA_dbgfs_get, - pnv_eeh_inbA_dbgfs_set, "0x%llx\n"); -DEFINE_SIMPLE_ATTRIBUTE(pnv_eeh_inbB_dbgfs_ops, pnv_eeh_inbB_dbgfs_get, - pnv_eeh_inbB_dbgfs_set, "0x%llx\n"); #endif /* CONFIG_DEBUG_FS */ /** @@ -268,13 +252,13 @@ static int pnv_eeh_post_init(void) debugfs_create_file("err_injct_outbound", 0600, phb->dbgfs, hose, - &pnv_eeh_outb_dbgfs_ops); + &pnv_eeh_dbgfs_ops_outb); debugfs_create_file("err_injct_inboundA", 0600, phb->dbgfs, hose, - &pnv_eeh_inbA_dbgfs_ops); + &pnv_eeh_dbgfs_ops_inbA); debugfs_create_file("err_injct_inboundB", 0600, phb->dbgfs, hose, - &pnv_eeh_inbB_dbgfs_ops); + &pnv_eeh_dbgfs_ops_inbB); #endif /* CONFIG_DEBUG_FS */ } @@ -387,6 +371,7 @@ static void *pnv_eeh_probe(struct pci_dn *pdn, void *data) edev->mode &= 0xFFFFFF00; edev->pcix_cap = pnv_eeh_find_cap(pdn, PCI_CAP_ID_PCIX); edev->pcie_cap = pnv_eeh_find_cap(pdn, PCI_CAP_ID_EXP); + edev->af_cap = pnv_eeh_find_cap(pdn, PCI_CAP_ID_AF); edev->aer_cap = pnv_eeh_find_ecap(pdn, PCI_EXT_CAP_ID_ERR); if ((edev->class_code >> 8) == PCI_CLASS_BRIDGE_PCI) { edev->mode |= EEH_DEV_BRIDGE; @@ -895,6 +880,120 @@ void pnv_pci_reset_secondary_bus(struct pci_dev *dev) } } +static void pnv_eeh_wait_for_pending(struct pci_dn *pdn, const char *type, + int pos, u16 mask) +{ + struct eeh_dev *edev = pdn_to_eeh_dev(pdn); + int i, status = 0; + + /* Wait for Transaction Pending bit to be cleared */ + for (i = 0; i < 4; i++) { + eeh_ops->read_config(pdn, pos, 2, &status); + if (!(status & mask)) + return; + + msleep((1 << i) * 100); + } + + pr_warn("%s: Pending transaction while issuing %sFLR to %04x:%02x:%02x.%01x\n", + __func__, type, + edev->phb->global_number, pdn->busno, + PCI_SLOT(pdn->devfn), PCI_FUNC(pdn->devfn)); +} + +static int pnv_eeh_do_flr(struct pci_dn *pdn, int option) +{ + struct eeh_dev *edev = pdn_to_eeh_dev(pdn); + u32 reg = 0; + + if (WARN_ON(!edev->pcie_cap)) + return -ENOTTY; + + eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCAP, 4, ®); + if (!(reg & PCI_EXP_DEVCAP_FLR)) + return -ENOTTY; + + switch (option) { + case EEH_RESET_HOT: + case EEH_RESET_FUNDAMENTAL: + pnv_eeh_wait_for_pending(pdn, "", + edev->pcie_cap + PCI_EXP_DEVSTA, + PCI_EXP_DEVSTA_TRPND); + eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL, + 4, ®); + reg |= PCI_EXP_DEVCTL_BCR_FLR; + eeh_ops->write_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL, + 4, reg); + msleep(EEH_PE_RST_HOLD_TIME); + break; + case EEH_RESET_DEACTIVATE: + eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL, + 4, ®); + reg &= ~PCI_EXP_DEVCTL_BCR_FLR; + eeh_ops->write_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL, + 4, reg); + msleep(EEH_PE_RST_SETTLE_TIME); + break; + } + + return 0; +} + +static int pnv_eeh_do_af_flr(struct pci_dn *pdn, int option) +{ + struct eeh_dev *edev = pdn_to_eeh_dev(pdn); + u32 cap = 0; + + if (WARN_ON(!edev->af_cap)) + return -ENOTTY; + + eeh_ops->read_config(pdn, edev->af_cap + PCI_AF_CAP, 1, &cap); + if (!(cap & PCI_AF_CAP_TP) || !(cap & PCI_AF_CAP_FLR)) + return -ENOTTY; + + switch (option) { + case EEH_RESET_HOT: + case EEH_RESET_FUNDAMENTAL: + /* + * Wait for Transaction Pending bit to clear. A word-aligned + * test is used, so we use the conrol offset rather than status + * and shift the test bit to match. + */ + pnv_eeh_wait_for_pending(pdn, "AF", + edev->af_cap + PCI_AF_CTRL, + PCI_AF_STATUS_TP << 8); + eeh_ops->write_config(pdn, edev->af_cap + PCI_AF_CTRL, + 1, PCI_AF_CTRL_FLR); + msleep(EEH_PE_RST_HOLD_TIME); + break; + case EEH_RESET_DEACTIVATE: + eeh_ops->write_config(pdn, edev->af_cap + PCI_AF_CTRL, 1, 0); + msleep(EEH_PE_RST_SETTLE_TIME); + break; + } + + return 0; +} + +static int pnv_eeh_reset_vf_pe(struct eeh_pe *pe, int option) +{ + struct eeh_dev *edev; + struct pci_dn *pdn; + int ret; + + /* The VF PE should have only one child device */ + edev = list_first_entry_or_null(&pe->edevs, struct eeh_dev, list); + pdn = eeh_dev_to_pdn(edev); + if (!pdn) + return -ENXIO; + + ret = pnv_eeh_do_flr(pdn, option); + if (!ret) + return ret; + + return pnv_eeh_do_af_flr(pdn, option); +} + /** * pnv_eeh_reset - Reset the specified PE * @pe: EEH PE @@ -956,7 +1055,9 @@ static int pnv_eeh_reset(struct eeh_pe *pe, int option) } bus = eeh_pe_bus_get(pe); - if (pci_is_root_bus(bus) || + if (pe->type & EEH_PE_VF) + ret = pnv_eeh_reset_vf_pe(pe, option); + else if (pci_is_root_bus(bus) || pci_is_root_bus(bus->parent)) ret = pnv_eeh_root_reset(hose, option); else @@ -1095,6 +1196,14 @@ static inline bool pnv_eeh_cfg_blocked(struct pci_dn *pdn) if (!edev || !edev->pe) return false; + /* + * We will issue FLR or AF FLR to all VFs, which are contained + * in VF PE. It relies on the EEH PCI config accessors. So we + * can't block them during the window. + */ + if (edev->physfn && (edev->pe->state & EEH_PE_RESET)) + return false; + if (edev->pe->state & EEH_PE_CFG_BLOCKED) return true; @@ -1479,6 +1588,65 @@ static int pnv_eeh_next_error(struct eeh_pe **pe) return ret; } +static int pnv_eeh_restore_vf_config(struct pci_dn *pdn) +{ + struct eeh_dev *edev = pdn_to_eeh_dev(pdn); + u32 devctl, cmd, cap2, aer_capctl; + int old_mps; + + if (edev->pcie_cap) { + /* Restore MPS */ + old_mps = (ffs(pdn->mps) - 8) << 5; + eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL, + 2, &devctl); + devctl &= ~PCI_EXP_DEVCTL_PAYLOAD; + devctl |= old_mps; + eeh_ops->write_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL, + 2, devctl); + + /* Disable Completion Timeout */ + eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCAP2, + 4, &cap2); + if (cap2 & 0x10) { + eeh_ops->read_config(pdn, + edev->pcie_cap + PCI_EXP_DEVCTL2, + 4, &cap2); + cap2 |= 0x10; + eeh_ops->write_config(pdn, + edev->pcie_cap + PCI_EXP_DEVCTL2, + 4, cap2); + } + } + + /* Enable SERR and parity checking */ + eeh_ops->read_config(pdn, PCI_COMMAND, 2, &cmd); + cmd |= (PCI_COMMAND_PARITY | PCI_COMMAND_SERR); + eeh_ops->write_config(pdn, PCI_COMMAND, 2, cmd); + + /* Enable report various errors */ + if (edev->pcie_cap) { + eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL, + 2, &devctl); + devctl &= ~PCI_EXP_DEVCTL_CERE; + devctl |= (PCI_EXP_DEVCTL_NFERE | + PCI_EXP_DEVCTL_FERE | + PCI_EXP_DEVCTL_URRE); + eeh_ops->write_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL, + 2, devctl); + } + + /* Enable ECRC generation and check */ + if (edev->pcie_cap && edev->aer_cap) { + eeh_ops->read_config(pdn, edev->aer_cap + PCI_ERR_CAP, + 4, &aer_capctl); + aer_capctl |= (PCI_ERR_CAP_ECRC_GENE | PCI_ERR_CAP_ECRC_CHKE); + eeh_ops->write_config(pdn, edev->aer_cap + PCI_ERR_CAP, + 4, aer_capctl); + } + + return 0; +} + static int pnv_eeh_restore_config(struct pci_dn *pdn) { struct eeh_dev *edev = pdn_to_eeh_dev(pdn); @@ -1488,9 +1656,21 @@ static int pnv_eeh_restore_config(struct pci_dn *pdn) if (!edev) return -EEXIST; - phb = edev->phb->private_data; - ret = opal_pci_reinit(phb->opal_id, - OPAL_REINIT_PCI_DEV, edev->config_addr); + /* + * We have to restore the PCI config space after reset since the + * firmware can't see SRIOV VFs. + * + * FIXME: The MPS, error routing rules, timeout setting are worthy + * to be exported by firmware in extendible way. + */ + if (edev->physfn) { + ret = pnv_eeh_restore_vf_config(pdn); + } else { + phb = edev->phb->private_data; + ret = opal_pci_reinit(phb->opal_id, + OPAL_REINIT_PCI_DEV, edev->config_addr); + } + if (ret) { pr_warn("%s: Can't reinit PCI dev 0x%x (%lld)\n", __func__, edev->config_addr, ret); @@ -1519,6 +1699,40 @@ static struct eeh_ops pnv_eeh_ops = { .restore_config = pnv_eeh_restore_config }; +void pcibios_bus_add_device(struct pci_dev *pdev) +{ + struct pci_dn *pdn = pci_get_pdn(pdev); + + if (!pdev->is_virtfn) + return; + + /* + * The following operations will fail if VF's sysfs files + * aren't created or its resources aren't finalized. + */ + eeh_add_device_early(pdn); + eeh_add_device_late(pdev); + eeh_sysfs_add_device(pdev); +} + +#ifdef CONFIG_PCI_IOV +static void pnv_pci_fixup_vf_mps(struct pci_dev *pdev) +{ + struct pci_dn *pdn = pci_get_pdn(pdev); + int parent_mps; + + if (!pdev->is_virtfn) + return; + + /* Synchronize MPS for VF and PF */ + parent_mps = pcie_get_mps(pdev->physfn); + if ((128 << pdev->pcie_mpss) >= parent_mps) + pcie_set_mps(pdev, parent_mps); + pdn->mps = pcie_get_mps(pdev); +} +DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pnv_pci_fixup_vf_mps); +#endif /* CONFIG_PCI_IOV */ + /** * eeh_powernv_init - Register platform dependent EEH operations * diff --git a/arch/powerpc/platforms/powernv/idle.c b/arch/powerpc/platforms/powernv/idle.c index 15bfbcd5debc2db9e8e44930b66f5cdda5717a39..fcc8b6861b63e60b809618b62c39155fb359346d 100644 --- a/arch/powerpc/platforms/powernv/idle.c +++ b/arch/powerpc/platforms/powernv/idle.c @@ -35,9 +35,9 @@ int pnv_save_sprs_for_winkle(void) int rc; /* - * hid0, hid1, hid4, hid5, hmeer and lpcr values are symmetric accross + * hid0, hid1, hid4, hid5, hmeer and lpcr values are symmetric across * all cpus at boot. Get these reg values of current cpu and use the - * same accross all cpus. + * same across all cpus. */ uint64_t lpcr_val = mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1; uint64_t hid0_val = mfspr(SPRN_HID0); @@ -185,7 +185,7 @@ static ssize_t store_fastsleep_workaround_applyonce(struct device *dev, * fastsleep workaround needs to be left in 'applied' state on all * the cores. Do this by- * 1. Patching out the call to 'undo' workaround in fastsleep exit path - * 2. Sending ipi to all the cores which have atleast one online thread + * 2. Sending ipi to all the cores which have at least one online thread * 3. Patching out the call to 'apply' workaround in fastsleep entry * path * There is no need to send ipi to cores which have all threads diff --git a/arch/powerpc/platforms/powernv/npu-dma.c b/arch/powerpc/platforms/powernv/npu-dma.c index e85aa900f5c0761c3a95cf1480c02e7db70b4c3d..7229acd9bb3af5bf7eeb15e60d733f22ff6593b0 100644 --- a/arch/powerpc/platforms/powernv/npu-dma.c +++ b/arch/powerpc/platforms/powernv/npu-dma.c @@ -278,7 +278,7 @@ static void pnv_npu_disable_bypass(struct pnv_ioda_pe *npe) /* * Enable/disable bypass mode on the NPU. The NPU only supports one - * window per link, so bypass needs to be explicity enabled or + * window per link, so bypass needs to be explicitly enabled or * disabled. Unlike for a PHB3 bypass and non-bypass modes can't be * active at the same time. */ diff --git a/arch/powerpc/platforms/powernv/opal-msglog.c b/arch/powerpc/platforms/powernv/opal-msglog.c index 44ed78af1a0dd53bb9e33f16b3ce465ffc5c6f4f..39d6ff9e56309f4c6bb73a2f1f2000aeb2ba6df9 100644 --- a/arch/powerpc/platforms/powernv/opal-msglog.c +++ b/arch/powerpc/platforms/powernv/opal-msglog.c @@ -31,26 +31,25 @@ struct memcons { __be32 in_cons; }; -static ssize_t opal_msglog_read(struct file *file, struct kobject *kobj, - struct bin_attribute *bin_attr, char *to, - loff_t pos, size_t count) +static struct memcons *opal_memcons = NULL; + +ssize_t opal_msglog_copy(char *to, loff_t pos, size_t count) { - struct memcons *mc = bin_attr->private; const char *conbuf; ssize_t ret; size_t first_read = 0; uint32_t out_pos, avail; - if (!mc) + if (!opal_memcons) return -ENODEV; - out_pos = be32_to_cpu(ACCESS_ONCE(mc->out_pos)); + out_pos = be32_to_cpu(ACCESS_ONCE(opal_memcons->out_pos)); /* Now we've read out_pos, put a barrier in before reading the new * data it points to in conbuf. */ smp_rmb(); - conbuf = phys_to_virt(be64_to_cpu(mc->obuf_phys)); + conbuf = phys_to_virt(be64_to_cpu(opal_memcons->obuf_phys)); /* When the buffer has wrapped, read from the out_pos marker to the end * of the buffer, and then read the remaining data as in the un-wrapped @@ -58,7 +57,7 @@ static ssize_t opal_msglog_read(struct file *file, struct kobject *kobj, if (out_pos & MEMCONS_OUT_POS_WRAP) { out_pos &= MEMCONS_OUT_POS_MASK; - avail = be32_to_cpu(mc->obuf_size) - out_pos; + avail = be32_to_cpu(opal_memcons->obuf_size) - out_pos; ret = memory_read_from_buffer(to, count, &pos, conbuf + out_pos, avail); @@ -76,7 +75,7 @@ static ssize_t opal_msglog_read(struct file *file, struct kobject *kobj, } /* Sanity check. The firmware should not do this to us. */ - if (out_pos > be32_to_cpu(mc->obuf_size)) { + if (out_pos > be32_to_cpu(opal_memcons->obuf_size)) { pr_err("OPAL: memory console corruption. Aborting read.\n"); return -EINVAL; } @@ -91,6 +90,13 @@ static ssize_t opal_msglog_read(struct file *file, struct kobject *kobj, return ret; } +static ssize_t opal_msglog_read(struct file *file, struct kobject *kobj, + struct bin_attribute *bin_attr, char *to, + loff_t pos, size_t count) +{ + return opal_msglog_copy(to, pos, count); +} + static struct bin_attribute opal_msglog_attr = { .attr = {.name = "msglog", .mode = 0444}, .read = opal_msglog_read @@ -117,7 +123,15 @@ void __init opal_msglog_init(void) return; } - opal_msglog_attr.private = mc; + opal_memcons = mc; +} + +void __init opal_msglog_sysfs_init(void) +{ + if (!opal_memcons) { + pr_warn("OPAL: message log initialisation failed, not creating sysfs entry\n"); + return; + } if (sysfs_create_bin_file(opal_kobj, &opal_msglog_attr) != 0) pr_warn("OPAL: sysfs file creation failed\n"); diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index 4e0da5af94a124db13fb524b7cce79f9a1704035..0256d07292524b044b87c9b8423d231e0aa5cf2d 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c @@ -724,6 +724,9 @@ static int __init opal_init(void) of_node_put(leds); } + /* Initialise OPAL message log interface */ + opal_msglog_init(); + /* Create "opal" kobject under /sys/firmware */ rc = opal_sysfs_init(); if (rc == 0) { @@ -739,8 +742,8 @@ static int __init opal_init(void) opal_platform_dump_init(); /* Setup system parameters interface */ opal_sys_param_init(); - /* Setup message log interface. */ - opal_msglog_init(); + /* Setup message log sysfs interface. */ + opal_msglog_sysfs_init(); } /* Initialize platform devices: IPMI backend, PRD & flash interface */ diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index f90dc04395bf47bcc0e662a7a1c17526220ccda2..c5baaf3cc4e5ef565bcaadeb125bd6ac2138a4c9 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -872,9 +872,6 @@ static int pnv_pci_vf_resource_shift(struct pci_dev *dev, int offset) if (!res->flags || !res->parent) continue; - if (!pnv_pci_is_mem_pref_64(res->flags)) - continue; - /* * The actual IOV BAR range is determined by the start address * and the actual size for num_vfs VFs BAR. This check is to @@ -903,9 +900,6 @@ static int pnv_pci_vf_resource_shift(struct pci_dev *dev, int offset) if (!res->flags || !res->parent) continue; - if (!pnv_pci_is_mem_pref_64(res->flags)) - continue; - size = pci_iov_resource_size(dev, i + PCI_IOV_RESOURCES); res2 = *res; res->start += size * offset; @@ -1196,29 +1190,36 @@ static void pnv_pci_ioda_setup_PEs(void) } #ifdef CONFIG_PCI_IOV -static int pnv_pci_vf_release_m64(struct pci_dev *pdev) +static int pnv_pci_vf_release_m64(struct pci_dev *pdev, u16 num_vfs) { struct pci_bus *bus; struct pci_controller *hose; struct pnv_phb *phb; struct pci_dn *pdn; int i, j; + int m64_bars; bus = pdev->bus; hose = pci_bus_to_host(bus); phb = hose->private_data; pdn = pci_get_pdn(pdev); + if (pdn->m64_single_mode) + m64_bars = num_vfs; + else + m64_bars = 1; + for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) - for (j = 0; j < M64_PER_IOV; j++) { - if (pdn->m64_wins[i][j] == IODA_INVALID_M64) + for (j = 0; j < m64_bars; j++) { + if (pdn->m64_map[j][i] == IODA_INVALID_M64) continue; opal_pci_phb_mmio_enable(phb->opal_id, - OPAL_M64_WINDOW_TYPE, pdn->m64_wins[i][j], 0); - clear_bit(pdn->m64_wins[i][j], &phb->ioda.m64_bar_alloc); - pdn->m64_wins[i][j] = IODA_INVALID_M64; + OPAL_M64_WINDOW_TYPE, pdn->m64_map[j][i], 0); + clear_bit(pdn->m64_map[j][i], &phb->ioda.m64_bar_alloc); + pdn->m64_map[j][i] = IODA_INVALID_M64; } + kfree(pdn->m64_map); return 0; } @@ -1235,8 +1236,7 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs) int total_vfs; resource_size_t size, start; int pe_num; - int vf_groups; - int vf_per_group; + int m64_bars; bus = pdev->bus; hose = pci_bus_to_host(bus); @@ -1244,29 +1244,26 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs) pdn = pci_get_pdn(pdev); total_vfs = pci_sriov_get_totalvfs(pdev); - /* Initialize the m64_wins to IODA_INVALID_M64 */ - for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) - for (j = 0; j < M64_PER_IOV; j++) - pdn->m64_wins[i][j] = IODA_INVALID_M64; + if (pdn->m64_single_mode) + m64_bars = num_vfs; + else + m64_bars = 1; + + pdn->m64_map = kmalloc(sizeof(*pdn->m64_map) * m64_bars, GFP_KERNEL); + if (!pdn->m64_map) + return -ENOMEM; + /* Initialize the m64_map to IODA_INVALID_M64 */ + for (i = 0; i < m64_bars ; i++) + for (j = 0; j < PCI_SRIOV_NUM_BARS; j++) + pdn->m64_map[i][j] = IODA_INVALID_M64; - if (pdn->m64_per_iov == M64_PER_IOV) { - vf_groups = (num_vfs <= M64_PER_IOV) ? num_vfs: M64_PER_IOV; - vf_per_group = (num_vfs <= M64_PER_IOV)? 1: - roundup_pow_of_two(num_vfs) / pdn->m64_per_iov; - } else { - vf_groups = 1; - vf_per_group = 1; - } for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) { res = &pdev->resource[i + PCI_IOV_RESOURCES]; if (!res->flags || !res->parent) continue; - if (!pnv_pci_is_mem_pref_64(res->flags)) - continue; - - for (j = 0; j < vf_groups; j++) { + for (j = 0; j < m64_bars; j++) { do { win = find_next_zero_bit(&phb->ioda.m64_bar_alloc, phb->ioda.m64_bar_idx + 1, 0); @@ -1275,12 +1272,11 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs) goto m64_failed; } while (test_and_set_bit(win, &phb->ioda.m64_bar_alloc)); - pdn->m64_wins[i][j] = win; + pdn->m64_map[j][i] = win; - if (pdn->m64_per_iov == M64_PER_IOV) { + if (pdn->m64_single_mode) { size = pci_iov_resource_size(pdev, PCI_IOV_RESOURCES + i); - size = size * vf_per_group; start = res->start + size * j; } else { size = resource_size(res); @@ -1288,16 +1284,16 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs) } /* Map the M64 here */ - if (pdn->m64_per_iov == M64_PER_IOV) { - pe_num = pdn->offset + j; + if (pdn->m64_single_mode) { + pe_num = pdn->pe_num_map[j]; rc = opal_pci_map_pe_mmio_window(phb->opal_id, pe_num, OPAL_M64_WINDOW_TYPE, - pdn->m64_wins[i][j], 0); + pdn->m64_map[j][i], 0); } rc = opal_pci_set_phb_mem_window(phb->opal_id, OPAL_M64_WINDOW_TYPE, - pdn->m64_wins[i][j], + pdn->m64_map[j][i], start, 0, /* unused */ size); @@ -1309,12 +1305,12 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs) goto m64_failed; } - if (pdn->m64_per_iov == M64_PER_IOV) + if (pdn->m64_single_mode) rc = opal_pci_phb_mmio_enable(phb->opal_id, - OPAL_M64_WINDOW_TYPE, pdn->m64_wins[i][j], 2); + OPAL_M64_WINDOW_TYPE, pdn->m64_map[j][i], 2); else rc = opal_pci_phb_mmio_enable(phb->opal_id, - OPAL_M64_WINDOW_TYPE, pdn->m64_wins[i][j], 1); + OPAL_M64_WINDOW_TYPE, pdn->m64_map[j][i], 1); if (rc != OPAL_SUCCESS) { dev_err(&pdev->dev, "Failed to enable M64 window #%d: %llx\n", @@ -1326,7 +1322,7 @@ static int pnv_pci_vf_assign_m64(struct pci_dev *pdev, u16 num_vfs) return 0; m64_failed: - pnv_pci_vf_release_m64(pdev); + pnv_pci_vf_release_m64(pdev, num_vfs); return -EBUSY; } @@ -1353,15 +1349,13 @@ static void pnv_pci_ioda2_release_dma_pe(struct pci_dev *dev, struct pnv_ioda_pe iommu_free_table(tbl, of_node_full_name(dev->dev.of_node)); } -static void pnv_ioda_release_vf_PE(struct pci_dev *pdev, u16 num_vfs) +static void pnv_ioda_release_vf_PE(struct pci_dev *pdev) { struct pci_bus *bus; struct pci_controller *hose; struct pnv_phb *phb; struct pnv_ioda_pe *pe, *pe_n; struct pci_dn *pdn; - u16 vf_index; - int64_t rc; bus = pdev->bus; hose = pci_bus_to_host(bus); @@ -1371,35 +1365,6 @@ static void pnv_ioda_release_vf_PE(struct pci_dev *pdev, u16 num_vfs) if (!pdev->is_physfn) return; - if (pdn->m64_per_iov == M64_PER_IOV && num_vfs > M64_PER_IOV) { - int vf_group; - int vf_per_group; - int vf_index1; - - vf_per_group = roundup_pow_of_two(num_vfs) / pdn->m64_per_iov; - - for (vf_group = 0; vf_group < M64_PER_IOV; vf_group++) - for (vf_index = vf_group * vf_per_group; - vf_index < (vf_group + 1) * vf_per_group && - vf_index < num_vfs; - vf_index++) - for (vf_index1 = vf_group * vf_per_group; - vf_index1 < (vf_group + 1) * vf_per_group && - vf_index1 < num_vfs; - vf_index1++){ - - rc = opal_pci_set_peltv(phb->opal_id, - pdn->offset + vf_index, - pdn->offset + vf_index1, - OPAL_REMOVE_PE_FROM_DOMAIN); - - if (rc) - dev_warn(&pdev->dev, "%s: Failed to unlink same group PE#%d(%lld)\n", - __func__, - pdn->offset + vf_index1, rc); - } - } - list_for_each_entry_safe(pe, pe_n, &phb->ioda.pe_list, list) { if (pe->parent_dev != pdev) continue; @@ -1424,7 +1389,7 @@ void pnv_pci_sriov_disable(struct pci_dev *pdev) struct pnv_phb *phb; struct pci_dn *pdn; struct pci_sriov *iov; - u16 num_vfs; + u16 num_vfs, i; bus = pdev->bus; hose = pci_bus_to_host(bus); @@ -1434,18 +1399,25 @@ void pnv_pci_sriov_disable(struct pci_dev *pdev) num_vfs = pdn->num_vfs; /* Release VF PEs */ - pnv_ioda_release_vf_PE(pdev, num_vfs); + pnv_ioda_release_vf_PE(pdev); if (phb->type == PNV_PHB_IODA2) { - if (pdn->m64_per_iov == 1) - pnv_pci_vf_resource_shift(pdev, -pdn->offset); + if (!pdn->m64_single_mode) + pnv_pci_vf_resource_shift(pdev, -*pdn->pe_num_map); /* Release M64 windows */ - pnv_pci_vf_release_m64(pdev); + pnv_pci_vf_release_m64(pdev, num_vfs); /* Release PE numbers */ - bitmap_clear(phb->ioda.pe_alloc, pdn->offset, num_vfs); - pdn->offset = 0; + if (pdn->m64_single_mode) { + for (i = 0; i < num_vfs; i++) { + if (pdn->pe_num_map[i] != IODA_INVALID_PE) + pnv_ioda_free_pe(phb, pdn->pe_num_map[i]); + } + } else + bitmap_clear(phb->ioda.pe_alloc, *pdn->pe_num_map, num_vfs); + /* Releasing pe_num_map */ + kfree(pdn->pe_num_map); } } @@ -1460,7 +1432,6 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, u16 num_vfs) int pe_num; u16 vf_index; struct pci_dn *pdn; - int64_t rc; bus = pdev->bus; hose = pci_bus_to_host(bus); @@ -1472,7 +1443,10 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, u16 num_vfs) /* Reserve PE for each VF */ for (vf_index = 0; vf_index < num_vfs; vf_index++) { - pe_num = pdn->offset + vf_index; + if (pdn->m64_single_mode) + pe_num = pdn->pe_num_map[vf_index]; + else + pe_num = *pdn->pe_num_map + vf_index; pe = &phb->ioda.pe_array[pe_num]; pe->pe_number = pe_num; @@ -1505,37 +1479,6 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, u16 num_vfs) pnv_pci_ioda2_setup_dma_pe(phb, pe); } - - if (pdn->m64_per_iov == M64_PER_IOV && num_vfs > M64_PER_IOV) { - int vf_group; - int vf_per_group; - int vf_index1; - - vf_per_group = roundup_pow_of_two(num_vfs) / pdn->m64_per_iov; - - for (vf_group = 0; vf_group < M64_PER_IOV; vf_group++) { - for (vf_index = vf_group * vf_per_group; - vf_index < (vf_group + 1) * vf_per_group && - vf_index < num_vfs; - vf_index++) { - for (vf_index1 = vf_group * vf_per_group; - vf_index1 < (vf_group + 1) * vf_per_group && - vf_index1 < num_vfs; - vf_index1++) { - - rc = opal_pci_set_peltv(phb->opal_id, - pdn->offset + vf_index, - pdn->offset + vf_index1, - OPAL_ADD_PE_TO_DOMAIN); - - if (rc) - dev_warn(&pdev->dev, "%s: Failed to link same group PE#%d(%lld)\n", - __func__, - pdn->offset + vf_index1, rc); - } - } - } - } } int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs) @@ -1545,6 +1488,7 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs) struct pnv_phb *phb; struct pci_dn *pdn; int ret; + u16 i; bus = pdev->bus; hose = pci_bus_to_host(bus); @@ -1552,20 +1496,59 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs) pdn = pci_get_pdn(pdev); if (phb->type == PNV_PHB_IODA2) { + if (!pdn->vfs_expanded) { + dev_info(&pdev->dev, "don't support this SRIOV device" + " with non 64bit-prefetchable IOV BAR\n"); + return -ENOSPC; + } + + /* + * When M64 BARs functions in Single PE mode, the number of VFs + * could be enabled must be less than the number of M64 BARs. + */ + if (pdn->m64_single_mode && num_vfs > phb->ioda.m64_bar_idx) { + dev_info(&pdev->dev, "Not enough M64 BAR for VFs\n"); + return -EBUSY; + } + + /* Allocating pe_num_map */ + if (pdn->m64_single_mode) + pdn->pe_num_map = kmalloc(sizeof(*pdn->pe_num_map) * num_vfs, + GFP_KERNEL); + else + pdn->pe_num_map = kmalloc(sizeof(*pdn->pe_num_map), GFP_KERNEL); + + if (!pdn->pe_num_map) + return -ENOMEM; + + if (pdn->m64_single_mode) + for (i = 0; i < num_vfs; i++) + pdn->pe_num_map[i] = IODA_INVALID_PE; + /* Calculate available PE for required VFs */ - mutex_lock(&phb->ioda.pe_alloc_mutex); - pdn->offset = bitmap_find_next_zero_area( - phb->ioda.pe_alloc, phb->ioda.total_pe, - 0, num_vfs, 0); - if (pdn->offset >= phb->ioda.total_pe) { + if (pdn->m64_single_mode) { + for (i = 0; i < num_vfs; i++) { + pdn->pe_num_map[i] = pnv_ioda_alloc_pe(phb); + if (pdn->pe_num_map[i] == IODA_INVALID_PE) { + ret = -EBUSY; + goto m64_failed; + } + } + } else { + mutex_lock(&phb->ioda.pe_alloc_mutex); + *pdn->pe_num_map = bitmap_find_next_zero_area( + phb->ioda.pe_alloc, phb->ioda.total_pe, + 0, num_vfs, 0); + if (*pdn->pe_num_map >= phb->ioda.total_pe) { + mutex_unlock(&phb->ioda.pe_alloc_mutex); + dev_info(&pdev->dev, "Failed to enable VF%d\n", num_vfs); + kfree(pdn->pe_num_map); + return -EBUSY; + } + bitmap_set(phb->ioda.pe_alloc, *pdn->pe_num_map, num_vfs); mutex_unlock(&phb->ioda.pe_alloc_mutex); - dev_info(&pdev->dev, "Failed to enable VF%d\n", num_vfs); - pdn->offset = 0; - return -EBUSY; } - bitmap_set(phb->ioda.pe_alloc, pdn->offset, num_vfs); pdn->num_vfs = num_vfs; - mutex_unlock(&phb->ioda.pe_alloc_mutex); /* Assign M64 window accordingly */ ret = pnv_pci_vf_assign_m64(pdev, num_vfs); @@ -1579,8 +1562,8 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs) * the IOV BAR according to the PE# allocated to the VFs. * Otherwise, the PE# for the VF will conflict with others. */ - if (pdn->m64_per_iov == 1) { - ret = pnv_pci_vf_resource_shift(pdev, pdn->offset); + if (!pdn->m64_single_mode) { + ret = pnv_pci_vf_resource_shift(pdev, *pdn->pe_num_map); if (ret) goto m64_failed; } @@ -1592,8 +1575,16 @@ int pnv_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs) return 0; m64_failed: - bitmap_clear(phb->ioda.pe_alloc, pdn->offset, num_vfs); - pdn->offset = 0; + if (pdn->m64_single_mode) { + for (i = 0; i < num_vfs; i++) { + if (pdn->pe_num_map[i] != IODA_INVALID_PE) + pnv_ioda_free_pe(phb, pdn->pe_num_map[i]); + } + } else + bitmap_clear(phb->ioda.pe_alloc, *pdn->pe_num_map, num_vfs); + + /* Releasing pe_num_map */ + kfree(pdn->pe_num_map); return ret; } @@ -1612,8 +1603,7 @@ int pcibios_sriov_enable(struct pci_dev *pdev, u16 num_vfs) /* Allocate PCI data */ add_dev_pci_data(pdev); - pnv_pci_sriov_enable(pdev, num_vfs); - return 0; + return pnv_pci_sriov_enable(pdev, num_vfs); } #endif /* CONFIG_PCI_IOV */ @@ -2851,45 +2841,58 @@ static void pnv_pci_init_ioda_msis(struct pnv_phb *phb) { } #ifdef CONFIG_PCI_IOV static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev) { - struct pci_controller *hose; - struct pnv_phb *phb; + struct pci_controller *hose = pci_bus_to_host(pdev->bus); + struct pnv_phb *phb = hose->private_data; + const resource_size_t gate = phb->ioda.m64_segsize >> 2; struct resource *res; int i; - resource_size_t size; + resource_size_t size, total_vf_bar_sz; struct pci_dn *pdn; int mul, total_vfs; if (!pdev->is_physfn || pdev->is_added) return; - hose = pci_bus_to_host(pdev->bus); - phb = hose->private_data; - pdn = pci_get_pdn(pdev); pdn->vfs_expanded = 0; + pdn->m64_single_mode = false; total_vfs = pci_sriov_get_totalvfs(pdev); - pdn->m64_per_iov = 1; mul = phb->ioda.total_pe; + total_vf_bar_sz = 0; for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) { res = &pdev->resource[i + PCI_IOV_RESOURCES]; if (!res->flags || res->parent) continue; if (!pnv_pci_is_mem_pref_64(res->flags)) { - dev_warn(&pdev->dev, " non M64 VF BAR%d: %pR\n", + dev_warn(&pdev->dev, "Don't support SR-IOV with" + " non M64 VF BAR%d: %pR. \n", i, res); - continue; + goto truncate_iov; } - size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES); + total_vf_bar_sz += pci_iov_resource_size(pdev, + i + PCI_IOV_RESOURCES); - /* bigger than 64M */ - if (size > (1 << 26)) { - dev_info(&pdev->dev, "PowerNV: VF BAR%d: %pR IOV size is bigger than 64M, roundup power2\n", - i, res); - pdn->m64_per_iov = M64_PER_IOV; + /* + * If bigger than quarter of M64 segment size, just round up + * power of two. + * + * Generally, one M64 BAR maps one IOV BAR. To avoid conflict + * with other devices, IOV BAR size is expanded to be + * (total_pe * VF_BAR_size). When VF_BAR_size is half of M64 + * segment size , the expanded size would equal to half of the + * whole M64 space size, which will exhaust the M64 Space and + * limit the system flexibility. This is a design decision to + * set the boundary to quarter of the M64 segment size. + */ + if (total_vf_bar_sz > gate) { mul = roundup_pow_of_two(total_vfs); + dev_info(&pdev->dev, + "VF BAR Total IOV size %llx > %llx, roundup to %d VFs\n", + total_vf_bar_sz, gate, mul); + pdn->m64_single_mode = true; break; } } @@ -2898,20 +2901,31 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev) res = &pdev->resource[i + PCI_IOV_RESOURCES]; if (!res->flags || res->parent) continue; - if (!pnv_pci_is_mem_pref_64(res->flags)) { - dev_warn(&pdev->dev, "Skipping expanding VF BAR%d: %pR\n", - i, res); - continue; - } - dev_dbg(&pdev->dev, " Fixing VF BAR%d: %pR to\n", i, res); size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES); + /* + * On PHB3, the minimum size alignment of M64 BAR in single + * mode is 32MB. + */ + if (pdn->m64_single_mode && (size < SZ_32M)) + goto truncate_iov; + dev_dbg(&pdev->dev, " Fixing VF BAR%d: %pR to\n", i, res); res->end = res->start + size * mul - 1; dev_dbg(&pdev->dev, " %pR\n", res); dev_info(&pdev->dev, "VF BAR%d: %pR (expanded to %d VFs for PE alignment)", i, res, mul); } pdn->vfs_expanded = mul; + + return; + +truncate_iov: + /* To save MMIO space, IOV BAR is truncated. */ + for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) { + res = &pdev->resource[i + PCI_IOV_RESOURCES]; + res->flags = 0; + res->end = res->start - 1; + } } #endif /* CONFIG_PCI_IOV */ @@ -3125,18 +3139,35 @@ static resource_size_t pnv_pci_window_alignment(struct pci_bus *bus, static resource_size_t pnv_pci_iov_resource_alignment(struct pci_dev *pdev, int resno) { + struct pci_controller *hose = pci_bus_to_host(pdev->bus); + struct pnv_phb *phb = hose->private_data; struct pci_dn *pdn = pci_get_pdn(pdev); - resource_size_t align, iov_align; - - iov_align = resource_size(&pdev->resource[resno]); - if (iov_align) - return iov_align; + resource_size_t align; + /* + * On PowerNV platform, IOV BAR is mapped by M64 BAR to enable the + * SR-IOV. While from hardware perspective, the range mapped by M64 + * BAR should be size aligned. + * + * When IOV BAR is mapped with M64 BAR in Single PE mode, the extra + * powernv-specific hardware restriction is gone. But if just use the + * VF BAR size as the alignment, PF BAR / VF BAR may be allocated with + * in one segment of M64 #15, which introduces the PE conflict between + * PF and VF. Based on this, the minimum alignment of an IOV BAR is + * m64_segsize. + * + * This function returns the total IOV BAR size if M64 BAR is in + * Shared PE mode or just VF BAR size if not. + * If the M64 BAR is in Single PE mode, return the VF BAR size or + * M64 segment size if IOV BAR size is less. + */ align = pci_iov_resource_size(pdev, resno); - if (pdn->vfs_expanded) - return pdn->vfs_expanded * align; + if (!pdn->vfs_expanded) + return align; + if (pdn->m64_single_mode) + return max(align, (resource_size_t)phb->ioda.m64_segsize); - return align; + return pdn->vfs_expanded * align; } #endif /* CONFIG_PCI_IOV */ diff --git a/arch/powerpc/platforms/powernv/pci-p5ioc2.c b/arch/powerpc/platforms/powernv/pci-p5ioc2.c deleted file mode 100644 index f2bdfea3b68d067cb28a91d259e84ec126783001..0000000000000000000000000000000000000000 --- a/arch/powerpc/platforms/powernv/pci-p5ioc2.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Support PCI/PCIe on PowerNV platforms - * - * Currently supports only P5IOC2 - * - * Copyright 2011 Benjamin Herrenschmidt, IBM Corp. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "powernv.h" -#include "pci.h" - -/* For now, use a fixed amount of TCE memory for each p5ioc2 - * hub, 16M will do - */ -#define P5IOC2_TCE_MEMORY 0x01000000 - -#ifdef CONFIG_PCI_MSI -static int pnv_pci_p5ioc2_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, - unsigned int hwirq, unsigned int virq, - unsigned int is_64, struct msi_msg *msg) -{ - if (WARN_ON(!is_64)) - return -ENXIO; - msg->data = hwirq - phb->msi_base; - msg->address_hi = 0x10000000; - msg->address_lo = 0; - - return 0; -} - -static void pnv_pci_init_p5ioc2_msis(struct pnv_phb *phb) -{ - unsigned int count; - const __be32 *prop = of_get_property(phb->hose->dn, - "ibm,opal-msi-ranges", NULL); - if (!prop) - return; - - /* Don't do MSI's on p5ioc2 PCI-X are they are not properly - * verified in HW - */ - if (of_device_is_compatible(phb->hose->dn, "ibm,p5ioc2-pcix")) - return; - phb->msi_base = be32_to_cpup(prop); - count = be32_to_cpup(prop + 1); - if (msi_bitmap_alloc(&phb->msi_bmp, count, phb->hose->dn)) { - pr_err("PCI %d: Failed to allocate MSI bitmap !\n", - phb->hose->global_number); - return; - } - phb->msi_setup = pnv_pci_p5ioc2_msi_setup; - phb->msi32_support = 0; - pr_info(" Allocated bitmap for %d MSIs (base IRQ 0x%x)\n", - count, phb->msi_base); -} -#else -static void pnv_pci_init_p5ioc2_msis(struct pnv_phb *phb) { } -#endif /* CONFIG_PCI_MSI */ - -static struct iommu_table_ops pnv_p5ioc2_iommu_ops = { - .set = pnv_tce_build, -#ifdef CONFIG_IOMMU_API - .exchange = pnv_tce_xchg, -#endif - .clear = pnv_tce_free, - .get = pnv_tce_get, -}; - -static void pnv_pci_p5ioc2_dma_dev_setup(struct pnv_phb *phb, - struct pci_dev *pdev) -{ - struct iommu_table *tbl = phb->p5ioc2.table_group.tables[0]; - - if (!tbl->it_map) { - tbl->it_ops = &pnv_p5ioc2_iommu_ops; - iommu_init_table(tbl, phb->hose->node); - iommu_register_group(&phb->p5ioc2.table_group, - pci_domain_nr(phb->hose->bus), phb->opal_id); - INIT_LIST_HEAD_RCU(&tbl->it_group_list); - pnv_pci_link_table_and_group(phb->hose->node, 0, - tbl, &phb->p5ioc2.table_group); - } - - set_iommu_table_base(&pdev->dev, tbl); - iommu_add_device(&pdev->dev); -} - -static const struct pci_controller_ops pnv_pci_p5ioc2_controller_ops = { - .dma_dev_setup = pnv_pci_dma_dev_setup, -#ifdef CONFIG_PCI_MSI - .setup_msi_irqs = pnv_setup_msi_irqs, - .teardown_msi_irqs = pnv_teardown_msi_irqs, -#endif -}; - -static void __init pnv_pci_init_p5ioc2_phb(struct device_node *np, u64 hub_id, - void *tce_mem, u64 tce_size) -{ - struct pnv_phb *phb; - const __be64 *prop64; - u64 phb_id; - int64_t rc; - static int primary = 1; - struct iommu_table_group *table_group; - struct iommu_table *tbl; - - pr_info(" Initializing p5ioc2 PHB %s\n", np->full_name); - - prop64 = of_get_property(np, "ibm,opal-phbid", NULL); - if (!prop64) { - pr_err(" Missing \"ibm,opal-phbid\" property !\n"); - return; - } - phb_id = be64_to_cpup(prop64); - pr_devel(" PHB-ID : 0x%016llx\n", phb_id); - pr_devel(" TCE AT : 0x%016lx\n", __pa(tce_mem)); - pr_devel(" TCE SZ : 0x%016llx\n", tce_size); - - rc = opal_pci_set_phb_tce_memory(phb_id, __pa(tce_mem), tce_size); - if (rc != OPAL_SUCCESS) { - pr_err(" Failed to set TCE memory, OPAL error %lld\n", rc); - return; - } - - phb = memblock_virt_alloc(sizeof(struct pnv_phb), 0); - phb->hose = pcibios_alloc_controller(np); - if (!phb->hose) { - pr_err(" Failed to allocate PCI controller\n"); - return; - } - - spin_lock_init(&phb->lock); - phb->hose->first_busno = 0; - phb->hose->last_busno = 0xff; - phb->hose->private_data = phb; - phb->hose->controller_ops = pnv_pci_p5ioc2_controller_ops; - phb->hub_id = hub_id; - phb->opal_id = phb_id; - phb->type = PNV_PHB_P5IOC2; - phb->model = PNV_PHB_MODEL_P5IOC2; - - phb->regs = of_iomap(np, 0); - - if (phb->regs == NULL) - pr_err(" Failed to map registers !\n"); - else { - pr_devel(" P_BUID = 0x%08x\n", in_be32(phb->regs + 0x100)); - pr_devel(" P_IOSZ = 0x%08x\n", in_be32(phb->regs + 0x1b0)); - pr_devel(" P_IO_ST = 0x%08x\n", in_be32(phb->regs + 0x1e0)); - pr_devel(" P_MEM1_H = 0x%08x\n", in_be32(phb->regs + 0x1a0)); - pr_devel(" P_MEM1_L = 0x%08x\n", in_be32(phb->regs + 0x190)); - pr_devel(" P_MSZ1_L = 0x%08x\n", in_be32(phb->regs + 0x1c0)); - pr_devel(" P_MEM_ST = 0x%08x\n", in_be32(phb->regs + 0x1d0)); - pr_devel(" P_MEM2_H = 0x%08x\n", in_be32(phb->regs + 0x2c0)); - pr_devel(" P_MEM2_L = 0x%08x\n", in_be32(phb->regs + 0x2b0)); - pr_devel(" P_MSZ2_H = 0x%08x\n", in_be32(phb->regs + 0x2d0)); - pr_devel(" P_MSZ2_L = 0x%08x\n", in_be32(phb->regs + 0x2e0)); - } - - /* Interpret the "ranges" property */ - /* This also maps the I/O region and sets isa_io/mem_base */ - pci_process_bridge_OF_ranges(phb->hose, np, primary); - primary = 0; - - phb->hose->ops = &pnv_pci_ops; - - /* Setup MSI support */ - pnv_pci_init_p5ioc2_msis(phb); - - /* Setup TCEs */ - phb->dma_dev_setup = pnv_pci_p5ioc2_dma_dev_setup; - pnv_pci_setup_iommu_table(&phb->p5ioc2.iommu_table, - tce_mem, tce_size, 0, - IOMMU_PAGE_SHIFT_4K); - /* - * We do not allocate iommu_table as we do not support - * hotplug or SRIOV on P5IOC2 and therefore iommu_free_table() - * should not be called for phb->p5ioc2.table_group.tables[0] ever. - */ - tbl = phb->p5ioc2.table_group.tables[0] = &phb->p5ioc2.iommu_table; - table_group = &phb->p5ioc2.table_group; - table_group->tce32_start = tbl->it_offset << tbl->it_page_shift; - table_group->tce32_size = tbl->it_size << tbl->it_page_shift; -} - -void __init pnv_pci_init_p5ioc2_hub(struct device_node *np) -{ - struct device_node *phbn; - const __be64 *prop64; - u64 hub_id; - void *tce_mem; - uint64_t tce_per_phb; - int64_t rc; - int phb_count = 0; - - pr_info("Probing p5ioc2 IO-Hub %s\n", np->full_name); - - prop64 = of_get_property(np, "ibm,opal-hubid", NULL); - if (!prop64) { - pr_err(" Missing \"ibm,opal-hubid\" property !\n"); - return; - } - hub_id = be64_to_cpup(prop64); - pr_info(" HUB-ID : 0x%016llx\n", hub_id); - - /* Count child PHBs and calculate TCE space per PHB */ - for_each_child_of_node(np, phbn) { - if (of_device_is_compatible(phbn, "ibm,p5ioc2-pcix") || - of_device_is_compatible(phbn, "ibm,p5ioc2-pciex")) - phb_count++; - } - - if (phb_count <= 0) { - pr_info(" No PHBs for Hub %s\n", np->full_name); - return; - } - - tce_per_phb = __rounddown_pow_of_two(P5IOC2_TCE_MEMORY / phb_count); - pr_info(" Allocating %lld MB of TCE memory per PHB\n", - tce_per_phb >> 20); - - /* Currently allocate 16M of TCE memory for every Hub - * - * XXX TODO: Make it chip local if possible - */ - tce_mem = memblock_virt_alloc(P5IOC2_TCE_MEMORY, P5IOC2_TCE_MEMORY); - pr_debug(" TCE : 0x%016lx..0x%016lx\n", - __pa(tce_mem), __pa(tce_mem) + P5IOC2_TCE_MEMORY - 1); - rc = opal_pci_set_hub_tce_memory(hub_id, __pa(tce_mem), - P5IOC2_TCE_MEMORY); - if (rc != OPAL_SUCCESS) { - pr_err(" Failed to allocate TCE memory, OPAL error %lld\n", rc); - return; - } - - /* Initialize PHBs */ - for_each_child_of_node(np, phbn) { - if (of_device_is_compatible(phbn, "ibm,p5ioc2-pcix") || - of_device_is_compatible(phbn, "ibm,p5ioc2-pciex")) { - pnv_pci_init_p5ioc2_phb(phbn, hub_id, - tce_mem, tce_per_phb); - tce_mem += tce_per_phb; - } - } -} diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index b1ef84a6c9d13cff03c2d4a5234e57265ef5bc75..73c8dc2a353fdd540b9a05a5aa208b3e50970e47 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c @@ -380,10 +380,7 @@ static void pnv_pci_config_check_eeh(struct pci_dn *pdn) */ pe_no = pdn->pe_number; if (pe_no == IODA_INVALID_PE) { - if (phb->type == PNV_PHB_P5IOC2) - pe_no = 0; - else - pe_no = phb->ioda.reserved_pe; + pe_no = phb->ioda.reserved_pe; } /* @@ -805,7 +802,6 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_IBM, 0x3b9, pnv_p7ioc_rc_quirk); void __init pnv_pci_init(void) { struct device_node *np; - bool found_ioda = false; pci_add_flags(PCI_CAN_SKIP_ISA_ALIGN); @@ -813,20 +809,11 @@ void __init pnv_pci_init(void) if (!firmware_has_feature(FW_FEATURE_OPAL)) return; - /* Look for IODA IO-Hubs. We don't support mixing IODA - * and p5ioc2 due to the need to change some global - * probing flags - */ + /* Look for IODA IO-Hubs. */ for_each_compatible_node(np, NULL, "ibm,ioda-hub") { pnv_pci_init_ioda_hub(np); - found_ioda = true; } - /* Look for p5ioc2 IO-Hubs */ - if (!found_ioda) - for_each_compatible_node(np, NULL, "ibm,p5ioc2") - pnv_pci_init_p5ioc2_hub(np); - /* Look for ioda2 built-in PHB3's */ for_each_compatible_node(np, NULL, "ibm,ioda2-phb") pnv_pci_init_ioda2_phb(np); diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h index 00691a9b99af67b09967c73b39b652b973392f06..3f814f382b2e793bf0b5374abb74bebf35246a98 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h @@ -4,16 +4,14 @@ struct pci_dn; enum pnv_phb_type { - PNV_PHB_P5IOC2 = 0, - PNV_PHB_IODA1 = 1, - PNV_PHB_IODA2 = 2, - PNV_PHB_NPU = 3, + PNV_PHB_IODA1 = 0, + PNV_PHB_IODA2 = 1, + PNV_PHB_NPU = 2, }; /* Precise PHB model for error management */ enum pnv_phb_model { PNV_PHB_MODEL_UNKNOWN, - PNV_PHB_MODEL_P5IOC2, PNV_PHB_MODEL_P7IOC, PNV_PHB_MODEL_PHB3, PNV_PHB_MODEL_NPU, @@ -121,81 +119,74 @@ struct pnv_phb { void (*freeze_pe)(struct pnv_phb *phb, int pe_no); int (*unfreeze_pe)(struct pnv_phb *phb, int pe_no, int opt); - union { - struct { - struct iommu_table iommu_table; - struct iommu_table_group table_group; - } p5ioc2; - - struct { - /* Global bridge info */ - unsigned int total_pe; - unsigned int reserved_pe; - - /* 32-bit MMIO window */ - unsigned int m32_size; - unsigned int m32_segsize; - unsigned int m32_pci_base; - - /* 64-bit MMIO window */ - unsigned int m64_bar_idx; - unsigned long m64_size; - unsigned long m64_segsize; - unsigned long m64_base; - unsigned long m64_bar_alloc; - - /* IO ports */ - unsigned int io_size; - unsigned int io_segsize; - unsigned int io_pci_base; - - /* PE allocation bitmap */ - unsigned long *pe_alloc; - /* PE allocation mutex */ - struct mutex pe_alloc_mutex; - - /* M32 & IO segment maps */ - unsigned int *m32_segmap; - unsigned int *io_segmap; - struct pnv_ioda_pe *pe_array; - - /* IRQ chip */ - int irq_chip_init; - struct irq_chip irq_chip; - - /* Sorted list of used PE's based - * on the sequence of creation - */ - struct list_head pe_list; - struct mutex pe_list_mutex; - - /* Reverse map of PEs, will have to extend if - * we are to support more than 256 PEs, indexed - * bus { bus, devfn } - */ - unsigned char pe_rmap[0x10000]; - - /* 32-bit TCE tables allocation */ - unsigned long tce32_count; - - /* Total "weight" for the sake of DMA resources - * allocation - */ - unsigned int dma_weight; - unsigned int dma_pe_count; - - /* Sorted list of used PE's, sorted at - * boot for resource allocation purposes - */ - struct list_head pe_dma_list; - - /* TCE cache invalidate registers (physical and - * remapped) - */ - phys_addr_t tce_inval_reg_phys; - __be64 __iomem *tce_inval_reg; - } ioda; - }; + struct { + /* Global bridge info */ + unsigned int total_pe; + unsigned int reserved_pe; + + /* 32-bit MMIO window */ + unsigned int m32_size; + unsigned int m32_segsize; + unsigned int m32_pci_base; + + /* 64-bit MMIO window */ + unsigned int m64_bar_idx; + unsigned long m64_size; + unsigned long m64_segsize; + unsigned long m64_base; + unsigned long m64_bar_alloc; + + /* IO ports */ + unsigned int io_size; + unsigned int io_segsize; + unsigned int io_pci_base; + + /* PE allocation bitmap */ + unsigned long *pe_alloc; + /* PE allocation mutex */ + struct mutex pe_alloc_mutex; + + /* M32 & IO segment maps */ + unsigned int *m32_segmap; + unsigned int *io_segmap; + struct pnv_ioda_pe *pe_array; + + /* IRQ chip */ + int irq_chip_init; + struct irq_chip irq_chip; + + /* Sorted list of used PE's based + * on the sequence of creation + */ + struct list_head pe_list; + struct mutex pe_list_mutex; + + /* Reverse map of PEs, will have to extend if + * we are to support more than 256 PEs, indexed + * bus { bus, devfn } + */ + unsigned char pe_rmap[0x10000]; + + /* 32-bit TCE tables allocation */ + unsigned long tce32_count; + + /* Total "weight" for the sake of DMA resources + * allocation + */ + unsigned int dma_weight; + unsigned int dma_pe_count; + + /* Sorted list of used PE's, sorted at + * boot for resource allocation purposes + */ + struct list_head pe_dma_list; + + /* TCE cache invalidate registers (physical and + * remapped) + */ + phys_addr_t tce_inval_reg_phys; + __be64 __iomem *tce_inval_reg; + } ioda; /* PHB and hub status structure */ union { @@ -232,7 +223,6 @@ extern void pnv_pci_unlink_table_and_group(struct iommu_table *tbl, extern void pnv_pci_setup_iommu_table(struct iommu_table *tbl, void *tce_mem, u64 tce_size, u64 dma_offset, unsigned page_shift); -extern void pnv_pci_init_p5ioc2_hub(struct device_node *np); extern void pnv_pci_init_ioda_hub(struct device_node *np); extern void pnv_pci_init_ioda2_phb(struct device_node *np); extern void pnv_pci_init_npu_phb(struct device_node *np); diff --git a/arch/powerpc/platforms/powernv/subcore.c b/arch/powerpc/platforms/powernv/subcore.c index 503a73f593599b37e7936e48ff47067577bd40d9..0babef11136fc8daba7f2666fed3f3b649cc2bd8 100644 --- a/arch/powerpc/platforms/powernv/subcore.c +++ b/arch/powerpc/platforms/powernv/subcore.c @@ -407,7 +407,7 @@ static DEVICE_ATTR(subcores_per_core, 0644, static int subcore_init(void) { - if (!cpu_has_feature(CPU_FTR_ARCH_207S)) + if (!cpu_has_feature(CPU_FTR_SUBCORE)) return 0; /* diff --git a/arch/powerpc/platforms/ps3/gelic_udbg.c b/arch/powerpc/platforms/ps3/gelic_udbg.c index 20b46a19a48fc179071a742022a2be84bbd042f8..09bf24d616a5735d416cc67367ac0ff55de1f2b9 100644 --- a/arch/powerpc/platforms/ps3/gelic_udbg.c +++ b/arch/powerpc/platforms/ps3/gelic_udbg.c @@ -13,6 +13,12 @@ * */ +#include +#include +#include +#include +#include + #include #include #include @@ -56,39 +62,8 @@ struct debug_block { u8 pkt[1520]; } __packed; -struct ethhdr { - u8 dest[6]; - u8 src[6]; - u16 type; -} __packed; - -struct vlantag { - u16 vlan; - u16 subtype; -} __packed; - -struct iphdr { - u8 ver_len; - u8 dscp_ecn; - u16 total_length; - u16 ident; - u16 frag_off_flags; - u8 ttl; - u8 proto; - u16 checksum; - u32 src; - u32 dest; -} __packed; - -struct udphdr { - u16 src; - u16 dest; - u16 len; - u16 checksum; -} __packed; - static __iomem struct ethhdr *h_eth; -static __iomem struct vlantag *h_vlan; +static __iomem struct vlan_hdr *h_vlan; static __iomem struct iphdr *h_ip; static __iomem struct udphdr *h_udp; @@ -173,8 +148,8 @@ static void gelic_debug_init(void) h_eth = (struct ethhdr *)dbg.pkt; - memset(&h_eth->dest, 0xff, 6); - memcpy(&h_eth->src, &mac, 6); + eth_broadcast_addr(h_eth->h_dest); + memcpy(&h_eth->h_source, &mac, ETH_ALEN); header_size = sizeof(struct ethhdr); @@ -183,28 +158,29 @@ static void gelic_debug_init(void) GELIC_LV1_VLAN_TX_ETHERNET_0, 0, 0, &vlan_id, &v2); if (!result) { - h_eth->type = 0x8100; + h_eth->h_proto= ETH_P_8021Q; - header_size += sizeof(struct vlantag); - h_vlan = (struct vlantag *)(h_eth + 1); - h_vlan->vlan = vlan_id; - h_vlan->subtype = 0x0800; + header_size += sizeof(struct vlan_hdr); + h_vlan = (struct vlan_hdr *)(h_eth + 1); + h_vlan->h_vlan_TCI = vlan_id; + h_vlan->h_vlan_encapsulated_proto = ETH_P_IP; h_ip = (struct iphdr *)(h_vlan + 1); } else { - h_eth->type = 0x0800; + h_eth->h_proto= 0x0800; h_ip = (struct iphdr *)(h_eth + 1); } header_size += sizeof(struct iphdr); - h_ip->ver_len = 0x45; + h_ip->version = 4; + h_ip->ihl = 5; h_ip->ttl = 10; - h_ip->proto = 0x11; - h_ip->src = 0x00000000; - h_ip->dest = 0xffffffff; + h_ip->protocol = 0x11; + h_ip->saddr = 0x00000000; + h_ip->daddr = 0xffffffff; header_size += sizeof(struct udphdr); h_udp = (struct udphdr *)(h_ip + 1); - h_udp->src = GELIC_DEBUG_PORT; + h_udp->source = GELIC_DEBUG_PORT; h_udp->dest = GELIC_DEBUG_PORT; pmsgc = pmsg = (char *)(h_udp + 1); @@ -225,16 +201,16 @@ static void gelic_sendbuf(int msgsize) int i; dbg.descr.buf_size = header_size + msgsize; - h_ip->total_length = msgsize + sizeof(struct udphdr) + + h_ip->tot_len = msgsize + sizeof(struct udphdr) + sizeof(struct iphdr); h_udp->len = msgsize + sizeof(struct udphdr); - h_ip->checksum = 0; + h_ip->check = 0; sum = 0; p = (u16 *)h_ip; for (i = 0; i < 5; i++) sum += *p++; - h_ip->checksum = ~(sum + (sum >> 16)); + h_ip->check = ~(sum + (sum >> 16)); dbg.descr.dmac_cmd_status = GELIC_DESCR_DMA_CMD_NO_CHKSUM | GELIC_DESCR_TX_DMA_FRAME_TAIL; diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c index 638c4060938e387aa55629a085dd0fa1ad993e4c..b831638e6f4a7fd3f3b8b4b9a67f50bf61b3dce0 100644 --- a/arch/powerpc/platforms/ps3/interrupt.c +++ b/arch/powerpc/platforms/ps3/interrupt.c @@ -78,7 +78,7 @@ struct ps3_bmp { /** * struct ps3_private - a per cpu data structure * @bmp: ps3_bmp structure - * @bmp_lock: Syncronize access to bmp. + * @bmp_lock: Synchronize access to bmp. * @ipi_debug_brk_mask: Mask for debug break IPIs * @ppe_id: HV logical_ppe_id * @thread_id: HV thread_id diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index 32274f72fe3fc361baa3f44e71e84a683bb9dfe3..282837a1d74b03265d046ff76383222d19f0c3fb 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -47,20 +47,14 @@ static DEFINE_PER_CPU(enum cpu_state_vals, current_state) = CPU_STATE_OFFLINE; static enum cpu_state_vals default_offline_state = CPU_STATE_OFFLINE; -static int cede_offline_enabled __read_mostly = 1; +static bool cede_offline_enabled __read_mostly = true; /* * Enable/disable cede_offline when available. */ static int __init setup_cede_offline(char *str) { - if (!strcmp(str, "off")) - cede_offline_enabled = 0; - else if (!strcmp(str, "on")) - cede_offline_enabled = 1; - else - return 0; - return 1; + return (kstrtobool(str, &cede_offline_enabled) == 0); } __setup("cede_offline=", setup_cede_offline); diff --git a/arch/powerpc/platforms/pseries/hvconsole.c b/arch/powerpc/platforms/pseries/hvconsole.c index 849b29b3e9ae0d6ec7b4121a004fc6ce3f7a96b5..74da18de853af670f911acc800e50d076bff4f8c 100644 --- a/arch/powerpc/platforms/pseries/hvconsole.c +++ b/arch/powerpc/platforms/pseries/hvconsole.c @@ -31,7 +31,7 @@ #include /** - * hvc_get_chars - retrieve characters from firmware for denoted vterm adatper + * hvc_get_chars - retrieve characters from firmware for denoted vterm adapter * @vtermno: The vtermno or unit_address of the adapter from which to fetch the * data. * @buf: The character buffer into which to put the character data fetched from diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 477290ad855e50a5f0c5da5065ba4b174b77fcfa..2415a0d31f8fd82117af5e7ab80582229a40c555 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -505,8 +505,8 @@ static void pSeries_lpar_hugepage_invalidate(unsigned long vsid, } #endif -static void pSeries_lpar_hpte_removebolted(unsigned long ea, - int psize, int ssize) +static int pSeries_lpar_hpte_removebolted(unsigned long ea, + int psize, int ssize) { unsigned long vpn; unsigned long slot, vsid; @@ -515,11 +515,14 @@ static void pSeries_lpar_hpte_removebolted(unsigned long ea, vpn = hpt_vpn(ea, vsid, ssize); slot = pSeries_lpar_hpte_find(vpn, psize, ssize); - BUG_ON(slot == -1); + if (slot == -1) + return -ENOENT; + /* * lpar doesn't use the passed actual page size */ pSeries_lpar_hpte_invalidate(slot, vpn, psize, 0, ssize, 0); + return 0; } /* diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 36df46eaba24900549e394fc6cd94ec55bad8588..6e944fc6e5f979d2559fd805970a81af7886315f 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -515,7 +515,7 @@ static void __init pSeries_setup_arch(void) fwnmi_init(); - /* By default, only probe PCI (can be overriden by rtas_pci) */ + /* By default, only probe PCI (can be overridden by rtas_pci) */ pci_add_flags(PCI_PROBE_ONLY); /* Find and initialize PCI host bridges */ diff --git a/arch/powerpc/scripts/gcc-check-mprofile-kernel.sh b/arch/powerpc/scripts/gcc-check-mprofile-kernel.sh new file mode 100755 index 0000000000000000000000000000000000000000..c658d8cf760bffd82bc7af1206aef2a092434eec --- /dev/null +++ b/arch/powerpc/scripts/gcc-check-mprofile-kernel.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +set -e +set -o pipefail + +# To debug, uncomment the following line +# set -x + +# Test whether the compile option -mprofile-kernel exists and generates +# profiling code (ie. a call to _mcount()). +echo "int func() { return 0; }" | \ + $* -S -x c -O2 -p -mprofile-kernel - -o - 2> /dev/null | \ + grep -q "_mcount" + +# Test whether the notrace attribute correctly suppresses calls to _mcount(). + +echo -e "#include \nnotrace int func() { return 0; }" | \ + $* -S -x c -O2 -p -mprofile-kernel - -o - 2> /dev/null | \ + grep -q "_mcount" && \ + exit 1 + +echo "OK" +exit 0 diff --git a/arch/powerpc/sysdev/Kconfig b/arch/powerpc/sysdev/Kconfig index a19332a3871551713e2194e8490aaa15cb493c36..52dc165c0efb6eaf233359ccb7fd0ab7de6c14db 100644 --- a/arch/powerpc/sysdev/Kconfig +++ b/arch/powerpc/sysdev/Kconfig @@ -40,3 +40,8 @@ config SCOM_DEBUGFS config GE_FPGA bool default n + +config FSL_CORENET_RCPM + bool + help + This option enables support for RCPM (Run Control/Power Management). diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index bd6bd729969c87b8faa213857c743217a1f4c2ad..a254824719f152148551daee9dd38f02e3538d02 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o obj-$(CONFIG_FSL_SOC) += fsl_soc.o fsl_mpic_err.o obj-$(CONFIG_FSL_PCI) += fsl_pci.o $(fsl-msi-obj-y) obj-$(CONFIG_FSL_PMC) += fsl_pmc.o +obj-$(CONFIG_FSL_CORENET_RCPM) += fsl_rcpm.o obj-$(CONFIG_FSL_LBC) += fsl_lbc.o obj-$(CONFIG_FSL_GTM) += fsl_gtm.o obj-$(CONFIG_FSL_85XX_CACHE_SRAM) += fsl_85xx_l2ctlr.o fsl_85xx_cache_sram.o diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c index 5e6ff38ea69f197a873e9f47923d9f3434107221..8ed65365be508848616843cea2f383a321942a8f 100644 --- a/arch/powerpc/sysdev/cpm1.c +++ b/arch/powerpc/sysdev/cpm1.c @@ -228,7 +228,10 @@ void __init cpm_reset(void) * Bit 25, FAM can also be set to use FEC aggressive mode (860T). */ siu_conf = immr_map(im_siu_conf); - out_be32(&siu_conf->sc_sdcr, 1); + if ((mfspr(SPRN_IMMR) & 0xffff) == 0x0900) /* MPC885 */ + out_be32(&siu_conf->sc_sdcr, 0x40); + else + out_be32(&siu_conf->sc_sdcr, 1); immr_unmap(siu_conf); cpm_muram_init(); diff --git a/arch/powerpc/sysdev/fsl_lbc.c b/arch/powerpc/sysdev/fsl_lbc.c index 47f781059eeb667b3114f1990e5ce0863a8490f3..424b67fdb57f722bb47c8fd33530bfe98ac40e11 100644 --- a/arch/powerpc/sysdev/fsl_lbc.c +++ b/arch/powerpc/sysdev/fsl_lbc.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -352,24 +353,42 @@ static int fsl_lbc_ctrl_probe(struct platform_device *dev) #ifdef CONFIG_SUSPEND /* save lbc registers */ -static int fsl_lbc_suspend(struct platform_device *pdev, pm_message_t state) +static int fsl_lbc_syscore_suspend(void) { - struct fsl_lbc_ctrl *ctrl = dev_get_drvdata(&pdev->dev); - struct fsl_lbc_regs __iomem *lbc = ctrl->regs; + struct fsl_lbc_ctrl *ctrl; + struct fsl_lbc_regs __iomem *lbc; + + ctrl = fsl_lbc_ctrl_dev; + if (!ctrl) + goto out; + + lbc = ctrl->regs; + if (!lbc) + goto out; ctrl->saved_regs = kmalloc(sizeof(struct fsl_lbc_regs), GFP_KERNEL); if (!ctrl->saved_regs) return -ENOMEM; _memcpy_fromio(ctrl->saved_regs, lbc, sizeof(struct fsl_lbc_regs)); + +out: return 0; } /* restore lbc registers */ -static int fsl_lbc_resume(struct platform_device *pdev) +static void fsl_lbc_syscore_resume(void) { - struct fsl_lbc_ctrl *ctrl = dev_get_drvdata(&pdev->dev); - struct fsl_lbc_regs __iomem *lbc = ctrl->regs; + struct fsl_lbc_ctrl *ctrl; + struct fsl_lbc_regs __iomem *lbc; + + ctrl = fsl_lbc_ctrl_dev; + if (!ctrl) + goto out; + + lbc = ctrl->regs; + if (!lbc) + goto out; if (ctrl->saved_regs) { _memcpy_toio(lbc, ctrl->saved_regs, @@ -377,7 +396,9 @@ static int fsl_lbc_resume(struct platform_device *pdev) kfree(ctrl->saved_regs); ctrl->saved_regs = NULL; } - return 0; + +out: + return; } #endif /* CONFIG_SUSPEND */ @@ -389,20 +410,26 @@ static const struct of_device_id fsl_lbc_match[] = { {}, }; +#ifdef CONFIG_SUSPEND +static struct syscore_ops lbc_syscore_pm_ops = { + .suspend = fsl_lbc_syscore_suspend, + .resume = fsl_lbc_syscore_resume, +}; +#endif + static struct platform_driver fsl_lbc_ctrl_driver = { .driver = { .name = "fsl-lbc", .of_match_table = fsl_lbc_match, }, .probe = fsl_lbc_ctrl_probe, -#ifdef CONFIG_SUSPEND - .suspend = fsl_lbc_suspend, - .resume = fsl_lbc_resume, -#endif }; static int __init fsl_lbc_init(void) { +#ifdef CONFIG_SUSPEND + register_syscore_ops(&lbc_syscore_pm_ops); +#endif return platform_driver_register(&fsl_lbc_ctrl_driver); } subsys_initcall(fsl_lbc_init); diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index c69e88e91459f256c6ba568eaac050666c920403..85729f49764fc04c98604c119cf28f69e7da107b 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -575,7 +575,7 @@ int fsl_add_bridge(struct platform_device *pdev, int is_primary) if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) { /* use fsl_indirect_read_config for PCIe */ hose->ops = &fsl_indirect_pcie_ops; - /* For PCIE read HEADER_TYPE to identify controler mode */ + /* For PCIE read HEADER_TYPE to identify controller mode */ early_read_config_byte(hose, 0, 0, PCI_HEADER_TYPE, &hdr_type); if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE) goto no_bridge; diff --git a/arch/powerpc/sysdev/fsl_rcpm.c b/arch/powerpc/sysdev/fsl_rcpm.c new file mode 100644 index 0000000000000000000000000000000000000000..9259a94f70e1dcb026dc8171d5c314a81fda9162 --- /dev/null +++ b/arch/powerpc/sysdev/fsl_rcpm.c @@ -0,0 +1,386 @@ +/* + * RCPM(Run Control/Power Management) support + * + * Copyright 2012-2015 Freescale Semiconductor Inc. + * + * Author: Chenhui Zhao + * + * 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. + */ + +#define pr_fmt(fmt) "%s: " fmt, __func__ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +static struct ccsr_rcpm_v1 __iomem *rcpm_v1_regs; +static struct ccsr_rcpm_v2 __iomem *rcpm_v2_regs; +static unsigned int fsl_supported_pm_modes; + +static void rcpm_v1_irq_mask(int cpu) +{ + int hw_cpu = get_hard_smp_processor_id(cpu); + unsigned int mask = 1 << hw_cpu; + + setbits32(&rcpm_v1_regs->cpmimr, mask); + setbits32(&rcpm_v1_regs->cpmcimr, mask); + setbits32(&rcpm_v1_regs->cpmmcmr, mask); + setbits32(&rcpm_v1_regs->cpmnmimr, mask); +} + +static void rcpm_v2_irq_mask(int cpu) +{ + int hw_cpu = get_hard_smp_processor_id(cpu); + unsigned int mask = 1 << hw_cpu; + + setbits32(&rcpm_v2_regs->tpmimr0, mask); + setbits32(&rcpm_v2_regs->tpmcimr0, mask); + setbits32(&rcpm_v2_regs->tpmmcmr0, mask); + setbits32(&rcpm_v2_regs->tpmnmimr0, mask); +} + +static void rcpm_v1_irq_unmask(int cpu) +{ + int hw_cpu = get_hard_smp_processor_id(cpu); + unsigned int mask = 1 << hw_cpu; + + clrbits32(&rcpm_v1_regs->cpmimr, mask); + clrbits32(&rcpm_v1_regs->cpmcimr, mask); + clrbits32(&rcpm_v1_regs->cpmmcmr, mask); + clrbits32(&rcpm_v1_regs->cpmnmimr, mask); +} + +static void rcpm_v2_irq_unmask(int cpu) +{ + int hw_cpu = get_hard_smp_processor_id(cpu); + unsigned int mask = 1 << hw_cpu; + + clrbits32(&rcpm_v2_regs->tpmimr0, mask); + clrbits32(&rcpm_v2_regs->tpmcimr0, mask); + clrbits32(&rcpm_v2_regs->tpmmcmr0, mask); + clrbits32(&rcpm_v2_regs->tpmnmimr0, mask); +} + +static void rcpm_v1_set_ip_power(bool enable, u32 mask) +{ + if (enable) + setbits32(&rcpm_v1_regs->ippdexpcr, mask); + else + clrbits32(&rcpm_v1_regs->ippdexpcr, mask); +} + +static void rcpm_v2_set_ip_power(bool enable, u32 mask) +{ + if (enable) + setbits32(&rcpm_v2_regs->ippdexpcr[0], mask); + else + clrbits32(&rcpm_v2_regs->ippdexpcr[0], mask); +} + +static void rcpm_v1_cpu_enter_state(int cpu, int state) +{ + int hw_cpu = get_hard_smp_processor_id(cpu); + unsigned int mask = 1 << hw_cpu; + + switch (state) { + case E500_PM_PH10: + setbits32(&rcpm_v1_regs->cdozcr, mask); + break; + case E500_PM_PH15: + setbits32(&rcpm_v1_regs->cnapcr, mask); + break; + default: + pr_warn("Unknown cpu PM state (%d)\n", state); + break; + } +} + +static void rcpm_v2_cpu_enter_state(int cpu, int state) +{ + int hw_cpu = get_hard_smp_processor_id(cpu); + u32 mask = 1 << cpu_core_index_of_thread(cpu); + + switch (state) { + case E500_PM_PH10: + /* one bit corresponds to one thread for PH10 of 6500 */ + setbits32(&rcpm_v2_regs->tph10setr0, 1 << hw_cpu); + break; + case E500_PM_PH15: + setbits32(&rcpm_v2_regs->pcph15setr, mask); + break; + case E500_PM_PH20: + setbits32(&rcpm_v2_regs->pcph20setr, mask); + break; + case E500_PM_PH30: + setbits32(&rcpm_v2_regs->pcph30setr, mask); + break; + default: + pr_warn("Unknown cpu PM state (%d)\n", state); + } +} + +static void rcpm_v1_cpu_die(int cpu) +{ + rcpm_v1_cpu_enter_state(cpu, E500_PM_PH15); +} + +#ifdef CONFIG_PPC64 +static void qoriq_disable_thread(int cpu) +{ + int thread = cpu_thread_in_core(cpu); + + book3e_stop_thread(thread); +} +#endif + +static void rcpm_v2_cpu_die(int cpu) +{ +#ifdef CONFIG_PPC64 + int primary; + + if (threads_per_core == 2) { + primary = cpu_first_thread_sibling(cpu); + if (cpu_is_offline(primary) && cpu_is_offline(primary + 1)) { + /* if both threads are offline, put the cpu in PH20 */ + rcpm_v2_cpu_enter_state(cpu, E500_PM_PH20); + } else { + /* if only one thread is offline, disable the thread */ + qoriq_disable_thread(cpu); + } + } +#endif + + if (threads_per_core == 1) + rcpm_v2_cpu_enter_state(cpu, E500_PM_PH20); +} + +static void rcpm_v1_cpu_exit_state(int cpu, int state) +{ + int hw_cpu = get_hard_smp_processor_id(cpu); + unsigned int mask = 1 << hw_cpu; + + switch (state) { + case E500_PM_PH10: + clrbits32(&rcpm_v1_regs->cdozcr, mask); + break; + case E500_PM_PH15: + clrbits32(&rcpm_v1_regs->cnapcr, mask); + break; + default: + pr_warn("Unknown cpu PM state (%d)\n", state); + break; + } +} + +static void rcpm_v1_cpu_up_prepare(int cpu) +{ + rcpm_v1_cpu_exit_state(cpu, E500_PM_PH15); + rcpm_v1_irq_unmask(cpu); +} + +static void rcpm_v2_cpu_exit_state(int cpu, int state) +{ + int hw_cpu = get_hard_smp_processor_id(cpu); + u32 mask = 1 << cpu_core_index_of_thread(cpu); + + switch (state) { + case E500_PM_PH10: + setbits32(&rcpm_v2_regs->tph10clrr0, 1 << hw_cpu); + break; + case E500_PM_PH15: + setbits32(&rcpm_v2_regs->pcph15clrr, mask); + break; + case E500_PM_PH20: + setbits32(&rcpm_v2_regs->pcph20clrr, mask); + break; + case E500_PM_PH30: + setbits32(&rcpm_v2_regs->pcph30clrr, mask); + break; + default: + pr_warn("Unknown cpu PM state (%d)\n", state); + } +} + +static void rcpm_v2_cpu_up_prepare(int cpu) +{ + rcpm_v2_cpu_exit_state(cpu, E500_PM_PH20); + rcpm_v2_irq_unmask(cpu); +} + +static int rcpm_v1_plat_enter_state(int state) +{ + u32 *pmcsr_reg = &rcpm_v1_regs->powmgtcsr; + int ret = 0; + int result; + + switch (state) { + case PLAT_PM_SLEEP: + setbits32(pmcsr_reg, RCPM_POWMGTCSR_SLP); + + /* Upon resume, wait for RCPM_POWMGTCSR_SLP bit to be clear. */ + result = spin_event_timeout( + !(in_be32(pmcsr_reg) & RCPM_POWMGTCSR_SLP), 10000, 10); + if (!result) { + pr_err("timeout waiting for SLP bit to be cleared\n"); + ret = -ETIMEDOUT; + } + break; + default: + pr_warn("Unknown platform PM state (%d)", state); + ret = -EINVAL; + } + + return ret; +} + +static int rcpm_v2_plat_enter_state(int state) +{ + u32 *pmcsr_reg = &rcpm_v2_regs->powmgtcsr; + int ret = 0; + int result; + + switch (state) { + case PLAT_PM_LPM20: + /* clear previous LPM20 status */ + setbits32(pmcsr_reg, RCPM_POWMGTCSR_P_LPM20_ST); + /* enter LPM20 status */ + setbits32(pmcsr_reg, RCPM_POWMGTCSR_LPM20_RQ); + + /* At this point, the device is in LPM20 status. */ + + /* resume ... */ + result = spin_event_timeout( + !(in_be32(pmcsr_reg) & RCPM_POWMGTCSR_LPM20_ST), 10000, 10); + if (!result) { + pr_err("timeout waiting for LPM20 bit to be cleared\n"); + ret = -ETIMEDOUT; + } + break; + default: + pr_warn("Unknown platform PM state (%d)\n", state); + ret = -EINVAL; + } + + return ret; +} + +static int rcpm_v1_plat_enter_sleep(void) +{ + return rcpm_v1_plat_enter_state(PLAT_PM_SLEEP); +} + +static int rcpm_v2_plat_enter_sleep(void) +{ + return rcpm_v2_plat_enter_state(PLAT_PM_LPM20); +} + +static void rcpm_common_freeze_time_base(u32 *tben_reg, int freeze) +{ + static u32 mask; + + if (freeze) { + mask = in_be32(tben_reg); + clrbits32(tben_reg, mask); + } else { + setbits32(tben_reg, mask); + } + + /* read back to push the previous write */ + in_be32(tben_reg); +} + +static void rcpm_v1_freeze_time_base(bool freeze) +{ + rcpm_common_freeze_time_base(&rcpm_v1_regs->ctbenr, freeze); +} + +static void rcpm_v2_freeze_time_base(bool freeze) +{ + rcpm_common_freeze_time_base(&rcpm_v2_regs->pctbenr, freeze); +} + +static unsigned int rcpm_get_pm_modes(void) +{ + return fsl_supported_pm_modes; +} + +static const struct fsl_pm_ops qoriq_rcpm_v1_ops = { + .irq_mask = rcpm_v1_irq_mask, + .irq_unmask = rcpm_v1_irq_unmask, + .cpu_enter_state = rcpm_v1_cpu_enter_state, + .cpu_exit_state = rcpm_v1_cpu_exit_state, + .cpu_up_prepare = rcpm_v1_cpu_up_prepare, + .cpu_die = rcpm_v1_cpu_die, + .plat_enter_sleep = rcpm_v1_plat_enter_sleep, + .set_ip_power = rcpm_v1_set_ip_power, + .freeze_time_base = rcpm_v1_freeze_time_base, + .get_pm_modes = rcpm_get_pm_modes, +}; + +static const struct fsl_pm_ops qoriq_rcpm_v2_ops = { + .irq_mask = rcpm_v2_irq_mask, + .irq_unmask = rcpm_v2_irq_unmask, + .cpu_enter_state = rcpm_v2_cpu_enter_state, + .cpu_exit_state = rcpm_v2_cpu_exit_state, + .cpu_up_prepare = rcpm_v2_cpu_up_prepare, + .cpu_die = rcpm_v2_cpu_die, + .plat_enter_sleep = rcpm_v2_plat_enter_sleep, + .set_ip_power = rcpm_v2_set_ip_power, + .freeze_time_base = rcpm_v2_freeze_time_base, + .get_pm_modes = rcpm_get_pm_modes, +}; + +static const struct of_device_id rcpm_matches[] = { + { + .compatible = "fsl,qoriq-rcpm-1.0", + .data = &qoriq_rcpm_v1_ops, + }, + { + .compatible = "fsl,qoriq-rcpm-2.0", + .data = &qoriq_rcpm_v2_ops, + }, + { + .compatible = "fsl,qoriq-rcpm-2.1", + .data = &qoriq_rcpm_v2_ops, + }, + {}, +}; + +int __init fsl_rcpm_init(void) +{ + struct device_node *np; + const struct of_device_id *match; + void __iomem *base; + + np = of_find_matching_node_and_match(NULL, rcpm_matches, &match); + if (!np) + return 0; + + base = of_iomap(np, 0); + of_node_put(np); + if (!base) { + pr_err("of_iomap() error.\n"); + return -ENOMEM; + } + + rcpm_v1_regs = base; + rcpm_v2_regs = base; + + /* support sleep by default */ + fsl_supported_pm_modes = FSL_PM_SLEEP; + + qoriq_pm_ops = match->data; + + return 0; +} diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index c1cd3698f534eea2e3abc728798151ed184200bd..f5bf38b9459585fcd1f8d4a34ed24c8067e67daa 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c @@ -606,6 +606,12 @@ int fsl_rio_setup(struct platform_device *dev) if (!port) continue; + rc = rio_mport_initialize(port); + if (rc) { + kfree(port); + continue; + } + i = *port_index - 1; port->index = (unsigned char)i; @@ -682,12 +688,6 @@ int fsl_rio_setup(struct platform_device *dev) dev_info(&dev->dev, "RapidIO Common Transport System size: %d\n", port->sys_size ? 65536 : 256); - if (rio_register_mport(port)) { - release_resource(&port->iores); - kfree(priv); - kfree(port); - continue; - } if (port->host_deviceid >= 0) out_be32(priv->regs_win + RIO_GCCSR, RIO_PORT_GEN_HOST | RIO_PORT_GEN_MASTER | RIO_PORT_GEN_DISCOVERED); @@ -726,7 +726,14 @@ int fsl_rio_setup(struct platform_device *dev) fsl_rio_inbound_mem_init(priv); dbell->mport[i] = port; + pw->mport[i] = port; + if (rio_register_mport(port)) { + release_resource(&port->iores); + kfree(priv); + kfree(port); + continue; + } active_ports++; } diff --git a/arch/powerpc/sysdev/fsl_rio.h b/arch/powerpc/sysdev/fsl_rio.h index d53407a34f32884909deb932625b49de9990b22d..12dd18fd479561dfafdc053463465ce0d73c4a07 100644 --- a/arch/powerpc/sysdev/fsl_rio.h +++ b/arch/powerpc/sysdev/fsl_rio.h @@ -97,6 +97,7 @@ struct fsl_rio_dbell { }; struct fsl_rio_pw { + struct rio_mport *mport[MAX_PORT_NUM]; struct device *dev; struct rio_pw_regs __iomem *pw_regs; struct rio_port_write_msg port_write_msg; diff --git a/arch/powerpc/sysdev/fsl_rmu.c b/arch/powerpc/sysdev/fsl_rmu.c index b48197ae44d0f1ebfb26a8ca4b5d4ca023c5dbce..c1826de4e749dc1ab15987831d310fb91f0fc6c9 100644 --- a/arch/powerpc/sysdev/fsl_rmu.c +++ b/arch/powerpc/sysdev/fsl_rmu.c @@ -481,14 +481,14 @@ fsl_rio_port_write_handler(int irq, void *dev_instance) static void fsl_pw_dpc(struct work_struct *work) { struct fsl_rio_pw *pw = container_of(work, struct fsl_rio_pw, pw_work); - u32 msg_buffer[RIO_PW_MSG_SIZE/sizeof(u32)]; + union rio_pw_msg msg_buffer; + int i; /* * Process port-write messages */ - while (kfifo_out_spinlocked(&pw->pw_fifo, (unsigned char *)msg_buffer, + while (kfifo_out_spinlocked(&pw->pw_fifo, (unsigned char *)&msg_buffer, RIO_PW_MSG_SIZE, &pw->pw_fifo_lock)) { - /* Process one message */ #ifdef DEBUG_PW { u32 i; @@ -496,15 +496,19 @@ static void fsl_pw_dpc(struct work_struct *work) for (i = 0; i < RIO_PW_MSG_SIZE/sizeof(u32); i++) { if ((i%4) == 0) pr_debug("\n0x%02x: 0x%08x", i*4, - msg_buffer[i]); + msg_buffer.raw[i]); else - pr_debug(" 0x%08x", msg_buffer[i]); + pr_debug(" 0x%08x", msg_buffer.raw[i]); } pr_debug("\n"); } #endif /* Pass the port-write message to RIO core for processing */ - rio_inb_pwrite_handler((union rio_pw_msg *)msg_buffer); + for (i = 0; i < MAX_PORT_NUM; i++) { + if (pw->mport[i]) + rio_inb_pwrite_handler(pw->mport[i], + &msg_buffer); + } } } @@ -570,7 +574,7 @@ int fsl_rio_port_write_init(struct fsl_rio_pw *pw) out_be32(&pw->pw_regs->pwsr, (RIO_IPWSR_TE | RIO_IPWSR_QFI | RIO_IPWSR_PWD)); - /* Configure port write contoller for snooping enable all reporting, + /* Configure port write controller for snooping enable all reporting, clear queue full */ out_be32(&pw->pw_regs->pwmr, RIO_IPWMR_SEN | RIO_IPWMR_QFIE | RIO_IPWMR_EIE | RIO_IPWMR_CQ); diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c index 6f99ed3967fdef3ad382a03758d361e1ee3223db..aa2c186d311585f823c20c16c4a685f11f5624da 100644 --- a/arch/powerpc/sysdev/i8259.c +++ b/arch/powerpc/sysdev/i8259.c @@ -238,7 +238,7 @@ void i8259_init(struct device_node *node, unsigned long intack_addr) /* init master interrupt controller */ outb(0x11, 0x20); /* Start init sequence */ outb(0x00, 0x21); /* Vector base */ - outb(0x04, 0x21); /* edge tiggered, Cascade (slave) on IRQ2 */ + outb(0x04, 0x21); /* edge triggered, Cascade (slave) on IRQ2 */ outb(0x01, 0x21); /* Select 8086 mode */ /* init slave interrupt controller */ diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 2a0452e364ba70a49c9985e086bc20a724b2cb16..afe3c7cd395d3ddce0077d79044f71f3030fd164 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -2,7 +2,7 @@ * arch/powerpc/kernel/mpic.c * * Driver for interrupt controllers following the OpenPIC standard, the - * common implementation beeing IBM's MPIC. This driver also can deal + * common implementation being IBM's MPIC. This driver also can deal * with various broken implementations of this HW. * * Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp. @@ -1657,7 +1657,7 @@ void __init mpic_init(struct mpic *mpic) } } - /* FSL mpic error interrupt intialization */ + /* FSL mpic error interrupt initialization */ if (mpic->flags & MPIC_FSL_HAS_EIMR) mpic_err_int_init(mpic, MPIC_FSL_ERR_INT); } diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 07a8508cb7fae6cd1d0a742eb0c1d4c19769eeac..942796fa476750221133664d35d701a97b659499 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -47,6 +47,9 @@ #include #include +#include +#include + #ifdef CONFIG_PPC64 #include #include @@ -119,6 +122,16 @@ static void dump(void); static void prdump(unsigned long, long); static int ppc_inst_dump(unsigned long, long, int); static void dump_log_buf(void); + +#ifdef CONFIG_PPC_POWERNV +static void dump_opal_msglog(void); +#else +static inline void dump_opal_msglog(void) +{ + printf("Machine is not running OPAL firmware.\n"); +} +#endif + static void backtrace(struct pt_regs *); static void excprint(struct pt_regs *); static void prregs(struct pt_regs *); @@ -150,6 +163,7 @@ static int cpu_cmd(void); static void csum(void); static void bootcmds(void); static void proccall(void); +static void show_tasks(void); void dump_segments(void); static void symbol_lookup(void); static void xmon_show_stack(unsigned long sp, unsigned long lr, @@ -202,6 +216,10 @@ Commands:\n\ df dump float values\n\ dd dump double values\n\ dl dump the kernel log buffer\n" +#ifdef CONFIG_PPC_POWERNV + "\ + do dump the OPAL message log\n" +#endif #ifdef CONFIG_PPC64 "\ dp[#] dump paca for current cpu, or cpu #\n\ @@ -221,6 +239,7 @@ Commands:\n\ mz zero a block of memory\n\ mi show information about memory allocation\n\ p call a procedure\n\ + P list processes/tasks\n\ r print registers\n\ s single step\n" #ifdef CONFIG_SPU_BASE @@ -233,7 +252,7 @@ Commands:\n\ " S print special registers\n\ t print backtrace\n\ x exit monitor and recover\n\ - X exit monitor and dont recover\n" + X exit monitor and don't recover\n" #if defined(CONFIG_PPC64) && !defined(CONFIG_PPC_BOOK3E) " u dump segment table or SLB\n" #elif defined(CONFIG_PPC_STD_MMU_32) @@ -950,6 +969,9 @@ cmds(struct pt_regs *excp) case 'p': proccall(); break; + case 'P': + show_tasks(); + break; #ifdef CONFIG_PPC_STD_MMU case 'u': dump_segments(); @@ -2253,6 +2275,8 @@ dump(void) last_cmd = "di\n"; } else if (c == 'l') { dump_log_buf(); + } else if (c == 'o') { + dump_opal_msglog(); } else if (c == 'r') { scanhex(&ndump); if (ndump == 0) @@ -2395,6 +2419,45 @@ dump_log_buf(void) catch_memory_errors = 0; } +#ifdef CONFIG_PPC_POWERNV +static void dump_opal_msglog(void) +{ + unsigned char buf[128]; + ssize_t res; + loff_t pos = 0; + + if (!firmware_has_feature(FW_FEATURE_OPAL)) { + printf("Machine is not running OPAL firmware.\n"); + return; + } + + if (setjmp(bus_error_jmp) != 0) { + printf("Error dumping OPAL msglog!\n"); + return; + } + + catch_memory_errors = 1; + sync(); + + xmon_start_pagination(); + while ((res = opal_msglog_copy(buf, pos, sizeof(buf) - 1))) { + if (res < 0) { + printf("Error dumping OPAL msglog! Error: %zd\n", res); + break; + } + buf[res] = '\0'; + printf("%s", buf); + pos += res; + } + xmon_end_pagination(); + + sync(); + /* wait a little while to see if we get a machine check */ + __delay(200); + catch_memory_errors = 0; +} +#endif + /* * Memory operations - move, set, print differences */ @@ -2508,6 +2571,61 @@ memzcan(void) printf("%.8x\n", a - mskip); } +static void show_task(struct task_struct *tsk) +{ + char state; + + /* + * Cloned from kdb_task_state_char(), which is not entirely + * appropriate for calling from xmon. This could be moved + * to a common, generic, routine used by both. + */ + state = (tsk->state == 0) ? 'R' : + (tsk->state < 0) ? 'U' : + (tsk->state & TASK_UNINTERRUPTIBLE) ? 'D' : + (tsk->state & TASK_STOPPED) ? 'T' : + (tsk->state & TASK_TRACED) ? 'C' : + (tsk->exit_state & EXIT_ZOMBIE) ? 'Z' : + (tsk->exit_state & EXIT_DEAD) ? 'E' : + (tsk->state & TASK_INTERRUPTIBLE) ? 'S' : '?'; + + printf("%p %016lx %6d %6d %c %2d %s\n", tsk, + tsk->thread.ksp, + tsk->pid, tsk->parent->pid, + state, task_thread_info(tsk)->cpu, + tsk->comm); +} + +static void show_tasks(void) +{ + unsigned long tskv; + struct task_struct *tsk = NULL; + + printf(" task_struct ->thread.ksp PID PPID S P CMD\n"); + + if (scanhex(&tskv)) + tsk = (struct task_struct *)tskv; + + if (setjmp(bus_error_jmp) != 0) { + catch_memory_errors = 0; + printf("*** Error dumping task %p\n", tsk); + return; + } + + catch_memory_errors = 1; + sync(); + + if (tsk) + show_task(tsk); + else + for_each_process(tsk) + show_task(tsk); + + sync(); + __delay(200); + catch_memory_errors = 0; +} + static void proccall(void) { unsigned long args[8]; diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 7e3e8a8338d6c5a3f45de1535d59bd64c91e1475..aad23e3dff2c17b0bba5a7d2740ea47c21839480 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -59,6 +59,9 @@ config PCI_QUIRKS config ARCH_SUPPORTS_UPROBES def_bool y +config DEBUG_RODATA + def_bool y + config S390 def_bool y select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE @@ -124,6 +127,7 @@ config S390 select HAVE_CMPXCHG_DOUBLE select HAVE_CMPXCHG_LOCAL select HAVE_DEBUG_KMEMLEAK + select HAVE_DMA_API_DEBUG select HAVE_DYNAMIC_FTRACE select HAVE_DYNAMIC_FTRACE_WITH_REGS select HAVE_FTRACE_MCOUNT_RECORD @@ -617,10 +621,6 @@ config HAS_IOMEM config IOMMU_HELPER def_bool PCI -config HAS_DMA - def_bool PCI - select HAVE_DMA_API_DEBUG - config NEED_SG_DMA_LENGTH def_bool PCI diff --git a/arch/s390/crypto/prng.c b/arch/s390/crypto/prng.c index b8045b97f4fbd888c35783b13a2b5b9dc89f353f..d750cc0dfe301ed1dd5fa5edd8df1a6fb97cc451 100644 --- a/arch/s390/crypto/prng.c +++ b/arch/s390/crypto/prng.c @@ -669,11 +669,13 @@ static const struct file_operations prng_tdes_fops = { static struct miscdevice prng_sha512_dev = { .name = "prandom", .minor = MISC_DYNAMIC_MINOR, + .mode = 0644, .fops = &prng_sha512_fops, }; static struct miscdevice prng_tdes_dev = { .name = "prandom", .minor = MISC_DYNAMIC_MINOR, + .mode = 0644, .fops = &prng_tdes_fops, }; diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c index 0f3da2cb2bd63c0d26649776fd53d844f3153d18..255c7eec44810420ae1b4d7608142db58fbad7e7 100644 --- a/arch/s390/hypfs/inode.c +++ b/arch/s390/hypfs/inode.c @@ -278,8 +278,8 @@ static int hypfs_fill_super(struct super_block *sb, void *data, int silent) sbi->uid = current_uid(); sbi->gid = current_gid(); sb->s_fs_info = sbi; - sb->s_blocksize = PAGE_CACHE_SIZE; - sb->s_blocksize_bits = PAGE_CACHE_SHIFT; + sb->s_blocksize = PAGE_SIZE; + sb->s_blocksize_bits = PAGE_SHIFT; sb->s_magic = HYPFS_MAGIC; sb->s_op = &hypfs_s_ops; if (hypfs_parse_options(data, sb)) diff --git a/arch/s390/include/asm/cache.h b/arch/s390/include/asm/cache.h index 4d7ccac5fd1d693e3875f2eac011d46ff3750a0e..22da3b34c6557dcb979d6187ed9424769a17464e 100644 --- a/arch/s390/include/asm/cache.h +++ b/arch/s390/include/asm/cache.h @@ -15,4 +15,7 @@ #define __read_mostly __attribute__((__section__(".data..read_mostly"))) +/* Read-only memory is marked before mark_rodata_ro() is called. */ +#define __ro_after_init __read_mostly + #endif diff --git a/arch/s390/include/asm/checksum.h b/arch/s390/include/asm/checksum.h index 7403648563554604e19b6cfbd0873bee868c7644..d7f100c53f07fd483a39cd6e00315e460455c19b 100644 --- a/arch/s390/include/asm/checksum.h +++ b/arch/s390/include/asm/checksum.h @@ -91,8 +91,7 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) * returns a 32-bit checksum */ static inline __wsum -csum_tcpudp_nofold(__be32 saddr, __be32 daddr, - unsigned short len, unsigned short proto, +csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len, __u8 proto, __wsum sum) { __u32 csum = (__force __u32)sum; @@ -118,8 +117,7 @@ csum_tcpudp_nofold(__be32 saddr, __be32 daddr, */ static inline __sum16 -csum_tcpudp_magic(__be32 saddr, __be32 daddr, - unsigned short len, unsigned short proto, +csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len, __u8 proto, __wsum sum) { return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); diff --git a/arch/s390/include/asm/device.h b/arch/s390/include/asm/device.h index d8f9872b0e2dc3587a9e658adc957f093b7906fb..4a9f35e0973ff166956c123d594fd24c7dfafc92 100644 --- a/arch/s390/include/asm/device.h +++ b/arch/s390/include/asm/device.h @@ -3,5 +3,9 @@ * * This file is released under the GPLv2 */ -#include +struct dev_archdata { + struct dma_map_ops *dma_ops; +}; +struct pdev_archdata { +}; diff --git a/arch/s390/include/asm/dma-mapping.h b/arch/s390/include/asm/dma-mapping.h index e64bfcb9702f668ada47197049718b1531ddc1a1..3249b746488961e8f64a401f45911abab45c4521 100644 --- a/arch/s390/include/asm/dma-mapping.h +++ b/arch/s390/include/asm/dma-mapping.h @@ -11,11 +11,13 @@ #define DMA_ERROR_CODE (~(dma_addr_t) 0x0) -extern struct dma_map_ops s390_dma_ops; +extern struct dma_map_ops s390_pci_dma_ops; static inline struct dma_map_ops *get_dma_ops(struct device *dev) { - return &s390_dma_ops; + if (dev && dev->archdata.dma_ops) + return dev->archdata.dma_ops; + return &dma_noop_ops; } static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, diff --git a/arch/s390/include/asm/livepatch.h b/arch/s390/include/asm/livepatch.h index a52b6cca873d380adc9bec726cc31816dba5cd6b..d5427c78b1b3edb1bbccff92bfbf4c86c45d6214 100644 --- a/arch/s390/include/asm/livepatch.h +++ b/arch/s390/include/asm/livepatch.h @@ -19,7 +19,6 @@ #include -#ifdef CONFIG_LIVEPATCH static inline int klp_check_compiler_support(void) { return 0; @@ -36,8 +35,5 @@ static inline void klp_arch_set_pc(struct pt_regs *regs, unsigned long ip) { regs->psw.addr = ip; } -#else -#error Include linux/livepatch.h, not asm/livepatch.h -#endif #endif diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h index e485817f7b1a97683e64ab04d1f7444e1aae2e1d..d321469eeda7316205f019b7201f54f68a71d79b 100644 --- a/arch/s390/include/asm/mmu_context.h +++ b/arch/s390/include/asm/mmu_context.h @@ -136,4 +136,16 @@ static inline void arch_bprm_mm_init(struct mm_struct *mm, { } +static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, + bool write, bool execute, bool foreign) +{ + /* by default, allow everything */ + return true; +} + +static inline bool arch_pte_access_permitted(pte_t pte, bool write) +{ + /* by default, allow everything */ + return true; +} #endif /* __S390_MMU_CONTEXT_H */ diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h index 9dd4cc47ddc79298886fe40a5e229628b2ceff3d..e0900ddf91dd0144a92e3f962eabd18395f5bcb6 100644 --- a/arch/s390/include/asm/uaccess.h +++ b/arch/s390/include/asm/uaccess.h @@ -79,18 +79,12 @@ struct exception_table_entry int insn, fixup; }; -static inline unsigned long extable_insn(const struct exception_table_entry *x) -{ - return (unsigned long)&x->insn + x->insn; -} - static inline unsigned long extable_fixup(const struct exception_table_entry *x) { return (unsigned long)&x->fixup + x->fixup; } -#define ARCH_HAS_SORT_EXTABLE -#define ARCH_HAS_SEARCH_EXTABLE +#define ARCH_HAS_RELATIVE_EXTABLE /** * __copy_from_user: - Copy a block of data from user space, with less checking. diff --git a/arch/s390/include/uapi/asm/socket.h b/arch/s390/include/uapi/asm/socket.h index d02e89d14fefe45d298e564685a9de377ce7f901..41b51c2f4f1ba98055f7f75ac36915665b62392c 100644 --- a/arch/s390/include/uapi/asm/socket.h +++ b/arch/s390/include/uapi/asm/socket.h @@ -94,4 +94,6 @@ #define SO_ATTACH_REUSEPORT_CBPF 51 #define SO_ATTACH_REUSEPORT_EBPF 52 +#define SO_CNX_ADVICE 53 + #endif /* _ASM_SOCKET_H */ diff --git a/arch/s390/include/uapi/asm/unistd.h b/arch/s390/include/uapi/asm/unistd.h index ab3aa6875a59ca4dc3760663d79189090286d7ab..4384bc797a54f9d77dd593123f0cfc567124f792 100644 --- a/arch/s390/include/uapi/asm/unistd.h +++ b/arch/s390/include/uapi/asm/unistd.h @@ -311,7 +311,9 @@ #define __NR_shutdown 373 #define __NR_mlock2 374 #define __NR_copy_file_range 375 -#define NR_syscalls 376 +#define __NR_preadv2 376 +#define __NR_pwritev2 377 +#define NR_syscalls 378 /* * There are some system calls that are not present on 64 bit, some diff --git a/arch/s390/kernel/perf_cpum_cf.c b/arch/s390/kernel/perf_cpum_cf.c index 58bf4572d457f09465abf82cc6e8e4cfda1b21ca..62f066b5259e30dd6661671e5e06525e5c42ba5e 100644 --- a/arch/s390/kernel/perf_cpum_cf.c +++ b/arch/s390/kernel/perf_cpum_cf.c @@ -670,6 +670,7 @@ static int cpumf_pmu_notifier(struct notifier_block *self, unsigned long action, switch (action & ~CPU_TASKS_FROZEN) { case CPU_ONLINE: + case CPU_DOWN_FAILED: flags = PMC_INIT; smp_call_function_single(cpu, setup_pmc_cpu, &flags, 1); break; diff --git a/arch/s390/kernel/perf_cpum_sf.c b/arch/s390/kernel/perf_cpum_sf.c index 1a43474df541a08008d011f0678211ab63eb19fa..eaab9a7cb3be6a43f38dfa10a1a670656ca110dc 100644 --- a/arch/s390/kernel/perf_cpum_sf.c +++ b/arch/s390/kernel/perf_cpum_sf.c @@ -1521,7 +1521,7 @@ static int cpumf_pmu_notifier(struct notifier_block *self, switch (action & ~CPU_TASKS_FROZEN) { case CPU_ONLINE: - case CPU_ONLINE_FROZEN: + case CPU_DOWN_FAILED: flags = PMC_INIT; smp_call_function_single(cpu, setup_pmc_cpu, &flags, 1); break; diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 293d8b98fd525c992146fa4f5c85f1287d90bc62..9b59e6212d8fd22cadbc35f9e3546f7aa47e540c 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -384,3 +384,5 @@ SYSCALL(sys_recvmsg,compat_sys_recvmsg) SYSCALL(sys_shutdown,sys_shutdown) SYSCALL(sys_mlock2,compat_sys_mlock2) SYSCALL(sys_copy_file_range,compat_sys_copy_file_range) /* 375 */ +SYSCALL(sys_preadv2,compat_sys_preadv2) +SYSCALL(sys_pwritev2,compat_sys_pwritev2) diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index c4e5f183f225d23519295f9f4900a2a3b2734367..9409d32f285e903580a50aa9e5b90ccd37f6b1cb 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -1432,7 +1432,7 @@ device_initcall(etr_init_sysfs); /* * Server Time Protocol (STP) code. */ -static int stp_online; +static bool stp_online; static struct stp_sstpi stp_info; static void *stp_page; @@ -1443,11 +1443,7 @@ static struct timer_list stp_timer; static int __init early_parse_stp(char *p) { - if (strncmp(p, "off", 3) == 0) - stp_online = 0; - else if (strncmp(p, "on", 2) == 0) - stp_online = 1; - return 0; + return kstrtobool(p, &stp_online); } early_param("stp", early_parse_stp); diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c index 40b8102fdadb84790ecde278de7fbc8f0c5314e5..64298a8675895e4529954fcb7103acbae712b1a7 100644 --- a/arch/s390/kernel/topology.c +++ b/arch/s390/kernel/topology.c @@ -37,7 +37,7 @@ static void set_topology_timer(void); static void topology_work_fn(struct work_struct *work); static struct sysinfo_15_1_x *tl_info; -static int topology_enabled = 1; +static bool topology_enabled = true; static DECLARE_WORK(topology_work, topology_work_fn); /* @@ -444,10 +444,7 @@ static const struct cpumask *cpu_book_mask(int cpu) static int __init early_parse_topology(char *p) { - if (strncmp(p, "off", 3)) - return 0; - topology_enabled = 0; - return 0; + return kstrtobool(p, &topology_enabled); } early_param("topology", early_parse_topology); diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S index 445657fe658cc62b4308f7fda4a23360dadfbb26..0f41a8286378503a3708d78d79255ef41bde65fe 100644 --- a/arch/s390/kernel/vmlinux.lds.S +++ b/arch/s390/kernel/vmlinux.lds.S @@ -28,6 +28,7 @@ SECTIONS LOCK_TEXT KPROBES_TEXT IRQENTRY_TEXT + SOFTIRQENTRY_TEXT *(.fixup) *(.gnu.warning) } :text = 0x0700 diff --git a/arch/s390/mm/Makefile b/arch/s390/mm/Makefile index 2ae54cad2b6ab2734f999694bbb968b940416d00..0aa0ad165d8b95fcd3eca000f7eedeee3714f319 100644 --- a/arch/s390/mm/Makefile +++ b/arch/s390/mm/Makefile @@ -3,7 +3,7 @@ # obj-y := init.o fault.o extmem.o mmap.o vmem.o maccess.o -obj-y += page-states.o gup.o extable.o pageattr.o mem_detect.o +obj-y += page-states.o gup.o pageattr.o mem_detect.o obj-y += pgtable.o pgalloc.o obj-$(CONFIG_CMM) += cmm.o diff --git a/arch/s390/mm/extable.c b/arch/s390/mm/extable.c deleted file mode 100644 index 18c8b819b0aa96fa6cabfad631a38e02fd59dbbf..0000000000000000000000000000000000000000 --- a/arch/s390/mm/extable.c +++ /dev/null @@ -1,85 +0,0 @@ -#include -#include -#include - -/* - * Search one exception table for an entry corresponding to the - * given instruction address, and return the address of the entry, - * or NULL if none is found. - * We use a binary search, and thus we assume that the table is - * already sorted. - */ -const struct exception_table_entry * -search_extable(const struct exception_table_entry *first, - const struct exception_table_entry *last, - unsigned long value) -{ - const struct exception_table_entry *mid; - unsigned long addr; - - while (first <= last) { - mid = ((last - first) >> 1) + first; - addr = extable_insn(mid); - if (addr < value) - first = mid + 1; - else if (addr > value) - last = mid - 1; - else - return mid; - } - return NULL; -} - -/* - * The exception table needs to be sorted so that the binary - * search that we use to find entries in it works properly. - * This is used both for the kernel exception table and for - * the exception tables of modules that get loaded. - * - */ -static int cmp_ex(const void *a, const void *b) -{ - const struct exception_table_entry *x = a, *y = b; - - /* This compare is only valid after normalization. */ - return x->insn - y->insn; -} - -void sort_extable(struct exception_table_entry *start, - struct exception_table_entry *finish) -{ - struct exception_table_entry *p; - int i; - - /* Normalize entries to being relative to the start of the section */ - for (p = start, i = 0; p < finish; p++, i += 8) { - p->insn += i; - p->fixup += i + 4; - } - sort(start, finish - start, sizeof(*start), cmp_ex, NULL); - /* Denormalize all entries */ - for (p = start, i = 0; p < finish; p++, i += 8) { - p->insn -= i; - p->fixup -= i + 4; - } -} - -#ifdef CONFIG_MODULES -/* - * If the exception table is sorted, any referring to the module init - * will be at the beginning or the end. - */ -void trim_init_extable(struct module *m) -{ - /* Trim the beginning */ - while (m->num_exentries && - within_module_init(extable_insn(&m->extable[0]), m)) { - m->extable++; - m->num_exentries--; - } - /* Trim the end */ - while (m->num_exentries && - within_module_init(extable_insn(&m->extable[m->num_exentries-1]), m)) - m->num_exentries--; -} -#endif /* CONFIG_MODULES */ diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c index 69247b4dcc43ab94a3ea7427c5f3998c7696ca86..cace818d86eb95bae2cd6f36038f177a5548a926 100644 --- a/arch/s390/mm/gmap.c +++ b/arch/s390/mm/gmap.c @@ -23,7 +23,7 @@ /** * gmap_alloc - allocate a guest address space * @mm: pointer to the parent mm_struct - * @limit: maximum size of the gmap address space + * @limit: maximum address of the gmap address space * * Returns a guest address space structure. */ @@ -292,7 +292,7 @@ int gmap_map_segment(struct gmap *gmap, unsigned long from, if ((from | to | len) & (PMD_SIZE - 1)) return -EINVAL; if (len == 0 || from + len < from || to + len < to || - from + len > TASK_MAX_SIZE || to + len > gmap->asce_end) + from + len - 1 > TASK_MAX_SIZE || to + len - 1 > gmap->asce_end) return -EINVAL; flush = 0; diff --git a/arch/s390/mm/gup.c b/arch/s390/mm/gup.c index 13dab0c1645c12de6b284b1b948758a524154441..a8a6765f1a519501b0f28bf7ca3a318d0b47f9a1 100644 --- a/arch/s390/mm/gup.c +++ b/arch/s390/mm/gup.c @@ -20,9 +20,9 @@ static inline int gup_pte_range(pmd_t *pmdp, pmd_t pmd, unsigned long addr, unsigned long end, int write, struct page **pages, int *nr) { + struct page *head, *page; unsigned long mask; pte_t *ptep, pte; - struct page *page; mask = (write ? _PAGE_PROTECT : 0) | _PAGE_INVALID | _PAGE_SPECIAL; @@ -37,12 +37,14 @@ static inline int gup_pte_range(pmd_t *pmdp, pmd_t pmd, unsigned long addr, return 0; VM_BUG_ON(!pfn_valid(pte_pfn(pte))); page = pte_page(pte); - if (!page_cache_get_speculative(page)) + head = compound_head(page); + if (!page_cache_get_speculative(head)) return 0; if (unlikely(pte_val(pte) != pte_val(*ptep))) { - put_page(page); + put_page(head); return 0; } + VM_BUG_ON_PAGE(compound_head(page) != head, page); pages[*nr] = page; (*nr)++; @@ -210,7 +212,6 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write, int get_user_pages_fast(unsigned long start, int nr_pages, int write, struct page **pages) { - struct mm_struct *mm = current->mm; int nr, ret; might_sleep(); @@ -222,8 +223,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, /* Try to get the remaining pages with get_user_pages */ start += nr << PAGE_SHIFT; pages += nr; - ret = get_user_pages_unlocked(current, mm, start, - nr_pages - nr, write, 0, pages); + ret = get_user_pages_unlocked(start, nr_pages - nr, write, 0, pages); /* Have to be a bit careful with return values */ if (nr > 0) ret = (ret < 0) ? nr : ret + nr; diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index 73e29033709285b44ceb5609919c07aff86e9de9..c7b0451397d6fbf6ac65f75c408c079601d0ad0a 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -108,6 +108,13 @@ void __init paging_init(void) free_area_init_nodes(max_zone_pfns); } +void mark_rodata_ro(void) +{ + /* Text and rodata are already protected. Nothing to do here. */ + pr_info("Write protecting the kernel read-only data: %luk\n", + ((unsigned long)&_eshared - (unsigned long)&_stext) >> 10); +} + void __init mem_init(void) { if (MACHINE_HAS_TLB_LC) @@ -126,9 +133,6 @@ void __init mem_init(void) setup_zero_pages(); /* Setup zeroed pages. */ mem_init_print_info(NULL); - printk("Write protected kernel read-only data: %#lx - %#lx\n", - (unsigned long)&_stext, - PFN_ALIGN((unsigned long)&_eshared) - 1); } void free_initmem(void) diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index 9fd59a7cfcd3c31133bac69b6e62ffbf0a9654ed..871af75c69c24cd1a7c59c0feb9c43124efaf5c6 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c @@ -641,6 +641,7 @@ int pcibios_add_device(struct pci_dev *pdev) int i; pdev->dev.groups = zpci_attr_groups; + pdev->dev.archdata.dma_ops = &s390_pci_dma_ops; zpci_map_resources(pdev); for (i = 0; i < PCI_BAR_COUNT; i++) { diff --git a/arch/s390/pci/pci_clp.c b/arch/s390/pci/pci_clp.c index 21591ddb4c1fddcd59aeb1d990f484040e57aeae..1a4512c8544ad6f516108e9eef2b4a8e22dfc5c1 100644 --- a/arch/s390/pci/pci_clp.c +++ b/arch/s390/pci/pci_clp.c @@ -176,8 +176,7 @@ static int clp_query_pci_fn(struct zpci_dev *zdev, u32 fh) rc = clp_store_query_pci_fn(zdev, &rrb->response); if (rc) goto out; - if (rrb->response.pfgid) - rc = clp_query_pci_fngrp(zdev, rrb->response.pfgid); + rc = clp_query_pci_fngrp(zdev, rrb->response.pfgid); } else { zpci_err("Q PCI FN:\n"); zpci_err_clp(rrb->response.hdr.rsp, rc); diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c index a06ce8037cec0257f805dd211d7ea4cfecbb5fd2..e595e89eac65d1f59831b5766d96507fbdbbd75a 100644 --- a/arch/s390/pci/pci_dma.c +++ b/arch/s390/pci/pci_dma.c @@ -547,7 +547,7 @@ static int __init dma_debug_do_init(void) } fs_initcall(dma_debug_do_init); -struct dma_map_ops s390_dma_ops = { +struct dma_map_ops s390_pci_dma_ops = { .alloc = s390_dma_alloc, .free = s390_dma_free, .map_sg = s390_dma_map_sg, @@ -558,7 +558,7 @@ struct dma_map_ops s390_dma_ops = { .is_phys = 0, /* dma_supported is unconditionally true without a callback */ }; -EXPORT_SYMBOL_GPL(s390_dma_ops); +EXPORT_SYMBOL_GPL(s390_pci_dma_ops); static int __init s390_iommu_setup(char *str) { diff --git a/arch/score/include/asm/checksum.h b/arch/score/include/asm/checksum.h index 961bd64015a817b50452499d992ce23f14291247..539d9fd45d211969a3fb5cd4ca697ae033722f10 100644 --- a/arch/score/include/asm/checksum.h +++ b/arch/score/include/asm/checksum.h @@ -127,10 +127,10 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) } static inline __wsum -csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) +csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len, + __u8 proto, __wsum sum) { - unsigned long tmp = (ntohs(len) << 16) + proto * 256; + unsigned long tmp = (len + proto) << 8; __asm__ __volatile__( ".set volatile\n\t" "add\t%0, %0, %2\n\t" @@ -161,8 +161,8 @@ csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, * returns a 16-bit checksum, already complemented */ static inline __sum16 -csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) +csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len, + __u8 proto, __wsum sum) { return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum)); } @@ -179,9 +179,8 @@ static inline unsigned short ip_compute_csum(const void *buff, int len) #define _HAVE_ARCH_IPV6_CSUM static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr, - const struct in6_addr *daddr, - __u32 len, unsigned short proto, - __wsum sum) + const struct in6_addr *daddr, + __u32 len, __u8 proto, __wsum sum) { __asm__ __volatile__( ".set\tvolatile\t\t\t# csum_ipv6_magic\n\t" diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 17a4f1593d6564bcfb2f09e4c677f31931725516..7ed20fc3fc81b1eee367e81cae239d89deeecf97 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -1,5 +1,6 @@ config SUPERH def_bool y + select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST select ARCH_MIGHT_HAVE_PC_PARPORT select HAVE_PATA_PLATFORM select CLKDEV_LOOKUP diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig index 89963d13f930a1a346c97710bf1233eee162ef9f..5e52d5362292b6f4db01872bcbdd08738711fd1e 100644 --- a/arch/sh/boards/Kconfig +++ b/arch/sh/boards/Kconfig @@ -6,6 +6,21 @@ config SOLUTION_ENGINE config SH_ALPHA_BOARD bool +config SH_DEVICE_TREE + bool "Board Described by Device Tree" + select OF + select OF_EARLY_FLATTREE + select CLKSRC_OF + select GENERIC_CALIBRATE_DELAY + help + Select Board Described by Device Tree to build a kernel that + does not hard-code any board-specific knowledge but instead uses + a device tree blob provided by the boot-loader. You must enable + drivers for any hardware you want to use separately. At this + time, only boards based on the open-hardware J-Core processors + have sufficient driver coverage to use this option; do not + select it if you are using original SuperH hardware. + config SH_SOLUTION_ENGINE bool "SolutionEngine" select SOLUTION_ENGINE diff --git a/arch/sh/boards/Makefile b/arch/sh/boards/Makefile index 975a0f64ff20a5691cfbd9b5f71a8bfb2c9ad7c6..cea300362035b38794932962e030c02f061b455d 100644 --- a/arch/sh/boards/Makefile +++ b/arch/sh/boards/Makefile @@ -15,3 +15,5 @@ obj-$(CONFIG_SH_TITAN) += board-titan.o obj-$(CONFIG_SH_SH7757LCR) += board-sh7757lcr.o obj-$(CONFIG_SH_APSH4A3A) += board-apsh4a3a.o obj-$(CONFIG_SH_APSH4AD0A) += board-apsh4ad0a.o + +obj-$(CONFIG_SH_DEVICE_TREE) += of-generic.o diff --git a/arch/sh/boards/of-generic.c b/arch/sh/boards/of-generic.c new file mode 100644 index 0000000000000000000000000000000000000000..bf3a166a5407f5daaaf008fdf86392390fa4e86d --- /dev/null +++ b/arch/sh/boards/of-generic.c @@ -0,0 +1,196 @@ +/* + * SH generic board support, using device tree + * + * Copyright (C) 2015-2016 Smart Energy Instruments, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_SMP + +static void dummy_smp_setup(void) +{ +} + +static void dummy_prepare_cpus(unsigned int max_cpus) +{ +} + +static void dummy_start_cpu(unsigned int cpu, unsigned long entry_point) +{ +} + +static unsigned int dummy_smp_processor_id(void) +{ + return 0; +} + +static void dummy_send_ipi(unsigned int cpu, unsigned int message) +{ +} + +static struct plat_smp_ops dummy_smp_ops = { + .smp_setup = dummy_smp_setup, + .prepare_cpus = dummy_prepare_cpus, + .start_cpu = dummy_start_cpu, + .smp_processor_id = dummy_smp_processor_id, + .send_ipi = dummy_send_ipi, + .cpu_die = native_cpu_die, + .cpu_disable = native_cpu_disable, + .play_dead = native_play_dead, +}; + +extern const struct of_cpu_method __cpu_method_of_table[]; +const struct of_cpu_method __cpu_method_of_table_sentinel + __section(__cpu_method_of_table_end); + +static void sh_of_smp_probe(void) +{ + struct device_node *np = 0; + const char *method = 0; + const struct of_cpu_method *m = __cpu_method_of_table; + + pr_info("SH generic board support: scanning for cpus\n"); + + init_cpu_possible(cpumask_of(0)); + + while ((np = of_find_node_by_type(np, "cpu"))) { + const __be32 *cell = of_get_property(np, "reg", NULL); + u64 id = -1; + if (cell) id = of_read_number(cell, of_n_addr_cells(np)); + if (id < NR_CPUS) { + if (!method) + of_property_read_string(np, "enable-method", &method); + set_cpu_possible(id, true); + set_cpu_present(id, true); + __cpu_number_map[id] = id; + __cpu_logical_map[id] = id; + } + } + if (!method) { + np = of_find_node_by_name(NULL, "cpus"); + of_property_read_string(np, "enable-method", &method); + } + + pr_info("CPU enable method: %s\n", method); + if (method) + for (; m->method; m++) + if (!strcmp(m->method, method)) { + register_smp_ops(m->ops); + return; + } + + register_smp_ops(&dummy_smp_ops); +} + +#else + +static void sh_of_smp_probe(void) +{ +} + +#endif + +static void noop(void) +{ +} + +static int noopi(void) +{ + return 0; +} + +static void __init sh_of_mem_reserve(void) +{ + early_init_fdt_reserve_self(); + early_init_fdt_scan_reserved_mem(); +} + +static void __init sh_of_time_init(void) +{ + pr_info("SH generic board support: scanning for clocksource devices\n"); + clocksource_probe(); +} + +static void __init sh_of_setup(char **cmdline_p) +{ + unflatten_device_tree(); + + board_time_init = sh_of_time_init; + + sh_mv.mv_name = of_flat_dt_get_machine_name(); + if (!sh_mv.mv_name) + sh_mv.mv_name = "Unknown SH model"; + + sh_of_smp_probe(); +} + +static int sh_of_irq_demux(int irq) +{ + /* FIXME: eventually this should not be used at all; + * the interrupt controller should set_handle_irq(). */ + return irq; +} + +static void __init sh_of_init_irq(void) +{ + pr_info("SH generic board support: scanning for interrupt controllers\n"); + irqchip_init(); +} + +static int __init sh_of_clk_init(void) +{ +#ifdef CONFIG_COMMON_CLK + /* Disabled pending move to COMMON_CLK framework. */ + pr_info("SH generic board support: scanning for clk providers\n"); + of_clk_init(NULL); +#endif + return 0; +} + +static struct sh_machine_vector __initmv sh_of_generic_mv = { + .mv_setup = sh_of_setup, + .mv_name = "devicetree", /* replaced by DT root's model */ + .mv_irq_demux = sh_of_irq_demux, + .mv_init_irq = sh_of_init_irq, + .mv_clk_init = sh_of_clk_init, + .mv_mode_pins = noopi, + .mv_mem_init = noop, + .mv_mem_reserve = sh_of_mem_reserve, +}; + +struct sh_clk_ops; + +void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx) +{ +} + +void __init plat_irq_setup(void) +{ +} + +static int __init sh_of_device_init(void) +{ + pr_info("SH generic board support: populating platform devices\n"); + if (of_have_populated_dt()) { + of_iommu_init(); + of_platform_populate(NULL, of_default_bus_match_table, + NULL, NULL); + } else { + pr_crit("Device tree not populated\n"); + } + return 0; +} +arch_initcall_sync(sh_of_device_init); diff --git a/arch/sh/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile index 23bc849d9c64a2274924cbab5f29462c22402103..6df826ee731637489410f247f48d21d3d9a87189 100644 --- a/arch/sh/boot/compressed/Makefile +++ b/arch/sh/boot/compressed/Makefile @@ -48,7 +48,7 @@ ifeq ($(BITS),64) lib1funcs-dir := $(addsuffix $(BITS), $(lib1funcs-dir)) endif -KBUILD_CFLAGS += -I$(lib1funcs-dir) +KBUILD_CFLAGS += -I$(lib1funcs-dir) -DDISABLE_BRANCH_PROFILING $(addprefix $(obj)/,$(lib1funcs-y)): $(obj)/%: $(lib1funcs-dir)/% FORCE $(call cmd,shipped) diff --git a/arch/sh/include/asm/Kbuild b/arch/sh/include/asm/Kbuild index aac452b26aa896a00cd59c65977739ed078d9201..a319745a7b635e16561fe33a061486372abf2004 100644 --- a/arch/sh/include/asm/Kbuild +++ b/arch/sh/include/asm/Kbuild @@ -1,5 +1,6 @@ generic-y += bitsperlong.h +generic-y += clkdev.h generic-y += cputime.h generic-y += current.h generic-y += delay.h diff --git a/arch/sh/include/asm/checksum_32.h b/arch/sh/include/asm/checksum_32.h index 14b7ac2f0a07a7e187fed823712ac74319785a65..9c84386d35cba988f95bc6d2c80b558cbc99ad9a 100644 --- a/arch/sh/include/asm/checksum_32.h +++ b/arch/sh/include/asm/checksum_32.h @@ -115,8 +115,7 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) } static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, + __u32 len, __u8 proto, __wsum sum) { #ifdef __LITTLE_ENDIAN__ @@ -142,8 +141,7 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, * returns a 16-bit checksum, already complemented */ static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, + __u32 len, __u8 proto, __wsum sum) { return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum)); @@ -161,8 +159,7 @@ static inline __sum16 ip_compute_csum(const void *buff, int len) #define _HAVE_ARCH_IPV6_CSUM static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, - __u32 len, unsigned short proto, - __wsum sum) + __u32 len, __u8 proto, __wsum sum) { unsigned int __dummy; __asm__("clrt\n\t" diff --git a/arch/sh/include/asm/clkdev.h b/arch/sh/include/asm/clkdev.h deleted file mode 100644 index c41901465fb065f702083781d34b4c187473151d..0000000000000000000000000000000000000000 --- a/arch/sh/include/asm/clkdev.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2010 Paul Mundt - * - * 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. - * - * Helper for the clk API to assist looking up a struct clk. - */ - -#ifndef __CLKDEV__H_ -#define __CLKDEV__H_ - -#include -#include -#include - -#include - -static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size) -{ - if (!slab_is_available()) - return alloc_bootmem_low_pages(size); - else - return kzalloc(size, GFP_KERNEL); -} - -#ifndef CONFIG_COMMON_CLK -#define __clk_put(clk) -#define __clk_get(clk) ({ 1; }) -#endif - -#endif /* __CLKDEV_H__ */ diff --git a/arch/sh/include/asm/smp.h b/arch/sh/include/asm/smp.h index 78b0d0f4b24b24ca07b186bc2bfbd475e99863a6..1baf0ba962426f8e92b6789aabacaf5c47787014 100644 --- a/arch/sh/include/asm/smp.h +++ b/arch/sh/include/asm/smp.h @@ -69,6 +69,16 @@ static inline int hard_smp_processor_id(void) return mp_ops->smp_processor_id(); } +struct of_cpu_method { + const char *method; + struct plat_smp_ops *ops; +}; + +#define CPU_METHOD_OF_DECLARE(name, _method, _ops) \ + static const struct of_cpu_method __cpu_method_of_table_##name \ + __used __section(__cpu_method_of_table) \ + = { .method = _method, .ops = _ops } + #else #define hard_smp_processor_id() (0) diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile index 2ccf36c824c65ff6bd97fd0fe65e65d12999f124..09040fd07d2ef61c36e1178d069b538b7efaa254 100644 --- a/arch/sh/kernel/Makefile +++ b/arch/sh/kernel/Makefile @@ -46,6 +46,5 @@ obj-$(CONFIG_DWARF_UNWINDER) += dwarf.o obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_callchain.o obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o -obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o ccflags-y := -Werror diff --git a/arch/sh/kernel/cpu/sh2/entry.S b/arch/sh/kernel/cpu/sh2/entry.S index c8a4331d9b8d7398e98df914178bb6ed4aed1eb9..a1505956ef28b4f0fd694cc4d1c609281b782811 100644 --- a/arch/sh/kernel/cpu/sh2/entry.S +++ b/arch/sh/kernel/cpu/sh2/entry.S @@ -144,9 +144,9 @@ ENTRY(exception_handler) mov #64,r8 cmp/hs r8,r9 bt interrupt_entry ! vec >= 64 is interrupt - mov #32,r8 + mov #31,r8 cmp/hs r8,r9 - bt trap_entry ! 64 > vec >= 32 is trap + bt trap_entry ! 64 > vec >= 31 is trap mov.l 4f,r8 mov r9,r4 @@ -178,9 +178,9 @@ interrupt_entry: trap_entry: mov #0x30,r8 - cmp/ge r8,r9 ! vector 0x20-0x2f is systemcall + cmp/ge r8,r9 ! vector 0x1f-0x2f is systemcall bt 1f - add #-0x10,r9 ! convert SH2 to SH3/4 ABI + mov #0x1f,r9 ! convert to unified SH2/3/4 trap number 1: shll2 r9 ! TRA bra system_call ! jump common systemcall entry diff --git a/arch/sh/kernel/cpu/sh2a/entry.S b/arch/sh/kernel/cpu/sh2a/entry.S index 222742ddc0d6a656ae16b3e5eb9ae5ba0ddb3691..da77a8ef4696e2dacb7e4bbf9bb4ccac8139c7a1 100644 --- a/arch/sh/kernel/cpu/sh2a/entry.S +++ b/arch/sh/kernel/cpu/sh2a/entry.S @@ -109,9 +109,9 @@ ENTRY(exception_handler) mov #64,r8 cmp/hs r8,r9 bt interrupt_entry ! vec >= 64 is interrupt - mov #32,r8 + mov #31,r8 cmp/hs r8,r9 - bt trap_entry ! 64 > vec >= 32 is trap + bt trap_entry ! 64 > vec >= 31 is trap mov.l 4f,r8 mov r9,r4 @@ -143,9 +143,9 @@ interrupt_entry: trap_entry: mov #0x30,r8 - cmp/ge r8,r9 ! vector 0x20-0x2f is systemcall + cmp/ge r8,r9 ! vector 0x1f-0x2f is systemcall bt 1f - add #-0x10,r9 ! convert SH2 to SH3/4 ABI + mov #0x1f,r9 ! convert to unified SH2/3/4 trap number 1: shll2 r9 ! TRA bra system_call ! jump common systemcall entry diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S index 13047a4facd2eb442866d751dc0c84fa35062063..c001f782c5f1c6320c89011d1bc3627f10bfb3ea 100644 --- a/arch/sh/kernel/entry-common.S +++ b/arch/sh/kernel/entry-common.S @@ -268,20 +268,29 @@ debug_trap: * Syscall #: R3 * Arguments #0 to #3: R4--R7 * Arguments #4 to #6: R0, R1, R2 - * TRA: (number of arguments + ABI revision) x 4 + * TRA: See following table. * - * This code also handles delegating other traps to the BIOS/gdb stub - * according to: - * - * Trap number * (TRA>>2) Purpose * -------- ------- * 0x00-0x0f original SH-3/4 syscall ABI (not in general use). * 0x10-0x1f general SH-3/4 syscall ABI. - * 0x20-0x2f syscall ABI for SH-2 parts. + * 0x1f unified SH-2/3/4 syscall ABI (preferred). + * 0x20-0x2f original SH-2 syscall ABI. * 0x30-0x3f debug traps used by the kernel. * 0x40-0xff Not supported by all parts, so left unhandled. * + * For making system calls, any trap number in the range for the + * given cpu model may be used, but the unified trap number 0x1f is + * preferred for compatibility with all models. + * + * The low bits of the trap number were once documented as matching + * the number of arguments, but they were never actually used as such + * by the kernel. SH-2 originally used its own separate trap range + * because several hardware exceptions fell in the range used for the + * SH-3/4 syscall ABI. + * + * This code also handles delegating other traps to the BIOS/gdb stub. + * * Note: When we're first called, the TRA value must be shifted * right 2 bits in order to get the value that was used as the "trapa" * argument. diff --git a/arch/sh/kernel/head_32.S b/arch/sh/kernel/head_32.S index 7db248936b60ef7ca6639fc3420612b0c22d06d3..974bc152cc8432163e5e47b27570f81e364672e1 100644 --- a/arch/sh/kernel/head_32.S +++ b/arch/sh/kernel/head_32.S @@ -66,6 +66,10 @@ ENTRY(_stext) mov #0, r0 ldc r0, r6_bank #endif + +#ifdef CONFIG_OF + mov r4, r12 ! Store device tree blob pointer in r12 +#endif /* * Prefetch if possible to reduce cache miss penalty. @@ -314,6 +318,12 @@ ENTRY(_stext) 10: #endif +#ifdef CONFIG_OF + mov.l 8f, r0 ! Make flat device tree available early. + jsr @r0 + mov r12, r4 +#endif + ! Additional CPU initialization mov.l 6f, r0 jsr @r0 @@ -339,6 +349,9 @@ ENTRY(stack_start) 5: .long start_kernel 6: .long cpu_init 7: .long init_thread_union +#if defined(CONFIG_OF) +8: .long sh_fdt_init +#endif #ifdef CONFIG_PMB .LPMB_ADDR: .long PMB_ADDR diff --git a/arch/sh/kernel/localtimer.c b/arch/sh/kernel/localtimer.c deleted file mode 100644 index cbb7d4636ec0a37b52e4873e5c073a1b487f0e3d..0000000000000000000000000000000000000000 --- a/arch/sh/kernel/localtimer.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Dummy local timer - * - * Copyright (C) 2008 Paul Mundt - * - * cloned from: - * - * linux/arch/arm/mach-realview/localtimer.c - * - * Copyright (C) 2002 ARM Ltd. - * All Rights Reserved - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static DEFINE_PER_CPU(struct clock_event_device, local_clockevent); - -/* - * Used on SMP for either the local timer or SMP_MSG_TIMER - */ -void local_timer_interrupt(void) -{ - struct clock_event_device *clk = this_cpu_ptr(&local_clockevent); - - irq_enter(); - clk->event_handler(clk); - irq_exit(); -} - -void local_timer_setup(unsigned int cpu) -{ - struct clock_event_device *clk = &per_cpu(local_clockevent, cpu); - - clk->name = "dummy_timer"; - clk->features = CLOCK_EVT_FEAT_ONESHOT | - CLOCK_EVT_FEAT_PERIODIC | - CLOCK_EVT_FEAT_DUMMY; - clk->rating = 400; - clk->mult = 1; - clk->broadcast = smp_timer_broadcast; - clk->cpumask = cpumask_of(cpu); - - clockevents_register_device(clk); -} - -void local_timer_stop(unsigned int cpu) -{ -} diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 3f1c18b28e8af5fc414c13ebeb29ccbf04cd63a5..5d34605b58b5d6b01e3b444fe349b243c2e397f9 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -29,6 +29,8 @@ #include #include #include +#include +#include #include #include #include @@ -172,6 +174,7 @@ void __init check_for_initrd(void) #endif } +#ifndef CONFIG_GENERIC_CALIBRATE_DELAY void calibrate_delay(void) { struct clk *clk = clk_get(NULL, "cpu_clk"); @@ -187,6 +190,7 @@ void calibrate_delay(void) (loops_per_jiffy/(5000/HZ)) % 100, loops_per_jiffy); } +#endif void __init __add_active_range(unsigned int nid, unsigned long start_pfn, unsigned long end_pfn) @@ -238,6 +242,29 @@ void __init __weak plat_early_device_setup(void) { } +#ifdef CONFIG_OF +void __ref sh_fdt_init(phys_addr_t dt_phys) +{ + static int done = 0; + void *dt_virt; + + /* Avoid calling an __init function on secondary cpus. */ + if (done) return; + + dt_virt = phys_to_virt(dt_phys); + + if (!dt_virt || !early_init_dt_scan(dt_virt)) { + pr_crit("Error: invalid device tree blob" + " at physical address %p\n", (void *)dt_phys); + + while (true) + cpu_relax(); + } + + done = 1; +} +#endif + void __init setup_arch(char **cmdline_p) { enable_mmu(); diff --git a/arch/sh/kernel/sh_ksyms_32.c b/arch/sh/kernel/sh_ksyms_32.c index d77f2f6c7ff0761de1b51f09eb8926923c817681..0b30b9dfc87f22ae20a9d5355a2f5cc15e4ed03e 100644 --- a/arch/sh/kernel/sh_ksyms_32.c +++ b/arch/sh/kernel/sh_ksyms_32.c @@ -34,6 +34,9 @@ DECLARE_EXPORT(__sdivsi3); DECLARE_EXPORT(__lshrsi3); DECLARE_EXPORT(__ashrsi3); DECLARE_EXPORT(__ashlsi3); +DECLARE_EXPORT(__lshrsi3_r0); +DECLARE_EXPORT(__ashrsi3_r0); +DECLARE_EXPORT(__ashlsi3_r0); DECLARE_EXPORT(__ashiftrt_r4_6); DECLARE_EXPORT(__ashiftrt_r4_7); DECLARE_EXPORT(__ashiftrt_r4_8); diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c index 13f633add29ac46f21850400d63e6dafdc3d63c8..38e7860845db1e37f7519881337a5161f59afdfd 100644 --- a/arch/sh/kernel/smp.c +++ b/arch/sh/kernel/smp.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -140,17 +141,14 @@ int __cpu_disable(void) */ migrate_irqs(); - /* - * Stop the local timer for this CPU. - */ - local_timer_stop(cpu); - /* * Flush user cache and TLB mappings, and then remove this CPU * from the vm mask set of all processes. */ flush_cache_all(); +#ifdef CONFIG_MMU local_flush_tlb_all(); +#endif clear_tasks_mm_cpumask(cpu); @@ -183,8 +181,10 @@ asmlinkage void start_secondary(void) atomic_inc(&mm->mm_count); atomic_inc(&mm->mm_users); current->active_mm = mm; +#ifdef CONFIG_MMU enter_lazy_tlb(mm, current); local_flush_tlb_all(); +#endif per_cpu_trap_init(); @@ -194,8 +194,6 @@ asmlinkage void start_secondary(void) local_irq_enable(); - /* Enable local timers */ - local_timer_setup(cpu); calibrate_delay(); smp_store_cpu_info(cpu); @@ -285,7 +283,8 @@ void arch_send_call_function_single_ipi(int cpu) mp_ops->send_ipi(cpu, SMP_MSG_FUNCTION_SINGLE); } -void smp_timer_broadcast(const struct cpumask *mask) +#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST +void tick_broadcast(const struct cpumask *mask) { int cpu; @@ -296,9 +295,10 @@ void smp_timer_broadcast(const struct cpumask *mask) static void ipi_timer(void) { irq_enter(); - local_timer_interrupt(); + tick_receive_broadcast(); irq_exit(); } +#endif void smp_message_recv(unsigned int msg) { @@ -312,9 +312,11 @@ void smp_message_recv(unsigned int msg) case SMP_MSG_FUNCTION_SINGLE: generic_smp_call_function_single_interrupt(); break; +#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST case SMP_MSG_TIMER: ipi_timer(); break; +#endif default: printk(KERN_WARNING "SMP %d: %s(): unknown IPI %d\n", smp_processor_id(), __func__, msg); @@ -328,6 +330,8 @@ int setup_profiling_timer(unsigned int multiplier) return 0; } +#ifdef CONFIG_MMU + static void flush_tlb_all_ipi(void *info) { local_flush_tlb_all(); @@ -467,3 +471,5 @@ void flush_tlb_one(unsigned long asid, unsigned long vaddr) smp_call_function(flush_tlb_one_ipi, (void *)&fd, 1); local_flush_tlb_one(asid, vaddr); } + +#endif diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S index db88cbf9eafdc815d76d72784c18e4df42b361e5..235a4101999fe5a4462bd5ec1d78cba49eb49b90 100644 --- a/arch/sh/kernel/vmlinux.lds.S +++ b/arch/sh/kernel/vmlinux.lds.S @@ -39,6 +39,7 @@ SECTIONS LOCK_TEXT KPROBES_TEXT IRQENTRY_TEXT + SOFTIRQENTRY_TEXT *(.fixup) *(.gnu.warning) _etext = .; /* End of text section */ diff --git a/arch/sh/lib/ashlsi3.S b/arch/sh/lib/ashlsi3.S index bd47e9b403a5bc605fa3b424c5001269ab519e3c..70a6434945ab8acf084c166c4c21cb457334617b 100644 --- a/arch/sh/lib/ashlsi3.S +++ b/arch/sh/lib/ashlsi3.S @@ -54,21 +54,38 @@ Boston, MA 02110-1301, USA. */ ! ! (none) ! +! __ashlsi3_r0 +! +! Entry: +! +! r4: Value to shift +! r0: Shifts +! +! Exit: +! +! r0: Result +! +! Destroys: +! +! (none) + + .global __ashlsi3 + .global __ashlsi3_r0 .align 2 __ashlsi3: - mov #31,r0 - and r0,r5 + mov r5,r0 + .align 2 +__ashlsi3_r0: + and #31,r0 + mov.l r4,@-r15 + mov r0,r4 mova ashlsi3_table,r0 - mov.b @(r0,r5),r5 -#ifdef __sh1__ - add r5,r0 + mov.b @(r0,r4),r4 + add r4,r0 jmp @r0 -#else - braf r5 -#endif - mov r4,r0 + mov.l @r15+,r0 .align 2 ashlsi3_table: diff --git a/arch/sh/lib/ashrsi3.S b/arch/sh/lib/ashrsi3.S index 6f3cf46b77c2c1cac502030cb3a0c7a8acdb1308..602599d80209114bfc2de066f2f0e74459fc5648 100644 --- a/arch/sh/lib/ashrsi3.S +++ b/arch/sh/lib/ashrsi3.S @@ -54,22 +54,37 @@ Boston, MA 02110-1301, USA. */ ! ! (none) ! +! __ashrsi3_r0 +! +! Entry: +! +! r4: Value to shift +! r0: Shifts +! +! Exit: +! +! r0: Result +! +! Destroys: +! +! (none) .global __ashrsi3 + .global __ashrsi3_r0 .align 2 __ashrsi3: - mov #31,r0 - and r0,r5 + mov r5,r0 + .align 2 +__ashrsi3_r0: + and #31,r0 + mov.l r4,@-r15 + mov r0,r4 mova ashrsi3_table,r0 - mov.b @(r0,r5),r5 -#ifdef __sh1__ - add r5,r0 + mov.b @(r0,r4),r4 + add r4,r0 jmp @r0 -#else - braf r5 -#endif - mov r4,r0 + mov.l @r15+,r0 .align 2 ashrsi3_table: diff --git a/arch/sh/lib/lshrsi3.S b/arch/sh/lib/lshrsi3.S index 1e7aaa55713035f8d9ba8c5a4e08adfe1268265d..f2a6959f526d30bcda3c7ed0b0eab2d7975aa2b1 100644 --- a/arch/sh/lib/lshrsi3.S +++ b/arch/sh/lib/lshrsi3.S @@ -53,22 +53,38 @@ Boston, MA 02110-1301, USA. */ ! Destroys: ! ! (none) +! +! __lshrsi3_r0 +! +! Entry: +! +! r0: Value to shift +! r5: Shifts +! +! Exit: +! +! r0: Result +! +! Destroys: +! +! (none) ! .global __lshrsi3 + .global __lshrsi3_r0 .align 2 __lshrsi3: - mov #31,r0 - and r0,r5 + mov r5,r0 + .align 2 +__lshrsi3_r0: + and #31,r0 + mov.l r4,@-r15 + mov r0,r4 mova lshrsi3_table,r0 - mov.b @(r0,r5),r5 -#ifdef __sh1__ - add r5,r0 + mov.b @(r0,r4),r4 + add r4,r0 jmp @r0 -#else - braf r5 -#endif - mov r4,r0 + mov.l @r15+,r0 .align 2 lshrsi3_table: diff --git a/arch/sh/mm/gup.c b/arch/sh/mm/gup.c index e7af6a65baab915552ae405a16d3bd405b84f763..40fa6c8adc43a361c60ffee8929aa39d2449e926 100644 --- a/arch/sh/mm/gup.c +++ b/arch/sh/mm/gup.c @@ -257,7 +257,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, start += nr << PAGE_SHIFT; pages += nr; - ret = get_user_pages_unlocked(current, mm, start, + ret = get_user_pages_unlocked(start, (end - start) >> PAGE_SHIFT, write, 0, pages); /* Have to be a bit careful with return values */ diff --git a/arch/sh/mm/hugetlbpage.c b/arch/sh/mm/hugetlbpage.c index 6385f60209b65adefc2bbbcc8e5309a5d574455d..cc948db74878045bdcfeeed4c17d821098f0c3fa 100644 --- a/arch/sh/mm/hugetlbpage.c +++ b/arch/sh/mm/hugetlbpage.c @@ -35,7 +35,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, if (pud) { pmd = pmd_alloc(mm, pud, addr); if (pmd) - pte = pte_alloc_map(mm, NULL, pmd, addr); + pte = pte_alloc_map(mm, pmd, addr); } } diff --git a/arch/sh/mm/kmap.c b/arch/sh/mm/kmap.c index ec29e14ec5a85643b600952b3140f013ada5d258..bf25d7c79a2d82d5dd6b26ca95b79a72643f2791 100644 --- a/arch/sh/mm/kmap.c +++ b/arch/sh/mm/kmap.c @@ -36,6 +36,7 @@ void *kmap_coherent(struct page *page, unsigned long addr) BUG_ON(!test_bit(PG_dcache_clean, &page->flags)); + preempt_disable(); pagefault_disable(); idx = FIX_CMAP_END - @@ -64,4 +65,5 @@ void kunmap_coherent(void *kvaddr) } pagefault_enable(); + preempt_enable(); } diff --git a/arch/sparc/configs/sparc64_defconfig b/arch/sparc/configs/sparc64_defconfig index 6b68f12f29db4615fe36569b0e4d9d9fe30229be..04920ab8e292b75a99986b1a2d10ac6273e2db94 100644 --- a/arch/sparc/configs/sparc64_defconfig +++ b/arch/sparc/configs/sparc64_defconfig @@ -102,6 +102,7 @@ CONFIG_SUNLANCE=m CONFIG_HAPPYMEAL=m CONFIG_SUNGEM=m CONFIG_SUNVNET=m +CONFIG_LDMVSW=m CONFIG_NET_PCI=y CONFIG_E1000=m CONFIG_E1000E=m diff --git a/arch/sparc/include/asm/checksum_32.h b/arch/sparc/include/asm/checksum_32.h index 426b2389a1c29fe83b16a0a84b7f262f055a2c74..eff748c871ec372009111d9fbf2f20701ce1e04f 100644 --- a/arch/sparc/include/asm/checksum_32.h +++ b/arch/sparc/include/asm/checksum_32.h @@ -170,9 +170,8 @@ static inline __sum16 csum_fold(__wsum sum) } static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum) + __u32 len, __u8 proto, + __wsum sum) { __asm__ __volatile__("addcc\t%1, %0, %0\n\t" "addxcc\t%2, %0, %0\n\t" @@ -190,9 +189,8 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, * returns a 16-bit checksum, already complemented */ static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum) + __u32 len, __u8 proto, + __wsum sum) { return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); } @@ -201,8 +199,7 @@ static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, - __u32 len, unsigned short proto, - __wsum sum) + __u32 len, __u8 proto, __wsum sum) { __asm__ __volatile__ ( "addcc %3, %4, %%g4\n\t" diff --git a/arch/sparc/include/asm/checksum_64.h b/arch/sparc/include/asm/checksum_64.h index b8779a6a59117d13c51eeb0965e78f6a635299a8..0395d75322e9640cda2a2de4d77fe8c980b6ca7a 100644 --- a/arch/sparc/include/asm/checksum_64.h +++ b/arch/sparc/include/asm/checksum_64.h @@ -96,8 +96,7 @@ static inline __sum16 csum_fold(__wsum sum) } static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, - unsigned int len, - unsigned short proto, + __u32 len, __u8 proto, __wsum sum) { __asm__ __volatile__( @@ -116,8 +115,7 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, * returns a 16-bit checksum, already complemented */ static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, + __u32 len, __u8 proto, __wsum sum) { return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); @@ -127,8 +125,7 @@ static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, - __u32 len, unsigned short proto, - __wsum sum) + __u32 len, __u8 proto, __wsum sum) { __asm__ __volatile__ ( " addcc %3, %4, %%g7\n" diff --git a/arch/sparc/include/asm/compat.h b/arch/sparc/include/asm/compat.h index 830502fe62b4e6a3d334abaf4076a5957deb2d9c..6f251c4d613efdb9857d85e1c58b7cdbb15e46b5 100644 --- a/arch/sparc/include/asm/compat.h +++ b/arch/sparc/include/asm/compat.h @@ -307,4 +307,11 @@ static inline int is_compat_task(void) return test_thread_flag(TIF_32BIT); } +static inline bool in_compat_syscall(void) +{ + /* Vector 0x110 is LINUX_32BIT_SYSCALL_TRAP */ + return pt_regs_trap_type(current_pt_regs()) == 0x110; +} +#define in_compat_syscall in_compat_syscall + #endif /* _ASM_SPARC64_COMPAT_H */ diff --git a/arch/sparc/include/asm/compat_signal.h b/arch/sparc/include/asm/compat_signal.h index 9ed1f128b4d1c0f562fb9cd67cc66beef6d17d67..4b027b1044fad6dcd44ec051173de59003f1a590 100644 --- a/arch/sparc/include/asm/compat_signal.h +++ b/arch/sparc/include/asm/compat_signal.h @@ -6,17 +6,17 @@ #ifdef CONFIG_COMPAT struct __new_sigaction32 { - unsigned sa_handler; + unsigned int sa_handler; unsigned int sa_flags; - unsigned sa_restorer; /* not used by Linux/SPARC yet */ + unsigned int sa_restorer; /* not used by Linux/SPARC yet */ compat_sigset_t sa_mask; }; struct __old_sigaction32 { - unsigned sa_handler; + unsigned int sa_handler; compat_old_sigset_t sa_mask; unsigned int sa_flags; - unsigned sa_restorer; /* not used by Linux/SPARC yet */ + unsigned int sa_restorer; /* not used by Linux/SPARC yet */ }; #endif diff --git a/arch/sparc/include/asm/obio.h b/arch/sparc/include/asm/obio.h index 910c1d9af1f80d8cf031f0f86970e94607dfe1aa..426ad75103fb5e3e3d0a0bd5f72d75d6936e3f6e 100644 --- a/arch/sparc/include/asm/obio.h +++ b/arch/sparc/include/asm/obio.h @@ -117,9 +117,9 @@ static inline void bw_clear_intr_mask(int sbus_level, int mask) "i" (ASI_M_CTL)); } -static inline unsigned bw_get_prof_limit(int cpu) +static inline unsigned int bw_get_prof_limit(int cpu) { - unsigned limit; + unsigned int limit; __asm__ __volatile__ ("lda [%1] %2, %0" : "=r" (limit) : @@ -128,7 +128,7 @@ static inline unsigned bw_get_prof_limit(int cpu) return limit; } -static inline void bw_set_prof_limit(int cpu, unsigned limit) +static inline void bw_set_prof_limit(int cpu, unsigned int limit) { __asm__ __volatile__ ("sta %0, [%1] %2" : : "r" (limit), @@ -136,9 +136,9 @@ static inline void bw_set_prof_limit(int cpu, unsigned limit) "i" (ASI_M_CTL)); } -static inline unsigned bw_get_ctrl(int cpu) +static inline unsigned int bw_get_ctrl(int cpu) { - unsigned ctrl; + unsigned int ctrl; __asm__ __volatile__ ("lda [%1] %2, %0" : "=r" (ctrl) : @@ -147,7 +147,7 @@ static inline unsigned bw_get_ctrl(int cpu) return ctrl; } -static inline void bw_set_ctrl(int cpu, unsigned ctrl) +static inline void bw_set_ctrl(int cpu, unsigned int ctrl) { __asm__ __volatile__ ("sta %0, [%1] %2" : : "r" (ctrl), @@ -155,9 +155,9 @@ static inline void bw_set_ctrl(int cpu, unsigned ctrl) "i" (ASI_M_CTL)); } -static inline unsigned cc_get_ipen(void) +static inline unsigned int cc_get_ipen(void) { - unsigned pending; + unsigned int pending; __asm__ __volatile__ ("lduha [%1] %2, %0" : "=r" (pending) : @@ -166,7 +166,7 @@ static inline unsigned cc_get_ipen(void) return pending; } -static inline void cc_set_iclr(unsigned clear) +static inline void cc_set_iclr(unsigned int clear) { __asm__ __volatile__ ("stha %0, [%1] %2" : : "r" (clear), @@ -174,9 +174,9 @@ static inline void cc_set_iclr(unsigned clear) "i" (ASI_M_MXCC)); } -static inline unsigned cc_get_imsk(void) +static inline unsigned int cc_get_imsk(void) { - unsigned mask; + unsigned int mask; __asm__ __volatile__ ("lduha [%1] %2, %0" : "=r" (mask) : @@ -185,7 +185,7 @@ static inline unsigned cc_get_imsk(void) return mask; } -static inline void cc_set_imsk(unsigned mask) +static inline void cc_set_imsk(unsigned int mask) { __asm__ __volatile__ ("stha %0, [%1] %2" : : "r" (mask), @@ -193,9 +193,9 @@ static inline void cc_set_imsk(unsigned mask) "i" (ASI_M_MXCC)); } -static inline unsigned cc_get_imsk_other(int cpuid) +static inline unsigned int cc_get_imsk_other(int cpuid) { - unsigned mask; + unsigned int mask; __asm__ __volatile__ ("lduha [%1] %2, %0" : "=r" (mask) : @@ -204,7 +204,7 @@ static inline unsigned cc_get_imsk_other(int cpuid) return mask; } -static inline void cc_set_imsk_other(int cpuid, unsigned mask) +static inline void cc_set_imsk_other(int cpuid, unsigned int mask) { __asm__ __volatile__ ("stha %0, [%1] %2" : : "r" (mask), @@ -212,7 +212,7 @@ static inline void cc_set_imsk_other(int cpuid, unsigned mask) "i" (ASI_M_CTL)); } -static inline void cc_set_igen(unsigned gen) +static inline void cc_set_igen(unsigned int gen) { __asm__ __volatile__ ("sta %0, [%1] %2" : : "r" (gen), diff --git a/arch/sparc/include/asm/openprom.h b/arch/sparc/include/asm/openprom.h index 47eaafad15ceb63c8de66a8ef573d8fed32a714d..63374c4413a859fcb55adb2404f95f094a82a172 100644 --- a/arch/sparc/include/asm/openprom.h +++ b/arch/sparc/include/asm/openprom.h @@ -29,12 +29,12 @@ struct linux_dev_v0_funcs { /* V2 and later prom device operations. */ struct linux_dev_v2_funcs { phandle (*v2_inst2pkg)(int d); /* Convert ihandle to phandle */ - char * (*v2_dumb_mem_alloc)(char *va, unsigned sz); - void (*v2_dumb_mem_free)(char *va, unsigned sz); + char * (*v2_dumb_mem_alloc)(char *va, unsigned int sz); + void (*v2_dumb_mem_free)(char *va, unsigned int sz); /* To map devices into virtual I/O space. */ - char * (*v2_dumb_mmap)(char *virta, int which_io, unsigned paddr, unsigned sz); - void (*v2_dumb_munmap)(char *virta, unsigned size); + char * (*v2_dumb_mmap)(char *virta, int which_io, unsigned int paddr, unsigned int sz); + void (*v2_dumb_munmap)(char *virta, unsigned int size); int (*v2_dev_open)(char *devpath); void (*v2_dev_close)(int d); @@ -50,7 +50,7 @@ struct linux_dev_v2_funcs { struct linux_mlist_v0 { struct linux_mlist_v0 *theres_more; unsigned int start_adr; - unsigned num_bytes; + unsigned int num_bytes; }; struct linux_mem_v0 { diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h index 7a38d6a576c5e2ea718deb632e63c0939e60c011..f089cfa249f335b419de702333ddc341e7e3acc3 100644 --- a/arch/sparc/include/asm/pgtable_64.h +++ b/arch/sparc/include/asm/pgtable_64.h @@ -218,7 +218,7 @@ extern pgprot_t PAGE_KERNEL_LOCKED; extern pgprot_t PAGE_COPY; extern pgprot_t PAGE_SHARED; -/* XXX This uglyness is for the atyfb driver's sparc mmap() support. XXX */ +/* XXX This ugliness is for the atyfb driver's sparc mmap() support. XXX */ extern unsigned long _PAGE_IE; extern unsigned long _PAGE_E; extern unsigned long _PAGE_CACHE; diff --git a/arch/sparc/include/asm/processor_64.h b/arch/sparc/include/asm/processor_64.h index 6924bdefe148451c584f0a6b183b8a23b92bae05..ce2595c894711367d36027dbe5db3324575596b3 100644 --- a/arch/sparc/include/asm/processor_64.h +++ b/arch/sparc/include/asm/processor_64.h @@ -201,7 +201,7 @@ unsigned long get_wchan(struct task_struct *task); #define KSTK_ESP(tsk) (task_pt_regs(tsk)->u_regs[UREG_FP]) /* Please see the commentary in asm/backoff.h for a description of - * what these instructions are doing and how they have been choosen. + * what these instructions are doing and how they have been chosen. * To make a long story short, we are trying to yield the current cpu * strand during busy loops. */ diff --git a/arch/sparc/include/asm/sigcontext.h b/arch/sparc/include/asm/sigcontext.h index fc2df1e892cbb196d7c62fd3695d65837d3a97cc..f4eb630a58ed49fe1032137dd11d773edd0de25a 100644 --- a/arch/sparc/include/asm/sigcontext.h +++ b/arch/sparc/include/asm/sigcontext.h @@ -25,7 +25,7 @@ struct sigcontext32 { int sigc_oswins; /* outstanding windows */ /* stack ptrs for each regwin buf */ - unsigned sigc_spbuf[__SUNOS_MAXWIN]; + unsigned int sigc_spbuf[__SUNOS_MAXWIN]; /* Windows to restore after signal */ struct reg_window32 sigc_wbuf[__SUNOS_MAXWIN]; diff --git a/arch/sparc/include/asm/syscall.h b/arch/sparc/include/asm/syscall.h index 49f71fd5b56ee83566895b0674dca3bd6c7057e5..1757cd6c521bcba1c9ded32f98bd60fd92c07909 100644 --- a/arch/sparc/include/asm/syscall.h +++ b/arch/sparc/include/asm/syscall.h @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -128,7 +129,13 @@ static inline void syscall_set_arguments(struct task_struct *task, static inline int syscall_get_arch(void) { - return is_32bit_task() ? AUDIT_ARCH_SPARC : AUDIT_ARCH_SPARC64; +#if defined(CONFIG_SPARC64) && defined(CONFIG_COMPAT) + return in_compat_syscall() ? AUDIT_ARCH_SPARC : AUDIT_ARCH_SPARC64; +#elif defined(CONFIG_SPARC64) + return AUDIT_ARCH_SPARC64; +#else + return AUDIT_ARCH_SPARC; +#endif } #endif /* __ASM_SPARC_SYSCALL_H */ diff --git a/arch/sparc/include/asm/tsb.h b/arch/sparc/include/asm/tsb.h index ecb49cfa3be9fa274053fb15bc2d5f3c38c76e08..c6a155c3904ece984d3075094e3ee8b55845a68f 100644 --- a/arch/sparc/include/asm/tsb.h +++ b/arch/sparc/include/asm/tsb.h @@ -149,7 +149,7 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; * page size in question. So for PMD mappings (which fall on * bit 23, for 8MB per PMD) we must propagate bit 22 for a * 4MB huge page. For huge PUDs (which fall on bit 33, for - * 8GB per PUD), we have to accomodate 256MB and 2GB huge + * 8GB per PUD), we have to accommodate 256MB and 2GB huge * pages. So for those we propagate bits 32 to 28. */ #define KERN_PGTABLE_WALK(VADDR, REG1, REG2, FAIL_LABEL) \ diff --git a/arch/sparc/include/uapi/asm/socket.h b/arch/sparc/include/uapi/asm/socket.h index d270ee91968e50ae1e527aea02eecb832e70d2d2..31aede3af088034934c4205f2ab3bf7003956370 100644 --- a/arch/sparc/include/uapi/asm/socket.h +++ b/arch/sparc/include/uapi/asm/socket.h @@ -84,6 +84,8 @@ #define SO_ATTACH_REUSEPORT_CBPF 0x0035 #define SO_ATTACH_REUSEPORT_EBPF 0x0036 +#define SO_CNX_ADVICE 0x0037 + /* Security levels - as per NRL IPv6 - don't actually do anything */ #define SO_SECURITY_AUTHENTICATION 0x5001 #define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002 diff --git a/arch/sparc/include/uapi/asm/stat.h b/arch/sparc/include/uapi/asm/stat.h index a232e9e1f4e515d19e8f089872a797c746241777..2f0583a2c689b3218af86171fc40c6f677149fdb 100644 --- a/arch/sparc/include/uapi/asm/stat.h +++ b/arch/sparc/include/uapi/asm/stat.h @@ -6,13 +6,13 @@ #if defined(__sparc__) && defined(__arch64__) /* 64 bit sparc */ struct stat { - unsigned st_dev; + unsigned int st_dev; ino_t st_ino; mode_t st_mode; short st_nlink; uid_t st_uid; gid_t st_gid; - unsigned st_rdev; + unsigned int st_rdev; off_t st_size; time_t st_atime; time_t st_mtime; diff --git a/arch/sparc/kernel/audit.c b/arch/sparc/kernel/audit.c index 24361b494a93529706d9f120dad2e05bcd3fd4c4..2585c1e14bccf672ec1082c79cc27f87c5cc31b3 100644 --- a/arch/sparc/kernel/audit.c +++ b/arch/sparc/kernel/audit.c @@ -5,27 +5,27 @@ #include "kernel.h" -static unsigned dir_class[] = { +static unsigned int dir_class[] = { #include ~0U }; -static unsigned read_class[] = { +static unsigned int read_class[] = { #include ~0U }; -static unsigned write_class[] = { +static unsigned int write_class[] = { #include ~0U }; -static unsigned chattr_class[] = { +static unsigned int chattr_class[] = { #include ~0U }; -static unsigned signal_class[] = { +static unsigned int signal_class[] = { #include ~0U }; @@ -39,7 +39,7 @@ int audit_classify_arch(int arch) return 0; } -int audit_classify_syscall(int abi, unsigned syscall) +int audit_classify_syscall(int abi, unsigned int syscall) { #ifdef CONFIG_COMPAT if (abi == AUDIT_ARCH_SPARC) diff --git a/arch/sparc/kernel/compat_audit.c b/arch/sparc/kernel/compat_audit.c index 7062263d09c19ca41727a6a9b8a4c7ecb5f42c6e..e5611cd428f111c4858eee3a2a9877293f2627c5 100644 --- a/arch/sparc/kernel/compat_audit.c +++ b/arch/sparc/kernel/compat_audit.c @@ -2,32 +2,32 @@ #include #include "kernel.h" -unsigned sparc32_dir_class[] = { +unsigned int sparc32_dir_class[] = { #include ~0U }; -unsigned sparc32_chattr_class[] = { +unsigned int sparc32_chattr_class[] = { #include ~0U }; -unsigned sparc32_write_class[] = { +unsigned int sparc32_write_class[] = { #include ~0U }; -unsigned sparc32_read_class[] = { +unsigned int sparc32_read_class[] = { #include ~0U }; -unsigned sparc32_signal_class[] = { +unsigned int sparc32_signal_class[] = { #include ~0U }; -int sparc32_classify_syscall(unsigned syscall) +int sparc32_classify_syscall(unsigned int syscall) { switch(syscall) { case __NR_open: diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index a83707c83be803b78b3019cac6dde9dba2cfabd6..51aa6e86a5f88f5f8e3fe144f0609679cf365d3d 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S @@ -1255,7 +1255,7 @@ flush_patch_exception: kuw_patch1_7win: sll %o3, 6, %o3 /* No matter how much overhead this routine has in the worst - * case scenerio, it is several times better than taking the + * case scenario, it is several times better than taking the * traps with the old method of just doing flush_user_windows(). */ kill_user_windows: diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index 28fed53b13a0d3f1c69be7aec07734b39a2fac92..ffd5ff4678cf59f54fa65fbf0e790636a34f116a 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c @@ -131,7 +131,7 @@ void __iomem *ioremap(unsigned long offset, unsigned long size) EXPORT_SYMBOL(ioremap); /* - * Comlimentary to ioremap(). + * Complementary to ioremap(). */ void iounmap(volatile void __iomem *virtual) { @@ -233,7 +233,7 @@ _sparc_ioremap(struct resource *res, u32 bus, u32 pa, int sz) } /* - * Comlimentary to _sparc_ioremap(). + * Complementary to _sparc_ioremap(). */ static void _sparc_free_io(struct resource *res) { @@ -532,7 +532,7 @@ static void pci32_unmap_page(struct device *dev, dma_addr_t ba, size_t size, } /* Map a set of buffers described by scatterlist in streaming - * mode for DMA. This is the scather-gather version of the + * mode for DMA. This is the scatter-gather version of the * above pci_map_single interface. Here the scatter gather list * elements are each tagged with the appropriate dma address * and length. They are obtained via sg_dma_{address,length}(SG). diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h index e7f652be9e61efee4ff9b64418ad17ac6a3eca63..5057ec2e4af65201fb3acea5f1d648c8dbad85a0 100644 --- a/arch/sparc/kernel/kernel.h +++ b/arch/sparc/kernel/kernel.h @@ -54,12 +54,12 @@ void do_signal32(struct pt_regs * regs); asmlinkage int do_sys32_sigstack(u32 u_ssptr, u32 u_ossptr, unsigned long sp); /* compat_audit.c */ -extern unsigned sparc32_dir_class[]; -extern unsigned sparc32_chattr_class[]; -extern unsigned sparc32_write_class[]; -extern unsigned sparc32_read_class[]; -extern unsigned sparc32_signal_class[]; -int sparc32_classify_syscall(unsigned syscall); +extern unsigned int sparc32_dir_class[]; +extern unsigned int sparc32_chattr_class[]; +extern unsigned int sparc32_write_class[]; +extern unsigned int sparc32_read_class[]; +extern unsigned int sparc32_signal_class[]; +int sparc32_classify_syscall(unsigned int syscall); #endif #ifdef CONFIG_SPARC32 diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c index 42efcf85f721b17196f88810fa52f82b0d24bf0d..33cd171d933ee996d2156d43b18beabe090c3eb6 100644 --- a/arch/sparc/kernel/leon_kernel.c +++ b/arch/sparc/kernel/leon_kernel.c @@ -203,7 +203,7 @@ static struct irq_chip leon_irq = { /* * Build a LEON IRQ for the edge triggered LEON IRQ controller: - * Edge (normal) IRQ - handle_simple_irq, ack=DONT-CARE, never ack + * Edge (normal) IRQ - handle_simple_irq, ack=DON'T-CARE, never ack * Level IRQ (PCI|Level-GPIO) - handle_fasteoi_irq, ack=1, ack after ISR * Per-CPU Edge - handle_percpu_irq, ack=0 */ diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c index 46a59643bb1cee71edbd3d91d3f8f2eb09b3a26a..c16ef1af1843cffaf8488c9991b72a0f48cfedac 100644 --- a/arch/sparc/kernel/process_64.c +++ b/arch/sparc/kernel/process_64.c @@ -103,7 +103,7 @@ static void show_regwindow32(struct pt_regs *regs) mm_segment_t old_fs; __asm__ __volatile__ ("flushw"); - rw = compat_ptr((unsigned)regs->u_regs[14]); + rw = compat_ptr((unsigned int)regs->u_regs[14]); old_fs = get_fs(); set_fs (USER_DS); if (copy_from_user (&r_w, rw, sizeof(r_w))) { diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c index baef495c06bdb081c0744a33f0e9564bd125a1eb..69d75ff1c25c3a473b1876ae63c2327b72cd861d 100644 --- a/arch/sparc/kernel/setup_32.c +++ b/arch/sparc/kernel/setup_32.c @@ -109,7 +109,7 @@ unsigned long cmdline_memory_size __initdata = 0; unsigned char boot_cpu_id = 0xff; /* 0xff will make it into DATA section... */ static void -prom_console_write(struct console *con, const char *s, unsigned n) +prom_console_write(struct console *con, const char *s, unsigned int n) { prom_write(s, n); } diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c index f3185e2b028b86886a2a185faee9d99fa5c5c47f..26db95b54ee94c44537590a1b94a4870bd9227ce 100644 --- a/arch/sparc/kernel/setup_64.c +++ b/arch/sparc/kernel/setup_64.c @@ -77,7 +77,7 @@ struct screen_info screen_info = { }; static void -prom_console_write(struct console *con, const char *s, unsigned n) +prom_console_write(struct console *con, const char *s, unsigned int n) { prom_write(s, n); } diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c index 4eed773a77358b718b5e0134a56eff5b9be75772..3c25241fa5cbd416ca5f95bff873c72c609a6a10 100644 --- a/arch/sparc/kernel/signal32.c +++ b/arch/sparc/kernel/signal32.c @@ -144,7 +144,7 @@ void do_sigreturn32(struct pt_regs *regs) compat_uptr_t fpu_save; compat_uptr_t rwin_save; unsigned int psr; - unsigned pc, npc; + unsigned int pc, npc; sigset_t set; compat_sigset_t seta; int err, i; diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index b489e9759518182b6a3884935e5a1c22b1af3524..fe8b8ee8e6602307bebf6813704146da7d9bc30e 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c @@ -337,10 +337,10 @@ SYSCALL_DEFINE6(sparc_ipc, unsigned int, call, int, first, unsigned long, second switch (call) { case SEMOP: err = sys_semtimedop(first, ptr, - (unsigned)second, NULL); + (unsigned int)second, NULL); goto out; case SEMTIMEDOP: - err = sys_semtimedop(first, ptr, (unsigned)second, + err = sys_semtimedop(first, ptr, (unsigned int)second, (const struct timespec __user *) (unsigned long) fifth); goto out; diff --git a/arch/sparc/kernel/sysfs.c b/arch/sparc/kernel/sysfs.c index 7f41d40b7e6e8ccf89b5ce12a9422bbf4e84ac2e..fa8e21abb5e0359ed5c34bf537b6949ca8510942 100644 --- a/arch/sparc/kernel/sysfs.c +++ b/arch/sparc/kernel/sysfs.c @@ -1,4 +1,4 @@ -/* sysfs.c: Toplogy sysfs support code for sparc64. +/* sysfs.c: Topology sysfs support code for sparc64. * * Copyright (C) 2007 David S. Miller */ diff --git a/arch/sparc/kernel/unaligned_64.c b/arch/sparc/kernel/unaligned_64.c index d89e97b374cf4dab95cc72ee073263c472e8eaff..9aacb91592621119bd3da3d6572352479c4dc16d 100644 --- a/arch/sparc/kernel/unaligned_64.c +++ b/arch/sparc/kernel/unaligned_64.c @@ -209,8 +209,8 @@ static inline int do_int_store(int reg_num, int size, unsigned long *dst_addr, if (size == 16) { size = 8; zero = (((long)(reg_num ? - (unsigned)fetch_reg(reg_num, regs) : 0)) << 32) | - (unsigned)fetch_reg(reg_num + 1, regs); + (unsigned int)fetch_reg(reg_num, regs) : 0)) << 32) | + (unsigned int)fetch_reg(reg_num + 1, regs); } else if (reg_num) { src_val_p = fetch_reg_addr(reg_num, regs); } diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S index f1a2f688b28a31fc47d2232f3ed10e9d95930223..aadd321aa05db983af75a13ee14f2693ad75ed5c 100644 --- a/arch/sparc/kernel/vmlinux.lds.S +++ b/arch/sparc/kernel/vmlinux.lds.S @@ -48,6 +48,7 @@ SECTIONS LOCK_TEXT KPROBES_TEXT IRQENTRY_TEXT + SOFTIRQENTRY_TEXT *(.gnu.warning) } = 0 _etext = .; diff --git a/arch/sparc/mm/fault_32.c b/arch/sparc/mm/fault_32.c index c399e7b3b035250d66ed4522d2da190dc6169aa3..b6c559cbd64da3348cb76aee8db6d47f01c9da67 100644 --- a/arch/sparc/mm/fault_32.c +++ b/arch/sparc/mm/fault_32.c @@ -303,10 +303,10 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, fixup = search_extables_range(regs->pc, &g2); /* Values below 10 are reserved for other things */ if (fixup > 10) { - extern const unsigned __memset_start[]; - extern const unsigned __memset_end[]; - extern const unsigned __csum_partial_copy_start[]; - extern const unsigned __csum_partial_copy_end[]; + extern const unsigned int __memset_start[]; + extern const unsigned int __memset_end[]; + extern const unsigned int __csum_partial_copy_start[]; + extern const unsigned int __csum_partial_copy_end[]; #ifdef DEBUG_EXCEPTIONS printk("Exception: PC<%08lx> faddr<%08lx>\n", diff --git a/arch/sparc/mm/gup.c b/arch/sparc/mm/gup.c index eb3d8e8ebc6b064febae847c92ef5329a02b8ae4..4e06750a5d295649660ff4ca0998eb03b00da9e9 100644 --- a/arch/sparc/mm/gup.c +++ b/arch/sparc/mm/gup.c @@ -237,7 +237,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, start += nr << PAGE_SHIFT; pages += nr; - ret = get_user_pages_unlocked(current, mm, start, + ret = get_user_pages_unlocked(start, (end - start) >> PAGE_SHIFT, write, 0, pages); /* Have to be a bit careful with return values */ diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c index 131eaf4ad7f598aacaaf31a8f59da9ad1335c2da..4977800e9770552e44b9fd4571d6aa90e15168ed 100644 --- a/arch/sparc/mm/hugetlbpage.c +++ b/arch/sparc/mm/hugetlbpage.c @@ -146,7 +146,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, if (pud) { pmd = pmd_alloc(mm, pud, addr); if (pmd) - pte = pte_alloc_map(mm, NULL, pmd, addr); + pte = pte_alloc_map(mm, pmd, addr); } return pte; } diff --git a/arch/sparc/net/bpf_jit_comp.c b/arch/sparc/net/bpf_jit_comp.c index 3e6e05a7c4c22b297861eb82871d92b7217cffee..a6d9204a6a0bd352ec6fa4e3c89450a81dee8a37 100644 --- a/arch/sparc/net/bpf_jit_comp.c +++ b/arch/sparc/net/bpf_jit_comp.c @@ -351,7 +351,7 @@ do { *prog++ = BR_OPC | WDISP22(OFF); \ * * Sometimes we need to emit a branch earlier in the code * sequence. And in these situations we adjust "destination" - * to accomodate this difference. For example, if we needed + * to accommodate this difference. For example, if we needed * to emit a branch (and it's delay slot) right before the * final instruction emitted for a BPF opcode, we'd use * "destination + 4" instead of just plain "destination" above. diff --git a/arch/tile/configs/tilegx_defconfig b/arch/tile/configs/tilegx_defconfig index c1387b7f447da9e70c0cee1e5cedc564010b26ad..3f3dfb8b150a114adb5d0e29d2f453b89f8194ad 100644 --- a/arch/tile/configs/tilegx_defconfig +++ b/arch/tile/configs/tilegx_defconfig @@ -222,7 +222,7 @@ CONFIG_TUN=y CONFIG_VETH=m CONFIG_NET_DSA_MV88E6060=y CONFIG_NET_DSA_MV88E6131=y -CONFIG_NET_DSA_MV88E6123_61_65=y +CONFIG_NET_DSA_MV88E6123=y CONFIG_SKY2=y CONFIG_PTP_1588_CLOCK_TILEGX=y # CONFIG_WLAN is not set diff --git a/arch/tile/configs/tilepro_defconfig b/arch/tile/configs/tilepro_defconfig index 6d9ce8af11074eef6a283ad08c5247f000fba206..ef9e27eb2f50cfa11b2c931bbbdc31928ba49385 100644 --- a/arch/tile/configs/tilepro_defconfig +++ b/arch/tile/configs/tilepro_defconfig @@ -341,7 +341,7 @@ CONFIG_TUN=y CONFIG_VETH=m CONFIG_NET_DSA_MV88E6060=y CONFIG_NET_DSA_MV88E6131=y -CONFIG_NET_DSA_MV88E6123_61_65=y +CONFIG_NET_DSA_MV88E6123=y # CONFIG_NET_VENDOR_3COM is not set CONFIG_E1000E=y # CONFIG_WLAN is not set diff --git a/arch/tile/include/hv/drv_mpipe_intf.h b/arch/tile/include/hv/drv_mpipe_intf.h index c97e416dd963b585c8907097408fa53aebf55bcb..ff7f50f970a58ba9de68b88b161cd53ddaa30ee1 100644 --- a/arch/tile/include/hv/drv_mpipe_intf.h +++ b/arch/tile/include/hv/drv_mpipe_intf.h @@ -211,7 +211,7 @@ _gxio_mpipe_link_mac_t; * request shared data permission on the same link. * * No more than one of ::GXIO_MPIPE_LINK_DATA, ::GXIO_MPIPE_LINK_NO_DATA, - * or ::GXIO_MPIPE_LINK_EXCL_DATA may be specifed in a gxio_mpipe_link_open() + * or ::GXIO_MPIPE_LINK_EXCL_DATA may be specified in a gxio_mpipe_link_open() * call. If none are specified, ::GXIO_MPIPE_LINK_DATA is assumed. */ #define GXIO_MPIPE_LINK_DATA 0x00000001UL @@ -219,7 +219,7 @@ _gxio_mpipe_link_mac_t; /** Do not request data permission on the specified link. * * No more than one of ::GXIO_MPIPE_LINK_DATA, ::GXIO_MPIPE_LINK_NO_DATA, - * or ::GXIO_MPIPE_LINK_EXCL_DATA may be specifed in a gxio_mpipe_link_open() + * or ::GXIO_MPIPE_LINK_EXCL_DATA may be specified in a gxio_mpipe_link_open() * call. If none are specified, ::GXIO_MPIPE_LINK_DATA is assumed. */ #define GXIO_MPIPE_LINK_NO_DATA 0x00000002UL @@ -230,7 +230,7 @@ _gxio_mpipe_link_mac_t; * data permission on it, this open will fail. * * No more than one of ::GXIO_MPIPE_LINK_DATA, ::GXIO_MPIPE_LINK_NO_DATA, - * or ::GXIO_MPIPE_LINK_EXCL_DATA may be specifed in a gxio_mpipe_link_open() + * or ::GXIO_MPIPE_LINK_EXCL_DATA may be specified in a gxio_mpipe_link_open() * call. If none are specified, ::GXIO_MPIPE_LINK_DATA is assumed. */ #define GXIO_MPIPE_LINK_EXCL_DATA 0x00000004UL @@ -241,7 +241,7 @@ _gxio_mpipe_link_mac_t; * permission on the same link. * * No more than one of ::GXIO_MPIPE_LINK_STATS, ::GXIO_MPIPE_LINK_NO_STATS, - * or ::GXIO_MPIPE_LINK_EXCL_STATS may be specifed in a gxio_mpipe_link_open() + * or ::GXIO_MPIPE_LINK_EXCL_STATS may be specified in a gxio_mpipe_link_open() * call. If none are specified, ::GXIO_MPIPE_LINK_STATS is assumed. */ #define GXIO_MPIPE_LINK_STATS 0x00000008UL @@ -249,7 +249,7 @@ _gxio_mpipe_link_mac_t; /** Do not request stats permission on the specified link. * * No more than one of ::GXIO_MPIPE_LINK_STATS, ::GXIO_MPIPE_LINK_NO_STATS, - * or ::GXIO_MPIPE_LINK_EXCL_STATS may be specifed in a gxio_mpipe_link_open() + * or ::GXIO_MPIPE_LINK_EXCL_STATS may be specified in a gxio_mpipe_link_open() * call. If none are specified, ::GXIO_MPIPE_LINK_STATS is assumed. */ #define GXIO_MPIPE_LINK_NO_STATS 0x00000010UL @@ -267,7 +267,7 @@ _gxio_mpipe_link_mac_t; * reset by other statistics programs. * * No more than one of ::GXIO_MPIPE_LINK_STATS, ::GXIO_MPIPE_LINK_NO_STATS, - * or ::GXIO_MPIPE_LINK_EXCL_STATS may be specifed in a gxio_mpipe_link_open() + * or ::GXIO_MPIPE_LINK_EXCL_STATS may be specified in a gxio_mpipe_link_open() * call. If none are specified, ::GXIO_MPIPE_LINK_STATS is assumed. */ #define GXIO_MPIPE_LINK_EXCL_STATS 0x00000020UL @@ -278,7 +278,7 @@ _gxio_mpipe_link_mac_t; * permission on the same link. * * No more than one of ::GXIO_MPIPE_LINK_CTL, ::GXIO_MPIPE_LINK_NO_CTL, - * or ::GXIO_MPIPE_LINK_EXCL_CTL may be specifed in a gxio_mpipe_link_open() + * or ::GXIO_MPIPE_LINK_EXCL_CTL may be specified in a gxio_mpipe_link_open() * call. If none are specified, ::GXIO_MPIPE_LINK_CTL is assumed. */ #define GXIO_MPIPE_LINK_CTL 0x00000040UL @@ -286,7 +286,7 @@ _gxio_mpipe_link_mac_t; /** Do not request control permission on the specified link. * * No more than one of ::GXIO_MPIPE_LINK_CTL, ::GXIO_MPIPE_LINK_NO_CTL, - * or ::GXIO_MPIPE_LINK_EXCL_CTL may be specifed in a gxio_mpipe_link_open() + * or ::GXIO_MPIPE_LINK_EXCL_CTL may be specified in a gxio_mpipe_link_open() * call. If none are specified, ::GXIO_MPIPE_LINK_CTL is assumed. */ #define GXIO_MPIPE_LINK_NO_CTL 0x00000080UL @@ -301,7 +301,7 @@ _gxio_mpipe_link_mac_t; * it prevents programs like mpipe-link from configuring the link. * * No more than one of ::GXIO_MPIPE_LINK_CTL, ::GXIO_MPIPE_LINK_NO_CTL, - * or ::GXIO_MPIPE_LINK_EXCL_CTL may be specifed in a gxio_mpipe_link_open() + * or ::GXIO_MPIPE_LINK_EXCL_CTL may be specified in a gxio_mpipe_link_open() * call. If none are specified, ::GXIO_MPIPE_LINK_CTL is assumed. */ #define GXIO_MPIPE_LINK_EXCL_CTL 0x00000100UL @@ -311,7 +311,7 @@ _gxio_mpipe_link_mac_t; * change the desired state of the link when it is closed or the process * exits. No more than one of ::GXIO_MPIPE_LINK_AUTO_UP, * ::GXIO_MPIPE_LINK_AUTO_UPDOWN, ::GXIO_MPIPE_LINK_AUTO_DOWN, or - * ::GXIO_MPIPE_LINK_AUTO_NONE may be specifed in a gxio_mpipe_link_open() + * ::GXIO_MPIPE_LINK_AUTO_NONE may be specified in a gxio_mpipe_link_open() * call. If none are specified, ::GXIO_MPIPE_LINK_AUTO_UPDOWN is assumed. */ #define GXIO_MPIPE_LINK_AUTO_UP 0x00000200UL @@ -322,7 +322,7 @@ _gxio_mpipe_link_mac_t; * open, set the desired state of the link to down. No more than one of * ::GXIO_MPIPE_LINK_AUTO_UP, ::GXIO_MPIPE_LINK_AUTO_UPDOWN, * ::GXIO_MPIPE_LINK_AUTO_DOWN, or ::GXIO_MPIPE_LINK_AUTO_NONE may be - * specifed in a gxio_mpipe_link_open() call. If none are specified, + * specified in a gxio_mpipe_link_open() call. If none are specified, * ::GXIO_MPIPE_LINK_AUTO_UPDOWN is assumed. */ #define GXIO_MPIPE_LINK_AUTO_UPDOWN 0x00000400UL @@ -332,7 +332,7 @@ _gxio_mpipe_link_mac_t; * process has the link open, set the desired state of the link to down. * No more than one of ::GXIO_MPIPE_LINK_AUTO_UP, * ::GXIO_MPIPE_LINK_AUTO_UPDOWN, ::GXIO_MPIPE_LINK_AUTO_DOWN, or - * ::GXIO_MPIPE_LINK_AUTO_NONE may be specifed in a gxio_mpipe_link_open() + * ::GXIO_MPIPE_LINK_AUTO_NONE may be specified in a gxio_mpipe_link_open() * call. If none are specified, ::GXIO_MPIPE_LINK_AUTO_UPDOWN is assumed. */ #define GXIO_MPIPE_LINK_AUTO_DOWN 0x00000800UL @@ -342,7 +342,7 @@ _gxio_mpipe_link_mac_t; * closed or the process exits. No more than one of * ::GXIO_MPIPE_LINK_AUTO_UP, ::GXIO_MPIPE_LINK_AUTO_UPDOWN, * ::GXIO_MPIPE_LINK_AUTO_DOWN, or ::GXIO_MPIPE_LINK_AUTO_NONE may be - * specifed in a gxio_mpipe_link_open() call. If none are specified, + * specified in a gxio_mpipe_link_open() call. If none are specified, * ::GXIO_MPIPE_LINK_AUTO_UPDOWN is assumed. */ #define GXIO_MPIPE_LINK_AUTO_NONE 0x00001000UL diff --git a/arch/tile/kernel/kgdb.c b/arch/tile/kernel/kgdb.c index a506c2c28943715770ab43fa451797a8cb1566e4..9247d6b562f494d5885b6c1390551710e85951a9 100644 --- a/arch/tile/kernel/kgdb.c +++ b/arch/tile/kernel/kgdb.c @@ -126,15 +126,15 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task) { struct pt_regs *thread_regs; + const int NGPRS = TREG_LAST_GPR + 1; if (task == NULL) return; - /* Initialize to zero. */ - memset(gdb_regs, 0, NUMREGBYTES); - thread_regs = task_pt_regs(task); - memcpy(gdb_regs, thread_regs, TREG_LAST_GPR * sizeof(unsigned long)); + memcpy(gdb_regs, thread_regs, NGPRS * sizeof(unsigned long)); + memset(&gdb_regs[NGPRS], 0, + (TILEGX_PC_REGNUM - NGPRS) * sizeof(unsigned long)); gdb_regs[TILEGX_PC_REGNUM] = thread_regs->pc; gdb_regs[TILEGX_FAULTNUM_REGNUM] = thread_regs->faultnum; } @@ -433,9 +433,9 @@ int kgdb_arch_handle_exception(int vector, int signo, int err_code, struct kgdb_arch arch_kgdb_ops; /* - * kgdb_arch_init - Perform any architecture specific initalization. + * kgdb_arch_init - Perform any architecture specific initialization. * - * This function will handle the initalization of any architecture + * This function will handle the initialization of any architecture * specific callbacks. */ int kgdb_arch_init(void) @@ -447,9 +447,9 @@ int kgdb_arch_init(void) } /* - * kgdb_arch_exit - Perform any architecture specific uninitalization. + * kgdb_arch_exit - Perform any architecture specific uninitialization. * - * This function will handle the uninitalization of any architecture + * This function will handle the uninitialization of any architecture * specific callbacks, for dynamic registration and unregistration. */ void kgdb_arch_exit(void) diff --git a/arch/tile/kernel/pci_gx.c b/arch/tile/kernel/pci_gx.c index 4c017d0d2de8c193f14f301138a45134bd587c5e..aa2b44cd8fd34c0a25576323a8135f94d935e9d5 100644 --- a/arch/tile/kernel/pci_gx.c +++ b/arch/tile/kernel/pci_gx.c @@ -1326,7 +1326,7 @@ static int tile_cfg_read(struct pci_bus *bus, unsigned int devfn, int offset, /* - * See tile_cfg_read() for relevent comments. + * See tile_cfg_read() for relevant comments. * Note that "val" is the value to write, not a pointer to that value. */ static int tile_cfg_write(struct pci_bus *bus, unsigned int devfn, int offset, diff --git a/arch/tile/kernel/vmlinux.lds.S b/arch/tile/kernel/vmlinux.lds.S index 0e059a0101ea3097527968bd2632a2b91436bb0d..378f5d8d1ec8aa8ca77cd34848e34ea3d962dc5b 100644 --- a/arch/tile/kernel/vmlinux.lds.S +++ b/arch/tile/kernel/vmlinux.lds.S @@ -45,6 +45,7 @@ SECTIONS LOCK_TEXT KPROBES_TEXT IRQENTRY_TEXT + SOFTIRQENTRY_TEXT __fix_text_end = .; /* tile-cpack won't rearrange before this */ ALIGN_FUNCTION(); *(.hottext*) diff --git a/arch/tile/mm/hugetlbpage.c b/arch/tile/mm/hugetlbpage.c index c034dc3fe2d42cb80502517816dd188ff8801557..e212c64682c55bcaaa9b4aa78c13cf6326a95e39 100644 --- a/arch/tile/mm/hugetlbpage.c +++ b/arch/tile/mm/hugetlbpage.c @@ -77,7 +77,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, else { if (sz != PAGE_SIZE << huge_shift[HUGE_SHIFT_PAGE]) panic("Unexpected page size %#lx\n", sz); - return pte_alloc_map(mm, NULL, pmd, addr); + return pte_alloc_map(mm, pmd, addr); } } #else diff --git a/arch/tile/mm/init.c b/arch/tile/mm/init.c index d4e1fc41d06db21a475b1bdbd6508df5b7f5ab8a..a0582b7f41d3357b4db0507df4a7153a028b0fe7 100644 --- a/arch/tile/mm/init.c +++ b/arch/tile/mm/init.c @@ -896,17 +896,15 @@ void __init pgtable_cache_init(void) panic("pgtable_cache_init(): Cannot create pgd cache"); } -#ifdef CONFIG_DEBUG_PAGEALLOC -static long __write_once initfree; -#else static long __write_once initfree = 1; -#endif +static bool __write_once set_initfree_done; /* Select whether to free (1) or mark unusable (0) the __init pages. */ static int __init set_initfree(char *str) { long val; if (kstrtol(str, 0, &val) == 0) { + set_initfree_done = true; initfree = val; pr_info("initfree: %s free init pages\n", initfree ? "will" : "won't"); @@ -919,6 +917,11 @@ static void free_init_pages(char *what, unsigned long begin, unsigned long end) { unsigned long addr = (unsigned long) begin; + /* Prefer user request first */ + if (!set_initfree_done) { + if (debug_pagealloc_enabled()) + initfree = 0; + } if (kdata_huge && !initfree) { pr_warn("Warning: ignoring initfree=0: incompatible with kdata=huge\n"); initfree = 1; diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index b821b13d343a7bb37e1c260aa59ab5387cba195d..8a6b57108ac26120cc25a037499d15432e6a0851 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c @@ -133,7 +133,7 @@ void mconsole_proc(struct mc_request *req) ptr += strlen("proc"); ptr = skip_spaces(ptr); - file = file_open_root(mnt->mnt_root, mnt, ptr, O_RDONLY); + file = file_open_root(mnt->mnt_root, mnt, ptr, O_RDONLY, 0); if (IS_ERR(file)) { mconsole_reply(req, "Failed to open file", 1, 0); printk(KERN_ERR "open /proc/%s: %ld\n", ptr, PTR_ERR(file)); diff --git a/arch/um/include/asm/mmu_context.h b/arch/um/include/asm/mmu_context.h index 941527e507f76f417f83110407eec29f652e1a9d..1a60e1328e2fa1fa2fa7186d73615543a70d9ec2 100644 --- a/arch/um/include/asm/mmu_context.h +++ b/arch/um/include/asm/mmu_context.h @@ -27,6 +27,20 @@ static inline void arch_bprm_mm_init(struct mm_struct *mm, struct vm_area_struct *vma) { } + +static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, + bool write, bool execute, bool foreign) +{ + /* by default, allow everything */ + return true; +} + +static inline bool arch_pte_access_permitted(pte_t pte, bool write) +{ + /* by default, allow everything */ + return true; +} + /* * end asm-generic/mm_hooks.h functions */ diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c index 9591a66aa5c513b5fe8773e2b21634c19b3758ed..3943e9d7d13d2d28f1b83b1fc8da5500acef795d 100644 --- a/arch/um/kernel/skas/mmu.c +++ b/arch/um/kernel/skas/mmu.c @@ -31,7 +31,7 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc, if (!pmd) goto out_pmd; - pte = pte_alloc_map(mm, NULL, pmd, proc); + pte = pte_alloc_map(mm, pmd, proc); if (!pte) goto out_pte; diff --git a/arch/unicore32/include/asm/checksum.h b/arch/unicore32/include/asm/checksum.h index f55c3f937c3ed78132d43befd00efa86c915e1d7..23ceb9e3a89bf1d9bca440700d19f8e9caaba82a 100644 --- a/arch/unicore32/include/asm/checksum.h +++ b/arch/unicore32/include/asm/checksum.h @@ -20,8 +20,8 @@ */ static inline __wsum -csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) +csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len, + __u8 proto, __wsum sum) { __asm__( "add.a %0, %1, %2\n" diff --git a/arch/unicore32/include/asm/mmu_context.h b/arch/unicore32/include/asm/mmu_context.h index 1cb5220afaf9dbdb13c2ad2f250566d2881a1c1e..e35632ef23c759a43e4673d222aac430172cdad7 100644 --- a/arch/unicore32/include/asm/mmu_context.h +++ b/arch/unicore32/include/asm/mmu_context.h @@ -97,4 +97,16 @@ static inline void arch_bprm_mm_init(struct mm_struct *mm, { } +static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, + bool write, bool foreign) +{ + /* by default, allow everything */ + return true; +} + +static inline bool arch_pte_access_permitted(pte_t pte, bool write) +{ + /* by default, allow everything */ + return true; +} #endif diff --git a/arch/unicore32/mm/fault.c b/arch/unicore32/mm/fault.c index afccef5529ccb8d44409519aa075476af747722e..2ec3d3adcefc948870ab4419575aecab3f6f47e7 100644 --- a/arch/unicore32/mm/fault.c +++ b/arch/unicore32/mm/fault.c @@ -276,7 +276,7 @@ static int do_pf(unsigned long addr, unsigned int fsr, struct pt_regs *regs) up_read(&mm->mmap_sem); /* - * Handle the "normal" case first - VM_FAULT_MAJOR / VM_FAULT_MINOR + * Handle the "normal" case first - VM_FAULT_MAJOR */ if (likely(!(fault & (VM_FAULT_ERROR | VM_FAULT_BADMAP | VM_FAULT_BADACCESS)))) diff --git a/arch/unicore32/mm/pgd.c b/arch/unicore32/mm/pgd.c index 2ade20d8eab3965d749e2c44d475cc931b52a3c3..c572a28c76c98997f5a4a80af3dc63d3119abc0f 100644 --- a/arch/unicore32/mm/pgd.c +++ b/arch/unicore32/mm/pgd.c @@ -54,7 +54,7 @@ pgd_t *get_pgd_slow(struct mm_struct *mm) if (!new_pmd) goto no_pmd; - new_pte = pte_alloc_map(mm, NULL, new_pmd, 0); + new_pte = pte_alloc_map(mm, new_pmd, 0); if (!new_pte) goto no_pte; diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 3c74b549ea9a3bbb5e3962a7d202cb8079cb1f63..2dc18605831f6e88fd45c2863fc3d1fc7e6b6622 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -28,6 +28,7 @@ config X86 select ARCH_HAS_ELF_RANDOMIZE select ARCH_HAS_FAST_MULTIPLIER select ARCH_HAS_GCOV_PROFILE_ALL + select ARCH_HAS_KCOV if X86_64 select ARCH_HAS_PMEM_API if X86_64 select ARCH_HAS_MMIO_FLUSH select ARCH_HAS_SG_CHAIN @@ -155,6 +156,9 @@ config X86 select VIRT_TO_BUS select X86_DEV_DMA_OPS if X86_64 select X86_FEATURE_NAMES if PROC_FS + select HAVE_STACK_VALIDATION if X86_64 + select ARCH_USES_HIGH_VMA_FLAGS if X86_INTEL_MEMORY_PROTECTION_KEYS + select ARCH_HAS_PKEYS if X86_INTEL_MEMORY_PROTECTION_KEYS config INSTRUCTION_DECODER def_bool y @@ -1206,6 +1210,15 @@ config MICROCODE_OLD_INTERFACE def_bool y depends on MICROCODE +config PERF_EVENTS_AMD_POWER + depends on PERF_EVENTS && CPU_SUP_AMD + tristate "AMD Processor Power Reporting Mechanism" + ---help--- + Provide power reporting mechanism support for AMD processors. + Currently, it leverages X86_FEATURE_ACC_POWER + (CPUID Fn8000_0007_EDX[12]) interface to calculate the + average power consumption on Family 15h processors. + config X86_MSR tristate "/dev/cpu/*/msr - Model-specific register support" ---help--- @@ -1718,6 +1731,20 @@ config X86_INTEL_MPX If unsure, say N. +config X86_INTEL_MEMORY_PROTECTION_KEYS + prompt "Intel Memory Protection Keys" + def_bool y + # Note: only available in 64-bit mode + depends on CPU_SUP_INTEL && X86_64 + ---help--- + Memory Protection Keys provides a mechanism for enforcing + page-based protections, but without requiring modification of the + page tables when an application changes protection domains. + + For details, see Documentation/x86/protection-keys.txt + + If unsure, say y. + config EFI bool "EFI runtime service support" depends on ACPI diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile index bbe1a62efc021aadb29f27a1c7a68257b8478cef..b1ef9e48908474bf95dbe6f577cc1fab1a5ea669 100644 --- a/arch/x86/boot/Makefile +++ b/arch/x86/boot/Makefile @@ -9,7 +9,15 @@ # Changed by many, many contributors over the years. # -KASAN_SANITIZE := n +KASAN_SANITIZE := n +OBJECT_FILES_NON_STANDARD := y + +# Kernel does not boot with kcov instrumentation here. +# One of the problems observed was insertion of __sanitizer_cov_trace_pc() +# callback into middle of per-cpu data enabling code. Thus the callback observed +# inconsistent state and crashed. We are interested mostly in syscall coverage, +# so boot code is not interesting anyway. +KCOV_INSTRUMENT := n # If you want to preset the SVGA mode, uncomment the next line and # set SVGA_MODE to whatever number you want. diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index f9ce75d80101cc7a620bed1169a1128056b9caa5..6915ff2bd9962e0b495d0af05c18f51a9382c36e 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile @@ -16,7 +16,11 @@ # (see scripts/Makefile.lib size_append) # compressed vmlinux.bin.all + u32 size of vmlinux.bin.all -KASAN_SANITIZE := n +KASAN_SANITIZE := n +OBJECT_FILES_NON_STANDARD := y + +# Prevents link failures: __sanitizer_cov_trace_pc() is not linked in. +KCOV_INSTRUMENT := n targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \ vmlinux.bin.xz vmlinux.bin.lzo vmlinux.bin.lz4 diff --git a/arch/x86/crypto/aesni-intel_asm.S b/arch/x86/crypto/aesni-intel_asm.S index 6bd2c6c95373f58dc8f915f5e50967105bf404d0..383a6f84a060f103c7c43923ad84029e0ce2a9f1 100644 --- a/arch/x86/crypto/aesni-intel_asm.S +++ b/arch/x86/crypto/aesni-intel_asm.S @@ -31,6 +31,7 @@ #include #include +#include /* * The following macros are used to move an (un)aligned 16 byte value to/from @@ -1800,11 +1801,12 @@ ENDPROC(_key_expansion_256b) * unsigned int key_len) */ ENTRY(aesni_set_key) + FRAME_BEGIN #ifndef __x86_64__ pushl KEYP - movl 8(%esp), KEYP # ctx - movl 12(%esp), UKEYP # in_key - movl 16(%esp), %edx # key_len + movl (FRAME_OFFSET+8)(%esp), KEYP # ctx + movl (FRAME_OFFSET+12)(%esp), UKEYP # in_key + movl (FRAME_OFFSET+16)(%esp), %edx # key_len #endif movups (UKEYP), %xmm0 # user key (first 16 bytes) movaps %xmm0, (KEYP) @@ -1905,6 +1907,7 @@ ENTRY(aesni_set_key) #ifndef __x86_64__ popl KEYP #endif + FRAME_END ret ENDPROC(aesni_set_key) @@ -1912,12 +1915,13 @@ ENDPROC(aesni_set_key) * void aesni_enc(struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src) */ ENTRY(aesni_enc) + FRAME_BEGIN #ifndef __x86_64__ pushl KEYP pushl KLEN - movl 12(%esp), KEYP - movl 16(%esp), OUTP - movl 20(%esp), INP + movl (FRAME_OFFSET+12)(%esp), KEYP # ctx + movl (FRAME_OFFSET+16)(%esp), OUTP # dst + movl (FRAME_OFFSET+20)(%esp), INP # src #endif movl 480(KEYP), KLEN # key length movups (INP), STATE # input @@ -1927,6 +1931,7 @@ ENTRY(aesni_enc) popl KLEN popl KEYP #endif + FRAME_END ret ENDPROC(aesni_enc) @@ -2101,12 +2106,13 @@ ENDPROC(_aesni_enc4) * void aesni_dec (struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src) */ ENTRY(aesni_dec) + FRAME_BEGIN #ifndef __x86_64__ pushl KEYP pushl KLEN - movl 12(%esp), KEYP - movl 16(%esp), OUTP - movl 20(%esp), INP + movl (FRAME_OFFSET+12)(%esp), KEYP # ctx + movl (FRAME_OFFSET+16)(%esp), OUTP # dst + movl (FRAME_OFFSET+20)(%esp), INP # src #endif mov 480(KEYP), KLEN # key length add $240, KEYP @@ -2117,6 +2123,7 @@ ENTRY(aesni_dec) popl KLEN popl KEYP #endif + FRAME_END ret ENDPROC(aesni_dec) @@ -2292,14 +2299,15 @@ ENDPROC(_aesni_dec4) * size_t len) */ ENTRY(aesni_ecb_enc) + FRAME_BEGIN #ifndef __x86_64__ pushl LEN pushl KEYP pushl KLEN - movl 16(%esp), KEYP - movl 20(%esp), OUTP - movl 24(%esp), INP - movl 28(%esp), LEN + movl (FRAME_OFFSET+16)(%esp), KEYP # ctx + movl (FRAME_OFFSET+20)(%esp), OUTP # dst + movl (FRAME_OFFSET+24)(%esp), INP # src + movl (FRAME_OFFSET+28)(%esp), LEN # len #endif test LEN, LEN # check length jz .Lecb_enc_ret @@ -2342,6 +2350,7 @@ ENTRY(aesni_ecb_enc) popl KEYP popl LEN #endif + FRAME_END ret ENDPROC(aesni_ecb_enc) @@ -2350,14 +2359,15 @@ ENDPROC(aesni_ecb_enc) * size_t len); */ ENTRY(aesni_ecb_dec) + FRAME_BEGIN #ifndef __x86_64__ pushl LEN pushl KEYP pushl KLEN - movl 16(%esp), KEYP - movl 20(%esp), OUTP - movl 24(%esp), INP - movl 28(%esp), LEN + movl (FRAME_OFFSET+16)(%esp), KEYP # ctx + movl (FRAME_OFFSET+20)(%esp), OUTP # dst + movl (FRAME_OFFSET+24)(%esp), INP # src + movl (FRAME_OFFSET+28)(%esp), LEN # len #endif test LEN, LEN jz .Lecb_dec_ret @@ -2401,6 +2411,7 @@ ENTRY(aesni_ecb_dec) popl KEYP popl LEN #endif + FRAME_END ret ENDPROC(aesni_ecb_dec) @@ -2409,16 +2420,17 @@ ENDPROC(aesni_ecb_dec) * size_t len, u8 *iv) */ ENTRY(aesni_cbc_enc) + FRAME_BEGIN #ifndef __x86_64__ pushl IVP pushl LEN pushl KEYP pushl KLEN - movl 20(%esp), KEYP - movl 24(%esp), OUTP - movl 28(%esp), INP - movl 32(%esp), LEN - movl 36(%esp), IVP + movl (FRAME_OFFSET+20)(%esp), KEYP # ctx + movl (FRAME_OFFSET+24)(%esp), OUTP # dst + movl (FRAME_OFFSET+28)(%esp), INP # src + movl (FRAME_OFFSET+32)(%esp), LEN # len + movl (FRAME_OFFSET+36)(%esp), IVP # iv #endif cmp $16, LEN jb .Lcbc_enc_ret @@ -2443,6 +2455,7 @@ ENTRY(aesni_cbc_enc) popl LEN popl IVP #endif + FRAME_END ret ENDPROC(aesni_cbc_enc) @@ -2451,16 +2464,17 @@ ENDPROC(aesni_cbc_enc) * size_t len, u8 *iv) */ ENTRY(aesni_cbc_dec) + FRAME_BEGIN #ifndef __x86_64__ pushl IVP pushl LEN pushl KEYP pushl KLEN - movl 20(%esp), KEYP - movl 24(%esp), OUTP - movl 28(%esp), INP - movl 32(%esp), LEN - movl 36(%esp), IVP + movl (FRAME_OFFSET+20)(%esp), KEYP # ctx + movl (FRAME_OFFSET+24)(%esp), OUTP # dst + movl (FRAME_OFFSET+28)(%esp), INP # src + movl (FRAME_OFFSET+32)(%esp), LEN # len + movl (FRAME_OFFSET+36)(%esp), IVP # iv #endif cmp $16, LEN jb .Lcbc_dec_just_ret @@ -2534,13 +2548,16 @@ ENTRY(aesni_cbc_dec) popl LEN popl IVP #endif + FRAME_END ret ENDPROC(aesni_cbc_dec) #ifdef __x86_64__ +.pushsection .rodata .align 16 .Lbswap_mask: .byte 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 +.popsection /* * _aesni_inc_init: internal ABI @@ -2598,6 +2615,7 @@ ENDPROC(_aesni_inc) * size_t len, u8 *iv) */ ENTRY(aesni_ctr_enc) + FRAME_BEGIN cmp $16, LEN jb .Lctr_enc_just_ret mov 480(KEYP), KLEN @@ -2651,6 +2669,7 @@ ENTRY(aesni_ctr_enc) .Lctr_enc_ret: movups IV, (IVP) .Lctr_enc_just_ret: + FRAME_END ret ENDPROC(aesni_ctr_enc) @@ -2677,6 +2696,7 @@ ENDPROC(aesni_ctr_enc) * bool enc, u8 *iv) */ ENTRY(aesni_xts_crypt8) + FRAME_BEGIN cmpb $0, %cl movl $0, %ecx movl $240, %r10d @@ -2777,6 +2797,7 @@ ENTRY(aesni_xts_crypt8) pxor INC, STATE4 movdqu STATE4, 0x70(OUTP) + FRAME_END ret ENDPROC(aesni_xts_crypt8) diff --git a/arch/x86/crypto/camellia-aesni-avx-asm_64.S b/arch/x86/crypto/camellia-aesni-avx-asm_64.S index ce71f9212409f16326ffc92efec812c2be7d731c..aa9e8bd163f61b0440372bfbc26e956f71bf95d3 100644 --- a/arch/x86/crypto/camellia-aesni-avx-asm_64.S +++ b/arch/x86/crypto/camellia-aesni-avx-asm_64.S @@ -16,6 +16,7 @@ */ #include +#include #define CAMELLIA_TABLE_BYTE_LEN 272 @@ -726,6 +727,7 @@ __camellia_enc_blk16: * %xmm0..%xmm15: 16 encrypted blocks, order swapped: * 7, 8, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8 */ + FRAME_BEGIN leaq 8 * 16(%rax), %rcx; @@ -780,6 +782,7 @@ __camellia_enc_blk16: %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, (key_table)(CTX, %r8, 8), (%rax), 1 * 16(%rax)); + FRAME_END ret; .align 8 @@ -812,6 +815,7 @@ __camellia_dec_blk16: * %xmm0..%xmm15: 16 plaintext blocks, order swapped: * 7, 8, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8 */ + FRAME_BEGIN leaq 8 * 16(%rax), %rcx; @@ -865,6 +869,7 @@ __camellia_dec_blk16: %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, (key_table)(CTX), (%rax), 1 * 16(%rax)); + FRAME_END ret; .align 8 @@ -890,6 +895,7 @@ ENTRY(camellia_ecb_enc_16way) * %rsi: dst (16 blocks) * %rdx: src (16 blocks) */ + FRAME_BEGIN inpack16_pre(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14, @@ -904,6 +910,7 @@ ENTRY(camellia_ecb_enc_16way) %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9, %xmm8, %rsi); + FRAME_END ret; ENDPROC(camellia_ecb_enc_16way) @@ -913,6 +920,7 @@ ENTRY(camellia_ecb_dec_16way) * %rsi: dst (16 blocks) * %rdx: src (16 blocks) */ + FRAME_BEGIN cmpl $16, key_length(CTX); movl $32, %r8d; @@ -932,6 +940,7 @@ ENTRY(camellia_ecb_dec_16way) %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9, %xmm8, %rsi); + FRAME_END ret; ENDPROC(camellia_ecb_dec_16way) @@ -941,6 +950,7 @@ ENTRY(camellia_cbc_dec_16way) * %rsi: dst (16 blocks) * %rdx: src (16 blocks) */ + FRAME_BEGIN cmpl $16, key_length(CTX); movl $32, %r8d; @@ -981,6 +991,7 @@ ENTRY(camellia_cbc_dec_16way) %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9, %xmm8, %rsi); + FRAME_END ret; ENDPROC(camellia_cbc_dec_16way) @@ -997,6 +1008,7 @@ ENTRY(camellia_ctr_16way) * %rdx: src (16 blocks) * %rcx: iv (little endian, 128bit) */ + FRAME_BEGIN subq $(16 * 16), %rsp; movq %rsp, %rax; @@ -1092,6 +1104,7 @@ ENTRY(camellia_ctr_16way) %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9, %xmm8, %rsi); + FRAME_END ret; ENDPROC(camellia_ctr_16way) @@ -1112,6 +1125,7 @@ camellia_xts_crypt_16way: * %r8: index for input whitening key * %r9: pointer to __camellia_enc_blk16 or __camellia_dec_blk16 */ + FRAME_BEGIN subq $(16 * 16), %rsp; movq %rsp, %rax; @@ -1234,6 +1248,7 @@ camellia_xts_crypt_16way: %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9, %xmm8, %rsi); + FRAME_END ret; ENDPROC(camellia_xts_crypt_16way) diff --git a/arch/x86/crypto/camellia-aesni-avx2-asm_64.S b/arch/x86/crypto/camellia-aesni-avx2-asm_64.S index 0e0b8863a34bd168c618941407b2890c385a442d..16186c18656dfdc67fc7433a48dcc51ee62d9bea 100644 --- a/arch/x86/crypto/camellia-aesni-avx2-asm_64.S +++ b/arch/x86/crypto/camellia-aesni-avx2-asm_64.S @@ -11,6 +11,7 @@ */ #include +#include #define CAMELLIA_TABLE_BYTE_LEN 272 @@ -766,6 +767,7 @@ __camellia_enc_blk32: * %ymm0..%ymm15: 32 encrypted blocks, order swapped: * 7, 8, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8 */ + FRAME_BEGIN leaq 8 * 32(%rax), %rcx; @@ -820,6 +822,7 @@ __camellia_enc_blk32: %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14, %ymm15, (key_table)(CTX, %r8, 8), (%rax), 1 * 32(%rax)); + FRAME_END ret; .align 8 @@ -852,6 +855,7 @@ __camellia_dec_blk32: * %ymm0..%ymm15: 16 plaintext blocks, order swapped: * 7, 8, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8 */ + FRAME_BEGIN leaq 8 * 32(%rax), %rcx; @@ -905,6 +909,7 @@ __camellia_dec_blk32: %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14, %ymm15, (key_table)(CTX), (%rax), 1 * 32(%rax)); + FRAME_END ret; .align 8 @@ -930,6 +935,7 @@ ENTRY(camellia_ecb_enc_32way) * %rsi: dst (32 blocks) * %rdx: src (32 blocks) */ + FRAME_BEGIN vzeroupper; @@ -948,6 +954,7 @@ ENTRY(camellia_ecb_enc_32way) vzeroupper; + FRAME_END ret; ENDPROC(camellia_ecb_enc_32way) @@ -957,6 +964,7 @@ ENTRY(camellia_ecb_dec_32way) * %rsi: dst (32 blocks) * %rdx: src (32 blocks) */ + FRAME_BEGIN vzeroupper; @@ -980,6 +988,7 @@ ENTRY(camellia_ecb_dec_32way) vzeroupper; + FRAME_END ret; ENDPROC(camellia_ecb_dec_32way) @@ -989,6 +998,7 @@ ENTRY(camellia_cbc_dec_32way) * %rsi: dst (32 blocks) * %rdx: src (32 blocks) */ + FRAME_BEGIN vzeroupper; @@ -1046,6 +1056,7 @@ ENTRY(camellia_cbc_dec_32way) vzeroupper; + FRAME_END ret; ENDPROC(camellia_cbc_dec_32way) @@ -1070,6 +1081,7 @@ ENTRY(camellia_ctr_32way) * %rdx: src (32 blocks) * %rcx: iv (little endian, 128bit) */ + FRAME_BEGIN vzeroupper; @@ -1184,6 +1196,7 @@ ENTRY(camellia_ctr_32way) vzeroupper; + FRAME_END ret; ENDPROC(camellia_ctr_32way) @@ -1216,6 +1229,7 @@ camellia_xts_crypt_32way: * %r8: index for input whitening key * %r9: pointer to __camellia_enc_blk32 or __camellia_dec_blk32 */ + FRAME_BEGIN vzeroupper; @@ -1349,6 +1363,7 @@ camellia_xts_crypt_32way: vzeroupper; + FRAME_END ret; ENDPROC(camellia_xts_crypt_32way) diff --git a/arch/x86/crypto/cast5-avx-x86_64-asm_64.S b/arch/x86/crypto/cast5-avx-x86_64-asm_64.S index c35fd5d6ecd26f4b01180484c520c19a10637389..14fa1966bf01d4b89eb68456c21a5e750884d785 100644 --- a/arch/x86/crypto/cast5-avx-x86_64-asm_64.S +++ b/arch/x86/crypto/cast5-avx-x86_64-asm_64.S @@ -24,6 +24,7 @@ */ #include +#include .file "cast5-avx-x86_64-asm_64.S" @@ -365,6 +366,7 @@ ENTRY(cast5_ecb_enc_16way) * %rsi: dst * %rdx: src */ + FRAME_BEGIN movq %rsi, %r11; @@ -388,6 +390,7 @@ ENTRY(cast5_ecb_enc_16way) vmovdqu RR4, (6*4*4)(%r11); vmovdqu RL4, (7*4*4)(%r11); + FRAME_END ret; ENDPROC(cast5_ecb_enc_16way) @@ -398,6 +401,7 @@ ENTRY(cast5_ecb_dec_16way) * %rdx: src */ + FRAME_BEGIN movq %rsi, %r11; vmovdqu (0*4*4)(%rdx), RL1; @@ -420,6 +424,7 @@ ENTRY(cast5_ecb_dec_16way) vmovdqu RR4, (6*4*4)(%r11); vmovdqu RL4, (7*4*4)(%r11); + FRAME_END ret; ENDPROC(cast5_ecb_dec_16way) @@ -429,6 +434,7 @@ ENTRY(cast5_cbc_dec_16way) * %rsi: dst * %rdx: src */ + FRAME_BEGIN pushq %r12; @@ -469,6 +475,7 @@ ENTRY(cast5_cbc_dec_16way) popq %r12; + FRAME_END ret; ENDPROC(cast5_cbc_dec_16way) @@ -479,6 +486,7 @@ ENTRY(cast5_ctr_16way) * %rdx: src * %rcx: iv (big endian, 64bit) */ + FRAME_BEGIN pushq %r12; @@ -542,5 +550,6 @@ ENTRY(cast5_ctr_16way) popq %r12; + FRAME_END ret; ENDPROC(cast5_ctr_16way) diff --git a/arch/x86/crypto/cast6-avx-x86_64-asm_64.S b/arch/x86/crypto/cast6-avx-x86_64-asm_64.S index e3531f833951bbc2535d1f6c51fe58d428c3b637..c419389889cddf24d60080940148bddecc8f6889 100644 --- a/arch/x86/crypto/cast6-avx-x86_64-asm_64.S +++ b/arch/x86/crypto/cast6-avx-x86_64-asm_64.S @@ -24,6 +24,7 @@ */ #include +#include #include "glue_helper-asm-avx.S" .file "cast6-avx-x86_64-asm_64.S" @@ -349,6 +350,7 @@ ENTRY(cast6_ecb_enc_8way) * %rsi: dst * %rdx: src */ + FRAME_BEGIN movq %rsi, %r11; @@ -358,6 +360,7 @@ ENTRY(cast6_ecb_enc_8way) store_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); + FRAME_END ret; ENDPROC(cast6_ecb_enc_8way) @@ -367,6 +370,7 @@ ENTRY(cast6_ecb_dec_8way) * %rsi: dst * %rdx: src */ + FRAME_BEGIN movq %rsi, %r11; @@ -376,6 +380,7 @@ ENTRY(cast6_ecb_dec_8way) store_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); + FRAME_END ret; ENDPROC(cast6_ecb_dec_8way) @@ -385,6 +390,7 @@ ENTRY(cast6_cbc_dec_8way) * %rsi: dst * %rdx: src */ + FRAME_BEGIN pushq %r12; @@ -399,6 +405,7 @@ ENTRY(cast6_cbc_dec_8way) popq %r12; + FRAME_END ret; ENDPROC(cast6_cbc_dec_8way) @@ -409,6 +416,7 @@ ENTRY(cast6_ctr_8way) * %rdx: src * %rcx: iv (little endian, 128bit) */ + FRAME_BEGIN pushq %r12; @@ -424,6 +432,7 @@ ENTRY(cast6_ctr_8way) popq %r12; + FRAME_END ret; ENDPROC(cast6_ctr_8way) @@ -434,6 +443,7 @@ ENTRY(cast6_xts_enc_8way) * %rdx: src * %rcx: iv (t ⊕ αⁿ ∈ GF(2¹²⁸)) */ + FRAME_BEGIN movq %rsi, %r11; @@ -446,6 +456,7 @@ ENTRY(cast6_xts_enc_8way) /* dst <= regs xor IVs(in dst) */ store_xts_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); + FRAME_END ret; ENDPROC(cast6_xts_enc_8way) @@ -456,6 +467,7 @@ ENTRY(cast6_xts_dec_8way) * %rdx: src * %rcx: iv (t ⊕ αⁿ ∈ GF(2¹²⁸)) */ + FRAME_BEGIN movq %rsi, %r11; @@ -468,5 +480,6 @@ ENTRY(cast6_xts_dec_8way) /* dst <= regs xor IVs(in dst) */ store_xts_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); + FRAME_END ret; ENDPROC(cast6_xts_dec_8way) diff --git a/arch/x86/crypto/crc32c-pcl-intel-asm_64.S b/arch/x86/crypto/crc32c-pcl-intel-asm_64.S index 4fe27e07419486055ca7bc5f9108dbe05639df5c..dc05f010ca9b6fd598c444c60a488953e7725655 100644 --- a/arch/x86/crypto/crc32c-pcl-intel-asm_64.S +++ b/arch/x86/crypto/crc32c-pcl-intel-asm_64.S @@ -170,8 +170,8 @@ continue_block: ## branch into array lea jump_table(%rip), bufp movzxw (bufp, %rax, 2), len - offset=crc_array-jump_table - lea offset(bufp, len, 1), bufp + lea crc_array(%rip), bufp + lea (bufp, len, 1), bufp jmp *bufp ################################################################ @@ -310,7 +310,9 @@ do_return: popq %rdi popq %rbx ret +ENDPROC(crc_pcl) +.section .rodata, "a", %progbits ################################################################ ## jump table Table is 129 entries x 2 bytes each ################################################################ @@ -324,13 +326,11 @@ JMPTBL_ENTRY %i i=i+1 .endr -ENDPROC(crc_pcl) ################################################################ ## PCLMULQDQ tables ## Table is 128 entries x 2 words (8 bytes) each ################################################################ -.section .rodata, "a", %progbits .align 8 K_table: .long 0x493c7d27, 0x00000001 diff --git a/arch/x86/crypto/ghash-clmulni-intel_asm.S b/arch/x86/crypto/ghash-clmulni-intel_asm.S index 5d1e0075ac24fa5eae975930647f6fc14c5b256d..eed55c8cca4f8e64b2ef203453ab8c2b34e75722 100644 --- a/arch/x86/crypto/ghash-clmulni-intel_asm.S +++ b/arch/x86/crypto/ghash-clmulni-intel_asm.S @@ -18,6 +18,7 @@ #include #include +#include .data @@ -94,6 +95,7 @@ ENDPROC(__clmul_gf128mul_ble) /* void clmul_ghash_mul(char *dst, const u128 *shash) */ ENTRY(clmul_ghash_mul) + FRAME_BEGIN movups (%rdi), DATA movups (%rsi), SHASH movaps .Lbswap_mask, BSWAP @@ -101,6 +103,7 @@ ENTRY(clmul_ghash_mul) call __clmul_gf128mul_ble PSHUFB_XMM BSWAP DATA movups DATA, (%rdi) + FRAME_END ret ENDPROC(clmul_ghash_mul) @@ -109,6 +112,7 @@ ENDPROC(clmul_ghash_mul) * const u128 *shash); */ ENTRY(clmul_ghash_update) + FRAME_BEGIN cmp $16, %rdx jb .Lupdate_just_ret # check length movaps .Lbswap_mask, BSWAP @@ -128,5 +132,6 @@ ENTRY(clmul_ghash_update) PSHUFB_XMM BSWAP DATA movups DATA, (%rdi) .Lupdate_just_ret: + FRAME_END ret ENDPROC(clmul_ghash_update) diff --git a/arch/x86/crypto/serpent-avx-x86_64-asm_64.S b/arch/x86/crypto/serpent-avx-x86_64-asm_64.S index 2f202f49872b2f6a6ed4ed5a6c6d01a8f0958660..8be571808342b85df775ac897a2e38ad9f35cab4 100644 --- a/arch/x86/crypto/serpent-avx-x86_64-asm_64.S +++ b/arch/x86/crypto/serpent-avx-x86_64-asm_64.S @@ -24,6 +24,7 @@ */ #include +#include #include "glue_helper-asm-avx.S" .file "serpent-avx-x86_64-asm_64.S" @@ -681,6 +682,7 @@ ENTRY(serpent_ecb_enc_8way_avx) * %rsi: dst * %rdx: src */ + FRAME_BEGIN load_8way(%rdx, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); @@ -688,6 +690,7 @@ ENTRY(serpent_ecb_enc_8way_avx) store_8way(%rsi, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); + FRAME_END ret; ENDPROC(serpent_ecb_enc_8way_avx) @@ -697,6 +700,7 @@ ENTRY(serpent_ecb_dec_8way_avx) * %rsi: dst * %rdx: src */ + FRAME_BEGIN load_8way(%rdx, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); @@ -704,6 +708,7 @@ ENTRY(serpent_ecb_dec_8way_avx) store_8way(%rsi, RC1, RD1, RB1, RE1, RC2, RD2, RB2, RE2); + FRAME_END ret; ENDPROC(serpent_ecb_dec_8way_avx) @@ -713,6 +718,7 @@ ENTRY(serpent_cbc_dec_8way_avx) * %rsi: dst * %rdx: src */ + FRAME_BEGIN load_8way(%rdx, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); @@ -720,6 +726,7 @@ ENTRY(serpent_cbc_dec_8way_avx) store_cbc_8way(%rdx, %rsi, RC1, RD1, RB1, RE1, RC2, RD2, RB2, RE2); + FRAME_END ret; ENDPROC(serpent_cbc_dec_8way_avx) @@ -730,6 +737,7 @@ ENTRY(serpent_ctr_8way_avx) * %rdx: src * %rcx: iv (little endian, 128bit) */ + FRAME_BEGIN load_ctr_8way(%rcx, .Lbswap128_mask, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2, RK0, RK1, RK2); @@ -738,6 +746,7 @@ ENTRY(serpent_ctr_8way_avx) store_ctr_8way(%rdx, %rsi, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); + FRAME_END ret; ENDPROC(serpent_ctr_8way_avx) @@ -748,6 +757,7 @@ ENTRY(serpent_xts_enc_8way_avx) * %rdx: src * %rcx: iv (t ⊕ αⁿ ∈ GF(2¹²⁸)) */ + FRAME_BEGIN /* regs <= src, dst <= IVs, regs <= regs xor IVs */ load_xts_8way(%rcx, %rdx, %rsi, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2, @@ -758,6 +768,7 @@ ENTRY(serpent_xts_enc_8way_avx) /* dst <= regs xor IVs(in dst) */ store_xts_8way(%rsi, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); + FRAME_END ret; ENDPROC(serpent_xts_enc_8way_avx) @@ -768,6 +779,7 @@ ENTRY(serpent_xts_dec_8way_avx) * %rdx: src * %rcx: iv (t ⊕ αⁿ ∈ GF(2¹²⁸)) */ + FRAME_BEGIN /* regs <= src, dst <= IVs, regs <= regs xor IVs */ load_xts_8way(%rcx, %rdx, %rsi, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2, @@ -778,5 +790,6 @@ ENTRY(serpent_xts_dec_8way_avx) /* dst <= regs xor IVs(in dst) */ store_xts_8way(%rsi, RC1, RD1, RB1, RE1, RC2, RD2, RB2, RE2); + FRAME_END ret; ENDPROC(serpent_xts_dec_8way_avx) diff --git a/arch/x86/crypto/serpent-avx2-asm_64.S b/arch/x86/crypto/serpent-avx2-asm_64.S index b222085cccac756efc94be3e6780a67c9dd61779..97c48add33ed965e14561f663d98061fd3670ccd 100644 --- a/arch/x86/crypto/serpent-avx2-asm_64.S +++ b/arch/x86/crypto/serpent-avx2-asm_64.S @@ -15,6 +15,7 @@ */ #include +#include #include "glue_helper-asm-avx2.S" .file "serpent-avx2-asm_64.S" @@ -673,6 +674,7 @@ ENTRY(serpent_ecb_enc_16way) * %rsi: dst * %rdx: src */ + FRAME_BEGIN vzeroupper; @@ -684,6 +686,7 @@ ENTRY(serpent_ecb_enc_16way) vzeroupper; + FRAME_END ret; ENDPROC(serpent_ecb_enc_16way) @@ -693,6 +696,7 @@ ENTRY(serpent_ecb_dec_16way) * %rsi: dst * %rdx: src */ + FRAME_BEGIN vzeroupper; @@ -704,6 +708,7 @@ ENTRY(serpent_ecb_dec_16way) vzeroupper; + FRAME_END ret; ENDPROC(serpent_ecb_dec_16way) @@ -713,6 +718,7 @@ ENTRY(serpent_cbc_dec_16way) * %rsi: dst * %rdx: src */ + FRAME_BEGIN vzeroupper; @@ -725,6 +731,7 @@ ENTRY(serpent_cbc_dec_16way) vzeroupper; + FRAME_END ret; ENDPROC(serpent_cbc_dec_16way) @@ -735,6 +742,7 @@ ENTRY(serpent_ctr_16way) * %rdx: src (16 blocks) * %rcx: iv (little endian, 128bit) */ + FRAME_BEGIN vzeroupper; @@ -748,6 +756,7 @@ ENTRY(serpent_ctr_16way) vzeroupper; + FRAME_END ret; ENDPROC(serpent_ctr_16way) @@ -758,6 +767,7 @@ ENTRY(serpent_xts_enc_16way) * %rdx: src (16 blocks) * %rcx: iv (t ⊕ αⁿ ∈ GF(2¹²⁸)) */ + FRAME_BEGIN vzeroupper; @@ -772,6 +782,7 @@ ENTRY(serpent_xts_enc_16way) vzeroupper; + FRAME_END ret; ENDPROC(serpent_xts_enc_16way) @@ -782,6 +793,7 @@ ENTRY(serpent_xts_dec_16way) * %rdx: src (16 blocks) * %rcx: iv (t ⊕ αⁿ ∈ GF(2¹²⁸)) */ + FRAME_BEGIN vzeroupper; @@ -796,5 +808,6 @@ ENTRY(serpent_xts_dec_16way) vzeroupper; + FRAME_END ret; ENDPROC(serpent_xts_dec_16way) diff --git a/arch/x86/crypto/sha-mb/sha1_mb_mgr_flush_avx2.S b/arch/x86/crypto/sha-mb/sha1_mb_mgr_flush_avx2.S index 85c4e1cf717235b8fc1cafcef458c386b84b8f66..96df6a39d7e240d241d1c46077a1336d2717f80d 100644 --- a/arch/x86/crypto/sha-mb/sha1_mb_mgr_flush_avx2.S +++ b/arch/x86/crypto/sha-mb/sha1_mb_mgr_flush_avx2.S @@ -52,6 +52,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include +#include #include "sha1_mb_mgr_datastruct.S" @@ -86,16 +87,6 @@ #define extra_blocks %arg2 #define p %arg2 - -# STACK_SPACE needs to be an odd multiple of 8 -_XMM_SAVE_SIZE = 10*16 -_GPR_SAVE_SIZE = 8*8 -_ALIGN_SIZE = 8 - -_XMM_SAVE = 0 -_GPR_SAVE = _XMM_SAVE + _XMM_SAVE_SIZE -STACK_SPACE = _GPR_SAVE + _GPR_SAVE_SIZE + _ALIGN_SIZE - .macro LABEL prefix n \prefix\n\(): .endm @@ -113,16 +104,8 @@ offset = \_offset # JOB* sha1_mb_mgr_flush_avx2(MB_MGR *state) # arg 1 : rcx : state ENTRY(sha1_mb_mgr_flush_avx2) - mov %rsp, %r10 - sub $STACK_SPACE, %rsp - and $~31, %rsp - mov %rbx, _GPR_SAVE(%rsp) - mov %r10, _GPR_SAVE+8*1(%rsp) #save rsp - mov %rbp, _GPR_SAVE+8*3(%rsp) - mov %r12, _GPR_SAVE+8*4(%rsp) - mov %r13, _GPR_SAVE+8*5(%rsp) - mov %r14, _GPR_SAVE+8*6(%rsp) - mov %r15, _GPR_SAVE+8*7(%rsp) + FRAME_BEGIN + push %rbx # If bit (32+3) is set, then all lanes are empty mov _unused_lanes(state), unused_lanes @@ -230,16 +213,8 @@ len_is_0: mov tmp2_w, offset(job_rax) return: - - mov _GPR_SAVE(%rsp), %rbx - mov _GPR_SAVE+8*1(%rsp), %r10 #saved rsp - mov _GPR_SAVE+8*3(%rsp), %rbp - mov _GPR_SAVE+8*4(%rsp), %r12 - mov _GPR_SAVE+8*5(%rsp), %r13 - mov _GPR_SAVE+8*6(%rsp), %r14 - mov _GPR_SAVE+8*7(%rsp), %r15 - mov %r10, %rsp - + pop %rbx + FRAME_END ret return_null: diff --git a/arch/x86/crypto/sha-mb/sha1_mb_mgr_submit_avx2.S b/arch/x86/crypto/sha-mb/sha1_mb_mgr_submit_avx2.S index c420d89b175f046491bf0e44d1cf2b22c1541fe2..63a0d9c8e31f7b5b94d526d051e9efce2090cacb 100644 --- a/arch/x86/crypto/sha-mb/sha1_mb_mgr_submit_avx2.S +++ b/arch/x86/crypto/sha-mb/sha1_mb_mgr_submit_avx2.S @@ -53,6 +53,7 @@ */ #include +#include #include "sha1_mb_mgr_datastruct.S" @@ -86,33 +87,21 @@ job_rax = %rax len = %rax DWORD_len = %eax -lane = %rbp -tmp3 = %rbp +lane = %r12 +tmp3 = %r12 tmp = %r9 DWORD_tmp = %r9d lane_data = %r10 -# STACK_SPACE needs to be an odd multiple of 8 -STACK_SPACE = 8*8 + 16*10 + 8 - # JOB* submit_mb_mgr_submit_avx2(MB_MGR *state, job_sha1 *job) # arg 1 : rcx : state # arg 2 : rdx : job ENTRY(sha1_mb_mgr_submit_avx2) - - mov %rsp, %r10 - sub $STACK_SPACE, %rsp - and $~31, %rsp - - mov %rbx, (%rsp) - mov %r10, 8*2(%rsp) #save old rsp - mov %rbp, 8*3(%rsp) - mov %r12, 8*4(%rsp) - mov %r13, 8*5(%rsp) - mov %r14, 8*6(%rsp) - mov %r15, 8*7(%rsp) + FRAME_BEGIN + push %rbx + push %r12 mov _unused_lanes(state), unused_lanes mov unused_lanes, lane @@ -203,16 +192,9 @@ len_is_0: movl DWORD_tmp, _result_digest+1*16(job_rax) return: - - mov (%rsp), %rbx - mov 8*2(%rsp), %r10 #save old rsp - mov 8*3(%rsp), %rbp - mov 8*4(%rsp), %r12 - mov 8*5(%rsp), %r13 - mov 8*6(%rsp), %r14 - mov 8*7(%rsp), %r15 - mov %r10, %rsp - + pop %r12 + pop %rbx + FRAME_END ret return_null: diff --git a/arch/x86/crypto/twofish-avx-x86_64-asm_64.S b/arch/x86/crypto/twofish-avx-x86_64-asm_64.S index 05058134c443176ec717cbdec6eb50235530fb03..dc66273e610d972d54efbd3f4b6b6f865015c92b 100644 --- a/arch/x86/crypto/twofish-avx-x86_64-asm_64.S +++ b/arch/x86/crypto/twofish-avx-x86_64-asm_64.S @@ -24,6 +24,7 @@ */ #include +#include #include "glue_helper-asm-avx.S" .file "twofish-avx-x86_64-asm_64.S" @@ -333,6 +334,7 @@ ENTRY(twofish_ecb_enc_8way) * %rsi: dst * %rdx: src */ + FRAME_BEGIN movq %rsi, %r11; @@ -342,6 +344,7 @@ ENTRY(twofish_ecb_enc_8way) store_8way(%r11, RC1, RD1, RA1, RB1, RC2, RD2, RA2, RB2); + FRAME_END ret; ENDPROC(twofish_ecb_enc_8way) @@ -351,6 +354,7 @@ ENTRY(twofish_ecb_dec_8way) * %rsi: dst * %rdx: src */ + FRAME_BEGIN movq %rsi, %r11; @@ -360,6 +364,7 @@ ENTRY(twofish_ecb_dec_8way) store_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); + FRAME_END ret; ENDPROC(twofish_ecb_dec_8way) @@ -369,6 +374,7 @@ ENTRY(twofish_cbc_dec_8way) * %rsi: dst * %rdx: src */ + FRAME_BEGIN pushq %r12; @@ -383,6 +389,7 @@ ENTRY(twofish_cbc_dec_8way) popq %r12; + FRAME_END ret; ENDPROC(twofish_cbc_dec_8way) @@ -393,6 +400,7 @@ ENTRY(twofish_ctr_8way) * %rdx: src * %rcx: iv (little endian, 128bit) */ + FRAME_BEGIN pushq %r12; @@ -408,6 +416,7 @@ ENTRY(twofish_ctr_8way) popq %r12; + FRAME_END ret; ENDPROC(twofish_ctr_8way) @@ -418,6 +427,7 @@ ENTRY(twofish_xts_enc_8way) * %rdx: src * %rcx: iv (t ⊕ αⁿ ∈ GF(2¹²⁸)) */ + FRAME_BEGIN movq %rsi, %r11; @@ -430,6 +440,7 @@ ENTRY(twofish_xts_enc_8way) /* dst <= regs xor IVs(in dst) */ store_xts_8way(%r11, RC1, RD1, RA1, RB1, RC2, RD2, RA2, RB2); + FRAME_END ret; ENDPROC(twofish_xts_enc_8way) @@ -440,6 +451,7 @@ ENTRY(twofish_xts_dec_8way) * %rdx: src * %rcx: iv (t ⊕ αⁿ ∈ GF(2¹²⁸)) */ + FRAME_BEGIN movq %rsi, %r11; @@ -452,5 +464,6 @@ ENTRY(twofish_xts_dec_8way) /* dst <= regs xor IVs(in dst) */ store_xts_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2); + FRAME_END ret; ENDPROC(twofish_xts_dec_8way) diff --git a/arch/x86/entry/Makefile b/arch/x86/entry/Makefile index bd55dedd7614aee2c38e5793a47c66197403f34c..fe91c25092da2662b67413a154e446843e7d5f7a 100644 --- a/arch/x86/entry/Makefile +++ b/arch/x86/entry/Makefile @@ -1,6 +1,10 @@ # # Makefile for the x86 low level entry code # + +OBJECT_FILES_NON_STANDARD_entry_$(BITS).o := y +OBJECT_FILES_NON_STANDARD_entry_64_compat.o := y + obj-y := entry_$(BITS).o thunk_$(BITS).o syscall_$(BITS).o obj-y += common.o diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl index cb713df81180ba91521296b4014b0ad2b74ee7d6..b30dd8154cc244080c395d8913b3ab4fed1cadb3 100644 --- a/arch/x86/entry/syscalls/syscall_32.tbl +++ b/arch/x86/entry/syscalls/syscall_32.tbl @@ -384,3 +384,5 @@ 375 i386 membarrier sys_membarrier 376 i386 mlock2 sys_mlock2 377 i386 copy_file_range sys_copy_file_range +378 i386 preadv2 sys_preadv2 +379 i386 pwritev2 sys_pwritev2 diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl index 2e5b565adacc542415854612ad752e04cfc5df95..cac6d17ce5db000ea008d63d5905acbd6fea21e0 100644 --- a/arch/x86/entry/syscalls/syscall_64.tbl +++ b/arch/x86/entry/syscalls/syscall_64.tbl @@ -333,6 +333,8 @@ 324 common membarrier sys_membarrier 325 common mlock2 sys_mlock2 326 common copy_file_range sys_copy_file_range +327 64 preadv2 sys_preadv2 +328 64 pwritev2 sys_pwritev2 # # x32-specific system call numbers start at 512 to avoid cache impact diff --git a/arch/x86/entry/thunk_64.S b/arch/x86/entry/thunk_64.S index efb2b932b7483419ec6921ac800506012e9030ae..98df1fa8825cdeeea525e9900839347eabbde53c 100644 --- a/arch/x86/entry/thunk_64.S +++ b/arch/x86/entry/thunk_64.S @@ -8,11 +8,14 @@ #include #include "calling.h" #include +#include /* rdi: arg1 ... normal C conventions. rax is saved/restored. */ .macro THUNK name, func, put_ret_addr_in_rdi=0 .globl \name + .type \name, @function \name: + FRAME_BEGIN /* this one pushes 9 elems, the next one would be %rIP */ pushq %rdi @@ -62,6 +65,7 @@ restore: popq %rdx popq %rsi popq %rdi + FRAME_END ret _ASM_NOKPROBE(restore) #endif diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile index c854541d93ff66d71fa8b38d0d4f7f1ed9e16c15..6874da5f67fcf38b3b50c0274bb7a104f35ecdbf 100644 --- a/arch/x86/entry/vdso/Makefile +++ b/arch/x86/entry/vdso/Makefile @@ -3,8 +3,12 @@ # KBUILD_CFLAGS += $(DISABLE_LTO) -KASAN_SANITIZE := n -UBSAN_SANITIZE := n +KASAN_SANITIZE := n +UBSAN_SANITIZE := n +OBJECT_FILES_NON_STANDARD := y + +# Prevents link failures: __sanitizer_cov_trace_pc() is not linked in. +KCOV_INSTRUMENT := n VDSO64-$(CONFIG_X86_64) := y VDSOX32-$(CONFIG_X86_X32_ABI) := y @@ -16,6 +20,7 @@ vobjs-y := vdso-note.o vclock_gettime.o vgetcpu.o # files to link into kernel obj-y += vma.o +OBJECT_FILES_NON_STANDARD_vma.o := n # vDSO images to build vdso_img-$(VDSO64-y) += 64 diff --git a/arch/x86/entry/vdso/vclock_gettime.c b/arch/x86/entry/vdso/vclock_gettime.c index 1a50e09c945bd41564a0ef94e43e3f19d8d05b88..03c3eb77bfcebce765b838271b6d7789365ff3de 100644 --- a/arch/x86/entry/vdso/vclock_gettime.c +++ b/arch/x86/entry/vdso/vclock_gettime.c @@ -178,7 +178,7 @@ notrace static cycle_t vread_tsc(void) /* * GCC likes to generate cmov here, but this branch is extremely - * predictable (it's just a funciton of time and the likely is + * predictable (it's just a function of time and the likely is * very likely) and there's a data dependence, so force GCC * to generate a branch instead. I don't barrier() because * we don't actually need a barrier, and if this function diff --git a/arch/x86/events/Makefile b/arch/x86/events/Makefile index fdfea1511cc0e10462fe5413fbd0ac8863caee9b..f59618a3999058515027f413e7691fa2f7cdbb02 100644 --- a/arch/x86/events/Makefile +++ b/arch/x86/events/Makefile @@ -1,6 +1,7 @@ obj-y += core.o obj-$(CONFIG_CPU_SUP_AMD) += amd/core.o amd/uncore.o +obj-$(CONFIG_PERF_EVENTS_AMD_POWER) += amd/power.o obj-$(CONFIG_X86_LOCAL_APIC) += amd/ibs.o msr.o ifdef CONFIG_AMD_IOMMU obj-$(CONFIG_CPU_SUP_AMD) += amd/iommu.o diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c index 049ada8d4e9c98b9c187b62528a55d9206a3d7cc..86a9bec18dab57950ea9af4201a670b99fe1db71 100644 --- a/arch/x86/events/amd/core.c +++ b/arch/x86/events/amd/core.c @@ -369,7 +369,7 @@ static int amd_pmu_cpu_prepare(int cpu) WARN_ON_ONCE(cpuc->amd_nb); - if (boot_cpu_data.x86_max_cores < 2) + if (!x86_pmu.amd_nb_constraints) return NOTIFY_OK; cpuc->amd_nb = amd_alloc_nb(cpu); @@ -388,7 +388,7 @@ static void amd_pmu_cpu_starting(int cpu) cpuc->perf_ctr_virt_mask = AMD64_EVENTSEL_HOSTONLY; - if (boot_cpu_data.x86_max_cores < 2) + if (!x86_pmu.amd_nb_constraints) return; nb_id = amd_get_nb_id(cpu); @@ -414,7 +414,7 @@ static void amd_pmu_cpu_dead(int cpu) { struct cpu_hw_events *cpuhw; - if (boot_cpu_data.x86_max_cores < 2) + if (!x86_pmu.amd_nb_constraints) return; cpuhw = &per_cpu(cpu_hw_events, cpu); @@ -648,6 +648,8 @@ static __initconst const struct x86_pmu amd_pmu = { .cpu_prepare = amd_pmu_cpu_prepare, .cpu_starting = amd_pmu_cpu_starting, .cpu_dead = amd_pmu_cpu_dead, + + .amd_nb_constraints = 1, }; static int __init amd_core_pmu_init(void) @@ -674,6 +676,11 @@ static int __init amd_core_pmu_init(void) x86_pmu.eventsel = MSR_F15H_PERF_CTL; x86_pmu.perfctr = MSR_F15H_PERF_CTR; x86_pmu.num_counters = AMD64_NUM_COUNTERS_CORE; + /* + * AMD Core perfctr has separate MSRs for the NB events, see + * the amd/uncore.c driver. + */ + x86_pmu.amd_nb_constraints = 0; pr_cont("core perfctr, "); return 0; @@ -693,6 +700,14 @@ __init int amd_pmu_init(void) if (ret) return ret; + if (num_possible_cpus() == 1) { + /* + * No point in allocating data structures to serialize + * against other CPUs, when there is only the one CPU. + */ + x86_pmu.amd_nb_constraints = 0; + } + /* Events are common for all AMDs */ memcpy(hw_cache_event_ids, amd_hw_cache_event_ids, sizeof(hw_cache_event_ids)); diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c index 51087c29b2c231906aa348fb9a78f046c81b2dc1..feb90f6730e8aebc06780090dcb6738750dd0a43 100644 --- a/arch/x86/events/amd/ibs.c +++ b/arch/x86/events/amd/ibs.c @@ -28,10 +28,46 @@ static u32 ibs_caps; #define IBS_FETCH_CONFIG_MASK (IBS_FETCH_RAND_EN | IBS_FETCH_MAX_CNT) #define IBS_OP_CONFIG_MASK IBS_OP_MAX_CNT + +/* + * IBS states: + * + * ENABLED; tracks the pmu::add(), pmu::del() state, when set the counter is taken + * and any further add()s must fail. + * + * STARTED/STOPPING/STOPPED; deal with pmu::start(), pmu::stop() state but are + * complicated by the fact that the IBS hardware can send late NMIs (ie. after + * we've cleared the EN bit). + * + * In order to consume these late NMIs we have the STOPPED state, any NMI that + * happens after we've cleared the EN state will clear this bit and report the + * NMI handled (this is fundamentally racy in the face or multiple NMI sources, + * someone else can consume our BIT and our NMI will go unhandled). + * + * And since we cannot set/clear this separate bit together with the EN bit, + * there are races; if we cleared STARTED early, an NMI could land in + * between clearing STARTED and clearing the EN bit (in fact multiple NMIs + * could happen if the period is small enough), and consume our STOPPED bit + * and trigger streams of unhandled NMIs. + * + * If, however, we clear STARTED late, an NMI can hit between clearing the + * EN bit and clearing STARTED, still see STARTED set and process the event. + * If this event will have the VALID bit clear, we bail properly, but this + * is not a given. With VALID set we can end up calling pmu::stop() again + * (the throttle logic) and trigger the WARNs in there. + * + * So what we do is set STOPPING before clearing EN to avoid the pmu::stop() + * nesting, and clear STARTED late, so that we have a well defined state over + * the clearing of the EN bit. + * + * XXX: we could probably be using !atomic bitops for all this. + */ + enum ibs_states { IBS_ENABLED = 0, IBS_STARTED = 1, IBS_STOPPING = 2, + IBS_STOPPED = 3, IBS_MAX_STATES, }; @@ -376,7 +412,12 @@ static void perf_ibs_start(struct perf_event *event, int flags) hwc->state = 0; perf_ibs_set_period(perf_ibs, hwc, &period); - set_bit(IBS_STARTED, pcpu->state); + /* + * Set STARTED before enabling the hardware, such that a subsequent NMI + * must observe it. + */ + set_bit(IBS_STARTED, pcpu->state); + clear_bit(IBS_STOPPING, pcpu->state); perf_ibs_enable_event(perf_ibs, hwc, period >> 4); perf_event_update_userpage(event); @@ -390,7 +431,10 @@ static void perf_ibs_stop(struct perf_event *event, int flags) u64 config; int stopping; - stopping = test_and_clear_bit(IBS_STARTED, pcpu->state); + if (test_and_set_bit(IBS_STOPPING, pcpu->state)) + return; + + stopping = test_bit(IBS_STARTED, pcpu->state); if (!stopping && (hwc->state & PERF_HES_UPTODATE)) return; @@ -398,8 +442,24 @@ static void perf_ibs_stop(struct perf_event *event, int flags) rdmsrl(hwc->config_base, config); if (stopping) { - set_bit(IBS_STOPPING, pcpu->state); + /* + * Set STOPPED before disabling the hardware, such that it + * must be visible to NMIs the moment we clear the EN bit, + * at which point we can generate an !VALID sample which + * we need to consume. + */ + set_bit(IBS_STOPPED, pcpu->state); perf_ibs_disable_event(perf_ibs, hwc, config); + /* + * Clear STARTED after disabling the hardware; if it were + * cleared before an NMI hitting after the clear but before + * clearing the EN bit might think it a spurious NMI and not + * handle it. + * + * Clearing it after, however, creates the problem of the NMI + * handler seeing STARTED but not having a valid sample. + */ + clear_bit(IBS_STARTED, pcpu->state); WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED); hwc->state |= PERF_HES_STOPPED; } @@ -527,20 +587,24 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs) u64 *buf, *config, period; if (!test_bit(IBS_STARTED, pcpu->state)) { +fail: /* * Catch spurious interrupts after stopping IBS: After * disabling IBS there could be still incoming NMIs * with samples that even have the valid bit cleared. * Mark all this NMIs as handled. */ - return test_and_clear_bit(IBS_STOPPING, pcpu->state) ? 1 : 0; + if (test_and_clear_bit(IBS_STOPPED, pcpu->state)) + return 1; + + return 0; } msr = hwc->config_base; buf = ibs_data.regs; rdmsrl(msr, *buf); if (!(*buf++ & perf_ibs->valid_mask)) - return 0; + goto fail; config = &ibs_data.regs[0]; perf_ibs_event_update(perf_ibs, event, config); @@ -599,7 +663,7 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs) throttle = perf_event_overflow(event, &data, ®s); out: if (throttle) - perf_ibs_disable_event(perf_ibs, hwc, *config); + perf_ibs_stop(event, 0); else perf_ibs_enable_event(perf_ibs, hwc, period >> 4); @@ -611,6 +675,7 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs) static int perf_ibs_nmi_handler(unsigned int cmd, struct pt_regs *regs) { + u64 stamp = sched_clock(); int handled = 0; handled += perf_ibs_handle_irq(&perf_ibs_fetch, regs); @@ -619,6 +684,8 @@ perf_ibs_nmi_handler(unsigned int cmd, struct pt_regs *regs) if (handled) inc_irq_stat(apic_perf_irqs); + perf_sample_event_took(sched_clock() - stamp); + return handled; } NOKPROBE_SYMBOL(perf_ibs_nmi_handler); diff --git a/arch/x86/events/amd/iommu.c b/arch/x86/events/amd/iommu.c index 635e5eba0caf87f432d97bcf178db025e5cb4cca..40625ca7a190953fc87c386a03017bab96903435 100644 --- a/arch/x86/events/amd/iommu.c +++ b/arch/x86/events/amd/iommu.c @@ -118,6 +118,11 @@ static struct amd_iommu_event_desc amd_iommu_v2_event_descs[] = { AMD_IOMMU_EVENT_DESC(cmd_processed, "csource=0x11"), AMD_IOMMU_EVENT_DESC(cmd_processed_inv, "csource=0x12"), AMD_IOMMU_EVENT_DESC(tlb_inv, "csource=0x13"), + AMD_IOMMU_EVENT_DESC(ign_rd_wr_mmio_1ff8h, "csource=0x14"), + AMD_IOMMU_EVENT_DESC(vapic_int_non_guest, "csource=0x15"), + AMD_IOMMU_EVENT_DESC(vapic_int_guest, "csource=0x16"), + AMD_IOMMU_EVENT_DESC(smi_recv, "csource=0x17"), + AMD_IOMMU_EVENT_DESC(smi_blk, "csource=0x18"), { /* end: all zeroes */ }, }; diff --git a/arch/x86/events/amd/power.c b/arch/x86/events/amd/power.c new file mode 100644 index 0000000000000000000000000000000000000000..55a3529dbf127ece3a6dbfcac930ccee5e6c9562 --- /dev/null +++ b/arch/x86/events/amd/power.c @@ -0,0 +1,353 @@ +/* + * Performance events - AMD Processor Power Reporting Mechanism + * + * Copyright (C) 2016 Advanced Micro Devices, Inc. + * + * Author: Huang Rui + * + * 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 "../perf_event.h" + +#define MSR_F15H_CU_PWR_ACCUMULATOR 0xc001007a +#define MSR_F15H_CU_MAX_PWR_ACCUMULATOR 0xc001007b +#define MSR_F15H_PTSC 0xc0010280 + +/* Event code: LSB 8 bits, passed in attr->config any other bit is reserved. */ +#define AMD_POWER_EVENT_MASK 0xFFULL + +/* + * Accumulated power status counters. + */ +#define AMD_POWER_EVENTSEL_PKG 1 + +/* + * The ratio of compute unit power accumulator sample period to the + * PTSC period. + */ +static unsigned int cpu_pwr_sample_ratio; + +/* Maximum accumulated power of a compute unit. */ +static u64 max_cu_acc_power; + +static struct pmu pmu_class; + +/* + * Accumulated power represents the sum of each compute unit's (CU) power + * consumption. On any core of each CU we read the total accumulated power from + * MSR_F15H_CU_PWR_ACCUMULATOR. cpu_mask represents CPU bit map of all cores + * which are picked to measure the power for the CUs they belong to. + */ +static cpumask_t cpu_mask; + +static void event_update(struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + u64 prev_pwr_acc, new_pwr_acc, prev_ptsc, new_ptsc; + u64 delta, tdelta; + + prev_pwr_acc = hwc->pwr_acc; + prev_ptsc = hwc->ptsc; + rdmsrl(MSR_F15H_CU_PWR_ACCUMULATOR, new_pwr_acc); + rdmsrl(MSR_F15H_PTSC, new_ptsc); + + /* + * Calculate the CU power consumption over a time period, the unit of + * final value (delta) is micro-Watts. Then add it to the event count. + */ + if (new_pwr_acc < prev_pwr_acc) { + delta = max_cu_acc_power + new_pwr_acc; + delta -= prev_pwr_acc; + } else + delta = new_pwr_acc - prev_pwr_acc; + + delta *= cpu_pwr_sample_ratio * 1000; + tdelta = new_ptsc - prev_ptsc; + + do_div(delta, tdelta); + local64_add(delta, &event->count); +} + +static void __pmu_event_start(struct perf_event *event) +{ + if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED))) + return; + + event->hw.state = 0; + + rdmsrl(MSR_F15H_PTSC, event->hw.ptsc); + rdmsrl(MSR_F15H_CU_PWR_ACCUMULATOR, event->hw.pwr_acc); +} + +static void pmu_event_start(struct perf_event *event, int mode) +{ + __pmu_event_start(event); +} + +static void pmu_event_stop(struct perf_event *event, int mode) +{ + struct hw_perf_event *hwc = &event->hw; + + /* Mark event as deactivated and stopped. */ + if (!(hwc->state & PERF_HES_STOPPED)) + hwc->state |= PERF_HES_STOPPED; + + /* Check if software counter update is necessary. */ + if ((mode & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) { + /* + * Drain the remaining delta count out of an event + * that we are disabling: + */ + event_update(event); + hwc->state |= PERF_HES_UPTODATE; + } +} + +static int pmu_event_add(struct perf_event *event, int mode) +{ + struct hw_perf_event *hwc = &event->hw; + + hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED; + + if (mode & PERF_EF_START) + __pmu_event_start(event); + + return 0; +} + +static void pmu_event_del(struct perf_event *event, int flags) +{ + pmu_event_stop(event, PERF_EF_UPDATE); +} + +static int pmu_event_init(struct perf_event *event) +{ + u64 cfg = event->attr.config & AMD_POWER_EVENT_MASK; + + /* Only look at AMD power events. */ + if (event->attr.type != pmu_class.type) + return -ENOENT; + + /* Unsupported modes and filters. */ + if (event->attr.exclude_user || + event->attr.exclude_kernel || + event->attr.exclude_hv || + event->attr.exclude_idle || + event->attr.exclude_host || + event->attr.exclude_guest || + /* no sampling */ + event->attr.sample_period) + return -EINVAL; + + if (cfg != AMD_POWER_EVENTSEL_PKG) + return -EINVAL; + + return 0; +} + +static void pmu_event_read(struct perf_event *event) +{ + event_update(event); +} + +static ssize_t +get_attr_cpumask(struct device *dev, struct device_attribute *attr, char *buf) +{ + return cpumap_print_to_pagebuf(true, buf, &cpu_mask); +} + +static DEVICE_ATTR(cpumask, S_IRUGO, get_attr_cpumask, NULL); + +static struct attribute *pmu_attrs[] = { + &dev_attr_cpumask.attr, + NULL, +}; + +static struct attribute_group pmu_attr_group = { + .attrs = pmu_attrs, +}; + +/* + * Currently it only supports to report the power of each + * processor/package. + */ +EVENT_ATTR_STR(power-pkg, power_pkg, "event=0x01"); + +EVENT_ATTR_STR(power-pkg.unit, power_pkg_unit, "mWatts"); + +/* Convert the count from micro-Watts to milli-Watts. */ +EVENT_ATTR_STR(power-pkg.scale, power_pkg_scale, "1.000000e-3"); + +static struct attribute *events_attr[] = { + EVENT_PTR(power_pkg), + EVENT_PTR(power_pkg_unit), + EVENT_PTR(power_pkg_scale), + NULL, +}; + +static struct attribute_group pmu_events_group = { + .name = "events", + .attrs = events_attr, +}; + +PMU_FORMAT_ATTR(event, "config:0-7"); + +static struct attribute *formats_attr[] = { + &format_attr_event.attr, + NULL, +}; + +static struct attribute_group pmu_format_group = { + .name = "format", + .attrs = formats_attr, +}; + +static const struct attribute_group *attr_groups[] = { + &pmu_attr_group, + &pmu_format_group, + &pmu_events_group, + NULL, +}; + +static struct pmu pmu_class = { + .attr_groups = attr_groups, + /* system-wide only */ + .task_ctx_nr = perf_invalid_context, + .event_init = pmu_event_init, + .add = pmu_event_add, + .del = pmu_event_del, + .start = pmu_event_start, + .stop = pmu_event_stop, + .read = pmu_event_read, +}; + +static void power_cpu_exit(int cpu) +{ + int target; + + if (!cpumask_test_and_clear_cpu(cpu, &cpu_mask)) + return; + + /* + * Find a new CPU on the same compute unit, if was set in cpumask + * and still some CPUs on compute unit. Then migrate event and + * context to new CPU. + */ + target = cpumask_any_but(topology_sibling_cpumask(cpu), cpu); + if (target < nr_cpumask_bits) { + cpumask_set_cpu(target, &cpu_mask); + perf_pmu_migrate_context(&pmu_class, cpu, target); + } +} + +static void power_cpu_init(int cpu) +{ + int target; + + /* + * 1) If any CPU is set at cpu_mask in the same compute unit, do + * nothing. + * 2) If no CPU is set at cpu_mask in the same compute unit, + * set current STARTING CPU. + * + * Note: if there is a CPU aside of the new one already in the + * sibling mask, then it is also in cpu_mask. + */ + target = cpumask_any_but(topology_sibling_cpumask(cpu), cpu); + if (target >= nr_cpumask_bits) + cpumask_set_cpu(cpu, &cpu_mask); +} + +static int +power_cpu_notifier(struct notifier_block *self, unsigned long action, void *hcpu) +{ + unsigned int cpu = (long)hcpu; + + switch (action & ~CPU_TASKS_FROZEN) { + case CPU_DOWN_FAILED: + case CPU_STARTING: + power_cpu_init(cpu); + break; + case CPU_DOWN_PREPARE: + power_cpu_exit(cpu); + break; + default: + break; + } + + return NOTIFY_OK; +} + +static struct notifier_block power_cpu_notifier_nb = { + .notifier_call = power_cpu_notifier, + .priority = CPU_PRI_PERF, +}; + +static const struct x86_cpu_id cpu_match[] = { + { .vendor = X86_VENDOR_AMD, .family = 0x15 }, + {}, +}; + +static int __init amd_power_pmu_init(void) +{ + int cpu, target, ret; + + if (!x86_match_cpu(cpu_match)) + return 0; + + if (!boot_cpu_has(X86_FEATURE_ACC_POWER)) + return -ENODEV; + + cpu_pwr_sample_ratio = cpuid_ecx(0x80000007); + + if (rdmsrl_safe(MSR_F15H_CU_MAX_PWR_ACCUMULATOR, &max_cu_acc_power)) { + pr_err("Failed to read max compute unit power accumulator MSR\n"); + return -ENODEV; + } + + cpu_notifier_register_begin(); + + /* Choose one online core of each compute unit. */ + for_each_online_cpu(cpu) { + target = cpumask_first(topology_sibling_cpumask(cpu)); + if (!cpumask_test_cpu(target, &cpu_mask)) + cpumask_set_cpu(target, &cpu_mask); + } + + ret = perf_pmu_register(&pmu_class, "power", -1); + if (WARN_ON(ret)) { + pr_warn("AMD Power PMU registration failed\n"); + goto out; + } + + __register_cpu_notifier(&power_cpu_notifier_nb); + + pr_info("AMD Power PMU detected\n"); + +out: + cpu_notifier_register_done(); + + return ret; +} +module_init(amd_power_pmu_init); + +static void __exit amd_power_pmu_exit(void) +{ + cpu_notifier_register_begin(); + __unregister_cpu_notifier(&power_cpu_notifier_nb); + cpu_notifier_register_done(); + + perf_pmu_unregister(&pmu_class); +} +module_exit(amd_power_pmu_exit); + +MODULE_AUTHOR("Huang Rui "); +MODULE_DESCRIPTION("AMD Processor Power Reporting Mechanism"); +MODULE_LICENSE("GPL v2"); diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c index 5e830d0c95c999780bae39ecc1ce84c003fa1ece..041e442a3e2806ed884584758cb8e62abd809e36 100644 --- a/arch/x86/events/core.c +++ b/arch/x86/events/core.c @@ -1602,8 +1602,7 @@ __init struct attribute **merge_attr(struct attribute **a, struct attribute **b) return new; } -ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr, - char *page) +ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr, char *page) { struct perf_pmu_events_attr *pmu_attr = \ container_of(attr, struct perf_pmu_events_attr, attr); @@ -1615,6 +1614,7 @@ ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr, return x86_pmu.events_sysfs_show(page, config); } +EXPORT_SYMBOL_GPL(events_sysfs_show); EVENT_ATTR(cpu-cycles, CPU_CYCLES ); EVENT_ATTR(instructions, INSTRUCTIONS ); @@ -2194,11 +2194,11 @@ static int backtrace_stack(void *data, char *name) return 0; } -static void backtrace_address(void *data, unsigned long addr, int reliable) +static int backtrace_address(void *data, unsigned long addr, int reliable) { struct perf_callchain_entry *entry = data; - perf_callchain_store(entry, addr); + return perf_callchain_store(entry, addr); } static const struct stacktrace_ops backtrace_ops = { diff --git a/arch/x86/events/intel/cqm.c b/arch/x86/events/intel/cqm.c index 93cb412a55792fbc68f2460da7295c77098e4532..7b5fd811ef456a189f0271ad08f5044adb1b266f 100644 --- a/arch/x86/events/intel/cqm.c +++ b/arch/x86/events/intel/cqm.c @@ -13,8 +13,16 @@ #define MSR_IA32_QM_CTR 0x0c8e #define MSR_IA32_QM_EVTSEL 0x0c8d +#define MBM_CNTR_WIDTH 24 +/* + * Guaranteed time in ms as per SDM where MBM counters will not overflow. + */ +#define MBM_CTR_OVERFLOW_TIME 1000 + static u32 cqm_max_rmid = -1; static unsigned int cqm_l3_scale; /* supposedly cacheline size */ +static bool cqm_enabled, mbm_enabled; +unsigned int mbm_socket_max; /** * struct intel_pqr_state - State cache for the PQR MSR @@ -42,7 +50,36 @@ struct intel_pqr_state { * interrupts disabled, which is sufficient for the protection. */ static DEFINE_PER_CPU(struct intel_pqr_state, pqr_state); +static struct hrtimer *mbm_timers; +/** + * struct sample - mbm event's (local or total) data + * @total_bytes #bytes since we began monitoring + * @prev_msr previous value of MSR + */ +struct sample { + u64 total_bytes; + u64 prev_msr; +}; +/* + * samples profiled for total memory bandwidth type events + */ +static struct sample *mbm_total; +/* + * samples profiled for local memory bandwidth type events + */ +static struct sample *mbm_local; + +#define pkg_id topology_physical_package_id(smp_processor_id()) +/* + * rmid_2_index returns the index for the rmid in mbm_local/mbm_total array. + * mbm_total[] and mbm_local[] are linearly indexed by socket# * max number of + * rmids per socket, an example is given below + * RMID1 of Socket0: vrmid = 1 + * RMID1 of Socket1: vrmid = 1 * (cqm_max_rmid + 1) + 1 + * RMID1 of Socket2: vrmid = 2 * (cqm_max_rmid + 1) + 1 + */ +#define rmid_2_index(rmid) ((pkg_id * (cqm_max_rmid + 1)) + rmid) /* * Protects cache_cgroups and cqm_rmid_free_lru and cqm_rmid_limbo_lru. * Also protects event->hw.cqm_rmid @@ -65,9 +102,13 @@ static cpumask_t cqm_cpumask; #define RMID_VAL_ERROR (1ULL << 63) #define RMID_VAL_UNAVAIL (1ULL << 62) -#define QOS_L3_OCCUP_EVENT_ID (1 << 0) - -#define QOS_EVENT_MASK QOS_L3_OCCUP_EVENT_ID +/* + * Event IDs are used to program IA32_QM_EVTSEL before reading event + * counter from IA32_QM_CTR + */ +#define QOS_L3_OCCUP_EVENT_ID 0x01 +#define QOS_MBM_TOTAL_EVENT_ID 0x02 +#define QOS_MBM_LOCAL_EVENT_ID 0x03 /* * This is central to the rotation algorithm in __intel_cqm_rmid_rotate(). @@ -211,6 +252,21 @@ static void __put_rmid(u32 rmid) list_add_tail(&entry->list, &cqm_rmid_limbo_lru); } +static void cqm_cleanup(void) +{ + int i; + + if (!cqm_rmid_ptrs) + return; + + for (i = 0; i < cqm_max_rmid; i++) + kfree(cqm_rmid_ptrs[i]); + + kfree(cqm_rmid_ptrs); + cqm_rmid_ptrs = NULL; + cqm_enabled = false; +} + static int intel_cqm_setup_rmid_cache(void) { struct cqm_rmid_entry *entry; @@ -218,7 +274,7 @@ static int intel_cqm_setup_rmid_cache(void) int r = 0; nr_rmids = cqm_max_rmid + 1; - cqm_rmid_ptrs = kmalloc(sizeof(struct cqm_rmid_entry *) * + cqm_rmid_ptrs = kzalloc(sizeof(struct cqm_rmid_entry *) * nr_rmids, GFP_KERNEL); if (!cqm_rmid_ptrs) return -ENOMEM; @@ -249,11 +305,9 @@ static int intel_cqm_setup_rmid_cache(void) mutex_unlock(&cache_mutex); return 0; -fail: - while (r--) - kfree(cqm_rmid_ptrs[r]); - kfree(cqm_rmid_ptrs); +fail: + cqm_cleanup(); return -ENOMEM; } @@ -281,9 +335,13 @@ static bool __match_event(struct perf_event *a, struct perf_event *b) /* * Events that target same task are placed into the same cache group. + * Mark it as a multi event group, so that we update ->count + * for every event rather than just the group leader later. */ - if (a->hw.target == b->hw.target) + if (a->hw.target == b->hw.target) { + b->hw.is_group_event = true; return true; + } /* * Are we an inherited event? @@ -392,10 +450,26 @@ static bool __conflict_event(struct perf_event *a, struct perf_event *b) struct rmid_read { u32 rmid; + u32 evt_type; atomic64_t value; }; static void __intel_cqm_event_count(void *info); +static void init_mbm_sample(u32 rmid, u32 evt_type); +static void __intel_mbm_event_count(void *info); + +static bool is_mbm_event(int e) +{ + return (e >= QOS_MBM_TOTAL_EVENT_ID && e <= QOS_MBM_LOCAL_EVENT_ID); +} + +static void cqm_mask_call(struct rmid_read *rr) +{ + if (is_mbm_event(rr->evt_type)) + on_each_cpu_mask(&cqm_cpumask, __intel_mbm_event_count, rr, 1); + else + on_each_cpu_mask(&cqm_cpumask, __intel_cqm_event_count, rr, 1); +} /* * Exchange the RMID of a group of events. @@ -413,12 +487,12 @@ static u32 intel_cqm_xchg_rmid(struct perf_event *group, u32 rmid) */ if (__rmid_valid(old_rmid) && !__rmid_valid(rmid)) { struct rmid_read rr = { - .value = ATOMIC64_INIT(0), .rmid = old_rmid, + .evt_type = group->attr.config, + .value = ATOMIC64_INIT(0), }; - on_each_cpu_mask(&cqm_cpumask, __intel_cqm_event_count, - &rr, 1); + cqm_mask_call(&rr); local64_set(&group->count, atomic64_read(&rr.value)); } @@ -430,6 +504,22 @@ static u32 intel_cqm_xchg_rmid(struct perf_event *group, u32 rmid) raw_spin_unlock_irq(&cache_lock); + /* + * If the allocation is for mbm, init the mbm stats. + * Need to check if each event in the group is mbm event + * because there could be multiple type of events in the same group. + */ + if (__rmid_valid(rmid)) { + event = group; + if (is_mbm_event(event->attr.config)) + init_mbm_sample(rmid, event->attr.config); + + list_for_each_entry(event, head, hw.cqm_group_entry) { + if (is_mbm_event(event->attr.config)) + init_mbm_sample(rmid, event->attr.config); + } + } + return old_rmid; } @@ -837,6 +927,72 @@ static void intel_cqm_rmid_rotate(struct work_struct *work) schedule_delayed_work(&intel_cqm_rmid_work, delay); } +static u64 update_sample(unsigned int rmid, u32 evt_type, int first) +{ + struct sample *mbm_current; + u32 vrmid = rmid_2_index(rmid); + u64 val, bytes, shift; + u32 eventid; + + if (evt_type == QOS_MBM_LOCAL_EVENT_ID) { + mbm_current = &mbm_local[vrmid]; + eventid = QOS_MBM_LOCAL_EVENT_ID; + } else { + mbm_current = &mbm_total[vrmid]; + eventid = QOS_MBM_TOTAL_EVENT_ID; + } + + wrmsr(MSR_IA32_QM_EVTSEL, eventid, rmid); + rdmsrl(MSR_IA32_QM_CTR, val); + if (val & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL)) + return mbm_current->total_bytes; + + if (first) { + mbm_current->prev_msr = val; + mbm_current->total_bytes = 0; + return mbm_current->total_bytes; + } + + /* + * The h/w guarantees that counters will not overflow + * so long as we poll them at least once per second. + */ + shift = 64 - MBM_CNTR_WIDTH; + bytes = (val << shift) - (mbm_current->prev_msr << shift); + bytes >>= shift; + + bytes *= cqm_l3_scale; + + mbm_current->total_bytes += bytes; + mbm_current->prev_msr = val; + + return mbm_current->total_bytes; +} + +static u64 rmid_read_mbm(unsigned int rmid, u32 evt_type) +{ + return update_sample(rmid, evt_type, 0); +} + +static void __intel_mbm_event_init(void *info) +{ + struct rmid_read *rr = info; + + update_sample(rr->rmid, rr->evt_type, 1); +} + +static void init_mbm_sample(u32 rmid, u32 evt_type) +{ + struct rmid_read rr = { + .rmid = rmid, + .evt_type = evt_type, + .value = ATOMIC64_INIT(0), + }; + + /* on each socket, init sample */ + on_each_cpu_mask(&cqm_cpumask, __intel_mbm_event_init, &rr, 1); +} + /* * Find a group and setup RMID. * @@ -849,6 +1005,7 @@ static void intel_cqm_setup_event(struct perf_event *event, bool conflict = false; u32 rmid; + event->hw.is_group_event = false; list_for_each_entry(iter, &cache_groups, hw.cqm_groups_entry) { rmid = iter->hw.cqm_rmid; @@ -856,6 +1013,8 @@ static void intel_cqm_setup_event(struct perf_event *event, /* All tasks in a group share an RMID */ event->hw.cqm_rmid = rmid; *group = iter; + if (is_mbm_event(event->attr.config) && __rmid_valid(rmid)) + init_mbm_sample(rmid, event->attr.config); return; } @@ -872,6 +1031,9 @@ static void intel_cqm_setup_event(struct perf_event *event, else rmid = __get_rmid(); + if (is_mbm_event(event->attr.config) && __rmid_valid(rmid)) + init_mbm_sample(rmid, event->attr.config); + event->hw.cqm_rmid = rmid; } @@ -893,7 +1055,10 @@ static void intel_cqm_event_read(struct perf_event *event) if (!__rmid_valid(rmid)) goto out; - val = __rmid_read(rmid); + if (is_mbm_event(event->attr.config)) + val = rmid_read_mbm(rmid, event->attr.config); + else + val = __rmid_read(rmid); /* * Ignore this reading on error states and do not update the value. @@ -924,10 +1089,100 @@ static inline bool cqm_group_leader(struct perf_event *event) return !list_empty(&event->hw.cqm_groups_entry); } +static void __intel_mbm_event_count(void *info) +{ + struct rmid_read *rr = info; + u64 val; + + val = rmid_read_mbm(rr->rmid, rr->evt_type); + if (val & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL)) + return; + atomic64_add(val, &rr->value); +} + +static enum hrtimer_restart mbm_hrtimer_handle(struct hrtimer *hrtimer) +{ + struct perf_event *iter, *iter1; + int ret = HRTIMER_RESTART; + struct list_head *head; + unsigned long flags; + u32 grp_rmid; + + /* + * Need to cache_lock as the timer Event Select MSR reads + * can race with the mbm/cqm count() and mbm_init() reads. + */ + raw_spin_lock_irqsave(&cache_lock, flags); + + if (list_empty(&cache_groups)) { + ret = HRTIMER_NORESTART; + goto out; + } + + list_for_each_entry(iter, &cache_groups, hw.cqm_groups_entry) { + grp_rmid = iter->hw.cqm_rmid; + if (!__rmid_valid(grp_rmid)) + continue; + if (is_mbm_event(iter->attr.config)) + update_sample(grp_rmid, iter->attr.config, 0); + + head = &iter->hw.cqm_group_entry; + if (list_empty(head)) + continue; + list_for_each_entry(iter1, head, hw.cqm_group_entry) { + if (!iter1->hw.is_group_event) + break; + if (is_mbm_event(iter1->attr.config)) + update_sample(iter1->hw.cqm_rmid, + iter1->attr.config, 0); + } + } + + hrtimer_forward_now(hrtimer, ms_to_ktime(MBM_CTR_OVERFLOW_TIME)); +out: + raw_spin_unlock_irqrestore(&cache_lock, flags); + + return ret; +} + +static void __mbm_start_timer(void *info) +{ + hrtimer_start(&mbm_timers[pkg_id], ms_to_ktime(MBM_CTR_OVERFLOW_TIME), + HRTIMER_MODE_REL_PINNED); +} + +static void __mbm_stop_timer(void *info) +{ + hrtimer_cancel(&mbm_timers[pkg_id]); +} + +static void mbm_start_timers(void) +{ + on_each_cpu_mask(&cqm_cpumask, __mbm_start_timer, NULL, 1); +} + +static void mbm_stop_timers(void) +{ + on_each_cpu_mask(&cqm_cpumask, __mbm_stop_timer, NULL, 1); +} + +static void mbm_hrtimer_init(void) +{ + struct hrtimer *hr; + int i; + + for (i = 0; i < mbm_socket_max; i++) { + hr = &mbm_timers[i]; + hrtimer_init(hr, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + hr->function = mbm_hrtimer_handle; + } +} + static u64 intel_cqm_event_count(struct perf_event *event) { unsigned long flags; struct rmid_read rr = { + .evt_type = event->attr.config, .value = ATOMIC64_INIT(0), }; @@ -940,7 +1195,9 @@ static u64 intel_cqm_event_count(struct perf_event *event) return __perf_event_count(event); /* - * Only the group leader gets to report values. This stops us + * Only the group leader gets to report values except in case of + * multiple events in the same group, we still need to read the + * other events.This stops us * reporting duplicate values to userspace, and gives us a clear * rule for which task gets to report the values. * @@ -948,7 +1205,7 @@ static u64 intel_cqm_event_count(struct perf_event *event) * specific packages - we forfeit that ability when we create * task events. */ - if (!cqm_group_leader(event)) + if (!cqm_group_leader(event) && !event->hw.is_group_event) return 0; /* @@ -975,7 +1232,7 @@ static u64 intel_cqm_event_count(struct perf_event *event) if (!__rmid_valid(rr.rmid)) goto out; - on_each_cpu_mask(&cqm_cpumask, __intel_cqm_event_count, &rr, 1); + cqm_mask_call(&rr); raw_spin_lock_irqsave(&cache_lock, flags); if (event->hw.cqm_rmid == rr.rmid) @@ -1046,8 +1303,14 @@ static int intel_cqm_event_add(struct perf_event *event, int mode) static void intel_cqm_event_destroy(struct perf_event *event) { struct perf_event *group_other = NULL; + unsigned long flags; mutex_lock(&cache_mutex); + /* + * Hold the cache_lock as mbm timer handlers could be + * scanning the list of events. + */ + raw_spin_lock_irqsave(&cache_lock, flags); /* * If there's another event in this group... @@ -1079,6 +1342,14 @@ static void intel_cqm_event_destroy(struct perf_event *event) } } + raw_spin_unlock_irqrestore(&cache_lock, flags); + + /* + * Stop the mbm overflow timers when the last event is destroyed. + */ + if (mbm_enabled && list_empty(&cache_groups)) + mbm_stop_timers(); + mutex_unlock(&cache_mutex); } @@ -1086,11 +1357,13 @@ static int intel_cqm_event_init(struct perf_event *event) { struct perf_event *group = NULL; bool rotate = false; + unsigned long flags; if (event->attr.type != intel_cqm_pmu.type) return -ENOENT; - if (event->attr.config & ~QOS_EVENT_MASK) + if ((event->attr.config < QOS_L3_OCCUP_EVENT_ID) || + (event->attr.config > QOS_MBM_LOCAL_EVENT_ID)) return -EINVAL; /* unsupported modes and filters */ @@ -1110,9 +1383,21 @@ static int intel_cqm_event_init(struct perf_event *event) mutex_lock(&cache_mutex); + /* + * Start the mbm overflow timers when the first event is created. + */ + if (mbm_enabled && list_empty(&cache_groups)) + mbm_start_timers(); + /* Will also set rmid */ intel_cqm_setup_event(event, &group); + /* + * Hold the cache_lock as mbm timer handlers be + * scanning the list of events. + */ + raw_spin_lock_irqsave(&cache_lock, flags); + if (group) { list_add_tail(&event->hw.cqm_group_entry, &group->hw.cqm_group_entry); @@ -1131,6 +1416,7 @@ static int intel_cqm_event_init(struct perf_event *event) rotate = true; } + raw_spin_unlock_irqrestore(&cache_lock, flags); mutex_unlock(&cache_mutex); if (rotate) @@ -1145,6 +1431,16 @@ EVENT_ATTR_STR(llc_occupancy.unit, intel_cqm_llc_unit, "Bytes"); EVENT_ATTR_STR(llc_occupancy.scale, intel_cqm_llc_scale, NULL); EVENT_ATTR_STR(llc_occupancy.snapshot, intel_cqm_llc_snapshot, "1"); +EVENT_ATTR_STR(total_bytes, intel_cqm_total_bytes, "event=0x02"); +EVENT_ATTR_STR(total_bytes.per-pkg, intel_cqm_total_bytes_pkg, "1"); +EVENT_ATTR_STR(total_bytes.unit, intel_cqm_total_bytes_unit, "MB"); +EVENT_ATTR_STR(total_bytes.scale, intel_cqm_total_bytes_scale, "1e-6"); + +EVENT_ATTR_STR(local_bytes, intel_cqm_local_bytes, "event=0x03"); +EVENT_ATTR_STR(local_bytes.per-pkg, intel_cqm_local_bytes_pkg, "1"); +EVENT_ATTR_STR(local_bytes.unit, intel_cqm_local_bytes_unit, "MB"); +EVENT_ATTR_STR(local_bytes.scale, intel_cqm_local_bytes_scale, "1e-6"); + static struct attribute *intel_cqm_events_attr[] = { EVENT_PTR(intel_cqm_llc), EVENT_PTR(intel_cqm_llc_pkg), @@ -1154,9 +1450,38 @@ static struct attribute *intel_cqm_events_attr[] = { NULL, }; +static struct attribute *intel_mbm_events_attr[] = { + EVENT_PTR(intel_cqm_total_bytes), + EVENT_PTR(intel_cqm_local_bytes), + EVENT_PTR(intel_cqm_total_bytes_pkg), + EVENT_PTR(intel_cqm_local_bytes_pkg), + EVENT_PTR(intel_cqm_total_bytes_unit), + EVENT_PTR(intel_cqm_local_bytes_unit), + EVENT_PTR(intel_cqm_total_bytes_scale), + EVENT_PTR(intel_cqm_local_bytes_scale), + NULL, +}; + +static struct attribute *intel_cmt_mbm_events_attr[] = { + EVENT_PTR(intel_cqm_llc), + EVENT_PTR(intel_cqm_total_bytes), + EVENT_PTR(intel_cqm_local_bytes), + EVENT_PTR(intel_cqm_llc_pkg), + EVENT_PTR(intel_cqm_total_bytes_pkg), + EVENT_PTR(intel_cqm_local_bytes_pkg), + EVENT_PTR(intel_cqm_llc_unit), + EVENT_PTR(intel_cqm_total_bytes_unit), + EVENT_PTR(intel_cqm_local_bytes_unit), + EVENT_PTR(intel_cqm_llc_scale), + EVENT_PTR(intel_cqm_total_bytes_scale), + EVENT_PTR(intel_cqm_local_bytes_scale), + EVENT_PTR(intel_cqm_llc_snapshot), + NULL, +}; + static struct attribute_group intel_cqm_events_group = { .name = "events", - .attrs = intel_cqm_events_attr, + .attrs = NULL, }; PMU_FORMAT_ATTR(event, "config:0-7"); @@ -1303,12 +1628,70 @@ static const struct x86_cpu_id intel_cqm_match[] = { {} }; +static void mbm_cleanup(void) +{ + if (!mbm_enabled) + return; + + kfree(mbm_local); + kfree(mbm_total); + mbm_enabled = false; +} + +static const struct x86_cpu_id intel_mbm_local_match[] = { + { .vendor = X86_VENDOR_INTEL, .feature = X86_FEATURE_CQM_MBM_LOCAL }, + {} +}; + +static const struct x86_cpu_id intel_mbm_total_match[] = { + { .vendor = X86_VENDOR_INTEL, .feature = X86_FEATURE_CQM_MBM_TOTAL }, + {} +}; + +static int intel_mbm_init(void) +{ + int ret = 0, array_size, maxid = cqm_max_rmid + 1; + + mbm_socket_max = topology_max_packages(); + array_size = sizeof(struct sample) * maxid * mbm_socket_max; + mbm_local = kmalloc(array_size, GFP_KERNEL); + if (!mbm_local) + return -ENOMEM; + + mbm_total = kmalloc(array_size, GFP_KERNEL); + if (!mbm_total) { + ret = -ENOMEM; + goto out; + } + + array_size = sizeof(struct hrtimer) * mbm_socket_max; + mbm_timers = kmalloc(array_size, GFP_KERNEL); + if (!mbm_timers) { + ret = -ENOMEM; + goto out; + } + mbm_hrtimer_init(); + +out: + if (ret) + mbm_cleanup(); + + return ret; +} + static int __init intel_cqm_init(void) { - char *str, scale[20]; + char *str = NULL, scale[20]; int i, cpu, ret; - if (!x86_match_cpu(intel_cqm_match)) + if (x86_match_cpu(intel_cqm_match)) + cqm_enabled = true; + + if (x86_match_cpu(intel_mbm_local_match) && + x86_match_cpu(intel_mbm_total_match)) + mbm_enabled = true; + + if (!cqm_enabled && !mbm_enabled) return -ENODEV; cqm_l3_scale = boot_cpu_data.x86_cache_occ_scale; @@ -1365,16 +1748,41 @@ static int __init intel_cqm_init(void) cqm_pick_event_reader(i); } - __perf_cpu_notifier(intel_cqm_cpu_notifier); + if (mbm_enabled) + ret = intel_mbm_init(); + if (ret && !cqm_enabled) + goto out; + + if (cqm_enabled && mbm_enabled) + intel_cqm_events_group.attrs = intel_cmt_mbm_events_attr; + else if (!cqm_enabled && mbm_enabled) + intel_cqm_events_group.attrs = intel_mbm_events_attr; + else if (cqm_enabled && !mbm_enabled) + intel_cqm_events_group.attrs = intel_cqm_events_attr; ret = perf_pmu_register(&intel_cqm_pmu, "intel_cqm", -1); - if (ret) + if (ret) { pr_err("Intel CQM perf registration failed: %d\n", ret); - else + goto out; + } + + if (cqm_enabled) pr_info("Intel CQM monitoring enabled\n"); + if (mbm_enabled) + pr_info("Intel MBM enabled\n"); + /* + * Register the hot cpu notifier once we are sure cqm + * is enabled to avoid notifier leak. + */ + __perf_cpu_notifier(intel_cqm_cpu_notifier); out: cpu_notifier_register_done(); + if (ret) { + kfree(str); + cqm_cleanup(); + mbm_cleanup(); + } return ret; } diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c index ce7211a07c0b809767c88481d41127cd6f331b6d..8584b90d8e0bb08e8e9ddc3dd7b6f38dae5363c2 100644 --- a/arch/x86/events/intel/ds.c +++ b/arch/x86/events/intel/ds.c @@ -570,11 +570,12 @@ int intel_pmu_drain_bts_buffer(void) * We will overwrite the from and to address before we output * the sample. */ + rcu_read_lock(); perf_prepare_sample(&header, &data, event, ®s); if (perf_output_begin(&handle, event, header.size * (top - base - skip))) - return 1; + goto unlock; for (at = base; at < top; at++) { /* Filter out any records that contain kernel addresses. */ @@ -593,6 +594,8 @@ int intel_pmu_drain_bts_buffer(void) /* There's new data available. */ event->hw.interrupts++; event->pending_kill = POLL_IN; +unlock: + rcu_read_unlock(); return 1; } diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c index 69dd11887dd1e1a50d63405f1a508a3ed759e8cc..6c3b7c1780c983627d866584f4c2c6c2379cc65a 100644 --- a/arch/x86/events/intel/lbr.c +++ b/arch/x86/events/intel/lbr.c @@ -649,7 +649,7 @@ int intel_pmu_setup_lbr_filter(struct perf_event *event) /* * return the type of control flow change at address "from" - * intruction is not necessarily a branch (in case of interrupt). + * instruction is not necessarily a branch (in case of interrupt). * * The branch type returned also includes the priv level of the * target of the control flow change (X86_BR_USER, X86_BR_KERNEL). diff --git a/arch/x86/events/intel/rapl.c b/arch/x86/events/intel/rapl.c index b834a3f55a015b0cd2a45972a0e2bdde24c24dfa..70c93f9b03acc49e245154323b2b2787d362d76d 100644 --- a/arch/x86/events/intel/rapl.c +++ b/arch/x86/events/intel/rapl.c @@ -711,6 +711,7 @@ static int __init rapl_pmu_init(void) rapl_pmu_events_group.attrs = rapl_events_cln_attr; break; case 63: /* Haswell-Server */ + case 79: /* Broadwell-Server */ apply_quirk = true; rapl_cntr_mask = RAPL_IDX_SRV; rapl_pmu_events_group.attrs = rapl_events_srv_attr; @@ -718,6 +719,7 @@ static int __init rapl_pmu_init(void) case 60: /* Haswell */ case 69: /* Haswell-Celeron */ case 61: /* Broadwell */ + case 71: /* Broadwell-H */ rapl_cntr_mask = RAPL_IDX_HSW; rapl_pmu_events_group.attrs = rapl_events_hsw_attr; break; diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c index 93f6bd9bf7610ea204046368837d279ac1ce1c17..ab2bcaaebe38d464ab7863c901ac41fc7b847711 100644 --- a/arch/x86/events/intel/uncore_snbep.c +++ b/arch/x86/events/intel/uncore_snbep.c @@ -46,7 +46,6 @@ (SNBEP_PMON_CTL_EV_SEL_MASK | \ SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \ SNBEP_PMON_CTL_EDGE_DET | \ - SNBEP_PMON_CTL_EV_SEL_EXT | \ SNBEP_PMON_CTL_INVERT | \ SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK | \ SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \ @@ -148,7 +147,6 @@ /* IVBEP PCU */ #define IVBEP_PCU_MSR_PMON_RAW_EVENT_MASK \ (SNBEP_PMON_CTL_EV_SEL_MASK | \ - SNBEP_PMON_CTL_EV_SEL_EXT | \ SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \ SNBEP_PMON_CTL_EDGE_DET | \ SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK | \ @@ -258,7 +256,6 @@ SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \ SNBEP_PMON_CTL_EDGE_DET | \ SNBEP_CBO_PMON_CTL_TID_EN | \ - SNBEP_PMON_CTL_EV_SEL_EXT | \ SNBEP_PMON_CTL_INVERT | \ KNL_PCU_MSR_PMON_CTL_TRESH_MASK | \ SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \ @@ -472,7 +469,7 @@ static struct attribute *snbep_uncore_cbox_formats_attr[] = { }; static struct attribute *snbep_uncore_pcu_formats_attr[] = { - &format_attr_event_ext.attr, + &format_attr_event.attr, &format_attr_occ_sel.attr, &format_attr_edge.attr, &format_attr_inv.attr, @@ -1313,7 +1310,7 @@ static struct attribute *ivbep_uncore_cbox_formats_attr[] = { }; static struct attribute *ivbep_uncore_pcu_formats_attr[] = { - &format_attr_event_ext.attr, + &format_attr_event.attr, &format_attr_occ_sel.attr, &format_attr_edge.attr, &format_attr_thresh5.attr, diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h index 68155cafa8a13d88907493a4bf32f0e083189b73..ad4dc7ffffb5eb44eeb79c08e924697547f14ebd 100644 --- a/arch/x86/events/perf_event.h +++ b/arch/x86/events/perf_event.h @@ -272,7 +272,7 @@ struct cpu_hw_events { * events to select for counter rescheduling. * * Care must be taken as the rescheduling algorithm is O(n!) which - * will increase scheduling cycles for an over-commited system + * will increase scheduling cycles for an over-committed system * dramatically. The number of such EVENT_CONSTRAINT_OVERLAP() macros * and its counter masks must be kept at a minimum. */ @@ -607,6 +607,11 @@ struct x86_pmu { */ atomic_t lbr_exclusive[x86_lbr_exclusive_max]; + /* + * AMD bits + */ + unsigned int amd_nb_constraints : 1; + /* * Extra registers for events */ @@ -795,6 +800,9 @@ ssize_t intel_event_sysfs_show(char *page, u64 config); struct attribute **merge_attr(struct attribute **a, struct attribute **b); +ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr, + char *page); + #ifdef CONFIG_CPU_SUP_AMD int amd_pmu_init(void); @@ -925,9 +933,6 @@ int p6_pmu_init(void); int knc_pmu_init(void); -ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr, - char *page); - static inline int is_ht_workaround_enabled(void) { return !!(x86_pmu.flags & PMU_FL_EXCL_ENABLED); diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index 0899cfc8dfe8f84f98edc6a0c19e7ff40225ae74..98f25bbafac4c52c10e87dc8cd85e6e3914fa4d6 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -643,8 +643,8 @@ static inline void entering_irq(void) static inline void entering_ack_irq(void) { - ack_APIC_irq(); entering_irq(); + ack_APIC_irq(); } static inline void ipi_entering_ack_irq(void) diff --git a/arch/x86/include/asm/checksum_32.h b/arch/x86/include/asm/checksum_32.h index f50de69517384b712c1266a3c98626b888d6953a..532f85e6651f4e86060fd35add94431d78c20df3 100644 --- a/arch/x86/include/asm/checksum_32.h +++ b/arch/x86/include/asm/checksum_32.h @@ -112,8 +112,7 @@ static inline __sum16 csum_fold(__wsum sum) } static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, + __u32 len, __u8 proto, __wsum sum) { asm("addl %1, %0 ;\n" @@ -131,8 +130,7 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, * returns a 16-bit checksum, already complemented */ static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, + __u32 len, __u8 proto, __wsum sum) { return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum)); @@ -151,8 +149,7 @@ static inline __sum16 ip_compute_csum(const void *buff, int len) #define _HAVE_ARCH_IPV6_CSUM static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, - __u32 len, unsigned short proto, - __wsum sum) + __u32 len, __u8 proto, __wsum sum) { asm("addl 0(%1), %0 ;\n" "adcl 4(%1), %0 ;\n" diff --git a/arch/x86/include/asm/checksum_64.h b/arch/x86/include/asm/checksum_64.h index cd00e17744914c5b2e1d7d16da887a2809ebb5b5..c020ee75dce7757efae7232a3e2a0815619a42fc 100644 --- a/arch/x86/include/asm/checksum_64.h +++ b/arch/x86/include/asm/checksum_64.h @@ -84,8 +84,8 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) * 32bit unfolded. */ static inline __wsum -csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) +csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len, + __u8 proto, __wsum sum) { asm(" addl %1, %0\n" " adcl %2, %0\n" @@ -110,8 +110,8 @@ csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, * complemented and ready to be filled in. */ static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, __wsum sum) + __u32 len, __u8 proto, + __wsum sum) { return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum)); } @@ -177,7 +177,7 @@ struct in6_addr; #define _HAVE_ARCH_IPV6_CSUM 1 extern __sum16 csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, - __u32 len, unsigned short proto, __wsum sum); + __u32 len, __u8 proto, __wsum sum); static inline unsigned add32_with_carry(unsigned a, unsigned b) { diff --git a/arch/x86/include/asm/compat.h b/arch/x86/include/asm/compat.h index acdee09228b30e020332f0beb7e55e58e65b718e..ebb102e1bbc7ad84cff580de23380becbe900ed1 100644 --- a/arch/x86/include/asm/compat.h +++ b/arch/x86/include/asm/compat.h @@ -316,9 +316,10 @@ static inline bool is_x32_task(void) return false; } -static inline bool is_compat_task(void) +static inline bool in_compat_syscall(void) { return is_ia32_task() || is_x32_task(); } +#define in_compat_syscall in_compat_syscall /* override the generic impl */ #endif /* _ASM_X86_COMPAT_H */ diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index 68e4e8258b84126d59094ea1023568a8272dcdbd..3636ec06c88758ccf13793dd6a1d14c31bb7fc4e 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h @@ -26,6 +26,7 @@ enum cpuid_leafs CPUID_8000_0008_EBX, CPUID_6_EAX, CPUID_8000_000A_EDX, + CPUID_7_ECX, }; #ifdef CONFIG_X86_FEATURE_NAMES @@ -48,28 +49,42 @@ extern const char * const x86_bug_flags[NBUGINTS*32]; test_bit(bit, (unsigned long *)((c)->x86_capability)) #define REQUIRED_MASK_BIT_SET(bit) \ - ( (((bit)>>5)==0 && (1UL<<((bit)&31) & REQUIRED_MASK0)) || \ - (((bit)>>5)==1 && (1UL<<((bit)&31) & REQUIRED_MASK1)) || \ - (((bit)>>5)==2 && (1UL<<((bit)&31) & REQUIRED_MASK2)) || \ - (((bit)>>5)==3 && (1UL<<((bit)&31) & REQUIRED_MASK3)) || \ - (((bit)>>5)==4 && (1UL<<((bit)&31) & REQUIRED_MASK4)) || \ - (((bit)>>5)==5 && (1UL<<((bit)&31) & REQUIRED_MASK5)) || \ - (((bit)>>5)==6 && (1UL<<((bit)&31) & REQUIRED_MASK6)) || \ - (((bit)>>5)==7 && (1UL<<((bit)&31) & REQUIRED_MASK7)) || \ - (((bit)>>5)==8 && (1UL<<((bit)&31) & REQUIRED_MASK8)) || \ - (((bit)>>5)==9 && (1UL<<((bit)&31) & REQUIRED_MASK9)) ) + ( (((bit)>>5)==0 && (1UL<<((bit)&31) & REQUIRED_MASK0 )) || \ + (((bit)>>5)==1 && (1UL<<((bit)&31) & REQUIRED_MASK1 )) || \ + (((bit)>>5)==2 && (1UL<<((bit)&31) & REQUIRED_MASK2 )) || \ + (((bit)>>5)==3 && (1UL<<((bit)&31) & REQUIRED_MASK3 )) || \ + (((bit)>>5)==4 && (1UL<<((bit)&31) & REQUIRED_MASK4 )) || \ + (((bit)>>5)==5 && (1UL<<((bit)&31) & REQUIRED_MASK5 )) || \ + (((bit)>>5)==6 && (1UL<<((bit)&31) & REQUIRED_MASK6 )) || \ + (((bit)>>5)==7 && (1UL<<((bit)&31) & REQUIRED_MASK7 )) || \ + (((bit)>>5)==8 && (1UL<<((bit)&31) & REQUIRED_MASK8 )) || \ + (((bit)>>5)==9 && (1UL<<((bit)&31) & REQUIRED_MASK9 )) || \ + (((bit)>>5)==10 && (1UL<<((bit)&31) & REQUIRED_MASK10)) || \ + (((bit)>>5)==11 && (1UL<<((bit)&31) & REQUIRED_MASK11)) || \ + (((bit)>>5)==12 && (1UL<<((bit)&31) & REQUIRED_MASK12)) || \ + (((bit)>>5)==13 && (1UL<<((bit)&31) & REQUIRED_MASK13)) || \ + (((bit)>>5)==13 && (1UL<<((bit)&31) & REQUIRED_MASK14)) || \ + (((bit)>>5)==13 && (1UL<<((bit)&31) & REQUIRED_MASK15)) || \ + (((bit)>>5)==14 && (1UL<<((bit)&31) & REQUIRED_MASK16)) ) #define DISABLED_MASK_BIT_SET(bit) \ - ( (((bit)>>5)==0 && (1UL<<((bit)&31) & DISABLED_MASK0)) || \ - (((bit)>>5)==1 && (1UL<<((bit)&31) & DISABLED_MASK1)) || \ - (((bit)>>5)==2 && (1UL<<((bit)&31) & DISABLED_MASK2)) || \ - (((bit)>>5)==3 && (1UL<<((bit)&31) & DISABLED_MASK3)) || \ - (((bit)>>5)==4 && (1UL<<((bit)&31) & DISABLED_MASK4)) || \ - (((bit)>>5)==5 && (1UL<<((bit)&31) & DISABLED_MASK5)) || \ - (((bit)>>5)==6 && (1UL<<((bit)&31) & DISABLED_MASK6)) || \ - (((bit)>>5)==7 && (1UL<<((bit)&31) & DISABLED_MASK7)) || \ - (((bit)>>5)==8 && (1UL<<((bit)&31) & DISABLED_MASK8)) || \ - (((bit)>>5)==9 && (1UL<<((bit)&31) & DISABLED_MASK9)) ) + ( (((bit)>>5)==0 && (1UL<<((bit)&31) & DISABLED_MASK0 )) || \ + (((bit)>>5)==1 && (1UL<<((bit)&31) & DISABLED_MASK1 )) || \ + (((bit)>>5)==2 && (1UL<<((bit)&31) & DISABLED_MASK2 )) || \ + (((bit)>>5)==3 && (1UL<<((bit)&31) & DISABLED_MASK3 )) || \ + (((bit)>>5)==4 && (1UL<<((bit)&31) & DISABLED_MASK4 )) || \ + (((bit)>>5)==5 && (1UL<<((bit)&31) & DISABLED_MASK5 )) || \ + (((bit)>>5)==6 && (1UL<<((bit)&31) & DISABLED_MASK6 )) || \ + (((bit)>>5)==7 && (1UL<<((bit)&31) & DISABLED_MASK7 )) || \ + (((bit)>>5)==8 && (1UL<<((bit)&31) & DISABLED_MASK8 )) || \ + (((bit)>>5)==9 && (1UL<<((bit)&31) & DISABLED_MASK9 )) || \ + (((bit)>>5)==10 && (1UL<<((bit)&31) & DISABLED_MASK10)) || \ + (((bit)>>5)==11 && (1UL<<((bit)&31) & DISABLED_MASK11)) || \ + (((bit)>>5)==12 && (1UL<<((bit)&31) & DISABLED_MASK12)) || \ + (((bit)>>5)==13 && (1UL<<((bit)&31) & DISABLED_MASK13)) || \ + (((bit)>>5)==13 && (1UL<<((bit)&31) & DISABLED_MASK14)) || \ + (((bit)>>5)==13 && (1UL<<((bit)&31) & DISABLED_MASK15)) || \ + (((bit)>>5)==14 && (1UL<<((bit)&31) & DISABLED_MASK16)) ) #define cpu_has(c, bit) \ (__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \ diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h index 074b7604bd5122d2b5d7da01f14a610d4df31239..8f9afefd2dc5ab8159131ae1815f9ae122d7024b 100644 --- a/arch/x86/include/asm/cpufeatures.h +++ b/arch/x86/include/asm/cpufeatures.h @@ -12,7 +12,7 @@ /* * Defines x86 CPU feature bits */ -#define NCAPINTS 16 /* N 32-bit words worth of info */ +#define NCAPINTS 17 /* N 32-bit words worth of info */ #define NBUGINTS 1 /* N 32-bit bug flags */ /* @@ -94,7 +94,7 @@ #define X86_FEATURE_REP_GOOD ( 3*32+16) /* rep microcode works well */ #define X86_FEATURE_MFENCE_RDTSC ( 3*32+17) /* "" Mfence synchronizes RDTSC */ #define X86_FEATURE_LFENCE_RDTSC ( 3*32+18) /* "" Lfence synchronizes RDTSC */ -/* free, was #define X86_FEATURE_11AP ( 3*32+19) * "" Bad local APIC aka 11AP */ +#define X86_FEATURE_ACC_POWER ( 3*32+19) /* AMD Accumulated Power Mechanism */ #define X86_FEATURE_NOPL ( 3*32+20) /* The NOPL (0F 1F) instructions */ #define X86_FEATURE_ALWAYS ( 3*32+21) /* "" Always-present feature */ #define X86_FEATURE_XTOPOLOGY ( 3*32+22) /* cpu topology enum extensions */ @@ -245,6 +245,8 @@ /* Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:1 (edx), word 12 */ #define X86_FEATURE_CQM_OCCUP_LLC (12*32+ 0) /* LLC occupancy monitoring if 1 */ +#define X86_FEATURE_CQM_MBM_TOTAL (12*32+ 1) /* LLC Total MBM monitoring */ +#define X86_FEATURE_CQM_MBM_LOCAL (12*32+ 2) /* LLC Local MBM monitoring */ /* AMD-defined CPU features, CPUID level 0x80000008 (ebx), word 13 */ #define X86_FEATURE_CLZERO (13*32+0) /* CLZERO instruction */ @@ -274,6 +276,10 @@ #define X86_FEATURE_PFTHRESHOLD (15*32+12) /* pause filter threshold */ #define X86_FEATURE_AVIC (15*32+13) /* Virtual Interrupt Controller */ +/* Intel-defined CPU features, CPUID level 0x00000007:0 (ecx), word 16 */ +#define X86_FEATURE_PKU (16*32+ 3) /* Protection Keys for Userspace */ +#define X86_FEATURE_OSPKE (16*32+ 4) /* OS Protection Keys Enable */ + /* * BUG word(s) */ diff --git a/arch/x86/include/asm/disabled-features.h b/arch/x86/include/asm/disabled-features.h index f226df064660464e6bf8663314dfb6bcf7379ac5..39343be7d4f4315592da1026c700533ec435204b 100644 --- a/arch/x86/include/asm/disabled-features.h +++ b/arch/x86/include/asm/disabled-features.h @@ -28,6 +28,14 @@ # define DISABLE_CENTAUR_MCR 0 #endif /* CONFIG_X86_64 */ +#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS +# define DISABLE_PKU (1<<(X86_FEATURE_PKU)) +# define DISABLE_OSPKE (1<<(X86_FEATURE_OSPKE)) +#else +# define DISABLE_PKU 0 +# define DISABLE_OSPKE 0 +#endif /* CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS */ + /* * Make sure to add features to the correct mask */ @@ -41,5 +49,12 @@ #define DISABLED_MASK7 0 #define DISABLED_MASK8 0 #define DISABLED_MASK9 (DISABLE_MPX) +#define DISABLED_MASK10 0 +#define DISABLED_MASK11 0 +#define DISABLED_MASK12 0 +#define DISABLED_MASK13 0 +#define DISABLED_MASK14 0 +#define DISABLED_MASK15 0 +#define DISABLED_MASK16 (DISABLE_PKU|DISABLE_OSPKE) #endif /* _ASM_X86_DISABLED_FEATURES_H */ diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index 08b1f2f6ea50c186933d0d9e79c82da0b9da4f3f..53748c45e4885f574531f8cd6cf143f6dbc264d6 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h @@ -3,6 +3,7 @@ #include #include +#include /* * We map the EFI regions needed for runtime services non-contiguously, @@ -66,6 +67,17 @@ extern u64 asmlinkage efi_call(void *fp, ...); #define efi_call_phys(f, args...) efi_call((f), args) +/* + * Scratch space used for switching the pagetable in the EFI stub + */ +struct efi_scratch { + u64 r15; + u64 prev_cr3; + pgd_t *efi_pgt; + bool use_pgd; + u64 phys_stack; +} __packed; + #define efi_call_virt(f, ...) \ ({ \ efi_status_t __s; \ @@ -73,7 +85,20 @@ extern u64 asmlinkage efi_call(void *fp, ...); efi_sync_low_kernel_mappings(); \ preempt_disable(); \ __kernel_fpu_begin(); \ + \ + if (efi_scratch.use_pgd) { \ + efi_scratch.prev_cr3 = read_cr3(); \ + write_cr3((unsigned long)efi_scratch.efi_pgt); \ + __flush_tlb_all(); \ + } \ + \ __s = efi_call((void *)efi.systab->runtime->f, __VA_ARGS__); \ + \ + if (efi_scratch.use_pgd) { \ + write_cr3(efi_scratch.prev_cr3); \ + __flush_tlb_all(); \ + } \ + \ __kernel_fpu_end(); \ preempt_enable(); \ __s; \ @@ -113,11 +138,12 @@ extern void __init efi_memory_uc(u64 addr, unsigned long size); extern void __init efi_map_region(efi_memory_desc_t *md); extern void __init efi_map_region_fixed(efi_memory_desc_t *md); extern void efi_sync_low_kernel_mappings(void); +extern int __init efi_alloc_page_tables(void); extern int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages); extern void __init efi_cleanup_page_tables(unsigned long pa_memmap, unsigned num_pages); extern void __init old_map_region(efi_memory_desc_t *md); extern void __init runtime_code_page_mkexec(void); -extern void __init efi_runtime_mkexec(void); +extern void __init efi_runtime_update_mappings(void); extern void __init efi_dump_pagetable(void); extern void __init efi_apply_memmap_quirks(void); extern int __init efi_reuse_config(u64 tables, int nr_tables); diff --git a/arch/x86/include/asm/fpu/internal.h b/arch/x86/include/asm/fpu/internal.h index a2124343edf5448fa06eece0015729505cf93412..31ac8e6d9f36693a18a9aa46299d4cf3b5c84acd 100644 --- a/arch/x86/include/asm/fpu/internal.h +++ b/arch/x86/include/asm/fpu/internal.h @@ -25,6 +25,8 @@ extern void fpu__activate_curr(struct fpu *fpu); extern void fpu__activate_fpstate_read(struct fpu *fpu); extern void fpu__activate_fpstate_write(struct fpu *fpu); +extern void fpu__current_fpstate_write_begin(void); +extern void fpu__current_fpstate_write_end(void); extern void fpu__save(struct fpu *fpu); extern void fpu__restore(struct fpu *fpu); extern int fpu__restore_sig(void __user *buf, int ia32_frame); diff --git a/arch/x86/include/asm/fpu/types.h b/arch/x86/include/asm/fpu/types.h index 1c6f6ac52ad0a2cfe44db5eab9825b59408cde01..36b90bbfc69fa8eb5fa4daa6d97438730ab8887f 100644 --- a/arch/x86/include/asm/fpu/types.h +++ b/arch/x86/include/asm/fpu/types.h @@ -108,6 +108,8 @@ enum xfeature { XFEATURE_OPMASK, XFEATURE_ZMM_Hi256, XFEATURE_Hi16_ZMM, + XFEATURE_PT_UNIMPLEMENTED_SO_FAR, + XFEATURE_PKRU, XFEATURE_MAX, }; @@ -120,6 +122,7 @@ enum xfeature { #define XFEATURE_MASK_OPMASK (1 << XFEATURE_OPMASK) #define XFEATURE_MASK_ZMM_Hi256 (1 << XFEATURE_ZMM_Hi256) #define XFEATURE_MASK_Hi16_ZMM (1 << XFEATURE_Hi16_ZMM) +#define XFEATURE_MASK_PKRU (1 << XFEATURE_PKRU) #define XFEATURE_MASK_FPSSE (XFEATURE_MASK_FP | XFEATURE_MASK_SSE) #define XFEATURE_MASK_AVX512 (XFEATURE_MASK_OPMASK \ @@ -212,6 +215,15 @@ struct avx_512_hi16_state { struct reg_512_bit hi16_zmm[16]; } __packed; +/* + * State component 9: 32-bit PKRU register. The state is + * 8 bytes long but only 4 bytes is used currently. + */ +struct pkru_state { + u32 pkru; + u32 pad; +} __packed; + struct xstate_header { u64 xfeatures; u64 xcomp_bv; diff --git a/arch/x86/include/asm/fpu/xstate.h b/arch/x86/include/asm/fpu/xstate.h index f23cd8c80b1c818057053e831ec704ab4006fba4..38951b0fcc5a408130b697296d0bfd48ceee83f4 100644 --- a/arch/x86/include/asm/fpu/xstate.h +++ b/arch/x86/include/asm/fpu/xstate.h @@ -24,7 +24,8 @@ XFEATURE_MASK_YMM | \ XFEATURE_MASK_OPMASK | \ XFEATURE_MASK_ZMM_Hi256 | \ - XFEATURE_MASK_Hi16_ZMM) + XFEATURE_MASK_Hi16_ZMM | \ + XFEATURE_MASK_PKRU) /* Supported features which require eager state saving */ #define XFEATURE_MASK_EAGER (XFEATURE_MASK_BNDREGS | XFEATURE_MASK_BNDCSR) diff --git a/arch/x86/include/asm/ftrace.h b/arch/x86/include/asm/ftrace.h index 24938852db3013e0290df0b2ff77c2aafeff73d3..a4820d4df617daede213516eea42becd5b874640 100644 --- a/arch/x86/include/asm/ftrace.h +++ b/arch/x86/include/asm/ftrace.h @@ -52,13 +52,13 @@ int ftrace_int3_handler(struct pt_regs *regs); * this screws up the trace output when tracing a ia32 task. * Instead of reporting bogus syscalls, just do not trace them. * - * If the user realy wants these, then they should use the + * If the user really wants these, then they should use the * raw syscall tracepoints with filtering. */ #define ARCH_TRACE_IGNORE_COMPAT_SYSCALLS 1 static inline bool arch_trace_is_compat_syscall(struct pt_regs *regs) { - if (is_compat_task()) + if (in_compat_syscall()) return true; return false; } diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h index 1815b736269d1ef46265f8e580f27335371e64de..b90e1053049bdd17ad36989315db8ac1b3ccc973 100644 --- a/arch/x86/include/asm/hw_irq.h +++ b/arch/x86/include/asm/hw_irq.h @@ -141,6 +141,7 @@ struct irq_alloc_info { struct irq_cfg { unsigned int dest_apicid; u8 vector; + u8 old_vector; }; extern struct irq_cfg *irq_cfg(unsigned int irq); @@ -168,20 +169,6 @@ extern atomic_t irq_mis_count; extern void elcr_set_level_irq(unsigned int irq); -/* SMP */ -extern __visible void smp_apic_timer_interrupt(struct pt_regs *); -extern __visible void smp_spurious_interrupt(struct pt_regs *); -extern __visible void smp_x86_platform_ipi(struct pt_regs *); -extern __visible void smp_error_interrupt(struct pt_regs *); -#ifdef CONFIG_X86_IO_APIC -extern asmlinkage void smp_irq_move_cleanup_interrupt(void); -#endif -#ifdef CONFIG_SMP -extern __visible void smp_reschedule_interrupt(struct pt_regs *); -extern __visible void smp_call_function_interrupt(struct pt_regs *); -extern __visible void smp_call_function_single_interrupt(struct pt_regs *); -#endif - extern char irq_entries_start[]; #ifdef CONFIG_TRACING #define trace_irq_entries_start irq_entries_start diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 01c8b501cb6d5afbdd5eb1c5dfaba366ea158cf8..b7e394485a5f2a641bc466eef1bc210c348a936c 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -43,7 +43,7 @@ #define KVM_PIO_PAGE_OFFSET 1 #define KVM_COALESCED_MMIO_PAGE_OFFSET 2 -#define KVM_HALT_POLL_NS_DEFAULT 500000 +#define KVM_HALT_POLL_NS_DEFAULT 400000 #define KVM_IRQCHIP_NUM_PINS KVM_IOAPIC_NUM_PINS @@ -84,7 +84,8 @@ | X86_CR4_PSE | X86_CR4_PAE | X86_CR4_MCE \ | X86_CR4_PGE | X86_CR4_PCE | X86_CR4_OSFXSR | X86_CR4_PCIDE \ | X86_CR4_OSXSAVE | X86_CR4_SMEP | X86_CR4_FSGSBASE \ - | X86_CR4_OSXMMEXCPT | X86_CR4_VMXE | X86_CR4_SMAP)) + | X86_CR4_OSXMMEXCPT | X86_CR4_VMXE | X86_CR4_SMAP \ + | X86_CR4_PKE)) #define CR8_RESERVED_BITS (~(unsigned long)X86_CR8_TPR) @@ -187,12 +188,14 @@ enum { #define PFERR_USER_BIT 2 #define PFERR_RSVD_BIT 3 #define PFERR_FETCH_BIT 4 +#define PFERR_PK_BIT 5 #define PFERR_PRESENT_MASK (1U << PFERR_PRESENT_BIT) #define PFERR_WRITE_MASK (1U << PFERR_WRITE_BIT) #define PFERR_USER_MASK (1U << PFERR_USER_BIT) #define PFERR_RSVD_MASK (1U << PFERR_RSVD_BIT) #define PFERR_FETCH_MASK (1U << PFERR_FETCH_BIT) +#define PFERR_PK_MASK (1U << PFERR_PK_BIT) /* apic attention bits */ #define KVM_APIC_CHECK_VAPIC 0 @@ -335,6 +338,14 @@ struct kvm_mmu { */ u8 permissions[16]; + /* + * The pkru_mask indicates if protection key checks are needed. It + * consists of 16 domains indexed by page fault error code bits [4:1], + * with PFEC.RSVD replaced by ACC_USER_MASK from the page tables. + * Each domain has 2 bits which are ANDed with AD and WD from PKRU. + */ + u32 pkru_mask; + u64 *pae_root; u64 *lm_root; @@ -874,6 +885,7 @@ struct kvm_x86_ops { void (*cache_reg)(struct kvm_vcpu *vcpu, enum kvm_reg reg); unsigned long (*get_rflags)(struct kvm_vcpu *vcpu); void (*set_rflags)(struct kvm_vcpu *vcpu, unsigned long rflags); + u32 (*get_pkru)(struct kvm_vcpu *vcpu); void (*fpu_activate)(struct kvm_vcpu *vcpu); void (*fpu_deactivate)(struct kvm_vcpu *vcpu); diff --git a/arch/x86/include/asm/livepatch.h b/arch/x86/include/asm/livepatch.h index e795f5274217a47cf1713063399675a175d5a4ea..7e68f95585523bdc315883b023bdae4a0deeb017 100644 --- a/arch/x86/include/asm/livepatch.h +++ b/arch/x86/include/asm/livepatch.h @@ -25,7 +25,6 @@ #include #include -#ifdef CONFIG_LIVEPATCH static inline int klp_check_compiler_support(void) { #ifndef CC_USING_FENTRY @@ -40,8 +39,5 @@ static inline void klp_arch_set_pc(struct pt_regs *regs, unsigned long ip) { regs->ip = ip; } -#else -#error Include linux/livepatch.h, not asm/livepatch.h -#endif #endif /* _ASM_X86_LIVEPATCH_H */ diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h index bfd9b2a35a0b14aa879ac9973202ef882dae52d7..84280029cafd73a83e64efd3133a8f9d9575bcb3 100644 --- a/arch/x86/include/asm/mmu_context.h +++ b/arch/x86/include/asm/mmu_context.h @@ -52,15 +52,15 @@ struct ldt_struct { /* * Used for LDT copy/destruction. */ -int init_new_context(struct task_struct *tsk, struct mm_struct *mm); -void destroy_context(struct mm_struct *mm); +int init_new_context_ldt(struct task_struct *tsk, struct mm_struct *mm); +void destroy_context_ldt(struct mm_struct *mm); #else /* CONFIG_MODIFY_LDT_SYSCALL */ -static inline int init_new_context(struct task_struct *tsk, - struct mm_struct *mm) +static inline int init_new_context_ldt(struct task_struct *tsk, + struct mm_struct *mm) { return 0; } -static inline void destroy_context(struct mm_struct *mm) {} +static inline void destroy_context_ldt(struct mm_struct *mm) {} #endif static inline void load_mm_ldt(struct mm_struct *mm) @@ -104,6 +104,17 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) #endif } +static inline int init_new_context(struct task_struct *tsk, + struct mm_struct *mm) +{ + init_new_context_ldt(tsk, mm); + return 0; +} +static inline void destroy_context(struct mm_struct *mm) +{ + destroy_context_ldt(mm); +} + static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk) { @@ -275,4 +286,68 @@ static inline void arch_unmap(struct mm_struct *mm, struct vm_area_struct *vma, mpx_notify_unmap(mm, vma, start, end); } +static inline int vma_pkey(struct vm_area_struct *vma) +{ + u16 pkey = 0; +#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS + unsigned long vma_pkey_mask = VM_PKEY_BIT0 | VM_PKEY_BIT1 | + VM_PKEY_BIT2 | VM_PKEY_BIT3; + pkey = (vma->vm_flags & vma_pkey_mask) >> VM_PKEY_SHIFT; +#endif + return pkey; +} + +static inline bool __pkru_allows_pkey(u16 pkey, bool write) +{ + u32 pkru = read_pkru(); + + if (!__pkru_allows_read(pkru, pkey)) + return false; + if (write && !__pkru_allows_write(pkru, pkey)) + return false; + + return true; +} + +/* + * We only want to enforce protection keys on the current process + * because we effectively have no access to PKRU for other + * processes or any way to tell *which * PKRU in a threaded + * process we could use. + * + * So do not enforce things if the VMA is not from the current + * mm, or if we are in a kernel thread. + */ +static inline bool vma_is_foreign(struct vm_area_struct *vma) +{ + if (!current->mm) + return true; + /* + * Should PKRU be enforced on the access to this VMA? If + * the VMA is from another process, then PKRU has no + * relevance and should not be enforced. + */ + if (current->mm != vma->vm_mm) + return true; + + return false; +} + +static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, + bool write, bool execute, bool foreign) +{ + /* pkeys never affect instruction fetches */ + if (execute) + return true; + /* allow access if the VMA is not one from this process */ + if (foreign || vma_is_foreign(vma)) + return true; + return __pkru_allows_pkey(vma_pkey(vma), write); +} + +static inline bool arch_pte_access_permitted(pte_t pte, bool write) +{ + return __pkru_allows_pkey(pte_flags_pkey(pte_flags(pte)), write); +} + #endif /* _ASM_X86_MMU_CONTEXT_H */ diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 2da46ac16e3750441294d983d82f359fdccdb0a4..5b3c9a55f51cbeda86cb52dedac1f3f494042e55 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -167,6 +167,14 @@ #define MSR_PKG_C9_RESIDENCY 0x00000631 #define MSR_PKG_C10_RESIDENCY 0x00000632 +/* Interrupt Response Limit */ +#define MSR_PKGC3_IRTL 0x0000060a +#define MSR_PKGC6_IRTL 0x0000060b +#define MSR_PKGC7_IRTL 0x0000060c +#define MSR_PKGC8_IRTL 0x00000633 +#define MSR_PKGC9_IRTL 0x00000634 +#define MSR_PKGC10_IRTL 0x00000635 + /* Run Time Average Power Limiting (RAPL) Interface */ #define MSR_RAPL_POWER_UNIT 0x00000606 @@ -190,6 +198,7 @@ #define MSR_PP1_ENERGY_STATUS 0x00000641 #define MSR_PP1_POLICY 0x00000642 +/* Config TDP MSRs */ #define MSR_CONFIG_TDP_NOMINAL 0x00000648 #define MSR_CONFIG_TDP_LEVEL_1 0x00000649 #define MSR_CONFIG_TDP_LEVEL_2 0x0000064A @@ -210,13 +219,6 @@ #define MSR_GFX_PERF_LIMIT_REASONS 0x000006B0 #define MSR_RING_PERF_LIMIT_REASONS 0x000006B1 -/* Config TDP MSRs */ -#define MSR_CONFIG_TDP_NOMINAL 0x00000648 -#define MSR_CONFIG_TDP_LEVEL1 0x00000649 -#define MSR_CONFIG_TDP_LEVEL2 0x0000064A -#define MSR_CONFIG_TDP_CONTROL 0x0000064B -#define MSR_TURBO_ACTIVATION_RATIO 0x0000064C - /* Hardware P state interface */ #define MSR_PPERF 0x0000064e #define MSR_PERF_LIMIT_REASONS 0x0000064f diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h index 93fb7c1cffda7a03e8e0248f634e86eb78e3ff3d..7a79ee2778b3b5067fa816e541bf93bc26cf782d 100644 --- a/arch/x86/include/asm/msr.h +++ b/arch/x86/include/asm/msr.h @@ -42,14 +42,6 @@ struct saved_msrs { struct saved_msr *array; }; -static inline unsigned long long native_read_tscp(unsigned int *aux) -{ - unsigned long low, high; - asm volatile(".byte 0x0f,0x01,0xf9" - : "=a" (low), "=d" (high), "=c" (*aux)); - return low | ((u64)high << 32); -} - /* * both i386 and x86_64 returns 64-bit value in edx:eax, but gcc's "A" * constraint has different meanings. For i386, "A" means exactly diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index f6192502149e58064aa75950d4bb361db54c58f2..601f1b8f9961af35f113ad456b1ab90f1aceaced 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h @@ -13,6 +13,7 @@ #include #include #include +#include static inline int paravirt_enabled(void) { @@ -756,15 +757,19 @@ static __always_inline void __ticket_unlock_kick(struct arch_spinlock *lock, * call. The return value in rax/eax will not be saved, even for void * functions. */ +#define PV_THUNK_NAME(func) "__raw_callee_save_" #func #define PV_CALLEE_SAVE_REGS_THUNK(func) \ extern typeof(func) __raw_callee_save_##func; \ \ asm(".pushsection .text;" \ - ".globl __raw_callee_save_" #func " ; " \ - "__raw_callee_save_" #func ": " \ + ".globl " PV_THUNK_NAME(func) ";" \ + ".type " PV_THUNK_NAME(func) ", @function;" \ + PV_THUNK_NAME(func) ":" \ + FRAME_BEGIN \ PV_SAVE_ALL_CALLER_REGS \ "call " #func ";" \ PV_RESTORE_ALL_CALLER_REGS \ + FRAME_END \ "ret;" \ ".popsection") diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h index 77db5616a4739703ddf0edb2f7b10f10f67d4552..e8c2326478c8fabc4e03c04534c599072e2598fe 100644 --- a/arch/x86/include/asm/paravirt_types.h +++ b/arch/x86/include/asm/paravirt_types.h @@ -466,8 +466,9 @@ int paravirt_disable_iospace(void); * makes sure the incoming and outgoing types are always correct. */ #ifdef CONFIG_X86_32 -#define PVOP_VCALL_ARGS \ - unsigned long __eax = __eax, __edx = __edx, __ecx = __ecx +#define PVOP_VCALL_ARGS \ + unsigned long __eax = __eax, __edx = __edx, __ecx = __ecx; \ + register void *__sp asm("esp") #define PVOP_CALL_ARGS PVOP_VCALL_ARGS #define PVOP_CALL_ARG1(x) "a" ((unsigned long)(x)) @@ -485,9 +486,10 @@ int paravirt_disable_iospace(void); #define VEXTRA_CLOBBERS #else /* CONFIG_X86_64 */ /* [re]ax isn't an arg, but the return val */ -#define PVOP_VCALL_ARGS \ - unsigned long __edi = __edi, __esi = __esi, \ - __edx = __edx, __ecx = __ecx, __eax = __eax +#define PVOP_VCALL_ARGS \ + unsigned long __edi = __edi, __esi = __esi, \ + __edx = __edx, __ecx = __ecx, __eax = __eax; \ + register void *__sp asm("rsp") #define PVOP_CALL_ARGS PVOP_VCALL_ARGS #define PVOP_CALL_ARG1(x) "D" ((unsigned long)(x)) @@ -526,7 +528,7 @@ int paravirt_disable_iospace(void); asm volatile(pre \ paravirt_alt(PARAVIRT_CALL) \ post \ - : call_clbr \ + : call_clbr, "+r" (__sp) \ : paravirt_type(op), \ paravirt_clobber(clbr), \ ##__VA_ARGS__ \ @@ -536,7 +538,7 @@ int paravirt_disable_iospace(void); asm volatile(pre \ paravirt_alt(PARAVIRT_CALL) \ post \ - : call_clbr \ + : call_clbr, "+r" (__sp) \ : paravirt_type(op), \ paravirt_clobber(clbr), \ ##__VA_ARGS__ \ @@ -563,7 +565,7 @@ int paravirt_disable_iospace(void); asm volatile(pre \ paravirt_alt(PARAVIRT_CALL) \ post \ - : call_clbr \ + : call_clbr, "+r" (__sp) \ : paravirt_type(op), \ paravirt_clobber(clbr), \ ##__VA_ARGS__ \ diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 0687c4748b8f87690471c94bade518d2b768242d..97f3242e133ccc9c2866baade8ca4f82ade65f04 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -99,6 +99,20 @@ static inline int pte_dirty(pte_t pte) return pte_flags(pte) & _PAGE_DIRTY; } + +static inline u32 read_pkru(void) +{ + if (boot_cpu_has(X86_FEATURE_OSPKE)) + return __read_pkru(); + return 0; +} + +static inline void write_pkru(u32 pkru) +{ + if (boot_cpu_has(X86_FEATURE_OSPKE)) + __write_pkru(pkru); +} + static inline int pte_young(pte_t pte) { return pte_flags(pte) & _PAGE_ACCESSED; @@ -911,6 +925,36 @@ static inline pte_t pte_swp_clear_soft_dirty(pte_t pte) } #endif +#define PKRU_AD_BIT 0x1 +#define PKRU_WD_BIT 0x2 +#define PKRU_BITS_PER_PKEY 2 + +static inline bool __pkru_allows_read(u32 pkru, u16 pkey) +{ + int pkru_pkey_bits = pkey * PKRU_BITS_PER_PKEY; + return !(pkru & (PKRU_AD_BIT << pkru_pkey_bits)); +} + +static inline bool __pkru_allows_write(u32 pkru, u16 pkey) +{ + int pkru_pkey_bits = pkey * PKRU_BITS_PER_PKEY; + /* + * Access-disable disables writes too so we need to check + * both bits here. + */ + return !(pkru & ((PKRU_AD_BIT|PKRU_WD_BIT) << pkru_pkey_bits)); +} + +static inline u16 pte_flags_pkey(unsigned long pte_flags) +{ +#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS + /* ifdef to avoid doing 59-bit shift on 32-bit values */ + return (pte_flags & _PAGE_PKEY_MASK) >> _PAGE_BIT_PKEY_BIT0; +#else + return 0; +#endif +} + #include #endif /* __ASSEMBLY__ */ diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h index 4432ab7f407ccc5f47ea9c19a850c29af821d8c9..7b5efe264eff253d1bbb9ea69fbca9caadf44389 100644 --- a/arch/x86/include/asm/pgtable_types.h +++ b/arch/x86/include/asm/pgtable_types.h @@ -20,13 +20,18 @@ #define _PAGE_BIT_SOFTW2 10 /* " */ #define _PAGE_BIT_SOFTW3 11 /* " */ #define _PAGE_BIT_PAT_LARGE 12 /* On 2MB or 1GB pages */ +#define _PAGE_BIT_SOFTW4 58 /* available for programmer */ +#define _PAGE_BIT_PKEY_BIT0 59 /* Protection Keys, bit 1/4 */ +#define _PAGE_BIT_PKEY_BIT1 60 /* Protection Keys, bit 2/4 */ +#define _PAGE_BIT_PKEY_BIT2 61 /* Protection Keys, bit 3/4 */ +#define _PAGE_BIT_PKEY_BIT3 62 /* Protection Keys, bit 4/4 */ +#define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */ + #define _PAGE_BIT_SPECIAL _PAGE_BIT_SOFTW1 #define _PAGE_BIT_CPA_TEST _PAGE_BIT_SOFTW1 #define _PAGE_BIT_HIDDEN _PAGE_BIT_SOFTW3 /* hidden by kmemcheck */ #define _PAGE_BIT_SOFT_DIRTY _PAGE_BIT_SOFTW3 /* software dirty tracking */ -#define _PAGE_BIT_SOFTW4 58 /* available for programmer */ -#define _PAGE_BIT_DEVMAP _PAGE_BIT_SOFTW4 -#define _PAGE_BIT_NX 63 /* No execute: only valid after cpuid check */ +#define _PAGE_BIT_DEVMAP _PAGE_BIT_SOFTW4 /* If _PAGE_BIT_PRESENT is clear, we use these: */ /* - if the user mapped it with PROT_NONE; pte_present gives true */ @@ -47,8 +52,24 @@ #define _PAGE_PAT_LARGE (_AT(pteval_t, 1) << _PAGE_BIT_PAT_LARGE) #define _PAGE_SPECIAL (_AT(pteval_t, 1) << _PAGE_BIT_SPECIAL) #define _PAGE_CPA_TEST (_AT(pteval_t, 1) << _PAGE_BIT_CPA_TEST) +#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS +#define _PAGE_PKEY_BIT0 (_AT(pteval_t, 1) << _PAGE_BIT_PKEY_BIT0) +#define _PAGE_PKEY_BIT1 (_AT(pteval_t, 1) << _PAGE_BIT_PKEY_BIT1) +#define _PAGE_PKEY_BIT2 (_AT(pteval_t, 1) << _PAGE_BIT_PKEY_BIT2) +#define _PAGE_PKEY_BIT3 (_AT(pteval_t, 1) << _PAGE_BIT_PKEY_BIT3) +#else +#define _PAGE_PKEY_BIT0 (_AT(pteval_t, 0)) +#define _PAGE_PKEY_BIT1 (_AT(pteval_t, 0)) +#define _PAGE_PKEY_BIT2 (_AT(pteval_t, 0)) +#define _PAGE_PKEY_BIT3 (_AT(pteval_t, 0)) +#endif #define __HAVE_ARCH_PTE_SPECIAL +#define _PAGE_PKEY_MASK (_PAGE_PKEY_BIT0 | \ + _PAGE_PKEY_BIT1 | \ + _PAGE_PKEY_BIT2 | \ + _PAGE_PKEY_BIT3) + #ifdef CONFIG_KMEMCHECK #define _PAGE_HIDDEN (_AT(pteval_t, 1) << _PAGE_BIT_HIDDEN) #else @@ -99,7 +120,12 @@ #define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | \ _PAGE_DIRTY) -/* Set of bits not changed in pte_modify */ +/* + * Set of bits not changed in pte_modify. The pte's + * protection key is treated like _PAGE_RW, for + * instance, and is *not* included in this mask since + * pte_modify() does modify it. + */ #define _PAGE_CHG_MASK (PTE_PFN_MASK | _PAGE_PCD | _PAGE_PWT | \ _PAGE_SPECIAL | _PAGE_ACCESSED | _PAGE_DIRTY | \ _PAGE_SOFT_DIRTY) @@ -215,7 +241,10 @@ enum page_cache_mode { /* Extracts the PFN from a (pte|pmd|pud|pgd)val_t of a 4KB page */ #define PTE_PFN_MASK ((pteval_t)PHYSICAL_PAGE_MASK) -/* Extracts the flags from a (pte|pmd|pud|pgd)val_t of a 4KB page */ +/* + * Extracts the flags from a (pte|pmd|pud|pgd)val_t + * This includes the protection key value. + */ #define PTE_FLAGS_MASK (~PTE_PFN_MASK) typedef struct pgprot { pgprotval_t pgprot; } pgprot_t; diff --git a/arch/x86/include/asm/pkeys.h b/arch/x86/include/asm/pkeys.h new file mode 100644 index 0000000000000000000000000000000000000000..7b84565c916c7b0329ac92c79c789748ff9eeb28 --- /dev/null +++ b/arch/x86/include/asm/pkeys.h @@ -0,0 +1,34 @@ +#ifndef _ASM_X86_PKEYS_H +#define _ASM_X86_PKEYS_H + +#define arch_max_pkey() (boot_cpu_has(X86_FEATURE_OSPKE) ? 16 : 1) + +extern int arch_set_user_pkey_access(struct task_struct *tsk, int pkey, + unsigned long init_val); + +/* + * Try to dedicate one of the protection keys to be used as an + * execute-only protection key. + */ +#define PKEY_DEDICATED_EXECUTE_ONLY 15 +extern int __execute_only_pkey(struct mm_struct *mm); +static inline int execute_only_pkey(struct mm_struct *mm) +{ + if (!boot_cpu_has(X86_FEATURE_OSPKE)) + return 0; + + return __execute_only_pkey(mm); +} + +extern int __arch_override_mprotect_pkey(struct vm_area_struct *vma, + int prot, int pkey); +static inline int arch_override_mprotect_pkey(struct vm_area_struct *vma, + int prot, int pkey) +{ + if (!boot_cpu_has(X86_FEATURE_OSPKE)) + return 0; + + return __arch_override_mprotect_pkey(vma, prot, pkey); +} + +#endif /*_ASM_X86_PKEYS_H */ diff --git a/arch/x86/include/asm/pmem.h b/arch/x86/include/asm/pmem.h index bf8b35d2035a86afa6469e32d123cefaee1d25f1..fbc5e92e1ecc43bbf29e07de629d801a37d95ee5 100644 --- a/arch/x86/include/asm/pmem.h +++ b/arch/x86/include/asm/pmem.h @@ -47,6 +47,15 @@ static inline void arch_memcpy_to_pmem(void __pmem *dst, const void *src, BUG(); } +static inline int arch_memcpy_from_pmem(void *dst, const void __pmem *src, + size_t n) +{ + if (static_cpu_has(X86_FEATURE_MCE_RECOVERY)) + return memcpy_mcsafe(dst, (void __force *) src, n); + memcpy(dst, (void __force *) src, n); + return 0; +} + /** * arch_wmb_pmem - synchronize writes to persistent memory * diff --git a/arch/x86/include/asm/preempt.h b/arch/x86/include/asm/preempt.h index 01bcde84d3e40fb36e16625f0c1024f1291bb9ae..d397deb5814677a64c6ab8debf5ea1f403dfd898 100644 --- a/arch/x86/include/asm/preempt.h +++ b/arch/x86/include/asm/preempt.h @@ -94,10 +94,19 @@ static __always_inline bool should_resched(int preempt_offset) #ifdef CONFIG_PREEMPT extern asmlinkage void ___preempt_schedule(void); -# define __preempt_schedule() asm ("call ___preempt_schedule") +# define __preempt_schedule() \ +({ \ + register void *__sp asm(_ASM_SP); \ + asm volatile ("call ___preempt_schedule" : "+r"(__sp)); \ +}) + extern asmlinkage void preempt_schedule(void); extern asmlinkage void ___preempt_schedule_notrace(void); -# define __preempt_schedule_notrace() asm ("call ___preempt_schedule_notrace") +# define __preempt_schedule_notrace() \ +({ \ + register void *__sp asm(_ASM_SP); \ + asm volatile ("call ___preempt_schedule_notrace" : "+r"(__sp)); \ +}) extern asmlinkage void preempt_schedule_notrace(void); #endif diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 983738ac014c6508f499b26650d44b6f5b3b1b2b..9264476f3d578e8fa346411aad4900e85afcb41a 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -132,8 +132,6 @@ struct cpuinfo_x86 { u16 logical_proc_id; /* Core id: */ u16 cpu_core_id; - /* Compute unit id */ - u8 compute_unit_id; /* Index into per_cpu list: */ u16 cpu_index; u32 microcode; diff --git a/arch/x86/include/asm/qspinlock_paravirt.h b/arch/x86/include/asm/qspinlock_paravirt.h index 9f92c180ed2fb769bf0e5d0b83ae6eba9ac27f75..9d55f9b6e167c16db344acd7e42992e1625f0459 100644 --- a/arch/x86/include/asm/qspinlock_paravirt.h +++ b/arch/x86/include/asm/qspinlock_paravirt.h @@ -36,8 +36,10 @@ PV_CALLEE_SAVE_REGS_THUNK(__pv_queued_spin_unlock_slowpath); */ asm (".pushsection .text;" ".globl " PV_UNLOCK ";" + ".type " PV_UNLOCK ", @function;" ".align 4,0x90;" PV_UNLOCK ": " + FRAME_BEGIN "push %rdx;" "mov $0x1,%eax;" "xor %edx,%edx;" @@ -45,6 +47,7 @@ asm (".pushsection .text;" "cmp $0x1,%al;" "jne .slowpath;" "pop %rdx;" + FRAME_END "ret;" ".slowpath: " "push %rsi;" @@ -52,6 +55,7 @@ asm (".pushsection .text;" "call " PV_UNLOCK_SLOWPATH ";" "pop %rsi;" "pop %rdx;" + FRAME_END "ret;" ".size " PV_UNLOCK ", .-" PV_UNLOCK ";" ".popsection"); diff --git a/arch/x86/include/asm/required-features.h b/arch/x86/include/asm/required-features.h index 5c6e4fb370f5aac25ee36002022ed72a59592f5e..4916144e3c42668a3e07af33859b4a1af3f2985b 100644 --- a/arch/x86/include/asm/required-features.h +++ b/arch/x86/include/asm/required-features.h @@ -92,5 +92,12 @@ #define REQUIRED_MASK7 0 #define REQUIRED_MASK8 0 #define REQUIRED_MASK9 0 +#define REQUIRED_MASK10 0 +#define REQUIRED_MASK11 0 +#define REQUIRED_MASK12 0 +#define REQUIRED_MASK13 0 +#define REQUIRED_MASK14 0 +#define REQUIRED_MASK15 0 +#define REQUIRED_MASK16 0 #endif /* _ASM_X86_REQUIRED_FEATURES_H */ diff --git a/arch/x86/include/asm/rwsem.h b/arch/x86/include/asm/rwsem.h index cad82c9c2fdef9cb157285379f3aaa4d8532a222..ceec86eb68e963d9b6d51ca015d8753ee8bd5144 100644 --- a/arch/x86/include/asm/rwsem.h +++ b/arch/x86/include/asm/rwsem.h @@ -25,7 +25,7 @@ * This should be totally fair - if anything is waiting, a process that wants a * lock will go to the back of the queue. When the currently active lock is * released, if there's a writer at the front of the queue, then that and only - * that will be woken up; if there's a bunch of consequtive readers at the + * that will be woken up; if there's a bunch of consecutive readers at the * front, then they'll all be woken up, but no other readers will be. */ diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h index 20a3de5cb3b0dd5e3362833baebd752c1142ae4e..66b057306f404718c233c18c5603ec30e9e535ba 100644 --- a/arch/x86/include/asm/smp.h +++ b/arch/x86/include/asm/smp.h @@ -155,6 +155,7 @@ static inline int wbinvd_on_all_cpus(void) wbinvd(); return 0; } +#define smp_num_siblings 1 #endif /* CONFIG_SMP */ extern unsigned disabled_cpus; diff --git a/arch/x86/include/asm/special_insns.h b/arch/x86/include/asm/special_insns.h index 2270e41b32fd856e226840d4f76dddaa7852d13d..d96d0437776569f5c9c0e6f28d125dbc5671d037 100644 --- a/arch/x86/include/asm/special_insns.h +++ b/arch/x86/include/asm/special_insns.h @@ -98,6 +98,44 @@ static inline void native_write_cr8(unsigned long val) } #endif +#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS +static inline u32 __read_pkru(void) +{ + u32 ecx = 0; + u32 edx, pkru; + + /* + * "rdpkru" instruction. Places PKRU contents in to EAX, + * clears EDX and requires that ecx=0. + */ + asm volatile(".byte 0x0f,0x01,0xee\n\t" + : "=a" (pkru), "=d" (edx) + : "c" (ecx)); + return pkru; +} + +static inline void __write_pkru(u32 pkru) +{ + u32 ecx = 0, edx = 0; + + /* + * "wrpkru" instruction. Loads contents in EAX to PKRU, + * requires that ecx = edx = 0. + */ + asm volatile(".byte 0x0f,0x01,0xef\n\t" + : : "a" (pkru), "c"(ecx), "d"(edx)); +} +#else +static inline u32 __read_pkru(void) +{ + return 0; +} + +static inline void __write_pkru(u32 pkru) +{ +} +#endif + static inline void native_wbinvd(void) { asm volatile("wbinvd": : :"memory"); diff --git a/arch/x86/include/asm/stacktrace.h b/arch/x86/include/asm/stacktrace.h index 70bbe39043a9cda384e9afcd0a2f633cfde20931..7c247e7404be778e06ebff15f020dbd792fb7be0 100644 --- a/arch/x86/include/asm/stacktrace.h +++ b/arch/x86/include/asm/stacktrace.h @@ -37,7 +37,7 @@ print_context_stack_bp(struct thread_info *tinfo, /* Generic stack tracer with callbacks */ struct stacktrace_ops { - void (*address)(void *data, unsigned long address, int reliable); + int (*address)(void *data, unsigned long address, int reliable); /* On negative return stop dumping */ int (*stack)(void *data, char *name); walk_stack_t walk_stack; diff --git a/arch/x86/include/asm/string_64.h b/arch/x86/include/asm/string_64.h index ca6ba36077054605580e8b8a6236eab7aa65733f..90dbbd9666d43cef657542251b4824d29c0fa7b9 100644 --- a/arch/x86/include/asm/string_64.h +++ b/arch/x86/include/asm/string_64.h @@ -87,9 +87,9 @@ int strcmp(const char *cs, const char *ct); * * Low level memory copy function that catches machine checks * - * Return true for success, false for fail + * Return 0 for success, -EFAULT for fail */ -bool memcpy_mcsafe(void *dst, const void *src, size_t cnt); +int memcpy_mcsafe(void *dst, const void *src, size_t cnt); #endif /* __KERNEL__ */ diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index 82866697fcf186ac7f63f1f6b5f1f77385dc8ab4..ffae84df8a9313cd3cc7b12953c0c24a809cd792 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h @@ -276,11 +276,9 @@ static inline bool is_ia32_task(void) */ #define force_iret() set_thread_flag(TIF_NOTIFY_RESUME) -#endif /* !__ASSEMBLY__ */ - -#ifndef __ASSEMBLY__ extern void arch_task_cache_init(void); extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src); extern void arch_release_task_struct(struct task_struct *tsk); -#endif +#endif /* !__ASSEMBLY__ */ + #endif /* _ASM_X86_THREAD_INFO_H */ diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h index c24b4224d439267051d85af645a026a54fd67f84..1fde8d580a5bac371c7a56cf60e688c49d2299f6 100644 --- a/arch/x86/include/asm/tlbflush.h +++ b/arch/x86/include/asm/tlbflush.h @@ -319,12 +319,6 @@ static inline void reset_lazy_tlbstate(void) #endif /* SMP */ -/* Not inlined due to inc_irq_stat not being defined yet */ -#define flush_tlb_local() { \ - inc_irq_stat(irq_tlb_count); \ - local_flush_tlb(); \ -} - #ifndef CONFIG_PARAVIRT #define flush_tlb_others(mask, mm, start, end) \ native_flush_tlb_others(mask, mm, start, end) diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h index c0f27d7ea7ff95eaea44987bd94417fabe68ca98..a969ae607be8323578865285b27cb443451b4483 100644 --- a/arch/x86/include/asm/uaccess.h +++ b/arch/x86/include/asm/uaccess.h @@ -105,9 +105,8 @@ static inline bool __chk_range_not_ok(unsigned long addr, unsigned long size, un struct exception_table_entry { int insn, fixup, handler; }; -/* This is not the generic standard exception_table_entry format */ -#define ARCH_HAS_SORT_EXTABLE -#define ARCH_HAS_SEARCH_EXTABLE + +#define ARCH_HAS_RELATIVE_EXTABLE extern int fixup_exception(struct pt_regs *regs, int trapnr); extern bool ex_has_fault_handler(unsigned long ip); @@ -179,10 +178,11 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL)) ({ \ int __ret_gu; \ register __inttype(*(ptr)) __val_gu asm("%"_ASM_DX); \ + register void *__sp asm(_ASM_SP); \ __chk_user_ptr(ptr); \ might_fault(); \ - asm volatile("call __get_user_%P3" \ - : "=a" (__ret_gu), "=r" (__val_gu) \ + asm volatile("call __get_user_%P4" \ + : "=a" (__ret_gu), "=r" (__val_gu), "+r" (__sp) \ : "0" (ptr), "i" (sizeof(*(ptr)))); \ (x) = (__force __typeof__(*(ptr))) __val_gu; \ __builtin_expect(__ret_gu, 0); \ diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h index 3bcdcc84259d98b919a7cc455b07082660bb6393..a12a047184ee4789d8fd041493862c543fa692ac 100644 --- a/arch/x86/include/asm/xen/hypercall.h +++ b/arch/x86/include/asm/xen/hypercall.h @@ -110,9 +110,10 @@ extern struct { char _entry[32]; } hypercall_page[]; register unsigned long __arg2 asm(__HYPERCALL_ARG2REG) = __arg2; \ register unsigned long __arg3 asm(__HYPERCALL_ARG3REG) = __arg3; \ register unsigned long __arg4 asm(__HYPERCALL_ARG4REG) = __arg4; \ - register unsigned long __arg5 asm(__HYPERCALL_ARG5REG) = __arg5; + register unsigned long __arg5 asm(__HYPERCALL_ARG5REG) = __arg5; \ + register void *__sp asm(_ASM_SP); -#define __HYPERCALL_0PARAM "=r" (__res) +#define __HYPERCALL_0PARAM "=r" (__res), "+r" (__sp) #define __HYPERCALL_1PARAM __HYPERCALL_0PARAM, "+r" (__arg1) #define __HYPERCALL_2PARAM __HYPERCALL_1PARAM, "+r" (__arg2) #define __HYPERCALL_3PARAM __HYPERCALL_2PARAM, "+r" (__arg3) diff --git a/arch/x86/include/asm/xen/hypervisor.h b/arch/x86/include/asm/xen/hypervisor.h index 8b2d4bea996273e1a72ee78aaa1a2b6358ccd189..39171b3646bba09d5c9a76e98632ae7339f6fbe8 100644 --- a/arch/x86/include/asm/xen/hypervisor.h +++ b/arch/x86/include/asm/xen/hypervisor.h @@ -62,4 +62,6 @@ void xen_arch_register_cpu(int num); void xen_arch_unregister_cpu(int num); #endif +extern void xen_set_iopl_mask(unsigned mask); + #endif /* _ASM_X86_XEN_HYPERVISOR_H */ diff --git a/arch/x86/include/uapi/asm/mman.h b/arch/x86/include/uapi/asm/mman.h index 513b05f15bb4f8cdeeb42369b18223ad506ded40..39bca7fac087098c1f972de4b1468733ffe6220a 100644 --- a/arch/x86/include/uapi/asm/mman.h +++ b/arch/x86/include/uapi/asm/mman.h @@ -6,6 +6,28 @@ #define MAP_HUGE_2MB (21 << MAP_HUGE_SHIFT) #define MAP_HUGE_1GB (30 << MAP_HUGE_SHIFT) +#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS +/* + * Take the 4 protection key bits out of the vma->vm_flags + * value and turn them in to the bits that we can put in + * to a pte. + * + * Only override these if Protection Keys are available + * (which is only on 64-bit). + */ +#define arch_vm_get_page_prot(vm_flags) __pgprot( \ + ((vm_flags) & VM_PKEY_BIT0 ? _PAGE_PKEY_BIT0 : 0) | \ + ((vm_flags) & VM_PKEY_BIT1 ? _PAGE_PKEY_BIT1 : 0) | \ + ((vm_flags) & VM_PKEY_BIT2 ? _PAGE_PKEY_BIT2 : 0) | \ + ((vm_flags) & VM_PKEY_BIT3 ? _PAGE_PKEY_BIT3 : 0)) + +#define arch_calc_vm_prot_bits(prot, key) ( \ + ((key) & 0x1 ? VM_PKEY_BIT0 : 0) | \ + ((key) & 0x2 ? VM_PKEY_BIT1 : 0) | \ + ((key) & 0x4 ? VM_PKEY_BIT2 : 0) | \ + ((key) & 0x8 ? VM_PKEY_BIT3 : 0)) +#endif + #include #endif /* _ASM_X86_MMAN_H */ diff --git a/arch/x86/include/uapi/asm/processor-flags.h b/arch/x86/include/uapi/asm/processor-flags.h index 79887abcb5e1fe1e45c08e94a3912fdd4ede9d4e..567de50a4c2a59c1a85ed4ee6025498352227dc1 100644 --- a/arch/x86/include/uapi/asm/processor-flags.h +++ b/arch/x86/include/uapi/asm/processor-flags.h @@ -118,6 +118,8 @@ #define X86_CR4_SMEP _BITUL(X86_CR4_SMEP_BIT) #define X86_CR4_SMAP_BIT 21 /* enable SMAP support */ #define X86_CR4_SMAP _BITUL(X86_CR4_SMAP_BIT) +#define X86_CR4_PKE_BIT 22 /* enable Protection Keys support */ +#define X86_CR4_PKE _BITUL(X86_CR4_PKE_BIT) /* * x86-64 Task Priority Register, CR8 diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index b1b78ffe01d060a38c93c3c7486393702edd4ffc..616ebd22ef9a2eee183dde7fae5bac7d03e28351 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -16,9 +16,21 @@ CFLAGS_REMOVE_ftrace.o = -pg CFLAGS_REMOVE_early_printk.o = -pg endif -KASAN_SANITIZE_head$(BITS).o := n -KASAN_SANITIZE_dumpstack.o := n -KASAN_SANITIZE_dumpstack_$(BITS).o := n +KASAN_SANITIZE_head$(BITS).o := n +KASAN_SANITIZE_dumpstack.o := n +KASAN_SANITIZE_dumpstack_$(BITS).o := n +KASAN_SANITIZE_stacktrace.o := n + +OBJECT_FILES_NON_STANDARD_head_$(BITS).o := y +OBJECT_FILES_NON_STANDARD_relocate_kernel_$(BITS).o := y +OBJECT_FILES_NON_STANDARD_mcount_$(BITS).o := y +OBJECT_FILES_NON_STANDARD_test_nx.o := y + +# If instrumentation of this dir is enabled, boot hangs during first second. +# Probably could be more selective here, but note that files related to irqs, +# boot, dumpstack/stacktrace, etc are either non-interesting or can lead to +# non-deterministic coverage. +KCOV_INSTRUMENT := n CFLAGS_irq.o := -I$(src)/../include/asm/trace diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index e75907601a41c349e05c8dfe63047dc460ccdf30..8c2f1ef6ca236ea16b9ae25a390b32d33ef566d4 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -956,7 +956,7 @@ static int __init early_acpi_parse_madt_lapic_addr_ovr(void) /* * Note that the LAPIC address is obtained from the MADT (32-bit value) - * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value). + * and (optionally) overridden by a LAPIC_ADDR_OVR entry (64-bit value). */ count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE, @@ -984,7 +984,7 @@ static int __init acpi_parse_madt_lapic_entries(void) /* * Note that the LAPIC address is obtained from the MADT (32-bit value) - * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value). + * and (optionally) overridden by a LAPIC_ADDR_OVR entry (64-bit value). */ count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE, diff --git a/arch/x86/kernel/acpi/wakeup_64.S b/arch/x86/kernel/acpi/wakeup_64.S index 8c35df4681041eee92f14020de8f795a8b7d710c..169963f471bbb2138352c2cdfd24d4f7cf9581a2 100644 --- a/arch/x86/kernel/acpi/wakeup_64.S +++ b/arch/x86/kernel/acpi/wakeup_64.S @@ -5,6 +5,7 @@ #include #include #include +#include # Copyright 2003 Pavel Machek , distribute under GPLv2 @@ -39,6 +40,7 @@ bogus_64_magic: jmp bogus_64_magic ENTRY(do_suspend_lowlevel) + FRAME_BEGIN subq $8, %rsp xorl %eax, %eax call save_processor_state @@ -109,6 +111,7 @@ ENTRY(do_suspend_lowlevel) xorl %eax, %eax addq $8, %rsp + FRAME_END jmp restore_processor_state ENDPROC(do_suspend_lowlevel) diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c index 29fa475ec51823e61a9e94f34142e37341a1208b..a147e676fc7b3439d156534472d63be5c2d10f4a 100644 --- a/arch/x86/kernel/amd_nb.c +++ b/arch/x86/kernel/amd_nb.c @@ -170,15 +170,13 @@ int amd_get_subcaches(int cpu) { struct pci_dev *link = node_to_amd_nb(amd_get_nb_id(cpu))->link; unsigned int mask; - int cuid; if (!amd_nb_has_feature(AMD_NB_L3_PARTITIONING)) return 0; pci_read_config_dword(link, 0x1d4, &mask); - cuid = cpu_data(cpu).compute_unit_id; - return (mask >> (4 * cuid)) & 0xf; + return (mask >> (4 * cpu_data(cpu).cpu_core_id)) & 0xf; } int amd_set_subcaches(int cpu, unsigned long mask) @@ -204,7 +202,7 @@ int amd_set_subcaches(int cpu, unsigned long mask) pci_write_config_dword(nb->misc, 0x1b8, reg & ~0x180000); } - cuid = cpu_data(cpu).compute_unit_id; + cuid = cpu_data(cpu).cpu_core_id; mask <<= 4 * cuid; mask |= (0xf ^ (1 << cuid)) << 26; diff --git a/arch/x86/kernel/apb_timer.c b/arch/x86/kernel/apb_timer.c index 222a57076039f25686087274ef6a42d7db9f91fc..cefacbad153118620348bb1e3bc88838f75dcde7 100644 --- a/arch/x86/kernel/apb_timer.c +++ b/arch/x86/kernel/apb_timer.c @@ -221,7 +221,7 @@ static int apbt_cpuhp_notify(struct notifier_block *n, unsigned long cpu = (unsigned long)hcpu; struct apbt_dev *adev = &per_cpu(cpu_apbt_dev, cpu); - switch (action & 0xf) { + switch (action & ~CPU_TASKS_FROZEN) { case CPU_DEAD: dw_apb_clockevent_pause(adev->timer); if (system_state == SYSTEM_RUNNING) { diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c index 6e85f713641dda77bd2d9dfeb99fa10cdbe0cb0d..0a2bb1f62e724d5820632eb59bbdaea18acdc659 100644 --- a/arch/x86/kernel/aperture_64.c +++ b/arch/x86/kernel/aperture_64.c @@ -227,19 +227,11 @@ static u32 __init search_agp_bridge(u32 *order, int *valid_agp) return 0; } -static int gart_fix_e820 __initdata = 1; +static bool gart_fix_e820 __initdata = true; static int __init parse_gart_mem(char *p) { - if (!p) - return -EINVAL; - - if (!strncmp(p, "off", 3)) - gart_fix_e820 = 0; - else if (!strncmp(p, "on", 2)) - gart_fix_e820 = 1; - - return 0; + return kstrtobool(p, &gart_fix_e820); } early_param("gart_fix_e820", parse_gart_mem); diff --git a/arch/x86/kernel/apic/Makefile b/arch/x86/kernel/apic/Makefile index 8bb12ddc5db8c8b9c7f2e0abdce44fef00f46453..8e63ebdcbd0b4cb2cfe43605ad48eaa46ca2d967 100644 --- a/arch/x86/kernel/apic/Makefile +++ b/arch/x86/kernel/apic/Makefile @@ -2,6 +2,10 @@ # Makefile for local APIC drivers and for the IO-APIC code # +# Leads to non-deterministic coverage that is not a function of syscall inputs. +# In particualr, smp_apic_timer_interrupt() is called in random places. +KCOV_INSTRUMENT := n + obj-$(CONFIG_X86_LOCAL_APIC) += apic.o apic_noop.o ipi.o vector.o obj-y += hw_nmi.o diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 531b9611c51d5d4b42f721f45609a5f4ecd3cce2..d356987a04e97ba6537b2895d45114851e7b705b 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -1611,7 +1611,7 @@ void __init enable_IR_x2apic(void) legacy_pic->mask_all(); mask_ioapic_entries(); - /* If irq_remapping_prepare() succeded, try to enable it */ + /* If irq_remapping_prepare() succeeded, try to enable it */ if (ir_stat >= 0) ir_stat = try_to_enable_IR(); /* ir_stat contains the remap mode or an error code */ diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c index 3b670df4ba7b429f48102b1401c9133957ecb6a9..ad59d70bcb1a6109742773e5f69a7235bca712f5 100644 --- a/arch/x86/kernel/apic/vector.c +++ b/arch/x86/kernel/apic/vector.c @@ -213,6 +213,7 @@ static int __assign_irq_vector(int irq, struct apic_chip_data *d, */ cpumask_and(d->old_domain, d->old_domain, cpu_online_mask); d->move_in_progress = !cpumask_empty(d->old_domain); + d->cfg.old_vector = d->move_in_progress ? d->cfg.vector : 0; d->cfg.vector = vector; cpumask_copy(d->domain, vector_cpumask); success: @@ -655,46 +656,97 @@ void irq_complete_move(struct irq_cfg *cfg) } /* - * Called with @desc->lock held and interrupts disabled. + * Called from fixup_irqs() with @desc->lock held and interrupts disabled. */ void irq_force_complete_move(struct irq_desc *desc) { struct irq_data *irqdata = irq_desc_get_irq_data(desc); struct apic_chip_data *data = apic_chip_data(irqdata); struct irq_cfg *cfg = data ? &data->cfg : NULL; + unsigned int cpu; if (!cfg) return; - __irq_complete_move(cfg, cfg->vector); - /* * This is tricky. If the cleanup of @data->old_domain has not been * done yet, then the following setaffinity call will fail with * -EBUSY. This can leave the interrupt in a stale state. * - * The cleanup cannot make progress because we hold @desc->lock. So in - * case @data->old_domain is not yet cleaned up, we need to drop the - * lock and acquire it again. @desc cannot go away, because the - * hotplug code holds the sparse irq lock. + * All CPUs are stuck in stop machine with interrupts disabled so + * calling __irq_complete_move() would be completely pointless. */ raw_spin_lock(&vector_lock); - /* Clean out all offline cpus (including ourself) first. */ + /* + * Clean out all offline cpus (including the outgoing one) from the + * old_domain mask. + */ cpumask_and(data->old_domain, data->old_domain, cpu_online_mask); - while (!cpumask_empty(data->old_domain)) { + + /* + * If move_in_progress is cleared and the old_domain mask is empty, + * then there is nothing to cleanup. fixup_irqs() will take care of + * the stale vectors on the outgoing cpu. + */ + if (!data->move_in_progress && cpumask_empty(data->old_domain)) { raw_spin_unlock(&vector_lock); - raw_spin_unlock(&desc->lock); - cpu_relax(); - raw_spin_lock(&desc->lock); + return; + } + + /* + * 1) The interrupt is in move_in_progress state. That means that we + * have not seen an interrupt since the io_apic was reprogrammed to + * the new vector. + * + * 2) The interrupt has fired on the new vector, but the cleanup IPIs + * have not been processed yet. + */ + if (data->move_in_progress) { /* - * Reevaluate apic_chip_data. It might have been cleared after - * we dropped @desc->lock. + * In theory there is a race: + * + * set_ioapic(new_vector) <-- Interrupt is raised before update + * is effective, i.e. it's raised on + * the old vector. + * + * So if the target cpu cannot handle that interrupt before + * the old vector is cleaned up, we get a spurious interrupt + * and in the worst case the ioapic irq line becomes stale. + * + * But in case of cpu hotplug this should be a non issue + * because if the affinity update happens right before all + * cpus rendevouz in stop machine, there is no way that the + * interrupt can be blocked on the target cpu because all cpus + * loops first with interrupts enabled in stop machine, so the + * old vector is not yet cleaned up when the interrupt fires. + * + * So the only way to run into this issue is if the delivery + * of the interrupt on the apic/system bus would be delayed + * beyond the point where the target cpu disables interrupts + * in stop machine. I doubt that it can happen, but at least + * there is a theroretical chance. Virtualization might be + * able to expose this, but AFAICT the IOAPIC emulation is not + * as stupid as the real hardware. + * + * Anyway, there is nothing we can do about that at this point + * w/o refactoring the whole fixup_irq() business completely. + * We print at least the irq number and the old vector number, + * so we have the necessary information when a problem in that + * area arises. */ - data = apic_chip_data(irqdata); - if (!data) - return; - raw_spin_lock(&vector_lock); + pr_warn("IRQ fixup: irq %d move in progress, old vector %d\n", + irqdata->irq, cfg->old_vector); } + /* + * If old_domain is not empty, then other cpus still have the irq + * descriptor set in their vector array. Clean it up. + */ + for_each_cpu(cpu, data->old_domain) + per_cpu(vector_irq, cpu)[cfg->old_vector] = VECTOR_UNUSED; + + /* Cleanup the left overs of the (half finished) move */ + cpumask_clear(data->old_domain); + data->move_in_progress = 0; raw_spin_unlock(&vector_lock); } #endif diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index 624db00583f44a76283c4d8d5e5377a8342f6517..8f4942e2bcbb21584a78225b1208adefe86e0aa9 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -792,7 +792,8 @@ static int uv_scir_cpu_notify(struct notifier_block *self, unsigned long action, { long cpu = (long)hcpu; - switch (action) { + switch (action & ~CPU_TASKS_FROZEN) { + case CPU_DOWN_FAILED: case CPU_ONLINE: uv_heartbeat_enable(cpu); break; @@ -860,7 +861,7 @@ int uv_set_vga_state(struct pci_dev *pdev, bool decode, */ void uv_cpu_init(void) { - /* CPU 0 initilization will be done via uv_system_init. */ + /* CPU 0 initialization will be done via uv_system_init. */ if (!uv_blade_info) return; diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c index 052c9c3026cce69ff68aaf9f0a3b5fd4a8c2cadf..9307f182fe3049f8e4f1c3d38bb9b1ebb3008d26 100644 --- a/arch/x86/kernel/apm_32.c +++ b/arch/x86/kernel/apm_32.c @@ -1088,7 +1088,7 @@ static int apm_get_battery_status(u_short which, u_short *status, * @device: identity of device * @enable: on/off * - * Activate or deactive power management on either a specific device + * Activate or deactivate power management on either a specific device * or the entire system (%APM_DEVICE_ALL). */ diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index 0d373d7affc8d48d1039f6c6d759a3b9cc191c38..4a8697f7d4ef804921c7422fac02f28c4b8b0c2b 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile @@ -8,6 +8,10 @@ CFLAGS_REMOVE_common.o = -pg CFLAGS_REMOVE_perf_event.o = -pg endif +# If these files are instrumented, boot hangs during the first second. +KCOV_INSTRUMENT_common.o := n +KCOV_INSTRUMENT_perf_event.o := n + # Make sure load_percpu_segment has no stackprotector nostackp := $(call cc-option, -fno-stack-protector) CFLAGS_common.o := $(nostackp) diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 97c59fd60702f4ceacad7c4d46a3c8d5de7dacbf..7b76eb67a9b3dcb84bb8e6cd6e40945924d32938 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -75,14 +75,17 @@ static inline int wrmsrl_amd_safe(unsigned msr, unsigned long long val) */ extern __visible void vide(void); -__asm__(".globl vide\n\t.align 4\nvide: ret"); +__asm__(".globl vide\n" + ".type vide, @function\n" + ".align 4\n" + "vide: ret\n"); static void init_amd_k5(struct cpuinfo_x86 *c) { #ifdef CONFIG_X86_32 /* * General Systems BIOSen alias the cpu frequency registers - * of the Elan at 0x000df000. Unfortuantly, one of the Linux + * of the Elan at 0x000df000. Unfortunately, one of the Linux * drivers subsequently pokes it, and changes the CPU speed. * Workaround : Remove the unneeded alias. */ @@ -297,7 +300,6 @@ static int nearby_node(int apicid) #ifdef CONFIG_SMP static void amd_get_topology(struct cpuinfo_x86 *c) { - u32 cores_per_cu = 1; u8 node_id; int cpu = smp_processor_id(); @@ -306,37 +308,32 @@ static void amd_get_topology(struct cpuinfo_x86 *c) u32 eax, ebx, ecx, edx; cpuid(0x8000001e, &eax, &ebx, &ecx, &edx); - nodes_per_socket = ((ecx >> 8) & 7) + 1; node_id = ecx & 7; /* get compute unit information */ smp_num_siblings = ((ebx >> 8) & 3) + 1; - c->compute_unit_id = ebx & 0xff; - cores_per_cu += ((ebx >> 8) & 3); + c->x86_max_cores /= smp_num_siblings; + c->cpu_core_id = ebx & 0xff; } else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) { u64 value; rdmsrl(MSR_FAM10H_NODE_ID, value); - nodes_per_socket = ((value >> 3) & 7) + 1; node_id = value & 7; } else return; /* fixup multi-node processor information */ if (nodes_per_socket > 1) { - u32 cores_per_node; u32 cus_per_node; set_cpu_cap(c, X86_FEATURE_AMD_DCM); - cores_per_node = c->x86_max_cores / nodes_per_socket; - cus_per_node = cores_per_node / cores_per_cu; + cus_per_node = c->x86_max_cores / nodes_per_socket; /* store NodeID, use llc_shared_map to store sibling info */ per_cpu(cpu_llc_id, cpu) = node_id; /* core id has to be in the [0 .. cores_per_node - 1] range */ - c->cpu_core_id %= cores_per_node; - c->compute_unit_id %= cus_per_node; + c->cpu_core_id %= cus_per_node; } } #endif @@ -519,6 +516,18 @@ static void bsp_init_amd(struct cpuinfo_x86 *c) if (cpu_has(c, X86_FEATURE_MWAITX)) use_mwaitx_delay(); + + if (boot_cpu_has(X86_FEATURE_TOPOEXT)) { + u32 ecx; + + ecx = cpuid_ecx(0x8000001e); + nodes_per_socket = ((ecx >> 8) & 7) + 1; + } else if (boot_cpu_has(X86_FEATURE_NODEID_MSR)) { + u64 value; + + rdmsrl(MSR_FAM10H_NODE_ID, value); + nodes_per_socket = ((value >> 3) & 7) + 1; + } } static void early_init_amd(struct cpuinfo_x86 *c) @@ -536,6 +545,10 @@ static void early_init_amd(struct cpuinfo_x86 *c) set_sched_clock_stable(); } + /* Bit 12 of 8000_0007 edx is accumulated power mechanism. */ + if (c->x86_power & BIT(12)) + set_cpu_cap(c, X86_FEATURE_ACC_POWER); + #ifdef CONFIG_X86_64 set_cpu_cap(c, X86_FEATURE_SYSCALL32); #else diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 249461f958516a5a281af53532e771c9d55e8189..8394b3d1f94fca21913fb27c2e7432e343006b64 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -303,6 +303,48 @@ static __always_inline void setup_smap(struct cpuinfo_x86 *c) } } +/* + * Protection Keys are not available in 32-bit mode. + */ +static bool pku_disabled; + +static __always_inline void setup_pku(struct cpuinfo_x86 *c) +{ + if (!cpu_has(c, X86_FEATURE_PKU)) + return; + if (pku_disabled) + return; + + cr4_set_bits(X86_CR4_PKE); + /* + * Seting X86_CR4_PKE will cause the X86_FEATURE_OSPKE + * cpuid bit to be set. We need to ensure that we + * update that bit in this CPU's "cpu_info". + */ + get_cpu_cap(c); +} + +#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS +static __init int setup_disable_pku(char *arg) +{ + /* + * Do not clear the X86_FEATURE_PKU bit. All of the + * runtime checks are against OSPKE so clearing the + * bit does nothing. + * + * This way, we will see "pku" in cpuinfo, but not + * "ospke", which is exactly what we want. It shows + * that the CPU has PKU, but the OS has not enabled it. + * This happens to be exactly how a system would look + * if we disabled the config option. + */ + pr_info("x86: 'nopku' specified, disabling Memory Protection Keys\n"); + pku_disabled = true; + return 1; +} +__setup("nopku", setup_disable_pku); +#endif /* CONFIG_X86_64 */ + /* * Some CPU features depend on higher CPUID levels, which may not always * be available due to CPUID level capping or broken virtualization @@ -625,6 +667,7 @@ void get_cpu_cap(struct cpuinfo_x86 *c) c->x86_capability[CPUID_7_0_EBX] = ebx; c->x86_capability[CPUID_6_EAX] = cpuid_eax(0x00000006); + c->x86_capability[CPUID_7_ECX] = ecx; } /* Extended state features: level 0x0000000d */ @@ -649,7 +692,9 @@ void get_cpu_cap(struct cpuinfo_x86 *c) cpuid_count(0x0000000F, 1, &eax, &ebx, &ecx, &edx); c->x86_capability[CPUID_F_1_EDX] = edx; - if (cpu_has(c, X86_FEATURE_CQM_OCCUP_LLC)) { + if ((cpu_has(c, X86_FEATURE_CQM_OCCUP_LLC)) || + ((cpu_has(c, X86_FEATURE_CQM_MBM_TOTAL)) || + (cpu_has(c, X86_FEATURE_CQM_MBM_LOCAL)))) { c->x86_cache_max_rmid = ecx; c->x86_cache_occ_scale = ebx; } @@ -925,7 +970,7 @@ static void identify_cpu(struct cpuinfo_x86 *c) if (this_cpu->c_identify) this_cpu->c_identify(c); - /* Clear/Set all flags overriden by options, after probe */ + /* Clear/Set all flags overridden by options, after probe */ for (i = 0; i < NCAPINTS; i++) { c->x86_capability[i] &= ~cpu_caps_cleared[i]; c->x86_capability[i] |= cpu_caps_set[i]; @@ -982,9 +1027,10 @@ static void identify_cpu(struct cpuinfo_x86 *c) init_hypervisor(c); x86_init_rdrand(c); x86_init_cache_qos(c); + setup_pku(c); /* - * Clear/Set all flags overriden by options, need do it + * Clear/Set all flags overridden by options, need do it * before following smp all cpus cap AND. */ for (i = 0; i < NCAPINTS; i++) { diff --git a/arch/x86/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c index 0b445c2ff735d44fedc469fd8ce0c1b8b1f1633b..ac780cad3b8601db3bcc2e174f69dc9ca3f00473 100644 --- a/arch/x86/kernel/cpu/mcheck/therm_throt.c +++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c @@ -384,6 +384,9 @@ static void intel_thermal_interrupt(void) { __u64 msr_val; + if (static_cpu_has(X86_FEATURE_HWP)) + wrmsrl_safe(MSR_HWP_STATUS, 0); + rdmsrl(MSR_IA32_THERM_STATUS, msr_val); /* Check for violation of core thermal thresholds*/ diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c index fcbcb2f678ca47360d23623887d216165969d6e8..19f57360dfd2583b82743c8cb69ffaef7175139b 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c @@ -42,7 +42,7 @@ EXPORT_SYMBOL_GPL(mtrr_state); * "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD * Opteron Processors" (26094 Rev. 3.30 February 2006), section * "13.2.1.2 SYSCFG Register": "The MtrrFixDramModEn bit should be set - * to 1 during BIOS initalization of the fixed MTRRs, then cleared to + * to 1 during BIOS initialization of the fixed MTRRs, then cleared to * 0 for operation." */ static inline void k8_check_syscfg_dram_mod_en(void) diff --git a/arch/x86/kernel/cpu/powerflags.c b/arch/x86/kernel/cpu/powerflags.c index 31f0f335ed2241d6d561e6b4edc98f8e03216e96..1dd8294fd7301c979744deedc1922f226b0e0346 100644 --- a/arch/x86/kernel/cpu/powerflags.c +++ b/arch/x86/kernel/cpu/powerflags.c @@ -18,4 +18,6 @@ const char *const x86_power_flags[32] = { "", /* tsc invariant mapped to constant_tsc */ "cpb", /* core performance boost */ "eff_freq_ro", /* Readonly aperf/mperf */ + "proc_feedback", /* processor feedback interface */ + "acc_power", /* accumulated power mechanism */ }; diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c index 32e5699eadfee52043a3028e2040a00ea2cc3375..8efa57a5f29ea58d119a0ab2ca130598d3144f0e 100644 --- a/arch/x86/kernel/dumpstack.c +++ b/arch/x86/kernel/dumpstack.c @@ -135,7 +135,8 @@ print_context_stack_bp(struct thread_info *tinfo, if (!__kernel_text_address(addr)) break; - ops->address(data, addr, 1); + if (ops->address(data, addr, 1)) + break; frame = frame->next_frame; ret_addr = &frame->return_address; print_ftrace_graph_addr(addr, data, ops, tinfo, graph); @@ -154,10 +155,11 @@ static int print_trace_stack(void *data, char *name) /* * Print one address/symbol entries per line. */ -static void print_trace_address(void *data, unsigned long addr, int reliable) +static int print_trace_address(void *data, unsigned long addr, int reliable) { touch_nmi_watchdog(); printk_stack_address(addr, reliable, data); + return 0; } static const struct stacktrace_ops print_trace_ops = { diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c index 21bf92490a7b9c8897fef3ccb3846ddd82875a70..8a121991e5ba9f742ef6f9b04072bbd06be31ddb 100644 --- a/arch/x86/kernel/early_printk.c +++ b/arch/x86/kernel/early_printk.c @@ -287,7 +287,7 @@ static __init void early_pci_serial_init(char *s) } /* - * Lastly, initalize the hardware + * Lastly, initialize the hardware */ if (*s) { if (strcmp(s, "nocfg") == 0) diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c index 0b1b9abd4d5fe002c2f31d70736dc3d785027305..8e37cc8a539adc1c9d348d9a25b13815d4166aa6 100644 --- a/arch/x86/kernel/fpu/core.c +++ b/arch/x86/kernel/fpu/core.c @@ -353,6 +353,69 @@ void fpu__activate_fpstate_write(struct fpu *fpu) } } +/* + * This function must be called before we write the current + * task's fpstate. + * + * This call gets the current FPU register state and moves + * it in to the 'fpstate'. Preemption is disabled so that + * no writes to the 'fpstate' can occur from context + * swiches. + * + * Must be followed by a fpu__current_fpstate_write_end(). + */ +void fpu__current_fpstate_write_begin(void) +{ + struct fpu *fpu = ¤t->thread.fpu; + + /* + * Ensure that the context-switching code does not write + * over the fpstate while we are doing our update. + */ + preempt_disable(); + + /* + * Move the fpregs in to the fpu's 'fpstate'. + */ + fpu__activate_fpstate_read(fpu); + + /* + * The caller is about to write to 'fpu'. Ensure that no + * CPU thinks that its fpregs match the fpstate. This + * ensures we will not be lazy and skip a XRSTOR in the + * future. + */ + fpu->last_cpu = -1; +} + +/* + * This function must be paired with fpu__current_fpstate_write_begin() + * + * This will ensure that the modified fpstate gets placed back in + * the fpregs if necessary. + * + * Note: This function may be called whether or not an _actual_ + * write to the fpstate occurred. + */ +void fpu__current_fpstate_write_end(void) +{ + struct fpu *fpu = ¤t->thread.fpu; + + /* + * 'fpu' now has an updated copy of the state, but the + * registers may still be out of date. Update them with + * an XRSTOR if they are active. + */ + if (fpregs_active()) + copy_kernel_to_fpregs(&fpu->state); + + /* + * Our update is done and the fpregs/fpstate are in sync + * if necessary. Context switches can happen again. + */ + preempt_enable(); +} + /* * 'fpu__restore()' is called to copy FPU registers from * the FPU fpstate to the live hw registers and to activate diff --git a/arch/x86/kernel/fpu/regset.c b/arch/x86/kernel/fpu/regset.c index 0bc3490420c55e1fcbecb458d8442766b901aab2..8bd1c003942aa801ed026ec770bdf00bc4cae946 100644 --- a/arch/x86/kernel/fpu/regset.c +++ b/arch/x86/kernel/fpu/regset.c @@ -8,7 +8,7 @@ /* * The xstateregs_active() routine is the same as the regset_fpregs_active() routine, * as the "regset->n" for the xstate regset will be updated based on the feature - * capabilites supported by the xsave. + * capabilities supported by the xsave. */ int regset_fpregs_active(struct task_struct *target, const struct user_regset *regset) { diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c index 6e8354f5a59353bd18801860980d779a19c61f74..b48ef35b28d4fbcab4b5f00d613b57e63a00b1d0 100644 --- a/arch/x86/kernel/fpu/xstate.c +++ b/arch/x86/kernel/fpu/xstate.c @@ -5,6 +5,7 @@ */ #include #include +#include #include #include @@ -13,6 +14,11 @@ #include +/* + * Although we spell it out in here, the Processor Trace + * xfeature is completely unused. We use other mechanisms + * to save/restore PT state in Linux. + */ static const char *xfeature_names[] = { "x87 floating point registers" , @@ -23,6 +29,8 @@ static const char *xfeature_names[] = "AVX-512 opmask" , "AVX-512 Hi256" , "AVX-512 ZMM_Hi256" , + "Processor Trace (unused)" , + "Protection Keys User registers", "unknown xstate feature" , }; @@ -56,6 +64,7 @@ void fpu__xstate_clear_all_cpu_caps(void) setup_clear_cpu_cap(X86_FEATURE_AVX512VL); setup_clear_cpu_cap(X86_FEATURE_MPX); setup_clear_cpu_cap(X86_FEATURE_XGETBV1); + setup_clear_cpu_cap(X86_FEATURE_PKU); } /* @@ -234,7 +243,7 @@ static void __init print_xstate_feature(u64 xstate_mask) const char *feature_name; if (cpu_has_xfeatures(xstate_mask, &feature_name)) - pr_info("x86/fpu: Supporting XSAVE feature 0x%02Lx: '%s'\n", xstate_mask, feature_name); + pr_info("x86/fpu: Supporting XSAVE feature 0x%03Lx: '%s'\n", xstate_mask, feature_name); } /* @@ -250,6 +259,7 @@ static void __init print_xstate_features(void) print_xstate_feature(XFEATURE_MASK_OPMASK); print_xstate_feature(XFEATURE_MASK_ZMM_Hi256); print_xstate_feature(XFEATURE_MASK_Hi16_ZMM); + print_xstate_feature(XFEATURE_MASK_PKRU); } /* @@ -466,6 +476,7 @@ static void check_xstate_against_struct(int nr) XCHECK_SZ(sz, nr, XFEATURE_OPMASK, struct avx_512_opmask_state); XCHECK_SZ(sz, nr, XFEATURE_ZMM_Hi256, struct avx_512_zmm_uppers_state); XCHECK_SZ(sz, nr, XFEATURE_Hi16_ZMM, struct avx_512_hi16_state); + XCHECK_SZ(sz, nr, XFEATURE_PKRU, struct pkru_state); /* * Make *SURE* to add any feature numbers in below if @@ -473,7 +484,8 @@ static void check_xstate_against_struct(int nr) * numbers. */ if ((nr < XFEATURE_YMM) || - (nr >= XFEATURE_MAX)) { + (nr >= XFEATURE_MAX) || + (nr == XFEATURE_PT_UNIMPLEMENTED_SO_FAR)) { WARN_ONCE(1, "no structure for xstate: %d\n", nr); XSTATE_WARN_ON(1); } @@ -670,6 +682,19 @@ void fpu__resume_cpu(void) xsetbv(XCR_XFEATURE_ENABLED_MASK, xfeatures_mask); } +/* + * Given an xstate feature mask, calculate where in the xsave + * buffer the state is. Callers should ensure that the buffer + * is valid. + * + * Note: does not work for compacted buffers. + */ +void *__raw_xsave_addr(struct xregs_state *xsave, int xstate_feature_mask) +{ + int feature_nr = fls64(xstate_feature_mask) - 1; + + return (void *)xsave + xstate_comp_offsets[feature_nr]; +} /* * Given the xsave area and a state inside, this function returns the * address of the state. @@ -690,7 +715,6 @@ void fpu__resume_cpu(void) */ void *get_xsave_addr(struct xregs_state *xsave, int xstate_feature) { - int feature_nr = fls64(xstate_feature) - 1; /* * Do we even *have* xsave state? */ @@ -718,7 +742,7 @@ void *get_xsave_addr(struct xregs_state *xsave, int xstate_feature) if (!(xsave->header.xfeatures & xstate_feature)) return NULL; - return (void *)xsave + xstate_comp_offsets[feature_nr]; + return __raw_xsave_addr(xsave, xstate_feature); } EXPORT_SYMBOL_GPL(get_xsave_addr); @@ -753,3 +777,156 @@ const void *get_xsave_field_ptr(int xsave_state) return get_xsave_addr(&fpu->state.xsave, xsave_state); } + + +/* + * Set xfeatures (aka XSTATE_BV) bit for a feature that we want + * to take out of its "init state". This will ensure that an + * XRSTOR actually restores the state. + */ +static void fpu__xfeature_set_non_init(struct xregs_state *xsave, + int xstate_feature_mask) +{ + xsave->header.xfeatures |= xstate_feature_mask; +} + +/* + * This function is safe to call whether the FPU is in use or not. + * + * Note that this only works on the current task. + * + * Inputs: + * @xsave_state: state which is defined in xsave.h (e.g. XFEATURE_MASK_FP, + * XFEATURE_MASK_SSE, etc...) + * @xsave_state_ptr: a pointer to a copy of the state that you would + * like written in to the current task's FPU xsave state. This pointer + * must not be located in the current tasks's xsave area. + * Output: + * address of the state in the xsave area or NULL if the state + * is not present or is in its 'init state'. + */ +static void fpu__xfeature_set_state(int xstate_feature_mask, + void *xstate_feature_src, size_t len) +{ + struct xregs_state *xsave = ¤t->thread.fpu.state.xsave; + struct fpu *fpu = ¤t->thread.fpu; + void *dst; + + if (!boot_cpu_has(X86_FEATURE_XSAVE)) { + WARN_ONCE(1, "%s() attempted with no xsave support", __func__); + return; + } + + /* + * Tell the FPU code that we need the FPU state to be in + * 'fpu' (not in the registers), and that we need it to + * be stable while we write to it. + */ + fpu__current_fpstate_write_begin(); + + /* + * This method *WILL* *NOT* work for compact-format + * buffers. If the 'xstate_feature_mask' is unset in + * xcomp_bv then we may need to move other feature state + * "up" in the buffer. + */ + if (xsave->header.xcomp_bv & xstate_feature_mask) { + WARN_ON_ONCE(1); + goto out; + } + + /* find the location in the xsave buffer of the desired state */ + dst = __raw_xsave_addr(&fpu->state.xsave, xstate_feature_mask); + + /* + * Make sure that the pointer being passed in did not + * come from the xsave buffer itself. + */ + WARN_ONCE(xstate_feature_src == dst, "set from xsave buffer itself"); + + /* put the caller-provided data in the location */ + memcpy(dst, xstate_feature_src, len); + + /* + * Mark the xfeature so that the CPU knows there is state + * in the buffer now. + */ + fpu__xfeature_set_non_init(xsave, xstate_feature_mask); +out: + /* + * We are done writing to the 'fpu'. Reenable preeption + * and (possibly) move the fpstate back in to the fpregs. + */ + fpu__current_fpstate_write_end(); +} + +#define NR_VALID_PKRU_BITS (CONFIG_NR_PROTECTION_KEYS * 2) +#define PKRU_VALID_MASK (NR_VALID_PKRU_BITS - 1) + +/* + * This will go out and modify the XSAVE buffer so that PKRU is + * set to a particular state for access to 'pkey'. + * + * PKRU state does affect kernel access to user memory. We do + * not modfiy PKRU *itself* here, only the XSAVE state that will + * be restored in to PKRU when we return back to userspace. + */ +int arch_set_user_pkey_access(struct task_struct *tsk, int pkey, + unsigned long init_val) +{ + struct xregs_state *xsave = &tsk->thread.fpu.state.xsave; + struct pkru_state *old_pkru_state; + struct pkru_state new_pkru_state; + int pkey_shift = (pkey * PKRU_BITS_PER_PKEY); + u32 new_pkru_bits = 0; + + /* + * This check implies XSAVE support. OSPKE only gets + * set if we enable XSAVE and we enable PKU in XCR0. + */ + if (!boot_cpu_has(X86_FEATURE_OSPKE)) + return -EINVAL; + + /* Set the bits we need in PKRU */ + if (init_val & PKEY_DISABLE_ACCESS) + new_pkru_bits |= PKRU_AD_BIT; + if (init_val & PKEY_DISABLE_WRITE) + new_pkru_bits |= PKRU_WD_BIT; + + /* Shift the bits in to the correct place in PKRU for pkey. */ + new_pkru_bits <<= pkey_shift; + + /* Locate old copy of the state in the xsave buffer */ + old_pkru_state = get_xsave_addr(xsave, XFEATURE_MASK_PKRU); + + /* + * When state is not in the buffer, it is in the init + * state, set it manually. Otherwise, copy out the old + * state. + */ + if (!old_pkru_state) + new_pkru_state.pkru = 0; + else + new_pkru_state.pkru = old_pkru_state->pkru; + + /* mask off any old bits in place */ + new_pkru_state.pkru &= ~((PKRU_AD_BIT|PKRU_WD_BIT) << pkey_shift); + /* Set the newly-requested bits */ + new_pkru_state.pkru |= new_pkru_bits; + + /* + * We could theoretically live without zeroing pkru.pad. + * The current XSAVE feature state definition says that + * only bytes 0->3 are used. But we do not want to + * chance leaking kernel stack out to userspace in case a + * memcpy() of the whole xsave buffer was done. + * + * They're in the same cacheline anyway. + */ + new_pkru_state.pad = 0; + + fpu__xfeature_set_state(XFEATURE_MASK_PKRU, &new_pkru_state, + sizeof(new_pkru_state)); + + return 0; +} diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index 702547ce33c9c7a33fd321fdb94367af5515dd8b..d036cfb4495db30015db71eee64cf7f633603a2b 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c @@ -1,5 +1,5 @@ /* - * Code for replacing ftrace calls with jumps. + * Dynamic function tracing support. * * Copyright (C) 2007-2008 Steven Rostedt * diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index be0ebbb6d1d144fc86bcab6716871ea8cdaa4744..a1f0e4a5c47e3239824ac9c61774127e378d4f03 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c @@ -717,7 +717,7 @@ static int hpet_cpuhp_notify(struct notifier_block *n, struct hpet_work_struct work; struct hpet_dev *hdev = per_cpu(cpu_hpet_dev, cpu); - switch (action & 0xf) { + switch (action & ~CPU_TASKS_FROZEN) { case CPU_ONLINE: INIT_DELAYED_WORK_ONSTACK(&work.work, hpet_work); init_completion(&work.complete); diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c index 37dae792dbbed00b480aa67a33cb0b2ae1699428..589b3193f1020b8389a5f64b296cff531e85e849 100644 --- a/arch/x86/kernel/ioport.c +++ b/arch/x86/kernel/ioport.c @@ -96,9 +96,14 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on) SYSCALL_DEFINE1(iopl, unsigned int, level) { struct pt_regs *regs = current_pt_regs(); - unsigned int old = (regs->flags >> 12) & 3; struct thread_struct *t = ¤t->thread; + /* + * Careful: the IOPL bits in regs->flags are undefined under Xen PV + * and changing them has no effect. + */ + unsigned int old = t->iopl >> X86_EFLAGS_IOPL_BIT; + if (level > 3) return -EINVAL; /* Trying to gain more privileges? */ @@ -106,8 +111,9 @@ SYSCALL_DEFINE1(iopl, unsigned int, level) if (!capable(CAP_SYS_RAWIO)) return -EPERM; } - regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12); - t->iopl = level << 12; + regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | + (level << X86_EFLAGS_IOPL_BIT); + t->iopl = level << X86_EFLAGS_IOPL_BIT; set_iopl_mask(t->iopl); return 0; diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c index 0f8a6bbaaa443c9cc1b936755373e2b28c59ab4d..2af478e3fd4e2a5c9565adbe781eb06ed9ca5b60 100644 --- a/arch/x86/kernel/kexec-bzimage64.c +++ b/arch/x86/kernel/kexec-bzimage64.c @@ -271,7 +271,7 @@ static int bzImage64_probe(const char *buf, unsigned long len) int ret = -ENOEXEC; struct setup_header *header; - /* kernel should be atleast two sectors long */ + /* kernel should be at least two sectors long */ if (len < 2 * 512) { pr_err("File is too short to be a bzImage\n"); return ret; diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c index ed15cd486d06347626c080a0081e3eed01ac9128..2da6ee9ae69b725a1d960c0467005c1e581d96c4 100644 --- a/arch/x86/kernel/kgdb.c +++ b/arch/x86/kernel/kgdb.c @@ -609,9 +609,9 @@ static struct notifier_block kgdb_notifier = { }; /** - * kgdb_arch_init - Perform any architecture specific initalization. + * kgdb_arch_init - Perform any architecture specific initialization. * - * This function will handle the initalization of any architecture + * This function will handle the initialization of any architecture * specific callbacks. */ int kgdb_arch_init(void) diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index 0f05deeff5ce2e2af5aa7fb1f2fe1f59f4ed8348..ae703acb85c185e8c6f3735da83f9998b2f8e7a1 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -671,39 +672,39 @@ NOKPROBE_SYMBOL(kprobe_int3_handler); * When a retprobed function returns, this code saves registers and * calls trampoline_handler() runs, which calls the kretprobe's handler. */ -static void __used kretprobe_trampoline_holder(void) -{ - asm volatile ( - ".global kretprobe_trampoline\n" - "kretprobe_trampoline: \n" +asm( + ".global kretprobe_trampoline\n" + ".type kretprobe_trampoline, @function\n" + "kretprobe_trampoline:\n" #ifdef CONFIG_X86_64 - /* We don't bother saving the ss register */ - " pushq %rsp\n" - " pushfq\n" - SAVE_REGS_STRING - " movq %rsp, %rdi\n" - " call trampoline_handler\n" - /* Replace saved sp with true return address. */ - " movq %rax, 152(%rsp)\n" - RESTORE_REGS_STRING - " popfq\n" + /* We don't bother saving the ss register */ + " pushq %rsp\n" + " pushfq\n" + SAVE_REGS_STRING + " movq %rsp, %rdi\n" + " call trampoline_handler\n" + /* Replace saved sp with true return address. */ + " movq %rax, 152(%rsp)\n" + RESTORE_REGS_STRING + " popfq\n" #else - " pushf\n" - SAVE_REGS_STRING - " movl %esp, %eax\n" - " call trampoline_handler\n" - /* Move flags to cs */ - " movl 56(%esp), %edx\n" - " movl %edx, 52(%esp)\n" - /* Replace saved flags with true return address. */ - " movl %eax, 56(%esp)\n" - RESTORE_REGS_STRING - " popf\n" + " pushf\n" + SAVE_REGS_STRING + " movl %esp, %eax\n" + " call trampoline_handler\n" + /* Move flags to cs */ + " movl 56(%esp), %edx\n" + " movl %edx, 52(%esp)\n" + /* Replace saved flags with true return address. */ + " movl %eax, 56(%esp)\n" + RESTORE_REGS_STRING + " popf\n" #endif - " ret\n"); -} -NOKPROBE_SYMBOL(kretprobe_trampoline_holder); + " ret\n" + ".size kretprobe_trampoline, .-kretprobe_trampoline\n" +); NOKPROBE_SYMBOL(kretprobe_trampoline); +STACK_FRAME_NON_STANDARD(kretprobe_trampoline); /* * Called from kretprobe_trampoline diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index 47190bd399e7ef5680172859fa78d9ae1ba0e595..807950860fb7028e28fe1e98d8a2cddeccfa8063 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -91,14 +92,14 @@ static void kvm_io_delay(void) struct kvm_task_sleep_node { struct hlist_node link; - wait_queue_head_t wq; + struct swait_queue_head wq; u32 token; int cpu; bool halted; }; static struct kvm_task_sleep_head { - spinlock_t lock; + raw_spinlock_t lock; struct hlist_head list; } async_pf_sleepers[KVM_TASK_SLEEP_HASHSIZE]; @@ -122,17 +123,17 @@ void kvm_async_pf_task_wait(u32 token) u32 key = hash_32(token, KVM_TASK_SLEEP_HASHBITS); struct kvm_task_sleep_head *b = &async_pf_sleepers[key]; struct kvm_task_sleep_node n, *e; - DEFINE_WAIT(wait); + DECLARE_SWAITQUEUE(wait); rcu_irq_enter(); - spin_lock(&b->lock); + raw_spin_lock(&b->lock); e = _find_apf_task(b, token); if (e) { /* dummy entry exist -> wake up was delivered ahead of PF */ hlist_del(&e->link); kfree(e); - spin_unlock(&b->lock); + raw_spin_unlock(&b->lock); rcu_irq_exit(); return; @@ -141,13 +142,13 @@ void kvm_async_pf_task_wait(u32 token) n.token = token; n.cpu = smp_processor_id(); n.halted = is_idle_task(current) || preempt_count() > 1; - init_waitqueue_head(&n.wq); + init_swait_queue_head(&n.wq); hlist_add_head(&n.link, &b->list); - spin_unlock(&b->lock); + raw_spin_unlock(&b->lock); for (;;) { if (!n.halted) - prepare_to_wait(&n.wq, &wait, TASK_UNINTERRUPTIBLE); + prepare_to_swait(&n.wq, &wait, TASK_UNINTERRUPTIBLE); if (hlist_unhashed(&n.link)) break; @@ -166,7 +167,7 @@ void kvm_async_pf_task_wait(u32 token) } } if (!n.halted) - finish_wait(&n.wq, &wait); + finish_swait(&n.wq, &wait); rcu_irq_exit(); return; @@ -178,8 +179,8 @@ static void apf_task_wake_one(struct kvm_task_sleep_node *n) hlist_del_init(&n->link); if (n->halted) smp_send_reschedule(n->cpu); - else if (waitqueue_active(&n->wq)) - wake_up(&n->wq); + else if (swait_active(&n->wq)) + swake_up(&n->wq); } static void apf_task_wake_all(void) @@ -189,14 +190,14 @@ static void apf_task_wake_all(void) for (i = 0; i < KVM_TASK_SLEEP_HASHSIZE; i++) { struct hlist_node *p, *next; struct kvm_task_sleep_head *b = &async_pf_sleepers[i]; - spin_lock(&b->lock); + raw_spin_lock(&b->lock); hlist_for_each_safe(p, next, &b->list) { struct kvm_task_sleep_node *n = hlist_entry(p, typeof(*n), link); if (n->cpu == smp_processor_id()) apf_task_wake_one(n); } - spin_unlock(&b->lock); + raw_spin_unlock(&b->lock); } } @@ -212,7 +213,7 @@ void kvm_async_pf_task_wake(u32 token) } again: - spin_lock(&b->lock); + raw_spin_lock(&b->lock); n = _find_apf_task(b, token); if (!n) { /* @@ -225,17 +226,17 @@ void kvm_async_pf_task_wake(u32 token) * Allocation failed! Busy wait while other cpu * handles async PF. */ - spin_unlock(&b->lock); + raw_spin_unlock(&b->lock); cpu_relax(); goto again; } n->token = token; n->cpu = smp_processor_id(); - init_waitqueue_head(&n->wq); + init_swait_queue_head(&n->wq); hlist_add_head(&n->link, &b->list); } else apf_task_wake_one(n); - spin_unlock(&b->lock); + raw_spin_unlock(&b->lock); return; } EXPORT_SYMBOL_GPL(kvm_async_pf_task_wake); @@ -486,7 +487,7 @@ void __init kvm_guest_init(void) paravirt_ops_setup(); register_reboot_notifier(&kvm_pv_reboot_nb); for (i = 0; i < KVM_TASK_SLEEP_HASHSIZE; i++) - spin_lock_init(&async_pf_sleepers[i].lock); + raw_spin_lock_init(&async_pf_sleepers[i].lock); if (kvm_para_has_feature(KVM_FEATURE_ASYNC_PF)) x86_init.irqs.trap_init = kvm_apf_trap_init; diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c index 72cef58693c7388cc69ceb9e0f8cd4149d3ade95..1d39bfbd26bb3d0918271f13af86c94385983150 100644 --- a/arch/x86/kernel/kvmclock.c +++ b/arch/x86/kernel/kvmclock.c @@ -226,7 +226,7 @@ static void kvm_setup_secondary_clock(void) * registered memory location. If the guest happens to shutdown, this memory * won't be valid. In cases like kexec, in which you install a new kernel, this * means a random memory location will be kept being written. So before any - * kind of shutdown from our side, we unregister the clock by writting anything + * kind of shutdown from our side, we unregister the clock by writing anything * that does not have the 'enable' bit set in the msr */ #ifdef CONFIG_KEXEC_CORE diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c index 6acc9dd91f368a1fada3f2d6dd2a0755f1d7b46d..6707039b9032d98ebdb21b37769d4e400fa80cd0 100644 --- a/arch/x86/kernel/ldt.c +++ b/arch/x86/kernel/ldt.c @@ -103,7 +103,7 @@ static void free_ldt_struct(struct ldt_struct *ldt) * we do not have to muck with descriptors here, that is * done in switch_mm() as needed. */ -int init_new_context(struct task_struct *tsk, struct mm_struct *mm) +int init_new_context_ldt(struct task_struct *tsk, struct mm_struct *mm) { struct ldt_struct *new_ldt; struct mm_struct *old_mm; @@ -144,7 +144,7 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm) * * 64bit: Don't touch the LDT register - we're already in the next thread. */ -void destroy_context(struct mm_struct *mm) +void destroy_context_ldt(struct mm_struct *mm) { free_ldt_struct(mm->context.ldt); mm->context.ldt = NULL; diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index b9d99e0f82c4f072a15f7cb3fb3434d391281daf..6cbab31ac23a20fb3980f06f88becddff135411b 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -48,6 +48,7 @@ #include #include #include +#include asmlinkage extern void ret_from_fork(void); @@ -116,6 +117,8 @@ void __show_regs(struct pt_regs *regs, int all) printk(KERN_DEFAULT "DR0: %016lx DR1: %016lx DR2: %016lx\n", d0, d1, d2); printk(KERN_DEFAULT "DR3: %016lx DR6: %016lx DR7: %016lx\n", d3, d6, d7); + if (boot_cpu_has(X86_FEATURE_OSPKE)) + printk(KERN_DEFAULT "PKRU: %08x\n", read_pkru()); } void release_thread(struct task_struct *dead_task) @@ -411,6 +414,17 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) task_thread_info(prev_p)->flags & _TIF_WORK_CTXSW_PREV)) __switch_to_xtra(prev_p, next_p, tss); +#ifdef CONFIG_XEN + /* + * On Xen PV, IOPL bits in pt_regs->flags have no effect, and + * current_pt_regs()->flags may not match the current task's + * intended IOPL. We need to switch it manually. + */ + if (unlikely(static_cpu_has(X86_FEATURE_XENPV) && + prev->iopl != next->iopl)) + xen_set_iopl_mask(next->iopl); +#endif + if (static_cpu_has_bug(X86_BUG_SYSRET_SS_ATTRS)) { /* * AMD CPUs have a misfeature: SYSRET sets the SS selector but @@ -476,7 +490,7 @@ void set_personality_ia32(bool x32) if (current->mm) current->mm->context.ia32_compat = TIF_X32; current->personality &= ~READ_IMPLIES_EXEC; - /* is_compat_task() uses the presence of the x32 + /* in_compat_syscall() uses the presence of the x32 syscall bit flag to determine compat status */ current_thread_info()->status &= ~TS_COMPAT; } else { diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index aa52c10094755e2fa9fdd5ac7a39b0c36effac8a..319b08a5b6ed353fb1ca9a03bc1e29626b59677d 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -112,6 +112,7 @@ #include #include #include +#include /* * max_low_pfn_mapped: highest direct mapped pfn under 4GB @@ -145,31 +146,6 @@ int default_check_phys_apicid_present(int phys_apicid) struct boot_params boot_params; -/* - * Machine setup.. - */ -static struct resource data_resource = { - .name = "Kernel data", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM -}; - -static struct resource code_resource = { - .name = "Kernel code", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM -}; - -static struct resource bss_resource = { - .name = "Kernel bss", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM -}; - - #ifdef CONFIG_X86_32 /* cpu data as detected by the assembly code in head.S */ struct cpuinfo_x86 new_cpu_data = { @@ -948,13 +924,6 @@ void __init setup_arch(char **cmdline_p) mpx_mm_init(&init_mm); - code_resource.start = __pa_symbol(_text); - code_resource.end = __pa_symbol(_etext)-1; - data_resource.start = __pa_symbol(_etext); - data_resource.end = __pa_symbol(_edata)-1; - bss_resource.start = __pa_symbol(__bss_start); - bss_resource.end = __pa_symbol(__bss_stop)-1; - #ifdef CONFIG_CMDLINE_BOOL #ifdef CONFIG_CMDLINE_OVERRIDE strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); @@ -1018,11 +987,6 @@ void __init setup_arch(char **cmdline_p) x86_init.resources.probe_roms(); - /* after parse_early_param, so could debug it */ - insert_resource(&iomem_resource, &code_resource); - insert_resource(&iomem_resource, &data_resource); - insert_resource(&iomem_resource, &bss_resource); - e820_add_kernel_range(); trim_bios_range(); #ifdef CONFIG_X86_32 @@ -1282,3 +1246,11 @@ static int __init register_kernel_offset_dumper(void) return 0; } __initcall(register_kernel_offset_dumper); + +void arch_show_smap(struct seq_file *m, struct vm_area_struct *vma) +{ + if (!boot_cpu_has(X86_FEATURE_OSPKE)) + return; + + seq_printf(m, "ProtectionKey: %8u\n", vma_pkey(vma)); +} diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 643dbdccf4bc9ac41305d79f1da91762574f7b12..a2065d3b3b396f4503f4e4f42acc2af2bd4b307b 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -274,11 +274,6 @@ int topology_update_package_map(unsigned int apicid, unsigned int cpu) if (test_and_set_bit(pkg, physical_package_map)) goto found; - if (pkg < __max_logical_packages) { - set_bit(pkg, logical_package_map); - physical_to_logical_pkg[pkg] = pkg; - goto found; - } new = find_first_zero_bit(logical_package_map, __max_logical_packages); if (new >= __max_logical_packages) { physical_to_logical_pkg[pkg] = -1; @@ -317,9 +312,27 @@ static void __init smp_init_package_map(void) /* * Today neither Intel nor AMD support heterogenous systems. That * might change in the future.... + * + * While ideally we'd want '* smp_num_siblings' in the below @ncpus + * computation, this won't actually work since some Intel BIOSes + * report inconsistent HT data when they disable HT. + * + * In particular, they reduce the APIC-IDs to only include the cores, + * but leave the CPUID topology to say there are (2) siblings. + * This means we don't know how many threads there will be until + * after the APIC enumeration. + * + * By not including this we'll sometimes over-estimate the number of + * logical packages by the amount of !present siblings, but this is + * still better than MAX_LOCAL_APIC. + * + * We use total_cpus not nr_cpu_ids because nr_cpu_ids can be limited + * on the command line leading to a similar issue as the HT disable + * problem because the hyperthreads are usually enumerated after the + * primary cores. */ - ncpus = boot_cpu_data.x86_max_cores * smp_num_siblings; - __max_logical_packages = DIV_ROUND_UP(nr_cpu_ids, ncpus); + ncpus = boot_cpu_data.x86_max_cores; + __max_logical_packages = DIV_ROUND_UP(total_cpus, ncpus); /* * Possibly larger than what we need as the number of apic ids per @@ -409,7 +422,7 @@ static bool match_smt(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o) if (c->phys_proc_id == o->phys_proc_id && per_cpu(cpu_llc_id, cpu1) == per_cpu(cpu_llc_id, cpu2) && - c->compute_unit_id == o->compute_unit_id) + c->cpu_core_id == o->cpu_core_id) return topology_sane(c, o, "smt"); } else if (c->phys_proc_id == o->phys_proc_id && diff --git a/arch/x86/kernel/stacktrace.c b/arch/x86/kernel/stacktrace.c index fdd0c6430e5abc97c878d192439447298b2fd06c..9ee98eefc44dec04148dada9c3b8000c016fd738 100644 --- a/arch/x86/kernel/stacktrace.c +++ b/arch/x86/kernel/stacktrace.c @@ -14,30 +14,34 @@ static int save_stack_stack(void *data, char *name) return 0; } -static void +static int __save_stack_address(void *data, unsigned long addr, bool reliable, bool nosched) { struct stack_trace *trace = data; #ifdef CONFIG_FRAME_POINTER if (!reliable) - return; + return 0; #endif if (nosched && in_sched_functions(addr)) - return; + return 0; if (trace->skip > 0) { trace->skip--; - return; + return 0; } - if (trace->nr_entries < trace->max_entries) + if (trace->nr_entries < trace->max_entries) { trace->entries[trace->nr_entries++] = addr; + return 0; + } else { + return -1; /* no more room, stop walking the stack */ + } } -static void save_stack_address(void *data, unsigned long addr, int reliable) +static int save_stack_address(void *data, unsigned long addr, int reliable) { return __save_stack_address(data, addr, reliable, false); } -static void +static int save_stack_address_nosched(void *data, unsigned long addr, int reliable) { return __save_stack_address(data, addr, reliable, true); diff --git a/arch/x86/kernel/tboot.c b/arch/x86/kernel/tboot.c index 91a4496db43429de294e481075782295b76ff0e6..e72a07f20b05cfb079f2dca79e063b1dd340f2e4 100644 --- a/arch/x86/kernel/tboot.c +++ b/arch/x86/kernel/tboot.c @@ -135,7 +135,7 @@ static int map_tboot_page(unsigned long vaddr, unsigned long pfn, pmd = pmd_alloc(&tboot_mm, pud, vaddr); if (!pmd) return -1; - pte = pte_alloc_map(&tboot_mm, NULL, pmd, vaddr); + pte = pte_alloc_map(&tboot_mm, pmd, vaddr); if (!pte) return -1; set_pte_at(&tboot_mm, vaddr, pte, pfn_pte(pfn, prot)); diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 56380440d86229a41314487792decd6a04190fca..c9c4c7ce3eb23c8fea3f6b05647c482edf81c939 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -881,7 +881,7 @@ void tsc_restore_sched_clock_state(void) local_irq_save(flags); /* - * We're comming out of suspend, there's no concurrency yet; don't + * We're coming out of suspend, there's no concurrency yet; don't * bother being nice about the RCU stuff, just write to both * data fields. */ @@ -1306,11 +1306,15 @@ void __init tsc_init(void) unsigned long calibrate_delay_is_known(void) { int sibling, cpu = smp_processor_id(); + struct cpumask *mask = topology_core_cpumask(cpu); if (!tsc_disabled && !cpu_has(&cpu_data(cpu), X86_FEATURE_CONSTANT_TSC)) return 0; - sibling = cpumask_any_but(topology_core_cpumask(cpu), cpu); + if (!mask) + return 0; + + sibling = cpumask_any_but(mask, cpu); if (sibling < nr_cpu_ids) return cpu_data(sibling).loops_per_jiffy; return 0; diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index 5af9958cbdb6be4293b62181ffe104f435caf830..4c941f88d405fbe339d9194e845d9d748fd72604 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S @@ -81,11 +81,11 @@ PHDRS { SECTIONS { #ifdef CONFIG_X86_32 - . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR; - phys_startup_32 = startup_32 - LOAD_OFFSET; + . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR; + phys_startup_32 = ABSOLUTE(startup_32 - LOAD_OFFSET); #else - . = __START_KERNEL; - phys_startup_64 = startup_64 - LOAD_OFFSET; + . = __START_KERNEL; + phys_startup_64 = ABSOLUTE(startup_64 - LOAD_OFFSET); #endif /* Text and read-only data */ @@ -101,6 +101,7 @@ SECTIONS KPROBES_TEXT ENTRY_TEXT IRQENTRY_TEXT + SOFTIRQENTRY_TEXT *(.fixup) *(.gnu.warning) /* End of text section */ @@ -333,6 +334,7 @@ SECTIONS __brk_limit = .; } + . = ALIGN(PAGE_SIZE); _end = .; STABS_DEBUG @@ -340,7 +342,10 @@ SECTIONS /* Sections to be discarded */ DISCARDS - /DISCARD/ : { *(.eh_frame) } + /DISCARD/ : { + *(.eh_frame) + *(__func_stack_frame_non_standard) + } } diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 0029644bf09c39117ef7c1d2cca05561341a24e1..8efb839948e512e9aac6aaf544230195614297c1 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -88,6 +88,16 @@ int kvm_update_cpuid(struct kvm_vcpu *vcpu) apic->lapic_timer.timer_mode_mask = 1 << 17; } + best = kvm_find_cpuid_entry(vcpu, 7, 0); + if (best) { + /* Update OSPKE bit */ + if (boot_cpu_has(X86_FEATURE_PKU) && best->function == 0x7) { + best->ecx &= ~F(OSPKE); + if (kvm_read_cr4_bits(vcpu, X86_CR4_PKE)) + best->ecx |= F(OSPKE); + } + } + best = kvm_find_cpuid_entry(vcpu, 0xD, 0); if (!best) { vcpu->arch.guest_supported_xcr0 = 0; @@ -305,7 +315,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, unsigned f_xsaves = kvm_x86_ops->xsaves_supported() ? F(XSAVES) : 0; /* cpuid 1.edx */ - const u32 kvm_supported_word0_x86_features = + const u32 kvm_cpuid_1_edx_x86_features = F(FPU) | F(VME) | F(DE) | F(PSE) | F(TSC) | F(MSR) | F(PAE) | F(MCE) | F(CX8) | F(APIC) | 0 /* Reserved */ | F(SEP) | @@ -315,7 +325,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, F(FXSR) | F(XMM) | F(XMM2) | F(SELFSNOOP) | 0 /* HTT, TM, Reserved, PBE */; /* cpuid 0x80000001.edx */ - const u32 kvm_supported_word1_x86_features = + const u32 kvm_cpuid_8000_0001_edx_x86_features = F(FPU) | F(VME) | F(DE) | F(PSE) | F(TSC) | F(MSR) | F(PAE) | F(MCE) | F(CX8) | F(APIC) | 0 /* Reserved */ | F(SYSCALL) | @@ -325,7 +335,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, F(FXSR) | F(FXSR_OPT) | f_gbpages | f_rdtscp | 0 /* Reserved */ | f_lm | F(3DNOWEXT) | F(3DNOW); /* cpuid 1.ecx */ - const u32 kvm_supported_word4_x86_features = + const u32 kvm_cpuid_1_ecx_x86_features = /* NOTE: MONITOR (and MWAIT) are emulated as NOP, * but *not* advertised to guests via CPUID ! */ F(XMM3) | F(PCLMULQDQ) | 0 /* DTES64, MONITOR */ | @@ -337,29 +347,32 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, 0 /* Reserved*/ | F(AES) | F(XSAVE) | 0 /* OSXSAVE */ | F(AVX) | F(F16C) | F(RDRAND); /* cpuid 0x80000001.ecx */ - const u32 kvm_supported_word6_x86_features = + const u32 kvm_cpuid_8000_0001_ecx_x86_features = F(LAHF_LM) | F(CMP_LEGACY) | 0 /*SVM*/ | 0 /* ExtApicSpace */ | F(CR8_LEGACY) | F(ABM) | F(SSE4A) | F(MISALIGNSSE) | F(3DNOWPREFETCH) | F(OSVW) | 0 /* IBS */ | F(XOP) | 0 /* SKINIT, WDT, LWP */ | F(FMA4) | F(TBM); /* cpuid 0xC0000001.edx */ - const u32 kvm_supported_word5_x86_features = + const u32 kvm_cpuid_C000_0001_edx_x86_features = F(XSTORE) | F(XSTORE_EN) | F(XCRYPT) | F(XCRYPT_EN) | F(ACE2) | F(ACE2_EN) | F(PHE) | F(PHE_EN) | F(PMM) | F(PMM_EN); /* cpuid 7.0.ebx */ - const u32 kvm_supported_word9_x86_features = + const u32 kvm_cpuid_7_0_ebx_x86_features = F(FSGSBASE) | F(BMI1) | F(HLE) | F(AVX2) | F(SMEP) | F(BMI2) | F(ERMS) | f_invpcid | F(RTM) | f_mpx | F(RDSEED) | F(ADX) | F(SMAP) | F(AVX512F) | F(AVX512PF) | F(AVX512ER) | F(AVX512CD) | F(CLFLUSHOPT) | F(CLWB) | F(PCOMMIT); /* cpuid 0xD.1.eax */ - const u32 kvm_supported_word10_x86_features = + const u32 kvm_cpuid_D_1_eax_x86_features = F(XSAVEOPT) | F(XSAVEC) | F(XGETBV1) | f_xsaves; + /* cpuid 7.0.ecx*/ + const u32 kvm_cpuid_7_0_ecx_x86_features = F(PKU) | 0 /*OSPKE*/; + /* all calls to cpuid_count() should be made on the same cpu */ get_cpu(); @@ -376,10 +389,10 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, entry->eax = min(entry->eax, (u32)0xd); break; case 1: - entry->edx &= kvm_supported_word0_x86_features; - cpuid_mask(&entry->edx, 0); - entry->ecx &= kvm_supported_word4_x86_features; - cpuid_mask(&entry->ecx, 4); + entry->edx &= kvm_cpuid_1_edx_x86_features; + cpuid_mask(&entry->edx, CPUID_1_EDX); + entry->ecx &= kvm_cpuid_1_ecx_x86_features; + cpuid_mask(&entry->ecx, CPUID_1_ECX); /* we support x2apic emulation even if host does not support * it since we emulate x2apic in software */ entry->ecx |= F(X2APIC); @@ -433,14 +446,20 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX; /* Mask ebx against host capability word 9 */ if (index == 0) { - entry->ebx &= kvm_supported_word9_x86_features; - cpuid_mask(&entry->ebx, 9); + entry->ebx &= kvm_cpuid_7_0_ebx_x86_features; + cpuid_mask(&entry->ebx, CPUID_7_0_EBX); // TSC_ADJUST is emulated entry->ebx |= F(TSC_ADJUST); - } else + entry->ecx &= kvm_cpuid_7_0_ecx_x86_features; + cpuid_mask(&entry->ecx, CPUID_7_ECX); + /* PKU is not yet implemented for shadow paging. */ + if (!tdp_enabled) + entry->ecx &= ~F(PKU); + } else { entry->ebx = 0; + entry->ecx = 0; + } entry->eax = 0; - entry->ecx = 0; entry->edx = 0; break; } @@ -514,7 +533,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, do_cpuid_1_ent(&entry[i], function, idx); if (idx == 1) { - entry[i].eax &= kvm_supported_word10_x86_features; + entry[i].eax &= kvm_cpuid_D_1_eax_x86_features; entry[i].ebx = 0; if (entry[i].eax & (F(XSAVES)|F(XSAVEC))) entry[i].ebx = @@ -564,10 +583,10 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, entry->eax = min(entry->eax, 0x8000001a); break; case 0x80000001: - entry->edx &= kvm_supported_word1_x86_features; - cpuid_mask(&entry->edx, 1); - entry->ecx &= kvm_supported_word6_x86_features; - cpuid_mask(&entry->ecx, 6); + entry->edx &= kvm_cpuid_8000_0001_edx_x86_features; + cpuid_mask(&entry->edx, CPUID_8000_0001_EDX); + entry->ecx &= kvm_cpuid_8000_0001_ecx_x86_features; + cpuid_mask(&entry->ecx, CPUID_8000_0001_ECX); break; case 0x80000007: /* Advanced power management */ /* invariant TSC is CPUID.80000007H:EDX[8] */ @@ -600,8 +619,8 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, entry->eax = min(entry->eax, 0xC0000004); break; case 0xC0000001: - entry->edx &= kvm_supported_word5_x86_features; - cpuid_mask(&entry->edx, 5); + entry->edx &= kvm_cpuid_C000_0001_edx_x86_features; + cpuid_mask(&entry->edx, CPUID_C000_0001_EDX); break; case 3: /* Processor serial number */ case 5: /* MONITOR/MWAIT */ diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h index 66a6581724ad264aa2f7d9e2678efa243a471fbd..e17a74b1d8525708a051c18f93854af5667805be 100644 --- a/arch/x86/kvm/cpuid.h +++ b/arch/x86/kvm/cpuid.h @@ -80,6 +80,14 @@ static inline bool guest_cpuid_has_fsgsbase(struct kvm_vcpu *vcpu) return best && (best->ebx & bit(X86_FEATURE_FSGSBASE)); } +static inline bool guest_cpuid_has_pku(struct kvm_vcpu *vcpu) +{ + struct kvm_cpuid_entry2 *best; + + best = kvm_find_cpuid_entry(vcpu, 7, 0); + return best && (best->ecx & bit(X86_FEATURE_PKU)); +} + static inline bool guest_cpuid_has_longmode(struct kvm_vcpu *vcpu) { struct kvm_cpuid_entry2 *best; diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index b9b09fec173bf2fedb0b9ee122b3c4668eb6e471..0f6294376fbdcaa2863956822583d09108cecada 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -309,23 +309,29 @@ static void invalidate_registers(struct x86_emulate_ctxt *ctxt) static int fastop(struct x86_emulate_ctxt *ctxt, void (*fop)(struct fastop *)); -#define FOP_ALIGN ".align " __stringify(FASTOP_SIZE) " \n\t" +#define FOP_FUNC(name) \ + ".align " __stringify(FASTOP_SIZE) " \n\t" \ + ".type " name ", @function \n\t" \ + name ":\n\t" + #define FOP_RET "ret \n\t" #define FOP_START(op) \ extern void em_##op(struct fastop *fake); \ asm(".pushsection .text, \"ax\" \n\t" \ ".global em_" #op " \n\t" \ - FOP_ALIGN \ - "em_" #op ": \n\t" + FOP_FUNC("em_" #op) #define FOP_END \ ".popsection") -#define FOPNOP() FOP_ALIGN FOP_RET +#define FOPNOP() \ + FOP_FUNC(__stringify(__UNIQUE_ID(nop))) \ + FOP_RET #define FOP1E(op, dst) \ - FOP_ALIGN "10: " #op " %" #dst " \n\t" FOP_RET + FOP_FUNC(#op "_" #dst) \ + "10: " #op " %" #dst " \n\t" FOP_RET #define FOP1EEX(op, dst) \ FOP1E(op, dst) _ASM_EXTABLE(10b, kvm_fastop_exception) @@ -357,7 +363,8 @@ static int fastop(struct x86_emulate_ctxt *ctxt, void (*fop)(struct fastop *)); FOP_END #define FOP2E(op, dst, src) \ - FOP_ALIGN #op " %" #src ", %" #dst " \n\t" FOP_RET + FOP_FUNC(#op "_" #dst "_" #src) \ + #op " %" #src ", %" #dst " \n\t" FOP_RET #define FASTOP2(op) \ FOP_START(op) \ @@ -395,7 +402,8 @@ static int fastop(struct x86_emulate_ctxt *ctxt, void (*fop)(struct fastop *)); FOP_END #define FOP3E(op, dst, src, src2) \ - FOP_ALIGN #op " %" #src2 ", %" #src ", %" #dst " \n\t" FOP_RET + FOP_FUNC(#op "_" #dst "_" #src "_" #src2) \ + #op " %" #src2 ", %" #src ", %" #dst " \n\t" FOP_RET /* 3-operand, word-only, src2=cl */ #define FASTOP3WCL(op) \ @@ -407,7 +415,12 @@ static int fastop(struct x86_emulate_ctxt *ctxt, void (*fop)(struct fastop *)); FOP_END /* Special case for SETcc - 1 instruction per cc */ -#define FOP_SETCC(op) ".align 4; " #op " %al; ret \n\t" +#define FOP_SETCC(op) \ + ".align 4 \n\t" \ + ".type " #op ", @function \n\t" \ + #op ": \n\t" \ + #op " %al \n\t" \ + FOP_RET asm(".global kvm_fastop_exception \n" "kvm_fastop_exception: xor %esi, %esi; ret"); @@ -956,7 +969,7 @@ static int em_bsr_c(struct x86_emulate_ctxt *ctxt) return fastop(ctxt, em_bsr); } -static u8 test_cc(unsigned int condition, unsigned long flags) +static __always_inline u8 test_cc(unsigned int condition, unsigned long flags) { u8 rc; void (*fop)(void) = (void *)em_setcc + 4 * (condition & 0xf); diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c index 5ff3485acb60b2ad37a93084cd91a13c888c6fbc..01bd7b7a6866ec0f93f30f62091ec384d783660a 100644 --- a/arch/x86/kvm/hyperv.c +++ b/arch/x86/kvm/hyperv.c @@ -1116,6 +1116,11 @@ int kvm_hv_hypercall(struct kvm_vcpu *vcpu) break; case HVCALL_POST_MESSAGE: case HVCALL_SIGNAL_EVENT: + /* don't bother userspace if it has no way to handle it */ + if (!vcpu_to_synic(vcpu)->active) { + res = HV_STATUS_INVALID_HYPERCALL_CODE; + break; + } vcpu->run->exit_reason = KVM_EXIT_HYPERV; vcpu->run->hyperv.type = KVM_EXIT_HYPERV_HCALL; vcpu->run->hyperv.u.hcall.input = param; diff --git a/arch/x86/kvm/kvm_cache_regs.h b/arch/x86/kvm/kvm_cache_regs.h index e1e89ee4af750dc51f78cfbf8aa71e22d77b4cd1..762cdf2595f992fd4ac8bb1e4c2c8914b344db04 100644 --- a/arch/x86/kvm/kvm_cache_regs.h +++ b/arch/x86/kvm/kvm_cache_regs.h @@ -84,6 +84,11 @@ static inline u64 kvm_read_edx_eax(struct kvm_vcpu *vcpu) | ((u64)(kvm_register_read(vcpu, VCPU_REGS_RDX) & -1u) << 32); } +static inline u32 kvm_read_pkru(struct kvm_vcpu *vcpu) +{ + return kvm_x86_ops->get_pkru(vcpu); +} + static inline void enter_guest_mode(struct kvm_vcpu *vcpu) { vcpu->arch.hflags |= HF_GUEST_MASK; diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 443d2a57ad3d9620246097a48ed3cd7de9e02f50..1a2da0e5a373284f6397c3b5485986f086995e1a 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -1369,7 +1369,7 @@ static void start_apic_timer(struct kvm_lapic *apic) hrtimer_start(&apic->lapic_timer.timer, ktime_add_ns(now, apic->lapic_timer.period), - HRTIMER_MODE_ABS); + HRTIMER_MODE_ABS_PINNED); apic_debug("%s: bus cycle is %" PRId64 "ns, now 0x%016" PRIx64 ", " @@ -1402,7 +1402,7 @@ static void start_apic_timer(struct kvm_lapic *apic) expire = ktime_add_ns(now, ns); expire = ktime_sub_ns(expire, lapic_timer_advance_ns); hrtimer_start(&apic->lapic_timer.timer, - expire, HRTIMER_MODE_ABS); + expire, HRTIMER_MODE_ABS_PINNED); } else apic_timer_expired(apic); @@ -1868,7 +1868,7 @@ int kvm_create_lapic(struct kvm_vcpu *vcpu) apic->vcpu = vcpu; hrtimer_init(&apic->lapic_timer.timer, CLOCK_MONOTONIC, - HRTIMER_MODE_ABS); + HRTIMER_MODE_ABS_PINNED); apic->lapic_timer.timer.function = apic_timer_fn; /* @@ -2003,7 +2003,7 @@ void __kvm_migrate_apic_timer(struct kvm_vcpu *vcpu) timer = &vcpu->arch.apic->lapic_timer.timer; if (hrtimer_cancel(timer)) - hrtimer_start_expires(timer, HRTIMER_MODE_ABS); + hrtimer_start_expires(timer, HRTIMER_MODE_ABS_PINNED); } /* diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index c512f095cdac82b9e2ba258ae052a9a4199dc13c..1ff4dbb73fb7a7ee56c2c28e0d37a6a049f3adc9 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -479,7 +479,7 @@ static bool spte_is_locklessly_modifiable(u64 spte) static bool spte_has_volatile_bits(u64 spte) { /* - * Always atomicly update spte if it can be updated + * Always atomically update spte if it can be updated * out of mmu-lock, it can ensure dirty bit is not lost, * also, it can help us to get a stable is_writable_pte() * to ensure tlb flush is not missed. @@ -550,15 +550,22 @@ static bool mmu_spte_update(u64 *sptep, u64 new_spte) /* * For the spte updated out of mmu-lock is safe, since - * we always atomicly update it, see the comments in + * we always atomically update it, see the comments in * spte_has_volatile_bits(). */ if (spte_is_locklessly_modifiable(old_spte) && !is_writable_pte(new_spte)) ret = true; - if (!shadow_accessed_mask) + if (!shadow_accessed_mask) { + /* + * We don't set page dirty when dropping non-writable spte. + * So do it now if the new spte is becoming non-writable. + */ + if (ret) + kvm_set_pfn_dirty(spte_to_pfn(old_spte)); return ret; + } /* * Flush TLB when accessed/dirty bits are changed in the page tables, @@ -605,7 +612,8 @@ static int mmu_spte_clear_track_bits(u64 *sptep) if (!shadow_accessed_mask || old_spte & shadow_accessed_mask) kvm_set_pfn_accessed(pfn); - if (!shadow_dirty_mask || (old_spte & shadow_dirty_mask)) + if (old_spte & (shadow_dirty_mask ? shadow_dirty_mask : + PT_WRITABLE_MASK)) kvm_set_pfn_dirty(pfn); return 1; } @@ -632,12 +640,12 @@ static void walk_shadow_page_lockless_begin(struct kvm_vcpu *vcpu) * kvm_flush_remote_tlbs() IPI to all active vcpus. */ local_irq_disable(); - vcpu->mode = READING_SHADOW_PAGE_TABLES; + /* * Make sure a following spte read is not reordered ahead of the write * to vcpu->mode. */ - smp_mb(); + smp_store_mb(vcpu->mode, READING_SHADOW_PAGE_TABLES); } static void walk_shadow_page_lockless_end(struct kvm_vcpu *vcpu) @@ -647,8 +655,7 @@ static void walk_shadow_page_lockless_end(struct kvm_vcpu *vcpu) * reads to sptes. If it does, kvm_commit_zap_page() can see us * OUTSIDE_GUEST_MODE and proceed to free the shadow page table. */ - smp_mb(); - vcpu->mode = OUTSIDE_GUEST_MODE; + smp_store_release(&vcpu->mode, OUTSIDE_GUEST_MODE); local_irq_enable(); } @@ -2390,14 +2397,13 @@ static void kvm_mmu_commit_zap_page(struct kvm *kvm, return; /* - * wmb: make sure everyone sees our modifications to the page tables - * rmb: make sure we see changes to vcpu->mode - */ - smp_mb(); - - /* - * Wait for all vcpus to exit guest mode and/or lockless shadow - * page table walks. + * We need to make sure everyone sees our modifications to + * the page tables and see changes to vcpu->mode here. The barrier + * in the kvm_flush_remote_tlbs() achieves this. This pairs + * with vcpu_enter_guest and walk_shadow_page_lockless_begin/end. + * + * In addition, kvm_flush_remote_tlbs waits for all vcpus to exit + * guest mode and/or lockless shadow page table walks. */ kvm_flush_remote_tlbs(kvm); @@ -3923,6 +3929,81 @@ static void update_permission_bitmask(struct kvm_vcpu *vcpu, } } +/* +* PKU is an additional mechanism by which the paging controls access to +* user-mode addresses based on the value in the PKRU register. Protection +* key violations are reported through a bit in the page fault error code. +* Unlike other bits of the error code, the PK bit is not known at the +* call site of e.g. gva_to_gpa; it must be computed directly in +* permission_fault based on two bits of PKRU, on some machine state (CR4, +* CR0, EFER, CPL), and on other bits of the error code and the page tables. +* +* In particular the following conditions come from the error code, the +* page tables and the machine state: +* - PK is always zero unless CR4.PKE=1 and EFER.LMA=1 +* - PK is always zero if RSVD=1 (reserved bit set) or F=1 (instruction fetch) +* - PK is always zero if U=0 in the page tables +* - PKRU.WD is ignored if CR0.WP=0 and the access is a supervisor access. +* +* The PKRU bitmask caches the result of these four conditions. The error +* code (minus the P bit) and the page table's U bit form an index into the +* PKRU bitmask. Two bits of the PKRU bitmask are then extracted and ANDed +* with the two bits of the PKRU register corresponding to the protection key. +* For the first three conditions above the bits will be 00, thus masking +* away both AD and WD. For all reads or if the last condition holds, WD +* only will be masked away. +*/ +static void update_pkru_bitmask(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, + bool ept) +{ + unsigned bit; + bool wp; + + if (ept) { + mmu->pkru_mask = 0; + return; + } + + /* PKEY is enabled only if CR4.PKE and EFER.LMA are both set. */ + if (!kvm_read_cr4_bits(vcpu, X86_CR4_PKE) || !is_long_mode(vcpu)) { + mmu->pkru_mask = 0; + return; + } + + wp = is_write_protection(vcpu); + + for (bit = 0; bit < ARRAY_SIZE(mmu->permissions); ++bit) { + unsigned pfec, pkey_bits; + bool check_pkey, check_write, ff, uf, wf, pte_user; + + pfec = bit << 1; + ff = pfec & PFERR_FETCH_MASK; + uf = pfec & PFERR_USER_MASK; + wf = pfec & PFERR_WRITE_MASK; + + /* PFEC.RSVD is replaced by ACC_USER_MASK. */ + pte_user = pfec & PFERR_RSVD_MASK; + + /* + * Only need to check the access which is not an + * instruction fetch and is to a user page. + */ + check_pkey = (!ff && pte_user); + /* + * write access is controlled by PKRU if it is a + * user access or CR0.WP = 1. + */ + check_write = check_pkey && wf && (uf || wp); + + /* PKRU.AD stops both read and write access. */ + pkey_bits = !!check_pkey; + /* PKRU.WD stops write access. */ + pkey_bits |= (!!check_write) << 1; + + mmu->pkru_mask |= (pkey_bits & 3) << pfec; + } +} + static void update_last_nonleaf_level(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu) { unsigned root_level = mmu->root_level; @@ -3941,6 +4022,7 @@ static void paging64_init_context_common(struct kvm_vcpu *vcpu, reset_rsvds_bits_mask(vcpu, context); update_permission_bitmask(vcpu, context, false); + update_pkru_bitmask(vcpu, context, false); update_last_nonleaf_level(vcpu, context); MMU_WARN_ON(!is_pae(vcpu)); @@ -3968,6 +4050,7 @@ static void paging32_init_context(struct kvm_vcpu *vcpu, reset_rsvds_bits_mask(vcpu, context); update_permission_bitmask(vcpu, context, false); + update_pkru_bitmask(vcpu, context, false); update_last_nonleaf_level(vcpu, context); context->page_fault = paging32_page_fault; @@ -4026,6 +4109,7 @@ static void init_kvm_tdp_mmu(struct kvm_vcpu *vcpu) } update_permission_bitmask(vcpu, context, false); + update_pkru_bitmask(vcpu, context, false); update_last_nonleaf_level(vcpu, context); reset_tdp_shadow_zero_bits_mask(vcpu, context); } @@ -4078,6 +4162,7 @@ void kvm_init_shadow_ept_mmu(struct kvm_vcpu *vcpu, bool execonly) context->direct_map = false; update_permission_bitmask(vcpu, context, true); + update_pkru_bitmask(vcpu, context, true); reset_rsvds_bits_mask_ept(vcpu, context, execonly); reset_ept_shadow_zero_bits_mask(vcpu, context, execonly); } @@ -4132,6 +4217,7 @@ static void init_kvm_nested_mmu(struct kvm_vcpu *vcpu) } update_permission_bitmask(vcpu, g_context, false); + update_pkru_bitmask(vcpu, g_context, false); update_last_nonleaf_level(vcpu, g_context); } diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h index 58fe98a0a526c00f1126ee3af212428ff5123b06..b70df72e2b33d417307d01f57bca57388650d34f 100644 --- a/arch/x86/kvm/mmu.h +++ b/arch/x86/kvm/mmu.h @@ -10,10 +10,11 @@ #define PT32_ENT_PER_PAGE (1 << PT32_PT_BITS) #define PT_WRITABLE_SHIFT 1 +#define PT_USER_SHIFT 2 #define PT_PRESENT_MASK (1ULL << 0) #define PT_WRITABLE_MASK (1ULL << PT_WRITABLE_SHIFT) -#define PT_USER_MASK (1ULL << 2) +#define PT_USER_MASK (1ULL << PT_USER_SHIFT) #define PT_PWT_MASK (1ULL << 3) #define PT_PCD_MASK (1ULL << 4) #define PT_ACCESSED_SHIFT 5 @@ -141,11 +142,16 @@ static inline bool is_write_protection(struct kvm_vcpu *vcpu) } /* - * Will a fault with a given page-fault error code (pfec) cause a permission - * fault with the given access (in ACC_* format)? + * Check if a given access (described through the I/D, W/R and U/S bits of a + * page fault error code pfec) causes a permission fault with the given PTE + * access rights (in ACC_* format). + * + * Return zero if the access does not fault; return the page fault error code + * if the access faults. */ -static inline bool permission_fault(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, - unsigned pte_access, unsigned pfec) +static inline u8 permission_fault(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, + unsigned pte_access, unsigned pte_pkey, + unsigned pfec) { int cpl = kvm_x86_ops->get_cpl(vcpu); unsigned long rflags = kvm_x86_ops->get_rflags(vcpu); @@ -166,10 +172,32 @@ static inline bool permission_fault(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, unsigned long smap = (cpl - 3) & (rflags & X86_EFLAGS_AC); int index = (pfec >> 1) + (smap >> (X86_EFLAGS_AC_BIT - PFERR_RSVD_BIT + 1)); + bool fault = (mmu->permissions[index] >> pte_access) & 1; + + WARN_ON(pfec & (PFERR_PK_MASK | PFERR_RSVD_MASK)); + pfec |= PFERR_PRESENT_MASK; + + if (unlikely(mmu->pkru_mask)) { + u32 pkru_bits, offset; + + /* + * PKRU defines 32 bits, there are 16 domains and 2 + * attribute bits per domain in pkru. pte_pkey is the + * index of the protection domain, so pte_pkey * 2 is + * is the index of the first bit for the domain. + */ + pkru_bits = (kvm_read_pkru(vcpu) >> (pte_pkey * 2)) & 3; + + /* clear present bit, replace PFEC.RSVD with ACC_USER_MASK. */ + offset = pfec - 1 + + ((pte_access & PT_USER_MASK) << (PFERR_RSVD_BIT - PT_USER_SHIFT)); - WARN_ON(pfec & PFERR_RSVD_MASK); + pkru_bits &= mmu->pkru_mask >> offset; + pfec |= -pkru_bits & PFERR_PK_MASK; + fault |= (pkru_bits != 0); + } - return (mmu->permissions[index] >> pte_access) & 1; + return -(uint32_t)fault & pfec; } void kvm_mmu_invalidate_zap_all_pages(struct kvm *kvm); diff --git a/arch/x86/kvm/page_track.c b/arch/x86/kvm/page_track.c index 11f76436f74f0d762123a4dc38dbcf31b0c47f53..b431539c3714b0e9b72420180aee914583699dbb 100644 --- a/arch/x86/kvm/page_track.c +++ b/arch/x86/kvm/page_track.c @@ -142,12 +142,17 @@ void kvm_slot_page_track_remove_page(struct kvm *kvm, bool kvm_page_track_is_active(struct kvm_vcpu *vcpu, gfn_t gfn, enum kvm_page_track_mode mode) { - struct kvm_memory_slot *slot = kvm_vcpu_gfn_to_memslot(vcpu, gfn); - int index = gfn_to_index(gfn, slot->base_gfn, PT_PAGE_TABLE_LEVEL); + struct kvm_memory_slot *slot; + int index; if (WARN_ON(!page_track_mode_is_valid(mode))) return false; + slot = kvm_vcpu_gfn_to_memslot(vcpu, gfn); + if (!slot) + return false; + + index = gfn_to_index(gfn, slot->base_gfn, PT_PAGE_TABLE_LEVEL); return !!ACCESS_ONCE(slot->arch.gfn_track[mode][index]); } diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h index e159a8185ad9af081de317ff6b686d1ee3eb1d4b..1d971c7553c3847f0d1335487ce551a19875b709 100644 --- a/arch/x86/kvm/paging_tmpl.h +++ b/arch/x86/kvm/paging_tmpl.h @@ -257,6 +257,17 @@ static int FNAME(update_accessed_dirty_bits)(struct kvm_vcpu *vcpu, return 0; } +static inline unsigned FNAME(gpte_pkeys)(struct kvm_vcpu *vcpu, u64 gpte) +{ + unsigned pkeys = 0; +#if PTTYPE == 64 + pte_t pte = {.pte = gpte}; + + pkeys = pte_flags_pkey(pte_flags(pte)); +#endif + return pkeys; +} + /* * Fetch a guest pte for a guest virtual address */ @@ -268,7 +279,7 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker, pt_element_t pte; pt_element_t __user *uninitialized_var(ptep_user); gfn_t table_gfn; - unsigned index, pt_access, pte_access, accessed_dirty; + unsigned index, pt_access, pte_access, accessed_dirty, pte_pkey; gpa_t pte_gpa; int offset; const int write_fault = access & PFERR_WRITE_MASK; @@ -359,10 +370,10 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker, walker->ptes[walker->level - 1] = pte; } while (!is_last_gpte(mmu, walker->level, pte)); - if (unlikely(permission_fault(vcpu, mmu, pte_access, access))) { - errcode |= PFERR_PRESENT_MASK; + pte_pkey = FNAME(gpte_pkeys)(vcpu, pte); + errcode = permission_fault(vcpu, mmu, pte_access, pte_pkey, access); + if (unlikely(errcode)) goto error; - } gfn = gpte_to_gfn_lvl(pte, walker->level); gfn += (addr & PT_LVL_OFFSET_MASK(walker->level)) >> PAGE_SHIFT; @@ -949,6 +960,12 @@ static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) return 0; if (FNAME(prefetch_invalid_gpte)(vcpu, sp, &sp->spt[i], gpte)) { + /* + * Update spte before increasing tlbs_dirty to make + * sure no tlb flush is lost after spte is zapped; see + * the comments in kvm_flush_remote_tlbs(). + */ + smp_wmb(); vcpu->kvm->tlbs_dirty++; continue; } @@ -964,6 +981,11 @@ static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) if (gfn != sp->gfns[i]) { drop_spte(vcpu->kvm, &sp->spt[i]); + /* + * The same as above where we are doing + * prefetch_invalid_gpte(). + */ + smp_wmb(); vcpu->kvm->tlbs_dirty++; continue; } diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 95070386d5991baef11e2934349727af714cfce3..31346a3f20a5c8b5384e6fda2a81029059cdf621 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1280,6 +1280,11 @@ static void svm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) to_svm(vcpu)->vmcb->save.rflags = rflags; } +static u32 svm_get_pkru(struct kvm_vcpu *vcpu) +{ + return 0; +} + static void svm_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg) { switch (reg) { @@ -4347,6 +4352,9 @@ static struct kvm_x86_ops svm_x86_ops = { .cache_reg = svm_cache_reg, .get_rflags = svm_get_rflags, .set_rflags = svm_set_rflags, + + .get_pkru = svm_get_pkru, + .fpu_activate = svm_fpu_activate, .fpu_deactivate = svm_fpu_deactivate, diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 5e45c2731a5d60ba6a9adfc58841ca075cd90834..ee1c8a93871c551f9cddc93de56197806d0c0cfd 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -598,6 +598,10 @@ struct vcpu_vmx { struct page *pml_pg; u64 current_tsc_ratio; + + bool guest_pkru_valid; + u32 guest_pkru; + u32 host_pkru; }; enum segment_cache_field { @@ -2107,6 +2111,7 @@ static void vmx_vcpu_pi_load(struct kvm_vcpu *vcpu, int cpu) } while (cmpxchg(&pi_desc->control, old.control, new.control) != old.control); } + /* * Switches to specified vcpu, until a matching vcpu_put(), but assumes * vcpu mutex is already taken. @@ -2167,6 +2172,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) } vmx_vcpu_pi_load(vcpu, cpu); + vmx->host_pkru = read_pkru(); } static void vmx_vcpu_pi_put(struct kvm_vcpu *vcpu) @@ -2286,6 +2292,11 @@ static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags) vmcs_writel(GUEST_RFLAGS, rflags); } +static u32 vmx_get_pkru(struct kvm_vcpu *vcpu) +{ + return to_vmx(vcpu)->guest_pkru; +} + static u32 vmx_get_interrupt_shadow(struct kvm_vcpu *vcpu) { u32 interruptibility = vmcs_read32(GUEST_INTERRUPTIBILITY_INFO); @@ -2712,8 +2723,15 @@ static void nested_vmx_setup_ctls_msrs(struct vcpu_vmx *vmx) } else vmx->nested.nested_vmx_ept_caps = 0; + /* + * Old versions of KVM use the single-context version without + * checking for support, so declare that it is supported even + * though it is treated as global context. The alternative is + * not failing the single-context invvpid, and it is worse. + */ if (enable_vpid) vmx->nested.nested_vmx_vpid_caps = VMX_VPID_INVVPID_BIT | + VMX_VPID_EXTENT_SINGLE_CONTEXT_BIT | VMX_VPID_EXTENT_GLOBAL_CONTEXT_BIT; else vmx->nested.nested_vmx_vpid_caps = 0; @@ -3886,13 +3904,17 @@ static int vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) if (!enable_unrestricted_guest && !is_paging(vcpu)) /* - * SMEP/SMAP is disabled if CPU is in non-paging mode in - * hardware. However KVM always uses paging mode without - * unrestricted guest. - * To emulate this behavior, SMEP/SMAP needs to be manually - * disabled when guest switches to non-paging mode. + * SMEP/SMAP/PKU is disabled if CPU is in non-paging mode in + * hardware. To emulate this behavior, SMEP/SMAP/PKU needs + * to be manually disabled when guest switches to non-paging + * mode. + * + * If !enable_unrestricted_guest, the CPU is always running + * with CR0.PG=1 and CR4 needs to be modified. + * If enable_unrestricted_guest, the CPU automatically + * disables SMEP/SMAP/PKU when the guest sets CR0.PG=0. */ - hw_cr4 &= ~(X86_CR4_SMEP | X86_CR4_SMAP); + hw_cr4 &= ~(X86_CR4_SMEP | X86_CR4_SMAP | X86_CR4_PKE); vmcs_writel(CR4_READ_SHADOW, cr4); vmcs_writel(GUEST_CR4, hw_cr4); @@ -5506,7 +5528,7 @@ static int handle_set_cr4(struct kvm_vcpu *vcpu, unsigned long val) return kvm_set_cr4(vcpu, val); } -/* called to set cr0 as approriate for clts instruction exit. */ +/* called to set cr0 as appropriate for clts instruction exit. */ static void handle_clts(struct kvm_vcpu *vcpu) { if (is_guest_mode(vcpu)) { @@ -7245,7 +7267,7 @@ static int handle_vmwrite(struct kvm_vcpu *vcpu) /* The value to write might be 32 or 64 bits, depending on L1's long * mode, and eventually we need to write that into a field of several * possible lengths. The code below first zero-extends the value to 64 - * bit (field_value), and then copies only the approriate number of + * bit (field_value), and then copies only the appropriate number of * bits into the vmcs12 field. */ u64 field_value = 0; @@ -7399,6 +7421,7 @@ static int handle_invept(struct kvm_vcpu *vcpu) if (!(types & (1UL << type))) { nested_vmx_failValid(vcpu, VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID); + skip_emulated_instruction(vcpu); return 1; } @@ -7457,6 +7480,7 @@ static int handle_invvpid(struct kvm_vcpu *vcpu) if (!(types & (1UL << type))) { nested_vmx_failValid(vcpu, VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID); + skip_emulated_instruction(vcpu); return 1; } @@ -7473,12 +7497,17 @@ static int handle_invvpid(struct kvm_vcpu *vcpu) } switch (type) { + case VMX_VPID_EXTENT_SINGLE_CONTEXT: + /* + * Old versions of KVM use the single-context version so we + * have to support it; just treat it the same as all-context. + */ case VMX_VPID_EXTENT_ALL_CONTEXT: __vmx_flush_tlb(vcpu, to_vmx(vcpu)->nested.vpid02); nested_vmx_succeed(vcpu); break; default: - /* Trap single context invalidation invvpid calls */ + /* Trap individual address invalidation invvpid calls */ BUG_ON(1); break; } @@ -8385,6 +8414,7 @@ static void vmx_complete_atomic_exit(struct vcpu_vmx *vmx) static void vmx_handle_external_intr(struct kvm_vcpu *vcpu) { u32 exit_intr_info = vmcs_read32(VM_EXIT_INTR_INFO); + register void *__sp asm(_ASM_SP); /* * If external interrupt exists, IF bit is set in rflags/eflags on the @@ -8417,8 +8447,9 @@ static void vmx_handle_external_intr(struct kvm_vcpu *vcpu) "call *%[entry]\n\t" : #ifdef CONFIG_X86_64 - [sp]"=&r"(tmp) + [sp]"=&r"(tmp), #endif + "+r"(__sp) : [entry]"r"(entry), [ss]"i"(__KERNEL_DS), @@ -8619,6 +8650,9 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) vmx_set_interrupt_shadow(vcpu, 0); + if (vmx->guest_pkru_valid) + __write_pkru(vmx->guest_pkru); + atomic_switch_perf_msrs(vmx); debugctlmsr = get_debugctlmsr(); @@ -8758,6 +8792,20 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) vmx->exit_reason = vmcs_read32(VM_EXIT_REASON); + /* + * eager fpu is enabled if PKEY is supported and CR4 is switched + * back on host, so it is safe to read guest PKRU from current + * XSAVE. + */ + if (boot_cpu_has(X86_FEATURE_OSPKE)) { + vmx->guest_pkru = __read_pkru(); + if (vmx->guest_pkru != vmx->host_pkru) { + vmx->guest_pkru_valid = true; + __write_pkru(vmx->host_pkru); + } else + vmx->guest_pkru_valid = false; + } + /* * the KVM_REQ_EVENT optimization bit is only on for one entry, and if * we did not inject a still-pending event to L1 now because of @@ -10882,6 +10930,9 @@ static struct kvm_x86_ops vmx_x86_ops = { .cache_reg = vmx_cache_reg, .get_rflags = vmx_get_rflags, .set_rflags = vmx_set_rflags, + + .get_pkru = vmx_get_pkru, + .fpu_activate = vmx_fpu_activate, .fpu_deactivate = vmx_fpu_deactivate, diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 7236bd3a4c3d7a0c5a6148decc6fad276eb18bb7..0a2c70e43bc884de800dc792ebeab81fb75478ef 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -723,7 +723,7 @@ int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) { unsigned long old_cr4 = kvm_read_cr4(vcpu); unsigned long pdptr_bits = X86_CR4_PGE | X86_CR4_PSE | X86_CR4_PAE | - X86_CR4_SMEP | X86_CR4_SMAP; + X86_CR4_SMEP | X86_CR4_SMAP | X86_CR4_PKE; if (cr4 & CR4_RESERVED_BITS) return 1; @@ -740,6 +740,9 @@ int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) if (!guest_cpuid_has_fsgsbase(vcpu) && (cr4 & X86_CR4_FSGSBASE)) return 1; + if (!guest_cpuid_has_pku(vcpu) && (cr4 & X86_CR4_PKE)) + return 1; + if (is_long_mode(vcpu)) { if (!(cr4 & X86_CR4_PAE)) return 1; @@ -765,7 +768,7 @@ int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) (!(cr4 & X86_CR4_PCIDE) && (old_cr4 & X86_CR4_PCIDE))) kvm_mmu_reset_context(vcpu); - if ((cr4 ^ old_cr4) & X86_CR4_OSXSAVE) + if ((cr4 ^ old_cr4) & (X86_CR4_OSXSAVE | X86_CR4_PKE)) kvm_update_cpuid(vcpu); return 0; @@ -1559,7 +1562,7 @@ static cycle_t read_tsc(void) /* * GCC likes to generate cmov here, but this branch is extremely - * predictable (it's just a funciton of time and the likely is + * predictable (it's just a function of time and the likely is * very likely) and there's a data dependence, so force GCC * to generate a branch instead. I don't barrier() because * we don't actually need a barrier, and if this function @@ -4326,9 +4329,14 @@ static int vcpu_mmio_gva_to_gpa(struct kvm_vcpu *vcpu, unsigned long gva, u32 access = ((kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0) | (write ? PFERR_WRITE_MASK : 0); + /* + * currently PKRU is only applied to ept enabled guest so + * there is no pkey in EPT page table for L1 guest or EPT + * shadow page table for L2 guest. + */ if (vcpu_match_mmio_gva(vcpu, gva) && !permission_fault(vcpu, vcpu->arch.walk_mmu, - vcpu->arch.access, access)) { + vcpu->arch.access, 0, access)) { *gpa = vcpu->arch.mmio_gfn << PAGE_SHIFT | (gva & (PAGE_SIZE - 1)); trace_vcpu_match_mmio(gva, *gpa, write, false); @@ -6087,12 +6095,10 @@ static int inject_pending_event(struct kvm_vcpu *vcpu, bool req_int_win) } /* try to inject new event if pending */ - if (vcpu->arch.nmi_pending) { - if (kvm_x86_ops->nmi_allowed(vcpu)) { - --vcpu->arch.nmi_pending; - vcpu->arch.nmi_injected = true; - kvm_x86_ops->set_nmi(vcpu); - } + if (vcpu->arch.nmi_pending && kvm_x86_ops->nmi_allowed(vcpu)) { + --vcpu->arch.nmi_pending; + vcpu->arch.nmi_injected = true; + kvm_x86_ops->set_nmi(vcpu); } else if (kvm_cpu_has_injectable_intr(vcpu)) { /* * Because interrupts can be injected asynchronously, we are @@ -6561,10 +6567,12 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) if (inject_pending_event(vcpu, req_int_win) != 0) req_immediate_exit = true; /* enable NMI/IRQ window open exits if needed */ - else if (vcpu->arch.nmi_pending) - kvm_x86_ops->enable_nmi_window(vcpu); - else if (kvm_cpu_has_injectable_intr(vcpu) || req_int_win) - kvm_x86_ops->enable_irq_window(vcpu); + else { + if (vcpu->arch.nmi_pending) + kvm_x86_ops->enable_nmi_window(vcpu); + if (kvm_cpu_has_injectable_intr(vcpu) || req_int_win) + kvm_x86_ops->enable_irq_window(vcpu); + } if (kvm_lapic_enabled(vcpu)) { update_cr8_intercept(vcpu); @@ -6588,8 +6596,12 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx); - /* We should set ->mode before check ->requests, - * see the comment in make_all_cpus_request. + /* + * We should set ->mode before check ->requests, + * Please see the comment in kvm_make_all_cpus_request. + * This also orders the write to mode from any reads + * to the page tables done while the VCPU is running. + * Please see the comment in kvm_flush_remote_tlbs. */ smp_mb__after_srcu_read_unlock(); @@ -7123,7 +7135,7 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, mmu_reset_needed |= kvm_read_cr4(vcpu) != sregs->cr4; kvm_x86_ops->set_cr4(vcpu, sregs->cr4); - if (sregs->cr4 & X86_CR4_OSXSAVE) + if (sregs->cr4 & (X86_CR4_OSXSAVE | X86_CR4_PKE)) kvm_update_cpuid(vcpu); idx = srcu_read_lock(&vcpu->kvm->srcu); diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index 007940faa5c6357d1c5c1c4bd200b3b8ae195cb0..7ce3634ab5fe6189a95163d8cd9781a923d21727 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h @@ -183,7 +183,8 @@ bool kvm_vector_hashing_enabled(void); #define KVM_SUPPORTED_XCR0 (XFEATURE_MASK_FP | XFEATURE_MASK_SSE \ | XFEATURE_MASK_YMM | XFEATURE_MASK_BNDREGS \ - | XFEATURE_MASK_BNDCSR | XFEATURE_MASK_AVX512) + | XFEATURE_MASK_BNDCSR | XFEATURE_MASK_AVX512 \ + | XFEATURE_MASK_PKRU) extern u64 host_xcr0; extern u64 kvm_supported_xcr0(void); diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index a501fa25da41faac952fc05bba7c7ad45f8d0ca8..72a576752a7ec062f92e433362306e7a6b4648de 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -2,6 +2,9 @@ # Makefile for x86 specific library files. # +# Produces uninteresting flaky coverage. +KCOV_INSTRUMENT_delay.o := n + inat_tables_script = $(srctree)/arch/x86/tools/gen-insn-attr-x86.awk inat_tables_maps = $(srctree)/arch/x86/lib/x86-opcode-map.txt quiet_cmd_inat_tables = GEN $@ diff --git a/arch/x86/lib/csum-wrappers_64.c b/arch/x86/lib/csum-wrappers_64.c index 1318f75d56e4f072885276a18ca00363f074fcd4..28a6654f0d08e34bb11d81747305fa8fbe67f4fe 100644 --- a/arch/x86/lib/csum-wrappers_64.c +++ b/arch/x86/lib/csum-wrappers_64.c @@ -135,7 +135,7 @@ EXPORT_SYMBOL(csum_partial_copy_nocheck); __sum16 csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, - __u32 len, unsigned short proto, __wsum sum) + __u32 len, __u8 proto, __wsum sum) { __u64 rest, sum64; diff --git a/arch/x86/lib/insn.c b/arch/x86/lib/insn.c index 8f72b334aea03387ab7084d9998f497cf7287da2..1a416935bac98ffec19256448673335feb84bb74 100644 --- a/arch/x86/lib/insn.c +++ b/arch/x86/lib/insn.c @@ -374,7 +374,7 @@ void insn_get_displacement(struct insn *insn) if (mod == 3) goto out; if (mod == 1) { - insn->displacement.value = get_next(char, insn); + insn->displacement.value = get_next(signed char, insn); insn->displacement.nbytes = 1; } else if (insn->addr_bytes == 2) { if ((mod == 0 && rm == 6) || mod == 2) { @@ -532,7 +532,7 @@ void insn_get_immediate(struct insn *insn) switch (inat_immediate_size(insn->attr)) { case INAT_IMM_BYTE: - insn->immediate.value = get_next(char, insn); + insn->immediate.value = get_next(signed char, insn); insn->immediate.nbytes = 1; break; case INAT_IMM_WORD: @@ -566,7 +566,7 @@ void insn_get_immediate(struct insn *insn) goto err_out; } if (inat_has_second_immediate(insn->attr)) { - insn->immediate2.value = get_next(char, insn); + insn->immediate2.value = get_next(signed char, insn); insn->immediate2.nbytes = 1; } done: diff --git a/arch/x86/lib/memcpy_64.S b/arch/x86/lib/memcpy_64.S index cbb8ee5830ff134f131533fd91ea8be35a853dba..2ec0b0abbfaa876fb242b71061b70cdb7dc9db20 100644 --- a/arch/x86/lib/memcpy_64.S +++ b/arch/x86/lib/memcpy_64.S @@ -1,6 +1,7 @@ /* Copyright 2002 Andi Kleen */ #include +#include #include #include @@ -268,16 +269,16 @@ ENTRY(memcpy_mcsafe) decl %ecx jnz .L_copy_trailing_bytes - /* Copy successful. Return true */ + /* Copy successful. Return zero */ .L_done_memcpy_trap: xorq %rax, %rax ret ENDPROC(memcpy_mcsafe) .section .fixup, "ax" - /* Return false for any failure */ + /* Return -EFAULT for any failure */ .L_memcpy_mcsafe_fail: - mov $1, %rax + mov $-EFAULT, %rax ret .previous diff --git a/arch/x86/lib/memset_64.S b/arch/x86/lib/memset_64.S index c9c81227ea37d14968b3acb3ccfa346e73cda5dc..e1229ecd2a82057cc6f0171169b6871f0e438167 100644 --- a/arch/x86/lib/memset_64.S +++ b/arch/x86/lib/memset_64.S @@ -9,7 +9,7 @@ /* * ISO C memset - set a memory block to a byte value. This function uses fast * string to get better performance than the original function. The code is - * simpler and shorter than the orignal function as well. + * simpler and shorter than the original function as well. * * rdi destination * rsi value (char) diff --git a/arch/x86/lib/rwsem.S b/arch/x86/lib/rwsem.S index 40027db991405ba123a508a7d9523afe04fd744b..be110efa0096687c1ea35ada3fc439a9cb3f6180 100644 --- a/arch/x86/lib/rwsem.S +++ b/arch/x86/lib/rwsem.S @@ -15,6 +15,7 @@ #include #include +#include #define __ASM_HALF_REG(reg) __ASM_SEL(reg, e##reg) #define __ASM_HALF_SIZE(inst) __ASM_SEL(inst##w, inst##l) @@ -84,24 +85,29 @@ /* Fix up special calling conventions */ ENTRY(call_rwsem_down_read_failed) + FRAME_BEGIN save_common_regs __ASM_SIZE(push,) %__ASM_REG(dx) movq %rax,%rdi call rwsem_down_read_failed __ASM_SIZE(pop,) %__ASM_REG(dx) restore_common_regs + FRAME_END ret ENDPROC(call_rwsem_down_read_failed) ENTRY(call_rwsem_down_write_failed) + FRAME_BEGIN save_common_regs movq %rax,%rdi call rwsem_down_write_failed restore_common_regs + FRAME_END ret ENDPROC(call_rwsem_down_write_failed) ENTRY(call_rwsem_wake) + FRAME_BEGIN /* do nothing if still outstanding active readers */ __ASM_HALF_SIZE(dec) %__ASM_HALF_REG(dx) jnz 1f @@ -109,15 +115,18 @@ ENTRY(call_rwsem_wake) movq %rax,%rdi call rwsem_wake restore_common_regs -1: ret +1: FRAME_END + ret ENDPROC(call_rwsem_wake) ENTRY(call_rwsem_downgrade_wake) + FRAME_BEGIN save_common_regs __ASM_SIZE(push,) %__ASM_REG(dx) movq %rax,%rdi call rwsem_downgrade_wake __ASM_SIZE(pop,) %__ASM_REG(dx) restore_common_regs + FRAME_END ret ENDPROC(call_rwsem_downgrade_wake) diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile index f9d38a48e3c847f129ddd62c4f6d4e40180711ad..f98913258c639dac160fa8f01304486c48fb391d 100644 --- a/arch/x86/mm/Makefile +++ b/arch/x86/mm/Makefile @@ -1,3 +1,6 @@ +# Kernel does not boot with instrumentation of tlb.c. +KCOV_INSTRUMENT_tlb.o := n + obj-y := init.o init_$(BITS).o fault.o ioremap.o extable.o pageattr.o mmap.o \ pat.o pgtable.o physaddr.o gup.o setup_nx.o @@ -34,3 +37,5 @@ obj-$(CONFIG_ACPI_NUMA) += srat.o obj-$(CONFIG_NUMA_EMU) += numa_emulation.o obj-$(CONFIG_X86_INTEL_MPX) += mpx.o +obj-$(CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS) += pkeys.o + diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c index 9dd7e4b7fcdee4a847f98937b9a287b826366a2d..82447b3fba380d6547619958c07ed7c3d2d3010b 100644 --- a/arch/x86/mm/extable.c +++ b/arch/x86/mm/extable.c @@ -1,16 +1,9 @@ #include -#include -#include #include typedef bool (*ex_handler_t)(const struct exception_table_entry *, struct pt_regs *, int); -static inline unsigned long -ex_insn_addr(const struct exception_table_entry *x) -{ - return (unsigned long)&x->insn + x->insn; -} static inline unsigned long ex_fixup_addr(const struct exception_table_entry *x) { @@ -110,104 +103,3 @@ int __init early_fixup_exception(unsigned long *ip) *ip = new_ip; return 1; } - -/* - * Search one exception table for an entry corresponding to the - * given instruction address, and return the address of the entry, - * or NULL if none is found. - * We use a binary search, and thus we assume that the table is - * already sorted. - */ -const struct exception_table_entry * -search_extable(const struct exception_table_entry *first, - const struct exception_table_entry *last, - unsigned long value) -{ - while (first <= last) { - const struct exception_table_entry *mid; - unsigned long addr; - - mid = ((last - first) >> 1) + first; - addr = ex_insn_addr(mid); - if (addr < value) - first = mid + 1; - else if (addr > value) - last = mid - 1; - else - return mid; - } - return NULL; -} - -/* - * The exception table needs to be sorted so that the binary - * search that we use to find entries in it works properly. - * This is used both for the kernel exception table and for - * the exception tables of modules that get loaded. - * - */ -static int cmp_ex(const void *a, const void *b) -{ - const struct exception_table_entry *x = a, *y = b; - - /* - * This value will always end up fittin in an int, because on - * both i386 and x86-64 the kernel symbol-reachable address - * space is < 2 GiB. - * - * This compare is only valid after normalization. - */ - return x->insn - y->insn; -} - -void sort_extable(struct exception_table_entry *start, - struct exception_table_entry *finish) -{ - struct exception_table_entry *p; - int i; - - /* Convert all entries to being relative to the start of the section */ - i = 0; - for (p = start; p < finish; p++) { - p->insn += i; - i += 4; - p->fixup += i; - i += 4; - p->handler += i; - i += 4; - } - - sort(start, finish - start, sizeof(struct exception_table_entry), - cmp_ex, NULL); - - /* Denormalize all entries */ - i = 0; - for (p = start; p < finish; p++) { - p->insn -= i; - i += 4; - p->fixup -= i; - i += 4; - p->handler -= i; - i += 4; - } -} - -#ifdef CONFIG_MODULES -/* - * If the exception table is sorted, any referring to the module init - * will be at the beginning or the end. - */ -void trim_init_extable(struct module *m) -{ - /*trim the beginning*/ - while (m->num_exentries && - within_module_init(ex_insn_addr(&m->extable[0]), m)) { - m->extable++; - m->num_exentries--; - } - /*trim the end*/ - while (m->num_exentries && - within_module_init(ex_insn_addr(&m->extable[m->num_exentries-1]), m)) - m->num_exentries--; -} -#endif /* CONFIG_MODULES */ diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 03898aea6e0f2697e2196e9de7f8fe3aeb200ec9..5ce1ed02f7e80900ead34c8b8af2bfe223a9d3bd 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -15,12 +15,14 @@ #include /* exception_enter(), ... */ #include /* faulthandler_disabled() */ +#include /* boot_cpu_has, ... */ #include /* dotraplinkage, ... */ #include /* pgd_*(), ... */ #include /* kmemcheck_*(), ... */ #include /* VSYSCALL_ADDR */ #include /* emulate_vsyscall */ #include /* struct vm86 */ +#include /* vma_pkey() */ #define CREATE_TRACE_POINTS #include @@ -33,6 +35,7 @@ * bit 2 == 0: kernel-mode access 1: user-mode access * bit 3 == 1: use of reserved bit detected * bit 4 == 1: fault was an instruction fetch + * bit 5 == 1: protection keys block access */ enum x86_pf_error_code { @@ -41,6 +44,7 @@ enum x86_pf_error_code { PF_USER = 1 << 2, PF_RSVD = 1 << 3, PF_INSTR = 1 << 4, + PF_PK = 1 << 5, }; /* @@ -167,9 +171,60 @@ is_prefetch(struct pt_regs *regs, unsigned long error_code, unsigned long addr) return prefetch; } +/* + * A protection key fault means that the PKRU value did not allow + * access to some PTE. Userspace can figure out what PKRU was + * from the XSAVE state, and this function fills out a field in + * siginfo so userspace can discover which protection key was set + * on the PTE. + * + * If we get here, we know that the hardware signaled a PF_PK + * fault and that there was a VMA once we got in the fault + * handler. It does *not* guarantee that the VMA we find here + * was the one that we faulted on. + * + * 1. T1 : mprotect_key(foo, PAGE_SIZE, pkey=4); + * 2. T1 : set PKRU to deny access to pkey=4, touches page + * 3. T1 : faults... + * 4. T2: mprotect_key(foo, PAGE_SIZE, pkey=5); + * 5. T1 : enters fault handler, takes mmap_sem, etc... + * 6. T1 : reaches here, sees vma_pkey(vma)=5, when we really + * faulted on a pte with its pkey=4. + */ +static void fill_sig_info_pkey(int si_code, siginfo_t *info, + struct vm_area_struct *vma) +{ + /* This is effectively an #ifdef */ + if (!boot_cpu_has(X86_FEATURE_OSPKE)) + return; + + /* Fault not from Protection Keys: nothing to do */ + if (si_code != SEGV_PKUERR) + return; + /* + * force_sig_info_fault() is called from a number of + * contexts, some of which have a VMA and some of which + * do not. The PF_PK handing happens after we have a + * valid VMA, so we should never reach this without a + * valid VMA. + */ + if (!vma) { + WARN_ONCE(1, "PKU fault with no VMA passed in"); + info->si_pkey = 0; + return; + } + /* + * si_pkey should be thought of as a strong hint, but not + * absolutely guranteed to be 100% accurate because of + * the race explained above. + */ + info->si_pkey = vma_pkey(vma); +} + static void force_sig_info_fault(int si_signo, int si_code, unsigned long address, - struct task_struct *tsk, int fault) + struct task_struct *tsk, struct vm_area_struct *vma, + int fault) { unsigned lsb = 0; siginfo_t info; @@ -184,6 +239,8 @@ force_sig_info_fault(int si_signo, int si_code, unsigned long address, lsb = PAGE_SHIFT; info.si_addr_lsb = lsb; + fill_sig_info_pkey(si_code, &info, vma); + force_sig_info(si_signo, &info, tsk); } @@ -661,6 +718,8 @@ no_context(struct pt_regs *regs, unsigned long error_code, struct task_struct *tsk = current; unsigned long flags; int sig; + /* No context means no VMA to pass down */ + struct vm_area_struct *vma = NULL; /* Are we prepared to handle this kernel fault? */ if (fixup_exception(regs, X86_TRAP_PF)) { @@ -684,7 +743,8 @@ no_context(struct pt_regs *regs, unsigned long error_code, tsk->thread.cr2 = address; /* XXX: hwpoison faults will set the wrong code. */ - force_sig_info_fault(signal, si_code, address, tsk, 0); + force_sig_info_fault(signal, si_code, address, + tsk, vma, 0); } /* @@ -761,7 +821,8 @@ show_signal_msg(struct pt_regs *regs, unsigned long error_code, static void __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code, - unsigned long address, int si_code) + unsigned long address, struct vm_area_struct *vma, + int si_code) { struct task_struct *tsk = current; @@ -804,7 +865,7 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code, tsk->thread.error_code = error_code; tsk->thread.trap_nr = X86_TRAP_PF; - force_sig_info_fault(SIGSEGV, si_code, address, tsk, 0); + force_sig_info_fault(SIGSEGV, si_code, address, tsk, vma, 0); return; } @@ -817,14 +878,14 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code, static noinline void bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code, - unsigned long address) + unsigned long address, struct vm_area_struct *vma) { - __bad_area_nosemaphore(regs, error_code, address, SEGV_MAPERR); + __bad_area_nosemaphore(regs, error_code, address, vma, SEGV_MAPERR); } static void __bad_area(struct pt_regs *regs, unsigned long error_code, - unsigned long address, int si_code) + unsigned long address, struct vm_area_struct *vma, int si_code) { struct mm_struct *mm = current->mm; @@ -834,25 +895,50 @@ __bad_area(struct pt_regs *regs, unsigned long error_code, */ up_read(&mm->mmap_sem); - __bad_area_nosemaphore(regs, error_code, address, si_code); + __bad_area_nosemaphore(regs, error_code, address, vma, si_code); } static noinline void bad_area(struct pt_regs *regs, unsigned long error_code, unsigned long address) { - __bad_area(regs, error_code, address, SEGV_MAPERR); + __bad_area(regs, error_code, address, NULL, SEGV_MAPERR); +} + +static inline bool bad_area_access_from_pkeys(unsigned long error_code, + struct vm_area_struct *vma) +{ + /* This code is always called on the current mm */ + bool foreign = false; + + if (!boot_cpu_has(X86_FEATURE_OSPKE)) + return false; + if (error_code & PF_PK) + return true; + /* this checks permission keys on the VMA: */ + if (!arch_vma_access_permitted(vma, (error_code & PF_WRITE), + (error_code & PF_INSTR), foreign)) + return true; + return false; } static noinline void bad_area_access_error(struct pt_regs *regs, unsigned long error_code, - unsigned long address) + unsigned long address, struct vm_area_struct *vma) { - __bad_area(regs, error_code, address, SEGV_ACCERR); + /* + * This OSPKE check is not strictly necessary at runtime. + * But, doing it this way allows compiler optimizations + * if pkeys are compiled out. + */ + if (bad_area_access_from_pkeys(error_code, vma)) + __bad_area(regs, error_code, address, vma, SEGV_PKUERR); + else + __bad_area(regs, error_code, address, vma, SEGV_ACCERR); } static void do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address, - unsigned int fault) + struct vm_area_struct *vma, unsigned int fault) { struct task_struct *tsk = current; int code = BUS_ADRERR; @@ -879,12 +965,13 @@ do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address, code = BUS_MCEERR_AR; } #endif - force_sig_info_fault(SIGBUS, code, address, tsk, fault); + force_sig_info_fault(SIGBUS, code, address, tsk, vma, fault); } static noinline void mm_fault_error(struct pt_regs *regs, unsigned long error_code, - unsigned long address, unsigned int fault) + unsigned long address, struct vm_area_struct *vma, + unsigned int fault) { if (fatal_signal_pending(current) && !(error_code & PF_USER)) { no_context(regs, error_code, address, 0, 0); @@ -908,9 +995,9 @@ mm_fault_error(struct pt_regs *regs, unsigned long error_code, } else { if (fault & (VM_FAULT_SIGBUS|VM_FAULT_HWPOISON| VM_FAULT_HWPOISON_LARGE)) - do_sigbus(regs, error_code, address, fault); + do_sigbus(regs, error_code, address, vma, fault); else if (fault & VM_FAULT_SIGSEGV) - bad_area_nosemaphore(regs, error_code, address); + bad_area_nosemaphore(regs, error_code, address, vma); else BUG(); } @@ -923,6 +1010,12 @@ static int spurious_fault_check(unsigned long error_code, pte_t *pte) if ((error_code & PF_INSTR) && !pte_exec(*pte)) return 0; + /* + * Note: We do not do lazy flushing on protection key + * changes, so no spurious fault will ever set PF_PK. + */ + if ((error_code & PF_PK)) + return 1; return 1; } @@ -1012,6 +1105,17 @@ int show_unhandled_signals = 1; static inline int access_error(unsigned long error_code, struct vm_area_struct *vma) { + /* This is only called for the current mm, so: */ + bool foreign = false; + /* + * Make sure to check the VMA so that we do not perform + * faults just to hit a PF_PK as soon as we fill in a + * page. + */ + if (!arch_vma_access_permitted(vma, (error_code & PF_WRITE), + (error_code & PF_INSTR), foreign)) + return 1; + if (error_code & PF_WRITE) { /* write, present and write, not present: */ if (unlikely(!(vma->vm_flags & VM_WRITE))) @@ -1118,7 +1222,7 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code, * Don't take the mm semaphore here. If we fixup a prefetch * fault we could otherwise deadlock: */ - bad_area_nosemaphore(regs, error_code, address); + bad_area_nosemaphore(regs, error_code, address, NULL); return; } @@ -1131,7 +1235,7 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code, pgtable_bad(regs, error_code, address); if (unlikely(smap_violation(error_code, regs))) { - bad_area_nosemaphore(regs, error_code, address); + bad_area_nosemaphore(regs, error_code, address, NULL); return; } @@ -1140,7 +1244,7 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code, * in a region with pagefaults disabled then we must not take the fault */ if (unlikely(faulthandler_disabled() || !mm)) { - bad_area_nosemaphore(regs, error_code, address); + bad_area_nosemaphore(regs, error_code, address, NULL); return; } @@ -1164,6 +1268,8 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code, if (error_code & PF_WRITE) flags |= FAULT_FLAG_WRITE; + if (error_code & PF_INSTR) + flags |= FAULT_FLAG_INSTRUCTION; /* * When running in the kernel we expect faults to occur only to @@ -1184,7 +1290,7 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code, if (unlikely(!down_read_trylock(&mm->mmap_sem))) { if ((error_code & PF_USER) == 0 && !search_exception_tables(regs->ip)) { - bad_area_nosemaphore(regs, error_code, address); + bad_area_nosemaphore(regs, error_code, address, NULL); return; } retry: @@ -1232,7 +1338,7 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code, */ good_area: if (unlikely(access_error(error_code, vma))) { - bad_area_access_error(regs, error_code, address); + bad_area_access_error(regs, error_code, address, vma); return; } @@ -1270,7 +1376,7 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code, up_read(&mm->mmap_sem); if (unlikely(fault & VM_FAULT_ERROR)) { - mm_fault_error(regs, error_code, address, fault); + mm_fault_error(regs, error_code, address, vma, fault); return; } diff --git a/arch/x86/mm/gup.c b/arch/x86/mm/gup.c index d8a798d8bf50ac037fa2ac4854085bd78759c249..b8b6a60b32cf47837070518bd44d4c4742910697 100644 --- a/arch/x86/mm/gup.c +++ b/arch/x86/mm/gup.c @@ -11,6 +11,7 @@ #include #include +#include #include static inline pte_t gup_get_pte(pte_t *ptep) @@ -74,6 +75,28 @@ static void undo_dev_pagemap(int *nr, int nr_start, struct page **pages) } } +/* + * 'pteval' can come from a pte, pmd or pud. We only check + * _PAGE_PRESENT, _PAGE_USER, and _PAGE_RW in here which are the + * same value on all 3 types. + */ +static inline int pte_allows_gup(unsigned long pteval, int write) +{ + unsigned long need_pte_bits = _PAGE_PRESENT|_PAGE_USER; + + if (write) + need_pte_bits |= _PAGE_RW; + + if ((pteval & need_pte_bits) != need_pte_bits) + return 0; + + /* Check memory protection keys permissions. */ + if (!__pkru_allows_pkey(pte_flags_pkey(pteval), write)) + return 0; + + return 1; +} + /* * The performance critical leaf functions are made noinline otherwise gcc * inlines everything into a single function which results in too much @@ -83,14 +106,9 @@ static noinline int gup_pte_range(pmd_t pmd, unsigned long addr, unsigned long end, int write, struct page **pages, int *nr) { struct dev_pagemap *pgmap = NULL; - unsigned long mask; int nr_start = *nr; pte_t *ptep; - mask = _PAGE_PRESENT|_PAGE_USER; - if (write) - mask |= _PAGE_RW; - ptep = pte_offset_map(&pmd, addr); do { pte_t pte = gup_get_pte(ptep); @@ -109,7 +127,8 @@ static noinline int gup_pte_range(pmd_t pmd, unsigned long addr, pte_unmap(ptep); return 0; } - } else if ((pte_flags(pte) & (mask | _PAGE_SPECIAL)) != mask) { + } else if (!pte_allows_gup(pte_val(pte), write) || + pte_special(pte)) { pte_unmap(ptep); return 0; } @@ -131,7 +150,7 @@ static inline void get_head_page_multiple(struct page *page, int nr) { VM_BUG_ON_PAGE(page != compound_head(page), page); VM_BUG_ON_PAGE(page_count(page) == 0, page); - atomic_add(nr, &page->_count); + page_ref_add(page, nr); SetPageReferenced(page); } @@ -164,14 +183,10 @@ static int __gup_device_huge_pmd(pmd_t pmd, unsigned long addr, static noinline int gup_huge_pmd(pmd_t pmd, unsigned long addr, unsigned long end, int write, struct page **pages, int *nr) { - unsigned long mask; struct page *head, *page; int refs; - mask = _PAGE_PRESENT|_PAGE_USER; - if (write) - mask |= _PAGE_RW; - if ((pmd_flags(pmd) & mask) != mask) + if (!pte_allows_gup(pmd_val(pmd), write)) return 0; VM_BUG_ON(!pfn_valid(pmd_pfn(pmd))); @@ -231,14 +246,10 @@ static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end, static noinline int gup_huge_pud(pud_t pud, unsigned long addr, unsigned long end, int write, struct page **pages, int *nr) { - unsigned long mask; struct page *head, *page; int refs; - mask = _PAGE_PRESENT|_PAGE_USER; - if (write) - mask |= _PAGE_RW; - if ((pud_flags(pud) & mask) != mask) + if (!pte_allows_gup(pud_val(pud), write)) return 0; /* hugepages are never "special" */ VM_BUG_ON(pud_flags(pud) & _PAGE_SPECIAL); @@ -422,7 +433,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, start += nr << PAGE_SHIFT; pages += nr; - ret = get_user_pages_unlocked(current, mm, start, + ret = get_user_pages_unlocked(start, (end - start) >> PAGE_SHIFT, write, 0, pages); diff --git a/arch/x86/mm/mpx.c b/arch/x86/mm/mpx.c index ef05755a190063cdf79210f7ac164aef1a0f4ec5..80476878eb4ca5c8ad56340bb52b2423995a7867 100644 --- a/arch/x86/mm/mpx.c +++ b/arch/x86/mm/mpx.c @@ -546,8 +546,8 @@ static int mpx_resolve_fault(long __user *addr, int write) int nr_pages = 1; int force = 0; - gup_ret = get_user_pages(current, current->mm, (unsigned long)addr, - nr_pages, write, force, NULL, NULL); + gup_ret = get_user_pages((unsigned long)addr, nr_pages, write, + force, NULL, NULL); /* * get_user_pages() returns number of pages gotten. * 0 means we failed to fault in and get anything, @@ -728,14 +728,14 @@ static inline unsigned long bd_entry_virt_space(struct mm_struct *mm) /* * This covers 32-bit emulation as well as 32-bit kernels - * running on 64-bit harware. + * running on 64-bit hardware. */ if (!is_64bit_mm(mm)) return (4ULL * GB) / MPX_BD_NR_ENTRIES_32; /* * 'x86_virt_bits' returns what the hardware is capable - * of, and returns the full >32-bit adddress space when + * of, and returns the full >32-bit address space when * running 32-bit kernels on 64-bit hardware. */ virt_space = (1ULL << boot_cpu_data.x86_virt_bits); diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 4d0b26253042d525107106f8e230535c65f25ca8..01be9ec3bf792f65ac91cc57fe7d64e8e644998f 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -909,16 +909,25 @@ static void populate_pte(struct cpa_data *cpa, pte = pte_offset_kernel(pmd, start); - while (num_pages-- && start < end) { + /* + * Set the GLOBAL flags only if the PRESENT flag is + * set otherwise pte_present will return true even on + * a non present pte. The canon_pgprot will clear + * _PAGE_GLOBAL for the ancient hardware that doesn't + * support it. + */ + if (pgprot_val(pgprot) & _PAGE_PRESENT) + pgprot_val(pgprot) |= _PAGE_GLOBAL; + else + pgprot_val(pgprot) &= ~_PAGE_GLOBAL; - /* deal with the NX bit */ - if (!(pgprot_val(pgprot) & _PAGE_NX)) - cpa->pfn &= ~_PAGE_NX; + pgprot = canon_pgprot(pgprot); - set_pte(pte, pfn_pte(cpa->pfn >> PAGE_SHIFT, pgprot)); + while (num_pages-- && start < end) { + set_pte(pte, pfn_pte(cpa->pfn, pgprot)); start += PAGE_SIZE; - cpa->pfn += PAGE_SIZE; + cpa->pfn++; pte++; } } @@ -974,11 +983,11 @@ static int populate_pmd(struct cpa_data *cpa, pmd = pmd_offset(pud, start); - set_pmd(pmd, __pmd(cpa->pfn | _PAGE_PSE | + set_pmd(pmd, __pmd(cpa->pfn << PAGE_SHIFT | _PAGE_PSE | massage_pgprot(pmd_pgprot))); start += PMD_SIZE; - cpa->pfn += PMD_SIZE; + cpa->pfn += PMD_SIZE >> PAGE_SHIFT; cur_pages += PMD_SIZE >> PAGE_SHIFT; } @@ -1046,12 +1055,12 @@ static int populate_pud(struct cpa_data *cpa, unsigned long start, pgd_t *pgd, /* * Map everything starting from the Gb boundary, possibly with 1G pages */ - while (end - start >= PUD_SIZE) { - set_pud(pud, __pud(cpa->pfn | _PAGE_PSE | + while (cpu_has_gbpages && end - start >= PUD_SIZE) { + set_pud(pud, __pud(cpa->pfn << PAGE_SHIFT | _PAGE_PSE | massage_pgprot(pud_pgprot))); start += PUD_SIZE; - cpa->pfn += PUD_SIZE; + cpa->pfn += PUD_SIZE >> PAGE_SHIFT; cur_pages += PUD_SIZE >> PAGE_SHIFT; pud++; } @@ -1964,6 +1973,9 @@ int kernel_map_pages_in_pgd(pgd_t *pgd, u64 pfn, unsigned long address, if (!(page_flags & _PAGE_NX)) cpa.mask_clr = __pgprot(_PAGE_NX); + if (!(page_flags & _PAGE_RW)) + cpa.mask_clr = __pgprot(_PAGE_RW); + cpa.mask_set = __pgprot(_PAGE_PRESENT | page_flags); retval = __change_page_attr_set_clr(&cpa, 0); diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index 04e2e7144beee51205df17a4e3df024833eac7db..faec01e7a17d21fbd7abafc42fb9855dc7d530f4 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c @@ -149,7 +149,7 @@ enum { PAT_WT = 4, /* Write Through */ PAT_WP = 5, /* Write Protected */ PAT_WB = 6, /* Write Back (default) */ - PAT_UC_MINUS = 7, /* UC, but can be overriden by MTRR */ + PAT_UC_MINUS = 7, /* UC, but can be overridden by MTRR */ }; #define CM(c) (_PAGE_CACHE_MODE_ ## c) diff --git a/arch/x86/mm/pkeys.c b/arch/x86/mm/pkeys.c new file mode 100644 index 0000000000000000000000000000000000000000..e8c474451928a709b46a80b55caf371f405f87b2 --- /dev/null +++ b/arch/x86/mm/pkeys.c @@ -0,0 +1,101 @@ +/* + * Intel Memory Protection Keys management + * Copyright (c) 2015, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + */ +#include /* mm_struct, vma, etc... */ +#include /* PKEY_* */ +#include + +#include /* boot_cpu_has, ... */ +#include /* vma_pkey() */ +#include /* fpregs_active() */ + +int __execute_only_pkey(struct mm_struct *mm) +{ + int ret; + + /* + * We do not want to go through the relatively costly + * dance to set PKRU if we do not need to. Check it + * first and assume that if the execute-only pkey is + * write-disabled that we do not have to set it + * ourselves. We need preempt off so that nobody + * can make fpregs inactive. + */ + preempt_disable(); + if (fpregs_active() && + !__pkru_allows_read(read_pkru(), PKEY_DEDICATED_EXECUTE_ONLY)) { + preempt_enable(); + return PKEY_DEDICATED_EXECUTE_ONLY; + } + preempt_enable(); + ret = arch_set_user_pkey_access(current, PKEY_DEDICATED_EXECUTE_ONLY, + PKEY_DISABLE_ACCESS); + /* + * If the PKRU-set operation failed somehow, just return + * 0 and effectively disable execute-only support. + */ + if (ret) + return 0; + + return PKEY_DEDICATED_EXECUTE_ONLY; +} + +static inline bool vma_is_pkey_exec_only(struct vm_area_struct *vma) +{ + /* Do this check first since the vm_flags should be hot */ + if ((vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC)) != VM_EXEC) + return false; + if (vma_pkey(vma) != PKEY_DEDICATED_EXECUTE_ONLY) + return false; + + return true; +} + +/* + * This is only called for *plain* mprotect calls. + */ +int __arch_override_mprotect_pkey(struct vm_area_struct *vma, int prot, int pkey) +{ + /* + * Is this an mprotect_pkey() call? If so, never + * override the value that came from the user. + */ + if (pkey != -1) + return pkey; + /* + * Look for a protection-key-drive execute-only mapping + * which is now being given permissions that are not + * execute-only. Move it back to the default pkey. + */ + if (vma_is_pkey_exec_only(vma) && + (prot & (PROT_READ|PROT_WRITE))) { + return 0; + } + /* + * The mapping is execute-only. Go try to get the + * execute-only protection key. If we fail to do that, + * fall through as if we do not have execute-only + * support. + */ + if (prot == PROT_EXEC) { + pkey = execute_only_pkey(vma->vm_mm); + if (pkey > 0) + return pkey; + } + /* + * This is a vanilla, non-pkey mprotect (or we failed to + * setup execute-only), inherit the pkey from the VMA we + * are working on. + */ + return vma_pkey(vma); +} diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c index 8f4cc3dfac322a2911ab2b2e8471c6e8e87d8af0..fe9b9f77636168752f989b9d007634396864bf13 100644 --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c @@ -104,10 +104,8 @@ static void flush_tlb_func(void *info) inc_irq_stat(irq_tlb_count); - if (f->flush_mm != this_cpu_read(cpu_tlbstate.active_mm)) + if (f->flush_mm && f->flush_mm != this_cpu_read(cpu_tlbstate.active_mm)) return; - if (!f->flush_end) - f->flush_end = f->flush_start + PAGE_SIZE; count_vm_tlb_event(NR_TLB_REMOTE_FLUSH_RECEIVED); if (this_cpu_read(cpu_tlbstate.state) == TLBSTATE_OK) { @@ -135,12 +133,20 @@ void native_flush_tlb_others(const struct cpumask *cpumask, unsigned long end) { struct flush_tlb_info info; + + if (end == 0) + end = start + PAGE_SIZE; info.flush_mm = mm; info.flush_start = start; info.flush_end = end; count_vm_tlb_event(NR_TLB_REMOTE_FLUSH); - trace_tlb_flush(TLB_REMOTE_SEND_IPI, end - start); + if (end == TLB_FLUSH_ALL) + trace_tlb_flush(TLB_REMOTE_SEND_IPI, TLB_FLUSH_ALL); + else + trace_tlb_flush(TLB_REMOTE_SEND_IPI, + (end - start) >> PAGE_SHIFT); + if (is_uv_system()) { unsigned int cpu; diff --git a/arch/x86/net/bpf_jit.S b/arch/x86/net/bpf_jit.S index 4093216b3791311c995bfb2f644deed3845ef708..f2a7faf4706eb64debcc65d3c9ad0b0fd9c70599 100644 --- a/arch/x86/net/bpf_jit.S +++ b/arch/x86/net/bpf_jit.S @@ -8,6 +8,7 @@ * of the License. */ #include +#include /* * Calling convention : @@ -22,15 +23,16 @@ 32 /* space for rbx,r13,r14,r15 */ + \ 8 /* space for skb_copy_bits */) -sk_load_word: - .globl sk_load_word +#define FUNC(name) \ + .globl name; \ + .type name, @function; \ + name: +FUNC(sk_load_word) test %esi,%esi js bpf_slow_path_word_neg -sk_load_word_positive_offset: - .globl sk_load_word_positive_offset - +FUNC(sk_load_word_positive_offset) mov %r9d,%eax # hlen sub %esi,%eax # hlen - offset cmp $3,%eax @@ -39,15 +41,11 @@ sk_load_word_positive_offset: bswap %eax /* ntohl() */ ret -sk_load_half: - .globl sk_load_half - +FUNC(sk_load_half) test %esi,%esi js bpf_slow_path_half_neg -sk_load_half_positive_offset: - .globl sk_load_half_positive_offset - +FUNC(sk_load_half_positive_offset) mov %r9d,%eax sub %esi,%eax # hlen - offset cmp $1,%eax @@ -56,15 +54,11 @@ sk_load_half_positive_offset: rol $8,%ax # ntohs() ret -sk_load_byte: - .globl sk_load_byte - +FUNC(sk_load_byte) test %esi,%esi js bpf_slow_path_byte_neg -sk_load_byte_positive_offset: - .globl sk_load_byte_positive_offset - +FUNC(sk_load_byte_positive_offset) cmp %esi,%r9d /* if (offset >= hlen) goto bpf_slow_path_byte */ jle bpf_slow_path_byte movzbl (SKBDATA,%rsi),%eax @@ -72,16 +66,18 @@ sk_load_byte_positive_offset: /* rsi contains offset and can be scratched */ #define bpf_slow_path_common(LEN) \ + lea -MAX_BPF_STACK + 32(%rbp), %rdx;\ + FRAME_BEGIN; \ mov %rbx, %rdi; /* arg1 == skb */ \ push %r9; \ push SKBDATA; \ /* rsi already has offset */ \ mov $LEN,%ecx; /* len */ \ - lea - MAX_BPF_STACK + 32(%rbp),%rdx; \ call skb_copy_bits; \ test %eax,%eax; \ pop SKBDATA; \ - pop %r9; + pop %r9; \ + FRAME_END bpf_slow_path_word: @@ -106,6 +102,7 @@ bpf_slow_path_byte: ret #define sk_negative_common(SIZE) \ + FRAME_BEGIN; \ mov %rbx, %rdi; /* arg1 == skb */ \ push %r9; \ push SKBDATA; \ @@ -115,13 +112,14 @@ bpf_slow_path_byte: test %rax,%rax; \ pop SKBDATA; \ pop %r9; \ + FRAME_END; \ jz bpf_error bpf_slow_path_word_neg: cmp SKF_MAX_NEG_OFF, %esi /* test range */ jl bpf_error /* offset lower -> error */ -sk_load_word_negative_offset: - .globl sk_load_word_negative_offset + +FUNC(sk_load_word_negative_offset) sk_negative_common(4) mov (%rax), %eax bswap %eax @@ -130,8 +128,8 @@ sk_load_word_negative_offset: bpf_slow_path_half_neg: cmp SKF_MAX_NEG_OFF, %esi jl bpf_error -sk_load_half_negative_offset: - .globl sk_load_half_negative_offset + +FUNC(sk_load_half_negative_offset) sk_negative_common(2) mov (%rax),%ax rol $8,%ax @@ -141,8 +139,8 @@ sk_load_half_negative_offset: bpf_slow_path_byte_neg: cmp SKF_MAX_NEG_OFF, %esi jl bpf_error -sk_load_byte_negative_offset: - .globl sk_load_byte_negative_offset + +FUNC(sk_load_byte_negative_offset) sk_negative_common(1) movzbl (%rax), %eax ret diff --git a/arch/x86/oprofile/backtrace.c b/arch/x86/oprofile/backtrace.c index 4e664bdb535ad89d09633fd73ea6eca5a46d4097..cb31a4440e588552f5fd046ae787c107aa09ec94 100644 --- a/arch/x86/oprofile/backtrace.c +++ b/arch/x86/oprofile/backtrace.c @@ -23,12 +23,13 @@ static int backtrace_stack(void *data, char *name) return 0; } -static void backtrace_address(void *data, unsigned long addr, int reliable) +static int backtrace_address(void *data, unsigned long addr, int reliable) { unsigned int *depth = data; if ((*depth)--) oprofile_add_trace(addr); + return 0; } static struct stacktrace_ops backtrace_ops = { diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index 1d2e6392f5faaf6f450cdfa598b9b2a734064962..0e07e0968c3a0d5959d554c0c29ab358eb78b82b 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c @@ -437,7 +437,8 @@ static int oprofile_cpu_notifier(struct notifier_block *b, unsigned long action, void *data) { int cpu = (unsigned long)data; - switch (action) { + + switch (action & ~CPU_TASKS_FROZEN) { case CPU_DOWN_FAILED: case CPU_ONLINE: smp_call_function_single(cpu, nmi_cpu_up, NULL, 0); diff --git a/arch/x86/platform/efi/Makefile b/arch/x86/platform/efi/Makefile index 2846aaab510352117b808f8eb16e4d9ff7002f32..066619b0700c91643c31c49f1cbc8f2d4899bb88 100644 --- a/arch/x86/platform/efi/Makefile +++ b/arch/x86/platform/efi/Makefile @@ -1,3 +1,5 @@ +OBJECT_FILES_NON_STANDARD_efi_thunk_$(BITS).o := y + obj-$(CONFIG_EFI) += quirks.o efi.o efi_$(BITS).o efi_stub_$(BITS).o obj-$(CONFIG_ACPI_BGRT) += efi-bgrt.o obj-$(CONFIG_EARLY_PRINTK_EFI) += early_printk.o diff --git a/arch/x86/platform/efi/efi-bgrt.c b/arch/x86/platform/efi/efi-bgrt.c index ea48449b2e63d1428de814d654ba58087dee436a..a2433817c987833f525380d8425bb6e902873bbd 100644 --- a/arch/x86/platform/efi/efi-bgrt.c +++ b/arch/x86/platform/efi/efi-bgrt.c @@ -10,6 +10,9 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -28,8 +31,7 @@ struct bmp_header { void __init efi_bgrt_init(void) { acpi_status status; - void __iomem *image; - bool ioremapped = false; + void *image; struct bmp_header bmp_header; if (acpi_disabled) @@ -55,11 +57,6 @@ void __init efi_bgrt_init(void) bgrt_tab->status); return; } - if (bgrt_tab->status != 1) { - pr_debug("Ignoring BGRT: invalid status %u (expected 1)\n", - bgrt_tab->status); - return; - } if (bgrt_tab->image_type != 0) { pr_err("Ignoring BGRT: invalid image type %u (expected 0)\n", bgrt_tab->image_type); @@ -70,20 +67,19 @@ void __init efi_bgrt_init(void) return; } - image = efi_lookup_mapped_addr(bgrt_tab->image_address); + image = memremap(bgrt_tab->image_address, sizeof(bmp_header), MEMREMAP_WB); if (!image) { - image = early_ioremap(bgrt_tab->image_address, - sizeof(bmp_header)); - ioremapped = true; - if (!image) { - pr_err("Ignoring BGRT: failed to map image header memory\n"); - return; - } + pr_err("Ignoring BGRT: failed to map image header memory\n"); + return; } - memcpy_fromio(&bmp_header, image, sizeof(bmp_header)); - if (ioremapped) - early_iounmap(image, sizeof(bmp_header)); + memcpy(&bmp_header, image, sizeof(bmp_header)); + memunmap(image); + if (bmp_header.id != 0x4d42) { + pr_err("Ignoring BGRT: Incorrect BMP magic number 0x%x (expected 0x4d42)\n", + bmp_header.id); + return; + } bgrt_image_size = bmp_header.size; bgrt_image = kmalloc(bgrt_image_size, GFP_KERNEL | __GFP_NOWARN); @@ -93,18 +89,14 @@ void __init efi_bgrt_init(void) return; } - if (ioremapped) { - image = early_ioremap(bgrt_tab->image_address, - bmp_header.size); - if (!image) { - pr_err("Ignoring BGRT: failed to map image memory\n"); - kfree(bgrt_image); - bgrt_image = NULL; - return; - } + image = memremap(bgrt_tab->image_address, bmp_header.size, MEMREMAP_WB); + if (!image) { + pr_err("Ignoring BGRT: failed to map image memory\n"); + kfree(bgrt_image); + bgrt_image = NULL; + return; } - memcpy_fromio(bgrt_image, image, bgrt_image_size); - if (ioremapped) - early_iounmap(image, bmp_header.size); + memcpy(bgrt_image, image, bgrt_image_size); + memunmap(image); } diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index ad285404ea7f58ac74e998d5658a8c72a9be019d..994a7df84a7bc713aa4913f04fc7c85992840183 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -235,10 +235,10 @@ void __init efi_print_memmap(void) char buf[64]; md = p; - pr_info("mem%02u: %s range=[0x%016llx-0x%016llx) (%lluMB)\n", + pr_info("mem%02u: %s range=[0x%016llx-0x%016llx] (%lluMB)\n", i, efi_md_typeattr_format(buf, sizeof(buf), md), md->phys_addr, - md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT), + md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - 1, (md->num_pages >> (20 - EFI_PAGE_SHIFT))); } #endif /* EFI_DEBUG */ @@ -815,6 +815,7 @@ static void __init kexec_enter_virtual_mode(void) { #ifdef CONFIG_KEXEC_CORE efi_memory_desc_t *md; + unsigned int num_pages; void *p; efi.systab = NULL; @@ -829,6 +830,12 @@ static void __init kexec_enter_virtual_mode(void) return; } + if (efi_alloc_page_tables()) { + pr_err("Failed to allocate EFI page tables\n"); + clear_bit(EFI_RUNTIME_SERVICES, &efi.flags); + return; + } + /* * Map efi regions which were passed via setup_data. The virt_addr is a * fixed addr which was used in first kernel of a kexec boot. @@ -843,6 +850,14 @@ static void __init kexec_enter_virtual_mode(void) BUG_ON(!efi.systab); + num_pages = ALIGN(memmap.nr_map * memmap.desc_size, PAGE_SIZE); + num_pages >>= PAGE_SHIFT; + + if (efi_setup_page_tables(memmap.phys_map, num_pages)) { + clear_bit(EFI_RUNTIME_SERVICES, &efi.flags); + return; + } + efi_sync_low_kernel_mappings(); /* @@ -869,7 +884,7 @@ static void __init kexec_enter_virtual_mode(void) * This function will switch the EFI runtime services to virtual mode. * Essentially, we look through the EFI memmap and map every region that * has the runtime attribute bit set in its memory descriptor into the - * ->trampoline_pgd page table using a top-down VA allocation scheme. + * efi_pgd page table. * * The old method which used to update that memory descriptor with the * virtual address obtained from ioremap() is still supported when the @@ -879,8 +894,8 @@ static void __init kexec_enter_virtual_mode(void) * * The new method does a pagetable switch in a preemption-safe manner * so that we're in a different address space when calling a runtime - * function. For function arguments passing we do copy the PGDs of the - * kernel page table into ->trampoline_pgd prior to each call. + * function. For function arguments passing we do copy the PUDs of the + * kernel page table into efi_pgd prior to each call. * * Specially for kexec boot, efi runtime maps in previous kernel should * be passed in via setup_data. In that case runtime ranges will be mapped @@ -895,6 +910,12 @@ static void __init __efi_enter_virtual_mode(void) efi.systab = NULL; + if (efi_alloc_page_tables()) { + pr_err("Failed to allocate EFI page tables\n"); + clear_bit(EFI_RUNTIME_SERVICES, &efi.flags); + return; + } + efi_merge_regions(); new_memmap = efi_map_regions(&count, &pg_shift); if (!new_memmap) { @@ -913,7 +934,6 @@ static void __init __efi_enter_virtual_mode(void) } efi_sync_low_kernel_mappings(); - efi_dump_pagetable(); if (efi_is_native()) { status = phys_efi_set_virtual_address_map( @@ -951,31 +971,20 @@ static void __init __efi_enter_virtual_mode(void) efi.set_virtual_address_map = NULL; - efi_runtime_mkexec(); + /* + * Apply more restrictive page table mapping attributes now that + * SVAM() has been called and the firmware has performed all + * necessary relocation fixups for the new virtual addresses. + */ + efi_runtime_update_mappings(); + efi_dump_pagetable(); /* - * We mapped the descriptor array into the EFI pagetable above but we're - * not unmapping it here. Here's why: - * - * We're copying select PGDs from the kernel page table to the EFI page - * table and when we do so and make changes to those PGDs like unmapping - * stuff from them, those changes appear in the kernel page table and we - * go boom. - * - * From setup_real_mode(): - * - * ... - * trampoline_pgd[0] = init_level4_pgt[pgd_index(__PAGE_OFFSET)].pgd; - * - * In this particular case, our allocation is in PGD 0 of the EFI page - * table but we've copied that PGD from PGD[272] of the EFI page table: - * - * pgd_index(__PAGE_OFFSET = 0xffff880000000000) = 272 - * - * where the direct memory mapping in kernel space is. - * - * new_memmap's VA comes from that direct mapping and thus clearing it, - * it would get cleared in the kernel page table too. + * We mapped the descriptor array into the EFI pagetable above + * but we're not unmapping it here because if we're running in + * EFI mixed mode we need all of memory to be accessible when + * we pass parameters to the EFI runtime services in the + * thunking code. * * efi_cleanup_page_tables(__pa(new_memmap), 1 << pg_shift); */ diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c index ed5b67338294f1325fffe5f7d9fce637731d5917..338402b91d2e5654b83c0530030d5aaa8f0a02c2 100644 --- a/arch/x86/platform/efi/efi_32.c +++ b/arch/x86/platform/efi/efi_32.c @@ -38,6 +38,11 @@ * say 0 - 3G. */ +int __init efi_alloc_page_tables(void) +{ + return 0; +} + void efi_sync_low_kernel_mappings(void) {} void __init efi_dump_pagetable(void) {} int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) @@ -85,7 +90,7 @@ void __init efi_call_phys_epilog(pgd_t *save_pgd) __flush_tlb_all(); } -void __init efi_runtime_mkexec(void) +void __init efi_runtime_update_mappings(void) { if (__supported_pte_mask & _PAGE_NX) runtime_code_page_mkexec(); diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index a0ac0f9c307f661c8b3ed08c4ca6d23507772e36..49e4dd4a1f58257630c8b341bf8b12922200cd2e 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -15,6 +15,8 @@ * */ +#define pr_fmt(fmt) "efi: " fmt + #include #include #include @@ -40,6 +42,7 @@ #include #include #include +#include /* * We allocate runtime services regions bottom-up, starting from -4G, i.e. @@ -47,16 +50,7 @@ */ static u64 efi_va = EFI_VA_START; -/* - * Scratch space used for switching the pagetable in the EFI stub - */ -struct efi_scratch { - u64 r15; - u64 prev_cr3; - pgd_t *efi_pgt; - bool use_pgd; - u64 phys_stack; -} __packed; +struct efi_scratch efi_scratch; static void __init early_code_mapping_set_exec(int executable) { @@ -83,8 +77,11 @@ pgd_t * __init efi_call_phys_prolog(void) int pgd; int n_pgds; - if (!efi_enabled(EFI_OLD_MEMMAP)) - return NULL; + if (!efi_enabled(EFI_OLD_MEMMAP)) { + save_pgd = (pgd_t *)read_cr3(); + write_cr3((unsigned long)efi_scratch.efi_pgt); + goto out; + } early_code_mapping_set_exec(1); @@ -96,6 +93,7 @@ pgd_t * __init efi_call_phys_prolog(void) vaddress = (unsigned long)__va(pgd * PGDIR_SIZE); set_pgd(pgd_offset_k(pgd * PGDIR_SIZE), *pgd_offset_k(vaddress)); } +out: __flush_tlb_all(); return save_pgd; @@ -109,8 +107,11 @@ void __init efi_call_phys_epilog(pgd_t *save_pgd) int pgd_idx; int nr_pgds; - if (!save_pgd) + if (!efi_enabled(EFI_OLD_MEMMAP)) { + write_cr3((unsigned long)save_pgd); + __flush_tlb_all(); return; + } nr_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT) , PGDIR_SIZE); @@ -123,27 +124,98 @@ void __init efi_call_phys_epilog(pgd_t *save_pgd) early_code_mapping_set_exec(0); } +static pgd_t *efi_pgd; + +/* + * We need our own copy of the higher levels of the page tables + * because we want to avoid inserting EFI region mappings (EFI_VA_END + * to EFI_VA_START) into the standard kernel page tables. Everything + * else can be shared, see efi_sync_low_kernel_mappings(). + */ +int __init efi_alloc_page_tables(void) +{ + pgd_t *pgd; + pud_t *pud; + gfp_t gfp_mask; + + if (efi_enabled(EFI_OLD_MEMMAP)) + return 0; + + gfp_mask = GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO; + efi_pgd = (pgd_t *)__get_free_page(gfp_mask); + if (!efi_pgd) + return -ENOMEM; + + pgd = efi_pgd + pgd_index(EFI_VA_END); + + pud = pud_alloc_one(NULL, 0); + if (!pud) { + free_page((unsigned long)efi_pgd); + return -ENOMEM; + } + + pgd_populate(NULL, pgd, pud); + + return 0; +} + /* * Add low kernel mappings for passing arguments to EFI functions. */ void efi_sync_low_kernel_mappings(void) { - unsigned num_pgds; - pgd_t *pgd = (pgd_t *)__va(real_mode_header->trampoline_pgd); + unsigned num_entries; + pgd_t *pgd_k, *pgd_efi; + pud_t *pud_k, *pud_efi; if (efi_enabled(EFI_OLD_MEMMAP)) return; - num_pgds = pgd_index(MODULES_END - 1) - pgd_index(PAGE_OFFSET); + /* + * We can share all PGD entries apart from the one entry that + * covers the EFI runtime mapping space. + * + * Make sure the EFI runtime region mappings are guaranteed to + * only span a single PGD entry and that the entry also maps + * other important kernel regions. + */ + BUILD_BUG_ON(pgd_index(EFI_VA_END) != pgd_index(MODULES_END)); + BUILD_BUG_ON((EFI_VA_START & PGDIR_MASK) != + (EFI_VA_END & PGDIR_MASK)); + + pgd_efi = efi_pgd + pgd_index(PAGE_OFFSET); + pgd_k = pgd_offset_k(PAGE_OFFSET); - memcpy(pgd + pgd_index(PAGE_OFFSET), - init_mm.pgd + pgd_index(PAGE_OFFSET), - sizeof(pgd_t) * num_pgds); + num_entries = pgd_index(EFI_VA_END) - pgd_index(PAGE_OFFSET); + memcpy(pgd_efi, pgd_k, sizeof(pgd_t) * num_entries); + + /* + * We share all the PUD entries apart from those that map the + * EFI regions. Copy around them. + */ + BUILD_BUG_ON((EFI_VA_START & ~PUD_MASK) != 0); + BUILD_BUG_ON((EFI_VA_END & ~PUD_MASK) != 0); + + pgd_efi = efi_pgd + pgd_index(EFI_VA_END); + pud_efi = pud_offset(pgd_efi, 0); + + pgd_k = pgd_offset_k(EFI_VA_END); + pud_k = pud_offset(pgd_k, 0); + + num_entries = pud_index(EFI_VA_END); + memcpy(pud_efi, pud_k, sizeof(pud_t) * num_entries); + + pud_efi = pud_offset(pgd_efi, EFI_VA_START); + pud_k = pud_offset(pgd_k, EFI_VA_START); + + num_entries = PTRS_PER_PUD - pud_index(EFI_VA_START); + memcpy(pud_efi, pud_k, sizeof(pud_t) * num_entries); } int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) { - unsigned long text; + unsigned long pfn, text; + efi_memory_desc_t *md; struct page *page; unsigned npages; pgd_t *pgd; @@ -151,8 +223,8 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) if (efi_enabled(EFI_OLD_MEMMAP)) return 0; - efi_scratch.efi_pgt = (pgd_t *)(unsigned long)real_mode_header->trampoline_pgd; - pgd = __va(efi_scratch.efi_pgt); + efi_scratch.efi_pgt = (pgd_t *)__pa(efi_pgd); + pgd = efi_pgd; /* * It can happen that the physical address of new_memmap lands in memory @@ -160,7 +232,8 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) * and ident-map those pages containing the map before calling * phys_efi_set_virtual_address_map(). */ - if (kernel_map_pages_in_pgd(pgd, pa_memmap, pa_memmap, num_pages, _PAGE_NX)) { + pfn = pa_memmap >> PAGE_SHIFT; + if (kernel_map_pages_in_pgd(pgd, pfn, pa_memmap, num_pages, _PAGE_NX | _PAGE_RW)) { pr_err("Error ident-mapping new memmap (0x%lx)!\n", pa_memmap); return 1; } @@ -176,6 +249,25 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) if (!IS_ENABLED(CONFIG_EFI_MIXED)) return 0; + /* + * Map all of RAM so that we can access arguments in the 1:1 + * mapping when making EFI runtime calls. + */ + for_each_efi_memory_desc(&memmap, md) { + if (md->type != EFI_CONVENTIONAL_MEMORY && + md->type != EFI_LOADER_DATA && + md->type != EFI_LOADER_CODE) + continue; + + pfn = md->phys_addr >> PAGE_SHIFT; + npages = md->num_pages; + + if (kernel_map_pages_in_pgd(pgd, pfn, md->phys_addr, npages, _PAGE_RW)) { + pr_err("Failed to map 1:1 memory\n"); + return 1; + } + } + page = alloc_page(GFP_KERNEL|__GFP_DMA32); if (!page) panic("Unable to allocate EFI runtime stack < 4GB\n"); @@ -183,10 +275,11 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) efi_scratch.phys_stack = virt_to_phys(page_address(page)); efi_scratch.phys_stack += PAGE_SIZE; /* stack grows down */ - npages = (_end - _text) >> PAGE_SHIFT; + npages = (_etext - _text) >> PAGE_SHIFT; text = __pa(_text); + pfn = text >> PAGE_SHIFT; - if (kernel_map_pages_in_pgd(pgd, text >> PAGE_SHIFT, text, npages, 0)) { + if (kernel_map_pages_in_pgd(pgd, pfn, text, npages, _PAGE_RW)) { pr_err("Failed to map kernel text 1:1\n"); return 1; } @@ -196,20 +289,20 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) void __init efi_cleanup_page_tables(unsigned long pa_memmap, unsigned num_pages) { - pgd_t *pgd = (pgd_t *)__va(real_mode_header->trampoline_pgd); - - kernel_unmap_pages_in_pgd(pgd, pa_memmap, num_pages); + kernel_unmap_pages_in_pgd(efi_pgd, pa_memmap, num_pages); } static void __init __map_region(efi_memory_desc_t *md, u64 va) { - pgd_t *pgd = (pgd_t *)__va(real_mode_header->trampoline_pgd); - unsigned long pf = 0; + unsigned long flags = _PAGE_RW; + unsigned long pfn; + pgd_t *pgd = efi_pgd; if (!(md->attribute & EFI_MEMORY_WB)) - pf |= _PAGE_PCD; + flags |= _PAGE_PCD; - if (kernel_map_pages_in_pgd(pgd, md->phys_addr, va, md->num_pages, pf)) + pfn = md->phys_addr >> PAGE_SHIFT; + if (kernel_map_pages_in_pgd(pgd, pfn, va, md->num_pages, flags)) pr_warn("Error mapping PA 0x%llx -> VA 0x%llx!\n", md->phys_addr, va); } @@ -300,21 +393,56 @@ void __init parse_efi_setup(u64 phys_addr, u32 data_len) efi_setup = phys_addr + sizeof(struct setup_data); } -void __init efi_runtime_mkexec(void) +void __init efi_runtime_update_mappings(void) { - if (!efi_enabled(EFI_OLD_MEMMAP)) + unsigned long pfn; + pgd_t *pgd = efi_pgd; + efi_memory_desc_t *md; + void *p; + + if (efi_enabled(EFI_OLD_MEMMAP)) { + if (__supported_pte_mask & _PAGE_NX) + runtime_code_page_mkexec(); return; + } + + if (!efi_enabled(EFI_NX_PE_DATA)) + return; + + for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { + unsigned long pf = 0; + md = p; + + if (!(md->attribute & EFI_MEMORY_RUNTIME)) + continue; - if (__supported_pte_mask & _PAGE_NX) - runtime_code_page_mkexec(); + if (!(md->attribute & EFI_MEMORY_WB)) + pf |= _PAGE_PCD; + + if ((md->attribute & EFI_MEMORY_XP) || + (md->type == EFI_RUNTIME_SERVICES_DATA)) + pf |= _PAGE_NX; + + if (!(md->attribute & EFI_MEMORY_RO) && + (md->type != EFI_RUNTIME_SERVICES_CODE)) + pf |= _PAGE_RW; + + /* Update the 1:1 mapping */ + pfn = md->phys_addr >> PAGE_SHIFT; + if (kernel_map_pages_in_pgd(pgd, pfn, md->phys_addr, md->num_pages, pf)) + pr_warn("Error mapping PA 0x%llx -> VA 0x%llx!\n", + md->phys_addr, md->virt_addr); + + if (kernel_map_pages_in_pgd(pgd, pfn, md->virt_addr, md->num_pages, pf)) + pr_warn("Error mapping PA 0x%llx -> VA 0x%llx!\n", + md->phys_addr, md->virt_addr); + } } void __init efi_dump_pagetable(void) { #ifdef CONFIG_EFI_PGT_DUMP - pgd_t *pgd = (pgd_t *)__va(real_mode_header->trampoline_pgd); - - ptdump_walk_pgd_level(NULL, pgd); + ptdump_walk_pgd_level(NULL, efi_pgd); #endif } diff --git a/arch/x86/platform/efi/efi_stub_64.S b/arch/x86/platform/efi/efi_stub_64.S index 86d0f9e08dd95eb1023d5ac7ec4fb006aafb72c9..92723aeae0f96d2d5def8aac111765d9683f4d7f 100644 --- a/arch/x86/platform/efi/efi_stub_64.S +++ b/arch/x86/platform/efi/efi_stub_64.S @@ -11,6 +11,7 @@ #include #include #include +#include #define SAVE_XMM \ mov %rsp, %rax; \ @@ -38,42 +39,8 @@ mov %rsi, %cr0; \ mov (%rsp), %rsp - /* stolen from gcc */ - .macro FLUSH_TLB_ALL - movq %r15, efi_scratch(%rip) - movq %r14, efi_scratch+8(%rip) - movq %cr4, %r15 - movq %r15, %r14 - andb $0x7f, %r14b - movq %r14, %cr4 - movq %r15, %cr4 - movq efi_scratch+8(%rip), %r14 - movq efi_scratch(%rip), %r15 - .endm - - .macro SWITCH_PGT - cmpb $0, efi_scratch+24(%rip) - je 1f - movq %r15, efi_scratch(%rip) # r15 - # save previous CR3 - movq %cr3, %r15 - movq %r15, efi_scratch+8(%rip) # prev_cr3 - movq efi_scratch+16(%rip), %r15 # EFI pgt - movq %r15, %cr3 - 1: - .endm - - .macro RESTORE_PGT - cmpb $0, efi_scratch+24(%rip) - je 2f - movq efi_scratch+8(%rip), %r15 - movq %r15, %cr3 - movq efi_scratch(%rip), %r15 - FLUSH_TLB_ALL - 2: - .endm - ENTRY(efi_call) + FRAME_BEGIN SAVE_XMM mov (%rsp), %rax mov 8(%rax), %rax @@ -83,16 +50,9 @@ ENTRY(efi_call) mov %r8, %r9 mov %rcx, %r8 mov %rsi, %rcx - SWITCH_PGT call *%rdi - RESTORE_PGT addq $48, %rsp RESTORE_XMM + FRAME_END ret ENDPROC(efi_call) - - .data -ENTRY(efi_scratch) - .fill 3,8,0 - .byte 0 - .quad 0 diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c index ed30e79347e86377198009dcafb1c0b26a9865df..ab50ada1d56e4f87f6fff3207995ea32312fb37b 100644 --- a/arch/x86/platform/efi/quirks.c +++ b/arch/x86/platform/efi/quirks.c @@ -1,3 +1,5 @@ +#define pr_fmt(fmt) "efi: " fmt + #include #include #include @@ -54,6 +56,33 @@ void efi_delete_dummy_variable(void) 0, NULL); } +/* + * In the nonblocking case we do not attempt to perform garbage + * collection if we do not have enough free space. Rather, we do the + * bare minimum check and give up immediately if the available space + * is below EFI_MIN_RESERVE. + * + * This function is intended to be small and simple because it is + * invoked from crash handler paths. + */ +static efi_status_t +query_variable_store_nonblocking(u32 attributes, unsigned long size) +{ + efi_status_t status; + u64 storage_size, remaining_size, max_size; + + status = efi.query_variable_info_nonblocking(attributes, &storage_size, + &remaining_size, + &max_size); + if (status != EFI_SUCCESS) + return status; + + if (remaining_size - size < EFI_MIN_RESERVE) + return EFI_OUT_OF_RESOURCES; + + return EFI_SUCCESS; +} + /* * Some firmware implementations refuse to boot if there's insufficient space * in the variable store. Ensure that we never use more than a safe limit. @@ -61,7 +90,8 @@ void efi_delete_dummy_variable(void) * Return EFI_SUCCESS if it is safe to write 'size' bytes to the variable * store. */ -efi_status_t efi_query_variable_store(u32 attributes, unsigned long size) +efi_status_t efi_query_variable_store(u32 attributes, unsigned long size, + bool nonblocking) { efi_status_t status; u64 storage_size, remaining_size, max_size; @@ -69,6 +99,9 @@ efi_status_t efi_query_variable_store(u32 attributes, unsigned long size) if (!(attributes & EFI_VARIABLE_NON_VOLATILE)) return 0; + if (nonblocking) + return query_variable_store_nonblocking(attributes, size); + status = efi.query_variable_info(attributes, &storage_size, &remaining_size, &max_size); if (status != EFI_SUCCESS) @@ -312,7 +345,7 @@ void __init efi_apply_memmap_quirks(void) * services. */ if (!efi_runtime_supported()) { - pr_info("efi: Setup done, disabling due to 32/64-bit mismatch\n"); + pr_info("Setup done, disabling due to 32/64-bit mismatch\n"); efi_unmap_memmap(); } diff --git a/arch/x86/platform/intel-mid/device_libs/platform_bma023.c b/arch/x86/platform/intel-mid/device_libs/platform_bma023.c index 0ae7f2ae22968c128712197b7f80c14d72cc4e14..c26cf393d35aac12473617a4181b7d60c81bfeb4 100644 --- a/arch/x86/platform/intel-mid/device_libs/platform_bma023.c +++ b/arch/x86/platform/intel-mid/device_libs/platform_bma023.c @@ -1,5 +1,5 @@ /* - * platform_bma023.c: bma023 platform data initilization file + * platform_bma023.c: bma023 platform data initialization file * * (C) Copyright 2013 Intel Corporation * diff --git a/arch/x86/platform/intel-mid/device_libs/platform_emc1403.c b/arch/x86/platform/intel-mid/device_libs/platform_emc1403.c index 69a783689d21b7c2c7ac9db8c21f10b6582a318d..c259fb6c8f4f8773425b2ce5a213724af2152fa6 100644 --- a/arch/x86/platform/intel-mid/device_libs/platform_emc1403.c +++ b/arch/x86/platform/intel-mid/device_libs/platform_emc1403.c @@ -1,5 +1,5 @@ /* - * platform_emc1403.c: emc1403 platform data initilization file + * platform_emc1403.c: emc1403 platform data initialization file * * (C) Copyright 2013 Intel Corporation * Author: Sathyanarayanan Kuppuswamy diff --git a/arch/x86/platform/intel-mid/device_libs/platform_gpio_keys.c b/arch/x86/platform/intel-mid/device_libs/platform_gpio_keys.c index dccae6b0413f86a2f5fd91bfe3d8384553829d25..52534ec29765358d0a40b88073ea3de2f7fa012b 100644 --- a/arch/x86/platform/intel-mid/device_libs/platform_gpio_keys.c +++ b/arch/x86/platform/intel-mid/device_libs/platform_gpio_keys.c @@ -1,5 +1,5 @@ /* - * platform_gpio_keys.c: gpio_keys platform data initilization file + * platform_gpio_keys.c: gpio_keys platform data initialization file * * (C) Copyright 2013 Intel Corporation * Author: Sathyanarayanan Kuppuswamy diff --git a/arch/x86/platform/intel-mid/device_libs/platform_lis331.c b/arch/x86/platform/intel-mid/device_libs/platform_lis331.c index 54226de7541a7f43149b068657184e04b10f123f..a35cf912de43257cb3012dd0bff474121969bc63 100644 --- a/arch/x86/platform/intel-mid/device_libs/platform_lis331.c +++ b/arch/x86/platform/intel-mid/device_libs/platform_lis331.c @@ -1,5 +1,5 @@ /* - * platform_lis331.c: lis331 platform data initilization file + * platform_lis331.c: lis331 platform data initialization file * * (C) Copyright 2013 Intel Corporation * Author: Sathyanarayanan Kuppuswamy diff --git a/arch/x86/platform/intel-mid/device_libs/platform_max7315.c b/arch/x86/platform/intel-mid/device_libs/platform_max7315.c index 2c8acbc1e9ad906840d85269de5a428e45c4838f..6e075afa7877b349dc3372a122597b663c5ae77e 100644 --- a/arch/x86/platform/intel-mid/device_libs/platform_max7315.c +++ b/arch/x86/platform/intel-mid/device_libs/platform_max7315.c @@ -1,5 +1,5 @@ /* - * platform_max7315.c: max7315 platform data initilization file + * platform_max7315.c: max7315 platform data initialization file * * (C) Copyright 2013 Intel Corporation * Author: Sathyanarayanan Kuppuswamy diff --git a/arch/x86/platform/intel-mid/device_libs/platform_mpu3050.c b/arch/x86/platform/intel-mid/device_libs/platform_mpu3050.c index cfe9a47a1e8778409d2819e6ed20823ad5b299b6..ee22864bbc2f762f258463efd0b65bac28b2995e 100644 --- a/arch/x86/platform/intel-mid/device_libs/platform_mpu3050.c +++ b/arch/x86/platform/intel-mid/device_libs/platform_mpu3050.c @@ -1,5 +1,5 @@ /* - * platform_mpu3050.c: mpu3050 platform data initilization file + * platform_mpu3050.c: mpu3050 platform data initialization file * * (C) Copyright 2013 Intel Corporation * Author: Sathyanarayanan Kuppuswamy diff --git a/arch/x86/platform/intel-mid/device_libs/platform_msic.c b/arch/x86/platform/intel-mid/device_libs/platform_msic.c index 9f4a775a69d6a156457c0eae45d0c19102306370..e421106c11cf4af5024a5eb54a56e73fe7ba35df 100644 --- a/arch/x86/platform/intel-mid/device_libs/platform_msic.c +++ b/arch/x86/platform/intel-mid/device_libs/platform_msic.c @@ -1,5 +1,5 @@ /* - * platform_msic.c: MSIC platform data initilization file + * platform_msic.c: MSIC platform data initialization file * * (C) Copyright 2013 Intel Corporation * Author: Sathyanarayanan Kuppuswamy diff --git a/arch/x86/platform/intel-mid/device_libs/platform_msic_audio.c b/arch/x86/platform/intel-mid/device_libs/platform_msic_audio.c index 29629397d2b3eeb1133cb54ed66d9619be825e25..cb3490ecb341227062125e12f28b8bcdc47f07e2 100644 --- a/arch/x86/platform/intel-mid/device_libs/platform_msic_audio.c +++ b/arch/x86/platform/intel-mid/device_libs/platform_msic_audio.c @@ -1,5 +1,5 @@ /* - * platform_msic_audio.c: MSIC audio platform data initilization file + * platform_msic_audio.c: MSIC audio platform data initialization file * * (C) Copyright 2013 Intel Corporation * Author: Sathyanarayanan Kuppuswamy diff --git a/arch/x86/platform/intel-mid/device_libs/platform_msic_battery.c b/arch/x86/platform/intel-mid/device_libs/platform_msic_battery.c index f446c33df1a8098b2cdd4a2dd043e1c883d82e61..4f72193939a68c668cba48eed07a2f6d236fd4b7 100644 --- a/arch/x86/platform/intel-mid/device_libs/platform_msic_battery.c +++ b/arch/x86/platform/intel-mid/device_libs/platform_msic_battery.c @@ -1,5 +1,5 @@ /* - * platform_msic_battery.c: MSIC battery platform data initilization file + * platform_msic_battery.c: MSIC battery platform data initialization file * * (C) Copyright 2013 Intel Corporation * Author: Sathyanarayanan Kuppuswamy diff --git a/arch/x86/platform/intel-mid/device_libs/platform_msic_gpio.c b/arch/x86/platform/intel-mid/device_libs/platform_msic_gpio.c index 2a4f7b1dd917037dea5a2c405854731c7b4e49a2..70de5b531ba0b7959eb8b4b26afc436b5aae300a 100644 --- a/arch/x86/platform/intel-mid/device_libs/platform_msic_gpio.c +++ b/arch/x86/platform/intel-mid/device_libs/platform_msic_gpio.c @@ -1,5 +1,5 @@ /* - * platform_msic_gpio.c: MSIC GPIO platform data initilization file + * platform_msic_gpio.c: MSIC GPIO platform data initialization file * * (C) Copyright 2013 Intel Corporation * Author: Sathyanarayanan Kuppuswamy diff --git a/arch/x86/platform/intel-mid/device_libs/platform_msic_ocd.c b/arch/x86/platform/intel-mid/device_libs/platform_msic_ocd.c index 6497111ddb549c9ae734c70538915b8d34000634..3d7c2011b6cfe41b431ae108041e5615cf157d98 100644 --- a/arch/x86/platform/intel-mid/device_libs/platform_msic_ocd.c +++ b/arch/x86/platform/intel-mid/device_libs/platform_msic_ocd.c @@ -1,5 +1,5 @@ /* - * platform_msic_ocd.c: MSIC OCD platform data initilization file + * platform_msic_ocd.c: MSIC OCD platform data initialization file * * (C) Copyright 2013 Intel Corporation * Author: Sathyanarayanan Kuppuswamy diff --git a/arch/x86/platform/intel-mid/device_libs/platform_msic_power_btn.c b/arch/x86/platform/intel-mid/device_libs/platform_msic_power_btn.c index 83a3459bc3377c3d5f79556e6a936489737f17c6..038f618fbc525592dc269e08658d3c47b6868771 100644 --- a/arch/x86/platform/intel-mid/device_libs/platform_msic_power_btn.c +++ b/arch/x86/platform/intel-mid/device_libs/platform_msic_power_btn.c @@ -1,5 +1,5 @@ /* - * platform_msic_power_btn.c: MSIC power btn platform data initilization file + * platform_msic_power_btn.c: MSIC power btn platform data initialization file * * (C) Copyright 2013 Intel Corporation * Author: Sathyanarayanan Kuppuswamy diff --git a/arch/x86/platform/intel-mid/device_libs/platform_msic_thermal.c b/arch/x86/platform/intel-mid/device_libs/platform_msic_thermal.c index a351878b96bcfab6a85b1333ffb77ffb02310c23..114a5755b1e49a181f0577c93164518106aa4dfd 100644 --- a/arch/x86/platform/intel-mid/device_libs/platform_msic_thermal.c +++ b/arch/x86/platform/intel-mid/device_libs/platform_msic_thermal.c @@ -1,5 +1,5 @@ /* - * platform_msic_thermal.c: msic_thermal platform data initilization file + * platform_msic_thermal.c: msic_thermal platform data initialization file * * (C) Copyright 2013 Intel Corporation * Author: Sathyanarayanan Kuppuswamy diff --git a/arch/x86/platform/intel-mid/device_libs/platform_pmic_gpio.c b/arch/x86/platform/intel-mid/device_libs/platform_pmic_gpio.c index 65c2a9a19db4d0f69378ff2effc390f3ad48f8ef..e30cb62e3300204d41aa7cc220aa89515ce42ab1 100644 --- a/arch/x86/platform/intel-mid/device_libs/platform_pmic_gpio.c +++ b/arch/x86/platform/intel-mid/device_libs/platform_pmic_gpio.c @@ -1,5 +1,5 @@ /* - * platform_pmic_gpio.c: PMIC GPIO platform data initilization file + * platform_pmic_gpio.c: PMIC GPIO platform data initialization file * * (C) Copyright 2013 Intel Corporation * Author: Sathyanarayanan Kuppuswamy diff --git a/arch/x86/platform/intel-mid/device_libs/platform_tc35876x.c b/arch/x86/platform/intel-mid/device_libs/platform_tc35876x.c index 740fc757050cf3e3016cc0e911fcfb43572c6b59..b1526b95fd43acbd3a517b2f6332a361b1da9726 100644 --- a/arch/x86/platform/intel-mid/device_libs/platform_tc35876x.c +++ b/arch/x86/platform/intel-mid/device_libs/platform_tc35876x.c @@ -1,5 +1,5 @@ /* - * platform_tc35876x.c: tc35876x platform data initilization file + * platform_tc35876x.c: tc35876x platform data initialization file * * (C) Copyright 2013 Intel Corporation * Author: Sathyanarayanan Kuppuswamy diff --git a/arch/x86/platform/intel-mid/device_libs/platform_tca6416.c b/arch/x86/platform/intel-mid/device_libs/platform_tca6416.c index 33be0b3be6e12080fd63ae249829b93504174cc6..4f41372ce400cea52f6cbdc9101d90c8c0bbe5f4 100644 --- a/arch/x86/platform/intel-mid/device_libs/platform_tca6416.c +++ b/arch/x86/platform/intel-mid/device_libs/platform_tca6416.c @@ -1,5 +1,5 @@ /* - * platform_tca6416.c: tca6416 platform data initilization file + * platform_tca6416.c: tca6416 platform data initialization file * * (C) Copyright 2013 Intel Corporation * Author: Sathyanarayanan Kuppuswamy diff --git a/arch/x86/power/hibernate_asm_64.S b/arch/x86/power/hibernate_asm_64.S index e2386cb4e0c315f32fae03afd13045c4047eb902..4400a43b9e28f20aaac68c1a20091e683e31b799 100644 --- a/arch/x86/power/hibernate_asm_64.S +++ b/arch/x86/power/hibernate_asm_64.S @@ -21,8 +21,10 @@ #include #include #include +#include ENTRY(swsusp_arch_suspend) + FRAME_BEGIN movq $saved_context, %rax movq %rsp, pt_regs_sp(%rax) movq %rbp, pt_regs_bp(%rax) @@ -50,7 +52,9 @@ ENTRY(swsusp_arch_suspend) movq %rax, restore_cr3(%rip) call swsusp_save + FRAME_END ret +ENDPROC(swsusp_arch_suspend) ENTRY(restore_image) /* switch to temporary page tables */ @@ -107,6 +111,7 @@ ENTRY(core_restore_code) */ ENTRY(restore_registers) + FRAME_BEGIN /* go back to the original page tables */ movq %rbx, %cr3 @@ -147,4 +152,6 @@ ENTRY(restore_registers) /* tell the hibernation core that we've just restored the memory */ movq %rax, in_suspend(%rip) + FRAME_END ret +ENDPROC(restore_registers) diff --git a/arch/x86/purgatory/Makefile b/arch/x86/purgatory/Makefile index 2c835e356349b9284b6b6997fff19208b6dd1b61..92e3e1d84c1d73fb86b086b6ea8783ccf2f3663e 100644 --- a/arch/x86/purgatory/Makefile +++ b/arch/x86/purgatory/Makefile @@ -1,3 +1,5 @@ +OBJECT_FILES_NON_STANDARD := y + purgatory-y := purgatory.o stack.o setup-x86_$(BITS).o sha256.o entry64.o string.o targets += $(purgatory-y) diff --git a/arch/x86/purgatory/stack.S b/arch/x86/purgatory/stack.S index 3cefba1fefc8066e58b40ef2182efa065b746077..50a4147f91fb88b15e89e7a5c712cb61780926e3 100644 --- a/arch/x86/purgatory/stack.S +++ b/arch/x86/purgatory/stack.S @@ -8,7 +8,7 @@ */ /* A stack for the loaded kernel. - * Seperate and in the data section so it can be prepopulated. + * Separate and in the data section so it can be prepopulated. */ .data .balign 4096 diff --git a/arch/x86/ras/mce_amd_inj.c b/arch/x86/ras/mce_amd_inj.c index 55d38cfa46c2626c6d2f85587da27c05ca3e6bf7..9e02dcaef68311ed376f8fcd0579d6c207e80103 100644 --- a/arch/x86/ras/mce_amd_inj.c +++ b/arch/x86/ras/mce_amd_inj.c @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -206,7 +207,7 @@ static u32 get_nbc_for_node(int node_id) struct cpuinfo_x86 *c = &boot_cpu_data; u32 cores_per_node; - cores_per_node = c->x86_max_cores / amd_get_nodes_per_socket(); + cores_per_node = (c->x86_max_cores * smp_num_siblings) / amd_get_nodes_per_socket(); return cores_per_node * node_id; } diff --git a/arch/x86/realmode/Makefile b/arch/x86/realmode/Makefile index e02c2c6c56a57a8a762c66d8e2f1f34315fa0410..682c895753d96a7c3a9b231cbf5f01dcbc8420ba 100644 --- a/arch/x86/realmode/Makefile +++ b/arch/x86/realmode/Makefile @@ -6,7 +6,9 @@ # for more details. # # -KASAN_SANITIZE := n +KASAN_SANITIZE := n +OBJECT_FILES_NON_STANDARD := y + subdir- := rm obj-y += init.o diff --git a/arch/x86/realmode/rm/Makefile b/arch/x86/realmode/rm/Makefile index 3e75fcf6b8362e7c43f24340a3836386a4d5ac48..b95964610ea7f45320105f0378267a39aa7b427e 100644 --- a/arch/x86/realmode/rm/Makefile +++ b/arch/x86/realmode/rm/Makefile @@ -6,7 +6,11 @@ # for more details. # # -KASAN_SANITIZE := n +KASAN_SANITIZE := n +OBJECT_FILES_NON_STANDARD := y + +# Prevents link failures: __sanitizer_cov_trace_pc() is not linked in. +KCOV_INSTRUMENT := n always := realmode.bin realmode.relocs diff --git a/arch/x86/um/asm/checksum.h b/arch/x86/um/asm/checksum.h index ee940185e89f28c9d7553f4f6d15e057eadc7883..54d96f1e35943c227fa998f7d6c5120417df9956 100644 --- a/arch/x86/um/asm/checksum.h +++ b/arch/x86/um/asm/checksum.h @@ -87,8 +87,8 @@ static inline __sum16 csum_fold(__wsum sum) * 32bit unfolded. */ static inline __wsum -csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, __wsum sum) +csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len, + __u8 proto, __wsum sum) { asm(" addl %1, %0\n" " adcl %2, %0\n" @@ -104,9 +104,8 @@ csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, * returns a 16-bit checksum, already complemented */ static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum) + __u32 len, __u8 proto, + __wsum sum) { return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); } diff --git a/arch/x86/um/asm/checksum_32.h b/arch/x86/um/asm/checksum_32.h index ab77b6f9a4bf3eef1abc883820067a50cb68ccd2..83a75f8a12330237a73b20a9d5c96c9a77d4b450 100644 --- a/arch/x86/um/asm/checksum_32.h +++ b/arch/x86/um/asm/checksum_32.h @@ -13,7 +13,7 @@ static inline __sum16 ip_compute_csum(const void *buff, int len) #define _HAVE_ARCH_IPV6_CSUM static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, - __u32 len, unsigned short proto, + __u32 len, __u8 proto, __wsum sum) { __asm__( diff --git a/arch/x86/video/fbdev.c b/arch/x86/video/fbdev.c index d5644bbe8cbac5de5432005d1d694ffc36112563..9fd24846d0943628c565f20fccebb4062a019592 100644 --- a/arch/x86/video/fbdev.c +++ b/arch/x86/video/fbdev.c @@ -14,26 +14,24 @@ int fb_is_primary_device(struct fb_info *info) { struct device *device = info->device; - struct pci_dev *pci_dev = NULL; struct pci_dev *default_device = vga_default_device(); - struct resource *res = NULL; + struct pci_dev *pci_dev; + struct resource *res; - if (device) - pci_dev = to_pci_dev(device); - - if (!pci_dev) + if (!device || !dev_is_pci(device)) return 0; + pci_dev = to_pci_dev(device); + if (default_device) { if (pci_dev == default_device) return 1; - else - return 0; + return 0; } - res = &pci_dev->resource[PCI_ROM_RESOURCE]; + res = pci_dev->resource + PCI_ROM_RESOURCE; - if (res && res->flags & IORESOURCE_ROM_SHADOW) + if (res->flags & IORESOURCE_ROM_SHADOW) return 1; return 0; diff --git a/arch/x86/xen/apic.c b/arch/x86/xen/apic.c index abf4901c917bacd58e8172b4566ad8b3eb10a467..db52a7fafcc2ce7dc9b4294065ef9807f9a311a1 100644 --- a/arch/x86/xen/apic.c +++ b/arch/x86/xen/apic.c @@ -66,7 +66,7 @@ static u32 xen_apic_read(u32 reg) ret = HYPERVISOR_platform_op(&op); if (ret) - return 0; + op.u.pcpu_info.apic_id = BAD_APICID; return op.u.pcpu_info.apic_id << 24; } @@ -142,6 +142,14 @@ static void xen_silent_inquire(int apicid) { } +static int xen_cpu_present_to_apicid(int cpu) +{ + if (cpu_present(cpu)) + return xen_get_apic_id(xen_apic_read(APIC_ID)); + else + return BAD_APICID; +} + static struct apic xen_pv_apic = { .name = "Xen PV", .probe = xen_apic_probe_pv, @@ -162,7 +170,7 @@ static struct apic xen_pv_apic = { .ioapic_phys_id_map = default_ioapic_phys_id_map, /* Used on 32-bit */ .setup_apic_routing = NULL, - .cpu_present_to_apicid = default_cpu_present_to_apicid, + .cpu_present_to_apicid = xen_cpu_present_to_apicid, .apicid_to_cpu_present = physid_set_mask_of_physid, /* Used on 32-bit */ .check_phys_apicid_present = default_check_phys_apicid_present, /* smp_sanity_check needs it */ .phys_pkg_id = xen_phys_pkg_id, /* detect_ht */ diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 2c261082eadf82f693d062e7f600660fcd56817f..880862c7d9ddba51e1b6964bc80dcf49d6a8b6ff 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -32,6 +32,7 @@ #include #include #include +#include #ifdef CONFIG_KEXEC_CORE #include @@ -351,8 +352,8 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx, *cx &= maskecx; *cx |= setecx; *dx &= maskedx; - } +STACK_FRAME_NON_STANDARD(xen_cpuid); /* XEN_EMULATE_PREFIX */ static bool __init xen_check_mwait(void) { @@ -961,7 +962,7 @@ static void xen_load_sp0(struct tss_struct *tss, tss->x86_tss.sp0 = thread->sp0; } -static void xen_set_iopl_mask(unsigned mask) +void xen_set_iopl_mask(unsigned mask) { struct physdev_set_iopl set_iopl; diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index c913ca4f6958693f6d7357c53bf149076a4b6d4f..478a2de543a59ea797515be2f8145a503277778f 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c @@ -1256,7 +1256,7 @@ static void __init xen_pagetable_cleanhighmap(void) xen_cleanhighmap(addr, addr + size); xen_start_info->pt_base = (unsigned long)__va(__pa(xen_start_info->pt_base)); #ifdef DEBUG - /* This is superflous and is not neccessary, but you know what + /* This is superfluous and is not necessary, but you know what * lets do it. The MODULES_VADDR -> MODULES_END should be clear of * anything at this stage. */ xen_cleanhighmap(MODULES_VADDR, roundup(MODULES_VADDR, PUD_SIZE) - 1); @@ -1474,7 +1474,7 @@ static void xen_write_cr3(unsigned long cr3) /* * At the start of the day - when Xen launches a guest, it has already * built pagetables for the guest. We diligently look over them - * in xen_setup_kernel_pagetable and graft as appropiate them in the + * in xen_setup_kernel_pagetable and graft as appropriate them in the * init_level4_pgt and its friends. Then when we are happy we load * the new init_level4_pgt - and continue on. * @@ -2792,7 +2792,7 @@ static int remap_area_mfn_pte_fn(pte_t *ptep, pgtable_t token, struct remap_data *rmd = data; pte_t pte = pte_mkspecial(mfn_pte(*rmd->mfn, rmd->prot)); - /* If we have a contigious range, just update the mfn itself, + /* If we have a contiguous range, just update the mfn itself, else update pointer to be "next mfn". */ if (rmd->contiguous) (*rmd->mfn)++; @@ -2833,7 +2833,7 @@ static int do_remap_gfn(struct vm_area_struct *vma, rmd.mfn = gfn; rmd.prot = prot; - /* We use the err_ptr to indicate if there we are doing a contigious + /* We use the err_ptr to indicate if there we are doing a contiguous * mapping or a discontigious mapping. */ rmd.contiguous = !err_ptr; diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index 3c6d17fd423a82006d89c71e7345bb6a566aec09..719cf291dcdf195e68e52c97dd054686192aa936 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c @@ -545,6 +545,8 @@ static void xen_play_dead(void) /* used only with HOTPLUG_CPU */ * data back is to call: */ tick_nohz_idle_enter(); + + cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); } #else /* !CONFIG_HOTPLUG_CPU */ diff --git a/arch/x86/xen/xen-asm.S b/arch/x86/xen/xen-asm.S index 3e45aa000718aa2cd63d78f5c849e42666905d0e..eff224df813fdd88092b16d2942aaa000b815e97 100644 --- a/arch/x86/xen/xen-asm.S +++ b/arch/x86/xen/xen-asm.S @@ -14,6 +14,7 @@ #include #include #include +#include #include "xen-asm.h" @@ -23,6 +24,7 @@ * then enter the hypervisor to get them handled. */ ENTRY(xen_irq_enable_direct) + FRAME_BEGIN /* Unmask events */ movb $0, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask @@ -39,6 +41,7 @@ ENTRY(xen_irq_enable_direct) 2: call check_events 1: ENDPATCH(xen_irq_enable_direct) + FRAME_END ret ENDPROC(xen_irq_enable_direct) RELOC(xen_irq_enable_direct, 2b+1) @@ -82,6 +85,7 @@ ENDPATCH(xen_save_fl_direct) * enters the hypervisor to get them delivered if so. */ ENTRY(xen_restore_fl_direct) + FRAME_BEGIN #ifdef CONFIG_X86_64 testw $X86_EFLAGS_IF, %di #else @@ -100,6 +104,7 @@ ENTRY(xen_restore_fl_direct) 2: call check_events 1: ENDPATCH(xen_restore_fl_direct) + FRAME_END ret ENDPROC(xen_restore_fl_direct) RELOC(xen_restore_fl_direct, 2b+1) @@ -109,7 +114,8 @@ ENDPATCH(xen_restore_fl_direct) * Force an event check by making a hypercall, but preserve regs * before making the call. */ -check_events: +ENTRY(check_events) + FRAME_BEGIN #ifdef CONFIG_X86_32 push %eax push %ecx @@ -139,4 +145,6 @@ check_events: pop %rcx pop %rax #endif + FRAME_END ret +ENDPROC(check_events) diff --git a/arch/x86/xen/xen-asm_64.S b/arch/x86/xen/xen-asm_64.S index cc8acc410ddb81d9c3a86b87c0b11f96b29c4bb4..c3df43141e7064477b1d2da432e7f8d0d81ea3f2 100644 --- a/arch/x86/xen/xen-asm_64.S +++ b/arch/x86/xen/xen-asm_64.S @@ -26,6 +26,7 @@ ENTRY(xen_adjust_exception_frame) mov 8+0(%rsp), %rcx mov 8+8(%rsp), %r11 ret $16 +ENDPROC(xen_adjust_exception_frame) hypercall_iret = hypercall_page + __HYPERVISOR_iret * 32 /* diff --git a/arch/x86/xen/xen-head.S b/arch/x86/xen/xen-head.S index b65f59a358a220fac788fef178fa3bc2e6dbc8d6..7f8d8abf4c1ab8b1ea114fee0365f1505b81aeea 100644 --- a/arch/x86/xen/xen-head.S +++ b/arch/x86/xen/xen-head.S @@ -26,7 +26,7 @@ (1 << XENFEAT_auto_translated_physmap) | \ (1 << XENFEAT_supervisor_mode_kernel) | \ (1 << XENFEAT_hvm_callback_vector)) -/* The XENFEAT_writable_page_tables is not stricly neccessary as we set that +/* The XENFEAT_writable_page_tables is not stricly necessary as we set that * up regardless whether this CONFIG option is enabled or not, but it * clarifies what the right flags need to be. */ @@ -38,13 +38,18 @@ __INIT ENTRY(startup_xen) cld -#ifdef CONFIG_X86_32 - mov %esi,xen_start_info - mov $init_thread_union+THREAD_SIZE,%esp -#else - mov %rsi,xen_start_info - mov $init_thread_union+THREAD_SIZE,%rsp -#endif + + /* Clear .bss */ + xor %eax,%eax + mov $__bss_start, %_ASM_DI + mov $__bss_stop, %_ASM_CX + sub %_ASM_DI, %_ASM_CX + shr $__ASM_SEL(2, 3), %_ASM_CX + rep __ASM_SIZE(stos) + + mov %_ASM_SI, xen_start_info + mov $init_thread_union+THREAD_SIZE, %_ASM_SP + jmp xen_start_kernel __FINIT diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 7e9464b0fc00bb3de3267d3e707647f760c852c5..e832d3e9835eff5ba2fe2a78be0279d861f89321 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -17,6 +17,7 @@ config XTENSA select HAVE_DMA_API_DEBUG select HAVE_FUNCTION_TRACER select HAVE_FUTEX_CMPXCHG if !MMU + select HAVE_HW_BREAKPOINT if PERF_EVENTS select HAVE_IRQ_TIME_ACCOUNTING select HAVE_OPROFILE select HAVE_PERF_EVENTS @@ -138,6 +139,22 @@ config XTENSA_VARIANT_HAVE_PERF_EVENTS If unsure, say N. +config XTENSA_FAKE_NMI + bool "Treat PMM IRQ as NMI" + depends on XTENSA_VARIANT_HAVE_PERF_EVENTS + default n + help + If PMM IRQ is the only IRQ at EXCM level it is safe to + treat it as NMI, which improves accuracy of profiling. + + If there are other interrupts at or above PMM IRQ priority level + but not above the EXCM level, PMM IRQ still may be treated as NMI, + but only if these IRQs are not used. There will be a build warning + saying that this is not safe, and a bugcheck if one of these IRQs + actually fire. + + If unsure, say N. + config XTENSA_UNALIGNED_USER bool "Unaligned memory access in use space" help diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile index 709b5748a2d7ed44aeacf7d378cc99b4e37c0939..e54189427b315159ed00e5f7d4c2ae81d8c78773 100644 --- a/arch/xtensa/Makefile +++ b/arch/xtensa/Makefile @@ -53,9 +53,11 @@ endif ifeq ($(shell echo __XTENSA_EB__ | $(CC) -E - | grep -v "\#"),1) CHECKFLAGS += -D__XTENSA_EB__ +KBUILD_CPPFLAGS += -DCONFIG_CPU_BIG_ENDIAN endif ifeq ($(shell echo __XTENSA_EL__ | $(CC) -E - | grep -v "\#"),1) CHECKFLAGS += -D__XTENSA_EL__ +KBUILD_CPPFLAGS += -DCONFIG_CPU_LITTLE_ENDIAN endif vardirs := $(patsubst %,arch/xtensa/variants/%/,$(variant-y)) diff --git a/arch/xtensa/boot/dts/kc705.dts b/arch/xtensa/boot/dts/kc705.dts index c4d17a34ab86ca3d61ca85f398cf0fd80b753f41..b1f4ee8c9a22371ba9abedfcc7d21fb279b585f0 100644 --- a/arch/xtensa/boot/dts/kc705.dts +++ b/arch/xtensa/boot/dts/kc705.dts @@ -5,7 +5,7 @@ / { compatible = "cdns,xtensa-kc705"; chosen { - bootargs = "earlycon=uart8250,mmio32,0xfd050020,115200n8 console=ttyS0,115200n8 ip=dhcp root=/dev/nfs rw debug memmap=0x38000000"; + bootargs = "earlycon=uart8250,mmio32native,0xfd050020,115200n8 console=ttyS0,115200n8 ip=dhcp root=/dev/nfs rw debug memmap=0x38000000"; }; memory@0 { device_type = "memory"; diff --git a/arch/xtensa/boot/dts/xtfpga.dtsi b/arch/xtensa/boot/dts/xtfpga.dtsi index cd0b9e34adc8b371d3548c6a9e1218aaef24bd38..cd45f9c2c4484225960dc63267230bb3c7f5a2eb 100644 --- a/arch/xtensa/boot/dts/xtfpga.dtsi +++ b/arch/xtensa/boot/dts/xtfpga.dtsi @@ -5,7 +5,7 @@ interrupt-parent = <&pic>; chosen { - bootargs = "earlycon=uart8250,mmio32,0xfd050020,115200n8 console=ttyS0,115200n8 ip=dhcp root=/dev/nfs rw debug"; + bootargs = "earlycon=uart8250,mmio32native,0xfd050020,115200n8 console=ttyS0,115200n8 ip=dhcp root=/dev/nfs rw debug"; }; memory@0 { @@ -60,6 +60,8 @@ no-loopback-test; reg = <0x0d050020 0x20>; reg-shift = <2>; + reg-io-width = <4>; + native-endian; interrupts = <0 1>; /* external irq 0 */ clocks = <&osc>; }; @@ -67,6 +69,7 @@ enet0: ethoc@0d030000 { compatible = "opencores,ethoc"; reg = <0x0d030000 0x4000 0x0d800000 0x4000>; + native-endian; interrupts = <1 1>; /* external irq 1 */ local-mac-address = [00 50 c2 13 6f 00]; clocks = <&osc>; @@ -86,7 +89,8 @@ #size-cells = <0>; reg = <0x0d090000 0x20>; reg-shift = <2>; - reg-io-width = <1>; + reg-io-width = <4>; + native-endian; interrupts = <4 1>; clocks = <&osc>; diff --git a/arch/xtensa/include/asm/checksum.h b/arch/xtensa/include/asm/checksum.h index 0593de689b565131c9b0cd53081b6d2c245718f3..ec35074fcb03ac1064af1e6c8f5112ae03187194 100644 --- a/arch/xtensa/include/asm/checksum.h +++ b/arch/xtensa/include/asm/checksum.h @@ -123,9 +123,8 @@ static __inline__ __sum16 ip_fast_csum(const void *iph, unsigned int ihl) } static __inline__ __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum) + __u32 len, __u8 proto, + __wsum sum) { #ifdef __XTENSA_EL__ @@ -157,9 +156,8 @@ static __inline__ __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, * returns a 16-bit checksum, already complemented */ static __inline__ __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum) + __u32 len, __u8 proto, + __wsum sum) { return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); } @@ -177,7 +175,7 @@ static __inline__ __sum16 ip_compute_csum(const void *buff, int len) #define _HAVE_ARCH_IPV6_CSUM static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, - __u32 len, unsigned short proto, + __u32 len, __u8 proto, __wsum sum) { unsigned int __dummy; diff --git a/arch/xtensa/include/asm/hw_breakpoint.h b/arch/xtensa/include/asm/hw_breakpoint.h new file mode 100644 index 0000000000000000000000000000000000000000..dbe3053b284a4286970decf9f3d966f53e7c3a28 --- /dev/null +++ b/arch/xtensa/include/asm/hw_breakpoint.h @@ -0,0 +1,58 @@ +/* + * Xtensa hardware breakpoints/watchpoints handling functions + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2016 Cadence Design Systems Inc. + */ + +#ifndef __ASM_XTENSA_HW_BREAKPOINT_H +#define __ASM_XTENSA_HW_BREAKPOINT_H + +#ifdef CONFIG_HAVE_HW_BREAKPOINT + +#include +#include +#include + +/* Breakpoint */ +#define XTENSA_BREAKPOINT_EXECUTE 0 + +/* Watchpoints */ +#define XTENSA_BREAKPOINT_LOAD 1 +#define XTENSA_BREAKPOINT_STORE 2 + +struct arch_hw_breakpoint { + unsigned long address; + u16 len; + u16 type; +}; + +struct perf_event; +struct pt_regs; +struct task_struct; + +int hw_breakpoint_slots(int type); +int arch_check_bp_in_kernelspace(struct perf_event *bp); +int arch_validate_hwbkpt_settings(struct perf_event *bp); +int hw_breakpoint_exceptions_notify(struct notifier_block *unused, + unsigned long val, void *data); + +int arch_install_hw_breakpoint(struct perf_event *bp); +void arch_uninstall_hw_breakpoint(struct perf_event *bp); +void hw_breakpoint_pmu_read(struct perf_event *bp); +int check_hw_breakpoint(struct pt_regs *regs); +void clear_ptrace_hw_breakpoint(struct task_struct *tsk); + +#else + +struct task_struct; + +static inline void clear_ptrace_hw_breakpoint(struct task_struct *tsk) +{ +} + +#endif /* CONFIG_HAVE_HW_BREAKPOINT */ +#endif /* __ASM_XTENSA_HW_BREAKPOINT_H */ diff --git a/arch/xtensa/include/asm/io.h b/arch/xtensa/include/asm/io.h index 74fed0b4e2c2b58a84bd0bbc699d7bca74f422de..c38e5a732d86f69b44826349314a6fb286305985 100644 --- a/arch/xtensa/include/asm/io.h +++ b/arch/xtensa/include/asm/io.h @@ -25,9 +25,12 @@ #ifdef CONFIG_MMU +void __iomem *xtensa_ioremap_nocache(unsigned long addr, unsigned long size); +void __iomem *xtensa_ioremap_cache(unsigned long addr, unsigned long size); +void xtensa_iounmap(volatile void __iomem *addr); + /* * Return the virtual address for the specified bus memory. - * Note that we currently don't support any address outside the KIO segment. */ static inline void __iomem *ioremap_nocache(unsigned long offset, unsigned long size) @@ -36,7 +39,7 @@ static inline void __iomem *ioremap_nocache(unsigned long offset, && offset - XCHAL_KIO_PADDR < XCHAL_KIO_SIZE) return (void*)(offset-XCHAL_KIO_PADDR+XCHAL_KIO_BYPASS_VADDR); else - BUG(); + return xtensa_ioremap_nocache(offset, size); } static inline void __iomem *ioremap_cache(unsigned long offset, @@ -46,7 +49,7 @@ static inline void __iomem *ioremap_cache(unsigned long offset, && offset - XCHAL_KIO_PADDR < XCHAL_KIO_SIZE) return (void*)(offset-XCHAL_KIO_PADDR+XCHAL_KIO_CACHED_VADDR); else - BUG(); + return xtensa_ioremap_cache(offset, size); } #define ioremap_cache ioremap_cache @@ -60,6 +63,13 @@ static inline void __iomem *ioremap(unsigned long offset, unsigned long size) static inline void iounmap(volatile void __iomem *addr) { + unsigned long va = (unsigned long) addr; + + if (!(va >= XCHAL_KIO_CACHED_VADDR && + va - XCHAL_KIO_CACHED_VADDR < XCHAL_KIO_SIZE) && + !(va >= XCHAL_KIO_BYPASS_VADDR && + va - XCHAL_KIO_BYPASS_VADDR < XCHAL_KIO_SIZE)) + xtensa_iounmap(addr); } #define virt_to_bus virt_to_phys diff --git a/arch/xtensa/include/asm/irqflags.h b/arch/xtensa/include/asm/irqflags.h index 8e090c709046f9663d4c80d16e5011846d8cf3a6..407606e576f8911728ab0232e8419e63d39b343d 100644 --- a/arch/xtensa/include/asm/irqflags.h +++ b/arch/xtensa/include/asm/irqflags.h @@ -13,6 +13,7 @@ #define _XTENSA_IRQFLAGS_H #include +#include static inline unsigned long arch_local_save_flags(void) { diff --git a/arch/xtensa/include/asm/processor.h b/arch/xtensa/include/asm/processor.h index 83e2e4bc01ba24f54965df8b4ee3de7855e028e0..d2e40d39c6158102de48debffe76a0c5fe4f4cbc 100644 --- a/arch/xtensa/include/asm/processor.h +++ b/arch/xtensa/include/asm/processor.h @@ -78,22 +78,20 @@ #define XTENSA_INTLEVEL_MASK(level) _XTENSA_INTLEVEL_MASK(level) #define _XTENSA_INTLEVEL_MASK(level) (XCHAL_INTLEVEL##level##_MASK) -#define IS_POW2(v) (((v) & ((v) - 1)) == 0) +#define XTENSA_INTLEVEL_ANDBELOW_MASK(l) _XTENSA_INTLEVEL_ANDBELOW_MASK(l) +#define _XTENSA_INTLEVEL_ANDBELOW_MASK(l) (XCHAL_INTLEVEL##l##_ANDBELOW_MASK) #define PROFILING_INTLEVEL XTENSA_INT_LEVEL(XCHAL_PROFILING_INTERRUPT) /* LOCKLEVEL defines the interrupt level that masks all * general-purpose interrupts. */ -#if defined(CONFIG_XTENSA_VARIANT_HAVE_PERF_EVENTS) && \ - defined(XCHAL_PROFILING_INTERRUPT) && \ - PROFILING_INTLEVEL == XCHAL_EXCM_LEVEL && \ - XCHAL_EXCM_LEVEL > 1 && \ - IS_POW2(XTENSA_INTLEVEL_MASK(PROFILING_INTLEVEL)) -#define LOCKLEVEL (XCHAL_EXCM_LEVEL - 1) +#if defined(CONFIG_XTENSA_FAKE_NMI) && defined(XCHAL_PROFILING_INTERRUPT) +#define LOCKLEVEL (PROFILING_INTLEVEL - 1) #else #define LOCKLEVEL XCHAL_EXCM_LEVEL #endif + #define TOPLEVEL XCHAL_EXCM_LEVEL #define XTENSA_FAKE_NMI (LOCKLEVEL < TOPLEVEL) @@ -132,11 +130,10 @@ struct thread_struct { unsigned long bad_vaddr; /* last user fault */ unsigned long bad_uaddr; /* last kernel fault accessing user space */ unsigned long error_code; - - unsigned long ibreak[XCHAL_NUM_IBREAK]; - unsigned long dbreaka[XCHAL_NUM_DBREAK]; - unsigned long dbreakc[XCHAL_NUM_DBREAK]; - +#ifdef CONFIG_HAVE_HW_BREAKPOINT + struct perf_event *ptrace_bp[XCHAL_NUM_IBREAK]; + struct perf_event *ptrace_wp[XCHAL_NUM_DBREAK]; +#endif /* Make structure 16 bytes aligned. */ int align[0] __attribute__ ((aligned(16))); }; diff --git a/arch/xtensa/include/asm/regs.h b/arch/xtensa/include/asm/regs.h index 4ba9f516b0e27b934e174592b8ad0653c7af62ac..881a1134a4b40f1838822518be9d463eec33df67 100644 --- a/arch/xtensa/include/asm/regs.h +++ b/arch/xtensa/include/asm/regs.h @@ -28,6 +28,7 @@ /* Special registers. */ #define SREG_MR 32 +#define SREG_IBREAKENABLE 96 #define SREG_IBREAKA 128 #define SREG_DBREAKA 144 #define SREG_DBREAKC 160 @@ -103,6 +104,8 @@ /* DEBUGCAUSE register fields. */ +#define DEBUGCAUSE_DBNUM_MASK 0xf00 +#define DEBUGCAUSE_DBNUM_SHIFT 8 /* First bit of DBNUM field */ #define DEBUGCAUSE_DEBUGINT_BIT 5 /* External debug interrupt */ #define DEBUGCAUSE_BREAKN_BIT 4 /* BREAK.N instruction */ #define DEBUGCAUSE_BREAK_BIT 3 /* BREAK instruction */ diff --git a/arch/xtensa/include/asm/thread_info.h b/arch/xtensa/include/asm/thread_info.h index 9ad12c6171842513d0df4a6dd31de0666a31cbfc..7be2400f745a088d553bbbdf6c2cc232fc1d18a0 100644 --- a/arch/xtensa/include/asm/thread_info.h +++ b/arch/xtensa/include/asm/thread_info.h @@ -111,6 +111,7 @@ static inline struct thread_info *current_thread_info(void) #define TIF_MEMDIE 5 /* is terminating due to OOM killer */ #define TIF_RESTORE_SIGMASK 6 /* restore signal mask in do_signal() */ #define TIF_NOTIFY_RESUME 7 /* callback before returning to user */ +#define TIF_DB_DISABLED 8 /* debug trap disabled for syscall */ #define _TIF_SYSCALL_TRACE (1< #include -#define _INTLEVEL(x) XCHAL_INT ## x ## _LEVEL -#define INTLEVEL(x) _INTLEVEL(x) - #if XCHAL_NUM_TIMERS > 0 && \ - INTLEVEL(XCHAL_TIMER0_INTERRUPT) <= XCHAL_EXCM_LEVEL + XTENSA_INT_LEVEL(XCHAL_TIMER0_INTERRUPT) <= XCHAL_EXCM_LEVEL # define LINUX_TIMER 0 # define LINUX_TIMER_INT XCHAL_TIMER0_INTERRUPT #elif XCHAL_NUM_TIMERS > 1 && \ - INTLEVEL(XCHAL_TIMER1_INTERRUPT) <= XCHAL_EXCM_LEVEL + XTENSA_INT_LEVEL(XCHAL_TIMER1_INTERRUPT) <= XCHAL_EXCM_LEVEL # define LINUX_TIMER 1 # define LINUX_TIMER_INT XCHAL_TIMER1_INTERRUPT #elif XCHAL_NUM_TIMERS > 2 && \ - INTLEVEL(XCHAL_TIMER2_INTERRUPT) <= XCHAL_EXCM_LEVEL + XTENSA_INT_LEVEL(XCHAL_TIMER2_INTERRUPT) <= XCHAL_EXCM_LEVEL # define LINUX_TIMER 2 # define LINUX_TIMER_INT XCHAL_TIMER2_INTERRUPT #else diff --git a/arch/xtensa/include/asm/traps.h b/arch/xtensa/include/asm/traps.h index 28f33a8b7f5f5b5b70d7d2f6cb6c0533bdc80a05..2e69aa4b843f605146d8e35ebb59f80d20a9598f 100644 --- a/arch/xtensa/include/asm/traps.h +++ b/arch/xtensa/include/asm/traps.h @@ -65,4 +65,21 @@ static inline void spill_registers(void) #endif } +struct debug_table { + /* Pointer to debug exception handler */ + void (*debug_exception)(void); + /* Temporary register save area */ + unsigned long debug_save[1]; +#ifdef CONFIG_HAVE_HW_BREAKPOINT + /* Save area for DBREAKC registers */ + unsigned long dbreakc_save[XCHAL_NUM_DBREAK]; + /* Saved ICOUNT register */ + unsigned long icount_save; + /* Saved ICOUNTLEVEL register */ + unsigned long icount_level_save; +#endif +}; + +void debug_exception(void); + #endif /* _XTENSA_TRAPS_H */ diff --git a/arch/xtensa/include/uapi/asm/ptrace.h b/arch/xtensa/include/uapi/asm/ptrace.h index ee17aa842fdffcba25859f6067e927685bdc3985..6ccbd9e38e3516e6f89f70518bf2a43aa4657985 100644 --- a/arch/xtensa/include/uapi/asm/ptrace.h +++ b/arch/xtensa/include/uapi/asm/ptrace.h @@ -72,6 +72,8 @@ #define PTRACE_SETREGS 13 #define PTRACE_GETXTREGS 18 #define PTRACE_SETXTREGS 19 +#define PTRACE_GETHBPREGS 20 +#define PTRACE_SETHBPREGS 21 #endif /* _UAPI_XTENSA_PTRACE_H */ diff --git a/arch/xtensa/include/uapi/asm/socket.h b/arch/xtensa/include/uapi/asm/socket.h index fd3b96d1153fdf04e8813f1612a4ad7903fae574..81435d995e1183d07ed0aac8903503e174a5c21e 100644 --- a/arch/xtensa/include/uapi/asm/socket.h +++ b/arch/xtensa/include/uapi/asm/socket.h @@ -99,4 +99,6 @@ #define SO_ATTACH_REUSEPORT_CBPF 51 #define SO_ATTACH_REUSEPORT_EBPF 52 +#define SO_CNX_ADVICE 53 + #endif /* _XTENSA_SOCKET_H */ diff --git a/arch/xtensa/kernel/Makefile b/arch/xtensa/kernel/Makefile index 4db730290d2ddc7bbf373b10b441c177017bfaf8..c31f5d5afc7d2d969a2a0c532e9f91a4395ba49d 100644 --- a/arch/xtensa/kernel/Makefile +++ b/arch/xtensa/kernel/Makefile @@ -8,12 +8,12 @@ obj-y := align.o coprocessor.o entry.o irq.o pci-dma.o platform.o process.o \ ptrace.o setup.o signal.o stacktrace.o syscall.o time.o traps.o \ vectors.o -obj-$(CONFIG_KGDB) += xtensa-stub.o obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_MODULES) += xtensa_ksyms.o module.o obj-$(CONFIG_FUNCTION_TRACER) += mcount.o obj-$(CONFIG_SMP) += smp.o mxhead.o obj-$(CONFIG_XTENSA_VARIANT_HAVE_PERF_EVENTS) += perf_event.o +obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o AFLAGS_head.o += -mtext-section-literals AFLAGS_mxhead.o += -mtext-section-literals diff --git a/arch/xtensa/kernel/asm-offsets.c b/arch/xtensa/kernel/asm-offsets.c index b123ace3b67c7651c1e25505a5649e45be3fe874..8e10e357ee329bcd6cdafcd2e34bddc3ddd3e02c 100644 --- a/arch/xtensa/kernel/asm-offsets.c +++ b/arch/xtensa/kernel/asm-offsets.c @@ -23,6 +23,7 @@ #include #include +#include #include int main(void) @@ -117,5 +118,16 @@ int main(void) DEFINE(_CLONE_UNTRACED, CLONE_UNTRACED); DEFINE(PG_ARCH_1, PG_arch_1); + /* struct debug_table */ + DEFINE(DT_DEBUG_EXCEPTION, + offsetof(struct debug_table, debug_exception)); + DEFINE(DT_DEBUG_SAVE, offsetof(struct debug_table, debug_save)); +#ifdef CONFIG_HAVE_HW_BREAKPOINT + DEFINE(DT_DBREAKC_SAVE, offsetof(struct debug_table, dbreakc_save)); + DEFINE(DT_ICOUNT_SAVE, offsetof(struct debug_table, icount_save)); + DEFINE(DT_ICOUNT_LEVEL_SAVE, + offsetof(struct debug_table, icount_level_save)); +#endif + return 0; } diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index db5c1765b413745fa5cc876adb2e4468f7770439..fe8f7e7efb9dc180c12bcfa0cedb6f4d0f59366f 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S @@ -543,6 +543,12 @@ common_exception_return: #endif 5: +#ifdef CONFIG_HAVE_HW_BREAKPOINT + _bbci.l a4, TIF_DB_DISABLED, 7f + movi a4, restore_dbreak + callx4 a4 +7: +#endif #ifdef CONFIG_DEBUG_TLB_SANITY l32i a4, a1, PT_DEPC bgeui a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 4f @@ -789,39 +795,99 @@ ENTRY(debug_exception) movi a2, 1 << PS_EXCM_BIT or a2, a0, a2 - movi a0, debug_exception # restore a3, debug jump vector wsr a2, ps - xsr a0, SREG_EXCSAVE + XCHAL_DEBUGLEVEL /* Switch to kernel/user stack, restore jump vector, and save a0 */ bbsi.l a2, PS_UM_BIT, 2f # jump if user mode addi a2, a1, -16-PT_SIZE # assume kernel stack +3: + l32i a0, a3, DT_DEBUG_SAVE + s32i a1, a2, PT_AREG1 s32i a0, a2, PT_AREG0 movi a0, 0 - s32i a1, a2, PT_AREG1 s32i a0, a2, PT_DEPC # mark it as a regular exception + xsr a3, SREG_EXCSAVE + XCHAL_DEBUGLEVEL xsr a0, depc s32i a3, a2, PT_AREG3 s32i a0, a2, PT_AREG2 mov a1, a2 + + /* Debug exception is handled as an exception, so interrupts will + * likely be enabled in the common exception handler. Disable + * preemption if we have HW breakpoints to preserve DEBUGCAUSE.DBNUM + * meaning. + */ +#if defined(CONFIG_PREEMPT_COUNT) && defined(CONFIG_HAVE_HW_BREAKPOINT) + GET_THREAD_INFO(a2, a1) + l32i a3, a2, TI_PRE_COUNT + addi a3, a3, 1 + s32i a3, a2, TI_PRE_COUNT +#endif + + rsr a2, ps + bbsi.l a2, PS_UM_BIT, _user_exception j _kernel_exception 2: rsr a2, excsave1 l32i a2, a2, EXC_TABLE_KSTK # load kernel stack pointer - s32i a0, a2, PT_AREG0 + j 3b + +#ifdef CONFIG_HAVE_HW_BREAKPOINT + /* Debug exception while in exception mode. This may happen when + * window overflow/underflow handler or fast exception handler hits + * data breakpoint, in which case save and disable all data + * breakpoints, single-step faulting instruction and restore data + * breakpoints. + */ +1: + bbci.l a0, PS_UM_BIT, 1b # jump if kernel mode + + rsr a0, debugcause + bbsi.l a0, DEBUGCAUSE_DBREAK_BIT, .Ldebug_save_dbreak + + .set _index, 0 + .rept XCHAL_NUM_DBREAK + l32i a0, a3, DT_DBREAKC_SAVE + _index * 4 + wsr a0, SREG_DBREAKC + _index + .set _index, _index + 1 + .endr + + l32i a0, a3, DT_ICOUNT_LEVEL_SAVE + wsr a0, icountlevel + + l32i a0, a3, DT_ICOUNT_SAVE + xsr a0, icount + + l32i a0, a3, DT_DEBUG_SAVE + xsr a3, SREG_EXCSAVE + XCHAL_DEBUGLEVEL + rfi XCHAL_DEBUGLEVEL + +.Ldebug_save_dbreak: + .set _index, 0 + .rept XCHAL_NUM_DBREAK movi a0, 0 - s32i a1, a2, PT_AREG1 - s32i a0, a2, PT_DEPC - xsr a0, depc - s32i a3, a2, PT_AREG3 - s32i a0, a2, PT_AREG2 - mov a1, a2 - j _user_exception + xsr a0, SREG_DBREAKC + _index + s32i a0, a3, DT_DBREAKC_SAVE + _index * 4 + .set _index, _index + 1 + .endr - /* Debug exception while in exception mode. */ + movi a0, XCHAL_EXCM_LEVEL + 1 + xsr a0, icountlevel + s32i a0, a3, DT_ICOUNT_LEVEL_SAVE + + movi a0, 0xfffffffe + xsr a0, icount + s32i a0, a3, DT_ICOUNT_SAVE + + l32i a0, a3, DT_DEBUG_SAVE + xsr a3, SREG_EXCSAVE + XCHAL_DEBUGLEVEL + rfi XCHAL_DEBUGLEVEL +#else + /* Debug exception while in exception mode. Should not happen. */ 1: j 1b // FIXME!! +#endif ENDPROC(debug_exception) diff --git a/arch/xtensa/kernel/head.S b/arch/xtensa/kernel/head.S index 9ed55649ac8ef1d8e6befae8f5d50498f6f5f35b..bc4f4bf050999d7694a711341d5fe75800896e7f 100644 --- a/arch/xtensa/kernel/head.S +++ b/arch/xtensa/kernel/head.S @@ -128,7 +128,7 @@ ENTRY(_startup) wsr a0, icountlevel .set _index, 0 - .rept XCHAL_NUM_DBREAK - 1 + .rept XCHAL_NUM_DBREAK wsr a0, SREG_DBREAKC + _index .set _index, _index + 1 .endr @@ -197,11 +197,6 @@ ENTRY(_startup) wsr a2, ps # (enable reg-windows; progmode stack) rsync - /* Set up EXCSAVE[DEBUGLEVEL] to point to the Debug Exception Handler.*/ - - movi a2, debug_exception - wsr a2, SREG_EXCSAVE + XCHAL_DEBUGLEVEL - #ifdef CONFIG_SMP /* * Notice that we assume with SMP that cores have PRID diff --git a/arch/xtensa/kernel/hw_breakpoint.c b/arch/xtensa/kernel/hw_breakpoint.c new file mode 100644 index 0000000000000000000000000000000000000000..b35656ab7dbd184ba4bb099c9f716ea4b7ee9657 --- /dev/null +++ b/arch/xtensa/kernel/hw_breakpoint.c @@ -0,0 +1,317 @@ +/* + * Xtensa hardware breakpoints/watchpoints handling functions + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2016 Cadence Design Systems Inc. + */ + +#include +#include +#include +#include +#include + +/* Breakpoint currently in use for each IBREAKA. */ +static DEFINE_PER_CPU(struct perf_event *, bp_on_reg[XCHAL_NUM_IBREAK]); + +/* Watchpoint currently in use for each DBREAKA. */ +static DEFINE_PER_CPU(struct perf_event *, wp_on_reg[XCHAL_NUM_DBREAK]); + +int hw_breakpoint_slots(int type) +{ + switch (type) { + case TYPE_INST: + return XCHAL_NUM_IBREAK; + case TYPE_DATA: + return XCHAL_NUM_DBREAK; + default: + pr_warn("unknown slot type: %d\n", type); + return 0; + } +} + +int arch_check_bp_in_kernelspace(struct perf_event *bp) +{ + unsigned int len; + unsigned long va; + struct arch_hw_breakpoint *info = counter_arch_bp(bp); + + va = info->address; + len = bp->attr.bp_len; + + return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE); +} + +/* + * Construct an arch_hw_breakpoint from a perf_event. + */ +static int arch_build_bp_info(struct perf_event *bp) +{ + struct arch_hw_breakpoint *info = counter_arch_bp(bp); + + /* Type */ + switch (bp->attr.bp_type) { + case HW_BREAKPOINT_X: + info->type = XTENSA_BREAKPOINT_EXECUTE; + break; + case HW_BREAKPOINT_R: + info->type = XTENSA_BREAKPOINT_LOAD; + break; + case HW_BREAKPOINT_W: + info->type = XTENSA_BREAKPOINT_STORE; + break; + case HW_BREAKPOINT_RW: + info->type = XTENSA_BREAKPOINT_LOAD | XTENSA_BREAKPOINT_STORE; + break; + default: + return -EINVAL; + } + + /* Len */ + info->len = bp->attr.bp_len; + if (info->len < 1 || info->len > 64 || !is_power_of_2(info->len)) + return -EINVAL; + + /* Address */ + info->address = bp->attr.bp_addr; + if (info->address & (info->len - 1)) + return -EINVAL; + + return 0; +} + +int arch_validate_hwbkpt_settings(struct perf_event *bp) +{ + int ret; + + /* Build the arch_hw_breakpoint. */ + ret = arch_build_bp_info(bp); + return ret; +} + +int hw_breakpoint_exceptions_notify(struct notifier_block *unused, + unsigned long val, void *data) +{ + return NOTIFY_DONE; +} + +static void xtensa_wsr(unsigned long v, u8 sr) +{ + /* We don't have indexed wsr and creating instruction dynamically + * doesn't seem worth it given how small XCHAL_NUM_IBREAK and + * XCHAL_NUM_DBREAK are. Thus the switch. In case build breaks here + * the switch below needs to be extended. + */ + BUILD_BUG_ON(XCHAL_NUM_IBREAK > 2); + BUILD_BUG_ON(XCHAL_NUM_DBREAK > 2); + + switch (sr) { +#if XCHAL_NUM_IBREAK > 0 + case SREG_IBREAKA + 0: + WSR(v, SREG_IBREAKA + 0); + break; +#endif +#if XCHAL_NUM_IBREAK > 1 + case SREG_IBREAKA + 1: + WSR(v, SREG_IBREAKA + 1); + break; +#endif + +#if XCHAL_NUM_DBREAK > 0 + case SREG_DBREAKA + 0: + WSR(v, SREG_DBREAKA + 0); + break; + case SREG_DBREAKC + 0: + WSR(v, SREG_DBREAKC + 0); + break; +#endif +#if XCHAL_NUM_DBREAK > 1 + case SREG_DBREAKA + 1: + WSR(v, SREG_DBREAKA + 1); + break; + + case SREG_DBREAKC + 1: + WSR(v, SREG_DBREAKC + 1); + break; +#endif + } +} + +static int alloc_slot(struct perf_event **slot, size_t n, + struct perf_event *bp) +{ + size_t i; + + for (i = 0; i < n; ++i) { + if (!slot[i]) { + slot[i] = bp; + return i; + } + } + return -EBUSY; +} + +static void set_ibreak_regs(int reg, struct perf_event *bp) +{ + struct arch_hw_breakpoint *info = counter_arch_bp(bp); + unsigned long ibreakenable; + + xtensa_wsr(info->address, SREG_IBREAKA + reg); + RSR(ibreakenable, SREG_IBREAKENABLE); + WSR(ibreakenable | (1 << reg), SREG_IBREAKENABLE); +} + +static void set_dbreak_regs(int reg, struct perf_event *bp) +{ + struct arch_hw_breakpoint *info = counter_arch_bp(bp); + unsigned long dbreakc = DBREAKC_MASK_MASK & -info->len; + + if (info->type & XTENSA_BREAKPOINT_LOAD) + dbreakc |= DBREAKC_LOAD_MASK; + if (info->type & XTENSA_BREAKPOINT_STORE) + dbreakc |= DBREAKC_STOR_MASK; + + xtensa_wsr(info->address, SREG_DBREAKA + reg); + xtensa_wsr(dbreakc, SREG_DBREAKC + reg); +} + +int arch_install_hw_breakpoint(struct perf_event *bp) +{ + int i; + + if (counter_arch_bp(bp)->type == XTENSA_BREAKPOINT_EXECUTE) { + /* Breakpoint */ + i = alloc_slot(this_cpu_ptr(bp_on_reg), XCHAL_NUM_IBREAK, bp); + if (i < 0) + return i; + set_ibreak_regs(i, bp); + + } else { + /* Watchpoint */ + i = alloc_slot(this_cpu_ptr(wp_on_reg), XCHAL_NUM_DBREAK, bp); + if (i < 0) + return i; + set_dbreak_regs(i, bp); + } + return 0; +} + +static int free_slot(struct perf_event **slot, size_t n, + struct perf_event *bp) +{ + size_t i; + + for (i = 0; i < n; ++i) { + if (slot[i] == bp) { + slot[i] = NULL; + return i; + } + } + return -EBUSY; +} + +void arch_uninstall_hw_breakpoint(struct perf_event *bp) +{ + struct arch_hw_breakpoint *info = counter_arch_bp(bp); + int i; + + if (info->type == XTENSA_BREAKPOINT_EXECUTE) { + unsigned long ibreakenable; + + /* Breakpoint */ + i = free_slot(this_cpu_ptr(bp_on_reg), XCHAL_NUM_IBREAK, bp); + if (i >= 0) { + RSR(ibreakenable, SREG_IBREAKENABLE); + WSR(ibreakenable & ~(1 << i), SREG_IBREAKENABLE); + } + } else { + /* Watchpoint */ + i = free_slot(this_cpu_ptr(wp_on_reg), XCHAL_NUM_DBREAK, bp); + if (i >= 0) + xtensa_wsr(0, SREG_DBREAKC + i); + } +} + +void hw_breakpoint_pmu_read(struct perf_event *bp) +{ +} + +void flush_ptrace_hw_breakpoint(struct task_struct *tsk) +{ + int i; + struct thread_struct *t = &tsk->thread; + + for (i = 0; i < XCHAL_NUM_IBREAK; ++i) { + if (t->ptrace_bp[i]) { + unregister_hw_breakpoint(t->ptrace_bp[i]); + t->ptrace_bp[i] = NULL; + } + } + for (i = 0; i < XCHAL_NUM_DBREAK; ++i) { + if (t->ptrace_wp[i]) { + unregister_hw_breakpoint(t->ptrace_wp[i]); + t->ptrace_wp[i] = NULL; + } + } +} + +/* + * Set ptrace breakpoint pointers to zero for this task. + * This is required in order to prevent child processes from unregistering + * breakpoints held by their parent. + */ +void clear_ptrace_hw_breakpoint(struct task_struct *tsk) +{ + memset(tsk->thread.ptrace_bp, 0, sizeof(tsk->thread.ptrace_bp)); + memset(tsk->thread.ptrace_wp, 0, sizeof(tsk->thread.ptrace_wp)); +} + +void restore_dbreak(void) +{ + int i; + + for (i = 0; i < XCHAL_NUM_DBREAK; ++i) { + struct perf_event *bp = this_cpu_ptr(wp_on_reg)[i]; + + if (bp) + set_dbreak_regs(i, bp); + } + clear_thread_flag(TIF_DB_DISABLED); +} + +int check_hw_breakpoint(struct pt_regs *regs) +{ + if (regs->debugcause & BIT(DEBUGCAUSE_IBREAK_BIT)) { + int i; + struct perf_event **bp = this_cpu_ptr(bp_on_reg); + + for (i = 0; i < XCHAL_NUM_IBREAK; ++i) { + if (bp[i] && !bp[i]->attr.disabled && + regs->pc == bp[i]->attr.bp_addr) + perf_bp_event(bp[i], regs); + } + return 0; + } else if (regs->debugcause & BIT(DEBUGCAUSE_DBREAK_BIT)) { + struct perf_event **bp = this_cpu_ptr(wp_on_reg); + int dbnum = (regs->debugcause & DEBUGCAUSE_DBNUM_MASK) >> + DEBUGCAUSE_DBNUM_SHIFT; + + if (dbnum < XCHAL_NUM_DBREAK && bp[dbnum]) { + if (user_mode(regs)) { + perf_bp_event(bp[dbnum], regs); + } else { + set_thread_flag(TIF_DB_DISABLED); + xtensa_wsr(0, SREG_DBREAKC + dbnum); + } + } else { + WARN_ONCE(1, + "Wrong/unconfigured DBNUM reported in DEBUGCAUSE: %d\n", + dbnum); + } + return 0; + } + return -ENOENT; +} diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c index 1c85323f01d7de73c2781b4b8b295ac98ceb6cb9..5bbfed81c97be65eef96a68935a6c5fc672c2087 100644 --- a/arch/xtensa/kernel/process.c +++ b/arch/xtensa/kernel/process.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -43,6 +44,7 @@ #include #include #include +#include extern void ret_from_fork(void); extern void ret_from_kernel_thread(void); @@ -131,6 +133,7 @@ void flush_thread(void) coprocessor_flush_all(ti); coprocessor_release_all(ti); #endif + flush_ptrace_hw_breakpoint(current); } /* @@ -273,6 +276,8 @@ int copy_thread(unsigned long clone_flags, unsigned long usp_thread_fn, ti->cpenable = 0; #endif + clear_ptrace_hw_breakpoint(p); + return 0; } diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c index 4d54b481123b64e286f45f6fc03121a0d5024474..a651f3a628eec0b4708d34d4f736192c344bd5b6 100644 --- a/arch/xtensa/kernel/ptrace.c +++ b/arch/xtensa/kernel/ptrace.c @@ -13,21 +13,23 @@ * Marc Gauthier */ +#include +#include #include -#include #include -#include +#include #include -#include +#include #include #include +#include -#include +#include +#include #include -#include +#include #include -#include -#include +#include void user_enable_single_step(struct task_struct *child) @@ -267,6 +269,146 @@ int ptrace_pokeusr(struct task_struct *child, long regno, long val) return 0; } +#ifdef CONFIG_HAVE_HW_BREAKPOINT +static void ptrace_hbptriggered(struct perf_event *bp, + struct perf_sample_data *data, + struct pt_regs *regs) +{ + int i; + siginfo_t info; + struct arch_hw_breakpoint *bkpt = counter_arch_bp(bp); + + if (bp->attr.bp_type & HW_BREAKPOINT_X) { + for (i = 0; i < XCHAL_NUM_IBREAK; ++i) + if (current->thread.ptrace_bp[i] == bp) + break; + i <<= 1; + } else { + for (i = 0; i < XCHAL_NUM_DBREAK; ++i) + if (current->thread.ptrace_wp[i] == bp) + break; + i = (i << 1) | 1; + } + + info.si_signo = SIGTRAP; + info.si_errno = i; + info.si_code = TRAP_HWBKPT; + info.si_addr = (void __user *)bkpt->address; + + force_sig_info(SIGTRAP, &info, current); +} + +static struct perf_event *ptrace_hbp_create(struct task_struct *tsk, int type) +{ + struct perf_event_attr attr; + + ptrace_breakpoint_init(&attr); + + /* Initialise fields to sane defaults. */ + attr.bp_addr = 0; + attr.bp_len = 1; + attr.bp_type = type; + attr.disabled = 1; + + return register_user_hw_breakpoint(&attr, ptrace_hbptriggered, NULL, + tsk); +} + +/* + * Address bit 0 choose instruction (0) or data (1) break register, bits + * 31..1 are the register number. + * Both PTRACE_GETHBPREGS and PTRACE_SETHBPREGS transfer two 32-bit words: + * address (0) and control (1). + * Instruction breakpoint contorl word is 0 to clear breakpoint, 1 to set. + * Data breakpoint control word bit 31 is 'trigger on store', bit 30 is + * 'trigger on load, bits 29..0 are length. Length 0 is used to clear a + * breakpoint. To set a breakpoint length must be a power of 2 in the range + * 1..64 and the address must be length-aligned. + */ + +static long ptrace_gethbpregs(struct task_struct *child, long addr, + long __user *datap) +{ + struct perf_event *bp; + u32 user_data[2] = {0}; + bool dbreak = addr & 1; + unsigned idx = addr >> 1; + + if ((!dbreak && idx >= XCHAL_NUM_IBREAK) || + (dbreak && idx >= XCHAL_NUM_DBREAK)) + return -EINVAL; + + if (dbreak) + bp = child->thread.ptrace_wp[idx]; + else + bp = child->thread.ptrace_bp[idx]; + + if (bp) { + user_data[0] = bp->attr.bp_addr; + user_data[1] = bp->attr.disabled ? 0 : bp->attr.bp_len; + if (dbreak) { + if (bp->attr.bp_type & HW_BREAKPOINT_R) + user_data[1] |= DBREAKC_LOAD_MASK; + if (bp->attr.bp_type & HW_BREAKPOINT_W) + user_data[1] |= DBREAKC_STOR_MASK; + } + } + + if (copy_to_user(datap, user_data, sizeof(user_data))) + return -EFAULT; + + return 0; +} + +static long ptrace_sethbpregs(struct task_struct *child, long addr, + long __user *datap) +{ + struct perf_event *bp; + struct perf_event_attr attr; + u32 user_data[2]; + bool dbreak = addr & 1; + unsigned idx = addr >> 1; + int bp_type = 0; + + if ((!dbreak && idx >= XCHAL_NUM_IBREAK) || + (dbreak && idx >= XCHAL_NUM_DBREAK)) + return -EINVAL; + + if (copy_from_user(user_data, datap, sizeof(user_data))) + return -EFAULT; + + if (dbreak) { + bp = child->thread.ptrace_wp[idx]; + if (user_data[1] & DBREAKC_LOAD_MASK) + bp_type |= HW_BREAKPOINT_R; + if (user_data[1] & DBREAKC_STOR_MASK) + bp_type |= HW_BREAKPOINT_W; + } else { + bp = child->thread.ptrace_bp[idx]; + bp_type = HW_BREAKPOINT_X; + } + + if (!bp) { + bp = ptrace_hbp_create(child, + bp_type ? bp_type : HW_BREAKPOINT_RW); + if (IS_ERR(bp)) + return PTR_ERR(bp); + if (dbreak) + child->thread.ptrace_wp[idx] = bp; + else + child->thread.ptrace_bp[idx] = bp; + } + + attr = bp->attr; + attr.bp_addr = user_data[0]; + attr.bp_len = user_data[1] & ~(DBREAKC_LOAD_MASK | DBREAKC_STOR_MASK); + attr.bp_type = bp_type; + attr.disabled = !attr.bp_len; + + return modify_user_hw_breakpoint(bp, &attr); +} +#endif + long arch_ptrace(struct task_struct *child, long request, unsigned long addr, unsigned long data) { @@ -307,7 +449,15 @@ long arch_ptrace(struct task_struct *child, long request, case PTRACE_SETXTREGS: ret = ptrace_setxregs(child, datap); break; +#ifdef CONFIG_HAVE_HW_BREAKPOINT + case PTRACE_GETHBPREGS: + ret = ptrace_gethbpregs(child, addr, datap); + break; + case PTRACE_SETHBPREGS: + ret = ptrace_sethbpregs(child, addr, datap); + break; +#endif default: ret = ptrace_request(child, request, addr, data); break; diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c index 42d441f7898b94db35e3a2cd55af500f23f6435a..d02fc304b31c10ea9019172b8fd15d8aaea41bdc 100644 --- a/arch/xtensa/kernel/traps.c +++ b/arch/xtensa/kernel/traps.c @@ -39,11 +39,7 @@ #include #include #include - -#ifdef CONFIG_KGDB -extern int gdb_enter; -extern int return_from_debug_flag; -#endif +#include /* * Machine specific interrupt handlers @@ -162,6 +158,8 @@ COPROCESSOR(7), DEFINE_PER_CPU(unsigned long, exc_table[EXC_TABLE_SIZE/4]); +DEFINE_PER_CPU(struct debug_table, debug_table); + void die(const char*, struct pt_regs*, long); static inline void @@ -205,6 +203,32 @@ extern void do_IRQ(int, struct pt_regs *); #if XTENSA_FAKE_NMI +#define IS_POW2(v) (((v) & ((v) - 1)) == 0) + +#if !(PROFILING_INTLEVEL == XCHAL_EXCM_LEVEL && \ + IS_POW2(XTENSA_INTLEVEL_MASK(PROFILING_INTLEVEL))) +#warning "Fake NMI is requested for PMM, but there are other IRQs at or above its level." +#warning "Fake NMI will be used, but there will be a bugcheck if one of those IRQs fire." + +static inline void check_valid_nmi(void) +{ + unsigned intread = get_sr(interrupt); + unsigned intenable = get_sr(intenable); + + BUG_ON(intread & intenable & + ~(XTENSA_INTLEVEL_ANDBELOW_MASK(PROFILING_INTLEVEL) ^ + XTENSA_INTLEVEL_MASK(PROFILING_INTLEVEL) ^ + BIT(XCHAL_PROFILING_INTERRUPT))); +} + +#else + +static inline void check_valid_nmi(void) +{ +} + +#endif + irqreturn_t xtensa_pmu_irq_handler(int irq, void *dev_id); DEFINE_PER_CPU(unsigned long, nmi_count); @@ -219,6 +243,7 @@ void do_nmi(struct pt_regs *regs) old_regs = set_irq_regs(regs); nmi_enter(); ++*this_cpu_ptr(&nmi_count); + check_valid_nmi(); xtensa_pmu_irq_handler(0, NULL); nmi_exit(); set_irq_regs(old_regs); @@ -314,23 +339,22 @@ do_unaligned_user (struct pt_regs *regs) } #endif +/* Handle debug events. + * When CONFIG_HAVE_HW_BREAKPOINT is on this handler is called with + * preemption disabled to avoid rescheduling and keep mapping of hardware + * breakpoint structures to debug registers intact, so that + * DEBUGCAUSE.DBNUM could be used in case of data breakpoint hit. + */ void do_debug(struct pt_regs *regs) { -#ifdef CONFIG_KGDB - /* If remote debugging is configured AND enabled, we give control to - * kgdb. Otherwise, we fall through, perhaps giving control to the - * native debugger. - */ - - if (gdb_enter) { - extern void gdb_handle_exception(struct pt_regs *); - gdb_handle_exception(regs); - return_from_debug_flag = 1; +#ifdef CONFIG_HAVE_HW_BREAKPOINT + int ret = check_hw_breakpoint(regs); + + preempt_enable(); + if (ret == 0) return; - } #endif - __die_if_kernel("Breakpoint in kernel", regs, SIGKILL); /* If in user mode, send SIGTRAP signal to current process */ @@ -364,6 +388,15 @@ static void trap_init_excsave(void) __asm__ __volatile__("wsr %0, excsave1\n" : : "a" (excsave1)); } +static void trap_init_debug(void) +{ + unsigned long debugsave = (unsigned long)this_cpu_ptr(&debug_table); + + this_cpu_ptr(&debug_table)->debug_exception = debug_exception; + __asm__ __volatile__("wsr %0, excsave" __stringify(XCHAL_DEBUGLEVEL) + :: "a"(debugsave)); +} + /* * Initialize dispatch tables. * @@ -407,12 +440,14 @@ void __init trap_init(void) /* Initialize EXCSAVE_1 to hold the address of the exception table. */ trap_init_excsave(); + trap_init_debug(); } #ifdef CONFIG_SMP void secondary_trap_init(void) { trap_init_excsave(); + trap_init_debug(); } #endif diff --git a/arch/xtensa/kernel/vectors.S b/arch/xtensa/kernel/vectors.S index fc25318e75ad032cb2bd108845aa5a77e24e14e5..332e9d635fb6f07a21855f215ab55435ae24e6c5 100644 --- a/arch/xtensa/kernel/vectors.S +++ b/arch/xtensa/kernel/vectors.S @@ -601,7 +601,9 @@ ENDPROC(window_overflow_restore_a0_fixup) ENTRY(_DebugInterruptVector) - xsr a0, SREG_EXCSAVE + XCHAL_DEBUGLEVEL + xsr a3, SREG_EXCSAVE + XCHAL_DEBUGLEVEL + s32i a0, a3, DT_DEBUG_SAVE + l32i a0, a3, DT_DEBUG_EXCEPTION jx a0 ENDPROC(_DebugInterruptVector) diff --git a/arch/xtensa/mm/Makefile b/arch/xtensa/mm/Makefile index e601e2fbe8e6ebadc109a1c2754f6a47ce64f1c2..0b3d296a016a38cd1373588e52a1623b14833403 100644 --- a/arch/xtensa/mm/Makefile +++ b/arch/xtensa/mm/Makefile @@ -3,5 +3,5 @@ # obj-y := init.o misc.o -obj-$(CONFIG_MMU) += cache.o fault.o mmu.o tlb.o +obj-$(CONFIG_MMU) += cache.o fault.o ioremap.o mmu.o tlb.o obj-$(CONFIG_HIGHMEM) += highmem.o diff --git a/arch/xtensa/mm/cache.c b/arch/xtensa/mm/cache.c index d75aa1476da7595d224c02576a8ee5fcb3fe716e..1a804a2f9a5be6212c57febc01f6d28f47b8c91a 100644 --- a/arch/xtensa/mm/cache.c +++ b/arch/xtensa/mm/cache.c @@ -97,11 +97,11 @@ void clear_user_highpage(struct page *page, unsigned long vaddr) unsigned long paddr; void *kvaddr = coherent_kvaddr(page, TLBTEMP_BASE_1, vaddr, &paddr); - pagefault_disable(); + preempt_disable(); kmap_invalidate_coherent(page, vaddr); set_bit(PG_arch_1, &page->flags); clear_page_alias(kvaddr, paddr); - pagefault_enable(); + preempt_enable(); } void copy_user_highpage(struct page *dst, struct page *src, @@ -113,11 +113,11 @@ void copy_user_highpage(struct page *dst, struct page *src, void *src_vaddr = coherent_kvaddr(src, TLBTEMP_BASE_2, vaddr, &src_paddr); - pagefault_disable(); + preempt_disable(); kmap_invalidate_coherent(dst, vaddr); set_bit(PG_arch_1, &dst->flags); copy_page_alias(dst_vaddr, src_vaddr, dst_paddr, src_paddr); - pagefault_enable(); + preempt_enable(); } #endif /* DCACHE_WAY_SIZE > PAGE_SIZE */ diff --git a/arch/xtensa/mm/fault.c b/arch/xtensa/mm/fault.c index c9784c1b18d8c6223afe359e4e4405b430b91780..7f4a1fdb1502005aa23431a5f36d568882f0aacf 100644 --- a/arch/xtensa/mm/fault.c +++ b/arch/xtensa/mm/fault.c @@ -146,7 +146,7 @@ void do_page_fault(struct pt_regs *regs) perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address); if (flags & VM_FAULT_MAJOR) perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, regs, address); - else if (flags & VM_FAULT_MINOR) + else perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, regs, address); return; diff --git a/arch/xtensa/mm/ioremap.c b/arch/xtensa/mm/ioremap.c new file mode 100644 index 0000000000000000000000000000000000000000..d89c3c5fd962de011c80f41e0e1ebf8cf3a221c6 --- /dev/null +++ b/arch/xtensa/mm/ioremap.c @@ -0,0 +1,68 @@ +/* + * ioremap implementation. + * + * Copyright (C) 2015 Cadence Design Systems 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 +#include +#include +#include +#include + +static void __iomem *xtensa_ioremap(unsigned long paddr, unsigned long size, + pgprot_t prot) +{ + unsigned long offset = paddr & ~PAGE_MASK; + unsigned long pfn = __phys_to_pfn(paddr); + struct vm_struct *area; + unsigned long vaddr; + int err; + + paddr &= PAGE_MASK; + + WARN_ON(pfn_valid(pfn)); + + size = PAGE_ALIGN(offset + size); + + area = get_vm_area(size, VM_IOREMAP); + if (!area) + return NULL; + + vaddr = (unsigned long)area->addr; + area->phys_addr = paddr; + + err = ioremap_page_range(vaddr, vaddr + size, paddr, prot); + + if (err) { + vunmap((void *)vaddr); + return NULL; + } + + flush_cache_vmap(vaddr, vaddr + size); + return (void __iomem *)(offset + vaddr); +} + +void __iomem *xtensa_ioremap_nocache(unsigned long addr, unsigned long size) +{ + return xtensa_ioremap(addr, size, pgprot_noncached(PAGE_KERNEL)); +} +EXPORT_SYMBOL(xtensa_ioremap_nocache); + +void __iomem *xtensa_ioremap_cache(unsigned long addr, unsigned long size) +{ + return xtensa_ioremap(addr, size, PAGE_KERNEL); +} +EXPORT_SYMBOL(xtensa_ioremap_cache); + +void xtensa_iounmap(volatile void __iomem *io_addr) +{ + void *addr = (void *)(PAGE_MASK & (unsigned long)io_addr); + + vunmap(addr); +} +EXPORT_SYMBOL(xtensa_iounmap); diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c index c54505dcf4db9b5e973fb9bbcd5e48b26c40c04d..c68f1e6158aa67901696d075336fae3d04b0803d 100644 --- a/arch/xtensa/platforms/iss/console.c +++ b/arch/xtensa/platforms/iss/console.c @@ -96,21 +96,23 @@ static void rs_poll(unsigned long priv) { struct tty_port *port = (struct tty_port *)priv; int i = 0; + int rd = 1; unsigned char c; spin_lock(&timer_lock); while (simc_poll(0)) { - simc_read(0, &c, 1); + rd = simc_read(0, &c, 1); + if (rd <= 0) + break; tty_insert_flip_char(port, c, TTY_NORMAL); i++; } if (i) tty_flip_buffer_push(port); - - - mod_timer(&serial_timer, jiffies + SERIAL_TIMER_VALUE); + if (rd) + mod_timer(&serial_timer, jiffies + SERIAL_TIMER_VALUE); spin_unlock(&timer_lock); } diff --git a/arch/xtensa/platforms/xtfpga/setup.c b/arch/xtensa/platforms/xtfpga/setup.c index e9f65f79cf2ea0bff6393313385bbebf500db9a3..b509d1f55ed5c2445f1bb4930b48a84c9d34edce 100644 --- a/arch/xtensa/platforms/xtfpga/setup.c +++ b/arch/xtensa/platforms/xtfpga/setup.c @@ -223,6 +223,7 @@ static struct ethoc_platform_data ethoc_pdata = { */ .hwaddr = { 0x00, 0x50, 0xc2, 0x13, 0x6f, 0 }, .phy_id = -1, + .big_endian = XCHAL_HAVE_BE, }; static struct platform_device ethoc_device = { @@ -283,7 +284,7 @@ static struct plat_serial8250_port serial_platform_data[] = { .irq = DUART16552_INTNUM, .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, - .iotype = UPIO_MEM32, + .iotype = XCHAL_HAVE_BE ? UPIO_MEM32BE : UPIO_MEM32, .regshift = 2, .uartclk = 0, /* set in xtavnet_init() */ }, diff --git a/arch/xtensa/variants/test_kc705_hifi/include/variant/core.h b/arch/xtensa/variants/test_kc705_hifi/include/variant/core.h new file mode 100644 index 0000000000000000000000000000000000000000..4a2222979f866b586a1c46e7b9213202c8f47b8e --- /dev/null +++ b/arch/xtensa/variants/test_kc705_hifi/include/variant/core.h @@ -0,0 +1,531 @@ +/* + * xtensa/config/core-isa.h -- HAL definitions that are dependent on Xtensa + * processor CORE configuration + * + * See , which includes this file, for more details. + */ + +/* Xtensa processor core configuration information. + + Copyright (c) 1999-2014 Tensilica Inc. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef _XTENSA_CORE_CONFIGURATION_H +#define _XTENSA_CORE_CONFIGURATION_H + + +/**************************************************************************** + Parameters Useful for Any Code, USER or PRIVILEGED + ****************************************************************************/ + +/* + * Note: Macros of the form XCHAL_HAVE_*** have a value of 1 if the option is + * configured, and a value of 0 otherwise. These macros are always defined. + */ + + +/*---------------------------------------------------------------------- + ISA + ----------------------------------------------------------------------*/ + +#define XCHAL_HAVE_BE 0 /* big-endian byte ordering */ +#define XCHAL_HAVE_WINDOWED 1 /* windowed registers option */ +#define XCHAL_NUM_AREGS 32 /* num of physical addr regs */ +#define XCHAL_NUM_AREGS_LOG2 5 /* log2(XCHAL_NUM_AREGS) */ +#define XCHAL_MAX_INSTRUCTION_SIZE 8 /* max instr bytes (3..8) */ +#define XCHAL_HAVE_DEBUG 1 /* debug option */ +#define XCHAL_HAVE_DENSITY 1 /* 16-bit instructions */ +#define XCHAL_HAVE_LOOPS 1 /* zero-overhead loops */ +#define XCHAL_LOOP_BUFFER_SIZE 0 /* zero-ov. loop instr buffer size */ +#define XCHAL_HAVE_NSA 1 /* NSA/NSAU instructions */ +#define XCHAL_HAVE_MINMAX 1 /* MIN/MAX instructions */ +#define XCHAL_HAVE_SEXT 1 /* SEXT instruction */ +#define XCHAL_HAVE_CLAMPS 1 /* CLAMPS instruction */ +#define XCHAL_HAVE_MUL16 1 /* MUL16S/MUL16U instructions */ +#define XCHAL_HAVE_MUL32 1 /* MULL instruction */ +#define XCHAL_HAVE_MUL32_HIGH 1 /* MULUH/MULSH instructions */ +#define XCHAL_HAVE_DIV32 1 /* QUOS/QUOU/REMS/REMU instructions */ +#define XCHAL_HAVE_L32R 1 /* L32R instruction */ +#define XCHAL_HAVE_ABSOLUTE_LITERALS 0 /* non-PC-rel (extended) L32R */ +#define XCHAL_HAVE_CONST16 0 /* CONST16 instruction */ +#define XCHAL_HAVE_ADDX 1 /* ADDX#/SUBX# instructions */ +#define XCHAL_HAVE_WIDE_BRANCHES 0 /* B*.W18 or B*.W15 instr's */ +#define XCHAL_HAVE_PREDICTED_BRANCHES 0 /* B[EQ/EQZ/NE/NEZ]T instr's */ +#define XCHAL_HAVE_CALL4AND12 1 /* (obsolete option) */ +#define XCHAL_HAVE_ABS 1 /* ABS instruction */ +/*#define XCHAL_HAVE_POPC 0*/ /* POPC instruction */ +/*#define XCHAL_HAVE_CRC 0*/ /* CRC instruction */ +#define XCHAL_HAVE_RELEASE_SYNC 1 /* L32AI/S32RI instructions */ +#define XCHAL_HAVE_S32C1I 1 /* S32C1I instruction */ +#define XCHAL_HAVE_SPECULATION 0 /* speculation */ +#define XCHAL_HAVE_FULL_RESET 1 /* all regs/state reset */ +#define XCHAL_NUM_CONTEXTS 1 /* */ +#define XCHAL_NUM_MISC_REGS 2 /* num of scratch regs (0..4) */ +#define XCHAL_HAVE_TAP_MASTER 0 /* JTAG TAP control instr's */ +#define XCHAL_HAVE_PRID 1 /* processor ID register */ +#define XCHAL_HAVE_EXTERN_REGS 1 /* WER/RER instructions */ +#define XCHAL_HAVE_MX 0 /* MX core (Tensilica internal) */ +#define XCHAL_HAVE_MP_INTERRUPTS 0 /* interrupt distributor port */ +#define XCHAL_HAVE_MP_RUNSTALL 0 /* core RunStall control port */ +#define XCHAL_HAVE_PSO 0 /* Power Shut-Off */ +#define XCHAL_HAVE_PSO_CDM 0 /* core/debug/mem pwr domains */ +#define XCHAL_HAVE_PSO_FULL_RETENTION 0 /* all regs preserved on PSO */ +#define XCHAL_HAVE_THREADPTR 1 /* THREADPTR register */ +#define XCHAL_HAVE_BOOLEANS 1 /* boolean registers */ +#define XCHAL_HAVE_CP 1 /* CPENABLE reg (coprocessor) */ +#define XCHAL_CP_MAXCFG 8 /* max allowed cp id plus one */ +#define XCHAL_HAVE_MAC16 1 /* MAC16 package */ +#define XCHAL_HAVE_VECTORFPU2005 0 /* vector floating-point pkg */ +#define XCHAL_HAVE_FP 0 /* single prec floating point */ +#define XCHAL_HAVE_FP_DIV 0 /* FP with DIV instructions */ +#define XCHAL_HAVE_FP_RECIP 0 /* FP with RECIP instructions */ +#define XCHAL_HAVE_FP_SQRT 0 /* FP with SQRT instructions */ +#define XCHAL_HAVE_FP_RSQRT 0 /* FP with RSQRT instructions */ +#define XCHAL_HAVE_DFP 0 /* double precision FP pkg */ +#define XCHAL_HAVE_DFP_DIV 0 /* DFP with DIV instructions */ +#define XCHAL_HAVE_DFP_RECIP 0 /* DFP with RECIP instructions*/ +#define XCHAL_HAVE_DFP_SQRT 0 /* DFP with SQRT instructions */ +#define XCHAL_HAVE_DFP_RSQRT 0 /* DFP with RSQRT instructions*/ +#define XCHAL_HAVE_DFP_accel 0 /* double precision FP acceleration pkg */ +#define XCHAL_HAVE_VECTRA1 0 /* Vectra I pkg */ +#define XCHAL_HAVE_VECTRALX 0 /* Vectra LX pkg */ +#define XCHAL_HAVE_HIFIPRO 0 /* HiFiPro Audio Engine pkg */ +#define XCHAL_HAVE_HIFI3 1 /* HiFi3 Audio Engine pkg */ +#define XCHAL_HAVE_HIFI2 0 /* HiFi2 Audio Engine pkg */ +#define XCHAL_HAVE_HIFI2EP 0 /* HiFi2EP */ +#define XCHAL_HAVE_HIFI_MINI 0 +#define XCHAL_HAVE_CONNXD2 0 /* ConnX D2 pkg */ +#define XCHAL_HAVE_BBE16 0 /* ConnX BBE16 pkg */ +#define XCHAL_HAVE_BBE16_RSQRT 0 /* BBE16 & vector recip sqrt */ +#define XCHAL_HAVE_BBE16_VECDIV 0 /* BBE16 & vector divide */ +#define XCHAL_HAVE_BBE16_DESPREAD 0 /* BBE16 & despread */ +#define XCHAL_HAVE_BBENEP 0 /* ConnX BBENEP pkgs */ +#define XCHAL_HAVE_BSP3 0 /* ConnX BSP3 pkg */ +#define XCHAL_HAVE_BSP3_TRANSPOSE 0 /* BSP3 & transpose32x32 */ +#define XCHAL_HAVE_SSP16 0 /* ConnX SSP16 pkg */ +#define XCHAL_HAVE_SSP16_VITERBI 0 /* SSP16 & viterbi */ +#define XCHAL_HAVE_TURBO16 0 /* ConnX Turbo16 pkg */ +#define XCHAL_HAVE_BBP16 0 /* ConnX BBP16 pkg */ +#define XCHAL_HAVE_FLIX3 0 /* basic 3-way FLIX option */ + + +/*---------------------------------------------------------------------- + MISC + ----------------------------------------------------------------------*/ + +#define XCHAL_NUM_LOADSTORE_UNITS 1 /* load/store units */ +#define XCHAL_NUM_WRITEBUFFER_ENTRIES 8 /* size of write buffer */ +#define XCHAL_INST_FETCH_WIDTH 8 /* instr-fetch width in bytes */ +#define XCHAL_DATA_WIDTH 8 /* data width in bytes */ +#define XCHAL_DATA_PIPE_DELAY 1 /* d-side pipeline delay + (1 = 5-stage, 2 = 7-stage) */ +/* In T1050, applies to selected core load and store instructions (see ISA): */ +#define XCHAL_UNALIGNED_LOAD_EXCEPTION 1 /* unaligned loads cause exc. */ +#define XCHAL_UNALIGNED_STORE_EXCEPTION 1 /* unaligned stores cause exc.*/ +#define XCHAL_UNALIGNED_LOAD_HW 0 /* unaligned loads work in hw */ +#define XCHAL_UNALIGNED_STORE_HW 0 /* unaligned stores work in hw*/ + +#define XCHAL_SW_VERSION 1000004 /* sw version of this header */ + +#define XCHAL_CORE_ID "test_kc705_hifi" /* alphanum core name + (CoreID) set in the Xtensa + Processor Generator */ + +#define XCHAL_BUILD_UNIQUE_ID 0x0004983D /* 22-bit sw build ID */ + +/* + * These definitions describe the hardware targeted by this software. + */ +#define XCHAL_HW_CONFIGID0 0xC1B3FFFE /* ConfigID hi 32 bits*/ +#define XCHAL_HW_CONFIGID1 0x1904983D /* ConfigID lo 32 bits*/ +#define XCHAL_HW_VERSION_NAME "LX5.0.4" /* full version name */ +#define XCHAL_HW_VERSION_MAJOR 2500 /* major ver# of targeted hw */ +#define XCHAL_HW_VERSION_MINOR 4 /* minor ver# of targeted hw */ +#define XCHAL_HW_VERSION 250004 /* major*100+minor */ +#define XCHAL_HW_REL_LX5 1 +#define XCHAL_HW_REL_LX5_0 1 +#define XCHAL_HW_REL_LX5_0_4 1 +#define XCHAL_HW_CONFIGID_RELIABLE 1 +/* If software targets a *range* of hardware versions, these are the bounds: */ +#define XCHAL_HW_MIN_VERSION_MAJOR 2500 /* major v of earliest tgt hw */ +#define XCHAL_HW_MIN_VERSION_MINOR 4 /* minor v of earliest tgt hw */ +#define XCHAL_HW_MIN_VERSION 250004 /* earliest targeted hw */ +#define XCHAL_HW_MAX_VERSION_MAJOR 2500 /* major v of latest tgt hw */ +#define XCHAL_HW_MAX_VERSION_MINOR 4 /* minor v of latest tgt hw */ +#define XCHAL_HW_MAX_VERSION 250004 /* latest targeted hw */ + + +/*---------------------------------------------------------------------- + CACHE + ----------------------------------------------------------------------*/ + +#define XCHAL_ICACHE_LINESIZE 32 /* I-cache line size in bytes */ +#define XCHAL_DCACHE_LINESIZE 32 /* D-cache line size in bytes */ +#define XCHAL_ICACHE_LINEWIDTH 5 /* log2(I line size in bytes) */ +#define XCHAL_DCACHE_LINEWIDTH 5 /* log2(D line size in bytes) */ + +#define XCHAL_ICACHE_SIZE 16384 /* I-cache size in bytes or 0 */ +#define XCHAL_DCACHE_SIZE 16384 /* D-cache size in bytes or 0 */ + +#define XCHAL_DCACHE_IS_WRITEBACK 1 /* writeback feature */ +#define XCHAL_DCACHE_IS_COHERENT 0 /* MP coherence feature */ + +#define XCHAL_HAVE_PREFETCH 1 /* PREFCTL register */ +#define XCHAL_HAVE_PREFETCH_L1 0 /* prefetch to L1 dcache */ +#define XCHAL_PREFETCH_CASTOUT_LINES 1 /* dcache pref. castout bufsz */ + + + + +/**************************************************************************** + Parameters Useful for PRIVILEGED (Supervisory or Non-Virtualized) Code + ****************************************************************************/ + + +#ifndef XTENSA_HAL_NON_PRIVILEGED_ONLY + +/*---------------------------------------------------------------------- + CACHE + ----------------------------------------------------------------------*/ + +#define XCHAL_HAVE_PIF 1 /* any outbound PIF present */ + +/* If present, cache size in bytes == (ways * 2^(linewidth + setwidth)). */ + +/* Number of cache sets in log2(lines per way): */ +#define XCHAL_ICACHE_SETWIDTH 7 +#define XCHAL_DCACHE_SETWIDTH 7 + +/* Cache set associativity (number of ways): */ +#define XCHAL_ICACHE_WAYS 4 +#define XCHAL_DCACHE_WAYS 4 + +/* Cache features: */ +#define XCHAL_ICACHE_LINE_LOCKABLE 1 +#define XCHAL_DCACHE_LINE_LOCKABLE 1 +#define XCHAL_ICACHE_ECC_PARITY 0 +#define XCHAL_DCACHE_ECC_PARITY 0 + +/* Cache access size in bytes (affects operation of SICW instruction): */ +#define XCHAL_ICACHE_ACCESS_SIZE 8 +#define XCHAL_DCACHE_ACCESS_SIZE 8 + +#define XCHAL_DCACHE_BANKS 1 /* number of banks */ + +/* Number of encoded cache attr bits (see for decoded bits): */ +#define XCHAL_CA_BITS 4 + + +/*---------------------------------------------------------------------- + INTERNAL I/D RAM/ROMs and XLMI + ----------------------------------------------------------------------*/ + +#define XCHAL_NUM_INSTROM 0 /* number of core instr. ROMs */ +#define XCHAL_NUM_INSTRAM 0 /* number of core instr. RAMs */ +#define XCHAL_NUM_DATAROM 0 /* number of core data ROMs */ +#define XCHAL_NUM_DATARAM 0 /* number of core data RAMs */ +#define XCHAL_NUM_URAM 0 /* number of core unified RAMs*/ +#define XCHAL_NUM_XLMI 0 /* number of core XLMI ports */ + +#define XCHAL_HAVE_IMEM_LOADSTORE 1 /* can load/store to IROM/IRAM*/ + + +/*---------------------------------------------------------------------- + INTERRUPTS and TIMERS + ----------------------------------------------------------------------*/ + +#define XCHAL_HAVE_INTERRUPTS 1 /* interrupt option */ +#define XCHAL_HAVE_HIGHPRI_INTERRUPTS 1 /* med/high-pri. interrupts */ +#define XCHAL_HAVE_NMI 1 /* non-maskable interrupt */ +#define XCHAL_HAVE_CCOUNT 1 /* CCOUNT reg. (timer option) */ +#define XCHAL_NUM_TIMERS 3 /* number of CCOMPAREn regs */ +#define XCHAL_NUM_INTERRUPTS 22 /* number of interrupts */ +#define XCHAL_NUM_INTERRUPTS_LOG2 5 /* ceil(log2(NUM_INTERRUPTS)) */ +#define XCHAL_NUM_EXTINTERRUPTS 16 /* num of external interrupts */ +#define XCHAL_NUM_INTLEVELS 6 /* number of interrupt levels + (not including level zero) */ +#define XCHAL_EXCM_LEVEL 3 /* level masked by PS.EXCM */ + /* (always 1 in XEA1; levels 2 .. EXCM_LEVEL are "medium priority") */ + +/* Masks of interrupts at each interrupt level: */ +#define XCHAL_INTLEVEL1_MASK 0x001F00BF +#define XCHAL_INTLEVEL2_MASK 0x00000140 +#define XCHAL_INTLEVEL3_MASK 0x00200E00 +#define XCHAL_INTLEVEL4_MASK 0x00009000 +#define XCHAL_INTLEVEL5_MASK 0x00002000 +#define XCHAL_INTLEVEL6_MASK 0x00000000 +#define XCHAL_INTLEVEL7_MASK 0x00004000 + +/* Masks of interrupts at each range 1..n of interrupt levels: */ +#define XCHAL_INTLEVEL1_ANDBELOW_MASK 0x001F00BF +#define XCHAL_INTLEVEL2_ANDBELOW_MASK 0x001F01FF +#define XCHAL_INTLEVEL3_ANDBELOW_MASK 0x003F0FFF +#define XCHAL_INTLEVEL4_ANDBELOW_MASK 0x003F9FFF +#define XCHAL_INTLEVEL5_ANDBELOW_MASK 0x003FBFFF +#define XCHAL_INTLEVEL6_ANDBELOW_MASK 0x003FBFFF +#define XCHAL_INTLEVEL7_ANDBELOW_MASK 0x003FFFFF + +/* Level of each interrupt: */ +#define XCHAL_INT0_LEVEL 1 +#define XCHAL_INT1_LEVEL 1 +#define XCHAL_INT2_LEVEL 1 +#define XCHAL_INT3_LEVEL 1 +#define XCHAL_INT4_LEVEL 1 +#define XCHAL_INT5_LEVEL 1 +#define XCHAL_INT6_LEVEL 2 +#define XCHAL_INT7_LEVEL 1 +#define XCHAL_INT8_LEVEL 2 +#define XCHAL_INT9_LEVEL 3 +#define XCHAL_INT10_LEVEL 3 +#define XCHAL_INT11_LEVEL 3 +#define XCHAL_INT12_LEVEL 4 +#define XCHAL_INT13_LEVEL 5 +#define XCHAL_INT14_LEVEL 7 +#define XCHAL_INT15_LEVEL 4 +#define XCHAL_INT16_LEVEL 1 +#define XCHAL_INT17_LEVEL 1 +#define XCHAL_INT18_LEVEL 1 +#define XCHAL_INT19_LEVEL 1 +#define XCHAL_INT20_LEVEL 1 +#define XCHAL_INT21_LEVEL 3 +#define XCHAL_DEBUGLEVEL 6 /* debug interrupt level */ +#define XCHAL_HAVE_DEBUG_EXTERN_INT 1 /* OCD external db interrupt */ +#define XCHAL_NMILEVEL 7 /* NMI "level" (for use with + EXCSAVE/EPS/EPC_n, RFI n) */ + +/* Type of each interrupt: */ +#define XCHAL_INT0_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT1_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT2_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT3_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT4_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT5_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT6_TYPE XTHAL_INTTYPE_TIMER +#define XCHAL_INT7_TYPE XTHAL_INTTYPE_SOFTWARE +#define XCHAL_INT8_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT9_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT10_TYPE XTHAL_INTTYPE_TIMER +#define XCHAL_INT11_TYPE XTHAL_INTTYPE_SOFTWARE +#define XCHAL_INT12_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT13_TYPE XTHAL_INTTYPE_TIMER +#define XCHAL_INT14_TYPE XTHAL_INTTYPE_NMI +#define XCHAL_INT15_TYPE XTHAL_INTTYPE_PROFILING +#define XCHAL_INT16_TYPE XTHAL_INTTYPE_EXTERN_EDGE +#define XCHAL_INT17_TYPE XTHAL_INTTYPE_EXTERN_EDGE +#define XCHAL_INT18_TYPE XTHAL_INTTYPE_EXTERN_EDGE +#define XCHAL_INT19_TYPE XTHAL_INTTYPE_EXTERN_EDGE +#define XCHAL_INT20_TYPE XTHAL_INTTYPE_EXTERN_EDGE +#define XCHAL_INT21_TYPE XTHAL_INTTYPE_EXTERN_EDGE + +/* Masks of interrupts for each type of interrupt: */ +#define XCHAL_INTTYPE_MASK_UNCONFIGURED 0xFFC00000 +#define XCHAL_INTTYPE_MASK_SOFTWARE 0x00000880 +#define XCHAL_INTTYPE_MASK_EXTERN_EDGE 0x003F0000 +#define XCHAL_INTTYPE_MASK_EXTERN_LEVEL 0x0000133F +#define XCHAL_INTTYPE_MASK_TIMER 0x00002440 +#define XCHAL_INTTYPE_MASK_NMI 0x00004000 +#define XCHAL_INTTYPE_MASK_WRITE_ERROR 0x00000000 +#define XCHAL_INTTYPE_MASK_PROFILING 0x00008000 + +/* Interrupt numbers assigned to specific interrupt sources: */ +#define XCHAL_TIMER0_INTERRUPT 6 /* CCOMPARE0 */ +#define XCHAL_TIMER1_INTERRUPT 10 /* CCOMPARE1 */ +#define XCHAL_TIMER2_INTERRUPT 13 /* CCOMPARE2 */ +#define XCHAL_TIMER3_INTERRUPT XTHAL_TIMER_UNCONFIGURED +#define XCHAL_NMI_INTERRUPT 14 /* non-maskable interrupt */ +#define XCHAL_PROFILING_INTERRUPT 15 /* profiling interrupt */ + +/* Interrupt numbers for levels at which only one interrupt is configured: */ +#define XCHAL_INTLEVEL5_NUM 13 +#define XCHAL_INTLEVEL7_NUM 14 +/* (There are many interrupts each at level(s) 1, 2, 3, 4.) */ + + +/* + * External interrupt mapping. + * These macros describe how Xtensa processor interrupt numbers + * (as numbered internally, eg. in INTERRUPT and INTENABLE registers) + * map to external BInterrupt pins, for those interrupts + * configured as external (level-triggered, edge-triggered, or NMI). + * See the Xtensa processor databook for more details. + */ + +/* Core interrupt numbers mapped to each EXTERNAL BInterrupt pin number: */ +#define XCHAL_EXTINT0_NUM 0 /* (intlevel 1) */ +#define XCHAL_EXTINT1_NUM 1 /* (intlevel 1) */ +#define XCHAL_EXTINT2_NUM 2 /* (intlevel 1) */ +#define XCHAL_EXTINT3_NUM 3 /* (intlevel 1) */ +#define XCHAL_EXTINT4_NUM 4 /* (intlevel 1) */ +#define XCHAL_EXTINT5_NUM 5 /* (intlevel 1) */ +#define XCHAL_EXTINT6_NUM 8 /* (intlevel 2) */ +#define XCHAL_EXTINT7_NUM 9 /* (intlevel 3) */ +#define XCHAL_EXTINT8_NUM 12 /* (intlevel 4) */ +#define XCHAL_EXTINT9_NUM 14 /* (intlevel 7) */ +#define XCHAL_EXTINT10_NUM 16 /* (intlevel 1) */ +#define XCHAL_EXTINT11_NUM 17 /* (intlevel 1) */ +#define XCHAL_EXTINT12_NUM 18 /* (intlevel 1) */ +#define XCHAL_EXTINT13_NUM 19 /* (intlevel 1) */ +#define XCHAL_EXTINT14_NUM 20 /* (intlevel 1) */ +#define XCHAL_EXTINT15_NUM 21 /* (intlevel 3) */ +/* EXTERNAL BInterrupt pin numbers mapped to each core interrupt number: */ +#define XCHAL_INT0_EXTNUM 0 /* (intlevel 1) */ +#define XCHAL_INT1_EXTNUM 1 /* (intlevel 1) */ +#define XCHAL_INT2_EXTNUM 2 /* (intlevel 1) */ +#define XCHAL_INT3_EXTNUM 3 /* (intlevel 1) */ +#define XCHAL_INT4_EXTNUM 4 /* (intlevel 1) */ +#define XCHAL_INT5_EXTNUM 5 /* (intlevel 1) */ +#define XCHAL_INT8_EXTNUM 6 /* (intlevel 2) */ +#define XCHAL_INT9_EXTNUM 7 /* (intlevel 3) */ +#define XCHAL_INT12_EXTNUM 8 /* (intlevel 4) */ +#define XCHAL_INT14_EXTNUM 9 /* (intlevel 7) */ +#define XCHAL_INT16_EXTNUM 10 /* (intlevel 1) */ +#define XCHAL_INT17_EXTNUM 11 /* (intlevel 1) */ +#define XCHAL_INT18_EXTNUM 12 /* (intlevel 1) */ +#define XCHAL_INT19_EXTNUM 13 /* (intlevel 1) */ +#define XCHAL_INT20_EXTNUM 14 /* (intlevel 1) */ +#define XCHAL_INT21_EXTNUM 15 /* (intlevel 3) */ + + +/*---------------------------------------------------------------------- + EXCEPTIONS and VECTORS + ----------------------------------------------------------------------*/ + +#define XCHAL_XEA_VERSION 2 /* Xtensa Exception Architecture + number: 1 == XEA1 (old) + 2 == XEA2 (new) + 0 == XEAX (extern) or TX */ +#define XCHAL_HAVE_XEA1 0 /* Exception Architecture 1 */ +#define XCHAL_HAVE_XEA2 1 /* Exception Architecture 2 */ +#define XCHAL_HAVE_XEAX 0 /* External Exception Arch. */ +#define XCHAL_HAVE_EXCEPTIONS 1 /* exception option */ +#define XCHAL_HAVE_HALT 0 /* halt architecture option */ +#define XCHAL_HAVE_BOOTLOADER 0 /* boot loader (for TX) */ +#define XCHAL_HAVE_MEM_ECC_PARITY 0 /* local memory ECC/parity */ +#define XCHAL_HAVE_VECTOR_SELECT 1 /* relocatable vectors */ +#define XCHAL_HAVE_VECBASE 1 /* relocatable vectors */ +#define XCHAL_VECBASE_RESET_VADDR 0x00002000 /* VECBASE reset value */ +#define XCHAL_VECBASE_RESET_PADDR 0x00002000 +#define XCHAL_RESET_VECBASE_OVERLAP 0 + +#define XCHAL_RESET_VECTOR0_VADDR 0xFE000000 +#define XCHAL_RESET_VECTOR0_PADDR 0xFE000000 +#define XCHAL_RESET_VECTOR1_VADDR 0x00001000 +#define XCHAL_RESET_VECTOR1_PADDR 0x00001000 +#define XCHAL_RESET_VECTOR_VADDR 0xFE000000 +#define XCHAL_RESET_VECTOR_PADDR 0xFE000000 +#define XCHAL_USER_VECOFS 0x00000340 +#define XCHAL_USER_VECTOR_VADDR 0x00002340 +#define XCHAL_USER_VECTOR_PADDR 0x00002340 +#define XCHAL_KERNEL_VECOFS 0x00000300 +#define XCHAL_KERNEL_VECTOR_VADDR 0x00002300 +#define XCHAL_KERNEL_VECTOR_PADDR 0x00002300 +#define XCHAL_DOUBLEEXC_VECOFS 0x000003C0 +#define XCHAL_DOUBLEEXC_VECTOR_VADDR 0x000023C0 +#define XCHAL_DOUBLEEXC_VECTOR_PADDR 0x000023C0 +#define XCHAL_WINDOW_OF4_VECOFS 0x00000000 +#define XCHAL_WINDOW_UF4_VECOFS 0x00000040 +#define XCHAL_WINDOW_OF8_VECOFS 0x00000080 +#define XCHAL_WINDOW_UF8_VECOFS 0x000000C0 +#define XCHAL_WINDOW_OF12_VECOFS 0x00000100 +#define XCHAL_WINDOW_UF12_VECOFS 0x00000140 +#define XCHAL_WINDOW_VECTORS_VADDR 0x00002000 +#define XCHAL_WINDOW_VECTORS_PADDR 0x00002000 +#define XCHAL_INTLEVEL2_VECOFS 0x00000180 +#define XCHAL_INTLEVEL2_VECTOR_VADDR 0x00002180 +#define XCHAL_INTLEVEL2_VECTOR_PADDR 0x00002180 +#define XCHAL_INTLEVEL3_VECOFS 0x000001C0 +#define XCHAL_INTLEVEL3_VECTOR_VADDR 0x000021C0 +#define XCHAL_INTLEVEL3_VECTOR_PADDR 0x000021C0 +#define XCHAL_INTLEVEL4_VECOFS 0x00000200 +#define XCHAL_INTLEVEL4_VECTOR_VADDR 0x00002200 +#define XCHAL_INTLEVEL4_VECTOR_PADDR 0x00002200 +#define XCHAL_INTLEVEL5_VECOFS 0x00000240 +#define XCHAL_INTLEVEL5_VECTOR_VADDR 0x00002240 +#define XCHAL_INTLEVEL5_VECTOR_PADDR 0x00002240 +#define XCHAL_INTLEVEL6_VECOFS 0x00000280 +#define XCHAL_INTLEVEL6_VECTOR_VADDR 0x00002280 +#define XCHAL_INTLEVEL6_VECTOR_PADDR 0x00002280 +#define XCHAL_DEBUG_VECOFS XCHAL_INTLEVEL6_VECOFS +#define XCHAL_DEBUG_VECTOR_VADDR XCHAL_INTLEVEL6_VECTOR_VADDR +#define XCHAL_DEBUG_VECTOR_PADDR XCHAL_INTLEVEL6_VECTOR_PADDR +#define XCHAL_NMI_VECOFS 0x000002C0 +#define XCHAL_NMI_VECTOR_VADDR 0x000022C0 +#define XCHAL_NMI_VECTOR_PADDR 0x000022C0 +#define XCHAL_INTLEVEL7_VECOFS XCHAL_NMI_VECOFS +#define XCHAL_INTLEVEL7_VECTOR_VADDR XCHAL_NMI_VECTOR_VADDR +#define XCHAL_INTLEVEL7_VECTOR_PADDR XCHAL_NMI_VECTOR_PADDR + + +/*---------------------------------------------------------------------- + DEBUG MODULE + ----------------------------------------------------------------------*/ + +/* Misc */ +#define XCHAL_HAVE_DEBUG_ERI 1 /* ERI to debug module */ +#define XCHAL_HAVE_DEBUG_APB 0 /* APB to debug module */ +#define XCHAL_HAVE_DEBUG_JTAG 1 /* JTAG to debug module */ + +/* On-Chip Debug (OCD) */ +#define XCHAL_HAVE_OCD 1 /* OnChipDebug option */ +#define XCHAL_NUM_IBREAK 2 /* number of IBREAKn regs */ +#define XCHAL_NUM_DBREAK 2 /* number of DBREAKn regs */ +#define XCHAL_HAVE_OCD_DIR_ARRAY 0 /* faster OCD option (to LX4) */ +#define XCHAL_HAVE_OCD_LS32DDR 1 /* L32DDR/S32DDR (faster OCD) */ + +/* TRAX (in core) */ +#define XCHAL_HAVE_TRAX 1 /* TRAX in debug module */ +#define XCHAL_TRAX_MEM_SIZE 262144 /* TRAX memory size in bytes */ +#define XCHAL_TRAX_MEM_SHAREABLE 1 /* start/end regs; ready sig. */ +#define XCHAL_TRAX_ATB_WIDTH 0 /* ATB width (bits), 0=no ATB */ +#define XCHAL_TRAX_TIME_WIDTH 0 /* timestamp bitwidth, 0=none */ + +/* Perf counters */ +#define XCHAL_NUM_PERF_COUNTERS 8 /* performance counters */ + + +/*---------------------------------------------------------------------- + MMU + ----------------------------------------------------------------------*/ + +/* See core-matmap.h header file for more details. */ + +#define XCHAL_HAVE_TLBS 1 /* inverse of HAVE_CACHEATTR */ +#define XCHAL_HAVE_SPANNING_WAY 1 /* one way maps I+D 4GB vaddr */ +#define XCHAL_SPANNING_WAY 6 /* TLB spanning way number */ +#define XCHAL_HAVE_IDENTITY_MAP 0 /* vaddr == paddr always */ +#define XCHAL_HAVE_CACHEATTR 0 /* CACHEATTR register present */ +#define XCHAL_HAVE_MIMIC_CACHEATTR 0 /* region protection */ +#define XCHAL_HAVE_XLT_CACHEATTR 0 /* region prot. w/translation */ +#define XCHAL_HAVE_PTP_MMU 1 /* full MMU (with page table + [autorefill] and protection) + usable for an MMU-based OS */ +/* If none of the above last 4 are set, it's a custom TLB configuration. */ +#define XCHAL_ITLB_ARF_ENTRIES_LOG2 2 /* log2(autorefill way size) */ +#define XCHAL_DTLB_ARF_ENTRIES_LOG2 2 /* log2(autorefill way size) */ + +#define XCHAL_MMU_ASID_BITS 8 /* number of bits in ASIDs */ +#define XCHAL_MMU_RINGS 4 /* number of rings (1..4) */ +#define XCHAL_MMU_RING_BITS 2 /* num of bits in RING field */ + +#endif /* !XTENSA_HAL_NON_PRIVILEGED_ONLY */ + + +#endif /* _XTENSA_CORE_CONFIGURATION_H */ diff --git a/arch/xtensa/variants/test_kc705_hifi/include/variant/tie-asm.h b/arch/xtensa/variants/test_kc705_hifi/include/variant/tie-asm.h new file mode 100644 index 0000000000000000000000000000000000000000..378163c0a7ade11560d273e5c907789fb535feb3 --- /dev/null +++ b/arch/xtensa/variants/test_kc705_hifi/include/variant/tie-asm.h @@ -0,0 +1,328 @@ +/* + * tie-asm.h -- compile-time HAL assembler definitions dependent on CORE & TIE + * + * NOTE: This header file is not meant to be included directly. + */ + +/* This header file contains assembly-language definitions (assembly + macros, etc.) for this specific Xtensa processor's TIE extensions + and options. It is customized to this Xtensa processor configuration. + + Copyright (c) 1999-2014 Tensilica Inc. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef _XTENSA_CORE_TIE_ASM_H +#define _XTENSA_CORE_TIE_ASM_H + +/* Selection parameter values for save-area save/restore macros: */ +/* Option vs. TIE: */ +#define XTHAL_SAS_TIE 0x0001 /* custom extension or coprocessor */ +#define XTHAL_SAS_OPT 0x0002 /* optional (and not a coprocessor) */ +#define XTHAL_SAS_ANYOT 0x0003 /* both of the above */ +/* Whether used automatically by compiler: */ +#define XTHAL_SAS_NOCC 0x0004 /* not used by compiler w/o special opts/code */ +#define XTHAL_SAS_CC 0x0008 /* used by compiler without special opts/code */ +#define XTHAL_SAS_ANYCC 0x000C /* both of the above */ +/* ABI handling across function calls: */ +#define XTHAL_SAS_CALR 0x0010 /* caller-saved */ +#define XTHAL_SAS_CALE 0x0020 /* callee-saved */ +#define XTHAL_SAS_GLOB 0x0040 /* global across function calls (in thread) */ +#define XTHAL_SAS_ANYABI 0x0070 /* all of the above three */ +/* Misc */ +#define XTHAL_SAS_ALL 0xFFFF /* include all default NCP contents */ +#define XTHAL_SAS3(optie,ccuse,abi) ( ((optie) & XTHAL_SAS_ANYOT) \ + | ((ccuse) & XTHAL_SAS_ANYCC) \ + | ((abi) & XTHAL_SAS_ANYABI) ) + + + + /* + * Macro to save all non-coprocessor (extra) custom TIE and optional state + * (not including zero-overhead loop registers). + * Required parameters: + * ptr Save area pointer address register (clobbered) + * (register must contain a 4 byte aligned address). + * at1..at4 Four temporary address registers (first XCHAL_NCP_NUM_ATMPS + * registers are clobbered, the remaining are unused). + * Optional parameters: + * continue If macro invoked as part of a larger store sequence, set to 1 + * if this is not the first in the sequence. Defaults to 0. + * ofs Offset from start of larger sequence (from value of first ptr + * in sequence) at which to store. Defaults to next available space + * (or 0 if is 0). + * select Select what category(ies) of registers to store, as a bitmask + * (see XTHAL_SAS_xxx constants). Defaults to all registers. + * alloc Select what category(ies) of registers to allocate; if any + * category is selected here that is not in , space for + * the corresponding registers is skipped without doing any load. + */ + .macro xchal_ncp_load ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL alloc=0 + xchal_sa_start \continue, \ofs + // Optional global register used by default by the compiler: + .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_GLOB) & ~(\select) + xchal_sa_align \ptr, 0, 1020, 4, 4 + l32i \at1, \ptr, .Lxchal_ofs_+0 + wur.THREADPTR \at1 // threadptr option + .set .Lxchal_ofs_, .Lxchal_ofs_ + 4 + .elseif ((XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_GLOB) & ~(\alloc)) == 0 + xchal_sa_align \ptr, 0, 1020, 4, 4 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 4 + .endif + // Optional caller-saved registers used by default by the compiler: + .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_CALR) & ~(\select) + xchal_sa_align \ptr, 0, 1016, 4, 4 + l32i \at1, \ptr, .Lxchal_ofs_+0 + wsr.ACCLO \at1 // MAC16 option + l32i \at1, \ptr, .Lxchal_ofs_+4 + wsr.ACCHI \at1 // MAC16 option + .set .Lxchal_ofs_, .Lxchal_ofs_ + 8 + .elseif ((XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_CALR) & ~(\alloc)) == 0 + xchal_sa_align \ptr, 0, 1016, 4, 4 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 8 + .endif + // Optional caller-saved registers not used by default by the compiler: + .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\select) + xchal_sa_align \ptr, 0, 1000, 4, 4 + l32i \at1, \ptr, .Lxchal_ofs_+0 + wsr.M0 \at1 // MAC16 option + l32i \at1, \ptr, .Lxchal_ofs_+4 + wsr.M1 \at1 // MAC16 option + l32i \at1, \ptr, .Lxchal_ofs_+8 + wsr.M2 \at1 // MAC16 option + l32i \at1, \ptr, .Lxchal_ofs_+12 + wsr.M3 \at1 // MAC16 option + l32i \at1, \ptr, .Lxchal_ofs_+16 + wsr.BR \at1 // boolean option + l32i \at1, \ptr, .Lxchal_ofs_+20 + wsr.SCOMPARE1 \at1 // conditional store option + .set .Lxchal_ofs_, .Lxchal_ofs_ + 24 + .elseif ((XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\alloc)) == 0 + xchal_sa_align \ptr, 0, 1000, 4, 4 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 24 + .endif + .endm // xchal_ncp_load + + +#define XCHAL_NCP_NUM_ATMPS 1 + + + + + /* + * Macro to save the state of TIE coprocessor AudioEngineLX. + * Required parameters: + * ptr Save area pointer address register (clobbered) + * (register must contain a 8 byte aligned address). + * at1..at4 Four temporary address registers (first XCHAL_CP1_NUM_ATMPS + * registers are clobbered, the remaining are unused). + * Optional parameters are the same as for xchal_ncp_store. + */ +#define xchal_cp_AudioEngineLX_store xchal_cp1_store + .macro xchal_cp1_store ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL alloc=0 + xchal_sa_start \continue, \ofs + // Custom caller-saved registers not used by default by the compiler: + .ifeq (XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\select) + xchal_sa_align \ptr, 0, 0, 8, 8 + rur.AE_OVF_SAR \at1 // ureg 240 + s32i \at1, \ptr, .Lxchal_ofs_+0 + rur.AE_BITHEAD \at1 // ureg 241 + s32i \at1, \ptr, .Lxchal_ofs_+4 + rur.AE_TS_FTS_BU_BP \at1 // ureg 242 + s32i \at1, \ptr, .Lxchal_ofs_+8 + rur.AE_CW_SD_NO \at1 // ureg 243 + s32i \at1, \ptr, .Lxchal_ofs_+12 + rur.AE_CBEGIN0 \at1 // ureg 246 + s32i \at1, \ptr, .Lxchal_ofs_+16 + rur.AE_CEND0 \at1 // ureg 247 + s32i \at1, \ptr, .Lxchal_ofs_+20 + AE_S64.I aed0, \ptr, .Lxchal_ofs_+24 + AE_S64.I aed1, \ptr, .Lxchal_ofs_+32 + AE_S64.I aed2, \ptr, .Lxchal_ofs_+40 + AE_S64.I aed3, \ptr, .Lxchal_ofs_+48 + AE_S64.I aed4, \ptr, .Lxchal_ofs_+56 + addi \ptr, \ptr, 64 + AE_S64.I aed5, \ptr, .Lxchal_ofs_+0 + AE_S64.I aed6, \ptr, .Lxchal_ofs_+8 + AE_S64.I aed7, \ptr, .Lxchal_ofs_+16 + AE_S64.I aed8, \ptr, .Lxchal_ofs_+24 + AE_S64.I aed9, \ptr, .Lxchal_ofs_+32 + AE_S64.I aed10, \ptr, .Lxchal_ofs_+40 + AE_S64.I aed11, \ptr, .Lxchal_ofs_+48 + AE_S64.I aed12, \ptr, .Lxchal_ofs_+56 + addi \ptr, \ptr, 64 + AE_S64.I aed13, \ptr, .Lxchal_ofs_+0 + AE_S64.I aed14, \ptr, .Lxchal_ofs_+8 + AE_S64.I aed15, \ptr, .Lxchal_ofs_+16 + AE_SALIGN64.I u0, \ptr, .Lxchal_ofs_+24 + AE_SALIGN64.I u1, \ptr, .Lxchal_ofs_+32 + AE_SALIGN64.I u2, \ptr, .Lxchal_ofs_+40 + AE_SALIGN64.I u3, \ptr, .Lxchal_ofs_+48 + .set .Lxchal_pofs_, .Lxchal_pofs_ + 128 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 56 + .elseif ((XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\alloc)) == 0 + xchal_sa_align \ptr, 0, 0, 8, 8 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 184 + .endif + .endm // xchal_cp1_store + + /* + * Macro to restore the state of TIE coprocessor AudioEngineLX. + * Required parameters: + * ptr Save area pointer address register (clobbered) + * (register must contain a 8 byte aligned address). + * at1..at4 Four temporary address registers (first XCHAL_CP1_NUM_ATMPS + * registers are clobbered, the remaining are unused). + * Optional parameters are the same as for xchal_ncp_load. + */ +#define xchal_cp_AudioEngineLX_load xchal_cp1_load + .macro xchal_cp1_load ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL alloc=0 + xchal_sa_start \continue, \ofs + // Custom caller-saved registers not used by default by the compiler: + .ifeq (XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\select) + xchal_sa_align \ptr, 0, 0, 8, 8 + l32i \at1, \ptr, .Lxchal_ofs_+0 + wur.AE_OVF_SAR \at1 // ureg 240 + l32i \at1, \ptr, .Lxchal_ofs_+4 + wur.AE_BITHEAD \at1 // ureg 241 + l32i \at1, \ptr, .Lxchal_ofs_+8 + wur.AE_TS_FTS_BU_BP \at1 // ureg 242 + l32i \at1, \ptr, .Lxchal_ofs_+12 + wur.AE_CW_SD_NO \at1 // ureg 243 + l32i \at1, \ptr, .Lxchal_ofs_+16 + wur.AE_CBEGIN0 \at1 // ureg 246 + l32i \at1, \ptr, .Lxchal_ofs_+20 + wur.AE_CEND0 \at1 // ureg 247 + AE_L64.I aed0, \ptr, .Lxchal_ofs_+24 + AE_L64.I aed1, \ptr, .Lxchal_ofs_+32 + AE_L64.I aed2, \ptr, .Lxchal_ofs_+40 + AE_L64.I aed3, \ptr, .Lxchal_ofs_+48 + AE_L64.I aed4, \ptr, .Lxchal_ofs_+56 + addi \ptr, \ptr, 64 + AE_L64.I aed5, \ptr, .Lxchal_ofs_+0 + AE_L64.I aed6, \ptr, .Lxchal_ofs_+8 + AE_L64.I aed7, \ptr, .Lxchal_ofs_+16 + AE_L64.I aed8, \ptr, .Lxchal_ofs_+24 + AE_L64.I aed9, \ptr, .Lxchal_ofs_+32 + AE_L64.I aed10, \ptr, .Lxchal_ofs_+40 + AE_L64.I aed11, \ptr, .Lxchal_ofs_+48 + AE_L64.I aed12, \ptr, .Lxchal_ofs_+56 + addi \ptr, \ptr, 64 + AE_L64.I aed13, \ptr, .Lxchal_ofs_+0 + AE_L64.I aed14, \ptr, .Lxchal_ofs_+8 + AE_L64.I aed15, \ptr, .Lxchal_ofs_+16 + AE_LALIGN64.I u0, \ptr, .Lxchal_ofs_+24 + AE_LALIGN64.I u1, \ptr, .Lxchal_ofs_+32 + AE_LALIGN64.I u2, \ptr, .Lxchal_ofs_+40 + AE_LALIGN64.I u3, \ptr, .Lxchal_ofs_+48 + .set .Lxchal_pofs_, .Lxchal_pofs_ + 128 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 56 + .elseif ((XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~(\alloc)) == 0 + xchal_sa_align \ptr, 0, 0, 8, 8 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 184 + .endif + .endm // xchal_cp1_load + +#define XCHAL_CP1_NUM_ATMPS 1 +#define XCHAL_SA_NUM_ATMPS 1 + + /* Empty macros for unconfigured coprocessors: */ + .macro xchal_cp0_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp0_load p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp2_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp2_load p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp3_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp3_load p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp4_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp4_load p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp5_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp5_load p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp6_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp6_load p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp7_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp7_load p a b c d continue=0 ofs=-1 select=-1 ; .endm + +#endif /*_XTENSA_CORE_TIE_ASM_H*/ diff --git a/arch/xtensa/variants/test_kc705_hifi/include/variant/tie.h b/arch/xtensa/variants/test_kc705_hifi/include/variant/tie.h new file mode 100644 index 0000000000000000000000000000000000000000..e39fea64391e8d24e9ef0afdfe8a7842113db2c4 --- /dev/null +++ b/arch/xtensa/variants/test_kc705_hifi/include/variant/tie.h @@ -0,0 +1,189 @@ +/* + * tie.h -- compile-time HAL definitions dependent on CORE & TIE configuration + * + * NOTE: This header file is not meant to be included directly. + */ + +/* This header file describes this specific Xtensa processor's TIE extensions + that extend basic Xtensa core functionality. It is customized to this + Xtensa processor configuration. + + Copyright (c) 1999-2014 Tensilica Inc. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef _XTENSA_CORE_TIE_H +#define _XTENSA_CORE_TIE_H + +#define XCHAL_CP_NUM 2 /* number of coprocessors */ +#define XCHAL_CP_MAX 8 /* max CP ID + 1 (0 if none) */ +#define XCHAL_CP_MASK 0x82 /* bitmask of all CPs by ID */ +#define XCHAL_CP_PORT_MASK 0x80 /* bitmask of only port CPs */ + +/* Basic parameters of each coprocessor: */ +#define XCHAL_CP1_NAME "AudioEngineLX" +#define XCHAL_CP1_IDENT AudioEngineLX +#define XCHAL_CP1_SA_SIZE 184 /* size of state save area */ +#define XCHAL_CP1_SA_ALIGN 8 /* min alignment of save area */ +#define XCHAL_CP_ID_AUDIOENGINELX 1 /* coprocessor ID (0..7) */ +#define XCHAL_CP7_NAME "XTIOP" +#define XCHAL_CP7_IDENT XTIOP +#define XCHAL_CP7_SA_SIZE 0 /* size of state save area */ +#define XCHAL_CP7_SA_ALIGN 1 /* min alignment of save area */ +#define XCHAL_CP_ID_XTIOP 7 /* coprocessor ID (0..7) */ + +/* Filler info for unassigned coprocessors, to simplify arrays etc: */ +#define XCHAL_CP0_SA_SIZE 0 +#define XCHAL_CP0_SA_ALIGN 1 +#define XCHAL_CP2_SA_SIZE 0 +#define XCHAL_CP2_SA_ALIGN 1 +#define XCHAL_CP3_SA_SIZE 0 +#define XCHAL_CP3_SA_ALIGN 1 +#define XCHAL_CP4_SA_SIZE 0 +#define XCHAL_CP4_SA_ALIGN 1 +#define XCHAL_CP5_SA_SIZE 0 +#define XCHAL_CP5_SA_ALIGN 1 +#define XCHAL_CP6_SA_SIZE 0 +#define XCHAL_CP6_SA_ALIGN 1 + +/* Save area for non-coprocessor optional and custom (TIE) state: */ +#define XCHAL_NCP_SA_SIZE 36 +#define XCHAL_NCP_SA_ALIGN 4 + +/* Total save area for optional and custom state (NCP + CPn): */ +#define XCHAL_TOTAL_SA_SIZE 240 /* with 16-byte align padding */ +#define XCHAL_TOTAL_SA_ALIGN 8 /* actual minimum alignment */ + +/* + * Detailed contents of save areas. + * NOTE: caller must define the XCHAL_SA_REG macro (not defined here) + * before expanding the XCHAL_xxx_SA_LIST() macros. + * + * XCHAL_SA_REG(s,ccused,abikind,kind,opt,name,galign,align,asize, + * dbnum,base,regnum,bitsz,gapsz,reset,x...) + * + * s = passed from XCHAL_*_LIST(s), eg. to select how to expand + * ccused = set if used by compiler without special options or code + * abikind = 0 (caller-saved), 1 (callee-saved), or 2 (thread-global) + * kind = 0 (special reg), 1 (TIE user reg), or 2 (TIE regfile reg) + * opt = 0 (custom TIE extension or coprocessor), or 1 (optional reg) + * name = lowercase reg name (no quotes) + * galign = group byte alignment (power of 2) (galign >= align) + * align = register byte alignment (power of 2) + * asize = allocated size in bytes (asize*8 == bitsz + gapsz + padsz) + * (not including any pad bytes required to galign this or next reg) + * dbnum = unique target number f/debug (see ) + * base = reg shortname w/o index (or sr=special, ur=TIE user reg) + * regnum = reg index in regfile, or special/TIE-user reg number + * bitsz = number of significant bits (regfile width, or ur/sr mask bits) + * gapsz = intervening bits, if bitsz bits not stored contiguously + * (padsz = pad bits at end [TIE regfile] or at msbits [ur,sr] of asize) + * reset = register reset value (or 0 if undefined at reset) + * x = reserved for future use (0 until then) + * + * To filter out certain registers, e.g. to expand only the non-global + * registers used by the compiler, you can do something like this: + * + * #define XCHAL_SA_REG(s,ccused,p...) SELCC##ccused(p) + * #define SELCC0(p...) + * #define SELCC1(abikind,p...) SELAK##abikind(p) + * #define SELAK0(p...) REG(p) + * #define SELAK1(p...) REG(p) + * #define SELAK2(p...) + * #define REG(kind,tie,name,galn,aln,asz,csz,dbnum,base,rnum,bsz,rst,x...) \ + * ...what you want to expand... + */ + +#define XCHAL_NCP_SA_NUM 9 +#define XCHAL_NCP_SA_LIST(s) \ + XCHAL_SA_REG(s,1,2,1,1, threadptr, 4, 4, 4,0x03E7, ur,231, 32,0,0,0) \ + XCHAL_SA_REG(s,1,0,0,1, acclo, 4, 4, 4,0x0210, sr,16 , 32,0,0,0) \ + XCHAL_SA_REG(s,1,0,0,1, acchi, 4, 4, 4,0x0211, sr,17 , 8,0,0,0) \ + XCHAL_SA_REG(s,0,0,0,1, m0, 4, 4, 4,0x0220, sr,32 , 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,0,1, m1, 4, 4, 4,0x0221, sr,33 , 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,0,1, m2, 4, 4, 4,0x0222, sr,34 , 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,0,1, m3, 4, 4, 4,0x0223, sr,35 , 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,0,1, br, 4, 4, 4,0x0204, sr,4 , 16,0,0,0) \ + XCHAL_SA_REG(s,0,0,0,1, scompare1, 4, 4, 4,0x020C, sr,12 , 32,0,0,0) + +#define XCHAL_CP0_SA_NUM 0 +#define XCHAL_CP0_SA_LIST(s) /* empty */ + +#define XCHAL_CP1_SA_NUM 26 +#define XCHAL_CP1_SA_LIST(s) \ + XCHAL_SA_REG(s,0,0,1,0, ae_ovf_sar, 8, 4, 4,0x03F0, ur,240, 8,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, ae_bithead, 4, 4, 4,0x03F1, ur,241, 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0,ae_ts_fts_bu_bp, 4, 4, 4,0x03F2, ur,242, 16,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, ae_cw_sd_no, 4, 4, 4,0x03F3, ur,243, 29,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, ae_cbegin0, 4, 4, 4,0x03F6, ur,246, 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, ae_cend0, 4, 4, 4,0x03F7, ur,247, 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed0, 8, 8, 8,0x1010, aed,0 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed1, 8, 8, 8,0x1011, aed,1 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed2, 8, 8, 8,0x1012, aed,2 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed3, 8, 8, 8,0x1013, aed,3 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed4, 8, 8, 8,0x1014, aed,4 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed5, 8, 8, 8,0x1015, aed,5 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed6, 8, 8, 8,0x1016, aed,6 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed7, 8, 8, 8,0x1017, aed,7 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed8, 8, 8, 8,0x1018, aed,8 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed9, 8, 8, 8,0x1019, aed,9 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed10, 8, 8, 8,0x101A, aed,10 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed11, 8, 8, 8,0x101B, aed,11 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed12, 8, 8, 8,0x101C, aed,12 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed13, 8, 8, 8,0x101D, aed,13 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed14, 8, 8, 8,0x101E, aed,14 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aed15, 8, 8, 8,0x101F, aed,15 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, u0, 8, 8, 8,0x1020, u,0 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, u1, 8, 8, 8,0x1021, u,1 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, u2, 8, 8, 8,0x1022, u,2 , 64,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, u3, 8, 8, 8,0x1023, u,3 , 64,0,0,0) + +#define XCHAL_CP2_SA_NUM 0 +#define XCHAL_CP2_SA_LIST(s) /* empty */ + +#define XCHAL_CP3_SA_NUM 0 +#define XCHAL_CP3_SA_LIST(s) /* empty */ + +#define XCHAL_CP4_SA_NUM 0 +#define XCHAL_CP4_SA_LIST(s) /* empty */ + +#define XCHAL_CP5_SA_NUM 0 +#define XCHAL_CP5_SA_LIST(s) /* empty */ + +#define XCHAL_CP6_SA_NUM 0 +#define XCHAL_CP6_SA_LIST(s) /* empty */ + +#define XCHAL_CP7_SA_NUM 0 +#define XCHAL_CP7_SA_LIST(s) /* empty */ + +/* Byte length of instruction from its first nibble (op0 field), per FLIX. */ +#define XCHAL_OP0_FORMAT_LENGTHS 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,8 +/* Byte length of instruction from its first byte, per FLIX. */ +#define XCHAL_BYTE0_FORMAT_LENGTHS \ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,8, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,8,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,8, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,8,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,8, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,8,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,8, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,8,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,8, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,8,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,8, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,8,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,8, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,8,\ + 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,8, 3,3,3,3,3,3,3,3,2,2,2,2,2,2,8,8 + +#endif /*_XTENSA_CORE_TIE_H*/ diff --git a/arch/xtensa/variants/test_mmuhifi_c3/include/variant/core.h b/arch/xtensa/variants/test_mmuhifi_c3/include/variant/core.h new file mode 100644 index 0000000000000000000000000000000000000000..7c5d3a22da12b125b54f08e46de1a169e1a820ee --- /dev/null +++ b/arch/xtensa/variants/test_mmuhifi_c3/include/variant/core.h @@ -0,0 +1,383 @@ +/* + * Xtensa processor core configuration information. + * + * This file is subject to the terms and conditions of version 2.1 of the GNU + * Lesser General Public License as published by the Free Software Foundation. + * + * Copyright (c) 1999-2009 Tensilica Inc. + */ + +#ifndef _XTENSA_CORE_CONFIGURATION_H +#define _XTENSA_CORE_CONFIGURATION_H + + +/**************************************************************************** + Parameters Useful for Any Code, USER or PRIVILEGED + ****************************************************************************/ + +/* + * Note: Macros of the form XCHAL_HAVE_*** have a value of 1 if the option is + * configured, and a value of 0 otherwise. These macros are always defined. + */ + + +/*---------------------------------------------------------------------- + ISA + ----------------------------------------------------------------------*/ + +#define XCHAL_HAVE_BE 0 /* big-endian byte ordering */ +#define XCHAL_HAVE_WINDOWED 1 /* windowed registers option */ +#define XCHAL_NUM_AREGS 32 /* num of physical addr regs */ +#define XCHAL_NUM_AREGS_LOG2 5 /* log2(XCHAL_NUM_AREGS) */ +#define XCHAL_MAX_INSTRUCTION_SIZE 8 /* max instr bytes (3..8) */ +#define XCHAL_HAVE_DEBUG 1 /* debug option */ +#define XCHAL_HAVE_DENSITY 1 /* 16-bit instructions */ +#define XCHAL_HAVE_LOOPS 1 /* zero-overhead loops */ +#define XCHAL_HAVE_NSA 1 /* NSA/NSAU instructions */ +#define XCHAL_HAVE_MINMAX 1 /* MIN/MAX instructions */ +#define XCHAL_HAVE_SEXT 1 /* SEXT instruction */ +#define XCHAL_HAVE_CLAMPS 1 /* CLAMPS instruction */ +#define XCHAL_HAVE_MUL16 1 /* MUL16S/MUL16U instructions */ +#define XCHAL_HAVE_MUL32 1 /* MULL instruction */ +#define XCHAL_HAVE_MUL32_HIGH 0 /* MULUH/MULSH instructions */ +#define XCHAL_HAVE_DIV32 0 /* QUOS/QUOU/REMS/REMU instructions */ +#define XCHAL_HAVE_L32R 1 /* L32R instruction */ +#define XCHAL_HAVE_ABSOLUTE_LITERALS 1 /* non-PC-rel (extended) L32R */ +#define XCHAL_HAVE_CONST16 0 /* CONST16 instruction */ +#define XCHAL_HAVE_ADDX 1 /* ADDX#/SUBX# instructions */ +#define XCHAL_HAVE_WIDE_BRANCHES 0 /* B*.W18 or B*.W15 instr's */ +#define XCHAL_HAVE_PREDICTED_BRANCHES 0 /* B[EQ/EQZ/NE/NEZ]T instr's */ +#define XCHAL_HAVE_CALL4AND12 1 /* (obsolete option) */ +#define XCHAL_HAVE_ABS 1 /* ABS instruction */ +/*#define XCHAL_HAVE_POPC 0*/ /* POPC instruction */ +/*#define XCHAL_HAVE_CRC 0*/ /* CRC instruction */ +#define XCHAL_HAVE_RELEASE_SYNC 1 /* L32AI/S32RI instructions */ +#define XCHAL_HAVE_S32C1I 1 /* S32C1I instruction */ +#define XCHAL_HAVE_SPECULATION 0 /* speculation */ +#define XCHAL_HAVE_FULL_RESET 1 /* all regs/state reset */ +#define XCHAL_NUM_CONTEXTS 1 /* */ +#define XCHAL_NUM_MISC_REGS 2 /* num of scratch regs (0..4) */ +#define XCHAL_HAVE_TAP_MASTER 0 /* JTAG TAP control instr's */ +#define XCHAL_HAVE_PRID 1 /* processor ID register */ +#define XCHAL_HAVE_EXTERN_REGS 1 /* WER/RER instructions */ +#define XCHAL_HAVE_MP_INTERRUPTS 1 /* interrupt distributor port */ +#define XCHAL_HAVE_MP_RUNSTALL 1 /* core RunStall control port */ +#define XCHAL_HAVE_THREADPTR 1 /* THREADPTR register */ +#define XCHAL_HAVE_BOOLEANS 1 /* boolean registers */ +#define XCHAL_HAVE_CP 1 /* CPENABLE reg (coprocessor) */ +#define XCHAL_CP_MAXCFG 2 /* max allowed cp id plus one */ +#define XCHAL_HAVE_MAC16 0 /* MAC16 package */ +#define XCHAL_HAVE_VECTORFPU2005 0 /* vector floating-point pkg */ +#define XCHAL_HAVE_FP 0 /* floating point pkg */ +#define XCHAL_HAVE_DFP 0 /* double precision FP pkg */ +#define XCHAL_HAVE_DFP_accel 0 /* double precision FP acceleration pkg */ +#define XCHAL_HAVE_VECTRA1 0 /* Vectra I pkg */ +#define XCHAL_HAVE_VECTRALX 0 /* Vectra LX pkg */ +#define XCHAL_HAVE_HIFIPRO 0 /* HiFiPro Audio Engine pkg */ +#define XCHAL_HAVE_HIFI2 1 /* HiFi2 Audio Engine pkg */ +#define XCHAL_HAVE_CONNXD2 0 /* ConnX D2 pkg */ + + +/*---------------------------------------------------------------------- + MISC + ----------------------------------------------------------------------*/ + +#define XCHAL_NUM_WRITEBUFFER_ENTRIES 8 /* size of write buffer */ +#define XCHAL_INST_FETCH_WIDTH 8 /* instr-fetch width in bytes */ +#define XCHAL_DATA_WIDTH 8 /* data width in bytes */ +/* In T1050, applies to selected core load and store instructions (see ISA): */ +#define XCHAL_UNALIGNED_LOAD_EXCEPTION 1 /* unaligned loads cause exc. */ +#define XCHAL_UNALIGNED_STORE_EXCEPTION 1 /* unaligned stores cause exc.*/ +#define XCHAL_UNALIGNED_LOAD_HW 0 /* unaligned loads work in hw */ +#define XCHAL_UNALIGNED_STORE_HW 0 /* unaligned stores work in hw*/ + +#define XCHAL_SW_VERSION 800000 /* sw version of this header */ + +#define XCHAL_CORE_ID "test_mmuhifi_c3" /* alphanum core name + (CoreID) set in the Xtensa + Processor Generator */ + +#define XCHAL_CORE_DESCRIPTION "test_mmuhifi_c3" +#define XCHAL_BUILD_UNIQUE_ID 0x00005A6A /* 22-bit sw build ID */ + +/* + * These definitions describe the hardware targeted by this software. + */ +#define XCHAL_HW_CONFIGID0 0xC1B3CBFE /* ConfigID hi 32 bits*/ +#define XCHAL_HW_CONFIGID1 0x10405A6A /* ConfigID lo 32 bits*/ +#define XCHAL_HW_VERSION_NAME "LX3.0.0" /* full version name */ +#define XCHAL_HW_VERSION_MAJOR 2300 /* major ver# of targeted hw */ +#define XCHAL_HW_VERSION_MINOR 0 /* minor ver# of targeted hw */ +#define XCHAL_HW_VERSION 230000 /* major*100+minor */ +#define XCHAL_HW_REL_LX3 1 +#define XCHAL_HW_REL_LX3_0 1 +#define XCHAL_HW_REL_LX3_0_0 1 +#define XCHAL_HW_CONFIGID_RELIABLE 1 +/* If software targets a *range* of hardware versions, these are the bounds: */ +#define XCHAL_HW_MIN_VERSION_MAJOR 2300 /* major v of earliest tgt hw */ +#define XCHAL_HW_MIN_VERSION_MINOR 0 /* minor v of earliest tgt hw */ +#define XCHAL_HW_MIN_VERSION 230000 /* earliest targeted hw */ +#define XCHAL_HW_MAX_VERSION_MAJOR 2300 /* major v of latest tgt hw */ +#define XCHAL_HW_MAX_VERSION_MINOR 0 /* minor v of latest tgt hw */ +#define XCHAL_HW_MAX_VERSION 230000 /* latest targeted hw */ + + +/*---------------------------------------------------------------------- + CACHE + ----------------------------------------------------------------------*/ + +#define XCHAL_ICACHE_LINESIZE 32 /* I-cache line size in bytes */ +#define XCHAL_DCACHE_LINESIZE 32 /* D-cache line size in bytes */ +#define XCHAL_ICACHE_LINEWIDTH 5 /* log2(I line size in bytes) */ +#define XCHAL_DCACHE_LINEWIDTH 5 /* log2(D line size in bytes) */ + +#define XCHAL_ICACHE_SIZE 16384 /* I-cache size in bytes or 0 */ +#define XCHAL_DCACHE_SIZE 16384 /* D-cache size in bytes or 0 */ + +#define XCHAL_DCACHE_IS_WRITEBACK 1 /* writeback feature */ +#define XCHAL_DCACHE_IS_COHERENT 1 /* MP coherence feature */ + + + + +/**************************************************************************** + Parameters Useful for PRIVILEGED (Supervisory or Non-Virtualized) Code + ****************************************************************************/ + + +#ifndef XTENSA_HAL_NON_PRIVILEGED_ONLY + +/*---------------------------------------------------------------------- + CACHE + ----------------------------------------------------------------------*/ + +#define XCHAL_HAVE_PIF 1 /* any outbound PIF present */ + +/* If present, cache size in bytes == (ways * 2^(linewidth + setwidth)). */ + +/* Number of cache sets in log2(lines per way): */ +#define XCHAL_ICACHE_SETWIDTH 8 +#define XCHAL_DCACHE_SETWIDTH 8 + +/* Cache set associativity (number of ways): */ +#define XCHAL_ICACHE_WAYS 2 +#define XCHAL_DCACHE_WAYS 2 + +/* Cache features: */ +#define XCHAL_ICACHE_LINE_LOCKABLE 0 +#define XCHAL_DCACHE_LINE_LOCKABLE 0 +#define XCHAL_ICACHE_ECC_PARITY 0 +#define XCHAL_DCACHE_ECC_PARITY 0 + +/* Cache access size in bytes (affects operation of SICW instruction): */ +#define XCHAL_ICACHE_ACCESS_SIZE 8 +#define XCHAL_DCACHE_ACCESS_SIZE 8 + +/* Number of encoded cache attr bits (see for decoded bits): */ +#define XCHAL_CA_BITS 4 + + +/*---------------------------------------------------------------------- + INTERNAL I/D RAM/ROMs and XLMI + ----------------------------------------------------------------------*/ + +#define XCHAL_NUM_INSTROM 0 /* number of core instr. ROMs */ +#define XCHAL_NUM_INSTRAM 0 /* number of core instr. RAMs */ +#define XCHAL_NUM_DATAROM 0 /* number of core data ROMs */ +#define XCHAL_NUM_DATARAM 0 /* number of core data RAMs */ +#define XCHAL_NUM_URAM 0 /* number of core unified RAMs*/ +#define XCHAL_NUM_XLMI 0 /* number of core XLMI ports */ + + +/*---------------------------------------------------------------------- + INTERRUPTS and TIMERS + ----------------------------------------------------------------------*/ + +#define XCHAL_HAVE_INTERRUPTS 1 /* interrupt option */ +#define XCHAL_HAVE_HIGHPRI_INTERRUPTS 1 /* med/high-pri. interrupts */ +#define XCHAL_HAVE_NMI 0 /* non-maskable interrupt */ +#define XCHAL_HAVE_CCOUNT 1 /* CCOUNT reg. (timer option) */ +#define XCHAL_NUM_TIMERS 2 /* number of CCOMPAREn regs */ +#define XCHAL_NUM_INTERRUPTS 12 /* number of interrupts */ +#define XCHAL_NUM_INTERRUPTS_LOG2 4 /* ceil(log2(NUM_INTERRUPTS)) */ +#define XCHAL_NUM_EXTINTERRUPTS 9 /* num of external interrupts */ +#define XCHAL_NUM_INTLEVELS 2 /* number of interrupt levels + (not including level zero) */ +#define XCHAL_EXCM_LEVEL 1 /* level masked by PS.EXCM */ + /* (always 1 in XEA1; levels 2 .. EXCM_LEVEL are "medium priority") */ + +/* Masks of interrupts at each interrupt level: */ +#define XCHAL_INTLEVEL1_MASK 0x00000FFF +#define XCHAL_INTLEVEL2_MASK 0x00000000 +#define XCHAL_INTLEVEL3_MASK 0x00000000 +#define XCHAL_INTLEVEL4_MASK 0x00000000 +#define XCHAL_INTLEVEL5_MASK 0x00000000 +#define XCHAL_INTLEVEL6_MASK 0x00000000 +#define XCHAL_INTLEVEL7_MASK 0x00000000 + +/* Masks of interrupts at each range 1..n of interrupt levels: */ +#define XCHAL_INTLEVEL1_ANDBELOW_MASK 0x00000FFF +#define XCHAL_INTLEVEL2_ANDBELOW_MASK 0x00000FFF +#define XCHAL_INTLEVEL3_ANDBELOW_MASK 0x00000FFF +#define XCHAL_INTLEVEL4_ANDBELOW_MASK 0x00000FFF +#define XCHAL_INTLEVEL5_ANDBELOW_MASK 0x00000FFF +#define XCHAL_INTLEVEL6_ANDBELOW_MASK 0x00000FFF +#define XCHAL_INTLEVEL7_ANDBELOW_MASK 0x00000FFF + +/* Level of each interrupt: */ +#define XCHAL_INT0_LEVEL 1 +#define XCHAL_INT1_LEVEL 1 +#define XCHAL_INT2_LEVEL 1 +#define XCHAL_INT3_LEVEL 1 +#define XCHAL_INT4_LEVEL 1 +#define XCHAL_INT5_LEVEL 1 +#define XCHAL_INT6_LEVEL 1 +#define XCHAL_INT7_LEVEL 1 +#define XCHAL_INT8_LEVEL 1 +#define XCHAL_INT9_LEVEL 1 +#define XCHAL_INT10_LEVEL 1 +#define XCHAL_INT11_LEVEL 1 +#define XCHAL_DEBUGLEVEL 2 /* debug interrupt level */ +#define XCHAL_HAVE_DEBUG_EXTERN_INT 1 /* OCD external db interrupt */ + +/* Type of each interrupt: */ +#define XCHAL_INT0_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT1_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT2_TYPE XTHAL_INTTYPE_EXTERN_EDGE +#define XCHAL_INT3_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT4_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT5_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT6_TYPE XTHAL_INTTYPE_TIMER +#define XCHAL_INT7_TYPE XTHAL_INTTYPE_SOFTWARE +#define XCHAL_INT8_TYPE XTHAL_INTTYPE_TIMER +#define XCHAL_INT9_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT10_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT11_TYPE XTHAL_INTTYPE_EXTERN_LEVEL + +/* Masks of interrupts for each type of interrupt: */ +#define XCHAL_INTTYPE_MASK_UNCONFIGURED 0xFFFFF000 +#define XCHAL_INTTYPE_MASK_SOFTWARE 0x00000080 +#define XCHAL_INTTYPE_MASK_EXTERN_EDGE 0x00000004 +#define XCHAL_INTTYPE_MASK_EXTERN_LEVEL 0x00000E3B +#define XCHAL_INTTYPE_MASK_TIMER 0x00000140 +#define XCHAL_INTTYPE_MASK_NMI 0x00000000 +#define XCHAL_INTTYPE_MASK_WRITE_ERROR 0x00000000 + +/* Interrupt numbers assigned to specific interrupt sources: */ +#define XCHAL_TIMER0_INTERRUPT 6 /* CCOMPARE0 */ +#define XCHAL_TIMER1_INTERRUPT 8 /* CCOMPARE1 */ +#define XCHAL_TIMER2_INTERRUPT XTHAL_TIMER_UNCONFIGURED +#define XCHAL_TIMER3_INTERRUPT XTHAL_TIMER_UNCONFIGURED + +/* Interrupt numbers for levels at which only one interrupt is configured: */ +/* (There are many interrupts each at level(s) 1.) */ + + +/* + * External interrupt vectors/levels. + * These macros describe how Xtensa processor interrupt numbers + * (as numbered internally, eg. in INTERRUPT and INTENABLE registers) + * map to external BInterrupt pins, for those interrupts + * configured as external (level-triggered, edge-triggered, or NMI). + * See the Xtensa processor databook for more details. + */ + +/* Core interrupt numbers mapped to each EXTERNAL interrupt number: */ +#define XCHAL_EXTINT0_NUM 0 /* (intlevel 1) */ +#define XCHAL_EXTINT1_NUM 1 /* (intlevel 1) */ +#define XCHAL_EXTINT2_NUM 2 /* (intlevel 1) */ +#define XCHAL_EXTINT3_NUM 3 /* (intlevel 1) */ +#define XCHAL_EXTINT4_NUM 4 /* (intlevel 1) */ +#define XCHAL_EXTINT5_NUM 5 /* (intlevel 1) */ +#define XCHAL_EXTINT6_NUM 9 /* (intlevel 1) */ +#define XCHAL_EXTINT7_NUM 10 /* (intlevel 1) */ +#define XCHAL_EXTINT8_NUM 11 /* (intlevel 1) */ + + +/*---------------------------------------------------------------------- + EXCEPTIONS and VECTORS + ----------------------------------------------------------------------*/ + +#define XCHAL_XEA_VERSION 2 /* Xtensa Exception Architecture + number: 1 == XEA1 (old) + 2 == XEA2 (new) + 0 == XEAX (extern) */ +#define XCHAL_HAVE_XEA1 0 /* Exception Architecture 1 */ +#define XCHAL_HAVE_XEA2 1 /* Exception Architecture 2 */ +#define XCHAL_HAVE_XEAX 0 /* External Exception Arch. */ +#define XCHAL_HAVE_EXCEPTIONS 1 /* exception option */ +#define XCHAL_HAVE_MEM_ECC_PARITY 0 /* local memory ECC/parity */ +#define XCHAL_HAVE_VECTOR_SELECT 1 /* relocatable vectors */ +#define XCHAL_HAVE_VECBASE 1 /* relocatable vectors */ +#define XCHAL_VECBASE_RESET_VADDR 0xD0000000 /* VECBASE reset value */ +#define XCHAL_VECBASE_RESET_PADDR 0x00000000 +#define XCHAL_RESET_VECBASE_OVERLAP 0 + +#define XCHAL_RESET_VECTOR0_VADDR 0xFE000000 +#define XCHAL_RESET_VECTOR0_PADDR 0xFE000000 +#define XCHAL_RESET_VECTOR1_VADDR 0xD8000500 +#define XCHAL_RESET_VECTOR1_PADDR 0x00000500 +#define XCHAL_RESET_VECTOR_VADDR 0xFE000000 +#define XCHAL_RESET_VECTOR_PADDR 0xFE000000 +#define XCHAL_USER_VECOFS 0x00000340 +#define XCHAL_USER_VECTOR_VADDR 0xD0000340 +#define XCHAL_USER_VECTOR_PADDR 0x00000340 +#define XCHAL_KERNEL_VECOFS 0x00000300 +#define XCHAL_KERNEL_VECTOR_VADDR 0xD0000300 +#define XCHAL_KERNEL_VECTOR_PADDR 0x00000300 +#define XCHAL_DOUBLEEXC_VECOFS 0x000003C0 +#define XCHAL_DOUBLEEXC_VECTOR_VADDR 0xD00003C0 +#define XCHAL_DOUBLEEXC_VECTOR_PADDR 0x000003C0 +#define XCHAL_WINDOW_OF4_VECOFS 0x00000000 +#define XCHAL_WINDOW_UF4_VECOFS 0x00000040 +#define XCHAL_WINDOW_OF8_VECOFS 0x00000080 +#define XCHAL_WINDOW_UF8_VECOFS 0x000000C0 +#define XCHAL_WINDOW_OF12_VECOFS 0x00000100 +#define XCHAL_WINDOW_UF12_VECOFS 0x00000140 +#define XCHAL_WINDOW_VECTORS_VADDR 0xD0000000 +#define XCHAL_WINDOW_VECTORS_PADDR 0x00000000 +#define XCHAL_INTLEVEL2_VECOFS 0x00000280 +#define XCHAL_INTLEVEL2_VECTOR_VADDR 0xD0000280 +#define XCHAL_INTLEVEL2_VECTOR_PADDR 0x00000280 +#define XCHAL_DEBUG_VECOFS XCHAL_INTLEVEL2_VECOFS +#define XCHAL_DEBUG_VECTOR_VADDR XCHAL_INTLEVEL2_VECTOR_VADDR +#define XCHAL_DEBUG_VECTOR_PADDR XCHAL_INTLEVEL2_VECTOR_PADDR + + +/*---------------------------------------------------------------------- + DEBUG + ----------------------------------------------------------------------*/ + +#define XCHAL_HAVE_OCD 1 /* OnChipDebug option */ +#define XCHAL_NUM_IBREAK 0 /* number of IBREAKn regs */ +#define XCHAL_NUM_DBREAK 0 /* number of DBREAKn regs */ +#define XCHAL_HAVE_OCD_DIR_ARRAY 0 /* faster OCD option */ + + +/*---------------------------------------------------------------------- + MMU + ----------------------------------------------------------------------*/ + +/* See core-matmap.h header file for more details. */ + +#define XCHAL_HAVE_TLBS 1 /* inverse of HAVE_CACHEATTR */ +#define XCHAL_HAVE_SPANNING_WAY 0 /* one way maps I+D 4GB vaddr */ +#define XCHAL_HAVE_IDENTITY_MAP 0 /* vaddr == paddr always */ +#define XCHAL_HAVE_CACHEATTR 0 /* CACHEATTR register present */ +#define XCHAL_HAVE_MIMIC_CACHEATTR 0 /* region protection */ +#define XCHAL_HAVE_XLT_CACHEATTR 0 /* region prot. w/translation */ +#define XCHAL_HAVE_PTP_MMU 1 /* full MMU (with page table + [autorefill] and protection) + usable for an MMU-based OS */ +/* If none of the above last 4 are set, it's a custom TLB configuration. */ +#define XCHAL_ITLB_ARF_ENTRIES_LOG2 2 /* log2(autorefill way size) */ +#define XCHAL_DTLB_ARF_ENTRIES_LOG2 2 /* log2(autorefill way size) */ + +#define XCHAL_MMU_ASID_BITS 8 /* number of bits in ASIDs */ +#define XCHAL_MMU_RINGS 4 /* number of rings (1..4) */ +#define XCHAL_MMU_RING_BITS 2 /* num of bits in RING field */ + +#endif /* !XTENSA_HAL_NON_PRIVILEGED_ONLY */ + + +#endif /* _XTENSA_CORE_CONFIGURATION_H */ diff --git a/arch/xtensa/variants/test_mmuhifi_c3/include/variant/tie-asm.h b/arch/xtensa/variants/test_mmuhifi_c3/include/variant/tie-asm.h new file mode 100644 index 0000000000000000000000000000000000000000..6e9d69caf7e69cff44a55111e638b6106c84ab66 --- /dev/null +++ b/arch/xtensa/variants/test_mmuhifi_c3/include/variant/tie-asm.h @@ -0,0 +1,182 @@ +/* + * This header file contains assembly-language definitions (assembly + * macros, etc.) for this specific Xtensa processor's TIE extensions + * and options. It is customized to this Xtensa processor configuration. + * + * This file is subject to the terms and conditions of version 2.1 of the GNU + * Lesser General Public License as published by the Free Software Foundation. + * + * Copyright (C) 1999-2009 Tensilica Inc. + */ + +#ifndef _XTENSA_CORE_TIE_ASM_H +#define _XTENSA_CORE_TIE_ASM_H + +/* Selection parameter values for save-area save/restore macros: */ +/* Option vs. TIE: */ +#define XTHAL_SAS_TIE 0x0001 /* custom extension or coprocessor */ +#define XTHAL_SAS_OPT 0x0002 /* optional (and not a coprocessor) */ +/* Whether used automatically by compiler: */ +#define XTHAL_SAS_NOCC 0x0004 /* not used by compiler w/o special opts/code */ +#define XTHAL_SAS_CC 0x0008 /* used by compiler without special opts/code */ +/* ABI handling across function calls: */ +#define XTHAL_SAS_CALR 0x0010 /* caller-saved */ +#define XTHAL_SAS_CALE 0x0020 /* callee-saved */ +#define XTHAL_SAS_GLOB 0x0040 /* global across function calls (in thread) */ +/* Misc */ +#define XTHAL_SAS_ALL 0xFFFF /* include all default NCP contents */ + + + +/* Macro to save all non-coprocessor (extra) custom TIE and optional state + * (not including zero-overhead loop registers). + * Save area ptr (clobbered): ptr (8 byte aligned) + * Scratch regs (clobbered): at1..at4 (only first XCHAL_NCP_NUM_ATMPS needed) + */ + .macro xchal_ncp_store ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL + xchal_sa_start \continue, \ofs + .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select + xchal_sa_align \ptr, 0, 1024-4, 4, 4 + rsr \at1, BR // boolean option + s32i \at1, \ptr, .Lxchal_ofs_ + 0 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 4 + .endif + .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select + xchal_sa_align \ptr, 0, 1024-4, 4, 4 + rsr \at1, SCOMPARE1 // conditional store option + s32i \at1, \ptr, .Lxchal_ofs_ + 0 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 4 + .endif + .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_GLOB) & ~\select + xchal_sa_align \ptr, 0, 1024-4, 4, 4 + rur \at1, THREADPTR // threadptr option + s32i \at1, \ptr, .Lxchal_ofs_ + 0 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 4 + .endif + .endm // xchal_ncp_store + +/* Macro to save all non-coprocessor (extra) custom TIE and optional state + * (not including zero-overhead loop registers). + * Save area ptr (clobbered): ptr (8 byte aligned) + * Scratch regs (clobbered): at1..at4 (only first XCHAL_NCP_NUM_ATMPS needed) + */ + .macro xchal_ncp_load ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL + xchal_sa_start \continue, \ofs + .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select + xchal_sa_align \ptr, 0, 1024-4, 4, 4 + l32i \at1, \ptr, .Lxchal_ofs_ + 0 + wsr \at1, BR // boolean option + .set .Lxchal_ofs_, .Lxchal_ofs_ + 4 + .endif + .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select + xchal_sa_align \ptr, 0, 1024-4, 4, 4 + l32i \at1, \ptr, .Lxchal_ofs_ + 0 + wsr \at1, SCOMPARE1 // conditional store option + .set .Lxchal_ofs_, .Lxchal_ofs_ + 4 + .endif + .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_GLOB) & ~\select + xchal_sa_align \ptr, 0, 1024-4, 4, 4 + l32i \at1, \ptr, .Lxchal_ofs_ + 0 + wur \at1, THREADPTR // threadptr option + .set .Lxchal_ofs_, .Lxchal_ofs_ + 4 + .endif + .endm // xchal_ncp_load + + + +#define XCHAL_NCP_NUM_ATMPS 1 + + + +/* Macro to save the state of TIE coprocessor AudioEngineLX. + * Save area ptr (clobbered): ptr (8 byte aligned) + * Scratch regs (clobbered): at1..at4 (only first XCHAL_CP1_NUM_ATMPS needed) + */ +#define xchal_cp_AudioEngineLX_store xchal_cp1_store +/* #define xchal_cp_AudioEngineLX_store_a2 xchal_cp1_store a2 a3 a4 a5 a6 */ + .macro xchal_cp1_store ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL + xchal_sa_start \continue, \ofs + .ifeq (XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select + xchal_sa_align \ptr, 0, 0, 1, 8 + rur240 \at1 // AE_OVF_SAR + s32i \at1, \ptr, 0 + rur241 \at1 // AE_BITHEAD + s32i \at1, \ptr, 4 + rur242 \at1 // AE_TS_FTS_BU_BP + s32i \at1, \ptr, 8 + rur243 \at1 // AE_SD_NO + s32i \at1, \ptr, 12 + AE_SP24X2S.I aep0, \ptr, 16 + AE_SP24X2S.I aep1, \ptr, 24 + AE_SP24X2S.I aep2, \ptr, 32 + AE_SP24X2S.I aep3, \ptr, 40 + AE_SP24X2S.I aep4, \ptr, 48 + AE_SP24X2S.I aep5, \ptr, 56 + addi \ptr, \ptr, 64 + AE_SP24X2S.I aep6, \ptr, 0 + AE_SP24X2S.I aep7, \ptr, 8 + AE_SQ56S.I aeq0, \ptr, 16 + AE_SQ56S.I aeq1, \ptr, 24 + AE_SQ56S.I aeq2, \ptr, 32 + AE_SQ56S.I aeq3, \ptr, 40 + .set .Lxchal_pofs_, .Lxchal_pofs_ + 64 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 112 + .endif + .endm // xchal_cp1_store + +/* Macro to restore the state of TIE coprocessor AudioEngineLX. + * Save area ptr (clobbered): ptr (8 byte aligned) + * Scratch regs (clobbered): at1..at4 (only first XCHAL_CP1_NUM_ATMPS needed) + */ +#define xchal_cp_AudioEngineLX_load xchal_cp1_load +/* #define xchal_cp_AudioEngineLX_load_a2 xchal_cp1_load a2 a3 a4 a5 a6 */ + .macro xchal_cp1_load ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL + xchal_sa_start \continue, \ofs + .ifeq (XTHAL_SAS_TIE | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select + xchal_sa_align \ptr, 0, 0, 1, 8 + l32i \at1, \ptr, 0 + wur240 \at1 // AE_OVF_SAR + l32i \at1, \ptr, 4 + wur241 \at1 // AE_BITHEAD + l32i \at1, \ptr, 8 + wur242 \at1 // AE_TS_FTS_BU_BP + l32i \at1, \ptr, 12 + wur243 \at1 // AE_SD_NO + addi \ptr, \ptr, 80 + AE_LQ56.I aeq0, \ptr, 0 + AE_LQ56.I aeq1, \ptr, 8 + AE_LQ56.I aeq2, \ptr, 16 + AE_LQ56.I aeq3, \ptr, 24 + AE_LP24X2.I aep0, \ptr, -64 + AE_LP24X2.I aep1, \ptr, -56 + AE_LP24X2.I aep2, \ptr, -48 + AE_LP24X2.I aep3, \ptr, -40 + AE_LP24X2.I aep4, \ptr, -32 + AE_LP24X2.I aep5, \ptr, -24 + AE_LP24X2.I aep6, \ptr, -16 + AE_LP24X2.I aep7, \ptr, -8 + .set .Lxchal_pofs_, .Lxchal_pofs_ + 80 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 112 + .endif + .endm // xchal_cp1_load + +#define XCHAL_CP1_NUM_ATMPS 1 +#define XCHAL_SA_NUM_ATMPS 1 + + /* Empty macros for unconfigured coprocessors: */ + .macro xchal_cp0_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp0_load p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp2_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp2_load p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp3_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp3_load p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp4_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp4_load p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp5_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp5_load p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp6_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp6_load p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp7_store p a b c d continue=0 ofs=-1 select=-1 ; .endm + .macro xchal_cp7_load p a b c d continue=0 ofs=-1 select=-1 ; .endm + +#endif /*_XTENSA_CORE_TIE_ASM_H*/ diff --git a/arch/xtensa/variants/test_mmuhifi_c3/include/variant/tie.h b/arch/xtensa/variants/test_mmuhifi_c3/include/variant/tie.h new file mode 100644 index 0000000000000000000000000000000000000000..fb1f5f004c92acb217b8babdf0923b5d634756fa --- /dev/null +++ b/arch/xtensa/variants/test_mmuhifi_c3/include/variant/tie.h @@ -0,0 +1,140 @@ +/* + * This header file describes this specific Xtensa processor's TIE extensions + * that extend basic Xtensa core functionality. It is customized to this + * Xtensa processor configuration. + * + * This file is subject to the terms and conditions of version 2.1 of the GNU + * Lesser General Public License as published by the Free Software Foundation. + * + * Copyright (C) 1999-2009 Tensilica Inc. + */ + +#ifndef _XTENSA_CORE_TIE_H +#define _XTENSA_CORE_TIE_H + +#define XCHAL_CP_NUM 1 /* number of coprocessors */ +#define XCHAL_CP_MAX 2 /* max CP ID + 1 (0 if none) */ +#define XCHAL_CP_MASK 0x02 /* bitmask of all CPs by ID */ +#define XCHAL_CP_PORT_MASK 0x00 /* bitmask of only port CPs */ + +/* Basic parameters of each coprocessor: */ +#define XCHAL_CP1_NAME "AudioEngineLX" +#define XCHAL_CP1_IDENT AudioEngineLX +#define XCHAL_CP1_SA_SIZE 112 /* size of state save area */ +#define XCHAL_CP1_SA_ALIGN 8 /* min alignment of save area */ +#define XCHAL_CP_ID_AUDIOENGINELX 1 /* coprocessor ID (0..7) */ + +/* Filler info for unassigned coprocessors, to simplify arrays etc: */ +#define XCHAL_CP0_SA_SIZE 0 +#define XCHAL_CP0_SA_ALIGN 1 +#define XCHAL_CP2_SA_SIZE 0 +#define XCHAL_CP2_SA_ALIGN 1 +#define XCHAL_CP3_SA_SIZE 0 +#define XCHAL_CP3_SA_ALIGN 1 +#define XCHAL_CP4_SA_SIZE 0 +#define XCHAL_CP4_SA_ALIGN 1 +#define XCHAL_CP5_SA_SIZE 0 +#define XCHAL_CP5_SA_ALIGN 1 +#define XCHAL_CP6_SA_SIZE 0 +#define XCHAL_CP6_SA_ALIGN 1 +#define XCHAL_CP7_SA_SIZE 0 +#define XCHAL_CP7_SA_ALIGN 1 + +/* Save area for non-coprocessor optional and custom (TIE) state: */ +#define XCHAL_NCP_SA_SIZE 12 +#define XCHAL_NCP_SA_ALIGN 4 + +/* Total save area for optional and custom state (NCP + CPn): */ +#define XCHAL_TOTAL_SA_SIZE 128 /* with 16-byte align padding */ +#define XCHAL_TOTAL_SA_ALIGN 8 /* actual minimum alignment */ + +/* + * Detailed contents of save areas. + * NOTE: caller must define the XCHAL_SA_REG macro (not defined here) + * before expanding the XCHAL_xxx_SA_LIST() macros. + * + * XCHAL_SA_REG(s,ccused,abikind,kind,opt,name,galign,align,asize, + * dbnum,base,regnum,bitsz,gapsz,reset,x...) + * + * s = passed from XCHAL_*_LIST(s), eg. to select how to expand + * ccused = set if used by compiler without special options or code + * abikind = 0 (caller-saved), 1 (callee-saved), or 2 (thread-global) + * kind = 0 (special reg), 1 (TIE user reg), or 2 (TIE regfile reg) + * opt = 0 (custom TIE extension or coprocessor), or 1 (optional reg) + * name = lowercase reg name (no quotes) + * galign = group byte alignment (power of 2) (galign >= align) + * align = register byte alignment (power of 2) + * asize = allocated size in bytes (asize*8 == bitsz + gapsz + padsz) + * (not including any pad bytes required to galign this or next reg) + * dbnum = unique target number f/debug (see ) + * base = reg shortname w/o index (or sr=special, ur=TIE user reg) + * regnum = reg index in regfile, or special/TIE-user reg number + * bitsz = number of significant bits (regfile width, or ur/sr mask bits) + * gapsz = intervening bits, if bitsz bits not stored contiguously + * (padsz = pad bits at end [TIE regfile] or at msbits [ur,sr] of asize) + * reset = register reset value (or 0 if undefined at reset) + * x = reserved for future use (0 until then) + * + * To filter out certain registers, e.g. to expand only the non-global + * registers used by the compiler, you can do something like this: + * + * #define XCHAL_SA_REG(s,ccused,p...) SELCC##ccused(p) + * #define SELCC0(p...) + * #define SELCC1(abikind,p...) SELAK##abikind(p) + * #define SELAK0(p...) REG(p) + * #define SELAK1(p...) REG(p) + * #define SELAK2(p...) + * #define REG(kind,tie,name,galn,aln,asz,csz,dbnum,base,rnum,bsz,rst,x...) \ + * ...what you want to expand... + */ + +#define XCHAL_NCP_SA_NUM 3 +#define XCHAL_NCP_SA_LIST(s) \ + XCHAL_SA_REG(s,0,0,0,1, br, 4, 4, 4,0x0204, sr,4 , 16,0,0,0) \ + XCHAL_SA_REG(s,0,0,0,1, scompare1, 4, 4, 4,0x020C, sr,12 , 32,0,0,0) \ + XCHAL_SA_REG(s,1,2,1,1, threadptr, 4, 4, 4,0x03E7, ur,231, 32,0,0,0) + +#define XCHAL_CP0_SA_NUM 0 +#define XCHAL_CP0_SA_LIST(s) /* empty */ + +#define XCHAL_CP1_SA_NUM 16 +#define XCHAL_CP1_SA_LIST(s) \ + XCHAL_SA_REG(s,0,0,1,0, ae_ovf_sar, 8, 4, 4,0x03F0, ur,240, 7,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, ae_bithead, 4, 4, 4,0x03F1, ur,241, 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0,ae_ts_fts_bu_bp, 4, 4, 4,0x03F2, ur,242, 16,0,0,0) \ + XCHAL_SA_REG(s,0,0,1,0, ae_sd_no, 4, 4, 4,0x03F3, ur,243, 28,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aep0, 8, 8, 8,0x0060, aep,0 , 48,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aep1, 8, 8, 8,0x0061, aep,1 , 48,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aep2, 8, 8, 8,0x0062, aep,2 , 48,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aep3, 8, 8, 8,0x0063, aep,3 , 48,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aep4, 8, 8, 8,0x0064, aep,4 , 48,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aep5, 8, 8, 8,0x0065, aep,5 , 48,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aep6, 8, 8, 8,0x0066, aep,6 , 48,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aep7, 8, 8, 8,0x0067, aep,7 , 48,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aeq0, 8, 8, 8,0x0068, aeq,0 , 56,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aeq1, 8, 8, 8,0x0069, aeq,1 , 56,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aeq2, 8, 8, 8,0x006A, aeq,2 , 56,0,0,0) \ + XCHAL_SA_REG(s,0,0,2,0, aeq3, 8, 8, 8,0x006B, aeq,3 , 56,0,0,0) + +#define XCHAL_CP2_SA_NUM 0 +#define XCHAL_CP2_SA_LIST(s) /* empty */ + +#define XCHAL_CP3_SA_NUM 0 +#define XCHAL_CP3_SA_LIST(s) /* empty */ + +#define XCHAL_CP4_SA_NUM 0 +#define XCHAL_CP4_SA_LIST(s) /* empty */ + +#define XCHAL_CP5_SA_NUM 0 +#define XCHAL_CP5_SA_LIST(s) /* empty */ + +#define XCHAL_CP6_SA_NUM 0 +#define XCHAL_CP6_SA_LIST(s) /* empty */ + +#define XCHAL_CP7_SA_NUM 0 +#define XCHAL_CP7_SA_LIST(s) /* empty */ + +/* Byte length of instruction from its first nibble (op0 field), per FLIX. */ +#define XCHAL_OP0_FORMAT_LENGTHS 3,3,3,3,3,3,3,3,2,2,2,2,2,2,3,8 + +#endif /*_XTENSA_CORE_TIE_H*/ diff --git a/block/bio.c b/block/bio.c index cf7591551b1716b74fa3765cb1c271a554e8ef56..807d25e466ec2ab7ae8c319e62a5621dc4fc29a7 100644 --- a/block/bio.c +++ b/block/bio.c @@ -296,13 +296,19 @@ void bio_reset(struct bio *bio) } EXPORT_SYMBOL(bio_reset); -static void bio_chain_endio(struct bio *bio) +static struct bio *__bio_chain_endio(struct bio *bio) { struct bio *parent = bio->bi_private; - parent->bi_error = bio->bi_error; - bio_endio(parent); + if (!parent->bi_error) + parent->bi_error = bio->bi_error; bio_put(bio); + return parent; +} + +static void bio_chain_endio(struct bio *bio) +{ + bio_endio(__bio_chain_endio(bio)); } /* @@ -1333,7 +1339,7 @@ struct bio *bio_map_user_iov(struct request_queue *q, * release the pages we didn't map into the bio, if any */ while (j < page_limit) - page_cache_release(pages[j++]); + put_page(pages[j++]); } kfree(pages); @@ -1359,7 +1365,7 @@ struct bio *bio_map_user_iov(struct request_queue *q, for (j = 0; j < nr_pages; j++) { if (!pages[j]) break; - page_cache_release(pages[j]); + put_page(pages[j]); } out: kfree(pages); @@ -1379,7 +1385,7 @@ static void __bio_unmap_user(struct bio *bio) if (bio_data_dir(bio) == READ) set_page_dirty_lock(bvec->bv_page); - page_cache_release(bvec->bv_page); + put_page(bvec->bv_page); } bio_put(bio); @@ -1609,8 +1615,8 @@ static void bio_release_pages(struct bio *bio) * the BIO and the offending pages and re-dirty the pages in process context. * * It is expected that bio_check_pages_dirty() will wholly own the BIO from - * here on. It will run one page_cache_release() against each page and will - * run one bio_put() against the BIO. + * here on. It will run one put_page() against each page and will run one + * bio_put() against the BIO. */ static void bio_dirty_fn(struct work_struct *work); @@ -1652,7 +1658,7 @@ void bio_check_pages_dirty(struct bio *bio) struct page *page = bvec->bv_page; if (PageDirty(page) || PageCompound(page)) { - page_cache_release(page); + put_page(page); bvec->bv_page = NULL; } else { nr_clean_pages++; @@ -1742,29 +1748,25 @@ static inline bool bio_remaining_done(struct bio *bio) **/ void bio_endio(struct bio *bio) { - while (bio) { - if (unlikely(!bio_remaining_done(bio))) - break; +again: + if (!bio_remaining_done(bio)) + return; - /* - * Need to have a real endio function for chained bios, - * otherwise various corner cases will break (like stacking - * block devices that save/restore bi_end_io) - however, we want - * to avoid unbounded recursion and blowing the stack. Tail call - * optimization would handle this, but compiling with frame - * pointers also disables gcc's sibling call optimization. - */ - if (bio->bi_end_io == bio_chain_endio) { - struct bio *parent = bio->bi_private; - parent->bi_error = bio->bi_error; - bio_put(bio); - bio = parent; - } else { - if (bio->bi_end_io) - bio->bi_end_io(bio); - bio = NULL; - } + /* + * Need to have a real endio function for chained bios, otherwise + * various corner cases will break (like stacking block devices that + * save/restore bi_end_io) - however, we want to avoid unbounded + * recursion and blowing the stack. Tail call optimization would + * handle this, but compiling with frame pointers also disables + * gcc's sibling call optimization. + */ + if (bio->bi_end_io == bio_chain_endio) { + bio = __bio_chain_endio(bio); + goto again; } + + if (bio->bi_end_io) + bio->bi_end_io(bio); } EXPORT_SYMBOL(bio_endio); diff --git a/block/blk-core.c b/block/blk-core.c index 45f4d7efbf349efa77f8c9d425e1d0ece4fbd9d4..b60537b2c35b4152343c0239374d8ba332865b09 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -706,7 +706,7 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id) goto fail_id; q->backing_dev_info.ra_pages = - (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE; + (VM_MAX_READAHEAD * 1024) / PAGE_SIZE; q->backing_dev_info.capabilities = BDI_CAP_CGROUP_WRITEBACK; q->backing_dev_info.name = "block"; q->node = node_id; @@ -3529,6 +3529,30 @@ void blk_post_runtime_resume(struct request_queue *q, int err) spin_unlock_irq(q->queue_lock); } EXPORT_SYMBOL(blk_post_runtime_resume); + +/** + * blk_set_runtime_active - Force runtime status of the queue to be active + * @q: the queue of the device + * + * If the device is left runtime suspended during system suspend the resume + * hook typically resumes the device and corrects runtime status + * accordingly. However, that does not affect the queue runtime PM status + * which is still "suspended". This prevents processing requests from the + * queue. + * + * This function can be used in driver's resume hook to correct queue + * runtime PM status and re-enable peeking requests from the queue. It + * should be called before first request is added to the queue. + */ +void blk_set_runtime_active(struct request_queue *q) +{ + spin_lock_irq(q->queue_lock); + q->rpm_status = RPM_ACTIVE; + pm_runtime_mark_last_busy(q->dev); + pm_request_autosuspend(q->dev); + spin_unlock_irq(q->queue_lock); +} +EXPORT_SYMBOL(blk_set_runtime_active); #endif int __init blk_dev_init(void) diff --git a/block/blk-mq-sysfs.c b/block/blk-mq-sysfs.c index 1cf18784c5cf3c44be94dbd003ca9d7088f883e0..4ea4dd8a1eed5a46763fd59f391faad8ff91d3b5 100644 --- a/block/blk-mq-sysfs.c +++ b/block/blk-mq-sysfs.c @@ -408,19 +408,22 @@ void blk_mq_unregister_disk(struct gendisk *disk) blk_mq_enable_hotplug(); } +void blk_mq_hctx_kobj_init(struct blk_mq_hw_ctx *hctx) +{ + kobject_init(&hctx->kobj, &blk_mq_hw_ktype); +} + static void blk_mq_sysfs_init(struct request_queue *q) { - struct blk_mq_hw_ctx *hctx; struct blk_mq_ctx *ctx; - int i; + int cpu; kobject_init(&q->mq_kobj, &blk_mq_ktype); - queue_for_each_hw_ctx(q, hctx, i) - kobject_init(&hctx->kobj, &blk_mq_hw_ktype); - - queue_for_each_ctx(q, ctx, i) + for_each_possible_cpu(cpu) { + ctx = per_cpu_ptr(q->queue_ctx, cpu); kobject_init(&ctx->kobj, &blk_mq_ctx_ktype); + } } int blk_mq_register_disk(struct gendisk *disk) diff --git a/block/blk-mq.c b/block/blk-mq.c index 56c0a726b619374ec9f8cf4b60649a14919f0625..1699baf39b78a8379c3cd5559b324d71da41f100 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -544,7 +544,10 @@ EXPORT_SYMBOL(blk_mq_abort_requeue_list); struct request *blk_mq_tag_to_rq(struct blk_mq_tags *tags, unsigned int tag) { - return tags->rqs[tag]; + if (tag < tags->nr_tags) + return tags->rqs[tag]; + + return NULL; } EXPORT_SYMBOL(blk_mq_tag_to_rq); @@ -1744,31 +1747,6 @@ static int blk_mq_init_hctx(struct request_queue *q, return -1; } -static int blk_mq_init_hw_queues(struct request_queue *q, - struct blk_mq_tag_set *set) -{ - struct blk_mq_hw_ctx *hctx; - unsigned int i; - - /* - * Initialize hardware queues - */ - queue_for_each_hw_ctx(q, hctx, i) { - if (blk_mq_init_hctx(q, set, hctx, i)) - break; - } - - if (i == q->nr_hw_queues) - return 0; - - /* - * Init failed - */ - blk_mq_exit_hw_queues(q, set, i); - - return 1; -} - static void blk_mq_init_cpu_queues(struct request_queue *q, unsigned int nr_hw_queues) { @@ -1820,12 +1798,14 @@ static void blk_mq_map_swqueue(struct request_queue *q, /* * Map software to hardware queues */ - queue_for_each_ctx(q, ctx, i) { + for_each_possible_cpu(i) { /* If the cpu isn't online, the cpu is mapped to first hctx */ if (!cpumask_test_cpu(i, online_mask)) continue; + ctx = per_cpu_ptr(q->queue_ctx, i); hctx = q->mq_ops->map_queue(q, i); + cpumask_set_cpu(i, hctx->cpumask); ctx->index_hw = hctx->nr_ctx; hctx->ctxs[hctx->nr_ctx++] = ctx; @@ -1974,56 +1954,93 @@ struct request_queue *blk_mq_init_queue(struct blk_mq_tag_set *set) } EXPORT_SYMBOL(blk_mq_init_queue); -struct request_queue *blk_mq_init_allocated_queue(struct blk_mq_tag_set *set, - struct request_queue *q) +static void blk_mq_realloc_hw_ctxs(struct blk_mq_tag_set *set, + struct request_queue *q) { - struct blk_mq_hw_ctx **hctxs; - struct blk_mq_ctx __percpu *ctx; - unsigned int *map; - int i; - - ctx = alloc_percpu(struct blk_mq_ctx); - if (!ctx) - return ERR_PTR(-ENOMEM); - - hctxs = kmalloc_node(set->nr_hw_queues * sizeof(*hctxs), GFP_KERNEL, - set->numa_node); - - if (!hctxs) - goto err_percpu; - - map = blk_mq_make_queue_map(set); - if (!map) - goto err_map; + int i, j; + struct blk_mq_hw_ctx **hctxs = q->queue_hw_ctx; + blk_mq_sysfs_unregister(q); for (i = 0; i < set->nr_hw_queues; i++) { - int node = blk_mq_hw_queue_to_node(map, i); + int node; + + if (hctxs[i]) + continue; + node = blk_mq_hw_queue_to_node(q->mq_map, i); hctxs[i] = kzalloc_node(sizeof(struct blk_mq_hw_ctx), GFP_KERNEL, node); if (!hctxs[i]) - goto err_hctxs; + break; if (!zalloc_cpumask_var_node(&hctxs[i]->cpumask, GFP_KERNEL, - node)) - goto err_hctxs; + node)) { + kfree(hctxs[i]); + hctxs[i] = NULL; + break; + } atomic_set(&hctxs[i]->nr_active, 0); hctxs[i]->numa_node = node; hctxs[i]->queue_num = i; + + if (blk_mq_init_hctx(q, set, hctxs[i], i)) { + free_cpumask_var(hctxs[i]->cpumask); + kfree(hctxs[i]); + hctxs[i] = NULL; + break; + } + blk_mq_hctx_kobj_init(hctxs[i]); + } + for (j = i; j < q->nr_hw_queues; j++) { + struct blk_mq_hw_ctx *hctx = hctxs[j]; + + if (hctx) { + if (hctx->tags) { + blk_mq_free_rq_map(set, hctx->tags, j); + set->tags[j] = NULL; + } + blk_mq_exit_hctx(q, set, hctx, j); + free_cpumask_var(hctx->cpumask); + kobject_put(&hctx->kobj); + kfree(hctx->ctxs); + kfree(hctx); + hctxs[j] = NULL; + + } } + q->nr_hw_queues = i; + blk_mq_sysfs_register(q); +} + +struct request_queue *blk_mq_init_allocated_queue(struct blk_mq_tag_set *set, + struct request_queue *q) +{ + /* mark the queue as mq asap */ + q->mq_ops = set->ops; + + q->queue_ctx = alloc_percpu(struct blk_mq_ctx); + if (!q->queue_ctx) + return ERR_PTR(-ENOMEM); + + q->queue_hw_ctx = kzalloc_node(nr_cpu_ids * sizeof(*(q->queue_hw_ctx)), + GFP_KERNEL, set->numa_node); + if (!q->queue_hw_ctx) + goto err_percpu; + + q->mq_map = blk_mq_make_queue_map(set); + if (!q->mq_map) + goto err_map; + + blk_mq_realloc_hw_ctxs(set, q); + if (!q->nr_hw_queues) + goto err_hctxs; INIT_WORK(&q->timeout_work, blk_mq_timeout_work); blk_queue_rq_timeout(q, set->timeout ? set->timeout : 30 * HZ); q->nr_queues = nr_cpu_ids; - q->nr_hw_queues = set->nr_hw_queues; - q->mq_map = map; - q->queue_ctx = ctx; - q->queue_hw_ctx = hctxs; - - q->mq_ops = set->ops; q->queue_flags |= QUEUE_FLAG_MQ_DEFAULT; if (!(set->flags & BLK_MQ_F_SG_MERGE)) @@ -2050,9 +2067,6 @@ struct request_queue *blk_mq_init_allocated_queue(struct blk_mq_tag_set *set, blk_mq_init_cpu_queues(q, set->nr_hw_queues); - if (blk_mq_init_hw_queues(q, set)) - goto err_hctxs; - get_online_cpus(); mutex_lock(&all_q_mutex); @@ -2066,17 +2080,11 @@ struct request_queue *blk_mq_init_allocated_queue(struct blk_mq_tag_set *set, return q; err_hctxs: - kfree(map); - for (i = 0; i < set->nr_hw_queues; i++) { - if (!hctxs[i]) - break; - free_cpumask_var(hctxs[i]->cpumask); - kfree(hctxs[i]); - } + kfree(q->mq_map); err_map: - kfree(hctxs); + kfree(q->queue_hw_ctx); err_percpu: - free_percpu(ctx); + free_percpu(q->queue_ctx); return ERR_PTR(-ENOMEM); } EXPORT_SYMBOL(blk_mq_init_allocated_queue); @@ -2284,9 +2292,13 @@ int blk_mq_alloc_tag_set(struct blk_mq_tag_set *set) set->nr_hw_queues = 1; set->queue_depth = min(64U, set->queue_depth); } + /* + * There is no use for more h/w queues than cpus. + */ + if (set->nr_hw_queues > nr_cpu_ids) + set->nr_hw_queues = nr_cpu_ids; - set->tags = kmalloc_node(set->nr_hw_queues * - sizeof(struct blk_mq_tags *), + set->tags = kzalloc_node(nr_cpu_ids * sizeof(struct blk_mq_tags *), GFP_KERNEL, set->numa_node); if (!set->tags) return -ENOMEM; @@ -2309,7 +2321,7 @@ void blk_mq_free_tag_set(struct blk_mq_tag_set *set) { int i; - for (i = 0; i < set->nr_hw_queues; i++) { + for (i = 0; i < nr_cpu_ids; i++) { if (set->tags[i]) blk_mq_free_rq_map(set, set->tags[i], i); } @@ -2330,6 +2342,8 @@ int blk_mq_update_nr_requests(struct request_queue *q, unsigned int nr) ret = 0; queue_for_each_hw_ctx(q, hctx, i) { + if (!hctx->tags) + continue; ret = blk_mq_tag_update_depth(hctx->tags, nr); if (ret) break; @@ -2341,6 +2355,35 @@ int blk_mq_update_nr_requests(struct request_queue *q, unsigned int nr) return ret; } +void blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, int nr_hw_queues) +{ + struct request_queue *q; + + if (nr_hw_queues > nr_cpu_ids) + nr_hw_queues = nr_cpu_ids; + if (nr_hw_queues < 1 || nr_hw_queues == set->nr_hw_queues) + return; + + list_for_each_entry(q, &set->tag_list, tag_set_list) + blk_mq_freeze_queue(q); + + set->nr_hw_queues = nr_hw_queues; + list_for_each_entry(q, &set->tag_list, tag_set_list) { + blk_mq_realloc_hw_ctxs(set, q); + + if (q->nr_hw_queues > 1) + blk_queue_make_request(q, blk_mq_make_request); + else + blk_queue_make_request(q, blk_sq_make_request); + + blk_mq_queue_reinit(q, cpu_online_mask); + } + + list_for_each_entry(q, &set->tag_list, tag_set_list) + blk_mq_unfreeze_queue(q); +} +EXPORT_SYMBOL_GPL(blk_mq_update_nr_hw_queues); + void blk_mq_disable_hotplug(void) { mutex_lock(&all_q_mutex); diff --git a/block/blk-mq.h b/block/blk-mq.h index eaede8e45c9c3e5f2555ea86ec39492e1c042e59..9087b11037b70ae514fd46ea10f659152f291aa2 100644 --- a/block/blk-mq.h +++ b/block/blk-mq.h @@ -57,6 +57,7 @@ extern int blk_mq_hw_queue_to_node(unsigned int *map, unsigned int); */ extern int blk_mq_sysfs_register(struct request_queue *q); extern void blk_mq_sysfs_unregister(struct request_queue *q); +extern void blk_mq_hctx_kobj_init(struct blk_mq_hw_ctx *hctx); extern void blk_mq_rq_timed_out(struct request *req, bool reserved); diff --git a/block/blk-settings.c b/block/blk-settings.c index c7bb666aafd100a329c67b97e616c9f9037c508e..331e4eee0dda0c29cc673b63c7e7341ae45e5859 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c @@ -239,8 +239,8 @@ void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_hw_secto struct queue_limits *limits = &q->limits; unsigned int max_sectors; - if ((max_hw_sectors << 9) < PAGE_CACHE_SIZE) { - max_hw_sectors = 1 << (PAGE_CACHE_SHIFT - 9); + if ((max_hw_sectors << 9) < PAGE_SIZE) { + max_hw_sectors = 1 << (PAGE_SHIFT - 9); printk(KERN_INFO "%s: set to minimum %d\n", __func__, max_hw_sectors); } @@ -329,8 +329,8 @@ EXPORT_SYMBOL(blk_queue_max_segments); **/ void blk_queue_max_segment_size(struct request_queue *q, unsigned int max_size) { - if (max_size < PAGE_CACHE_SIZE) { - max_size = PAGE_CACHE_SIZE; + if (max_size < PAGE_SIZE) { + max_size = PAGE_SIZE; printk(KERN_INFO "%s: set to minimum %d\n", __func__, max_size); } @@ -760,8 +760,8 @@ EXPORT_SYMBOL_GPL(blk_queue_dma_drain); **/ void blk_queue_segment_boundary(struct request_queue *q, unsigned long mask) { - if (mask < PAGE_CACHE_SIZE - 1) { - mask = PAGE_CACHE_SIZE - 1; + if (mask < PAGE_SIZE - 1) { + mask = PAGE_SIZE - 1; printk(KERN_INFO "%s: set to minimum %lx\n", __func__, mask); } diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index dd93763057ce0187dcc1b81602b75a43310d451d..995b58d46ed109b0c7241b6db5b870ed911dc845 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c @@ -76,7 +76,7 @@ queue_requests_store(struct request_queue *q, const char *page, size_t count) static ssize_t queue_ra_show(struct request_queue *q, char *page) { unsigned long ra_kb = q->backing_dev_info.ra_pages << - (PAGE_CACHE_SHIFT - 10); + (PAGE_SHIFT - 10); return queue_var_show(ra_kb, (page)); } @@ -90,7 +90,7 @@ queue_ra_store(struct request_queue *q, const char *page, size_t count) if (ret < 0) return ret; - q->backing_dev_info.ra_pages = ra_kb >> (PAGE_CACHE_SHIFT - 10); + q->backing_dev_info.ra_pages = ra_kb >> (PAGE_SHIFT - 10); return ret; } @@ -117,7 +117,7 @@ static ssize_t queue_max_segment_size_show(struct request_queue *q, char *page) if (blk_queue_cluster(q)) return queue_var_show(queue_max_segment_size(q), (page)); - return queue_var_show(PAGE_CACHE_SIZE, (page)); + return queue_var_show(PAGE_SIZE, (page)); } static ssize_t queue_logical_block_size_show(struct request_queue *q, char *page) @@ -198,7 +198,7 @@ queue_max_sectors_store(struct request_queue *q, const char *page, size_t count) { unsigned long max_sectors_kb, max_hw_sectors_kb = queue_max_hw_sectors(q) >> 1, - page_kb = 1 << (PAGE_CACHE_SHIFT - 10); + page_kb = 1 << (PAGE_SHIFT - 10); ssize_t ret = queue_var_store(&max_sectors_kb, page, count); if (ret < 0) diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 1f9093e901daed7849a54633be5d80ce96b010f4..4a349787bc6280b30d224c87d6800bef0ddd9a60 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -632,6 +632,13 @@ static inline struct cfq_group *cfqg_parent(struct cfq_group *cfqg) return pblkg ? blkg_to_cfqg(pblkg) : NULL; } +static inline bool cfqg_is_descendant(struct cfq_group *cfqg, + struct cfq_group *ancestor) +{ + return cgroup_is_descendant(cfqg_to_blkg(cfqg)->blkcg->css.cgroup, + cfqg_to_blkg(ancestor)->blkcg->css.cgroup); +} + static inline void cfqg_get(struct cfq_group *cfqg) { return blkg_get(cfqg_to_blkg(cfqg)); @@ -758,6 +765,11 @@ static void cfqg_stats_xfer_dead(struct cfq_group *cfqg) #else /* CONFIG_CFQ_GROUP_IOSCHED */ static inline struct cfq_group *cfqg_parent(struct cfq_group *cfqg) { return NULL; } +static inline bool cfqg_is_descendant(struct cfq_group *cfqg, + struct cfq_group *ancestor) +{ + return true; +} static inline void cfqg_get(struct cfq_group *cfqg) { } static inline void cfqg_put(struct cfq_group *cfqg) { } @@ -2897,6 +2909,7 @@ static bool cfq_should_idle(struct cfq_data *cfqd, struct cfq_queue *cfqq) static void cfq_arm_slice_timer(struct cfq_data *cfqd) { struct cfq_queue *cfqq = cfqd->active_queue; + struct cfq_rb_root *st = cfqq->service_tree; struct cfq_io_cq *cic; unsigned long sl, group_idle = 0; @@ -2947,8 +2960,13 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd) return; } - /* There are other queues in the group, don't do group idle */ - if (group_idle && cfqq->cfqg->nr_cfqq > 1) + /* + * There are other queues in the group or this is the only group and + * it has too big thinktime, don't do group idle. + */ + if (group_idle && + (cfqq->cfqg->nr_cfqq > 1 || + cfq_io_thinktime_big(cfqd, &st->ttime, true))) return; cfq_mark_cfqq_wait_request(cfqq); @@ -3947,16 +3965,27 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq, if (rq_is_sync(rq) && !cfq_cfqq_sync(cfqq)) return true; - if (new_cfqq->cfqg != cfqq->cfqg) + /* + * Treat ancestors of current cgroup the same way as current cgroup. + * For anybody else we disallow preemption to guarantee service + * fairness among cgroups. + */ + if (!cfqg_is_descendant(cfqq->cfqg, new_cfqq->cfqg)) return false; if (cfq_slice_used(cfqq)) return true; + /* + * Allow an RT request to pre-empt an ongoing non-RT cfqq timeslice. + */ + if (cfq_class_rt(new_cfqq) && !cfq_class_rt(cfqq)) + return true; + + WARN_ON_ONCE(cfqq->ioprio_class != new_cfqq->ioprio_class); /* Allow preemption only if we are idling on sync-noidle tree */ if (cfqd->serving_wl_type == SYNC_NOIDLE_WORKLOAD && cfqq_type(new_cfqq) == SYNC_NOIDLE_WORKLOAD && - new_cfqq->service_tree->count == 2 && RB_EMPTY_ROOT(&cfqq->sort_list)) return true; @@ -3967,12 +3996,6 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq, if ((rq->cmd_flags & REQ_PRIO) && !cfqq->prio_pending) return true; - /* - * Allow an RT request to pre-empt an ongoing non-RT cfqq timeslice. - */ - if (cfq_class_rt(new_cfqq) && !cfq_class_rt(cfqq)) - return true; - /* An idle queue should not be idle now for some reason */ if (RB_EMPTY_ROOT(&cfqq->sort_list) && !cfq_should_idle(cfqd, cfqq)) return true; @@ -4052,7 +4075,7 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, * idle timer unplug to continue working. */ if (cfq_cfqq_wait_request(cfqq)) { - if (blk_rq_bytes(rq) > PAGE_CACHE_SIZE || + if (blk_rq_bytes(rq) > PAGE_SIZE || cfqd->busy_queues > 1) { cfq_del_timer(cfqd, cfqq); cfq_clear_cfqq_wait_request(cfqq); diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c index f678c733df404189bdff2a87a01225c6aa124816..556826ac7cb4837c44d15d9f5576469d578055b3 100644 --- a/block/compat_ioctl.c +++ b/block/compat_ioctl.c @@ -710,7 +710,7 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg) return -EINVAL; bdi = blk_get_backing_dev_info(bdev); return compat_put_long(arg, - (bdi->ra_pages * PAGE_CACHE_SIZE) / 512); + (bdi->ra_pages * PAGE_SIZE) / 512); case BLKROGET: /* compatible */ return compat_put_int(arg, bdev_read_only(bdev) != 0); case BLKBSZGET_32: /* get the logical block size (cf. BLKSSZGET) */ @@ -729,7 +729,7 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg) if (!capable(CAP_SYS_ADMIN)) return -EACCES; bdi = blk_get_backing_dev_info(bdev); - bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE; + bdi->ra_pages = (arg * 512) / PAGE_SIZE; return 0; case BLKGETSIZE: size = i_size_read(bdev->bd_inode); diff --git a/block/ioctl.c b/block/ioctl.c index d8996bbd7f12805b9c74429813f5b3ee3d744bdc..4ff1f92f89ca0cec08830a71104e38d928592583 100644 --- a/block/ioctl.c +++ b/block/ioctl.c @@ -550,7 +550,7 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, if (!arg) return -EINVAL; bdi = blk_get_backing_dev_info(bdev); - return put_long(arg, (bdi->ra_pages * PAGE_CACHE_SIZE) / 512); + return put_long(arg, (bdi->ra_pages * PAGE_SIZE) / 512); case BLKROGET: return put_int(arg, bdev_read_only(bdev) != 0); case BLKBSZGET: /* get block device soft block size (cf. BLKSSZGET) */ @@ -578,7 +578,7 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, if(!capable(CAP_SYS_ADMIN)) return -EACCES; bdi = blk_get_backing_dev_info(bdev); - bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE; + bdi->ra_pages = (arg * 512) / PAGE_SIZE; return 0; case BLKBSZSET: return blkdev_bszset(bdev, mode, argp); diff --git a/block/partition-generic.c b/block/partition-generic.c index 5d87019410542951c8c94afffe9e4df62fdc8755..2c6ae2aed2c4711072386643d4260a808cb8d17b 100644 --- a/block/partition-generic.c +++ b/block/partition-generic.c @@ -566,8 +566,8 @@ static struct page *read_pagecache_sector(struct block_device *bdev, sector_t n) { struct address_space *mapping = bdev->bd_inode->i_mapping; - return read_mapping_page(mapping, (pgoff_t)(n >> (PAGE_CACHE_SHIFT-9)), - NULL); + return read_mapping_page(mapping, (pgoff_t)(n >> (PAGE_SHIFT-9)), + NULL); } unsigned char *read_dev_sector(struct block_device *bdev, sector_t n, Sector *p) @@ -584,9 +584,9 @@ unsigned char *read_dev_sector(struct block_device *bdev, sector_t n, Sector *p) if (PageError(page)) goto fail; p->v = page; - return (unsigned char *)page_address(page) + ((n & ((1 << (PAGE_CACHE_SHIFT - 9)) - 1)) << 9); + return (unsigned char *)page_address(page) + ((n & ((1 << (PAGE_SHIFT - 9)) - 1)) << 9); fail: - page_cache_release(page); + put_page(page); } p->v = NULL; return NULL; diff --git a/crypto/asymmetric_keys/pkcs7_trust.c b/crypto/asymmetric_keys/pkcs7_trust.c index 3bbdcc79a3d345549a51e816754559f2a650ccd9..7d7a39b47c6236a85cc5e9b3f5c42528a3c0fbb0 100644 --- a/crypto/asymmetric_keys/pkcs7_trust.c +++ b/crypto/asymmetric_keys/pkcs7_trust.c @@ -178,6 +178,8 @@ int pkcs7_validate_trust(struct pkcs7_message *pkcs7, int cached_ret = -ENOKEY; int ret; + *_trusted = false; + for (p = pkcs7->certs; p; p = p->next) p->seen = false; diff --git a/crypto/async_tx/async_pq.c b/crypto/async_tx/async_pq.c index c0748bbd4c083b47f78c662cdd7cb490590a2587..08b3ac68952b19fba6e4ab747744ca3317f0de9d 100644 --- a/crypto/async_tx/async_pq.c +++ b/crypto/async_tx/async_pq.c @@ -444,7 +444,7 @@ static int __init async_pq_init(void) static void __exit async_pq_exit(void) { - put_page(pq_scribble_page); + __free_page(pq_scribble_page); } module_init(async_pq_init); diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c index d0aad06b38720555a7da9138d5bc7f307100ca43..f245bf35bedb59c38dad79badfd8e084cccb5644 100644 --- a/drivers/acpi/acpi_apd.c +++ b/drivers/acpi/acpi_apd.c @@ -145,6 +145,7 @@ static const struct acpi_device_id acpi_apd_device_ids[] = { { "AMD0010", APD_ADDR(cz_i2c_desc) }, { "AMDI0010", APD_ADDR(cz_i2c_desc) }, { "AMD0020", APD_ADDR(cz_uart_desc) }, + { "AMDI0020", APD_ADDR(cz_uart_desc) }, { "AMD0030", }, #endif #ifdef CONFIG_ARM64 diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c index b5e54f2da53de81a9d31448265d3633e47f696b6..0d92d0f915e9acb0f04dcbce9583fcd16d7c8422 100644 --- a/drivers/acpi/acpi_processor.c +++ b/drivers/acpi/acpi_processor.c @@ -491,6 +491,58 @@ static void acpi_processor_remove(struct acpi_device *device) } #endif /* CONFIG_ACPI_HOTPLUG_CPU */ +#ifdef CONFIG_X86 +static bool acpi_hwp_native_thermal_lvt_set; +static acpi_status __init acpi_hwp_native_thermal_lvt_osc(acpi_handle handle, + u32 lvl, + void *context, + void **rv) +{ + u8 sb_uuid_str[] = "4077A616-290C-47BE-9EBD-D87058713953"; + u32 capbuf[2]; + struct acpi_osc_context osc_context = { + .uuid_str = sb_uuid_str, + .rev = 1, + .cap.length = 8, + .cap.pointer = capbuf, + }; + + if (acpi_hwp_native_thermal_lvt_set) + return AE_CTRL_TERMINATE; + + capbuf[0] = 0x0000; + capbuf[1] = 0x1000; /* set bit 12 */ + + if (ACPI_SUCCESS(acpi_run_osc(handle, &osc_context))) { + if (osc_context.ret.pointer && osc_context.ret.length > 1) { + u32 *capbuf_ret = osc_context.ret.pointer; + + if (capbuf_ret[1] & 0x1000) { + acpi_handle_info(handle, + "_OSC native thermal LVT Acked\n"); + acpi_hwp_native_thermal_lvt_set = true; + } + } + kfree(osc_context.ret.pointer); + } + + return AE_OK; +} + +void __init acpi_early_processor_osc(void) +{ + if (boot_cpu_has(X86_FEATURE_HWP)) { + acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, + ACPI_UINT32_MAX, + acpi_hwp_native_thermal_lvt_osc, + NULL, NULL, NULL); + acpi_get_devices(ACPI_PROCESSOR_DEVICE_HID, + acpi_hwp_native_thermal_lvt_osc, + NULL, NULL); + } +} +#endif + /* * The following ACPI IDs are known to be suitable for representing as * processor devices. diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 0e8567846f1afbce5185361be758cb743c0b6836..c068c829b4537da3c3d8427dd58713a4cfdb9e5b 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -1019,6 +1019,9 @@ static int __init acpi_bus_init(void) goto error1; } + /* Set capability bits for _OSC under processor scope */ + acpi_early_processor_osc(); + /* * _OSC method may exist in module level code, * so it must be run after ACPI_FULL_INITIALIZATION diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index a37508ef66c1b544dbf2a677c7a4c7608022cd40..7c188472d9c276f985f06f6c658e7329b7f2423b 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -145,6 +145,12 @@ void acpi_early_processor_set_pdc(void); static inline void acpi_early_processor_set_pdc(void) {} #endif +#ifdef CONFIG_X86 +void acpi_early_processor_osc(void); +#else +static inline void acpi_early_processor_osc(void) {} +#endif + /* -------------------------------------------------------------------------- Embedded Controller -------------------------------------------------------------------------- */ diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c index 2aee41655ce9223a264a56e11d439ddccc365632..f2fd3fee588a8233a80bdc5da3549fea5703b9f8 100644 --- a/drivers/acpi/property.c +++ b/drivers/acpi/property.c @@ -816,6 +816,7 @@ struct fwnode_handle *acpi_get_next_subnode(struct device *dev, next = adev->node.next; if (next == head) { child = NULL; + adev = ACPI_COMPANION(dev); goto nondev; } adev = list_entry(next, struct acpi_device, node); diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index d02fd53042a5d95603f1cd99176bff6b799dd9dd..56241eb341f4b0c3d995704619503ee4f3a8d8c3 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -27,8 +27,20 @@ #ifdef CONFIG_X86 #define valid_IRQ(i) (((i) != 0) && ((i) != 2)) +static inline bool acpi_iospace_resource_valid(struct resource *res) +{ + /* On X86 IO space is limited to the [0 - 64K] IO port range */ + return res->end < 0x10003; +} #else #define valid_IRQ(i) (true) +/* + * ACPI IO descriptors on arches other than X86 contain MMIO CPU physical + * addresses mapping IO space in CPU physical address space, IO space + * resources can be placed anywhere in the 64-bit physical address space. + */ +static inline bool +acpi_iospace_resource_valid(struct resource *res) { return true; } #endif static bool acpi_dev_resource_len_valid(u64 start, u64 end, u64 len, bool io) @@ -127,7 +139,7 @@ static void acpi_dev_ioresource_flags(struct resource *res, u64 len, if (!acpi_dev_resource_len_valid(res->start, res->end, len, true)) res->flags |= IORESOURCE_DISABLED | IORESOURCE_UNSET; - if (res->end >= 0x10003) + if (!acpi_iospace_resource_valid(res)) res->flags |= IORESOURCE_DISABLED | IORESOURCE_UNSET; if (io_decode == ACPI_DECODE_16) diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index fbfcce3b5227e0c4ea90e5838f8762582978ae99..2a8b5964429753b212a0f28ff9be5f19a7a1b777 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -748,6 +748,7 @@ static int acpi_hibernation_enter(void) static void acpi_hibernation_leave(void) { + pm_set_resume_via_firmware(); /* * If ACPI is not enabled by the BIOS and the boot kernel, we need to * enable it here. diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index f12a72428aacc76eef7a24845fe847ff55919e94..050673f0c0b3e4e382ad223e03ac4d655eb1be60 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -692,7 +692,7 @@ bool acpi_check_dsm(acpi_handle handle, const u8 *uuid, int rev, u64 funcs) mask = obj->integer.value; else if (obj->type == ACPI_TYPE_BUFFER) for (i = 0; i < obj->buffer.length && i < 8; i++) - mask |= (((u8)obj->buffer.pointer[i]) << (i * 8)); + mask |= (((u64)obj->buffer.pointer[i]) << (i * 8)); ACPI_FREE(obj); /* diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 57f52a2afa356788d4ee18f02867361da2b20a26..16288e777ec3dfdb50db2b133dd44f7e0045d8ad 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2744,6 +2744,10 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) /*pr_info("binder_ioctl: %d:%d %x %lx\n", proc->pid, current->pid, cmd, arg);*/ + if (unlikely(current->mm != proc->vma_vm_mm)) { + pr_err("current mm mismatch proc mm\n"); + return -EINVAL; + } trace_binder_ioctl(cmd, arg); ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2); @@ -2958,6 +2962,7 @@ static int binder_open(struct inode *nodp, struct file *filp) return -ENOMEM; get_task_struct(current); proc->tsk = current; + proc->vma_vm_mm = current->mm; INIT_LIST_HEAD(&proc->todo); init_waitqueue_head(&proc->wait); proc->default_priority = task_nice(current); diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 861643ea91b5b5c1d13d4b01a5311e2dcd6171ec..5083f85efea76edb7f2968ffa967becbf4d4943a 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -151,6 +151,15 @@ config AHCI_MVEBU If unsure, say N. +config AHCI_OCTEON + tristate "Cavium Octeon Soc Serial ATA" + depends on SATA_AHCI_PLATFORM && CAVIUM_OCTEON_SOC + default y + help + This option enables support for Cavium Octeon SoC Serial ATA. + + If unsure, say N. + config AHCI_SUNXI tristate "Allwinner sunxi AHCI SATA support" depends on ARCH_SUNXI @@ -355,7 +364,7 @@ config SATA_PROMISE config SATA_RCAR tristate "Renesas R-Car SATA support" - depends on ARCH_SHMOBILE || COMPILE_TEST + depends on ARCH_RENESAS || COMPILE_TEST help This option enables support for Renesas R-Car Serial ATA. diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index af45effac18c144f569080b944b595eaaae78fea..18579521464e48e22001838ab4d0abf3efbc4b0a 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_AHCI_CEVA) += ahci_ceva.o libahci.o libahci_platform.o obj-$(CONFIG_AHCI_DA850) += ahci_da850.o libahci.o libahci_platform.o obj-$(CONFIG_AHCI_IMX) += ahci_imx.o libahci.o libahci_platform.o obj-$(CONFIG_AHCI_MVEBU) += ahci_mvebu.o libahci.o libahci_platform.o +obj-$(CONFIG_AHCI_OCTEON) += ahci_octeon.o obj-$(CONFIG_AHCI_SUNXI) += ahci_sunxi.o libahci.o libahci_platform.o obj-$(CONFIG_AHCI_ST) += ahci_st.o libahci.o libahci_platform.o obj-$(CONFIG_AHCI_TEGRA) += ahci_tegra.o libahci.o libahci_platform.o diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 146dc0b8ec61752c03278cf5121061aaaf4c27ce..a83bbcc58b4c231b7cab78741dcfa8c7fee8b7b6 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -85,6 +85,7 @@ enum board_ids { }; static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); +static void ahci_remove_one(struct pci_dev *dev); static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class, unsigned long deadline); static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class, @@ -94,9 +95,13 @@ static bool is_mcp89_apple(struct pci_dev *pdev); static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class, unsigned long deadline); #ifdef CONFIG_PM -static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); -static int ahci_pci_device_resume(struct pci_dev *pdev); +static int ahci_pci_device_runtime_suspend(struct device *dev); +static int ahci_pci_device_runtime_resume(struct device *dev); +#ifdef CONFIG_PM_SLEEP +static int ahci_pci_device_suspend(struct device *dev); +static int ahci_pci_device_resume(struct device *dev); #endif +#endif /* CONFIG_PM */ static struct scsi_host_template ahci_sht = { AHCI_SHT("ahci"), @@ -371,15 +376,11 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* Lewisburg RAID*/ { PCI_VDEVICE(INTEL, 0x2827), board_ahci }, /* Lewisburg RAID*/ { PCI_VDEVICE(INTEL, 0xa182), board_ahci }, /* Lewisburg AHCI*/ - { PCI_VDEVICE(INTEL, 0xa184), board_ahci }, /* Lewisburg RAID*/ { PCI_VDEVICE(INTEL, 0xa186), board_ahci }, /* Lewisburg RAID*/ - { PCI_VDEVICE(INTEL, 0xa18e), board_ahci }, /* Lewisburg RAID*/ { PCI_VDEVICE(INTEL, 0xa1d2), board_ahci }, /* Lewisburg RAID*/ { PCI_VDEVICE(INTEL, 0xa1d6), board_ahci }, /* Lewisburg RAID*/ { PCI_VDEVICE(INTEL, 0xa202), board_ahci }, /* Lewisburg AHCI*/ - { PCI_VDEVICE(INTEL, 0xa204), board_ahci }, /* Lewisburg RAID*/ { PCI_VDEVICE(INTEL, 0xa206), board_ahci }, /* Lewisburg RAID*/ - { PCI_VDEVICE(INTEL, 0xa20e), board_ahci }, /* Lewisburg RAID*/ { PCI_VDEVICE(INTEL, 0xa252), board_ahci }, /* Lewisburg RAID*/ { PCI_VDEVICE(INTEL, 0xa256), board_ahci }, /* Lewisburg RAID*/ @@ -563,16 +564,20 @@ static const struct pci_device_id ahci_pci_tbl[] = { { } /* terminate list */ }; +static const struct dev_pm_ops ahci_pci_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(ahci_pci_device_suspend, ahci_pci_device_resume) + SET_RUNTIME_PM_OPS(ahci_pci_device_runtime_suspend, + ahci_pci_device_runtime_resume, NULL) +}; static struct pci_driver ahci_pci_driver = { .name = DRV_NAME, .id_table = ahci_pci_tbl, .probe = ahci_init_one, - .remove = ata_pci_remove_one, -#ifdef CONFIG_PM - .suspend = ahci_pci_device_suspend, - .resume = ahci_pci_device_resume, -#endif + .remove = ahci_remove_one, + .driver = { + .pm = &ahci_pci_pm_ops, + }, }; #if defined(CONFIG_PATA_MARVELL) || defined(CONFIG_PATA_MARVELL_MODULE) @@ -801,42 +806,66 @@ static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class, #ifdef CONFIG_PM -static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) +static void ahci_pci_disable_interrupts(struct ata_host *host) { - struct ata_host *host = pci_get_drvdata(pdev); struct ahci_host_priv *hpriv = host->private_data; void __iomem *mmio = hpriv->mmio; u32 ctl; - if (mesg.event & PM_EVENT_SUSPEND && - hpriv->flags & AHCI_HFLAG_NO_SUSPEND) { - dev_err(&pdev->dev, - "BIOS update required for suspend/resume\n"); - return -EIO; - } + /* AHCI spec rev1.1 section 8.3.3: + * Software must disable interrupts prior to requesting a + * transition of the HBA to D3 state. + */ + ctl = readl(mmio + HOST_CTL); + ctl &= ~HOST_IRQ_EN; + writel(ctl, mmio + HOST_CTL); + readl(mmio + HOST_CTL); /* flush */ +} - if (mesg.event & PM_EVENT_SLEEP) { - /* AHCI spec rev1.1 section 8.3.3: - * Software must disable interrupts prior to requesting a - * transition of the HBA to D3 state. - */ - ctl = readl(mmio + HOST_CTL); - ctl &= ~HOST_IRQ_EN; - writel(ctl, mmio + HOST_CTL); - readl(mmio + HOST_CTL); /* flush */ - } +static int ahci_pci_device_runtime_suspend(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct ata_host *host = pci_get_drvdata(pdev); - return ata_pci_device_suspend(pdev, mesg); + ahci_pci_disable_interrupts(host); + return 0; } -static int ahci_pci_device_resume(struct pci_dev *pdev) +static int ahci_pci_device_runtime_resume(struct device *dev) { + struct pci_dev *pdev = to_pci_dev(dev); struct ata_host *host = pci_get_drvdata(pdev); int rc; - rc = ata_pci_device_do_resume(pdev); + rc = ahci_pci_reset_controller(host); if (rc) return rc; + ahci_pci_init_controller(host); + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int ahci_pci_device_suspend(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct ata_host *host = pci_get_drvdata(pdev); + struct ahci_host_priv *hpriv = host->private_data; + + if (hpriv->flags & AHCI_HFLAG_NO_SUSPEND) { + dev_err(&pdev->dev, + "BIOS update required for suspend/resume\n"); + return -EIO; + } + + ahci_pci_disable_interrupts(host); + return ata_host_suspend(host, PMSG_SUSPEND); +} + +static int ahci_pci_device_resume(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct ata_host *host = pci_get_drvdata(pdev); + int rc; /* Apple BIOS helpfully mangles the registers on resume */ if (is_mcp89_apple(pdev)) @@ -856,6 +885,8 @@ static int ahci_pci_device_resume(struct pci_dev *pdev) } #endif +#endif /* CONFIG_PM */ + static int ahci_configure_dma_masks(struct pci_dev *pdev, int using_dac) { int rc; @@ -1718,7 +1749,18 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_master(pdev); - return ahci_host_activate(host, &ahci_sht); + rc = ahci_host_activate(host, &ahci_sht); + if (rc) + return rc; + + pm_runtime_put_noidle(&pdev->dev); + return 0; +} + +static void ahci_remove_one(struct pci_dev *pdev) +{ + pm_runtime_get_noresume(&pdev->dev); + ata_pci_remove_one(pdev); } module_pci_driver(ahci_pci_driver); diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index 167ba7e3b92e8fcec115ddcbd1988326e7c67ba5..70b06bcfb7e3535b47e02a913da680f67595888e 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h @@ -335,6 +335,7 @@ struct ahci_host_priv { void __iomem * mmio; /* bus-independent mem map */ u32 cap; /* cap to use */ u32 cap2; /* cap2 to use */ + u32 version; /* cached version */ u32 port_map; /* port map to use */ u32 saved_cap; /* saved initial cap */ u32 saved_cap2; /* saved initial cap2 */ diff --git a/drivers/ata/ahci_mvebu.c b/drivers/ata/ahci_mvebu.c index f7a7fa81740e8f7e7f1daa0c6d6e48d344496ceb..de7128d81e9ccbc168627a02bb2a39d3e4f11c5c 100644 --- a/drivers/ata/ahci_mvebu.c +++ b/drivers/ata/ahci_mvebu.c @@ -112,12 +112,15 @@ static int ahci_mvebu_probe(struct platform_device *pdev) if (rc) return rc; - dram = mv_mbus_dram_info(); - if (!dram) - return -ENODEV; + if (of_device_is_compatible(pdev->dev.of_node, + "marvell,armada-380-ahci")) { + dram = mv_mbus_dram_info(); + if (!dram) + return -ENODEV; - ahci_mvebu_mbus_config(hpriv, dram); - ahci_mvebu_regret_option(hpriv); + ahci_mvebu_mbus_config(hpriv, dram); + ahci_mvebu_regret_option(hpriv); + } rc = ahci_platform_init_host(pdev, hpriv, &ahci_mvebu_port_info, &ahci_platform_sht); @@ -133,6 +136,7 @@ static int ahci_mvebu_probe(struct platform_device *pdev) static const struct of_device_id ahci_mvebu_of_match[] = { { .compatible = "marvell,armada-380-ahci", }, + { .compatible = "marvell,armada-3700-ahci", }, { }, }; MODULE_DEVICE_TABLE(of, ahci_mvebu_of_match); diff --git a/drivers/ata/ahci_octeon.c b/drivers/ata/ahci_octeon.c new file mode 100644 index 0000000000000000000000000000000000000000..ea865fe953e1f8c620ef896164be71e7a8bb8740 --- /dev/null +++ b/drivers/ata/ahci_octeon.c @@ -0,0 +1,105 @@ +/* + * SATA glue for Cavium Octeon III SOCs. + * + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2010-2015 Cavium Networks + * + */ + +#include +#include +#include +#include + +#include +#include + +#define CVMX_SATA_UCTL_SHIM_CFG 0xE8 + +#define SATA_UCTL_ENDIAN_MODE_BIG 1 +#define SATA_UCTL_ENDIAN_MODE_LITTLE 0 +#define SATA_UCTL_ENDIAN_MODE_MASK 3 + +#define SATA_UCTL_DMA_ENDIAN_MODE_SHIFT 8 +#define SATA_UCTL_CSR_ENDIAN_MODE_SHIFT 0 +#define SATA_UCTL_DMA_READ_CMD_SHIFT 12 + +static int ahci_octeon_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *node = dev->of_node; + struct resource *res; + void __iomem *base; + u64 cfg; + int ret; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "Platform resource[0] is missing\n"); + return -ENODEV; + } + + base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + cfg = cvmx_readq_csr(base + CVMX_SATA_UCTL_SHIM_CFG); + + cfg &= ~(SATA_UCTL_ENDIAN_MODE_MASK << SATA_UCTL_DMA_ENDIAN_MODE_SHIFT); + cfg &= ~(SATA_UCTL_ENDIAN_MODE_MASK << SATA_UCTL_CSR_ENDIAN_MODE_SHIFT); + +#ifdef __BIG_ENDIAN + cfg |= SATA_UCTL_ENDIAN_MODE_BIG << SATA_UCTL_DMA_ENDIAN_MODE_SHIFT; + cfg |= SATA_UCTL_ENDIAN_MODE_BIG << SATA_UCTL_CSR_ENDIAN_MODE_SHIFT; +#else + cfg |= SATA_UCTL_ENDIAN_MODE_LITTLE << SATA_UCTL_DMA_ENDIAN_MODE_SHIFT; + cfg |= SATA_UCTL_ENDIAN_MODE_LITTLE << SATA_UCTL_CSR_ENDIAN_MODE_SHIFT; +#endif + + cfg |= 1 << SATA_UCTL_DMA_READ_CMD_SHIFT; + + cvmx_writeq_csr(base + CVMX_SATA_UCTL_SHIM_CFG, cfg); + + if (!node) { + dev_err(dev, "no device node, failed to add octeon sata\n"); + return -ENODEV; + } + + ret = of_platform_populate(node, NULL, NULL, dev); + if (ret) { + dev_err(dev, "failed to add ahci-platform core\n"); + return ret; + } + + return 0; +} + +static int ahci_octeon_remove(struct platform_device *pdev) +{ + return 0; +} + +static const struct of_device_id octeon_ahci_match[] = { + { .compatible = "cavium,octeon-7130-sata-uctl", }, + {}, +}; +MODULE_DEVICE_TABLE(of, octeon_ahci_match); + +static struct platform_driver ahci_octeon_driver = { + .probe = ahci_octeon_probe, + .remove = ahci_octeon_remove, + .driver = { + .name = "octeon-ahci", + .of_match_table = octeon_ahci_match, + }, +}; + +module_platform_driver(ahci_octeon_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Cavium, Inc. "); +MODULE_DESCRIPTION("Cavium Inc. sata config."); diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index 04975b851c237c4894282f94feed4ad19a1c9b01..40442332bfa7c154b93b540eae3eb8ae94e6d9f3 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c @@ -76,6 +76,7 @@ static const struct of_device_id ahci_of_match[] = { { .compatible = "ibm,476gtr-ahci", }, { .compatible = "snps,dwc-ahci", }, { .compatible = "hisilicon,hisi-ahci", }, + { .compatible = "cavium,octeon-7130-ahci", }, {}, }; MODULE_DEVICE_TABLE(of, ahci_of_match); diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c index 8e3f7faf00d383f8eea284fe122e90a44ee7ce40..73b19b2771385517b094d5fd548f3abf91751b2f 100644 --- a/drivers/ata/ahci_xgene.c +++ b/drivers/ata/ahci_xgene.c @@ -821,9 +821,9 @@ static int xgene_ahci_probe(struct platform_device *pdev) dev_warn(&pdev->dev, "%s: Error reading device info. Assume version1\n", __func__); version = XGENE_AHCI_V1; - } - if (info->valid & ACPI_VALID_CID) + } else if (info->valid & ACPI_VALID_CID) { version = XGENE_AHCI_V2; + } } } #endif diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 85ea5142a09518acc9e5c781fffbbf737f262f31..3982054060b81bb0d253b001883b32e346c6dc74 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -225,6 +225,31 @@ static void ahci_enable_ahci(void __iomem *mmio) WARN_ON(1); } +/** + * ahci_rpm_get_port - Make sure the port is powered on + * @ap: Port to power on + * + * Whenever there is need to access the AHCI host registers outside of + * normal execution paths, call this function to make sure the host is + * actually powered on. + */ +static int ahci_rpm_get_port(struct ata_port *ap) +{ + return pm_runtime_get_sync(ap->dev); +} + +/** + * ahci_rpm_put_port - Undoes ahci_rpm_get_port() + * @ap: Port to power down + * + * Undoes ahci_rpm_get_port() and possibly powers down the AHCI host + * if it has no more active users. + */ +static void ahci_rpm_put_port(struct ata_port *ap) +{ + pm_runtime_put(ap->dev); +} + static ssize_t ahci_show_host_caps(struct device *dev, struct device_attribute *attr, char *buf) { @@ -251,9 +276,8 @@ static ssize_t ahci_show_host_version(struct device *dev, struct Scsi_Host *shost = class_to_shost(dev); struct ata_port *ap = ata_shost_to_port(shost); struct ahci_host_priv *hpriv = ap->host->private_data; - void __iomem *mmio = hpriv->mmio; - return sprintf(buf, "%x\n", readl(mmio + HOST_VERSION)); + return sprintf(buf, "%x\n", hpriv->version); } static ssize_t ahci_show_port_cmd(struct device *dev, @@ -262,8 +286,13 @@ static ssize_t ahci_show_port_cmd(struct device *dev, struct Scsi_Host *shost = class_to_shost(dev); struct ata_port *ap = ata_shost_to_port(shost); void __iomem *port_mmio = ahci_port_base(ap); + ssize_t ret; + + ahci_rpm_get_port(ap); + ret = sprintf(buf, "%x\n", readl(port_mmio + PORT_CMD)); + ahci_rpm_put_port(ap); - return sprintf(buf, "%x\n", readl(port_mmio + PORT_CMD)); + return ret; } static ssize_t ahci_read_em_buffer(struct device *dev, @@ -279,17 +308,20 @@ static ssize_t ahci_read_em_buffer(struct device *dev, size_t count; int i; + ahci_rpm_get_port(ap); spin_lock_irqsave(ap->lock, flags); em_ctl = readl(mmio + HOST_EM_CTL); if (!(ap->flags & ATA_FLAG_EM) || em_ctl & EM_CTL_XMT || !(hpriv->em_msg_type & EM_MSG_TYPE_SGPIO)) { spin_unlock_irqrestore(ap->lock, flags); + ahci_rpm_put_port(ap); return -EINVAL; } if (!(em_ctl & EM_CTL_MR)) { spin_unlock_irqrestore(ap->lock, flags); + ahci_rpm_put_port(ap); return -EAGAIN; } @@ -317,6 +349,7 @@ static ssize_t ahci_read_em_buffer(struct device *dev, } spin_unlock_irqrestore(ap->lock, flags); + ahci_rpm_put_port(ap); return i; } @@ -341,11 +374,13 @@ static ssize_t ahci_store_em_buffer(struct device *dev, size % 4 || size > hpriv->em_buf_sz) return -EINVAL; + ahci_rpm_get_port(ap); spin_lock_irqsave(ap->lock, flags); em_ctl = readl(mmio + HOST_EM_CTL); if (em_ctl & EM_CTL_TM) { spin_unlock_irqrestore(ap->lock, flags); + ahci_rpm_put_port(ap); return -EBUSY; } @@ -358,6 +393,7 @@ static ssize_t ahci_store_em_buffer(struct device *dev, writel(em_ctl | EM_CTL_TM, mmio + HOST_EM_CTL); spin_unlock_irqrestore(ap->lock, flags); + ahci_rpm_put_port(ap); return size; } @@ -371,7 +407,9 @@ static ssize_t ahci_show_em_supported(struct device *dev, void __iomem *mmio = hpriv->mmio; u32 em_ctl; + ahci_rpm_get_port(ap); em_ctl = readl(mmio + HOST_EM_CTL); + ahci_rpm_put_port(ap); return sprintf(buf, "%s%s%s%s\n", em_ctl & EM_CTL_LED ? "led " : "", @@ -509,6 +547,7 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv) /* record values to use during operation */ hpriv->cap = cap; hpriv->cap2 = cap2; + hpriv->version = readl(mmio + HOST_VERSION); hpriv->port_map = port_map; if (!hpriv->start_engine) @@ -1014,6 +1053,7 @@ static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state, else return -EINVAL; + ahci_rpm_get_port(ap); spin_lock_irqsave(ap->lock, flags); /* @@ -1023,6 +1063,7 @@ static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state, em_ctl = readl(mmio + HOST_EM_CTL); if (em_ctl & EM_CTL_TM) { spin_unlock_irqrestore(ap->lock, flags); + ahci_rpm_put_port(ap); return -EBUSY; } @@ -1050,6 +1091,8 @@ static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state, emp->led_state = state; spin_unlock_irqrestore(ap->lock, flags); + ahci_rpm_put_port(ap); + return size; } @@ -2215,6 +2258,8 @@ static void ahci_pmp_detach(struct ata_port *ap) int ahci_port_resume(struct ata_port *ap) { + ahci_rpm_get_port(ap); + ahci_power_up(ap); ahci_start_port(ap); @@ -2241,6 +2286,7 @@ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg) ata_port_freeze(ap); } + ahci_rpm_put_port(ap); return rc; } #endif @@ -2356,11 +2402,10 @@ static void ahci_port_stop(struct ata_port *ap) void ahci_print_info(struct ata_host *host, const char *scc_s) { struct ahci_host_priv *hpriv = host->private_data; - void __iomem *mmio = hpriv->mmio; u32 vers, cap, cap2, impl, speed; const char *speed_s; - vers = readl(mmio + HOST_VERSION); + vers = hpriv->version; cap = hpriv->cap; cap2 = hpriv->cap2; impl = hpriv->port_map; diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index e417e1a1d02c568595fa465682ade483a9d0645a..567859ce0512f8e61a46b4c10d9aa3b788493617 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -174,13 +174,13 @@ static ssize_t ata_scsi_park_show(struct device *device, struct ata_port *ap; struct ata_link *link; struct ata_device *dev; - unsigned long flags, now; + unsigned long now; unsigned int uninitialized_var(msecs); int rc = 0; ap = ata_shost_to_port(sdev->host); - spin_lock_irqsave(ap->lock, flags); + spin_lock_irq(ap->lock); dev = ata_scsi_find_dev(ap, sdev); if (!dev) { rc = -ENODEV; diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c index 0038dc4c06c7dbd89b7cef8f424f374fc250da42..e5fb7525a5df4595c0ba8f969ee4e74d6639f6a7 100644 --- a/drivers/ata/pata_hpt366.c +++ b/drivers/ata/pata_hpt366.c @@ -176,17 +176,14 @@ static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, const char * const list[]) { unsigned char model_num[ATA_ID_PROD_LEN + 1]; - int i = 0; + int i; ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num)); - while (list[i] != NULL) { - if (!strcmp(list[i], model_num)) { - pr_warn("%s is not supported for %s\n", - modestr, list[i]); - return 1; - } - i++; + i = match_string(list, -1, model_num); + if (i >= 0) { + pr_warn("%s is not supported for %s\n", modestr, list[i]); + return 1; } return 0; } diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c index 17d31fc009abbcf14e0ea3f14ad9c06be8ac5b35..0636d84fbefe0acc889004b39e83c0137fc0f6a0 100644 --- a/drivers/ata/sata_via.c +++ b/drivers/ata/sata_via.c @@ -61,6 +61,7 @@ enum { SATA_CHAN_ENAB = 0x40, /* SATA channel enable */ SATA_INT_GATE = 0x41, /* SATA interrupt gating */ SATA_NATIVE_MODE = 0x42, /* Native mode enable */ + SVIA_MISC_3 = 0x46, /* Miscellaneous Control III */ PATA_UDMA_TIMING = 0xB3, /* PATA timing for DMA/ cable detect */ PATA_PIO_TIMING = 0xAB, /* PATA timing register */ @@ -71,9 +72,18 @@ enum { NATIVE_MODE_ALL = (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4), SATA_EXT_PHY = (1 << 6), /* 0==use PATA, 1==ext phy */ + + SATA_HOTPLUG = (1 << 5), /* enable IRQ on hotplug */ +}; + +struct svia_priv { + bool wd_workaround; }; static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); +#ifdef CONFIG_PM_SLEEP +static int svia_pci_device_resume(struct pci_dev *pdev); +#endif static int svia_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val); static int svia_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val); static int vt8251_scr_read(struct ata_link *link, unsigned int scr, u32 *val); @@ -85,6 +95,7 @@ static void vt6420_bmdma_start(struct ata_queued_cmd *qc); static int vt6421_pata_cable_detect(struct ata_port *ap); static void vt6421_set_pio_mode(struct ata_port *ap, struct ata_device *adev); static void vt6421_set_dma_mode(struct ata_port *ap, struct ata_device *adev); +static void vt6421_error_handler(struct ata_port *ap); static const struct pci_device_id svia_pci_tbl[] = { { PCI_VDEVICE(VIA, 0x5337), vt6420 }, @@ -105,7 +116,7 @@ static struct pci_driver svia_pci_driver = { .probe = svia_init_one, #ifdef CONFIG_PM_SLEEP .suspend = ata_pci_device_suspend, - .resume = ata_pci_device_resume, + .resume = svia_pci_device_resume, #endif .remove = ata_pci_remove_one, }; @@ -137,6 +148,7 @@ static struct ata_port_operations vt6421_sata_ops = { .inherits = &svia_base_ops, .scr_read = svia_scr_read, .scr_write = svia_scr_write, + .error_handler = vt6421_error_handler, }; static struct ata_port_operations vt8251_ops = { @@ -536,7 +548,67 @@ static int vt8251_prepare_host(struct pci_dev *pdev, struct ata_host **r_host) return 0; } -static void svia_configure(struct pci_dev *pdev, int board_id) +static void svia_wd_fix(struct pci_dev *pdev) +{ + u8 tmp8; + + pci_read_config_byte(pdev, 0x52, &tmp8); + pci_write_config_byte(pdev, 0x52, tmp8 | BIT(2)); +} + +static irqreturn_t vt6421_interrupt(int irq, void *dev_instance) +{ + struct ata_host *host = dev_instance; + irqreturn_t rc = ata_bmdma_interrupt(irq, dev_instance); + + /* if the IRQ was not handled, it might be a hotplug IRQ */ + if (rc != IRQ_HANDLED) { + u32 serror; + unsigned long flags; + + spin_lock_irqsave(&host->lock, flags); + /* check for hotplug on port 0 */ + svia_scr_read(&host->ports[0]->link, SCR_ERROR, &serror); + if (serror & SERR_PHYRDY_CHG) { + ata_ehi_hotplugged(&host->ports[0]->link.eh_info); + ata_port_freeze(host->ports[0]); + rc = IRQ_HANDLED; + } + /* check for hotplug on port 1 */ + svia_scr_read(&host->ports[1]->link, SCR_ERROR, &serror); + if (serror & SERR_PHYRDY_CHG) { + ata_ehi_hotplugged(&host->ports[1]->link.eh_info); + ata_port_freeze(host->ports[1]); + rc = IRQ_HANDLED; + } + spin_unlock_irqrestore(&host->lock, flags); + } + + return rc; +} + +static void vt6421_error_handler(struct ata_port *ap) +{ + struct svia_priv *hpriv = ap->host->private_data; + struct pci_dev *pdev = to_pci_dev(ap->host->dev); + u32 serror; + + /* see svia_configure() for description */ + if (!hpriv->wd_workaround) { + svia_scr_read(&ap->link, SCR_ERROR, &serror); + if (serror == 0x1000500) { + ata_port_warn(ap, "Incompatible drive: enabling workaround. This slows down transfer rate to ~60 MB/s"); + svia_wd_fix(pdev); + hpriv->wd_workaround = true; + ap->link.eh_context.i.flags |= ATA_EHI_QUIET; + } + } + + ata_sff_error_handler(ap); +} + +static void svia_configure(struct pci_dev *pdev, int board_id, + struct svia_priv *hpriv) { u8 tmp8; @@ -572,6 +644,16 @@ static void svia_configure(struct pci_dev *pdev, int board_id) pci_write_config_byte(pdev, SATA_NATIVE_MODE, tmp8); } + /* enable IRQ on hotplug */ + pci_read_config_byte(pdev, SVIA_MISC_3, &tmp8); + if ((tmp8 & SATA_HOTPLUG) != SATA_HOTPLUG) { + dev_dbg(&pdev->dev, + "enabling SATA hotplug (0x%x)\n", + (int) tmp8); + tmp8 |= SATA_HOTPLUG; + pci_write_config_byte(pdev, SVIA_MISC_3, tmp8); + } + /* * vt6420/1 has problems talking to some drives. The following * is the fix from Joseph Chan . @@ -593,11 +675,15 @@ static void svia_configure(struct pci_dev *pdev, int board_id) * https://bugzilla.kernel.org/show_bug.cgi?id=15173 * http://article.gmane.org/gmane.linux.ide/46352 * http://thread.gmane.org/gmane.linux.kernel/1062139 + * + * As the fix slows down data transfer, apply it only if the error + * actually appears - see vt6421_error_handler() + * Apply the fix always on vt6420 as we don't know if SCR_ERROR can be + * read safely. */ - if (board_id == vt6420 || board_id == vt6421) { - pci_read_config_byte(pdev, 0x52, &tmp8); - tmp8 |= 1 << 2; - pci_write_config_byte(pdev, 0x52, tmp8); + if (board_id == vt6420) { + svia_wd_fix(pdev); + hpriv->wd_workaround = true; } } @@ -608,6 +694,7 @@ static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) struct ata_host *host = NULL; int board_id = (int) ent->driver_data; const unsigned *bar_sizes; + struct svia_priv *hpriv; ata_print_version_once(&pdev->dev, DRV_VERSION); @@ -647,11 +734,39 @@ static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if (rc) return rc; - svia_configure(pdev, board_id); + hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL); + if (!hpriv) + return -ENOMEM; + host->private_data = hpriv; + + svia_configure(pdev, board_id, hpriv); pci_set_master(pdev); - return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, - IRQF_SHARED, &svia_sht); + if (board_id == vt6421) + return ata_host_activate(host, pdev->irq, vt6421_interrupt, + IRQF_SHARED, &svia_sht); + else + return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt, + IRQF_SHARED, &svia_sht); +} + +#ifdef CONFIG_PM_SLEEP +static int svia_pci_device_resume(struct pci_dev *pdev) +{ + struct ata_host *host = pci_get_drvdata(pdev); + struct svia_priv *hpriv = host->private_data; + int rc; + + rc = ata_pci_device_do_resume(pdev); + if (rc) + return rc; + + if (hpriv->wd_workaround) + svia_wd_fix(pdev); + ata_host_resume(host); + + return 0; } +#endif module_pci_driver(svia_pci_driver); diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c index 82f2ae0d7cc488a337772aaf8d7a19b3373bcd94..a969a7e443be26edded6d21245c0b29f24450a72 100644 --- a/drivers/atm/firestream.c +++ b/drivers/atm/firestream.c @@ -168,7 +168,7 @@ static char *res_strings[] = { "reserved 14", "Unrecognized cell", "reserved 16", - "reassemby abort: AAL5 abort", + "reassembly abort: AAL5 abort", "packet purged", "packet ageing timeout", "channel ageing timeout", diff --git a/drivers/base/dd.c b/drivers/base/dd.c index c4da2df62e02525617a23ebe68fff4af0bb69350..16688f50729cfac7112a740804c00b226680ca4a 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -560,6 +560,7 @@ static int __device_attach_driver(struct device_driver *drv, void *_data) struct device_attach_data *data = _data; struct device *dev = data->dev; bool async_allowed; + int ret; /* * Check if device has already been claimed. This may @@ -570,8 +571,17 @@ static int __device_attach_driver(struct device_driver *drv, void *_data) if (dev->driver) return -EBUSY; - if (!driver_match_device(drv, dev)) + ret = driver_match_device(drv, dev); + if (ret == 0) { + /* no match */ return 0; + } else if (ret == -EPROBE_DEFER) { + dev_dbg(dev, "Device match requests probe deferral\n"); + driver_deferred_probe_add(dev); + } else if (ret < 0) { + dev_dbg(dev, "Bus failed to match device: %d", ret); + return ret; + } /* ret > 0 means positive match */ async_allowed = driver_allows_async_probing(drv); @@ -691,6 +701,7 @@ void device_initial_probe(struct device *dev) static int __driver_attach(struct device *dev, void *data) { struct device_driver *drv = data; + int ret; /* * Lock device and try to bind to it. We drop the error @@ -702,8 +713,17 @@ static int __driver_attach(struct device *dev, void *data) * is an error. */ - if (!driver_match_device(drv, dev)) + ret = driver_match_device(drv, dev); + if (ret == 0) { + /* no match */ return 0; + } else if (ret == -EPROBE_DEFER) { + dev_dbg(dev, "Device match requests probe deferral\n"); + driver_deferred_probe_add(dev); + } else if (ret < 0) { + dev_dbg(dev, "Bus failed to match device: %d", ret); + return ret; + } /* ret > 0 means positive match */ if (dev->parent) /* Needed for USB */ device_lock(dev->parent); diff --git a/drivers/base/dma-coherent.c b/drivers/base/dma-coherent.c index 87b8083748885592c8da34f2defa4a1b46be0be5..bdf28f7dd5e8638bfee9f522aef1cbfa71b89cbf 100644 --- a/drivers/base/dma-coherent.c +++ b/drivers/base/dma-coherent.c @@ -2,6 +2,7 @@ * Coherent per-device memory handling. * Borrowed from i386 */ +#include #include #include #include @@ -31,7 +32,10 @@ static bool dma_init_coherent_memory( if (!size) goto out; - mem_base = ioremap(phys_addr, size); + if (flags & DMA_MEMORY_MAP) + mem_base = memremap(phys_addr, size, MEMREMAP_WC); + else + mem_base = ioremap(phys_addr, size); if (!mem_base) goto out; @@ -54,8 +58,12 @@ static bool dma_init_coherent_memory( out: kfree(dma_mem); - if (mem_base) - iounmap(mem_base); + if (mem_base) { + if (flags & DMA_MEMORY_MAP) + memunmap(mem_base); + else + iounmap(mem_base); + } return false; } @@ -63,7 +71,11 @@ static void dma_release_coherent_memory(struct dma_coherent_mem *mem) { if (!mem) return; - iounmap(mem->virt_base); + + if (mem->flags & DMA_MEMORY_MAP) + memunmap(mem->virt_base); + else + iounmap(mem->virt_base); kfree(mem->bitmap); kfree(mem); } @@ -175,7 +187,10 @@ int dma_alloc_from_coherent(struct device *dev, ssize_t size, */ *dma_handle = mem->device_base + (pageno << PAGE_SHIFT); *ret = mem->virt_base + (pageno << PAGE_SHIFT); - memset(*ret, 0, size); + if (mem->flags & DMA_MEMORY_MAP) + memset(*ret, 0, size); + else + memset_io(*ret, 0, size); spin_unlock_irqrestore(&mem->spinlock, flags); return 1; diff --git a/drivers/base/power/clock_ops.c b/drivers/base/power/clock_ops.c index 272a52ebafc09d0c4a3d974b6ca0bf16aef5e612..0e64a1b5e62a0a768b568da8ed7dbc6554e11060 100644 --- a/drivers/base/power/clock_ops.c +++ b/drivers/base/power/clock_ops.c @@ -137,6 +137,62 @@ int pm_clk_add_clk(struct device *dev, struct clk *clk) return __pm_clk_add(dev, NULL, clk); } + +/** + * of_pm_clk_add_clks - Start using device clock(s) for power management. + * @dev: Device whose clock(s) is going to be used for power management. + * + * Add a series of clocks described in the 'clocks' device-tree node for + * a device to the list of clocks used for the power management of @dev. + * On success, returns the number of clocks added. Returns a negative + * error code if there are no clocks in the device node for the device + * or if adding a clock fails. + */ +int of_pm_clk_add_clks(struct device *dev) +{ + struct clk **clks; + unsigned int i, count; + int ret; + + if (!dev || !dev->of_node) + return -EINVAL; + + count = of_count_phandle_with_args(dev->of_node, "clocks", + "#clock-cells"); + if (count == 0) + return -ENODEV; + + clks = kcalloc(count, sizeof(*clks), GFP_KERNEL); + if (!clks) + return -ENOMEM; + + for (i = 0; i < count; i++) { + clks[i] = of_clk_get(dev->of_node, i); + if (IS_ERR(clks[i])) { + ret = PTR_ERR(clks[i]); + goto error; + } + + ret = pm_clk_add_clk(dev, clks[i]); + if (ret) { + clk_put(clks[i]); + goto error; + } + } + + kfree(clks); + + return i; + +error: + while (i--) + pm_clk_remove_clk(dev, clks[i]); + + kfree(clks); + + return ret; +} + /** * __pm_clk_remove - Destroy PM clock entry. * @ce: PM clock entry to destroy. @@ -197,6 +253,39 @@ void pm_clk_remove(struct device *dev, const char *con_id) __pm_clk_remove(ce); } +/** + * pm_clk_remove_clk - Stop using a device clock for power management. + * @dev: Device whose clock should not be used for PM any more. + * @clk: Clock pointer + * + * Remove the clock pointed to by @clk from the list of clocks used for + * the power management of @dev. + */ +void pm_clk_remove_clk(struct device *dev, struct clk *clk) +{ + struct pm_subsys_data *psd = dev_to_psd(dev); + struct pm_clock_entry *ce; + + if (!psd || !clk) + return; + + spin_lock_irq(&psd->lock); + + list_for_each_entry(ce, &psd->clock_list, node) { + if (clk == ce->clk) + goto remove; + } + + spin_unlock_irq(&psd->lock); + return; + + remove: + list_del(&ce->node); + spin_unlock_irq(&psd->lock); + + __pm_clk_remove(ce); +} + /** * pm_clk_init - Initialize a device's list of power management clocks. * @dev: Device to initialize the list of PM clocks for. diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index a1e0b9ab847a345c6a09adab3ff9f2fd9af3ad3e..5fb7718f256cf9d7bd45229dcc6e8a0b2225b1c5 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -246,6 +246,8 @@ static int device_wakeup_attach(struct device *dev, struct wakeup_source *ws) return -EEXIST; } dev->power.wakeup = ws; + if (dev->power.wakeirq) + device_wakeup_attach_irq(dev, dev->power.wakeirq); spin_unlock_irq(&dev->power.lock); return 0; } diff --git a/drivers/base/property.c b/drivers/base/property.c index 76628a7b45f1efb81fb43cc9ec63d85885883692..9b1a65debd49e645d41343eac7d54a4369ddc2fd 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -651,7 +651,7 @@ int fwnode_property_match_string(struct fwnode_handle *fwnode, const char *propname, const char *string) { const char **values; - int nval, ret, i; + int nval, ret; nval = fwnode_property_read_string_array(fwnode, propname, NULL, 0); if (nval < 0) @@ -668,13 +668,9 @@ int fwnode_property_match_string(struct fwnode_handle *fwnode, if (ret < 0) goto out; - ret = -ENODATA; - for (i = 0; i < nval; i++) { - if (!strcmp(values[i], string)) { - ret = i; - break; - } - } + ret = match_string(values, nval, string); + if (ret < 0) + ret = -ENODATA; out: kfree(values); return ret; diff --git a/drivers/bcma/Kconfig b/drivers/bcma/Kconfig index 023d448ed3fa6047549d635fade7fb26205a8633..efdc2ae8441af08dd7b55bf2249148ddcb1d66f3 100644 --- a/drivers/bcma/Kconfig +++ b/drivers/bcma/Kconfig @@ -70,6 +70,11 @@ config BCMA_DRIVER_MIPS If unsure, say N +config BCMA_PFLASH + bool + depends on BCMA_DRIVER_MIPS + default y + config BCMA_SFLASH bool depends on BCMA_DRIVER_MIPS diff --git a/drivers/bcma/Makefile b/drivers/bcma/Makefile index f32af9b76bcd2aaa7e0da61e26b2e33174803f7f..087948a1d20d96d9aa83540897b827cc34936e8f 100644 --- a/drivers/bcma/Makefile +++ b/drivers/bcma/Makefile @@ -1,6 +1,7 @@ bcma-y += main.o scan.o core.o sprom.o bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o bcma-y += driver_chipcommon_b.o +bcma-$(CONFIG_BCMA_PFLASH) += driver_chipcommon_pflash.o bcma-$(CONFIG_BCMA_SFLASH) += driver_chipcommon_sflash.o bcma-$(CONFIG_BCMA_NFLASH) += driver_chipcommon_nflash.o bcma-$(CONFIG_BCMA_DRIVER_PCI) += driver_pci.o diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h index 38f156745d533a666deae90f167dd6d51d718d54..eda09090cb523f5ddc2a6c174502110ae8999a57 100644 --- a/drivers/bcma/bcma_private.h +++ b/drivers/bcma/bcma_private.h @@ -47,10 +47,6 @@ int bcma_sprom_get(struct bcma_bus *bus); void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc); void bcma_core_chipcommon_init(struct bcma_drv_cc *cc); void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable); -#ifdef CONFIG_BCMA_DRIVER_MIPS -void bcma_chipco_serial_init(struct bcma_drv_cc *cc); -extern struct platform_device bcma_pflash_dev; -#endif /* CONFIG_BCMA_DRIVER_MIPS */ /* driver_chipcommon_b.c */ int bcma_core_chipcommon_b_init(struct bcma_drv_cc_b *ccb); @@ -62,6 +58,21 @@ void bcma_pmu_init(struct bcma_drv_cc *cc); u32 bcma_pmu_get_alp_clock(struct bcma_drv_cc *cc); u32 bcma_pmu_get_cpu_clock(struct bcma_drv_cc *cc); +/************************************************** + * driver_chipcommon_sflash.c + **************************************************/ + +#ifdef CONFIG_BCMA_PFLASH +extern struct platform_device bcma_pflash_dev; +int bcma_pflash_init(struct bcma_drv_cc *cc); +#else +static inline int bcma_pflash_init(struct bcma_drv_cc *cc) +{ + bcma_err(cc->core->bus, "Parallel flash not supported\n"); + return 0; +} +#endif /* CONFIG_BCMA_PFLASH */ + #ifdef CONFIG_BCMA_SFLASH /* driver_chipcommon_sflash.c */ int bcma_sflash_init(struct bcma_drv_cc *cc); diff --git a/drivers/bcma/driver_chipcommon.c b/drivers/bcma/driver_chipcommon.c index b7c8a8d4e6d1a232d44a28412a8b9ceba94e1ce9..921ce1834673231e597d2b85e48bb5e4307bf3b1 100644 --- a/drivers/bcma/driver_chipcommon.c +++ b/drivers/bcma/driver_chipcommon.c @@ -15,6 +15,8 @@ #include #include +static void bcma_chipco_serial_init(struct bcma_drv_cc *cc); + static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset, u32 mask, u32 value) { @@ -113,8 +115,37 @@ int bcma_chipco_watchdog_register(struct bcma_drv_cc *cc) return 0; } +static void bcma_core_chipcommon_flash_detect(struct bcma_drv_cc *cc) +{ + struct bcma_bus *bus = cc->core->bus; + + switch (cc->capabilities & BCMA_CC_CAP_FLASHT) { + case BCMA_CC_FLASHT_STSER: + case BCMA_CC_FLASHT_ATSER: + bcma_debug(bus, "Found serial flash\n"); + bcma_sflash_init(cc); + break; + case BCMA_CC_FLASHT_PARA: + bcma_debug(bus, "Found parallel flash\n"); + bcma_pflash_init(cc); + break; + default: + bcma_err(bus, "Flash type not supported\n"); + } + + if (cc->core->id.rev == 38 || + bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) { + if (cc->capabilities & BCMA_CC_CAP_NFLASH) { + bcma_debug(bus, "Found NAND flash\n"); + bcma_nflash_init(cc); + } + } +} + void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc) { + struct bcma_bus *bus = cc->core->bus; + if (cc->early_setup_done) return; @@ -129,6 +160,12 @@ void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc) if (cc->capabilities & BCMA_CC_CAP_PMU) bcma_pmu_early_init(cc); + if (IS_BUILTIN(CONFIG_BCM47XX) && bus->hosttype == BCMA_HOSTTYPE_SOC) + bcma_chipco_serial_init(cc); + + if (bus->hosttype == BCMA_HOSTTYPE_SOC) + bcma_core_chipcommon_flash_detect(cc); + cc->early_setup_done = true; } @@ -185,11 +222,12 @@ u32 bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks) ticks = 2; else if (ticks > maxt) ticks = maxt; - bcma_cc_write32(cc, BCMA_CC_PMU_WATCHDOG, ticks); + bcma_pmu_write32(cc, BCMA_CC_PMU_WATCHDOG, ticks); } else { struct bcma_bus *bus = cc->core->bus; if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4707 && + bus->chipinfo.id != BCMA_CHIP_ID_BCM47094 && bus->chipinfo.id != BCMA_CHIP_ID_BCM53018) bcma_core_set_clockmode(cc->core, ticks ? BCMA_CLKMODE_FAST : BCMA_CLKMODE_DYNAMIC); @@ -314,9 +352,9 @@ u32 bcma_chipco_gpio_pulldown(struct bcma_drv_cc *cc, u32 mask, u32 value) return res; } -#ifdef CONFIG_BCMA_DRIVER_MIPS -void bcma_chipco_serial_init(struct bcma_drv_cc *cc) +static void bcma_chipco_serial_init(struct bcma_drv_cc *cc) { +#if IS_BUILTIN(CONFIG_BCM47XX) unsigned int irq; u32 baud_base; u32 i; @@ -358,5 +396,5 @@ void bcma_chipco_serial_init(struct bcma_drv_cc *cc) ports[i].baud_base = baud_base; ports[i].reg_shift = 0; } +#endif /* CONFIG_BCM47XX */ } -#endif /* CONFIG_BCMA_DRIVER_MIPS */ diff --git a/drivers/bcma/driver_chipcommon_pflash.c b/drivers/bcma/driver_chipcommon_pflash.c new file mode 100644 index 0000000000000000000000000000000000000000..3b497c9ee0d4cad59d768dc53394152cda4dacfa --- /dev/null +++ b/drivers/bcma/driver_chipcommon_pflash.c @@ -0,0 +1,49 @@ +/* + * Broadcom specific AMBA + * ChipCommon parallel flash + * + * Licensed under the GNU/GPL. See COPYING for details. + */ + +#include "bcma_private.h" + +#include +#include +#include + +static const char * const part_probes[] = { "bcm47xxpart", NULL }; + +static struct physmap_flash_data bcma_pflash_data = { + .part_probe_types = part_probes, +}; + +static struct resource bcma_pflash_resource = { + .name = "bcma_pflash", + .flags = IORESOURCE_MEM, +}; + +struct platform_device bcma_pflash_dev = { + .name = "physmap-flash", + .dev = { + .platform_data = &bcma_pflash_data, + }, + .resource = &bcma_pflash_resource, + .num_resources = 1, +}; + +int bcma_pflash_init(struct bcma_drv_cc *cc) +{ + struct bcma_pflash *pflash = &cc->pflash; + + pflash->present = true; + + if (!(bcma_read32(cc->core, BCMA_CC_FLASH_CFG) & BCMA_CC_FLASH_CFG_DS)) + bcma_pflash_data.width = 1; + else + bcma_pflash_data.width = 2; + + bcma_pflash_resource.start = BCMA_SOC_FLASH2; + bcma_pflash_resource.end = BCMA_SOC_FLASH2 + BCMA_SOC_FLASH2_SZ; + + return 0; +} diff --git a/drivers/bcma/driver_chipcommon_pmu.c b/drivers/bcma/driver_chipcommon_pmu.c index fe0d48cb17788a9f3614fd8a36add7bac5f58848..f1eb4d3e1d575b2806c3d43155efb85f7640228d 100644 --- a/drivers/bcma/driver_chipcommon_pmu.c +++ b/drivers/bcma/driver_chipcommon_pmu.c @@ -15,44 +15,44 @@ u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset) { - bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset); - bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR); - return bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA); + bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_ADDR, offset); + bcma_pmu_read32(cc, BCMA_CC_PMU_PLLCTL_ADDR); + return bcma_pmu_read32(cc, BCMA_CC_PMU_PLLCTL_DATA); } EXPORT_SYMBOL_GPL(bcma_chipco_pll_read); void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value) { - bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset); - bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR); - bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, value); + bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_ADDR, offset); + bcma_pmu_read32(cc, BCMA_CC_PMU_PLLCTL_ADDR); + bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_DATA, value); } EXPORT_SYMBOL_GPL(bcma_chipco_pll_write); void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask, u32 set) { - bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset); - bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR); - bcma_cc_maskset32(cc, BCMA_CC_PLLCTL_DATA, mask, set); + bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_ADDR, offset); + bcma_pmu_read32(cc, BCMA_CC_PMU_PLLCTL_ADDR); + bcma_pmu_maskset32(cc, BCMA_CC_PMU_PLLCTL_DATA, mask, set); } EXPORT_SYMBOL_GPL(bcma_chipco_pll_maskset); void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask, u32 set) { - bcma_cc_write32(cc, BCMA_CC_CHIPCTL_ADDR, offset); - bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR); - bcma_cc_maskset32(cc, BCMA_CC_CHIPCTL_DATA, mask, set); + bcma_pmu_write32(cc, BCMA_CC_PMU_CHIPCTL_ADDR, offset); + bcma_pmu_read32(cc, BCMA_CC_PMU_CHIPCTL_ADDR); + bcma_pmu_maskset32(cc, BCMA_CC_PMU_CHIPCTL_DATA, mask, set); } EXPORT_SYMBOL_GPL(bcma_chipco_chipctl_maskset); void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask, u32 set) { - bcma_cc_write32(cc, BCMA_CC_REGCTL_ADDR, offset); - bcma_cc_read32(cc, BCMA_CC_REGCTL_ADDR); - bcma_cc_maskset32(cc, BCMA_CC_REGCTL_DATA, mask, set); + bcma_pmu_write32(cc, BCMA_CC_PMU_REGCTL_ADDR, offset); + bcma_pmu_read32(cc, BCMA_CC_PMU_REGCTL_ADDR); + bcma_pmu_maskset32(cc, BCMA_CC_PMU_REGCTL_DATA, mask, set); } EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset); @@ -60,18 +60,18 @@ static u32 bcma_pmu_xtalfreq(struct bcma_drv_cc *cc) { u32 ilp_ctl, alp_hz; - if (!(bcma_cc_read32(cc, BCMA_CC_PMU_STAT) & + if (!(bcma_pmu_read32(cc, BCMA_CC_PMU_STAT) & BCMA_CC_PMU_STAT_EXT_LPO_AVAIL)) return 0; - bcma_cc_write32(cc, BCMA_CC_PMU_XTAL_FREQ, - BIT(BCMA_CC_PMU_XTAL_FREQ_MEASURE_SHIFT)); + bcma_pmu_write32(cc, BCMA_CC_PMU_XTAL_FREQ, + BIT(BCMA_CC_PMU_XTAL_FREQ_MEASURE_SHIFT)); usleep_range(1000, 2000); - ilp_ctl = bcma_cc_read32(cc, BCMA_CC_PMU_XTAL_FREQ); + ilp_ctl = bcma_pmu_read32(cc, BCMA_CC_PMU_XTAL_FREQ); ilp_ctl &= BCMA_CC_PMU_XTAL_FREQ_ILPCTL_MASK; - bcma_cc_write32(cc, BCMA_CC_PMU_XTAL_FREQ, 0); + bcma_pmu_write32(cc, BCMA_CC_PMU_XTAL_FREQ, 0); alp_hz = ilp_ctl * 32768 / 4; return (alp_hz + 50000) / 100000 * 100; @@ -127,8 +127,8 @@ static void bcma_pmu2_pll_init0(struct bcma_drv_cc *cc, u32 xtalfreq) mask = (u32)~(BCMA_RES_4314_HT_AVAIL | BCMA_RES_4314_MACPHY_CLK_AVAIL); - bcma_cc_mask32(cc, BCMA_CC_PMU_MINRES_MSK, mask); - bcma_cc_mask32(cc, BCMA_CC_PMU_MAXRES_MSK, mask); + bcma_pmu_mask32(cc, BCMA_CC_PMU_MINRES_MSK, mask); + bcma_pmu_mask32(cc, BCMA_CC_PMU_MAXRES_MSK, mask); bcma_wait_value(cc->core, BCMA_CLKCTLST, BCMA_CLKCTLST_HAVEHT, 0, 20000); break; @@ -140,7 +140,7 @@ static void bcma_pmu2_pll_init0(struct bcma_drv_cc *cc, u32 xtalfreq) /* Flush */ if (cc->pmu.rev >= 2) - bcma_cc_set32(cc, BCMA_CC_PMU_CTL, BCMA_CC_PMU_CTL_PLL_UPD); + bcma_pmu_set32(cc, BCMA_CC_PMU_CTL, BCMA_CC_PMU_CTL_PLL_UPD); /* TODO: Do we need to update OTP? */ } @@ -195,9 +195,9 @@ static void bcma_pmu_resources_init(struct bcma_drv_cc *cc) /* Set the resource masks. */ if (min_msk) - bcma_cc_write32(cc, BCMA_CC_PMU_MINRES_MSK, min_msk); + bcma_pmu_write32(cc, BCMA_CC_PMU_MINRES_MSK, min_msk); if (max_msk) - bcma_cc_write32(cc, BCMA_CC_PMU_MAXRES_MSK, max_msk); + bcma_pmu_write32(cc, BCMA_CC_PMU_MAXRES_MSK, max_msk); /* * Add some delay; allow resources to come up and settle. @@ -269,23 +269,33 @@ static void bcma_pmu_workarounds(struct bcma_drv_cc *cc) void bcma_pmu_early_init(struct bcma_drv_cc *cc) { + struct bcma_bus *bus = cc->core->bus; u32 pmucap; - pmucap = bcma_cc_read32(cc, BCMA_CC_PMU_CAP); + if (cc->core->id.rev >= 35 && + cc->capabilities_ext & BCMA_CC_CAP_EXT_AOB_PRESENT) { + cc->pmu.core = bcma_find_core(bus, BCMA_CORE_PMU); + if (!cc->pmu.core) + bcma_warn(bus, "Couldn't find expected PMU core"); + } + if (!cc->pmu.core) + cc->pmu.core = cc->core; + + pmucap = bcma_pmu_read32(cc, BCMA_CC_PMU_CAP); cc->pmu.rev = (pmucap & BCMA_CC_PMU_CAP_REVISION); - bcma_debug(cc->core->bus, "Found rev %u PMU (capabilities 0x%08X)\n", - cc->pmu.rev, pmucap); + bcma_debug(bus, "Found rev %u PMU (capabilities 0x%08X)\n", cc->pmu.rev, + pmucap); } void bcma_pmu_init(struct bcma_drv_cc *cc) { if (cc->pmu.rev == 1) - bcma_cc_mask32(cc, BCMA_CC_PMU_CTL, - ~BCMA_CC_PMU_CTL_NOILPONW); + bcma_pmu_mask32(cc, BCMA_CC_PMU_CTL, + ~BCMA_CC_PMU_CTL_NOILPONW); else - bcma_cc_set32(cc, BCMA_CC_PMU_CTL, - BCMA_CC_PMU_CTL_NOILPONW); + bcma_pmu_set32(cc, BCMA_CC_PMU_CTL, + BCMA_CC_PMU_CTL_NOILPONW); bcma_pmu_pll_init(cc); bcma_pmu_resources_init(cc); @@ -472,8 +482,8 @@ u32 bcma_pmu_get_cpu_clock(struct bcma_drv_cc *cc) static void bcma_pmu_spuravoid_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value) { - bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset); - bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, value); + bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_ADDR, offset); + bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_DATA, value); } void bcma_pmu_spuravoid_pllupdate(struct bcma_drv_cc *cc, int spuravoid) @@ -497,20 +507,20 @@ void bcma_pmu_spuravoid_pllupdate(struct bcma_drv_cc *cc, int spuravoid) bus->chipinfo.id == BCMA_CHIP_ID_BCM53572) ? 6 : 0; /* RMW only the P1 divider */ - bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, + bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_ADDR, BCMA_CC_PMU_PLL_CTL0 + phypll_offset); - tmp = bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA); + tmp = bcma_pmu_read32(cc, BCMA_CC_PMU_PLLCTL_DATA); tmp &= (~(BCMA_CC_PMU1_PLL0_PC0_P1DIV_MASK)); tmp |= (bcm5357_bcm43236_p1div[spuravoid] << BCMA_CC_PMU1_PLL0_PC0_P1DIV_SHIFT); - bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, tmp); + bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_DATA, tmp); /* RMW only the int feedback divider */ - bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, + bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_ADDR, BCMA_CC_PMU_PLL_CTL2 + phypll_offset); - tmp = bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA); + tmp = bcma_pmu_read32(cc, BCMA_CC_PMU_PLLCTL_DATA); tmp &= ~(BCMA_CC_PMU1_PLL0_PC2_NDIV_INT_MASK); tmp |= (bcm5357_bcm43236_ndiv[spuravoid]) << BCMA_CC_PMU1_PLL0_PC2_NDIV_INT_SHIFT; - bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, tmp); + bcma_pmu_write32(cc, BCMA_CC_PMU_PLLCTL_DATA, tmp); tmp = BCMA_CC_PMU_CTL_PLL_UPD; break; @@ -646,7 +656,7 @@ void bcma_pmu_spuravoid_pllupdate(struct bcma_drv_cc *cc, int spuravoid) break; } - tmp |= bcma_cc_read32(cc, BCMA_CC_PMU_CTL); - bcma_cc_write32(cc, BCMA_CC_PMU_CTL, tmp); + tmp |= bcma_pmu_read32(cc, BCMA_CC_PMU_CTL); + bcma_pmu_write32(cc, BCMA_CC_PMU_CTL, tmp); } EXPORT_SYMBOL_GPL(bcma_pmu_spuravoid_pllupdate); diff --git a/drivers/bcma/driver_chipcommon_sflash.c b/drivers/bcma/driver_chipcommon_sflash.c index 7e11ef4cb7dbed69bd52685cf03a177fe6a8a01a..04d706ca5f439be4576c8f78afb4b10a66b5dd3e 100644 --- a/drivers/bcma/driver_chipcommon_sflash.c +++ b/drivers/bcma/driver_chipcommon_sflash.c @@ -38,6 +38,7 @@ static const struct bcma_sflash_tbl_e bcma_sflash_st_tbl[] = { { "M25P32", 0x15, 0x10000, 64, }, { "M25P64", 0x16, 0x10000, 128, }, { "M25FL128", 0x17, 0x10000, 256, }, + { "MX25L25635F", 0x18, 0x10000, 512, }, { NULL }, }; diff --git a/drivers/bcma/driver_gpio.c b/drivers/bcma/driver_gpio.c index 98067f757fb0d9348fc8fb8f6fd25eb81e32bbf2..771a2a253440f736711bd996044d78b6ce3b723a 100644 --- a/drivers/bcma/driver_gpio.c +++ b/drivers/bcma/driver_gpio.c @@ -192,6 +192,7 @@ int bcma_gpio_init(struct bcma_drv_cc *cc) case BCMA_CHIP_ID_BCM4707: case BCMA_CHIP_ID_BCM5357: case BCMA_CHIP_ID_BCM53572: + case BCMA_CHIP_ID_BCM47094: chip->ngpio = 32; break; default: diff --git a/drivers/bcma/driver_mips.c b/drivers/bcma/driver_mips.c index 24424f3fef96d5784be6d5af59dbf40b3abc94e2..96f17132820080843e9216523bc1328b2f8f7939 100644 --- a/drivers/bcma/driver_mips.c +++ b/drivers/bcma/driver_mips.c @@ -14,8 +14,6 @@ #include -#include -#include #include #include #include @@ -32,26 +30,6 @@ enum bcma_boot_dev { BCMA_BOOT_DEV_NAND, }; -static const char * const part_probes[] = { "bcm47xxpart", NULL }; - -static struct physmap_flash_data bcma_pflash_data = { - .part_probe_types = part_probes, -}; - -static struct resource bcma_pflash_resource = { - .name = "bcma_pflash", - .flags = IORESOURCE_MEM, -}; - -struct platform_device bcma_pflash_dev = { - .name = "physmap-flash", - .dev = { - .platform_data = &bcma_pflash_data, - }, - .resource = &bcma_pflash_resource, - .num_resources = 1, -}; - /* The 47162a0 hangs when reading MIPS DMP registers registers */ static inline bool bcma_core_mips_bcm47162a0_quirk(struct bcma_device *dev) { @@ -272,48 +250,11 @@ static enum bcma_boot_dev bcma_boot_dev(struct bcma_bus *bus) return BCMA_BOOT_DEV_SERIAL; } -static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore) +static void bcma_core_mips_nvram_init(struct bcma_drv_mips *mcore) { struct bcma_bus *bus = mcore->core->bus; - struct bcma_drv_cc *cc = &bus->drv_cc; - struct bcma_pflash *pflash = &cc->pflash; enum bcma_boot_dev boot_dev; - switch (cc->capabilities & BCMA_CC_CAP_FLASHT) { - case BCMA_CC_FLASHT_STSER: - case BCMA_CC_FLASHT_ATSER: - bcma_debug(bus, "Found serial flash\n"); - bcma_sflash_init(cc); - break; - case BCMA_CC_FLASHT_PARA: - bcma_debug(bus, "Found parallel flash\n"); - pflash->present = true; - pflash->window = BCMA_SOC_FLASH2; - pflash->window_size = BCMA_SOC_FLASH2_SZ; - - if ((bcma_read32(cc->core, BCMA_CC_FLASH_CFG) & - BCMA_CC_FLASH_CFG_DS) == 0) - pflash->buswidth = 1; - else - pflash->buswidth = 2; - - bcma_pflash_data.width = pflash->buswidth; - bcma_pflash_resource.start = pflash->window; - bcma_pflash_resource.end = pflash->window + pflash->window_size; - - break; - default: - bcma_err(bus, "Flash type not supported\n"); - } - - if (cc->core->id.rev == 38 || - bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) { - if (cc->capabilities & BCMA_CC_CAP_NFLASH) { - bcma_debug(bus, "Found NAND flash\n"); - bcma_nflash_init(cc); - } - } - /* Determine flash type this SoC boots from */ boot_dev = bcma_boot_dev(bus); switch (boot_dev) { @@ -337,13 +278,10 @@ static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore) void bcma_core_mips_early_init(struct bcma_drv_mips *mcore) { - struct bcma_bus *bus = mcore->core->bus; - if (mcore->early_setup_done) return; - bcma_chipco_serial_init(&bus->drv_cc); - bcma_core_mips_flash_detect(mcore); + bcma_core_mips_nvram_init(mcore); mcore->early_setup_done = true; } diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c index 0856189c065fd57826df7edab2dba3217d5e283c..cae5385cf4996c28353e55f0676f8aa9ba8ec1ac 100644 --- a/drivers/bcma/host_pci.c +++ b/drivers/bcma/host_pci.c @@ -294,7 +294,7 @@ static const struct pci_device_id bcma_pci_bridge_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4358) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4360) }, - { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4365) }, + { PCI_DEVICE_SUB(PCI_VENDOR_ID_BROADCOM, 0x4365, PCI_VENDOR_ID_DELL, 0x0016) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a0) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a9) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43aa) }, diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index c466f752b067d2bbbcbbd2cdcaf50bb82942d80f..786be8fed39e980add0b9e1cddc9e0682171dc9a 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c @@ -350,7 +350,7 @@ static int bcma_register_devices(struct bcma_bus *bus) bcma_register_core(bus, core); } -#ifdef CONFIG_BCMA_DRIVER_MIPS +#ifdef CONFIG_BCMA_PFLASH if (bus->drv_cc.pflash.present) { err = platform_device_register(&bcma_pflash_dev); if (err) diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c index df806b9c549084fab8e61569718b2441485f17e4..4a2d1b235fb5af3e51ac8b044e6a18aed5753cec 100644 --- a/drivers/bcma/scan.c +++ b/drivers/bcma/scan.c @@ -98,6 +98,9 @@ static const struct bcma_device_id_name bcma_bcm_device_names[] = { { BCMA_CORE_SHIM, "SHIM" }, { BCMA_CORE_PCIE2, "PCIe Gen2" }, { BCMA_CORE_ARM_CR4, "ARM CR4" }, + { BCMA_CORE_GCI, "GCI" }, + { BCMA_CORE_CMEM, "CNDS DDR2/3 memory controller" }, + { BCMA_CORE_ARM_CA7, "ARM CA7" }, { BCMA_CORE_DEFAULT, "Default" }, }; @@ -315,6 +318,8 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr, switch (core->id.id) { case BCMA_CORE_4706_MAC_GBIT_COMMON: case BCMA_CORE_NS_CHIPCOMMON_B: + case BCMA_CORE_PMU: + case BCMA_CORE_GCI: /* Not used yet: case BCMA_CORE_OOB_ROUTER: */ break; default: diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 29819e719afab0bc9d76279db5970e428609cbd8..39dd30b6ef86e8aac5db98a2db52c1f28a3787e3 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -110,16 +110,6 @@ source "drivers/block/mtip32xx/Kconfig" source "drivers/block/zram/Kconfig" -config BLK_CPQ_DA - tristate "Compaq SMART2 support" - depends on PCI && VIRT_TO_BUS && 0 - help - This is the driver for Compaq Smart Array controllers. Everyone - using these boards should say Y here. See the file - for the current list of - boards supported by this driver, and for further information on the - use of this driver. - config BLK_CPQ_CISS_DA tristate "Compaq Smart Array 5xxx support" depends on PCI diff --git a/drivers/block/Makefile b/drivers/block/Makefile index 671329023ec2717c416446c7de65104de0561a95..1e9661e26f294fcbfec07a064adb6aad1789101d 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -15,7 +15,6 @@ obj-$(CONFIG_ATARI_FLOPPY) += ataflop.o obj-$(CONFIG_AMIGA_Z2RAM) += z2ram.o obj-$(CONFIG_BLK_DEV_RAM) += brd.o obj-$(CONFIG_BLK_DEV_LOOP) += loop.o -obj-$(CONFIG_BLK_CPQ_DA) += cpqarray.o obj-$(CONFIG_BLK_CPQ_CISS_DA) += cciss.o obj-$(CONFIG_BLK_DEV_DAC960) += DAC960.o obj-$(CONFIG_XILINX_SYSACE) += xsysace.o diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c index dd73e1ff1759c902db1734ac94975abea11e1b02..ec9d8610b25f772eefe20917cc8921db17c29016 100644 --- a/drivers/block/aoe/aoeblk.c +++ b/drivers/block/aoe/aoeblk.c @@ -397,7 +397,7 @@ aoeblk_gdalloc(void *vp) WARN_ON(d->flags & DEVFL_UP); blk_queue_max_hw_sectors(q, BLK_DEF_MAX_SECTORS); q->backing_dev_info.name = "aoe"; - q->backing_dev_info.ra_pages = READ_AHEAD / PAGE_CACHE_SIZE; + q->backing_dev_info.ra_pages = READ_AHEAD / PAGE_SIZE; d->bufpool = mp; d->blkq = gd->queue = q; q->queuedata = d; diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index d048d2009e897a7e76d523ec704b1fd1f77dd76b..437b3a822f4482c5a6e34a2c1f827f5560d1f56e 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c @@ -875,7 +875,7 @@ bio_pageinc(struct bio *bio) * compound pages is no longer allowed by the kernel. */ page = compound_head(bv.bv_page); - atomic_inc(&page->_count); + page_ref_inc(page); } } @@ -888,7 +888,7 @@ bio_pagedec(struct bio *bio) bio_for_each_segment(bv, bio, iter) { page = compound_head(bv.bv_page); - atomic_dec(&page->_count); + page_ref_dec(page); } } diff --git a/drivers/block/brd.c b/drivers/block/brd.c index cb27190e9f395f94a4cac646e3a4beb12b7fa6fc..51a071e322213982247aa7ff01a15d6057d3fb34 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c @@ -341,7 +341,7 @@ static blk_qc_t brd_make_request(struct request_queue *q, struct bio *bio) if (unlikely(bio->bi_rw & REQ_DISCARD)) { if (sector & ((PAGE_SIZE >> SECTOR_SHIFT) - 1) || - bio->bi_iter.bi_size & PAGE_MASK) + bio->bi_iter.bi_size & ~PAGE_MASK) goto io_error; discard_from_brd(brd, sector, bio->bi_iter.bi_size); goto out; @@ -374,7 +374,7 @@ static int brd_rw_page(struct block_device *bdev, sector_t sector, struct page *page, int rw) { struct brd_device *brd = bdev->bd_disk->private_data; - int err = brd_do_bvec(brd, page, PAGE_CACHE_SIZE, 0, rw, sector); + int err = brd_do_bvec(brd, page, PAGE_SIZE, 0, rw, sector); page_endio(page, rw & WRITE, err); return err; } diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c deleted file mode 100644 index f749df9e15cd427054d572c6f6e283630ca2bcc6..0000000000000000000000000000000000000000 --- a/drivers/block/cpqarray.c +++ /dev/null @@ -1,1820 +0,0 @@ -/* - * Disk Array driver for Compaq SMART2 Controllers - * Copyright 1998 Compaq Computer Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Questions/Comments/Bugfixes to iss_storagedev@hp.com - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define SMART2_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin)) - -#define DRIVER_NAME "Compaq SMART2 Driver (v 2.6.0)" -#define DRIVER_VERSION SMART2_DRIVER_VERSION(2,6,0) - -/* Embedded module documentation macros - see modules.h */ -/* Original author Chris Frantz - Compaq Computer Corporation */ -MODULE_AUTHOR("Compaq Computer Corporation"); -MODULE_DESCRIPTION("Driver for Compaq Smart2 Array Controllers version 2.6.0"); -MODULE_LICENSE("GPL"); - -#include "cpqarray.h" -#include "ida_cmd.h" -#include "smart1,2.h" -#include "ida_ioctl.h" - -#define READ_AHEAD 128 -#define NR_CMDS 128 /* This could probably go as high as ~400 */ - -#define MAX_CTLR 8 -#define CTLR_SHIFT 8 - -#define CPQARRAY_DMA_MASK 0xFFFFFFFF /* 32 bit DMA */ - -static DEFINE_MUTEX(cpqarray_mutex); -static int nr_ctlr; -static ctlr_info_t *hba[MAX_CTLR]; - -static int eisa[8]; - -#define NR_PRODUCTS ARRAY_SIZE(products) - -/* board_id = Subsystem Device ID & Vendor ID - * product = Marketing Name for the board - * access = Address of the struct of function pointers - */ -static struct board_type products[] = { - { 0x0040110E, "IDA", &smart1_access }, - { 0x0140110E, "IDA-2", &smart1_access }, - { 0x1040110E, "IAES", &smart1_access }, - { 0x2040110E, "SMART", &smart1_access }, - { 0x3040110E, "SMART-2/E", &smart2e_access }, - { 0x40300E11, "SMART-2/P", &smart2_access }, - { 0x40310E11, "SMART-2SL", &smart2_access }, - { 0x40320E11, "Smart Array 3200", &smart2_access }, - { 0x40330E11, "Smart Array 3100ES", &smart2_access }, - { 0x40340E11, "Smart Array 221", &smart2_access }, - { 0x40400E11, "Integrated Array", &smart4_access }, - { 0x40480E11, "Compaq Raid LC2", &smart4_access }, - { 0x40500E11, "Smart Array 4200", &smart4_access }, - { 0x40510E11, "Smart Array 4250ES", &smart4_access }, - { 0x40580E11, "Smart Array 431", &smart4_access }, -}; - -/* define the PCI info for the PCI cards this driver can control */ -static const struct pci_device_id cpqarray_pci_device_id[] = -{ - { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_COMPAQ_42XX, - 0x0E11, 0x4058, 0, 0, 0}, /* SA431 */ - { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_COMPAQ_42XX, - 0x0E11, 0x4051, 0, 0, 0}, /* SA4250ES */ - { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_COMPAQ_42XX, - 0x0E11, 0x4050, 0, 0, 0}, /* SA4200 */ - { PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C1510, - 0x0E11, 0x4048, 0, 0, 0}, /* LC2 */ - { PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C1510, - 0x0E11, 0x4040, 0, 0, 0}, /* Integrated Array */ - { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_SMART2P, - 0x0E11, 0x4034, 0, 0, 0}, /* SA 221 */ - { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_SMART2P, - 0x0E11, 0x4033, 0, 0, 0}, /* SA 3100ES*/ - { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_SMART2P, - 0x0E11, 0x4032, 0, 0, 0}, /* SA 3200*/ - { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_SMART2P, - 0x0E11, 0x4031, 0, 0, 0}, /* SA 2SL*/ - { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_SMART2P, - 0x0E11, 0x4030, 0, 0, 0}, /* SA 2P */ - { 0 } -}; - -MODULE_DEVICE_TABLE(pci, cpqarray_pci_device_id); - -static struct gendisk *ida_gendisk[MAX_CTLR][NWD]; - -/* Debug... */ -#define DBG(s) do { s } while(0) -/* Debug (general info)... */ -#define DBGINFO(s) do { } while(0) -/* Debug Paranoid... */ -#define DBGP(s) do { } while(0) -/* Debug Extra Paranoid... */ -#define DBGPX(s) do { } while(0) - -static int cpqarray_pci_init(ctlr_info_t *c, struct pci_dev *pdev); -static void __iomem *remap_pci_mem(ulong base, ulong size); -static int cpqarray_eisa_detect(void); -static int pollcomplete(int ctlr); -static void getgeometry(int ctlr); -static void start_fwbk(int ctlr); - -static cmdlist_t * cmd_alloc(ctlr_info_t *h, int get_from_pool); -static void cmd_free(ctlr_info_t *h, cmdlist_t *c, int got_from_pool); - -static void free_hba(int i); -static int alloc_cpqarray_hba(void); - -static int sendcmd( - __u8 cmd, - int ctlr, - void *buff, - size_t size, - unsigned int blk, - unsigned int blkcnt, - unsigned int log_unit ); - -static int ida_unlocked_open(struct block_device *bdev, fmode_t mode); -static void ida_release(struct gendisk *disk, fmode_t mode); -static int ida_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg); -static int ida_getgeo(struct block_device *bdev, struct hd_geometry *geo); -static int ida_ctlr_ioctl(ctlr_info_t *h, int dsk, ida_ioctl_t *io); - -static void do_ida_request(struct request_queue *q); -static void start_io(ctlr_info_t *h); - -static inline void addQ(cmdlist_t **Qptr, cmdlist_t *c); -static inline cmdlist_t *removeQ(cmdlist_t **Qptr, cmdlist_t *c); -static inline void complete_command(cmdlist_t *cmd, int timeout); - -static irqreturn_t do_ida_intr(int irq, void *dev_id); -static void ida_timer(unsigned long tdata); -static int ida_revalidate(struct gendisk *disk); -static int revalidate_allvol(ctlr_info_t *host); -static int cpqarray_register_ctlr(int ctlr, struct pci_dev *pdev); - -#ifdef CONFIG_PROC_FS -static void ida_procinit(int i); -#else -static void ida_procinit(int i) {} -#endif - -static inline drv_info_t *get_drv(struct gendisk *disk) -{ - return disk->private_data; -} - -static inline ctlr_info_t *get_host(struct gendisk *disk) -{ - return disk->queue->queuedata; -} - - -static const struct block_device_operations ida_fops = { - .owner = THIS_MODULE, - .open = ida_unlocked_open, - .release = ida_release, - .ioctl = ida_ioctl, - .getgeo = ida_getgeo, - .revalidate_disk= ida_revalidate, -}; - - -#ifdef CONFIG_PROC_FS - -static struct proc_dir_entry *proc_array; -static const struct file_operations ida_proc_fops; - -/* - * Get us a file in /proc/array that says something about each controller. - * Create /proc/array if it doesn't exist yet. - */ -static void __init ida_procinit(int i) -{ - if (proc_array == NULL) { - proc_array = proc_mkdir("driver/cpqarray", NULL); - if (!proc_array) return; - } - - proc_create_data(hba[i]->devname, 0, proc_array, &ida_proc_fops, hba[i]); -} - -/* - * Report information about this controller. - */ -static int ida_proc_show(struct seq_file *m, void *v) -{ - int i, ctlr; - ctlr_info_t *h = (ctlr_info_t*)m->private; - drv_info_t *drv; -#ifdef CPQ_PROC_PRINT_QUEUES - cmdlist_t *c; - unsigned long flags; -#endif - - ctlr = h->ctlr; - seq_printf(m, "%s: Compaq %s Controller\n" - " Board ID: 0x%08lx\n" - " Firmware Revision: %c%c%c%c\n" - " Controller Sig: 0x%08lx\n" - " Memory Address: 0x%08lx\n" - " I/O Port: 0x%04x\n" - " IRQ: %d\n" - " Logical drives: %d\n" - " Physical drives: %d\n\n" - " Current Q depth: %d\n" - " Max Q depth since init: %d\n\n", - h->devname, - h->product_name, - (unsigned long)h->board_id, - h->firm_rev[0], h->firm_rev[1], h->firm_rev[2], h->firm_rev[3], - (unsigned long)h->ctlr_sig, (unsigned long)h->vaddr, - (unsigned int) h->io_mem_addr, (unsigned int)h->intr, - h->log_drives, h->phys_drives, - h->Qdepth, h->maxQsinceinit); - - seq_puts(m, "Logical Drive Info:\n"); - - for(i=0; ilog_drives; i++) { - drv = &h->drv[i]; - seq_printf(m, "ida/c%dd%d: blksz=%d nr_blks=%d\n", - ctlr, i, drv->blk_size, drv->nr_blks); - } - -#ifdef CPQ_PROC_PRINT_QUEUES - spin_lock_irqsave(IDA_LOCK(h->ctlr), flags); - seq_puts(m, "\nCurrent Queues:\n"); - - c = h->reqQ; - seq_printf(m, "reqQ = %p", c); - if (c) c=c->next; - while(c && c != h->reqQ) { - seq_printf(m, "->%p", c); - c=c->next; - } - - c = h->cmpQ; - seq_printf(m, "\ncmpQ = %p", c); - if (c) c=c->next; - while(c && c != h->cmpQ) { - seq_printf(m, "->%p", c); - c=c->next; - } - - seq_putc(m, '\n'); - spin_unlock_irqrestore(IDA_LOCK(h->ctlr), flags); -#endif - seq_printf(m, "nr_allocs = %d\nnr_frees = %d\n", - h->nr_allocs, h->nr_frees); - return 0; -} - -static int ida_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, ida_proc_show, PDE_DATA(inode)); -} - -static const struct file_operations ida_proc_fops = { - .owner = THIS_MODULE, - .open = ida_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; -#endif /* CONFIG_PROC_FS */ - -module_param_array(eisa, int, NULL, 0); - -static void release_io_mem(ctlr_info_t *c) -{ - /* if IO mem was not protected do nothing */ - if( c->io_mem_addr == 0) - return; - release_region(c->io_mem_addr, c->io_mem_length); - c->io_mem_addr = 0; - c->io_mem_length = 0; -} - -static void cpqarray_remove_one(int i) -{ - int j; - char buff[4]; - - /* sendcmd will turn off interrupt, and send the flush... - * To write all data in the battery backed cache to disks - * no data returned, but don't want to send NULL to sendcmd */ - if( sendcmd(FLUSH_CACHE, i, buff, 4, 0, 0, 0)) - { - printk(KERN_WARNING "Unable to flush cache on controller %d\n", - i); - } - free_irq(hba[i]->intr, hba[i]); - iounmap(hba[i]->vaddr); - unregister_blkdev(COMPAQ_SMART2_MAJOR+i, hba[i]->devname); - del_timer(&hba[i]->timer); - remove_proc_entry(hba[i]->devname, proc_array); - pci_free_consistent(hba[i]->pci_dev, - NR_CMDS * sizeof(cmdlist_t), (hba[i]->cmd_pool), - hba[i]->cmd_pool_dhandle); - kfree(hba[i]->cmd_pool_bits); - for(j = 0; j < NWD; j++) { - if (ida_gendisk[i][j]->flags & GENHD_FL_UP) - del_gendisk(ida_gendisk[i][j]); - put_disk(ida_gendisk[i][j]); - } - blk_cleanup_queue(hba[i]->queue); - release_io_mem(hba[i]); - free_hba(i); -} - -static void cpqarray_remove_one_pci(struct pci_dev *pdev) -{ - int i; - ctlr_info_t *tmp_ptr; - - if (pci_get_drvdata(pdev) == NULL) { - printk( KERN_ERR "cpqarray: Unable to remove device \n"); - return; - } - - tmp_ptr = pci_get_drvdata(pdev); - i = tmp_ptr->ctlr; - if (hba[i] == NULL) { - printk(KERN_ERR "cpqarray: controller %d appears to have" - "already been removed \n", i); - return; - } - pci_set_drvdata(pdev, NULL); - - cpqarray_remove_one(i); -} - -/* removing an instance that was not removed automatically.. - * must be an eisa card. - */ -static void cpqarray_remove_one_eisa(int i) -{ - if (hba[i] == NULL) { - printk(KERN_ERR "cpqarray: controller %d appears to have" - "already been removed \n", i); - return; - } - cpqarray_remove_one(i); -} - -/* pdev is NULL for eisa */ -static int cpqarray_register_ctlr(int i, struct pci_dev *pdev) -{ - struct request_queue *q; - int j; - - /* - * register block devices - * Find disks and fill in structs - * Get an interrupt, set the Q depth and get into /proc - */ - - /* If this successful it should insure that we are the only */ - /* instance of the driver */ - if (register_blkdev(COMPAQ_SMART2_MAJOR+i, hba[i]->devname)) { - goto Enomem4; - } - hba[i]->access.set_intr_mask(hba[i], 0); - if (request_irq(hba[i]->intr, do_ida_intr, IRQF_SHARED, - hba[i]->devname, hba[i])) - { - printk(KERN_ERR "cpqarray: Unable to get irq %d for %s\n", - hba[i]->intr, hba[i]->devname); - goto Enomem3; - } - - for (j=0; jcmd_pool = pci_alloc_consistent( - hba[i]->pci_dev, NR_CMDS * sizeof(cmdlist_t), - &(hba[i]->cmd_pool_dhandle)); - hba[i]->cmd_pool_bits = kcalloc( - DIV_ROUND_UP(NR_CMDS, BITS_PER_LONG), sizeof(unsigned long), - GFP_KERNEL); - - if (!hba[i]->cmd_pool_bits || !hba[i]->cmd_pool) - goto Enomem1; - - memset(hba[i]->cmd_pool, 0, NR_CMDS * sizeof(cmdlist_t)); - printk(KERN_INFO "cpqarray: Finding drives on %s", - hba[i]->devname); - - spin_lock_init(&hba[i]->lock); - q = blk_init_queue(do_ida_request, &hba[i]->lock); - if (!q) - goto Enomem1; - - hba[i]->queue = q; - q->queuedata = hba[i]; - - getgeometry(i); - start_fwbk(i); - - ida_procinit(i); - - if (pdev) - blk_queue_bounce_limit(q, hba[i]->pci_dev->dma_mask); - - /* This is a hardware imposed limit. */ - blk_queue_max_segments(q, SG_MAX); - - init_timer(&hba[i]->timer); - hba[i]->timer.expires = jiffies + IDA_TIMER; - hba[i]->timer.data = (unsigned long)hba[i]; - hba[i]->timer.function = ida_timer; - add_timer(&hba[i]->timer); - - /* Enable IRQ now that spinlock and rate limit timer are set up */ - hba[i]->access.set_intr_mask(hba[i], FIFO_NOT_EMPTY); - - for(j=0; jdrv[j]; - sprintf(disk->disk_name, "ida/c%dd%d", i, j); - disk->major = COMPAQ_SMART2_MAJOR + i; - disk->first_minor = j<fops = &ida_fops; - if (j && !drv->nr_blks) - continue; - blk_queue_logical_block_size(hba[i]->queue, drv->blk_size); - set_capacity(disk, drv->nr_blks); - disk->queue = hba[i]->queue; - disk->private_data = drv; - add_disk(disk); - } - - /* done ! */ - return(i); - -Enomem1: - nr_ctlr = i; - kfree(hba[i]->cmd_pool_bits); - if (hba[i]->cmd_pool) - pci_free_consistent(hba[i]->pci_dev, NR_CMDS*sizeof(cmdlist_t), - hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle); -Enomem2: - while (j--) { - put_disk(ida_gendisk[i][j]); - ida_gendisk[i][j] = NULL; - } - free_irq(hba[i]->intr, hba[i]); -Enomem3: - unregister_blkdev(COMPAQ_SMART2_MAJOR+i, hba[i]->devname); -Enomem4: - if (pdev) - pci_set_drvdata(pdev, NULL); - release_io_mem(hba[i]); - free_hba(i); - - printk( KERN_ERR "cpqarray: out of memory"); - - return -1; -} - -static int cpqarray_init_one(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - int i; - - printk(KERN_DEBUG "cpqarray: Device 0x%x has been found at" - " bus %d dev %d func %d\n", - pdev->device, pdev->bus->number, PCI_SLOT(pdev->devfn), - PCI_FUNC(pdev->devfn)); - i = alloc_cpqarray_hba(); - if( i < 0 ) - return (-1); - memset(hba[i], 0, sizeof(ctlr_info_t)); - sprintf(hba[i]->devname, "ida%d", i); - hba[i]->ctlr = i; - /* Initialize the pdev driver private data */ - pci_set_drvdata(pdev, hba[i]); - - if (cpqarray_pci_init(hba[i], pdev) != 0) { - pci_set_drvdata(pdev, NULL); - release_io_mem(hba[i]); - free_hba(i); - return -1; - } - - return (cpqarray_register_ctlr(i, pdev)); -} - -static struct pci_driver cpqarray_pci_driver = { - .name = "cpqarray", - .probe = cpqarray_init_one, - .remove = cpqarray_remove_one_pci, - .id_table = cpqarray_pci_device_id, -}; - -/* - * This is it. Find all the controllers and register them. - * returns the number of block devices registered. - */ -static int __init cpqarray_init(void) -{ - int num_cntlrs_reg = 0; - int i; - int rc = 0; - - /* detect controllers */ - printk(DRIVER_NAME "\n"); - - rc = pci_register_driver(&cpqarray_pci_driver); - if (rc) - return rc; - cpqarray_eisa_detect(); - - for (i=0; i < MAX_CTLR; i++) { - if (hba[i] != NULL) - num_cntlrs_reg++; - } - - if (num_cntlrs_reg) - return 0; - else { - pci_unregister_driver(&cpqarray_pci_driver); - return -ENODEV; - } -} - -/* Function to find the first free pointer into our hba[] array */ -/* Returns -1 if no free entries are left. */ -static int alloc_cpqarray_hba(void) -{ - int i; - - for(i=0; i< MAX_CTLR; i++) { - if (hba[i] == NULL) { - hba[i] = kmalloc(sizeof(ctlr_info_t), GFP_KERNEL); - if(hba[i]==NULL) { - printk(KERN_ERR "cpqarray: out of memory.\n"); - return (-1); - } - return (i); - } - } - printk(KERN_WARNING "cpqarray: This driver supports a maximum" - " of 8 controllers.\n"); - return(-1); -} - -static void free_hba(int i) -{ - kfree(hba[i]); - hba[i]=NULL; -} - -/* - * Find the IO address of the controller, its IRQ and so forth. Fill - * in some basic stuff into the ctlr_info_t structure. - */ -static int cpqarray_pci_init(ctlr_info_t *c, struct pci_dev *pdev) -{ - ushort vendor_id, device_id, command; - unchar cache_line_size, latency_timer; - unchar irq, revision; - unsigned long addr[6]; - __u32 board_id; - - int i; - - c->pci_dev = pdev; - pci_set_master(pdev); - if (pci_enable_device(pdev)) { - printk(KERN_ERR "cpqarray: Unable to Enable PCI device\n"); - return -1; - } - vendor_id = pdev->vendor; - device_id = pdev->device; - revision = pdev->revision; - irq = pdev->irq; - - for(i=0; i<6; i++) - addr[i] = pci_resource_start(pdev, i); - - if (pci_set_dma_mask(pdev, CPQARRAY_DMA_MASK) != 0) - { - printk(KERN_ERR "cpqarray: Unable to set DMA mask\n"); - return -1; - } - - pci_read_config_word(pdev, PCI_COMMAND, &command); - pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache_line_size); - pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency_timer); - - pci_read_config_dword(pdev, 0x2c, &board_id); - - /* check to see if controller has been disabled */ - if(!(command & 0x02)) { - printk(KERN_WARNING - "cpqarray: controller appears to be disabled\n"); - return(-1); - } - -DBGINFO( - printk("vendor_id = %x\n", vendor_id); - printk("device_id = %x\n", device_id); - printk("command = %x\n", command); - for(i=0; i<6; i++) - printk("addr[%d] = %lx\n", i, addr[i]); - printk("revision = %x\n", revision); - printk("irq = %x\n", irq); - printk("cache_line_size = %x\n", cache_line_size); - printk("latency_timer = %x\n", latency_timer); - printk("board_id = %x\n", board_id); -); - - c->intr = irq; - - for(i=0; i<6; i++) { - if (pci_resource_flags(pdev, i) & PCI_BASE_ADDRESS_SPACE_IO) - { /* IO space */ - c->io_mem_addr = addr[i]; - c->io_mem_length = pci_resource_end(pdev, i) - - pci_resource_start(pdev, i) + 1; - if(!request_region( c->io_mem_addr, c->io_mem_length, - "cpqarray")) - { - printk( KERN_WARNING "cpqarray I/O memory range already in use addr %lx length = %ld\n", c->io_mem_addr, c->io_mem_length); - c->io_mem_addr = 0; - c->io_mem_length = 0; - } - break; - } - } - - c->paddr = 0; - for(i=0; i<6; i++) - if (!(pci_resource_flags(pdev, i) & - PCI_BASE_ADDRESS_SPACE_IO)) { - c->paddr = pci_resource_start (pdev, i); - break; - } - if (!c->paddr) - return -1; - c->vaddr = remap_pci_mem(c->paddr, 128); - if (!c->vaddr) - return -1; - c->board_id = board_id; - - for(i=0; iproduct_name = products[i].product_name; - c->access = *(products[i].access); - break; - } - } - if (i == NR_PRODUCTS) { - printk(KERN_WARNING "cpqarray: Sorry, I don't know how" - " to access the SMART Array controller %08lx\n", - (unsigned long)board_id); - return -1; - } - - return 0; -} - -/* - * Map (physical) PCI mem into (virtual) kernel space - */ -static void __iomem *remap_pci_mem(ulong base, ulong size) -{ - ulong page_base = ((ulong) base) & PAGE_MASK; - ulong page_offs = ((ulong) base) - page_base; - void __iomem *page_remapped = ioremap(page_base, page_offs+size); - - return (page_remapped ? (page_remapped + page_offs) : NULL); -} - -#ifndef MODULE -/* - * Config string is a comma separated set of i/o addresses of EISA cards. - */ -static int cpqarray_setup(char *str) -{ - int i, ints[9]; - - (void)get_options(str, ARRAY_SIZE(ints), ints); - - for(i=0; iio_mem_addr = eisa[i]; - hba[ctlr]->io_mem_length = 0x7FF; - if(!request_region(hba[ctlr]->io_mem_addr, - hba[ctlr]->io_mem_length, - "cpqarray")) - { - printk(KERN_WARNING "cpqarray: I/O range already in " - "use addr = %lx length = %ld\n", - hba[ctlr]->io_mem_addr, - hba[ctlr]->io_mem_length); - free_hba(ctlr); - continue; - } - - /* - * Read the config register to find our interrupt - */ - intr = inb(eisa[i]+0xCC0) >> 4; - if (intr & 1) intr = 11; - else if (intr & 2) intr = 10; - else if (intr & 4) intr = 14; - else if (intr & 8) intr = 15; - - hba[ctlr]->intr = intr; - sprintf(hba[ctlr]->devname, "ida%d", nr_ctlr); - hba[ctlr]->product_name = products[j].product_name; - hba[ctlr]->access = *(products[j].access); - hba[ctlr]->ctlr = ctlr; - hba[ctlr]->board_id = board_id; - hba[ctlr]->pci_dev = NULL; /* not PCI */ - -DBGINFO( - printk("i = %d, j = %d\n", i, j); - printk("irq = %x\n", intr); - printk("product name = %s\n", products[j].product_name); - printk("board_id = %x\n", board_id); -); - - num_ctlr++; - i++; - - if (cpqarray_register_ctlr(ctlr, NULL) == -1) - printk(KERN_WARNING - "cpqarray: Can't register EISA controller %d\n", - ctlr); - - } - - return num_ctlr; -} - -/* - * Open. Make sure the device is really there. - */ -static int ida_open(struct block_device *bdev, fmode_t mode) -{ - drv_info_t *drv = get_drv(bdev->bd_disk); - ctlr_info_t *host = get_host(bdev->bd_disk); - - DBGINFO(printk("ida_open %s\n", bdev->bd_disk->disk_name)); - /* - * Root is allowed to open raw volume zero even if it's not configured - * so array config can still work. I don't think I really like this, - * but I'm already using way to many device nodes to claim another one - * for "raw controller". - */ - if (!drv->nr_blks) { - if (!capable(CAP_SYS_RAWIO)) - return -ENXIO; - if (!capable(CAP_SYS_ADMIN) && drv != host->drv) - return -ENXIO; - } - host->usage_count++; - return 0; -} - -static int ida_unlocked_open(struct block_device *bdev, fmode_t mode) -{ - int ret; - - mutex_lock(&cpqarray_mutex); - ret = ida_open(bdev, mode); - mutex_unlock(&cpqarray_mutex); - - return ret; -} - -/* - * Close. Sync first. - */ -static void ida_release(struct gendisk *disk, fmode_t mode) -{ - ctlr_info_t *host; - - mutex_lock(&cpqarray_mutex); - host = get_host(disk); - host->usage_count--; - mutex_unlock(&cpqarray_mutex); -} - -/* - * Enqueuing and dequeuing functions for cmdlists. - */ -static inline void addQ(cmdlist_t **Qptr, cmdlist_t *c) -{ - if (*Qptr == NULL) { - *Qptr = c; - c->next = c->prev = c; - } else { - c->prev = (*Qptr)->prev; - c->next = (*Qptr); - (*Qptr)->prev->next = c; - (*Qptr)->prev = c; - } -} - -static inline cmdlist_t *removeQ(cmdlist_t **Qptr, cmdlist_t *c) -{ - if (c && c->next != c) { - if (*Qptr == c) *Qptr = c->next; - c->prev->next = c->next; - c->next->prev = c->prev; - } else { - *Qptr = NULL; - } - return c; -} - -/* - * Get a request and submit it to the controller. - * This routine needs to grab all the requests it possibly can from the - * req Q and submit them. Interrupts are off (and need to be off) when you - * are in here (either via the dummy do_ida_request functions or by being - * called from the interrupt handler - */ -static void do_ida_request(struct request_queue *q) -{ - ctlr_info_t *h = q->queuedata; - cmdlist_t *c; - struct request *creq; - struct scatterlist tmp_sg[SG_MAX]; - int i, dir, seg; - -queue_next: - creq = blk_peek_request(q); - if (!creq) - goto startio; - - BUG_ON(creq->nr_phys_segments > SG_MAX); - - if ((c = cmd_alloc(h,1)) == NULL) - goto startio; - - blk_start_request(creq); - - c->ctlr = h->ctlr; - c->hdr.unit = (drv_info_t *)(creq->rq_disk->private_data) - h->drv; - c->hdr.size = sizeof(rblk_t) >> 2; - c->size += sizeof(rblk_t); - - c->req.hdr.blk = blk_rq_pos(creq); - c->rq = creq; -DBGPX( - printk("sector=%d, nr_sectors=%u\n", - blk_rq_pos(creq), blk_rq_sectors(creq)); -); - sg_init_table(tmp_sg, SG_MAX); - seg = blk_rq_map_sg(q, creq, tmp_sg); - - /* Now do all the DMA Mappings */ - if (rq_data_dir(creq) == READ) - dir = PCI_DMA_FROMDEVICE; - else - dir = PCI_DMA_TODEVICE; - for( i=0; i < seg; i++) - { - c->req.sg[i].size = tmp_sg[i].length; - c->req.sg[i].addr = (__u32) pci_map_page(h->pci_dev, - sg_page(&tmp_sg[i]), - tmp_sg[i].offset, - tmp_sg[i].length, dir); - } -DBGPX( printk("Submitting %u sectors in %d segments\n", blk_rq_sectors(creq), seg); ); - c->req.hdr.sg_cnt = seg; - c->req.hdr.blk_cnt = blk_rq_sectors(creq); - c->req.hdr.cmd = (rq_data_dir(creq) == READ) ? IDA_READ : IDA_WRITE; - c->type = CMD_RWREQ; - - /* Put the request on the tail of the request queue */ - addQ(&h->reqQ, c); - h->Qdepth++; - if (h->Qdepth > h->maxQsinceinit) - h->maxQsinceinit = h->Qdepth; - - goto queue_next; - -startio: - start_io(h); -} - -/* - * start_io submits everything on a controller's request queue - * and moves it to the completion queue. - * - * Interrupts had better be off if you're in here - */ -static void start_io(ctlr_info_t *h) -{ - cmdlist_t *c; - - while((c = h->reqQ) != NULL) { - /* Can't do anything if we're busy */ - if (h->access.fifo_full(h) == 0) - return; - - /* Get the first entry from the request Q */ - removeQ(&h->reqQ, c); - h->Qdepth--; - - /* Tell the controller to do our bidding */ - h->access.submit_command(h, c); - - /* Get onto the completion Q */ - addQ(&h->cmpQ, c); - } -} - -/* - * Mark all buffers that cmd was responsible for - */ -static inline void complete_command(cmdlist_t *cmd, int timeout) -{ - struct request *rq = cmd->rq; - int error = 0; - int i, ddir; - - if (cmd->req.hdr.rcode & RCODE_NONFATAL && - (hba[cmd->ctlr]->misc_tflags & MISC_NONFATAL_WARN) == 0) { - printk(KERN_NOTICE "Non Fatal error on ida/c%dd%d\n", - cmd->ctlr, cmd->hdr.unit); - hba[cmd->ctlr]->misc_tflags |= MISC_NONFATAL_WARN; - } - if (cmd->req.hdr.rcode & RCODE_FATAL) { - printk(KERN_WARNING "Fatal error on ida/c%dd%d\n", - cmd->ctlr, cmd->hdr.unit); - error = -EIO; - } - if (cmd->req.hdr.rcode & RCODE_INVREQ) { - printk(KERN_WARNING "Invalid request on ida/c%dd%d = (cmd=%x sect=%d cnt=%d sg=%d ret=%x)\n", - cmd->ctlr, cmd->hdr.unit, cmd->req.hdr.cmd, - cmd->req.hdr.blk, cmd->req.hdr.blk_cnt, - cmd->req.hdr.sg_cnt, cmd->req.hdr.rcode); - error = -EIO; - } - if (timeout) - error = -EIO; - /* unmap the DMA mapping for all the scatter gather elements */ - if (cmd->req.hdr.cmd == IDA_READ) - ddir = PCI_DMA_FROMDEVICE; - else - ddir = PCI_DMA_TODEVICE; - for(i=0; ireq.hdr.sg_cnt; i++) - pci_unmap_page(hba[cmd->ctlr]->pci_dev, cmd->req.sg[i].addr, - cmd->req.sg[i].size, ddir); - - DBGPX(printk("Done with %p\n", rq);); - __blk_end_request_all(rq, error); -} - -/* - * The controller will interrupt us upon completion of commands. - * Find the command on the completion queue, remove it, tell the OS and - * try to queue up more IO - */ -static irqreturn_t do_ida_intr(int irq, void *dev_id) -{ - ctlr_info_t *h = dev_id; - cmdlist_t *c; - unsigned long istat; - unsigned long flags; - __u32 a,a1; - - istat = h->access.intr_pending(h); - /* Is this interrupt for us? */ - if (istat == 0) - return IRQ_NONE; - - /* - * If there are completed commands in the completion queue, - * we had better do something about it. - */ - spin_lock_irqsave(IDA_LOCK(h->ctlr), flags); - if (istat & FIFO_NOT_EMPTY) { - while((a = h->access.command_completed(h))) { - a1 = a; a &= ~3; - if ((c = h->cmpQ) == NULL) - { - printk(KERN_WARNING "cpqarray: Completion of %08lx ignored\n", (unsigned long)a1); - continue; - } - while(c->busaddr != a) { - c = c->next; - if (c == h->cmpQ) - break; - } - /* - * If we've found the command, take it off the - * completion Q and free it - */ - if (c->busaddr == a) { - removeQ(&h->cmpQ, c); - /* Check for invalid command. - * Controller returns command error, - * But rcode = 0. - */ - - if((a1 & 0x03) && (c->req.hdr.rcode == 0)) - { - c->req.hdr.rcode = RCODE_INVREQ; - } - if (c->type == CMD_RWREQ) { - complete_command(c, 0); - cmd_free(h, c, 1); - } else if (c->type == CMD_IOCTL_PEND) { - c->type = CMD_IOCTL_DONE; - } - continue; - } - } - } - - /* - * See if we can queue up some more IO - */ - do_ida_request(h->queue); - spin_unlock_irqrestore(IDA_LOCK(h->ctlr), flags); - return IRQ_HANDLED; -} - -/* - * This timer was for timing out requests that haven't happened after - * IDA_TIMEOUT. That wasn't such a good idea. This timer is used to - * reset a flags structure so we don't flood the user with - * "Non-Fatal error" messages. - */ -static void ida_timer(unsigned long tdata) -{ - ctlr_info_t *h = (ctlr_info_t*)tdata; - - h->timer.expires = jiffies + IDA_TIMER; - add_timer(&h->timer); - h->misc_tflags = 0; -} - -static int ida_getgeo(struct block_device *bdev, struct hd_geometry *geo) -{ - drv_info_t *drv = get_drv(bdev->bd_disk); - - if (drv->cylinders) { - geo->heads = drv->heads; - geo->sectors = drv->sectors; - geo->cylinders = drv->cylinders; - } else { - geo->heads = 0xff; - geo->sectors = 0x3f; - geo->cylinders = drv->nr_blks / (0xff*0x3f); - } - - return 0; -} - -/* - * ida_ioctl does some miscellaneous stuff like reporting drive geometry, - * setting readahead and submitting commands from userspace to the controller. - */ -static int ida_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) -{ - drv_info_t *drv = get_drv(bdev->bd_disk); - ctlr_info_t *host = get_host(bdev->bd_disk); - int error; - ida_ioctl_t __user *io = (ida_ioctl_t __user *)arg; - ida_ioctl_t *my_io; - - switch(cmd) { - case IDAGETDRVINFO: - if (copy_to_user(&io->c.drv, drv, sizeof(drv_info_t))) - return -EFAULT; - return 0; - case IDAPASSTHRU: - if (!capable(CAP_SYS_RAWIO)) - return -EPERM; - my_io = kmalloc(sizeof(ida_ioctl_t), GFP_KERNEL); - if (!my_io) - return -ENOMEM; - error = -EFAULT; - if (copy_from_user(my_io, io, sizeof(*my_io))) - goto out_passthru; - error = ida_ctlr_ioctl(host, drv - host->drv, my_io); - if (error) - goto out_passthru; - error = -EFAULT; - if (copy_to_user(io, my_io, sizeof(*my_io))) - goto out_passthru; - error = 0; -out_passthru: - kfree(my_io); - return error; - case IDAGETCTLRSIG: - if (!arg) return -EINVAL; - if (put_user(host->ctlr_sig, (int __user *)arg)) - return -EFAULT; - return 0; - case IDAREVALIDATEVOLS: - if (MINOR(bdev->bd_dev) != 0) - return -ENXIO; - return revalidate_allvol(host); - case IDADRIVERVERSION: - if (!arg) return -EINVAL; - if (put_user(DRIVER_VERSION, (unsigned long __user *)arg)) - return -EFAULT; - return 0; - case IDAGETPCIINFO: - { - - ida_pci_info_struct pciinfo; - - if (!arg) return -EINVAL; - memset(&pciinfo, 0, sizeof(pciinfo)); - pciinfo.bus = host->pci_dev->bus->number; - pciinfo.dev_fn = host->pci_dev->devfn; - pciinfo.board_id = host->board_id; - if(copy_to_user((void __user *) arg, &pciinfo, - sizeof( ida_pci_info_struct))) - return -EFAULT; - return(0); - } - - default: - return -EINVAL; - } - -} - -static int ida_ioctl(struct block_device *bdev, fmode_t mode, - unsigned int cmd, unsigned long param) -{ - int ret; - - mutex_lock(&cpqarray_mutex); - ret = ida_locked_ioctl(bdev, mode, cmd, param); - mutex_unlock(&cpqarray_mutex); - - return ret; -} - -/* - * ida_ctlr_ioctl is for passing commands to the controller from userspace. - * The command block (io) has already been copied to kernel space for us, - * however, any elements in the sglist need to be copied to kernel space - * or copied back to userspace. - * - * Only root may perform a controller passthru command, however I'm not doing - * any serious sanity checking on the arguments. Doing an IDA_WRITE_MEDIA and - * putting a 64M buffer in the sglist is probably a *bad* idea. - */ -static int ida_ctlr_ioctl(ctlr_info_t *h, int dsk, ida_ioctl_t *io) -{ - int ctlr = h->ctlr; - cmdlist_t *c; - void *p = NULL; - unsigned long flags; - int error; - - if ((c = cmd_alloc(h, 0)) == NULL) - return -ENOMEM; - c->ctlr = ctlr; - c->hdr.unit = (io->unit & UNITVALID) ? (io->unit & ~UNITVALID) : dsk; - c->hdr.size = sizeof(rblk_t) >> 2; - c->size += sizeof(rblk_t); - - c->req.hdr.cmd = io->cmd; - c->req.hdr.blk = io->blk; - c->req.hdr.blk_cnt = io->blk_cnt; - c->type = CMD_IOCTL_PEND; - - /* Pre submit processing */ - switch(io->cmd) { - case PASSTHRU_A: - p = memdup_user(io->sg[0].addr, io->sg[0].size); - if (IS_ERR(p)) { - error = PTR_ERR(p); - cmd_free(h, c, 0); - return error; - } - c->req.hdr.blk = pci_map_single(h->pci_dev, &(io->c), - sizeof(ida_ioctl_t), - PCI_DMA_BIDIRECTIONAL); - c->req.sg[0].size = io->sg[0].size; - c->req.sg[0].addr = pci_map_single(h->pci_dev, p, - c->req.sg[0].size, PCI_DMA_BIDIRECTIONAL); - c->req.hdr.sg_cnt = 1; - break; - case IDA_READ: - case READ_FLASH_ROM: - case SENSE_CONTROLLER_PERFORMANCE: - p = kmalloc(io->sg[0].size, GFP_KERNEL); - if (!p) - { - error = -ENOMEM; - cmd_free(h, c, 0); - return(error); - } - - c->req.sg[0].size = io->sg[0].size; - c->req.sg[0].addr = pci_map_single(h->pci_dev, p, - c->req.sg[0].size, PCI_DMA_BIDIRECTIONAL); - c->req.hdr.sg_cnt = 1; - break; - case IDA_WRITE: - case IDA_WRITE_MEDIA: - case DIAG_PASS_THRU: - case COLLECT_BUFFER: - case WRITE_FLASH_ROM: - p = memdup_user(io->sg[0].addr, io->sg[0].size); - if (IS_ERR(p)) { - error = PTR_ERR(p); - cmd_free(h, c, 0); - return error; - } - c->req.sg[0].size = io->sg[0].size; - c->req.sg[0].addr = pci_map_single(h->pci_dev, p, - c->req.sg[0].size, PCI_DMA_BIDIRECTIONAL); - c->req.hdr.sg_cnt = 1; - break; - default: - c->req.sg[0].size = sizeof(io->c); - c->req.sg[0].addr = pci_map_single(h->pci_dev,&io->c, - c->req.sg[0].size, PCI_DMA_BIDIRECTIONAL); - c->req.hdr.sg_cnt = 1; - } - - /* Put the request on the tail of the request queue */ - spin_lock_irqsave(IDA_LOCK(ctlr), flags); - addQ(&h->reqQ, c); - h->Qdepth++; - start_io(h); - spin_unlock_irqrestore(IDA_LOCK(ctlr), flags); - - /* Wait for completion */ - while(c->type != CMD_IOCTL_DONE) - schedule(); - - /* Unmap the DMA */ - pci_unmap_single(h->pci_dev, c->req.sg[0].addr, c->req.sg[0].size, - PCI_DMA_BIDIRECTIONAL); - /* Post submit processing */ - switch(io->cmd) { - case PASSTHRU_A: - pci_unmap_single(h->pci_dev, c->req.hdr.blk, - sizeof(ida_ioctl_t), - PCI_DMA_BIDIRECTIONAL); - case IDA_READ: - case DIAG_PASS_THRU: - case SENSE_CONTROLLER_PERFORMANCE: - case READ_FLASH_ROM: - if (copy_to_user(io->sg[0].addr, p, io->sg[0].size)) { - kfree(p); - return -EFAULT; - } - /* fall through and free p */ - case IDA_WRITE: - case IDA_WRITE_MEDIA: - case COLLECT_BUFFER: - case WRITE_FLASH_ROM: - kfree(p); - break; - default:; - /* Nothing to do */ - } - - io->rcode = c->req.hdr.rcode; - cmd_free(h, c, 0); - return(0); -} - -/* - * Commands are pre-allocated in a large block. Here we use a simple bitmap - * scheme to suballocte them to the driver. Operations that are not time - * critical (and can wait for kmalloc and possibly sleep) can pass in NULL - * as the first argument to get a new command. - */ -static cmdlist_t * cmd_alloc(ctlr_info_t *h, int get_from_pool) -{ - cmdlist_t * c; - int i; - dma_addr_t cmd_dhandle; - - if (!get_from_pool) { - c = (cmdlist_t*)pci_alloc_consistent(h->pci_dev, - sizeof(cmdlist_t), &cmd_dhandle); - if(c==NULL) - return NULL; - } else { - do { - i = find_first_zero_bit(h->cmd_pool_bits, NR_CMDS); - if (i == NR_CMDS) - return NULL; - } while(test_and_set_bit(i&(BITS_PER_LONG-1), h->cmd_pool_bits+(i/BITS_PER_LONG)) != 0); - c = h->cmd_pool + i; - cmd_dhandle = h->cmd_pool_dhandle + i*sizeof(cmdlist_t); - h->nr_allocs++; - } - - memset(c, 0, sizeof(cmdlist_t)); - c->busaddr = cmd_dhandle; - return c; -} - -static void cmd_free(ctlr_info_t *h, cmdlist_t *c, int got_from_pool) -{ - int i; - - if (!got_from_pool) { - pci_free_consistent(h->pci_dev, sizeof(cmdlist_t), c, - c->busaddr); - } else { - i = c - h->cmd_pool; - clear_bit(i&(BITS_PER_LONG-1), h->cmd_pool_bits+(i/BITS_PER_LONG)); - h->nr_frees++; - } -} - -/*********************************************************************** - name: sendcmd - Send a command to an IDA using the memory mapped FIFO interface - and wait for it to complete. - This routine should only be called at init time. -***********************************************************************/ -static int sendcmd( - __u8 cmd, - int ctlr, - void *buff, - size_t size, - unsigned int blk, - unsigned int blkcnt, - unsigned int log_unit ) -{ - cmdlist_t *c; - int complete; - unsigned long temp; - unsigned long i; - ctlr_info_t *info_p = hba[ctlr]; - - c = cmd_alloc(info_p, 1); - if(!c) - return IO_ERROR; - c->ctlr = ctlr; - c->hdr.unit = log_unit; - c->hdr.prio = 0; - c->hdr.size = sizeof(rblk_t) >> 2; - c->size += sizeof(rblk_t); - - /* The request information. */ - c->req.hdr.next = 0; - c->req.hdr.rcode = 0; - c->req.bp = 0; - c->req.hdr.sg_cnt = 1; - c->req.hdr.reserved = 0; - - if (size == 0) - c->req.sg[0].size = 512; - else - c->req.sg[0].size = size; - - c->req.hdr.blk = blk; - c->req.hdr.blk_cnt = blkcnt; - c->req.hdr.cmd = (unsigned char) cmd; - c->req.sg[0].addr = (__u32) pci_map_single(info_p->pci_dev, - buff, c->req.sg[0].size, PCI_DMA_BIDIRECTIONAL); - /* - * Disable interrupt - */ - info_p->access.set_intr_mask(info_p, 0); - /* Make sure there is room in the command FIFO */ - /* Actually it should be completely empty at this time. */ - for (i = 200000; i > 0; i--) { - temp = info_p->access.fifo_full(info_p); - if (temp != 0) { - break; - } - udelay(10); -DBG( - printk(KERN_WARNING "cpqarray ida%d: idaSendPciCmd FIFO full," - " waiting!\n", ctlr); -); - } - /* - * Send the cmd - */ - info_p->access.submit_command(info_p, c); - complete = pollcomplete(ctlr); - - pci_unmap_single(info_p->pci_dev, (dma_addr_t) c->req.sg[0].addr, - c->req.sg[0].size, PCI_DMA_BIDIRECTIONAL); - if (complete != 1) { - if (complete != c->busaddr) { - printk( KERN_WARNING - "cpqarray ida%d: idaSendPciCmd " - "Invalid command list address returned! (%08lx)\n", - ctlr, (unsigned long)complete); - cmd_free(info_p, c, 1); - return (IO_ERROR); - } - } else { - printk( KERN_WARNING - "cpqarray ida%d: idaSendPciCmd Timeout out, " - "No command list address returned!\n", - ctlr); - cmd_free(info_p, c, 1); - return (IO_ERROR); - } - - if (c->req.hdr.rcode & 0x00FE) { - if (!(c->req.hdr.rcode & BIG_PROBLEM)) { - printk( KERN_WARNING - "cpqarray ida%d: idaSendPciCmd, error: " - "Controller failed at init time " - "cmd: 0x%x, return code = 0x%x\n", - ctlr, c->req.hdr.cmd, c->req.hdr.rcode); - - cmd_free(info_p, c, 1); - return (IO_ERROR); - } - } - cmd_free(info_p, c, 1); - return (IO_OK); -} - -/* - * revalidate_allvol is for online array config utilities. After a - * utility reconfigures the drives in the array, it can use this function - * (through an ioctl) to make the driver zap any previous disk structs for - * that controller and get new ones. - * - * Right now I'm using the getgeometry() function to do this, but this - * function should probably be finer grained and allow you to revalidate one - * particualar logical volume (instead of all of them on a particular - * controller). - */ -static int revalidate_allvol(ctlr_info_t *host) -{ - int ctlr = host->ctlr; - int i; - unsigned long flags; - - spin_lock_irqsave(IDA_LOCK(ctlr), flags); - if (host->usage_count > 1) { - spin_unlock_irqrestore(IDA_LOCK(ctlr), flags); - printk(KERN_WARNING "cpqarray: Device busy for volume" - " revalidation (usage=%d)\n", host->usage_count); - return -EBUSY; - } - host->usage_count++; - spin_unlock_irqrestore(IDA_LOCK(ctlr), flags); - - /* - * Set the partition and block size structures for all volumes - * on this controller to zero. We will reread all of this data - */ - set_capacity(ida_gendisk[ctlr][0], 0); - for (i = 1; i < NWD; i++) { - struct gendisk *disk = ida_gendisk[ctlr][i]; - if (disk->flags & GENHD_FL_UP) - del_gendisk(disk); - } - memset(host->drv, 0, sizeof(drv_info_t)*NWD); - - /* - * Tell the array controller not to give us any interrupts while - * we check the new geometry. Then turn interrupts back on when - * we're done. - */ - host->access.set_intr_mask(host, 0); - getgeometry(ctlr); - host->access.set_intr_mask(host, FIFO_NOT_EMPTY); - - for(i=0; idrv[i]; - if (i && !drv->nr_blks) - continue; - blk_queue_logical_block_size(host->queue, drv->blk_size); - set_capacity(disk, drv->nr_blks); - disk->queue = host->queue; - disk->private_data = drv; - if (i) - add_disk(disk); - } - - host->usage_count--; - return 0; -} - -static int ida_revalidate(struct gendisk *disk) -{ - drv_info_t *drv = disk->private_data; - set_capacity(disk, drv->nr_blks); - return 0; -} - -/******************************************************************** - name: pollcomplete - Wait polling for a command to complete. - The memory mapped FIFO is polled for the completion. - Used only at init time, interrupts disabled. - ********************************************************************/ -static int pollcomplete(int ctlr) -{ - int done; - int i; - - /* Wait (up to 2 seconds) for a command to complete */ - - for (i = 200000; i > 0; i--) { - done = hba[ctlr]->access.command_completed(hba[ctlr]); - if (done == 0) { - udelay(10); /* a short fixed delay */ - } else - return (done); - } - /* Invalid address to tell caller we ran out of time */ - return 1; -} -/***************************************************************** - start_fwbk - Starts controller firmwares background processing. - Currently only the Integrated Raid controller needs this done. - If the PCI mem address registers are written to after this, - data corruption may occur -*****************************************************************/ -static void start_fwbk(int ctlr) -{ - id_ctlr_t *id_ctlr_buf; - int ret_code; - - if( (hba[ctlr]->board_id != 0x40400E11) - && (hba[ctlr]->board_id != 0x40480E11) ) - - /* Not a Integrated Raid, so there is nothing for us to do */ - return; - printk(KERN_DEBUG "cpqarray: Starting firmware's background" - " processing\n"); - /* Command does not return anything, but idasend command needs a - buffer */ - id_ctlr_buf = kmalloc(sizeof(id_ctlr_t), GFP_KERNEL); - if(id_ctlr_buf==NULL) - { - printk(KERN_WARNING "cpqarray: Out of memory. " - "Unable to start background processing.\n"); - return; - } - ret_code = sendcmd(RESUME_BACKGROUND_ACTIVITY, ctlr, - id_ctlr_buf, 0, 0, 0, 0); - if(ret_code != IO_OK) - printk(KERN_WARNING "cpqarray: Unable to start" - " background processing\n"); - - kfree(id_ctlr_buf); -} -/***************************************************************** - getgeometry - Get ida logical volume geometry from the controller - This is a large bit of code which once existed in two flavors, - It is used only at init time. -*****************************************************************/ -static void getgeometry(int ctlr) -{ - id_log_drv_t *id_ldrive; - id_ctlr_t *id_ctlr_buf; - sense_log_drv_stat_t *id_lstatus_buf; - config_t *sense_config_buf; - unsigned int log_unit, log_index; - int ret_code, size; - drv_info_t *drv; - ctlr_info_t *info_p = hba[ctlr]; - int i; - - info_p->log_drv_map = 0; - - id_ldrive = kzalloc(sizeof(id_log_drv_t), GFP_KERNEL); - if (!id_ldrive) { - printk( KERN_ERR "cpqarray: out of memory.\n"); - goto err_0; - } - - id_ctlr_buf = kzalloc(sizeof(id_ctlr_t), GFP_KERNEL); - if (!id_ctlr_buf) { - printk( KERN_ERR "cpqarray: out of memory.\n"); - goto err_1; - } - - id_lstatus_buf = kzalloc(sizeof(sense_log_drv_stat_t), GFP_KERNEL); - if (!id_lstatus_buf) { - printk( KERN_ERR "cpqarray: out of memory.\n"); - goto err_2; - } - - sense_config_buf = kzalloc(sizeof(config_t), GFP_KERNEL); - if (!sense_config_buf) { - printk( KERN_ERR "cpqarray: out of memory.\n"); - goto err_3; - } - - info_p->phys_drives = 0; - info_p->log_drv_map = 0; - info_p->drv_assign_map = 0; - info_p->drv_spare_map = 0; - info_p->mp_failed_drv_map = 0; /* only initialized here */ - /* Get controllers info for this logical drive */ - ret_code = sendcmd(ID_CTLR, ctlr, id_ctlr_buf, 0, 0, 0, 0); - if (ret_code == IO_ERROR) { - /* - * If can't get controller info, set the logical drive map to 0, - * so the idastubopen will fail on all logical drives - * on the controller. - */ - printk(KERN_ERR "cpqarray: error sending ID controller\n"); - goto err_4; - } - - info_p->log_drives = id_ctlr_buf->nr_drvs; - for(i=0;i<4;i++) - info_p->firm_rev[i] = id_ctlr_buf->firm_rev[i]; - info_p->ctlr_sig = id_ctlr_buf->cfg_sig; - - printk(" (%s)\n", info_p->product_name); - /* - * Initialize logical drive map to zero - */ - log_index = 0; - /* - * Get drive geometry for all logical drives - */ - if (id_ctlr_buf->nr_drvs > 16) - printk(KERN_WARNING "cpqarray ida%d: This driver supports " - "16 logical drives per controller.\n. " - " Additional drives will not be " - "detected\n", ctlr); - - for (log_unit = 0; - (log_index < id_ctlr_buf->nr_drvs) - && (log_unit < NWD); - log_unit++) { - size = sizeof(sense_log_drv_stat_t); - - /* - Send "Identify logical drive status" cmd - */ - ret_code = sendcmd(SENSE_LOG_DRV_STAT, - ctlr, id_lstatus_buf, size, 0, 0, log_unit); - if (ret_code == IO_ERROR) { - /* - If can't get logical drive status, set - the logical drive map to 0, so the - idastubopen will fail for all logical drives - on the controller. - */ - info_p->log_drv_map = 0; - printk( KERN_WARNING - "cpqarray ida%d: idaGetGeometry - Controller" - " failed to report status of logical drive %d\n" - "Access to this controller has been disabled\n", - ctlr, log_unit); - goto err_4; - } - /* - Make sure the logical drive is configured - */ - if (id_lstatus_buf->status != LOG_NOT_CONF) { - ret_code = sendcmd(ID_LOG_DRV, ctlr, id_ldrive, - sizeof(id_log_drv_t), 0, 0, log_unit); - /* - If error, the bit for this - logical drive won't be set and - idastubopen will return error. - */ - if (ret_code != IO_ERROR) { - drv = &info_p->drv[log_unit]; - drv->blk_size = id_ldrive->blk_size; - drv->nr_blks = id_ldrive->nr_blks; - drv->cylinders = id_ldrive->drv.cyl; - drv->heads = id_ldrive->drv.heads; - drv->sectors = id_ldrive->drv.sect_per_track; - info_p->log_drv_map |= (1 << log_unit); - - printk(KERN_INFO "cpqarray ida/c%dd%d: blksz=%d nr_blks=%d\n", - ctlr, log_unit, drv->blk_size, drv->nr_blks); - ret_code = sendcmd(SENSE_CONFIG, - ctlr, sense_config_buf, - sizeof(config_t), 0, 0, log_unit); - if (ret_code == IO_ERROR) { - info_p->log_drv_map = 0; - printk(KERN_ERR "cpqarray: error sending sense config\n"); - goto err_4; - } - - info_p->phys_drives = - sense_config_buf->ctlr_phys_drv; - info_p->drv_assign_map - |= sense_config_buf->drv_asgn_map; - info_p->drv_assign_map - |= sense_config_buf->spare_asgn_map; - info_p->drv_spare_map - |= sense_config_buf->spare_asgn_map; - } /* end of if no error on id_ldrive */ - log_index = log_index + 1; - } /* end of if logical drive configured */ - } /* end of for log_unit */ - - /* Free all the buffers and return */ -err_4: - kfree(sense_config_buf); -err_3: - kfree(id_lstatus_buf); -err_2: - kfree(id_ctlr_buf); -err_1: - kfree(id_ldrive); -err_0: - return; -} - -static void __exit cpqarray_exit(void) -{ - int i; - - pci_unregister_driver(&cpqarray_pci_driver); - - /* Double check that all controller entries have been removed */ - for(i=0; i -#include -#include -#include -#endif - -#include "ida_cmd.h" - -#define IO_OK 0 -#define IO_ERROR 1 -#define NWD 16 -#define NWD_SHIFT 4 - -#define IDA_TIMER (5*HZ) -#define IDA_TIMEOUT (10*HZ) - -#define MISC_NONFATAL_WARN 0x01 - -typedef struct { - unsigned blk_size; - unsigned nr_blks; - unsigned cylinders; - unsigned heads; - unsigned sectors; - int usage_count; -} drv_info_t; - -#ifdef __KERNEL__ - -struct ctlr_info; -typedef struct ctlr_info ctlr_info_t; - -struct access_method { - void (*submit_command)(ctlr_info_t *h, cmdlist_t *c); - void (*set_intr_mask)(ctlr_info_t *h, unsigned long val); - unsigned long (*fifo_full)(ctlr_info_t *h); - unsigned long (*intr_pending)(ctlr_info_t *h); - unsigned long (*command_completed)(ctlr_info_t *h); -}; - -struct board_type { - __u32 board_id; - char *product_name; - struct access_method *access; -}; - -struct ctlr_info { - int ctlr; - char devname[8]; - __u32 log_drv_map; - __u32 drv_assign_map; - __u32 drv_spare_map; - __u32 mp_failed_drv_map; - - char firm_rev[4]; - int ctlr_sig; - - int log_drives; - int phys_drives; - - struct pci_dev *pci_dev; /* NULL if EISA */ - __u32 board_id; - char *product_name; - - void __iomem *vaddr; - unsigned long paddr; - unsigned long io_mem_addr; - unsigned long io_mem_length; - int intr; - int usage_count; - drv_info_t drv[NWD]; - struct proc_dir_entry *proc; - - struct access_method access; - - cmdlist_t *reqQ; - cmdlist_t *cmpQ; - cmdlist_t *cmd_pool; - dma_addr_t cmd_pool_dhandle; - unsigned long *cmd_pool_bits; - struct request_queue *queue; - spinlock_t lock; - - unsigned int Qdepth; - unsigned int maxQsinceinit; - - unsigned int nr_requests; - unsigned int nr_allocs; - unsigned int nr_frees; - struct timer_list timer; - unsigned int misc_tflags; -}; - -#define IDA_LOCK(i) (&hba[i]->lock) - -#endif - -#endif /* CPQARRAY_H */ diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index c227fd4cad75fe62eba5bcfd8b0ef22742a080e3..7a1cf7eaa71dc8adccd1a5a5d332edacda8df40f 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -1327,8 +1327,8 @@ struct bm_extent { #endif #endif -/* BIO_MAX_SIZE is 256 * PAGE_CACHE_SIZE, - * so for typical PAGE_CACHE_SIZE of 4k, that is (1<<20) Byte. +/* BIO_MAX_SIZE is 256 * PAGE_SIZE, + * so for typical PAGE_SIZE of 4k, that is (1<<20) Byte. * Since we may live in a mixed-platform cluster, * we limit us to a platform agnostic constant here for now. * A followup commit may allow even bigger BIO sizes, diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 226eb0c9f0fb33a7ee795dbf3661ec5bac58da77..1fd1dccebb6bc9c6b16184a3693ffcfa59045563 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -1178,7 +1178,7 @@ static void drbd_setup_queue_param(struct drbd_device *device, struct drbd_backi blk_queue_max_hw_sectors(q, max_hw_sectors); /* This is the workaround for "bio would need to, but cannot, be split" */ blk_queue_max_segments(q, max_segments ? max_segments : BLK_MAX_SEGMENTS); - blk_queue_segment_boundary(q, PAGE_CACHE_SIZE-1); + blk_queue_segment_boundary(q, PAGE_SIZE-1); if (b) { struct drbd_connection *connection = first_peer_device(device)->connection; diff --git a/drivers/block/ida_cmd.h b/drivers/block/ida_cmd.h deleted file mode 100644 index 98b5746b30893bb613fbb0deff3b4cdae787f2bd..0000000000000000000000000000000000000000 --- a/drivers/block/ida_cmd.h +++ /dev/null @@ -1,349 +0,0 @@ -/* - * Disk Array driver for Compaq SMART2 Controllers - * Copyright 1998 Compaq Computer Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Questions/Comments/Bugfixes to iss_storagedev@hp.com - * - */ -#ifndef ARRAYCMD_H -#define ARRAYCMD_H - -#include -#if 0 -#include -#endif - -/* for the Smart Array 42XX cards */ -#define S42XX_REQUEST_PORT_OFFSET 0x40 -#define S42XX_REPLY_INTR_MASK_OFFSET 0x34 -#define S42XX_REPLY_PORT_OFFSET 0x44 -#define S42XX_INTR_STATUS 0x30 - -#define S42XX_INTR_OFF 0x08 -#define S42XX_INTR_PENDING 0x08 - -#define COMMAND_FIFO 0x04 -#define COMMAND_COMPLETE_FIFO 0x08 -#define INTR_MASK 0x0C -#define INTR_STATUS 0x10 -#define INTR_PENDING 0x14 - -#define FIFO_NOT_EMPTY 0x01 -#define FIFO_NOT_FULL 0x02 - -#define BIG_PROBLEM 0x40 -#define LOG_NOT_CONF 2 - -#pragma pack(1) -typedef struct { - __u32 size; - __u32 addr; -} sg_t; - -#define RCODE_NONFATAL 0x02 -#define RCODE_FATAL 0x04 -#define RCODE_INVREQ 0x10 -typedef struct { - __u16 next; - __u8 cmd; - __u8 rcode; - __u32 blk; - __u16 blk_cnt; - __u8 sg_cnt; - __u8 reserved; -} rhdr_t; - -#define SG_MAX 32 -typedef struct { - rhdr_t hdr; - sg_t sg[SG_MAX]; - __u32 bp; -} rblk_t; - -typedef struct { - __u8 unit; - __u8 prio; - __u16 size; -} chdr_t; - -#define CMD_RWREQ 0x00 -#define CMD_IOCTL_PEND 0x01 -#define CMD_IOCTL_DONE 0x02 - -typedef struct cmdlist { - chdr_t hdr; - rblk_t req; - __u32 size; - int retry_cnt; - __u32 busaddr; - int ctlr; - struct cmdlist *prev; - struct cmdlist *next; - struct request *rq; - int type; -} cmdlist_t; - -#define ID_CTLR 0x11 -typedef struct { - __u8 nr_drvs; - __u32 cfg_sig; - __u8 firm_rev[4]; - __u8 rom_rev[4]; - __u8 hw_rev; - __u32 bb_rev; - __u32 drv_present_map; - __u32 ext_drv_map; - __u32 board_id; - __u8 cfg_error; - __u32 non_disk_bits; - __u8 bad_ram_addr; - __u8 cpu_rev; - __u8 pdpi_rev; - __u8 epic_rev; - __u8 wcxc_rev; - __u8 marketing_rev; - __u8 ctlr_flags; - __u8 host_flags; - __u8 expand_dis; - __u8 scsi_chips; - __u32 max_req_blocks; - __u32 ctlr_clock; - __u8 drvs_per_bus; - __u16 big_drv_present_map[8]; - __u16 big_ext_drv_map[8]; - __u16 big_non_disk_map[8]; - __u16 task_flags; - __u8 icl_bus; - __u8 red_modes; - __u8 cur_red_mode; - __u8 red_ctlr_stat; - __u8 red_fail_reason; - __u8 reserved[403]; -} id_ctlr_t; - -typedef struct { - __u16 cyl; - __u8 heads; - __u8 xsig; - __u8 psectors; - __u16 wpre; - __u8 maxecc; - __u8 drv_ctrl; - __u16 pcyls; - __u8 pheads; - __u16 landz; - __u8 sect_per_track; - __u8 cksum; -} drv_param_t; - -#define ID_LOG_DRV 0x10 -typedef struct { - __u16 blk_size; - __u32 nr_blks; - drv_param_t drv; - __u8 fault_tol; - __u8 reserved; - __u8 bios_disable; -} id_log_drv_t; - -#define ID_LOG_DRV_EXT 0x18 -typedef struct { - __u32 log_drv_id; - __u8 log_drv_label[64]; - __u8 reserved[418]; -} id_log_drv_ext_t; - -#define SENSE_LOG_DRV_STAT 0x12 -typedef struct { - __u8 status; - __u32 fail_map; - __u16 read_err[32]; - __u16 write_err[32]; - __u8 drv_err_data[256]; - __u8 drq_timeout[32]; - __u32 blks_to_recover; - __u8 drv_recovering; - __u16 remap_cnt[32]; - __u32 replace_drv_map; - __u32 act_spare_map; - __u8 spare_stat; - __u8 spare_repl_map[32]; - __u32 repl_ok_map; - __u8 media_exch; - __u8 cache_fail; - __u8 expn_fail; - __u8 unit_flags; - __u16 big_fail_map[8]; - __u16 big_remap_map[128]; - __u16 big_repl_map[8]; - __u16 big_act_spare_map[8]; - __u8 big_spar_repl_map[128]; - __u16 big_repl_ok_map[8]; - __u8 big_drv_rebuild; - __u8 reserved[36]; -} sense_log_drv_stat_t; - -#define START_RECOVER 0x13 - -#define ID_PHYS_DRV 0x15 -typedef struct { - __u8 scsi_bus; - __u8 scsi_id; - __u16 blk_size; - __u32 nr_blks; - __u32 rsvd_blks; - __u8 drv_model[40]; - __u8 drv_sn[40]; - __u8 drv_fw[8]; - __u8 scsi_iq_bits; - __u8 compaq_drv_stmp; - __u8 last_fail; - __u8 phys_drv_flags; - __u8 phys_drv_flags1; - __u8 scsi_lun; - __u8 phys_drv_flags2; - __u8 reserved; - __u32 spi_speed_rules; - __u8 phys_connector[2]; - __u8 phys_box_on_bus; - __u8 phys_bay_in_box; -} id_phys_drv_t; - -#define BLINK_DRV_LEDS 0x16 -typedef struct { - __u32 blink_duration; - __u32 reserved; - __u8 blink[256]; - __u8 reserved1[248]; -} blink_drv_leds_t; - -#define SENSE_BLINK_LEDS 0x17 -typedef struct { - __u32 blink_duration; - __u32 btime_elap; - __u8 blink[256]; - __u8 reserved1[248]; -} sense_blink_leds_t; - -#define IDA_READ 0x20 -#define IDA_WRITE 0x30 -#define IDA_WRITE_MEDIA 0x31 -#define RESET_TO_DIAG 0x40 -#define DIAG_PASS_THRU 0x41 - -#define SENSE_CONFIG 0x50 -#define SET_CONFIG 0x51 -typedef struct { - __u32 cfg_sig; - __u16 compat_port; - __u8 data_dist_mode; - __u8 surf_an_ctrl; - __u16 ctlr_phys_drv; - __u16 log_unit_phys_drv; - __u16 fault_tol_mode; - __u8 phys_drv_param[16]; - drv_param_t drv; - __u32 drv_asgn_map; - __u16 dist_factor; - __u32 spare_asgn_map; - __u8 reserved[6]; - __u16 os; - __u8 ctlr_order; - __u8 extra_info; - __u32 data_offs; - __u8 parity_backedout_write_drvs; - __u8 parity_dist_mode; - __u8 parity_shift_fact; - __u8 bios_disable_flag; - __u32 blks_on_vol; - __u32 blks_per_drv; - __u8 scratch[16]; - __u16 big_drv_map[8]; - __u16 big_spare_map[8]; - __u8 ss_source_vol; - __u8 mix_drv_cap_range; - struct { - __u16 big_drv_map[8]; - __u32 blks_per_drv; - __u16 fault_tol_mode; - __u16 dist_factor; - } MDC_range[4]; - __u8 reserved1[248]; -} config_t; - -#define BYPASS_VOL_STATE 0x52 -#define SS_CREATE_VOL 0x53 -#define CHANGE_CONFIG 0x54 -#define SENSE_ORIG_CONF 0x55 -#define REORDER_LOG_DRV 0x56 -typedef struct { - __u8 old_units[32]; -} reorder_log_drv_t; - -#define LABEL_LOG_DRV 0x57 -typedef struct { - __u8 log_drv_label[64]; -} label_log_drv_t; - -#define SS_TO_VOL 0x58 - -#define SET_SURF_DELAY 0x60 -typedef struct { - __u16 delay; - __u8 reserved[510]; -} surf_delay_t; - -#define SET_OVERHEAT_DELAY 0x61 -typedef struct { - __u16 delay; -} overhead_delay_t; - -#define SET_MP_DELAY -typedef struct { - __u16 delay; - __u8 reserved[510]; -} mp_delay_t; - -#define PASSTHRU_A 0x91 -typedef struct { - __u8 target; - __u8 bus; - __u8 lun; - __u32 timeout; - __u32 flags; - __u8 status; - __u8 error; - __u8 cdb_len; - __u8 sense_error; - __u8 sense_key; - __u32 sense_info; - __u8 sense_code; - __u8 sense_qual; - __u32 residual; - __u8 reserved[4]; - __u8 cdb[12]; -} scsi_param_t; - -#define RESUME_BACKGROUND_ACTIVITY 0x99 -#define SENSE_CONTROLLER_PERFORMANCE 0xa8 -#define FLUSH_CACHE 0xc2 -#define COLLECT_BUFFER 0xd2 -#define READ_FLASH_ROM 0xf6 -#define WRITE_FLASH_ROM 0xf7 -#pragma pack() - -#endif /* ARRAYCMD_H */ diff --git a/drivers/block/ida_ioctl.h b/drivers/block/ida_ioctl.h deleted file mode 100644 index 888fff9caed089e0491bf8fbd9bf7c0c67ea1b54..0000000000000000000000000000000000000000 --- a/drivers/block/ida_ioctl.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Disk Array driver for Compaq SMART2 Controllers - * Copyright 1998 Compaq Computer Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Questions/Comments/Bugfixes to iss_storagedev@hp.com - * - */ -#ifndef IDA_IOCTL_H -#define IDA_IOCTL_H - -#include "ida_cmd.h" -#include "cpqarray.h" - -#define IDAGETDRVINFO 0x27272828 -#define IDAPASSTHRU 0x28282929 -#define IDAGETCTLRSIG 0x29293030 -#define IDAREVALIDATEVOLS 0x30303131 -#define IDADRIVERVERSION 0x31313232 -#define IDAGETPCIINFO 0x32323333 - -typedef struct _ida_pci_info_struct -{ - unsigned char bus; - unsigned char dev_fn; - __u32 board_id; -} ida_pci_info_struct; -/* - * Normally, the ioctl determines the logical unit for this command by - * the major,minor number of the fd passed to ioctl. If you need to send - * a command to a different/nonexistant unit (such as during config), you - * can override the normal behavior by setting the unit valid bit. (Normally, - * it should be zero) The controller the command is sent to is still - * determined by the major number of the open device. - */ - -#define UNITVALID 0x80 -typedef struct { - __u8 cmd; - __u8 rcode; - __u8 unit; - __u32 blk; - __u16 blk_cnt; - -/* currently, sg_cnt is assumed to be 1: only the 0th element of sg is used */ - struct { - void __user *addr; - size_t size; - } sg[SG_MAX]; - int sg_cnt; - - union ctlr_cmds { - drv_info_t drv; - unsigned char buf[1024]; - - id_ctlr_t id_ctlr; - drv_param_t drv_param; - id_log_drv_t id_log_drv; - id_log_drv_ext_t id_log_drv_ext; - sense_log_drv_stat_t sense_log_drv_stat; - id_phys_drv_t id_phys_drv; - blink_drv_leds_t blink_drv_leds; - sense_blink_leds_t sense_blink_leds; - config_t config; - reorder_log_drv_t reorder_log_drv; - label_log_drv_t label_log_drv; - surf_delay_t surf_delay; - overhead_delay_t overhead_delay; - mp_delay_t mp_delay; - scsi_param_t scsi_param; - } c; -} ida_ioctl_t; - -#endif /* IDA_IOCTL_H */ diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 9b180dbbd03cc822c776e636183614bf59a76d3d..25824c1697c508e03125d05bd5d5fa44d0dacacf 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -173,7 +173,13 @@ static struct mtip_cmd *mtip_get_int_command(struct driver_data *dd) { struct request *rq; + if (mtip_check_surprise_removal(dd->pdev)) + return NULL; + rq = blk_mq_alloc_request(dd->queue, 0, BLK_MQ_REQ_RESERVED); + if (IS_ERR(rq)) + return NULL; + return blk_mq_rq_to_pdu(rq); } @@ -233,15 +239,9 @@ static void mtip_async_complete(struct mtip_port *port, "Command tag %d failed due to TFE\n", tag); } - /* Unmap the DMA scatter list entries */ - dma_unmap_sg(&dd->pdev->dev, cmd->sg, cmd->scatter_ents, cmd->direction); - rq = mtip_rq_from_tag(dd, tag); - if (unlikely(cmd->unaligned)) - up(&port->cmd_slot_unal); - - blk_mq_end_request(rq, status ? -EIO : 0); + blk_mq_complete_request(rq, status); } /* @@ -581,6 +581,8 @@ static void mtip_completion(struct mtip_port *port, dev_warn(&port->dd->pdev->dev, "Internal command %d completed with TFE\n", tag); + command->comp_func = NULL; + command->comp_data = NULL; complete(waiting); } @@ -618,8 +620,6 @@ static void mtip_handle_tfe(struct driver_data *dd) port = dd->port; - set_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); - if (test_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags)) { cmd = mtip_cmd_from_tag(dd, MTIP_TAG_INTERNAL); dbg_printk(MTIP_DRV_NAME " TFE for the internal command\n"); @@ -628,7 +628,7 @@ static void mtip_handle_tfe(struct driver_data *dd) cmd->comp_func(port, MTIP_TAG_INTERNAL, cmd, PORT_IRQ_TF_ERR); } - goto handle_tfe_exit; + return; } /* clear the tag accumulator */ @@ -701,7 +701,7 @@ static void mtip_handle_tfe(struct driver_data *dd) fail_reason = "thermal shutdown"; } if (buf[288] == 0xBF) { - set_bit(MTIP_DDF_SEC_LOCK_BIT, &dd->dd_flag); + set_bit(MTIP_DDF_REBUILD_FAILED_BIT, &dd->dd_flag); dev_info(&dd->pdev->dev, "Drive indicates rebuild has failed. Secure erase required.\n"); fail_all_ncq_cmds = 1; @@ -771,11 +771,6 @@ static void mtip_handle_tfe(struct driver_data *dd) } } print_tags(dd, "reissued (TFE)", tagaccum, cmd_cnt); - -handle_tfe_exit: - /* clear eh_active */ - clear_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags); - wake_up_interruptible(&port->svc_wait); } /* @@ -1007,6 +1002,7 @@ static bool mtip_pause_ncq(struct mtip_port *port, (fis->features == 0x27 || fis->features == 0x72 || fis->features == 0x62 || fis->features == 0x26))) { clear_bit(MTIP_DDF_SEC_LOCK_BIT, &port->dd->dd_flag); + clear_bit(MTIP_DDF_REBUILD_FAILED_BIT, &port->dd->dd_flag); /* Com reset after secure erase or lowlevel format */ mtip_restart_port(port); clear_bit(MTIP_PF_SE_ACTIVE_BIT, &port->flags); @@ -1021,12 +1017,14 @@ static bool mtip_pause_ncq(struct mtip_port *port, * * @port Pointer to port data structure * @timeout Max duration to wait (ms) + * @atomic gfp_t flag to indicate blockable context or not * * return value * 0 Success * -EBUSY Commands still active */ -static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout) +static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout, + gfp_t atomic) { unsigned long to; unsigned int n; @@ -1037,16 +1035,21 @@ static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout) to = jiffies + msecs_to_jiffies(timeout); do { if (test_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags) && - test_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags)) { + test_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags) && + atomic == GFP_KERNEL) { msleep(20); continue; /* svc thd is actively issuing commands */ } - msleep(100); + if (atomic == GFP_KERNEL) + msleep(100); + else { + cpu_relax(); + udelay(100); + } + if (mtip_check_surprise_removal(port->dd->pdev)) goto err_fault; - if (test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &port->dd->dd_flag)) - goto err_fault; /* * Ignore s_active bit 0 of array element 0. @@ -1099,6 +1102,7 @@ static int mtip_exec_internal_command(struct mtip_port *port, struct mtip_cmd *int_cmd; struct driver_data *dd = port->dd; int rv = 0; + unsigned long start; /* Make sure the buffer is 8 byte aligned. This is asic specific. */ if (buffer & 0x00000007) { @@ -1107,6 +1111,10 @@ static int mtip_exec_internal_command(struct mtip_port *port, } int_cmd = mtip_get_int_command(dd); + if (!int_cmd) { + dbg_printk(MTIP_DRV_NAME "Unable to allocate tag for PIO cmd\n"); + return -EFAULT; + } set_bit(MTIP_PF_IC_ACTIVE_BIT, &port->flags); @@ -1119,7 +1127,7 @@ static int mtip_exec_internal_command(struct mtip_port *port, if (fis->command != ATA_CMD_STANDBYNOW1) { /* wait for io to complete if non atomic */ if (mtip_quiesce_io(port, - MTIP_QUIESCE_IO_TIMEOUT_MS) < 0) { + MTIP_QUIESCE_IO_TIMEOUT_MS, atomic) < 0) { dev_warn(&dd->pdev->dev, "Failed to quiesce IO\n"); mtip_put_int_command(dd, int_cmd); @@ -1162,6 +1170,8 @@ static int mtip_exec_internal_command(struct mtip_port *port, /* Populate the command header */ int_cmd->command_header->byte_count = 0; + start = jiffies; + /* Issue the command to the hardware */ mtip_issue_non_ncq_command(port, MTIP_TAG_INTERNAL); @@ -1170,10 +1180,12 @@ static int mtip_exec_internal_command(struct mtip_port *port, if ((rv = wait_for_completion_interruptible_timeout( &wait, msecs_to_jiffies(timeout))) <= 0) { + if (rv == -ERESTARTSYS) { /* interrupted */ dev_err(&dd->pdev->dev, - "Internal command [%02X] was interrupted after %lu ms\n", - fis->command, timeout); + "Internal command [%02X] was interrupted after %u ms\n", + fis->command, + jiffies_to_msecs(jiffies - start)); rv = -EINTR; goto exec_ic_exit; } else if (rv == 0) /* timeout */ @@ -2039,7 +2051,7 @@ static int exec_drive_taskfile(struct driver_data *dd, outbuf, taskout, DMA_TO_DEVICE); - if (outbuf_dma == 0) { + if (pci_dma_mapping_error(dd->pdev, outbuf_dma)) { err = -ENOMEM; goto abort; } @@ -2056,7 +2068,7 @@ static int exec_drive_taskfile(struct driver_data *dd, inbuf_dma = pci_map_single(dd->pdev, inbuf, taskin, DMA_FROM_DEVICE); - if (inbuf_dma == 0) { + if (pci_dma_mapping_error(dd->pdev, inbuf_dma)) { err = -ENOMEM; goto abort; } @@ -2890,6 +2902,42 @@ static int mtip_ftl_rebuild_poll(struct driver_data *dd) return -EFAULT; } +static void mtip_softirq_done_fn(struct request *rq) +{ + struct mtip_cmd *cmd = blk_mq_rq_to_pdu(rq); + struct driver_data *dd = rq->q->queuedata; + + /* Unmap the DMA scatter list entries */ + dma_unmap_sg(&dd->pdev->dev, cmd->sg, cmd->scatter_ents, + cmd->direction); + + if (unlikely(cmd->unaligned)) + up(&dd->port->cmd_slot_unal); + + blk_mq_end_request(rq, rq->errors); +} + +static void mtip_abort_cmd(struct request *req, void *data, + bool reserved) +{ + struct driver_data *dd = data; + + dbg_printk(MTIP_DRV_NAME " Aborting request, tag = %d\n", req->tag); + + clear_bit(req->tag, dd->port->cmds_to_issue); + req->errors = -EIO; + mtip_softirq_done_fn(req); +} + +static void mtip_queue_cmd(struct request *req, void *data, + bool reserved) +{ + struct driver_data *dd = data; + + set_bit(req->tag, dd->port->cmds_to_issue); + blk_abort_request(req); +} + /* * service thread to issue queued commands * @@ -2902,7 +2950,7 @@ static int mtip_ftl_rebuild_poll(struct driver_data *dd) static int mtip_service_thread(void *data) { struct driver_data *dd = (struct driver_data *)data; - unsigned long slot, slot_start, slot_wrap; + unsigned long slot, slot_start, slot_wrap, to; unsigned int num_cmd_slots = dd->slot_groups * 32; struct mtip_port *port = dd->port; @@ -2917,9 +2965,7 @@ static int mtip_service_thread(void *data) * is in progress nor error handling is active */ wait_event_interruptible(port->svc_wait, (port->flags) && - !(port->flags & MTIP_PF_PAUSE_IO)); - - set_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags); + (port->flags & MTIP_PF_SVC_THD_WORK)); if (kthread_should_stop() || test_bit(MTIP_PF_SVC_THD_STOP_BIT, &port->flags)) @@ -2929,6 +2975,8 @@ static int mtip_service_thread(void *data) &dd->dd_flag))) goto st_out; + set_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags); + restart_eh: /* Demux bits: start with error handling */ if (test_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags)) { @@ -2939,6 +2987,32 @@ static int mtip_service_thread(void *data) if (test_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags)) goto restart_eh; + if (test_bit(MTIP_PF_TO_ACTIVE_BIT, &port->flags)) { + to = jiffies + msecs_to_jiffies(5000); + + do { + mdelay(100); + } while (atomic_read(&dd->irq_workers_active) != 0 && + time_before(jiffies, to)); + + if (atomic_read(&dd->irq_workers_active) != 0) + dev_warn(&dd->pdev->dev, + "Completion workers still active!"); + + spin_lock(dd->queue->queue_lock); + blk_mq_all_tag_busy_iter(*dd->tags.tags, + mtip_queue_cmd, dd); + spin_unlock(dd->queue->queue_lock); + + set_bit(MTIP_PF_ISSUE_CMDS_BIT, &dd->port->flags); + + if (mtip_device_reset(dd)) + blk_mq_all_tag_busy_iter(*dd->tags.tags, + mtip_abort_cmd, dd); + + clear_bit(MTIP_PF_TO_ACTIVE_BIT, &dd->port->flags); + } + if (test_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags)) { slot = 1; /* used to restrict the loop to one iteration */ @@ -2971,10 +3045,8 @@ static int mtip_service_thread(void *data) } if (test_bit(MTIP_PF_REBUILD_BIT, &port->flags)) { - if (mtip_ftl_rebuild_poll(dd) < 0) - set_bit(MTIP_DDF_REBUILD_FAILED_BIT, - &dd->dd_flag); - clear_bit(MTIP_PF_REBUILD_BIT, &port->flags); + if (mtip_ftl_rebuild_poll(dd) == 0) + clear_bit(MTIP_PF_REBUILD_BIT, &port->flags); } } @@ -3089,7 +3161,7 @@ static int mtip_hw_get_identify(struct driver_data *dd) if (buf[288] == 0xBF) { dev_info(&dd->pdev->dev, "Drive indicates rebuild has failed.\n"); - /* TODO */ + set_bit(MTIP_DDF_REBUILD_FAILED_BIT, &dd->dd_flag); } } @@ -3263,20 +3335,25 @@ static int mtip_hw_init(struct driver_data *dd) return rv; } -static void mtip_standby_drive(struct driver_data *dd) +static int mtip_standby_drive(struct driver_data *dd) { - if (dd->sr) - return; + int rv = 0; + if (dd->sr || !dd->port) + return -ENODEV; /* * Send standby immediate (E0h) to the drive so that it * saves its state. */ if (!test_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags) && - !test_bit(MTIP_DDF_SEC_LOCK_BIT, &dd->dd_flag)) - if (mtip_standby_immediate(dd->port)) + !test_bit(MTIP_DDF_REBUILD_FAILED_BIT, &dd->dd_flag) && + !test_bit(MTIP_DDF_SEC_LOCK_BIT, &dd->dd_flag)) { + rv = mtip_standby_immediate(dd->port); + if (rv) dev_warn(&dd->pdev->dev, "STANDBY IMMEDIATE failed\n"); + } + return rv; } /* @@ -3289,10 +3366,6 @@ static void mtip_standby_drive(struct driver_data *dd) */ static int mtip_hw_exit(struct driver_data *dd) { - /* - * Send standby immediate (E0h) to the drive so that it - * saves its state. - */ if (!dd->sr) { /* de-initialize the port. */ mtip_deinit_port(dd->port); @@ -3334,8 +3407,7 @@ static int mtip_hw_shutdown(struct driver_data *dd) * Send standby immediate (E0h) to the drive so that it * saves its state. */ - if (!dd->sr && dd->port) - mtip_standby_immediate(dd->port); + mtip_standby_drive(dd); return 0; } @@ -3358,7 +3430,7 @@ static int mtip_hw_suspend(struct driver_data *dd) * Send standby immediate (E0h) to the drive * so that it saves its state. */ - if (mtip_standby_immediate(dd->port) != 0) { + if (mtip_standby_drive(dd) != 0) { dev_err(&dd->pdev->dev, "Failed standby-immediate command\n"); return -EFAULT; @@ -3596,6 +3668,28 @@ static int mtip_block_getgeo(struct block_device *dev, return 0; } +static int mtip_block_open(struct block_device *dev, fmode_t mode) +{ + struct driver_data *dd; + + if (dev && dev->bd_disk) { + dd = (struct driver_data *) dev->bd_disk->private_data; + + if (dd) { + if (test_bit(MTIP_DDF_REMOVAL_BIT, + &dd->dd_flag)) { + return -ENODEV; + } + return 0; + } + } + return -ENODEV; +} + +void mtip_block_release(struct gendisk *disk, fmode_t mode) +{ +} + /* * Block device operation function. * @@ -3603,6 +3697,8 @@ static int mtip_block_getgeo(struct block_device *dev, * layer. */ static const struct block_device_operations mtip_block_ops = { + .open = mtip_block_open, + .release = mtip_block_release, .ioctl = mtip_block_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = mtip_block_compat_ioctl, @@ -3664,10 +3760,9 @@ static int mtip_submit_request(struct blk_mq_hw_ctx *hctx, struct request *rq) rq_data_dir(rq))) { return -ENODATA; } - if (unlikely(test_bit(MTIP_DDF_SEC_LOCK_BIT, &dd->dd_flag))) + if (unlikely(test_bit(MTIP_DDF_SEC_LOCK_BIT, &dd->dd_flag) || + test_bit(MTIP_DDF_REBUILD_FAILED_BIT, &dd->dd_flag))) return -ENODATA; - if (test_bit(MTIP_DDF_REBUILD_FAILED_BIT, &dd->dd_flag)) - return -ENXIO; } if (rq->cmd_flags & REQ_DISCARD) { @@ -3779,11 +3874,32 @@ static int mtip_init_cmd(void *data, struct request *rq, unsigned int hctx_idx, return 0; } +static enum blk_eh_timer_return mtip_cmd_timeout(struct request *req, + bool reserved) +{ + struct driver_data *dd = req->q->queuedata; + + if (reserved) + goto exit_handler; + + if (test_bit(req->tag, dd->port->cmds_to_issue)) + goto exit_handler; + + if (test_and_set_bit(MTIP_PF_TO_ACTIVE_BIT, &dd->port->flags)) + goto exit_handler; + + wake_up_interruptible(&dd->port->svc_wait); +exit_handler: + return BLK_EH_RESET_TIMER; +} + static struct blk_mq_ops mtip_mq_ops = { .queue_rq = mtip_queue_rq, .map_queue = blk_mq_map_queue, .init_request = mtip_init_cmd, .exit_request = mtip_free_cmd, + .complete = mtip_softirq_done_fn, + .timeout = mtip_cmd_timeout, }; /* @@ -3850,7 +3966,6 @@ static int mtip_block_initialize(struct driver_data *dd) mtip_hw_debugfs_init(dd); -skip_create_disk: memset(&dd->tags, 0, sizeof(dd->tags)); dd->tags.ops = &mtip_mq_ops; dd->tags.nr_hw_queues = 1; @@ -3860,12 +3975,13 @@ static int mtip_block_initialize(struct driver_data *dd) dd->tags.numa_node = dd->numa_node; dd->tags.flags = BLK_MQ_F_SHOULD_MERGE; dd->tags.driver_data = dd; + dd->tags.timeout = MTIP_NCQ_CMD_TIMEOUT_MS; rv = blk_mq_alloc_tag_set(&dd->tags); if (rv) { dev_err(&dd->pdev->dev, "Unable to allocate request queue\n"); - goto block_queue_alloc_init_error; + goto block_queue_alloc_tag_error; } /* Allocate the request queue. */ @@ -3880,6 +3996,7 @@ static int mtip_block_initialize(struct driver_data *dd) dd->disk->queue = dd->queue; dd->queue->queuedata = dd; +skip_create_disk: /* Initialize the protocol layer. */ wait_for_rebuild = mtip_hw_get_identify(dd); if (wait_for_rebuild < 0) { @@ -3976,8 +4093,9 @@ static int mtip_block_initialize(struct driver_data *dd) read_capacity_error: init_hw_cmds_error: blk_cleanup_queue(dd->queue); - blk_mq_free_tag_set(&dd->tags); block_queue_alloc_init_error: + blk_mq_free_tag_set(&dd->tags); +block_queue_alloc_tag_error: mtip_hw_debugfs_exit(dd); disk_index_error: spin_lock(&rssd_index_lock); @@ -3994,6 +4112,22 @@ static int mtip_block_initialize(struct driver_data *dd) return rv; } +static void mtip_no_dev_cleanup(struct request *rq, void *data, bool reserv) +{ + struct driver_data *dd = (struct driver_data *)data; + struct mtip_cmd *cmd; + + if (likely(!reserv)) + blk_mq_complete_request(rq, -ENODEV); + else if (test_bit(MTIP_PF_IC_ACTIVE_BIT, &dd->port->flags)) { + + cmd = mtip_cmd_from_tag(dd, MTIP_TAG_INTERNAL); + if (cmd->comp_func) + cmd->comp_func(dd->port, MTIP_TAG_INTERNAL, + cmd, -ENODEV); + } +} + /* * Block layer deinitialization function. * @@ -4025,12 +4159,23 @@ static int mtip_block_remove(struct driver_data *dd) } } - if (!dd->sr) - mtip_standby_drive(dd); + if (!dd->sr) { + /* + * Explicitly wait here for IOs to quiesce, + * as mtip_standby_drive usually won't wait for IOs. + */ + if (!mtip_quiesce_io(dd->port, MTIP_QUIESCE_IO_TIMEOUT_MS, + GFP_KERNEL)) + mtip_standby_drive(dd); + } else dev_info(&dd->pdev->dev, "device %s surprise removal\n", dd->disk->disk_name); + blk_mq_freeze_queue_start(dd->queue); + blk_mq_stop_hw_queues(dd->queue); + blk_mq_all_tag_busy_iter(dd->tags.tags[0], mtip_no_dev_cleanup, dd); + /* * Delete our gendisk structure. This also removes the device * from /dev @@ -4040,7 +4185,8 @@ static int mtip_block_remove(struct driver_data *dd) dd->bdev = NULL; } if (dd->disk) { - del_gendisk(dd->disk); + if (test_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag)) + del_gendisk(dd->disk); if (dd->disk->queue) { blk_cleanup_queue(dd->queue); blk_mq_free_tag_set(&dd->tags); @@ -4081,7 +4227,8 @@ static int mtip_block_shutdown(struct driver_data *dd) dev_info(&dd->pdev->dev, "Shutting down %s ...\n", dd->disk->disk_name); - del_gendisk(dd->disk); + if (test_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag)) + del_gendisk(dd->disk); if (dd->disk->queue) { blk_cleanup_queue(dd->queue); blk_mq_free_tag_set(&dd->tags); @@ -4426,7 +4573,7 @@ static void mtip_pci_remove(struct pci_dev *pdev) struct driver_data *dd = pci_get_drvdata(pdev); unsigned long flags, to; - set_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag); + set_bit(MTIP_DDF_REMOVAL_BIT, &dd->dd_flag); spin_lock_irqsave(&dev_lock, flags); list_del_init(&dd->online_list); @@ -4443,12 +4590,17 @@ static void mtip_pci_remove(struct pci_dev *pdev) } while (atomic_read(&dd->irq_workers_active) != 0 && time_before(jiffies, to)); + if (!dd->sr) + fsync_bdev(dd->bdev); + if (atomic_read(&dd->irq_workers_active) != 0) { dev_warn(&dd->pdev->dev, "Completion workers still active!\n"); } - blk_mq_stop_hw_queues(dd->queue); + blk_set_queue_dying(dd->queue); + set_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag); + /* Clean up the block layer. */ mtip_block_remove(dd); diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h index 3274784008ebc9ef4fcfe65b47ee1bc0306223f9..7617888f79449d55ac9402bfef7f01788ef138cf 100644 --- a/drivers/block/mtip32xx/mtip32xx.h +++ b/drivers/block/mtip32xx/mtip32xx.h @@ -134,16 +134,24 @@ enum { MTIP_PF_EH_ACTIVE_BIT = 1, /* error handling */ MTIP_PF_SE_ACTIVE_BIT = 2, /* secure erase */ MTIP_PF_DM_ACTIVE_BIT = 3, /* download microcde */ + MTIP_PF_TO_ACTIVE_BIT = 9, /* timeout handling */ MTIP_PF_PAUSE_IO = ((1 << MTIP_PF_IC_ACTIVE_BIT) | (1 << MTIP_PF_EH_ACTIVE_BIT) | (1 << MTIP_PF_SE_ACTIVE_BIT) | - (1 << MTIP_PF_DM_ACTIVE_BIT)), + (1 << MTIP_PF_DM_ACTIVE_BIT) | + (1 << MTIP_PF_TO_ACTIVE_BIT)), MTIP_PF_SVC_THD_ACTIVE_BIT = 4, MTIP_PF_ISSUE_CMDS_BIT = 5, MTIP_PF_REBUILD_BIT = 6, MTIP_PF_SVC_THD_STOP_BIT = 8, + MTIP_PF_SVC_THD_WORK = ((1 << MTIP_PF_EH_ACTIVE_BIT) | + (1 << MTIP_PF_ISSUE_CMDS_BIT) | + (1 << MTIP_PF_REBUILD_BIT) | + (1 << MTIP_PF_SVC_THD_STOP_BIT) | + (1 << MTIP_PF_TO_ACTIVE_BIT)), + /* below are bit numbers in 'dd_flag' defined in driver_data */ MTIP_DDF_SEC_LOCK_BIT = 0, MTIP_DDF_REMOVE_PENDING_BIT = 1, @@ -153,6 +161,7 @@ enum { MTIP_DDF_RESUME_BIT = 6, MTIP_DDF_INIT_DONE_BIT = 7, MTIP_DDF_REBUILD_FAILED_BIT = 8, + MTIP_DDF_REMOVAL_BIT = 9, MTIP_DDF_STOP_IO = ((1 << MTIP_DDF_REMOVE_PENDING_BIT) | (1 << MTIP_DDF_SEC_LOCK_BIT) | diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index e4c5cc1079344110298f0becd938d91b27685924..08afbc7a2bb87171a2c4255c74705d39dd7a2b94 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -57,10 +57,12 @@ struct nbd_device { int blksize; loff_t bytesize; int xmit_timeout; + bool timedout; bool disconnect; /* a disconnect has been requested by user */ struct timer_list timeout_timer; - spinlock_t tasks_lock; + /* protects initialization and shutdown of the socket */ + spinlock_t sock_lock; struct task_struct *task_recv; struct task_struct *task_send; @@ -98,6 +100,11 @@ static inline struct device *nbd_to_dev(struct nbd_device *nbd) return disk_to_dev(nbd->disk); } +static bool nbd_is_connected(struct nbd_device *nbd) +{ + return !!nbd->task_recv; +} + static const char *nbdcmd_to_ascii(int cmd) { switch (cmd) { @@ -110,6 +117,42 @@ static const char *nbdcmd_to_ascii(int cmd) return "invalid"; } +static int nbd_size_clear(struct nbd_device *nbd, struct block_device *bdev) +{ + bdev->bd_inode->i_size = 0; + set_capacity(nbd->disk, 0); + kobject_uevent(&nbd_to_dev(nbd)->kobj, KOBJ_CHANGE); + + return 0; +} + +static void nbd_size_update(struct nbd_device *nbd, struct block_device *bdev) +{ + if (!nbd_is_connected(nbd)) + return; + + bdev->bd_inode->i_size = nbd->bytesize; + set_capacity(nbd->disk, nbd->bytesize >> 9); + kobject_uevent(&nbd_to_dev(nbd)->kobj, KOBJ_CHANGE); +} + +static int nbd_size_set(struct nbd_device *nbd, struct block_device *bdev, + int blocksize, int nr_blocks) +{ + int ret; + + ret = set_blocksize(bdev, blocksize); + if (ret) + return ret; + + nbd->blksize = blocksize; + nbd->bytesize = (loff_t)blocksize * (loff_t)nr_blocks; + + nbd_size_update(nbd, bdev); + + return 0; +} + static void nbd_end_request(struct nbd_device *nbd, struct request *req) { int error = req->errors ? -EIO : 0; @@ -129,13 +172,20 @@ static void nbd_end_request(struct nbd_device *nbd, struct request *req) */ static void sock_shutdown(struct nbd_device *nbd) { - if (!nbd->sock) + spin_lock_irq(&nbd->sock_lock); + + if (!nbd->sock) { + spin_unlock_irq(&nbd->sock_lock); return; + } dev_warn(disk_to_dev(nbd->disk), "shutting down socket\n"); kernel_sock_shutdown(nbd->sock, SHUT_RDWR); + sockfd_put(nbd->sock); nbd->sock = NULL; - del_timer_sync(&nbd->timeout_timer); + spin_unlock_irq(&nbd->sock_lock); + + del_timer(&nbd->timeout_timer); } static void nbd_xmit_timeout(unsigned long arg) @@ -146,19 +196,16 @@ static void nbd_xmit_timeout(unsigned long arg) if (list_empty(&nbd->queue_head)) return; - nbd->disconnect = true; + spin_lock_irqsave(&nbd->sock_lock, flags); - spin_lock_irqsave(&nbd->tasks_lock, flags); + nbd->timedout = true; - if (nbd->task_recv) - force_sig(SIGKILL, nbd->task_recv); - - if (nbd->task_send) - force_sig(SIGKILL, nbd->task_send); + if (nbd->sock) + kernel_sock_shutdown(nbd->sock, SHUT_RDWR); - spin_unlock_irqrestore(&nbd->tasks_lock, flags); + spin_unlock_irqrestore(&nbd->sock_lock, flags); - dev_err(nbd_to_dev(nbd), "Connection timed out, killed receiver and sender, shutting down connection\n"); + dev_err(nbd_to_dev(nbd), "Connection timed out, shutting down connection\n"); } /* @@ -171,7 +218,6 @@ static int sock_xmit(struct nbd_device *nbd, int send, void *buf, int size, int result; struct msghdr msg; struct kvec iov; - sigset_t blocked, oldset; unsigned long pflags = current->flags; if (unlikely(!sock)) { @@ -181,11 +227,6 @@ static int sock_xmit(struct nbd_device *nbd, int send, void *buf, int size, return -EINVAL; } - /* Allow interception of SIGKILL only - * Don't allow other signals to interrupt the transmission */ - siginitsetinv(&blocked, sigmask(SIGKILL)); - sigprocmask(SIG_SETMASK, &blocked, &oldset); - current->flags |= PF_MEMALLOC; do { sock->sk->sk_allocation = GFP_NOIO | __GFP_MEMALLOC; @@ -212,7 +253,6 @@ static int sock_xmit(struct nbd_device *nbd, int send, void *buf, int size, buf += result; } while (size > 0); - sigprocmask(SIG_SETMASK, &oldset, NULL); tsk_restore_flags(current, pflags, PF_MEMALLOC); if (!send && nbd->xmit_timeout) @@ -402,31 +442,28 @@ static struct device_attribute pid_attr = { .show = pid_show, }; -static int nbd_thread_recv(struct nbd_device *nbd) +static int nbd_thread_recv(struct nbd_device *nbd, struct block_device *bdev) { struct request *req; int ret; - unsigned long flags; BUG_ON(nbd->magic != NBD_MAGIC); sk_set_memalloc(nbd->sock->sk); - spin_lock_irqsave(&nbd->tasks_lock, flags); nbd->task_recv = current; - spin_unlock_irqrestore(&nbd->tasks_lock, flags); ret = device_create_file(disk_to_dev(nbd->disk), &pid_attr); if (ret) { dev_err(disk_to_dev(nbd->disk), "device_create_file failed!\n"); - spin_lock_irqsave(&nbd->tasks_lock, flags); nbd->task_recv = NULL; - spin_unlock_irqrestore(&nbd->tasks_lock, flags); return ret; } + nbd_size_update(nbd, bdev); + while (1) { req = nbd_read_stat(nbd); if (IS_ERR(req)) { @@ -437,21 +474,11 @@ static int nbd_thread_recv(struct nbd_device *nbd) nbd_end_request(nbd, req); } + nbd_size_clear(nbd, bdev); + device_remove_file(disk_to_dev(nbd->disk), &pid_attr); - spin_lock_irqsave(&nbd->tasks_lock, flags); nbd->task_recv = NULL; - spin_unlock_irqrestore(&nbd->tasks_lock, flags); - - if (signal_pending(current)) { - ret = kernel_dequeue_signal(NULL); - dev_warn(nbd_to_dev(nbd), "pid %d, %s, got signal %d\n", - task_pid_nr(current), current->comm, ret); - mutex_lock(&nbd->tx_lock); - sock_shutdown(nbd); - mutex_unlock(&nbd->tx_lock); - ret = -ETIMEDOUT; - } return ret; } @@ -544,11 +571,8 @@ static int nbd_thread_send(void *data) { struct nbd_device *nbd = data; struct request *req; - unsigned long flags; - spin_lock_irqsave(&nbd->tasks_lock, flags); nbd->task_send = current; - spin_unlock_irqrestore(&nbd->tasks_lock, flags); set_user_nice(current, MIN_NICE); while (!kthread_should_stop() || !list_empty(&nbd->waiting_queue)) { @@ -557,17 +581,6 @@ static int nbd_thread_send(void *data) kthread_should_stop() || !list_empty(&nbd->waiting_queue)); - if (signal_pending(current)) { - int ret = kernel_dequeue_signal(NULL); - - dev_warn(nbd_to_dev(nbd), "pid %d, %s, got signal %d\n", - task_pid_nr(current), current->comm, ret); - mutex_lock(&nbd->tx_lock); - sock_shutdown(nbd); - mutex_unlock(&nbd->tx_lock); - break; - } - /* extract request */ if (list_empty(&nbd->waiting_queue)) continue; @@ -582,13 +595,7 @@ static int nbd_thread_send(void *data) nbd_handle_req(nbd, req); } - spin_lock_irqsave(&nbd->tasks_lock, flags); nbd->task_send = NULL; - spin_unlock_irqrestore(&nbd->tasks_lock, flags); - - /* Clear maybe pending signals */ - if (signal_pending(current)) - kernel_dequeue_signal(NULL); return 0; } @@ -618,8 +625,8 @@ static void nbd_request_handler(struct request_queue *q) req, req->cmd_type); if (unlikely(!nbd->sock)) { - dev_err(disk_to_dev(nbd->disk), - "Attempted send on closed socket\n"); + dev_err_ratelimited(disk_to_dev(nbd->disk), + "Attempted send on closed socket\n"); req->errors++; nbd_end_request(nbd, req); spin_lock_irq(q->queue_lock); @@ -636,6 +643,61 @@ static void nbd_request_handler(struct request_queue *q) } } +static int nbd_set_socket(struct nbd_device *nbd, struct socket *sock) +{ + int ret = 0; + + spin_lock_irq(&nbd->sock_lock); + + if (nbd->sock) { + ret = -EBUSY; + goto out; + } + + nbd->sock = sock; + +out: + spin_unlock_irq(&nbd->sock_lock); + + return ret; +} + +/* Reset all properties of an NBD device */ +static void nbd_reset(struct nbd_device *nbd) +{ + nbd->disconnect = false; + nbd->timedout = false; + nbd->blksize = 1024; + nbd->bytesize = 0; + set_capacity(nbd->disk, 0); + nbd->flags = 0; + nbd->xmit_timeout = 0; + queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, nbd->disk->queue); + del_timer_sync(&nbd->timeout_timer); +} + +static void nbd_bdev_reset(struct block_device *bdev) +{ + set_device_ro(bdev, false); + bdev->bd_inode->i_size = 0; + if (max_part > 0) { + blkdev_reread_part(bdev); + bdev->bd_invalidated = 1; + } +} + +static void nbd_parse_flags(struct nbd_device *nbd, struct block_device *bdev) +{ + if (nbd->flags & NBD_FLAG_READ_ONLY) + set_device_ro(bdev, true); + if (nbd->flags & NBD_FLAG_SEND_TRIM) + queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, nbd->disk->queue); + if (nbd->flags & NBD_FLAG_SEND_FLUSH) + blk_queue_flush(nbd->disk->queue, REQ_FLUSH); + else + blk_queue_flush(nbd->disk->queue, 0); +} + static int nbd_dev_dbg_init(struct nbd_device *nbd); static void nbd_dev_dbg_close(struct nbd_device *nbd); @@ -668,48 +730,40 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd, return 0; } - case NBD_CLEAR_SOCK: { - struct socket *sock = nbd->sock; - nbd->sock = NULL; + case NBD_CLEAR_SOCK: + sock_shutdown(nbd); nbd_clear_que(nbd); BUG_ON(!list_empty(&nbd->queue_head)); BUG_ON(!list_empty(&nbd->waiting_queue)); kill_bdev(bdev); - if (sock) - sockfd_put(sock); return 0; - } case NBD_SET_SOCK: { - struct socket *sock; int err; - if (nbd->sock) - return -EBUSY; - sock = sockfd_lookup(arg, &err); - if (sock) { - nbd->sock = sock; - if (max_part > 0) - bdev->bd_invalidated = 1; - nbd->disconnect = false; /* we're connected now */ - return 0; - } - return -EINVAL; + struct socket *sock = sockfd_lookup(arg, &err); + + if (!sock) + return err; + + err = nbd_set_socket(nbd, sock); + if (!err && max_part) + bdev->bd_invalidated = 1; + + return err; } - case NBD_SET_BLKSIZE: - nbd->blksize = arg; - nbd->bytesize &= ~(nbd->blksize-1); - bdev->bd_inode->i_size = nbd->bytesize; - set_blocksize(bdev, nbd->blksize); - set_capacity(nbd->disk, nbd->bytesize >> 9); - return 0; + case NBD_SET_BLKSIZE: { + loff_t bsize = div_s64(nbd->bytesize, arg); + + return nbd_size_set(nbd, bdev, arg, bsize); + } case NBD_SET_SIZE: - nbd->bytesize = arg & ~(nbd->blksize-1); - bdev->bd_inode->i_size = nbd->bytesize; - set_blocksize(bdev, nbd->blksize); - set_capacity(nbd->disk, nbd->bytesize >> 9); - return 0; + return nbd_size_set(nbd, bdev, nbd->blksize, + arg / nbd->blksize); + + case NBD_SET_SIZE_BLOCKS: + return nbd_size_set(nbd, bdev, nbd->blksize, arg); case NBD_SET_TIMEOUT: nbd->xmit_timeout = arg * HZ; @@ -725,16 +779,8 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd, nbd->flags = arg; return 0; - case NBD_SET_SIZE_BLOCKS: - nbd->bytesize = ((u64) arg) * nbd->blksize; - bdev->bd_inode->i_size = nbd->bytesize; - set_blocksize(bdev, nbd->blksize); - set_capacity(nbd->disk, nbd->bytesize >> 9); - return 0; - case NBD_DO_IT: { struct task_struct *thread; - struct socket *sock; int error; if (nbd->task_recv) @@ -744,15 +790,7 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd, mutex_unlock(&nbd->tx_lock); - if (nbd->flags & NBD_FLAG_READ_ONLY) - set_device_ro(bdev, true); - if (nbd->flags & NBD_FLAG_SEND_TRIM) - queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, - nbd->disk->queue); - if (nbd->flags & NBD_FLAG_SEND_FLUSH) - blk_queue_flush(nbd->disk->queue, REQ_FLUSH); - else - blk_queue_flush(nbd->disk->queue, 0); + nbd_parse_flags(nbd, bdev); thread = kthread_run(nbd_thread_send, nbd, "%s", nbd_name(nbd)); @@ -762,29 +800,24 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd, } nbd_dev_dbg_init(nbd); - error = nbd_thread_recv(nbd); + error = nbd_thread_recv(nbd, bdev); nbd_dev_dbg_close(nbd); kthread_stop(thread); mutex_lock(&nbd->tx_lock); sock_shutdown(nbd); - sock = nbd->sock; - nbd->sock = NULL; nbd_clear_que(nbd); kill_bdev(bdev); - queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, nbd->disk->queue); - set_device_ro(bdev, false); - if (sock) - sockfd_put(sock); - nbd->flags = 0; - nbd->bytesize = 0; - bdev->bd_inode->i_size = 0; - set_capacity(nbd->disk, 0); - if (max_part > 0) - blkdev_reread_part(bdev); + nbd_bdev_reset(bdev); + if (nbd->disconnect) /* user requested, ignore socket errors */ - return 0; + error = 0; + if (nbd->timedout) + error = -ETIMEDOUT; + + nbd_reset(nbd); + return error; } @@ -892,50 +925,23 @@ static const struct file_operations nbd_dbg_flags_ops = { static int nbd_dev_dbg_init(struct nbd_device *nbd) { struct dentry *dir; - struct dentry *f; + + if (!nbd_dbg_dir) + return -EIO; dir = debugfs_create_dir(nbd_name(nbd), nbd_dbg_dir); - if (IS_ERR_OR_NULL(dir)) { - dev_err(nbd_to_dev(nbd), "Failed to create debugfs dir for '%s' (%ld)\n", - nbd_name(nbd), PTR_ERR(dir)); - return PTR_ERR(dir); + if (!dir) { + dev_err(nbd_to_dev(nbd), "Failed to create debugfs dir for '%s'\n", + nbd_name(nbd)); + return -EIO; } nbd->dbg_dir = dir; - f = debugfs_create_file("tasks", 0444, dir, nbd, &nbd_dbg_tasks_ops); - if (IS_ERR_OR_NULL(f)) { - dev_err(nbd_to_dev(nbd), "Failed to create debugfs file 'tasks', %ld\n", - PTR_ERR(f)); - return PTR_ERR(f); - } - - f = debugfs_create_u64("size_bytes", 0444, dir, &nbd->bytesize); - if (IS_ERR_OR_NULL(f)) { - dev_err(nbd_to_dev(nbd), "Failed to create debugfs file 'size_bytes', %ld\n", - PTR_ERR(f)); - return PTR_ERR(f); - } - - f = debugfs_create_u32("timeout", 0444, dir, &nbd->xmit_timeout); - if (IS_ERR_OR_NULL(f)) { - dev_err(nbd_to_dev(nbd), "Failed to create debugfs file 'timeout', %ld\n", - PTR_ERR(f)); - return PTR_ERR(f); - } - - f = debugfs_create_u32("blocksize", 0444, dir, &nbd->blksize); - if (IS_ERR_OR_NULL(f)) { - dev_err(nbd_to_dev(nbd), "Failed to create debugfs file 'blocksize', %ld\n", - PTR_ERR(f)); - return PTR_ERR(f); - } - - f = debugfs_create_file("flags", 0444, dir, &nbd, &nbd_dbg_flags_ops); - if (IS_ERR_OR_NULL(f)) { - dev_err(nbd_to_dev(nbd), "Failed to create debugfs file 'flags', %ld\n", - PTR_ERR(f)); - return PTR_ERR(f); - } + debugfs_create_file("tasks", 0444, dir, nbd, &nbd_dbg_tasks_ops); + debugfs_create_u64("size_bytes", 0444, dir, &nbd->bytesize); + debugfs_create_u32("timeout", 0444, dir, &nbd->xmit_timeout); + debugfs_create_u32("blocksize", 0444, dir, &nbd->blksize); + debugfs_create_file("flags", 0444, dir, &nbd, &nbd_dbg_flags_ops); return 0; } @@ -950,8 +956,8 @@ static int nbd_dbg_init(void) struct dentry *dbg_dir; dbg_dir = debugfs_create_dir("nbd", NULL); - if (IS_ERR(dbg_dir)) - return PTR_ERR(dbg_dir); + if (!dbg_dir) + return -EIO; nbd_dbg_dir = dbg_dir; @@ -1069,7 +1075,7 @@ static int __init nbd_init(void) nbd_dev[i].magic = NBD_MAGIC; INIT_LIST_HEAD(&nbd_dev[i].waiting_queue); spin_lock_init(&nbd_dev[i].queue_lock); - spin_lock_init(&nbd_dev[i].tasks_lock); + spin_lock_init(&nbd_dev[i].sock_lock); INIT_LIST_HEAD(&nbd_dev[i].queue_head); mutex_init(&nbd_dev[i].tx_lock); init_timer(&nbd_dev[i].timeout_timer); @@ -1077,14 +1083,12 @@ static int __init nbd_init(void) nbd_dev[i].timeout_timer.data = (unsigned long)&nbd_dev[i]; init_waitqueue_head(&nbd_dev[i].active_wq); init_waitqueue_head(&nbd_dev[i].waiting_wq); - nbd_dev[i].blksize = 1024; - nbd_dev[i].bytesize = 0; disk->major = NBD_MAJOR; disk->first_minor = i << part_shift; disk->fops = &nbd_fops; disk->private_data = &nbd_dev[i]; sprintf(disk->disk_name, "nbd%d", i); - set_capacity(disk, 0); + nbd_reset(&nbd_dev[i]); add_disk(disk); } diff --git a/drivers/block/null_blk.c b/drivers/block/null_blk.c index 64a7b5971b57046eafd210d726fa039b05bc705d..cab97593ba549e7eb73509f1807546244c057d8e 100644 --- a/drivers/block/null_blk.c +++ b/drivers/block/null_blk.c @@ -742,10 +742,11 @@ static int null_add_dev(void) add_disk(disk); +done: mutex_lock(&lock); list_add_tail(&nullb->list, &nullb_list); mutex_unlock(&lock); -done: + return 0; out_cleanup_lightnvm: diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 4a876785b68cd5c550dbbb1d2b63071446454081..94a1843b0426dec0f94919bb8f56e99ad4315e87 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -1847,14 +1847,12 @@ static void rbd_osd_req_callback(struct ceph_osd_request *osd_req, if (osd_req->r_result < 0) obj_request->result = osd_req->r_result; - rbd_assert(osd_req->r_num_ops <= CEPH_OSD_MAX_OP); - /* * We support a 64-bit length, but ultimately it has to be * passed to the block layer, which just supports a 32-bit * length field. */ - obj_request->xferred = osd_req->r_reply_op_len[0]; + obj_request->xferred = osd_req->r_ops[0].outdata_len; rbd_assert(obj_request->xferred < (u64)UINT_MAX); opcode = osd_req->r_ops[0].op; @@ -1955,7 +1953,7 @@ static struct ceph_osd_request *rbd_osd_req_create( osdc = &rbd_dev->rbd_client->client->osdc; osd_req = ceph_osdc_alloc_request(osdc, snapc, num_ops, false, - GFP_ATOMIC); + GFP_NOIO); if (!osd_req) return NULL; /* ENOMEM */ @@ -2004,7 +2002,7 @@ rbd_osd_req_create_copyup(struct rbd_obj_request *obj_request) rbd_dev = img_request->rbd_dev; osdc = &rbd_dev->rbd_client->client->osdc; osd_req = ceph_osdc_alloc_request(osdc, snapc, num_osd_ops, - false, GFP_ATOMIC); + false, GFP_NOIO); if (!osd_req) return NULL; /* ENOMEM */ @@ -2506,7 +2504,7 @@ static int rbd_img_request_fill(struct rbd_img_request *img_request, bio_chain_clone_range(&bio_list, &bio_offset, clone_size, - GFP_ATOMIC); + GFP_NOIO); if (!obj_request->bio_list) goto out_unwind; } else if (type == OBJ_REQUEST_PAGES) { @@ -5643,18 +5641,12 @@ static void rbd_sysfs_cleanup(void) static int rbd_slab_init(void) { rbd_assert(!rbd_img_request_cache); - rbd_img_request_cache = kmem_cache_create("rbd_img_request", - sizeof (struct rbd_img_request), - __alignof__(struct rbd_img_request), - 0, NULL); + rbd_img_request_cache = KMEM_CACHE(rbd_img_request, 0); if (!rbd_img_request_cache) return -ENOMEM; rbd_assert(!rbd_obj_request_cache); - rbd_obj_request_cache = kmem_cache_create("rbd_obj_request", - sizeof (struct rbd_obj_request), - __alignof__(struct rbd_obj_request), - 0, NULL); + rbd_obj_request_cache = KMEM_CACHE(rbd_obj_request, 0); if (!rbd_obj_request_cache) goto out_err; diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 6ca35495a5becdbac067cb4338981191fd6bc56a..28cff0d23d829ece7f2b00685b3ab089c632c5f9 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -477,8 +477,13 @@ static int virtblk_get_cache_mode(struct virtio_device *vdev) err = virtio_cread_feature(vdev, VIRTIO_BLK_F_CONFIG_WCE, struct virtio_blk_config, wce, &writeback); + + /* + * If WCE is not configurable and flush is not available, + * assume no writeback cache is in use. + */ if (err) - writeback = virtio_has_feature(vdev, VIRTIO_BLK_F_WCE); + writeback = virtio_has_feature(vdev, VIRTIO_BLK_F_FLUSH); return writeback; } @@ -833,14 +838,14 @@ static const struct virtio_device_id id_table[] = { static unsigned int features_legacy[] = { VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX, VIRTIO_BLK_F_GEOMETRY, VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE, VIRTIO_BLK_F_SCSI, - VIRTIO_BLK_F_WCE, VIRTIO_BLK_F_TOPOLOGY, VIRTIO_BLK_F_CONFIG_WCE, + VIRTIO_BLK_F_FLUSH, VIRTIO_BLK_F_TOPOLOGY, VIRTIO_BLK_F_CONFIG_WCE, VIRTIO_BLK_F_MQ, } ; static unsigned int features[] = { VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX, VIRTIO_BLK_F_GEOMETRY, VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE, - VIRTIO_BLK_F_WCE, VIRTIO_BLK_F_TOPOLOGY, VIRTIO_BLK_F_CONFIG_WCE, + VIRTIO_BLK_F_FLUSH, VIRTIO_BLK_F_TOPOLOGY, VIRTIO_BLK_F_CONFIG_WCE, VIRTIO_BLK_F_MQ, }; diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c index 876763f7f13e1a77f8f64738de967c1f21815440..26aa080e243cb59fa2ba4f2ba39d41f644c46265 100644 --- a/drivers/block/xen-blkback/xenbus.c +++ b/drivers/block/xen-blkback/xenbus.c @@ -23,8 +23,7 @@ #include #include "common.h" -/* Enlarge the array size in order to fully show blkback name. */ -#define BLKBACK_NAME_LEN (20) +/* On the XenBus the max length of 'ring-ref%u'. */ #define RINGREF_NAME_LEN (20) struct backend_info { @@ -76,7 +75,7 @@ static int blkback_name(struct xen_blkif *blkif, char *buf) else devname = devpath; - snprintf(buf, BLKBACK_NAME_LEN, "blkback.%d.%s", blkif->domid, devname); + snprintf(buf, TASK_COMM_LEN, "%d.%s", blkif->domid, devname); kfree(devpath); return 0; @@ -85,7 +84,7 @@ static int blkback_name(struct xen_blkif *blkif, char *buf) static void xen_update_blkif_status(struct xen_blkif *blkif) { int err; - char name[BLKBACK_NAME_LEN]; + char name[TASK_COMM_LEN]; struct xen_blkif_ring *ring; int i; @@ -618,6 +617,14 @@ static int xen_blkbk_probe(struct xenbus_device *dev, goto fail; } + err = xenbus_printf(XBT_NIL, dev->nodename, + "feature-max-indirect-segments", "%u", + MAX_INDIRECT_SEGMENTS); + if (err) + dev_warn(&dev->dev, + "writing %s/feature-max-indirect-segments (%d)", + dev->nodename, err); + /* Multi-queue: advertise how many queues are supported by us.*/ err = xenbus_printf(XBT_NIL, dev->nodename, "multi-queue-max-queues", "%u", xenblk_max_queues); @@ -849,11 +856,6 @@ static void connect(struct backend_info *be) dev->nodename); goto abort; } - err = xenbus_printf(xbt, dev->nodename, "feature-max-indirect-segments", "%u", - MAX_INDIRECT_SEGMENTS); - if (err) - dev_warn(&dev->dev, "writing %s/feature-max-indirect-segments (%d)", - dev->nodename, err); err = xenbus_printf(xbt, dev->nodename, "sectors", "%llu", (unsigned long long)vbd_sz(&be->blkif->vbd)); diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 83eb9e6bf8b06673640ff5d5ef05db1555e4912f..6405b65577926876587300e535490badf71f3414 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -125,8 +125,10 @@ static const struct block_device_operations xlvbd_block_fops; */ static unsigned int xen_blkif_max_segments = 32; -module_param_named(max, xen_blkif_max_segments, int, S_IRUGO); -MODULE_PARM_DESC(max, "Maximum amount of segments in indirect requests (default is 32)"); +module_param_named(max_indirect_segments, xen_blkif_max_segments, uint, + S_IRUGO); +MODULE_PARM_DESC(max_indirect_segments, + "Maximum amount of segments in indirect requests (default is 32)"); static unsigned int xen_blkif_max_queues = 4; module_param_named(max_queues, xen_blkif_max_queues, uint, S_IRUGO); diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig index ec6af15950622ef2448cfda759fd73bb141286f0..cf50fd2e96df8d886580e9f26885b6f5b4b18c2c 100644 --- a/drivers/bluetooth/Kconfig +++ b/drivers/bluetooth/Kconfig @@ -169,6 +169,17 @@ config BT_HCIUART_QCA Say Y here to compile support for QCA protocol. +config BT_HCIUART_AG6XX + bool "Intel AG6XX protocol support" + depends on BT_HCIUART + select BT_HCIUART_H4 + select BT_INTEL + help + The Intel/AG6XX protocol support enables Bluetooth HCI over serial + port interface for Intel ibt 2.1 Bluetooth controllers. + + Say Y here to compile support for Intel AG6XX protocol. + config BT_HCIBCM203X tristate "HCI BCM203x USB driver" depends on USB diff --git a/drivers/bluetooth/Makefile b/drivers/bluetooth/Makefile index 07c9cf381e5aeb2585a18beb0f9aa98a75862e9e..9c18939fc5c98fe02d0bfa039331c62f30d2632b 100644 --- a/drivers/bluetooth/Makefile +++ b/drivers/bluetooth/Makefile @@ -36,6 +36,7 @@ hci_uart-$(CONFIG_BT_HCIUART_3WIRE) += hci_h5.o hci_uart-$(CONFIG_BT_HCIUART_INTEL) += hci_intel.o hci_uart-$(CONFIG_BT_HCIUART_BCM) += hci_bcm.o hci_uart-$(CONFIG_BT_HCIUART_QCA) += hci_qca.o +hci_uart-$(CONFIG_BT_HCIUART_AG6XX) += hci_ag6xx.o hci_uart-objs := $(hci_uart-y) ccflags-y += -D__CHECK_ENDIAN__ diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index fa893c3ec4087f39382f3dc83b968c9859f41cca..47ca4b39d3065658c04d6b95add0b648da617a07 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -82,6 +82,7 @@ static const struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x0489, 0xe05f) }, { USB_DEVICE(0x0489, 0xe076) }, { USB_DEVICE(0x0489, 0xe078) }, + { USB_DEVICE(0x0489, 0xe095) }, { USB_DEVICE(0x04c5, 0x1330) }, { USB_DEVICE(0x04CA, 0x3004) }, { USB_DEVICE(0x04CA, 0x3005) }, @@ -92,6 +93,7 @@ static const struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x04CA, 0x300d) }, { USB_DEVICE(0x04CA, 0x300f) }, { USB_DEVICE(0x04CA, 0x3010) }, + { USB_DEVICE(0x04CA, 0x3014) }, { USB_DEVICE(0x0930, 0x0219) }, { USB_DEVICE(0x0930, 0x021c) }, { USB_DEVICE(0x0930, 0x0220) }, @@ -113,10 +115,12 @@ static const struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x13d3, 0x3362) }, { USB_DEVICE(0x13d3, 0x3375) }, { USB_DEVICE(0x13d3, 0x3393) }, + { USB_DEVICE(0x13d3, 0x3395) }, { USB_DEVICE(0x13d3, 0x3402) }, { USB_DEVICE(0x13d3, 0x3408) }, { USB_DEVICE(0x13d3, 0x3423) }, { USB_DEVICE(0x13d3, 0x3432) }, + { USB_DEVICE(0x13d3, 0x3472) }, { USB_DEVICE(0x13d3, 0x3474) }, /* Atheros AR5BBU12 with sflash firmware */ @@ -144,6 +148,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = { { USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe076), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe078), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0489, 0xe095), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, @@ -154,6 +159,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = { { USB_DEVICE(0x04ca, 0x300d), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x300f), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3010), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x04ca, 0x3014), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x021c), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 }, @@ -175,10 +181,12 @@ static const struct usb_device_id ath3k_blist_tbl[] = { { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3395), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3408), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3423), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3472), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3474), .driver_info = BTUSB_ATH3012 }, /* Atheros AR5BBU22 with sflash firmware */ @@ -497,6 +505,7 @@ static int ath3k_probe(struct usb_interface *intf, /* match device ID in ath3k blacklist table */ if (!id->driver_info) { const struct usb_device_id *match; + match = usb_match_id(intf, ath3k_blist_tbl); if (match) id = match; diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c index 0b697946e9bc7d91abf76b0dbfa7384fec4ce9b8..fdb44829ab6ff7009597a1b0080b741bcd09b9b9 100644 --- a/drivers/bluetooth/btbcm.c +++ b/drivers/bluetooth/btbcm.c @@ -467,7 +467,7 @@ int btbcm_setup_patchram(struct hci_dev *hdev) err = request_firmware(&fw, fw_name, &hdev->dev); if (err < 0) { BT_INFO("%s: BCM: Patch %s not found", hdev->name, fw_name); - return 0; + goto done; } btbcm_patchram(hdev, fw); @@ -501,6 +501,7 @@ int btbcm_setup_patchram(struct hci_dev *hdev) BT_INFO("%s: %s", hdev->name, (char *)(skb->data + 1)); kfree_skb(skb); +done: btbcm_check_bdaddr(hdev); set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks); diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index 6ed8acfcfa9cbfa6474e1fc790d214a9aaf48a3f..c6ef248de5e44880e2c7c5269010f95eb22fbf23 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c @@ -371,7 +371,7 @@ static int btmrvl_sdio_verify_fw_download(struct btmrvl_sdio_card *card, if (firmwarestat == FIRMWARE_READY) return 0; - msleep(10); + msleep(100); } return -ETIMEDOUT; diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index a191e318fab88a92fa52641b3d27d1ea94ced0ce..0d4e372e426d8e15c846c3bcdca7e410aa7604e8 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -196,6 +196,7 @@ static const struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe076), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe078), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0489, 0xe095), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, @@ -206,6 +207,7 @@ static const struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x04ca, 0x300d), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x300f), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3010), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x04ca, 0x3014), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x021c), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 }, @@ -227,10 +229,12 @@ static const struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3395), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3408), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3423), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3472), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3474), .driver_info = BTUSB_ATH3012 }, /* Atheros AR5BBU12 with sflash firmware */ diff --git a/drivers/bluetooth/hci_ag6xx.c b/drivers/bluetooth/hci_ag6xx.c new file mode 100644 index 0000000000000000000000000000000000000000..6923d17a022f80df3dcb578560f6b913321f3dc2 --- /dev/null +++ b/drivers/bluetooth/hci_ag6xx.c @@ -0,0 +1,337 @@ +/* + * + * Bluetooth HCI UART driver for Intel/AG6xx devices + * + * Copyright (C) 2016 Intel Corporation + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "hci_uart.h" +#include "btintel.h" + +struct ag6xx_data { + struct sk_buff *rx_skb; + struct sk_buff_head txq; +}; + +struct pbn_entry { + __le32 addr; + __le32 plen; + __u8 data[0]; +} __packed; + +static int ag6xx_open(struct hci_uart *hu) +{ + struct ag6xx_data *ag6xx; + + BT_DBG("hu %p", hu); + + ag6xx = kzalloc(sizeof(*ag6xx), GFP_KERNEL); + if (!ag6xx) + return -ENOMEM; + + skb_queue_head_init(&ag6xx->txq); + + hu->priv = ag6xx; + return 0; +} + +static int ag6xx_close(struct hci_uart *hu) +{ + struct ag6xx_data *ag6xx = hu->priv; + + BT_DBG("hu %p", hu); + + skb_queue_purge(&ag6xx->txq); + kfree_skb(ag6xx->rx_skb); + kfree(ag6xx); + + hu->priv = NULL; + return 0; +} + +static int ag6xx_flush(struct hci_uart *hu) +{ + struct ag6xx_data *ag6xx = hu->priv; + + BT_DBG("hu %p", hu); + + skb_queue_purge(&ag6xx->txq); + return 0; +} + +static struct sk_buff *ag6xx_dequeue(struct hci_uart *hu) +{ + struct ag6xx_data *ag6xx = hu->priv; + struct sk_buff *skb; + + skb = skb_dequeue(&ag6xx->txq); + if (!skb) + return skb; + + /* Prepend skb with frame type */ + memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); + return skb; +} + +static int ag6xx_enqueue(struct hci_uart *hu, struct sk_buff *skb) +{ + struct ag6xx_data *ag6xx = hu->priv; + + skb_queue_tail(&ag6xx->txq, skb); + return 0; +} + +static const struct h4_recv_pkt ag6xx_recv_pkts[] = { + { H4_RECV_ACL, .recv = hci_recv_frame }, + { H4_RECV_SCO, .recv = hci_recv_frame }, + { H4_RECV_EVENT, .recv = hci_recv_frame }, +}; + +static int ag6xx_recv(struct hci_uart *hu, const void *data, int count) +{ + struct ag6xx_data *ag6xx = hu->priv; + + if (!test_bit(HCI_UART_REGISTERED, &hu->flags)) + return -EUNATCH; + + ag6xx->rx_skb = h4_recv_buf(hu->hdev, ag6xx->rx_skb, data, count, + ag6xx_recv_pkts, + ARRAY_SIZE(ag6xx_recv_pkts)); + if (IS_ERR(ag6xx->rx_skb)) { + int err = PTR_ERR(ag6xx->rx_skb); + bt_dev_err(hu->hdev, "Frame reassembly failed (%d)", err); + ag6xx->rx_skb = NULL; + return err; + } + + return count; +} + +static int intel_mem_write(struct hci_dev *hdev, u32 addr, u32 plen, + const void *data) +{ + /* Can write a maximum of 247 bytes per HCI command. + * HCI cmd Header (3), Intel mem write header (6), data (247). + */ + while (plen > 0) { + struct sk_buff *skb; + u8 cmd_param[253], fragment_len = (plen > 247) ? 247 : plen; + __le32 leaddr = cpu_to_le32(addr); + + memcpy(cmd_param, &leaddr, 4); + cmd_param[4] = 0; + cmd_param[5] = fragment_len; + memcpy(cmd_param + 6, data, fragment_len); + + skb = __hci_cmd_sync(hdev, 0xfc8e, fragment_len + 6, cmd_param, + HCI_INIT_TIMEOUT); + if (IS_ERR(skb)) + return PTR_ERR(skb); + kfree_skb(skb); + + plen -= fragment_len; + data += fragment_len; + addr += fragment_len; + } + + return 0; +} + +static int ag6xx_setup(struct hci_uart *hu) +{ + struct hci_dev *hdev = hu->hdev; + struct sk_buff *skb; + struct intel_version ver; + const struct firmware *fw; + const u8 *fw_ptr; + char fwname[64]; + bool patched = false; + int err; + + hu->hdev->set_diag = btintel_set_diag; + hu->hdev->set_bdaddr = btintel_set_bdaddr; + + err = btintel_enter_mfg(hdev); + if (err) + return err; + + err = btintel_read_version(hdev, &ver); + if (err) + return err; + + btintel_version_info(hdev, &ver); + + /* The hardware platform number has a fixed value of 0x37 and + * for now only accept this single value. + */ + if (ver.hw_platform != 0x37) { + bt_dev_err(hdev, "Unsupported Intel hardware platform: 0x%X", + ver.hw_platform); + return -EINVAL; + } + + /* Only the hardware variant iBT 2.1 (AG6XX) is supported by this + * firmware setup method. + */ + if (ver.hw_variant != 0x0a) { + bt_dev_err(hdev, "Unsupported Intel hardware variant: 0x%x", + ver.hw_variant); + return -EINVAL; + } + + snprintf(fwname, sizeof(fwname), "intel/ibt-hw-%x.%x.bddata", + ver.hw_platform, ver.hw_variant); + + err = request_firmware(&fw, fwname, &hdev->dev); + if (err < 0) { + bt_dev_err(hdev, "Failed to open Intel bddata file: %s (%d)", + fwname, err); + goto patch; + } + fw_ptr = fw->data; + + bt_dev_info(hdev, "Applying bddata (%s)", fwname); + + skb = __hci_cmd_sync_ev(hdev, 0xfc2f, fw->size, fw->data, + HCI_EV_CMD_STATUS, HCI_CMD_TIMEOUT); + if (IS_ERR(skb)) { + bt_dev_err(hdev, "Applying bddata failed (%ld)", PTR_ERR(skb)); + release_firmware(fw); + return PTR_ERR(skb); + } + kfree_skb(skb); + + release_firmware(fw); + +patch: + /* If there is no applied patch, fw_patch_num is always 0x00. In other + * cases, current firmware is already patched. No need to patch it. + */ + if (ver.fw_patch_num) { + bt_dev_info(hdev, "Device is already patched. patch num: %02x", + ver.fw_patch_num); + patched = true; + goto complete; + } + + snprintf(fwname, sizeof(fwname), + "intel/ibt-hw-%x.%x.%x-fw-%x.%x.%x.%x.%x.pbn", + ver.hw_platform, ver.hw_variant, ver.hw_revision, + ver.fw_variant, ver.fw_revision, ver.fw_build_num, + ver.fw_build_ww, ver.fw_build_yy); + + err = request_firmware(&fw, fwname, &hdev->dev); + if (err < 0) { + bt_dev_err(hdev, "Failed to open Intel patch file: %s(%d)", + fwname, err); + goto complete; + } + fw_ptr = fw->data; + + bt_dev_info(hdev, "Patching firmware file (%s)", fwname); + + /* PBN patch file contains a list of binary patches to be applied on top + * of the embedded firmware. Each patch entry header contains the target + * address and patch size. + * + * Patch entry: + * | addr(le) | patch_len(le) | patch_data | + * | 4 Bytes | 4 Bytes | n Bytes | + * + * PBN file is terminated by a patch entry whose address is 0xffffffff. + */ + while (fw->size > fw_ptr - fw->data) { + struct pbn_entry *pbn = (void *)fw_ptr; + u32 addr, plen; + + if (pbn->addr == 0xffffffff) { + bt_dev_info(hdev, "Patching complete"); + patched = true; + break; + } + + addr = le32_to_cpu(pbn->addr); + plen = le32_to_cpu(pbn->plen); + + if (fw->data + fw->size <= pbn->data + plen) { + bt_dev_info(hdev, "Invalid patch len (%d)", plen); + break; + } + + bt_dev_info(hdev, "Patching %td/%zu", (fw_ptr - fw->data), + fw->size); + + err = intel_mem_write(hdev, addr, plen, pbn->data); + if (err) { + bt_dev_err(hdev, "Patching failed"); + break; + } + + fw_ptr = pbn->data + plen; + } + + release_firmware(fw); + +complete: + /* Exit manufacturing mode and reset */ + err = btintel_exit_mfg(hdev, true, patched); + if (err) + return err; + + /* Set the event mask for Intel specific vendor events. This enables + * a few extra events that are useful during general operation. + */ + btintel_set_event_mask_mfg(hdev, false); + + btintel_check_bdaddr(hdev); + return 0; +} + +static const struct hci_uart_proto ag6xx_proto = { + .id = HCI_UART_AG6XX, + .name = "AG6XX", + .manufacturer = 2, + .open = ag6xx_open, + .close = ag6xx_close, + .flush = ag6xx_flush, + .setup = ag6xx_setup, + .recv = ag6xx_recv, + .enqueue = ag6xx_enqueue, + .dequeue = ag6xx_dequeue, +}; + +int __init ag6xx_init(void) +{ + return hci_uart_register_proto(&ag6xx_proto); +} + +int __exit ag6xx_deinit(void) +{ + return hci_uart_unregister_proto(&ag6xx_proto); +} diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c index 5f3de181e7443632746ef77d6ee73ec9a26494fa..d8881dc0600cdad24c2e144cd692dd5b51680550 100644 --- a/drivers/bluetooth/hci_bcm.c +++ b/drivers/bluetooth/hci_bcm.c @@ -820,10 +820,13 @@ static const struct acpi_device_id bcm_acpi_match[] = { { "BCM2E3D", 0 }, { "BCM2E3F", 0 }, { "BCM2E40", 0 }, + { "BCM2E54", 0 }, + { "BCM2E55", 0 }, { "BCM2E64", 0 }, { "BCM2E65", 0 }, { "BCM2E67", 0 }, { "BCM2E7B", 0 }, + { "BCM2E7C", 0 }, { }, }; MODULE_DEVICE_TABLE(acpi, bcm_acpi_match); diff --git a/drivers/bluetooth/hci_intel.c b/drivers/bluetooth/hci_intel.c index 3d63ea37bd4ca683b37c7ea7661be70163b6590c..91d605147b10e45a721941582ac366185afb0da3 100644 --- a/drivers/bluetooth/hci_intel.c +++ b/drivers/bluetooth/hci_intel.c @@ -488,7 +488,7 @@ static int intel_set_baudrate(struct hci_uart *hu, unsigned int speed) clear_bit(STATE_BOOTING, &intel->flags); /* In case of timeout, try to continue anyway */ - if (err && err != ETIMEDOUT) + if (err && err != -ETIMEDOUT) return err; bt_dev_info(hdev, "Change controller speed to %d", speed); @@ -581,7 +581,7 @@ static int intel_setup(struct hci_uart *hu) clear_bit(STATE_BOOTING, &intel->flags); /* In case of timeout, try to continue anyway */ - if (err && err != ETIMEDOUT) + if (err && err != -ETIMEDOUT) return err; set_bit(STATE_BOOTLOADER, &intel->flags); diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 73202624133b4e180a45c75f12ae329cc934bac0..c00168a5bb800f3e74f6924f197e668020f02eb9 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -804,6 +804,9 @@ static int __init hci_uart_init(void) #ifdef CONFIG_BT_HCIUART_QCA qca_init(); #endif +#ifdef CONFIG_BT_HCIUART_AG6XX + ag6xx_init(); +#endif return 0; } @@ -836,6 +839,9 @@ static void __exit hci_uart_exit(void) #ifdef CONFIG_BT_HCIUART_QCA qca_deinit(); #endif +#ifdef CONFIG_BT_HCIUART_AG6XX + ag6xx_deinit(); +#endif /* Release tty registration of line discipline */ err = tty_unregister_ldisc(N_HCI); diff --git a/drivers/bluetooth/hci_uart.h b/drivers/bluetooth/hci_uart.h index 82c92f1b65b4af7c317c8a0af91723a481ac3874..4814ff08f4270156c70aaced894ec0cb2a5d5f63 100644 --- a/drivers/bluetooth/hci_uart.h +++ b/drivers/bluetooth/hci_uart.h @@ -35,7 +35,7 @@ #define HCIUARTGETFLAGS _IOR('U', 204, int) /* UART protocols */ -#define HCI_UART_MAX_PROTO 9 +#define HCI_UART_MAX_PROTO 10 #define HCI_UART_H4 0 #define HCI_UART_BCSP 1 @@ -46,6 +46,7 @@ #define HCI_UART_INTEL 6 #define HCI_UART_BCM 7 #define HCI_UART_QCA 8 +#define HCI_UART_AG6XX 9 #define HCI_UART_RAW_DEVICE 0 #define HCI_UART_RESET_ON_INIT 1 @@ -182,3 +183,8 @@ int bcm_deinit(void); int qca_init(void); int qca_deinit(void); #endif + +#ifdef CONFIG_BT_HCIUART_AG6XX +int ag6xx_init(void); +int ag6xx_deinit(void); +#endif diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig index 9a92c072a485def0b2730340503d1984d5a6dc1d..d4a3a3133da5410cd9c75aa263557b8b8b873321 100644 --- a/drivers/bus/Kconfig +++ b/drivers/bus/Kconfig @@ -34,15 +34,15 @@ config ARM_CCI400_PORT_CTRL Low level power management driver for CCI400 cache coherent interconnect for ARM platforms. -config ARM_CCI500_PMU - bool "ARM CCI500 PMU support" +config ARM_CCI5xx_PMU + bool "ARM CCI-500/CCI-550 PMU support" depends on (ARM && CPU_V7) || ARM64 depends on PERF_EVENTS select ARM_CCI_PMU help - Support for PMU events monitoring on the ARM CCI-500 cache coherent - interconnect. CCI-500 provides 8 independent event counters, which - can count events pertaining to the slave/master interfaces as well + Support for PMU events monitoring on the ARM CCI-500/CCI-550 cache + coherent interconnects. Both of them provide 8 independent event counters, + which can count events pertaining to the slave/master interfaces as well as the internal events to the CCI. If unsure, say Y diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c index 577cc4bf6a9d17987a2f6bf8e62935dc5aa71f01..a49b28378d5994851d7e217c42738a0a7584e50d 100644 --- a/drivers/bus/arm-cci.c +++ b/drivers/bus/arm-cci.c @@ -52,8 +52,9 @@ static const struct of_device_id arm_cci_matches[] = { #ifdef CONFIG_ARM_CCI400_COMMON {.compatible = "arm,cci-400", .data = CCI400_PORTS_DATA }, #endif -#ifdef CONFIG_ARM_CCI500_PMU +#ifdef CONFIG_ARM_CCI5xx_PMU { .compatible = "arm,cci-500", }, + { .compatible = "arm,cci-550", }, #endif {}, }; @@ -92,7 +93,7 @@ static const struct of_device_id arm_cci_matches[] = { enum { CCI_IF_SLAVE, CCI_IF_MASTER, -#ifdef CONFIG_ARM_CCI500_PMU +#ifdef CONFIG_ARM_CCI5xx_PMU CCI_IF_GLOBAL, #endif CCI_IF_MAX, @@ -121,13 +122,12 @@ struct cci_pmu_model { u32 fixed_hw_cntrs; u32 num_hw_cntrs; u32 cntr_size; - u64 nformat_attrs; - u64 nevent_attrs; - struct dev_ext_attribute *format_attrs; - struct dev_ext_attribute *event_attrs; + struct attribute **format_attrs; + struct attribute **event_attrs; struct event_range event_ranges[CCI_IF_MAX]; int (*validate_hw_event)(struct cci_pmu *, unsigned long); int (*get_event_idx)(struct cci_pmu *, struct cci_pmu_hw_events *, unsigned long); + void (*write_counters)(struct cci_pmu *, unsigned long *); }; static struct cci_pmu_model cci_pmu_models[]; @@ -155,19 +155,24 @@ enum cci_models { CCI400_R0, CCI400_R1, #endif -#ifdef CONFIG_ARM_CCI500_PMU +#ifdef CONFIG_ARM_CCI5xx_PMU CCI500_R0, + CCI550_R0, #endif CCI_MODEL_MAX }; +static void pmu_write_counters(struct cci_pmu *cci_pmu, + unsigned long *mask); static ssize_t cci_pmu_format_show(struct device *dev, struct device_attribute *attr, char *buf); static ssize_t cci_pmu_event_show(struct device *dev, struct device_attribute *attr, char *buf); -#define CCI_EXT_ATTR_ENTRY(_name, _func, _config) \ - { __ATTR(_name, S_IRUGO, _func, NULL), (void *)_config } +#define CCI_EXT_ATTR_ENTRY(_name, _func, _config) \ + &((struct dev_ext_attribute[]) { \ + { __ATTR(_name, S_IRUGO, _func, NULL), (void *)_config } \ + })[0].attr.attr #define CCI_FORMAT_EXT_ATTR_ENTRY(_name, _config) \ CCI_EXT_ATTR_ENTRY(_name, cci_pmu_format_show, (char *)_config) @@ -242,12 +247,13 @@ enum cci400_perf_events { static ssize_t cci400_pmu_cycle_event_show(struct device *dev, struct device_attribute *attr, char *buf); -static struct dev_ext_attribute cci400_pmu_format_attrs[] = { +static struct attribute *cci400_pmu_format_attrs[] = { CCI_FORMAT_EXT_ATTR_ENTRY(event, "config:0-4"), CCI_FORMAT_EXT_ATTR_ENTRY(source, "config:5-7"), + NULL }; -static struct dev_ext_attribute cci400_r0_pmu_event_attrs[] = { +static struct attribute *cci400_r0_pmu_event_attrs[] = { /* Slave events */ CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_any, 0x0), CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_device, 0x01), @@ -279,9 +285,10 @@ static struct dev_ext_attribute cci400_r0_pmu_event_attrs[] = { CCI_EVENT_EXT_ATTR_ENTRY(mi_wrq_stall_tt_full, 0x1A), /* Special event for cycles counter */ CCI400_CYCLE_EVENT_EXT_ATTR_ENTRY(cycles, 0xff), + NULL }; -static struct dev_ext_attribute cci400_r1_pmu_event_attrs[] = { +static struct attribute *cci400_r1_pmu_event_attrs[] = { /* Slave events */ CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_any, 0x0), CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_device, 0x01), @@ -325,6 +332,7 @@ static struct dev_ext_attribute cci400_r1_pmu_event_attrs[] = { CCI_EVENT_EXT_ATTR_ENTRY(mi_wrq_unique_or_line_unique_addr_hazard, 0x11), /* Special event for cycles counter */ CCI400_CYCLE_EVENT_EXT_ATTR_ENTRY(cycles, 0xff), + NULL }; static ssize_t cci400_pmu_cycle_event_show(struct device *dev, @@ -420,72 +428,68 @@ static inline struct cci_pmu_model *probe_cci_model(struct platform_device *pdev } #endif /* CONFIG_ARM_CCI400_PMU */ -#ifdef CONFIG_ARM_CCI500_PMU +#ifdef CONFIG_ARM_CCI5xx_PMU /* - * CCI500 provides 8 independent event counters that can count - * any of the events available. - * - * CCI500 PMU event id is an 9-bit value made of two parts. + * CCI5xx PMU event id is an 9-bit value made of two parts. * bits [8:5] - Source for the event - * 0x0-0x6 - Slave interfaces - * 0x8-0xD - Master interfaces - * 0xf - Global Events - * 0x7,0xe - Reserved - * * bits [4:0] - Event code (specific to type of interface) + * + * */ /* Port ids */ -#define CCI500_PORT_S0 0x0 -#define CCI500_PORT_S1 0x1 -#define CCI500_PORT_S2 0x2 -#define CCI500_PORT_S3 0x3 -#define CCI500_PORT_S4 0x4 -#define CCI500_PORT_S5 0x5 -#define CCI500_PORT_S6 0x6 - -#define CCI500_PORT_M0 0x8 -#define CCI500_PORT_M1 0x9 -#define CCI500_PORT_M2 0xa -#define CCI500_PORT_M3 0xb -#define CCI500_PORT_M4 0xc -#define CCI500_PORT_M5 0xd - -#define CCI500_PORT_GLOBAL 0xf - -#define CCI500_PMU_EVENT_MASK 0x1ffUL -#define CCI500_PMU_EVENT_SOURCE_SHIFT 0x5 -#define CCI500_PMU_EVENT_SOURCE_MASK 0xf -#define CCI500_PMU_EVENT_CODE_SHIFT 0x0 -#define CCI500_PMU_EVENT_CODE_MASK 0x1f - -#define CCI500_PMU_EVENT_SOURCE(event) \ - ((event >> CCI500_PMU_EVENT_SOURCE_SHIFT) & CCI500_PMU_EVENT_SOURCE_MASK) -#define CCI500_PMU_EVENT_CODE(event) \ - ((event >> CCI500_PMU_EVENT_CODE_SHIFT) & CCI500_PMU_EVENT_CODE_MASK) - -#define CCI500_SLAVE_PORT_MIN_EV 0x00 -#define CCI500_SLAVE_PORT_MAX_EV 0x1f -#define CCI500_MASTER_PORT_MIN_EV 0x00 -#define CCI500_MASTER_PORT_MAX_EV 0x06 -#define CCI500_GLOBAL_PORT_MIN_EV 0x00 -#define CCI500_GLOBAL_PORT_MAX_EV 0x0f - - -#define CCI500_GLOBAL_EVENT_EXT_ATTR_ENTRY(_name, _config) \ - CCI_EXT_ATTR_ENTRY(_name, cci500_pmu_global_event_show, \ +#define CCI5xx_PORT_S0 0x0 +#define CCI5xx_PORT_S1 0x1 +#define CCI5xx_PORT_S2 0x2 +#define CCI5xx_PORT_S3 0x3 +#define CCI5xx_PORT_S4 0x4 +#define CCI5xx_PORT_S5 0x5 +#define CCI5xx_PORT_S6 0x6 + +#define CCI5xx_PORT_M0 0x8 +#define CCI5xx_PORT_M1 0x9 +#define CCI5xx_PORT_M2 0xa +#define CCI5xx_PORT_M3 0xb +#define CCI5xx_PORT_M4 0xc +#define CCI5xx_PORT_M5 0xd +#define CCI5xx_PORT_M6 0xe + +#define CCI5xx_PORT_GLOBAL 0xf + +#define CCI5xx_PMU_EVENT_MASK 0x1ffUL +#define CCI5xx_PMU_EVENT_SOURCE_SHIFT 0x5 +#define CCI5xx_PMU_EVENT_SOURCE_MASK 0xf +#define CCI5xx_PMU_EVENT_CODE_SHIFT 0x0 +#define CCI5xx_PMU_EVENT_CODE_MASK 0x1f + +#define CCI5xx_PMU_EVENT_SOURCE(event) \ + ((event >> CCI5xx_PMU_EVENT_SOURCE_SHIFT) & CCI5xx_PMU_EVENT_SOURCE_MASK) +#define CCI5xx_PMU_EVENT_CODE(event) \ + ((event >> CCI5xx_PMU_EVENT_CODE_SHIFT) & CCI5xx_PMU_EVENT_CODE_MASK) + +#define CCI5xx_SLAVE_PORT_MIN_EV 0x00 +#define CCI5xx_SLAVE_PORT_MAX_EV 0x1f +#define CCI5xx_MASTER_PORT_MIN_EV 0x00 +#define CCI5xx_MASTER_PORT_MAX_EV 0x06 +#define CCI5xx_GLOBAL_PORT_MIN_EV 0x00 +#define CCI5xx_GLOBAL_PORT_MAX_EV 0x0f + + +#define CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(_name, _config) \ + CCI_EXT_ATTR_ENTRY(_name, cci5xx_pmu_global_event_show, \ (unsigned long) _config) -static ssize_t cci500_pmu_global_event_show(struct device *dev, +static ssize_t cci5xx_pmu_global_event_show(struct device *dev, struct device_attribute *attr, char *buf); -static struct dev_ext_attribute cci500_pmu_format_attrs[] = { +static struct attribute *cci5xx_pmu_format_attrs[] = { CCI_FORMAT_EXT_ATTR_ENTRY(event, "config:0-4"), CCI_FORMAT_EXT_ATTR_ENTRY(source, "config:5-8"), + NULL, }; -static struct dev_ext_attribute cci500_pmu_event_attrs[] = { +static struct attribute *cci5xx_pmu_event_attrs[] = { /* Slave events */ CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_hs_arvalid, 0x0), CCI_EVENT_EXT_ATTR_ENTRY(si_rrq_dev, 0x1), @@ -530,63 +534,73 @@ static struct dev_ext_attribute cci500_pmu_event_attrs[] = { CCI_EVENT_EXT_ATTR_ENTRY(mi_w_resp_stall, 0x6), /* Global events */ - CCI500_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_filter_bank_0_1, 0x0), - CCI500_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_filter_bank_2_3, 0x1), - CCI500_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_filter_bank_4_5, 0x2), - CCI500_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_filter_bank_6_7, 0x3), - CCI500_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_miss_filter_bank_0_1, 0x4), - CCI500_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_miss_filter_bank_2_3, 0x5), - CCI500_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_miss_filter_bank_4_5, 0x6), - CCI500_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_miss_filter_bank_6_7, 0x7), - CCI500_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_back_invalidation, 0x8), - CCI500_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_stall_alloc_busy, 0x9), - CCI500_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_stall_tt_full, 0xA), - CCI500_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_wrq, 0xB), - CCI500_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_cd_hs, 0xC), - CCI500_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_rq_stall_addr_hazard, 0xD), - CCI500_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snopp_rq_stall_tt_full, 0xE), - CCI500_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_rq_tzmp1_prot, 0xF), + CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_filter_bank_0_1, 0x0), + CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_filter_bank_2_3, 0x1), + CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_filter_bank_4_5, 0x2), + CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_filter_bank_6_7, 0x3), + CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_miss_filter_bank_0_1, 0x4), + CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_miss_filter_bank_2_3, 0x5), + CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_miss_filter_bank_4_5, 0x6), + CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_access_miss_filter_bank_6_7, 0x7), + CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_back_invalidation, 0x8), + CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_stall_alloc_busy, 0x9), + CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_stall_tt_full, 0xA), + CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_wrq, 0xB), + CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_cd_hs, 0xC), + CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_rq_stall_addr_hazard, 0xD), + CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snopp_rq_stall_tt_full, 0xE), + CCI5xx_GLOBAL_EVENT_EXT_ATTR_ENTRY(cci_snoop_rq_tzmp1_prot, 0xF), + NULL }; -static ssize_t cci500_pmu_global_event_show(struct device *dev, +static ssize_t cci5xx_pmu_global_event_show(struct device *dev, struct device_attribute *attr, char *buf) { struct dev_ext_attribute *eattr = container_of(attr, struct dev_ext_attribute, attr); /* Global events have single fixed source code */ return snprintf(buf, PAGE_SIZE, "event=0x%lx,source=0x%x\n", - (unsigned long)eattr->var, CCI500_PORT_GLOBAL); + (unsigned long)eattr->var, CCI5xx_PORT_GLOBAL); } +/* + * CCI500 provides 8 independent event counters that can count + * any of the events available. + * CCI500 PMU event source ids + * 0x0-0x6 - Slave interfaces + * 0x8-0xD - Master interfaces + * 0xf - Global Events + * 0x7,0xe - Reserved + */ static int cci500_validate_hw_event(struct cci_pmu *cci_pmu, unsigned long hw_event) { - u32 ev_source = CCI500_PMU_EVENT_SOURCE(hw_event); - u32 ev_code = CCI500_PMU_EVENT_CODE(hw_event); + u32 ev_source = CCI5xx_PMU_EVENT_SOURCE(hw_event); + u32 ev_code = CCI5xx_PMU_EVENT_CODE(hw_event); int if_type; - if (hw_event & ~CCI500_PMU_EVENT_MASK) + if (hw_event & ~CCI5xx_PMU_EVENT_MASK) return -ENOENT; switch (ev_source) { - case CCI500_PORT_S0: - case CCI500_PORT_S1: - case CCI500_PORT_S2: - case CCI500_PORT_S3: - case CCI500_PORT_S4: - case CCI500_PORT_S5: - case CCI500_PORT_S6: + case CCI5xx_PORT_S0: + case CCI5xx_PORT_S1: + case CCI5xx_PORT_S2: + case CCI5xx_PORT_S3: + case CCI5xx_PORT_S4: + case CCI5xx_PORT_S5: + case CCI5xx_PORT_S6: if_type = CCI_IF_SLAVE; break; - case CCI500_PORT_M0: - case CCI500_PORT_M1: - case CCI500_PORT_M2: - case CCI500_PORT_M3: - case CCI500_PORT_M4: - case CCI500_PORT_M5: + case CCI5xx_PORT_M0: + case CCI5xx_PORT_M1: + case CCI5xx_PORT_M2: + case CCI5xx_PORT_M3: + case CCI5xx_PORT_M4: + case CCI5xx_PORT_M5: if_type = CCI_IF_MASTER; break; - case CCI500_PORT_GLOBAL: + case CCI5xx_PORT_GLOBAL: if_type = CCI_IF_GLOBAL; break; default: @@ -599,7 +613,118 @@ static int cci500_validate_hw_event(struct cci_pmu *cci_pmu, return -ENOENT; } -#endif /* CONFIG_ARM_CCI500_PMU */ + +/* + * CCI550 provides 8 independent event counters that can count + * any of the events available. + * CCI550 PMU event source ids + * 0x0-0x6 - Slave interfaces + * 0x8-0xe - Master interfaces + * 0xf - Global Events + * 0x7 - Reserved + */ +static int cci550_validate_hw_event(struct cci_pmu *cci_pmu, + unsigned long hw_event) +{ + u32 ev_source = CCI5xx_PMU_EVENT_SOURCE(hw_event); + u32 ev_code = CCI5xx_PMU_EVENT_CODE(hw_event); + int if_type; + + if (hw_event & ~CCI5xx_PMU_EVENT_MASK) + return -ENOENT; + + switch (ev_source) { + case CCI5xx_PORT_S0: + case CCI5xx_PORT_S1: + case CCI5xx_PORT_S2: + case CCI5xx_PORT_S3: + case CCI5xx_PORT_S4: + case CCI5xx_PORT_S5: + case CCI5xx_PORT_S6: + if_type = CCI_IF_SLAVE; + break; + case CCI5xx_PORT_M0: + case CCI5xx_PORT_M1: + case CCI5xx_PORT_M2: + case CCI5xx_PORT_M3: + case CCI5xx_PORT_M4: + case CCI5xx_PORT_M5: + case CCI5xx_PORT_M6: + if_type = CCI_IF_MASTER; + break; + case CCI5xx_PORT_GLOBAL: + if_type = CCI_IF_GLOBAL; + break; + default: + return -ENOENT; + } + + if (ev_code >= cci_pmu->model->event_ranges[if_type].min && + ev_code <= cci_pmu->model->event_ranges[if_type].max) + return hw_event; + + return -ENOENT; +} + +#endif /* CONFIG_ARM_CCI5xx_PMU */ + +/* + * Program the CCI PMU counters which have PERF_HES_ARCH set + * with the event period and mark them ready before we enable + * PMU. + */ +static void cci_pmu_sync_counters(struct cci_pmu *cci_pmu) +{ + int i; + struct cci_pmu_hw_events *cci_hw = &cci_pmu->hw_events; + + DECLARE_BITMAP(mask, cci_pmu->num_cntrs); + + bitmap_zero(mask, cci_pmu->num_cntrs); + for_each_set_bit(i, cci_pmu->hw_events.used_mask, cci_pmu->num_cntrs) { + struct perf_event *event = cci_hw->events[i]; + + if (WARN_ON(!event)) + continue; + + /* Leave the events which are not counting */ + if (event->hw.state & PERF_HES_STOPPED) + continue; + if (event->hw.state & PERF_HES_ARCH) { + set_bit(i, mask); + event->hw.state &= ~PERF_HES_ARCH; + } + } + + pmu_write_counters(cci_pmu, mask); +} + +/* Should be called with cci_pmu->hw_events->pmu_lock held */ +static void __cci_pmu_enable_nosync(struct cci_pmu *cci_pmu) +{ + u32 val; + + /* Enable all the PMU counters. */ + val = readl_relaxed(cci_ctrl_base + CCI_PMCR) | CCI_PMCR_CEN; + writel(val, cci_ctrl_base + CCI_PMCR); +} + +/* Should be called with cci_pmu->hw_events->pmu_lock held */ +static void __cci_pmu_enable_sync(struct cci_pmu *cci_pmu) +{ + cci_pmu_sync_counters(cci_pmu); + __cci_pmu_enable_nosync(cci_pmu); +} + +/* Should be called with cci_pmu->hw_events->pmu_lock held */ +static void __cci_pmu_disable(void) +{ + u32 val; + + /* Disable all the PMU counters. */ + val = readl_relaxed(cci_ctrl_base + CCI_PMCR) & ~CCI_PMCR_CEN; + writel(val, cci_ctrl_base + CCI_PMCR); +} static ssize_t cci_pmu_format_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -633,8 +758,8 @@ static u32 pmu_read_register(struct cci_pmu *cci_pmu, int idx, unsigned int offs static void pmu_write_register(struct cci_pmu *cci_pmu, u32 value, int idx, unsigned int offset) { - return writel_relaxed(value, cci_pmu->base + - CCI_PMU_CNTR_BASE(cci_pmu->model, idx) + offset); + writel_relaxed(value, cci_pmu->base + + CCI_PMU_CNTR_BASE(cci_pmu->model, idx) + offset); } static void pmu_disable_counter(struct cci_pmu *cci_pmu, int idx) @@ -647,11 +772,55 @@ static void pmu_enable_counter(struct cci_pmu *cci_pmu, int idx) pmu_write_register(cci_pmu, 1, idx, CCI_PMU_CNTR_CTRL); } +static bool __maybe_unused +pmu_counter_is_enabled(struct cci_pmu *cci_pmu, int idx) +{ + return (pmu_read_register(cci_pmu, idx, CCI_PMU_CNTR_CTRL) & 0x1) != 0; +} + static void pmu_set_event(struct cci_pmu *cci_pmu, int idx, unsigned long event) { pmu_write_register(cci_pmu, event, idx, CCI_PMU_EVT_SEL); } +/* + * For all counters on the CCI-PMU, disable any 'enabled' counters, + * saving the changed counters in the mask, so that we can restore + * it later using pmu_restore_counters. The mask is private to the + * caller. We cannot rely on the used_mask maintained by the CCI_PMU + * as it only tells us if the counter is assigned to perf_event or not. + * The state of the perf_event cannot be locked by the PMU layer, hence + * we check the individual counter status (which can be locked by + * cci_pm->hw_events->pmu_lock). + * + * @mask should be initialised to empty by the caller. + */ +static void __maybe_unused +pmu_save_counters(struct cci_pmu *cci_pmu, unsigned long *mask) +{ + int i; + + for (i = 0; i < cci_pmu->num_cntrs; i++) { + if (pmu_counter_is_enabled(cci_pmu, i)) { + set_bit(i, mask); + pmu_disable_counter(cci_pmu, i); + } + } +} + +/* + * Restore the status of the counters. Reversal of the pmu_save_counters(). + * For each counter set in the mask, enable the counter back. + */ +static void __maybe_unused +pmu_restore_counters(struct cci_pmu *cci_pmu, unsigned long *mask) +{ + int i; + + for_each_set_bit(i, mask, cci_pmu->num_cntrs) + pmu_enable_counter(cci_pmu, i); +} + /* * Returns the number of programmable counters actually implemented * by the cci @@ -754,18 +923,98 @@ static u32 pmu_read_counter(struct perf_event *event) return value; } -static void pmu_write_counter(struct perf_event *event, u32 value) +static void pmu_write_counter(struct cci_pmu *cci_pmu, u32 value, int idx) { - struct cci_pmu *cci_pmu = to_cci_pmu(event->pmu); - struct hw_perf_event *hw_counter = &event->hw; - int idx = hw_counter->idx; + pmu_write_register(cci_pmu, value, idx, CCI_PMU_CNTR); +} - if (unlikely(!pmu_is_valid_counter(cci_pmu, idx))) - dev_err(&cci_pmu->plat_device->dev, "Invalid CCI PMU counter %d\n", idx); +static void __pmu_write_counters(struct cci_pmu *cci_pmu, unsigned long *mask) +{ + int i; + struct cci_pmu_hw_events *cci_hw = &cci_pmu->hw_events; + + for_each_set_bit(i, mask, cci_pmu->num_cntrs) { + struct perf_event *event = cci_hw->events[i]; + + if (WARN_ON(!event)) + continue; + pmu_write_counter(cci_pmu, local64_read(&event->hw.prev_count), i); + } +} + +static void pmu_write_counters(struct cci_pmu *cci_pmu, unsigned long *mask) +{ + if (cci_pmu->model->write_counters) + cci_pmu->model->write_counters(cci_pmu, mask); else - pmu_write_register(cci_pmu, value, idx, CCI_PMU_CNTR); + __pmu_write_counters(cci_pmu, mask); } +#ifdef CONFIG_ARM_CCI5xx_PMU + +/* + * CCI-500/CCI-550 has advanced power saving policies, which could gate the + * clocks to the PMU counters, which makes the writes to them ineffective. + * The only way to write to those counters is when the global counters + * are enabled and the particular counter is enabled. + * + * So we do the following : + * + * 1) Disable all the PMU counters, saving their current state + * 2) Enable the global PMU profiling, now that all counters are + * disabled. + * + * For each counter to be programmed, repeat steps 3-7: + * + * 3) Write an invalid event code to the event control register for the + counter, so that the counters are not modified. + * 4) Enable the counter control for the counter. + * 5) Set the counter value + * 6) Disable the counter + * 7) Restore the event in the target counter + * + * 8) Disable the global PMU. + * 9) Restore the status of the rest of the counters. + * + * We choose an event which for CCI-5xx is guaranteed not to count. + * We use the highest possible event code (0x1f) for the master interface 0. + */ +#define CCI5xx_INVALID_EVENT ((CCI5xx_PORT_M0 << CCI5xx_PMU_EVENT_SOURCE_SHIFT) | \ + (CCI5xx_PMU_EVENT_CODE_MASK << CCI5xx_PMU_EVENT_CODE_SHIFT)) +static void cci5xx_pmu_write_counters(struct cci_pmu *cci_pmu, unsigned long *mask) +{ + int i; + DECLARE_BITMAP(saved_mask, cci_pmu->num_cntrs); + + bitmap_zero(saved_mask, cci_pmu->num_cntrs); + pmu_save_counters(cci_pmu, saved_mask); + + /* + * Now that all the counters are disabled, we can safely turn the PMU on, + * without syncing the status of the counters + */ + __cci_pmu_enable_nosync(cci_pmu); + + for_each_set_bit(i, mask, cci_pmu->num_cntrs) { + struct perf_event *event = cci_pmu->hw_events.events[i]; + + if (WARN_ON(!event)) + continue; + + pmu_set_event(cci_pmu, i, CCI5xx_INVALID_EVENT); + pmu_enable_counter(cci_pmu, i); + pmu_write_counter(cci_pmu, local64_read(&event->hw.prev_count), i); + pmu_disable_counter(cci_pmu, i); + pmu_set_event(cci_pmu, i, event->hw.config_base); + } + + __cci_pmu_disable(); + + pmu_restore_counters(cci_pmu, saved_mask); +} + +#endif /* CONFIG_ARM_CCI5xx_PMU */ + static u64 pmu_event_update(struct perf_event *event) { struct hw_perf_event *hwc = &event->hw; @@ -789,7 +1038,7 @@ static void pmu_read(struct perf_event *event) pmu_event_update(event); } -void pmu_event_set_period(struct perf_event *event) +static void pmu_event_set_period(struct perf_event *event) { struct hw_perf_event *hwc = &event->hw; /* @@ -800,7 +1049,14 @@ void pmu_event_set_period(struct perf_event *event) */ u64 val = 1ULL << 31; local64_set(&hwc->prev_count, val); - pmu_write_counter(event, val); + + /* + * CCI PMU uses PERF_HES_ARCH to keep track of the counters, whose + * values needs to be sync-ed with the s/w state before the PMU is + * enabled. + * Mark this counter for sync. + */ + hwc->state |= PERF_HES_ARCH; } static irqreturn_t pmu_handle_irq(int irq_num, void *dev) @@ -811,6 +1067,9 @@ static irqreturn_t pmu_handle_irq(int irq_num, void *dev) int idx, handled = IRQ_NONE; raw_spin_lock_irqsave(&events->pmu_lock, flags); + + /* Disable the PMU while we walk through the counters */ + __cci_pmu_disable(); /* * Iterate over counters and update the corresponding perf events. * This should work regardless of whether we have per-counter overflow @@ -818,13 +1077,10 @@ static irqreturn_t pmu_handle_irq(int irq_num, void *dev) */ for (idx = 0; idx <= CCI_PMU_CNTR_LAST(cci_pmu); idx++) { struct perf_event *event = events->events[idx]; - struct hw_perf_event *hw_counter; if (!event) continue; - hw_counter = &event->hw; - /* Did this counter overflow? */ if (!(pmu_read_register(cci_pmu, idx, CCI_PMU_OVRFLW) & CCI_PMU_OVRFLW_FLAG)) @@ -837,6 +1093,9 @@ static irqreturn_t pmu_handle_irq(int irq_num, void *dev) pmu_event_set_period(event); handled = IRQ_HANDLED; } + + /* Enable the PMU and sync possibly overflowed counters */ + __cci_pmu_enable_sync(cci_pmu); raw_spin_unlock_irqrestore(&events->pmu_lock, flags); return IRQ_RETVAL(handled); @@ -875,16 +1134,12 @@ static void cci_pmu_enable(struct pmu *pmu) struct cci_pmu_hw_events *hw_events = &cci_pmu->hw_events; int enabled = bitmap_weight(hw_events->used_mask, cci_pmu->num_cntrs); unsigned long flags; - u32 val; if (!enabled) return; raw_spin_lock_irqsave(&hw_events->pmu_lock, flags); - - /* Enable all the PMU counters. */ - val = readl_relaxed(cci_ctrl_base + CCI_PMCR) | CCI_PMCR_CEN; - writel(val, cci_ctrl_base + CCI_PMCR); + __cci_pmu_enable_sync(cci_pmu); raw_spin_unlock_irqrestore(&hw_events->pmu_lock, flags); } @@ -894,13 +1149,9 @@ static void cci_pmu_disable(struct pmu *pmu) struct cci_pmu *cci_pmu = to_cci_pmu(pmu); struct cci_pmu_hw_events *hw_events = &cci_pmu->hw_events; unsigned long flags; - u32 val; raw_spin_lock_irqsave(&hw_events->pmu_lock, flags); - - /* Disable all the PMU counters. */ - val = readl_relaxed(cci_ctrl_base + CCI_PMCR) & ~CCI_PMCR_CEN; - writel(val, cci_ctrl_base + CCI_PMCR); + __cci_pmu_disable(); raw_spin_unlock_irqrestore(&hw_events->pmu_lock, flags); } @@ -1176,9 +1427,8 @@ static int cci_pmu_event_init(struct perf_event *event) static ssize_t pmu_cpumask_attr_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct dev_ext_attribute *eattr = container_of(attr, - struct dev_ext_attribute, attr); - struct cci_pmu *cci_pmu = eattr->var; + struct pmu *pmu = dev_get_drvdata(dev); + struct cci_pmu *cci_pmu = to_cci_pmu(pmu); int n = scnprintf(buf, PAGE_SIZE - 1, "%*pbl", cpumask_pr_args(&cci_pmu->cpus)); @@ -1187,13 +1437,11 @@ static ssize_t pmu_cpumask_attr_show(struct device *dev, return n; } -static struct dev_ext_attribute pmu_cpumask_attr = { - __ATTR(cpumask, S_IRUGO, pmu_cpumask_attr_show, NULL), - NULL, /* Populated in cci_pmu_init */ -}; +static struct device_attribute pmu_cpumask_attr = + __ATTR(cpumask, S_IRUGO, pmu_cpumask_attr_show, NULL); static struct attribute *pmu_attrs[] = { - &pmu_cpumask_attr.attr.attr, + &pmu_cpumask_attr.attr, NULL, }; @@ -1218,60 +1466,14 @@ static const struct attribute_group *pmu_attr_groups[] = { NULL }; -static struct attribute **alloc_attrs(struct platform_device *pdev, - int n, struct dev_ext_attribute *source) -{ - int i; - struct attribute **attrs; - - /* Alloc n + 1 (for terminating NULL) */ - attrs = devm_kcalloc(&pdev->dev, n + 1, sizeof(struct attribute *), - GFP_KERNEL); - if (!attrs) - return attrs; - for(i = 0; i < n; i++) - attrs[i] = &source[i].attr.attr; - return attrs; -} - -static int cci_pmu_init_attrs(struct cci_pmu *cci_pmu, struct platform_device *pdev) -{ - const struct cci_pmu_model *model = cci_pmu->model; - struct attribute **attrs; - - /* - * All allocations below are managed, hence doesn't need to be - * free'd explicitly in case of an error. - */ - - if (model->nevent_attrs) { - attrs = alloc_attrs(pdev, model->nevent_attrs, - model->event_attrs); - if (!attrs) - return -ENOMEM; - pmu_event_attr_group.attrs = attrs; - } - if (model->nformat_attrs) { - attrs = alloc_attrs(pdev, model->nformat_attrs, - model->format_attrs); - if (!attrs) - return -ENOMEM; - pmu_format_attr_group.attrs = attrs; - } - pmu_cpumask_attr.var = cci_pmu; - - return 0; -} - static int cci_pmu_init(struct cci_pmu *cci_pmu, struct platform_device *pdev) { - char *name = cci_pmu->model->name; + const struct cci_pmu_model *model = cci_pmu->model; + char *name = model->name; u32 num_cntrs; - int rc; - rc = cci_pmu_init_attrs(cci_pmu, pdev); - if (rc) - return rc; + pmu_event_attr_group.attrs = model->event_attrs; + pmu_format_attr_group.attrs = model->format_attrs; cci_pmu->pmu = (struct pmu) { .name = cci_pmu->model->name, @@ -1314,7 +1516,7 @@ static int cci_pmu_cpu_notifier(struct notifier_block *self, if (!cpumask_test_and_clear_cpu(cpu, &cci_pmu->cpus)) break; target = cpumask_any_but(cpu_online_mask, cpu); - if (target < 0) // UP, last CPU + if (target >= nr_cpu_ids) // UP, last CPU break; /* * TODO: migrate context once core races on event->ctx have @@ -1336,9 +1538,7 @@ static struct cci_pmu_model cci_pmu_models[] = { .num_hw_cntrs = 4, .cntr_size = SZ_4K, .format_attrs = cci400_pmu_format_attrs, - .nformat_attrs = ARRAY_SIZE(cci400_pmu_format_attrs), .event_attrs = cci400_r0_pmu_event_attrs, - .nevent_attrs = ARRAY_SIZE(cci400_r0_pmu_event_attrs), .event_ranges = { [CCI_IF_SLAVE] = { CCI400_R0_SLAVE_PORT_MIN_EV, @@ -1358,9 +1558,7 @@ static struct cci_pmu_model cci_pmu_models[] = { .num_hw_cntrs = 4, .cntr_size = SZ_4K, .format_attrs = cci400_pmu_format_attrs, - .nformat_attrs = ARRAY_SIZE(cci400_pmu_format_attrs), .event_attrs = cci400_r1_pmu_event_attrs, - .nevent_attrs = ARRAY_SIZE(cci400_r1_pmu_event_attrs), .event_ranges = { [CCI_IF_SLAVE] = { CCI400_R1_SLAVE_PORT_MIN_EV, @@ -1375,31 +1573,54 @@ static struct cci_pmu_model cci_pmu_models[] = { .get_event_idx = cci400_get_event_idx, }, #endif -#ifdef CONFIG_ARM_CCI500_PMU +#ifdef CONFIG_ARM_CCI5xx_PMU [CCI500_R0] = { .name = "CCI_500", .fixed_hw_cntrs = 0, .num_hw_cntrs = 8, .cntr_size = SZ_64K, - .format_attrs = cci500_pmu_format_attrs, - .nformat_attrs = ARRAY_SIZE(cci500_pmu_format_attrs), - .event_attrs = cci500_pmu_event_attrs, - .nevent_attrs = ARRAY_SIZE(cci500_pmu_event_attrs), + .format_attrs = cci5xx_pmu_format_attrs, + .event_attrs = cci5xx_pmu_event_attrs, .event_ranges = { [CCI_IF_SLAVE] = { - CCI500_SLAVE_PORT_MIN_EV, - CCI500_SLAVE_PORT_MAX_EV, + CCI5xx_SLAVE_PORT_MIN_EV, + CCI5xx_SLAVE_PORT_MAX_EV, }, [CCI_IF_MASTER] = { - CCI500_MASTER_PORT_MIN_EV, - CCI500_MASTER_PORT_MAX_EV, + CCI5xx_MASTER_PORT_MIN_EV, + CCI5xx_MASTER_PORT_MAX_EV, }, [CCI_IF_GLOBAL] = { - CCI500_GLOBAL_PORT_MIN_EV, - CCI500_GLOBAL_PORT_MAX_EV, + CCI5xx_GLOBAL_PORT_MIN_EV, + CCI5xx_GLOBAL_PORT_MAX_EV, }, }, .validate_hw_event = cci500_validate_hw_event, + .write_counters = cci5xx_pmu_write_counters, + }, + [CCI550_R0] = { + .name = "CCI_550", + .fixed_hw_cntrs = 0, + .num_hw_cntrs = 8, + .cntr_size = SZ_64K, + .format_attrs = cci5xx_pmu_format_attrs, + .event_attrs = cci5xx_pmu_event_attrs, + .event_ranges = { + [CCI_IF_SLAVE] = { + CCI5xx_SLAVE_PORT_MIN_EV, + CCI5xx_SLAVE_PORT_MAX_EV, + }, + [CCI_IF_MASTER] = { + CCI5xx_MASTER_PORT_MIN_EV, + CCI5xx_MASTER_PORT_MAX_EV, + }, + [CCI_IF_GLOBAL] = { + CCI5xx_GLOBAL_PORT_MIN_EV, + CCI5xx_GLOBAL_PORT_MAX_EV, + }, + }, + .validate_hw_event = cci550_validate_hw_event, + .write_counters = cci5xx_pmu_write_counters, }, #endif }; @@ -1419,11 +1640,15 @@ static const struct of_device_id arm_cci_pmu_matches[] = { .data = &cci_pmu_models[CCI400_R1], }, #endif -#ifdef CONFIG_ARM_CCI500_PMU +#ifdef CONFIG_ARM_CCI5xx_PMU { .compatible = "arm,cci-500-pmu,r0", .data = &cci_pmu_models[CCI500_R0], }, + { + .compatible = "arm,cci-550-pmu,r0", + .data = &cci_pmu_models[CCI550_R0], + }, #endif {}, }; diff --git a/drivers/bus/imx-weim.c b/drivers/bus/imx-weim.c index e98d15eaa7994c7349d1db8df4dd19f684b85ba6..1827fc4d15c1a710103c4daf7a62a6067989422a 100644 --- a/drivers/bus/imx-weim.c +++ b/drivers/bus/imx-weim.c @@ -150,7 +150,7 @@ static int __init weim_parse_dt(struct platform_device *pdev, return ret; } - for_each_child_of_node(pdev->dev.of_node, child) { + for_each_available_child_of_node(pdev->dev.of_node, child) { if (!child->name) continue; diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c index c43c3d2baf73c2e7663d367ad35aa97be8c6ba33..c2e52864bb03a5d862c00f712527df2d25e9217b 100644 --- a/drivers/bus/mvebu-mbus.c +++ b/drivers/bus/mvebu-mbus.c @@ -948,6 +948,58 @@ void mvebu_mbus_get_pcie_io_aperture(struct resource *res) *res = mbus_state.pcie_io_aperture; } +int mvebu_mbus_get_dram_win_info(phys_addr_t phyaddr, u8 *target, u8 *attr) +{ + const struct mbus_dram_target_info *dram; + int i; + + /* Get dram info */ + dram = mv_mbus_dram_info(); + if (!dram) { + pr_err("missing DRAM information\n"); + return -ENODEV; + } + + /* Try to find matching DRAM window for phyaddr */ + for (i = 0; i < dram->num_cs; i++) { + const struct mbus_dram_window *cs = dram->cs + i; + + if (cs->base <= phyaddr && + phyaddr <= (cs->base + cs->size - 1)) { + *target = dram->mbus_dram_target_id; + *attr = cs->mbus_attr; + return 0; + } + } + + pr_err("invalid dram address 0x%x\n", phyaddr); + return -EINVAL; +} +EXPORT_SYMBOL_GPL(mvebu_mbus_get_dram_win_info); + +int mvebu_mbus_get_io_win_info(phys_addr_t phyaddr, u32 *size, u8 *target, + u8 *attr) +{ + int win; + + for (win = 0; win < mbus_state.soc->num_wins; win++) { + u64 wbase; + int enabled; + + mvebu_mbus_read_window(&mbus_state, win, &enabled, &wbase, + size, target, attr, NULL); + + if (!enabled) + continue; + + if (wbase <= phyaddr && phyaddr <= wbase + *size) + return win; + } + + return -EINVAL; +} +EXPORT_SYMBOL_GPL(mvebu_mbus_get_io_win_info); + static __init int mvebu_mbus_debugfs_init(void) { struct mvebu_mbus_state *s = &mbus_state; diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c index 25996e2561105ac615cf4cc99c468f7a8db0f3df..795c9d9c96a6d5ae08c036a221ae1f9a4b1f9c1b 100644 --- a/drivers/bus/sunxi-rsb.c +++ b/drivers/bus/sunxi-rsb.c @@ -330,7 +330,7 @@ static int sunxi_rsb_read(struct sunxi_rsb *rsb, u8 rtaddr, u8 addr, cmd = RSB_CMD_RD32; break; default: - dev_err(rsb->dev, "Invalid access width: %d\n", len); + dev_err(rsb->dev, "Invalid access width: %zd\n", len); return -EINVAL; } @@ -372,7 +372,7 @@ static int sunxi_rsb_write(struct sunxi_rsb *rsb, u8 rtaddr, u8 addr, cmd = RSB_CMD_WR32; break; default: - dev_err(rsb->dev, "Invalid access width: %d\n", len); + dev_err(rsb->dev, "Invalid access width: %zd\n", len); return -EINVAL; } diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c index 09f17eb734863fd0dfc6d69fc6f7716906391424..0f64d149c98dcdea120a03ea6f191c36c01b3a29 100644 --- a/drivers/char/agp/frontend.c +++ b/drivers/char/agp/frontend.c @@ -156,7 +156,7 @@ static pgprot_t agp_convert_mmap_flags(int prot) { unsigned long prot_bits; - prot_bits = calc_vm_prot_bits(prot) | VM_SHARED; + prot_bits = calc_vm_prot_bits(prot, 0) | VM_SHARED; return vm_get_page_prot(prot_bits); } diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 1341a94cc7793aa0425eb83c4e446393be7f60c6..aef87fdbd187990d85cbe1b4332a54d82a1f499a 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -555,8 +555,10 @@ static unsigned int intel_gtt_mappable_entries(void) static void intel_gtt_teardown_scratch_page(void) { set_pages_wb(intel_private.scratch_page, 1); - pci_unmap_page(intel_private.pcidev, intel_private.scratch_page_dma, - PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); + if (intel_private.needs_dmar) + pci_unmap_page(intel_private.pcidev, + intel_private.scratch_page_dma, + PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); __free_page(intel_private.scratch_page); } @@ -1346,16 +1348,6 @@ int intel_gmch_probe(struct pci_dev *bridge_pdev, struct pci_dev *gpu_pdev, { int i, mask; - /* - * Can be called from the fake agp driver but also directly from - * drm/i915.ko. Hence we need to check whether everything is set up - * already. - */ - if (intel_private.driver) { - intel_private.refcount++; - return 1; - } - for (i = 0; intel_gtt_chipsets[i].name != NULL; i++) { if (gpu_pdev) { if (gpu_pdev->device == @@ -1376,16 +1368,26 @@ int intel_gmch_probe(struct pci_dev *bridge_pdev, struct pci_dev *gpu_pdev, if (!intel_private.driver) return 0; - intel_private.refcount++; - #if IS_ENABLED(CONFIG_AGP_INTEL) if (bridge) { + if (INTEL_GTT_GEN > 1) + return 0; + bridge->driver = &intel_fake_agp_driver; bridge->dev_private_data = &intel_private; bridge->dev = bridge_pdev; } #endif + + /* + * Can be called from the fake agp driver but also directly from + * drm/i915.ko. Hence we need to check whether everything is set up + * already. + */ + if (intel_private.refcount++) + return 1; + intel_private.bridge_dev = pci_dev_get(bridge_pdev); dev_info(&bridge_pdev->dev, "Intel %s Chipset\n", intel_gtt_chipsets[i].name); @@ -1430,6 +1432,8 @@ void intel_gmch_remove(void) if (--intel_private.refcount) return; + if (intel_private.scratch_page) + intel_gtt_teardown_scratch_page(); if (intel_private.pcidev) pci_dev_put(intel_private.pcidev); if (intel_private.bridge_dev) diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 7fddd8696211f0320011c964a88a37a16133c4ba..1e25b5205724deb703fab9b48df8ecdebd41bfb3 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -849,7 +849,7 @@ static enum si_sm_result smi_event_handler(struct smi_info *smi_info, smi_inc_stat(smi_info, complete_transactions); handle_transaction_done(smi_info); - si_sm_result = smi_info->handlers->event(smi_info->si_sm, 0); + goto restart; } else if (si_sm_result == SI_SM_HOSED) { smi_inc_stat(smi_info, hosed_count); @@ -866,7 +866,7 @@ static enum si_sm_result smi_event_handler(struct smi_info *smi_info, */ return_hosed_msg(smi_info, IPMI_ERR_UNSPECIFIED); } - si_sm_result = smi_info->handlers->event(smi_info->si_sm, 0); + goto restart; } /* @@ -1363,12 +1363,12 @@ MODULE_PARM_DESC(trydmi, "Setting this to zero will disable the" " default scan of the interfaces identified via DMI"); #endif module_param_named(tryplatform, si_tryplatform, bool, 0); -MODULE_PARM_DESC(tryacpi, "Setting this to zero will disable the" +MODULE_PARM_DESC(tryplatform, "Setting this to zero will disable the" " default scan of the interfaces identified via platform" " interfaces like openfirmware"); #ifdef CONFIG_PCI module_param_named(trypci, si_trypci, bool, 0); -MODULE_PARM_DESC(tryacpi, "Setting this to zero will disable the" +MODULE_PARM_DESC(trypci, "Setting this to zero will disable the" " default scan of the interfaces identified via pci"); #endif module_param_named(trydefaults, si_trydefaults, bool, 0); @@ -2690,6 +2690,9 @@ static int acpi_ipmi_probe(struct platform_device *dev) unsigned long long tmp; int rv = -EINVAL; + if (!si_tryacpi) + return 0; + handle = ACPI_HANDLE(&dev->dev); if (!handle) return -ENODEV; diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c index 5f1c3d08ba6540e4afc9469f888e442862d09fa3..8b3be8b9257398b7f0dd306158a6428ea0949ad9 100644 --- a/drivers/char/ipmi/ipmi_ssif.c +++ b/drivers/char/ipmi/ipmi_ssif.c @@ -920,23 +920,18 @@ static void msg_written_handler(struct ssif_info *ssif_info, int result, msg_done_handler(ssif_info, -EIO, NULL, 0); } } else { + /* Ready to request the result. */ unsigned long oflags, *flags; - bool got_alert; ssif_inc_stat(ssif_info, sent_messages); ssif_inc_stat(ssif_info, sent_messages_parts); flags = ipmi_ssif_lock_cond(ssif_info, &oflags); - got_alert = ssif_info->got_alert; - if (got_alert) { + if (ssif_info->got_alert) { + /* The result is already ready, just start it. */ ssif_info->got_alert = false; - ssif_info->waiting_alert = false; - } - - if (got_alert) { ipmi_ssif_unlock_cond(ssif_info, flags); - /* The alert already happened, try now. */ - retry_timeout((unsigned long) ssif_info); + start_get(ssif_info); } else { /* Wait a jiffie then request the next message */ ssif_info->waiting_alert = true; diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index 096f0cef4da14152653ea61daa010b367174759d..4facc7517a6a222350f2478568f81422980ff108 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c @@ -1140,7 +1140,7 @@ ipmi_nmi(unsigned int val, struct pt_regs *regs) the timer. So do so. */ pretimeout_since_last_heartbeat = 1; if (atomic_inc_and_test(&preop_panic_excl)) - panic(PFX "pre-timeout"); + nmi_panic(regs, PFX "pre-timeout"); } return NMI_HANDLED; diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c index d23368874710f726d485917e4d3f1ef93f3e3843..f8a483c67b07719be1f97af6bd1750bc53b04ae6 100644 --- a/drivers/char/ppdev.c +++ b/drivers/char/ppdev.c @@ -286,7 +286,7 @@ static int register_device(int minor, struct pp_struct *pp) struct parport *port; struct pardevice *pdev = NULL; char *name; - struct pardev_cb ppdev_cb; + int fl; name = kasprintf(GFP_KERNEL, CHRDEV "%x", minor); if (name == NULL) @@ -299,11 +299,9 @@ static int register_device(int minor, struct pp_struct *pp) return -ENXIO; } - memset(&ppdev_cb, 0, sizeof(ppdev_cb)); - ppdev_cb.irq_func = pp_irq; - ppdev_cb.flags = (pp->flags & PP_EXCL) ? PARPORT_FLAG_EXCL : 0; - ppdev_cb.private = pp; - pdev = parport_register_dev_model(port, name, &ppdev_cb, minor); + fl = (pp->flags & PP_EXCL) ? PARPORT_FLAG_EXCL : 0; + pdev = parport_register_device(port, name, NULL, + NULL, pp_irq, fl, pp); parport_put_port(port); if (!pdev) { @@ -801,23 +799,10 @@ static void pp_detach(struct parport *port) device_destroy(ppdev_class, MKDEV(PP_MAJOR, port->number)); } -static int pp_probe(struct pardevice *par_dev) -{ - struct device_driver *drv = par_dev->dev.driver; - int len = strlen(drv->name); - - if (strncmp(par_dev->name, drv->name, len)) - return -ENODEV; - - return 0; -} - static struct parport_driver pp_driver = { .name = CHRDEV, - .probe = pp_probe, - .match_port = pp_attach, + .attach = pp_attach, .detach = pp_detach, - .devmodel = true, }; static int __init ppdev_init(void) diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index eca8e019e0054bb7443c63196b01ca217fabbd55..16f7d33421d8b63bad61770b638b1034c2dac92e 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -6,9 +6,6 @@ config CLKDEV_LOOKUP config HAVE_CLK_PREPARE bool -config HAVE_MACH_CLKDEV - bool - config COMMON_CLK bool select HAVE_CLK_PREPARE @@ -99,6 +96,14 @@ config COMMON_CLK_SI570 This driver supports Silicon Labs 570/571/598/599 programmable clock generators. +config COMMON_CLK_CDCE706 + tristate "Clock driver for TI CDCE706 clock synthesizer" + depends on I2C + select REGMAP_I2C + select RATIONAL + ---help--- + This driver supports TI CDCE706 programmable 3-PLL clock synthesizer. + config COMMON_CLK_CDCE925 tristate "Clock driver for TI CDCE925 devices" depends on I2C @@ -190,23 +195,14 @@ config COMMON_CLK_PWM config COMMON_CLK_PXA def_bool COMMON_CLK && ARCH_PXA ---help--- - Sypport for the Marvell PXA SoC. - -config COMMON_CLK_CDCE706 - tristate "Clock driver for TI CDCE706 clock synthesizer" - depends on I2C - select REGMAP_I2C - select RATIONAL - ---help--- - This driver supports TI CDCE706 programmable 3-PLL clock synthesizer. + Support for the Marvell PXA SoC. source "drivers/clk/bcm/Kconfig" source "drivers/clk/hisilicon/Kconfig" -source "drivers/clk/qcom/Kconfig" - -endmenu - source "drivers/clk/mvebu/Kconfig" - +source "drivers/clk/qcom/Kconfig" source "drivers/clk/samsung/Kconfig" source "drivers/clk/tegra/Kconfig" +source "drivers/clk/ti/Kconfig" + +endmenu diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index bae4be6501dfb06a51dc0aaa3befb91b47156ca0..46869d696e4d7bba3962719fb9464684a2bb4c91 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -70,15 +70,14 @@ obj-$(CONFIG_COMMON_CLK_PXA) += pxa/ obj-$(CONFIG_COMMON_CLK_QCOM) += qcom/ obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ obj-$(CONFIG_COMMON_CLK_SAMSUNG) += samsung/ -obj-$(CONFIG_ARCH_SHMOBILE_MULTI) += shmobile/ -obj-$(CONFIG_ARCH_RENESAS) += shmobile/ +obj-$(CONFIG_ARCH_RENESAS) += renesas/ obj-$(CONFIG_ARCH_SIRF) += sirf/ obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/ obj-$(CONFIG_PLAT_SPEAR) += spear/ obj-$(CONFIG_ARCH_STI) += st/ obj-$(CONFIG_ARCH_SUNXI) += sunxi/ obj-$(CONFIG_ARCH_TEGRA) += tegra/ -obj-$(CONFIG_ARCH_OMAP2PLUS) += ti/ +obj-y += ti/ obj-$(CONFIG_ARCH_U8500) += ux500/ obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/ obj-$(CONFIG_X86) += x86/ diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c index abc80949e1ddbea4bb8a47941f9ab5cf278f3113..e1aa210dd7aa6a6bf3ca40bb76f31f36407eb116 100644 --- a/drivers/clk/at91/clk-generated.c +++ b/drivers/clk/at91/clk-generated.c @@ -15,8 +15,8 @@ #include #include #include -#include -#include +#include +#include #include "pmc.h" @@ -28,8 +28,9 @@ struct clk_generated { struct clk_hw hw; - struct at91_pmc *pmc; + struct regmap *regmap; struct clk_range range; + spinlock_t *lock; u32 id; u32 gckdiv; u8 parent_id; @@ -41,49 +42,52 @@ struct clk_generated { static int clk_generated_enable(struct clk_hw *hw) { struct clk_generated *gck = to_clk_generated(hw); - struct at91_pmc *pmc = gck->pmc; - u32 tmp; + unsigned long flags; pr_debug("GCLK: %s, gckdiv = %d, parent id = %d\n", __func__, gck->gckdiv, gck->parent_id); - pmc_lock(pmc); - pmc_write(pmc, AT91_PMC_PCR, (gck->id & AT91_PMC_PCR_PID_MASK)); - tmp = pmc_read(pmc, AT91_PMC_PCR) & - ~(AT91_PMC_PCR_GCKDIV_MASK | AT91_PMC_PCR_GCKCSS_MASK); - pmc_write(pmc, AT91_PMC_PCR, tmp | AT91_PMC_PCR_GCKCSS(gck->parent_id) - | AT91_PMC_PCR_CMD - | AT91_PMC_PCR_GCKDIV(gck->gckdiv) - | AT91_PMC_PCR_GCKEN); - pmc_unlock(pmc); + spin_lock_irqsave(gck->lock, flags); + regmap_write(gck->regmap, AT91_PMC_PCR, + (gck->id & AT91_PMC_PCR_PID_MASK)); + regmap_update_bits(gck->regmap, AT91_PMC_PCR, + AT91_PMC_PCR_GCKDIV_MASK | AT91_PMC_PCR_GCKCSS_MASK | + AT91_PMC_PCR_CMD | AT91_PMC_PCR_GCKEN, + AT91_PMC_PCR_GCKCSS(gck->parent_id) | + AT91_PMC_PCR_CMD | + AT91_PMC_PCR_GCKDIV(gck->gckdiv) | + AT91_PMC_PCR_GCKEN); + spin_unlock_irqrestore(gck->lock, flags); return 0; } static void clk_generated_disable(struct clk_hw *hw) { struct clk_generated *gck = to_clk_generated(hw); - struct at91_pmc *pmc = gck->pmc; - u32 tmp; - - pmc_lock(pmc); - pmc_write(pmc, AT91_PMC_PCR, (gck->id & AT91_PMC_PCR_PID_MASK)); - tmp = pmc_read(pmc, AT91_PMC_PCR) & ~AT91_PMC_PCR_GCKEN; - pmc_write(pmc, AT91_PMC_PCR, tmp | AT91_PMC_PCR_CMD); - pmc_unlock(pmc); + unsigned long flags; + + spin_lock_irqsave(gck->lock, flags); + regmap_write(gck->regmap, AT91_PMC_PCR, + (gck->id & AT91_PMC_PCR_PID_MASK)); + regmap_update_bits(gck->regmap, AT91_PMC_PCR, + AT91_PMC_PCR_CMD | AT91_PMC_PCR_GCKEN, + AT91_PMC_PCR_CMD); + spin_unlock_irqrestore(gck->lock, flags); } static int clk_generated_is_enabled(struct clk_hw *hw) { struct clk_generated *gck = to_clk_generated(hw); - struct at91_pmc *pmc = gck->pmc; - int ret; + unsigned long flags; + unsigned int status; - pmc_lock(pmc); - pmc_write(pmc, AT91_PMC_PCR, (gck->id & AT91_PMC_PCR_PID_MASK)); - ret = !!(pmc_read(pmc, AT91_PMC_PCR) & AT91_PMC_PCR_GCKEN); - pmc_unlock(pmc); + spin_lock_irqsave(gck->lock, flags); + regmap_write(gck->regmap, AT91_PMC_PCR, + (gck->id & AT91_PMC_PCR_PID_MASK)); + regmap_read(gck->regmap, AT91_PMC_PCR, &status); + spin_unlock_irqrestore(gck->lock, flags); - return ret; + return status & AT91_PMC_PCR_GCKEN ? 1 : 0; } static unsigned long @@ -214,13 +218,14 @@ static const struct clk_ops generated_ops = { */ static void clk_generated_startup(struct clk_generated *gck) { - struct at91_pmc *pmc = gck->pmc; u32 tmp; + unsigned long flags; - pmc_lock(pmc); - pmc_write(pmc, AT91_PMC_PCR, (gck->id & AT91_PMC_PCR_PID_MASK)); - tmp = pmc_read(pmc, AT91_PMC_PCR); - pmc_unlock(pmc); + spin_lock_irqsave(gck->lock, flags); + regmap_write(gck->regmap, AT91_PMC_PCR, + (gck->id & AT91_PMC_PCR_PID_MASK)); + regmap_read(gck->regmap, AT91_PMC_PCR, &tmp); + spin_unlock_irqrestore(gck->lock, flags); gck->parent_id = (tmp & AT91_PMC_PCR_GCKCSS_MASK) >> AT91_PMC_PCR_GCKCSS_OFFSET; @@ -229,8 +234,8 @@ static void clk_generated_startup(struct clk_generated *gck) } static struct clk * __init -at91_clk_register_generated(struct at91_pmc *pmc, const char *name, - const char **parent_names, u8 num_parents, +at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock, const char + *name, const char **parent_names, u8 num_parents, u8 id, const struct clk_range *range) { struct clk_generated *gck; @@ -249,7 +254,8 @@ at91_clk_register_generated(struct at91_pmc *pmc, const char *name, gck->id = id; gck->hw.init = &init; - gck->pmc = pmc; + gck->regmap = regmap; + gck->lock = lock; gck->range = *range; clk = clk_register(NULL, &gck->hw); @@ -261,20 +267,20 @@ at91_clk_register_generated(struct at91_pmc *pmc, const char *name, return clk; } -void __init of_sama5d2_clk_generated_setup(struct device_node *np, - struct at91_pmc *pmc) +void __init of_sama5d2_clk_generated_setup(struct device_node *np) { int num; u32 id; const char *name; struct clk *clk; - int num_parents; + unsigned int num_parents; const char *parent_names[GENERATED_SOURCE_MAX]; struct device_node *gcknp; struct clk_range range = CLK_RANGE(0, 0); + struct regmap *regmap; num_parents = of_clk_get_parent_count(np); - if (num_parents <= 0 || num_parents > GENERATED_SOURCE_MAX) + if (num_parents == 0 || num_parents > GENERATED_SOURCE_MAX) return; of_clk_parent_fill(np, parent_names, num_parents); @@ -283,6 +289,10 @@ void __init of_sama5d2_clk_generated_setup(struct device_node *np, if (!num || num > PERIPHERAL_MAX) return; + regmap = syscon_node_to_regmap(of_get_parent(np)); + if (IS_ERR(regmap)) + return; + for_each_child_of_node(np, gcknp) { if (of_property_read_u32(gcknp, "reg", &id)) continue; @@ -296,11 +306,14 @@ void __init of_sama5d2_clk_generated_setup(struct device_node *np, of_at91_get_clk_range(gcknp, "atmel,clk-output-range", &range); - clk = at91_clk_register_generated(pmc, name, parent_names, - num_parents, id, &range); + clk = at91_clk_register_generated(regmap, &pmc_pcr_lock, name, + parent_names, num_parents, + id, &range); if (IS_ERR(clk)) continue; of_clk_add_provider(gcknp, of_clk_src_simple_get, clk); } } +CLK_OF_DECLARE(of_sama5d2_clk_generated_setup, "atmel,sama5d2-clk-generated", + of_sama5d2_clk_generated_setup); diff --git a/drivers/clk/at91/clk-h32mx.c b/drivers/clk/at91/clk-h32mx.c index 61566bcefa53399ab3af07611398af3f114849c7..819f5842fa660a22e1bb32c1d301795acb25cd99 100644 --- a/drivers/clk/at91/clk-h32mx.c +++ b/drivers/clk/at91/clk-h32mx.c @@ -15,15 +15,9 @@ #include #include #include -#include #include -#include -#include -#include -#include -#include -#include -#include +#include +#include #include "pmc.h" @@ -31,7 +25,7 @@ struct clk_sama5d4_h32mx { struct clk_hw hw; - struct at91_pmc *pmc; + struct regmap *regmap; }; #define to_clk_sama5d4_h32mx(hw) container_of(hw, struct clk_sama5d4_h32mx, hw) @@ -40,8 +34,10 @@ static unsigned long clk_sama5d4_h32mx_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct clk_sama5d4_h32mx *h32mxclk = to_clk_sama5d4_h32mx(hw); + unsigned int mckr; - if (pmc_read(h32mxclk->pmc, AT91_PMC_MCKR) & AT91_PMC_H32MXDIV) + regmap_read(h32mxclk->regmap, AT91_PMC_MCKR, &mckr); + if (mckr & AT91_PMC_H32MXDIV) return parent_rate / 2; if (parent_rate > H32MX_MAX_FREQ) @@ -70,18 +66,16 @@ static int clk_sama5d4_h32mx_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { struct clk_sama5d4_h32mx *h32mxclk = to_clk_sama5d4_h32mx(hw); - struct at91_pmc *pmc = h32mxclk->pmc; - u32 tmp; + u32 mckr = 0; if (parent_rate != rate && (parent_rate / 2) != rate) return -EINVAL; - pmc_lock(pmc); - tmp = pmc_read(pmc, AT91_PMC_MCKR) & ~AT91_PMC_H32MXDIV; if ((parent_rate / 2) == rate) - tmp |= AT91_PMC_H32MXDIV; - pmc_write(pmc, AT91_PMC_MCKR, tmp); - pmc_unlock(pmc); + mckr = AT91_PMC_H32MXDIV; + + regmap_update_bits(h32mxclk->regmap, AT91_PMC_MCKR, + AT91_PMC_H32MXDIV, mckr); return 0; } @@ -92,14 +86,18 @@ static const struct clk_ops h32mx_ops = { .set_rate = clk_sama5d4_h32mx_set_rate, }; -void __init of_sama5d4_clk_h32mx_setup(struct device_node *np, - struct at91_pmc *pmc) +static void __init of_sama5d4_clk_h32mx_setup(struct device_node *np) { struct clk_sama5d4_h32mx *h32mxclk; struct clk_init_data init; const char *parent_name; + struct regmap *regmap; struct clk *clk; + regmap = syscon_node_to_regmap(of_get_parent(np)); + if (IS_ERR(regmap)) + return; + h32mxclk = kzalloc(sizeof(*h32mxclk), GFP_KERNEL); if (!h32mxclk) return; @@ -113,7 +111,7 @@ void __init of_sama5d4_clk_h32mx_setup(struct device_node *np, init.flags = CLK_SET_RATE_GATE; h32mxclk->hw.init = &init; - h32mxclk->pmc = pmc; + h32mxclk->regmap = regmap; clk = clk_register(NULL, &h32mxclk->hw); if (!clk) { @@ -123,3 +121,5 @@ void __init of_sama5d4_clk_h32mx_setup(struct device_node *np, of_clk_add_provider(np, of_clk_src_simple_get, clk); } +CLK_OF_DECLARE(of_sama5d4_clk_h32mx_setup, "atmel,sama5d4-clk-h32mx", + of_sama5d4_clk_h32mx_setup); diff --git a/drivers/clk/at91/clk-main.c b/drivers/clk/at91/clk-main.c index fd7247deabdc3de9cdf8ab0e4fb67d0c6775ef3e..58b5baca670c3416fe0fc1733088f7526349005c 100644 --- a/drivers/clk/at91/clk-main.c +++ b/drivers/clk/at91/clk-main.c @@ -13,13 +13,8 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include +#include +#include #include "pmc.h" @@ -34,18 +29,14 @@ struct clk_main_osc { struct clk_hw hw; - struct at91_pmc *pmc; - unsigned int irq; - wait_queue_head_t wait; + struct regmap *regmap; }; #define to_clk_main_osc(hw) container_of(hw, struct clk_main_osc, hw) struct clk_main_rc_osc { struct clk_hw hw; - struct at91_pmc *pmc; - unsigned int irq; - wait_queue_head_t wait; + struct regmap *regmap; unsigned long frequency; unsigned long accuracy; }; @@ -54,51 +45,47 @@ struct clk_main_rc_osc { struct clk_rm9200_main { struct clk_hw hw; - struct at91_pmc *pmc; + struct regmap *regmap; }; #define to_clk_rm9200_main(hw) container_of(hw, struct clk_rm9200_main, hw) struct clk_sam9x5_main { struct clk_hw hw; - struct at91_pmc *pmc; - unsigned int irq; - wait_queue_head_t wait; + struct regmap *regmap; u8 parent; }; #define to_clk_sam9x5_main(hw) container_of(hw, struct clk_sam9x5_main, hw) -static irqreturn_t clk_main_osc_irq_handler(int irq, void *dev_id) +static inline bool clk_main_osc_ready(struct regmap *regmap) { - struct clk_main_osc *osc = dev_id; + unsigned int status; - wake_up(&osc->wait); - disable_irq_nosync(osc->irq); + regmap_read(regmap, AT91_PMC_SR, &status); - return IRQ_HANDLED; + return status & AT91_PMC_MOSCS; } static int clk_main_osc_prepare(struct clk_hw *hw) { struct clk_main_osc *osc = to_clk_main_osc(hw); - struct at91_pmc *pmc = osc->pmc; + struct regmap *regmap = osc->regmap; u32 tmp; - tmp = pmc_read(pmc, AT91_CKGR_MOR) & ~MOR_KEY_MASK; + regmap_read(regmap, AT91_CKGR_MOR, &tmp); + tmp &= ~MOR_KEY_MASK; + if (tmp & AT91_PMC_OSCBYPASS) return 0; if (!(tmp & AT91_PMC_MOSCEN)) { tmp |= AT91_PMC_MOSCEN | AT91_PMC_KEY; - pmc_write(pmc, AT91_CKGR_MOR, tmp); + regmap_write(regmap, AT91_CKGR_MOR, tmp); } - while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCS)) { - enable_irq(osc->irq); - wait_event(osc->wait, - pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCS); - } + while (!clk_main_osc_ready(regmap)) + cpu_relax(); return 0; } @@ -106,9 +93,10 @@ static int clk_main_osc_prepare(struct clk_hw *hw) static void clk_main_osc_unprepare(struct clk_hw *hw) { struct clk_main_osc *osc = to_clk_main_osc(hw); - struct at91_pmc *pmc = osc->pmc; - u32 tmp = pmc_read(pmc, AT91_CKGR_MOR); + struct regmap *regmap = osc->regmap; + u32 tmp; + regmap_read(regmap, AT91_CKGR_MOR, &tmp); if (tmp & AT91_PMC_OSCBYPASS) return; @@ -116,20 +104,22 @@ static void clk_main_osc_unprepare(struct clk_hw *hw) return; tmp &= ~(AT91_PMC_KEY | AT91_PMC_MOSCEN); - pmc_write(pmc, AT91_CKGR_MOR, tmp | AT91_PMC_KEY); + regmap_write(regmap, AT91_CKGR_MOR, tmp | AT91_PMC_KEY); } static int clk_main_osc_is_prepared(struct clk_hw *hw) { struct clk_main_osc *osc = to_clk_main_osc(hw); - struct at91_pmc *pmc = osc->pmc; - u32 tmp = pmc_read(pmc, AT91_CKGR_MOR); + struct regmap *regmap = osc->regmap; + u32 tmp, status; + regmap_read(regmap, AT91_CKGR_MOR, &tmp); if (tmp & AT91_PMC_OSCBYPASS) return 1; - return !!((pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCS) && - (pmc_read(pmc, AT91_CKGR_MOR) & AT91_PMC_MOSCEN)); + regmap_read(regmap, AT91_PMC_SR, &status); + + return (status & AT91_PMC_MOSCS) && (tmp & AT91_PMC_MOSCEN); } static const struct clk_ops main_osc_ops = { @@ -139,18 +129,16 @@ static const struct clk_ops main_osc_ops = { }; static struct clk * __init -at91_clk_register_main_osc(struct at91_pmc *pmc, - unsigned int irq, +at91_clk_register_main_osc(struct regmap *regmap, const char *name, const char *parent_name, bool bypass) { - int ret; struct clk_main_osc *osc; struct clk *clk = NULL; struct clk_init_data init; - if (!pmc || !irq || !name || !parent_name) + if (!name || !parent_name) return ERR_PTR(-EINVAL); osc = kzalloc(sizeof(*osc), GFP_KERNEL); @@ -164,85 +152,70 @@ at91_clk_register_main_osc(struct at91_pmc *pmc, init.flags = CLK_IGNORE_UNUSED; osc->hw.init = &init; - osc->pmc = pmc; - osc->irq = irq; - - init_waitqueue_head(&osc->wait); - irq_set_status_flags(osc->irq, IRQ_NOAUTOEN); - ret = request_irq(osc->irq, clk_main_osc_irq_handler, - IRQF_TRIGGER_HIGH, name, osc); - if (ret) { - kfree(osc); - return ERR_PTR(ret); - } + osc->regmap = regmap; if (bypass) - pmc_write(pmc, AT91_CKGR_MOR, - (pmc_read(pmc, AT91_CKGR_MOR) & - ~(MOR_KEY_MASK | AT91_PMC_MOSCEN)) | - AT91_PMC_OSCBYPASS | AT91_PMC_KEY); + regmap_update_bits(regmap, + AT91_CKGR_MOR, MOR_KEY_MASK | + AT91_PMC_MOSCEN, + AT91_PMC_OSCBYPASS | AT91_PMC_KEY); clk = clk_register(NULL, &osc->hw); - if (IS_ERR(clk)) { - free_irq(irq, osc); + if (IS_ERR(clk)) kfree(osc); - } return clk; } -void __init of_at91rm9200_clk_main_osc_setup(struct device_node *np, - struct at91_pmc *pmc) +static void __init of_at91rm9200_clk_main_osc_setup(struct device_node *np) { struct clk *clk; - unsigned int irq; const char *name = np->name; const char *parent_name; + struct regmap *regmap; bool bypass; of_property_read_string(np, "clock-output-names", &name); bypass = of_property_read_bool(np, "atmel,osc-bypass"); parent_name = of_clk_get_parent_name(np, 0); - irq = irq_of_parse_and_map(np, 0); - if (!irq) + regmap = syscon_node_to_regmap(of_get_parent(np)); + if (IS_ERR(regmap)) return; - clk = at91_clk_register_main_osc(pmc, irq, name, parent_name, bypass); + clk = at91_clk_register_main_osc(regmap, name, parent_name, bypass); if (IS_ERR(clk)) return; of_clk_add_provider(np, of_clk_src_simple_get, clk); } +CLK_OF_DECLARE(at91rm9200_clk_main_osc, "atmel,at91rm9200-clk-main-osc", + of_at91rm9200_clk_main_osc_setup); -static irqreturn_t clk_main_rc_osc_irq_handler(int irq, void *dev_id) +static bool clk_main_rc_osc_ready(struct regmap *regmap) { - struct clk_main_rc_osc *osc = dev_id; + unsigned int status; - wake_up(&osc->wait); - disable_irq_nosync(osc->irq); + regmap_read(regmap, AT91_PMC_SR, &status); - return IRQ_HANDLED; + return status & AT91_PMC_MOSCRCS; } static int clk_main_rc_osc_prepare(struct clk_hw *hw) { struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw); - struct at91_pmc *pmc = osc->pmc; - u32 tmp; + struct regmap *regmap = osc->regmap; + unsigned int mor; - tmp = pmc_read(pmc, AT91_CKGR_MOR) & ~MOR_KEY_MASK; + regmap_read(regmap, AT91_CKGR_MOR, &mor); - if (!(tmp & AT91_PMC_MOSCRCEN)) { - tmp |= AT91_PMC_MOSCRCEN | AT91_PMC_KEY; - pmc_write(pmc, AT91_CKGR_MOR, tmp); - } + if (!(mor & AT91_PMC_MOSCRCEN)) + regmap_update_bits(regmap, AT91_CKGR_MOR, + MOR_KEY_MASK | AT91_PMC_MOSCRCEN, + AT91_PMC_MOSCRCEN | AT91_PMC_KEY); - while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCRCS)) { - enable_irq(osc->irq); - wait_event(osc->wait, - pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCRCS); - } + while (!clk_main_rc_osc_ready(regmap)) + cpu_relax(); return 0; } @@ -250,23 +223,28 @@ static int clk_main_rc_osc_prepare(struct clk_hw *hw) static void clk_main_rc_osc_unprepare(struct clk_hw *hw) { struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw); - struct at91_pmc *pmc = osc->pmc; - u32 tmp = pmc_read(pmc, AT91_CKGR_MOR); + struct regmap *regmap = osc->regmap; + unsigned int mor; + + regmap_read(regmap, AT91_CKGR_MOR, &mor); - if (!(tmp & AT91_PMC_MOSCRCEN)) + if (!(mor & AT91_PMC_MOSCRCEN)) return; - tmp &= ~(MOR_KEY_MASK | AT91_PMC_MOSCRCEN); - pmc_write(pmc, AT91_CKGR_MOR, tmp | AT91_PMC_KEY); + regmap_update_bits(regmap, AT91_CKGR_MOR, + MOR_KEY_MASK | AT91_PMC_MOSCRCEN, AT91_PMC_KEY); } static int clk_main_rc_osc_is_prepared(struct clk_hw *hw) { struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw); - struct at91_pmc *pmc = osc->pmc; + struct regmap *regmap = osc->regmap; + unsigned int mor, status; - return !!((pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCRCS) && - (pmc_read(pmc, AT91_CKGR_MOR) & AT91_PMC_MOSCRCEN)); + regmap_read(regmap, AT91_CKGR_MOR, &mor); + regmap_read(regmap, AT91_PMC_SR, &status); + + return (mor & AT91_PMC_MOSCRCEN) && (status & AT91_PMC_MOSCRCS); } static unsigned long clk_main_rc_osc_recalc_rate(struct clk_hw *hw, @@ -294,17 +272,15 @@ static const struct clk_ops main_rc_osc_ops = { }; static struct clk * __init -at91_clk_register_main_rc_osc(struct at91_pmc *pmc, - unsigned int irq, +at91_clk_register_main_rc_osc(struct regmap *regmap, const char *name, u32 frequency, u32 accuracy) { - int ret; struct clk_main_rc_osc *osc; struct clk *clk = NULL; struct clk_init_data init; - if (!pmc || !irq || !name || !frequency) + if (!name || !frequency) return ERR_PTR(-EINVAL); osc = kzalloc(sizeof(*osc), GFP_KERNEL); @@ -315,66 +291,56 @@ at91_clk_register_main_rc_osc(struct at91_pmc *pmc, init.ops = &main_rc_osc_ops; init.parent_names = NULL; init.num_parents = 0; - init.flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED; + init.flags = CLK_IGNORE_UNUSED; osc->hw.init = &init; - osc->pmc = pmc; - osc->irq = irq; + osc->regmap = regmap; osc->frequency = frequency; osc->accuracy = accuracy; - init_waitqueue_head(&osc->wait); - irq_set_status_flags(osc->irq, IRQ_NOAUTOEN); - ret = request_irq(osc->irq, clk_main_rc_osc_irq_handler, - IRQF_TRIGGER_HIGH, name, osc); - if (ret) - return ERR_PTR(ret); - clk = clk_register(NULL, &osc->hw); - if (IS_ERR(clk)) { - free_irq(irq, osc); + if (IS_ERR(clk)) kfree(osc); - } return clk; } -void __init of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np, - struct at91_pmc *pmc) +static void __init of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np) { struct clk *clk; - unsigned int irq; u32 frequency = 0; u32 accuracy = 0; const char *name = np->name; + struct regmap *regmap; of_property_read_string(np, "clock-output-names", &name); of_property_read_u32(np, "clock-frequency", &frequency); of_property_read_u32(np, "clock-accuracy", &accuracy); - irq = irq_of_parse_and_map(np, 0); - if (!irq) + regmap = syscon_node_to_regmap(of_get_parent(np)); + if (IS_ERR(regmap)) return; - clk = at91_clk_register_main_rc_osc(pmc, irq, name, frequency, - accuracy); + clk = at91_clk_register_main_rc_osc(regmap, name, frequency, accuracy); if (IS_ERR(clk)) return; of_clk_add_provider(np, of_clk_src_simple_get, clk); } +CLK_OF_DECLARE(at91sam9x5_clk_main_rc_osc, "atmel,at91sam9x5-clk-main-rc-osc", + of_at91sam9x5_clk_main_rc_osc_setup); -static int clk_main_probe_frequency(struct at91_pmc *pmc) +static int clk_main_probe_frequency(struct regmap *regmap) { unsigned long prep_time, timeout; - u32 tmp; + unsigned int mcfr; timeout = jiffies + usecs_to_jiffies(MAINFRDY_TIMEOUT); do { prep_time = jiffies; - tmp = pmc_read(pmc, AT91_CKGR_MCFR); - if (tmp & AT91_PMC_MAINRDY) + regmap_read(regmap, AT91_CKGR_MCFR, &mcfr); + if (mcfr & AT91_PMC_MAINRDY) return 0; usleep_range(MAINF_LOOP_MIN_WAIT, MAINF_LOOP_MAX_WAIT); } while (time_before(prep_time, timeout)); @@ -382,34 +348,37 @@ static int clk_main_probe_frequency(struct at91_pmc *pmc) return -ETIMEDOUT; } -static unsigned long clk_main_recalc_rate(struct at91_pmc *pmc, +static unsigned long clk_main_recalc_rate(struct regmap *regmap, unsigned long parent_rate) { - u32 tmp; + unsigned int mcfr; if (parent_rate) return parent_rate; pr_warn("Main crystal frequency not set, using approximate value\n"); - tmp = pmc_read(pmc, AT91_CKGR_MCFR); - if (!(tmp & AT91_PMC_MAINRDY)) + regmap_read(regmap, AT91_CKGR_MCFR, &mcfr); + if (!(mcfr & AT91_PMC_MAINRDY)) return 0; - return ((tmp & AT91_PMC_MAINF) * SLOW_CLOCK_FREQ) / MAINF_DIV; + return ((mcfr & AT91_PMC_MAINF) * SLOW_CLOCK_FREQ) / MAINF_DIV; } static int clk_rm9200_main_prepare(struct clk_hw *hw) { struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw); - return clk_main_probe_frequency(clkmain->pmc); + return clk_main_probe_frequency(clkmain->regmap); } static int clk_rm9200_main_is_prepared(struct clk_hw *hw) { struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw); + unsigned int status; + + regmap_read(clkmain->regmap, AT91_CKGR_MCFR, &status); - return !!(pmc_read(clkmain->pmc, AT91_CKGR_MCFR) & AT91_PMC_MAINRDY); + return status & AT91_PMC_MAINRDY ? 1 : 0; } static unsigned long clk_rm9200_main_recalc_rate(struct clk_hw *hw, @@ -417,7 +386,7 @@ static unsigned long clk_rm9200_main_recalc_rate(struct clk_hw *hw, { struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw); - return clk_main_recalc_rate(clkmain->pmc, parent_rate); + return clk_main_recalc_rate(clkmain->regmap, parent_rate); } static const struct clk_ops rm9200_main_ops = { @@ -427,7 +396,7 @@ static const struct clk_ops rm9200_main_ops = { }; static struct clk * __init -at91_clk_register_rm9200_main(struct at91_pmc *pmc, +at91_clk_register_rm9200_main(struct regmap *regmap, const char *name, const char *parent_name) { @@ -435,7 +404,7 @@ at91_clk_register_rm9200_main(struct at91_pmc *pmc, struct clk *clk = NULL; struct clk_init_data init; - if (!pmc || !name) + if (!name) return ERR_PTR(-EINVAL); if (!parent_name) @@ -452,7 +421,7 @@ at91_clk_register_rm9200_main(struct at91_pmc *pmc, init.flags = 0; clkmain->hw.init = &init; - clkmain->pmc = pmc; + clkmain->regmap = regmap; clk = clk_register(NULL, &clkmain->hw); if (IS_ERR(clk)) @@ -461,52 +430,54 @@ at91_clk_register_rm9200_main(struct at91_pmc *pmc, return clk; } -void __init of_at91rm9200_clk_main_setup(struct device_node *np, - struct at91_pmc *pmc) +static void __init of_at91rm9200_clk_main_setup(struct device_node *np) { struct clk *clk; const char *parent_name; const char *name = np->name; + struct regmap *regmap; parent_name = of_clk_get_parent_name(np, 0); of_property_read_string(np, "clock-output-names", &name); - clk = at91_clk_register_rm9200_main(pmc, name, parent_name); + regmap = syscon_node_to_regmap(of_get_parent(np)); + if (IS_ERR(regmap)) + return; + + clk = at91_clk_register_rm9200_main(regmap, name, parent_name); if (IS_ERR(clk)) return; of_clk_add_provider(np, of_clk_src_simple_get, clk); } +CLK_OF_DECLARE(at91rm9200_clk_main, "atmel,at91rm9200-clk-main", + of_at91rm9200_clk_main_setup); -static irqreturn_t clk_sam9x5_main_irq_handler(int irq, void *dev_id) +static inline bool clk_sam9x5_main_ready(struct regmap *regmap) { - struct clk_sam9x5_main *clkmain = dev_id; + unsigned int status; - wake_up(&clkmain->wait); - disable_irq_nosync(clkmain->irq); + regmap_read(regmap, AT91_PMC_SR, &status); - return IRQ_HANDLED; + return status & AT91_PMC_MOSCSELS ? 1 : 0; } static int clk_sam9x5_main_prepare(struct clk_hw *hw) { struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw); - struct at91_pmc *pmc = clkmain->pmc; + struct regmap *regmap = clkmain->regmap; - while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCSELS)) { - enable_irq(clkmain->irq); - wait_event(clkmain->wait, - pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCSELS); - } + while (!clk_sam9x5_main_ready(regmap)) + cpu_relax(); - return clk_main_probe_frequency(pmc); + return clk_main_probe_frequency(regmap); } static int clk_sam9x5_main_is_prepared(struct clk_hw *hw) { struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw); - return !!(pmc_read(clkmain->pmc, AT91_PMC_SR) & AT91_PMC_MOSCSELS); + return clk_sam9x5_main_ready(clkmain->regmap); } static unsigned long clk_sam9x5_main_recalc_rate(struct clk_hw *hw, @@ -514,30 +485,28 @@ static unsigned long clk_sam9x5_main_recalc_rate(struct clk_hw *hw, { struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw); - return clk_main_recalc_rate(clkmain->pmc, parent_rate); + return clk_main_recalc_rate(clkmain->regmap, parent_rate); } static int clk_sam9x5_main_set_parent(struct clk_hw *hw, u8 index) { struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw); - struct at91_pmc *pmc = clkmain->pmc; - u32 tmp; + struct regmap *regmap = clkmain->regmap; + unsigned int tmp; if (index > 1) return -EINVAL; - tmp = pmc_read(pmc, AT91_CKGR_MOR) & ~MOR_KEY_MASK; + regmap_read(regmap, AT91_CKGR_MOR, &tmp); + tmp &= ~MOR_KEY_MASK; if (index && !(tmp & AT91_PMC_MOSCSEL)) - pmc_write(pmc, AT91_CKGR_MOR, tmp | AT91_PMC_MOSCSEL); + regmap_write(regmap, AT91_CKGR_MOR, tmp | AT91_PMC_MOSCSEL); else if (!index && (tmp & AT91_PMC_MOSCSEL)) - pmc_write(pmc, AT91_CKGR_MOR, tmp & ~AT91_PMC_MOSCSEL); + regmap_write(regmap, AT91_CKGR_MOR, tmp & ~AT91_PMC_MOSCSEL); - while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCSELS)) { - enable_irq(clkmain->irq); - wait_event(clkmain->wait, - pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCSELS); - } + while (!clk_sam9x5_main_ready(regmap)) + cpu_relax(); return 0; } @@ -545,8 +514,11 @@ static int clk_sam9x5_main_set_parent(struct clk_hw *hw, u8 index) static u8 clk_sam9x5_main_get_parent(struct clk_hw *hw) { struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw); + unsigned int status; + + regmap_read(clkmain->regmap, AT91_CKGR_MOR, &status); - return !!(pmc_read(clkmain->pmc, AT91_CKGR_MOR) & AT91_PMC_MOSCEN); + return status & AT91_PMC_MOSCEN ? 1 : 0; } static const struct clk_ops sam9x5_main_ops = { @@ -558,18 +530,17 @@ static const struct clk_ops sam9x5_main_ops = { }; static struct clk * __init -at91_clk_register_sam9x5_main(struct at91_pmc *pmc, - unsigned int irq, +at91_clk_register_sam9x5_main(struct regmap *regmap, const char *name, const char **parent_names, int num_parents) { - int ret; struct clk_sam9x5_main *clkmain; struct clk *clk = NULL; struct clk_init_data init; + unsigned int status; - if (!pmc || !irq || !name) + if (!name) return ERR_PTR(-EINVAL); if (!parent_names || !num_parents) @@ -586,51 +557,42 @@ at91_clk_register_sam9x5_main(struct at91_pmc *pmc, init.flags = CLK_SET_PARENT_GATE; clkmain->hw.init = &init; - clkmain->pmc = pmc; - clkmain->irq = irq; - clkmain->parent = !!(pmc_read(clkmain->pmc, AT91_CKGR_MOR) & - AT91_PMC_MOSCEN); - init_waitqueue_head(&clkmain->wait); - irq_set_status_flags(clkmain->irq, IRQ_NOAUTOEN); - ret = request_irq(clkmain->irq, clk_sam9x5_main_irq_handler, - IRQF_TRIGGER_HIGH, name, clkmain); - if (ret) - return ERR_PTR(ret); + clkmain->regmap = regmap; + regmap_read(clkmain->regmap, AT91_CKGR_MOR, &status); + clkmain->parent = status & AT91_PMC_MOSCEN ? 1 : 0; clk = clk_register(NULL, &clkmain->hw); - if (IS_ERR(clk)) { - free_irq(clkmain->irq, clkmain); + if (IS_ERR(clk)) kfree(clkmain); - } return clk; } -void __init of_at91sam9x5_clk_main_setup(struct device_node *np, - struct at91_pmc *pmc) +static void __init of_at91sam9x5_clk_main_setup(struct device_node *np) { struct clk *clk; const char *parent_names[2]; - int num_parents; - unsigned int irq; + unsigned int num_parents; const char *name = np->name; + struct regmap *regmap; num_parents = of_clk_get_parent_count(np); - if (num_parents <= 0 || num_parents > 2) + if (num_parents == 0 || num_parents > 2) return; of_clk_parent_fill(np, parent_names, num_parents); + regmap = syscon_node_to_regmap(of_get_parent(np)); + if (IS_ERR(regmap)) + return; of_property_read_string(np, "clock-output-names", &name); - irq = irq_of_parse_and_map(np, 0); - if (!irq) - return; - - clk = at91_clk_register_sam9x5_main(pmc, irq, name, parent_names, + clk = at91_clk_register_sam9x5_main(regmap, name, parent_names, num_parents); if (IS_ERR(clk)) return; of_clk_add_provider(np, of_clk_src_simple_get, clk); } +CLK_OF_DECLARE(at91sam9x5_clk_main, "atmel,at91sam9x5-clk-main", + of_at91sam9x5_clk_main_setup); diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c index 620ea323356b62145c4f7ef7f1d19511c5832015..d1021e106191d844876ed829f847e72c833c86cf 100644 --- a/drivers/clk/at91/clk-master.c +++ b/drivers/clk/at91/clk-master.c @@ -12,13 +12,8 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include +#include +#include #include "pmc.h" @@ -44,32 +39,26 @@ struct clk_master_layout { struct clk_master { struct clk_hw hw; - struct at91_pmc *pmc; - unsigned int irq; - wait_queue_head_t wait; + struct regmap *regmap; const struct clk_master_layout *layout; const struct clk_master_characteristics *characteristics; }; -static irqreturn_t clk_master_irq_handler(int irq, void *dev_id) +static inline bool clk_master_ready(struct regmap *regmap) { - struct clk_master *master = (struct clk_master *)dev_id; + unsigned int status; - wake_up(&master->wait); - disable_irq_nosync(master->irq); + regmap_read(regmap, AT91_PMC_SR, &status); - return IRQ_HANDLED; + return status & AT91_PMC_MCKRDY ? 1 : 0; } + static int clk_master_prepare(struct clk_hw *hw) { struct clk_master *master = to_clk_master(hw); - struct at91_pmc *pmc = master->pmc; - while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MCKRDY)) { - enable_irq(master->irq); - wait_event(master->wait, - pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MCKRDY); - } + while (!clk_master_ready(master->regmap)) + cpu_relax(); return 0; } @@ -78,7 +67,7 @@ static int clk_master_is_prepared(struct clk_hw *hw) { struct clk_master *master = to_clk_master(hw); - return !!(pmc_read(master->pmc, AT91_PMC_SR) & AT91_PMC_MCKRDY); + return clk_master_ready(master->regmap); } static unsigned long clk_master_recalc_rate(struct clk_hw *hw, @@ -88,18 +77,16 @@ static unsigned long clk_master_recalc_rate(struct clk_hw *hw, u8 div; unsigned long rate = parent_rate; struct clk_master *master = to_clk_master(hw); - struct at91_pmc *pmc = master->pmc; const struct clk_master_layout *layout = master->layout; const struct clk_master_characteristics *characteristics = master->characteristics; - u32 tmp; + unsigned int mckr; - pmc_lock(pmc); - tmp = pmc_read(pmc, AT91_PMC_MCKR) & layout->mask; - pmc_unlock(pmc); + regmap_read(master->regmap, AT91_PMC_MCKR, &mckr); + mckr &= layout->mask; - pres = (tmp >> layout->pres_shift) & MASTER_PRES_MASK; - div = (tmp >> MASTER_DIV_SHIFT) & MASTER_DIV_MASK; + pres = (mckr >> layout->pres_shift) & MASTER_PRES_MASK; + div = (mckr >> MASTER_DIV_SHIFT) & MASTER_DIV_MASK; if (characteristics->have_div3_pres && pres == MASTER_PRES_MAX) rate /= 3; @@ -119,9 +106,11 @@ static unsigned long clk_master_recalc_rate(struct clk_hw *hw, static u8 clk_master_get_parent(struct clk_hw *hw) { struct clk_master *master = to_clk_master(hw); - struct at91_pmc *pmc = master->pmc; + unsigned int mckr; - return pmc_read(pmc, AT91_PMC_MCKR) & AT91_PMC_CSS; + regmap_read(master->regmap, AT91_PMC_MCKR, &mckr); + + return mckr & AT91_PMC_CSS; } static const struct clk_ops master_ops = { @@ -132,18 +121,17 @@ static const struct clk_ops master_ops = { }; static struct clk * __init -at91_clk_register_master(struct at91_pmc *pmc, unsigned int irq, +at91_clk_register_master(struct regmap *regmap, const char *name, int num_parents, const char **parent_names, const struct clk_master_layout *layout, const struct clk_master_characteristics *characteristics) { - int ret; struct clk_master *master; struct clk *clk = NULL; struct clk_init_data init; - if (!pmc || !irq || !name || !num_parents || !parent_names) + if (!name || !num_parents || !parent_names) return ERR_PTR(-EINVAL); master = kzalloc(sizeof(*master), GFP_KERNEL); @@ -159,20 +147,10 @@ at91_clk_register_master(struct at91_pmc *pmc, unsigned int irq, master->hw.init = &init; master->layout = layout; master->characteristics = characteristics; - master->pmc = pmc; - master->irq = irq; - init_waitqueue_head(&master->wait); - irq_set_status_flags(master->irq, IRQ_NOAUTOEN); - ret = request_irq(master->irq, clk_master_irq_handler, - IRQF_TRIGGER_HIGH, "clk-master", master); - if (ret) { - kfree(master); - return ERR_PTR(ret); - } + master->regmap = regmap; clk = clk_register(NULL, &master->hw); if (IS_ERR(clk)) { - free_irq(master->irq, master); kfree(master); } @@ -217,18 +195,18 @@ of_at91_clk_master_get_characteristics(struct device_node *np) } static void __init -of_at91_clk_master_setup(struct device_node *np, struct at91_pmc *pmc, +of_at91_clk_master_setup(struct device_node *np, const struct clk_master_layout *layout) { struct clk *clk; - int num_parents; - unsigned int irq; + unsigned int num_parents; const char *parent_names[MASTER_SOURCE_MAX]; const char *name = np->name; struct clk_master_characteristics *characteristics; + struct regmap *regmap; num_parents = of_clk_get_parent_count(np); - if (num_parents <= 0 || num_parents > MASTER_SOURCE_MAX) + if (num_parents == 0 || num_parents > MASTER_SOURCE_MAX) return; of_clk_parent_fill(np, parent_names, num_parents); @@ -239,11 +217,11 @@ of_at91_clk_master_setup(struct device_node *np, struct at91_pmc *pmc, if (!characteristics) return; - irq = irq_of_parse_and_map(np, 0); - if (!irq) - goto out_free_characteristics; + regmap = syscon_node_to_regmap(of_get_parent(np)); + if (IS_ERR(regmap)) + return; - clk = at91_clk_register_master(pmc, irq, name, num_parents, + clk = at91_clk_register_master(regmap, name, num_parents, parent_names, layout, characteristics); if (IS_ERR(clk)) @@ -256,14 +234,16 @@ of_at91_clk_master_setup(struct device_node *np, struct at91_pmc *pmc, kfree(characteristics); } -void __init of_at91rm9200_clk_master_setup(struct device_node *np, - struct at91_pmc *pmc) +static void __init of_at91rm9200_clk_master_setup(struct device_node *np) { - of_at91_clk_master_setup(np, pmc, &at91rm9200_master_layout); + of_at91_clk_master_setup(np, &at91rm9200_master_layout); } +CLK_OF_DECLARE(at91rm9200_clk_master, "atmel,at91rm9200-clk-master", + of_at91rm9200_clk_master_setup); -void __init of_at91sam9x5_clk_master_setup(struct device_node *np, - struct at91_pmc *pmc) +static void __init of_at91sam9x5_clk_master_setup(struct device_node *np) { - of_at91_clk_master_setup(np, pmc, &at91sam9x5_master_layout); + of_at91_clk_master_setup(np, &at91sam9x5_master_layout); } +CLK_OF_DECLARE(at91sam9x5_clk_master, "atmel,at91sam9x5-clk-master", + of_at91sam9x5_clk_master_setup); diff --git a/drivers/clk/at91/clk-peripheral.c b/drivers/clk/at91/clk-peripheral.c index 58f3b568e9cb9024beaf0831c9ac3e0237a93d03..fd160728e99022a06f8083198fe7a997a2375af2 100644 --- a/drivers/clk/at91/clk-peripheral.c +++ b/drivers/clk/at91/clk-peripheral.c @@ -12,11 +12,13 @@ #include #include #include -#include -#include +#include +#include #include "pmc.h" +DEFINE_SPINLOCK(pmc_pcr_lock); + #define PERIPHERAL_MAX 64 #define PERIPHERAL_AT91RM9200 0 @@ -33,7 +35,7 @@ struct clk_peripheral { struct clk_hw hw; - struct at91_pmc *pmc; + struct regmap *regmap; u32 id; }; @@ -41,8 +43,9 @@ struct clk_peripheral { struct clk_sam9x5_peripheral { struct clk_hw hw; - struct at91_pmc *pmc; + struct regmap *regmap; struct clk_range range; + spinlock_t *lock; u32 id; u32 div; bool auto_div; @@ -54,7 +57,6 @@ struct clk_sam9x5_peripheral { static int clk_peripheral_enable(struct clk_hw *hw) { struct clk_peripheral *periph = to_clk_peripheral(hw); - struct at91_pmc *pmc = periph->pmc; int offset = AT91_PMC_PCER; u32 id = periph->id; @@ -62,14 +64,14 @@ static int clk_peripheral_enable(struct clk_hw *hw) return 0; if (id > PERIPHERAL_ID_MAX) offset = AT91_PMC_PCER1; - pmc_write(pmc, offset, PERIPHERAL_MASK(id)); + regmap_write(periph->regmap, offset, PERIPHERAL_MASK(id)); + return 0; } static void clk_peripheral_disable(struct clk_hw *hw) { struct clk_peripheral *periph = to_clk_peripheral(hw); - struct at91_pmc *pmc = periph->pmc; int offset = AT91_PMC_PCDR; u32 id = periph->id; @@ -77,21 +79,23 @@ static void clk_peripheral_disable(struct clk_hw *hw) return; if (id > PERIPHERAL_ID_MAX) offset = AT91_PMC_PCDR1; - pmc_write(pmc, offset, PERIPHERAL_MASK(id)); + regmap_write(periph->regmap, offset, PERIPHERAL_MASK(id)); } static int clk_peripheral_is_enabled(struct clk_hw *hw) { struct clk_peripheral *periph = to_clk_peripheral(hw); - struct at91_pmc *pmc = periph->pmc; int offset = AT91_PMC_PCSR; + unsigned int status; u32 id = periph->id; if (id < PERIPHERAL_ID_MIN) return 1; if (id > PERIPHERAL_ID_MAX) offset = AT91_PMC_PCSR1; - return !!(pmc_read(pmc, offset) & PERIPHERAL_MASK(id)); + regmap_read(periph->regmap, offset, &status); + + return status & PERIPHERAL_MASK(id) ? 1 : 0; } static const struct clk_ops peripheral_ops = { @@ -101,14 +105,14 @@ static const struct clk_ops peripheral_ops = { }; static struct clk * __init -at91_clk_register_peripheral(struct at91_pmc *pmc, const char *name, +at91_clk_register_peripheral(struct regmap *regmap, const char *name, const char *parent_name, u32 id) { struct clk_peripheral *periph; struct clk *clk = NULL; struct clk_init_data init; - if (!pmc || !name || !parent_name || id > PERIPHERAL_ID_MAX) + if (!name || !parent_name || id > PERIPHERAL_ID_MAX) return ERR_PTR(-EINVAL); periph = kzalloc(sizeof(*periph), GFP_KERNEL); @@ -123,7 +127,7 @@ at91_clk_register_peripheral(struct at91_pmc *pmc, const char *name, periph->id = id; periph->hw.init = &init; - periph->pmc = pmc; + periph->regmap = regmap; clk = clk_register(NULL, &periph->hw); if (IS_ERR(clk)) @@ -160,53 +164,58 @@ static void clk_sam9x5_peripheral_autodiv(struct clk_sam9x5_peripheral *periph) static int clk_sam9x5_peripheral_enable(struct clk_hw *hw) { struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); - struct at91_pmc *pmc = periph->pmc; - u32 tmp; + unsigned long flags; if (periph->id < PERIPHERAL_ID_MIN) return 0; - pmc_lock(pmc); - pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK)); - tmp = pmc_read(pmc, AT91_PMC_PCR) & ~AT91_PMC_PCR_DIV_MASK; - pmc_write(pmc, AT91_PMC_PCR, tmp | AT91_PMC_PCR_DIV(periph->div) - | AT91_PMC_PCR_CMD - | AT91_PMC_PCR_EN); - pmc_unlock(pmc); + spin_lock_irqsave(periph->lock, flags); + regmap_write(periph->regmap, AT91_PMC_PCR, + (periph->id & AT91_PMC_PCR_PID_MASK)); + regmap_update_bits(periph->regmap, AT91_PMC_PCR, + AT91_PMC_PCR_DIV_MASK | AT91_PMC_PCR_CMD | + AT91_PMC_PCR_EN, + AT91_PMC_PCR_DIV(periph->div) | + AT91_PMC_PCR_CMD | + AT91_PMC_PCR_EN); + spin_unlock_irqrestore(periph->lock, flags); + return 0; } static void clk_sam9x5_peripheral_disable(struct clk_hw *hw) { struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); - struct at91_pmc *pmc = periph->pmc; - u32 tmp; + unsigned long flags; if (periph->id < PERIPHERAL_ID_MIN) return; - pmc_lock(pmc); - pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK)); - tmp = pmc_read(pmc, AT91_PMC_PCR) & ~AT91_PMC_PCR_EN; - pmc_write(pmc, AT91_PMC_PCR, tmp | AT91_PMC_PCR_CMD); - pmc_unlock(pmc); + spin_lock_irqsave(periph->lock, flags); + regmap_write(periph->regmap, AT91_PMC_PCR, + (periph->id & AT91_PMC_PCR_PID_MASK)); + regmap_update_bits(periph->regmap, AT91_PMC_PCR, + AT91_PMC_PCR_EN | AT91_PMC_PCR_CMD, + AT91_PMC_PCR_CMD); + spin_unlock_irqrestore(periph->lock, flags); } static int clk_sam9x5_peripheral_is_enabled(struct clk_hw *hw) { struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); - struct at91_pmc *pmc = periph->pmc; - int ret; + unsigned long flags; + unsigned int status; if (periph->id < PERIPHERAL_ID_MIN) return 1; - pmc_lock(pmc); - pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK)); - ret = !!(pmc_read(pmc, AT91_PMC_PCR) & AT91_PMC_PCR_EN); - pmc_unlock(pmc); + spin_lock_irqsave(periph->lock, flags); + regmap_write(periph->regmap, AT91_PMC_PCR, + (periph->id & AT91_PMC_PCR_PID_MASK)); + regmap_read(periph->regmap, AT91_PMC_PCR, &status); + spin_unlock_irqrestore(periph->lock, flags); - return ret; + return status & AT91_PMC_PCR_EN ? 1 : 0; } static unsigned long @@ -214,19 +223,20 @@ clk_sam9x5_peripheral_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); - struct at91_pmc *pmc = periph->pmc; - u32 tmp; + unsigned long flags; + unsigned int status; if (periph->id < PERIPHERAL_ID_MIN) return parent_rate; - pmc_lock(pmc); - pmc_write(pmc, AT91_PMC_PCR, (periph->id & AT91_PMC_PCR_PID_MASK)); - tmp = pmc_read(pmc, AT91_PMC_PCR); - pmc_unlock(pmc); + spin_lock_irqsave(periph->lock, flags); + regmap_write(periph->regmap, AT91_PMC_PCR, + (periph->id & AT91_PMC_PCR_PID_MASK)); + regmap_read(periph->regmap, AT91_PMC_PCR, &status); + spin_unlock_irqrestore(periph->lock, flags); - if (tmp & AT91_PMC_PCR_EN) { - periph->div = PERIPHERAL_RSHIFT(tmp); + if (status & AT91_PMC_PCR_EN) { + periph->div = PERIPHERAL_RSHIFT(status); periph->auto_div = false; } else { clk_sam9x5_peripheral_autodiv(periph); @@ -318,15 +328,15 @@ static const struct clk_ops sam9x5_peripheral_ops = { }; static struct clk * __init -at91_clk_register_sam9x5_peripheral(struct at91_pmc *pmc, const char *name, - const char *parent_name, u32 id, - const struct clk_range *range) +at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock, + const char *name, const char *parent_name, + u32 id, const struct clk_range *range) { struct clk_sam9x5_peripheral *periph; struct clk *clk = NULL; struct clk_init_data init; - if (!pmc || !name || !parent_name) + if (!name || !parent_name) return ERR_PTR(-EINVAL); periph = kzalloc(sizeof(*periph), GFP_KERNEL); @@ -342,7 +352,8 @@ at91_clk_register_sam9x5_peripheral(struct at91_pmc *pmc, const char *name, periph->id = id; periph->hw.init = &init; periph->div = 0; - periph->pmc = pmc; + periph->regmap = regmap; + periph->lock = lock; periph->auto_div = true; periph->range = *range; @@ -356,7 +367,7 @@ at91_clk_register_sam9x5_peripheral(struct at91_pmc *pmc, const char *name, } static void __init -of_at91_clk_periph_setup(struct device_node *np, struct at91_pmc *pmc, u8 type) +of_at91_clk_periph_setup(struct device_node *np, u8 type) { int num; u32 id; @@ -364,6 +375,7 @@ of_at91_clk_periph_setup(struct device_node *np, struct at91_pmc *pmc, u8 type) const char *parent_name; const char *name; struct device_node *periphclknp; + struct regmap *regmap; parent_name = of_clk_get_parent_name(np, 0); if (!parent_name) @@ -373,6 +385,10 @@ of_at91_clk_periph_setup(struct device_node *np, struct at91_pmc *pmc, u8 type) if (!num || num > PERIPHERAL_MAX) return; + regmap = syscon_node_to_regmap(of_get_parent(np)); + if (IS_ERR(regmap)) + return; + for_each_child_of_node(np, periphclknp) { if (of_property_read_u32(periphclknp, "reg", &id)) continue; @@ -384,7 +400,7 @@ of_at91_clk_periph_setup(struct device_node *np, struct at91_pmc *pmc, u8 type) name = periphclknp->name; if (type == PERIPHERAL_AT91RM9200) { - clk = at91_clk_register_peripheral(pmc, name, + clk = at91_clk_register_peripheral(regmap, name, parent_name, id); } else { struct clk_range range = CLK_RANGE(0, 0); @@ -393,7 +409,9 @@ of_at91_clk_periph_setup(struct device_node *np, struct at91_pmc *pmc, u8 type) "atmel,clk-output-range", &range); - clk = at91_clk_register_sam9x5_peripheral(pmc, name, + clk = at91_clk_register_sam9x5_peripheral(regmap, + &pmc_pcr_lock, + name, parent_name, id, &range); } @@ -405,14 +423,17 @@ of_at91_clk_periph_setup(struct device_node *np, struct at91_pmc *pmc, u8 type) } } -void __init of_at91rm9200_clk_periph_setup(struct device_node *np, - struct at91_pmc *pmc) +static void __init of_at91rm9200_clk_periph_setup(struct device_node *np) { - of_at91_clk_periph_setup(np, pmc, PERIPHERAL_AT91RM9200); + of_at91_clk_periph_setup(np, PERIPHERAL_AT91RM9200); } +CLK_OF_DECLARE(at91rm9200_clk_periph, "atmel,at91rm9200-clk-peripheral", + of_at91rm9200_clk_periph_setup); -void __init of_at91sam9x5_clk_periph_setup(struct device_node *np, - struct at91_pmc *pmc) +static void __init of_at91sam9x5_clk_periph_setup(struct device_node *np) { - of_at91_clk_periph_setup(np, pmc, PERIPHERAL_AT91SAM9X5); + of_at91_clk_periph_setup(np, PERIPHERAL_AT91SAM9X5); } +CLK_OF_DECLARE(at91sam9x5_clk_periph, "atmel,at91sam9x5-clk-peripheral", + of_at91sam9x5_clk_periph_setup); + diff --git a/drivers/clk/at91/clk-pll.c b/drivers/clk/at91/clk-pll.c index 18b60f4895a68477a74ebe99a8b64542bd7057c9..fb2e0b56d4b7fd5e51600df574ec52c0dedcc709 100644 --- a/drivers/clk/at91/clk-pll.c +++ b/drivers/clk/at91/clk-pll.c @@ -12,14 +12,8 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include #include "pmc.h" @@ -58,9 +52,7 @@ struct clk_pll_layout { struct clk_pll { struct clk_hw hw; - struct at91_pmc *pmc; - unsigned int irq; - wait_queue_head_t wait; + struct regmap *regmap; u8 id; u8 div; u8 range; @@ -69,20 +61,19 @@ struct clk_pll { const struct clk_pll_characteristics *characteristics; }; -static irqreturn_t clk_pll_irq_handler(int irq, void *dev_id) +static inline bool clk_pll_ready(struct regmap *regmap, int id) { - struct clk_pll *pll = (struct clk_pll *)dev_id; + unsigned int status; - wake_up(&pll->wait); - disable_irq_nosync(pll->irq); + regmap_read(regmap, AT91_PMC_SR, &status); - return IRQ_HANDLED; + return status & PLL_STATUS_MASK(id) ? 1 : 0; } static int clk_pll_prepare(struct clk_hw *hw) { struct clk_pll *pll = to_clk_pll(hw); - struct at91_pmc *pmc = pll->pmc; + struct regmap *regmap = pll->regmap; const struct clk_pll_layout *layout = pll->layout; const struct clk_pll_characteristics *characteristics = pll->characteristics; @@ -90,39 +81,34 @@ static int clk_pll_prepare(struct clk_hw *hw) u32 mask = PLL_STATUS_MASK(id); int offset = PLL_REG(id); u8 out = 0; - u32 pllr, icpr; + unsigned int pllr; + unsigned int status; u8 div; u16 mul; - pllr = pmc_read(pmc, offset); + regmap_read(regmap, offset, &pllr); div = PLL_DIV(pllr); mul = PLL_MUL(pllr, layout); - if ((pmc_read(pmc, AT91_PMC_SR) & mask) && + regmap_read(regmap, AT91_PMC_SR, &status); + if ((status & mask) && (div == pll->div && mul == pll->mul)) return 0; if (characteristics->out) out = characteristics->out[pll->range]; - if (characteristics->icpll) { - icpr = pmc_read(pmc, AT91_PMC_PLLICPR) & ~PLL_ICPR_MASK(id); - icpr |= (characteristics->icpll[pll->range] << - PLL_ICPR_SHIFT(id)); - pmc_write(pmc, AT91_PMC_PLLICPR, icpr); - } - pllr &= ~layout->pllr_mask; - pllr |= layout->pllr_mask & - (pll->div | (PLL_MAX_COUNT << PLL_COUNT_SHIFT) | - (out << PLL_OUT_SHIFT) | - ((pll->mul & layout->mul_mask) << layout->mul_shift)); - pmc_write(pmc, offset, pllr); - - while (!(pmc_read(pmc, AT91_PMC_SR) & mask)) { - enable_irq(pll->irq); - wait_event(pll->wait, - pmc_read(pmc, AT91_PMC_SR) & mask); - } + if (characteristics->icpll) + regmap_update_bits(regmap, AT91_PMC_PLLICPR, PLL_ICPR_MASK(id), + characteristics->icpll[pll->range] << PLL_ICPR_SHIFT(id)); + + regmap_update_bits(regmap, offset, layout->pllr_mask, + pll->div | (PLL_MAX_COUNT << PLL_COUNT_SHIFT) | + (out << PLL_OUT_SHIFT) | + ((pll->mul & layout->mul_mask) << layout->mul_shift)); + + while (!clk_pll_ready(regmap, pll->id)) + cpu_relax(); return 0; } @@ -130,32 +116,35 @@ static int clk_pll_prepare(struct clk_hw *hw) static int clk_pll_is_prepared(struct clk_hw *hw) { struct clk_pll *pll = to_clk_pll(hw); - struct at91_pmc *pmc = pll->pmc; - return !!(pmc_read(pmc, AT91_PMC_SR) & - PLL_STATUS_MASK(pll->id)); + return clk_pll_ready(pll->regmap, pll->id); } static void clk_pll_unprepare(struct clk_hw *hw) { struct clk_pll *pll = to_clk_pll(hw); - struct at91_pmc *pmc = pll->pmc; - const struct clk_pll_layout *layout = pll->layout; - int offset = PLL_REG(pll->id); - u32 tmp = pmc_read(pmc, offset) & ~(layout->pllr_mask); + unsigned int mask = pll->layout->pllr_mask; - pmc_write(pmc, offset, tmp); + regmap_update_bits(pll->regmap, PLL_REG(pll->id), mask, ~mask); } static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct clk_pll *pll = to_clk_pll(hw); + unsigned int pllr; + u16 mul; + u8 div; - if (!pll->div || !pll->mul) + regmap_read(pll->regmap, PLL_REG(pll->id), &pllr); + + div = PLL_DIV(pllr); + mul = PLL_MUL(pllr, pll->layout); + + if (!div || !mul) return 0; - return (parent_rate / pll->div) * (pll->mul + 1); + return (parent_rate / div) * (mul + 1); } static long clk_pll_get_best_div_mul(struct clk_pll *pll, unsigned long rate, @@ -308,7 +297,7 @@ static const struct clk_ops pll_ops = { }; static struct clk * __init -at91_clk_register_pll(struct at91_pmc *pmc, unsigned int irq, const char *name, +at91_clk_register_pll(struct regmap *regmap, const char *name, const char *parent_name, u8 id, const struct clk_pll_layout *layout, const struct clk_pll_characteristics *characteristics) @@ -316,9 +305,8 @@ at91_clk_register_pll(struct at91_pmc *pmc, unsigned int irq, const char *name, struct clk_pll *pll; struct clk *clk = NULL; struct clk_init_data init; - int ret; int offset = PLL_REG(id); - u32 tmp; + unsigned int pllr; if (id > PLL_MAX_ID) return ERR_PTR(-EINVAL); @@ -337,23 +325,13 @@ at91_clk_register_pll(struct at91_pmc *pmc, unsigned int irq, const char *name, pll->hw.init = &init; pll->layout = layout; pll->characteristics = characteristics; - pll->pmc = pmc; - pll->irq = irq; - tmp = pmc_read(pmc, offset) & layout->pllr_mask; - pll->div = PLL_DIV(tmp); - pll->mul = PLL_MUL(tmp, layout); - init_waitqueue_head(&pll->wait); - irq_set_status_flags(pll->irq, IRQ_NOAUTOEN); - ret = request_irq(pll->irq, clk_pll_irq_handler, IRQF_TRIGGER_HIGH, - id ? "clk-pllb" : "clk-plla", pll); - if (ret) { - kfree(pll); - return ERR_PTR(ret); - } + pll->regmap = regmap; + regmap_read(regmap, offset, &pllr); + pll->div = PLL_DIV(pllr); + pll->mul = PLL_MUL(pllr, layout); clk = clk_register(NULL, &pll->hw); if (IS_ERR(clk)) { - free_irq(pll->irq, pll); kfree(pll); } @@ -483,12 +461,12 @@ of_at91_clk_pll_get_characteristics(struct device_node *np) } static void __init -of_at91_clk_pll_setup(struct device_node *np, struct at91_pmc *pmc, +of_at91_clk_pll_setup(struct device_node *np, const struct clk_pll_layout *layout) { u32 id; - unsigned int irq; struct clk *clk; + struct regmap *regmap; const char *parent_name; const char *name = np->name; struct clk_pll_characteristics *characteristics; @@ -500,15 +478,15 @@ of_at91_clk_pll_setup(struct device_node *np, struct at91_pmc *pmc, of_property_read_string(np, "clock-output-names", &name); - characteristics = of_at91_clk_pll_get_characteristics(np); - if (!characteristics) + regmap = syscon_node_to_regmap(of_get_parent(np)); + if (IS_ERR(regmap)) return; - irq = irq_of_parse_and_map(np, 0); - if (!irq) + characteristics = of_at91_clk_pll_get_characteristics(np); + if (!characteristics) return; - clk = at91_clk_register_pll(pmc, irq, name, parent_name, id, layout, + clk = at91_clk_register_pll(regmap, name, parent_name, id, layout, characteristics); if (IS_ERR(clk)) goto out_free_characteristics; @@ -520,26 +498,30 @@ of_at91_clk_pll_setup(struct device_node *np, struct at91_pmc *pmc, kfree(characteristics); } -void __init of_at91rm9200_clk_pll_setup(struct device_node *np, - struct at91_pmc *pmc) +static void __init of_at91rm9200_clk_pll_setup(struct device_node *np) { - of_at91_clk_pll_setup(np, pmc, &at91rm9200_pll_layout); + of_at91_clk_pll_setup(np, &at91rm9200_pll_layout); } +CLK_OF_DECLARE(at91rm9200_clk_pll, "atmel,at91rm9200-clk-pll", + of_at91rm9200_clk_pll_setup); -void __init of_at91sam9g45_clk_pll_setup(struct device_node *np, - struct at91_pmc *pmc) +static void __init of_at91sam9g45_clk_pll_setup(struct device_node *np) { - of_at91_clk_pll_setup(np, pmc, &at91sam9g45_pll_layout); + of_at91_clk_pll_setup(np, &at91sam9g45_pll_layout); } +CLK_OF_DECLARE(at91sam9g45_clk_pll, "atmel,at91sam9g45-clk-pll", + of_at91sam9g45_clk_pll_setup); -void __init of_at91sam9g20_clk_pllb_setup(struct device_node *np, - struct at91_pmc *pmc) +static void __init of_at91sam9g20_clk_pllb_setup(struct device_node *np) { - of_at91_clk_pll_setup(np, pmc, &at91sam9g20_pllb_layout); + of_at91_clk_pll_setup(np, &at91sam9g20_pllb_layout); } +CLK_OF_DECLARE(at91sam9g20_clk_pllb, "atmel,at91sam9g20-clk-pllb", + of_at91sam9g20_clk_pllb_setup); -void __init of_sama5d3_clk_pll_setup(struct device_node *np, - struct at91_pmc *pmc) +static void __init of_sama5d3_clk_pll_setup(struct device_node *np) { - of_at91_clk_pll_setup(np, pmc, &sama5d3_pll_layout); + of_at91_clk_pll_setup(np, &sama5d3_pll_layout); } +CLK_OF_DECLARE(sama5d3_clk_pll, "atmel,sama5d3-clk-pll", + of_sama5d3_clk_pll_setup); diff --git a/drivers/clk/at91/clk-plldiv.c b/drivers/clk/at91/clk-plldiv.c index ea226562bb40be4f4d1d311a00df124cd9ea777a..2bed26481027f859aee2da14d43aa9d8333a9459 100644 --- a/drivers/clk/at91/clk-plldiv.c +++ b/drivers/clk/at91/clk-plldiv.c @@ -12,8 +12,8 @@ #include #include #include -#include -#include +#include +#include #include "pmc.h" @@ -21,16 +21,18 @@ struct clk_plldiv { struct clk_hw hw; - struct at91_pmc *pmc; + struct regmap *regmap; }; static unsigned long clk_plldiv_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct clk_plldiv *plldiv = to_clk_plldiv(hw); - struct at91_pmc *pmc = plldiv->pmc; + unsigned int mckr; - if (pmc_read(pmc, AT91_PMC_MCKR) & AT91_PMC_PLLADIV2) + regmap_read(plldiv->regmap, AT91_PMC_MCKR, &mckr); + + if (mckr & AT91_PMC_PLLADIV2) return parent_rate / 2; return parent_rate; @@ -57,18 +59,12 @@ static int clk_plldiv_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { struct clk_plldiv *plldiv = to_clk_plldiv(hw); - struct at91_pmc *pmc = plldiv->pmc; - u32 tmp; - if (parent_rate != rate && (parent_rate / 2) != rate) + if ((parent_rate != rate) && (parent_rate / 2 != rate)) return -EINVAL; - pmc_lock(pmc); - tmp = pmc_read(pmc, AT91_PMC_MCKR) & ~AT91_PMC_PLLADIV2; - if ((parent_rate / 2) == rate) - tmp |= AT91_PMC_PLLADIV2; - pmc_write(pmc, AT91_PMC_MCKR, tmp); - pmc_unlock(pmc); + regmap_update_bits(plldiv->regmap, AT91_PMC_MCKR, AT91_PMC_PLLADIV2, + parent_rate != rate ? AT91_PMC_PLLADIV2 : 0); return 0; } @@ -80,7 +76,7 @@ static const struct clk_ops plldiv_ops = { }; static struct clk * __init -at91_clk_register_plldiv(struct at91_pmc *pmc, const char *name, +at91_clk_register_plldiv(struct regmap *regmap, const char *name, const char *parent_name) { struct clk_plldiv *plldiv; @@ -98,7 +94,7 @@ at91_clk_register_plldiv(struct at91_pmc *pmc, const char *name, init.flags = CLK_SET_RATE_GATE; plldiv->hw.init = &init; - plldiv->pmc = pmc; + plldiv->regmap = regmap; clk = clk_register(NULL, &plldiv->hw); @@ -109,27 +105,27 @@ at91_clk_register_plldiv(struct at91_pmc *pmc, const char *name, } static void __init -of_at91_clk_plldiv_setup(struct device_node *np, struct at91_pmc *pmc) +of_at91sam9x5_clk_plldiv_setup(struct device_node *np) { struct clk *clk; const char *parent_name; const char *name = np->name; + struct regmap *regmap; parent_name = of_clk_get_parent_name(np, 0); of_property_read_string(np, "clock-output-names", &name); - clk = at91_clk_register_plldiv(pmc, name, parent_name); + regmap = syscon_node_to_regmap(of_get_parent(np)); + if (IS_ERR(regmap)) + return; + clk = at91_clk_register_plldiv(regmap, name, parent_name); if (IS_ERR(clk)) return; of_clk_add_provider(np, of_clk_src_simple_get, clk); return; } - -void __init of_at91sam9x5_clk_plldiv_setup(struct device_node *np, - struct at91_pmc *pmc) -{ - of_at91_clk_plldiv_setup(np, pmc); -} +CLK_OF_DECLARE(at91sam9x5_clk_plldiv, "atmel,at91sam9x5-clk-plldiv", + of_at91sam9x5_clk_plldiv_setup); diff --git a/drivers/clk/at91/clk-programmable.c b/drivers/clk/at91/clk-programmable.c index 14b270b85fec277a6fdea1ad0df260eeee95f27b..10f846cc8db172c5491ddc2508f7084ac5ef5e71 100644 --- a/drivers/clk/at91/clk-programmable.c +++ b/drivers/clk/at91/clk-programmable.c @@ -12,10 +12,8 @@ #include #include #include -#include -#include -#include -#include +#include +#include #include "pmc.h" @@ -24,6 +22,7 @@ #define PROG_STATUS_MASK(id) (1 << ((id) + 8)) #define PROG_PRES_MASK 0x7 +#define PROG_PRES(layout, pckr) ((pckr >> layout->pres_shift) & PROG_PRES_MASK) #define PROG_MAX_RM9200_CSS 3 struct clk_programmable_layout { @@ -34,7 +33,7 @@ struct clk_programmable_layout { struct clk_programmable { struct clk_hw hw; - struct at91_pmc *pmc; + struct regmap *regmap; u8 id; const struct clk_programmable_layout *layout; }; @@ -44,14 +43,12 @@ struct clk_programmable { static unsigned long clk_programmable_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { - u32 pres; struct clk_programmable *prog = to_clk_programmable(hw); - struct at91_pmc *pmc = prog->pmc; - const struct clk_programmable_layout *layout = prog->layout; + unsigned int pckr; + + regmap_read(prog->regmap, AT91_PMC_PCKR(prog->id), &pckr); - pres = (pmc_read(pmc, AT91_PMC_PCKR(prog->id)) >> layout->pres_shift) & - PROG_PRES_MASK; - return parent_rate >> pres; + return parent_rate >> PROG_PRES(prog->layout, pckr); } static int clk_programmable_determine_rate(struct clk_hw *hw, @@ -101,36 +98,36 @@ static int clk_programmable_set_parent(struct clk_hw *hw, u8 index) { struct clk_programmable *prog = to_clk_programmable(hw); const struct clk_programmable_layout *layout = prog->layout; - struct at91_pmc *pmc = prog->pmc; - u32 tmp = pmc_read(pmc, AT91_PMC_PCKR(prog->id)) & ~layout->css_mask; + unsigned int mask = layout->css_mask; + unsigned int pckr = 0; if (layout->have_slck_mck) - tmp &= AT91_PMC_CSSMCK_MCK; + mask |= AT91_PMC_CSSMCK_MCK; if (index > layout->css_mask) { - if (index > PROG_MAX_RM9200_CSS && layout->have_slck_mck) { - tmp |= AT91_PMC_CSSMCK_MCK; - return 0; - } else { + if (index > PROG_MAX_RM9200_CSS && !layout->have_slck_mck) return -EINVAL; - } + + pckr |= AT91_PMC_CSSMCK_MCK; } - pmc_write(pmc, AT91_PMC_PCKR(prog->id), tmp | index); + regmap_update_bits(prog->regmap, AT91_PMC_PCKR(prog->id), mask, pckr); + return 0; } static u8 clk_programmable_get_parent(struct clk_hw *hw) { - u32 tmp; - u8 ret; struct clk_programmable *prog = to_clk_programmable(hw); - struct at91_pmc *pmc = prog->pmc; const struct clk_programmable_layout *layout = prog->layout; + unsigned int pckr; + u8 ret; + + regmap_read(prog->regmap, AT91_PMC_PCKR(prog->id), &pckr); + + ret = pckr & layout->css_mask; - tmp = pmc_read(pmc, AT91_PMC_PCKR(prog->id)); - ret = tmp & layout->css_mask; - if (layout->have_slck_mck && (tmp & AT91_PMC_CSSMCK_MCK) && !ret) + if (layout->have_slck_mck && (pckr & AT91_PMC_CSSMCK_MCK) && !ret) ret = PROG_MAX_RM9200_CSS + 1; return ret; @@ -140,26 +137,27 @@ static int clk_programmable_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { struct clk_programmable *prog = to_clk_programmable(hw); - struct at91_pmc *pmc = prog->pmc; const struct clk_programmable_layout *layout = prog->layout; unsigned long div = parent_rate / rate; + unsigned int pckr; int shift = 0; - u32 tmp = pmc_read(pmc, AT91_PMC_PCKR(prog->id)) & - ~(PROG_PRES_MASK << layout->pres_shift); + + regmap_read(prog->regmap, AT91_PMC_PCKR(prog->id), &pckr); if (!div) return -EINVAL; shift = fls(div) - 1; - if (div != (1<= PROG_PRES_MASK) return -EINVAL; - pmc_write(pmc, AT91_PMC_PCKR(prog->id), - tmp | (shift << layout->pres_shift)); + regmap_update_bits(prog->regmap, AT91_PMC_PCKR(prog->id), + PROG_PRES_MASK << layout->pres_shift, + shift << layout->pres_shift); return 0; } @@ -173,7 +171,7 @@ static const struct clk_ops programmable_ops = { }; static struct clk * __init -at91_clk_register_programmable(struct at91_pmc *pmc, +at91_clk_register_programmable(struct regmap *regmap, const char *name, const char **parent_names, u8 num_parents, u8 id, const struct clk_programmable_layout *layout) @@ -198,7 +196,7 @@ at91_clk_register_programmable(struct at91_pmc *pmc, prog->id = id; prog->layout = layout; prog->hw.init = &init; - prog->pmc = pmc; + prog->regmap = regmap; clk = clk_register(NULL, &prog->hw); if (IS_ERR(clk)) @@ -226,19 +224,20 @@ static const struct clk_programmable_layout at91sam9x5_programmable_layout = { }; static void __init -of_at91_clk_prog_setup(struct device_node *np, struct at91_pmc *pmc, +of_at91_clk_prog_setup(struct device_node *np, const struct clk_programmable_layout *layout) { int num; u32 id; struct clk *clk; - int num_parents; + unsigned int num_parents; const char *parent_names[PROG_SOURCE_MAX]; const char *name; struct device_node *progclknp; + struct regmap *regmap; num_parents = of_clk_get_parent_count(np); - if (num_parents <= 0 || num_parents > PROG_SOURCE_MAX) + if (num_parents == 0 || num_parents > PROG_SOURCE_MAX) return; of_clk_parent_fill(np, parent_names, num_parents); @@ -247,6 +246,10 @@ of_at91_clk_prog_setup(struct device_node *np, struct at91_pmc *pmc, if (!num || num > (PROG_ID_MAX + 1)) return; + regmap = syscon_node_to_regmap(of_get_parent(np)); + if (IS_ERR(regmap)) + return; + for_each_child_of_node(np, progclknp) { if (of_property_read_u32(progclknp, "reg", &id)) continue; @@ -254,7 +257,7 @@ of_at91_clk_prog_setup(struct device_node *np, struct at91_pmc *pmc, if (of_property_read_string(np, "clock-output-names", &name)) name = progclknp->name; - clk = at91_clk_register_programmable(pmc, name, + clk = at91_clk_register_programmable(regmap, name, parent_names, num_parents, id, layout); if (IS_ERR(clk)) @@ -265,20 +268,23 @@ of_at91_clk_prog_setup(struct device_node *np, struct at91_pmc *pmc, } -void __init of_at91rm9200_clk_prog_setup(struct device_node *np, - struct at91_pmc *pmc) +static void __init of_at91rm9200_clk_prog_setup(struct device_node *np) { - of_at91_clk_prog_setup(np, pmc, &at91rm9200_programmable_layout); + of_at91_clk_prog_setup(np, &at91rm9200_programmable_layout); } +CLK_OF_DECLARE(at91rm9200_clk_prog, "atmel,at91rm9200-clk-programmable", + of_at91rm9200_clk_prog_setup); -void __init of_at91sam9g45_clk_prog_setup(struct device_node *np, - struct at91_pmc *pmc) +static void __init of_at91sam9g45_clk_prog_setup(struct device_node *np) { - of_at91_clk_prog_setup(np, pmc, &at91sam9g45_programmable_layout); + of_at91_clk_prog_setup(np, &at91sam9g45_programmable_layout); } +CLK_OF_DECLARE(at91sam9g45_clk_prog, "atmel,at91sam9g45-clk-programmable", + of_at91sam9g45_clk_prog_setup); -void __init of_at91sam9x5_clk_prog_setup(struct device_node *np, - struct at91_pmc *pmc) +static void __init of_at91sam9x5_clk_prog_setup(struct device_node *np) { - of_at91_clk_prog_setup(np, pmc, &at91sam9x5_programmable_layout); + of_at91_clk_prog_setup(np, &at91sam9x5_programmable_layout); } +CLK_OF_DECLARE(at91sam9x5_clk_prog, "atmel,at91sam9x5-clk-programmable", + of_at91sam9x5_clk_prog_setup); diff --git a/drivers/clk/at91/clk-slow.c b/drivers/clk/at91/clk-slow.c index 6f99a530ead6002d916ef67a42620ced1836d1fa..61090b1146cfd93e1255eb40a4d690502f08c6f5 100644 --- a/drivers/clk/at91/clk-slow.c +++ b/drivers/clk/at91/clk-slow.c @@ -12,17 +12,11 @@ #include #include -#include #include #include #include -#include -#include -#include -#include -#include -#include -#include +#include +#include #include "pmc.h" #include "sckc.h" @@ -58,7 +52,7 @@ struct clk_slow_rc_osc { struct clk_sam9260_slow { struct clk_hw hw; - struct at91_pmc *pmc; + struct regmap *regmap; }; #define to_clk_sam9260_slow(hw) container_of(hw, struct clk_sam9260_slow, hw) @@ -251,7 +245,7 @@ at91_clk_register_slow_rc_osc(void __iomem *sckcr, init.ops = &slow_rc_osc_ops; init.parent_names = NULL; init.num_parents = 0; - init.flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED; + init.flags = CLK_IGNORE_UNUSED; osc->hw.init = &init; osc->sckcr = sckcr; @@ -366,11 +360,11 @@ void __init of_at91sam9x5_clk_slow_setup(struct device_node *np, { struct clk *clk; const char *parent_names[2]; - int num_parents; + unsigned int num_parents; const char *name = np->name; num_parents = of_clk_get_parent_count(np); - if (num_parents <= 0 || num_parents > 2) + if (num_parents == 0 || num_parents > 2) return; of_clk_parent_fill(np, parent_names, num_parents); @@ -388,8 +382,11 @@ void __init of_at91sam9x5_clk_slow_setup(struct device_node *np, static u8 clk_sam9260_slow_get_parent(struct clk_hw *hw) { struct clk_sam9260_slow *slowck = to_clk_sam9260_slow(hw); + unsigned int status; + + regmap_read(slowck->regmap, AT91_PMC_SR, &status); - return !!(pmc_read(slowck->pmc, AT91_PMC_SR) & AT91_PMC_OSCSEL); + return status & AT91_PMC_OSCSEL ? 1 : 0; } static const struct clk_ops sam9260_slow_ops = { @@ -397,7 +394,7 @@ static const struct clk_ops sam9260_slow_ops = { }; static struct clk * __init -at91_clk_register_sam9260_slow(struct at91_pmc *pmc, +at91_clk_register_sam9260_slow(struct regmap *regmap, const char *name, const char **parent_names, int num_parents) @@ -406,7 +403,7 @@ at91_clk_register_sam9260_slow(struct at91_pmc *pmc, struct clk *clk = NULL; struct clk_init_data init; - if (!pmc || !name) + if (!name) return ERR_PTR(-EINVAL); if (!parent_names || !num_parents) @@ -423,7 +420,7 @@ at91_clk_register_sam9260_slow(struct at91_pmc *pmc, init.flags = 0; slowck->hw.init = &init; - slowck->pmc = pmc; + slowck->regmap = regmap; clk = clk_register(NULL, &slowck->hw); if (IS_ERR(clk)) @@ -432,26 +429,32 @@ at91_clk_register_sam9260_slow(struct at91_pmc *pmc, return clk; } -void __init of_at91sam9260_clk_slow_setup(struct device_node *np, - struct at91_pmc *pmc) +static void __init of_at91sam9260_clk_slow_setup(struct device_node *np) { struct clk *clk; const char *parent_names[2]; - int num_parents; + unsigned int num_parents; const char *name = np->name; + struct regmap *regmap; num_parents = of_clk_get_parent_count(np); if (num_parents != 2) return; of_clk_parent_fill(np, parent_names, num_parents); + regmap = syscon_node_to_regmap(of_get_parent(np)); + if (IS_ERR(regmap)) + return; of_property_read_string(np, "clock-output-names", &name); - clk = at91_clk_register_sam9260_slow(pmc, name, parent_names, + clk = at91_clk_register_sam9260_slow(regmap, name, parent_names, num_parents); if (IS_ERR(clk)) return; of_clk_add_provider(np, of_clk_src_simple_get, clk); } + +CLK_OF_DECLARE(at91sam9260_clk_slow, "atmel,at91sam9260-clk-slow", + of_at91sam9260_clk_slow_setup); diff --git a/drivers/clk/at91/clk-smd.c b/drivers/clk/at91/clk-smd.c index a7f8501cfa056222a103c1e0f05a442521f68eae..3c04b069d5b8f78975ee6af0b6a40d2fe3367e1a 100644 --- a/drivers/clk/at91/clk-smd.c +++ b/drivers/clk/at91/clk-smd.c @@ -12,8 +12,8 @@ #include #include #include -#include -#include +#include +#include #include "pmc.h" @@ -24,7 +24,7 @@ struct at91sam9x5_clk_smd { struct clk_hw hw; - struct at91_pmc *pmc; + struct regmap *regmap; }; #define to_at91sam9x5_clk_smd(hw) \ @@ -33,13 +33,13 @@ struct at91sam9x5_clk_smd { static unsigned long at91sam9x5_clk_smd_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { - u32 tmp; - u8 smddiv; struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw); - struct at91_pmc *pmc = smd->pmc; + unsigned int smdr; + u8 smddiv; + + regmap_read(smd->regmap, AT91_PMC_SMD, &smdr); + smddiv = (smdr & AT91_PMC_SMD_DIV) >> SMD_DIV_SHIFT; - tmp = pmc_read(pmc, AT91_PMC_SMD); - smddiv = (tmp & AT91_PMC_SMD_DIV) >> SMD_DIV_SHIFT; return parent_rate / (smddiv + 1); } @@ -67,40 +67,38 @@ static long at91sam9x5_clk_smd_round_rate(struct clk_hw *hw, unsigned long rate, static int at91sam9x5_clk_smd_set_parent(struct clk_hw *hw, u8 index) { - u32 tmp; struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw); - struct at91_pmc *pmc = smd->pmc; if (index > 1) return -EINVAL; - tmp = pmc_read(pmc, AT91_PMC_SMD) & ~AT91_PMC_SMDS; - if (index) - tmp |= AT91_PMC_SMDS; - pmc_write(pmc, AT91_PMC_SMD, tmp); + + regmap_update_bits(smd->regmap, AT91_PMC_SMD, AT91_PMC_SMDS, + index ? AT91_PMC_SMDS : 0); + return 0; } static u8 at91sam9x5_clk_smd_get_parent(struct clk_hw *hw) { struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw); - struct at91_pmc *pmc = smd->pmc; + unsigned int smdr; - return pmc_read(pmc, AT91_PMC_SMD) & AT91_PMC_SMDS; + regmap_read(smd->regmap, AT91_PMC_SMD, &smdr); + + return smdr & AT91_PMC_SMDS; } static int at91sam9x5_clk_smd_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { - u32 tmp; struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw); - struct at91_pmc *pmc = smd->pmc; unsigned long div = parent_rate / rate; if (parent_rate % rate || div < 1 || div > (SMD_MAX_DIV + 1)) return -EINVAL; - tmp = pmc_read(pmc, AT91_PMC_SMD) & ~AT91_PMC_SMD_DIV; - tmp |= (div - 1) << SMD_DIV_SHIFT; - pmc_write(pmc, AT91_PMC_SMD, tmp); + + regmap_update_bits(smd->regmap, AT91_PMC_SMD, AT91_PMC_SMD_DIV, + (div - 1) << SMD_DIV_SHIFT); return 0; } @@ -114,7 +112,7 @@ static const struct clk_ops at91sam9x5_smd_ops = { }; static struct clk * __init -at91sam9x5_clk_register_smd(struct at91_pmc *pmc, const char *name, +at91sam9x5_clk_register_smd(struct regmap *regmap, const char *name, const char **parent_names, u8 num_parents) { struct at91sam9x5_clk_smd *smd; @@ -132,7 +130,7 @@ at91sam9x5_clk_register_smd(struct at91_pmc *pmc, const char *name, init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE; smd->hw.init = &init; - smd->pmc = pmc; + smd->regmap = regmap; clk = clk_register(NULL, &smd->hw); if (IS_ERR(clk)) @@ -141,26 +139,32 @@ at91sam9x5_clk_register_smd(struct at91_pmc *pmc, const char *name, return clk; } -void __init of_at91sam9x5_clk_smd_setup(struct device_node *np, - struct at91_pmc *pmc) +static void __init of_at91sam9x5_clk_smd_setup(struct device_node *np) { struct clk *clk; - int num_parents; + unsigned int num_parents; const char *parent_names[SMD_SOURCE_MAX]; const char *name = np->name; + struct regmap *regmap; num_parents = of_clk_get_parent_count(np); - if (num_parents <= 0 || num_parents > SMD_SOURCE_MAX) + if (num_parents == 0 || num_parents > SMD_SOURCE_MAX) return; of_clk_parent_fill(np, parent_names, num_parents); of_property_read_string(np, "clock-output-names", &name); - clk = at91sam9x5_clk_register_smd(pmc, name, parent_names, + regmap = syscon_node_to_regmap(of_get_parent(np)); + if (IS_ERR(regmap)) + return; + + clk = at91sam9x5_clk_register_smd(regmap, name, parent_names, num_parents); if (IS_ERR(clk)) return; of_clk_add_provider(np, of_clk_src_simple_get, clk); } +CLK_OF_DECLARE(at91sam9x5_clk_smd, "atmel,at91sam9x5-clk-smd", + of_at91sam9x5_clk_smd_setup); diff --git a/drivers/clk/at91/clk-system.c b/drivers/clk/at91/clk-system.c index 3f5314344286e3335ec77f9c02360cb75c19cb93..8f35d8172909aa5d6765bb0e4f45439fbdce19e7 100644 --- a/drivers/clk/at91/clk-system.c +++ b/drivers/clk/at91/clk-system.c @@ -12,13 +12,8 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include +#include +#include #include "pmc.h" @@ -29,9 +24,7 @@ #define to_clk_system(hw) container_of(hw, struct clk_system, hw) struct clk_system { struct clk_hw hw; - struct at91_pmc *pmc; - unsigned int irq; - wait_queue_head_t wait; + struct regmap *regmap; u8 id; }; @@ -39,58 +32,54 @@ static inline int is_pck(int id) { return (id >= 8) && (id <= 15); } -static irqreturn_t clk_system_irq_handler(int irq, void *dev_id) + +static inline bool clk_system_ready(struct regmap *regmap, int id) { - struct clk_system *sys = (struct clk_system *)dev_id; + unsigned int status; - wake_up(&sys->wait); - disable_irq_nosync(sys->irq); + regmap_read(regmap, AT91_PMC_SR, &status); - return IRQ_HANDLED; + return status & (1 << id) ? 1 : 0; } static int clk_system_prepare(struct clk_hw *hw) { struct clk_system *sys = to_clk_system(hw); - struct at91_pmc *pmc = sys->pmc; - u32 mask = 1 << sys->id; - pmc_write(pmc, AT91_PMC_SCER, mask); + regmap_write(sys->regmap, AT91_PMC_SCER, 1 << sys->id); if (!is_pck(sys->id)) return 0; - while (!(pmc_read(pmc, AT91_PMC_SR) & mask)) { - if (sys->irq) { - enable_irq(sys->irq); - wait_event(sys->wait, - pmc_read(pmc, AT91_PMC_SR) & mask); - } else - cpu_relax(); - } + while (!clk_system_ready(sys->regmap, sys->id)) + cpu_relax(); + return 0; } static void clk_system_unprepare(struct clk_hw *hw) { struct clk_system *sys = to_clk_system(hw); - struct at91_pmc *pmc = sys->pmc; - pmc_write(pmc, AT91_PMC_SCDR, 1 << sys->id); + regmap_write(sys->regmap, AT91_PMC_SCDR, 1 << sys->id); } static int clk_system_is_prepared(struct clk_hw *hw) { struct clk_system *sys = to_clk_system(hw); - struct at91_pmc *pmc = sys->pmc; + unsigned int status; + + regmap_read(sys->regmap, AT91_PMC_SCSR, &status); - if (!(pmc_read(pmc, AT91_PMC_SCSR) & (1 << sys->id))) + if (!(status & (1 << sys->id))) return 0; if (!is_pck(sys->id)) return 1; - return !!(pmc_read(pmc, AT91_PMC_SR) & (1 << sys->id)); + regmap_read(sys->regmap, AT91_PMC_SR, &status); + + return status & (1 << sys->id) ? 1 : 0; } static const struct clk_ops system_ops = { @@ -100,13 +89,12 @@ static const struct clk_ops system_ops = { }; static struct clk * __init -at91_clk_register_system(struct at91_pmc *pmc, const char *name, - const char *parent_name, u8 id, int irq) +at91_clk_register_system(struct regmap *regmap, const char *name, + const char *parent_name, u8 id) { struct clk_system *sys; struct clk *clk = NULL; struct clk_init_data init; - int ret; if (!parent_name || id > SYSTEM_MAX_ID) return ERR_PTR(-EINVAL); @@ -123,44 +111,33 @@ at91_clk_register_system(struct at91_pmc *pmc, const char *name, sys->id = id; sys->hw.init = &init; - sys->pmc = pmc; - sys->irq = irq; - if (irq) { - init_waitqueue_head(&sys->wait); - irq_set_status_flags(sys->irq, IRQ_NOAUTOEN); - ret = request_irq(sys->irq, clk_system_irq_handler, - IRQF_TRIGGER_HIGH, name, sys); - if (ret) { - kfree(sys); - return ERR_PTR(ret); - } - } + sys->regmap = regmap; clk = clk_register(NULL, &sys->hw); - if (IS_ERR(clk)) { - if (irq) - free_irq(sys->irq, sys); + if (IS_ERR(clk)) kfree(sys); - } return clk; } -static void __init -of_at91_clk_sys_setup(struct device_node *np, struct at91_pmc *pmc) +static void __init of_at91rm9200_clk_sys_setup(struct device_node *np) { int num; - int irq = 0; u32 id; struct clk *clk; const char *name; struct device_node *sysclknp; const char *parent_name; + struct regmap *regmap; num = of_get_child_count(np); if (num > (SYSTEM_MAX_ID + 1)) return; + regmap = syscon_node_to_regmap(of_get_parent(np)); + if (IS_ERR(regmap)) + return; + for_each_child_of_node(np, sysclknp) { if (of_property_read_u32(sysclknp, "reg", &id)) continue; @@ -168,21 +145,14 @@ of_at91_clk_sys_setup(struct device_node *np, struct at91_pmc *pmc) if (of_property_read_string(np, "clock-output-names", &name)) name = sysclknp->name; - if (is_pck(id)) - irq = irq_of_parse_and_map(sysclknp, 0); - parent_name = of_clk_get_parent_name(sysclknp, 0); - clk = at91_clk_register_system(pmc, name, parent_name, id, irq); + clk = at91_clk_register_system(regmap, name, parent_name, id); if (IS_ERR(clk)) continue; of_clk_add_provider(sysclknp, of_clk_src_simple_get, clk); } } - -void __init of_at91rm9200_clk_sys_setup(struct device_node *np, - struct at91_pmc *pmc) -{ - of_at91_clk_sys_setup(np, pmc); -} +CLK_OF_DECLARE(at91rm9200_clk_sys, "atmel,at91rm9200-clk-system", + of_at91rm9200_clk_sys_setup); diff --git a/drivers/clk/at91/clk-usb.c b/drivers/clk/at91/clk-usb.c index 8ab8502778a282bac38b56ce9ecb7cd92c8962e2..d80bdb0a8b029750379107c5995c187c1b949747 100644 --- a/drivers/clk/at91/clk-usb.c +++ b/drivers/clk/at91/clk-usb.c @@ -12,8 +12,8 @@ #include #include #include -#include -#include +#include +#include #include "pmc.h" @@ -27,7 +27,7 @@ struct at91sam9x5_clk_usb { struct clk_hw hw; - struct at91_pmc *pmc; + struct regmap *regmap; }; #define to_at91sam9x5_clk_usb(hw) \ @@ -35,7 +35,7 @@ struct at91sam9x5_clk_usb { struct at91rm9200_clk_usb { struct clk_hw hw; - struct at91_pmc *pmc; + struct regmap *regmap; u32 divisors[4]; }; @@ -45,13 +45,12 @@ struct at91rm9200_clk_usb { static unsigned long at91sam9x5_clk_usb_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { - u32 tmp; - u8 usbdiv; struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); - struct at91_pmc *pmc = usb->pmc; + unsigned int usbr; + u8 usbdiv; - tmp = pmc_read(pmc, AT91_PMC_USB); - usbdiv = (tmp & AT91_PMC_OHCIUSBDIV) >> SAM9X5_USB_DIV_SHIFT; + regmap_read(usb->regmap, AT91_PMC_USB, &usbr); + usbdiv = (usbr & AT91_PMC_OHCIUSBDIV) >> SAM9X5_USB_DIV_SHIFT; return DIV_ROUND_CLOSEST(parent_rate, (usbdiv + 1)); } @@ -109,33 +108,31 @@ static int at91sam9x5_clk_usb_determine_rate(struct clk_hw *hw, static int at91sam9x5_clk_usb_set_parent(struct clk_hw *hw, u8 index) { - u32 tmp; struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); - struct at91_pmc *pmc = usb->pmc; if (index > 1) return -EINVAL; - tmp = pmc_read(pmc, AT91_PMC_USB) & ~AT91_PMC_USBS; - if (index) - tmp |= AT91_PMC_USBS; - pmc_write(pmc, AT91_PMC_USB, tmp); + + regmap_update_bits(usb->regmap, AT91_PMC_USB, AT91_PMC_USBS, + index ? AT91_PMC_USBS : 0); + return 0; } static u8 at91sam9x5_clk_usb_get_parent(struct clk_hw *hw) { struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); - struct at91_pmc *pmc = usb->pmc; + unsigned int usbr; - return pmc_read(pmc, AT91_PMC_USB) & AT91_PMC_USBS; + regmap_read(usb->regmap, AT91_PMC_USB, &usbr); + + return usbr & AT91_PMC_USBS; } static int at91sam9x5_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { - u32 tmp; struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); - struct at91_pmc *pmc = usb->pmc; unsigned long div; if (!rate) @@ -145,9 +142,8 @@ static int at91sam9x5_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate, if (div > SAM9X5_USB_MAX_DIV + 1 || !div) return -EINVAL; - tmp = pmc_read(pmc, AT91_PMC_USB) & ~AT91_PMC_OHCIUSBDIV; - tmp |= (div - 1) << SAM9X5_USB_DIV_SHIFT; - pmc_write(pmc, AT91_PMC_USB, tmp); + regmap_update_bits(usb->regmap, AT91_PMC_USB, AT91_PMC_OHCIUSBDIV, + (div - 1) << SAM9X5_USB_DIV_SHIFT); return 0; } @@ -163,28 +159,28 @@ static const struct clk_ops at91sam9x5_usb_ops = { static int at91sam9n12_clk_usb_enable(struct clk_hw *hw) { struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); - struct at91_pmc *pmc = usb->pmc; - pmc_write(pmc, AT91_PMC_USB, - pmc_read(pmc, AT91_PMC_USB) | AT91_PMC_USBS); + regmap_update_bits(usb->regmap, AT91_PMC_USB, AT91_PMC_USBS, + AT91_PMC_USBS); + return 0; } static void at91sam9n12_clk_usb_disable(struct clk_hw *hw) { struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); - struct at91_pmc *pmc = usb->pmc; - pmc_write(pmc, AT91_PMC_USB, - pmc_read(pmc, AT91_PMC_USB) & ~AT91_PMC_USBS); + regmap_update_bits(usb->regmap, AT91_PMC_USB, AT91_PMC_USBS, 0); } static int at91sam9n12_clk_usb_is_enabled(struct clk_hw *hw) { struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); - struct at91_pmc *pmc = usb->pmc; + unsigned int usbr; - return !!(pmc_read(pmc, AT91_PMC_USB) & AT91_PMC_USBS); + regmap_read(usb->regmap, AT91_PMC_USB, &usbr); + + return usbr & AT91_PMC_USBS; } static const struct clk_ops at91sam9n12_usb_ops = { @@ -197,7 +193,7 @@ static const struct clk_ops at91sam9n12_usb_ops = { }; static struct clk * __init -at91sam9x5_clk_register_usb(struct at91_pmc *pmc, const char *name, +at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name, const char **parent_names, u8 num_parents) { struct at91sam9x5_clk_usb *usb; @@ -216,7 +212,7 @@ at91sam9x5_clk_register_usb(struct at91_pmc *pmc, const char *name, CLK_SET_RATE_PARENT; usb->hw.init = &init; - usb->pmc = pmc; + usb->regmap = regmap; clk = clk_register(NULL, &usb->hw); if (IS_ERR(clk)) @@ -226,7 +222,7 @@ at91sam9x5_clk_register_usb(struct at91_pmc *pmc, const char *name, } static struct clk * __init -at91sam9n12_clk_register_usb(struct at91_pmc *pmc, const char *name, +at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name, const char *parent_name) { struct at91sam9x5_clk_usb *usb; @@ -244,7 +240,7 @@ at91sam9n12_clk_register_usb(struct at91_pmc *pmc, const char *name, init.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT; usb->hw.init = &init; - usb->pmc = pmc; + usb->regmap = regmap; clk = clk_register(NULL, &usb->hw); if (IS_ERR(clk)) @@ -257,12 +253,12 @@ static unsigned long at91rm9200_clk_usb_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw); - struct at91_pmc *pmc = usb->pmc; - u32 tmp; + unsigned int pllbr; u8 usbdiv; - tmp = pmc_read(pmc, AT91_CKGR_PLLBR); - usbdiv = (tmp & AT91_PMC_USBDIV) >> RM9200_USB_DIV_SHIFT; + regmap_read(usb->regmap, AT91_CKGR_PLLBR, &pllbr); + + usbdiv = (pllbr & AT91_PMC_USBDIV) >> RM9200_USB_DIV_SHIFT; if (usb->divisors[usbdiv]) return parent_rate / usb->divisors[usbdiv]; @@ -310,10 +306,8 @@ static long at91rm9200_clk_usb_round_rate(struct clk_hw *hw, unsigned long rate, static int at91rm9200_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { - u32 tmp; int i; struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw); - struct at91_pmc *pmc = usb->pmc; unsigned long div; if (!rate) @@ -323,10 +317,10 @@ static int at91rm9200_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate, for (i = 0; i < RM9200_USB_DIV_TAB_SIZE; i++) { if (usb->divisors[i] == div) { - tmp = pmc_read(pmc, AT91_CKGR_PLLBR) & - ~AT91_PMC_USBDIV; - tmp |= i << RM9200_USB_DIV_SHIFT; - pmc_write(pmc, AT91_CKGR_PLLBR, tmp); + regmap_update_bits(usb->regmap, AT91_CKGR_PLLBR, + AT91_PMC_USBDIV, + i << RM9200_USB_DIV_SHIFT); + return 0; } } @@ -341,7 +335,7 @@ static const struct clk_ops at91rm9200_usb_ops = { }; static struct clk * __init -at91rm9200_clk_register_usb(struct at91_pmc *pmc, const char *name, +at91rm9200_clk_register_usb(struct regmap *regmap, const char *name, const char *parent_name, const u32 *divisors) { struct at91rm9200_clk_usb *usb; @@ -359,7 +353,7 @@ at91rm9200_clk_register_usb(struct at91_pmc *pmc, const char *name, init.flags = CLK_SET_RATE_PARENT; usb->hw.init = &init; - usb->pmc = pmc; + usb->regmap = regmap; memcpy(usb->divisors, divisors, sizeof(usb->divisors)); clk = clk_register(NULL, &usb->hw); @@ -369,35 +363,42 @@ at91rm9200_clk_register_usb(struct at91_pmc *pmc, const char *name, return clk; } -void __init of_at91sam9x5_clk_usb_setup(struct device_node *np, - struct at91_pmc *pmc) +static void __init of_at91sam9x5_clk_usb_setup(struct device_node *np) { struct clk *clk; - int num_parents; + unsigned int num_parents; const char *parent_names[USB_SOURCE_MAX]; const char *name = np->name; + struct regmap *regmap; num_parents = of_clk_get_parent_count(np); - if (num_parents <= 0 || num_parents > USB_SOURCE_MAX) + if (num_parents == 0 || num_parents > USB_SOURCE_MAX) return; of_clk_parent_fill(np, parent_names, num_parents); of_property_read_string(np, "clock-output-names", &name); - clk = at91sam9x5_clk_register_usb(pmc, name, parent_names, num_parents); + regmap = syscon_node_to_regmap(of_get_parent(np)); + if (IS_ERR(regmap)) + return; + + clk = at91sam9x5_clk_register_usb(regmap, name, parent_names, + num_parents); if (IS_ERR(clk)) return; of_clk_add_provider(np, of_clk_src_simple_get, clk); } +CLK_OF_DECLARE(at91sam9x5_clk_usb, "atmel,at91sam9x5-clk-usb", + of_at91sam9x5_clk_usb_setup); -void __init of_at91sam9n12_clk_usb_setup(struct device_node *np, - struct at91_pmc *pmc) +static void __init of_at91sam9n12_clk_usb_setup(struct device_node *np) { struct clk *clk; const char *parent_name; const char *name = np->name; + struct regmap *regmap; parent_name = of_clk_get_parent_name(np, 0); if (!parent_name) @@ -405,20 +406,26 @@ void __init of_at91sam9n12_clk_usb_setup(struct device_node *np, of_property_read_string(np, "clock-output-names", &name); - clk = at91sam9n12_clk_register_usb(pmc, name, parent_name); + regmap = syscon_node_to_regmap(of_get_parent(np)); + if (IS_ERR(regmap)) + return; + + clk = at91sam9n12_clk_register_usb(regmap, name, parent_name); if (IS_ERR(clk)) return; of_clk_add_provider(np, of_clk_src_simple_get, clk); } +CLK_OF_DECLARE(at91sam9n12_clk_usb, "atmel,at91sam9n12-clk-usb", + of_at91sam9n12_clk_usb_setup); -void __init of_at91rm9200_clk_usb_setup(struct device_node *np, - struct at91_pmc *pmc) +static void __init of_at91rm9200_clk_usb_setup(struct device_node *np) { struct clk *clk; const char *parent_name; const char *name = np->name; u32 divisors[4] = {0, 0, 0, 0}; + struct regmap *regmap; parent_name = of_clk_get_parent_name(np, 0); if (!parent_name) @@ -430,9 +437,15 @@ void __init of_at91rm9200_clk_usb_setup(struct device_node *np, of_property_read_string(np, "clock-output-names", &name); - clk = at91rm9200_clk_register_usb(pmc, name, parent_name, divisors); + regmap = syscon_node_to_regmap(of_get_parent(np)); + if (IS_ERR(regmap)) + return; + + clk = at91rm9200_clk_register_usb(regmap, name, parent_name, divisors); if (IS_ERR(clk)) return; of_clk_add_provider(np, of_clk_src_simple_get, clk); } +CLK_OF_DECLARE(at91rm9200_clk_usb, "atmel,at91rm9200-clk-usb", + of_at91rm9200_clk_usb_setup); diff --git a/drivers/clk/at91/clk-utmi.c b/drivers/clk/at91/clk-utmi.c index ca561e90a60f48884d801bc1b81c61612a4954df..61fcf399e58ce33c8f77cb5780583964f162f6f4 100644 --- a/drivers/clk/at91/clk-utmi.c +++ b/drivers/clk/at91/clk-utmi.c @@ -11,14 +11,9 @@ #include #include #include -#include -#include #include -#include -#include -#include -#include -#include +#include +#include #include "pmc.h" @@ -26,37 +21,30 @@ struct clk_utmi { struct clk_hw hw; - struct at91_pmc *pmc; - unsigned int irq; - wait_queue_head_t wait; + struct regmap *regmap; }; #define to_clk_utmi(hw) container_of(hw, struct clk_utmi, hw) -static irqreturn_t clk_utmi_irq_handler(int irq, void *dev_id) +static inline bool clk_utmi_ready(struct regmap *regmap) { - struct clk_utmi *utmi = (struct clk_utmi *)dev_id; + unsigned int status; - wake_up(&utmi->wait); - disable_irq_nosync(utmi->irq); + regmap_read(regmap, AT91_PMC_SR, &status); - return IRQ_HANDLED; + return status & AT91_PMC_LOCKU; } static int clk_utmi_prepare(struct clk_hw *hw) { struct clk_utmi *utmi = to_clk_utmi(hw); - struct at91_pmc *pmc = utmi->pmc; - u32 tmp = pmc_read(pmc, AT91_CKGR_UCKR) | AT91_PMC_UPLLEN | - AT91_PMC_UPLLCOUNT | AT91_PMC_BIASEN; + unsigned int uckr = AT91_PMC_UPLLEN | AT91_PMC_UPLLCOUNT | + AT91_PMC_BIASEN; - pmc_write(pmc, AT91_CKGR_UCKR, tmp); + regmap_update_bits(utmi->regmap, AT91_CKGR_UCKR, uckr, uckr); - while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_LOCKU)) { - enable_irq(utmi->irq); - wait_event(utmi->wait, - pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_LOCKU); - } + while (!clk_utmi_ready(utmi->regmap)) + cpu_relax(); return 0; } @@ -64,18 +52,15 @@ static int clk_utmi_prepare(struct clk_hw *hw) static int clk_utmi_is_prepared(struct clk_hw *hw) { struct clk_utmi *utmi = to_clk_utmi(hw); - struct at91_pmc *pmc = utmi->pmc; - return !!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_LOCKU); + return clk_utmi_ready(utmi->regmap); } static void clk_utmi_unprepare(struct clk_hw *hw) { struct clk_utmi *utmi = to_clk_utmi(hw); - struct at91_pmc *pmc = utmi->pmc; - u32 tmp = pmc_read(pmc, AT91_CKGR_UCKR) & ~AT91_PMC_UPLLEN; - pmc_write(pmc, AT91_CKGR_UCKR, tmp); + regmap_update_bits(utmi->regmap, AT91_CKGR_UCKR, AT91_PMC_UPLLEN, 0); } static unsigned long clk_utmi_recalc_rate(struct clk_hw *hw, @@ -93,10 +78,9 @@ static const struct clk_ops utmi_ops = { }; static struct clk * __init -at91_clk_register_utmi(struct at91_pmc *pmc, unsigned int irq, +at91_clk_register_utmi(struct regmap *regmap, const char *name, const char *parent_name) { - int ret; struct clk_utmi *utmi; struct clk *clk = NULL; struct clk_init_data init; @@ -112,52 +96,36 @@ at91_clk_register_utmi(struct at91_pmc *pmc, unsigned int irq, init.flags = CLK_SET_RATE_GATE; utmi->hw.init = &init; - utmi->pmc = pmc; - utmi->irq = irq; - init_waitqueue_head(&utmi->wait); - irq_set_status_flags(utmi->irq, IRQ_NOAUTOEN); - ret = request_irq(utmi->irq, clk_utmi_irq_handler, - IRQF_TRIGGER_HIGH, "clk-utmi", utmi); - if (ret) { - kfree(utmi); - return ERR_PTR(ret); - } + utmi->regmap = regmap; clk = clk_register(NULL, &utmi->hw); - if (IS_ERR(clk)) { - free_irq(utmi->irq, utmi); + if (IS_ERR(clk)) kfree(utmi); - } return clk; } -static void __init -of_at91_clk_utmi_setup(struct device_node *np, struct at91_pmc *pmc) +static void __init of_at91sam9x5_clk_utmi_setup(struct device_node *np) { - unsigned int irq; struct clk *clk; const char *parent_name; const char *name = np->name; + struct regmap *regmap; parent_name = of_clk_get_parent_name(np, 0); of_property_read_string(np, "clock-output-names", &name); - irq = irq_of_parse_and_map(np, 0); - if (!irq) + regmap = syscon_node_to_regmap(of_get_parent(np)); + if (IS_ERR(regmap)) return; - clk = at91_clk_register_utmi(pmc, irq, name, parent_name); + clk = at91_clk_register_utmi(regmap, name, parent_name); if (IS_ERR(clk)) return; of_clk_add_provider(np, of_clk_src_simple_get, clk); return; } - -void __init of_at91sam9x5_clk_utmi_setup(struct device_node *np, - struct at91_pmc *pmc) -{ - of_at91_clk_utmi_setup(np, pmc); -} +CLK_OF_DECLARE(at91sam9x5_clk_utmi, "atmel,at91sam9x5-clk-utmi", + of_at91sam9x5_clk_utmi_setup); diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c index 8476b570779b2d2b04ce1b4283eec0688febd4d3..526df5ba042ddfd11a2bbe6441bccc6c1eb81f8d 100644 --- a/drivers/clk/at91/pmc.c +++ b/drivers/clk/at91/pmc.c @@ -12,36 +12,13 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include +#include +#include #include #include "pmc.h" -void __iomem *at91_pmc_base; -EXPORT_SYMBOL_GPL(at91_pmc_base); - -void at91rm9200_idle(void) -{ - /* - * Disable the processor clock. The processor will be automatically - * re-enabled by an interrupt or by a reset. - */ - at91_pmc_write(AT91_PMC_SCDR, AT91_PMC_PCK); -} - -void at91sam9_idle(void) -{ - at91_pmc_write(AT91_PMC_SCDR, AT91_PMC_PCK); - cpu_do_idle(); -} - int of_at91_get_clk_range(struct device_node *np, const char *propname, struct clk_range *range) { @@ -64,402 +41,3 @@ int of_at91_get_clk_range(struct device_node *np, const char *propname, return 0; } EXPORT_SYMBOL_GPL(of_at91_get_clk_range); - -static void pmc_irq_mask(struct irq_data *d) -{ - struct at91_pmc *pmc = irq_data_get_irq_chip_data(d); - - pmc_write(pmc, AT91_PMC_IDR, 1 << d->hwirq); -} - -static void pmc_irq_unmask(struct irq_data *d) -{ - struct at91_pmc *pmc = irq_data_get_irq_chip_data(d); - - pmc_write(pmc, AT91_PMC_IER, 1 << d->hwirq); -} - -static int pmc_irq_set_type(struct irq_data *d, unsigned type) -{ - if (type != IRQ_TYPE_LEVEL_HIGH) { - pr_warn("PMC: type not supported (support only IRQ_TYPE_LEVEL_HIGH type)\n"); - return -EINVAL; - } - - return 0; -} - -static void pmc_irq_suspend(struct irq_data *d) -{ - struct at91_pmc *pmc = irq_data_get_irq_chip_data(d); - - pmc->imr = pmc_read(pmc, AT91_PMC_IMR); - pmc_write(pmc, AT91_PMC_IDR, pmc->imr); -} - -static void pmc_irq_resume(struct irq_data *d) -{ - struct at91_pmc *pmc = irq_data_get_irq_chip_data(d); - - pmc_write(pmc, AT91_PMC_IER, pmc->imr); -} - -static struct irq_chip pmc_irq = { - .name = "PMC", - .irq_disable = pmc_irq_mask, - .irq_mask = pmc_irq_mask, - .irq_unmask = pmc_irq_unmask, - .irq_set_type = pmc_irq_set_type, - .irq_suspend = pmc_irq_suspend, - .irq_resume = pmc_irq_resume, -}; - -static struct lock_class_key pmc_lock_class; - -static int pmc_irq_map(struct irq_domain *h, unsigned int virq, - irq_hw_number_t hw) -{ - struct at91_pmc *pmc = h->host_data; - - irq_set_lockdep_class(virq, &pmc_lock_class); - - irq_set_chip_and_handler(virq, &pmc_irq, - handle_level_irq); - irq_set_chip_data(virq, pmc); - - return 0; -} - -static int pmc_irq_domain_xlate(struct irq_domain *d, - struct device_node *ctrlr, - const u32 *intspec, unsigned int intsize, - irq_hw_number_t *out_hwirq, - unsigned int *out_type) -{ - struct at91_pmc *pmc = d->host_data; - const struct at91_pmc_caps *caps = pmc->caps; - - if (WARN_ON(intsize < 1)) - return -EINVAL; - - *out_hwirq = intspec[0]; - - if (!(caps->available_irqs & (1 << *out_hwirq))) - return -EINVAL; - - *out_type = IRQ_TYPE_LEVEL_HIGH; - - return 0; -} - -static const struct irq_domain_ops pmc_irq_ops = { - .map = pmc_irq_map, - .xlate = pmc_irq_domain_xlate, -}; - -static irqreturn_t pmc_irq_handler(int irq, void *data) -{ - struct at91_pmc *pmc = (struct at91_pmc *)data; - unsigned long sr; - int n; - - sr = pmc_read(pmc, AT91_PMC_SR) & pmc_read(pmc, AT91_PMC_IMR); - if (!sr) - return IRQ_NONE; - - for_each_set_bit(n, &sr, BITS_PER_LONG) - generic_handle_irq(irq_find_mapping(pmc->irqdomain, n)); - - return IRQ_HANDLED; -} - -static const struct at91_pmc_caps at91rm9200_caps = { - .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_LOCKB | - AT91_PMC_MCKRDY | AT91_PMC_PCK0RDY | - AT91_PMC_PCK1RDY | AT91_PMC_PCK2RDY | - AT91_PMC_PCK3RDY, -}; - -static const struct at91_pmc_caps at91sam9260_caps = { - .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_LOCKB | - AT91_PMC_MCKRDY | AT91_PMC_PCK0RDY | - AT91_PMC_PCK1RDY, -}; - -static const struct at91_pmc_caps at91sam9g45_caps = { - .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY | - AT91_PMC_LOCKU | AT91_PMC_PCK0RDY | - AT91_PMC_PCK1RDY, -}; - -static const struct at91_pmc_caps at91sam9n12_caps = { - .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_LOCKB | - AT91_PMC_MCKRDY | AT91_PMC_PCK0RDY | - AT91_PMC_PCK1RDY | AT91_PMC_MOSCSELS | - AT91_PMC_MOSCRCS | AT91_PMC_CFDEV, -}; - -static const struct at91_pmc_caps at91sam9x5_caps = { - .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY | - AT91_PMC_LOCKU | AT91_PMC_PCK0RDY | - AT91_PMC_PCK1RDY | AT91_PMC_MOSCSELS | - AT91_PMC_MOSCRCS | AT91_PMC_CFDEV, -}; - -static const struct at91_pmc_caps sama5d2_caps = { - .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY | - AT91_PMC_LOCKU | AT91_PMC_PCK0RDY | - AT91_PMC_PCK1RDY | AT91_PMC_PCK2RDY | - AT91_PMC_MOSCSELS | AT91_PMC_MOSCRCS | - AT91_PMC_CFDEV | AT91_PMC_GCKRDY, -}; - -static const struct at91_pmc_caps sama5d3_caps = { - .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY | - AT91_PMC_LOCKU | AT91_PMC_PCK0RDY | - AT91_PMC_PCK1RDY | AT91_PMC_PCK2RDY | - AT91_PMC_MOSCSELS | AT91_PMC_MOSCRCS | - AT91_PMC_CFDEV, -}; - -static struct at91_pmc *__init at91_pmc_init(struct device_node *np, - void __iomem *regbase, int virq, - const struct at91_pmc_caps *caps) -{ - struct at91_pmc *pmc; - - if (!regbase || !virq || !caps) - return NULL; - - at91_pmc_base = regbase; - - pmc = kzalloc(sizeof(*pmc), GFP_KERNEL); - if (!pmc) - return NULL; - - spin_lock_init(&pmc->lock); - pmc->regbase = regbase; - pmc->virq = virq; - pmc->caps = caps; - - pmc->irqdomain = irq_domain_add_linear(np, 32, &pmc_irq_ops, pmc); - - if (!pmc->irqdomain) - goto out_free_pmc; - - pmc_write(pmc, AT91_PMC_IDR, 0xffffffff); - if (request_irq(pmc->virq, pmc_irq_handler, - IRQF_SHARED | IRQF_COND_SUSPEND, "pmc", pmc)) - goto out_remove_irqdomain; - - return pmc; - -out_remove_irqdomain: - irq_domain_remove(pmc->irqdomain); -out_free_pmc: - kfree(pmc); - - return NULL; -} - -static const struct of_device_id pmc_clk_ids[] __initconst = { - /* Slow oscillator */ - { - .compatible = "atmel,at91sam9260-clk-slow", - .data = of_at91sam9260_clk_slow_setup, - }, - /* Main clock */ - { - .compatible = "atmel,at91rm9200-clk-main-osc", - .data = of_at91rm9200_clk_main_osc_setup, - }, - { - .compatible = "atmel,at91sam9x5-clk-main-rc-osc", - .data = of_at91sam9x5_clk_main_rc_osc_setup, - }, - { - .compatible = "atmel,at91rm9200-clk-main", - .data = of_at91rm9200_clk_main_setup, - }, - { - .compatible = "atmel,at91sam9x5-clk-main", - .data = of_at91sam9x5_clk_main_setup, - }, - /* PLL clocks */ - { - .compatible = "atmel,at91rm9200-clk-pll", - .data = of_at91rm9200_clk_pll_setup, - }, - { - .compatible = "atmel,at91sam9g45-clk-pll", - .data = of_at91sam9g45_clk_pll_setup, - }, - { - .compatible = "atmel,at91sam9g20-clk-pllb", - .data = of_at91sam9g20_clk_pllb_setup, - }, - { - .compatible = "atmel,sama5d3-clk-pll", - .data = of_sama5d3_clk_pll_setup, - }, - { - .compatible = "atmel,at91sam9x5-clk-plldiv", - .data = of_at91sam9x5_clk_plldiv_setup, - }, - /* Master clock */ - { - .compatible = "atmel,at91rm9200-clk-master", - .data = of_at91rm9200_clk_master_setup, - }, - { - .compatible = "atmel,at91sam9x5-clk-master", - .data = of_at91sam9x5_clk_master_setup, - }, - /* System clocks */ - { - .compatible = "atmel,at91rm9200-clk-system", - .data = of_at91rm9200_clk_sys_setup, - }, - /* Peripheral clocks */ - { - .compatible = "atmel,at91rm9200-clk-peripheral", - .data = of_at91rm9200_clk_periph_setup, - }, - { - .compatible = "atmel,at91sam9x5-clk-peripheral", - .data = of_at91sam9x5_clk_periph_setup, - }, - /* Programmable clocks */ - { - .compatible = "atmel,at91rm9200-clk-programmable", - .data = of_at91rm9200_clk_prog_setup, - }, - { - .compatible = "atmel,at91sam9g45-clk-programmable", - .data = of_at91sam9g45_clk_prog_setup, - }, - { - .compatible = "atmel,at91sam9x5-clk-programmable", - .data = of_at91sam9x5_clk_prog_setup, - }, - /* UTMI clock */ -#if defined(CONFIG_HAVE_AT91_UTMI) - { - .compatible = "atmel,at91sam9x5-clk-utmi", - .data = of_at91sam9x5_clk_utmi_setup, - }, -#endif - /* USB clock */ -#if defined(CONFIG_HAVE_AT91_USB_CLK) - { - .compatible = "atmel,at91rm9200-clk-usb", - .data = of_at91rm9200_clk_usb_setup, - }, - { - .compatible = "atmel,at91sam9x5-clk-usb", - .data = of_at91sam9x5_clk_usb_setup, - }, - { - .compatible = "atmel,at91sam9n12-clk-usb", - .data = of_at91sam9n12_clk_usb_setup, - }, -#endif - /* SMD clock */ -#if defined(CONFIG_HAVE_AT91_SMD) - { - .compatible = "atmel,at91sam9x5-clk-smd", - .data = of_at91sam9x5_clk_smd_setup, - }, -#endif -#if defined(CONFIG_HAVE_AT91_H32MX) - { - .compatible = "atmel,sama5d4-clk-h32mx", - .data = of_sama5d4_clk_h32mx_setup, - }, -#endif -#if defined(CONFIG_HAVE_AT91_GENERATED_CLK) - { - .compatible = "atmel,sama5d2-clk-generated", - .data = of_sama5d2_clk_generated_setup, - }, -#endif - { /*sentinel*/ } -}; - -static void __init of_at91_pmc_setup(struct device_node *np, - const struct at91_pmc_caps *caps) -{ - struct at91_pmc *pmc; - struct device_node *childnp; - void (*clk_setup)(struct device_node *, struct at91_pmc *); - const struct of_device_id *clk_id; - void __iomem *regbase = of_iomap(np, 0); - int virq; - - if (!regbase) - return; - - virq = irq_of_parse_and_map(np, 0); - if (!virq) - return; - - pmc = at91_pmc_init(np, regbase, virq, caps); - if (!pmc) - return; - for_each_child_of_node(np, childnp) { - clk_id = of_match_node(pmc_clk_ids, childnp); - if (!clk_id) - continue; - clk_setup = clk_id->data; - clk_setup(childnp, pmc); - } -} - -static void __init of_at91rm9200_pmc_setup(struct device_node *np) -{ - of_at91_pmc_setup(np, &at91rm9200_caps); -} -CLK_OF_DECLARE(at91rm9200_clk_pmc, "atmel,at91rm9200-pmc", - of_at91rm9200_pmc_setup); - -static void __init of_at91sam9260_pmc_setup(struct device_node *np) -{ - of_at91_pmc_setup(np, &at91sam9260_caps); -} -CLK_OF_DECLARE(at91sam9260_clk_pmc, "atmel,at91sam9260-pmc", - of_at91sam9260_pmc_setup); - -static void __init of_at91sam9g45_pmc_setup(struct device_node *np) -{ - of_at91_pmc_setup(np, &at91sam9g45_caps); -} -CLK_OF_DECLARE(at91sam9g45_clk_pmc, "atmel,at91sam9g45-pmc", - of_at91sam9g45_pmc_setup); - -static void __init of_at91sam9n12_pmc_setup(struct device_node *np) -{ - of_at91_pmc_setup(np, &at91sam9n12_caps); -} -CLK_OF_DECLARE(at91sam9n12_clk_pmc, "atmel,at91sam9n12-pmc", - of_at91sam9n12_pmc_setup); - -static void __init of_at91sam9x5_pmc_setup(struct device_node *np) -{ - of_at91_pmc_setup(np, &at91sam9x5_caps); -} -CLK_OF_DECLARE(at91sam9x5_clk_pmc, "atmel,at91sam9x5-pmc", - of_at91sam9x5_pmc_setup); - -static void __init of_sama5d2_pmc_setup(struct device_node *np) -{ - of_at91_pmc_setup(np, &sama5d2_caps); -} -CLK_OF_DECLARE(sama5d2_clk_pmc, "atmel,sama5d2-pmc", - of_sama5d2_pmc_setup); - -static void __init of_sama5d3_pmc_setup(struct device_node *np) -{ - of_at91_pmc_setup(np, &sama5d3_caps); -} -CLK_OF_DECLARE(sama5d3_clk_pmc, "atmel,sama5d3-pmc", - of_sama5d3_pmc_setup); diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h index f65739272779d3677e74321d4c6ff89d31379adf..5771fff0ee3fdf345422baa54903b1864027f2c3 100644 --- a/drivers/clk/at91/pmc.h +++ b/drivers/clk/at91/pmc.h @@ -14,8 +14,11 @@ #include #include +#include #include +extern spinlock_t pmc_pcr_lock; + struct clk_range { unsigned long min; unsigned long max; @@ -23,102 +26,7 @@ struct clk_range { #define CLK_RANGE(MIN, MAX) {.min = MIN, .max = MAX,} -struct at91_pmc_caps { - u32 available_irqs; -}; - -struct at91_pmc { - void __iomem *regbase; - int virq; - spinlock_t lock; - const struct at91_pmc_caps *caps; - struct irq_domain *irqdomain; - u32 imr; -}; - -static inline void pmc_lock(struct at91_pmc *pmc) -{ - spin_lock(&pmc->lock); -} - -static inline void pmc_unlock(struct at91_pmc *pmc) -{ - spin_unlock(&pmc->lock); -} - -static inline u32 pmc_read(struct at91_pmc *pmc, int offset) -{ - return readl(pmc->regbase + offset); -} - -static inline void pmc_write(struct at91_pmc *pmc, int offset, u32 value) -{ - writel(value, pmc->regbase + offset); -} - int of_at91_get_clk_range(struct device_node *np, const char *propname, struct clk_range *range); -void of_at91sam9260_clk_slow_setup(struct device_node *np, - struct at91_pmc *pmc); - -void of_at91rm9200_clk_main_osc_setup(struct device_node *np, - struct at91_pmc *pmc); -void of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np, - struct at91_pmc *pmc); -void of_at91rm9200_clk_main_setup(struct device_node *np, - struct at91_pmc *pmc); -void of_at91sam9x5_clk_main_setup(struct device_node *np, - struct at91_pmc *pmc); - -void of_at91rm9200_clk_pll_setup(struct device_node *np, - struct at91_pmc *pmc); -void of_at91sam9g45_clk_pll_setup(struct device_node *np, - struct at91_pmc *pmc); -void of_at91sam9g20_clk_pllb_setup(struct device_node *np, - struct at91_pmc *pmc); -void of_sama5d3_clk_pll_setup(struct device_node *np, - struct at91_pmc *pmc); -void of_at91sam9x5_clk_plldiv_setup(struct device_node *np, - struct at91_pmc *pmc); - -void of_at91rm9200_clk_master_setup(struct device_node *np, - struct at91_pmc *pmc); -void of_at91sam9x5_clk_master_setup(struct device_node *np, - struct at91_pmc *pmc); - -void of_at91rm9200_clk_sys_setup(struct device_node *np, - struct at91_pmc *pmc); - -void of_at91rm9200_clk_periph_setup(struct device_node *np, - struct at91_pmc *pmc); -void of_at91sam9x5_clk_periph_setup(struct device_node *np, - struct at91_pmc *pmc); - -void of_at91rm9200_clk_prog_setup(struct device_node *np, - struct at91_pmc *pmc); -void of_at91sam9g45_clk_prog_setup(struct device_node *np, - struct at91_pmc *pmc); -void of_at91sam9x5_clk_prog_setup(struct device_node *np, - struct at91_pmc *pmc); - -void of_at91sam9x5_clk_utmi_setup(struct device_node *np, - struct at91_pmc *pmc); - -void of_at91rm9200_clk_usb_setup(struct device_node *np, - struct at91_pmc *pmc); -void of_at91sam9x5_clk_usb_setup(struct device_node *np, - struct at91_pmc *pmc); -void of_at91sam9n12_clk_usb_setup(struct device_node *np, - struct at91_pmc *pmc); - -void of_at91sam9x5_clk_smd_setup(struct device_node *np, - struct at91_pmc *pmc); - -void of_sama5d4_clk_h32mx_setup(struct device_node *np, - struct at91_pmc *pmc); - -void of_sama5d2_clk_generated_setup(struct device_node *np, - struct at91_pmc *pmc); - #endif /* __PMC_H_ */ diff --git a/drivers/clk/bcm/clk-bcm2835-aux.c b/drivers/clk/bcm/clk-bcm2835-aux.c index e4f89e28b5ecf5a88bbbdc50111904beb470b2a6..3a177ade6e6cc71d84337504df37543227bcb74f 100644 --- a/drivers/clk/bcm/clk-bcm2835-aux.c +++ b/drivers/clk/bcm/clk-bcm2835-aux.c @@ -38,8 +38,8 @@ static int bcm2835_aux_clk_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); reg = devm_ioremap_resource(dev, res); - if (!reg) - return -ENODEV; + if (IS_ERR(reg)) + return PTR_ERR(reg); onecell = devm_kmalloc(dev, sizeof(*onecell), GFP_KERNEL); if (!onecell) diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 015e687ffabe18423016d6cd299e79ef96418bf4..c74ed3fd496dba5a8d4fa867257ee5030491a3c9 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -88,10 +88,23 @@ #define CM_HSMDIV 0x08c #define CM_OTPCTL 0x090 #define CM_OTPDIV 0x094 +#define CM_PCMCTL 0x098 +#define CM_PCMDIV 0x09c #define CM_PWMCTL 0x0a0 #define CM_PWMDIV 0x0a4 +#define CM_SLIMCTL 0x0a8 +#define CM_SLIMDIV 0x0ac #define CM_SMICTL 0x0b0 #define CM_SMIDIV 0x0b4 +/* no definition for 0x0b8 and 0x0bc */ +#define CM_TCNTCTL 0x0c0 +#define CM_TCNTDIV 0x0c4 +#define CM_TECCTL 0x0c8 +#define CM_TECDIV 0x0cc +#define CM_TD0CTL 0x0d0 +#define CM_TD0DIV 0x0d4 +#define CM_TD1CTL 0x0d8 +#define CM_TD1DIV 0x0dc #define CM_TSENSCTL 0x0e0 #define CM_TSENSDIV 0x0e4 #define CM_TIMERCTL 0x0e8 @@ -311,21 +324,18 @@ void __init bcm2835_init_clocks(void) struct clk *clk; int ret; - clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, - 126000000); + clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, 0, 126000000); if (IS_ERR(clk)) pr_err("apb_pclk not registered\n"); - clk = clk_register_fixed_rate(NULL, "uart0_pclk", NULL, CLK_IS_ROOT, - 3000000); + clk = clk_register_fixed_rate(NULL, "uart0_pclk", NULL, 0, 3000000); if (IS_ERR(clk)) pr_err("uart0_pclk not registered\n"); ret = clk_register_clkdev(clk, NULL, "20201000.uart"); if (ret) pr_err("uart0_pclk alias not registered\n"); - clk = clk_register_fixed_rate(NULL, "uart1_pclk", NULL, CLK_IS_ROOT, - 125000000); + clk = clk_register_fixed_rate(NULL, "uart1_pclk", NULL, 0, 125000000); if (IS_ERR(clk)) pr_err("uart1_pclk not registered\n"); ret = clk_register_clkdev(clk, NULL, "20215000.uart"); @@ -1060,16 +1070,7 @@ static long bcm2835_pll_divider_round_rate(struct clk_hw *hw, static unsigned long bcm2835_pll_divider_get_rate(struct clk_hw *hw, unsigned long parent_rate) { - struct bcm2835_pll_divider *divider = bcm2835_pll_divider_from_hw(hw); - struct bcm2835_cprman *cprman = divider->cprman; - const struct bcm2835_pll_divider_data *data = divider->data; - u32 div = cprman_read(cprman, data->a2w_reg); - - div &= (1 << A2W_PLL_DIV_BITS) - 1; - if (div == 0) - div = 256; - - return parent_rate / div; + return clk_divider_ops.recalc_rate(hw, parent_rate); } static void bcm2835_pll_divider_off(struct clk_hw *hw) @@ -1107,13 +1108,15 @@ static int bcm2835_pll_divider_set_rate(struct clk_hw *hw, struct bcm2835_pll_divider *divider = bcm2835_pll_divider_from_hw(hw); struct bcm2835_cprman *cprman = divider->cprman; const struct bcm2835_pll_divider_data *data = divider->data; - u32 cm; - int ret; + u32 cm, div, max_div = 1 << A2W_PLL_DIV_BITS; - ret = clk_divider_ops.set_rate(hw, rate, parent_rate); - if (ret) - return ret; + div = DIV_ROUND_UP_ULL(parent_rate, rate); + + div = min(div, max_div); + if (div == max_div) + div = 0; + cprman_write(cprman, data->a2w_reg, div); cm = cprman_read(cprman, data->cm_reg); cprman_write(cprman, data->cm_reg, cm | data->load_mask); cprman_write(cprman, data->cm_reg, cm & ~data->load_mask); @@ -1428,7 +1431,7 @@ bcm2835_register_pll_divider(struct bcm2835_cprman *cprman, divider->div.reg = cprman->regs + data->a2w_reg; divider->div.shift = A2W_PLL_DIV_SHIFT; divider->div.width = A2W_PLL_DIV_BITS; - divider->div.flags = 0; + divider->div.flags = CLK_DIVIDER_MAX_AT_ZERO; divider->div.lock = &cprman->regs_lock; divider->div.hw.init = &init; divider->div.table = NULL; diff --git a/drivers/clk/bcm/clk-cygnus.c b/drivers/clk/bcm/clk-cygnus.c index 3a228b6d4feefe6466f29941e9f66fee0c532615..464fdc4bc66b38d971597b7726d907fcde26f6bb 100644 --- a/drivers/clk/bcm/clk-cygnus.c +++ b/drivers/clk/bcm/clk-cygnus.c @@ -268,3 +268,62 @@ static void __init cygnus_asiu_init(struct device_node *node) iproc_asiu_setup(node, asiu_div, asiu_gate, ARRAY_SIZE(asiu_div)); } CLK_OF_DECLARE(cygnus_asiu_clk, "brcm,cygnus-asiu-clk", cygnus_asiu_init); + +/* + * AUDIO PLL VCO frequency parameter table + * + * PLL output frequency = ((ndiv_int + ndiv_frac / 2^20) * + * (parent clock rate / pdiv) + * + * On Cygnus, parent is the 25MHz oscillator + */ +static const struct iproc_pll_vco_param audiopll_vco_params[] = { + /* rate (Hz) ndiv_int ndiv_frac pdiv */ + { 1354750204UL, 54, 199238, 1 }, + { 1769470191UL, 70, 816639, 1 }, +}; + +static const struct iproc_pll_ctrl audiopll = { + .flags = IPROC_CLK_PLL_NEEDS_SW_CFG | IPROC_CLK_PLL_HAS_NDIV_FRAC | + IPROC_CLK_PLL_USER_MODE_ON | IPROC_CLK_PLL_RESET_ACTIVE_LOW, + .reset = RESET_VAL(0x5c, 0, 1), + .dig_filter = DF_VAL(0x48, 0, 3, 6, 4, 3, 3), + .sw_ctrl = SW_CTRL_VAL(0x4, 0), + .ndiv_int = REG_VAL(0x8, 0, 10), + .ndiv_frac = REG_VAL(0x8, 10, 20), + .pdiv = REG_VAL(0x44, 0, 4), + .vco_ctrl = VCO_CTRL_VAL(0x0c, 0x10), + .status = REG_VAL(0x54, 0, 1), + .macro_mode = REG_VAL(0x0, 0, 3), +}; + +static const struct iproc_clk_ctrl audiopll_clk[] = { + [BCM_CYGNUS_AUDIOPLL_CH0] = { + .channel = BCM_CYGNUS_AUDIOPLL_CH0, + .flags = IPROC_CLK_AON | + IPROC_CLK_MCLK_DIV_BY_2, + .enable = ENABLE_VAL(0x14, 8, 10, 9), + .mdiv = REG_VAL(0x14, 0, 8), + }, + [BCM_CYGNUS_AUDIOPLL_CH1] = { + .channel = BCM_CYGNUS_AUDIOPLL_CH1, + .flags = IPROC_CLK_AON, + .enable = ENABLE_VAL(0x18, 8, 10, 9), + .mdiv = REG_VAL(0x18, 0, 8), + }, + [BCM_CYGNUS_AUDIOPLL_CH2] = { + .channel = BCM_CYGNUS_AUDIOPLL_CH2, + .flags = IPROC_CLK_AON, + .enable = ENABLE_VAL(0x1c, 8, 10, 9), + .mdiv = REG_VAL(0x1c, 0, 8), + }, +}; + +static void __init cygnus_audiopll_clk_init(struct device_node *node) +{ + iproc_pll_clk_setup(node, &audiopll, audiopll_vco_params, + ARRAY_SIZE(audiopll_vco_params), audiopll_clk, + ARRAY_SIZE(audiopll_clk)); +} +CLK_OF_DECLARE(cygnus_audiopll, "brcm,cygnus-audiopll", + cygnus_audiopll_clk_init); diff --git a/drivers/clk/bcm/clk-iproc-pll.c b/drivers/clk/bcm/clk-iproc-pll.c index afd5891ac9e6aafeb6f429e487d5e06cbfd2f4f1..fd492a5dad12bf48b96fbaa2484100093f581d96 100644 --- a/drivers/clk/bcm/clk-iproc-pll.c +++ b/drivers/clk/bcm/clk-iproc-pll.c @@ -25,6 +25,12 @@ #define PLL_VCO_HIGH_SHIFT 19 #define PLL_VCO_LOW_SHIFT 30 +/* + * PLL MACRO_SELECT modes 0 to 5 choose pre-calculated PLL output frequencies + * from a look-up table. Mode 7 allows user to manipulate PLL clock dividers + */ +#define PLL_USER_MODE 7 + /* number of delay loops waiting for PLL to lock */ #define LOCK_DELAY 100 @@ -215,7 +221,10 @@ static void __pll_put_in_reset(struct iproc_pll *pll) const struct iproc_pll_reset_ctrl *reset = &ctrl->reset; val = readl(pll->control_base + reset->offset); - val &= ~(1 << reset->reset_shift | 1 << reset->p_reset_shift); + if (ctrl->flags & IPROC_CLK_PLL_RESET_ACTIVE_LOW) + val |= BIT(reset->reset_shift) | BIT(reset->p_reset_shift); + else + val &= ~(BIT(reset->reset_shift) | BIT(reset->p_reset_shift)); iproc_pll_write(pll, pll->control_base, reset->offset, val); } @@ -236,7 +245,10 @@ static void __pll_bring_out_reset(struct iproc_pll *pll, unsigned int kp, iproc_pll_write(pll, pll->control_base, dig_filter->offset, val); val = readl(pll->control_base + reset->offset); - val |= 1 << reset->reset_shift | 1 << reset->p_reset_shift; + if (ctrl->flags & IPROC_CLK_PLL_RESET_ACTIVE_LOW) + val &= ~(BIT(reset->reset_shift) | BIT(reset->p_reset_shift)); + else + val |= BIT(reset->reset_shift) | BIT(reset->p_reset_shift); iproc_pll_write(pll, pll->control_base, reset->offset, val); } @@ -292,6 +304,16 @@ static int pll_set_rate(struct iproc_clk *clk, unsigned int rate_index, /* put PLL in reset */ __pll_put_in_reset(pll); + /* set PLL in user mode before modifying PLL controls */ + if (ctrl->flags & IPROC_CLK_PLL_USER_MODE_ON) { + val = readl(pll->control_base + ctrl->macro_mode.offset); + val &= ~(bit_mask(ctrl->macro_mode.width) << + ctrl->macro_mode.shift); + val |= PLL_USER_MODE << ctrl->macro_mode.shift; + iproc_pll_write(pll, pll->control_base, + ctrl->macro_mode.offset, val); + } + iproc_pll_write(pll, pll->control_base, ctrl->vco_ctrl.u_offset, 0); val = readl(pll->control_base + ctrl->vco_ctrl.l_offset); @@ -505,7 +527,10 @@ static unsigned long iproc_clk_recalc_rate(struct clk_hw *hw, if (mdiv == 0) mdiv = 256; - clk->rate = parent_rate / mdiv; + if (ctrl->flags & IPROC_CLK_MCLK_DIV_BY_2) + clk->rate = parent_rate / (mdiv * 2); + else + clk->rate = parent_rate / mdiv; return clk->rate; } @@ -543,7 +568,10 @@ static int iproc_clk_set_rate(struct clk_hw *hw, unsigned long rate, if (rate == 0 || parent_rate == 0) return -EINVAL; - div = DIV_ROUND_UP(parent_rate, rate); + if (ctrl->flags & IPROC_CLK_MCLK_DIV_BY_2) + div = DIV_ROUND_UP(parent_rate, rate * 2); + else + div = DIV_ROUND_UP(parent_rate, rate); if (div > 256) return -EINVAL; @@ -555,7 +583,10 @@ static int iproc_clk_set_rate(struct clk_hw *hw, unsigned long rate, val |= div << ctrl->mdiv.shift; } iproc_pll_write(pll, pll->control_base, ctrl->mdiv.offset, val); - clk->rate = parent_rate / div; + if (ctrl->flags & IPROC_CLK_MCLK_DIV_BY_2) + clk->rate = parent_rate / (div * 2); + else + clk->rate = parent_rate / div; return 0; } diff --git a/drivers/clk/bcm/clk-iproc.h b/drivers/clk/bcm/clk-iproc.h index 8988de70a98cc3fd38c4d72212443ce8250ffca3..2148b4ea9f2898e61cbc341ad30c25d761562862 100644 --- a/drivers/clk/bcm/clk-iproc.h +++ b/drivers/clk/bcm/clk-iproc.h @@ -60,6 +60,26 @@ */ #define IPROC_CLK_PLL_SPLIT_STAT_CTRL BIT(6) +/* + * Some PLLs have an additional divide by 2 in master clock calculation; + * MCLK = VCO_freq / (Mdiv * 2). Identify this to let the driver know + * of modified calculations + */ +#define IPROC_CLK_MCLK_DIV_BY_2 BIT(7) + +/* + * Some PLLs provide a look up table for the leaf clock frequencies and + * auto calculates VCO frequency parameters based on the provided leaf + * clock frequencies. They have a user mode that allows the divider + * controls to be determined by the user + */ +#define IPROC_CLK_PLL_USER_MODE_ON BIT(8) + +/* + * Some PLLs have an active low reset + */ +#define IPROC_CLK_PLL_RESET_ACTIVE_LOW BIT(9) + /* * Parameters for VCO frequency configuration * @@ -149,6 +169,7 @@ struct iproc_pll_ctrl { struct iproc_clk_reg_op pdiv; struct iproc_pll_vco_ctrl vco_ctrl; struct iproc_clk_reg_op status; + struct iproc_clk_reg_op macro_mode; }; /* @@ -183,16 +204,16 @@ struct iproc_asiu_div { unsigned int low_width; }; -void __init iproc_armpll_setup(struct device_node *node); -void __init iproc_pll_clk_setup(struct device_node *node, - const struct iproc_pll_ctrl *pll_ctrl, - const struct iproc_pll_vco_param *vco, - unsigned int num_vco_entries, - const struct iproc_clk_ctrl *clk_ctrl, - unsigned int num_clks); -void __init iproc_asiu_setup(struct device_node *node, - const struct iproc_asiu_div *div, - const struct iproc_asiu_gate *gate, - unsigned int num_clks); +void iproc_armpll_setup(struct device_node *node); +void iproc_pll_clk_setup(struct device_node *node, + const struct iproc_pll_ctrl *pll_ctrl, + const struct iproc_pll_vco_param *vco, + unsigned int num_vco_entries, + const struct iproc_clk_ctrl *clk_ctrl, + unsigned int num_clks); +void iproc_asiu_setup(struct device_node *node, + const struct iproc_asiu_div *div, + const struct iproc_asiu_gate *gate, + unsigned int num_clks); #endif /* _CLK_IPROC_H */ diff --git a/drivers/clk/clk-axi-clkgen.c b/drivers/clk/clk-axi-clkgen.c index 3bcd42fbb55e3fbbcdb401f707aef3879fe5d001..3294db3b4e4e7303903b7a0b10a149b25642b148 100644 --- a/drivers/clk/clk-axi-clkgen.c +++ b/drivers/clk/clk-axi-clkgen.c @@ -16,19 +16,8 @@ #include #include -#define AXI_CLKGEN_V1_REG_UPDATE_ENABLE 0x04 -#define AXI_CLKGEN_V1_REG_CLK_OUT1 0x08 -#define AXI_CLKGEN_V1_REG_CLK_OUT2 0x0c -#define AXI_CLKGEN_V1_REG_CLK_DIV 0x10 -#define AXI_CLKGEN_V1_REG_CLK_FB1 0x14 -#define AXI_CLKGEN_V1_REG_CLK_FB2 0x18 -#define AXI_CLKGEN_V1_REG_LOCK1 0x1c -#define AXI_CLKGEN_V1_REG_LOCK2 0x20 -#define AXI_CLKGEN_V1_REG_LOCK3 0x24 -#define AXI_CLKGEN_V1_REG_FILTER1 0x28 -#define AXI_CLKGEN_V1_REG_FILTER2 0x2c - #define AXI_CLKGEN_V2_REG_RESET 0x40 +#define AXI_CLKGEN_V2_REG_CLKSEL 0x44 #define AXI_CLKGEN_V2_REG_DRP_CNTRL 0x70 #define AXI_CLKGEN_V2_REG_DRP_STATUS 0x74 @@ -51,40 +40,11 @@ #define MMCM_REG_FILTER1 0x4e #define MMCM_REG_FILTER2 0x4f -struct axi_clkgen; - -struct axi_clkgen_mmcm_ops { - void (*enable)(struct axi_clkgen *axi_clkgen, bool enable); - int (*write)(struct axi_clkgen *axi_clkgen, unsigned int reg, - unsigned int val, unsigned int mask); - int (*read)(struct axi_clkgen *axi_clkgen, unsigned int reg, - unsigned int *val); -}; - struct axi_clkgen { void __iomem *base; - const struct axi_clkgen_mmcm_ops *mmcm_ops; struct clk_hw clk_hw; }; -static void axi_clkgen_mmcm_enable(struct axi_clkgen *axi_clkgen, - bool enable) -{ - axi_clkgen->mmcm_ops->enable(axi_clkgen, enable); -} - -static int axi_clkgen_mmcm_write(struct axi_clkgen *axi_clkgen, - unsigned int reg, unsigned int val, unsigned int mask) -{ - return axi_clkgen->mmcm_ops->write(axi_clkgen, reg, val, mask); -} - -static int axi_clkgen_mmcm_read(struct axi_clkgen *axi_clkgen, - unsigned int reg, unsigned int *val) -{ - return axi_clkgen->mmcm_ops->read(axi_clkgen, reg, val); -} - static uint32_t axi_clkgen_lookup_filter(unsigned int m) { switch (m) { @@ -207,70 +167,6 @@ static void axi_clkgen_read(struct axi_clkgen *axi_clkgen, *val = readl(axi_clkgen->base + reg); } -static unsigned int axi_clkgen_v1_map_mmcm_reg(unsigned int reg) -{ - switch (reg) { - case MMCM_REG_CLKOUT0_1: - return AXI_CLKGEN_V1_REG_CLK_OUT1; - case MMCM_REG_CLKOUT0_2: - return AXI_CLKGEN_V1_REG_CLK_OUT2; - case MMCM_REG_CLK_FB1: - return AXI_CLKGEN_V1_REG_CLK_FB1; - case MMCM_REG_CLK_FB2: - return AXI_CLKGEN_V1_REG_CLK_FB2; - case MMCM_REG_CLK_DIV: - return AXI_CLKGEN_V1_REG_CLK_DIV; - case MMCM_REG_LOCK1: - return AXI_CLKGEN_V1_REG_LOCK1; - case MMCM_REG_LOCK2: - return AXI_CLKGEN_V1_REG_LOCK2; - case MMCM_REG_LOCK3: - return AXI_CLKGEN_V1_REG_LOCK3; - case MMCM_REG_FILTER1: - return AXI_CLKGEN_V1_REG_FILTER1; - case MMCM_REG_FILTER2: - return AXI_CLKGEN_V1_REG_FILTER2; - default: - return 0; - } -} - -static int axi_clkgen_v1_mmcm_write(struct axi_clkgen *axi_clkgen, - unsigned int reg, unsigned int val, unsigned int mask) -{ - reg = axi_clkgen_v1_map_mmcm_reg(reg); - if (reg == 0) - return -EINVAL; - - axi_clkgen_write(axi_clkgen, reg, val); - - return 0; -} - -static int axi_clkgen_v1_mmcm_read(struct axi_clkgen *axi_clkgen, - unsigned int reg, unsigned int *val) -{ - reg = axi_clkgen_v1_map_mmcm_reg(reg); - if (reg == 0) - return -EINVAL; - - axi_clkgen_read(axi_clkgen, reg, val); - - return 0; -} - -static void axi_clkgen_v1_mmcm_enable(struct axi_clkgen *axi_clkgen, - bool enable) -{ - axi_clkgen_write(axi_clkgen, AXI_CLKGEN_V1_REG_UPDATE_ENABLE, enable); -} - -static const struct axi_clkgen_mmcm_ops axi_clkgen_v1_mmcm_ops = { - .write = axi_clkgen_v1_mmcm_write, - .read = axi_clkgen_v1_mmcm_read, - .enable = axi_clkgen_v1_mmcm_enable, -}; - static int axi_clkgen_wait_non_busy(struct axi_clkgen *axi_clkgen) { unsigned int timeout = 10000; @@ -286,7 +182,7 @@ static int axi_clkgen_wait_non_busy(struct axi_clkgen *axi_clkgen) return val & 0xffff; } -static int axi_clkgen_v2_mmcm_read(struct axi_clkgen *axi_clkgen, +static int axi_clkgen_mmcm_read(struct axi_clkgen *axi_clkgen, unsigned int reg, unsigned int *val) { unsigned int reg_val; @@ -310,7 +206,7 @@ static int axi_clkgen_v2_mmcm_read(struct axi_clkgen *axi_clkgen, return 0; } -static int axi_clkgen_v2_mmcm_write(struct axi_clkgen *axi_clkgen, +static int axi_clkgen_mmcm_write(struct axi_clkgen *axi_clkgen, unsigned int reg, unsigned int val, unsigned int mask) { unsigned int reg_val = 0; @@ -321,7 +217,7 @@ static int axi_clkgen_v2_mmcm_write(struct axi_clkgen *axi_clkgen, return ret; if (mask != 0xffff) { - axi_clkgen_v2_mmcm_read(axi_clkgen, reg, ®_val); + axi_clkgen_mmcm_read(axi_clkgen, reg, ®_val); reg_val &= ~mask; } @@ -332,7 +228,7 @@ static int axi_clkgen_v2_mmcm_write(struct axi_clkgen *axi_clkgen, return 0; } -static void axi_clkgen_v2_mmcm_enable(struct axi_clkgen *axi_clkgen, +static void axi_clkgen_mmcm_enable(struct axi_clkgen *axi_clkgen, bool enable) { unsigned int val = AXI_CLKGEN_V2_RESET_ENABLE; @@ -343,12 +239,6 @@ static void axi_clkgen_v2_mmcm_enable(struct axi_clkgen *axi_clkgen, axi_clkgen_write(axi_clkgen, AXI_CLKGEN_V2_REG_RESET, val); } -static const struct axi_clkgen_mmcm_ops axi_clkgen_v2_mmcm_ops = { - .write = axi_clkgen_v2_mmcm_write, - .read = axi_clkgen_v2_mmcm_read, - .enable = axi_clkgen_v2_mmcm_enable, -}; - static struct axi_clkgen *clk_hw_to_axi_clkgen(struct clk_hw *clk_hw) { return container_of(clk_hw, struct axi_clkgen, clk_hw); @@ -438,10 +328,7 @@ static unsigned long axi_clkgen_recalc_rate(struct clk_hw *clk_hw, tmp = (unsigned long long)(parent_rate / d) * m; do_div(tmp, dout); - if (tmp > ULONG_MAX) - return ULONG_MAX; - - return tmp; + return min_t(unsigned long long, tmp, ULONG_MAX); } static int axi_clkgen_enable(struct clk_hw *clk_hw) @@ -460,21 +347,38 @@ static void axi_clkgen_disable(struct clk_hw *clk_hw) axi_clkgen_mmcm_enable(axi_clkgen, false); } +static int axi_clkgen_set_parent(struct clk_hw *clk_hw, u8 index) +{ + struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw); + + axi_clkgen_write(axi_clkgen, AXI_CLKGEN_V2_REG_CLKSEL, index); + + return 0; +} + +static u8 axi_clkgen_get_parent(struct clk_hw *clk_hw) +{ + struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw); + unsigned int parent; + + axi_clkgen_read(axi_clkgen, AXI_CLKGEN_V2_REG_CLKSEL, &parent); + + return parent; +} + static const struct clk_ops axi_clkgen_ops = { .recalc_rate = axi_clkgen_recalc_rate, .round_rate = axi_clkgen_round_rate, .set_rate = axi_clkgen_set_rate, .enable = axi_clkgen_enable, .disable = axi_clkgen_disable, + .set_parent = axi_clkgen_set_parent, + .get_parent = axi_clkgen_get_parent, }; static const struct of_device_id axi_clkgen_ids[] = { { - .compatible = "adi,axi-clkgen-1.00.a", - .data = &axi_clkgen_v1_mmcm_ops - }, { .compatible = "adi,axi-clkgen-2.00.a", - .data = &axi_clkgen_v2_mmcm_ops, }, { }, }; @@ -485,10 +389,11 @@ static int axi_clkgen_probe(struct platform_device *pdev) const struct of_device_id *id; struct axi_clkgen *axi_clkgen; struct clk_init_data init; - const char *parent_name; + const char *parent_names[2]; const char *clk_name; struct resource *mem; struct clk *clk; + unsigned int i; if (!pdev->dev.of_node) return -ENODEV; @@ -501,26 +406,29 @@ static int axi_clkgen_probe(struct platform_device *pdev) if (!axi_clkgen) return -ENOMEM; - axi_clkgen->mmcm_ops = id->data; - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); axi_clkgen->base = devm_ioremap_resource(&pdev->dev, mem); if (IS_ERR(axi_clkgen->base)) return PTR_ERR(axi_clkgen->base); - parent_name = of_clk_get_parent_name(pdev->dev.of_node, 0); - if (!parent_name) + init.num_parents = of_clk_get_parent_count(pdev->dev.of_node); + if (init.num_parents < 1 || init.num_parents > 2) return -EINVAL; + for (i = 0; i < init.num_parents; i++) { + parent_names[i] = of_clk_get_parent_name(pdev->dev.of_node, i); + if (!parent_names[i]) + return -EINVAL; + } + clk_name = pdev->dev.of_node->name; of_property_read_string(pdev->dev.of_node, "clock-output-names", &clk_name); init.name = clk_name; init.ops = &axi_clkgen_ops; - init.flags = CLK_SET_RATE_GATE; - init.parent_names = &parent_name; - init.num_parents = 1; + init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE; + init.parent_names = parent_names; axi_clkgen_mmcm_enable(axi_clkgen, false); diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c index 4735de0660cc912f1bafea1e31388bcf9843543d..1f903e1f86a281385a817d0a450404240ac40109 100644 --- a/drivers/clk/clk-composite.c +++ b/drivers/clk/clk-composite.c @@ -19,8 +19,6 @@ #include #include -#define to_clk_composite(_hw) container_of(_hw, struct clk_composite, hw) - static u8 clk_composite_get_parent(struct clk_hw *hw) { struct clk_composite *composite = to_clk_composite(hw); diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index ded3ff4b91b9a2492710c0487976c36fcb6dfa80..00e035b51c695be31a215319fd3af62fcd72112d 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c @@ -28,8 +28,6 @@ * parent - fixed parent. No clk_set_parent support */ -#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw) - #define div_mask(width) ((1 << (width)) - 1) static unsigned int _get_table_maxdiv(const struct clk_div_table *table, @@ -305,9 +303,8 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate, */ maxdiv = min(ULONG_MAX / rate, maxdiv); - for (i = 1; i <= maxdiv; i = _next_div(table, i, flags)) { - if (!_is_valid_div(table, i, flags)) - continue; + for (i = _next_div(table, 0, flags); i <= maxdiv; + i = _next_div(table, i, flags)) { if (rate * i == parent_rate_saved) { /* * It's the most ideal case if the requested rate can be @@ -423,6 +420,12 @@ const struct clk_ops clk_divider_ops = { }; EXPORT_SYMBOL_GPL(clk_divider_ops); +const struct clk_ops clk_divider_ro_ops = { + .recalc_rate = clk_divider_recalc_rate, + .round_rate = clk_divider_round_rate, +}; +EXPORT_SYMBOL_GPL(clk_divider_ro_ops); + static struct clk *_register_divider(struct device *dev, const char *name, const char *parent_name, unsigned long flags, void __iomem *reg, u8 shift, u8 width, @@ -446,7 +449,10 @@ static struct clk *_register_divider(struct device *dev, const char *name, return ERR_PTR(-ENOMEM); init.name = name; - init.ops = &clk_divider_ops; + if (clk_divider_flags & CLK_DIVIDER_READ_ONLY) + init.ops = &clk_divider_ro_ops; + else + init.ops = &clk_divider_ops; init.flags = flags | CLK_IS_BASIC; init.parent_names = (parent_name ? &parent_name: NULL); init.num_parents = (parent_name ? 1 : 0); diff --git a/drivers/clk/clk-efm32gg.c b/drivers/clk/clk-efm32gg.c index bac4553f04b854d96f3269a5b624a3723e2e9259..22e4c659704e443a04464f85752329992a715bca 100644 --- a/drivers/clk/clk-efm32gg.c +++ b/drivers/clk/clk-efm32gg.c @@ -36,7 +36,7 @@ static void __init efm32gg_cmu_init(struct device_node *np) } clk[clk_HFXO] = clk_register_fixed_rate(NULL, "HFXO", NULL, - CLK_IS_ROOT, 48000000); + 0, 48000000); clk[clk_HFPERCLKUSART0] = clk_register_gate(NULL, "HFPERCLK.USART0", "HFXO", 0, base + CMU_HFPERCLKEN0, 0, 0, NULL); diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c index 83de57aeceea514dfaf53fc5a0271b1ca7d3b13d..053448e2453d7b2c44726440853495541138c714 100644 --- a/drivers/clk/clk-fixed-factor.c +++ b/drivers/clk/clk-fixed-factor.c @@ -23,8 +23,6 @@ * parent - fixed parent. No clk_set_parent support */ -#define to_clk_fixed_factor(_hw) container_of(_hw, struct clk_fixed_factor, hw) - static unsigned long clk_factor_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { @@ -102,6 +100,19 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name, } EXPORT_SYMBOL_GPL(clk_register_fixed_factor); +void clk_unregister_fixed_factor(struct clk *clk) +{ + struct clk_hw *hw; + + hw = __clk_get_hw(clk); + if (!hw) + return; + + clk_unregister(clk); + kfree(to_clk_fixed_factor(hw)); +} +EXPORT_SYMBOL_GPL(clk_unregister_fixed_factor); + #ifdef CONFIG_OF /** * of_fixed_factor_clk_setup() - Setup function for simple fixed factor clock diff --git a/drivers/clk/clk-fixed-rate.c b/drivers/clk/clk-fixed-rate.c index f85ec8d1711fb7f36ac2e724308745dbf7b1ef47..cd9dc925b3f85901822cdaf1c015eda743ffc040 100644 --- a/drivers/clk/clk-fixed-rate.c +++ b/drivers/clk/clk-fixed-rate.c @@ -26,8 +26,6 @@ * parent - fixed parent. No clk_set_parent support */ -#define to_clk_fixed_rate(_hw) container_of(_hw, struct clk_fixed_rate, hw) - static unsigned long clk_fixed_rate_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { @@ -106,6 +104,19 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name, } EXPORT_SYMBOL_GPL(clk_register_fixed_rate); +void clk_unregister_fixed_rate(struct clk *clk) +{ + struct clk_hw *hw; + + hw = __clk_get_hw(clk); + if (!hw) + return; + + clk_unregister(clk); + kfree(to_clk_fixed_rate(hw)); +} +EXPORT_SYMBOL_GPL(clk_unregister_fixed_rate); + #ifdef CONFIG_OF /** * of_fixed_clk_setup() - Setup function for simple fixed rate clock @@ -125,8 +136,7 @@ void of_fixed_clk_setup(struct device_node *node) of_property_read_string(node, "clock-output-names", &clk_name); clk = clk_register_fixed_rate_with_accuracy(NULL, clk_name, NULL, - CLK_IS_ROOT, rate, - accuracy); + 0, rate, accuracy); if (!IS_ERR(clk)) of_clk_add_provider(node, of_clk_src_simple_get, clk); } diff --git a/drivers/clk/clk-fractional-divider.c b/drivers/clk/clk-fractional-divider.c index 5c4955e33f7a259711b960593941df38d526f2bb..1abcd76b4993805f2b135b92e5bc285b10de5c95 100644 --- a/drivers/clk/clk-fractional-divider.c +++ b/drivers/clk/clk-fractional-divider.c @@ -16,8 +16,6 @@ #include #include -#define to_clk_fd(_hw) container_of(_hw, struct clk_fractional_divider, hw) - static unsigned long clk_fd_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c index de0b322f5f58d4a57677455e6a5a2a78dcf0687d..d0d8ec8e1f1b0c8ae6de9457179ddf6bb8616434 100644 --- a/drivers/clk/clk-gate.c +++ b/drivers/clk/clk-gate.c @@ -26,8 +26,6 @@ * parent - fixed parent. No clk_set_parent support */ -#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw) - /* * It works on following logic: * diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c index 7b09a265d79fc8595a31332ecd40480beaed7bc5..08f65acc5d57b99f122d22d06ee4487ad9ed424f 100644 --- a/drivers/clk/clk-gpio.c +++ b/drivers/clk/clk-gpio.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include /** * DOC: basic gpio gated clock which can be enabled and disabled @@ -31,8 +33,6 @@ * parent - fixed parent. No clk_set_parent support */ -#define to_clk_gpio(_hw) container_of(_hw, struct clk_gpio, hw) - static int clk_gpio_gate_enable(struct clk_hw *hw) { struct clk_gpio *clk = to_clk_gpio(hw); @@ -201,134 +201,69 @@ struct clk *clk_register_gpio_mux(struct device *dev, const char *name, } EXPORT_SYMBOL_GPL(clk_register_gpio_mux); -#ifdef CONFIG_OF -/** - * clk_register_get() has to be delayed, because -EPROBE_DEFER - * can not be handled properly at of_clk_init() call time. - */ - -struct clk_gpio_delayed_register_data { - const char *gpio_name; - int num_parents; - const char **parent_names; - struct device_node *node; - struct mutex lock; - struct clk *clk; - struct clk *(*clk_register_get)(const char *name, - const char * const *parent_names, u8 num_parents, - unsigned gpio, bool active_low); -}; - -static struct clk *of_clk_gpio_delayed_register_get( - struct of_phandle_args *clkspec, void *_data) +static int gpio_clk_driver_probe(struct platform_device *pdev) { - struct clk_gpio_delayed_register_data *data = _data; - struct clk *clk; + struct device_node *node = pdev->dev.of_node; + const char **parent_names, *gpio_name; + unsigned int num_parents; int gpio; enum of_gpio_flags of_flags; + struct clk *clk; + bool active_low, is_mux; - mutex_lock(&data->lock); + num_parents = of_clk_get_parent_count(node); + if (num_parents) { + parent_names = devm_kcalloc(&pdev->dev, num_parents, + sizeof(char *), GFP_KERNEL); + if (!parent_names) + return -ENOMEM; - if (data->clk) { - mutex_unlock(&data->lock); - return data->clk; + of_clk_parent_fill(node, parent_names, num_parents); + } else { + parent_names = NULL; } - gpio = of_get_named_gpio_flags(data->node, data->gpio_name, 0, - &of_flags); + is_mux = of_device_is_compatible(node, "gpio-mux-clock"); + + gpio_name = is_mux ? "select-gpios" : "enable-gpios"; + gpio = of_get_named_gpio_flags(node, gpio_name, 0, &of_flags); if (gpio < 0) { - mutex_unlock(&data->lock); if (gpio == -EPROBE_DEFER) pr_debug("%s: %s: GPIOs not yet available, retry later\n", - data->node->name, __func__); + node->name, __func__); else pr_err("%s: %s: Can't get '%s' DT property\n", - data->node->name, __func__, - data->gpio_name); - return ERR_PTR(gpio); + node->name, __func__, + gpio_name); + return gpio; } - clk = data->clk_register_get(data->node->name, data->parent_names, - data->num_parents, gpio, of_flags & OF_GPIO_ACTIVE_LOW); - if (IS_ERR(clk)) - goto out; - - data->clk = clk; -out: - mutex_unlock(&data->lock); - - return clk; -} - -static struct clk *of_clk_gpio_gate_delayed_register_get(const char *name, - const char * const *parent_names, u8 num_parents, - unsigned gpio, bool active_low) -{ - return clk_register_gpio_gate(NULL, name, parent_names ? - parent_names[0] : NULL, gpio, active_low, 0); -} - -static struct clk *of_clk_gpio_mux_delayed_register_get(const char *name, - const char * const *parent_names, u8 num_parents, unsigned gpio, - bool active_low) -{ - return clk_register_gpio_mux(NULL, name, parent_names, num_parents, - gpio, active_low, 0); -} - -static void __init of_gpio_clk_setup(struct device_node *node, - const char *gpio_name, - struct clk *(*clk_register_get)(const char *name, - const char * const *parent_names, - u8 num_parents, - unsigned gpio, bool active_low)) -{ - struct clk_gpio_delayed_register_data *data; - const char **parent_names; - int i, num_parents; - - num_parents = of_clk_get_parent_count(node); - if (num_parents < 0) - num_parents = 0; - - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) - return; - - if (num_parents) { - parent_names = kcalloc(num_parents, sizeof(char *), GFP_KERNEL); - if (!parent_names) { - kfree(data); - return; - } - - for (i = 0; i < num_parents; i++) - parent_names[i] = of_clk_get_parent_name(node, i); - } else { - parent_names = NULL; - } + active_low = of_flags & OF_GPIO_ACTIVE_LOW; - data->num_parents = num_parents; - data->parent_names = parent_names; - data->node = node; - data->gpio_name = gpio_name; - data->clk_register_get = clk_register_get; - mutex_init(&data->lock); + if (is_mux) + clk = clk_register_gpio_mux(&pdev->dev, node->name, + parent_names, num_parents, gpio, active_low, 0); + else + clk = clk_register_gpio_gate(&pdev->dev, node->name, + parent_names ? parent_names[0] : NULL, gpio, + active_low, 0); + if (IS_ERR(clk)) + return PTR_ERR(clk); - of_clk_add_provider(node, of_clk_gpio_delayed_register_get, data); + return of_clk_add_provider(node, of_clk_src_simple_get, clk); } -static void __init of_gpio_gate_clk_setup(struct device_node *node) -{ - of_gpio_clk_setup(node, "enable-gpios", - of_clk_gpio_gate_delayed_register_get); -} -CLK_OF_DECLARE(gpio_gate_clk, "gpio-gate-clock", of_gpio_gate_clk_setup); +static const struct of_device_id gpio_clk_match_table[] = { + { .compatible = "gpio-mux-clock" }, + { .compatible = "gpio-gate-clock" }, + { } +}; -void __init of_gpio_mux_clk_setup(struct device_node *node) -{ - of_gpio_clk_setup(node, "select-gpios", - of_clk_gpio_mux_delayed_register_get); -} -CLK_OF_DECLARE(gpio_mux_clk, "gpio-mux-clock", of_gpio_mux_clk_setup); -#endif +static struct platform_driver gpio_clk_driver = { + .probe = gpio_clk_driver_probe, + .driver = { + .name = "gpio-clk", + .of_match_table = gpio_clk_match_table, + }, +}; +builtin_platform_driver(gpio_clk_driver); diff --git a/drivers/clk/clk-max77686.c b/drivers/clk/clk-max77686.c index 446c2fe76dc28635b28b0fb116aaf5cd7e79e30e..9b6f2772e948ffca489046265a6d2729fddfb85e 100644 --- a/drivers/clk/clk-max77686.c +++ b/drivers/clk/clk-max77686.c @@ -38,17 +38,14 @@ static struct clk_init_data max77686_clks_init[MAX77686_CLKS_NUM] = { [MAX77686_CLK_AP] = { .name = "32khz_ap", .ops = &max_gen_clk_ops, - .flags = CLK_IS_ROOT, }, [MAX77686_CLK_CP] = { .name = "32khz_cp", .ops = &max_gen_clk_ops, - .flags = CLK_IS_ROOT, }, [MAX77686_CLK_PMIC] = { .name = "32khz_pmic", .ops = &max_gen_clk_ops, - .flags = CLK_IS_ROOT, }, }; diff --git a/drivers/clk/clk-max77802.c b/drivers/clk/clk-max77802.c index 4a89f7979ba070c3a90b93d7fdd757d3fd76ab8b..355dd2e522c38070af1e2c4e92c9d10be4895baf 100644 --- a/drivers/clk/clk-max77802.c +++ b/drivers/clk/clk-max77802.c @@ -39,12 +39,10 @@ static struct clk_init_data max77802_clks_init[MAX77802_CLKS_NUM] = { [MAX77802_CLK_32K_AP] = { .name = "32khz_ap", .ops = &max_gen_clk_ops, - .flags = CLK_IS_ROOT, }, [MAX77802_CLK_32K_CP] = { .name = "32khz_cp", .ops = &max_gen_clk_ops, - .flags = CLK_IS_ROOT, }, }; diff --git a/drivers/clk/clk-mb86s7x.c b/drivers/clk/clk-mb86s7x.c index f39c25a22f43047ed743b15280effc511bf1ef14..e0817754ca3eb65973f9050e088b653621ae5c63 100644 --- a/drivers/clk/clk-mb86s7x.c +++ b/drivers/clk/clk-mb86s7x.c @@ -217,7 +217,7 @@ static struct clk *crg11_get(struct of_phandle_args *clkspec, void *data) init.name = clkp; init.num_parents = 0; init.ops = &crg_port_ops; - init.flags = CLK_IS_ROOT; + init.flags = 0; crgclk->hw.init = &init; crgclk->cntrlr = cntrlr; crgclk->domain = domain; @@ -341,7 +341,7 @@ struct clk *mb86s7x_clclk_register(struct device *cpu_dev) init.name = dev_name(cpu_dev); init.ops = &clk_clc_ops; - init.flags = CLK_IS_ROOT | CLK_GET_RATE_NOCACHE; + init.flags = CLK_GET_RATE_NOCACHE; init.num_parents = 0; return devm_clk_register(cpu_dev, &clc->hw); diff --git a/drivers/clk/clk-multiplier.c b/drivers/clk/clk-multiplier.c index fe7806506bf34e8a554a815cef99c5afba754b26..9e449c7b751c328e23b074186e1bebf426172087 100644 --- a/drivers/clk/clk-multiplier.c +++ b/drivers/clk/clk-multiplier.c @@ -14,8 +14,6 @@ #include #include -#define to_clk_multiplier(_hw) container_of(_hw, struct clk_multiplier, hw) - static unsigned long __get_mult(struct clk_multiplier *mult, unsigned long rate, unsigned long parent_rate) diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c index 5ed03c8a8df9e122b904d5c62bb603f884d4deb5..252188fd8bcdf49872bff06d313142df6d297ba3 100644 --- a/drivers/clk/clk-mux.c +++ b/drivers/clk/clk-mux.c @@ -26,8 +26,6 @@ * parent - parent is adjustable through clk_set_parent */ -#define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw) - static u8 clk_mux_get_parent(struct clk_hw *hw) { struct clk_mux *mux = to_clk_mux(hw); diff --git a/drivers/clk/clk-palmas.c b/drivers/clk/clk-palmas.c index 8e3039f0c3f9544de39bc8c06be41a2337b8492a..9c0b8e6b1ab322b13aaef11ddb451c1b84ecffc9 100644 --- a/drivers/clk/clk-palmas.c +++ b/drivers/clk/clk-palmas.c @@ -44,7 +44,7 @@ struct palmas_clock_info { struct clk *clk; struct clk_hw hw; struct palmas *palmas; - struct palmas_clk32k_desc *clk_desc; + const struct palmas_clk32k_desc *clk_desc; int ext_control_pin; }; @@ -125,10 +125,10 @@ static struct clk_ops palmas_clks_ops = { struct palmas_clks_of_match_data { struct clk_init_data init; - struct palmas_clk32k_desc desc; + const struct palmas_clk32k_desc desc; }; -static struct palmas_clks_of_match_data palmas_of_clk32kg = { +static const struct palmas_clks_of_match_data palmas_of_clk32kg = { .init = { .name = "clk32kg", .ops = &palmas_clks_ops, @@ -144,7 +144,7 @@ static struct palmas_clks_of_match_data palmas_of_clk32kg = { }, }; -static struct palmas_clks_of_match_data palmas_of_clk32kgaudio = { +static const struct palmas_clks_of_match_data palmas_of_clk32kgaudio = { .init = { .name = "clk32kgaudio", .ops = &palmas_clks_ops, @@ -240,14 +240,14 @@ static int palmas_clks_probe(struct platform_device *pdev) { struct palmas *palmas = dev_get_drvdata(pdev->dev.parent); struct device_node *node = pdev->dev.of_node; - struct palmas_clks_of_match_data *match_data; - const struct of_device_id *match; + const struct palmas_clks_of_match_data *match_data; struct palmas_clock_info *cinfo; struct clk *clk; int ret; - match = of_match_device(palmas_clks_of_match, &pdev->dev); - match_data = (struct palmas_clks_of_match_data *)match->data; + match_data = of_device_get_match_data(&pdev->dev); + if (!match_data) + return 1; cinfo = devm_kzalloc(&pdev->dev, sizeof(*cinfo), GFP_KERNEL); if (!cinfo) diff --git a/drivers/clk/clk-pwm.c b/drivers/clk/clk-pwm.c index 328fcfcefd8c5f0303457dfee3201ebd5d5550c0..883045814dac2536fcb667b36e3db01d8715596e 100644 --- a/drivers/clk/clk-pwm.c +++ b/drivers/clk/clk-pwm.c @@ -95,7 +95,7 @@ static int clk_pwm_probe(struct platform_device *pdev) init.name = clk_name; init.ops = &clk_pwm_ops; - init.flags = CLK_IS_BASIC | CLK_IS_ROOT; + init.flags = CLK_IS_BASIC; init.num_parents = 0; clk_pwm->pwm = pwm; diff --git a/drivers/clk/clk-s2mps11.c b/drivers/clk/clk-s2mps11.c index d266299dfdb1a26e22477f78a2c389d5dc858f4f..f8c83977c7fa8ded548f9d6af43a954e41599c81 100644 --- a/drivers/clk/clk-s2mps11.c +++ b/drivers/clk/clk-s2mps11.c @@ -28,11 +28,6 @@ #include #include -#define s2mps11_name(a) (a->hw.init->name) - -static struct clk **clk_table; -static struct clk_onecell_data clk_data; - enum { S2MPS11_CLK_AP = 0, S2MPS11_CLK_CP, @@ -99,52 +94,19 @@ static struct clk_ops s2mps11_clk_ops = { .recalc_rate = s2mps11_clk_recalc_rate, }; +/* This s2mps11_clks_init tructure is common to s2mps11, s2mps13 and s2mps14 */ static struct clk_init_data s2mps11_clks_init[S2MPS11_CLKS_NUM] = { [S2MPS11_CLK_AP] = { .name = "s2mps11_ap", .ops = &s2mps11_clk_ops, - .flags = CLK_IS_ROOT, }, [S2MPS11_CLK_CP] = { .name = "s2mps11_cp", .ops = &s2mps11_clk_ops, - .flags = CLK_IS_ROOT, }, [S2MPS11_CLK_BT] = { .name = "s2mps11_bt", .ops = &s2mps11_clk_ops, - .flags = CLK_IS_ROOT, - }, -}; - -static struct clk_init_data s2mps13_clks_init[S2MPS11_CLKS_NUM] = { - [S2MPS11_CLK_AP] = { - .name = "s2mps13_ap", - .ops = &s2mps11_clk_ops, - .flags = CLK_IS_ROOT, - }, - [S2MPS11_CLK_CP] = { - .name = "s2mps13_cp", - .ops = &s2mps11_clk_ops, - .flags = CLK_IS_ROOT, - }, - [S2MPS11_CLK_BT] = { - .name = "s2mps13_bt", - .ops = &s2mps11_clk_ops, - .flags = CLK_IS_ROOT, - }, -}; - -static struct clk_init_data s2mps14_clks_init[S2MPS11_CLKS_NUM] = { - [S2MPS11_CLK_AP] = { - .name = "s2mps14_ap", - .ops = &s2mps11_clk_ops, - .flags = CLK_IS_ROOT, - }, - [S2MPS11_CLK_BT] = { - .name = "s2mps14_bt", - .ops = &s2mps11_clk_ops, - .flags = CLK_IS_ROOT, }, }; @@ -164,12 +126,9 @@ static struct device_node *s2mps11_clk_parse_dt(struct platform_device *pdev, return ERR_PTR(-EINVAL); } - for (i = 0; i < S2MPS11_CLKS_NUM; i++) { - if (!clks_init[i].name) - continue; /* Skip clocks not present in some devices */ + for (i = 0; i < S2MPS11_CLKS_NUM; i++) of_property_read_string_index(clk_np, "clock-output-names", i, &clks_init[i].name); - } return clk_np; } @@ -177,39 +136,38 @@ static struct device_node *s2mps11_clk_parse_dt(struct platform_device *pdev, static int s2mps11_clk_probe(struct platform_device *pdev) { struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); - struct s2mps11_clk *s2mps11_clks, *s2mps11_clk; + struct s2mps11_clk *s2mps11_clks; + struct clk_onecell_data *clk_data; unsigned int s2mps11_reg; - struct clk_init_data *clks_init; int i, ret = 0; + enum sec_device_type hwid = platform_get_device_id(pdev)->driver_data; s2mps11_clks = devm_kcalloc(&pdev->dev, S2MPS11_CLKS_NUM, - sizeof(*s2mps11_clk), GFP_KERNEL); + sizeof(*s2mps11_clks), GFP_KERNEL); if (!s2mps11_clks) return -ENOMEM; - s2mps11_clk = s2mps11_clks; + clk_data = devm_kzalloc(&pdev->dev, sizeof(*clk_data), GFP_KERNEL); + if (!clk_data) + return -ENOMEM; - clk_table = devm_kcalloc(&pdev->dev, S2MPS11_CLKS_NUM, + clk_data->clks = devm_kcalloc(&pdev->dev, S2MPS11_CLKS_NUM, sizeof(struct clk *), GFP_KERNEL); - if (!clk_table) + if (!clk_data->clks) return -ENOMEM; - switch(platform_get_device_id(pdev)->driver_data) { + switch (hwid) { case S2MPS11X: s2mps11_reg = S2MPS11_REG_RTC_CTRL; - clks_init = s2mps11_clks_init; break; case S2MPS13X: s2mps11_reg = S2MPS13_REG_RTCCTRL; - clks_init = s2mps13_clks_init; break; case S2MPS14X: s2mps11_reg = S2MPS14_REG_RTCCTRL; - clks_init = s2mps14_clks_init; break; case S5M8767X: s2mps11_reg = S5M8767_REG_CTRL1; - clks_init = s2mps11_clks_init; break; default: dev_err(&pdev->dev, "Invalid device type\n"); @@ -217,46 +175,39 @@ static int s2mps11_clk_probe(struct platform_device *pdev) } /* Store clocks of_node in first element of s2mps11_clks array */ - s2mps11_clks->clk_np = s2mps11_clk_parse_dt(pdev, clks_init); + s2mps11_clks->clk_np = s2mps11_clk_parse_dt(pdev, s2mps11_clks_init); if (IS_ERR(s2mps11_clks->clk_np)) return PTR_ERR(s2mps11_clks->clk_np); - for (i = 0; i < S2MPS11_CLKS_NUM; i++, s2mps11_clk++) { - if (!clks_init[i].name) + for (i = 0; i < S2MPS11_CLKS_NUM; i++) { + if (i == S2MPS11_CLK_CP && hwid == S2MPS14X) continue; /* Skip clocks not present in some devices */ - s2mps11_clk->iodev = iodev; - s2mps11_clk->hw.init = &clks_init[i]; - s2mps11_clk->mask = 1 << i; - s2mps11_clk->reg = s2mps11_reg; - - s2mps11_clk->clk = devm_clk_register(&pdev->dev, - &s2mps11_clk->hw); - if (IS_ERR(s2mps11_clk->clk)) { + s2mps11_clks[i].iodev = iodev; + s2mps11_clks[i].hw.init = &s2mps11_clks_init[i]; + s2mps11_clks[i].mask = 1 << i; + s2mps11_clks[i].reg = s2mps11_reg; + + s2mps11_clks[i].clk = devm_clk_register(&pdev->dev, + &s2mps11_clks[i].hw); + if (IS_ERR(s2mps11_clks[i].clk)) { dev_err(&pdev->dev, "Fail to register : %s\n", - s2mps11_name(s2mps11_clk)); - ret = PTR_ERR(s2mps11_clk->clk); + s2mps11_clks_init[i].name); + ret = PTR_ERR(s2mps11_clks[i].clk); goto err_reg; } - s2mps11_clk->lookup = clkdev_create(s2mps11_clk->clk, - s2mps11_name(s2mps11_clk), NULL); - if (!s2mps11_clk->lookup) { + s2mps11_clks[i].lookup = clkdev_create(s2mps11_clks[i].clk, + s2mps11_clks_init[i].name, NULL); + if (!s2mps11_clks[i].lookup) { ret = -ENOMEM; goto err_reg; } + clk_data->clks[i] = s2mps11_clks[i].clk; } - for (i = 0; i < S2MPS11_CLKS_NUM; i++) { - /* Skip clocks not present on S2MPS14 */ - if (!clks_init[i].name) - continue; - clk_table[i] = s2mps11_clks[i].clk; - } - - clk_data.clks = clk_table; - clk_data.clk_num = S2MPS11_CLKS_NUM; + clk_data->clk_num = S2MPS11_CLKS_NUM; of_clk_add_provider(s2mps11_clks->clk_np, of_clk_src_onecell_get, - &clk_data); + clk_data); platform_set_drvdata(pdev, s2mps11_clks); diff --git a/drivers/clk/clk-scpi.c b/drivers/clk/clk-scpi.c index 89e9ca78bb947ec2ff8242d5d826ccf8449d6259..6962ee5d1e9a8e4bf6066886f8f4e708444d78b9 100644 --- a/drivers/clk/clk-scpi.c +++ b/drivers/clk/clk-scpi.c @@ -155,7 +155,7 @@ scpi_clk_ops_init(struct device *dev, const struct of_device_id *match, unsigned long min = 0, max = 0; init.name = name; - init.flags = CLK_IS_ROOT; + init.flags = 0; init.num_parents = 0; init.ops = match->data; sclk->hw.init = &init; diff --git a/drivers/clk/clk-si514.c b/drivers/clk/clk-si514.c index 6af7dce542411eadc79ea308fa89307efb36f11c..ceef25b0990bb96df60ae6334859b1246e2ac86a 100644 --- a/drivers/clk/clk-si514.c +++ b/drivers/clk/clk-si514.c @@ -313,7 +313,7 @@ static int si514_probe(struct i2c_client *client, return -ENOMEM; init.ops = &si514_clk_ops; - init.flags = CLK_IS_ROOT; + init.flags = 0; init.num_parents = 0; data->hw.init = &init; data->i2c_client = client; diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c index 850316ac88317a485dd77e8811dac736ce8da6ac..b1bc12c045d34aff63f271bcc6faf93ecce2bff0 100644 --- a/drivers/clk/clk-si5351.c +++ b/drivers/clk/clk-si5351.c @@ -1495,7 +1495,7 @@ static int si5351_i2c_probe(struct i2c_client *client, if (drvdata->variant == SI5351_VARIANT_B) { init.name = si5351_pll_names[2]; init.ops = &si5351_vxco_ops; - init.flags = CLK_IS_ROOT; + init.flags = 0; init.parent_names = NULL; init.num_parents = 0; } else { diff --git a/drivers/clk/clk-si570.c b/drivers/clk/clk-si570.c index cf478aa9fa5d9e9b791d6fc9cd32ffaa1864d10a..d56648521a958ca6f78dda775f279ca7fceae0c4 100644 --- a/drivers/clk/clk-si570.c +++ b/drivers/clk/clk-si570.c @@ -418,7 +418,7 @@ static int si570_probe(struct i2c_client *client, return -ENOMEM; init.ops = &si570_clk_ops; - init.flags = CLK_IS_ROOT; + init.flags = 0; init.num_parents = 0; data->hw.init = &init; data->i2c_client = client; diff --git a/drivers/clk/clk-vt8500.c b/drivers/clk/clk-vt8500.c index 37e928846ec5b3fb1fed8144570c1f8aeaa027bb..b0f76a84f1e9fec9d3f2bcc7ec0f41eec37fbf93 100644 --- a/drivers/clk/clk-vt8500.c +++ b/drivers/clk/clk-vt8500.c @@ -355,7 +355,7 @@ CLK_OF_DECLARE(vt8500_device, "via,vt8500-device-clock", vtwm_device_clk_init); #define WM8850_BITS_TO_VAL(m, d1, d2) \ ((((m / 2) - 1) << 16) | ((d1 - 1) << 8) | d2) -static void vt8500_find_pll_bits(unsigned long rate, unsigned long parent_rate, +static int vt8500_find_pll_bits(unsigned long rate, unsigned long parent_rate, u32 *multiplier, u32 *prediv) { unsigned long tclk; @@ -365,7 +365,7 @@ static void vt8500_find_pll_bits(unsigned long rate, unsigned long parent_rate, pr_err("%s: requested rate out of range\n", __func__); *multiplier = 0; *prediv = 1; - return; + return -EINVAL; } if (rate <= parent_rate * 31) /* use the prediv to double the resolution */ @@ -379,12 +379,15 @@ static void vt8500_find_pll_bits(unsigned long rate, unsigned long parent_rate, if (tclk != rate) pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate, tclk); + + return 0; } -static void wm8650_find_pll_bits(unsigned long rate, unsigned long parent_rate, +static int wm8650_find_pll_bits(unsigned long rate, unsigned long parent_rate, u32 *multiplier, u32 *divisor1, u32 *divisor2) { - u32 mul, div1, div2; + u32 mul, div1; + int div2; u32 best_mul, best_div1, best_div2; unsigned long tclk, rate_err, best_err; @@ -403,7 +406,7 @@ static void wm8650_find_pll_bits(unsigned long rate, unsigned long parent_rate, *multiplier = mul; *divisor1 = div1; *divisor2 = div2; - return; + return 0; } if (rate_err < best_err) { @@ -414,12 +417,19 @@ static void wm8650_find_pll_bits(unsigned long rate, unsigned long parent_rate, } } + if (best_err == (unsigned long)-1) { + pr_warn("%s: impossible rate %lu\n", __func__, rate); + return -EINVAL; + } + /* if we got here, it wasn't an exact match */ pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate, rate - best_err); *multiplier = best_mul; *divisor1 = best_div1; *divisor2 = best_div2; + + return 0; } static u32 wm8750_get_filter(u32 parent_rate, u32 divisor1) @@ -449,10 +459,11 @@ static u32 wm8750_get_filter(u32 parent_rate, u32 divisor1) return 0; } -static void wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate, +static int wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate, u32 *filter, u32 *multiplier, u32 *divisor1, u32 *divisor2) { - u32 mul, div1, div2; + u32 mul; + int div1, div2; u32 best_mul, best_div1, best_div2; unsigned long tclk, rate_err, best_err; @@ -472,7 +483,7 @@ static void wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate, *multiplier = mul; *divisor1 = div1; *divisor2 = div2; - return; + return 0; } if (rate_err < best_err) { @@ -483,6 +494,11 @@ static void wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate, } } + if (best_err == (unsigned long)-1) { + pr_warn("%s: impossible rate %lu\n", __func__, rate); + return -EINVAL; + } + /* if we got here, it wasn't an exact match */ pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate, rate - best_err); @@ -491,12 +507,15 @@ static void wm8750_find_pll_bits(unsigned long rate, unsigned long parent_rate, *multiplier = best_mul; *divisor1 = best_div1; *divisor2 = best_div2; + + return 0; } -static void wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate, +static int wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate, u32 *multiplier, u32 *divisor1, u32 *divisor2) { - u32 mul, div1, div2; + u32 mul; + int div1, div2; u32 best_mul, best_div1, best_div2; unsigned long tclk, rate_err, best_err; @@ -516,7 +535,7 @@ static void wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate, *multiplier = mul; *divisor1 = div1; *divisor2 = div2; - return; + return 0; } if (rate_err < best_err) { @@ -527,6 +546,11 @@ static void wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate, } } + if (best_err == (unsigned long)-1) { + pr_warn("%s: impossible rate %lu\n", __func__, rate); + return -EINVAL; + } + /* if we got here, it wasn't an exact match */ pr_warn("%s: requested rate %lu, found rate %lu\n", __func__, rate, rate - best_err); @@ -534,6 +558,8 @@ static void wm8850_find_pll_bits(unsigned long rate, unsigned long parent_rate, *multiplier = best_mul; *divisor1 = best_div1; *divisor2 = best_div2; + + return 0; } static int vtwm_pll_set_rate(struct clk_hw *hw, unsigned long rate, @@ -543,31 +569,39 @@ static int vtwm_pll_set_rate(struct clk_hw *hw, unsigned long rate, u32 filter, mul, div1, div2; u32 pll_val; unsigned long flags = 0; + int ret; /* sanity check */ switch (pll->type) { case PLL_TYPE_VT8500: - vt8500_find_pll_bits(rate, parent_rate, &mul, &div1); - pll_val = VT8500_BITS_TO_VAL(mul, div1); + ret = vt8500_find_pll_bits(rate, parent_rate, &mul, &div1); + if (!ret) + pll_val = VT8500_BITS_TO_VAL(mul, div1); break; case PLL_TYPE_WM8650: - wm8650_find_pll_bits(rate, parent_rate, &mul, &div1, &div2); - pll_val = WM8650_BITS_TO_VAL(mul, div1, div2); + ret = wm8650_find_pll_bits(rate, parent_rate, &mul, &div1, &div2); + if (!ret) + pll_val = WM8650_BITS_TO_VAL(mul, div1, div2); break; case PLL_TYPE_WM8750: - wm8750_find_pll_bits(rate, parent_rate, &filter, &mul, &div1, &div2); - pll_val = WM8750_BITS_TO_VAL(filter, mul, div1, div2); + ret = wm8750_find_pll_bits(rate, parent_rate, &filter, &mul, &div1, &div2); + if (!ret) + pll_val = WM8750_BITS_TO_VAL(filter, mul, div1, div2); break; case PLL_TYPE_WM8850: - wm8850_find_pll_bits(rate, parent_rate, &mul, &div1, &div2); - pll_val = WM8850_BITS_TO_VAL(mul, div1, div2); + ret = wm8850_find_pll_bits(rate, parent_rate, &mul, &div1, &div2); + if (!ret) + pll_val = WM8850_BITS_TO_VAL(mul, div1, div2); break; default: pr_err("%s: invalid pll type\n", __func__); - return 0; + ret = -EINVAL; } + if (ret) + return ret; + spin_lock_irqsave(pll->lock, flags); vt8500_pmc_wait_busy(); @@ -585,28 +619,36 @@ static long vtwm_pll_round_rate(struct clk_hw *hw, unsigned long rate, struct clk_pll *pll = to_clk_pll(hw); u32 filter, mul, div1, div2; long round_rate; + int ret; switch (pll->type) { case PLL_TYPE_VT8500: - vt8500_find_pll_bits(rate, *prate, &mul, &div1); - round_rate = VT8500_BITS_TO_FREQ(*prate, mul, div1); + ret = vt8500_find_pll_bits(rate, *prate, &mul, &div1); + if (!ret) + round_rate = VT8500_BITS_TO_FREQ(*prate, mul, div1); break; case PLL_TYPE_WM8650: - wm8650_find_pll_bits(rate, *prate, &mul, &div1, &div2); - round_rate = WM8650_BITS_TO_FREQ(*prate, mul, div1, div2); + ret = wm8650_find_pll_bits(rate, *prate, &mul, &div1, &div2); + if (!ret) + round_rate = WM8650_BITS_TO_FREQ(*prate, mul, div1, div2); break; case PLL_TYPE_WM8750: - wm8750_find_pll_bits(rate, *prate, &filter, &mul, &div1, &div2); - round_rate = WM8750_BITS_TO_FREQ(*prate, mul, div1, div2); + ret = wm8750_find_pll_bits(rate, *prate, &filter, &mul, &div1, &div2); + if (!ret) + round_rate = WM8750_BITS_TO_FREQ(*prate, mul, div1, div2); break; case PLL_TYPE_WM8850: - wm8850_find_pll_bits(rate, *prate, &mul, &div1, &div2); - round_rate = WM8850_BITS_TO_FREQ(*prate, mul, div1, div2); + ret = wm8850_find_pll_bits(rate, *prate, &mul, &div1, &div2); + if (!ret) + round_rate = WM8850_BITS_TO_FREQ(*prate, mul, div1, div2); break; default: - round_rate = 0; + ret = -EINVAL; } + if (ret) + return ret; + return round_rate; } diff --git a/drivers/clk/clk-xgene.c b/drivers/clk/clk-xgene.c index 10224b01b97c5c6206372f36f9f81fa7ed861b56..d73450b60b2808413b7ca886644ff46e82a9d09e 100644 --- a/drivers/clk/clk-xgene.c +++ b/drivers/clk/clk-xgene.c @@ -29,7 +29,9 @@ #include /* Register SCU_PCPPLL bit fields */ -#define N_DIV_RD(src) (((src) & 0x000001ff)) +#define N_DIV_RD(src) ((src) & 0x000001ff) +#define SC_N_DIV_RD(src) ((src) & 0x0000007f) +#define SC_OUTDIV2(src) (((src) & 0x00000100) >> 8) /* Register SCU_SOCPLL bit fields */ #define CLKR_RD(src) (((src) & 0x07000000)>>24) @@ -48,7 +50,7 @@ static inline u32 xgene_clk_read(void __iomem *csr) static inline void xgene_clk_write(u32 data, void __iomem *csr) { - return writel_relaxed(data, csr); + writel_relaxed(data, csr); } /* PLL Clock */ @@ -63,6 +65,7 @@ struct xgene_clk_pll { spinlock_t *lock; u32 pll_offset; enum xgene_pll_type type; + int version; }; #define to_xgene_clk_pll(_hw) container_of(_hw, struct xgene_clk_pll, hw) @@ -92,27 +95,37 @@ static unsigned long xgene_clk_pll_recalc_rate(struct clk_hw *hw, pll = xgene_clk_read(pllclk->reg + pllclk->pll_offset); - if (pllclk->type == PLL_TYPE_PCP) { - /* - * PLL VCO = Reference clock * NF - * PCP PLL = PLL_VCO / 2 - */ - nout = 2; - fvco = parent_rate * (N_DIV_RD(pll) + 4); + if (pllclk->version <= 1) { + if (pllclk->type == PLL_TYPE_PCP) { + /* + * PLL VCO = Reference clock * NF + * PCP PLL = PLL_VCO / 2 + */ + nout = 2; + fvco = parent_rate * (N_DIV_RD(pll) + 4); + } else { + /* + * Fref = Reference Clock / NREF; + * Fvco = Fref * NFB; + * Fout = Fvco / NOUT; + */ + nref = CLKR_RD(pll) + 1; + nout = CLKOD_RD(pll) + 1; + nfb = CLKF_RD(pll); + fref = parent_rate / nref; + fvco = fref * nfb; + } } else { /* - * Fref = Reference Clock / NREF; - * Fvco = Fref * NFB; - * Fout = Fvco / NOUT; + * fvco = Reference clock * FBDIVC + * PLL freq = fvco / NOUT */ - nref = CLKR_RD(pll) + 1; - nout = CLKOD_RD(pll) + 1; - nfb = CLKF_RD(pll); - fref = parent_rate / nref; - fvco = fref * nfb; + nout = SC_OUTDIV2(pll) ? 2 : 3; + fvco = parent_rate * SC_N_DIV_RD(pll); } - pr_debug("%s pll recalc rate %ld parent %ld\n", clk_hw_get_name(hw), - fvco / nout, parent_rate); + pr_debug("%s pll recalc rate %ld parent %ld version %d\n", + clk_hw_get_name(hw), fvco / nout, parent_rate, + pllclk->version); return fvco / nout; } @@ -125,7 +138,7 @@ static const struct clk_ops xgene_clk_pll_ops = { static struct clk *xgene_register_clk_pll(struct device *dev, const char *name, const char *parent_name, unsigned long flags, void __iomem *reg, u32 pll_offset, - u32 type, spinlock_t *lock) + u32 type, spinlock_t *lock, int version) { struct xgene_clk_pll *apmclk; struct clk *clk; @@ -144,6 +157,7 @@ static struct clk *xgene_register_clk_pll(struct device *dev, init.parent_names = parent_name ? &parent_name : NULL; init.num_parents = parent_name ? 1 : 0; + apmclk->version = version; apmclk->reg = reg; apmclk->lock = lock; apmclk->pll_offset = pll_offset; @@ -160,26 +174,37 @@ static struct clk *xgene_register_clk_pll(struct device *dev, return clk; } +static int xgene_pllclk_version(struct device_node *np) +{ + if (of_device_is_compatible(np, "apm,xgene-socpll-clock")) + return 1; + if (of_device_is_compatible(np, "apm,xgene-pcppll-clock")) + return 1; + return 2; +} + static void xgene_pllclk_init(struct device_node *np, enum xgene_pll_type pll_type) { - const char *clk_name = np->full_name; - struct clk *clk; - void __iomem *reg; + const char *clk_name = np->full_name; + struct clk *clk; + void __iomem *reg; + int version = xgene_pllclk_version(np); - reg = of_iomap(np, 0); - if (reg == NULL) { - pr_err("Unable to map CSR register for %s\n", np->full_name); - return; - } - of_property_read_string(np, "clock-output-names", &clk_name); - clk = xgene_register_clk_pll(NULL, - clk_name, of_clk_get_parent_name(np, 0), - CLK_IS_ROOT, reg, 0, pll_type, &clk_lock); - if (!IS_ERR(clk)) { - of_clk_add_provider(np, of_clk_src_simple_get, clk); - clk_register_clkdev(clk, clk_name, NULL); - pr_debug("Add %s clock PLL\n", clk_name); - } + reg = of_iomap(np, 0); + if (reg == NULL) { + pr_err("Unable to map CSR register for %s\n", np->full_name); + return; + } + of_property_read_string(np, "clock-output-names", &clk_name); + clk = xgene_register_clk_pll(NULL, + clk_name, of_clk_get_parent_name(np, 0), + CLK_IS_ROOT, reg, 0, pll_type, &clk_lock, + version); + if (!IS_ERR(clk)) { + of_clk_add_provider(np, of_clk_src_simple_get, clk); + clk_register_clkdev(clk, clk_name, NULL); + pr_debug("Add %s clock PLL\n", clk_name); + } } static void xgene_socpllclk_init(struct device_node *np) @@ -351,8 +376,8 @@ static int xgene_clk_set_rate(struct clk_hw *hw, unsigned long rate, /* Set new divider */ data = xgene_clk_read(pclk->param.divider_reg + pclk->param.reg_divider_offset); - data &= ~((1 << pclk->param.reg_divider_width) - 1) - << pclk->param.reg_divider_shift; + data &= ~(((1 << pclk->param.reg_divider_width) - 1) + << pclk->param.reg_divider_shift); data |= divider; xgene_clk_write(data, pclk->param.divider_reg + pclk->param.reg_divider_offset); @@ -460,7 +485,7 @@ static void __init xgene_devclk_init(struct device_node *np) rc = of_address_to_resource(np, i, &res); if (rc != 0) { if (i == 0) { - pr_err("no DTS register for %s\n", + pr_err("no DTS register for %s\n", np->full_name); return; } @@ -518,4 +543,8 @@ static void __init xgene_devclk_init(struct device_node *np) CLK_OF_DECLARE(xgene_socpll_clock, "apm,xgene-socpll-clock", xgene_socpllclk_init); CLK_OF_DECLARE(xgene_pcppll_clock, "apm,xgene-pcppll-clock", xgene_pcppllclk_init); +CLK_OF_DECLARE(xgene_socpll_v2_clock, "apm,xgene-socpll-v2-clock", + xgene_socpllclk_init); +CLK_OF_DECLARE(xgene_pcppll_v2_clock, "apm,xgene-pcppll-v2-clock", + xgene_pcppllclk_init); CLK_OF_DECLARE(xgene_dev_clock, "apm,xgene-device-clock", xgene_devclk_init); diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index b4db67a446c81ad961d8ab3e027f1ff955483efb..fb74dc1f7520503d72f024b596dc72d002851e4c 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -350,13 +350,12 @@ static struct clk_core *clk_core_get_parent_by_index(struct clk_core *core, { if (!core || index >= core->num_parents) return NULL; - else if (!core->parents) - return clk_core_lookup(core->parent_names[index]); - else if (!core->parents[index]) - return core->parents[index] = - clk_core_lookup(core->parent_names[index]); - else - return core->parents[index]; + + if (!core->parents[index]) + core->parents[index] = + clk_core_lookup(core->parent_names[index]); + + return core->parents[index]; } struct clk_hw * @@ -386,7 +385,7 @@ static unsigned long clk_core_get_rate_nolock(struct clk_core *core) ret = core->rate; - if (core->flags & CLK_IS_ROOT) + if (!core->num_parents) goto out; if (!core->parent) @@ -1067,30 +1066,12 @@ static int clk_fetch_parent_index(struct clk_core *core, { int i; - if (!core->parents) { - core->parents = kcalloc(core->num_parents, - sizeof(struct clk *), GFP_KERNEL); - if (!core->parents) - return -ENOMEM; - } - - /* - * find index of new parent clock using cached parent ptrs, - * or if not yet cached, use string name comparison and cache - * them now to avoid future calls to clk_core_lookup. - */ - for (i = 0; i < core->num_parents; i++) { - if (core->parents[i] == parent) - return i; - - if (core->parents[i]) - continue; + if (!parent) + return -EINVAL; - if (!strcmp(core->parent_names[i], parent->name)) { - core->parents[i] = clk_core_lookup(parent->name); + for (i = 0; i < core->num_parents; i++) + if (clk_core_get_parent_by_index(core, i) == parent) return i; - } - } return -EINVAL; } @@ -1677,56 +1658,14 @@ struct clk *clk_get_parent(struct clk *clk) } EXPORT_SYMBOL_GPL(clk_get_parent); -/* - * .get_parent is mandatory for clocks with multiple possible parents. It is - * optional for single-parent clocks. Always call .get_parent if it is - * available and WARN if it is missing for multi-parent clocks. - * - * For single-parent clocks without .get_parent, first check to see if the - * .parents array exists, and if so use it to avoid an expensive tree - * traversal. If .parents does not exist then walk the tree. - */ static struct clk_core *__clk_init_parent(struct clk_core *core) { - struct clk_core *ret = NULL; - u8 index; + u8 index = 0; - /* handle the trivial cases */ + if (core->num_parents > 1 && core->ops->get_parent) + index = core->ops->get_parent(core->hw); - if (!core->num_parents) - goto out; - - if (core->num_parents == 1) { - if (IS_ERR_OR_NULL(core->parent)) - core->parent = clk_core_lookup(core->parent_names[0]); - ret = core->parent; - goto out; - } - - if (!core->ops->get_parent) { - WARN(!core->ops->get_parent, - "%s: multi-parent clocks must implement .get_parent\n", - __func__); - goto out; - } - - /* - * Do our best to cache parent clocks in core->parents. This prevents - * unnecessary and expensive lookups. We don't set core->parent here; - * that is done by the calling function. - */ - - index = core->ops->get_parent(core->hw); - - if (!core->parents) - core->parents = - kcalloc(core->num_parents, sizeof(struct clk *), - GFP_KERNEL); - - ret = clk_core_get_parent_by_index(core, index); - -out: - return ret; + return clk_core_get_parent_by_index(core, index); } static void clk_core_reparent(struct clk_core *core, @@ -1809,13 +1748,13 @@ static int clk_core_set_parent(struct clk_core *core, struct clk_core *parent) /* try finding the new parent index */ if (parent) { p_index = clk_fetch_parent_index(core, parent); - p_rate = parent->rate; if (p_index < 0) { pr_debug("%s: clk %s can not be parent of clk %s\n", __func__, parent->name, core->name); ret = p_index; goto out; } + p_rate = parent->rate; } /* propagate PRE_RATE_CHANGE notifications */ @@ -1902,6 +1841,10 @@ int clk_set_phase(struct clk *clk, int degrees) clk_prepare_lock(); + /* bail early if nothing to do */ + if (degrees == clk->core->phase) + goto out; + trace_clk_set_phase(clk->core, degrees); if (clk->core->ops->set_phase) @@ -1912,6 +1855,7 @@ int clk_set_phase(struct clk *clk, int degrees) if (!ret) clk->core->phase = degrees; +out: clk_prepare_unlock(); return ret; @@ -2218,7 +2162,7 @@ static int clk_debug_register(struct clk_core *core) * * Dynamically removes a clk and all its child nodes from the * debugfs clk directory if clk->dentry points to debugfs created by - * clk_debug_register in __clk_init. + * clk_debug_register in __clk_core_init. */ static void clk_debug_unregister(struct clk_core *core) { @@ -2303,26 +2247,22 @@ static inline void clk_debug_unregister(struct clk_core *core) #endif /** - * __clk_init - initialize the data structures in a struct clk - * @dev: device initializing this clk, placeholder for now - * @clk: clk being initialized + * __clk_core_init - initialize the data structures in a struct clk_core + * @core: clk_core being initialized * * Initializes the lists in struct clk_core, queries the hardware for the * parent and rate and sets them both. */ -static int __clk_init(struct device *dev, struct clk *clk_user) +static int __clk_core_init(struct clk_core *core) { int i, ret = 0; struct clk_core *orphan; struct hlist_node *tmp2; - struct clk_core *core; unsigned long rate; - if (!clk_user) + if (!core) return -EINVAL; - core = clk_user->core; - clk_prepare_lock(); /* check to see if a clock with this name is already registered */ @@ -2337,22 +2277,29 @@ static int __clk_init(struct device *dev, struct clk *clk_user) if (core->ops->set_rate && !((core->ops->round_rate || core->ops->determine_rate) && core->ops->recalc_rate)) { - pr_warning("%s: %s must implement .round_rate or .determine_rate in addition to .recalc_rate\n", - __func__, core->name); + pr_err("%s: %s must implement .round_rate or .determine_rate in addition to .recalc_rate\n", + __func__, core->name); ret = -EINVAL; goto out; } if (core->ops->set_parent && !core->ops->get_parent) { - pr_warning("%s: %s must implement .get_parent & .set_parent\n", - __func__, core->name); + pr_err("%s: %s must implement .get_parent & .set_parent\n", + __func__, core->name); + ret = -EINVAL; + goto out; + } + + if (core->num_parents > 1 && !core->ops->get_parent) { + pr_err("%s: %s must implement .get_parent as it has multi parents\n", + __func__, core->name); ret = -EINVAL; goto out; } if (core->ops->set_rate_and_parent && !(core->ops->set_parent && core->ops->set_rate)) { - pr_warn("%s: %s must implement .set_parent & .set_rate\n", + pr_err("%s: %s must implement .set_parent & .set_rate\n", __func__, core->name); ret = -EINVAL; goto out; @@ -2364,37 +2311,12 @@ static int __clk_init(struct device *dev, struct clk *clk_user) "%s: invalid NULL in %s's .parent_names\n", __func__, core->name); - /* - * Allocate an array of struct clk *'s to avoid unnecessary string - * look-ups of clk's possible parents. This can fail for clocks passed - * in to clk_init during early boot; thus any access to core->parents[] - * must always check for a NULL pointer and try to populate it if - * necessary. - * - * If core->parents is not NULL we skip this entire block. This allows - * for clock drivers to statically initialize core->parents. - */ - if (core->num_parents > 1 && !core->parents) { - core->parents = kcalloc(core->num_parents, sizeof(struct clk *), - GFP_KERNEL); - /* - * clk_core_lookup returns NULL for parents that have not been - * clk_init'd; thus any access to clk->parents[] must check - * for a NULL pointer. We can always perform lazy lookups for - * missing parents later on. - */ - if (core->parents) - for (i = 0; i < core->num_parents; i++) - core->parents[i] = - clk_core_lookup(core->parent_names[i]); - } - core->parent = __clk_init_parent(core); /* - * Populate core->parent if parent has already been __clk_init'd. If - * parent has not yet been __clk_init'd then place clk in the orphan - * list. If clk has set the CLK_IS_ROOT flag then place it in the root + * Populate core->parent if parent has already been clk_core_init'd. If + * parent has not yet been clk_core_init'd then place clk in the orphan + * list. If clk doesn't have any parents then place it in the root * clk list. * * Every time a new clk is clk_init'd then we walk the list of orphan @@ -2405,7 +2327,7 @@ static int __clk_init(struct device *dev, struct clk *clk_user) hlist_add_head(&core->child_node, &core->parent->children); core->orphan = core->parent->orphan; - } else if (core->flags & CLK_IS_ROOT) { + } else if (!core->num_parents) { hlist_add_head(&core->child_node, &clk_root_list); core->orphan = false; } else { @@ -2454,24 +2376,15 @@ static int __clk_init(struct device *dev, struct clk *clk_user) core->rate = core->req_rate = rate; /* - * walk the list of orphan clocks and reparent any that are children of - * this clock + * walk the list of orphan clocks and reparent any that newly finds a + * parent. */ hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) { - if (orphan->num_parents && orphan->ops->get_parent) { - i = orphan->ops->get_parent(orphan->hw); - if (i >= 0 && i < orphan->num_parents && - !strcmp(core->name, orphan->parent_names[i])) - clk_core_reparent(orphan, core); - continue; - } + struct clk_core *parent = __clk_init_parent(orphan); - for (i = 0; i < orphan->num_parents; i++) - if (!strcmp(core->name, orphan->parent_names[i])) { - clk_core_reparent(orphan, core); - break; - } - } + if (parent) + clk_core_reparent(orphan, parent); + } /* * optional platform-specific magic @@ -2585,21 +2498,31 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw) } } + /* avoid unnecessary string look-ups of clk_core's possible parents. */ + core->parents = kcalloc(core->num_parents, sizeof(*core->parents), + GFP_KERNEL); + if (!core->parents) { + ret = -ENOMEM; + goto fail_parents; + }; + INIT_HLIST_HEAD(&core->clks); hw->clk = __clk_create_clk(hw, NULL, NULL); if (IS_ERR(hw->clk)) { ret = PTR_ERR(hw->clk); - goto fail_parent_names_copy; + goto fail_parents; } - ret = __clk_init(dev, hw->clk); + ret = __clk_core_init(core); if (!ret) return hw->clk; __clk_free_clk(hw->clk); hw->clk = NULL; +fail_parents: + kfree(core->parents); fail_parent_names_copy: while (--i >= 0) kfree_const(core->parent_names[i]); @@ -2683,7 +2606,7 @@ void clk_unregister(struct clk *clk) if (clk->core->ops == &clk_nodrv_ops) { pr_err("%s: unregistered clock: %s\n", __func__, clk->core->name); - return; + goto unlock; } /* * Assign empty clock ops for consumers that might still hold @@ -2709,7 +2632,7 @@ void clk_unregister(struct clk *clk) pr_warn("%s: unregistering prepared clock: %s\n", __func__, clk->core->name); kref_put(&clk->core->ref, __clk_release); - +unlock: clk_prepare_unlock(); } EXPORT_SYMBOL_GPL(clk_unregister); @@ -3061,10 +2984,23 @@ struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec) { return __of_clk_get_from_provider(clkspec, NULL, __func__); } +EXPORT_SYMBOL_GPL(of_clk_get_from_provider); -int of_clk_get_parent_count(struct device_node *np) +/** + * of_clk_get_parent_count() - Count the number of clocks a device node has + * @np: device node to count + * + * Returns: The number of clocks that are possible parents of this node + */ +unsigned int of_clk_get_parent_count(struct device_node *np) { - return of_count_phandle_with_args(np, "clocks", "#clock-cells"); + int count; + + count = of_count_phandle_with_args(np, "clocks", "#clock-cells"); + if (count < 0) + return 0; + + return count; } EXPORT_SYMBOL_GPL(of_clk_get_parent_count); @@ -3214,6 +3150,9 @@ void __init of_clk_init(const struct of_device_id *matches) for_each_matching_node_and_match(np, matches, &match) { struct clock_provider *parent; + if (!of_device_is_available(np)) + continue; + parent = kzalloc(sizeof(*parent), GFP_KERNEL); if (!parent) { list_for_each_entry_safe(clk_provider, next, diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c index 779b6ff0c7ad4040a680a2155964bd3016363767..eb20b941154babe8ad145633b642e53ac9891069 100644 --- a/drivers/clk/clkdev.c +++ b/drivers/clk/clkdev.c @@ -353,11 +353,25 @@ void clkdev_drop(struct clk_lookup *cl) } EXPORT_SYMBOL(clkdev_drop); +static struct clk_lookup *__clk_register_clkdev(struct clk_hw *hw, + const char *con_id, + const char *dev_id, ...) +{ + struct clk_lookup *cl; + va_list ap; + + va_start(ap, dev_id); + cl = vclkdev_create(hw, con_id, dev_id, ap); + va_end(ap); + + return cl; +} + /** * clk_register_clkdev - register one clock lookup for a struct clk * @clk: struct clk to associate with all clk_lookups * @con_id: connection ID string on device - * @dev_id: format string describing device name + * @dev_id: string describing device name * * con_id or dev_id may be NULL as a wildcard, just as in the rest of * clkdev. @@ -368,17 +382,22 @@ EXPORT_SYMBOL(clkdev_drop); * after clk_register(). */ int clk_register_clkdev(struct clk *clk, const char *con_id, - const char *dev_fmt, ...) + const char *dev_id) { struct clk_lookup *cl; - va_list ap; if (IS_ERR(clk)) return PTR_ERR(clk); - va_start(ap, dev_fmt); - cl = vclkdev_create(__clk_get_hw(clk), con_id, dev_fmt, ap); - va_end(ap); + /* + * Since dev_id can be NULL, and NULL is handled specially, we must + * pass it as either a NULL format string, or with "%s". + */ + if (dev_id) + cl = __clk_register_clkdev(__clk_get_hw(clk), con_id, "%s", + dev_id); + else + cl = __clk_register_clkdev(__clk_get_hw(clk), con_id, NULL); return cl ? 0 : -ENOMEM; } diff --git a/drivers/clk/h8300/clk-div.c b/drivers/clk/h8300/clk-div.c index d71d01157dbb0ee0fe468db4f6f3156675936ce9..4bf44a25d950daea6c0b526b90b890e5c361cda3 100644 --- a/drivers/clk/h8300/clk-div.c +++ b/drivers/clk/h8300/clk-div.c @@ -13,7 +13,7 @@ static DEFINE_SPINLOCK(clklock); static void __init h8300_div_clk_setup(struct device_node *node) { - int num_parents; + unsigned int num_parents; struct clk *clk; const char *clk_name = node->name; const char *parent_name; @@ -22,7 +22,7 @@ static void __init h8300_div_clk_setup(struct device_node *node) int offset; num_parents = of_clk_get_parent_count(node); - if (num_parents < 1) { + if (!num_parents) { pr_err("%s: no parent found", clk_name); return; } @@ -34,7 +34,7 @@ static void __init h8300_div_clk_setup(struct device_node *node) } offset = (unsigned long)divcr & 3; offset = (3 - offset) * 8; - divcr = (void *)((unsigned long)divcr & ~3); + divcr = (void __iomem *)((unsigned long)divcr & ~3); parent_name = of_clk_get_parent_name(node, 0); of_property_read_u32(node, "renesas,width", &width); diff --git a/drivers/clk/h8300/clk-h8s2678.c b/drivers/clk/h8300/clk-h8s2678.c index 6cf38dc1c9291e843f140e187b5dd0f0aadf6d4b..c9c2fd575ef7d0e8aa660c61c8ec5470f09cf1c8 100644 --- a/drivers/clk/h8300/clk-h8s2678.c +++ b/drivers/clk/h8300/clk-h8s2678.c @@ -83,7 +83,7 @@ static const struct clk_ops pll_ops = { static void __init h8s2678_pll_clk_setup(struct device_node *node) { - int num_parents; + unsigned int num_parents; struct clk *clk; const char *clk_name = node->name; const char *parent_name; @@ -91,7 +91,7 @@ static void __init h8s2678_pll_clk_setup(struct device_node *node) struct clk_init_data init; num_parents = of_clk_get_parent_count(node); - if (num_parents < 1) { + if (!num_parents) { pr_err("%s: no parent found", clk_name); return; } diff --git a/drivers/clk/hisilicon/clk-hi3620.c b/drivers/clk/hisilicon/clk-hi3620.c index 7d03fe17d66f567cae3b69ec11b9e93279ca9dc5..d04a104ce1b4d2aa4409fcc217f3905c9d66e41f 100644 --- a/drivers/clk/hisilicon/clk-hi3620.c +++ b/drivers/clk/hisilicon/clk-hi3620.c @@ -78,15 +78,15 @@ static const char *const mmc3_mux_p[] __initconst = { "armpll2", "armpll3", }; /* fixed rate clocks */ static struct hisi_fixed_rate_clock hi3620_fixed_rate_clks[] __initdata = { - { HI3620_OSC32K, "osc32k", NULL, CLK_IS_ROOT, 32768, }, - { HI3620_OSC26M, "osc26m", NULL, CLK_IS_ROOT, 26000000, }, - { HI3620_PCLK, "pclk", NULL, CLK_IS_ROOT, 26000000, }, - { HI3620_PLL_ARM0, "armpll0", NULL, CLK_IS_ROOT, 1600000000, }, - { HI3620_PLL_ARM1, "armpll1", NULL, CLK_IS_ROOT, 1600000000, }, - { HI3620_PLL_PERI, "armpll2", NULL, CLK_IS_ROOT, 1440000000, }, - { HI3620_PLL_USB, "armpll3", NULL, CLK_IS_ROOT, 1440000000, }, - { HI3620_PLL_HDMI, "armpll4", NULL, CLK_IS_ROOT, 1188000000, }, - { HI3620_PLL_GPU, "armpll5", NULL, CLK_IS_ROOT, 1300000000, }, + { HI3620_OSC32K, "osc32k", NULL, 0, 32768, }, + { HI3620_OSC26M, "osc26m", NULL, 0, 26000000, }, + { HI3620_PCLK, "pclk", NULL, 0, 26000000, }, + { HI3620_PLL_ARM0, "armpll0", NULL, 0, 1600000000, }, + { HI3620_PLL_ARM1, "armpll1", NULL, 0, 1600000000, }, + { HI3620_PLL_PERI, "armpll2", NULL, 0, 1440000000, }, + { HI3620_PLL_USB, "armpll3", NULL, 0, 1440000000, }, + { HI3620_PLL_HDMI, "armpll4", NULL, 0, 1188000000, }, + { HI3620_PLL_GPU, "armpll5", NULL, 0, 1300000000, }, }; /* fixed factor clocks */ diff --git a/drivers/clk/hisilicon/clk-hi6220-stub.c b/drivers/clk/hisilicon/clk-hi6220-stub.c index 8afb40ef40ce81f884de1b0b677b86fc5fb5ed7d..329a09214d126769e22f7f8788fe034ea680f0c8 100644 --- a/drivers/clk/hisilicon/clk-hi6220-stub.c +++ b/drivers/clk/hisilicon/clk-hi6220-stub.c @@ -235,7 +235,7 @@ static int hi6220_stub_clk_probe(struct platform_device *pdev) init.name = "acpu0"; init.ops = &hi6220_stub_clk_ops; init.num_parents = 0; - init.flags = CLK_IS_ROOT; + init.flags = 0; clk = devm_clk_register(dev, &stub_clk->hw); if (IS_ERR(clk)) diff --git a/drivers/clk/hisilicon/clk-hi6220.c b/drivers/clk/hisilicon/clk-hi6220.c index 4563343b64209098a85b840d3aacacac7931d072..f02cb41d40a44fb2a04eedc67cabd6e4b5a87b98 100644 --- a/drivers/clk/hisilicon/clk-hi6220.c +++ b/drivers/clk/hisilicon/clk-hi6220.c @@ -26,19 +26,19 @@ /* clocks in AO (always on) controller */ static struct hisi_fixed_rate_clock hi6220_fixed_rate_clks[] __initdata = { - { HI6220_REF32K, "ref32k", NULL, CLK_IS_ROOT, 32764, }, - { HI6220_CLK_TCXO, "clk_tcxo", NULL, CLK_IS_ROOT, 19200000, }, - { HI6220_MMC1_PAD, "mmc1_pad", NULL, CLK_IS_ROOT, 100000000, }, - { HI6220_MMC2_PAD, "mmc2_pad", NULL, CLK_IS_ROOT, 100000000, }, - { HI6220_MMC0_PAD, "mmc0_pad", NULL, CLK_IS_ROOT, 200000000, }, - { HI6220_PLL_BBP, "bbppll0", NULL, CLK_IS_ROOT, 245760000, }, - { HI6220_PLL_GPU, "gpupll", NULL, CLK_IS_ROOT, 1000000000,}, - { HI6220_PLL1_DDR, "ddrpll1", NULL, CLK_IS_ROOT, 1066000000,}, - { HI6220_PLL_SYS, "syspll", NULL, CLK_IS_ROOT, 1200000000,}, - { HI6220_PLL_SYS_MEDIA, "media_syspll", NULL, CLK_IS_ROOT, 1200000000,}, - { HI6220_DDR_SRC, "ddr_sel_src", NULL, CLK_IS_ROOT, 1200000000,}, - { HI6220_PLL_MEDIA, "media_pll", NULL, CLK_IS_ROOT, 1440000000,}, - { HI6220_PLL_DDR, "ddrpll0", NULL, CLK_IS_ROOT, 1600000000,}, + { HI6220_REF32K, "ref32k", NULL, 0, 32764, }, + { HI6220_CLK_TCXO, "clk_tcxo", NULL, 0, 19200000, }, + { HI6220_MMC1_PAD, "mmc1_pad", NULL, 0, 100000000, }, + { HI6220_MMC2_PAD, "mmc2_pad", NULL, 0, 100000000, }, + { HI6220_MMC0_PAD, "mmc0_pad", NULL, 0, 200000000, }, + { HI6220_PLL_BBP, "bbppll0", NULL, 0, 245760000, }, + { HI6220_PLL_GPU, "gpupll", NULL, 0, 1000000000,}, + { HI6220_PLL1_DDR, "ddrpll1", NULL, 0, 1066000000,}, + { HI6220_PLL_SYS, "syspll", NULL, 0, 1200000000,}, + { HI6220_PLL_SYS_MEDIA, "media_syspll", NULL, 0, 1200000000,}, + { HI6220_DDR_SRC, "ddr_sel_src", NULL, 0, 1200000000,}, + { HI6220_PLL_MEDIA, "media_pll", NULL, 0, 1440000000,}, + { HI6220_PLL_DDR, "ddrpll0", NULL, 0, 1600000000,}, }; static struct hisi_fixed_factor_clock hi6220_fixed_factor_clks[] __initdata = { diff --git a/drivers/clk/hisilicon/clk-hip04.c b/drivers/clk/hisilicon/clk-hip04.c index 8ca9673083431e5229844749f4131dd8b2008c5e..b38e03da1d02842a85d54b23a090ff3f101fabfb 100644 --- a/drivers/clk/hisilicon/clk-hip04.c +++ b/drivers/clk/hisilicon/clk-hip04.c @@ -36,9 +36,9 @@ /* fixed rate clocks */ static struct hisi_fixed_rate_clock hip04_fixed_rate_clks[] __initdata = { - { HIP04_OSC50M, "osc50m", NULL, CLK_IS_ROOT, 50000000, }, - { HIP04_CLK_50M, "clk50m", NULL, CLK_IS_ROOT, 50000000, }, - { HIP04_CLK_168M, "clk168m", NULL, CLK_IS_ROOT, 168750000, }, + { HIP04_OSC50M, "osc50m", NULL, 0, 50000000, }, + { HIP04_CLK_50M, "clk50m", NULL, 0, 50000000, }, + { HIP04_CLK_168M, "clk168m", NULL, 0, 168750000, }, }; static void __init hip04_clk_init(struct device_node *np) diff --git a/drivers/clk/hisilicon/clk-hix5hd2.c b/drivers/clk/hisilicon/clk-hix5hd2.c index 0aaf29da84918337bb89dd83c1aec8c5dcb1a75a..14b05efa3c2ae4fca3b86e2afe270801074d066d 100644 --- a/drivers/clk/hisilicon/clk-hix5hd2.c +++ b/drivers/clk/hisilicon/clk-hix5hd2.c @@ -14,36 +14,36 @@ #include "clk.h" static struct hisi_fixed_rate_clock hix5hd2_fixed_rate_clks[] __initdata = { - { HIX5HD2_FIXED_1200M, "1200m", NULL, CLK_IS_ROOT, 1200000000, }, - { HIX5HD2_FIXED_400M, "400m", NULL, CLK_IS_ROOT, 400000000, }, - { HIX5HD2_FIXED_48M, "48m", NULL, CLK_IS_ROOT, 48000000, }, - { HIX5HD2_FIXED_24M, "24m", NULL, CLK_IS_ROOT, 24000000, }, - { HIX5HD2_FIXED_600M, "600m", NULL, CLK_IS_ROOT, 600000000, }, - { HIX5HD2_FIXED_300M, "300m", NULL, CLK_IS_ROOT, 300000000, }, - { HIX5HD2_FIXED_75M, "75m", NULL, CLK_IS_ROOT, 75000000, }, - { HIX5HD2_FIXED_200M, "200m", NULL, CLK_IS_ROOT, 200000000, }, - { HIX5HD2_FIXED_100M, "100m", NULL, CLK_IS_ROOT, 100000000, }, - { HIX5HD2_FIXED_40M, "40m", NULL, CLK_IS_ROOT, 40000000, }, - { HIX5HD2_FIXED_150M, "150m", NULL, CLK_IS_ROOT, 150000000, }, - { HIX5HD2_FIXED_1728M, "1728m", NULL, CLK_IS_ROOT, 1728000000, }, - { HIX5HD2_FIXED_28P8M, "28p8m", NULL, CLK_IS_ROOT, 28000000, }, - { HIX5HD2_FIXED_432M, "432m", NULL, CLK_IS_ROOT, 432000000, }, - { HIX5HD2_FIXED_345P6M, "345p6m", NULL, CLK_IS_ROOT, 345000000, }, - { HIX5HD2_FIXED_288M, "288m", NULL, CLK_IS_ROOT, 288000000, }, - { HIX5HD2_FIXED_60M, "60m", NULL, CLK_IS_ROOT, 60000000, }, - { HIX5HD2_FIXED_750M, "750m", NULL, CLK_IS_ROOT, 750000000, }, - { HIX5HD2_FIXED_500M, "500m", NULL, CLK_IS_ROOT, 500000000, }, - { HIX5HD2_FIXED_54M, "54m", NULL, CLK_IS_ROOT, 54000000, }, - { HIX5HD2_FIXED_27M, "27m", NULL, CLK_IS_ROOT, 27000000, }, - { HIX5HD2_FIXED_1500M, "1500m", NULL, CLK_IS_ROOT, 1500000000, }, - { HIX5HD2_FIXED_375M, "375m", NULL, CLK_IS_ROOT, 375000000, }, - { HIX5HD2_FIXED_187M, "187m", NULL, CLK_IS_ROOT, 187000000, }, - { HIX5HD2_FIXED_250M, "250m", NULL, CLK_IS_ROOT, 250000000, }, - { HIX5HD2_FIXED_125M, "125m", NULL, CLK_IS_ROOT, 125000000, }, - { HIX5HD2_FIXED_2P02M, "2m", NULL, CLK_IS_ROOT, 2000000, }, - { HIX5HD2_FIXED_50M, "50m", NULL, CLK_IS_ROOT, 50000000, }, - { HIX5HD2_FIXED_25M, "25m", NULL, CLK_IS_ROOT, 25000000, }, - { HIX5HD2_FIXED_83M, "83m", NULL, CLK_IS_ROOT, 83333333, }, + { HIX5HD2_FIXED_1200M, "1200m", NULL, 0, 1200000000, }, + { HIX5HD2_FIXED_400M, "400m", NULL, 0, 400000000, }, + { HIX5HD2_FIXED_48M, "48m", NULL, 0, 48000000, }, + { HIX5HD2_FIXED_24M, "24m", NULL, 0, 24000000, }, + { HIX5HD2_FIXED_600M, "600m", NULL, 0, 600000000, }, + { HIX5HD2_FIXED_300M, "300m", NULL, 0, 300000000, }, + { HIX5HD2_FIXED_75M, "75m", NULL, 0, 75000000, }, + { HIX5HD2_FIXED_200M, "200m", NULL, 0, 200000000, }, + { HIX5HD2_FIXED_100M, "100m", NULL, 0, 100000000, }, + { HIX5HD2_FIXED_40M, "40m", NULL, 0, 40000000, }, + { HIX5HD2_FIXED_150M, "150m", NULL, 0, 150000000, }, + { HIX5HD2_FIXED_1728M, "1728m", NULL, 0, 1728000000, }, + { HIX5HD2_FIXED_28P8M, "28p8m", NULL, 0, 28000000, }, + { HIX5HD2_FIXED_432M, "432m", NULL, 0, 432000000, }, + { HIX5HD2_FIXED_345P6M, "345p6m", NULL, 0, 345000000, }, + { HIX5HD2_FIXED_288M, "288m", NULL, 0, 288000000, }, + { HIX5HD2_FIXED_60M, "60m", NULL, 0, 60000000, }, + { HIX5HD2_FIXED_750M, "750m", NULL, 0, 750000000, }, + { HIX5HD2_FIXED_500M, "500m", NULL, 0, 500000000, }, + { HIX5HD2_FIXED_54M, "54m", NULL, 0, 54000000, }, + { HIX5HD2_FIXED_27M, "27m", NULL, 0, 27000000, }, + { HIX5HD2_FIXED_1500M, "1500m", NULL, 0, 1500000000, }, + { HIX5HD2_FIXED_375M, "375m", NULL, 0, 375000000, }, + { HIX5HD2_FIXED_187M, "187m", NULL, 0, 187000000, }, + { HIX5HD2_FIXED_250M, "250m", NULL, 0, 250000000, }, + { HIX5HD2_FIXED_125M, "125m", NULL, 0, 125000000, }, + { HIX5HD2_FIXED_2P02M, "2m", NULL, 0, 2000000, }, + { HIX5HD2_FIXED_50M, "50m", NULL, 0, 50000000, }, + { HIX5HD2_FIXED_25M, "25m", NULL, 0, 25000000, }, + { HIX5HD2_FIXED_83M, "83m", NULL, 0, 83333333, }, }; static const char *const sfc_mux_p[] __initconst = { diff --git a/drivers/clk/imx/clk-busy.c b/drivers/clk/imx/clk-busy.c index 4bb1bc419b798e5323652d36c0cf1413e45ccf31..5cc99590f9a33a397bc1fc51ffaf821867aeb6e9 100644 --- a/drivers/clk/imx/clk-busy.c +++ b/drivers/clk/imx/clk-busy.c @@ -38,7 +38,7 @@ struct clk_busy_divider { 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); + struct clk_divider *div = to_clk_divider(hw); return container_of(div, struct clk_busy_divider, div); } @@ -123,7 +123,7 @@ struct clk_busy_mux { 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); + struct clk_mux *mux = to_clk_mux(hw); return container_of(mux, struct clk_busy_mux, mux); } diff --git a/drivers/clk/imx/clk-fixup-div.c b/drivers/clk/imx/clk-fixup-div.c index 21db020b1f2dccee6b7646ac4cd0a4f6e8308e7d..ce57227327153064b9f359d82ce91da148e6f02e 100644 --- a/drivers/clk/imx/clk-fixup-div.c +++ b/drivers/clk/imx/clk-fixup-div.c @@ -15,7 +15,6 @@ #include #include "clk.h" -#define to_clk_div(_hw) container_of(_hw, struct clk_divider, hw) #define div_mask(d) ((1 << (d->width)) - 1) /** @@ -35,7 +34,7 @@ struct clk_fixup_div { static inline struct clk_fixup_div *to_clk_fixup_div(struct clk_hw *hw) { - struct clk_divider *divider = to_clk_div(hw); + struct clk_divider *divider = to_clk_divider(hw); return container_of(divider, struct clk_fixup_div, divider); } @@ -60,7 +59,7 @@ static int clk_fixup_div_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { struct clk_fixup_div *fixup_div = to_clk_fixup_div(hw); - struct clk_divider *div = to_clk_div(hw); + struct clk_divider *div = to_clk_divider(hw); unsigned int divider, value; unsigned long flags = 0; u32 val; diff --git a/drivers/clk/imx/clk-fixup-mux.c b/drivers/clk/imx/clk-fixup-mux.c index 0d40b35c557cba39980ad2644e6d4a97902f9555..c9b327e0a8dd9b2fd6f9c939f762c6dd46ae9917 100644 --- a/drivers/clk/imx/clk-fixup-mux.c +++ b/drivers/clk/imx/clk-fixup-mux.c @@ -15,8 +15,6 @@ #include #include "clk.h" -#define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw) - /** * struct clk_fixup_mux - imx integer fixup multiplexer clock * @mux: the parent class diff --git a/drivers/clk/imx/clk-gate-exclusive.c b/drivers/clk/imx/clk-gate-exclusive.c index c12f5f2e04dc1dda3d2a55c795e07e55ed012e52..3bd9dee618b2c2c06a9d18aa6f4efde5e8bf0f0d 100644 --- a/drivers/clk/imx/clk-gate-exclusive.c +++ b/drivers/clk/imx/clk-gate-exclusive.c @@ -31,7 +31,7 @@ struct clk_gate_exclusive { static int clk_gate_exclusive_enable(struct clk_hw *hw) { - struct clk_gate *gate = container_of(hw, struct clk_gate, hw); + struct clk_gate *gate = to_clk_gate(hw); struct clk_gate_exclusive *exgate = container_of(gate, struct clk_gate_exclusive, gate); u32 val = readl(gate->reg); diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c index f0efc6feeec2b5d5b12bb11739e990ba3ed10e9b..02e18182fcb5506da4c4981a0d5f1926376099e6 100644 --- a/drivers/clk/imx/clk-imx6q.c +++ b/drivers/clk/imx/clk-imx6q.c @@ -34,7 +34,9 @@ static const char *periph2_sels[] = { "periph2_pre", "periph2_clk2", }; static const char *axi_sels[] = { "periph", "pll2_pfd2_396m", "periph", "pll3_pfd1_540m", }; static const char *audio_sels[] = { "pll4_audio_div", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", }; static const char *gpu_axi_sels[] = { "axi", "ahb", }; +static const char *pre_axi_sels[] = { "axi", "ahb", }; static const char *gpu2d_core_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", }; +static const char *gpu2d_core_sels_2[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll3_pfd0_720m",}; 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", "pll3_pfd0_720m", }; static const char *ipu_sels[] = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", }; @@ -44,15 +46,24 @@ static const char *ipu1_di0_sels[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di 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 *ipu1_di0_sels_2[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0_podf", "ldb_di1_podf", }; +static const char *ipu1_di1_sels_2[] = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0_podf", "ldb_di1_podf", }; +static const char *ipu2_di0_sels_2[] = { "ipu2_di0_pre", "dummy", "dummy", "ldb_di0_podf", "ldb_di1_podf", }; +static const char *ipu2_di1_sels_2[] = { "ipu2_di1_pre", "dummy", "dummy", "ldb_di0_podf", "ldb_di1_podf", }; 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_div", }; static const char *usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", }; static const char *enfc_sels[] = { "pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", }; +static const char *enfc_sels_2[] = {"pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", "pll3_pfd3_454m", "dummy", }; static const char *eim_sels[] = { "pll2_pfd2_396m", "pll3_usb_otg", "axi", "pll2_pfd0_352m", }; static const char *eim_slow_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 *uart_sels[] = { "pll3_80m", "osc", }; +static const char *ipg_per_sels[] = { "ipg", "osc", }; +static const char *ecspi_sels[] = { "pll3_60m", "osc", }; +static const char *can_sels[] = { "pll3_60m", "osc", "pll3_80m", }; static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video_div", "dummy", "axi", "enfc", "ipu1_di0", "ipu1_di1", "ipu2_di0", "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_audio_div", }; @@ -121,12 +132,19 @@ static unsigned int share_count_ssi2; static unsigned int share_count_ssi3; static unsigned int share_count_mipi_core_cfg; static unsigned int share_count_spdif; +static unsigned int share_count_prg0; +static unsigned int share_count_prg1; static inline int clk_on_imx6q(void) { return of_machine_is_compatible("fsl,imx6q"); } +static inline int clk_on_imx6qp(void) +{ + return of_machine_is_compatible("fsl,imx6qp"); +} + static inline int clk_on_imx6dl(void) { return of_machine_is_compatible("fsl,imx6dl"); @@ -265,7 +283,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6QDL_CLK_TWD] = imx_clk_fixed_factor("twd", "arm", 1, 2); clk[IMX6QDL_CLK_GPT_3M] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8); clk[IMX6QDL_CLK_VIDEO_27M] = imx_clk_fixed_factor("video_27m", "pll3_pfd1_540m", 1, 20); - if (clk_on_imx6dl()) { + if (clk_on_imx6dl() || clk_on_imx6qp()) { clk[IMX6QDL_CLK_GPU2D_AXI] = imx_clk_fixed_factor("gpu2d_axi", "mmdc_ch0_axi_podf", 1, 1); clk[IMX6QDL_CLK_GPU3D_AXI] = imx_clk_fixed_factor("gpu3d_axi", "mmdc_ch0_axi_podf", 1, 1); } @@ -294,7 +312,15 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6QDL_CLK_GPU2D_AXI] = imx_clk_mux("gpu2d_axi", base + 0x18, 0, 1, gpu_axi_sels, ARRAY_SIZE(gpu_axi_sels)); clk[IMX6QDL_CLK_GPU3D_AXI] = imx_clk_mux("gpu3d_axi", base + 0x18, 1, 1, gpu_axi_sels, ARRAY_SIZE(gpu_axi_sels)); } - clk[IMX6QDL_CLK_GPU2D_CORE_SEL] = imx_clk_mux("gpu2d_core_sel", base + 0x18, 16, 2, gpu2d_core_sels, ARRAY_SIZE(gpu2d_core_sels)); + if (clk_on_imx6qp()) { + clk[IMX6QDL_CLK_CAN_SEL] = imx_clk_mux("can_sel", base + 0x20, 8, 2, can_sels, ARRAY_SIZE(can_sels)); + clk[IMX6QDL_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels)); + clk[IMX6QDL_CLK_IPG_PER_SEL] = imx_clk_mux("ipg_per_sel", base + 0x1c, 6, 1, ipg_per_sels, ARRAY_SIZE(ipg_per_sels)); + clk[IMX6QDL_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels)); + clk[IMX6QDL_CLK_GPU2D_CORE_SEL] = imx_clk_mux("gpu2d_core_sel", base + 0x18, 16, 2, gpu2d_core_sels_2, ARRAY_SIZE(gpu2d_core_sels_2)); + } else { + clk[IMX6QDL_CLK_GPU2D_CORE_SEL] = imx_clk_mux("gpu2d_core_sel", base + 0x18, 16, 2, gpu2d_core_sels, ARRAY_SIZE(gpu2d_core_sels)); + } clk[IMX6QDL_CLK_GPU3D_CORE_SEL] = imx_clk_mux("gpu3d_core_sel", base + 0x18, 4, 2, gpu3d_core_sels, ARRAY_SIZE(gpu3d_core_sels)); clk[IMX6QDL_CLK_GPU3D_SHADER_SEL] = imx_clk_mux("gpu3d_shader_sel", base + 0x18, 8, 2, gpu3d_shader_sels, ARRAY_SIZE(gpu3d_shader_sels)); clk[IMX6QDL_CLK_IPU1_SEL] = imx_clk_mux("ipu1_sel", base + 0x3c, 9, 2, ipu_sels, ARRAY_SIZE(ipu_sels)); @@ -305,22 +331,40 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6QDL_CLK_IPU1_DI1_PRE_SEL] = imx_clk_mux_flags("ipu1_di1_pre_sel", base + 0x34, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT); clk[IMX6QDL_CLK_IPU2_DI0_PRE_SEL] = imx_clk_mux_flags("ipu2_di0_pre_sel", base + 0x38, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT); clk[IMX6QDL_CLK_IPU2_DI1_PRE_SEL] = imx_clk_mux_flags("ipu2_di1_pre_sel", base + 0x38, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT); - clk[IMX6QDL_CLK_IPU1_DI0_SEL] = imx_clk_mux_flags("ipu1_di0_sel", base + 0x34, 0, 3, ipu1_di0_sels, ARRAY_SIZE(ipu1_di0_sels), CLK_SET_RATE_PARENT); - clk[IMX6QDL_CLK_IPU1_DI1_SEL] = imx_clk_mux_flags("ipu1_di1_sel", base + 0x34, 9, 3, ipu1_di1_sels, ARRAY_SIZE(ipu1_di1_sels), CLK_SET_RATE_PARENT); - clk[IMX6QDL_CLK_IPU2_DI0_SEL] = imx_clk_mux_flags("ipu2_di0_sel", base + 0x38, 0, 3, ipu2_di0_sels, ARRAY_SIZE(ipu2_di0_sels), CLK_SET_RATE_PARENT); - clk[IMX6QDL_CLK_IPU2_DI1_SEL] = imx_clk_mux_flags("ipu2_di1_sel", base + 0x38, 9, 3, ipu2_di1_sels, ARRAY_SIZE(ipu2_di1_sels), CLK_SET_RATE_PARENT); clk[IMX6QDL_CLK_HSI_TX_SEL] = imx_clk_mux("hsi_tx_sel", base + 0x30, 28, 1, hsi_tx_sels, ARRAY_SIZE(hsi_tx_sels)); clk[IMX6QDL_CLK_PCIE_AXI_SEL] = imx_clk_mux("pcie_axi_sel", base + 0x18, 10, 1, pcie_axi_sels, ARRAY_SIZE(pcie_axi_sels)); - clk[IMX6QDL_CLK_SSI1_SEL] = imx_clk_fixup_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup); - clk[IMX6QDL_CLK_SSI2_SEL] = imx_clk_fixup_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup); - clk[IMX6QDL_CLK_SSI3_SEL] = imx_clk_fixup_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup); - clk[IMX6QDL_CLK_USDHC1_SEL] = imx_clk_fixup_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); - clk[IMX6QDL_CLK_USDHC2_SEL] = imx_clk_fixup_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); - clk[IMX6QDL_CLK_USDHC3_SEL] = imx_clk_fixup_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); - clk[IMX6QDL_CLK_USDHC4_SEL] = imx_clk_fixup_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); - clk[IMX6QDL_CLK_ENFC_SEL] = imx_clk_mux("enfc_sel", base + 0x2c, 16, 2, enfc_sels, ARRAY_SIZE(enfc_sels)); - clk[IMX6QDL_CLK_EIM_SEL] = imx_clk_fixup_mux("eim_sel", base + 0x1c, 27, 2, eim_sels, ARRAY_SIZE(eim_sels), imx_cscmr1_fixup); - clk[IMX6QDL_CLK_EIM_SLOW_SEL] = imx_clk_fixup_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels), imx_cscmr1_fixup); + if (clk_on_imx6qp()) { + clk[IMX6QDL_CLK_IPU1_DI0_SEL] = imx_clk_mux_flags("ipu1_di0_sel", base + 0x34, 0, 3, ipu1_di0_sels_2, ARRAY_SIZE(ipu1_di0_sels_2), CLK_SET_RATE_PARENT); + clk[IMX6QDL_CLK_IPU1_DI1_SEL] = imx_clk_mux_flags("ipu1_di1_sel", base + 0x34, 9, 3, ipu1_di1_sels_2, ARRAY_SIZE(ipu1_di1_sels_2), CLK_SET_RATE_PARENT); + clk[IMX6QDL_CLK_IPU2_DI0_SEL] = imx_clk_mux_flags("ipu2_di0_sel", base + 0x38, 0, 3, ipu2_di0_sels_2, ARRAY_SIZE(ipu2_di0_sels_2), CLK_SET_RATE_PARENT); + clk[IMX6QDL_CLK_IPU2_DI1_SEL] = imx_clk_mux_flags("ipu2_di1_sel", base + 0x38, 9, 3, ipu2_di1_sels_2, ARRAY_SIZE(ipu2_di1_sels_2), CLK_SET_RATE_PARENT); + clk[IMX6QDL_CLK_SSI1_SEL] = imx_clk_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); + clk[IMX6QDL_CLK_SSI2_SEL] = imx_clk_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); + clk[IMX6QDL_CLK_SSI3_SEL] = imx_clk_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); + clk[IMX6QDL_CLK_USDHC1_SEL] = imx_clk_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); + clk[IMX6QDL_CLK_USDHC2_SEL] = imx_clk_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); + clk[IMX6QDL_CLK_USDHC3_SEL] = imx_clk_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); + clk[IMX6QDL_CLK_USDHC4_SEL] = imx_clk_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); + clk[IMX6QDL_CLK_ENFC_SEL] = imx_clk_mux("enfc_sel", base + 0x2c, 15, 3, enfc_sels_2, ARRAY_SIZE(enfc_sels_2)); + clk[IMX6QDL_CLK_EIM_SEL] = imx_clk_mux("eim_sel", base + 0x1c, 27, 2, eim_sels, ARRAY_SIZE(eim_sels)); + clk[IMX6QDL_CLK_EIM_SLOW_SEL] = imx_clk_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels)); + clk[IMX6QDL_CLK_PRE_AXI] = imx_clk_mux("pre_axi", base + 0x18, 1, 1, pre_axi_sels, ARRAY_SIZE(pre_axi_sels)); + } else { + clk[IMX6QDL_CLK_IPU1_DI0_SEL] = imx_clk_mux_flags("ipu1_di0_sel", base + 0x34, 0, 3, ipu1_di0_sels, ARRAY_SIZE(ipu1_di0_sels), CLK_SET_RATE_PARENT); + clk[IMX6QDL_CLK_IPU1_DI1_SEL] = imx_clk_mux_flags("ipu1_di1_sel", base + 0x34, 9, 3, ipu1_di1_sels, ARRAY_SIZE(ipu1_di1_sels), CLK_SET_RATE_PARENT); + clk[IMX6QDL_CLK_IPU2_DI0_SEL] = imx_clk_mux_flags("ipu2_di0_sel", base + 0x38, 0, 3, ipu2_di0_sels, ARRAY_SIZE(ipu2_di0_sels), CLK_SET_RATE_PARENT); + clk[IMX6QDL_CLK_IPU2_DI1_SEL] = imx_clk_mux_flags("ipu2_di1_sel", base + 0x38, 9, 3, ipu2_di1_sels, ARRAY_SIZE(ipu2_di1_sels), CLK_SET_RATE_PARENT); + clk[IMX6QDL_CLK_SSI1_SEL] = imx_clk_fixup_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup); + clk[IMX6QDL_CLK_SSI2_SEL] = imx_clk_fixup_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup); + clk[IMX6QDL_CLK_SSI3_SEL] = imx_clk_fixup_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup); + clk[IMX6QDL_CLK_USDHC1_SEL] = imx_clk_fixup_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); + clk[IMX6QDL_CLK_USDHC2_SEL] = imx_clk_fixup_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); + clk[IMX6QDL_CLK_USDHC3_SEL] = imx_clk_fixup_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); + clk[IMX6QDL_CLK_USDHC4_SEL] = imx_clk_fixup_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); + clk[IMX6QDL_CLK_ENFC_SEL] = imx_clk_mux("enfc_sel", base + 0x2c, 16, 2, enfc_sels, ARRAY_SIZE(enfc_sels)); + clk[IMX6QDL_CLK_EIM_SEL] = imx_clk_fixup_mux("eim_sel", base + 0x1c, 27, 2, eim_sels, ARRAY_SIZE(eim_sels), imx_cscmr1_fixup); + clk[IMX6QDL_CLK_EIM_SLOW_SEL] = imx_clk_fixup_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels), imx_cscmr1_fixup); + } clk[IMX6QDL_CLK_VDO_AXI_SEL] = imx_clk_mux("vdo_axi_sel", base + 0x18, 11, 1, vdo_axi_sels, ARRAY_SIZE(vdo_axi_sels)); clk[IMX6QDL_CLK_VPU_AXI_SEL] = imx_clk_mux("vpu_axi_sel", base + 0x18, 14, 2, vpu_axi_sels, ARRAY_SIZE(vpu_axi_sels)); clk[IMX6QDL_CLK_CKO1_SEL] = imx_clk_mux("cko1_sel", base + 0x60, 0, 4, cko1_sels, ARRAY_SIZE(cko1_sels)); @@ -335,23 +379,33 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6QDL_CLK_PERIPH_CLK2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3); clk[IMX6QDL_CLK_PERIPH2_CLK2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3); clk[IMX6QDL_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2); - clk[IMX6QDL_CLK_IPG_PER] = imx_clk_fixup_divider("ipg_per", "ipg", base + 0x1c, 0, 6, imx_cscmr1_fixup); clk[IMX6QDL_CLK_ESAI_PRED] = imx_clk_divider("esai_pred", "esai_sel", base + 0x28, 9, 3); clk[IMX6QDL_CLK_ESAI_PODF] = imx_clk_divider("esai_podf", "esai_pred", base + 0x28, 25, 3); clk[IMX6QDL_CLK_ASRC_PRED] = imx_clk_divider("asrc_pred", "asrc_sel", base + 0x30, 12, 3); clk[IMX6QDL_CLK_ASRC_PODF] = imx_clk_divider("asrc_podf", "asrc_pred", base + 0x30, 9, 3); clk[IMX6QDL_CLK_SPDIF_PRED] = imx_clk_divider("spdif_pred", "spdif_sel", base + 0x30, 25, 3); clk[IMX6QDL_CLK_SPDIF_PODF] = imx_clk_divider("spdif_podf", "spdif_pred", base + 0x30, 22, 3); - clk[IMX6QDL_CLK_CAN_ROOT] = imx_clk_divider("can_root", "pll3_60m", base + 0x20, 2, 6); - clk[IMX6QDL_CLK_ECSPI_ROOT] = imx_clk_divider("ecspi_root", "pll3_60m", base + 0x38, 19, 6); + if (clk_on_imx6qp()) { + clk[IMX6QDL_CLK_IPG_PER] = imx_clk_divider("ipg_per", "ipg_per_sel", base + 0x1c, 0, 6); + clk[IMX6QDL_CLK_ECSPI_ROOT] = imx_clk_divider("ecspi_root", "ecspi_sel", base + 0x38, 19, 6); + clk[IMX6QDL_CLK_CAN_ROOT] = imx_clk_divider("can_root", "can_sel", base + 0x20, 2, 6); + clk[IMX6QDL_CLK_UART_SERIAL_PODF] = imx_clk_divider("uart_serial_podf", "uart_sel", base + 0x24, 0, 6); + clk[IMX6QDL_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0", 2, 7); + clk[IMX6QDL_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1", 2, 7); + } else { + clk[IMX6QDL_CLK_ECSPI_ROOT] = imx_clk_divider("ecspi_root", "pll3_60m", base + 0x38, 19, 6); + clk[IMX6QDL_CLK_CAN_ROOT] = imx_clk_divider("can_root", "pll3_60", base + 0x20, 2, 6); + clk[IMX6QDL_CLK_IPG_PER] = imx_clk_fixup_divider("ipg_per", "ipg", base + 0x1c, 0, 6, imx_cscmr1_fixup); + clk[IMX6QDL_CLK_UART_SERIAL_PODF] = imx_clk_divider("uart_serial_podf", "pll3_80m", base + 0x24, 0, 6); + clk[IMX6QDL_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); + clk[IMX6QDL_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7); + } clk[IMX6QDL_CLK_GPU2D_CORE_PODF] = imx_clk_divider("gpu2d_core_podf", "gpu2d_core_sel", base + 0x18, 23, 3); clk[IMX6QDL_CLK_GPU3D_CORE_PODF] = imx_clk_divider("gpu3d_core_podf", "gpu3d_core_sel", base + 0x18, 26, 3); clk[IMX6QDL_CLK_GPU3D_SHADER] = imx_clk_divider("gpu3d_shader", "gpu3d_shader_sel", base + 0x18, 29, 3); clk[IMX6QDL_CLK_IPU1_PODF] = imx_clk_divider("ipu1_podf", "ipu1_sel", base + 0x3c, 11, 3); clk[IMX6QDL_CLK_IPU2_PODF] = imx_clk_divider("ipu2_podf", "ipu2_sel", base + 0x3c, 16, 3); - clk[IMX6QDL_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); clk[IMX6QDL_CLK_LDB_DI0_PODF] = imx_clk_divider_flags("ldb_di0_podf", "ldb_di0_div_3_5", base + 0x20, 10, 1, 0); - clk[IMX6QDL_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7); clk[IMX6QDL_CLK_LDB_DI1_PODF] = imx_clk_divider_flags("ldb_di1_podf", "ldb_di1_div_3_5", base + 0x20, 11, 1, 0); clk[IMX6QDL_CLK_IPU1_DI0_PRE] = imx_clk_divider("ipu1_di0_pre", "ipu1_di0_pre_sel", base + 0x34, 3, 3); clk[IMX6QDL_CLK_IPU1_DI1_PRE] = imx_clk_divider("ipu1_di1_pre", "ipu1_di1_pre_sel", base + 0x34, 12, 3); @@ -364,15 +418,19 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6QDL_CLK_SSI2_PODF] = imx_clk_divider("ssi2_podf", "ssi2_pred", base + 0x2c, 0, 6); clk[IMX6QDL_CLK_SSI3_PRED] = imx_clk_divider("ssi3_pred", "ssi3_sel", base + 0x28, 22, 3); clk[IMX6QDL_CLK_SSI3_PODF] = imx_clk_divider("ssi3_podf", "ssi3_pred", base + 0x28, 16, 6); - clk[IMX6QDL_CLK_UART_SERIAL_PODF] = imx_clk_divider("uart_serial_podf", "pll3_80m", base + 0x24, 0, 6); clk[IMX6QDL_CLK_USDHC1_PODF] = imx_clk_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3); clk[IMX6QDL_CLK_USDHC2_PODF] = imx_clk_divider("usdhc2_podf", "usdhc2_sel", base + 0x24, 16, 3); clk[IMX6QDL_CLK_USDHC3_PODF] = imx_clk_divider("usdhc3_podf", "usdhc3_sel", base + 0x24, 19, 3); clk[IMX6QDL_CLK_USDHC4_PODF] = imx_clk_divider("usdhc4_podf", "usdhc4_sel", base + 0x24, 22, 3); clk[IMX6QDL_CLK_ENFC_PRED] = imx_clk_divider("enfc_pred", "enfc_sel", base + 0x2c, 18, 3); clk[IMX6QDL_CLK_ENFC_PODF] = imx_clk_divider("enfc_podf", "enfc_pred", base + 0x2c, 21, 6); - clk[IMX6QDL_CLK_EIM_PODF] = imx_clk_fixup_divider("eim_podf", "eim_sel", base + 0x1c, 20, 3, imx_cscmr1_fixup); - clk[IMX6QDL_CLK_EIM_SLOW_PODF] = imx_clk_fixup_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3, imx_cscmr1_fixup); + if (clk_on_imx6qp()) { + clk[IMX6QDL_CLK_EIM_PODF] = imx_clk_divider("eim_podf", "eim_sel", base + 0x1c, 20, 3); + clk[IMX6QDL_CLK_EIM_SLOW_PODF] = imx_clk_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3); + } else { + clk[IMX6QDL_CLK_EIM_PODF] = imx_clk_fixup_divider("eim_podf", "eim_sel", base + 0x1c, 20, 3, imx_cscmr1_fixup); + clk[IMX6QDL_CLK_EIM_SLOW_PODF] = imx_clk_fixup_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3, imx_cscmr1_fixup); + } clk[IMX6QDL_CLK_VPU_AXI_PODF] = imx_clk_divider("vpu_axi_podf", "vpu_axi_sel", base + 0x24, 25, 3); clk[IMX6QDL_CLK_CKO1_PODF] = imx_clk_divider("cko1_podf", "cko1_sel", base + 0x60, 4, 3); clk[IMX6QDL_CLK_CKO2_PODF] = imx_clk_divider("cko2_podf", "cko2_sel", base + 0x60, 21, 3); @@ -380,7 +438,12 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) /* name parent_name reg shift width busy: reg, shift */ clk[IMX6QDL_CLK_AXI] = imx_clk_busy_divider("axi", "axi_sel", base + 0x14, 16, 3, base + 0x48, 0); clk[IMX6QDL_CLK_MMDC_CH0_AXI_PODF] = imx_clk_busy_divider("mmdc_ch0_axi_podf", "periph", base + 0x14, 19, 3, base + 0x48, 4); - clk[IMX6QDL_CLK_MMDC_CH1_AXI_PODF] = imx_clk_busy_divider("mmdc_ch1_axi_podf", "periph2", base + 0x14, 3, 3, base + 0x48, 2); + if (clk_on_imx6qp()) { + clk[IMX6QDL_CLK_MMDC_CH1_AXI_CG] = imx_clk_gate("mmdc_ch1_axi_cg", "periph2", base + 0x4, 18); + clk[IMX6QDL_CLK_MMDC_CH1_AXI_PODF] = imx_clk_busy_divider("mmdc_ch1_axi_podf", "mmdc_ch1_axi_cg", base + 0x14, 3, 3, base + 0x48, 2); + } else { + clk[IMX6QDL_CLK_MMDC_CH1_AXI_PODF] = imx_clk_busy_divider("mmdc_ch1_axi_podf", "periph2", base + 0x14, 3, 3, base + 0x48, 2); + } clk[IMX6QDL_CLK_ARM] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16); clk[IMX6QDL_CLK_AHB] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1); @@ -432,8 +495,13 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6QDL_CLK_IPU1_DI1] = imx_clk_gate2("ipu1_di1", "ipu1_di1_sel", base + 0x74, 4); clk[IMX6QDL_CLK_IPU2] = imx_clk_gate2("ipu2", "ipu2_podf", base + 0x74, 6); clk[IMX6QDL_CLK_IPU2_DI0] = imx_clk_gate2("ipu2_di0", "ipu2_di0_sel", base + 0x74, 8); - clk[IMX6QDL_CLK_LDB_DI0] = imx_clk_gate2("ldb_di0", "ldb_di0_podf", base + 0x74, 12); - clk[IMX6QDL_CLK_LDB_DI1] = imx_clk_gate2("ldb_di1", "ldb_di1_podf", base + 0x74, 14); + if (clk_on_imx6qp()) { + clk[IMX6QDL_CLK_LDB_DI0] = imx_clk_gate2("ldb_di0", "ldb_di0_sel", base + 0x74, 12); + clk[IMX6QDL_CLK_LDB_DI1] = imx_clk_gate2("ldb_di1", "ldb_di1_sel", base + 0x74, 14); + } else { + clk[IMX6QDL_CLK_LDB_DI0] = imx_clk_gate2("ldb_di0", "ldb_di0_podf", base + 0x74, 12); + clk[IMX6QDL_CLK_LDB_DI1] = imx_clk_gate2("ldb_di1", "ldb_di1_podf", base + 0x74, 14); + } clk[IMX6QDL_CLK_IPU2_DI1] = imx_clk_gate2("ipu2_di1", "ipu2_di1_sel", base + 0x74, 10); clk[IMX6QDL_CLK_HSI_TX] = imx_clk_gate2_shared("hsi_tx", "hsi_tx_podf", base + 0x74, 16, &share_count_mipi_core_cfg); clk[IMX6QDL_CLK_MIPI_CORE_CFG] = imx_clk_gate2_shared("mipi_core_cfg", "video_27m", base + 0x74, 16, &share_count_mipi_core_cfg); @@ -482,6 +550,16 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6QDL_CLK_EIM_SLOW] = imx_clk_gate2("eim_slow", "eim_slow_podf", base + 0x80, 10); clk[IMX6QDL_CLK_VDO_AXI] = imx_clk_gate2("vdo_axi", "vdo_axi_sel", base + 0x80, 12); clk[IMX6QDL_CLK_VPU_AXI] = imx_clk_gate2("vpu_axi", "vpu_axi_podf", base + 0x80, 14); + if (clk_on_imx6qp()) { + clk[IMX6QDL_CLK_PRE0] = imx_clk_gate2("pre0", "pre_axi", base + 0x80, 16); + clk[IMX6QDL_CLK_PRE1] = imx_clk_gate2("pre1", "pre_axi", base + 0x80, 18); + clk[IMX6QDL_CLK_PRE2] = imx_clk_gate2("pre2", "pre_axi", base + 0x80, 20); + clk[IMX6QDL_CLK_PRE3] = imx_clk_gate2("pre3", "pre_axi", base + 0x80, 22); + clk[IMX6QDL_CLK_PRG0_AXI] = imx_clk_gate2_shared("prg0_axi", "ipu1_podf", base + 0x80, 24, &share_count_prg0); + clk[IMX6QDL_CLK_PRG1_AXI] = imx_clk_gate2_shared("prg1_axi", "ipu2_podf", base + 0x80, 26, &share_count_prg1); + clk[IMX6QDL_CLK_PRG0_APB] = imx_clk_gate2_shared("prg0_apb", "ipg", base + 0x80, 24, &share_count_prg0); + clk[IMX6QDL_CLK_PRG1_APB] = imx_clk_gate2_shared("prg1_apb", "ipg", base + 0x80, 26, &share_count_prg1); + } clk[IMX6QDL_CLK_CKO1] = imx_clk_gate("cko1", "cko1_podf", base + 0x60, 7); clk[IMX6QDL_CLK_CKO2] = imx_clk_gate("cko2", "cko2_podf", base + 0x60, 24); diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c index 08692d74b8847d0dfb2bb09f9b006a902425f335..0f1f17a8f3ed3e43cbb2d8b7834c1f2f6af8251c 100644 --- a/drivers/clk/imx/clk-imx6ul.c +++ b/drivers/clk/imx/clk-imx6ul.c @@ -157,9 +157,9 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) clk_set_parent(clks[IMX6UL_PLL7_BYPASS], clks[IMX6UL_CLK_PLL7]); clks[IMX6UL_CLK_PLL1_SYS] = imx_clk_fixed_factor("pll1_sys", "pll1_bypass", 1, 1); - clks[IMX6UL_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13); - clks[IMX6UL_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13); - clks[IMX6UL_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13); + clks[IMX6UL_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13); + clks[IMX6UL_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13); + clks[IMX6UL_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13); clks[IMX6UL_CLK_PLL5_VIDEO] = imx_clk_gate("pll5_video", "pll5_bypass", base + 0xa0, 13); clks[IMX6UL_CLK_PLL6_ENET] = imx_clk_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13); clks[IMX6UL_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13); @@ -196,8 +196,8 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) base + 0xe0, 2, 2, 0, clk_enet_ref_table, &imx_ccm_lock); clks[IMX6UL_CLK_ENET2_REF_125M] = imx_clk_gate("enet_ref_125m", "enet2_ref", base + 0xe0, 20); - clks[IMX6UL_CLK_ENET_PTP_REF] = imx_clk_fixed_factor("enet_ptp_ref", "pll6_enet", 1, 20); - clks[IMX6UL_CLK_ENET_PTP] = imx_clk_gate("enet_ptp", "enet_ptp_ref", base + 0xe0, 21); + clks[IMX6UL_CLK_ENET_PTP_REF] = imx_clk_fixed_factor("enet_ptp_ref", "pll6_enet", 1, 20); + clks[IMX6UL_CLK_ENET_PTP] = imx_clk_gate("enet_ptp", "enet_ptp_ref", base + 0xe0, 21); clks[IMX6UL_CLK_PLL4_POST_DIV] = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio", CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock); @@ -210,8 +210,8 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) /* name parent_name mult div */ clks[IMX6UL_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1, 2); - clks[IMX6UL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6); - clks[IMX6UL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8); + clks[IMX6UL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6); + clks[IMX6UL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8); clks[IMX6UL_CLK_GPT_3M] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8); np = ccm_node; @@ -219,34 +219,34 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) WARN_ON(!base); clks[IMX6UL_CA7_SECONDARY_SEL] = imx_clk_mux("ca7_secondary_sel", base + 0xc, 3, 1, ca7_secondary_sels, ARRAY_SIZE(ca7_secondary_sels)); - clks[IMX6UL_CLK_STEP] = imx_clk_mux("step", base + 0x0c, 8, 1, step_sels, ARRAY_SIZE(step_sels)); - clks[IMX6UL_CLK_PLL1_SW] = imx_clk_mux_flags("pll1_sw", base + 0x0c, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels), 0); + clks[IMX6UL_CLK_STEP] = imx_clk_mux("step", base + 0x0c, 8, 1, step_sels, ARRAY_SIZE(step_sels)); + clks[IMX6UL_CLK_PLL1_SW] = imx_clk_mux_flags("pll1_sw", base + 0x0c, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels), 0); clks[IMX6UL_CLK_AXI_ALT_SEL] = imx_clk_mux("axi_alt_sel", base + 0x14, 7, 1, axi_alt_sels, ARRAY_SIZE(axi_alt_sels)); - clks[IMX6UL_CLK_AXI_SEL] = imx_clk_mux_flags("axi_sel", base + 0x14, 6, 1, axi_sels, ARRAY_SIZE(axi_sels), 0); - clks[IMX6UL_CLK_PERIPH_PRE] = imx_clk_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels)); - clks[IMX6UL_CLK_PERIPH2_PRE] = imx_clk_mux("periph2_pre", base + 0x18, 21, 2, periph2_pre_sels, ARRAY_SIZE(periph2_pre_sels)); + clks[IMX6UL_CLK_AXI_SEL] = imx_clk_mux_flags("axi_sel", base + 0x14, 6, 1, axi_sels, ARRAY_SIZE(axi_sels), 0); + clks[IMX6UL_CLK_PERIPH_PRE] = imx_clk_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels)); + clks[IMX6UL_CLK_PERIPH2_PRE] = imx_clk_mux("periph2_pre", base + 0x18, 21, 2, periph2_pre_sels, ARRAY_SIZE(periph2_pre_sels)); clks[IMX6UL_CLK_PERIPH_CLK2_SEL] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels)); clks[IMX6UL_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels)); - clks[IMX6UL_CLK_EIM_SLOW_SEL] = imx_clk_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels)); + clks[IMX6UL_CLK_EIM_SLOW_SEL] = imx_clk_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels)); clks[IMX6UL_CLK_GPMI_SEL] = imx_clk_mux("gpmi_sel", base + 0x1c, 19, 1, gpmi_sels, ARRAY_SIZE(gpmi_sels)); - clks[IMX6UL_CLK_BCH_SEL] = imx_clk_mux("bch_sel", base + 0x1c, 18, 1, bch_sels, ARRAY_SIZE(bch_sels)); + clks[IMX6UL_CLK_BCH_SEL] = imx_clk_mux("bch_sel", base + 0x1c, 18, 1, bch_sels, ARRAY_SIZE(bch_sels)); clks[IMX6UL_CLK_USDHC2_SEL] = imx_clk_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); clks[IMX6UL_CLK_USDHC1_SEL] = imx_clk_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); - clks[IMX6UL_CLK_SAI3_SEL] = imx_clk_mux("sai3_sel", base + 0x1c, 14, 2, sai_sels, ARRAY_SIZE(sai_sels)); + clks[IMX6UL_CLK_SAI3_SEL] = imx_clk_mux("sai3_sel", base + 0x1c, 14, 2, sai_sels, ARRAY_SIZE(sai_sels)); clks[IMX6UL_CLK_SAI2_SEL] = imx_clk_mux("sai2_sel", base + 0x1c, 12, 2, sai_sels, ARRAY_SIZE(sai_sels)); - clks[IMX6UL_CLK_SAI1_SEL] = imx_clk_mux("sai1_sel", base + 0x1c, 10, 2, sai_sels, ARRAY_SIZE(sai_sels)); - clks[IMX6UL_CLK_QSPI1_SEL] = imx_clk_mux("qspi1_sel", base + 0x1c, 7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels)); - clks[IMX6UL_CLK_PERCLK_SEL] = imx_clk_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels)); - clks[IMX6UL_CLK_CAN_SEL] = imx_clk_mux("can_sel", base + 0x20, 8, 2, can_sels, ARRAY_SIZE(can_sels)); + clks[IMX6UL_CLK_SAI1_SEL] = imx_clk_mux("sai1_sel", base + 0x1c, 10, 2, sai_sels, ARRAY_SIZE(sai_sels)); + clks[IMX6UL_CLK_QSPI1_SEL] = imx_clk_mux("qspi1_sel", base + 0x1c, 7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels)); + clks[IMX6UL_CLK_PERCLK_SEL] = imx_clk_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels)); + clks[IMX6UL_CLK_CAN_SEL] = imx_clk_mux("can_sel", base + 0x20, 8, 2, can_sels, ARRAY_SIZE(can_sels)); clks[IMX6UL_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels)); clks[IMX6UL_CLK_ENFC_SEL] = imx_clk_mux("enfc_sel", base + 0x2c, 15, 3, enfc_sels, ARRAY_SIZE(enfc_sels)); clks[IMX6UL_CLK_LDB_DI0_SEL] = imx_clk_mux("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di0_sels, ARRAY_SIZE(ldb_di0_sels)); clks[IMX6UL_CLK_SPDIF_SEL] = imx_clk_mux("spdif_sel", base + 0x30, 20, 2, spdif_sels, ARRAY_SIZE(spdif_sels)); - clks[IMX6UL_CLK_SIM_PRE_SEL] = imx_clk_mux("sim_pre_sel", base + 0x34, 15, 3, sim_pre_sels, ARRAY_SIZE(sim_pre_sels)); - clks[IMX6UL_CLK_SIM_SEL] = imx_clk_mux("sim_sel", base + 0x34, 9, 3, sim_sels, ARRAY_SIZE(sim_sels)); + clks[IMX6UL_CLK_SIM_PRE_SEL] = imx_clk_mux("sim_pre_sel", base + 0x34, 15, 3, sim_pre_sels, ARRAY_SIZE(sim_pre_sels)); + clks[IMX6UL_CLK_SIM_SEL] = imx_clk_mux("sim_sel", base + 0x34, 9, 3, sim_sels, ARRAY_SIZE(sim_sels)); clks[IMX6UL_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels)); clks[IMX6UL_CLK_LCDIF_PRE_SEL] = imx_clk_mux("lcdif_pre_sel", base + 0x38, 15, 3, lcdif_pre_sels, ARRAY_SIZE(lcdif_pre_sels)); - clks[IMX6UL_CLK_LCDIF_SEL] = imx_clk_mux("lcdif_sel", base + 0x38, 9, 3, lcdif_sels, ARRAY_SIZE(lcdif_sels)); + clks[IMX6UL_CLK_LCDIF_SEL] = imx_clk_mux("lcdif_sel", base + 0x38, 9, 3, lcdif_sels, ARRAY_SIZE(lcdif_sels)); clks[IMX6UL_CLK_LDB_DI0_DIV_SEL] = imx_clk_mux("ldb_di0", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels)); clks[IMX6UL_CLK_LDB_DI1_DIV_SEL] = imx_clk_mux("ldb_di1", base + 0x20, 11, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels)); @@ -259,11 +259,11 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) clks[IMX6UL_CLK_PERIPH] = imx_clk_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels)); clks[IMX6UL_CLK_PERIPH2] = imx_clk_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels)); - clks[IMX6UL_CLK_PERIPH_CLK2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3); - clks[IMX6UL_CLK_PERIPH2_CLK2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3); + clks[IMX6UL_CLK_PERIPH_CLK2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3); + clks[IMX6UL_CLK_PERIPH2_CLK2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3); clks[IMX6UL_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2); clks[IMX6UL_CLK_LCDIF_PODF] = imx_clk_divider("lcdif_podf", "lcdif_pred", base + 0x18, 23, 3); - clks[IMX6UL_CLK_QSPI1_PDOF] = imx_clk_divider("qspi1_podf", "qspi1_sel", base + 0x1c, 26, 3); + clks[IMX6UL_CLK_QSPI1_PDOF] = imx_clk_divider("qspi1_podf", "qspi1_sel", base + 0x1c, 26, 3); clks[IMX6UL_CLK_EIM_SLOW_PODF] = imx_clk_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3); clks[IMX6UL_CLK_PERCLK] = imx_clk_divider("perclk", "perclk_sel", base + 0x1c, 0, 6); clks[IMX6UL_CLK_CAN_PODF] = imx_clk_divider("can_podf", "can_sel", base + 0x20, 2, 6); @@ -287,14 +287,14 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) clks[IMX6UL_CLK_LCDIF_PRED] = imx_clk_divider("lcdif_pred", "lcdif_pre_sel", base + 0x38, 12, 3); clks[IMX6UL_CLK_CSI_PODF] = imx_clk_divider("csi_podf", "csi_sel", base + 0x3c, 11, 3); - clks[IMX6UL_CLK_ARM] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16); + clks[IMX6UL_CLK_ARM] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16); clks[IMX6UL_CLK_MMDC_PODF] = imx_clk_busy_divider("mmdc_podf", "periph2", base + 0x14, 3, 3, base + 0x48, 2); clks[IMX6UL_CLK_AXI_PODF] = imx_clk_busy_divider("axi_podf", "axi_sel", base + 0x14, 16, 3, base + 0x48, 0); clks[IMX6UL_CLK_AHB] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1); /* CCGR0 */ - clks[IMX6UL_CLK_AIPSTZ1] = imx_clk_gate2("aips_tz1", "ahb", base + 0x68, 0); - clks[IMX6UL_CLK_AIPSTZ2] = imx_clk_gate2("aips_tz2", "ahb", base + 0x68, 2); + clks[IMX6UL_CLK_AIPSTZ1] = imx_clk_gate2("aips_tz1", "ahb", base + 0x68, 0); + clks[IMX6UL_CLK_AIPSTZ2] = imx_clk_gate2("aips_tz2", "ahb", base + 0x68, 2); clks[IMX6UL_CLK_APBHDMA] = imx_clk_gate2("apbh_dma", "bch_podf", base + 0x68, 4); clks[IMX6UL_CLK_ASRC_IPG] = imx_clk_gate2_shared("asrc_ipg", "ahb", base + 0x68, 6, &share_count_asrc); clks[IMX6UL_CLK_ASRC_MEM] = imx_clk_gate2_shared("asrc_mem", "ahb", base + 0x68, 6, &share_count_asrc); @@ -302,7 +302,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) clks[IMX6UL_CLK_CAAM_ACLK] = imx_clk_gate2("caam_aclk", "ahb", base + 0x68, 10); clks[IMX6UL_CLK_CAAM_IPG] = imx_clk_gate2("caam_ipg", "ipg", base + 0x68, 12); clks[IMX6UL_CLK_CAN1_IPG] = imx_clk_gate2("can1_ipg", "ipg", base + 0x68, 14); - clks[IMX6UL_CLK_CAN1_SERIAL] = imx_clk_gate2("can1_serial", "can_podf", base + 0x68, 16); + clks[IMX6UL_CLK_CAN1_SERIAL] = imx_clk_gate2("can1_serial", "can_podf", base + 0x68, 16); clks[IMX6UL_CLK_CAN2_IPG] = imx_clk_gate2("can2_ipg", "ipg", base + 0x68, 18); clks[IMX6UL_CLK_CAN2_SERIAL] = imx_clk_gate2("can2_serial", "can_podf", base + 0x68, 20); clks[IMX6UL_CLK_GPT2_BUS] = imx_clk_gate2("gpt_bus", "perclk", base + 0x68, 24); @@ -331,7 +331,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) clks[IMX6UL_CLK_CSI] = imx_clk_gate2("csi", "csi_podf", base + 0x70, 2); clks[IMX6UL_CLK_I2C1] = imx_clk_gate2("i2c1", "perclk", base + 0x70, 6); clks[IMX6UL_CLK_I2C2] = imx_clk_gate2("i2c2", "perclk", base + 0x70, 8); - clks[IMX6UL_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10); + clks[IMX6UL_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10); clks[IMX6UL_CLK_OCOTP] = imx_clk_gate2("ocotp", "ipg", base + 0x70, 12); clks[IMX6UL_CLK_IOMUXC] = imx_clk_gate2("iomuxc", "lcdif_podf", base + 0x70, 14); clks[IMX6UL_CLK_LCDIF_APB] = imx_clk_gate2("lcdif_apb", "axi", base + 0x70, 28); @@ -365,6 +365,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) /* CCGR5 */ clks[IMX6UL_CLK_ROM] = imx_clk_gate2("rom", "ahb", base + 0x7c, 0); clks[IMX6UL_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6); + clks[IMX6UL_CLK_KPP] = imx_clk_gate2("kpp", "ipg", base + 0x7c, 8); clks[IMX6UL_CLK_WDOG2] = imx_clk_gate2("wdog2", "ipg", base + 0x7c, 10); clks[IMX6UL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); clks[IMX6UL_CLK_SPDIF] = imx_clk_gate2_shared("spdif", "spdif_podf", base + 0x7c, 14, &share_count_audio); @@ -391,10 +392,10 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) clks[IMX6UL_CLK_UART8_IPG] = imx_clk_gate2("uart8_ipg", "ipg", base + 0x80, 14); clks[IMX6UL_CLK_UART8_SERIAL] = imx_clk_gate2("uart8_serial", "uart_podf", base + 0x80, 14); clks[IMX6UL_CLK_WDOG3] = imx_clk_gate2("wdog3", "ipg", base + 0x80, 20); - clks[IMX6UL_CLK_I2C4] = imx_clk_gate2("i2c4", "perclk", base + 0x80, 24); + clks[IMX6UL_CLK_I2C4] = imx_clk_gate2("i2c4", "perclk", base + 0x80, 24); clks[IMX6UL_CLK_PWM5] = imx_clk_gate2("pwm5", "perclk", base + 0x80, 26); clks[IMX6UL_CLK_PWM6] = imx_clk_gate2("pwm6", "perclk", base + 0x80, 28); - clks[IMX6UL_CLK_PWM7] = imx_clk_gate2("Pwm7", "perclk", base + 0x80, 30); + clks[IMX6UL_CLK_PWM7] = imx_clk_gate2("pwm7", "perclk", base + 0x80, 30); /* mask handshake of mmdc */ writel_relaxed(BM_CCM_CCDR_MMDC_CH0_MASK, base + CCDR); diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h index c94ac5c26226df1edadfef4ebf1a0ac829c84c14..d942f5748d08ecad14f06cb6461765212a52f6a1 100644 --- a/drivers/clk/imx/clk.h +++ b/drivers/clk/imx/clk.h @@ -87,7 +87,7 @@ struct clk *imx_clk_fixup_mux(const char *name, void __iomem *reg, static inline struct clk *imx_clk_fixed(const char *name, int rate) { - return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate); + return clk_register_fixed_rate(NULL, name, NULL, 0, rate); } static inline struct clk *imx_clk_divider(const char *name, const char *parent, diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c index 576bdb7c98b8c98f6ece22aea9ae80443ad2b887..2a76901bf04bf377c3903bf19ff58670c96cd332 100644 --- a/drivers/clk/mediatek/clk-gate.c +++ b/drivers/clk/mediatek/clk-gate.c @@ -25,7 +25,7 @@ static int mtk_cg_bit_is_cleared(struct clk_hw *hw) { - struct mtk_clk_gate *cg = to_clk_gate(hw); + struct mtk_clk_gate *cg = to_mtk_clk_gate(hw); u32 val; regmap_read(cg->regmap, cg->sta_ofs, &val); @@ -37,7 +37,7 @@ static int mtk_cg_bit_is_cleared(struct clk_hw *hw) static int mtk_cg_bit_is_set(struct clk_hw *hw) { - struct mtk_clk_gate *cg = to_clk_gate(hw); + struct mtk_clk_gate *cg = to_mtk_clk_gate(hw); u32 val; regmap_read(cg->regmap, cg->sta_ofs, &val); @@ -49,14 +49,14 @@ static int mtk_cg_bit_is_set(struct clk_hw *hw) static void mtk_cg_set_bit(struct clk_hw *hw) { - struct mtk_clk_gate *cg = to_clk_gate(hw); + struct mtk_clk_gate *cg = to_mtk_clk_gate(hw); regmap_write(cg->regmap, cg->set_ofs, BIT(cg->bit)); } static void mtk_cg_clr_bit(struct clk_hw *hw) { - struct mtk_clk_gate *cg = to_clk_gate(hw); + struct mtk_clk_gate *cg = to_mtk_clk_gate(hw); regmap_write(cg->regmap, cg->clr_ofs, BIT(cg->bit)); } diff --git a/drivers/clk/mediatek/clk-gate.h b/drivers/clk/mediatek/clk-gate.h index 11e25c992948fdcc7ea00c5cfa31f0274e6dfb53..b1821603b887f2874f97c6fb1819ff0fddfcd619 100644 --- a/drivers/clk/mediatek/clk-gate.h +++ b/drivers/clk/mediatek/clk-gate.h @@ -29,7 +29,7 @@ struct mtk_clk_gate { u8 bit; }; -static inline struct mtk_clk_gate *to_clk_gate(struct clk_hw *hw) +static inline struct mtk_clk_gate *to_mtk_clk_gate(struct clk_hw *hw) { return container_of(hw, struct mtk_clk_gate, hw); } diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c index cf08db6c130c9887e6bc4ed40415aa683efd9b8d..5ada644e620075b2160726b094909183af9452bb 100644 --- a/drivers/clk/mediatek/clk-mtk.c +++ b/drivers/clk/mediatek/clk-mtk.c @@ -58,8 +58,8 @@ void __init mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks, for (i = 0; i < num; i++) { const struct mtk_fixed_clk *rc = &clks[i]; - clk = clk_register_fixed_rate(NULL, rc->name, rc->parent, - rc->parent ? 0 : CLK_IS_ROOT, rc->rate); + clk = clk_register_fixed_rate(NULL, rc->name, rc->parent, 0, + rc->rate); if (IS_ERR(clk)) { pr_err("Failed to register clk %s: %ld\n", @@ -209,12 +209,14 @@ struct clk * __init mtk_clk_register_composite(const struct mtk_composite *mc, mc->flags); if (IS_ERR(clk)) { - kfree(gate); - kfree(mux); + ret = PTR_ERR(clk); + goto err_out; } return clk; err_out: + kfree(div); + kfree(gate); kfree(mux); return ERR_PTR(ret); diff --git a/drivers/clk/mediatek/reset.c b/drivers/clk/mediatek/reset.c index 9e9fe4b19ac47b11dc2fba8431687137e1934f99..309049d41f1ba04539fee6a7853a98d1f44e7874 100644 --- a/drivers/clk/mediatek/reset.c +++ b/drivers/clk/mediatek/reset.c @@ -57,7 +57,7 @@ static int mtk_reset(struct reset_controller_dev *rcdev, return mtk_reset_deassert(rcdev, id); } -static struct reset_control_ops mtk_reset_ops = { +static const struct reset_control_ops mtk_reset_ops = { .assert = mtk_reset_assert, .deassert = mtk_reset_deassert, .reset = mtk_reset, diff --git a/drivers/clk/meson/clkc.c b/drivers/clk/meson/clkc.c index c83ae1367abc1791618b858fe3544211c12dfaaf..d920d410b51d2fb586c26a41fb989b68836d9751 100644 --- a/drivers/clk/meson/clkc.c +++ b/drivers/clk/meson/clkc.c @@ -198,7 +198,7 @@ meson_clk_register_fixed_rate(const struct clk_conf *clk_conf, } void __init meson_clk_register_clks(const struct clk_conf *clk_confs, - size_t nr_confs, + unsigned int nr_confs, void __iomem *clk_base) { unsigned int i; diff --git a/drivers/clk/mmp/reset.c b/drivers/clk/mmp/reset.c index b54da1fe73f07ea5f36a82ac33da211b9cc375a1..b4e4d6aa26319a3b871d7d609df4ac6ee9a9ab78 100644 --- a/drivers/clk/mmp/reset.c +++ b/drivers/clk/mmp/reset.c @@ -74,7 +74,7 @@ static int mmp_clk_reset_deassert(struct reset_controller_dev *rcdev, return 0; } -static struct reset_control_ops mmp_clk_reset_ops = { +static const struct reset_control_ops mmp_clk_reset_ops = { .assert = mmp_clk_reset_assert, .deassert = mmp_clk_reset_deassert, }; diff --git a/drivers/clk/mvebu/Kconfig b/drivers/clk/mvebu/Kconfig index 27696255486dee6feb00e728019d4b7752128bcc..eaee8f099c8c589f5771ebc6761c1bd66b0f729f 100644 --- a/drivers/clk/mvebu/Kconfig +++ b/drivers/clk/mvebu/Kconfig @@ -11,7 +11,6 @@ config ARMADA_370_CLK bool select MVEBU_CLK_COMMON select MVEBU_CLK_CPU - select MVEBU_CLK_COREDIV config ARMADA_375_CLK bool @@ -29,7 +28,6 @@ config ARMADA_XP_CLK bool select MVEBU_CLK_COMMON select MVEBU_CLK_CPU - select MVEBU_CLK_COREDIV config DOVE_CLK bool diff --git a/drivers/clk/mvebu/common.c b/drivers/clk/mvebu/common.c index 28aac67e7b92b0c668fee1d2d7c637a708141cef..66be2e0c82b488df5c8be50d1f0bd28367e4eb5d 100644 --- a/drivers/clk/mvebu/common.c +++ b/drivers/clk/mvebu/common.c @@ -137,8 +137,8 @@ void __init mvebu_coreclk_setup(struct device_node *np, of_property_read_string_index(np, "clock-output-names", 0, &tclk_name); rate = desc->get_tclk_freq(base); - clk_data.clks[0] = clk_register_fixed_rate(NULL, tclk_name, NULL, - CLK_IS_ROOT, rate); + clk_data.clks[0] = clk_register_fixed_rate(NULL, tclk_name, NULL, 0, + rate); WARN_ON(IS_ERR(clk_data.clks[0])); /* Register CPU clock */ @@ -150,8 +150,8 @@ void __init mvebu_coreclk_setup(struct device_node *np, && desc->is_sscg_enabled(base)) rate = desc->fix_sscg_deviation(rate); - clk_data.clks[1] = clk_register_fixed_rate(NULL, cpuclk_name, NULL, - CLK_IS_ROOT, rate); + clk_data.clks[1] = clk_register_fixed_rate(NULL, cpuclk_name, NULL, 0, + rate); WARN_ON(IS_ERR(clk_data.clks[1])); /* Register fixed-factor clocks derived from CPU clock */ @@ -174,8 +174,7 @@ void __init mvebu_coreclk_setup(struct device_node *np, 2 + desc->num_ratios, &name); rate = desc->get_refclk_freq(base); clk_data.clks[2 + desc->num_ratios] = - clk_register_fixed_rate(NULL, name, NULL, - CLK_IS_ROOT, rate); + clk_register_fixed_rate(NULL, name, NULL, 0, rate); WARN_ON(IS_ERR(clk_data.clks[2 + desc->num_ratios])); } @@ -199,8 +198,6 @@ struct clk_gating_ctrl { u32 saved_reg; }; -#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw) - static struct clk_gating_ctrl *ctrl; static struct clk *clk_gating_get_src( diff --git a/drivers/clk/mvebu/dove-divider.c b/drivers/clk/mvebu/dove-divider.c index 3e0b52daa35f8814a413ccfe7599ac80a3f59e8f..4091f3cfee19fd341ce962b41604aefef1885a18 100644 --- a/drivers/clk/mvebu/dove-divider.c +++ b/drivers/clk/mvebu/dove-divider.c @@ -225,8 +225,7 @@ static int dove_divider_init(struct device *dev, void __iomem *base, * Create the core PLL clock. We treat this as a fixed rate * clock as we don't know any better, and documentation is sparse. */ - clk = clk_register_fixed_rate(dev, core_pll[0], NULL, CLK_IS_ROOT, - 2000000000UL); + clk = clk_register_fixed_rate(dev, core_pll[0], NULL, 0, 2000000000UL); if (IS_ERR(clk)) return PTR_ERR(clk); diff --git a/drivers/clk/mvebu/kirkwood.c b/drivers/clk/mvebu/kirkwood.c index 99550f25975ea74b8963bb77910b5cf1614f3594..a2a8d614039da91a1b3f99272aa98e5952b79037 100644 --- a/drivers/clk/mvebu/kirkwood.c +++ b/drivers/clk/mvebu/kirkwood.c @@ -256,8 +256,6 @@ static const struct clk_muxing_soc_desc kirkwood_mux_desc[] __initconst = { 11, 1, 0 }, }; -#define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw) - static struct clk *clk_muxing_get_src( struct of_phandle_args *clkspec, void *data) { diff --git a/drivers/clk/mxs/clk-div.c b/drivers/clk/mxs/clk-div.c index 049ee27d5a22e680fad65c689a69813086d157e8..f75e989c578ffca5ce8474262a60b9809e13fd7f 100644 --- a/drivers/clk/mxs/clk-div.c +++ b/drivers/clk/mxs/clk-div.c @@ -33,7 +33,7 @@ struct clk_div { static inline struct clk_div *to_clk_div(struct clk_hw *hw) { - struct clk_divider *divider = container_of(hw, struct clk_divider, hw); + struct clk_divider *divider = to_clk_divider(hw); return container_of(divider, struct clk_div, divider); } diff --git a/drivers/clk/mxs/clk.h b/drivers/clk/mxs/clk.h index a4590956d2a28863565549b7e4b4ed0a40d7a66e..5a264a486ad90952943143d3f185394e85d181f0 100644 --- a/drivers/clk/mxs/clk.h +++ b/drivers/clk/mxs/clk.h @@ -38,7 +38,7 @@ struct clk *mxs_clk_frac(const char *name, const char *parent_name, static inline struct clk *mxs_clk_fixed(const char *name, int rate) { - return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate); + return clk_register_fixed_rate(NULL, name, NULL, 0, rate); } static inline struct clk *mxs_clk_gate(const char *name, diff --git a/drivers/clk/nxp/Makefile b/drivers/clk/nxp/Makefile index 607bd48c656306a770f7fa9b651bc58791577b9e..d456ee6cc3d332e8bacb42ec94d5d4fb18171837 100644 --- a/drivers/clk/nxp/Makefile +++ b/drivers/clk/nxp/Makefile @@ -1,3 +1,4 @@ obj-$(CONFIG_ARCH_LPC18XX) += clk-lpc18xx-cgu.o obj-$(CONFIG_ARCH_LPC18XX) += clk-lpc18xx-ccu.o +obj-$(CONFIG_ARCH_LPC18XX) += clk-lpc18xx-creg.o obj-$(CONFIG_ARCH_LPC32XX) += clk-lpc32xx.o diff --git a/drivers/clk/nxp/clk-lpc18xx-ccu.c b/drivers/clk/nxp/clk-lpc18xx-ccu.c index 13aabbb3acbec3ff91d1fd478f097cd3014bfd8d..f7136b94fd0ea51f8b877e6403f076a9463263da 100644 --- a/drivers/clk/nxp/clk-lpc18xx-ccu.c +++ b/drivers/clk/nxp/clk-lpc18xx-ccu.c @@ -28,8 +28,6 @@ #define CCU_BRANCH_IS_BUS BIT(0) #define CCU_BRANCH_HAVE_DIV2 BIT(1) -#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw) - struct lpc18xx_branch_clk_data { const char **name; int num; @@ -222,7 +220,7 @@ static void lpc18xx_ccu_register_branch_gate_div(struct lpc18xx_clk_branch *bran div->width = 1; div_hw = &div->hw; - div_ops = &clk_divider_ops; + div_ops = &clk_divider_ro_ops; } branch->gate.reg = branch->offset + reg_base; diff --git a/drivers/clk/nxp/clk-lpc18xx-cgu.c b/drivers/clk/nxp/clk-lpc18xx-cgu.c index c924572fc9bc1296b6c7353ff0b39d8ed92ead62..2531174b399ea28b4f5dd86f08853f65e2b20dc9 100644 --- a/drivers/clk/nxp/clk-lpc18xx-cgu.c +++ b/drivers/clk/nxp/clk-lpc18xx-cgu.c @@ -605,7 +605,7 @@ static void __init lpc18xx_cgu_register_source_clks(struct device_node *np, /* Register the internal 12 MHz RC oscillator (IRC) */ clk = clk_register_fixed_rate(NULL, clk_src_names[CLK_SRC_IRC], - NULL, CLK_IS_ROOT, 12000000); + NULL, 0, 12000000); if (IS_ERR(clk)) pr_warn("%s: failed to register irc clk\n", __func__); diff --git a/drivers/clk/nxp/clk-lpc18xx-creg.c b/drivers/clk/nxp/clk-lpc18xx-creg.c new file mode 100644 index 0000000000000000000000000000000000000000..d44b61afa2dc5185ab91a9d214663aea7e59496d --- /dev/null +++ b/drivers/clk/nxp/clk-lpc18xx-creg.c @@ -0,0 +1,226 @@ +/* + * Clk driver for NXP LPC18xx/43xx Configuration Registers (CREG) + * + * Copyright (C) 2015 Joachim Eastwood + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define LPC18XX_CREG_CREG0 0x004 +#define LPC18XX_CREG_CREG0_EN1KHZ BIT(0) +#define LPC18XX_CREG_CREG0_EN32KHZ BIT(1) +#define LPC18XX_CREG_CREG0_RESET32KHZ BIT(2) +#define LPC18XX_CREG_CREG0_PD32KHZ BIT(3) + +#define to_clk_creg(_hw) container_of(_hw, struct clk_creg_data, hw) + +enum { + CREG_CLK_1KHZ, + CREG_CLK_32KHZ, + CREG_CLK_MAX, +}; + +struct clk_creg_data { + struct clk_hw hw; + const char *name; + struct regmap *reg; + unsigned int en_mask; + const struct clk_ops *ops; +}; + +#define CREG_CLK(_name, _emask, _ops) \ +{ \ + .name = _name, \ + .en_mask = LPC18XX_CREG_CREG0_##_emask, \ + .ops = &_ops, \ +} + +static int clk_creg_32k_prepare(struct clk_hw *hw) +{ + struct clk_creg_data *creg = to_clk_creg(hw); + int ret; + + ret = regmap_update_bits(creg->reg, LPC18XX_CREG_CREG0, + LPC18XX_CREG_CREG0_PD32KHZ | + LPC18XX_CREG_CREG0_RESET32KHZ, 0); + + /* + * Powering up the 32k oscillator takes a long while + * and sadly there aren't any status bit to poll. + */ + msleep(2500); + + return ret; +} + +static void clk_creg_32k_unprepare(struct clk_hw *hw) +{ + struct clk_creg_data *creg = to_clk_creg(hw); + + regmap_update_bits(creg->reg, LPC18XX_CREG_CREG0, + LPC18XX_CREG_CREG0_PD32KHZ, + LPC18XX_CREG_CREG0_PD32KHZ); +} + +static int clk_creg_32k_is_prepared(struct clk_hw *hw) +{ + struct clk_creg_data *creg = to_clk_creg(hw); + u32 reg; + + regmap_read(creg->reg, LPC18XX_CREG_CREG0, ®); + + return !(reg & LPC18XX_CREG_CREG0_PD32KHZ) && + !(reg & LPC18XX_CREG_CREG0_RESET32KHZ); +} + +static unsigned long clk_creg_1k_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + return parent_rate / 32; +} + +static int clk_creg_enable(struct clk_hw *hw) +{ + struct clk_creg_data *creg = to_clk_creg(hw); + + return regmap_update_bits(creg->reg, LPC18XX_CREG_CREG0, + creg->en_mask, creg->en_mask); +} + +static void clk_creg_disable(struct clk_hw *hw) +{ + struct clk_creg_data *creg = to_clk_creg(hw); + + regmap_update_bits(creg->reg, LPC18XX_CREG_CREG0, + creg->en_mask, 0); +} + +static int clk_creg_is_enabled(struct clk_hw *hw) +{ + struct clk_creg_data *creg = to_clk_creg(hw); + u32 reg; + + regmap_read(creg->reg, LPC18XX_CREG_CREG0, ®); + + return !!(reg & creg->en_mask); +} + +static const struct clk_ops clk_creg_32k = { + .enable = clk_creg_enable, + .disable = clk_creg_disable, + .is_enabled = clk_creg_is_enabled, + .prepare = clk_creg_32k_prepare, + .unprepare = clk_creg_32k_unprepare, + .is_prepared = clk_creg_32k_is_prepared, +}; + +static const struct clk_ops clk_creg_1k = { + .enable = clk_creg_enable, + .disable = clk_creg_disable, + .is_enabled = clk_creg_is_enabled, + .recalc_rate = clk_creg_1k_recalc_rate, +}; + +static struct clk_creg_data clk_creg_clocks[] = { + [CREG_CLK_1KHZ] = CREG_CLK("1khz_clk", EN1KHZ, clk_creg_1k), + [CREG_CLK_32KHZ] = CREG_CLK("32khz_clk", EN32KHZ, clk_creg_32k), +}; + +static struct clk *clk_register_creg_clk(struct device *dev, + struct clk_creg_data *creg_clk, + const char **parent_name, + struct regmap *syscon) +{ + struct clk_init_data init; + + init.ops = creg_clk->ops; + init.name = creg_clk->name; + init.parent_names = parent_name; + init.num_parents = 1; + + creg_clk->reg = syscon; + creg_clk->hw.init = &init; + + if (dev) + return devm_clk_register(dev, &creg_clk->hw); + + return clk_register(NULL, &creg_clk->hw); +} + +static struct clk *clk_creg_early[CREG_CLK_MAX]; +static struct clk_onecell_data clk_creg_early_data = { + .clks = clk_creg_early, + .clk_num = CREG_CLK_MAX, +}; + +static void __init lpc18xx_creg_clk_init(struct device_node *np) +{ + const char *clk_32khz_parent; + struct regmap *syscon; + + syscon = syscon_node_to_regmap(np->parent); + if (IS_ERR(syscon)) { + pr_err("%s: syscon lookup failed\n", __func__); + return; + } + + clk_32khz_parent = of_clk_get_parent_name(np, 0); + + clk_creg_early[CREG_CLK_32KHZ] = + clk_register_creg_clk(NULL, &clk_creg_clocks[CREG_CLK_32KHZ], + &clk_32khz_parent, syscon); + clk_creg_early[CREG_CLK_1KHZ] = ERR_PTR(-EPROBE_DEFER); + + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_creg_early_data); +} +CLK_OF_DECLARE(lpc18xx_creg_clk, "nxp,lpc1850-creg-clk", lpc18xx_creg_clk_init); + +static struct clk *clk_creg[CREG_CLK_MAX]; +static struct clk_onecell_data clk_creg_data = { + .clks = clk_creg, + .clk_num = CREG_CLK_MAX, +}; + +static int lpc18xx_creg_clk_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct regmap *syscon; + + syscon = syscon_node_to_regmap(np->parent); + if (IS_ERR(syscon)) { + dev_err(&pdev->dev, "syscon lookup failed\n"); + return PTR_ERR(syscon); + } + + clk_creg[CREG_CLK_32KHZ] = clk_creg_early[CREG_CLK_32KHZ]; + clk_creg[CREG_CLK_1KHZ] = + clk_register_creg_clk(NULL, &clk_creg_clocks[CREG_CLK_1KHZ], + &clk_creg_clocks[CREG_CLK_32KHZ].name, + syscon); + + return of_clk_add_provider(np, of_clk_src_onecell_get, &clk_creg_data); +} + +static const struct of_device_id lpc18xx_creg_clk_of_match[] = { + { .compatible = "nxp,lpc1850-creg-clk" }, + {}, +}; + +static struct platform_driver lpc18xx_creg_clk_driver = { + .probe = lpc18xx_creg_clk_probe, + .driver = { + .name = "lpc18xx-creg-clk", + .of_match_table = lpc18xx_creg_clk_of_match, + }, +}; +builtin_platform_driver(lpc18xx_creg_clk_driver); diff --git a/drivers/clk/nxp/clk-lpc32xx.c b/drivers/clk/nxp/clk-lpc32xx.c index 10dd0fdaa474b2fcac7fa917d95e6fce890fba6f..481b2646b4964ba5974dc7a4f4f0f40742796b3e 100644 --- a/drivers/clk/nxp/clk-lpc32xx.c +++ b/drivers/clk/nxp/clk-lpc32xx.c @@ -87,7 +87,7 @@ enum { enum { /* Start from the last defined clock in dt bindings */ - LPC32XX_CLK_ADC_DIV = LPC32XX_CLK_ADC + 1, + LPC32XX_CLK_ADC_DIV = LPC32XX_CLK_HCLK_PLL + 1, LPC32XX_CLK_ADC_RTC, LPC32XX_CLK_TEST1, LPC32XX_CLK_TEST2, @@ -96,7 +96,6 @@ enum { LPC32XX_CLK_OSC, LPC32XX_CLK_SYS, LPC32XX_CLK_PLL397X, - LPC32XX_CLK_HCLK_PLL, LPC32XX_CLK_HCLK_DIV_PERIPH, LPC32XX_CLK_HCLK_DIV, LPC32XX_CLK_HCLK, @@ -589,7 +588,8 @@ static long clk_hclk_pll_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *parent_rate) { struct lpc32xx_pll_clk *clk = to_lpc32xx_pll_clk(hw); - u64 m_i, m, n, p, o = rate, i = *parent_rate, d = (u64)rate << 6; + u64 m_i, o = rate, i = *parent_rate, d = (u64)rate << 6; + u64 m = 0, n = 0, p = 0; int p_i, n_i; pr_debug("%s: %lu/%lu\n", clk_hw_get_name(hw), *parent_rate, rate); @@ -1429,6 +1429,8 @@ static struct clk * __init lpc32xx_clk_register(u32 id) hw = &clk_hw->hw0.div.hw; else if (clk_hw->type == CLK_GATE) hw = &clk_hw->hw0.gate.hw; + else + return ERR_PTR(-EINVAL); hw->init = &clk_init; clk = clk_register(NULL, hw); @@ -1515,7 +1517,7 @@ static void __init lpc32xx_clk_init(struct device_node *np) return; } - for (i = 0; i < LPC32XX_CLK_MAX; i++) { + for (i = 1; i < LPC32XX_CLK_MAX; i++) { clk[i] = lpc32xx_clk_register(i); if (IS_ERR(clk[i])) { pr_err("failed to register %s clock: %ld\n", @@ -1526,9 +1528,6 @@ static void __init lpc32xx_clk_init(struct device_node *np) of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); - /* For 13MHz osc valid output range of PLL is from 156MHz to 266.5MHz */ - clk_set_rate(clk[LPC32XX_CLK_HCLK_PLL], 208000000); - /* Set 48MHz rate of USB PLL clock */ clk_set_rate(clk[LPC32XX_CLK_USB_PLL], 48000000); @@ -1555,7 +1554,7 @@ static void __init lpc32xx_usb_clk_init(struct device_node *np) return; } - for (i = 0; i < LPC32XX_USB_CLK_MAX; i++) { + for (i = 1; i < LPC32XX_USB_CLK_MAX; i++) { usb_clk[i] = lpc32xx_clk_register(i + LPC32XX_CLK_USB_OFFSET); if (IS_ERR(usb_clk[i])) { pr_err("failed to register %s clock: %ld\n", diff --git a/drivers/clk/pxa/clk-pxa25x.c b/drivers/clk/pxa/clk-pxa25x.c index b7747229db9ac162172c93975a00cdd1602e1e30..a98b98e2a9e4404047d5f965924a660464a13ec6 100644 --- a/drivers/clk/pxa/clk-pxa25x.c +++ b/drivers/clk/pxa/clk-pxa25x.c @@ -84,7 +84,7 @@ unsigned int pxa25x_get_clk_frequency_khz(int info) static unsigned long clk_pxa25x_memory_get_rate(struct clk_hw *hw, unsigned long parent_rate) { - unsigned long cccr = CCCR; + unsigned long cccr = readl(CCCR); unsigned int m = M_clk_mult[(cccr >> 5) & 0x03]; return parent_rate / m; @@ -99,7 +99,7 @@ PARENTS(pxa25x_osc3) = { "osc_3_6864mhz", "osc_3_6864mhz" }; #define PXA25X_CKEN(dev_id, con_id, parents, mult, div, \ bit, is_lp, flags) \ PXA_CKEN(dev_id, con_id, bit, parents, mult, div, mult, div, \ - is_lp, &CKEN, CKEN_ ## bit, flags) + is_lp, CKEN, CKEN_ ## bit, flags) #define PXA25X_PBUS95_CKEN(dev_id, con_id, bit, mult_hp, div_hp, delay) \ PXA25X_CKEN(dev_id, con_id, pxa25x_pbus95_parents, mult_hp, \ div_hp, bit, NULL, 0) @@ -112,10 +112,10 @@ PARENTS(pxa25x_osc3) = { "osc_3_6864mhz", "osc_3_6864mhz" }; #define PXA25X_CKEN_1RATE(dev_id, con_id, bit, parents, delay) \ PXA_CKEN_1RATE(dev_id, con_id, bit, parents, \ - &CKEN, CKEN_ ## bit, 0) + CKEN, CKEN_ ## bit, 0) #define PXA25X_CKEN_1RATE_AO(dev_id, con_id, bit, parents, delay) \ PXA_CKEN_1RATE(dev_id, con_id, bit, parents, \ - &CKEN, CKEN_ ## bit, CLK_IGNORE_UNUSED) + CKEN, CKEN_ ## bit, CLK_IGNORE_UNUSED) static struct desc_clk_cken pxa25x_clocks[] __initdata = { PXA25X_PBUS95_CKEN("pxa2xx-mci.0", NULL, MMC, 1, 5, 0), @@ -162,7 +162,7 @@ MUX_RO_RATE_RO_OPS(clk_pxa25x_core, "core"); static unsigned long clk_pxa25x_run_get_rate(struct clk_hw *hw, unsigned long parent_rate) { - unsigned long cccr = CCCR; + unsigned long cccr = readl(CCCR); unsigned int n2 = N2_clk_mult[(cccr >> 7) & 0x07]; return (parent_rate / n2) * 2; @@ -173,7 +173,7 @@ RATE_RO_OPS(clk_pxa25x_run, "run"); static unsigned long clk_pxa25x_cpll_get_rate(struct clk_hw *hw, unsigned long parent_rate) { - unsigned long clkcfg, cccr = CCCR; + unsigned long clkcfg, cccr = readl(CCCR); unsigned int l, m, n2, t; asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg)); @@ -200,12 +200,10 @@ static void __init pxa25x_register_core(void) static void __init pxa25x_register_plls(void) { clk_register_fixed_rate(NULL, "osc_3_6864mhz", NULL, - CLK_GET_RATE_NOCACHE | CLK_IS_ROOT, - 3686400); + CLK_GET_RATE_NOCACHE, 3686400); clk_register_fixed_rate(NULL, "osc_32_768khz", NULL, - CLK_GET_RATE_NOCACHE | CLK_IS_ROOT, - 32768); - clk_register_fixed_rate(NULL, "clk_dummy", NULL, CLK_IS_ROOT, 0); + CLK_GET_RATE_NOCACHE, 32768); + clk_register_fixed_rate(NULL, "clk_dummy", NULL, 0, 0); clk_register_fixed_factor(NULL, "ppll_95_85mhz", "osc_3_6864mhz", 0, 26, 1); clk_register_fixed_factor(NULL, "ppll_147_46mhz", "osc_3_6864mhz", diff --git a/drivers/clk/pxa/clk-pxa27x.c b/drivers/clk/pxa/clk-pxa27x.c index 5b82d30baf9f36e9506544e554f1e79cf2b1b511..c40b1804f58caf33f7b1bf6cac90cc22ea381248 100644 --- a/drivers/clk/pxa/clk-pxa27x.c +++ b/drivers/clk/pxa/clk-pxa27x.c @@ -85,7 +85,7 @@ unsigned int pxa27x_get_clk_frequency_khz(int info) bool pxa27x_is_ppll_disabled(void) { - unsigned long ccsr = CCSR; + unsigned long ccsr = readl(CCSR); return ccsr & (1 << CCCR_PPDIS_BIT); } @@ -93,7 +93,7 @@ bool pxa27x_is_ppll_disabled(void) #define PXA27X_CKEN(dev_id, con_id, parents, mult_hp, div_hp, \ bit, is_lp, flags) \ PXA_CKEN(dev_id, con_id, bit, parents, 1, 1, mult_hp, div_hp, \ - is_lp, &CKEN, CKEN_ ## bit, flags) + is_lp, CKEN, CKEN_ ## bit, flags) #define PXA27X_PBUS_CKEN(dev_id, con_id, bit, mult_hp, div_hp, delay) \ PXA27X_CKEN(dev_id, con_id, pxa27x_pbus_parents, mult_hp, \ div_hp, bit, pxa27x_is_ppll_disabled, 0) @@ -106,10 +106,10 @@ PARENTS(pxa27x_membus) = { "lcd_base", "lcd_base" }; #define PXA27X_CKEN_1RATE(dev_id, con_id, bit, parents, delay) \ PXA_CKEN_1RATE(dev_id, con_id, bit, parents, \ - &CKEN, CKEN_ ## bit, 0) + CKEN, CKEN_ ## bit, 0) #define PXA27X_CKEN_1RATE_AO(dev_id, con_id, bit, parents, delay) \ PXA_CKEN_1RATE(dev_id, con_id, bit, parents, \ - &CKEN, CKEN_ ## bit, CLK_IGNORE_UNUSED) + CKEN, CKEN_ ## bit, CLK_IGNORE_UNUSED) static struct desc_clk_cken pxa27x_clocks[] __initdata = { PXA27X_PBUS_CKEN("pxa2xx-uart.0", NULL, FFUART, 2, 42, 1), @@ -151,7 +151,7 @@ static unsigned long clk_pxa27x_cpll_get_rate(struct clk_hw *hw, unsigned long clkcfg; unsigned int t, ht; unsigned int l, L, n2, N; - unsigned long ccsr = CCSR; + unsigned long ccsr = readl(CCSR); asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg)); t = clkcfg & (1 << 0); @@ -171,8 +171,8 @@ static unsigned long clk_pxa27x_lcd_base_get_rate(struct clk_hw *hw, unsigned long parent_rate) { unsigned int l, osc_forced; - unsigned long ccsr = CCSR; - unsigned long cccr = CCCR; + unsigned long ccsr = readl(CCSR); + unsigned long cccr = readl(CCCR); l = ccsr & CCSR_L_MASK; osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); @@ -193,7 +193,7 @@ static unsigned long clk_pxa27x_lcd_base_get_rate(struct clk_hw *hw, static u8 clk_pxa27x_lcd_base_get_parent(struct clk_hw *hw) { unsigned int osc_forced; - unsigned long ccsr = CCSR; + unsigned long ccsr = readl(CCSR); osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); if (osc_forced) @@ -208,12 +208,12 @@ MUX_RO_RATE_RO_OPS(clk_pxa27x_lcd_base, "lcd_base"); static void __init pxa27x_register_plls(void) { clk_register_fixed_rate(NULL, "osc_13mhz", NULL, - CLK_GET_RATE_NOCACHE | CLK_IS_ROOT, + CLK_GET_RATE_NOCACHE, 13 * MHz); clk_register_fixed_rate(NULL, "osc_32_768khz", NULL, - CLK_GET_RATE_NOCACHE | CLK_IS_ROOT, + CLK_GET_RATE_NOCACHE, 32768 * KHz); - clk_register_fixed_rate(NULL, "clk_dummy", NULL, CLK_IS_ROOT, 0); + clk_register_fixed_rate(NULL, "clk_dummy", NULL, 0, 0); clk_register_fixed_factor(NULL, "ppll_312mhz", "osc_13mhz", 0, 24, 1); } @@ -222,7 +222,7 @@ static unsigned long clk_pxa27x_core_get_rate(struct clk_hw *hw, { unsigned long clkcfg; unsigned int t, ht, b, osc_forced; - unsigned long ccsr = CCSR; + unsigned long ccsr = readl(CCSR); osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg)); @@ -242,7 +242,7 @@ static u8 clk_pxa27x_core_get_parent(struct clk_hw *hw) { unsigned long clkcfg; unsigned int t, ht, b, osc_forced; - unsigned long ccsr = CCSR; + unsigned long ccsr = readl(CCSR); osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); if (osc_forced) @@ -263,7 +263,7 @@ MUX_RO_RATE_RO_OPS(clk_pxa27x_core, "core"); static unsigned long clk_pxa27x_run_get_rate(struct clk_hw *hw, unsigned long parent_rate) { - unsigned long ccsr = CCSR; + unsigned long ccsr = readl(CCSR); unsigned int n2 = (ccsr & CCSR_N2_MASK) >> CCSR_N2_SHIFT; return (parent_rate / n2) * 2; @@ -285,7 +285,7 @@ static unsigned long clk_pxa27x_system_bus_get_rate(struct clk_hw *hw, { unsigned long clkcfg; unsigned int b, osc_forced; - unsigned long ccsr = CCSR; + unsigned long ccsr = readl(CCSR); osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); asm("mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg)); @@ -302,7 +302,7 @@ static unsigned long clk_pxa27x_system_bus_get_rate(struct clk_hw *hw, static u8 clk_pxa27x_system_bus_get_parent(struct clk_hw *hw) { unsigned int osc_forced; - unsigned long ccsr = CCSR; + unsigned long ccsr = readl(CCSR); osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); if (osc_forced) @@ -318,8 +318,8 @@ static unsigned long clk_pxa27x_memory_get_rate(struct clk_hw *hw, unsigned long parent_rate) { unsigned int a, l, osc_forced; - unsigned long cccr = CCCR; - unsigned long ccsr = CCSR; + unsigned long cccr = readl(CCCR); + unsigned long ccsr = readl(CCSR); osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); a = cccr & (1 << CCCR_A_BIT); @@ -337,8 +337,8 @@ static unsigned long clk_pxa27x_memory_get_rate(struct clk_hw *hw, static u8 clk_pxa27x_memory_get_parent(struct clk_hw *hw) { unsigned int osc_forced, a; - unsigned long cccr = CCCR; - unsigned long ccsr = CCSR; + unsigned long cccr = readl(CCCR); + unsigned long ccsr = readl(CCSR); osc_forced = ccsr & (1 << CCCR_CPDIS_BIT); a = cccr & (1 << CCCR_A_BIT); diff --git a/drivers/clk/pxa/clk-pxa3xx.c b/drivers/clk/pxa/clk-pxa3xx.c index 4af4eed5f89f03bb8affd1104de702b677326249..42bdaa772be06167a0974f6d975e33b8dc6bb5de 100644 --- a/drivers/clk/pxa/clk-pxa3xx.c +++ b/drivers/clk/pxa/clk-pxa3xx.c @@ -284,15 +284,15 @@ static void __init pxa3xx_register_core(void) static void __init pxa3xx_register_plls(void) { clk_register_fixed_rate(NULL, "osc_13mhz", NULL, - CLK_GET_RATE_NOCACHE | CLK_IS_ROOT, + CLK_GET_RATE_NOCACHE, 13 * MHz); clk_register_fixed_rate(NULL, "osc_32_768khz", NULL, - CLK_GET_RATE_NOCACHE | CLK_IS_ROOT, + CLK_GET_RATE_NOCACHE, 32768); clk_register_fixed_rate(NULL, "ring_osc_120mhz", NULL, - CLK_GET_RATE_NOCACHE | CLK_IS_ROOT, + CLK_GET_RATE_NOCACHE, 120 * MHz); - clk_register_fixed_rate(NULL, "clk_dummy", NULL, CLK_IS_ROOT, 0); + clk_register_fixed_rate(NULL, "clk_dummy", NULL, 0, 0); clk_register_fixed_factor(NULL, "spll_624mhz", "osc_13mhz", 0, 48, 1); clk_register_fixed_factor(NULL, "ring_osc_60mhz", "ring_osc_120mhz", 0, 1, 2); @@ -334,8 +334,7 @@ static void __init pxa3xx_base_clocks_init(void) clk_register_clk_pxa3xx_system_bus(); clk_register_clk_pxa3xx_ac97(); clk_register_clk_pxa3xx_smemc(); - clk_register_gate(NULL, "CLK_POUT", "osc_13mhz", 0, - (void __iomem *)&OSCC, 11, 0, NULL); + clk_register_gate(NULL, "CLK_POUT", "osc_13mhz", 0, OSCC, 11, 0, NULL); clkdev_pxa_register(CLK_OSTIMER, "OSTIMER0", NULL, clk_register_fixed_factor(NULL, "os-timer0", "osc_13mhz", 0, 1, 4)); diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index b552eceec2beb02400d45defb73cf33fa5bba313..95e3b3e0fa1c66921900c4dda37ff09f0be1db17 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -28,6 +28,14 @@ config APQ_MMCC_8084 Say Y if you want to support multimedia devices such as display, graphics, video encode/decode, camera, etc. +config IPQ_GCC_4019 + tristate "IPQ4019 Global Clock Controller" + depends on COMMON_CLK_QCOM + help + Support for the global clock controller on ipq4019 devices. + Say Y if you want to use peripheral devices such as UART, SPI, + i2c, USB, SD/eMMC, etc. + config IPQ_GCC_806X tristate "IPQ806x Global Clock Controller" depends on COMMON_CLK_QCOM diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index dc4280b85db1f677ff6637635aa2f7f7f534e484..2a25f4e75f49f74231fa638e1a2517822a5857a8 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -14,6 +14,7 @@ clk-qcom-$(CONFIG_QCOM_GDSC) += gdsc.o obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o +obj-$(CONFIG_IPQ_GCC_4019) += gcc-ipq4019.o obj-$(CONFIG_IPQ_GCC_806X) += gcc-ipq806x.o obj-$(CONFIG_IPQ_LCC_806X) += lcc-ipq806x.o obj-$(CONFIG_MSM_GCC_8660) += gcc-msm8660.o diff --git a/drivers/clk/qcom/clk-rcg.c b/drivers/clk/qcom/clk-rcg.c index bfbb28f450c2ea0ad4c10dfd96e34c8f5a56cbbf..67ce7c146a6ac60af8c65ceeefb9ee862d048a77 100644 --- a/drivers/clk/qcom/clk-rcg.c +++ b/drivers/clk/qcom/clk-rcg.c @@ -638,7 +638,6 @@ static int clk_rcg_pixel_set_rate(struct clk_hw *hw, unsigned long rate, return ret; src = ns_to_src(&rcg->s, ns); - f.pre_div = ns_to_pre_div(&rcg->p, ns) + 1; for (i = 0; i < num_parents; i++) { if (src == rcg->s.parent_map[i].cfg) { @@ -647,6 +646,9 @@ static int clk_rcg_pixel_set_rate(struct clk_hw *hw, unsigned long rate, } } + /* bypass the pre divider */ + f.pre_div = 1; + /* let us find appropriate m/n values for this */ for (; frac->num; frac++) { request = (rate * frac->den) / frac->num; diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c index c112ebaba70d179b1f9d99a9fc253ecf34ee6dbe..f7c226ab4307dbc308191d9392bfdb1bbf500431 100644 --- a/drivers/clk/qcom/common.c +++ b/drivers/clk/qcom/common.c @@ -119,7 +119,6 @@ static int _qcom_cc_register_board_clk(struct device *dev, const char *path, fixed->hw.init = &init_data; init_data.name = path; - init_data.flags = CLK_IS_ROOT; init_data.ops = &clk_fixed_rate_ops; clk = devm_clk_register(dev, &fixed->hw); @@ -185,6 +184,7 @@ int qcom_cc_really_probe(struct platform_device *pdev, struct clk **clks; struct qcom_reset_controller *reset; struct qcom_cc *cc; + struct gdsc_desc *scd; size_t num_clks = desc->num_clks; struct clk_regmap **rclks = desc->clks; @@ -213,7 +213,11 @@ int qcom_cc_really_probe(struct platform_device *pdev, if (ret) return ret; - devm_add_action(dev, qcom_cc_del_clk_provider, pdev->dev.of_node); + ret = devm_add_action_or_reset(dev, qcom_cc_del_clk_provider, + pdev->dev.of_node); + + if (ret) + return ret; reset = &cc->reset; reset->rcdev.of_node = dev->of_node; @@ -227,18 +231,28 @@ int qcom_cc_really_probe(struct platform_device *pdev, if (ret) return ret; - devm_add_action(dev, qcom_cc_reset_unregister, &reset->rcdev); + ret = devm_add_action_or_reset(dev, qcom_cc_reset_unregister, + &reset->rcdev); + + if (ret) + return ret; if (desc->gdscs && desc->num_gdscs) { - ret = gdsc_register(dev, desc->gdscs, desc->num_gdscs, - &reset->rcdev, regmap); + scd = devm_kzalloc(dev, sizeof(*scd), GFP_KERNEL); + if (!scd) + return -ENOMEM; + scd->dev = dev; + scd->scs = desc->gdscs; + scd->num = desc->num_gdscs; + ret = gdsc_register(scd, &reset->rcdev, regmap); + if (ret) + return ret; + ret = devm_add_action_or_reset(dev, qcom_cc_gdsc_unregister, + scd); if (ret) return ret; } - devm_add_action(dev, qcom_cc_gdsc_unregister, dev); - - return 0; } EXPORT_SYMBOL_GPL(qcom_cc_really_probe); diff --git a/drivers/clk/qcom/gcc-ipq4019.c b/drivers/clk/qcom/gcc-ipq4019.c new file mode 100644 index 0000000000000000000000000000000000000000..3cd1af0af0d97299facff7fcb0717b13256a6cbe --- /dev/null +++ b/drivers/clk/qcom/gcc-ipq4019.c @@ -0,0 +1,1354 @@ +/* + * Copyright (c) 2015 The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "common.h" +#include "clk-regmap.h" +#include "clk-rcg.h" +#include "clk-branch.h" +#include "reset.h" + +enum { + P_XO, + P_FEPLL200, + P_FEPLL500, + P_DDRPLL, + P_FEPLLWCSS2G, + P_FEPLLWCSS5G, + P_FEPLL125DLY, + P_DDRPLLAPSS, +}; + +static struct parent_map gcc_xo_200_500_map[] = { + { P_XO, 0 }, + { P_FEPLL200, 1 }, + { P_FEPLL500, 2 }, +}; + +static const char * const gcc_xo_200_500[] = { + "xo", + "fepll200", + "fepll500", +}; + +static struct parent_map gcc_xo_200_map[] = { + { P_XO, 0 }, + { P_FEPLL200, 1 }, +}; + +static const char * const gcc_xo_200[] = { + "xo", + "fepll200", +}; + +static struct parent_map gcc_xo_200_spi_map[] = { + { P_XO, 0 }, + { P_FEPLL200, 2 }, +}; + +static const char * const gcc_xo_200_spi[] = { + "xo", + "fepll200", +}; + +static struct parent_map gcc_xo_sdcc1_500_map[] = { + { P_XO, 0 }, + { P_DDRPLL, 1 }, + { P_FEPLL500, 2 }, +}; + +static const char * const gcc_xo_sdcc1_500[] = { + "xo", + "ddrpll", + "fepll500", +}; + +static struct parent_map gcc_xo_wcss2g_map[] = { + { P_XO, 0 }, + { P_FEPLLWCSS2G, 1 }, +}; + +static const char * const gcc_xo_wcss2g[] = { + "xo", + "fepllwcss2g", +}; + +static struct parent_map gcc_xo_wcss5g_map[] = { + { P_XO, 0 }, + { P_FEPLLWCSS5G, 1 }, +}; + +static const char * const gcc_xo_wcss5g[] = { + "xo", + "fepllwcss5g", +}; + +static struct parent_map gcc_xo_125_dly_map[] = { + { P_XO, 0 }, + { P_FEPLL125DLY, 1 }, +}; + +static const char * const gcc_xo_125_dly[] = { + "xo", + "fepll125dly", +}; + +static struct parent_map gcc_xo_ddr_500_200_map[] = { + { P_XO, 0 }, + { P_FEPLL200, 3 }, + { P_FEPLL500, 2 }, + { P_DDRPLLAPSS, 1 }, +}; + +static const char * const gcc_xo_ddr_500_200[] = { + "xo", + "fepll200", + "fepll500", + "ddrpllapss", +}; + +#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } + +static const struct freq_tbl ftbl_gcc_audio_pwm_clk[] = { + F(48000000, P_XO, 1, 0, 0), + F(200000000, P_FEPLL200, 1, 0, 0), + { } +}; + +static struct clk_rcg2 audio_clk_src = { + .cmd_rcgr = 0x1b000, + .hid_width = 5, + .parent_map = gcc_xo_200_map, + .freq_tbl = ftbl_gcc_audio_pwm_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "audio_clk_src", + .parent_names = gcc_xo_200, + .num_parents = 2, + .ops = &clk_rcg2_ops, + + }, +}; + +static struct clk_branch gcc_audio_ahb_clk = { + .halt_reg = 0x1b010, + .clkr = { + .enable_reg = 0x1b010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_audio_ahb_clk", + .parent_names = (const char *[]){ + "pcnoc_clk_src", + }, + .flags = CLK_SET_RATE_PARENT, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_audio_pwm_clk = { + .halt_reg = 0x1b00C, + .clkr = { + .enable_reg = 0x1b00C, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_audio_pwm_clk", + .parent_names = (const char *[]){ + "audio_clk_src", + }, + .flags = CLK_SET_RATE_PARENT, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_gcc_blsp1_qup1_2_i2c_apps_clk[] = { + F(19200000, P_XO, 1, 2, 5), + F(24000000, P_XO, 1, 1, 2), + { } +}; + +static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = { + .cmd_rcgr = 0x200c, + .hid_width = 5, + .parent_map = gcc_xo_200_map, + .freq_tbl = ftbl_gcc_blsp1_qup1_2_i2c_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup1_i2c_apps_clk_src", + .parent_names = gcc_xo_200, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = { + .halt_reg = 0x2008, + .clkr = { + .enable_reg = 0x2008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup1_i2c_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup1_i2c_apps_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = { + .cmd_rcgr = 0x3000, + .hid_width = 5, + .parent_map = gcc_xo_200_map, + .freq_tbl = ftbl_gcc_blsp1_qup1_2_i2c_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup2_i2c_apps_clk_src", + .parent_names = gcc_xo_200, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = { + .halt_reg = 0x3010, + .clkr = { + .enable_reg = 0x3010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup2_i2c_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup2_i2c_apps_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static const struct freq_tbl ftbl_gcc_blsp1_qup1_2_spi_apps_clk[] = { + F(960000, P_XO, 12, 1, 4), + F(4800000, P_XO, 1, 1, 10), + F(9600000, P_XO, 1, 1, 5), + F(15000000, P_XO, 1, 1, 3), + F(19200000, P_XO, 1, 2, 5), + F(24000000, P_XO, 1, 1, 2), + F(48000000, P_XO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = { + .cmd_rcgr = 0x2024, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_200_spi_map, + .freq_tbl = ftbl_gcc_blsp1_qup1_2_spi_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup1_spi_apps_clk_src", + .parent_names = gcc_xo_200_spi, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = { + .halt_reg = 0x2004, + .clkr = { + .enable_reg = 0x2004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup1_spi_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup1_spi_apps_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = { + .cmd_rcgr = 0x3014, + .mnd_width = 8, + .hid_width = 5, + .freq_tbl = ftbl_gcc_blsp1_qup1_2_spi_apps_clk, + .parent_map = gcc_xo_200_spi_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup2_spi_apps_clk_src", + .parent_names = gcc_xo_200_spi, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = { + .halt_reg = 0x300c, + .clkr = { + .enable_reg = 0x300c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup2_spi_apps_clk", + .parent_names = (const char *[]){ + "blsp1_qup2_spi_apps_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static const struct freq_tbl ftbl_gcc_blsp1_uart1_2_apps_clk[] = { + F(1843200, P_FEPLL200, 1, 144, 15625), + F(3686400, P_FEPLL200, 1, 288, 15625), + F(7372800, P_FEPLL200, 1, 576, 15625), + F(14745600, P_FEPLL200, 1, 1152, 15625), + F(16000000, P_FEPLL200, 1, 2, 25), + F(24000000, P_XO, 1, 1, 2), + F(32000000, P_FEPLL200, 1, 4, 25), + F(40000000, P_FEPLL200, 1, 1, 5), + F(46400000, P_FEPLL200, 1, 29, 125), + F(48000000, P_XO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 blsp1_uart1_apps_clk_src = { + .cmd_rcgr = 0x2044, + .mnd_width = 16, + .hid_width = 5, + .freq_tbl = ftbl_gcc_blsp1_uart1_2_apps_clk, + .parent_map = gcc_xo_200_spi_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart1_apps_clk_src", + .parent_names = gcc_xo_200_spi, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_blsp1_uart1_apps_clk = { + .halt_reg = 0x203c, + .clkr = { + .enable_reg = 0x203c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart1_apps_clk", + .parent_names = (const char *[]){ + "blsp1_uart1_apps_clk_src", + }, + .flags = CLK_SET_RATE_PARENT, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_rcg2 blsp1_uart2_apps_clk_src = { + .cmd_rcgr = 0x3034, + .mnd_width = 16, + .hid_width = 5, + .freq_tbl = ftbl_gcc_blsp1_uart1_2_apps_clk, + .parent_map = gcc_xo_200_spi_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart2_apps_clk_src", + .parent_names = gcc_xo_200_spi, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_blsp1_uart2_apps_clk = { + .halt_reg = 0x302c, + .clkr = { + .enable_reg = 0x302c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart2_apps_clk", + .parent_names = (const char *[]){ + "blsp1_uart2_apps_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static const struct freq_tbl ftbl_gcc_gp_clk[] = { + F(1250000, P_FEPLL200, 1, 16, 0), + F(2500000, P_FEPLL200, 1, 8, 0), + F(5000000, P_FEPLL200, 1, 4, 0), + { } +}; + +static struct clk_rcg2 gp1_clk_src = { + .cmd_rcgr = 0x8004, + .mnd_width = 8, + .hid_width = 5, + .freq_tbl = ftbl_gcc_gp_clk, + .parent_map = gcc_xo_200_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp1_clk_src", + .parent_names = gcc_xo_200, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_gp1_clk = { + .halt_reg = 0x8000, + .clkr = { + .enable_reg = 0x8000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp1_clk", + .parent_names = (const char *[]){ + "gp1_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg2 gp2_clk_src = { + .cmd_rcgr = 0x9004, + .mnd_width = 8, + .hid_width = 5, + .freq_tbl = ftbl_gcc_gp_clk, + .parent_map = gcc_xo_200_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp2_clk_src", + .parent_names = gcc_xo_200, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_gp2_clk = { + .halt_reg = 0x9000, + .clkr = { + .enable_reg = 0x9000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp2_clk", + .parent_names = (const char *[]){ + "gp2_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_rcg2 gp3_clk_src = { + .cmd_rcgr = 0xa004, + .mnd_width = 8, + .hid_width = 5, + .freq_tbl = ftbl_gcc_gp_clk, + .parent_map = gcc_xo_200_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp3_clk_src", + .parent_names = gcc_xo_200, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_gp3_clk = { + .halt_reg = 0xa000, + .clkr = { + .enable_reg = 0xa000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp3_clk", + .parent_names = (const char *[]){ + "gp3_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk[] = { + F(144000, P_XO, 1, 3, 240), + F(400000, P_XO, 1, 1, 0), + F(20000000, P_FEPLL500, 1, 1, 25), + F(25000000, P_FEPLL500, 1, 1, 20), + F(50000000, P_FEPLL500, 1, 1, 10), + F(100000000, P_FEPLL500, 1, 1, 5), + F(193000000, P_DDRPLL, 1, 0, 0), + { } +}; + +static struct clk_rcg2 sdcc1_apps_clk_src = { + .cmd_rcgr = 0x18004, + .hid_width = 5, + .freq_tbl = ftbl_gcc_sdcc1_apps_clk, + .parent_map = gcc_xo_sdcc1_500_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "sdcc1_apps_clk_src", + .parent_names = gcc_xo_sdcc1_500, + .num_parents = 3, + .ops = &clk_rcg2_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct freq_tbl ftbl_gcc_apps_clk[] = { + F(48000000, P_XO, 1, 0, 0), + F(200000000, P_FEPLL200, 1, 0, 0), + F(500000000, P_FEPLL500, 1, 0, 0), + F(626000000, P_DDRPLLAPSS, 1, 0, 0), + { } +}; + +static struct clk_rcg2 apps_clk_src = { + .cmd_rcgr = 0x1900c, + .hid_width = 5, + .freq_tbl = ftbl_gcc_apps_clk, + .parent_map = gcc_xo_ddr_500_200_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "apps_clk_src", + .parent_names = gcc_xo_ddr_500_200, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_apps_ahb_clk[] = { + F(48000000, P_XO, 1, 0, 0), + F(100000000, P_FEPLL200, 2, 0, 0), + { } +}; + +static struct clk_rcg2 apps_ahb_clk_src = { + .cmd_rcgr = 0x19014, + .hid_width = 5, + .parent_map = gcc_xo_200_500_map, + .freq_tbl = ftbl_gcc_apps_ahb_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "apps_ahb_clk_src", + .parent_names = gcc_xo_200_500, + .num_parents = 3, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_apss_ahb_clk = { + .halt_reg = 0x19004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x6000, + .enable_mask = BIT(14), + .hw.init = &(struct clk_init_data){ + .name = "gcc_apss_ahb_clk", + .parent_names = (const char *[]){ + "apps_ahb_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch gcc_blsp1_ahb_clk = { + .halt_reg = 0x1008, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x6000, + .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_ahb_clk", + .parent_names = (const char *[]){ + "pcnoc_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_dcd_xo_clk = { + .halt_reg = 0x2103c, + .clkr = { + .enable_reg = 0x2103c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_dcd_xo_clk", + .parent_names = (const char *[]){ + "xo", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_boot_rom_ahb_clk = { + .halt_reg = 0x1300c, + .clkr = { + .enable_reg = 0x1300c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_boot_rom_ahb_clk", + .parent_names = (const char *[]){ + "pcnoc_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch gcc_crypto_ahb_clk = { + .halt_reg = 0x16024, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x6000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_crypto_ahb_clk", + .parent_names = (const char *[]){ + "pcnoc_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_crypto_axi_clk = { + .halt_reg = 0x16020, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x6000, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gcc_crypto_axi_clk", + .parent_names = (const char *[]){ + "fepll125", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_crypto_clk = { + .halt_reg = 0x1601c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x6000, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "gcc_crypto_clk", + .parent_names = (const char *[]){ + "fepll125", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ess_clk = { + .halt_reg = 0x12010, + .clkr = { + .enable_reg = 0x12010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ess_clk", + .parent_names = (const char *[]){ + "fephy_125m_dly_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch gcc_imem_axi_clk = { + .halt_reg = 0xe004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x6000, + .enable_mask = BIT(17), + .hw.init = &(struct clk_init_data){ + .name = "gcc_imem_axi_clk", + .parent_names = (const char *[]){ + "fepll200", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_imem_cfg_ahb_clk = { + .halt_reg = 0xe008, + .clkr = { + .enable_reg = 0xe008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_imem_cfg_ahb_clk", + .parent_names = (const char *[]){ + "pcnoc_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_ahb_clk = { + .halt_reg = 0x1d00c, + .clkr = { + .enable_reg = 0x1d00c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_ahb_clk", + .parent_names = (const char *[]){ + "pcnoc_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_axi_m_clk = { + .halt_reg = 0x1d004, + .clkr = { + .enable_reg = 0x1d004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_axi_m_clk", + .parent_names = (const char *[]){ + "fepll200", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_axi_s_clk = { + .halt_reg = 0x1d008, + .clkr = { + .enable_reg = 0x1d008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pcie_axi_s_clk", + .parent_names = (const char *[]){ + "fepll200", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_prng_ahb_clk = { + .halt_reg = 0x13004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x6000, + .enable_mask = BIT(8), + .hw.init = &(struct clk_init_data){ + .name = "gcc_prng_ahb_clk", + .parent_names = (const char *[]){ + "pcnoc_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qpic_ahb_clk = { + .halt_reg = 0x1c008, + .clkr = { + .enable_reg = 0x1c008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qpic_ahb_clk", + .parent_names = (const char *[]){ + "pcnoc_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qpic_clk = { + .halt_reg = 0x1c004, + .clkr = { + .enable_reg = 0x1c004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qpic_clk", + .parent_names = (const char *[]){ + "pcnoc_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_ahb_clk = { + .halt_reg = 0x18010, + .clkr = { + .enable_reg = 0x18010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_ahb_clk", + .parent_names = (const char *[]){ + "pcnoc_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_apps_clk = { + .halt_reg = 0x1800c, + .clkr = { + .enable_reg = 0x1800c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_apps_clk", + .parent_names = (const char *[]){ + "sdcc1_apps_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch gcc_tlmm_ahb_clk = { + .halt_reg = 0x5004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x6000, + .enable_mask = BIT(5), + .hw.init = &(struct clk_init_data){ + .name = "gcc_tlmm_ahb_clk", + .parent_names = (const char *[]){ + "pcnoc_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb2_master_clk = { + .halt_reg = 0x1e00c, + .clkr = { + .enable_reg = 0x1e00c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb2_master_clk", + .parent_names = (const char *[]){ + "pcnoc_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb2_sleep_clk = { + .halt_reg = 0x1e010, + .clkr = { + .enable_reg = 0x1e010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb2_sleep_clk", + .parent_names = (const char *[]){ + "gcc_sleep_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb2_mock_utmi_clk = { + .halt_reg = 0x1e014, + .clkr = { + .enable_reg = 0x1e014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb2_mock_utmi_clk", + .parent_names = (const char *[]){ + "usb30_mock_utmi_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb30_mock_utmi_clk[] = { + F(2000000, P_FEPLL200, 10, 0, 0), + { } +}; + +static struct clk_rcg2 usb30_mock_utmi_clk_src = { + .cmd_rcgr = 0x1e000, + .hid_width = 5, + .parent_map = gcc_xo_200_map, + .freq_tbl = ftbl_gcc_usb30_mock_utmi_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb30_mock_utmi_clk_src", + .parent_names = gcc_xo_200, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_usb3_master_clk = { + .halt_reg = 0x1e028, + .clkr = { + .enable_reg = 0x1e028, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_master_clk", + .parent_names = (const char *[]){ + "fepll125", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_sleep_clk = { + .halt_reg = 0x1e02C, + .clkr = { + .enable_reg = 0x1e02C, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_sleep_clk", + .parent_names = (const char *[]){ + "gcc_sleep_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_mock_utmi_clk = { + .halt_reg = 0x1e030, + .clkr = { + .enable_reg = 0x1e030, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_mock_utmi_clk", + .parent_names = (const char *[]){ + "usb30_mock_utmi_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static const struct freq_tbl ftbl_gcc_fephy_dly_clk[] = { + F(125000000, P_FEPLL125DLY, 1, 0, 0), + { } +}; + +static struct clk_rcg2 fephy_125m_dly_clk_src = { + .cmd_rcgr = 0x12000, + .hid_width = 5, + .parent_map = gcc_xo_125_dly_map, + .freq_tbl = ftbl_gcc_fephy_dly_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "fephy_125m_dly_clk_src", + .parent_names = gcc_xo_125_dly, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + + +static const struct freq_tbl ftbl_gcc_wcss2g_clk[] = { + F(48000000, P_XO, 1, 0, 0), + F(250000000, P_FEPLLWCSS2G, 1, 0, 0), + { } +}; + +static struct clk_rcg2 wcss2g_clk_src = { + .cmd_rcgr = 0x1f000, + .hid_width = 5, + .freq_tbl = ftbl_gcc_wcss2g_clk, + .parent_map = gcc_xo_wcss2g_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "wcss2g_clk_src", + .parent_names = gcc_xo_wcss2g, + .num_parents = 2, + .ops = &clk_rcg2_ops, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_branch gcc_wcss2g_clk = { + .halt_reg = 0x1f00C, + .clkr = { + .enable_reg = 0x1f00C, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_wcss2g_clk", + .parent_names = (const char *[]){ + "wcss2g_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch gcc_wcss2g_ref_clk = { + .halt_reg = 0x1f00C, + .clkr = { + .enable_reg = 0x1f00C, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_wcss2g_ref_clk", + .parent_names = (const char *[]){ + "xo", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch gcc_wcss2g_rtc_clk = { + .halt_reg = 0x1f010, + .clkr = { + .enable_reg = 0x1f010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_wcss2g_rtc_clk", + .parent_names = (const char *[]){ + "gcc_sleep_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_gcc_wcss5g_clk[] = { + F(48000000, P_XO, 1, 0, 0), + F(250000000, P_FEPLLWCSS5G, 1, 0, 0), + { } +}; + +static struct clk_rcg2 wcss5g_clk_src = { + .cmd_rcgr = 0x20000, + .hid_width = 5, + .parent_map = gcc_xo_wcss5g_map, + .freq_tbl = ftbl_gcc_wcss5g_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "wcss5g_clk_src", + .parent_names = gcc_xo_wcss5g, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_wcss5g_clk = { + .halt_reg = 0x2000c, + .clkr = { + .enable_reg = 0x2000c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_wcss5g_clk", + .parent_names = (const char *[]){ + "wcss5g_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch gcc_wcss5g_ref_clk = { + .halt_reg = 0x2000c, + .clkr = { + .enable_reg = 0x2000c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_wcss5g_ref_clk", + .parent_names = (const char *[]){ + "xo", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_branch gcc_wcss5g_rtc_clk = { + .halt_reg = 0x20010, + .clkr = { + .enable_reg = 0x20010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_wcss5g_rtc_clk", + .parent_names = (const char *[]){ + "gcc_sleep_clk_src", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + .flags = CLK_SET_RATE_PARENT, + }, + }, +}; + +static struct clk_regmap *gcc_ipq4019_clocks[] = { + [AUDIO_CLK_SRC] = &audio_clk_src.clkr, + [BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr, + [BLSP1_QUP1_SPI_APPS_CLK_SRC] = &blsp1_qup1_spi_apps_clk_src.clkr, + [BLSP1_QUP2_I2C_APPS_CLK_SRC] = &blsp1_qup2_i2c_apps_clk_src.clkr, + [BLSP1_QUP2_SPI_APPS_CLK_SRC] = &blsp1_qup2_spi_apps_clk_src.clkr, + [BLSP1_UART1_APPS_CLK_SRC] = &blsp1_uart1_apps_clk_src.clkr, + [BLSP1_UART2_APPS_CLK_SRC] = &blsp1_uart2_apps_clk_src.clkr, + [GCC_USB3_MOCK_UTMI_CLK_SRC] = &usb30_mock_utmi_clk_src.clkr, + [GCC_APPS_CLK_SRC] = &apps_clk_src.clkr, + [GCC_APPS_AHB_CLK_SRC] = &apps_ahb_clk_src.clkr, + [GP1_CLK_SRC] = &gp1_clk_src.clkr, + [GP2_CLK_SRC] = &gp2_clk_src.clkr, + [GP3_CLK_SRC] = &gp3_clk_src.clkr, + [SDCC1_APPS_CLK_SRC] = &sdcc1_apps_clk_src.clkr, + [FEPHY_125M_DLY_CLK_SRC] = &fephy_125m_dly_clk_src.clkr, + [WCSS2G_CLK_SRC] = &wcss2g_clk_src.clkr, + [WCSS5G_CLK_SRC] = &wcss5g_clk_src.clkr, + [GCC_APSS_AHB_CLK] = &gcc_apss_ahb_clk.clkr, + [GCC_AUDIO_AHB_CLK] = &gcc_audio_ahb_clk.clkr, + [GCC_AUDIO_PWM_CLK] = &gcc_audio_pwm_clk.clkr, + [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr, + [GCC_BLSP1_QUP1_I2C_APPS_CLK] = &gcc_blsp1_qup1_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP1_SPI_APPS_CLK] = &gcc_blsp1_qup1_spi_apps_clk.clkr, + [GCC_BLSP1_QUP2_I2C_APPS_CLK] = &gcc_blsp1_qup2_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP2_SPI_APPS_CLK] = &gcc_blsp1_qup2_spi_apps_clk.clkr, + [GCC_BLSP1_UART1_APPS_CLK] = &gcc_blsp1_uart1_apps_clk.clkr, + [GCC_BLSP1_UART2_APPS_CLK] = &gcc_blsp1_uart2_apps_clk.clkr, + [GCC_DCD_XO_CLK] = &gcc_dcd_xo_clk.clkr, + [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, + [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, + [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, + [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, + [GCC_CRYPTO_AHB_CLK] = &gcc_crypto_ahb_clk.clkr, + [GCC_CRYPTO_AXI_CLK] = &gcc_crypto_axi_clk.clkr, + [GCC_CRYPTO_CLK] = &gcc_crypto_clk.clkr, + [GCC_ESS_CLK] = &gcc_ess_clk.clkr, + [GCC_IMEM_AXI_CLK] = &gcc_imem_axi_clk.clkr, + [GCC_IMEM_CFG_AHB_CLK] = &gcc_imem_cfg_ahb_clk.clkr, + [GCC_PCIE_AHB_CLK] = &gcc_pcie_ahb_clk.clkr, + [GCC_PCIE_AXI_M_CLK] = &gcc_pcie_axi_m_clk.clkr, + [GCC_PCIE_AXI_S_CLK] = &gcc_pcie_axi_s_clk.clkr, + [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr, + [GCC_QPIC_AHB_CLK] = &gcc_qpic_ahb_clk.clkr, + [GCC_QPIC_CLK] = &gcc_qpic_clk.clkr, + [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr, + [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr, + [GCC_TLMM_AHB_CLK] = &gcc_tlmm_ahb_clk.clkr, + [GCC_USB2_MASTER_CLK] = &gcc_usb2_master_clk.clkr, + [GCC_USB2_SLEEP_CLK] = &gcc_usb2_sleep_clk.clkr, + [GCC_USB2_MOCK_UTMI_CLK] = &gcc_usb2_mock_utmi_clk.clkr, + [GCC_USB3_MASTER_CLK] = &gcc_usb3_master_clk.clkr, + [GCC_USB3_SLEEP_CLK] = &gcc_usb3_sleep_clk.clkr, + [GCC_USB3_MOCK_UTMI_CLK] = &gcc_usb3_mock_utmi_clk.clkr, + [GCC_WCSS2G_CLK] = &gcc_wcss2g_clk.clkr, + [GCC_WCSS2G_REF_CLK] = &gcc_wcss2g_ref_clk.clkr, + [GCC_WCSS2G_RTC_CLK] = &gcc_wcss2g_rtc_clk.clkr, + [GCC_WCSS5G_CLK] = &gcc_wcss5g_clk.clkr, + [GCC_WCSS5G_REF_CLK] = &gcc_wcss5g_ref_clk.clkr, + [GCC_WCSS5G_RTC_CLK] = &gcc_wcss5g_rtc_clk.clkr, +}; + +static const struct qcom_reset_map gcc_ipq4019_resets[] = { + [WIFI0_CPU_INIT_RESET] = { 0x1f008, 5 }, + [WIFI0_RADIO_SRIF_RESET] = { 0x1f008, 4 }, + [WIFI0_RADIO_WARM_RESET] = { 0x1f008, 3 }, + [WIFI0_RADIO_COLD_RESET] = { 0x1f008, 2 }, + [WIFI0_CORE_WARM_RESET] = { 0x1f008, 1 }, + [WIFI0_CORE_COLD_RESET] = { 0x1f008, 0 }, + [WIFI1_CPU_INIT_RESET] = { 0x20008, 5 }, + [WIFI1_RADIO_SRIF_RESET] = { 0x20008, 4 }, + [WIFI1_RADIO_WARM_RESET] = { 0x20008, 3 }, + [WIFI1_RADIO_COLD_RESET] = { 0x20008, 2 }, + [WIFI1_CORE_WARM_RESET] = { 0x20008, 1 }, + [WIFI1_CORE_COLD_RESET] = { 0x20008, 0 }, + [USB3_UNIPHY_PHY_ARES] = { 0x1e038, 5 }, + [USB3_HSPHY_POR_ARES] = { 0x1e038, 4 }, + [USB3_HSPHY_S_ARES] = { 0x1e038, 2 }, + [USB2_HSPHY_POR_ARES] = { 0x1e01c, 4 }, + [USB2_HSPHY_S_ARES] = { 0x1e01c, 2 }, + [PCIE_PHY_AHB_ARES] = { 0x1d010, 11 }, + [PCIE_AHB_ARES] = { 0x1d010, 10 }, + [PCIE_PWR_ARES] = { 0x1d010, 9 }, + [PCIE_PIPE_STICKY_ARES] = { 0x1d010, 8 }, + [PCIE_AXI_M_STICKY_ARES] = { 0x1d010, 7 }, + [PCIE_PHY_ARES] = { 0x1d010, 6 }, + [PCIE_PARF_XPU_ARES] = { 0x1d010, 5 }, + [PCIE_AXI_S_XPU_ARES] = { 0x1d010, 4 }, + [PCIE_AXI_M_VMIDMT_ARES] = { 0x1d010, 3 }, + [PCIE_PIPE_ARES] = { 0x1d010, 2 }, + [PCIE_AXI_S_ARES] = { 0x1d010, 1 }, + [PCIE_AXI_M_ARES] = { 0x1d010, 0 }, + [ESS_RESET] = { 0x12008, 0}, + [GCC_BLSP1_BCR] = {0x01000, 0}, + [GCC_BLSP1_QUP1_BCR] = {0x02000, 0}, + [GCC_BLSP1_UART1_BCR] = {0x02038, 0}, + [GCC_BLSP1_QUP2_BCR] = {0x03008, 0}, + [GCC_BLSP1_UART2_BCR] = {0x03028, 0}, + [GCC_BIMC_BCR] = {0x04000, 0}, + [GCC_TLMM_BCR] = {0x05000, 0}, + [GCC_IMEM_BCR] = {0x0E000, 0}, + [GCC_ESS_BCR] = {0x12008, 0}, + [GCC_PRNG_BCR] = {0x13000, 0}, + [GCC_BOOT_ROM_BCR] = {0x13008, 0}, + [GCC_CRYPTO_BCR] = {0x16000, 0}, + [GCC_SDCC1_BCR] = {0x18000, 0}, + [GCC_SEC_CTRL_BCR] = {0x1A000, 0}, + [GCC_AUDIO_BCR] = {0x1B008, 0}, + [GCC_QPIC_BCR] = {0x1C000, 0}, + [GCC_PCIE_BCR] = {0x1D000, 0}, + [GCC_USB2_BCR] = {0x1E008, 0}, + [GCC_USB2_PHY_BCR] = {0x1E018, 0}, + [GCC_USB3_BCR] = {0x1E024, 0}, + [GCC_USB3_PHY_BCR] = {0x1E034, 0}, + [GCC_SYSTEM_NOC_BCR] = {0x21000, 0}, + [GCC_PCNOC_BCR] = {0x2102C, 0}, + [GCC_DCD_BCR] = {0x21038, 0}, + [GCC_SNOC_BUS_TIMEOUT0_BCR] = {0x21064, 0}, + [GCC_SNOC_BUS_TIMEOUT1_BCR] = {0x2106C, 0}, + [GCC_SNOC_BUS_TIMEOUT2_BCR] = {0x21074, 0}, + [GCC_SNOC_BUS_TIMEOUT3_BCR] = {0x2107C, 0}, + [GCC_PCNOC_BUS_TIMEOUT0_BCR] = {0x21084, 0}, + [GCC_PCNOC_BUS_TIMEOUT1_BCR] = {0x2108C, 0}, + [GCC_PCNOC_BUS_TIMEOUT2_BCR] = {0x21094, 0}, + [GCC_PCNOC_BUS_TIMEOUT3_BCR] = {0x2109C, 0}, + [GCC_PCNOC_BUS_TIMEOUT4_BCR] = {0x210A4, 0}, + [GCC_PCNOC_BUS_TIMEOUT5_BCR] = {0x210AC, 0}, + [GCC_PCNOC_BUS_TIMEOUT6_BCR] = {0x210B4, 0}, + [GCC_PCNOC_BUS_TIMEOUT7_BCR] = {0x210BC, 0}, + [GCC_PCNOC_BUS_TIMEOUT8_BCR] = {0x210C4, 0}, + [GCC_PCNOC_BUS_TIMEOUT9_BCR] = {0x210CC, 0}, + [GCC_TCSR_BCR] = {0x22000, 0}, + [GCC_MPM_BCR] = {0x24000, 0}, + [GCC_SPDM_BCR] = {0x25000, 0}, +}; + +static const struct regmap_config gcc_ipq4019_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x2dfff, + .fast_io = true, +}; + +static const struct qcom_cc_desc gcc_ipq4019_desc = { + .config = &gcc_ipq4019_regmap_config, + .clks = gcc_ipq4019_clocks, + .num_clks = ARRAY_SIZE(gcc_ipq4019_clocks), + .resets = gcc_ipq4019_resets, + .num_resets = ARRAY_SIZE(gcc_ipq4019_resets), +}; + +static const struct of_device_id gcc_ipq4019_match_table[] = { + { .compatible = "qcom,gcc-ipq4019" }, + { } +}; +MODULE_DEVICE_TABLE(of, gcc_ipq4019_match_table); + +static int gcc_ipq4019_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + + clk_register_fixed_rate(dev, "fepll125", "xo", 0, 200000000); + clk_register_fixed_rate(dev, "fepll125dly", "xo", 0, 200000000); + clk_register_fixed_rate(dev, "fepllwcss2g", "xo", 0, 200000000); + clk_register_fixed_rate(dev, "fepllwcss5g", "xo", 0, 200000000); + clk_register_fixed_rate(dev, "fepll200", "xo", 0, 200000000); + clk_register_fixed_rate(dev, "fepll500", "xo", 0, 200000000); + clk_register_fixed_rate(dev, "ddrpllapss", "xo", 0, 666000000); + + return qcom_cc_probe(pdev, &gcc_ipq4019_desc); +} + +static struct platform_driver gcc_ipq4019_driver = { + .probe = gcc_ipq4019_probe, + .driver = { + .name = "qcom,gcc-ipq4019", + .owner = THIS_MODULE, + .of_match_table = gcc_ipq4019_match_table, + }, +}; + +static int __init gcc_ipq4019_init(void) +{ + return platform_driver_register(&gcc_ipq4019_driver); +} +core_initcall(gcc_ipq4019_init); + +static void __exit gcc_ipq4019_exit(void) +{ + platform_driver_unregister(&gcc_ipq4019_driver); +} +module_exit(gcc_ipq4019_exit); + +MODULE_ALIAS("platform:gcc-ipq4019"); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("QCOM GCC IPQ4019 driver"); diff --git a/drivers/clk/qcom/gcc-ipq806x.c b/drivers/clk/qcom/gcc-ipq806x.c index dd5402bac62029824fd059a353d0c00d4e8576fc..52a7d3959875b2eee15bc75fc8398764849e8c63 100644 --- a/drivers/clk/qcom/gcc-ipq806x.c +++ b/drivers/clk/qcom/gcc-ipq806x.c @@ -890,7 +890,6 @@ static struct clk_branch gsbi1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -906,7 +905,6 @@ static struct clk_branch gsbi2_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi2_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -922,7 +920,6 @@ static struct clk_branch gsbi4_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi4_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -938,7 +935,6 @@ static struct clk_branch gsbi5_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi5_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -954,7 +950,6 @@ static struct clk_branch gsbi6_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi6_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -970,7 +965,6 @@ static struct clk_branch gsbi7_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi7_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1144,7 +1138,6 @@ static struct clk_branch pmem_clk = { .hw.init = &(struct clk_init_data){ .name = "pmem_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1308,7 +1301,6 @@ static struct clk_branch sdc1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "sdc1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1324,7 +1316,6 @@ static struct clk_branch sdc3_h_clk = { .hw.init = &(struct clk_init_data){ .name = "sdc3_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1394,7 +1385,6 @@ static struct clk_branch tsif_h_clk = { .hw.init = &(struct clk_init_data){ .name = "tsif_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1410,7 +1400,6 @@ static struct clk_branch dma_bam_h_clk = { .hw.init = &(struct clk_init_data){ .name = "dma_bam_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1425,7 +1414,6 @@ static struct clk_branch adm0_clk = { .hw.init = &(struct clk_init_data){ .name = "adm0_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1442,7 +1430,6 @@ static struct clk_branch adm0_pbus_clk = { .hw.init = &(struct clk_init_data){ .name = "adm0_pbus_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1457,7 +1444,6 @@ static struct clk_branch pmic_arb0_h_clk = { .hw.init = &(struct clk_init_data){ .name = "pmic_arb0_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1472,7 +1458,6 @@ static struct clk_branch pmic_arb1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "pmic_arb1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1487,7 +1472,6 @@ static struct clk_branch pmic_ssbi2_clk = { .hw.init = &(struct clk_init_data){ .name = "pmic_ssbi2_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1504,7 +1488,6 @@ static struct clk_branch rpm_msg_ram_h_clk = { .hw.init = &(struct clk_init_data){ .name = "rpm_msg_ram_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1563,7 +1546,6 @@ static struct clk_branch pcie_a_clk = { .hw.init = &(struct clk_init_data){ .name = "pcie_a_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1577,7 +1559,6 @@ static struct clk_branch pcie_aux_clk = { .hw.init = &(struct clk_init_data){ .name = "pcie_aux_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1591,7 +1572,6 @@ static struct clk_branch pcie_h_clk = { .hw.init = &(struct clk_init_data){ .name = "pcie_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1605,7 +1585,6 @@ static struct clk_branch pcie_phy_clk = { .hw.init = &(struct clk_init_data){ .name = "pcie_phy_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1659,7 +1638,6 @@ static struct clk_branch pcie1_a_clk = { .hw.init = &(struct clk_init_data){ .name = "pcie1_a_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1673,7 +1651,6 @@ static struct clk_branch pcie1_aux_clk = { .hw.init = &(struct clk_init_data){ .name = "pcie1_aux_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1687,7 +1664,6 @@ static struct clk_branch pcie1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "pcie1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1701,7 +1677,6 @@ static struct clk_branch pcie1_phy_clk = { .hw.init = &(struct clk_init_data){ .name = "pcie1_phy_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1755,7 +1730,6 @@ static struct clk_branch pcie2_a_clk = { .hw.init = &(struct clk_init_data){ .name = "pcie2_a_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1769,7 +1743,6 @@ static struct clk_branch pcie2_aux_clk = { .hw.init = &(struct clk_init_data){ .name = "pcie2_aux_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1783,7 +1756,6 @@ static struct clk_branch pcie2_h_clk = { .hw.init = &(struct clk_init_data){ .name = "pcie2_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1797,7 +1769,6 @@ static struct clk_branch pcie2_phy_clk = { .hw.init = &(struct clk_init_data){ .name = "pcie2_phy_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1887,7 +1858,6 @@ static struct clk_branch sata_a_clk = { .hw.init = &(struct clk_init_data){ .name = "sata_a_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1901,7 +1871,6 @@ static struct clk_branch sata_h_clk = { .hw.init = &(struct clk_init_data){ .name = "sata_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1915,7 +1884,6 @@ static struct clk_branch sfab_sata_s_h_clk = { .hw.init = &(struct clk_init_data){ .name = "sfab_sata_s_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1929,7 +1897,6 @@ static struct clk_branch sata_phy_cfg_clk = { .hw.init = &(struct clk_init_data){ .name = "sata_phy_cfg_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2139,7 +2106,6 @@ static struct clk_branch usb_hs1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "usb_hs1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2218,7 +2184,6 @@ static struct clk_branch usb_fs1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "usb_fs1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2234,7 +2199,6 @@ static struct clk_branch ebi2_clk = { .hw.init = &(struct clk_init_data){ .name = "ebi2_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2248,7 +2212,6 @@ static struct clk_branch ebi2_aon_clk = { .hw.init = &(struct clk_init_data){ .name = "ebi2_always_on_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; diff --git a/drivers/clk/qcom/gcc-msm8660.c b/drivers/clk/qcom/gcc-msm8660.c index ad413036f7c783ee0ba8576bf512dfe3dea08dda..6dc55864979c8843e03cb792b57f1af8e64ecdc6 100644 --- a/drivers/clk/qcom/gcc-msm8660.c +++ b/drivers/clk/qcom/gcc-msm8660.c @@ -1479,7 +1479,6 @@ static struct clk_branch pmem_clk = { .hw.init = &(struct clk_init_data){ .name = "pmem_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2027,7 +2026,6 @@ static struct clk_branch gsbi1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2041,7 +2039,6 @@ static struct clk_branch gsbi2_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi2_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2055,7 +2052,6 @@ static struct clk_branch gsbi3_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi3_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2069,7 +2065,6 @@ static struct clk_branch gsbi4_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi4_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2083,7 +2078,6 @@ static struct clk_branch gsbi5_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi5_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2097,7 +2091,6 @@ static struct clk_branch gsbi6_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi6_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2111,7 +2104,6 @@ static struct clk_branch gsbi7_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi7_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2125,7 +2117,6 @@ static struct clk_branch gsbi8_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi8_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2139,7 +2130,6 @@ static struct clk_branch gsbi9_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi9_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2153,7 +2143,6 @@ static struct clk_branch gsbi10_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi10_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2167,7 +2156,6 @@ static struct clk_branch gsbi11_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi11_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2181,7 +2169,6 @@ static struct clk_branch gsbi12_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi12_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2195,7 +2182,6 @@ static struct clk_branch tsif_h_clk = { .hw.init = &(struct clk_init_data){ .name = "tsif_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2209,7 +2195,6 @@ static struct clk_branch usb_fs1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "usb_fs1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2223,7 +2208,6 @@ static struct clk_branch usb_fs2_h_clk = { .hw.init = &(struct clk_init_data){ .name = "usb_fs2_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2237,7 +2221,6 @@ static struct clk_branch usb_hs1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "usb_hs1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2251,7 +2234,6 @@ static struct clk_branch sdc1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "sdc1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2265,7 +2247,6 @@ static struct clk_branch sdc2_h_clk = { .hw.init = &(struct clk_init_data){ .name = "sdc2_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2279,7 +2260,6 @@ static struct clk_branch sdc3_h_clk = { .hw.init = &(struct clk_init_data){ .name = "sdc3_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2293,7 +2273,6 @@ static struct clk_branch sdc4_h_clk = { .hw.init = &(struct clk_init_data){ .name = "sdc4_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2307,7 +2286,6 @@ static struct clk_branch sdc5_h_clk = { .hw.init = &(struct clk_init_data){ .name = "sdc5_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2322,7 +2300,6 @@ static struct clk_branch adm0_clk = { .hw.init = &(struct clk_init_data){ .name = "adm0_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2337,7 +2314,6 @@ static struct clk_branch adm0_pbus_clk = { .hw.init = &(struct clk_init_data){ .name = "adm0_pbus_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2352,7 +2328,6 @@ static struct clk_branch adm1_clk = { .hw.init = &(struct clk_init_data){ .name = "adm1_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2367,7 +2342,6 @@ static struct clk_branch adm1_pbus_clk = { .hw.init = &(struct clk_init_data){ .name = "adm1_pbus_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2382,7 +2356,6 @@ static struct clk_branch modem_ahb1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "modem_ahb1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2397,7 +2370,6 @@ static struct clk_branch modem_ahb2_h_clk = { .hw.init = &(struct clk_init_data){ .name = "modem_ahb2_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2412,7 +2384,6 @@ static struct clk_branch pmic_arb0_h_clk = { .hw.init = &(struct clk_init_data){ .name = "pmic_arb0_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2427,7 +2398,6 @@ static struct clk_branch pmic_arb1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "pmic_arb1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2442,7 +2412,6 @@ static struct clk_branch pmic_ssbi2_clk = { .hw.init = &(struct clk_init_data){ .name = "pmic_ssbi2_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2459,7 +2428,6 @@ static struct clk_branch rpm_msg_ram_h_clk = { .hw.init = &(struct clk_init_data){ .name = "rpm_msg_ram_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; diff --git a/drivers/clk/qcom/gcc-msm8916.c b/drivers/clk/qcom/gcc-msm8916.c index 8cc9b2868b41a83c1621d0b27bc18598888a6939..9c29080a84d8345781214a45af9e3ba08c4c02cb 100644 --- a/drivers/clk/qcom/gcc-msm8916.c +++ b/drivers/clk/qcom/gcc-msm8916.c @@ -2590,6 +2590,23 @@ static struct clk_branch gcc_mss_cfg_ahb_clk = { }, }; +static struct clk_branch gcc_mss_q6_bimc_axi_clk = { + .halt_reg = 0x49004, + .clkr = { + .enable_reg = 0x49004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_q6_bimc_axi_clk", + .parent_names = (const char *[]){ + "bimc_ddr_clk_src", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch gcc_oxili_ahb_clk = { .halt_reg = 0x59028, .clkr = { @@ -3227,6 +3244,7 @@ static struct clk_regmap *gcc_msm8916_clocks[] = { [GCC_ULTAUDIO_LPAIF_SEC_I2S_CLK] = &gcc_ultaudio_lpaif_sec_i2s_clk.clkr, [GCC_ULTAUDIO_LPAIF_AUX_I2S_CLK] = &gcc_ultaudio_lpaif_aux_i2s_clk.clkr, [GCC_CODEC_DIGCODEC_CLK] = &gcc_codec_digcodec_clk.clkr, + [GCC_MSS_Q6_BIMC_AXI_CLK] = &gcc_mss_q6_bimc_axi_clk.clkr, }; static struct gdsc *gcc_msm8916_gdscs[] = { diff --git a/drivers/clk/qcom/gcc-msm8960.c b/drivers/clk/qcom/gcc-msm8960.c index 983dd7dc89a7970e3c1c8d35a427a56b48959929..eb551c75fba6a523796fdeb2787d853d923c5231 100644 --- a/drivers/clk/qcom/gcc-msm8960.c +++ b/drivers/clk/qcom/gcc-msm8960.c @@ -1546,7 +1546,6 @@ static struct clk_branch pmem_clk = { .hw.init = &(struct clk_init_data){ .name = "pmem_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2143,7 +2142,6 @@ static struct clk_branch usb_hsic_hsio_cal_clk = { .hw.init = &(struct clk_init_data){ .name = "usb_hsic_hsio_cal_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2293,7 +2291,6 @@ static struct clk_branch ce1_core_clk = { .hw.init = &(struct clk_init_data){ .name = "ce1_core_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2307,7 +2304,6 @@ static struct clk_branch ce1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "ce1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2323,7 +2319,6 @@ static struct clk_branch dma_bam_h_clk = { .hw.init = &(struct clk_init_data){ .name = "dma_bam_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2339,7 +2334,6 @@ static struct clk_branch gsbi1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2355,7 +2349,6 @@ static struct clk_branch gsbi2_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi2_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2371,7 +2364,6 @@ static struct clk_branch gsbi3_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi3_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2387,7 +2379,6 @@ static struct clk_branch gsbi4_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi4_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2403,7 +2394,6 @@ static struct clk_branch gsbi5_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi5_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2419,7 +2409,6 @@ static struct clk_branch gsbi6_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi6_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2435,7 +2424,6 @@ static struct clk_branch gsbi7_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi7_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2451,7 +2439,6 @@ static struct clk_branch gsbi8_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi8_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2467,7 +2454,6 @@ static struct clk_branch gsbi9_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi9_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2483,7 +2469,6 @@ static struct clk_branch gsbi10_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi10_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2499,7 +2484,6 @@ static struct clk_branch gsbi11_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi11_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2515,7 +2499,6 @@ static struct clk_branch gsbi12_h_clk = { .hw.init = &(struct clk_init_data){ .name = "gsbi12_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2531,7 +2514,6 @@ static struct clk_branch tsif_h_clk = { .hw.init = &(struct clk_init_data){ .name = "tsif_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2545,7 +2527,6 @@ static struct clk_branch usb_fs1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "usb_fs1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2559,7 +2540,6 @@ static struct clk_branch usb_fs2_h_clk = { .hw.init = &(struct clk_init_data){ .name = "usb_fs2_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2575,7 +2555,6 @@ static struct clk_branch usb_hs1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "usb_hs1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2589,7 +2568,6 @@ static struct clk_branch usb_hs3_h_clk = { .hw.init = &(struct clk_init_data){ .name = "usb_hs3_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2603,7 +2581,6 @@ static struct clk_branch usb_hs4_h_clk = { .hw.init = &(struct clk_init_data){ .name = "usb_hs4_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2617,7 +2594,6 @@ static struct clk_branch usb_hsic_h_clk = { .hw.init = &(struct clk_init_data){ .name = "usb_hsic_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2633,7 +2609,6 @@ static struct clk_branch sdc1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "sdc1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2649,7 +2624,6 @@ static struct clk_branch sdc2_h_clk = { .hw.init = &(struct clk_init_data){ .name = "sdc2_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2665,7 +2639,6 @@ static struct clk_branch sdc3_h_clk = { .hw.init = &(struct clk_init_data){ .name = "sdc3_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2681,7 +2654,6 @@ static struct clk_branch sdc4_h_clk = { .hw.init = &(struct clk_init_data){ .name = "sdc4_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2697,7 +2669,6 @@ static struct clk_branch sdc5_h_clk = { .hw.init = &(struct clk_init_data){ .name = "sdc5_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2712,7 +2683,6 @@ static struct clk_branch adm0_clk = { .hw.init = &(struct clk_init_data){ .name = "adm0_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2729,7 +2699,6 @@ static struct clk_branch adm0_pbus_clk = { .hw.init = &(struct clk_init_data){ .name = "adm0_pbus_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2753,7 +2722,7 @@ static struct clk_rcg ce3_src = { }, .freq_tbl = clk_tbl_ce3, .clkr = { - .enable_reg = 0x2c08, + .enable_reg = 0x36c0, .enable_mask = BIT(7), .hw.init = &(struct clk_init_data){ .name = "ce3_src", @@ -2769,7 +2738,7 @@ static struct clk_branch ce3_core_clk = { .halt_reg = 0x2fdc, .halt_bit = 5, .clkr = { - .enable_reg = 0x36c4, + .enable_reg = 0x36cc, .enable_mask = BIT(4), .hw.init = &(struct clk_init_data){ .name = "ce3_core_clk", @@ -2883,7 +2852,6 @@ static struct clk_branch sata_a_clk = { .hw.init = &(struct clk_init_data){ .name = "sata_a_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2897,7 +2865,6 @@ static struct clk_branch sata_h_clk = { .hw.init = &(struct clk_init_data){ .name = "sata_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2911,7 +2878,6 @@ static struct clk_branch sfab_sata_s_h_clk = { .hw.init = &(struct clk_init_data){ .name = "sfab_sata_s_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2925,7 +2891,6 @@ static struct clk_branch sata_phy_cfg_clk = { .hw.init = &(struct clk_init_data){ .name = "sata_phy_cfg_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2939,7 +2904,6 @@ static struct clk_branch pcie_phy_ref_clk = { .hw.init = &(struct clk_init_data){ .name = "pcie_phy_ref_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2953,7 +2917,6 @@ static struct clk_branch pcie_h_clk = { .hw.init = &(struct clk_init_data){ .name = "pcie_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2967,7 +2930,6 @@ static struct clk_branch pcie_a_clk = { .hw.init = &(struct clk_init_data){ .name = "pcie_a_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2982,7 +2944,6 @@ static struct clk_branch pmic_arb0_h_clk = { .hw.init = &(struct clk_init_data){ .name = "pmic_arb0_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2997,7 +2958,6 @@ static struct clk_branch pmic_arb1_h_clk = { .hw.init = &(struct clk_init_data){ .name = "pmic_arb1_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -3012,7 +2972,6 @@ static struct clk_branch pmic_ssbi2_clk = { .hw.init = &(struct clk_init_data){ .name = "pmic_ssbi2_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -3029,7 +2988,6 @@ static struct clk_branch rpm_msg_ram_h_clk = { .hw.init = &(struct clk_init_data){ .name = "rpm_msg_ram_h_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; diff --git a/drivers/clk/qcom/gcc-msm8974.c b/drivers/clk/qcom/gcc-msm8974.c index 335952db309bd3260c4c86cd048417fb43ac9cbd..00915209e7c547f080b389be9f9478d4b70658f9 100644 --- a/drivers/clk/qcom/gcc-msm8974.c +++ b/drivers/clk/qcom/gcc-msm8974.c @@ -1965,7 +1965,6 @@ static struct clk_branch gcc_mss_q6_bimc_axi_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_mss_q6_bimc_axi_clk", - .flags = CLK_IS_ROOT, .ops = &clk_branch2_ops, }, }, diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c index 16d7c323db4985987b975ac35d13762237c120ff..c9b96f318d9c84159841b0ba40bd6e35cf841d3b 100644 --- a/drivers/clk/qcom/gcc-msm8996.c +++ b/drivers/clk/qcom/gcc-msm8996.c @@ -30,6 +30,7 @@ #include "clk-rcg.h" #include "clk-branch.h" #include "reset.h" +#include "gdsc.h" #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } @@ -1320,7 +1321,7 @@ static struct clk_branch gcc_mmss_bimc_gfx_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_mmss_bimc_gfx_clk", - .flags = CLK_SET_RATE_PARENT | CLK_IS_ROOT, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -2314,7 +2315,7 @@ static struct clk_branch gcc_bimc_gfx_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_bimc_gfx_clk", - .flags = CLK_SET_RATE_PARENT | CLK_IS_ROOT, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -2814,7 +2815,6 @@ static struct clk_branch gcc_ufs_sys_clk_core_clk = { .hw.init = &(struct clk_init_data){ .name = "gcc_ufs_sys_clk_core_clk", .ops = &clk_branch2_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2827,7 +2827,6 @@ static struct clk_branch gcc_ufs_tx_symbol_clk_core_clk = { .hw.init = &(struct clk_init_data){ .name = "gcc_ufs_tx_symbol_clk_core_clk", .ops = &clk_branch2_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -3059,6 +3058,83 @@ static struct clk_hw *gcc_msm8996_hws[] = { &ufs_ice_core_postdiv_clk_src.hw, }; +static struct gdsc aggre0_noc_gdsc = { + .gdscr = 0x81004, + .gds_hw_ctrl = 0x81028, + .pd = { + .name = "aggre0_noc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc hlos1_vote_aggre0_noc_gdsc = { + .gdscr = 0x7d024, + .pd = { + .name = "hlos1_vote_aggre0_noc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc hlos1_vote_lpass_adsp_gdsc = { + .gdscr = 0x7d034, + .pd = { + .name = "hlos1_vote_lpass_adsp", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc hlos1_vote_lpass_core_gdsc = { + .gdscr = 0x7d038, + .pd = { + .name = "hlos1_vote_lpass_core", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc usb30_gdsc = { + .gdscr = 0xf004, + .pd = { + .name = "usb30", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc pcie0_gdsc = { + .gdscr = 0x6b004, + .pd = { + .name = "pcie0", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc pcie1_gdsc = { + .gdscr = 0x6d004, + .pd = { + .name = "pcie1", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc pcie2_gdsc = { + .gdscr = 0x6e004, + .pd = { + .name = "pcie2", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc ufs_gdsc = { + .gdscr = 0x75004, + .pd = { + .name = "ufs", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + static struct clk_regmap *gcc_msm8996_clocks[] = { [GPLL0_EARLY] = &gpll0_early.clkr, [GPLL0] = &gpll0.clkr, @@ -3245,6 +3321,18 @@ static struct clk_regmap *gcc_msm8996_clocks[] = { [GCC_RX1_USB2_CLKREF_CLK] = &gcc_rx1_usb2_clkref_clk.clkr, }; +static struct gdsc *gcc_msm8996_gdscs[] = { + [AGGRE0_NOC_GDSC] = &aggre0_noc_gdsc, + [HLOS1_VOTE_AGGRE0_NOC_GDSC] = &hlos1_vote_aggre0_noc_gdsc, + [HLOS1_VOTE_LPASS_ADSP_GDSC] = &hlos1_vote_lpass_adsp_gdsc, + [HLOS1_VOTE_LPASS_CORE_GDSC] = &hlos1_vote_lpass_core_gdsc, + [USB30_GDSC] = &usb30_gdsc, + [PCIE0_GDSC] = &pcie0_gdsc, + [PCIE1_GDSC] = &pcie1_gdsc, + [PCIE2_GDSC] = &pcie2_gdsc, + [UFS_GDSC] = &ufs_gdsc, +}; + static const struct qcom_reset_map gcc_msm8996_resets[] = { [GCC_SYSTEM_NOC_BCR] = { 0x4000 }, [GCC_CONFIG_NOC_BCR] = { 0x5000 }, @@ -3363,6 +3451,8 @@ static const struct qcom_cc_desc gcc_msm8996_desc = { .num_clks = ARRAY_SIZE(gcc_msm8996_clocks), .resets = gcc_msm8996_resets, .num_resets = ARRAY_SIZE(gcc_msm8996_resets), + .gdscs = gcc_msm8996_gdscs, + .num_gdscs = ARRAY_SIZE(gcc_msm8996_gdscs), }; static const struct of_device_id gcc_msm8996_match_table[] = { diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index da9fad8b642b8067be64a7f43f3ff42243ecc0f4..f12d7b2bddd7061495bcd04a12f76245ed2721d1 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -42,12 +43,12 @@ #define domain_to_gdsc(domain) container_of(domain, struct gdsc, pd) -static int gdsc_is_enabled(struct gdsc *sc) +static int gdsc_is_enabled(struct gdsc *sc, unsigned int reg) { u32 val; int ret; - ret = regmap_read(sc->regmap, sc->gdscr, &val); + ret = regmap_read(sc->regmap, reg, &val); if (ret) return ret; @@ -58,28 +59,46 @@ static int gdsc_toggle_logic(struct gdsc *sc, bool en) { int ret; u32 val = en ? 0 : SW_COLLAPSE_MASK; - u32 check = en ? PWR_ON_MASK : 0; - unsigned long timeout; + ktime_t start; + unsigned int status_reg = sc->gdscr; ret = regmap_update_bits(sc->regmap, sc->gdscr, SW_COLLAPSE_MASK, val); if (ret) return ret; - timeout = jiffies + usecs_to_jiffies(TIMEOUT_US); - do { - ret = regmap_read(sc->regmap, sc->gdscr, &val); - if (ret) - return ret; + /* If disabling votable gdscs, don't poll on status */ + if ((sc->flags & VOTABLE) && !en) { + /* + * Add a short delay here to ensure that an enable + * right after it was disabled does not put it in an + * unknown state + */ + udelay(TIMEOUT_US); + return 0; + } - if ((val & PWR_ON_MASK) == check) - return 0; - } while (time_before(jiffies, timeout)); + if (sc->gds_hw_ctrl) { + status_reg = sc->gds_hw_ctrl; + /* + * The gds hw controller asserts/de-asserts the status bit soon + * after it receives a power on/off request from a master. + * The controller then takes around 8 xo cycles to start its + * internal state machine and update the status bit. During + * this time, the status bit does not reflect the true status + * of the core. + * Add a delay of 1 us between writing to the SW_COLLAPSE bit + * and polling the status bit. + */ + udelay(1); + } - ret = regmap_read(sc->regmap, sc->gdscr, &val); - if (ret) - return ret; + start = ktime_get(); + do { + if (gdsc_is_enabled(sc, status_reg) == en) + return 0; + } while (ktime_us_delta(ktime_get(), start) < TIMEOUT_US); - if ((val & PWR_ON_MASK) == check) + if (gdsc_is_enabled(sc, status_reg) == en) return 0; return -ETIMEDOUT; @@ -165,6 +184,7 @@ static int gdsc_init(struct gdsc *sc) { u32 mask, val; int on, ret; + unsigned int reg; /* * Disable HW trigger: collapse/restore occur based on registers writes. @@ -185,10 +205,18 @@ static int gdsc_init(struct gdsc *sc) return ret; } - on = gdsc_is_enabled(sc); + reg = sc->gds_hw_ctrl ? sc->gds_hw_ctrl : sc->gdscr; + on = gdsc_is_enabled(sc, reg); if (on < 0) return on; + /* + * Votable GDSCs can be ON due to Vote from other masters. + * If a Votable GDSC is ON, make sure we have a Vote. + */ + if ((sc->flags & VOTABLE) && on) + gdsc_enable(&sc->pd); + if (on || (sc->pwrsts & PWRSTS_RET)) gdsc_force_mem_on(sc); else @@ -201,11 +229,14 @@ static int gdsc_init(struct gdsc *sc) return 0; } -int gdsc_register(struct device *dev, struct gdsc **scs, size_t num, +int gdsc_register(struct gdsc_desc *desc, struct reset_controller_dev *rcdev, struct regmap *regmap) { int i, ret; struct genpd_onecell_data *data; + struct device *dev = desc->dev; + struct gdsc **scs = desc->scs; + size_t num = desc->num; data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); if (!data) @@ -228,10 +259,30 @@ int gdsc_register(struct device *dev, struct gdsc **scs, size_t num, data->domains[i] = &scs[i]->pd; } + /* Add subdomains */ + for (i = 0; i < num; i++) { + if (!scs[i]) + continue; + if (scs[i]->parent) + pm_genpd_add_subdomain(scs[i]->parent, &scs[i]->pd); + } + return of_genpd_add_provider_onecell(dev->of_node, data); } -void gdsc_unregister(struct device *dev) +void gdsc_unregister(struct gdsc_desc *desc) { + int i; + struct device *dev = desc->dev; + struct gdsc **scs = desc->scs; + size_t num = desc->num; + + /* Remove subdomains */ + for (i = 0; i < num; i++) { + if (!scs[i]) + continue; + if (scs[i]->parent) + pm_genpd_remove_subdomain(scs[i]->parent, &scs[i]->pd); + } of_genpd_del_provider(dev->of_node); } diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h index 5ded26884f08e936dddb3fdc9105d3b8e476abcd..3bf497c36bdf83b205733fb0201e33e7b103f61d 100644 --- a/drivers/clk/qcom/gdsc.h +++ b/drivers/clk/qcom/gdsc.h @@ -20,18 +20,12 @@ struct regmap; struct reset_controller_dev; -/* Powerdomain allowable state bitfields */ -#define PWRSTS_OFF BIT(0) -#define PWRSTS_RET BIT(1) -#define PWRSTS_ON BIT(2) -#define PWRSTS_OFF_ON (PWRSTS_OFF | PWRSTS_ON) -#define PWRSTS_RET_ON (PWRSTS_RET | PWRSTS_ON) - /** * struct gdsc - Globally Distributed Switch Controller * @pd: generic power domain * @regmap: regmap for MMIO accesses * @gdscr: gsdc control register + * @gds_hw_ctrl: gds_hw_ctrl register * @cxcs: offsets of branch registers to toggle mem/periph bits in * @cxc_count: number of @cxcs * @pwrsts: Possible powerdomain power states @@ -41,28 +35,44 @@ struct reset_controller_dev; */ struct gdsc { struct generic_pm_domain pd; + struct generic_pm_domain *parent; struct regmap *regmap; unsigned int gdscr; + unsigned int gds_hw_ctrl; unsigned int *cxcs; unsigned int cxc_count; const u8 pwrsts; +/* Powerdomain allowable state bitfields */ +#define PWRSTS_OFF BIT(0) +#define PWRSTS_RET BIT(1) +#define PWRSTS_ON BIT(2) +#define PWRSTS_OFF_ON (PWRSTS_OFF | PWRSTS_ON) +#define PWRSTS_RET_ON (PWRSTS_RET | PWRSTS_ON) + const u8 flags; +#define VOTABLE BIT(0) struct reset_controller_dev *rcdev; unsigned int *resets; unsigned int reset_count; }; +struct gdsc_desc { + struct device *dev; + struct gdsc **scs; + size_t num; +}; + #ifdef CONFIG_QCOM_GDSC -int gdsc_register(struct device *, struct gdsc **, size_t n, - struct reset_controller_dev *, struct regmap *); -void gdsc_unregister(struct device *); +int gdsc_register(struct gdsc_desc *desc, struct reset_controller_dev *, + struct regmap *); +void gdsc_unregister(struct gdsc_desc *desc); #else -static inline int gdsc_register(struct device *d, struct gdsc **g, size_t n, +static inline int gdsc_register(struct gdsc_desc *desc, struct reset_controller_dev *rcdev, struct regmap *r) { return -ENOSYS; } -static inline void gdsc_unregister(struct device *d) {}; +static inline void gdsc_unregister(struct gdsc_desc *desc) {}; #endif /* CONFIG_QCOM_GDSC */ #endif /* __QCOM_GDSC_H__ */ diff --git a/drivers/clk/qcom/mmcc-msm8960.c b/drivers/clk/qcom/mmcc-msm8960.c index 00e36192a1defe9131f1f1505f89b88b574f4284..7f21421c87d6bba60000a979d7c7e125fd76bee1 100644 --- a/drivers/clk/qcom/mmcc-msm8960.c +++ b/drivers/clk/qcom/mmcc-msm8960.c @@ -1789,7 +1789,6 @@ static struct clk_branch gmem_axi_clk = { .hw.init = &(struct clk_init_data){ .name = "gmem_axi_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1805,7 +1804,6 @@ static struct clk_branch ijpeg_axi_clk = { .hw.init = &(struct clk_init_data){ .name = "ijpeg_axi_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1821,7 +1819,6 @@ static struct clk_branch mmss_imem_axi_clk = { .hw.init = &(struct clk_init_data){ .name = "mmss_imem_axi_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1835,7 +1832,6 @@ static struct clk_branch jpegd_axi_clk = { .hw.init = &(struct clk_init_data){ .name = "jpegd_axi_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1851,7 +1847,6 @@ static struct clk_branch vcodec_axi_b_clk = { .hw.init = &(struct clk_init_data){ .name = "vcodec_axi_b_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1867,7 +1862,6 @@ static struct clk_branch vcodec_axi_a_clk = { .hw.init = &(struct clk_init_data){ .name = "vcodec_axi_a_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1883,7 +1877,6 @@ static struct clk_branch vcodec_axi_clk = { .hw.init = &(struct clk_init_data){ .name = "vcodec_axi_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1897,7 +1890,6 @@ static struct clk_branch vfe_axi_clk = { .hw.init = &(struct clk_init_data){ .name = "vfe_axi_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1913,7 +1905,6 @@ static struct clk_branch mdp_axi_clk = { .hw.init = &(struct clk_init_data){ .name = "mdp_axi_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1929,7 +1920,6 @@ static struct clk_branch rot_axi_clk = { .hw.init = &(struct clk_init_data){ .name = "rot_axi_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1945,7 +1935,6 @@ static struct clk_branch vcap_axi_clk = { .hw.init = &(struct clk_init_data){ .name = "vcap_axi_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1961,7 +1950,6 @@ static struct clk_branch vpe_axi_clk = { .hw.init = &(struct clk_init_data){ .name = "vpe_axi_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1977,7 +1965,6 @@ static struct clk_branch gfx3d_axi_clk = { .hw.init = &(struct clk_init_data){ .name = "gfx3d_axi_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -1991,7 +1978,6 @@ static struct clk_branch amp_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "amp_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2005,7 +1991,6 @@ static struct clk_branch csi_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "csi_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT }, }, }; @@ -2019,7 +2004,6 @@ static struct clk_branch dsi_m_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "dsi_m_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2035,7 +2019,6 @@ static struct clk_branch dsi_s_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "dsi_s_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2049,7 +2032,6 @@ static struct clk_branch dsi2_m_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "dsi2_m_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT }, }, }; @@ -2065,7 +2047,6 @@ static struct clk_branch dsi2_s_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "dsi2_s_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2425,7 +2406,6 @@ static struct clk_branch gfx2d0_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "gfx2d0_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2441,7 +2421,6 @@ static struct clk_branch gfx2d1_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "gfx2d1_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2457,7 +2436,6 @@ static struct clk_branch gfx3d_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "gfx3d_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2473,7 +2451,6 @@ static struct clk_branch hdmi_m_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "hdmi_m_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2489,7 +2466,6 @@ static struct clk_branch hdmi_s_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "hdmi_s_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2503,7 +2479,6 @@ static struct clk_branch ijpeg_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "ijpeg_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT }, }, }; @@ -2519,7 +2494,6 @@ static struct clk_branch mmss_imem_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "mmss_imem_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT }, }, }; @@ -2533,7 +2507,6 @@ static struct clk_branch jpegd_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "jpegd_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2547,7 +2520,6 @@ static struct clk_branch mdp_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "mdp_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2561,7 +2533,6 @@ static struct clk_branch rot_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "rot_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT }, }, }; @@ -2577,7 +2548,6 @@ static struct clk_branch smmu_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "smmu_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2591,7 +2561,6 @@ static struct clk_branch tv_enc_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "tv_enc_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2605,7 +2574,6 @@ static struct clk_branch vcap_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "vcap_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2621,7 +2589,6 @@ static struct clk_branch vcodec_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "vcodec_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2635,7 +2602,6 @@ static struct clk_branch vfe_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "vfe_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; @@ -2649,7 +2615,6 @@ static struct clk_branch vpe_ahb_clk = { .hw.init = &(struct clk_init_data){ .name = "vpe_ahb_clk", .ops = &clk_branch_ops, - .flags = CLK_IS_ROOT, }, }, }; diff --git a/drivers/clk/qcom/mmcc-msm8974.c b/drivers/clk/qcom/mmcc-msm8974.c index 9d790bcadf25a75a360f8d5aebfdf4ab50237c61..715e7cd94125e4188b7b5c39b02f23c9021be653 100644 --- a/drivers/clk/qcom/mmcc-msm8974.c +++ b/drivers/clk/qcom/mmcc-msm8974.c @@ -2400,6 +2400,7 @@ static struct gdsc oxilicx_gdsc = { .pd = { .name = "oxilicx", }, + .parent = &oxili_gdsc.pd, .pwrsts = PWRSTS_OFF_ON, }; @@ -2615,7 +2616,6 @@ MODULE_DEVICE_TABLE(of, mmcc_msm8974_match_table); static int mmcc_msm8974_probe(struct platform_device *pdev) { struct regmap *regmap; - int ret; regmap = qcom_cc_map(pdev, &mmcc_msm8974_desc); if (IS_ERR(regmap)) @@ -2624,22 +2624,11 @@ static int mmcc_msm8974_probe(struct platform_device *pdev) clk_pll_configure_sr_hpm_lp(&mmpll1, regmap, &mmpll1_config, true); clk_pll_configure_sr_hpm_lp(&mmpll3, regmap, &mmpll3_config, false); - ret = qcom_cc_really_probe(pdev, &mmcc_msm8974_desc, regmap); - if (ret) - return ret; - - return pm_genpd_add_subdomain(&oxili_gdsc.pd, &oxilicx_gdsc.pd); -} - -static int mmcc_msm8974_remove(struct platform_device *pdev) -{ - pm_genpd_remove_subdomain(&oxili_gdsc.pd, &oxilicx_gdsc.pd); - return 0; + return qcom_cc_really_probe(pdev, &mmcc_msm8974_desc, regmap); } static struct platform_driver mmcc_msm8974_driver = { .probe = mmcc_msm8974_probe, - .remove = mmcc_msm8974_remove, .driver = { .name = "mmcc-msm8974", .of_match_table = mmcc_msm8974_match_table, diff --git a/drivers/clk/qcom/mmcc-msm8996.c b/drivers/clk/qcom/mmcc-msm8996.c index 064f3eaa39d011d9e354fde0329bdc88e7b826d4..6df7ff36b416162d4b2979a35fd2b329eef777f9 100644 --- a/drivers/clk/qcom/mmcc-msm8996.c +++ b/drivers/clk/qcom/mmcc-msm8996.c @@ -32,6 +32,7 @@ #include "clk-rcg.h" #include "clk-branch.h" #include "reset.h" +#include "gdsc.h" #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } @@ -2917,6 +2918,144 @@ static struct clk_hw *mmcc_msm8996_hws[] = { &gpll0_div.hw, }; +static struct gdsc mmagic_video_gdsc = { + .gdscr = 0x119c, + .gds_hw_ctrl = 0x120c, + .pd = { + .name = "mmagic_video", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc mmagic_mdss_gdsc = { + .gdscr = 0x247c, + .gds_hw_ctrl = 0x2480, + .pd = { + .name = "mmagic_mdss", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc mmagic_camss_gdsc = { + .gdscr = 0x3c4c, + .gds_hw_ctrl = 0x3c50, + .pd = { + .name = "mmagic_camss", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc venus_gdsc = { + .gdscr = 0x1024, + .cxcs = (unsigned int []){ 0x1028, 0x1034, 0x1038 }, + .cxc_count = 3, + .pd = { + .name = "venus", + }, + .parent = &mmagic_video_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc venus_core0_gdsc = { + .gdscr = 0x1040, + .cxcs = (unsigned int []){ 0x1048 }, + .cxc_count = 1, + .pd = { + .name = "venus_core0", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc venus_core1_gdsc = { + .gdscr = 0x1044, + .cxcs = (unsigned int []){ 0x104c }, + .cxc_count = 1, + .pd = { + .name = "venus_core1", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc camss_gdsc = { + .gdscr = 0x34a0, + .cxcs = (unsigned int []){ 0x36bc, 0x36c4 }, + .cxc_count = 2, + .pd = { + .name = "camss", + }, + .parent = &mmagic_camss_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc vfe0_gdsc = { + .gdscr = 0x3664, + .cxcs = (unsigned int []){ 0x36a8 }, + .cxc_count = 1, + .pd = { + .name = "vfe0", + }, + .parent = &camss_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc vfe1_gdsc = { + .gdscr = 0x3674, + .cxcs = (unsigned int []){ 0x36ac }, + .cxc_count = 1, + .pd = { + .name = "vfe0", + }, + .parent = &camss_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc jpeg_gdsc = { + .gdscr = 0x35a4, + .cxcs = (unsigned int []){ 0x35a8, 0x35b0, 0x35c0, 0x35b8 }, + .cxc_count = 4, + .pd = { + .name = "jpeg", + }, + .parent = &camss_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc cpp_gdsc = { + .gdscr = 0x36d4, + .cxcs = (unsigned int []){ 0x36b0 }, + .cxc_count = 1, + .pd = { + .name = "cpp", + }, + .parent = &camss_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc fd_gdsc = { + .gdscr = 0x3b64, + .cxcs = (unsigned int []){ 0x3b68, 0x3b6c }, + .cxc_count = 2, + .pd = { + .name = "fd", + }, + .parent = &camss_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc mdss_gdsc = { + .gdscr = 0x2304, + .cxcs = (unsigned int []){ 0x2310, 0x231c }, + .cxc_count = 2, + .pd = { + .name = "mdss", + }, + .parent = &mmagic_mdss_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, +}; + static struct clk_regmap *mmcc_msm8996_clocks[] = { [MMPLL0_EARLY] = &mmpll0_early.clkr, [MMPLL0_PLL] = &mmpll0.clkr, @@ -3093,6 +3232,22 @@ static struct clk_regmap *mmcc_msm8996_clocks[] = { [FD_AHB_CLK] = &fd_ahb_clk.clkr, }; +static struct gdsc *mmcc_msm8996_gdscs[] = { + [MMAGIC_VIDEO_GDSC] = &mmagic_video_gdsc, + [MMAGIC_MDSS_GDSC] = &mmagic_mdss_gdsc, + [MMAGIC_CAMSS_GDSC] = &mmagic_camss_gdsc, + [VENUS_GDSC] = &venus_gdsc, + [VENUS_CORE0_GDSC] = &venus_core0_gdsc, + [VENUS_CORE1_GDSC] = &venus_core1_gdsc, + [CAMSS_GDSC] = &camss_gdsc, + [VFE0_GDSC] = &vfe0_gdsc, + [VFE1_GDSC] = &vfe1_gdsc, + [JPEG_GDSC] = &jpeg_gdsc, + [CPP_GDSC] = &cpp_gdsc, + [FD_GDSC] = &fd_gdsc, + [MDSS_GDSC] = &mdss_gdsc, +}; + static const struct qcom_reset_map mmcc_msm8996_resets[] = { [MMAGICAHB_BCR] = { 0x5020 }, [MMAGIC_CFG_BCR] = { 0x5050 }, @@ -3170,6 +3325,8 @@ static const struct qcom_cc_desc mmcc_msm8996_desc = { .num_clks = ARRAY_SIZE(mmcc_msm8996_clocks), .resets = mmcc_msm8996_resets, .num_resets = ARRAY_SIZE(mmcc_msm8996_resets), + .gdscs = mmcc_msm8996_gdscs, + .num_gdscs = ARRAY_SIZE(mmcc_msm8996_gdscs), }; static const struct of_device_id mmcc_msm8996_match_table[] = { diff --git a/drivers/clk/qcom/reset.c b/drivers/clk/qcom/reset.c index 6c977d3a8590674ff97fb81962ba3fccc33ce3a6..0324d8daab9bc01e6099ed78770dab235f9fd98d 100644 --- a/drivers/clk/qcom/reset.c +++ b/drivers/clk/qcom/reset.c @@ -55,7 +55,7 @@ qcom_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id) return regmap_update_bits(rst->regmap, map->reg, mask, 0); } -struct reset_control_ops qcom_reset_ops = { +const struct reset_control_ops qcom_reset_ops = { .reset = qcom_reset, .assert = qcom_reset_assert, .deassert = qcom_reset_deassert, diff --git a/drivers/clk/qcom/reset.h b/drivers/clk/qcom/reset.h index 0e11e2130f97cd244c56cc3a27a9bf49c72a6945..cda877927d43a03f5628149038da9d620354170c 100644 --- a/drivers/clk/qcom/reset.h +++ b/drivers/clk/qcom/reset.h @@ -32,6 +32,6 @@ struct qcom_reset_controller { #define to_qcom_reset_controller(r) \ container_of(r, struct qcom_reset_controller, rcdev); -extern struct reset_control_ops qcom_reset_ops; +extern const struct reset_control_ops qcom_reset_ops; #endif diff --git a/drivers/clk/shmobile/Makefile b/drivers/clk/renesas/Makefile similarity index 100% rename from drivers/clk/shmobile/Makefile rename to drivers/clk/renesas/Makefile diff --git a/drivers/clk/shmobile/clk-div6.c b/drivers/clk/renesas/clk-div6.c similarity index 98% rename from drivers/clk/shmobile/clk-div6.c rename to drivers/clk/renesas/clk-div6.c index 9999947694509d5867a09fd2903205af350b6814..0627860233cbf97e53af7f1be3edafb5fa5e95ce 100644 --- a/drivers/clk/shmobile/clk-div6.c +++ b/drivers/clk/renesas/clk-div6.c @@ -82,9 +82,8 @@ static unsigned long cpg_div6_clock_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct div6_clock *clock = to_div6_clock(hw); - unsigned int div = (clk_readl(clock->reg) & CPG_DIV6_DIV_MASK) + 1; - return parent_rate / div; + return parent_rate / clock->div; } static unsigned int cpg_div6_clock_calc_div(unsigned long rate, diff --git a/drivers/clk/shmobile/clk-div6.h b/drivers/clk/renesas/clk-div6.h similarity index 68% rename from drivers/clk/shmobile/clk-div6.h rename to drivers/clk/renesas/clk-div6.h index 9a85a95188daa813e42a1256d8dca161a16a0b8a..567b31d2bfa5269cf16b759196d6d39b9dbd804e 100644 --- a/drivers/clk/shmobile/clk-div6.h +++ b/drivers/clk/renesas/clk-div6.h @@ -1,5 +1,5 @@ -#ifndef __SHMOBILE_CLK_DIV6_H__ -#define __SHMOBILE_CLK_DIV6_H__ +#ifndef __RENESAS_CLK_DIV6_H__ +#define __RENESAS_CLK_DIV6_H__ struct clk *cpg_div6_register(const char *name, unsigned int num_parents, const char **parent_names, void __iomem *reg); diff --git a/drivers/clk/shmobile/clk-emev2.c b/drivers/clk/renesas/clk-emev2.c similarity index 100% rename from drivers/clk/shmobile/clk-emev2.c rename to drivers/clk/renesas/clk-emev2.c diff --git a/drivers/clk/shmobile/clk-mstp.c b/drivers/clk/renesas/clk-mstp.c similarity index 99% rename from drivers/clk/shmobile/clk-mstp.c rename to drivers/clk/renesas/clk-mstp.c index 3b09716ebda28227eebd52da5616c40245e490d5..3d44e183aedd61c7fd28d15b6ede180033e0b6e1 100644 --- a/drivers/clk/shmobile/clk-mstp.c +++ b/drivers/clk/renesas/clk-mstp.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/clk/shmobile/clk-r8a73a4.c b/drivers/clk/renesas/clk-r8a73a4.c similarity index 99% rename from drivers/clk/shmobile/clk-r8a73a4.c rename to drivers/clk/renesas/clk-r8a73a4.c index 9326204bed9d6cb7734cfb7b84b80252abcaba7a..28d204bb659e7879de4d7ad48c9221dfe4106af6 100644 --- a/drivers/clk/shmobile/clk-r8a73a4.c +++ b/drivers/clk/renesas/clk-r8a73a4.c @@ -9,7 +9,7 @@ */ #include -#include +#include #include #include #include diff --git a/drivers/clk/shmobile/clk-r8a7740.c b/drivers/clk/renesas/clk-r8a7740.c similarity index 99% rename from drivers/clk/shmobile/clk-r8a7740.c rename to drivers/clk/renesas/clk-r8a7740.c index 1e6b1da580658f46e6fc31f42c054760e52e0af6..2f7ce6696b6c0f1d98a9cd9d91dfe861acb8dc16 100644 --- a/drivers/clk/shmobile/clk-r8a7740.c +++ b/drivers/clk/renesas/clk-r8a7740.c @@ -9,7 +9,7 @@ */ #include -#include +#include #include #include #include diff --git a/drivers/clk/shmobile/clk-r8a7778.c b/drivers/clk/renesas/clk-r8a7778.c similarity index 99% rename from drivers/clk/shmobile/clk-r8a7778.c rename to drivers/clk/renesas/clk-r8a7778.c index b1741551fff2a6c9d555f3639891d78dffc48c02..40e3a501a50e200ff68e41710ad9fcecaf695327 100644 --- a/drivers/clk/shmobile/clk-r8a7778.c +++ b/drivers/clk/renesas/clk-r8a7778.c @@ -9,7 +9,7 @@ */ #include -#include +#include #include #include diff --git a/drivers/clk/shmobile/clk-r8a7779.c b/drivers/clk/renesas/clk-r8a7779.c similarity index 99% rename from drivers/clk/shmobile/clk-r8a7779.c rename to drivers/clk/renesas/clk-r8a7779.c index 92275c5f2c60303e4399ef77df7f261b7e7a7558..cf2a37df03b15e60ee70e44ce21fcc8f5341680c 100644 --- a/drivers/clk/shmobile/clk-r8a7779.c +++ b/drivers/clk/renesas/clk-r8a7779.c @@ -11,7 +11,7 @@ */ #include -#include +#include #include #include #include diff --git a/drivers/clk/shmobile/clk-rcar-gen2.c b/drivers/clk/renesas/clk-rcar-gen2.c similarity index 99% rename from drivers/clk/shmobile/clk-rcar-gen2.c rename to drivers/clk/renesas/clk-rcar-gen2.c index 841977240305db0bf4ebde3c711c2b47800be9af..00e6aba4b9c095960e7bd635d62eefdd33033da5 100644 --- a/drivers/clk/shmobile/clk-rcar-gen2.c +++ b/drivers/clk/renesas/clk-rcar-gen2.c @@ -11,7 +11,7 @@ */ #include -#include +#include #include #include #include diff --git a/drivers/clk/shmobile/clk-rz.c b/drivers/clk/renesas/clk-rz.c similarity index 98% rename from drivers/clk/shmobile/clk-rz.c rename to drivers/clk/renesas/clk-rz.c index 9766e3cb595fd25750a00c638744615eb1e40819..f6312c62f16bbc85209ca6a6262eb4908a67d58b 100644 --- a/drivers/clk/shmobile/clk-rz.c +++ b/drivers/clk/renesas/clk-rz.c @@ -10,7 +10,7 @@ */ #include -#include +#include #include #include #include diff --git a/drivers/clk/shmobile/clk-sh73a0.c b/drivers/clk/renesas/clk-sh73a0.c similarity index 99% rename from drivers/clk/shmobile/clk-sh73a0.c rename to drivers/clk/renesas/clk-sh73a0.c index 8966f8bbfd726e62f19cc997d2e2c1046aec0b09..eea38f6ea77e995d287831a5d6b34bd7663883c0 100644 --- a/drivers/clk/shmobile/clk-sh73a0.c +++ b/drivers/clk/renesas/clk-sh73a0.c @@ -9,7 +9,7 @@ */ #include -#include +#include #include #include #include diff --git a/drivers/clk/shmobile/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c similarity index 61% rename from drivers/clk/shmobile/r8a7795-cpg-mssr.c rename to drivers/clk/renesas/r8a7795-cpg-mssr.c index 13e994772dfd0cf20fa0a081d65fbebf309bde69..b2198aef5ed4291291d30ca1df3cc2ba5ab5c9a0 100644 --- a/drivers/clk/shmobile/r8a7795-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c @@ -20,6 +20,7 @@ #include #include #include +#include #include @@ -61,6 +62,7 @@ enum r8a7795_clk_types { CLK_TYPE_GEN3_PLL2, CLK_TYPE_GEN3_PLL3, CLK_TYPE_GEN3_PLL4, + CLK_TYPE_GEN3_SD, }; static const struct cpg_core_clk r8a7795_core_clks[] __initconst = { @@ -99,11 +101,18 @@ static const struct cpg_core_clk r8a7795_core_clks[] __initconst = { DEF_FIXED("s3d1", R8A7795_CLK_S3D1, CLK_S3, 1, 1), DEF_FIXED("s3d2", R8A7795_CLK_S3D2, CLK_S3, 2, 1), DEF_FIXED("s3d4", R8A7795_CLK_S3D4, CLK_S3, 4, 1), + + DEF_SD("sd0", R8A7795_CLK_SD0, CLK_PLL1_DIV2, 0x0074), + DEF_SD("sd1", R8A7795_CLK_SD1, CLK_PLL1_DIV2, 0x0078), + DEF_SD("sd2", R8A7795_CLK_SD2, CLK_PLL1_DIV2, 0x0268), + DEF_SD("sd3", R8A7795_CLK_SD3, CLK_PLL1_DIV2, 0x026c), + DEF_FIXED("cl", R8A7795_CLK_CL, CLK_PLL1_DIV2, 48, 1), DEF_FIXED("cp", R8A7795_CLK_CP, CLK_EXTAL, 2, 1), DEF_DIV6P1("mso", R8A7795_CLK_MSO, CLK_PLL1_DIV4, 0x014), DEF_DIV6P1("hdmi", R8A7795_CLK_HDMI, CLK_PLL1_DIV2, 0x250), + DEF_DIV6P1("canfd", R8A7795_CLK_CANFD, CLK_PLL1_DIV4, 0x244), }; static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = { @@ -120,8 +129,17 @@ static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = { DEF_MOD("sys-dmac1", 218, R8A7795_CLK_S3D1), DEF_MOD("sys-dmac0", 219, R8A7795_CLK_S3D1), DEF_MOD("scif2", 310, R8A7795_CLK_S3D4), + DEF_MOD("sdif3", 311, R8A7795_CLK_SD3), + DEF_MOD("sdif2", 312, R8A7795_CLK_SD2), + DEF_MOD("sdif1", 313, R8A7795_CLK_SD1), + DEF_MOD("sdif0", 314, R8A7795_CLK_SD0), DEF_MOD("pcie1", 318, R8A7795_CLK_S3D1), DEF_MOD("pcie0", 319, R8A7795_CLK_S3D1), + DEF_MOD("usb3-if1", 327, R8A7795_CLK_S3D1), + DEF_MOD("usb3-if0", 328, R8A7795_CLK_S3D1), + DEF_MOD("usb-dmac0", 330, R8A7795_CLK_S3D1), + DEF_MOD("usb-dmac1", 331, R8A7795_CLK_S3D1), + DEF_MOD("intc-ex", 407, R8A7795_CLK_CP), DEF_MOD("intc-ap", 408, R8A7795_CLK_S3D1), DEF_MOD("audmac0", 502, R8A7795_CLK_S3D4), DEF_MOD("audmac1", 501, R8A7795_CLK_S3D4), @@ -130,6 +148,21 @@ static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = { DEF_MOD("hscif2", 518, R8A7795_CLK_S3D1), DEF_MOD("hscif1", 519, R8A7795_CLK_S3D1), DEF_MOD("hscif0", 520, R8A7795_CLK_S3D1), + DEF_MOD("fcpvd3", 600, R8A7795_CLK_S2D1), + DEF_MOD("fcpvd2", 601, R8A7795_CLK_S2D1), + DEF_MOD("fcpvd1", 602, R8A7795_CLK_S2D1), + DEF_MOD("fcpvd0", 603, R8A7795_CLK_S2D1), + DEF_MOD("fcpvb1", 606, R8A7795_CLK_S2D1), + DEF_MOD("fcpvb0", 607, R8A7795_CLK_S2D1), + DEF_MOD("fcpvi2", 609, R8A7795_CLK_S2D1), + DEF_MOD("fcpvi1", 610, R8A7795_CLK_S2D1), + DEF_MOD("fcpvi0", 611, R8A7795_CLK_S2D1), + DEF_MOD("fcpf2", 613, R8A7795_CLK_S2D1), + DEF_MOD("fcpf1", 614, R8A7795_CLK_S2D1), + DEF_MOD("fcpf0", 615, R8A7795_CLK_S2D1), + DEF_MOD("fcpci1", 616, R8A7795_CLK_S2D1), + DEF_MOD("fcpci0", 617, R8A7795_CLK_S2D1), + DEF_MOD("fcpcs", 619, R8A7795_CLK_S2D1), DEF_MOD("vspd3", 620, R8A7795_CLK_S2D1), DEF_MOD("vspd2", 621, R8A7795_CLK_S2D1), DEF_MOD("vspd1", 622, R8A7795_CLK_S2D1), @@ -147,6 +180,7 @@ static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = { DEF_MOD("du2", 722, R8A7795_CLK_S2D1), DEF_MOD("du1", 723, R8A7795_CLK_S2D1), DEF_MOD("du0", 724, R8A7795_CLK_S2D1), + DEF_MOD("lvds", 727, R8A7795_CLK_S2D1), DEF_MOD("hdmi1", 728, R8A7795_CLK_HDMI), DEF_MOD("hdmi0", 729, R8A7795_CLK_HDMI), DEF_MOD("etheravb", 812, R8A7795_CLK_S3D2), @@ -159,6 +193,9 @@ static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = { DEF_MOD("gpio2", 910, R8A7795_CLK_CP), DEF_MOD("gpio1", 911, R8A7795_CLK_CP), DEF_MOD("gpio0", 912, R8A7795_CLK_CP), + DEF_MOD("can-fd", 914, R8A7795_CLK_S3D2), + DEF_MOD("can-if1", 915, R8A7795_CLK_S3D4), + DEF_MOD("can-if0", 916, R8A7795_CLK_S3D4), DEF_MOD("i2c6", 918, R8A7795_CLK_S3D2), DEF_MOD("i2c5", 919, R8A7795_CLK_S3D2), DEF_MOD("i2c4", 927, R8A7795_CLK_S3D2), @@ -198,6 +235,221 @@ static const unsigned int r8a7795_crit_mod_clks[] __initconst = { MOD_CLK_ID(408), /* INTC-AP (GIC) */ }; +/* ----------------------------------------------------------------------------- + * SDn Clock + * + */ +#define CPG_SD_STP_HCK BIT(9) +#define CPG_SD_STP_CK BIT(8) + +#define CPG_SD_STP_MASK (CPG_SD_STP_HCK | CPG_SD_STP_CK) +#define CPG_SD_FC_MASK (0x7 << 2 | 0x3 << 0) + +#define CPG_SD_DIV_TABLE_DATA(stp_hck, stp_ck, sd_srcfc, sd_fc, sd_div) \ +{ \ + .val = ((stp_hck) ? CPG_SD_STP_HCK : 0) | \ + ((stp_ck) ? CPG_SD_STP_CK : 0) | \ + ((sd_srcfc) << 2) | \ + ((sd_fc) << 0), \ + .div = (sd_div), \ +} + +struct sd_div_table { + u32 val; + unsigned int div; +}; + +struct sd_clock { + struct clk_hw hw; + void __iomem *reg; + const struct sd_div_table *div_table; + unsigned int div_num; + unsigned int div_min; + unsigned int div_max; +}; + +/* SDn divider + * sd_srcfc sd_fc div + * stp_hck stp_ck (div) (div) = sd_srcfc x sd_fc + *------------------------------------------------------------------- + * 0 0 0 (1) 1 (4) 4 + * 0 0 1 (2) 1 (4) 8 + * 1 0 2 (4) 1 (4) 16 + * 1 0 3 (8) 1 (4) 32 + * 1 0 4 (16) 1 (4) 64 + * 0 0 0 (1) 0 (2) 2 + * 0 0 1 (2) 0 (2) 4 + * 1 0 2 (4) 0 (2) 8 + * 1 0 3 (8) 0 (2) 16 + * 1 0 4 (16) 0 (2) 32 + */ +static const struct sd_div_table cpg_sd_div_table[] = { +/* CPG_SD_DIV_TABLE_DATA(stp_hck, stp_ck, sd_srcfc, sd_fc, sd_div) */ + CPG_SD_DIV_TABLE_DATA(0, 0, 0, 1, 4), + CPG_SD_DIV_TABLE_DATA(0, 0, 1, 1, 8), + CPG_SD_DIV_TABLE_DATA(1, 0, 2, 1, 16), + CPG_SD_DIV_TABLE_DATA(1, 0, 3, 1, 32), + CPG_SD_DIV_TABLE_DATA(1, 0, 4, 1, 64), + CPG_SD_DIV_TABLE_DATA(0, 0, 0, 0, 2), + CPG_SD_DIV_TABLE_DATA(0, 0, 1, 0, 4), + CPG_SD_DIV_TABLE_DATA(1, 0, 2, 0, 8), + CPG_SD_DIV_TABLE_DATA(1, 0, 3, 0, 16), + CPG_SD_DIV_TABLE_DATA(1, 0, 4, 0, 32), +}; + +#define to_sd_clock(_hw) container_of(_hw, struct sd_clock, hw) + +static int cpg_sd_clock_enable(struct clk_hw *hw) +{ + struct sd_clock *clock = to_sd_clock(hw); + u32 val, sd_fc; + unsigned int i; + + val = clk_readl(clock->reg); + + sd_fc = val & CPG_SD_FC_MASK; + for (i = 0; i < clock->div_num; i++) + if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK)) + break; + + if (i >= clock->div_num) + return -EINVAL; + + val &= ~(CPG_SD_STP_MASK); + val |= clock->div_table[i].val & CPG_SD_STP_MASK; + + clk_writel(val, clock->reg); + + return 0; +} + +static void cpg_sd_clock_disable(struct clk_hw *hw) +{ + struct sd_clock *clock = to_sd_clock(hw); + + clk_writel(clk_readl(clock->reg) | CPG_SD_STP_MASK, clock->reg); +} + +static int cpg_sd_clock_is_enabled(struct clk_hw *hw) +{ + struct sd_clock *clock = to_sd_clock(hw); + + return !(clk_readl(clock->reg) & CPG_SD_STP_MASK); +} + +static unsigned long cpg_sd_clock_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct sd_clock *clock = to_sd_clock(hw); + unsigned long rate = parent_rate; + u32 val, sd_fc; + unsigned int i; + + val = clk_readl(clock->reg); + + sd_fc = val & CPG_SD_FC_MASK; + for (i = 0; i < clock->div_num; i++) + if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK)) + break; + + if (i >= clock->div_num) + return -EINVAL; + + return DIV_ROUND_CLOSEST(rate, clock->div_table[i].div); +} + +static unsigned int cpg_sd_clock_calc_div(struct sd_clock *clock, + unsigned long rate, + unsigned long parent_rate) +{ + unsigned int div; + + if (!rate) + rate = 1; + + div = DIV_ROUND_CLOSEST(parent_rate, rate); + + return clamp_t(unsigned int, div, clock->div_min, clock->div_max); +} + +static long cpg_sd_clock_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + struct sd_clock *clock = to_sd_clock(hw); + unsigned int div = cpg_sd_clock_calc_div(clock, rate, *parent_rate); + + return DIV_ROUND_CLOSEST(*parent_rate, div); +} + +static int cpg_sd_clock_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct sd_clock *clock = to_sd_clock(hw); + unsigned int div = cpg_sd_clock_calc_div(clock, rate, parent_rate); + u32 val; + unsigned int i; + + for (i = 0; i < clock->div_num; i++) + if (div == clock->div_table[i].div) + break; + + if (i >= clock->div_num) + return -EINVAL; + + val = clk_readl(clock->reg); + val &= ~(CPG_SD_STP_MASK | CPG_SD_FC_MASK); + val |= clock->div_table[i].val & (CPG_SD_STP_MASK | CPG_SD_FC_MASK); + clk_writel(val, clock->reg); + + return 0; +} + +static const struct clk_ops cpg_sd_clock_ops = { + .enable = cpg_sd_clock_enable, + .disable = cpg_sd_clock_disable, + .is_enabled = cpg_sd_clock_is_enabled, + .recalc_rate = cpg_sd_clock_recalc_rate, + .round_rate = cpg_sd_clock_round_rate, + .set_rate = cpg_sd_clock_set_rate, +}; + +static struct clk * __init cpg_sd_clk_register(const struct cpg_core_clk *core, + void __iomem *base, + const char *parent_name) +{ + struct clk_init_data init; + struct sd_clock *clock; + struct clk *clk; + unsigned int i; + + clock = kzalloc(sizeof(*clock), GFP_KERNEL); + if (!clock) + return ERR_PTR(-ENOMEM); + + init.name = core->name; + init.ops = &cpg_sd_clock_ops; + init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; + init.parent_names = &parent_name; + init.num_parents = 1; + + clock->reg = base + core->offset; + clock->hw.init = &init; + clock->div_table = cpg_sd_div_table; + clock->div_num = ARRAY_SIZE(cpg_sd_div_table); + + clock->div_max = clock->div_table[0].div; + clock->div_min = clock->div_max; + for (i = 1; i < clock->div_num; i++) { + clock->div_max = max(clock->div_max, clock->div_table[i].div); + clock->div_min = min(clock->div_min, clock->div_table[i].div); + } + + clk = clk_register(NULL, &clock->hw); + if (IS_ERR(clk)) + kfree(clock); + + return clk; +} #define CPG_PLL0CR 0x00d8 #define CPG_PLL2CR 0x002c @@ -323,6 +575,9 @@ struct clk * __init r8a7795_cpg_clk_register(struct device *dev, mult = (((value >> 24) & 0x7f) + 1) * 2; break; + case CLK_TYPE_GEN3_SD: + return cpg_sd_clk_register(core, base, __clk_get_name(parent)); + default: return ERR_PTR(-EINVAL); } diff --git a/drivers/clk/shmobile/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c similarity index 99% rename from drivers/clk/shmobile/renesas-cpg-mssr.c rename to drivers/clk/renesas/renesas-cpg-mssr.c index 9a4d888164bb3082870ea535aaf783675ae9df23..58e24b326a48bb810cfee9dfb519ea504409404d 100644 --- a/drivers/clk/shmobile/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -348,6 +348,7 @@ static void __init cpg_mssr_register_mod_clk(const struct mssr_mod_clk *mod, #else dev_dbg(dev, "Ignoring MSTP %s to prevent disabling\n", mod->name); + kfree(clock); return; #endif } @@ -568,7 +569,11 @@ static int __init cpg_mssr_probe(struct platform_device *pdev) if (error) return error; - devm_add_action(dev, cpg_mssr_del_clk_provider, np); + error = devm_add_action_or_reset(dev, + cpg_mssr_del_clk_provider, + np); + if (error) + return error; error = cpg_mssr_add_clk_domain(dev, info->core_pm_clks, info->num_core_pm_clks); diff --git a/drivers/clk/shmobile/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h similarity index 97% rename from drivers/clk/shmobile/renesas-cpg-mssr.h rename to drivers/clk/renesas/renesas-cpg-mssr.h index e09f03cbf086b1d3d3de0c2bda7de0164d6ae644..952b6957233b46be624afde93c8a37598dd3ea95 100644 --- a/drivers/clk/shmobile/renesas-cpg-mssr.h +++ b/drivers/clk/renesas/renesas-cpg-mssr.h @@ -53,6 +53,8 @@ enum clk_types { DEF_BASE(_name, _id, CLK_TYPE_FF, _parent, .div = _div, .mult = _mult) #define DEF_DIV6P1(_name, _id, _parent, _offset) \ DEF_BASE(_name, _id, CLK_TYPE_DIV6P1, _parent, .offset = _offset) +#define DEF_SD(_name, _id, _parent, _offset) \ + DEF_BASE(_name, _id, CLK_TYPE_GEN3_SD, _parent, .offset = _offset) /* diff --git a/drivers/clk/rockchip/clk-cpu.c b/drivers/clk/rockchip/clk-cpu.c index d07374f48caf7ee6d8c5b8f6ed82cca089e964d0..4e73ed5cab5801110574f9846015e073b321c01b 100644 --- a/drivers/clk/rockchip/clk-cpu.c +++ b/drivers/clk/rockchip/clk-cpu.c @@ -116,7 +116,7 @@ static void rockchip_cpuclk_set_dividers(struct rockchip_cpuclk *cpuclk, pr_debug("%s: setting reg 0x%x to 0x%x\n", __func__, clksel->reg, clksel->val); - writel(clksel->val , cpuclk->reg_base + clksel->reg); + writel(clksel->val, cpuclk->reg_base + clksel->reg); } } @@ -290,14 +290,14 @@ struct clk *rockchip_clk_register_cpuclk(const char *name, pr_err("%s: could not lookup parent clock %s\n", __func__, parent_names[0]); ret = -EINVAL; - goto free_cpuclk; + goto free_alt_parent; } ret = clk_notifier_register(clk, &cpuclk->clk_nb); if (ret) { pr_err("%s: failed to register clock notifier for %s\n", __func__, name); - goto free_cpuclk; + goto free_alt_parent; } if (nrates > 0) { @@ -326,6 +326,8 @@ struct clk *rockchip_clk_register_cpuclk(const char *name, kfree(cpuclk->rate_table); unregister_notifier: clk_notifier_unregister(clk, &cpuclk->clk_nb); +free_alt_parent: + clk_disable_unprepare(cpuclk->alt_parent); free_cpuclk: kfree(cpuclk); return ERR_PTR(ret); diff --git a/drivers/clk/rockchip/clk-inverter.c b/drivers/clk/rockchip/clk-inverter.c index 7cbf43beb3c68acf2d8e35dc6d6180bc63b7d8b2..dcb6e37f3da1e13d3d5f654d5283afbec78f0c48 100644 --- a/drivers/clk/rockchip/clk-inverter.c +++ b/drivers/clk/rockchip/clk-inverter.c @@ -90,7 +90,7 @@ struct clk *rockchip_clk_register_inverter(const char *name, inv_clock = kmalloc(sizeof(*inv_clock), GFP_KERNEL); if (!inv_clock) - return NULL; + return ERR_PTR(-ENOMEM); init.name = name; init.num_parents = num_parents; @@ -106,11 +106,7 @@ struct clk *rockchip_clk_register_inverter(const char *name, clk = clk_register(NULL, &inv_clock->hw); if (IS_ERR(clk)) - goto err_free; + kfree(inv_clock); return clk; - -err_free: - kfree(inv_clock); - return NULL; } diff --git a/drivers/clk/rockchip/clk-mmc-phase.c b/drivers/clk/rockchip/clk-mmc-phase.c index 2685644826a06ed5a6f21240ad8af040bf4b0b9e..e0dc7e83403a90118a47102577962c55e88fa614 100644 --- a/drivers/clk/rockchip/clk-mmc-phase.c +++ b/drivers/clk/rockchip/clk-mmc-phase.c @@ -150,7 +150,7 @@ struct clk *rockchip_clk_register_mmc(const char *name, mmc_clock = kmalloc(sizeof(*mmc_clock), GFP_KERNEL); if (!mmc_clock) - return NULL; + return ERR_PTR(-ENOMEM); init.name = name; init.num_parents = num_parents; @@ -172,11 +172,7 @@ struct clk *rockchip_clk_register_mmc(const char *name, clk = clk_register(NULL, &mmc_clock->hw); if (IS_ERR(clk)) - goto err_free; + kfree(mmc_clock); return clk; - -err_free: - kfree(mmc_clock); - return NULL; } diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c index b7e66c9dd9f2ebb84ccbfd6aac582e648c461baa..5de797e34d545881f87346f242acb71cb5769c23 100644 --- a/drivers/clk/rockchip/clk-pll.c +++ b/drivers/clk/rockchip/clk-pll.c @@ -94,6 +94,11 @@ static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll) unsigned int val; int delay = 24000000, ret; + if (IS_ERR(grf)) { + pr_err("%s: grf regmap not available\n", __func__); + return PTR_ERR(grf); + } + while (delay > 0) { ret = regmap_read(grf, pll->lock_offset, &val); if (ret) { diff --git a/drivers/clk/rockchip/clk-rk3036.c b/drivers/clk/rockchip/clk-rk3036.c index bc7fbac83ab74dfca9e534401bc430f629d01357..7cdb2d61f3e0666075ac25d6eb83b7fba88e872d 100644 --- a/drivers/clk/rockchip/clk-rk3036.c +++ b/drivers/clk/rockchip/clk-rk3036.c @@ -177,6 +177,8 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { GATE(0, "gpll_armclk", "gpll", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(0), 6, GFLAGS), + FACTOR(0, "xin12m", "xin24m", 0, 1, 2), + /* * Clock-Architecture Diagram 2 */ @@ -187,6 +189,7 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { RK2928_CLKGATE_CON(0), 8, GFLAGS), COMPOSITE_NOGATE(0, "ddrphy2x", mux_ddrphy_p, CLK_IGNORE_UNUSED, RK2928_CLKSEL_CON(26), 8, 1, MFLAGS, 0, 2, DFLAGS | CLK_DIVIDER_POWER_OF_TWO), + FACTOR(0, "ddrphy", "ddrphy2x", 0, 1, 2), COMPOSITE_NOMUX(0, "pclk_dbg", "armclk", CLK_IGNORE_UNUSED, RK2928_CLKSEL_CON(1), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, @@ -263,6 +266,8 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { COMPOSITE(0, "aclk_vcodec", mux_pll_src_3plls_p, 0, RK2928_CLKSEL_CON(32), 14, 2, MFLAGS, 8, 5, DFLAGS, RK2928_CLKGATE_CON(3), 11, GFLAGS), + FACTOR_GATE(HCLK_VCODEC, "hclk_vcodec", "aclk_vcodec", 0, 1, 4, + RK2928_CLKGATE_CON(3), 12, GFLAGS), COMPOSITE(0, "aclk_hvec", mux_pll_src_3plls_p, 0, RK2928_CLKSEL_CON(20), 0, 2, MFLAGS, 2, 5, DFLAGS, @@ -343,7 +348,7 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { RK2928_CLKSEL_CON(16), 0, 2, MFLAGS, 2, 5, DFLAGS, RK2928_CLKGATE_CON(10), 5, GFLAGS), - COMPOSITE_NOGATE(0, "mac_pll_src", mux_pll_src_3plls_p, 0, + COMPOSITE_NOGATE(SCLK_MACPLL, "mac_pll_src", mux_pll_src_3plls_p, CLK_SET_RATE_NO_REPARENT, RK2928_CLKSEL_CON(21), 0, 2, MFLAGS, 9, 5, DFLAGS), MUX(SCLK_MACREF, "mac_clk_ref", mux_mac_p, CLK_SET_RATE_PARENT, RK2928_CLKSEL_CON(21), 3, 1, MFLAGS), @@ -351,6 +356,7 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { COMPOSITE_NOMUX(SCLK_MAC, "mac_clk", "mac_clk_ref", 0, RK2928_CLKSEL_CON(21), 4, 5, DFLAGS, RK2928_CLKGATE_CON(2), 6, GFLAGS), + FACTOR(0, "sclk_macref_out", "hclk_peri_src", 0, 1, 2), MUX(SCLK_HDMI, "dclk_hdmi", mux_dclk_p, 0, RK2928_CLKSEL_CON(31), 0, 1, MFLAGS), @@ -376,11 +382,9 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { GATE(ACLK_VIO, "aclk_vio", "aclk_disp1_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(6), 13, GFLAGS), GATE(ACLK_LCDC, "aclk_lcdc", "aclk_disp1_pre", 0, RK2928_CLKGATE_CON(9), 6, GFLAGS), - GATE(HCLK_VIO_BUS, "hclk_vio_bus", "hclk_disp_pre", 0, RK2928_CLKGATE_CON(6), 12, GFLAGS), + GATE(HCLK_VIO_BUS, "hclk_vio_bus", "hclk_disp_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(6), 12, GFLAGS), GATE(HCLK_LCDC, "hclk_lcdc", "hclk_disp_pre", 0, RK2928_CLKGATE_CON(9), 5, GFLAGS), - /* hclk_video gates */ - GATE(HCLK_VCODEC, "hclk_vcodec", "hclk_disp_pre", 0, RK2928_CLKGATE_CON(3), 12, GFLAGS), /* xin24m gates */ GATE(SCLK_PVTM_CORE, "sclk_pvtm_core", "xin24m", 0, RK2928_CLKGATE_CON(10), 0, GFLAGS), @@ -404,7 +408,7 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { GATE(HCLK_OTG1, "hclk_otg1", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(7), 3, GFLAGS), GATE(HCLK_I2S, "hclk_i2s", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 2, GFLAGS), GATE(0, "hclk_sfc", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(3), 14, GFLAGS), - GATE(0, "hclk_mac", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(3), 15, GFLAGS), + GATE(HCLK_MAC, "hclk_mac", "hclk_peri", 0, RK2928_CLKGATE_CON(3), 5, GFLAGS), /* pclk_peri gates */ GATE(0, "pclk_peri_matrix", "pclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 1, GFLAGS), @@ -444,34 +448,11 @@ static void __init rk3036_clk_init(struct device_node *np) rockchip_clk_init(np, reg_base, CLK_NR_CLKS); - /* xin12m is created by an cru-internal divider */ - clk = clk_register_fixed_factor(NULL, "xin12m", "xin24m", 0, 1, 2); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock xin12m: %ld\n", - __func__, PTR_ERR(clk)); - clk = clk_register_fixed_factor(NULL, "usb480m", "xin24m", 0, 20, 1); if (IS_ERR(clk)) pr_warn("%s: could not register clock usb480m: %ld\n", __func__, PTR_ERR(clk)); - clk = clk_register_fixed_factor(NULL, "ddrphy", "ddrphy2x", 0, 1, 2); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock ddrphy: %ld\n", - __func__, PTR_ERR(clk)); - - clk = clk_register_fixed_factor(NULL, "hclk_vcodec_pre", - "aclk_vcodec", 0, 1, 4); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock hclk_vcodec_pre: %ld\n", - __func__, PTR_ERR(clk)); - - clk = clk_register_fixed_factor(NULL, "sclk_macref_out", - "hclk_peri_src", 0, 1, 2); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock sclk_macref_out: %ld\n", - __func__, PTR_ERR(clk)); - rockchip_clk_register_plls(rk3036_pll_clks, ARRAY_SIZE(rk3036_pll_clks), RK3036_GRF_SOC_STATUS0); diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c index 7f7444cbf6fcc0e62ae85c195792edc10daca2f3..40bab39014915087e691257caf0b063b72fd04bf 100644 --- a/drivers/clk/rockchip/clk-rk3188.c +++ b/drivers/clk/rockchip/clk-rk3188.c @@ -339,13 +339,15 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { INVERTER(0, "pclk_cif0", "pclkin_cif0", RK2928_CLKSEL_CON(30), 8, IFLAGS), + FACTOR(0, "xin12m", "xin24m", 0, 1, 2), + /* * the 480m are generated inside the usb block from these clocks, * but they are also a source for the hsicphy clock. */ - GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", CLK_IGNORE_UNUSED, + GATE(SCLK_OTGPHY0, "sclk_otgphy0", "xin24m", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(1), 5, GFLAGS), - GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", CLK_IGNORE_UNUSED, + GATE(SCLK_OTGPHY1, "sclk_otgphy1", "xin24m", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(1), 6, GFLAGS), COMPOSITE(0, "mac_src", mux_mac_p, 0, @@ -605,7 +607,7 @@ static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = { GATE(SCLK_TIMER2, "timer2", "xin24m", 0, RK2928_CLKGATE_CON(3), 2, GFLAGS), - COMPOSITE_NOMUX(0, "sclk_tsadc", "xin24m", 0, + COMPOSITE_NOMUX(SCLK_TSADC, "sclk_tsadc", "xin24m", 0, RK2928_CLKSEL_CON(34), 0, 16, DFLAGS, RK2928_CLKGATE_CON(2), 15, GFLAGS), @@ -662,11 +664,11 @@ static struct clk_div_table div_rk3188_aclk_core_t[] = { { /* sentinel */ }, }; -PNAME(mux_hsicphy_p) = { "sclk_otgphy0", "sclk_otgphy1", +PNAME(mux_hsicphy_p) = { "sclk_otgphy0_480m", "sclk_otgphy1_480m", "gpll", "cpll" }; static struct rockchip_clk_branch rk3188_i2s0_fracmux __initdata = - MUX(SCLK_I2S0, "sclk_i2s0", mux_sclk_i2s0_p, 0, + MUX(SCLK_I2S0, "sclk_i2s0", mux_sclk_i2s0_p, CLK_SET_RATE_PARENT, RK2928_CLKSEL_CON(3), 8, 2, MFLAGS); static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = { @@ -722,7 +724,7 @@ static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = { COMPOSITE_NOMUX(0, "i2s0_pre", "i2s_src", 0, RK2928_CLKSEL_CON(3), 0, 7, DFLAGS, RK2928_CLKGATE_CON(0), 9, GFLAGS), - COMPOSITE_FRACMUX(0, "i2s0_frac", "i2s0_pre", 0, + COMPOSITE_FRACMUX(0, "i2s0_frac", "i2s0_pre", CLK_SET_RATE_PARENT, RK2928_CLKSEL_CON(7), 0, RK2928_CLKGATE_CON(0), 10, GFLAGS, &rk3188_i2s0_fracmux), @@ -748,12 +750,12 @@ static const char *const rk3188_critical_clocks[] __initconst = { "hclk_peri", "pclk_cpu", "pclk_peri", + "hclk_cpubus" }; static void __init rk3188_common_clk_init(struct device_node *np) { void __iomem *reg_base; - struct clk *clk; reg_base = of_iomap(np, 0); if (!reg_base) { @@ -763,17 +765,6 @@ static void __init rk3188_common_clk_init(struct device_node *np) rockchip_clk_init(np, reg_base, CLK_NR_CLKS); - /* xin12m is created by an cru-internal divider */ - clk = clk_register_fixed_factor(NULL, "xin12m", "xin24m", 0, 1, 2); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock xin12m: %ld\n", - __func__, PTR_ERR(clk)); - - clk = clk_register_fixed_factor(NULL, "usb480m", "xin24m", 0, 20, 1); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock usb480m: %ld\n", - __func__, PTR_ERR(clk)); - rockchip_clk_register_branches(common_clk_branches, ARRAY_SIZE(common_clk_branches)); diff --git a/drivers/clk/rockchip/clk-rk3228.c b/drivers/clk/rockchip/clk-rk3228.c index 981a50205339609617c271556c9d3227c0b3bd2c..7702d2855e9cf476bd0b2672679aa73057729fd9 100644 --- a/drivers/clk/rockchip/clk-rk3228.c +++ b/drivers/clk/rockchip/clk-rk3228.c @@ -187,7 +187,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { RK2928_CLKGATE_CON(7), 1, GFLAGS), GATE(0, "ddrc", "ddrphy_pre", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(8), 5, GFLAGS), - GATE(0, "ddrphy", "ddrphy_pre", CLK_IGNORE_UNUSED, + FACTOR_GATE(0, "ddrphy", "ddrphy4x", CLK_IGNORE_UNUSED, 1, 4, RK2928_CLKGATE_CON(7), 0, GFLAGS), /* PD_CORE */ @@ -240,13 +240,13 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { COMPOSITE(0, "aclk_vpu_pre", mux_pll_src_4plls_p, 0, RK2928_CLKSEL_CON(32), 5, 2, MFLAGS, 0, 5, DFLAGS, RK2928_CLKGATE_CON(3), 11, GFLAGS), - GATE(0, "hclk_vpu_src", "aclk_vpu_pre", 0, + FACTOR_GATE(0, "hclk_vpu_pre", "aclk_vpu_pre", 0, 1, 4, RK2928_CLKGATE_CON(4), 4, GFLAGS), COMPOSITE(0, "aclk_rkvdec_pre", mux_pll_src_4plls_p, 0, RK2928_CLKSEL_CON(28), 6, 2, MFLAGS, 0, 5, DFLAGS, RK2928_CLKGATE_CON(3), 2, GFLAGS), - GATE(0, "hclk_rkvdec_src", "aclk_rkvdec_pre", 0, + FACTOR_GATE(0, "hclk_rkvdec_pre", "aclk_rkvdec_pre", 0, 1, 4, RK2928_CLKGATE_CON(4), 5, GFLAGS), COMPOSITE(0, "sclk_vdec_cabac", mux_pll_src_4plls_p, 0, @@ -285,7 +285,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { RK2928_CLKSEL_CON(23), 14, 2, MFLAGS, 8, 6, DFLAGS, RK2928_CLKGATE_CON(3), 5, GFLAGS), - GATE(0, "sclk_hdmi_hdcp", "xin24m", 0, + GATE(SCLK_HDMI_HDCP, "sclk_hdmi_hdcp", "xin24m", 0, RK2928_CLKGATE_CON(3), 7, GFLAGS), COMPOSITE(0, "sclk_hdmi_cec", mux_sclk_hdmi_cec_p, 0, @@ -364,13 +364,15 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { RK2928_CLKGATE_CON(3), 1, GFLAGS), MUX(0, "sclk_vop_src", mux_sclk_vop_src_p, 0, RK2928_CLKSEL_CON(27), 0, 1, MFLAGS), - DIV(0, "dclk_hdmiphy", "sclk_vop_src", 0, + DIV(DCLK_HDMI_PHY, "dclk_hdmiphy", "sclk_vop_src", 0, RK2928_CLKSEL_CON(29), 0, 3, DFLAGS), DIV(0, "sclk_vop_pre", "sclk_vop_src", 0, RK2928_CLKSEL_CON(27), 8, 8, DFLAGS), - MUX(0, "dclk_vop", mux_dclk_vop_p, 0, + MUX(DCLK_VOP, "dclk_vop", mux_dclk_vop_p, 0, RK2928_CLKSEL_CON(27), 1, 1, MFLAGS), + FACTOR(0, "xin12m", "xin24m", 0, 1, 2), + COMPOSITE(0, "i2s0_src", mux_pll_src_2plls_p, 0, RK2928_CLKSEL_CON(9), 15, 1, MFLAGS, 0, 7, DFLAGS, RK2928_CLKGATE_CON(0), 3, GFLAGS), @@ -422,7 +424,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { GATE(0, "sclk_otgphy1", "xin24m", 0, RK2928_CLKGATE_CON(1), 6, GFLAGS), - COMPOSITE_NOMUX(0, "sclk_tsadc", "xin24m", 0, + COMPOSITE_NOMUX(SCLK_TSADC, "sclk_tsadc", "xin24m", 0, RK2928_CLKSEL_CON(24), 6, 10, DFLAGS, RK2928_CLKGATE_CON(2), 8, GFLAGS), @@ -503,7 +505,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { GATE(0, "aclk_iep", "aclk_iep_pre", 0, RK2928_CLKGATE_CON(13), 2, GFLAGS), GATE(0, "aclk_iep_noc", "aclk_iep_pre", 0, RK2928_CLKGATE_CON(13), 9, GFLAGS), - GATE(0, "aclk_vop", "aclk_vop_pre", 0, RK2928_CLKGATE_CON(13), 5, GFLAGS), + GATE(ACLK_VOP, "aclk_vop", "aclk_vop_pre", 0, RK2928_CLKGATE_CON(13), 5, GFLAGS), GATE(0, "aclk_vop_noc", "aclk_vop_pre", 0, RK2928_CLKGATE_CON(13), 12, GFLAGS), GATE(0, "aclk_hdcp", "aclk_hdcp_pre", 0, RK2928_CLKGATE_CON(14), 10, GFLAGS), @@ -511,13 +513,13 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { GATE(0, "hclk_rga", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 1, GFLAGS), GATE(0, "hclk_iep", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 3, GFLAGS), - GATE(0, "hclk_vop", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 6, GFLAGS), + GATE(HCLK_VOP, "hclk_vop", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 6, GFLAGS), GATE(0, "hclk_vio_ahb_arbi", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 7, GFLAGS), GATE(0, "hclk_vio_noc", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 8, GFLAGS), GATE(0, "hclk_vop_noc", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(13), 13, GFLAGS), GATE(0, "hclk_vio_h2p", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 7, GFLAGS), GATE(0, "hclk_hdcp_mmu", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 12, GFLAGS), - GATE(0, "pclk_hdmi_ctrl", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 6, GFLAGS), + GATE(PCLK_HDMI_CTRL, "pclk_hdmi_ctrl", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 6, GFLAGS), GATE(0, "pclk_vio_h2p", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 8, GFLAGS), GATE(0, "pclk_hdcp", "hclk_vio_pre", 0, RK2928_CLKGATE_CON(14), 11, GFLAGS), @@ -582,7 +584,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { GATE(PCLK_UART0, "pclk_uart0", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 12, GFLAGS), GATE(PCLK_UART1, "pclk_uart1", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 13, GFLAGS), GATE(PCLK_UART2, "pclk_uart2", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 14, GFLAGS), - GATE(0, "pclk_tsadc", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 15, GFLAGS), + GATE(PCLK_TSADC, "pclk_tsadc", "pclk_cpu", 0, RK2928_CLKGATE_CON(9), 15, GFLAGS), GATE(PCLK_GRF, "pclk_grf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(10), 0, GFLAGS), GATE(0, "pclk_cru", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(10), 1, GFLAGS), GATE(0, "pclk_sgrf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(10), 2, GFLAGS), @@ -590,7 +592,7 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { GATE(0, "pclk_ddrphy", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 3, GFLAGS), GATE(0, "pclk_acodecphy", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 5, GFLAGS), - GATE(0, "pclk_hdmiphy", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 7, GFLAGS), + GATE(PCLK_HDMI_PHY, "pclk_hdmiphy", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 7, GFLAGS), GATE(0, "pclk_vdacphy", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 8, GFLAGS), GATE(0, "pclk_phy_noc", "pclk_phy_pre", 0, RK2928_CLKGATE_CON(10), 9, GFLAGS), @@ -605,13 +607,13 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { /* PD_MMC */ MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "sclk_sdmmc", RK3228_SDMMC_CON0, 1), - MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "sclk_sdmmc", RK3228_SDMMC_CON1, 1), + MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "sclk_sdmmc", RK3228_SDMMC_CON1, 0), MMC(SCLK_SDIO_DRV, "sdio_drv", "sclk_sdio", RK3228_SDIO_CON0, 1), - MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "sclk_sdio", RK3228_SDIO_CON1, 1), + MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "sclk_sdio", RK3228_SDIO_CON1, 0), MMC(SCLK_EMMC_DRV, "emmc_drv", "sclk_emmc", RK3228_EMMC_CON0, 1), - MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "sclk_emmc", RK3228_EMMC_CON1, 1), + MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "sclk_emmc", RK3228_EMMC_CON1, 0), }; static const char *const rk3228_critical_clocks[] __initconst = { @@ -624,7 +626,6 @@ static const char *const rk3228_critical_clocks[] __initconst = { static void __init rk3228_clk_init(struct device_node *np) { void __iomem *reg_base; - struct clk *clk; reg_base = of_iomap(np, 0); if (!reg_base) { @@ -634,29 +635,6 @@ static void __init rk3228_clk_init(struct device_node *np) rockchip_clk_init(np, reg_base, CLK_NR_CLKS); - /* xin12m is created by an cru-internal divider */ - clk = clk_register_fixed_factor(NULL, "xin12m", "xin24m", 0, 1, 2); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock xin12m: %ld\n", - __func__, PTR_ERR(clk)); - - clk = clk_register_fixed_factor(NULL, "ddrphy_pre", "ddrphy4x", 0, 1, 4); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock ddrphy_pre: %ld\n", - __func__, PTR_ERR(clk)); - - clk = clk_register_fixed_factor(NULL, "hclk_vpu_pre", - "hclk_vpu_src", 0, 1, 4); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock hclk_vpu_pre: %ld\n", - __func__, PTR_ERR(clk)); - - clk = clk_register_fixed_factor(NULL, "hclk_rkvdec_pre", - "hclk_rkvdec_src", 0, 1, 4); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock hclk_rkvdec_pre: %ld\n", - __func__, PTR_ERR(clk)); - rockchip_clk_register_plls(rk3228_pll_clks, ARRAY_SIZE(rk3228_pll_clks), RK3228_GRF_SOC_STATUS0); diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index 984fc187d12ecf6e80d23bb52d2868c75c0daeca..3cb72163a5122ba9ef7695f0c5ba5d679afa9bd7 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -195,8 +195,8 @@ PNAME(mux_hsadcout_p) = { "hsadc_src", "ext_hsadc" }; PNAME(mux_edp_24m_p) = { "ext_edp_24m", "xin24m" }; PNAME(mux_tspout_p) = { "cpll", "gpll", "npll", "xin27m" }; -PNAME(mux_usbphy480m_p) = { "sclk_otgphy1", "sclk_otgphy2", - "sclk_otgphy0" }; +PNAME(mux_usbphy480m_p) = { "sclk_otgphy1_480m", "sclk_otgphy2_480m", + "sclk_otgphy0_480m" }; PNAME(mux_hsicphy480m_p) = { "cpll", "gpll", "usbphy480m_src" }; PNAME(mux_hsicphy12m_p) = { "hsicphy12m_xin12m", "hsicphy12m_usbphy" }; @@ -333,6 +333,8 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { GATE(0, "aclk_bus_2pmu", "aclk_cpu_pre", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(0), 7, GFLAGS), + FACTOR(0, "xin12m", "xin24m", 0, 1, 2), + COMPOSITE(0, "i2s_src", mux_pll_src_cpll_gpll_p, 0, RK3288_CLKSEL_CON(4), 15, 1, MFLAGS, 0, 7, DFLAGS, RK3288_CLKGATE_CON(4), 1, GFLAGS), @@ -399,12 +401,10 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { */ GATE(ACLK_VCODEC, "aclk_vcodec", "aclk_vdpu", 0, RK3288_CLKGATE_CON(9), 0, GFLAGS), - /* - * We introduce a virtul node of hclk_vodec_pre_v to split one clock - * struct with a gate and a fix divider into two node in software. - */ - GATE(0, "hclk_vcodec_pre_v", "aclk_vdpu", 0, + + FACTOR_GATE(0, "hclk_vcodec_pre", "aclk_vdpu", 0, 1, 4, RK3288_CLKGATE_CON(3), 10, GFLAGS), + GATE(HCLK_VCODEC, "hclk_vcodec", "hclk_vcodec_pre", 0, RK3288_CLKGATE_CON(9), 1, GFLAGS), @@ -537,11 +537,11 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { RK3288_CLKSEL_CON(35), 6, 2, MFLAGS, 0, 5, DFLAGS, RK3288_CLKGATE_CON(4), 10, GFLAGS), - GATE(SCLK_OTGPHY0, "sclk_otgphy0", "usb480m", CLK_IGNORE_UNUSED, + GATE(SCLK_OTGPHY0, "sclk_otgphy0", "xin24m", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(13), 4, GFLAGS), - GATE(SCLK_OTGPHY1, "sclk_otgphy1", "usb480m", CLK_IGNORE_UNUSED, + GATE(SCLK_OTGPHY1, "sclk_otgphy1", "xin24m", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(13), 5, GFLAGS), - GATE(SCLK_OTGPHY2, "sclk_otgphy2", "usb480m", CLK_IGNORE_UNUSED, + GATE(SCLK_OTGPHY2, "sclk_otgphy2", "xin24m", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(13), 6, GFLAGS), GATE(SCLK_OTG_ADP, "sclk_otg_adp", "xin32k", CLK_IGNORE_UNUSED, RK3288_CLKGATE_CON(13), 7, GFLAGS), @@ -888,24 +888,6 @@ static void __init rk3288_clk_init(struct device_node *np) rockchip_clk_init(np, rk3288_cru_base, CLK_NR_CLKS); - /* xin12m is created by an cru-internal divider */ - clk = clk_register_fixed_factor(NULL, "xin12m", "xin24m", 0, 1, 2); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock xin12m: %ld\n", - __func__, PTR_ERR(clk)); - - - clk = clk_register_fixed_factor(NULL, "usb480m", "xin24m", 0, 20, 1); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock usb480m: %ld\n", - __func__, PTR_ERR(clk)); - - clk = clk_register_fixed_factor(NULL, "hclk_vcodec_pre", - "hclk_vcodec_pre_v", 0, 1, 4); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock hclk_vcodec_pre: %ld\n", - __func__, PTR_ERR(clk)); - /* Watchdog pclk is controlled by RK3288_SGRF_SOC_CON0[1]. */ clk = clk_register_fixed_factor(NULL, "pclk_wdt", "pclk_pd_alive", 0, 1, 1); if (IS_ERR(clk)) diff --git a/drivers/clk/rockchip/clk-rk3368.c b/drivers/clk/rockchip/clk-rk3368.c index 21f3ea909fabdb7c4f753cd4ed817035c15a31e0..a2bb12200465cf34483eeaa0045b517e63747d17 100644 --- a/drivers/clk/rockchip/clk-rk3368.c +++ b/drivers/clk/rockchip/clk-rk3368.c @@ -121,7 +121,7 @@ PNAME(mux_i2s_2ch_p) = { "i2s_2ch_src", "i2s_2ch_frac", "dummy", "xin12m" }; PNAME(mux_spdif_8ch_p) = { "spdif_8ch_pre", "spdif_8ch_frac", "ext_i2s", "xin12m" }; -PNAME(mux_edp_24m_p) = { "dummy", "xin24m" }; +PNAME(mux_edp_24m_p) = { "xin24m", "dummy" }; PNAME(mux_vip_out_p) = { "vip_src", "xin24m" }; PNAME(mux_usbphy480m_p) = { "usbotg_out", "xin24m" }; PNAME(mux_hsic_usbphy480m_p) = { "usbotg_out", "dummy" }; @@ -165,7 +165,7 @@ static const struct rockchip_cpuclk_reg_data rk3368_cpuclkb_data = { .core_reg = RK3368_CLKSEL_CON(0), .div_core_shift = 0, .div_core_mask = 0x1f, - .mux_core_shift = 15, + .mux_core_shift = 7, }; static const struct rockchip_cpuclk_reg_data rk3368_cpuclkl_data = { @@ -218,36 +218,66 @@ static const struct rockchip_cpuclk_reg_data rk3368_cpuclkl_data = { } static struct rockchip_cpuclk_rate_table rk3368_cpuclkb_rates[] __initdata = { - RK3368_CPUCLKB_RATE(1512000000, 2, 6, 6), - RK3368_CPUCLKB_RATE(1488000000, 2, 5, 5), - RK3368_CPUCLKB_RATE(1416000000, 2, 5, 5), - RK3368_CPUCLKB_RATE(1200000000, 2, 4, 4), - RK3368_CPUCLKB_RATE(1008000000, 2, 4, 4), - RK3368_CPUCLKB_RATE( 816000000, 2, 3, 3), - RK3368_CPUCLKB_RATE( 696000000, 2, 3, 3), - RK3368_CPUCLKB_RATE( 600000000, 2, 2, 2), - RK3368_CPUCLKB_RATE( 408000000, 2, 2, 2), - RK3368_CPUCLKB_RATE( 312000000, 2, 2, 2), + RK3368_CPUCLKB_RATE(1512000000, 1, 5, 5), + RK3368_CPUCLKB_RATE(1488000000, 1, 4, 4), + RK3368_CPUCLKB_RATE(1416000000, 1, 4, 4), + RK3368_CPUCLKB_RATE(1200000000, 1, 3, 3), + RK3368_CPUCLKB_RATE(1008000000, 1, 3, 3), + RK3368_CPUCLKB_RATE( 816000000, 1, 2, 2), + RK3368_CPUCLKB_RATE( 696000000, 1, 2, 2), + RK3368_CPUCLKB_RATE( 600000000, 1, 1, 1), + RK3368_CPUCLKB_RATE( 408000000, 1, 1, 1), + RK3368_CPUCLKB_RATE( 312000000, 1, 1, 1), }; static struct rockchip_cpuclk_rate_table rk3368_cpuclkl_rates[] __initdata = { - RK3368_CPUCLKL_RATE(1512000000, 2, 7, 7), - RK3368_CPUCLKL_RATE(1488000000, 2, 6, 6), - RK3368_CPUCLKL_RATE(1416000000, 2, 6, 6), - RK3368_CPUCLKL_RATE(1200000000, 2, 5, 5), - RK3368_CPUCLKL_RATE(1008000000, 2, 5, 5), - RK3368_CPUCLKL_RATE( 816000000, 2, 4, 4), - RK3368_CPUCLKL_RATE( 696000000, 2, 3, 3), - RK3368_CPUCLKL_RATE( 600000000, 2, 3, 3), - RK3368_CPUCLKL_RATE( 408000000, 2, 2, 2), - RK3368_CPUCLKL_RATE( 312000000, 2, 2, 2), + RK3368_CPUCLKL_RATE(1512000000, 1, 6, 6), + RK3368_CPUCLKL_RATE(1488000000, 1, 5, 5), + RK3368_CPUCLKL_RATE(1416000000, 1, 5, 5), + RK3368_CPUCLKL_RATE(1200000000, 1, 4, 4), + RK3368_CPUCLKL_RATE(1008000000, 1, 4, 4), + RK3368_CPUCLKL_RATE( 816000000, 1, 3, 3), + RK3368_CPUCLKL_RATE( 696000000, 1, 2, 2), + RK3368_CPUCLKL_RATE( 600000000, 1, 2, 2), + RK3368_CPUCLKL_RATE( 408000000, 1, 1, 1), + RK3368_CPUCLKL_RATE( 312000000, 1, 1, 1), }; +static struct rockchip_clk_branch rk3368_i2s_8ch_fracmux __initdata = + MUX(0, "i2s_8ch_pre", mux_i2s_8ch_pre_p, CLK_SET_RATE_PARENT, + RK3368_CLKSEL_CON(27), 8, 2, MFLAGS); + +static struct rockchip_clk_branch rk3368_spdif_8ch_fracmux __initdata = + MUX(0, "spdif_8ch_pre", mux_spdif_8ch_p, CLK_SET_RATE_PARENT, + RK3368_CLKSEL_CON(31), 8, 2, MFLAGS); + +static struct rockchip_clk_branch rk3368_i2s_2ch_fracmux __initdata = + MUX(0, "i2s_2ch_pre", mux_i2s_2ch_p, CLK_SET_RATE_PARENT, + RK3368_CLKSEL_CON(53), 8, 2, MFLAGS); + +static struct rockchip_clk_branch rk3368_uart0_fracmux __initdata = + MUX(SCLK_UART0, "sclk_uart0", mux_uart0_p, CLK_SET_RATE_PARENT, + RK3368_CLKSEL_CON(33), 8, 2, MFLAGS); + +static struct rockchip_clk_branch rk3368_uart1_fracmux __initdata = + MUX(SCLK_UART1, "sclk_uart1", mux_uart1_p, CLK_SET_RATE_PARENT, + RK3368_CLKSEL_CON(35), 8, 2, MFLAGS); + +static struct rockchip_clk_branch rk3368_uart3_fracmux __initdata = + MUX(SCLK_UART3, "sclk_uart3", mux_uart3_p, CLK_SET_RATE_PARENT, + RK3368_CLKSEL_CON(39), 8, 2, MFLAGS); + +static struct rockchip_clk_branch rk3368_uart4_fracmux __initdata = + MUX(SCLK_UART4, "sclk_uart4", mux_uart4_p, CLK_SET_RATE_PARENT, + RK3368_CLKSEL_CON(41), 8, 2, MFLAGS); + static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { /* * Clock-Architecture Diagram 2 */ + FACTOR(0, "xin12m", "xin24m", 0, 1, 2), + MUX(SCLK_USBPHY480M, "usbphy_480m", mux_usbphy480m_p, CLK_SET_RATE_PARENT, RK3368_CLKSEL_CON(13), 8, 1, MFLAGS), @@ -299,7 +329,7 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { COMPOSITE_NOGATE_DIVTBL(0, "ddrphy_src", mux_ddrphy_p, CLK_IGNORE_UNUSED, RK3368_CLKSEL_CON(13), 4, 1, MFLAGS, 0, 2, DFLAGS, div_ddrphy_t), - GATE(0, "sclk_ddr", "ddrphy_div4", CLK_IGNORE_UNUSED, + FACTOR_GATE(0, "sclk_ddr", "ddrphy_src", CLK_IGNORE_UNUSED, 1, 4, RK3368_CLKGATE_CON(6), 14, GFLAGS), GATE(0, "sclk_ddr4x", "ddrphy_src", CLK_IGNORE_UNUSED, RK3368_CLKGATE_CON(6), 15, GFLAGS), @@ -337,11 +367,10 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { COMPOSITE(0, "i2s_8ch_src", mux_pll_src_cpll_gpll_p, 0, RK3368_CLKSEL_CON(27), 12, 1, MFLAGS, 0, 7, DFLAGS, RK3368_CLKGATE_CON(6), 1, GFLAGS), - COMPOSITE_FRAC(0, "i2s_8ch_frac", "i2s_8ch_src", CLK_SET_RATE_PARENT, - RK3368_CLKSEL_CON(28), 0, - RK3368_CLKGATE_CON(6), 2, GFLAGS), - MUX(0, "i2s_8ch_pre", mux_i2s_8ch_pre_p, CLK_SET_RATE_PARENT, - RK3368_CLKSEL_CON(27), 8, 2, MFLAGS), + COMPOSITE_FRACMUX(0, "i2s_8ch_frac", "i2s_8ch_src", CLK_SET_RATE_PARENT, + RK3368_CLKSEL_CON(28), 0, + RK3368_CLKGATE_CON(6), 2, GFLAGS, + &rk3368_i2s_8ch_fracmux), COMPOSITE_NODIV(SCLK_I2S_8CH_OUT, "i2s_8ch_clkout", mux_i2s_8ch_clkout_p, 0, RK3368_CLKSEL_CON(27), 15, 1, MFLAGS, RK3368_CLKGATE_CON(6), 0, GFLAGS), @@ -350,21 +379,21 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { COMPOSITE(0, "spdif_8ch_src", mux_pll_src_cpll_gpll_p, 0, RK3368_CLKSEL_CON(31), 12, 1, MFLAGS, 0, 7, DFLAGS, RK3368_CLKGATE_CON(6), 4, GFLAGS), - COMPOSITE_FRAC(0, "spdif_8ch_frac", "spdif_8ch_src", CLK_SET_RATE_PARENT, - RK3368_CLKSEL_CON(32), 0, - RK3368_CLKGATE_CON(6), 5, GFLAGS), - COMPOSITE_NODIV(SCLK_SPDIF_8CH, "sclk_spdif_8ch", mux_spdif_8ch_p, 0, - RK3368_CLKSEL_CON(31), 8, 2, MFLAGS, - RK3368_CLKGATE_CON(6), 6, GFLAGS), + COMPOSITE_FRACMUX(0, "spdif_8ch_frac", "spdif_8ch_src", CLK_SET_RATE_PARENT, + RK3368_CLKSEL_CON(32), 0, + RK3368_CLKGATE_CON(6), 5, GFLAGS, + &rk3368_spdif_8ch_fracmux), + GATE(SCLK_SPDIF_8CH, "sclk_spdif_8ch", "spdif_8ch_pre", CLK_SET_RATE_PARENT, + RK3368_CLKGATE_CON(6), 6, GFLAGS), COMPOSITE(0, "i2s_2ch_src", mux_pll_src_cpll_gpll_p, 0, RK3368_CLKSEL_CON(53), 12, 1, MFLAGS, 0, 7, DFLAGS, RK3368_CLKGATE_CON(5), 13, GFLAGS), - COMPOSITE_FRAC(0, "i2s_2ch_frac", "i2s_2ch_src", CLK_SET_RATE_PARENT, - RK3368_CLKSEL_CON(54), 0, - RK3368_CLKGATE_CON(5), 14, GFLAGS), - COMPOSITE_NODIV(SCLK_I2S_2CH, "sclk_i2s_2ch", mux_i2s_2ch_p, 0, - RK3368_CLKSEL_CON(53), 8, 2, MFLAGS, - RK3368_CLKGATE_CON(5), 15, GFLAGS), + COMPOSITE_FRACMUX(0, "i2s_2ch_frac", "i2s_2ch_src", CLK_SET_RATE_PARENT, + RK3368_CLKSEL_CON(54), 0, + RK3368_CLKGATE_CON(5), 14, GFLAGS, + &rk3368_i2s_2ch_fracmux), + GATE(SCLK_I2S_2CH, "sclk_i2s_2ch", "i2s_2ch_pre", CLK_SET_RATE_PARENT, + RK3368_CLKGATE_CON(5), 15, GFLAGS), COMPOSITE(0, "sclk_tsp", mux_pll_src_cpll_gpll_npll_p, 0, RK3368_CLKSEL_CON(46), 6, 2, MFLAGS, 0, 5, DFLAGS, @@ -384,18 +413,18 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { * Clock-Architecture Diagram 3 */ - COMPOSITE(0, "aclk_vepu", mux_pll_src_cpll_gpll_usb_p, 0, + COMPOSITE(0, "aclk_vepu", mux_pll_src_cpll_gpll_npll_usb_p, 0, RK3368_CLKSEL_CON(15), 6, 2, MFLAGS, 0, 5, DFLAGS, RK3368_CLKGATE_CON(4), 6, GFLAGS), - COMPOSITE(0, "aclk_vdpu", mux_pll_src_cpll_gpll_usb_p, 0, + COMPOSITE(0, "aclk_vdpu", mux_pll_src_cpll_gpll_npll_usb_p, 0, RK3368_CLKSEL_CON(15), 14, 2, MFLAGS, 8, 5, DFLAGS, RK3368_CLKGATE_CON(4), 7, GFLAGS), /* - * We introduce a virtual node of hclk_vodec_pre_v to split one clock - * struct with a gate and a fix divider into two node in software. + * We use aclk_vdpu by default ---GRF_SOC_CON0[7] setting in system, + * so we ignore the mux and make clocks nodes as following, */ - GATE(0, "hclk_video_pre_v", "aclk_vdpu", 0, + FACTOR_GATE(0, "hclk_video_pre", "aclk_vdpu", 0, 1, 4, RK3368_CLKGATE_CON(4), 8, GFLAGS), COMPOSITE(0, "sclk_hevc_cabac_src", mux_pll_src_cpll_gpll_npll_usb_p, 0, @@ -442,7 +471,7 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { GATE(SCLK_HDMI_HDCP, "sclk_hdmi_hdcp", "xin24m", 0, RK3368_CLKGATE_CON(4), 13, GFLAGS), GATE(SCLK_HDMI_CEC, "sclk_hdmi_cec", "xin32k", 0, - RK3368_CLKGATE_CON(5), 12, GFLAGS), + RK3368_CLKGATE_CON(4), 12, GFLAGS), COMPOSITE_NODIV(0, "vip_src", mux_pll_src_cpll_gpll_p, 0, RK3368_CLKSEL_CON(21), 15, 1, MFLAGS, @@ -560,38 +589,34 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { COMPOSITE(0, "uart0_src", mux_pll_src_cpll_gpll_usb_usb_p, 0, RK3368_CLKSEL_CON(33), 12, 2, MFLAGS, 0, 7, DFLAGS, RK3368_CLKGATE_CON(2), 0, GFLAGS), - COMPOSITE_FRAC(0, "uart0_frac", "uart0_src", CLK_SET_RATE_PARENT, - RK3368_CLKSEL_CON(34), 0, - RK3368_CLKGATE_CON(2), 1, GFLAGS), - MUX(SCLK_UART0, "sclk_uart0", mux_uart0_p, CLK_SET_RATE_PARENT, - RK3368_CLKSEL_CON(33), 8, 2, MFLAGS), + COMPOSITE_FRACMUX(0, "uart0_frac", "uart0_src", CLK_SET_RATE_PARENT, + RK3368_CLKSEL_CON(34), 0, + RK3368_CLKGATE_CON(2), 1, GFLAGS, + &rk3368_uart0_fracmux), COMPOSITE_NOMUX(0, "uart1_src", "uart_src", 0, RK3368_CLKSEL_CON(35), 0, 7, DFLAGS, RK3368_CLKGATE_CON(2), 2, GFLAGS), - COMPOSITE_FRAC(0, "uart1_frac", "uart1_src", CLK_SET_RATE_PARENT, - RK3368_CLKSEL_CON(36), 0, - RK3368_CLKGATE_CON(2), 3, GFLAGS), - MUX(SCLK_UART1, "sclk_uart1", mux_uart1_p, CLK_SET_RATE_PARENT, - RK3368_CLKSEL_CON(35), 8, 2, MFLAGS), + COMPOSITE_FRACMUX(0, "uart1_frac", "uart1_src", CLK_SET_RATE_PARENT, + RK3368_CLKSEL_CON(36), 0, + RK3368_CLKGATE_CON(2), 3, GFLAGS, + &rk3368_uart1_fracmux), COMPOSITE_NOMUX(0, "uart3_src", "uart_src", 0, RK3368_CLKSEL_CON(39), 0, 7, DFLAGS, RK3368_CLKGATE_CON(2), 6, GFLAGS), - COMPOSITE_FRAC(0, "uart3_frac", "uart3_src", CLK_SET_RATE_PARENT, - RK3368_CLKSEL_CON(40), 0, - RK3368_CLKGATE_CON(2), 7, GFLAGS), - MUX(SCLK_UART3, "sclk_uart3", mux_uart3_p, CLK_SET_RATE_PARENT, - RK3368_CLKSEL_CON(39), 8, 2, MFLAGS), + COMPOSITE_FRACMUX(0, "uart3_frac", "uart3_src", CLK_SET_RATE_PARENT, + RK3368_CLKSEL_CON(40), 0, + RK3368_CLKGATE_CON(2), 7, GFLAGS, + &rk3368_uart3_fracmux), COMPOSITE_NOMUX(0, "uart4_src", "uart_src", 0, RK3368_CLKSEL_CON(41), 0, 7, DFLAGS, RK3368_CLKGATE_CON(2), 8, GFLAGS), - COMPOSITE_FRAC(0, "uart4_frac", "uart4_src", CLK_SET_RATE_PARENT, - RK3368_CLKSEL_CON(42), 0, - RK3368_CLKGATE_CON(2), 9, GFLAGS), - MUX(SCLK_UART4, "sclk_uart4", mux_uart4_p, CLK_SET_RATE_PARENT, - RK3368_CLKSEL_CON(41), 8, 2, MFLAGS), + COMPOSITE_FRACMUX(0, "uart4_frac", "uart4_src", CLK_SET_RATE_PARENT, + RK3368_CLKSEL_CON(42), 0, + RK3368_CLKGATE_CON(2), 9, GFLAGS, + &rk3368_uart4_fracmux), COMPOSITE(0, "mac_pll_src", mux_pll_src_npll_cpll_gpll_p, 0, RK3368_CLKSEL_CON(43), 6, 2, MFLAGS, 0, 5, DFLAGS, @@ -842,24 +867,6 @@ static void __init rk3368_clk_init(struct device_node *np) rockchip_clk_init(np, reg_base, CLK_NR_CLKS); - /* xin12m is created by a cru-internal divider */ - clk = clk_register_fixed_factor(NULL, "xin12m", "xin24m", 0, 1, 2); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock xin12m: %ld\n", - __func__, PTR_ERR(clk)); - - /* ddrphy_div4 is created by a cru-internal divider */ - clk = clk_register_fixed_factor(NULL, "ddrphy_div4", "ddrphy_src", 0, 1, 4); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock xin12m: %ld\n", - __func__, PTR_ERR(clk)); - - clk = clk_register_fixed_factor(NULL, "hclk_video_pre", - "hclk_video_pre_v", 0, 1, 4); - if (IS_ERR(clk)) - pr_warn("%s: could not register clock hclk_vcodec_pre: %ld\n", - __func__, PTR_ERR(clk)); - /* Watchdog pclk is controlled by sgrf_soc_con3[7]. */ clk = clk_register_fixed_factor(NULL, "pclk_wdt", "pclk_pd_alive", 0, 1, 1); if (IS_ERR(clk)) diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c index d9a0b5d4d47f91137e78944de023b910972c4387..ec06350c78c4808c7dc6a849f157428402cccf0f 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c @@ -70,7 +70,7 @@ static struct clk *rockchip_clk_register_branch(const char *name, if (gate_offset >= 0) { gate = kzalloc(sizeof(*gate), GFP_KERNEL); if (!gate) - return ERR_PTR(-ENOMEM); + goto err_gate; gate->flags = gate_flags; gate->reg = base + gate_offset; @@ -82,7 +82,7 @@ static struct clk *rockchip_clk_register_branch(const char *name, if (div_width > 0) { div = kzalloc(sizeof(*div), GFP_KERNEL); if (!div) - return ERR_PTR(-ENOMEM); + goto err_div; div->flags = div_flags; div->reg = base + muxdiv_offset; @@ -90,7 +90,9 @@ static struct clk *rockchip_clk_register_branch(const char *name, div->width = div_width; div->lock = lock; div->table = div_table; - div_ops = &clk_divider_ops; + div_ops = (div_flags & CLK_DIVIDER_READ_ONLY) + ? &clk_divider_ro_ops + : &clk_divider_ops; } clk = clk_register_composite(NULL, name, parent_names, num_parents, @@ -100,6 +102,11 @@ static struct clk *rockchip_clk_register_branch(const char *name, flags); return clk; +err_div: + kfree(gate); +err_gate: + kfree(mux); + return ERR_PTR(-ENOMEM); } struct rockchip_clk_frac { @@ -260,6 +267,53 @@ static struct clk *rockchip_clk_register_frac_branch(const char *name, return clk; } +static struct clk *rockchip_clk_register_factor_branch(const char *name, + const char *const *parent_names, u8 num_parents, + void __iomem *base, unsigned int mult, unsigned int div, + int gate_offset, u8 gate_shift, u8 gate_flags, + unsigned long flags, spinlock_t *lock) +{ + struct clk *clk; + struct clk_gate *gate = NULL; + struct clk_fixed_factor *fix = NULL; + + /* without gate, register a simple factor clock */ + if (gate_offset == 0) { + return clk_register_fixed_factor(NULL, name, + parent_names[0], flags, mult, + div); + } + + gate = kzalloc(sizeof(*gate), GFP_KERNEL); + if (!gate) + return ERR_PTR(-ENOMEM); + + gate->flags = gate_flags; + gate->reg = base + gate_offset; + gate->bit_idx = gate_shift; + gate->lock = lock; + + fix = kzalloc(sizeof(*fix), GFP_KERNEL); + if (!fix) { + kfree(gate); + return ERR_PTR(-ENOMEM); + } + + fix->mult = mult; + fix->div = div; + + clk = clk_register_composite(NULL, name, parent_names, num_parents, + NULL, NULL, + &fix->hw, &clk_fixed_factor_ops, + &gate->hw, &clk_gate_ops, flags); + if (IS_ERR(clk)) { + kfree(fix); + kfree(gate); + } + + return clk; +} + static DEFINE_SPINLOCK(clk_lock); static struct clk **clk_table; static void __iomem *reg_base; @@ -395,6 +449,14 @@ void __init rockchip_clk_register_branches( reg_base + list->muxdiv_offset, list->div_shift, list->div_flags, &clk_lock); break; + case branch_factor: + clk = rockchip_clk_register_factor_branch( + list->name, list->parent_names, + list->num_parents, reg_base, + list->div_shift, list->div_width, + list->gate_offset, list->gate_shift, + list->gate_flags, flags, &clk_lock); + break; } /* none of the cases above matched */ diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h index ff8bd23a93ec2741ad00a40adbf0a462d836b82a..39c198bbcbee7be22f47b0c3f4f30bb297eea772 100644 --- a/drivers/clk/rockchip/clk.h +++ b/drivers/clk/rockchip/clk.h @@ -254,6 +254,7 @@ enum rockchip_clk_branch_type { branch_gate, branch_mmc, branch_inverter, + branch_factor, }; struct rockchip_clk_branch { @@ -508,6 +509,33 @@ struct rockchip_clk_branch { .div_flags = if, \ } +#define FACTOR(_id, cname, pname, f, fm, fd) \ + { \ + .id = _id, \ + .branch_type = branch_factor, \ + .name = cname, \ + .parent_names = (const char *[]){ pname }, \ + .num_parents = 1, \ + .flags = f, \ + .div_shift = fm, \ + .div_width = fd, \ + } + +#define FACTOR_GATE(_id, cname, pname, f, fm, fd, go, gb, gf) \ + { \ + .id = _id, \ + .branch_type = branch_factor, \ + .name = cname, \ + .parent_names = (const char *[]){ pname }, \ + .num_parents = 1, \ + .flags = f, \ + .div_shift = fm, \ + .div_width = fd, \ + .gate_offset = go, \ + .gate_shift = gb, \ + .gate_flags = gf, \ + } + void rockchip_clk_init(struct device_node *np, void __iomem *base, unsigned long nr_clks); struct regmap *rockchip_clk_get_grf(void); diff --git a/drivers/clk/rockchip/softrst.c b/drivers/clk/rockchip/softrst.c index 552f7bb15bc5bf82a8678ecc084fe7c06e0cea81..21218987bbc3d55141c7f28fbb94aa03c2cdb90c 100644 --- a/drivers/clk/rockchip/softrst.c +++ b/drivers/clk/rockchip/softrst.c @@ -81,7 +81,7 @@ static int rockchip_softrst_deassert(struct reset_controller_dev *rcdev, return 0; } -static struct reset_control_ops rockchip_softrst_ops = { +static const struct reset_control_ops rockchip_softrst_ops = { .assert = rockchip_softrst_assert, .deassert = rockchip_softrst_deassert, }; diff --git a/drivers/clk/samsung/Kconfig b/drivers/clk/samsung/Kconfig index 84196ecdaa12f5df319f6fafe2e9b6bd664bc9d5..20c5fe92ab4adf9da4e655e264f2ba1d486bd8b5 100644 --- a/drivers/clk/samsung/Kconfig +++ b/drivers/clk/samsung/Kconfig @@ -1,9 +1,17 @@ +# Recent Exynos platforms should just select COMMON_CLK_SAMSUNG: config COMMON_CLK_SAMSUNG - bool - select COMMON_CLK + bool "Samsung Exynos clock controller support" if COMPILE_TEST + # Clocks on ARM64 SoCs (e.g. Exynos5433, Exynos7) are chosen by + # EXYNOS_ARM64_COMMON_CLK to avoid building them on ARMv7: + select EXYNOS_ARM64_COMMON_CLK if ARM64 && ARCH_EXYNOS + +config EXYNOS_ARM64_COMMON_CLK + bool "Samsung Exynos ARMv8-family clock controller support" if COMPILE_TEST + depends on COMMON_CLK_SAMSUNG +# For S3C24XX platforms, select following symbols: config S3C2410_COMMON_CLK - bool + bool "Samsung S3C2410 clock controller support" if COMPILE_TEST select COMMON_CLK_SAMSUNG help Build the s3c2410 clock driver based on the common clock framework. @@ -17,10 +25,9 @@ config S3C2410_COMMON_DCLK framework. config S3C2412_COMMON_CLK - bool + bool "Samsung S3C2412 clock controller support" if COMPILE_TEST select COMMON_CLK_SAMSUNG config S3C2443_COMMON_CLK - bool + bool "Samsung S3C2443 clock controller support" if COMPILE_TEST select COMMON_CLK_SAMSUNG - diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile index 5f6833ea355d686a5d1429133715cf1ba1f48795..fc367d4b2902b14286ff4075f6d452612dd08f01 100644 --- a/drivers/clk/samsung/Makefile +++ b/drivers/clk/samsung/Makefile @@ -10,11 +10,11 @@ obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o obj-$(CONFIG_SOC_EXYNOS5260) += clk-exynos5260.o obj-$(CONFIG_SOC_EXYNOS5410) += clk-exynos5410.o obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5420.o -obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos5433.o +obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos5433.o obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-audss.o obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-clkout.o -obj-$(CONFIG_ARCH_EXYNOS7) += clk-exynos7.o +obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos7.o obj-$(CONFIG_S3C2410_COMMON_CLK)+= clk-s3c2410.o obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o obj-$(CONFIG_S3C2412_COMMON_CLK)+= clk-s3c2412.o diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index ac03e4fe287141f0fd2cd9ed34e7bbd21a04c345..7b3d0f97598740240fecec3afa0e08e074933876 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -500,19 +500,19 @@ PNAME(clkout_cpu_p4x12) = { "fout_apll_div_2", "none", "none", "none", /* fixed rate clocks generated outside the soc */ static struct samsung_fixed_rate_clock exynos4_fixed_rate_ext_clks[] __initdata = { - FRATE(CLK_XXTI, "xxti", NULL, CLK_IS_ROOT, 0), - FRATE(CLK_XUSBXTI, "xusbxti", NULL, CLK_IS_ROOT, 0), + FRATE(CLK_XXTI, "xxti", NULL, 0, 0), + FRATE(CLK_XUSBXTI, "xusbxti", NULL, 0, 0), }; /* fixed rate clocks generated inside the soc */ static struct samsung_fixed_rate_clock exynos4_fixed_rate_clks[] __initdata = { - FRATE(0, "sclk_hdmi24m", NULL, CLK_IS_ROOT, 24000000), + FRATE(0, "sclk_hdmi24m", NULL, 0, 24000000), FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", "hdmi", 0, 27000000), - FRATE(0, "sclk_usbphy0", NULL, CLK_IS_ROOT, 48000000), + FRATE(0, "sclk_usbphy0", NULL, 0, 48000000), }; static struct samsung_fixed_rate_clock exynos4210_fixed_rate_clks[] __initdata = { - FRATE(0, "sclk_usbphy1", NULL, CLK_IS_ROOT, 48000000), + FRATE(0, "sclk_usbphy1", NULL, 0, 48000000), }; static struct samsung_fixed_factor_clock exynos4_fixed_factor_clks[] __initdata = { @@ -1251,7 +1251,7 @@ static void __init exynos4_clk_register_finpll(struct samsung_clk_provider *ctx) fclk.id = CLK_FIN_PLL; fclk.name = "fin_pll"; fclk.parent_name = NULL; - fclk.flags = CLK_IS_ROOT; + fclk.flags = 0; fclk.fixed_rate = finpll_f; samsung_clk_register_fixed_rate(ctx, &fclk, 1); diff --git a/drivers/clk/samsung/clk-exynos4415.c b/drivers/clk/samsung/clk-exynos4415.c index 92c39f6efec82a1617881e2dd75d3261dcc4d007..86ee06b226bdbaa0f71793d1ea50265faee1c6e4 100644 --- a/drivers/clk/samsung/clk-exynos4415.c +++ b/drivers/clk/samsung/clk-exynos4415.c @@ -274,7 +274,7 @@ static struct samsung_fixed_factor_clock exynos4415_fixed_factor_clks[] __initda }; static struct samsung_fixed_rate_clock exynos4415_fixed_rate_clks[] __initdata = { - FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000), + FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", NULL, 0, 27000000), }; static struct samsung_mux_clock exynos4415_mux_clks[] __initdata = { diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c index 5bebf8cb0d70f3daeff4bb2d3f14eb67e1444451..837197db4ffbb5f1b3f9539e76ff1d755004c713 100644 --- a/drivers/clk/samsung/clk-exynos5250.c +++ b/drivers/clk/samsung/clk-exynos5250.c @@ -262,15 +262,15 @@ PNAME(mout_spdif_p) = { "sclk_audio0", "sclk_audio1", "sclk_audio2", /* fixed rate clocks generated outside the soc */ static struct samsung_fixed_rate_clock exynos5250_fixed_rate_ext_clks[] __initdata = { - FRATE(CLK_FIN_PLL, "fin_pll", NULL, CLK_IS_ROOT, 0), + FRATE(CLK_FIN_PLL, "fin_pll", NULL, 0, 0), }; /* fixed rate clocks generated inside the soc */ static struct samsung_fixed_rate_clock exynos5250_fixed_rate_clks[] __initdata = { - FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 24000000), - FRATE(0, "sclk_hdmi27m", NULL, CLK_IS_ROOT, 27000000), - FRATE(0, "sclk_dptxphy", NULL, CLK_IS_ROOT, 24000000), - FRATE(0, "sclk_uhostphy", NULL, CLK_IS_ROOT, 48000000), + FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", NULL, 0, 24000000), + FRATE(0, "sclk_hdmi27m", NULL, 0, 27000000), + FRATE(0, "sclk_dptxphy", NULL, 0, 24000000), + FRATE(0, "sclk_uhostphy", NULL, 0, 48000000), }; static struct samsung_fixed_factor_clock exynos5250_fixed_factor_clks[] __initdata = { diff --git a/drivers/clk/samsung/clk-exynos5260.c b/drivers/clk/samsung/clk-exynos5260.c index d1a29f6c10849f0a0023c7a040a9b55248c81e9a..7a7ed075a573d78699c86b2113e8a071f8033472 100644 --- a/drivers/clk/samsung/clk-exynos5260.c +++ b/drivers/clk/samsung/clk-exynos5260.c @@ -1432,42 +1432,38 @@ static unsigned long top_clk_regs[] __initdata = { /* fixed rate clocks generated inside the soc */ static struct samsung_fixed_rate_clock fixed_rate_clks[] __initdata = { FRATE(PHYCLK_DPTX_PHY_CH3_TXD_CLK, "phyclk_dptx_phy_ch3_txd_clk", NULL, - CLK_IS_ROOT, 270000000), + 0, 270000000), FRATE(PHYCLK_DPTX_PHY_CH2_TXD_CLK, "phyclk_dptx_phy_ch2_txd_clk", NULL, - CLK_IS_ROOT, 270000000), + 0, 270000000), FRATE(PHYCLK_DPTX_PHY_CH1_TXD_CLK, "phyclk_dptx_phy_ch1_txd_clk", NULL, - CLK_IS_ROOT, 270000000), + 0, 270000000), FRATE(PHYCLK_DPTX_PHY_CH0_TXD_CLK, "phyclk_dptx_phy_ch0_txd_clk", NULL, - CLK_IS_ROOT, 270000000), + 0, 270000000), FRATE(phyclk_hdmi_phy_tmds_clko, "phyclk_hdmi_phy_tmds_clko", NULL, - CLK_IS_ROOT, 250000000), + 0, 250000000), FRATE(PHYCLK_HDMI_PHY_PIXEL_CLKO, "phyclk_hdmi_phy_pixel_clko", NULL, - CLK_IS_ROOT, 1660000000), + 0, 1660000000), FRATE(PHYCLK_HDMI_LINK_O_TMDS_CLKHI, "phyclk_hdmi_link_o_tmds_clkhi", - NULL, CLK_IS_ROOT, 125000000), + NULL, 0, 125000000), FRATE(PHYCLK_MIPI_DPHY_4L_M_TXBYTECLKHS, "phyclk_mipi_dphy_4l_m_txbyte_clkhs" , NULL, - CLK_IS_ROOT, 187500000), + 0, 187500000), FRATE(PHYCLK_DPTX_PHY_O_REF_CLK_24M, "phyclk_dptx_phy_o_ref_clk_24m", - NULL, CLK_IS_ROOT, 24000000), + NULL, 0, 24000000), FRATE(PHYCLK_DPTX_PHY_CLK_DIV2, "phyclk_dptx_phy_clk_div2", NULL, - CLK_IS_ROOT, 135000000), + 0, 135000000), FRATE(PHYCLK_MIPI_DPHY_4L_M_RXCLKESC0, - "phyclk_mipi_dphy_4l_m_rxclkesc0", NULL, - CLK_IS_ROOT, 20000000), + "phyclk_mipi_dphy_4l_m_rxclkesc0", NULL, 0, 20000000), FRATE(PHYCLK_USBHOST20_PHY_PHYCLOCK, "phyclk_usbhost20_phy_phyclock", - NULL, CLK_IS_ROOT, 60000000), + NULL, 0, 60000000), FRATE(PHYCLK_USBHOST20_PHY_FREECLK, "phyclk_usbhost20_phy_freeclk", - NULL, CLK_IS_ROOT, 60000000), + NULL, 0, 60000000), FRATE(PHYCLK_USBHOST20_PHY_CLK48MOHCI, - "phyclk_usbhost20_phy_clk48mohci", - NULL, CLK_IS_ROOT, 48000000), + "phyclk_usbhost20_phy_clk48mohci", NULL, 0, 48000000), FRATE(PHYCLK_USBDRD30_UDRD30_PIPE_PCLK, - "phyclk_usbdrd30_udrd30_pipe_pclk", NULL, - CLK_IS_ROOT, 125000000), + "phyclk_usbdrd30_udrd30_pipe_pclk", NULL, 0, 125000000), FRATE(PHYCLK_USBDRD30_UDRD30_PHYCLOCK, - "phyclk_usbdrd30_udrd30_phyclock", NULL, - CLK_IS_ROOT, 60000000), + "phyclk_usbdrd30_udrd30_phyclock", NULL, 0, 60000000), }; PNAME(mout_memtop_pll_user_p) = {"fin_pll", "dout_mem_pll"}; diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index d048dedd8b72a4dd1cfb16ffe7a6113c5c791e35..be03ed0fcb6be74e3674b878f9691b67928008ee 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -480,16 +480,16 @@ PNAME(mout_group15_5800_p) = { "dout_osc_div", "mout_sw_aclk550_cam" }; /* fixed rate clocks generated outside the soc */ static struct samsung_fixed_rate_clock exynos5x_fixed_rate_ext_clks[] __initdata = { - FRATE(CLK_FIN_PLL, "fin_pll", NULL, CLK_IS_ROOT, 0), + FRATE(CLK_FIN_PLL, "fin_pll", NULL, 0, 0), }; /* fixed rate clocks generated inside the soc */ static struct samsung_fixed_rate_clock exynos5x_fixed_rate_clks[] __initdata = { - FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 24000000), - FRATE(0, "sclk_pwi", NULL, CLK_IS_ROOT, 24000000), - FRATE(0, "sclk_usbh20", NULL, CLK_IS_ROOT, 48000000), - FRATE(0, "mphy_refclk_ixtal24", NULL, CLK_IS_ROOT, 48000000), - FRATE(0, "sclk_usbh20_scan_clk", NULL, CLK_IS_ROOT, 480000000), + FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", NULL, 0, 24000000), + FRATE(0, "sclk_pwi", NULL, 0, 24000000), + FRATE(0, "sclk_usbh20", NULL, 0, 48000000), + FRATE(0, "mphy_refclk_ixtal24", NULL, 0, 48000000), + FRATE(0, "sclk_usbh20_scan_clk", NULL, 0, 480000000), }; static struct samsung_fixed_factor_clock diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index cee062c588dec2c2471b55c4c2b60a44d20ec42f..128527b8fbeb8e54a06d8abbeabe4a6e9f5f9903 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -142,17 +142,6 @@ static unsigned long top_clk_regs[] __initdata = { MUX_ENABLE_TOP_FSYS1, MUX_ENABLE_TOP_PERIC0, MUX_ENABLE_TOP_PERIC1, - MUX_STAT_TOP0, - MUX_STAT_TOP1, - MUX_STAT_TOP2, - MUX_STAT_TOP3, - MUX_STAT_TOP4, - MUX_STAT_TOP_MSCL, - MUX_STAT_TOP_CAM1, - MUX_STAT_TOP_FSYS0, - MUX_STAT_TOP_FSYS1, - MUX_STAT_TOP_PERIC0, - MUX_STAT_TOP_PERIC1, DIV_TOP0, DIV_TOP1, DIV_TOP2, @@ -170,22 +159,6 @@ static unsigned long top_clk_regs[] __initdata = { DIV_TOP_PERIC3, DIV_TOP_PERIC4, DIV_TOP_PLL_FREQ_DET, - DIV_STAT_TOP0, - DIV_STAT_TOP1, - DIV_STAT_TOP2, - DIV_STAT_TOP3, - DIV_STAT_TOP4, - DIV_STAT_TOP_MSCL, - DIV_STAT_TOP_CAM10, - DIV_STAT_TOP_CAM11, - DIV_STAT_TOP_FSYS0, - DIV_STAT_TOP_FSYS1, - DIV_STAT_TOP_FSYS2, - DIV_STAT_TOP_PERIC0, - DIV_STAT_TOP_PERIC1, - DIV_STAT_TOP_PERIC2, - DIV_STAT_TOP_PERIC3, - DIV_STAT_TOP_PLL_FREQ_DET, ENABLE_ACLK_TOP, ENABLE_SCLK_TOP, ENABLE_SCLK_TOP_MSCL, @@ -251,18 +224,18 @@ static struct samsung_fixed_factor_clock top_fixed_factor_clks[] __initdata = { static struct samsung_fixed_rate_clock top_fixed_clks[] __initdata = { /* Xi2s{0|1}CDCLK input clock for I2S/PCM */ - FRATE(0, "ioclk_audiocdclk1", NULL, CLK_IS_ROOT, 100000000), - FRATE(0, "ioclk_audiocdclk0", NULL, CLK_IS_ROOT, 100000000), + FRATE(0, "ioclk_audiocdclk1", NULL, 0, 100000000), + FRATE(0, "ioclk_audiocdclk0", NULL, 0, 100000000), /* Xi2s1SDI input clock for SPDIF */ - FRATE(0, "ioclk_spdif_extclk", NULL, CLK_IS_ROOT, 100000000), + FRATE(0, "ioclk_spdif_extclk", NULL, 0, 100000000), /* XspiCLK[4:0] input clock for SPI */ - FRATE(0, "ioclk_spi4_clk_in", NULL, CLK_IS_ROOT, 50000000), - FRATE(0, "ioclk_spi3_clk_in", NULL, CLK_IS_ROOT, 50000000), - FRATE(0, "ioclk_spi2_clk_in", NULL, CLK_IS_ROOT, 50000000), - FRATE(0, "ioclk_spi1_clk_in", NULL, CLK_IS_ROOT, 50000000), - FRATE(0, "ioclk_spi0_clk_in", NULL, CLK_IS_ROOT, 50000000), + FRATE(0, "ioclk_spi4_clk_in", NULL, 0, 50000000), + FRATE(0, "ioclk_spi3_clk_in", NULL, 0, 50000000), + FRATE(0, "ioclk_spi2_clk_in", NULL, 0, 50000000), + FRATE(0, "ioclk_spi1_clk_in", NULL, 0, 50000000), + FRATE(0, "ioclk_spi0_clk_in", NULL, 0, 50000000), /* Xi2s1SCLK input clock for I2S1_BCLK */ - FRATE(0, "ioclk_i2s1_bclk_in", NULL, CLK_IS_ROOT, 12288000), + FRATE(0, "ioclk_i2s1_bclk_in", NULL, 0, 12288000), }; static struct samsung_mux_clock top_mux_clks[] __initdata = { @@ -490,9 +463,9 @@ static struct samsung_div_clock top_div_clks[] __initdata = { DIV(CLK_DIV_SCLK_ISP_SENSOR1_A, "div_sclk_isp_sensor1_a", "mout_sclk_isp_sensor1", DIV_TOP_CAM11, 8, 4), DIV(CLK_DIV_SCLK_ISP_SENSOR0_B, "div_sclk_isp_sensor0_b", - "div_sclk_isp_sensor0_a", DIV_TOP_CAM11, 12, 4), + "div_sclk_isp_sensor0_a", DIV_TOP_CAM11, 4, 4), DIV(CLK_DIV_SCLK_ISP_SENSOR0_A, "div_sclk_isp_sensor0_a", - "mout_sclk_isp_sensor0", DIV_TOP_CAM11, 8, 4), + "mout_sclk_isp_sensor0", DIV_TOP_CAM11, 0, 4), /* DIV_TOP_FSYS0 */ DIV(CLK_DIV_SCLK_MMC1_B, "div_sclk_mmc1_b", "div_sclk_mmc1_a", @@ -999,26 +972,12 @@ static unsigned long mif_clk_regs[] __initdata = { MUX_ENABLE_MIF5, MUX_ENABLE_MIF6, MUX_ENABLE_MIF7, - MUX_STAT_MIF0, - MUX_STAT_MIF1, - MUX_STAT_MIF2, - MUX_STAT_MIF3, - MUX_STAT_MIF4, - MUX_STAT_MIF5, - MUX_STAT_MIF6, - MUX_STAT_MIF7, DIV_MIF1, DIV_MIF2, DIV_MIF3, DIV_MIF4, DIV_MIF5, DIV_MIF_PLL_FREQ_DET, - DIV_STAT_MIF1, - DIV_STAT_MIF2, - DIV_STAT_MIF3, - DIV_STAT_MIF4, - DIV_STAT_MIF5, - DIV_STAT_MIF_PLL_FREQ_DET, ENABLE_ACLK_MIF0, ENABLE_ACLK_MIF1, ENABLE_ACLK_MIF2, @@ -1565,7 +1524,6 @@ CLK_OF_DECLARE(exynos5433_cmu_mif, "samsung,exynos5433-cmu-mif", static unsigned long peric_clk_regs[] __initdata = { DIV_PERIC, - DIV_STAT_PERIC, ENABLE_ACLK_PERIC, ENABLE_PCLK_PERIC0, ENABLE_PCLK_PERIC1, @@ -2012,11 +1970,6 @@ static unsigned long fsys_clk_regs[] __initdata = { MUX_ENABLE_FSYS2, MUX_ENABLE_FSYS3, MUX_ENABLE_FSYS4, - MUX_STAT_FSYS0, - MUX_STAT_FSYS1, - MUX_STAT_FSYS2, - MUX_STAT_FSYS3, - MUX_STAT_FSYS4, MUX_IGNORE_FSYS2, MUX_IGNORE_FSYS3, ENABLE_ACLK_FSYS0, @@ -2031,42 +1984,40 @@ static struct samsung_fixed_rate_clock fsys_fixed_clks[] __initdata = { /* PHY clocks from USBDRD30_PHY */ FRATE(CLK_PHYCLK_USBDRD30_UDRD30_PHYCLOCK_PHY, "phyclk_usbdrd30_udrd30_phyclock_phy", NULL, - CLK_IS_ROOT, 60000000), + 0, 60000000), FRATE(CLK_PHYCLK_USBDRD30_UDRD30_PIPE_PCLK_PHY, "phyclk_usbdrd30_udrd30_pipe_pclk_phy", NULL, - CLK_IS_ROOT, 125000000), + 0, 125000000), /* PHY clocks from USBHOST30_PHY */ FRATE(CLK_PHYCLK_USBHOST30_UHOST30_PHYCLOCK_PHY, "phyclk_usbhost30_uhost30_phyclock_phy", NULL, - CLK_IS_ROOT, 60000000), + 0, 60000000), FRATE(CLK_PHYCLK_USBHOST30_UHOST30_PIPE_PCLK_PHY, "phyclk_usbhost30_uhost30_pipe_pclk_phy", NULL, - CLK_IS_ROOT, 125000000), + 0, 125000000), /* PHY clocks from USBHOST20_PHY */ FRATE(CLK_PHYCLK_USBHOST20_PHY_FREECLK_PHY, - "phyclk_usbhost20_phy_freeclk_phy", NULL, CLK_IS_ROOT, - 60000000), + "phyclk_usbhost20_phy_freeclk_phy", NULL, 0, 60000000), FRATE(CLK_PHYCLK_USBHOST20_PHY_PHYCLOCK_PHY, - "phyclk_usbhost20_phy_phyclock_phy", NULL, CLK_IS_ROOT, - 60000000), + "phyclk_usbhost20_phy_phyclock_phy", NULL, 0, 60000000), FRATE(CLK_PHYCLK_USBHOST20_PHY_CLK48MOHCI_PHY, "phyclk_usbhost20_phy_clk48mohci_phy", NULL, - CLK_IS_ROOT, 48000000), + 0, 48000000), FRATE(CLK_PHYCLK_USBHOST20_PHY_HSIC1_PHY, - "phyclk_usbhost20_phy_hsic1_phy", NULL, CLK_IS_ROOT, + "phyclk_usbhost20_phy_hsic1_phy", NULL, 0, 60000000), /* PHY clocks from UFS_PHY */ FRATE(CLK_PHYCLK_UFS_TX0_SYMBOL_PHY, "phyclk_ufs_tx0_symbol_phy", - NULL, CLK_IS_ROOT, 300000000), + NULL, 0, 300000000), FRATE(CLK_PHYCLK_UFS_RX0_SYMBOL_PHY, "phyclk_ufs_rx0_symbol_phy", - NULL, CLK_IS_ROOT, 300000000), + NULL, 0, 300000000), FRATE(CLK_PHYCLK_UFS_TX1_SYMBOL_PHY, "phyclk_ufs_tx1_symbol_phy", - NULL, CLK_IS_ROOT, 300000000), + NULL, 0, 300000000), FRATE(CLK_PHYCLK_UFS_RX1_SYMBOL_PHY, "phyclk_ufs_rx1_symbol_phy", - NULL, CLK_IS_ROOT, 300000000), + NULL, 0, 300000000), /* PHY clocks from LLI_PHY */ FRATE(CLK_PHYCLK_LLI_MPHY_TO_UFS_PHY, "phyclk_lli_mphy_to_ufs_phy", - NULL, CLK_IS_ROOT, 26000000), + NULL, 0, 26000000), }; static struct samsung_mux_clock fsys_mux_clks[] __initdata = { @@ -2362,9 +2313,7 @@ CLK_OF_DECLARE(exynos5433_cmu_fsys, "samsung,exynos5433-cmu-fsys", static unsigned long g2d_clk_regs[] __initdata = { MUX_SEL_G2D0, MUX_SEL_ENABLE_G2D0, - MUX_SEL_STAT_G2D0, DIV_G2D, - DIV_STAT_G2D, DIV_ENABLE_ACLK_G2D, DIV_ENABLE_ACLK_G2D_SECURE_SMMU_G2D, DIV_ENABLE_PCLK_G2D, @@ -2520,16 +2469,9 @@ static unsigned long disp_clk_regs[] __initdata = { MUX_ENABLE_DISP2, MUX_ENABLE_DISP3, MUX_ENABLE_DISP4, - MUX_STAT_DISP0, - MUX_STAT_DISP1, - MUX_STAT_DISP2, - MUX_STAT_DISP3, - MUX_STAT_DISP4, MUX_IGNORE_DISP2, DIV_DISP, DIV_DISP_PLL_FREQ_DET, - DIV_STAT_DISP, - DIV_STAT_DISP_PLL_FREQ_DET, ENABLE_ACLK_DISP0, ENABLE_ACLK_DISP1, ENABLE_PCLK_DISP, @@ -2604,18 +2546,16 @@ static struct samsung_fixed_factor_clock disp_fixed_factor_clks[] __initdata = { static struct samsung_fixed_rate_clock disp_fixed_clks[] __initdata = { /* PHY clocks from MIPI_DPHY1 */ - FRATE(0, "phyclk_mipidphy1_bitclkdiv8_phy", NULL, CLK_IS_ROOT, - 188000000), - FRATE(0, "phyclk_mipidphy1_rxclkesc0_phy", NULL, CLK_IS_ROOT, - 100000000), + FRATE(0, "phyclk_mipidphy1_bitclkdiv8_phy", NULL, 0, 188000000), + FRATE(0, "phyclk_mipidphy1_rxclkesc0_phy", NULL, 0, 100000000), /* PHY clocks from MIPI_DPHY0 */ - FRATE(0, "phyclk_mipidphy0_bitclkdiv8_phy", NULL, CLK_IS_ROOT, - 188000000), - FRATE(0, "phyclk_mipidphy0_rxclkesc0_phy", NULL, CLK_IS_ROOT, - 100000000), + FRATE(0, "phyclk_mipidphy0_bitclkdiv8_phy", NULL, 0, 188000000), + FRATE(0, "phyclk_mipidphy0_rxclkesc0_phy", NULL, 0, 100000000), /* PHY clocks from HDMI_PHY */ - FRATE(0, "phyclk_hdmiphy_tmds_clko_phy", NULL, CLK_IS_ROOT, 300000000), - FRATE(0, "phyclk_hdmiphy_pixel_clko_phy", NULL, CLK_IS_ROOT, 166000000), + FRATE(CLK_PHYCLK_HDMIPHY_TMDS_CLKO_PHY, "phyclk_hdmiphy_tmds_clko_phy", + NULL, 0, 300000000), + FRATE(CLK_PHYCLK_HDMIPHY_PIXEL_CLKO_PHY, "phyclk_hdmiphy_pixel_clko_phy", + NULL, 0, 166000000), }; static struct samsung_mux_clock disp_mux_clks[] __initdata = { @@ -2820,6 +2760,8 @@ static struct samsung_gate_clock disp_gate_clks[] __initdata = { ENABLE_PCLK_DISP, 2, 0, 0), GATE(CLK_PCLK_DECON_TV, "pclk_decon_tv", "div_pclk_disp", ENABLE_PCLK_DISP, 1, 0, 0), + GATE(CLK_PCLK_DECON, "pclk_decon", "div_pclk_disp", + ENABLE_PCLK_DISP, 0, 0, 0), /* ENABLE_SCLK_DISP */ GATE(CLK_PHYCLK_MIPIDPHY1_BITCLKDIV8, "phyclk_mipidphy1_bitclkdiv8", @@ -2919,11 +2861,8 @@ static unsigned long aud_clk_regs[] __initdata = { MUX_SEL_AUD1, MUX_ENABLE_AUD0, MUX_ENABLE_AUD1, - MUX_STAT_AUD0, DIV_AUD0, DIV_AUD1, - DIV_STAT_AUD0, - DIV_STAT_AUD1, ENABLE_ACLK_AUD, ENABLE_PCLK_AUD, ENABLE_SCLK_AUD0, @@ -2937,9 +2876,9 @@ PNAME(mout_aud_pll_user_aud_p) = { "oscclk", "fout_aud_pll", }; PNAME(mout_sclk_aud_pcm_p) = { "mout_aud_pll_user", "ioclk_audiocdclk0",}; static struct samsung_fixed_rate_clock aud_fixed_clks[] __initdata = { - FRATE(0, "ioclk_jtag_tclk", NULL, CLK_IS_ROOT, 33000000), - FRATE(0, "ioclk_slimbus_clk", NULL, CLK_IS_ROOT, 25000000), - FRATE(0, "ioclk_i2s_bclk", NULL, CLK_IS_ROOT, 50000000), + FRATE(0, "ioclk_jtag_tclk", NULL, 0, 33000000), + FRATE(0, "ioclk_slimbus_clk", NULL, 0, 25000000), + FRATE(0, "ioclk_i2s_bclk", NULL, 0, 50000000), }; static struct samsung_mux_clock aud_mux_clks[] __initdata = { @@ -3087,7 +3026,6 @@ PNAME(mout_aclk_bus2_400_p) = { "oscclk", "aclk_bus2_400", }; #define CMU_BUS_COMMON_CLK_REGS \ DIV_BUS, \ - DIV_STAT_BUS, \ ENABLE_ACLK_BUS, \ ENABLE_PCLK_BUS, \ ENABLE_IP_BUS0, \ @@ -3100,7 +3038,6 @@ static unsigned long bus01_clk_regs[] __initdata = { static unsigned long bus2_clk_regs[] __initdata = { MUX_SEL_BUS2, MUX_ENABLE_BUS2, - MUX_STAT_BUS2, CMU_BUS_COMMON_CLK_REGS, }; @@ -3259,11 +3196,8 @@ static unsigned long g3d_clk_regs[] __initdata = { G3D_PLL_FREQ_DET, MUX_SEL_G3D, MUX_ENABLE_G3D, - MUX_STAT_G3D, DIV_G3D, DIV_G3D_PLL_FREQ_DET, - DIV_STAT_G3D, - DIV_STAT_G3D_PLL_FREQ_DET, ENABLE_ACLK_G3D, ENABLE_PCLK_G3D, ENABLE_SCLK_G3D, @@ -3379,7 +3313,6 @@ CLK_OF_DECLARE(exynos5433_cmu_g3d, "samsung,exynos5433-cmu-g3d", static unsigned long gscl_clk_regs[] __initdata = { MUX_SEL_GSCL, MUX_ENABLE_GSCL, - MUX_STAT_GSCL, ENABLE_ACLK_GSCL, ENABLE_ACLK_GSCL_SECURE_SMMU_GSCL0, ENABLE_ACLK_GSCL_SECURE_SMMU_GSCL1, @@ -3472,11 +3405,11 @@ static struct samsung_gate_clock gscl_gate_clks[] __initdata = { /* ENABLE_PCLK_GSCL_SECURE_SMMU_GSCL1 */ GATE(CLK_PCLK_SMMU_GSCL1, "pclk_smmu_gscl1", "mout_aclk_gscl_111_user", - ENABLE_PCLK_GSCL_SECURE_SMMU_GSCL0, 0, 0, 0), + ENABLE_PCLK_GSCL_SECURE_SMMU_GSCL1, 0, 0, 0), /* ENABLE_PCLK_GSCL_SECURE_SMMU_GSCL2 */ GATE(CLK_PCLK_SMMU_GSCL2, "pclk_smmu_gscl2", "mout_aclk_gscl_111_user", - ENABLE_PCLK_GSCL_SECURE_SMMU_GSCL0, 0, 0, 0), + ENABLE_PCLK_GSCL_SECURE_SMMU_GSCL2, 0, 0, 0), }; static struct samsung_cmu_info gscl_cmu_info __initdata = { @@ -3543,15 +3476,9 @@ static unsigned long apollo_clk_regs[] __initdata = { MUX_ENABLE_APOLLO0, MUX_ENABLE_APOLLO1, MUX_ENABLE_APOLLO2, - MUX_STAT_APOLLO0, - MUX_STAT_APOLLO1, - MUX_STAT_APOLLO2, DIV_APOLLO0, DIV_APOLLO1, DIV_APOLLO_PLL_FREQ_DET, - DIV_STAT_APOLLO0, - DIV_STAT_APOLLO1, - DIV_STAT_APOLLO_PLL_FREQ_DET, ENABLE_ACLK_APOLLO, ENABLE_PCLK_APOLLO, ENABLE_SCLK_APOLLO, @@ -3735,15 +3662,9 @@ static unsigned long atlas_clk_regs[] __initdata = { MUX_ENABLE_ATLAS0, MUX_ENABLE_ATLAS1, MUX_ENABLE_ATLAS2, - MUX_STAT_ATLAS0, - MUX_STAT_ATLAS1, - MUX_STAT_ATLAS2, DIV_ATLAS0, DIV_ATLAS1, DIV_ATLAS_PLL_FREQ_DET, - DIV_STAT_ATLAS0, - DIV_STAT_ATLAS1, - DIV_STAT_ATLAS_PLL_FREQ_DET, ENABLE_ACLK_ATLAS, ENABLE_PCLK_ATLAS, ENABLE_SCLK_ATLAS, @@ -3937,10 +3858,7 @@ static unsigned long mscl_clk_regs[] __initdata = { MUX_SEL_MSCL1, MUX_ENABLE_MSCL0, MUX_ENABLE_MSCL1, - MUX_STAT_MSCL0, - MUX_STAT_MSCL1, DIV_MSCL, - DIV_STAT_MSCL, ENABLE_ACLK_MSCL, ENABLE_ACLK_MSCL_SECURE_SMMU_M2MSCALER0, ENABLE_ACLK_MSCL_SECURE_SMMU_M2MSCALER1, @@ -4097,9 +4015,7 @@ CLK_OF_DECLARE(exynos5433_cmu_mscl, "samsung,exynos5433-cmu-mscl", static unsigned long mfc_clk_regs[] __initdata = { MUX_SEL_MFC, MUX_ENABLE_MFC, - MUX_STAT_MFC, DIV_MFC, - DIV_STAT_MFC, ENABLE_ACLK_MFC, ENABLE_ACLK_MFC_SECURE_SMMU_MFC, ENABLE_PCLK_MFC, @@ -4207,9 +4123,7 @@ CLK_OF_DECLARE(exynos5433_cmu_mfc, "samsung,exynos5433-cmu-mfc", static unsigned long hevc_clk_regs[] __initdata = { MUX_SEL_HEVC, MUX_ENABLE_HEVC, - MUX_STAT_HEVC, DIV_HEVC, - DIV_STAT_HEVC, ENABLE_ACLK_HEVC, ENABLE_ACLK_HEVC_SECURE_SMMU_HEVC, ENABLE_PCLK_HEVC, @@ -4321,9 +4235,7 @@ CLK_OF_DECLARE(exynos5433_cmu_hevc, "samsung,exynos5433-cmu-hevc", static unsigned long isp_clk_regs[] __initdata = { MUX_SEL_ISP, MUX_ENABLE_ISP, - MUX_STAT_ISP, DIV_ISP, - DIV_STAT_ISP, ENABLE_ACLK_ISP0, ENABLE_ACLK_ISP1, ENABLE_ACLK_ISP2, @@ -4603,20 +4515,11 @@ static unsigned long cam0_clk_regs[] __initdata = { MUX_ENABLE_CAM02, MUX_ENABLE_CAM03, MUX_ENABLE_CAM04, - MUX_STAT_CAM00, - MUX_STAT_CAM01, - MUX_STAT_CAM02, - MUX_STAT_CAM03, - MUX_STAT_CAM04, MUX_IGNORE_CAM01, DIV_CAM00, DIV_CAM01, DIV_CAM02, DIV_CAM03, - DIV_STAT_CAM00, - DIV_STAT_CAM01, - DIV_STAT_CAM02, - DIV_STAT_CAM03, ENABLE_ACLK_CAM00, ENABLE_ACLK_CAM01, ENABLE_ACLK_CAM02, @@ -4687,9 +4590,9 @@ PNAME(mout_sclk_pixelasync_lite_c_init_a_p) = { static struct samsung_fixed_rate_clock cam0_fixed_clks[] __initdata = { FRATE(CLK_PHYCLK_RXBYTEECLKHS0_S4_PHY, "phyclk_rxbyteclkhs0_s4_phy", - NULL, CLK_IS_ROOT, 100000000), + NULL, 0, 100000000), FRATE(CLK_PHYCLK_RXBYTEECLKHS0_S2A_PHY, "phyclk_rxbyteclkhs0_s2a_phy", - NULL, CLK_IS_ROOT, 100000000), + NULL, 0, 100000000), }; static struct samsung_mux_clock cam0_mux_clks[] __initdata = { @@ -4749,21 +4652,21 @@ static struct samsung_mux_clock cam0_mux_clks[] __initdata = { MUX(CLK_MOUT_SCLK_LITE_FREECNT_C, "mout_sclk_lite_freecnt_c", mout_sclk_lite_freecnt_c_p, MUX_SEL_CAM04, 24, 1), MUX(CLK_MOUT_SCLK_LITE_FREECNT_B, "mout_sclk_lite_freecnt_b", - mout_sclk_lite_freecnt_b_p, MUX_SEL_CAM04, 24, 1), + mout_sclk_lite_freecnt_b_p, MUX_SEL_CAM04, 20, 1), MUX(CLK_MOUT_SCLK_LITE_FREECNT_A, "mout_sclk_lite_freecnt_a", - mout_sclk_lite_freecnt_a_p, MUX_SEL_CAM04, 24, 1), + mout_sclk_lite_freecnt_a_p, MUX_SEL_CAM04, 16, 1), MUX(CLK_MOUT_SCLK_PIXELASYNC_LITE_C_B, "mout_sclk_pixelasync_lite_c_b", - mout_sclk_pixelasync_lite_c_b_p, MUX_SEL_CAM04, 24, 1), + mout_sclk_pixelasync_lite_c_b_p, MUX_SEL_CAM04, 12, 1), MUX(CLK_MOUT_SCLK_PIXELASYNC_LITE_C_A, "mout_sclk_pixelasync_lite_c_a", - mout_sclk_pixelasync_lite_c_a_p, MUX_SEL_CAM04, 24, 1), + mout_sclk_pixelasync_lite_c_a_p, MUX_SEL_CAM04, 8, 1), MUX(CLK_MOUT_SCLK_PIXELASYNC_LITE_C_INIT_B, "mout_sclk_pixelasync_lite_c_init_b", mout_sclk_pixelasync_lite_c_init_b_p, - MUX_SEL_CAM04, 24, 1), + MUX_SEL_CAM04, 4, 1), MUX(CLK_MOUT_SCLK_PIXELASYNC_LITE_C_INIT_A, "mout_sclk_pixelasync_lite_c_init_a", mout_sclk_pixelasync_lite_c_init_a_p, - MUX_SEL_CAM04, 24, 1), + MUX_SEL_CAM04, 0, 1), }; static struct samsung_div_clock cam0_div_clks[] __initdata = { @@ -5074,14 +4977,9 @@ static unsigned long cam1_clk_regs[] __initdata = { MUX_ENABLE_CAM10, MUX_ENABLE_CAM11, MUX_ENABLE_CAM12, - MUX_STAT_CAM10, - MUX_STAT_CAM11, - MUX_STAT_CAM12, MUX_IGNORE_CAM11, DIV_CAM10, DIV_CAM11, - DIV_STAT_CAM10, - DIV_STAT_CAM11, ENABLE_ACLK_CAM10, ENABLE_ACLK_CAM11, ENABLE_ACLK_CAM12, @@ -5120,7 +5018,7 @@ PNAME(mout_aclk_lite_c_a_p) = { "mout_aclk_cam1_552_user", static struct samsung_fixed_rate_clock cam1_fixed_clks[] __initdata = { FRATE(CLK_PHYCLK_RXBYTEECLKHS0_S2B, "phyclk_rxbyteclkhs0_s2b_phy", NULL, - CLK_IS_ROOT, 100000000), + 0, 100000000), }; static struct samsung_mux_clock cam1_mux_clks[] __initdata = { @@ -5134,9 +5032,9 @@ static struct samsung_mux_clock cam1_mux_clks[] __initdata = { MUX(CLK_MOUT_ACLK_CAM1_333_USER, "mout_aclk_cam1_333_user", mout_aclk_cam1_333_user_p, MUX_SEL_CAM10, 8, 1), MUX(CLK_MOUT_ACLK_CAM1_400_USER, "mout_aclk_cam1_400_user", - mout_aclk_cam1_400_user_p, MUX_SEL_CAM01, 4, 1), + mout_aclk_cam1_400_user_p, MUX_SEL_CAM10, 4, 1), MUX(CLK_MOUT_ACLK_CAM1_552_USER, "mout_aclk_cam1_552_user", - mout_aclk_cam1_552_user_p, MUX_SEL_CAM01, 0, 1), + mout_aclk_cam1_552_user_p, MUX_SEL_CAM10, 0, 1), /* MUX_SEL_CAM11 */ MUX(CLK_MOUT_PHYCLK_RXBYTECLKHS0_S2B_USER, @@ -5161,7 +5059,7 @@ static struct samsung_mux_clock cam1_mux_clks[] __initdata = { static struct samsung_div_clock cam1_div_clks[] __initdata = { /* DIV_CAM10 */ - DIV(CLK_DIV_SCLK_ISP_WPWM, "div_sclk_isp_wpwm", + DIV(CLK_DIV_SCLK_ISP_MPWM, "div_sclk_isp_mpwm", "div_pclk_cam1_83", DIV_CAM10, 16, 2), DIV(CLK_DIV_PCLK_CAM1_83, "div_pclk_cam1_83", "mout_aclk_cam1_333_user", DIV_CAM10, 12, 2), @@ -5355,7 +5253,7 @@ static struct samsung_gate_clock cam1_gate_clks[] __initdata = { ENABLE_PCLK_CAM1, 5, CLK_IGNORE_UNUSED, 0), GATE(CLK_PCLK_ISP_I2C0, "pclk_isp_i2c0", "div_pclk_cam1_83", ENABLE_PCLK_CAM1, 4, CLK_IGNORE_UNUSED, 0), - GATE(CLK_PCLK_ISP_MPWM, "pclk_isp_wpwm", "div_pclk_cam1_83", + GATE(CLK_PCLK_ISP_MPWM, "pclk_isp_mpwm", "div_pclk_cam1_83", ENABLE_PCLK_CAM1, 3, CLK_IGNORE_UNUSED, 0), GATE(CLK_PCLK_FD, "pclk_fd", "div_pclk_fd", ENABLE_PCLK_CAM1, 3, CLK_IGNORE_UNUSED, 0), @@ -5388,7 +5286,7 @@ static struct samsung_gate_clock cam1_gate_clks[] __initdata = { ENABLE_SCLK_CAM1, 5, 0, 0), GATE(CLK_SCLK_ISP_SPI0, "sclk_isp_spi0", "mout_sclk_isp_spi0_user", ENABLE_SCLK_CAM1, 4, 0, 0), - GATE(CLK_SCLK_ISP_MPWM, "sclk_isp_wpwm", "div_sclk_isp_wpwm", + GATE(CLK_SCLK_ISP_MPWM, "sclk_isp_mpwm", "div_sclk_isp_mpwm", ENABLE_SCLK_CAM1, 3, 0, 0), GATE(CLK_PCLK_DBG_ISP, "sclk_dbg_isp", "div_pclk_dbg_cam1", ENABLE_SCLK_CAM1, 2, 0, 0), diff --git a/drivers/clk/samsung/clk-exynos5440.c b/drivers/clk/samsung/clk-exynos5440.c index 590813871ffe2bf80ab33be555ce036ea131d6b5..c57cff1e17980170cecc0cb33891241d9d214b40 100644 --- a/drivers/clk/samsung/clk-exynos5440.c +++ b/drivers/clk/samsung/clk-exynos5440.c @@ -31,16 +31,16 @@ PNAME(mout_spi_p) = { "div125", "div200" }; /* fixed rate clocks generated outside the soc */ static struct samsung_fixed_rate_clock exynos5440_fixed_rate_ext_clks[] __initdata = { - FRATE(0, "xtal", NULL, CLK_IS_ROOT, 0), + FRATE(0, "xtal", NULL, 0, 0), }; /* fixed rate clocks */ static struct samsung_fixed_rate_clock exynos5440_fixed_rate_clks[] __initdata = { - FRATE(0, "ppll", NULL, CLK_IS_ROOT, 1000000000), - FRATE(0, "usb_phy0", NULL, CLK_IS_ROOT, 60000000), - FRATE(0, "usb_phy1", NULL, CLK_IS_ROOT, 60000000), - FRATE(0, "usb_ohci12", NULL, CLK_IS_ROOT, 12000000), - FRATE(0, "usb_ohci48", NULL, CLK_IS_ROOT, 48000000), + FRATE(0, "ppll", NULL, 0, 1000000000), + FRATE(0, "usb_phy0", NULL, 0, 60000000), + FRATE(0, "usb_phy1", NULL, 0, 60000000), + FRATE(0, "usb_ohci12", NULL, 0, 12000000), + FRATE(0, "usb_ohci48", NULL, 0, 48000000), }; /* fixed factor clocks */ diff --git a/drivers/clk/samsung/clk-exynos7.c b/drivers/clk/samsung/clk-exynos7.c index 55f8e2e24ab852f4f5260f429525d0f864038952..ad68d463b12c66664d16487ba88e8996f5446ad2 100644 --- a/drivers/clk/samsung/clk-exynos7.c +++ b/drivers/clk/samsung/clk-exynos7.c @@ -894,10 +894,8 @@ PNAME(mout_phyclk_usbdrd300_udrd30_pipe_pclk_user_p) = { "fin_pll", /* fixed rate clocks used in the FSYS0 block */ static struct samsung_fixed_rate_clock fixed_rate_clks_fsys0[] __initdata = { - FRATE(0, "phyclk_usbdrd300_udrd30_phyclock", NULL, - CLK_IS_ROOT, 60000000), - FRATE(0, "phyclk_usbdrd300_udrd30_pipe_pclk", NULL, - CLK_IS_ROOT, 125000000), + FRATE(0, "phyclk_usbdrd300_udrd30_phyclock", NULL, 0, 60000000), + FRATE(0, "phyclk_usbdrd300_udrd30_pipe_pclk", NULL, 0, 125000000), }; static unsigned long fsys0_clk_regs[] __initdata = { @@ -1009,11 +1007,11 @@ PNAME(mout_phyclk_ufs20_rx1_user_p) = { "fin_pll", "phyclk_ufs20_rx1_symbol" }; /* fixed rate clocks used in the FSYS1 block */ static struct samsung_fixed_rate_clock fixed_rate_clks_fsys1[] __initdata = { FRATE(PHYCLK_UFS20_TX0_SYMBOL, "phyclk_ufs20_tx0_symbol", NULL, - CLK_IS_ROOT, 300000000), + 0, 300000000), FRATE(PHYCLK_UFS20_RX0_SYMBOL, "phyclk_ufs20_rx0_symbol", NULL, - CLK_IS_ROOT, 300000000), + 0, 300000000), FRATE(PHYCLK_UFS20_RX1_SYMBOL, "phyclk_ufs20_rx1_symbol", NULL, - CLK_IS_ROOT, 300000000), + 0, 300000000), }; static unsigned long fsys1_clk_regs[] __initdata = { diff --git a/drivers/clk/samsung/clk-s3c2410.c b/drivers/clk/samsung/clk-s3c2410.c index 0945a8852299d5f779bcaba6827efae37cb6653b..d7b011c1fcf8859bbddd514a361d8d39e00f11ae 100644 --- a/drivers/clk/samsung/clk-s3c2410.c +++ b/drivers/clk/samsung/clk-s3c2410.c @@ -344,7 +344,7 @@ struct samsung_mux_clock s3c2442_muxes[] __initdata = { */ #define XTI 1 struct samsung_fixed_rate_clock s3c2410_common_frate_clks[] __initdata = { - FRATE(XTI, "xti", NULL, CLK_IS_ROOT, 0), + FRATE(XTI, "xti", NULL, 0, 0), }; static void __init s3c2410_common_clk_register_fixed_ext( diff --git a/drivers/clk/samsung/clk-s3c2412.c b/drivers/clk/samsung/clk-s3c2412.c index 44d6a9f4f5b2f7d1d203f7257d708f6dc42d7590..effe3736ec6b69bfa753e55d54e6615fde1caa98 100644 --- a/drivers/clk/samsung/clk-s3c2412.c +++ b/drivers/clk/samsung/clk-s3c2412.c @@ -232,8 +232,8 @@ static struct notifier_block s3c2412_restart_handler = { */ #define XTI 1 struct samsung_fixed_rate_clock s3c2412_common_frate_clks[] __initdata = { - FRATE(XTI, "xti", NULL, CLK_IS_ROOT, 0), - FRATE(0, "ext", NULL, CLK_IS_ROOT, 0), + FRATE(XTI, "xti", NULL, 0, 0), + FRATE(0, "ext", NULL, 0, 0), }; static void __init s3c2412_common_clk_register_fixed_ext( diff --git a/drivers/clk/samsung/clk-s3c2443.c b/drivers/clk/samsung/clk-s3c2443.c index 2c0a1ea3c80c7eda87d73b2d0aeb6375009c9e8a..37562783b25e1733a36ac86b94ac31892ab002b9 100644 --- a/drivers/clk/samsung/clk-s3c2443.c +++ b/drivers/clk/samsung/clk-s3c2443.c @@ -371,10 +371,10 @@ static struct notifier_block s3c2443_restart_handler = { * Only necessary until the devicetree-move is complete */ struct samsung_fixed_rate_clock s3c2443_common_frate_clks[] __initdata = { - FRATE(0, "xti", NULL, CLK_IS_ROOT, 0), - FRATE(0, "ext", NULL, CLK_IS_ROOT, 0), - FRATE(0, "ext_i2s", NULL, CLK_IS_ROOT, 0), - FRATE(0, "ext_uart", NULL, CLK_IS_ROOT, 0), + FRATE(0, "xti", NULL, 0, 0), + FRATE(0, "ext", NULL, 0, 0), + FRATE(0, "ext_i2s", NULL, 0, 0), + FRATE(0, "ext_uart", NULL, 0, 0), }; static void __init s3c2443_common_clk_register_fixed_ext( diff --git a/drivers/clk/samsung/clk-s3c64xx.c b/drivers/clk/samsung/clk-s3c64xx.c index d325ed1e196bf4f536938edb12dce790666fa3db..60aa775bd3745de6e6ce514b16e2c57be9a321cf 100644 --- a/drivers/clk/samsung/clk-s3c64xx.c +++ b/drivers/clk/samsung/clk-s3c64xx.c @@ -176,14 +176,14 @@ PNAME(audio2_p6410) = { "mout_epll", "dout_mpll", "fin_pll", "iiscdclk2", /* Fixed rate clocks generated outside the SoC. */ FIXED_RATE_CLOCKS(s3c64xx_fixed_rate_ext_clks) __initdata = { - FRATE(0, "fin_pll", NULL, CLK_IS_ROOT, 0), - FRATE(0, "xusbxti", NULL, CLK_IS_ROOT, 0), + FRATE(0, "fin_pll", NULL, 0, 0), + FRATE(0, "xusbxti", NULL, 0, 0), }; /* Fixed rate clocks generated inside the SoC. */ FIXED_RATE_CLOCKS(s3c64xx_fixed_rate_clks) __initdata = { - FRATE(CLK27M, "clk27m", NULL, CLK_IS_ROOT, 27000000), - FRATE(CLK48M, "clk48m", NULL, CLK_IS_ROOT, 48000000), + FRATE(CLK27M, "clk27m", NULL, 0, 27000000), + FRATE(CLK48M, "clk48m", NULL, 0, 48000000), }; /* List of clock muxes present on all S3C64xx SoCs. */ diff --git a/drivers/clk/samsung/clk-s5pv210.c b/drivers/clk/samsung/clk-s5pv210.c index 759aaf342bea986db7414374e6805df2bf24aa5e..52302262045d4cbd9bca00cda8d79d597f8cd14e 100644 --- a/drivers/clk/samsung/clk-s5pv210.c +++ b/drivers/clk/samsung/clk-s5pv210.c @@ -503,15 +503,15 @@ static const struct samsung_mux_clock s5p6442_mux_clks[] __initconst = { /* S5PV210-specific fixed rate clocks generated inside the SoC. */ static const struct samsung_fixed_rate_clock s5pv210_frate_clks[] __initconst = { - FRATE(SCLK_HDMI27M, "sclk_hdmi27m", NULL, CLK_IS_ROOT, 27000000), - FRATE(SCLK_HDMIPHY, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000), - FRATE(SCLK_USBPHY0, "sclk_usbphy0", NULL, CLK_IS_ROOT, 48000000), - FRATE(SCLK_USBPHY1, "sclk_usbphy1", NULL, CLK_IS_ROOT, 48000000), + FRATE(SCLK_HDMI27M, "sclk_hdmi27m", NULL, 0, 27000000), + FRATE(SCLK_HDMIPHY, "sclk_hdmiphy", NULL, 0, 27000000), + FRATE(SCLK_USBPHY0, "sclk_usbphy0", NULL, 0, 48000000), + FRATE(SCLK_USBPHY1, "sclk_usbphy1", NULL, 0, 48000000), }; /* S5P6442-specific fixed rate clocks generated inside the SoC. */ static const struct samsung_fixed_rate_clock s5p6442_frate_clks[] __initconst = { - FRATE(SCLK_USBPHY0, "sclk_usbphy0", NULL, CLK_IS_ROOT, 30000000), + FRATE(SCLK_USBPHY0, "sclk_usbphy0", NULL, 0, 30000000), }; /* Common clock dividers. */ diff --git a/drivers/clk/sirf/clk-atlas7.c b/drivers/clk/sirf/clk-atlas7.c index 957aae63e7cce2796417a96555ed5cf43bff11fd..d0c6c9a2d06ae7d87cc5fe6b1d5866e33508e314 100644 --- a/drivers/clk/sirf/clk-atlas7.c +++ b/drivers/clk/sirf/clk-atlas7.c @@ -1423,7 +1423,7 @@ static int atlas7_reset_module(struct reset_controller_dev *rcdev, return 0; } -static struct reset_control_ops atlas7_rst_ops = { +static const struct reset_control_ops atlas7_rst_ops = { .reset = atlas7_reset_module, }; diff --git a/drivers/clk/socfpga/clk-gate-a10.c b/drivers/clk/socfpga/clk-gate-a10.c index 1cebf253e8fd44dbe22e37e1eb6a18ed63cd2f14..c2d5727481671b57f0cde52e31f9122297c1bb5b 100644 --- a/drivers/clk/socfpga/clk-gate-a10.c +++ b/drivers/clk/socfpga/clk-gate-a10.c @@ -115,7 +115,6 @@ static void __init __socfpga_gate_init(struct device_node *node, const char *parent_name[SOCFPGA_MAX_PARENTS]; struct clk_init_data init; int rc; - int i = 0; socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL); if (WARN_ON(!socfpga_clk)) @@ -167,12 +166,9 @@ static void __init __socfpga_gate_init(struct device_node *node, init.name = clk_name; init.ops = ops; init.flags = 0; - while (i < SOCFPGA_MAX_PARENTS && (parent_name[i] = - of_clk_get_parent_name(node, i)) != NULL) - i++; + init.num_parents = of_clk_parent_fill(node, parent_name, SOCFPGA_MAX_PARENTS); init.parent_names = parent_name; - init.num_parents = i; socfpga_clk->hw.hw.init = &init; clk = clk_register(NULL, &socfpga_clk->hw.hw); diff --git a/drivers/clk/socfpga/clk-periph-a10.c b/drivers/clk/socfpga/clk-periph-a10.c index 1f397cb72e89a8ff421edfaf92cddf2fee1e16a8..70993f1e88bcb24758dd8d825309eb3239f3697d 100644 --- a/drivers/clk/socfpga/clk-periph-a10.c +++ b/drivers/clk/socfpga/clk-periph-a10.c @@ -74,7 +74,7 @@ static __init void __socfpga_periph_init(struct device_node *node, struct clk *clk; struct socfpga_periph_clk *periph_clk; const char *clk_name = node->name; - const char *parent_name; + const char *parent_name[SOCFPGA_MAX_PARENTS]; struct clk_init_data init; int rc; u32 fixed_div; @@ -109,9 +109,8 @@ static __init void __socfpga_periph_init(struct device_node *node, init.ops = ops; init.flags = 0; - parent_name = of_clk_get_parent_name(node, 0); - init.num_parents = 1; - init.parent_names = &parent_name; + init.num_parents = of_clk_parent_fill(node, parent_name, SOCFPGA_MAX_PARENTS); + init.parent_names = parent_name; periph_clk->hw.hw.init = &init; diff --git a/drivers/clk/socfpga/clk-pll-a10.c b/drivers/clk/socfpga/clk-pll-a10.c index 402d630bd531ecf65ee15ba3f70966afe33cb8e7..35fabe1a32c30e4b400a77205c892f150b3f5f7c 100644 --- a/drivers/clk/socfpga/clk-pll-a10.c +++ b/drivers/clk/socfpga/clk-pll-a10.c @@ -74,7 +74,7 @@ static struct clk_ops clk_pll_ops = { .get_parent = clk_pll_get_parent, }; -static struct __init clk * __socfpga_pll_init(struct device_node *node, +static struct clk * __init __socfpga_pll_init(struct device_node *node, const struct clk_ops *ops) { u32 reg; diff --git a/drivers/clk/spear/spear1310_clock.c b/drivers/clk/spear/spear1310_clock.c index 009bd1410cfa87759d6aa3c224dbd3a1c64e832f..2f86e3f94efa6f2fe306fbbecd581bd70e4b392e 100644 --- a/drivers/clk/spear/spear1310_clock.c +++ b/drivers/clk/spear/spear1310_clock.c @@ -386,24 +386,20 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base) { struct clk *clk, *clk1; - clk = clk_register_fixed_rate(NULL, "osc_32k_clk", NULL, CLK_IS_ROOT, - 32000); + clk = clk_register_fixed_rate(NULL, "osc_32k_clk", NULL, 0, 32000); clk_register_clkdev(clk, "osc_32k_clk", NULL); - clk = clk_register_fixed_rate(NULL, "osc_24m_clk", NULL, CLK_IS_ROOT, - 24000000); + clk = clk_register_fixed_rate(NULL, "osc_24m_clk", NULL, 0, 24000000); clk_register_clkdev(clk, "osc_24m_clk", NULL); - clk = clk_register_fixed_rate(NULL, "osc_25m_clk", NULL, CLK_IS_ROOT, - 25000000); + clk = clk_register_fixed_rate(NULL, "osc_25m_clk", NULL, 0, 25000000); clk_register_clkdev(clk, "osc_25m_clk", NULL); - clk = clk_register_fixed_rate(NULL, "gmii_pad_clk", NULL, CLK_IS_ROOT, - 125000000); + clk = clk_register_fixed_rate(NULL, "gmii_pad_clk", NULL, 0, 125000000); clk_register_clkdev(clk, "gmii_pad_clk", NULL); - clk = clk_register_fixed_rate(NULL, "i2s_src_pad_clk", NULL, - CLK_IS_ROOT, 12288000); + clk = clk_register_fixed_rate(NULL, "i2s_src_pad_clk", NULL, 0, + 12288000); clk_register_clkdev(clk, "i2s_src_pad_clk", NULL); /* clock derived from 32 KHz osc clk */ @@ -897,11 +893,10 @@ void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base) &_lock); clk_register_clkdev(clk, "ras_apb_clk", NULL); - clk = clk_register_fixed_rate(NULL, "ras_plclk0_clk", NULL, CLK_IS_ROOT, + clk = clk_register_fixed_rate(NULL, "ras_plclk0_clk", NULL, 0, 50000000); - clk = clk_register_fixed_rate(NULL, "ras_tx50_clk", NULL, CLK_IS_ROOT, - 50000000); + clk = clk_register_fixed_rate(NULL, "ras_tx50_clk", NULL, 0, 50000000); clk = clk_register_gate(NULL, "can0_clk", "apb_clk", 0, SPEAR1310_RAS_SW_CLK_CTRL, SPEAR1310_CAN0_CLK_ENB, 0, diff --git a/drivers/clk/spear/spear1340_clock.c b/drivers/clk/spear/spear1340_clock.c index 9c7abfd951baa2fa91950dd0e4b0a2a76f8fecb5..cbb19a90f2d614569f48ad7ffec1c287714e5810 100644 --- a/drivers/clk/spear/spear1340_clock.c +++ b/drivers/clk/spear/spear1340_clock.c @@ -443,24 +443,20 @@ void __init spear1340_clk_init(void __iomem *misc_base) { struct clk *clk, *clk1; - clk = clk_register_fixed_rate(NULL, "osc_32k_clk", NULL, CLK_IS_ROOT, - 32000); + clk = clk_register_fixed_rate(NULL, "osc_32k_clk", NULL, 0, 32000); clk_register_clkdev(clk, "osc_32k_clk", NULL); - clk = clk_register_fixed_rate(NULL, "osc_24m_clk", NULL, CLK_IS_ROOT, - 24000000); + clk = clk_register_fixed_rate(NULL, "osc_24m_clk", NULL, 0, 24000000); clk_register_clkdev(clk, "osc_24m_clk", NULL); - clk = clk_register_fixed_rate(NULL, "osc_25m_clk", NULL, CLK_IS_ROOT, - 25000000); + clk = clk_register_fixed_rate(NULL, "osc_25m_clk", NULL, 0, 25000000); clk_register_clkdev(clk, "osc_25m_clk", NULL); - clk = clk_register_fixed_rate(NULL, "gmii_pad_clk", NULL, CLK_IS_ROOT, - 125000000); + clk = clk_register_fixed_rate(NULL, "gmii_pad_clk", NULL, 0, 125000000); clk_register_clkdev(clk, "gmii_pad_clk", NULL); - clk = clk_register_fixed_rate(NULL, "i2s_src_pad_clk", NULL, - CLK_IS_ROOT, 12288000); + clk = clk_register_fixed_rate(NULL, "i2s_src_pad_clk", NULL, 0, + 12288000); clk_register_clkdev(clk, "i2s_src_pad_clk", NULL); /* clock derived from 32 KHz osc clk */ diff --git a/drivers/clk/spear/spear3xx_clock.c b/drivers/clk/spear/spear3xx_clock.c index 404a55edd613d102f00bda3e127f7125b07fed88..c403c66b6583d15c90bd2f6473368d6bbcc25b6b 100644 --- a/drivers/clk/spear/spear3xx_clock.c +++ b/drivers/clk/spear/spear3xx_clock.c @@ -251,7 +251,7 @@ static void __init spear320_clk_init(void __iomem *soc_config_base, struct clk *clk; clk = clk_register_fixed_rate(NULL, "smii_125m_pad_clk", NULL, - CLK_IS_ROOT, 125000000); + 0, 125000000); clk_register_clkdev(clk, "smii_125m_pad", NULL); clk = clk_register_fixed_factor(NULL, "clcd_clk", "ras_pll3_clk", 0, @@ -391,12 +391,10 @@ void __init spear3xx_clk_init(void __iomem *misc_base, void __iomem *soc_config_ { struct clk *clk, *clk1, *ras_apb_clk; - clk = clk_register_fixed_rate(NULL, "osc_32k_clk", NULL, CLK_IS_ROOT, - 32000); + clk = clk_register_fixed_rate(NULL, "osc_32k_clk", NULL, 0, 32000); clk_register_clkdev(clk, "osc_32k_clk", NULL); - clk = clk_register_fixed_rate(NULL, "osc_24m_clk", NULL, CLK_IS_ROOT, - 24000000); + clk = clk_register_fixed_rate(NULL, "osc_24m_clk", NULL, 0, 24000000); clk_register_clkdev(clk, "osc_24m_clk", NULL); /* clock derived from 32 KHz osc clk */ diff --git a/drivers/clk/spear/spear6xx_clock.c b/drivers/clk/spear/spear6xx_clock.c index e24f85cd4300f39845f8bd8dd065ee5fceb1940b..7c9383c3c2c6085ab4e2ae18dff0b8e3df8ee372 100644 --- a/drivers/clk/spear/spear6xx_clock.c +++ b/drivers/clk/spear/spear6xx_clock.c @@ -117,12 +117,10 @@ void __init spear6xx_clk_init(void __iomem *misc_base) { struct clk *clk, *clk1; - clk = clk_register_fixed_rate(NULL, "osc_32k_clk", NULL, CLK_IS_ROOT, - 32000); + clk = clk_register_fixed_rate(NULL, "osc_32k_clk", NULL, 0, 32000); clk_register_clkdev(clk, "osc_32k_clk", NULL); - clk = clk_register_fixed_rate(NULL, "osc_30m_clk", NULL, CLK_IS_ROOT, - 30000000); + clk = clk_register_fixed_rate(NULL, "osc_30m_clk", NULL, 0, 30000000); clk_register_clkdev(clk, "osc_30m_clk", NULL); /* clock derived from 32 KHz osc clk */ diff --git a/drivers/clk/st/clk-flexgen.c b/drivers/clk/st/clk-flexgen.c index 24d99594c0b30d667251754982ebff75e1a56e26..627267c7ec5c0be3a09ca12fca851e039e0baf06 100644 --- a/drivers/clk/st/clk-flexgen.c +++ b/drivers/clk/st/clk-flexgen.c @@ -244,10 +244,10 @@ static const char ** __init flexgen_get_parents(struct device_node *np, int *num_parents) { const char **parents; - int nparents; + unsigned int nparents; nparents = of_clk_get_parent_count(np); - if (WARN_ON(nparents <= 0)) + if (WARN_ON(!nparents)) return NULL; parents = kcalloc(nparents, sizeof(const char *), GFP_KERNEL); diff --git a/drivers/clk/st/clkgen-fsyn.c b/drivers/clk/st/clkgen-fsyn.c index ccb324d97160d7756dd8e187633091c4e67064ce..dec4eaaecc0006c24aadac0a969e050505bb141c 100644 --- a/drivers/clk/st/clkgen-fsyn.c +++ b/drivers/clk/st/clkgen-fsyn.c @@ -574,12 +574,16 @@ static int quadfs_pll_fs660c32_set_rate(struct clk_hw *hw, unsigned long rate, struct stm_fs params; long hwrate = 0; unsigned long flags = 0; + int ret; if (!rate || !parent_rate) return -EINVAL; - if (!clk_fs660c32_vco_get_params(parent_rate, rate, ¶ms)) - clk_fs660c32_vco_get_rate(parent_rate, ¶ms, &hwrate); + ret = clk_fs660c32_vco_get_params(parent_rate, rate, ¶ms); + if (ret) + return ret; + + clk_fs660c32_vco_get_rate(parent_rate, ¶ms, &hwrate); pr_debug("%s: %s new rate %ld [ndiv=0x%x]\n", __func__, clk_hw_get_name(hw), diff --git a/drivers/clk/st/clkgen-mux.c b/drivers/clk/st/clkgen-mux.c index 5dc5ce21796065df6739d4e395a35ce5c50375b2..b1e10ffe7a4436134148d7bcc035b5498a5e2e51 100644 --- a/drivers/clk/st/clkgen-mux.c +++ b/drivers/clk/st/clkgen-mux.c @@ -26,10 +26,10 @@ static const char ** __init clkgen_mux_get_parents(struct device_node *np, int *num_parents) { const char **parents; - int nparents; + unsigned int nparents; nparents = of_clk_get_parent_count(np); - if (WARN_ON(nparents <= 0)) + if (WARN_ON(!nparents)) return ERR_PTR(-EINVAL); parents = kcalloc(nparents, sizeof(const char *), GFP_KERNEL); @@ -822,11 +822,10 @@ static void __init st_of_clkgen_vcc_setup(struct device_node *np) if (!clk_data->clks[i]) continue; - composite = container_of(__clk_get_hw(clk_data->clks[i]), - struct clk_composite, hw); - kfree(container_of(composite->gate_hw, struct clk_gate, hw)); - kfree(container_of(composite->rate_hw, struct clk_divider, hw)); - kfree(container_of(composite->mux_hw, struct clk_mux, hw)); + composite = to_clk_composite(__clk_get_hw(clk_data->clks[i])); + kfree(to_clk_gate(composite->gate_hw)); + kfree(to_clk_divider(composite->rate_hw)); + kfree(to_clk_mux(composite->mux_hw)); } kfree(clk_data->clks); diff --git a/drivers/clk/sunxi/clk-a10-hosc.c b/drivers/clk/sunxi/clk-a10-hosc.c index 0481d5d673d68a718a8052762c66b78d482543eb..6b598c6a02136d64bee24e23bc0d61ec8d8733c6 100644 --- a/drivers/clk/sunxi/clk-a10-hosc.c +++ b/drivers/clk/sunxi/clk-a10-hosc.c @@ -15,9 +15,9 @@ */ #include -#include #include #include +#include #define SUNXI_OSC24M_GATE 0 @@ -61,7 +61,6 @@ static void __init sun4i_osc_clk_setup(struct device_node *node) goto err_free_gate; of_clk_add_provider(node, of_clk_src_simple_get, clk); - clk_register_clkdev(clk, clk_name, NULL); return; diff --git a/drivers/clk/sunxi/clk-a10-ve.c b/drivers/clk/sunxi/clk-a10-ve.c index 044c1717b762a6568c22d5929fb0a5713094475b..d9ea22ec4e258b0dc29024d1549086b89a668852 100644 --- a/drivers/clk/sunxi/clk-a10-ve.c +++ b/drivers/clk/sunxi/clk-a10-ve.c @@ -85,7 +85,7 @@ static int sunxi_ve_of_xlate(struct reset_controller_dev *rcdev, return 0; } -static struct reset_control_ops sunxi_ve_reset_ops = { +static const struct reset_control_ops sunxi_ve_reset_ops = { .assert = sunxi_ve_reset_assert, .deassert = sunxi_ve_reset_deassert, }; diff --git a/drivers/clk/sunxi/clk-a20-gmac.c b/drivers/clk/sunxi/clk-a20-gmac.c index 1611b036421c20e76f438e13fb326111b24e5cda..3437f734c9bf1f7e2ba95051f2debbf71b3c3444 100644 --- a/drivers/clk/sunxi/clk-a20-gmac.c +++ b/drivers/clk/sunxi/clk-a20-gmac.c @@ -17,7 +17,6 @@ */ #include -#include #include #include #include @@ -107,7 +106,6 @@ static void __init sun7i_a20_gmac_clk_setup(struct device_node *node) goto iounmap_reg; of_clk_add_provider(node, of_clk_src_simple_get, clk); - clk_register_clkdev(clk, clk_name, NULL); return; diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c index 59428dbd607a85d3ff15e3b648f529e1a575abf9..ddefe9668863b0ffbaebfc5e33c709c49c2486e2 100644 --- a/drivers/clk/sunxi/clk-factors.c +++ b/drivers/clk/sunxi/clk-factors.c @@ -48,7 +48,7 @@ static unsigned long clk_factors_recalc_rate(struct clk_hw *hw, u32 reg; unsigned long rate; struct clk_factors *factors = to_clk_factors(hw); - struct clk_factors_config *config = factors->config; + const struct clk_factors_config *config = factors->config; /* Fetch the register value */ reg = readl(factors->reg); @@ -63,18 +63,28 @@ static unsigned long clk_factors_recalc_rate(struct clk_hw *hw, if (config->pwidth != SUNXI_FACTORS_NOT_APPLICABLE) p = FACTOR_GET(config->pshift, config->pwidth, reg); - /* Calculate the rate */ - rate = (parent_rate * (n + config->n_start) * (k + 1) >> p) / (m + 1); + if (factors->recalc) { + struct factors_request factors_req = { + .parent_rate = parent_rate, + .n = n, + .k = k, + .m = m, + .p = p, + }; - return rate; -} + /* get mux details from mux clk structure */ + if (factors->mux) + factors_req.parent_index = + (reg >> factors->mux->shift) & + factors->mux->mask; -static long clk_factors_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) -{ - struct clk_factors *factors = to_clk_factors(hw); - factors->get_factors((u32 *)&rate, (u32)*parent_rate, - NULL, NULL, NULL, NULL); + factors->recalc(&factors_req); + + return factors_req.rate; + } + + /* Calculate the rate */ + rate = (parent_rate * (n + config->n_start) * (k + 1) >> p) / (m + 1); return rate; } @@ -82,6 +92,7 @@ static long clk_factors_round_rate(struct clk_hw *hw, unsigned long rate, static int clk_factors_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { + struct clk_factors *factors = to_clk_factors(hw); struct clk_hw *parent, *best_parent = NULL; int i, num_parents; unsigned long parent_rate, best = 0, child_rate, best_child_rate = 0; @@ -89,6 +100,10 @@ static int clk_factors_determine_rate(struct clk_hw *hw, /* find the parent that can help provide the fastest rate <= rate */ num_parents = clk_hw_get_num_parents(hw); for (i = 0; i < num_parents; i++) { + struct factors_request factors_req = { + .rate = req->rate, + .parent_index = i, + }; parent = clk_hw_get_parent_by_index(hw, i); if (!parent) continue; @@ -97,8 +112,9 @@ static int clk_factors_determine_rate(struct clk_hw *hw, else parent_rate = clk_hw_get_rate(parent); - child_rate = clk_factors_round_rate(hw, req->rate, - &parent_rate); + factors_req.parent_rate = parent_rate; + factors->get_factors(&factors_req); + child_rate = factors_req.rate; if (child_rate <= req->rate && child_rate > best_child_rate) { best_parent = parent; @@ -120,13 +136,16 @@ static int clk_factors_determine_rate(struct clk_hw *hw, static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { - u8 n = 0, k = 0, m = 0, p = 0; + struct factors_request req = { + .rate = rate, + .parent_rate = parent_rate, + }; u32 reg; struct clk_factors *factors = to_clk_factors(hw); - struct clk_factors_config *config = factors->config; + const struct clk_factors_config *config = factors->config; unsigned long flags = 0; - factors->get_factors((u32 *)&rate, (u32)parent_rate, &n, &k, &m, &p); + factors->get_factors(&req); if (factors->lock) spin_lock_irqsave(factors->lock, flags); @@ -135,10 +154,10 @@ static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate, reg = readl(factors->reg); /* Set up the new factors - macros do not do anything if width is 0 */ - reg = FACTOR_SET(config->nshift, config->nwidth, reg, n); - reg = FACTOR_SET(config->kshift, config->kwidth, reg, k); - reg = FACTOR_SET(config->mshift, config->mwidth, reg, m); - reg = FACTOR_SET(config->pshift, config->pwidth, reg, p); + reg = FACTOR_SET(config->nshift, config->nwidth, reg, req.n); + reg = FACTOR_SET(config->kshift, config->kwidth, reg, req.k); + reg = FACTOR_SET(config->mshift, config->mwidth, reg, req.m); + reg = FACTOR_SET(config->pshift, config->pwidth, reg, req.p); /* Apply them now */ writel(reg, factors->reg); @@ -155,7 +174,6 @@ static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops clk_factors_ops = { .determine_rate = clk_factors_determine_rate, .recalc_rate = clk_factors_recalc_rate, - .round_rate = clk_factors_round_rate, .set_rate = clk_factors_set_rate, }; @@ -172,7 +190,7 @@ struct clk *sunxi_factors_register(struct device_node *node, struct clk_hw *mux_hw = NULL; const char *clk_name = node->name; const char *parents[FACTORS_MAX_PARENTS]; - int i = 0; + int ret, i = 0; /* if we have a mux, we will have >1 parents */ i = of_clk_parent_fill(node, parents, FACTORS_MAX_PARENTS); @@ -188,21 +206,22 @@ struct clk *sunxi_factors_register(struct device_node *node, factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL); if (!factors) - return NULL; + goto err_factors; /* set up factors properties */ factors->reg = reg; factors->config = data->table; factors->get_factors = data->getter; + factors->recalc = data->recalc; factors->lock = lock; /* Add a gate if this factor clock can be gated */ if (data->enable) { gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); - if (!gate) { - kfree(factors); - return NULL; - } + if (!gate) + goto err_gate; + + factors->gate = gate; /* set up gate properties */ gate->reg = reg; @@ -214,11 +233,10 @@ struct clk *sunxi_factors_register(struct device_node *node, /* Add a mux if this factor clock can be muxed */ if (data->mux) { mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL); - if (!mux) { - kfree(factors); - kfree(gate); - return NULL; - } + if (!mux) + goto err_mux; + + factors->mux = mux; /* set up gate properties */ mux->reg = reg; @@ -233,11 +251,44 @@ struct clk *sunxi_factors_register(struct device_node *node, mux_hw, &clk_mux_ops, &factors->hw, &clk_factors_ops, gate_hw, &clk_gate_ops, 0); + if (IS_ERR(clk)) + goto err_register; - if (!IS_ERR(clk)) { - of_clk_add_provider(node, of_clk_src_simple_get, clk); - clk_register_clkdev(clk, clk_name, NULL); - } + ret = of_clk_add_provider(node, of_clk_src_simple_get, clk); + if (ret) + goto err_provider; return clk; + +err_provider: + /* TODO: The composite clock stuff will leak a bit here. */ + clk_unregister(clk); +err_register: + kfree(mux); +err_mux: + kfree(gate); +err_gate: + kfree(factors); +err_factors: + return NULL; +} + +void sunxi_factors_unregister(struct device_node *node, struct clk *clk) +{ + struct clk_hw *hw = __clk_get_hw(clk); + struct clk_factors *factors; + const char *name; + + if (!hw) + return; + + factors = to_clk_factors(hw); + name = clk_hw_get_name(hw); + + of_clk_del_provider(node); + /* TODO: The composite clock stuff will leak a bit here. */ + clk_unregister(clk); + kfree(factors->mux); + kfree(factors->gate); + kfree(factors); } diff --git a/drivers/clk/sunxi/clk-factors.h b/drivers/clk/sunxi/clk-factors.h index 171085ab5513e4f724017d05d6f91929262a4f78..1e63c5b2d5f4cb6866127100be2274a7095641cd 100644 --- a/drivers/clk/sunxi/clk-factors.h +++ b/drivers/clk/sunxi/clk-factors.h @@ -2,7 +2,6 @@ #define __MACH_SUNXI_CLK_FACTORS_H #include -#include #include #define SUNXI_FACTORS_NOT_APPLICABLE (0) @@ -19,21 +18,36 @@ struct clk_factors_config { u8 n_start; }; +struct factors_request { + unsigned long rate; + unsigned long parent_rate; + u8 parent_index; + u8 n; + u8 k; + u8 m; + u8 p; +}; + struct factors_data { int enable; int mux; int muxmask; - struct clk_factors_config *table; - void (*getter) (u32 *rate, u32 parent_rate, u8 *n, u8 *k, u8 *m, u8 *p); + const struct clk_factors_config *table; + void (*getter)(struct factors_request *req); + void (*recalc)(struct factors_request *req); const char *name; }; struct clk_factors { struct clk_hw hw; void __iomem *reg; - struct clk_factors_config *config; - void (*get_factors) (u32 *rate, u32 parent, u8 *n, u8 *k, u8 *m, u8 *p); + const struct clk_factors_config *config; + void (*get_factors)(struct factors_request *req); + void (*recalc)(struct factors_request *req); spinlock_t *lock; + /* for cleanup */ + struct clk_mux *mux; + struct clk_gate *gate; }; struct clk *sunxi_factors_register(struct device_node *node, @@ -41,4 +55,6 @@ struct clk *sunxi_factors_register(struct device_node *node, spinlock_t *lock, void __iomem *reg); +void sunxi_factors_unregister(struct device_node *node, struct clk *clk); + #endif diff --git a/drivers/clk/sunxi/clk-mod0.c b/drivers/clk/sunxi/clk-mod0.c index d167e1efb92761a0f223a6054787587d58b11152..b38d71cec74c78300fce175de198cbd3fcb12623 100644 --- a/drivers/clk/sunxi/clk-mod0.c +++ b/drivers/clk/sunxi/clk-mod0.c @@ -15,6 +15,7 @@ */ #include +#include #include #include #include @@ -28,17 +29,16 @@ * rate = (parent_rate >> p) / (m + 1); */ -static void sun4i_a10_get_mod0_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun4i_a10_get_mod0_factors(struct factors_request *req) { u8 div, calcm, calcp; /* These clocks can only divide, so we will never be able to achieve * frequencies higher than the parent frequency */ - if (*freq > parent_rate) - *freq = parent_rate; + if (req->rate > req->parent_rate) + req->rate = req->parent_rate; - div = DIV_ROUND_UP(parent_rate, *freq); + div = DIV_ROUND_UP(req->parent_rate, req->rate); if (div < 16) calcp = 0; @@ -51,18 +51,13 @@ static void sun4i_a10_get_mod0_factors(u32 *freq, u32 parent_rate, calcm = DIV_ROUND_UP(div, 1 << calcp); - *freq = (parent_rate >> calcp) / calcm; - - /* we were called to round the frequency, we can now return */ - if (n == NULL) - return; - - *m = calcm - 1; - *p = calcp; + req->rate = (req->parent_rate >> calcp) / calcm; + req->m = calcm - 1; + req->p = calcp; } /* user manual says "n" but it's really "p" */ -static struct clk_factors_config sun4i_a10_mod0_config = { +static const struct clk_factors_config sun4i_a10_mod0_config = { .mshift = 0, .mwidth = 4, .pshift = 16, diff --git a/drivers/clk/sunxi/clk-simple-gates.c b/drivers/clk/sunxi/clk-simple-gates.c index f4da52b5ca0e838d37531a4cccf1e2d1941180f5..a085c3bc127c5d33fd4c4dfd1dbd00cced8e040a 100644 --- a/drivers/clk/sunxi/clk-simple-gates.c +++ b/drivers/clk/sunxi/clk-simple-gates.c @@ -98,6 +98,8 @@ static void __init sunxi_simple_gates_init(struct device_node *node) sunxi_simple_gates_setup(node, NULL, 0); } +CLK_OF_DECLARE(sun4i_a10_gates, "allwinner,sun4i-a10-gates-clk", + sunxi_simple_gates_init); CLK_OF_DECLARE(sun4i_a10_apb0, "allwinner,sun4i-a10-apb0-gates-clk", sunxi_simple_gates_init); CLK_OF_DECLARE(sun4i_a10_apb1, "allwinner,sun4i-a10-apb1-gates-clk", @@ -130,6 +132,8 @@ CLK_OF_DECLARE(sun8i_a23_apb2, "allwinner,sun8i-a23-apb2-gates-clk", sunxi_simple_gates_init); CLK_OF_DECLARE(sun8i_a33_ahb1, "allwinner,sun8i-a33-ahb1-gates-clk", sunxi_simple_gates_init); +CLK_OF_DECLARE(sun8i_a83t_apb0, "allwinner,sun8i-a83t-apb0-gates-clk", + sunxi_simple_gates_init); CLK_OF_DECLARE(sun9i_a80_ahb0, "allwinner,sun9i-a80-ahb0-gates-clk", sunxi_simple_gates_init); CLK_OF_DECLARE(sun9i_a80_ahb1, "allwinner,sun9i-a80-ahb1-gates-clk", diff --git a/drivers/clk/sunxi/clk-sun6i-apb0-gates.c b/drivers/clk/sunxi/clk-sun6i-apb0-gates.c index 23d042aabb4f7724d2cf1602b8a2b1f4028a8c41..68021fa5ecd9af5026a941940e0496329b567d5a 100644 --- a/drivers/clk/sunxi/clk-sun6i-apb0-gates.c +++ b/drivers/clk/sunxi/clk-sun6i-apb0-gates.c @@ -9,7 +9,6 @@ */ #include -#include #include #include #include @@ -87,7 +86,6 @@ static int sun6i_a31_apb0_gates_clk_probe(struct platform_device *pdev) clk_parent, 0, reg, i, 0, NULL); WARN_ON(IS_ERR(clk_data->clks[i])); - clk_register_clkdev(clk_data->clks[i], clk_name, NULL); j++; } diff --git a/drivers/clk/sunxi/clk-sun6i-ar100.c b/drivers/clk/sunxi/clk-sun6i-ar100.c index 20887686bdbee09fe7fbc90963f179ed45c651ab..84a187e55360fce909cdb5564aeffa423193d84c 100644 --- a/drivers/clk/sunxi/clk-sun6i-ar100.c +++ b/drivers/clk/sunxi/clk-sun6i-ar100.c @@ -8,211 +8,97 @@ * */ +#include #include #include #include #include +#include -#define SUN6I_AR100_MAX_PARENTS 4 -#define SUN6I_AR100_SHIFT_MASK 0x3 -#define SUN6I_AR100_SHIFT_MAX SUN6I_AR100_SHIFT_MASK -#define SUN6I_AR100_SHIFT_SHIFT 4 -#define SUN6I_AR100_DIV_MASK 0x1f -#define SUN6I_AR100_DIV_MAX (SUN6I_AR100_DIV_MASK + 1) -#define SUN6I_AR100_DIV_SHIFT 8 -#define SUN6I_AR100_MUX_MASK 0x3 -#define SUN6I_AR100_MUX_SHIFT 16 - -struct ar100_clk { - struct clk_hw hw; - void __iomem *reg; -}; - -static inline struct ar100_clk *to_ar100_clk(struct clk_hw *hw) -{ - return container_of(hw, struct ar100_clk, hw); -} - -static unsigned long ar100_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct ar100_clk *clk = to_ar100_clk(hw); - u32 val = readl(clk->reg); - int shift = (val >> SUN6I_AR100_SHIFT_SHIFT) & SUN6I_AR100_SHIFT_MASK; - int div = (val >> SUN6I_AR100_DIV_SHIFT) & SUN6I_AR100_DIV_MASK; - - return (parent_rate >> shift) / (div + 1); -} - -static int ar100_determine_rate(struct clk_hw *hw, - struct clk_rate_request *req) -{ - int nparents = clk_hw_get_num_parents(hw); - long best_rate = -EINVAL; - int i; - - req->best_parent_hw = NULL; - - for (i = 0; i < nparents; i++) { - unsigned long parent_rate; - unsigned long tmp_rate; - struct clk_hw *parent; - unsigned long div; - int shift; - - parent = clk_hw_get_parent_by_index(hw, i); - parent_rate = clk_hw_get_rate(parent); - div = DIV_ROUND_UP(parent_rate, req->rate); - - /* - * The AR100 clk contains 2 divisors: - * - one power of 2 divisor - * - one regular divisor - * - * First check if we can safely shift (or divide by a power - * of 2) without losing precision on the requested rate. - */ - shift = ffs(div) - 1; - if (shift > SUN6I_AR100_SHIFT_MAX) - shift = SUN6I_AR100_SHIFT_MAX; - - div >>= shift; - - /* - * Then if the divisor is still bigger than what the HW - * actually supports, use a bigger shift (or power of 2 - * divider) value and accept to lose some precision. - */ - while (div > SUN6I_AR100_DIV_MAX) { - shift++; - div >>= 1; - if (shift > SUN6I_AR100_SHIFT_MAX) - break; - } - - /* - * If the shift value (or power of 2 divider) is bigger - * than what the HW actually support, skip this parent. - */ - if (shift > SUN6I_AR100_SHIFT_MAX) - continue; - - tmp_rate = (parent_rate >> shift) / div; - if (!req->best_parent_hw || tmp_rate > best_rate) { - req->best_parent_hw = parent; - req->best_parent_rate = parent_rate; - best_rate = tmp_rate; - } - } - - if (best_rate < 0) - return best_rate; - - req->rate = best_rate; - - return 0; -} - -static int ar100_set_parent(struct clk_hw *hw, u8 index) -{ - struct ar100_clk *clk = to_ar100_clk(hw); - u32 val = readl(clk->reg); - - if (index >= SUN6I_AR100_MAX_PARENTS) - return -EINVAL; - - val &= ~(SUN6I_AR100_MUX_MASK << SUN6I_AR100_MUX_SHIFT); - val |= (index << SUN6I_AR100_MUX_SHIFT); - writel(val, clk->reg); - - return 0; -} +#include "clk-factors.h" -static u8 ar100_get_parent(struct clk_hw *hw) -{ - struct ar100_clk *clk = to_ar100_clk(hw); - return (readl(clk->reg) >> SUN6I_AR100_MUX_SHIFT) & - SUN6I_AR100_MUX_MASK; -} - -static int ar100_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) +/** + * sun6i_get_ar100_factors - Calculates factors p, m for AR100 + * + * AR100 rate is calculated as follows + * rate = (parent_rate >> p) / (m + 1); + */ +static void sun6i_get_ar100_factors(struct factors_request *req) { - unsigned long div = parent_rate / rate; - struct ar100_clk *clk = to_ar100_clk(hw); - u32 val = readl(clk->reg); + unsigned long div; int shift; - if (parent_rate % rate) - return -EINVAL; + /* clock only divides */ + if (req->rate > req->parent_rate) + req->rate = req->parent_rate; - shift = ffs(div) - 1; - if (shift > SUN6I_AR100_SHIFT_MAX) - shift = SUN6I_AR100_SHIFT_MAX; + div = DIV_ROUND_UP(req->parent_rate, req->rate); - div >>= shift; + if (div < 32) + shift = 0; + else if (div >> 1 < 32) + shift = 1; + else if (div >> 2 < 32) + shift = 2; + else + shift = 3; - if (div > SUN6I_AR100_DIV_MAX) - return -EINVAL; + div >>= shift; - val &= ~((SUN6I_AR100_SHIFT_MASK << SUN6I_AR100_SHIFT_SHIFT) | - (SUN6I_AR100_DIV_MASK << SUN6I_AR100_DIV_SHIFT)); - val |= (shift << SUN6I_AR100_SHIFT_SHIFT) | - (div << SUN6I_AR100_DIV_SHIFT); - writel(val, clk->reg); + if (div > 32) + div = 32; - return 0; + req->rate = (req->parent_rate >> shift) / div; + req->m = div - 1; + req->p = shift; } -static struct clk_ops ar100_ops = { - .recalc_rate = ar100_recalc_rate, - .determine_rate = ar100_determine_rate, - .set_parent = ar100_set_parent, - .get_parent = ar100_get_parent, - .set_rate = ar100_set_rate, +static const struct clk_factors_config sun6i_ar100_config = { + .mwidth = 5, + .mshift = 8, + .pwidth = 2, + .pshift = 4, }; +static const struct factors_data sun6i_ar100_data = { + .mux = 16, + .muxmask = GENMASK(1, 0), + .table = &sun6i_ar100_config, + .getter = sun6i_get_ar100_factors, +}; + +static DEFINE_SPINLOCK(sun6i_ar100_lock); + static int sun6i_a31_ar100_clk_probe(struct platform_device *pdev) { - const char *parents[SUN6I_AR100_MAX_PARENTS]; struct device_node *np = pdev->dev.of_node; - const char *clk_name = np->name; - struct clk_init_data init; - struct ar100_clk *ar100; struct resource *r; + void __iomem *reg; struct clk *clk; - int nparents; - - ar100 = devm_kzalloc(&pdev->dev, sizeof(*ar100), GFP_KERNEL); - if (!ar100) - return -ENOMEM; r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - ar100->reg = devm_ioremap_resource(&pdev->dev, r); - if (IS_ERR(ar100->reg)) - return PTR_ERR(ar100->reg); + reg = devm_ioremap_resource(&pdev->dev, r); + if (IS_ERR(reg)) + return PTR_ERR(reg); - nparents = of_clk_get_parent_count(np); - if (nparents > SUN6I_AR100_MAX_PARENTS) - nparents = SUN6I_AR100_MAX_PARENTS; - - of_clk_parent_fill(np, parents, nparents); + clk = sunxi_factors_register(np, &sun6i_ar100_data, &sun6i_ar100_lock, + reg); + if (!clk) + return -ENOMEM; - of_property_read_string(np, "clock-output-names", &clk_name); + platform_set_drvdata(pdev, clk); - init.name = clk_name; - init.ops = &ar100_ops; - init.parent_names = parents; - init.num_parents = nparents; - init.flags = 0; + return 0; +} - ar100->hw.init = &init; +static int sun6i_a31_ar100_clk_remove(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct clk *clk = platform_get_drvdata(pdev); - clk = clk_register(&pdev->dev, &ar100->hw); - if (IS_ERR(clk)) - return PTR_ERR(clk); + sunxi_factors_unregister(np, clk); - return of_clk_add_provider(np, of_clk_src_simple_get, clk); + return 0; } static const struct of_device_id sun6i_a31_ar100_clk_dt_ids[] = { @@ -227,6 +113,7 @@ static struct platform_driver sun6i_a31_ar100_clk_driver = { .of_match_table = sun6i_a31_ar100_clk_dt_ids, }, .probe = sun6i_a31_ar100_clk_probe, + .remove = sun6i_a31_ar100_clk_remove, }; module_platform_driver(sun6i_a31_ar100_clk_driver); diff --git a/drivers/clk/sunxi/clk-sun8i-apb0.c b/drivers/clk/sunxi/clk-sun8i-apb0.c index 7ba61103a6f539d8f7e8ffd25c70f0d1025c3a6f..2ea61debffc180162d51cc437b173dc4ee831890 100644 --- a/drivers/clk/sunxi/clk-sun8i-apb0.c +++ b/drivers/clk/sunxi/clk-sun8i-apb0.c @@ -36,7 +36,7 @@ static struct clk *sun8i_a23_apb0_register(struct device_node *node, /* The A23 APB0 clock is a standard 2 bit wide divider clock */ clk = clk_register_divider(NULL, clk_name, clk_parent, 0, reg, - 0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL); + 0, 2, 0, NULL); if (IS_ERR(clk)) return clk; diff --git a/drivers/clk/sunxi/clk-sun8i-bus-gates.c b/drivers/clk/sunxi/clk-sun8i-bus-gates.c index e32d18ba252be91ad308c66f10828a5ff7adcf36..63fdb790df2938ba1f1c35df96020926820ad065 100644 --- a/drivers/clk/sunxi/clk-sun8i-bus-gates.c +++ b/drivers/clk/sunxi/clk-sun8i-bus-gates.c @@ -17,7 +17,6 @@ * GNU General Public License for more details. */ -#include #include #include #include @@ -110,3 +109,5 @@ static void __init sun8i_h3_bus_gates_init(struct device_node *node) CLK_OF_DECLARE(sun8i_h3_bus_gates, "allwinner,sun8i-h3-bus-gates-clk", sun8i_h3_bus_gates_init); +CLK_OF_DECLARE(sun8i_a83t_bus_gates, "allwinner,sun8i-a83t-bus-gates-clk", + sun8i_h3_bus_gates_init); diff --git a/drivers/clk/sunxi/clk-sun8i-mbus.c b/drivers/clk/sunxi/clk-sun8i-mbus.c index bf117a636d2397f6a7059f55962134cade4b3cc0..411d3033a96e9a729fd9b289cf390344a17f415f 100644 --- a/drivers/clk/sunxi/clk-sun8i-mbus.c +++ b/drivers/clk/sunxi/clk-sun8i-mbus.c @@ -15,74 +15,106 @@ */ #include +#include #include +#include +#include #include -#include "clk-factors.h" +#define SUN8I_MBUS_ENABLE 31 +#define SUN8I_MBUS_MUX_SHIFT 24 +#define SUN8I_MBUS_MUX_MASK 0x3 +#define SUN8I_MBUS_DIV_SHIFT 0 +#define SUN8I_MBUS_DIV_WIDTH 3 +#define SUN8I_MBUS_MAX_PARENTS 4 -/** - * sun8i_a23_get_mbus_factors() - calculates m factor for MBUS clocks - * MBUS rate is calculated as follows - * rate = parent_rate / (m + 1); - */ +static DEFINE_SPINLOCK(sun8i_a23_mbus_lock); -static void sun8i_a23_get_mbus_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void __init sun8i_a23_mbus_setup(struct device_node *node) { - u8 div; + int num_parents = of_clk_get_parent_count(node); + const char **parents; + const char *clk_name = node->name; + struct resource res; + struct clk_divider *div; + struct clk_gate *gate; + struct clk_mux *mux; + struct clk *clk; + void __iomem *reg; + int err; - /* - * These clocks can only divide, so we will never be able to - * achieve frequencies higher than the parent frequency - */ - if (*freq > parent_rate) - *freq = parent_rate; + parents = kcalloc(num_parents, sizeof(*parents), GFP_KERNEL); + if (!parents) + return; - div = DIV_ROUND_UP(parent_rate, *freq); + reg = of_io_request_and_map(node, 0, of_node_full_name(node)); + if (!reg) { + pr_err("Could not get registers for sun8i-mbus-clk\n"); + goto err_free_parents; + } - if (div > 8) - div = 8; + div = kzalloc(sizeof(*div), GFP_KERNEL); + if (!div) + goto err_unmap; - *freq = parent_rate / div; + mux = kzalloc(sizeof(*mux), GFP_KERNEL); + if (!mux) + goto err_free_div; - /* we were called to round the frequency, we can now return */ - if (m == NULL) - return; + gate = kzalloc(sizeof(*gate), GFP_KERNEL); + if (!gate) + goto err_free_mux; - *m = div - 1; -} + of_property_read_string(node, "clock-output-names", &clk_name); + of_clk_parent_fill(node, parents, num_parents); -static struct clk_factors_config sun8i_a23_mbus_config = { - .mshift = 0, - .mwidth = 3, -}; + gate->reg = reg; + gate->bit_idx = SUN8I_MBUS_ENABLE; + gate->lock = &sun8i_a23_mbus_lock; -static const struct factors_data sun8i_a23_mbus_data __initconst = { - .enable = 31, - .mux = 24, - .muxmask = BIT(1) | BIT(0), - .table = &sun8i_a23_mbus_config, - .getter = sun8i_a23_get_mbus_factors, -}; + div->reg = reg; + div->shift = SUN8I_MBUS_DIV_SHIFT; + div->width = SUN8I_MBUS_DIV_WIDTH; + div->lock = &sun8i_a23_mbus_lock; -static DEFINE_SPINLOCK(sun8i_a23_mbus_lock); - -static void __init sun8i_a23_mbus_setup(struct device_node *node) -{ - struct clk *mbus; - void __iomem *reg; + mux->reg = reg; + mux->shift = SUN8I_MBUS_MUX_SHIFT; + mux->mask = SUN8I_MBUS_MUX_MASK; + mux->lock = &sun8i_a23_mbus_lock; - reg = of_iomap(node, 0); - if (!reg) { - pr_err("Could not get registers for a23-mbus-clk\n"); - return; - } + clk = clk_register_composite(NULL, clk_name, parents, num_parents, + &mux->hw, &clk_mux_ops, + &div->hw, &clk_divider_ops, + &gate->hw, &clk_gate_ops, + 0); + if (IS_ERR(clk)) + goto err_free_gate; - mbus = sunxi_factors_register(node, &sun8i_a23_mbus_data, - &sun8i_a23_mbus_lock, reg); + err = of_clk_add_provider(node, of_clk_src_simple_get, clk); + if (err) + goto err_unregister_clk; + kfree(parents); /* parents is deep copied */ /* The MBUS clocks needs to be always enabled */ - __clk_get(mbus); - clk_prepare_enable(mbus); + __clk_get(clk); + clk_prepare_enable(clk); + + return; + +err_unregister_clk: + /* TODO: The composite clock stuff will leak a bit here. */ + clk_unregister(clk); +err_free_gate: + kfree(gate); +err_free_mux: + kfree(mux); +err_free_div: + kfree(div); +err_unmap: + iounmap(reg); + of_address_to_resource(node, 0, &res); + release_mem_region(res.start, resource_size(&res)); +err_free_parents: + kfree(parents); } CLK_OF_DECLARE(sun8i_a23_mbus, "allwinner,sun8i-a23-mbus-clk", sun8i_a23_mbus_setup); diff --git a/drivers/clk/sunxi/clk-sun9i-core.c b/drivers/clk/sunxi/clk-sun9i-core.c index 6c4c98324d3cc6800bace1b4a918707e2b4cc53f..43f014f85803109aa5cca03dbe045d05a7a4b120 100644 --- a/drivers/clk/sunxi/clk-sun9i-core.c +++ b/drivers/clk/sunxi/clk-sun9i-core.c @@ -15,6 +15,7 @@ */ #include +#include #include #include #include @@ -32,15 +33,14 @@ * p and m are named div1 and div2 in Allwinner's SDK */ -static void sun9i_a80_get_pll4_factors(u32 *freq, u32 parent_rate, - u8 *n_ret, u8 *k, u8 *m_ret, u8 *p_ret) +static void sun9i_a80_get_pll4_factors(struct factors_request *req) { int n; int m = 1; int p = 1; /* Normalize value to a 6 MHz multiple (24 MHz / 4) */ - n = DIV_ROUND_UP(*freq, 6000000); + n = DIV_ROUND_UP(req->rate, 6000000); /* If n is too large switch to steps of 12 MHz */ if (n > 255) { @@ -60,18 +60,13 @@ static void sun9i_a80_get_pll4_factors(u32 *freq, u32 parent_rate, else if (n < 12) n = 12; - *freq = ((24000000 * n) >> p) / (m + 1); - - /* we were called to round the frequency, we can now return */ - if (n_ret == NULL) - return; - - *n_ret = n; - *m_ret = m; - *p_ret = p; + req->rate = ((24000000 * n) >> p) / (m + 1); + req->n = n; + req->m = m; + req->p = p; } -static struct clk_factors_config sun9i_a80_pll4_config = { +static const struct clk_factors_config sun9i_a80_pll4_config = { .mshift = 18, .mwidth = 1, .nshift = 8, @@ -111,30 +106,24 @@ CLK_OF_DECLARE(sun9i_a80_pll4, "allwinner,sun9i-a80-pll4-clk", sun9i_a80_pll4_se * rate = parent_rate / (m + 1); */ -static void sun9i_a80_get_gt_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun9i_a80_get_gt_factors(struct factors_request *req) { u32 div; - if (parent_rate < *freq) - *freq = parent_rate; + if (req->parent_rate < req->rate) + req->rate = req->parent_rate; - div = DIV_ROUND_UP(parent_rate, *freq); + div = DIV_ROUND_UP(req->parent_rate, req->rate); /* maximum divider is 4 */ if (div > 4) div = 4; - *freq = parent_rate / div; - - /* we were called to round the frequency, we can now return */ - if (!m) - return; - - *m = div; + req->rate = req->parent_rate / div; + req->m = div; } -static struct clk_factors_config sun9i_a80_gt_config = { +static const struct clk_factors_config sun9i_a80_gt_config = { .mshift = 0, .mwidth = 2, }; @@ -176,30 +165,24 @@ CLK_OF_DECLARE(sun9i_a80_gt, "allwinner,sun9i-a80-gt-clk", sun9i_a80_gt_setup); * rate = parent_rate >> p; */ -static void sun9i_a80_get_ahb_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun9i_a80_get_ahb_factors(struct factors_request *req) { u32 _p; - if (parent_rate < *freq) - *freq = parent_rate; + if (req->parent_rate < req->rate) + req->rate = req->parent_rate; - _p = order_base_2(DIV_ROUND_UP(parent_rate, *freq)); + _p = order_base_2(DIV_ROUND_UP(req->parent_rate, req->rate)); /* maximum p is 3 */ if (_p > 3) _p = 3; - *freq = parent_rate >> _p; - - /* we were called to round the frequency, we can now return */ - if (!p) - return; - - *p = _p; + req->rate = req->parent_rate >> _p; + req->p = _p; } -static struct clk_factors_config sun9i_a80_ahb_config = { +static const struct clk_factors_config sun9i_a80_ahb_config = { .pshift = 0, .pwidth = 2, }; @@ -262,34 +245,25 @@ CLK_OF_DECLARE(sun9i_a80_apb0, "allwinner,sun9i-a80-apb0-clk", sun9i_a80_apb0_se * rate = (parent_rate >> p) / (m + 1); */ -static void sun9i_a80_get_apb1_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun9i_a80_get_apb1_factors(struct factors_request *req) { u32 div; - u8 calcm, calcp; - if (parent_rate < *freq) - *freq = parent_rate; + if (req->parent_rate < req->rate) + req->rate = req->parent_rate; - div = DIV_ROUND_UP(parent_rate, *freq); + div = DIV_ROUND_UP(req->parent_rate, req->rate); /* Highest possible divider is 256 (p = 3, m = 31) */ if (div > 256) div = 256; - calcp = order_base_2(div); - calcm = (parent_rate >> calcp) - 1; - *freq = (parent_rate >> calcp) / (calcm + 1); - - /* we were called to round the frequency, we can now return */ - if (n == NULL) - return; - - *m = calcm; - *p = calcp; + req->p = order_base_2(div); + req->m = (req->parent_rate >> req->p) - 1; + req->rate = (req->parent_rate >> req->p) / (req->m + 1); } -static struct clk_factors_config sun9i_a80_apb1_config = { +static const struct clk_factors_config sun9i_a80_apb1_config = { .mshift = 0, .mwidth = 5, .pshift = 16, diff --git a/drivers/clk/sunxi/clk-sun9i-mmc.c b/drivers/clk/sunxi/clk-sun9i-mmc.c index a9b176139aca8b159329e25ef76b805825423229..028dd832a39f6f75b93021e4cd12ea5b7cc586f9 100644 --- a/drivers/clk/sunxi/clk-sun9i-mmc.c +++ b/drivers/clk/sunxi/clk-sun9i-mmc.c @@ -83,7 +83,7 @@ static int sun9i_mmc_reset_deassert(struct reset_controller_dev *rcdev, return 0; } -static struct reset_control_ops sun9i_mmc_reset_ops = { +static const struct reset_control_ops sun9i_mmc_reset_ops = { .assert = sun9i_mmc_reset_assert, .deassert = sun9i_mmc_reset_deassert, }; diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index 5ba2188ee99ccaa1f806113073c2e21b17813e5f..91de0a0067734c184c26c92d49f08ce285ab6e8c 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -28,214 +28,6 @@ static DEFINE_SPINLOCK(clk_lock); -/** - * sun6i_a31_ahb1_clk_setup() - Setup function for a31 ahb1 composite clk - */ - -#define SUN6I_AHB1_MAX_PARENTS 4 -#define SUN6I_AHB1_MUX_PARENT_PLL6 3 -#define SUN6I_AHB1_MUX_SHIFT 12 -/* un-shifted mask is what mux_clk expects */ -#define SUN6I_AHB1_MUX_MASK 0x3 -#define SUN6I_AHB1_MUX_GET_PARENT(reg) ((reg >> SUN6I_AHB1_MUX_SHIFT) & \ - SUN6I_AHB1_MUX_MASK) - -#define SUN6I_AHB1_DIV_SHIFT 4 -#define SUN6I_AHB1_DIV_MASK (0x3 << SUN6I_AHB1_DIV_SHIFT) -#define SUN6I_AHB1_DIV_GET(reg) ((reg & SUN6I_AHB1_DIV_MASK) >> \ - SUN6I_AHB1_DIV_SHIFT) -#define SUN6I_AHB1_DIV_SET(reg, div) ((reg & ~SUN6I_AHB1_DIV_MASK) | \ - (div << SUN6I_AHB1_DIV_SHIFT)) -#define SUN6I_AHB1_PLL6_DIV_SHIFT 6 -#define SUN6I_AHB1_PLL6_DIV_MASK (0x3 << SUN6I_AHB1_PLL6_DIV_SHIFT) -#define SUN6I_AHB1_PLL6_DIV_GET(reg) ((reg & SUN6I_AHB1_PLL6_DIV_MASK) >> \ - SUN6I_AHB1_PLL6_DIV_SHIFT) -#define SUN6I_AHB1_PLL6_DIV_SET(reg, div) ((reg & ~SUN6I_AHB1_PLL6_DIV_MASK) | \ - (div << SUN6I_AHB1_PLL6_DIV_SHIFT)) - -struct sun6i_ahb1_clk { - struct clk_hw hw; - void __iomem *reg; -}; - -#define to_sun6i_ahb1_clk(_hw) container_of(_hw, struct sun6i_ahb1_clk, hw) - -static unsigned long sun6i_ahb1_clk_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct sun6i_ahb1_clk *ahb1 = to_sun6i_ahb1_clk(hw); - unsigned long rate; - u32 reg; - - /* Fetch the register value */ - reg = readl(ahb1->reg); - - /* apply pre-divider first if parent is pll6 */ - if (SUN6I_AHB1_MUX_GET_PARENT(reg) == SUN6I_AHB1_MUX_PARENT_PLL6) - parent_rate /= SUN6I_AHB1_PLL6_DIV_GET(reg) + 1; - - /* clk divider */ - rate = parent_rate >> SUN6I_AHB1_DIV_GET(reg); - - return rate; -} - -static long sun6i_ahb1_clk_round(unsigned long rate, u8 *divp, u8 *pre_divp, - u8 parent, unsigned long parent_rate) -{ - u8 div, calcp, calcm = 1; - - /* - * clock can only divide, so we will never be able to achieve - * frequencies higher than the parent frequency - */ - if (parent_rate && rate > parent_rate) - rate = parent_rate; - - div = DIV_ROUND_UP(parent_rate, rate); - - /* calculate pre-divider if parent is pll6 */ - if (parent == SUN6I_AHB1_MUX_PARENT_PLL6) { - if (div < 4) - calcp = 0; - else if (div / 2 < 4) - calcp = 1; - else if (div / 4 < 4) - calcp = 2; - else - calcp = 3; - - calcm = DIV_ROUND_UP(div, 1 << calcp); - } else { - calcp = __roundup_pow_of_two(div); - calcp = calcp > 3 ? 3 : calcp; - } - - /* we were asked to pass back divider values */ - if (divp) { - *divp = calcp; - *pre_divp = calcm - 1; - } - - return (parent_rate / calcm) >> calcp; -} - -static int sun6i_ahb1_clk_determine_rate(struct clk_hw *hw, - struct clk_rate_request *req) -{ - struct clk_hw *parent, *best_parent = NULL; - int i, num_parents; - unsigned long parent_rate, best = 0, child_rate, best_child_rate = 0; - - /* find the parent that can help provide the fastest rate <= rate */ - num_parents = clk_hw_get_num_parents(hw); - for (i = 0; i < num_parents; i++) { - parent = clk_hw_get_parent_by_index(hw, i); - if (!parent) - continue; - if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) - parent_rate = clk_hw_round_rate(parent, req->rate); - else - parent_rate = clk_hw_get_rate(parent); - - child_rate = sun6i_ahb1_clk_round(req->rate, NULL, NULL, i, - parent_rate); - - if (child_rate <= req->rate && child_rate > best_child_rate) { - best_parent = parent; - best = parent_rate; - best_child_rate = child_rate; - } - } - - if (!best_parent) - return -EINVAL; - - req->best_parent_hw = best_parent; - req->best_parent_rate = best; - req->rate = best_child_rate; - - return 0; -} - -static int sun6i_ahb1_clk_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct sun6i_ahb1_clk *ahb1 = to_sun6i_ahb1_clk(hw); - unsigned long flags; - u8 div, pre_div, parent; - u32 reg; - - spin_lock_irqsave(&clk_lock, flags); - - reg = readl(ahb1->reg); - - /* need to know which parent is used to apply pre-divider */ - parent = SUN6I_AHB1_MUX_GET_PARENT(reg); - sun6i_ahb1_clk_round(rate, &div, &pre_div, parent, parent_rate); - - reg = SUN6I_AHB1_DIV_SET(reg, div); - reg = SUN6I_AHB1_PLL6_DIV_SET(reg, pre_div); - writel(reg, ahb1->reg); - - spin_unlock_irqrestore(&clk_lock, flags); - - return 0; -} - -static const struct clk_ops sun6i_ahb1_clk_ops = { - .determine_rate = sun6i_ahb1_clk_determine_rate, - .recalc_rate = sun6i_ahb1_clk_recalc_rate, - .set_rate = sun6i_ahb1_clk_set_rate, -}; - -static void __init sun6i_ahb1_clk_setup(struct device_node *node) -{ - struct clk *clk; - struct sun6i_ahb1_clk *ahb1; - struct clk_mux *mux; - const char *clk_name = node->name; - const char *parents[SUN6I_AHB1_MAX_PARENTS]; - void __iomem *reg; - int i; - - reg = of_io_request_and_map(node, 0, of_node_full_name(node)); - if (IS_ERR(reg)) - return; - - /* we have a mux, we will have >1 parents */ - i = of_clk_parent_fill(node, parents, SUN6I_AHB1_MAX_PARENTS); - of_property_read_string(node, "clock-output-names", &clk_name); - - ahb1 = kzalloc(sizeof(struct sun6i_ahb1_clk), GFP_KERNEL); - if (!ahb1) - return; - - mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL); - if (!mux) { - kfree(ahb1); - return; - } - - /* set up clock properties */ - mux->reg = reg; - mux->shift = SUN6I_AHB1_MUX_SHIFT; - mux->mask = SUN6I_AHB1_MUX_MASK; - mux->lock = &clk_lock; - ahb1->reg = reg; - - clk = clk_register_composite(NULL, clk_name, parents, i, - &mux->hw, &clk_mux_ops, - &ahb1->hw, &sun6i_ahb1_clk_ops, - NULL, NULL, 0); - - if (!IS_ERR(clk)) { - of_clk_add_provider(node, of_clk_src_simple_get, clk); - clk_register_clkdev(clk, clk_name, NULL); - } -} -CLK_OF_DECLARE(sun6i_a31_ahb1, "allwinner,sun6i-a31-ahb1-clk", sun6i_ahb1_clk_setup); - /* Maximum number of parents our clocks have */ #define SUNXI_MAX_PARENTS 5 @@ -246,49 +38,45 @@ CLK_OF_DECLARE(sun6i_a31_ahb1, "allwinner,sun6i-a31-ahb1-clk", sun6i_ahb1_clk_se * parent_rate is always 24Mhz */ -static void sun4i_get_pll1_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun4i_get_pll1_factors(struct factors_request *req) { u8 div; /* Normalize value to a 6M multiple */ - div = *freq / 6000000; - *freq = 6000000 * div; - - /* we were called to round the frequency, we can now return */ - if (n == NULL) - return; + div = req->rate / 6000000; + req->rate = 6000000 * div; /* m is always zero for pll1 */ - *m = 0; + req->m = 0; /* k is 1 only on these cases */ - if (*freq >= 768000000 || *freq == 42000000 || *freq == 54000000) - *k = 1; + if (req->rate >= 768000000 || req->rate == 42000000 || + req->rate == 54000000) + req->k = 1; else - *k = 0; + req->k = 0; /* p will be 3 for divs under 10 */ if (div < 10) - *p = 3; + req->p = 3; /* p will be 2 for divs between 10 - 20 and odd divs under 32 */ else if (div < 20 || (div < 32 && (div & 1))) - *p = 2; + req->p = 2; /* p will be 1 for even divs under 32, divs under 40 and odd pairs * of divs between 40-62 */ else if (div < 40 || (div < 64 && (div & 2))) - *p = 1; + req->p = 1; /* any other entries have p = 0 */ else - *p = 0; + req->p = 0; /* calculate a suitable n based on k and p */ - div <<= *p; - div /= (*k + 1); - *n = div / 4; + div <<= req->p; + div /= (req->k + 1); + req->n = div / 4; } /** @@ -297,15 +85,14 @@ static void sun4i_get_pll1_factors(u32 *freq, u32 parent_rate, * rate = parent_rate * (n + 1) * (k + 1) / (m + 1); * parent_rate should always be 24MHz */ -static void sun6i_a31_get_pll1_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun6i_a31_get_pll1_factors(struct factors_request *req) { /* * We can operate only on MHz, this will make our life easier * later. */ - u32 freq_mhz = *freq / 1000000; - u32 parent_freq_mhz = parent_rate / 1000000; + u32 freq_mhz = req->rate / 1000000; + u32 parent_freq_mhz = req->parent_rate / 1000000; /* * Round down the frequency to the closest multiple of either @@ -319,28 +106,20 @@ static void sun6i_a31_get_pll1_factors(u32 *freq, u32 parent_rate, else freq_mhz = round_freq_16; - *freq = freq_mhz * 1000000; - - /* - * If the factors pointer are null, we were just called to - * round down the frequency. - * Exit. - */ - if (n == NULL) - return; + req->rate = freq_mhz * 1000000; /* If the frequency is a multiple of 32 MHz, k is always 3 */ if (!(freq_mhz % 32)) - *k = 3; + req->k = 3; /* If the frequency is a multiple of 9 MHz, k is always 2 */ else if (!(freq_mhz % 9)) - *k = 2; + req->k = 2; /* If the frequency is a multiple of 8 MHz, k is always 1 */ else if (!(freq_mhz % 8)) - *k = 1; + req->k = 1; /* Otherwise, we don't use the k factor */ else - *k = 0; + req->k = 0; /* * If the frequency is a multiple of 2 but not a multiple of @@ -351,27 +130,28 @@ static void sun6i_a31_get_pll1_factors(u32 *freq, u32 parent_rate, * somehow relates to this frequency. */ if ((freq_mhz % 6) == 2 || (freq_mhz % 6) == 4) - *m = 2; + req->m = 2; /* * If the frequency is a multiple of 6MHz, but the factor is * odd, m will be 3 */ else if ((freq_mhz / 6) & 1) - *m = 3; + req->m = 3; /* Otherwise, we end up with m = 1 */ else - *m = 1; + req->m = 1; /* Calculate n thanks to the above factors we already got */ - *n = freq_mhz * (*m + 1) / ((*k + 1) * parent_freq_mhz) - 1; + req->n = freq_mhz * (req->m + 1) / ((req->k + 1) * parent_freq_mhz) + - 1; /* * If n end up being outbound, and that we can still decrease * m, do it. */ - if ((*n + 1) > 31 && (*m + 1) > 1) { - *n = (*n + 1) / 2 - 1; - *m = (*m + 1) / 2 - 1; + if ((req->n + 1) > 31 && (req->m + 1) > 1) { + req->n = (req->n + 1) / 2 - 1; + req->m = (req->m + 1) / 2 - 1; } } @@ -382,45 +162,41 @@ static void sun6i_a31_get_pll1_factors(u32 *freq, u32 parent_rate, * parent_rate is always 24Mhz */ -static void sun8i_a23_get_pll1_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun8i_a23_get_pll1_factors(struct factors_request *req) { u8 div; /* Normalize value to a 6M multiple */ - div = *freq / 6000000; - *freq = 6000000 * div; - - /* we were called to round the frequency, we can now return */ - if (n == NULL) - return; + div = req->rate / 6000000; + req->rate = 6000000 * div; /* m is always zero for pll1 */ - *m = 0; + req->m = 0; /* k is 1 only on these cases */ - if (*freq >= 768000000 || *freq == 42000000 || *freq == 54000000) - *k = 1; + if (req->rate >= 768000000 || req->rate == 42000000 || + req->rate == 54000000) + req->k = 1; else - *k = 0; + req->k = 0; /* p will be 2 for divs under 20 and odd divs under 32 */ if (div < 20 || (div < 32 && (div & 1))) - *p = 2; + req->p = 2; /* p will be 1 for even divs under 32, divs under 40 and odd pairs * of divs between 40-62 */ else if (div < 40 || (div < 64 && (div & 2))) - *p = 1; + req->p = 1; /* any other entries have p = 0 */ else - *p = 0; + req->p = 0; /* calculate a suitable n based on k and p */ - div <<= *p; - div /= (*k + 1); - *n = div / 4 - 1; + div <<= req->p; + div /= (req->k + 1); + req->n = div / 4 - 1; } /** @@ -430,29 +206,24 @@ static void sun8i_a23_get_pll1_factors(u32 *freq, u32 parent_rate, * parent_rate is always 24Mhz */ -static void sun4i_get_pll5_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun4i_get_pll5_factors(struct factors_request *req) { u8 div; /* Normalize value to a parent_rate multiple (24M) */ - div = *freq / parent_rate; - *freq = parent_rate * div; - - /* we were called to round the frequency, we can now return */ - if (n == NULL) - return; + div = req->rate / req->parent_rate; + req->rate = req->parent_rate * div; if (div < 31) - *k = 0; + req->k = 0; else if (div / 2 < 31) - *k = 1; + req->k = 1; else if (div / 3 < 31) - *k = 2; + req->k = 2; else - *k = 3; + req->k = 3; - *n = DIV_ROUND_UP(div, (*k+1)); + req->n = DIV_ROUND_UP(div, (req->k + 1)); } /** @@ -462,24 +233,19 @@ static void sun4i_get_pll5_factors(u32 *freq, u32 parent_rate, * parent_rate is always 24Mhz */ -static void sun6i_a31_get_pll6_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun6i_a31_get_pll6_factors(struct factors_request *req) { u8 div; /* Normalize value to a parent_rate multiple (24M) */ - div = *freq / parent_rate; - *freq = parent_rate * div; - - /* we were called to round the frequency, we can now return */ - if (n == NULL) - return; + div = req->rate / req->parent_rate; + req->rate = req->parent_rate * div; - *k = div / 32; - if (*k > 3) - *k = 3; + req->k = div / 32; + if (req->k > 3) + req->k = 3; - *n = DIV_ROUND_UP(div, (*k+1)) - 1; + req->n = DIV_ROUND_UP(div, (req->k + 1)) - 1; } /** @@ -488,37 +254,94 @@ static void sun6i_a31_get_pll6_factors(u32 *freq, u32 parent_rate, * rate = parent_rate >> p */ -static void sun5i_a13_get_ahb_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun5i_a13_get_ahb_factors(struct factors_request *req) { u32 div; /* divide only */ - if (parent_rate < *freq) - *freq = parent_rate; + if (req->parent_rate < req->rate) + req->rate = req->parent_rate; /* * user manual says valid speed is 8k ~ 276M, but tests show it * can work at speeds up to 300M, just after reparenting to pll6 */ - if (*freq < 8000) - *freq = 8000; - if (*freq > 300000000) - *freq = 300000000; + if (req->rate < 8000) + req->rate = 8000; + if (req->rate > 300000000) + req->rate = 300000000; - div = order_base_2(DIV_ROUND_UP(parent_rate, *freq)); + div = order_base_2(DIV_ROUND_UP(req->parent_rate, req->rate)); /* p = 0 ~ 3 */ if (div > 3) div = 3; - *freq = parent_rate >> div; + req->rate = req->parent_rate >> div; - /* we were called to round the frequency, we can now return */ - if (p == NULL) - return; + req->p = div; +} + +#define SUN6I_AHB1_PARENT_PLL6 3 + +/** + * sun6i_a31_get_ahb_factors() - calculates m, p factors for AHB + * AHB rate is calculated as follows + * rate = parent_rate >> p + * + * if parent is pll6, then + * parent_rate = pll6 rate / (m + 1) + */ + +static void sun6i_get_ahb1_factors(struct factors_request *req) +{ + u8 div, calcp, calcm = 1; + + /* + * clock can only divide, so we will never be able to achieve + * frequencies higher than the parent frequency + */ + if (req->parent_rate && req->rate > req->parent_rate) + req->rate = req->parent_rate; + + div = DIV_ROUND_UP(req->parent_rate, req->rate); + + /* calculate pre-divider if parent is pll6 */ + if (req->parent_index == SUN6I_AHB1_PARENT_PLL6) { + if (div < 4) + calcp = 0; + else if (div / 2 < 4) + calcp = 1; + else if (div / 4 < 4) + calcp = 2; + else + calcp = 3; + + calcm = DIV_ROUND_UP(div, 1 << calcp); + } else { + calcp = __roundup_pow_of_two(div); + calcp = calcp > 3 ? 3 : calcp; + } - *p = div; + req->rate = (req->parent_rate / calcm) >> calcp; + req->p = calcp; + req->m = calcm - 1; +} + +/** + * sun6i_ahb1_recalc() - calculates AHB clock rate from m, p factors and + * parent index + */ +static void sun6i_ahb1_recalc(struct factors_request *req) +{ + req->rate = req->parent_rate; + + /* apply pre-divider first if parent is pll6 */ + if (req->parent_index == SUN6I_AHB1_PARENT_PLL6) + req->rate /= req->m + 1; + + /* clk divider */ + req->rate >>= req->p; } /** @@ -527,39 +350,34 @@ static void sun5i_a13_get_ahb_factors(u32 *freq, u32 parent_rate, * rate = (parent_rate >> p) / (m + 1); */ -static void sun4i_get_apb1_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun4i_get_apb1_factors(struct factors_request *req) { u8 calcm, calcp; + int div; - if (parent_rate < *freq) - *freq = parent_rate; + if (req->parent_rate < req->rate) + req->rate = req->parent_rate; - parent_rate = DIV_ROUND_UP(parent_rate, *freq); + div = DIV_ROUND_UP(req->parent_rate, req->rate); /* Invalid rate! */ - if (parent_rate > 32) + if (div > 32) return; - if (parent_rate <= 4) + if (div <= 4) calcp = 0; - else if (parent_rate <= 8) + else if (div <= 8) calcp = 1; - else if (parent_rate <= 16) + else if (div <= 16) calcp = 2; else calcp = 3; - calcm = (parent_rate >> calcp) - 1; + calcm = (req->parent_rate >> calcp) - 1; - *freq = (parent_rate >> calcp) / (calcm + 1); - - /* we were called to round the frequency, we can now return */ - if (n == NULL) - return; - - *m = calcm; - *p = calcp; + req->rate = (req->parent_rate >> calcp) / (calcm + 1); + req->m = calcm; + req->p = calcp; } @@ -571,17 +389,16 @@ static void sun4i_get_apb1_factors(u32 *freq, u32 parent_rate, * rate = (parent_rate >> p) / (m + 1); */ -static void sun7i_a20_get_out_factors(u32 *freq, u32 parent_rate, - u8 *n, u8 *k, u8 *m, u8 *p) +static void sun7i_a20_get_out_factors(struct factors_request *req) { u8 div, calcm, calcp; /* These clocks can only divide, so we will never be able to achieve * frequencies higher than the parent frequency */ - if (*freq > parent_rate) - *freq = parent_rate; + if (req->rate > req->parent_rate) + req->rate = req->parent_rate; - div = DIV_ROUND_UP(parent_rate, *freq); + div = DIV_ROUND_UP(req->parent_rate, req->rate); if (div < 32) calcp = 0; @@ -594,21 +411,16 @@ static void sun7i_a20_get_out_factors(u32 *freq, u32 parent_rate, calcm = DIV_ROUND_UP(div, 1 << calcp); - *freq = (parent_rate >> calcp) / calcm; - - /* we were called to round the frequency, we can now return */ - if (n == NULL) - return; - - *m = calcm - 1; - *p = calcp; + req->rate = (req->parent_rate >> calcp) / calcm; + req->m = calcm - 1; + req->p = calcp; } /** * sunxi_factors_clk_setup() - Setup function for factor clocks */ -static struct clk_factors_config sun4i_pll1_config = { +static const struct clk_factors_config sun4i_pll1_config = { .nshift = 8, .nwidth = 5, .kshift = 4, @@ -619,7 +431,7 @@ static struct clk_factors_config sun4i_pll1_config = { .pwidth = 2, }; -static struct clk_factors_config sun6i_a31_pll1_config = { +static const struct clk_factors_config sun6i_a31_pll1_config = { .nshift = 8, .nwidth = 5, .kshift = 4, @@ -629,7 +441,7 @@ static struct clk_factors_config sun6i_a31_pll1_config = { .n_start = 1, }; -static struct clk_factors_config sun8i_a23_pll1_config = { +static const struct clk_factors_config sun8i_a23_pll1_config = { .nshift = 8, .nwidth = 5, .kshift = 4, @@ -641,14 +453,14 @@ static struct clk_factors_config sun8i_a23_pll1_config = { .n_start = 1, }; -static struct clk_factors_config sun4i_pll5_config = { +static const struct clk_factors_config sun4i_pll5_config = { .nshift = 8, .nwidth = 5, .kshift = 4, .kwidth = 2, }; -static struct clk_factors_config sun6i_a31_pll6_config = { +static const struct clk_factors_config sun6i_a31_pll6_config = { .nshift = 8, .nwidth = 5, .kshift = 4, @@ -656,12 +468,19 @@ static struct clk_factors_config sun6i_a31_pll6_config = { .n_start = 1, }; -static struct clk_factors_config sun5i_a13_ahb_config = { +static const struct clk_factors_config sun5i_a13_ahb_config = { .pshift = 4, .pwidth = 2, }; -static struct clk_factors_config sun4i_apb1_config = { +static const struct clk_factors_config sun6i_ahb1_config = { + .mshift = 6, + .mwidth = 2, + .pshift = 4, + .pwidth = 2, +}; + +static const struct clk_factors_config sun4i_apb1_config = { .mshift = 0, .mwidth = 5, .pshift = 16, @@ -669,7 +488,7 @@ static struct clk_factors_config sun4i_apb1_config = { }; /* user manual says "n" but it's really "p" */ -static struct clk_factors_config sun7i_a20_out_config = { +static const struct clk_factors_config sun7i_a20_out_config = { .mshift = 8, .mwidth = 5, .pshift = 20, @@ -728,6 +547,14 @@ static const struct factors_data sun5i_a13_ahb_data __initconst = { .getter = sun5i_a13_get_ahb_factors, }; +static const struct factors_data sun6i_ahb1_data __initconst = { + .mux = 12, + .muxmask = BIT(1) | BIT(0), + .table = &sun6i_ahb1_config, + .getter = sun6i_get_ahb1_factors, + .recalc = sun6i_ahb1_recalc, +}; + static const struct factors_data sun4i_apb1_data __initconst = { .mux = 24, .muxmask = BIT(1) | BIT(0), @@ -758,6 +585,61 @@ static struct clk * __init sunxi_factors_clk_setup(struct device_node *node, return sunxi_factors_register(node, data, &clk_lock, reg); } +static void __init sun4i_pll1_clk_setup(struct device_node *node) +{ + sunxi_factors_clk_setup(node, &sun4i_pll1_data); +} +CLK_OF_DECLARE(sun4i_pll1, "allwinner,sun4i-a10-pll1-clk", + sun4i_pll1_clk_setup); + +static void __init sun6i_pll1_clk_setup(struct device_node *node) +{ + sunxi_factors_clk_setup(node, &sun6i_a31_pll1_data); +} +CLK_OF_DECLARE(sun6i_pll1, "allwinner,sun6i-a31-pll1-clk", + sun6i_pll1_clk_setup); + +static void __init sun8i_pll1_clk_setup(struct device_node *node) +{ + sunxi_factors_clk_setup(node, &sun8i_a23_pll1_data); +} +CLK_OF_DECLARE(sun8i_pll1, "allwinner,sun8i-a23-pll1-clk", + sun8i_pll1_clk_setup); + +static void __init sun7i_pll4_clk_setup(struct device_node *node) +{ + sunxi_factors_clk_setup(node, &sun7i_a20_pll4_data); +} +CLK_OF_DECLARE(sun7i_pll4, "allwinner,sun7i-a20-pll4-clk", + sun7i_pll4_clk_setup); + +static void __init sun5i_ahb_clk_setup(struct device_node *node) +{ + sunxi_factors_clk_setup(node, &sun5i_a13_ahb_data); +} +CLK_OF_DECLARE(sun5i_ahb, "allwinner,sun5i-a13-ahb-clk", + sun5i_ahb_clk_setup); + +static void __init sun6i_ahb1_clk_setup(struct device_node *node) +{ + sunxi_factors_clk_setup(node, &sun6i_ahb1_data); +} +CLK_OF_DECLARE(sun6i_a31_ahb1, "allwinner,sun6i-a31-ahb1-clk", + sun6i_ahb1_clk_setup); + +static void __init sun4i_apb1_clk_setup(struct device_node *node) +{ + sunxi_factors_clk_setup(node, &sun4i_apb1_data); +} +CLK_OF_DECLARE(sun4i_apb1, "allwinner,sun4i-a10-apb1-clk", + sun4i_apb1_clk_setup); + +static void __init sun7i_out_clk_setup(struct device_node *node) +{ + sunxi_factors_clk_setup(node, &sun7i_a20_out_data); +} +CLK_OF_DECLARE(sun7i_out, "allwinner,sun7i-a20-out-clk", + sun7i_out_clk_setup); /** @@ -782,8 +664,8 @@ static const struct mux_data sun8i_h3_ahb2_mux_data __initconst = { .shift = 0, }; -static void __init sunxi_mux_clk_setup(struct device_node *node, - struct mux_data *data) +static struct clk * __init sunxi_mux_clk_setup(struct device_node *node, + const struct mux_data *data) { struct clk *clk; const char *clk_name = node->name; @@ -792,21 +674,71 @@ static void __init sunxi_mux_clk_setup(struct device_node *node, int i; reg = of_iomap(node, 0); + if (!reg) { + pr_err("Could not map registers for mux-clk: %s\n", + of_node_full_name(node)); + return NULL; + } i = of_clk_parent_fill(node, parents, SUNXI_MAX_PARENTS); - of_property_read_string(node, "clock-output-names", &clk_name); + if (of_property_read_string(node, "clock-output-names", &clk_name)) { + pr_err("%s: could not read clock-output-names from \"%s\"\n", + __func__, of_node_full_name(node)); + goto out_unmap; + } clk = clk_register_mux(NULL, clk_name, parents, i, CLK_SET_RATE_PARENT, reg, data->shift, SUNXI_MUX_GATE_WIDTH, 0, &clk_lock); - if (clk) { - of_clk_add_provider(node, of_clk_src_simple_get, clk); - clk_register_clkdev(clk, clk_name, NULL); + if (IS_ERR(clk)) { + pr_err("%s: failed to register mux clock %s: %ld\n", __func__, + clk_name, PTR_ERR(clk)); + goto out_unmap; + } + + if (of_clk_add_provider(node, of_clk_src_simple_get, clk)) { + pr_err("%s: failed to add clock provider for %s\n", + __func__, clk_name); + clk_unregister_divider(clk); + goto out_unmap; } + + return clk; +out_unmap: + iounmap(reg); + return NULL; +} + +static void __init sun4i_cpu_clk_setup(struct device_node *node) +{ + struct clk *clk; + + clk = sunxi_mux_clk_setup(node, &sun4i_cpu_mux_data); + if (!clk) + return; + + /* Protect CPU clock */ + __clk_get(clk); + clk_prepare_enable(clk); +} +CLK_OF_DECLARE(sun4i_cpu, "allwinner,sun4i-a10-cpu-clk", + sun4i_cpu_clk_setup); + +static void __init sun6i_ahb1_mux_clk_setup(struct device_node *node) +{ + sunxi_mux_clk_setup(node, &sun6i_a31_ahb1_mux_data); } +CLK_OF_DECLARE(sun6i_ahb1_mux, "allwinner,sun6i-a31-ahb1-mux-clk", + sun6i_ahb1_mux_clk_setup); +static void __init sun8i_ahb2_clk_setup(struct device_node *node) +{ + sunxi_mux_clk_setup(node, &sun8i_h3_ahb2_mux_data); +} +CLK_OF_DECLARE(sun8i_ahb2, "allwinner,sun8i-h3-ahb2-clk", + sun8i_ahb2_clk_setup); /** @@ -865,7 +797,7 @@ static const struct div_data sun4i_apb0_data __initconst = { }; static void __init sunxi_divider_clk_setup(struct device_node *node, - struct div_data *data) + const struct div_data *data) { struct clk *clk; const char *clk_name = node->name; @@ -873,21 +805,77 @@ static void __init sunxi_divider_clk_setup(struct device_node *node, void __iomem *reg; reg = of_iomap(node, 0); + if (!reg) { + pr_err("Could not map registers for mux-clk: %s\n", + of_node_full_name(node)); + return; + } clk_parent = of_clk_get_parent_name(node, 0); - of_property_read_string(node, "clock-output-names", &clk_name); + if (of_property_read_string(node, "clock-output-names", &clk_name)) { + pr_err("%s: could not read clock-output-names from \"%s\"\n", + __func__, of_node_full_name(node)); + goto out_unmap; + } clk = clk_register_divider_table(NULL, clk_name, clk_parent, 0, reg, data->shift, data->width, data->pow ? CLK_DIVIDER_POWER_OF_TWO : 0, data->table, &clk_lock); - if (clk) { - of_clk_add_provider(node, of_clk_src_simple_get, clk); - clk_register_clkdev(clk, clk_name, NULL); + if (IS_ERR(clk)) { + pr_err("%s: failed to register divider clock %s: %ld\n", + __func__, clk_name, PTR_ERR(clk)); + goto out_unmap; } + + if (of_clk_add_provider(node, of_clk_src_simple_get, clk)) { + pr_err("%s: failed to add clock provider for %s\n", + __func__, clk_name); + goto out_unregister; + } + + if (clk_register_clkdev(clk, clk_name, NULL)) { + of_clk_del_provider(node); + goto out_unregister; + } + + return; +out_unregister: + clk_unregister_divider(clk); + +out_unmap: + iounmap(reg); } +static void __init sun4i_ahb_clk_setup(struct device_node *node) +{ + sunxi_divider_clk_setup(node, &sun4i_ahb_data); +} +CLK_OF_DECLARE(sun4i_ahb, "allwinner,sun4i-a10-ahb-clk", + sun4i_ahb_clk_setup); + +static void __init sun4i_apb0_clk_setup(struct device_node *node) +{ + sunxi_divider_clk_setup(node, &sun4i_apb0_data); +} +CLK_OF_DECLARE(sun4i_apb0, "allwinner,sun4i-a10-apb0-clk", + sun4i_apb0_clk_setup); + +static void __init sun4i_axi_clk_setup(struct device_node *node) +{ + sunxi_divider_clk_setup(node, &sun4i_axi_data); +} +CLK_OF_DECLARE(sun4i_axi, "allwinner,sun4i-a10-axi-clk", + sun4i_axi_clk_setup); + +static void __init sun8i_axi_clk_setup(struct device_node *node) +{ + sunxi_divider_clk_setup(node, &sun8i_a23_axi_data); +} +CLK_OF_DECLARE(sun8i_axi, "allwinner,sun8i-a23-axi-clk", + sun8i_axi_clk_setup); + /** @@ -975,8 +963,8 @@ static const struct divs_data sun6i_a31_pll6_divs_data __initconst = { * |________________________| */ -static void __init sunxi_divs_clk_setup(struct device_node *node, - struct divs_data *data) +static struct clk ** __init sunxi_divs_clk_setup(struct device_node *node, + const struct divs_data *data) { struct clk_onecell_data *clk_data; const char *parent; @@ -997,13 +985,20 @@ static void __init sunxi_divs_clk_setup(struct device_node *node, /* Set up factor clock that we will be dividing */ pclk = sunxi_factors_clk_setup(node, data->factors); + if (!pclk) + return NULL; parent = __clk_get_name(pclk); reg = of_iomap(node, 0); + if (!reg) { + pr_err("Could not map registers for divs-clk: %s\n", + of_node_full_name(node)); + return NULL; + } clk_data = kmalloc(sizeof(struct clk_onecell_data), GFP_KERNEL); if (!clk_data) - return; + goto out_unmap; clks = kcalloc(ndivs, sizeof(*clks), GFP_KERNEL); if (!clks) @@ -1081,146 +1076,54 @@ static void __init sunxi_divs_clk_setup(struct device_node *node, clkflags); WARN_ON(IS_ERR(clk_data->clks[i])); - clk_register_clkdev(clks[i], clk_name, NULL); } /* Adjust to the real max */ clk_data->clk_num = i; - of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); - - return; + if (of_clk_add_provider(node, of_clk_src_onecell_get, clk_data)) { + pr_err("%s: failed to add clock provider for %s\n", + __func__, clk_name); + goto free_gate; + } + return clks; free_gate: kfree(gate); free_clks: kfree(clks); free_clkdata: kfree(clk_data); +out_unmap: + iounmap(reg); + return NULL; } - - -/* Matches for factors clocks */ -static const struct of_device_id clk_factors_match[] __initconst = { - {.compatible = "allwinner,sun4i-a10-pll1-clk", .data = &sun4i_pll1_data,}, - {.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,}, - {.compatible = "allwinner,sun8i-a23-pll1-clk", .data = &sun8i_a23_pll1_data,}, - {.compatible = "allwinner,sun7i-a20-pll4-clk", .data = &sun7i_a20_pll4_data,}, - {.compatible = "allwinner,sun5i-a13-ahb-clk", .data = &sun5i_a13_ahb_data,}, - {.compatible = "allwinner,sun4i-a10-apb1-clk", .data = &sun4i_apb1_data,}, - {.compatible = "allwinner,sun7i-a20-out-clk", .data = &sun7i_a20_out_data,}, - {} -}; - -/* Matches for divider clocks */ -static const struct of_device_id clk_div_match[] __initconst = { - {.compatible = "allwinner,sun4i-a10-axi-clk", .data = &sun4i_axi_data,}, - {.compatible = "allwinner,sun8i-a23-axi-clk", .data = &sun8i_a23_axi_data,}, - {.compatible = "allwinner,sun4i-a10-ahb-clk", .data = &sun4i_ahb_data,}, - {.compatible = "allwinner,sun4i-a10-apb0-clk", .data = &sun4i_apb0_data,}, - {} -}; - -/* Matches for divided outputs */ -static const struct of_device_id clk_divs_match[] __initconst = { - {.compatible = "allwinner,sun4i-a10-pll5-clk", .data = &pll5_divs_data,}, - {.compatible = "allwinner,sun4i-a10-pll6-clk", .data = &pll6_divs_data,}, - {.compatible = "allwinner,sun6i-a31-pll6-clk", .data = &sun6i_a31_pll6_divs_data,}, - {} -}; - -/* Matches for mux clocks */ -static const struct of_device_id clk_mux_match[] __initconst = { - {.compatible = "allwinner,sun4i-a10-cpu-clk", .data = &sun4i_cpu_mux_data,}, - {.compatible = "allwinner,sun6i-a31-ahb1-mux-clk", .data = &sun6i_a31_ahb1_mux_data,}, - {.compatible = "allwinner,sun8i-h3-ahb2-clk", .data = &sun8i_h3_ahb2_mux_data,}, - {} -}; - - -static void __init of_sunxi_table_clock_setup(const struct of_device_id *clk_match, - void *function) -{ - struct device_node *np; - const struct div_data *data; - const struct of_device_id *match; - void (*setup_function)(struct device_node *, const void *) = function; - - for_each_matching_node_and_match(np, clk_match, &match) { - data = match->data; - setup_function(np, data); - } -} - -static void __init sunxi_init_clocks(const char *clocks[], int nclocks) -{ - unsigned int i; - - /* Register divided output clocks */ - of_sunxi_table_clock_setup(clk_divs_match, sunxi_divs_clk_setup); - - /* Register factor clocks */ - of_sunxi_table_clock_setup(clk_factors_match, sunxi_factors_clk_setup); - - /* Register divider clocks */ - of_sunxi_table_clock_setup(clk_div_match, sunxi_divider_clk_setup); - - /* Register mux clocks */ - of_sunxi_table_clock_setup(clk_mux_match, sunxi_mux_clk_setup); - - /* Protect the clocks that needs to stay on */ - for (i = 0; i < nclocks; i++) { - struct clk *clk = clk_get(NULL, clocks[i]); - - if (!IS_ERR(clk)) - clk_prepare_enable(clk); - } -} - -static const char *sun4i_a10_critical_clocks[] __initdata = { - "pll5_ddr", -}; - -static void __init sun4i_a10_init_clocks(struct device_node *node) +static void __init sun4i_pll5_clk_setup(struct device_node *node) { - sunxi_init_clocks(sun4i_a10_critical_clocks, - ARRAY_SIZE(sun4i_a10_critical_clocks)); -} -CLK_OF_DECLARE(sun4i_a10_clk_init, "allwinner,sun4i-a10", sun4i_a10_init_clocks); + struct clk **clks; -static const char *sun5i_critical_clocks[] __initdata = { - "cpu", - "pll5_ddr", -}; + clks = sunxi_divs_clk_setup(node, &pll5_divs_data); + if (!clks) + return; -static void __init sun5i_init_clocks(struct device_node *node) -{ - sunxi_init_clocks(sun5i_critical_clocks, - ARRAY_SIZE(sun5i_critical_clocks)); + /* Protect PLL5_DDR */ + __clk_get(clks[0]); + clk_prepare_enable(clks[0]); } -CLK_OF_DECLARE(sun5i_a10s_clk_init, "allwinner,sun5i-a10s", sun5i_init_clocks); -CLK_OF_DECLARE(sun5i_a13_clk_init, "allwinner,sun5i-a13", sun5i_init_clocks); -CLK_OF_DECLARE(sun5i_r8_clk_init, "allwinner,sun5i-r8", sun5i_init_clocks); -CLK_OF_DECLARE(sun7i_a20_clk_init, "allwinner,sun7i-a20", sun5i_init_clocks); - -static const char *sun6i_critical_clocks[] __initdata = { - "cpu", -}; +CLK_OF_DECLARE(sun4i_pll5, "allwinner,sun4i-a10-pll5-clk", + sun4i_pll5_clk_setup); -static void __init sun6i_init_clocks(struct device_node *node) +static void __init sun4i_pll6_clk_setup(struct device_node *node) { - sunxi_init_clocks(sun6i_critical_clocks, - ARRAY_SIZE(sun6i_critical_clocks)); + sunxi_divs_clk_setup(node, &pll6_divs_data); } -CLK_OF_DECLARE(sun6i_a31_clk_init, "allwinner,sun6i-a31", sun6i_init_clocks); -CLK_OF_DECLARE(sun6i_a31s_clk_init, "allwinner,sun6i-a31s", sun6i_init_clocks); -CLK_OF_DECLARE(sun8i_a23_clk_init, "allwinner,sun8i-a23", sun6i_init_clocks); -CLK_OF_DECLARE(sun8i_a33_clk_init, "allwinner,sun8i-a33", sun6i_init_clocks); -CLK_OF_DECLARE(sun8i_h3_clk_init, "allwinner,sun8i-h3", sun6i_init_clocks); +CLK_OF_DECLARE(sun4i_pll6, "allwinner,sun4i-a10-pll6-clk", + sun4i_pll6_clk_setup); -static void __init sun9i_init_clocks(struct device_node *node) +static void __init sun6i_pll6_clk_setup(struct device_node *node) { - sunxi_init_clocks(NULL, 0); + sunxi_divs_clk_setup(node, &sun6i_a31_pll6_divs_data); } -CLK_OF_DECLARE(sun9i_a80_clk_init, "allwinner,sun9i-a80", sun9i_init_clocks); +CLK_OF_DECLARE(sun6i_pll6, "allwinner,sun6i-a31-pll6-clk", + sun6i_pll6_clk_setup); diff --git a/drivers/clk/sunxi/clk-usb.c b/drivers/clk/sunxi/clk-usb.c index 67b8e38f4ee96d1dfec6a1230f0258ab65285980..fe0c3d169377272bccde5f8464429a9ea5ef43de 100644 --- a/drivers/clk/sunxi/clk-usb.c +++ b/drivers/clk/sunxi/clk-usb.c @@ -76,7 +76,7 @@ static int sunxi_usb_reset_deassert(struct reset_controller_dev *rcdev, return 0; } -static struct reset_control_ops sunxi_usb_reset_ops = { +static const struct reset_control_ops sunxi_usb_reset_ops = { .assert = sunxi_usb_reset_assert, .deassert = sunxi_usb_reset_deassert, }; @@ -216,6 +216,18 @@ static void __init sun8i_a23_usb_setup(struct device_node *node) } CLK_OF_DECLARE(sun8i_a23_usb, "allwinner,sun8i-a23-usb-clk", sun8i_a23_usb_setup); +static const struct usb_clk_data sun8i_h3_usb_clk_data __initconst = { + .clk_mask = BIT(19) | BIT(18) | BIT(17) | BIT(16) | + BIT(11) | BIT(10) | BIT(9) | BIT(8), + .reset_mask = BIT(3) | BIT(2) | BIT(1) | BIT(0), +}; + +static void __init sun8i_h3_usb_setup(struct device_node *node) +{ + sunxi_usb_clk_setup(node, &sun8i_h3_usb_clk_data, &sun4i_a10_usb_lock); +} +CLK_OF_DECLARE(sun8i_h3_usb, "allwinner,sun8i-h3-usb-clk", sun8i_h3_usb_setup); + static const struct usb_clk_data sun9i_a80_usb_mod_data __initconst = { .clk_mask = BIT(6) | BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1), .reset_mask = BIT(19) | BIT(18) | BIT(17), @@ -243,15 +255,3 @@ static void __init sun9i_a80_usb_phy_setup(struct device_node *node) sunxi_usb_clk_setup(node, &sun9i_a80_usb_phy_data, &a80_usb_phy_lock); } CLK_OF_DECLARE(sun9i_a80_usb_phy, "allwinner,sun9i-a80-usb-phy-clk", sun9i_a80_usb_phy_setup); - -static const struct usb_clk_data sun8i_h3_usb_clk_data __initconst = { - .clk_mask = BIT(19) | BIT(18) | BIT(17) | BIT(16) | - BIT(11) | BIT(10) | BIT(9) | BIT(8), - .reset_mask = BIT(3) | BIT(2) | BIT(1) | BIT(0), -}; - -static void __init sun8i_h3_usb_setup(struct device_node *node) -{ - sunxi_usb_clk_setup(node, &sun8i_h3_usb_clk_data, &sun4i_a10_usb_lock); -} -CLK_OF_DECLARE(sun8i_h3_usb, "allwinner,sun8i-h3-usb-clk", sun8i_h3_usb_setup); diff --git a/drivers/clk/tegra/clk-audio-sync.c b/drivers/clk/tegra/clk-audio-sync.c index c0f7843e80e61ba5d947cec90348f9fa89b22e8e..92d04ce2dee6b7e4e5131a1f9052bbee7d5de134 100644 --- a/drivers/clk/tegra/clk-audio-sync.c +++ b/drivers/clk/tegra/clk-audio-sync.c @@ -72,7 +72,7 @@ struct clk *tegra_clk_register_sync_source(const char *name, init.ops = &tegra_clk_sync_source_ops; init.name = name; - init.flags = CLK_IS_ROOT; + init.flags = 0; init.parent_names = NULL; init.num_parents = 0; diff --git a/drivers/clk/tegra/clk-dfll.c b/drivers/clk/tegra/clk-dfll.c index 86a307b17eb0a922acd2bac5ea16c6de16f5756e..19bfa07e24b1b67baccc838a016ce4897cb61a11 100644 --- a/drivers/clk/tegra/clk-dfll.c +++ b/drivers/clk/tegra/clk-dfll.c @@ -995,7 +995,6 @@ static const struct clk_ops dfll_clk_ops = { }; static struct clk_init_data dfll_clk_init_data = { - .flags = CLK_IS_ROOT, .ops = &dfll_clk_ops, .num_parents = 0, }; diff --git a/drivers/clk/tegra/clk-tegra-fixed.c b/drivers/clk/tegra/clk-tegra-fixed.c index da0b5941c89ffae2ee3b7b367f0f0413f0a1959a..d64ec7a1b97674ada2c52aa55a5efcf6c675dfb7 100644 --- a/drivers/clk/tegra/clk-tegra-fixed.c +++ b/drivers/clk/tegra/clk-tegra-fixed.c @@ -52,8 +52,7 @@ int __init tegra_osc_clk_init(void __iomem *clk_base, struct tegra_clk *clks, return -EINVAL; } - osc = clk_register_fixed_rate(NULL, "osc", NULL, CLK_IS_ROOT, - *osc_freq); + osc = clk_register_fixed_rate(NULL, "osc", NULL, 0, *osc_freq); dt_clk = tegra_lookup_dt_id(tegra_clk_clk_m, clks); if (!dt_clk) @@ -88,8 +87,7 @@ void __init tegra_fixed_clk_init(struct tegra_clk *tegra_clks) /* clk_32k */ dt_clk = tegra_lookup_dt_id(tegra_clk_clk_32k, tegra_clks); if (dt_clk) { - clk = clk_register_fixed_rate(NULL, "clk_32k", NULL, - CLK_IS_ROOT, 32768); + clk = clk_register_fixed_rate(NULL, "clk_32k", NULL, 0, 32768); *dt_clk = clk; } diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 4a24aa4bbdea577ca52733275c11c69fffc799b4..df47ec3169c3451b67147d60cba3da83ec5e565b 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -972,8 +972,7 @@ static void __init tegra114_fixed_clk_init(void __iomem *clk_base) struct clk *clk; /* clk_32k */ - clk = clk_register_fixed_rate(NULL, "clk_32k", NULL, CLK_IS_ROOT, - 32768); + clk = clk_register_fixed_rate(NULL, "clk_32k", NULL, 0, 32768); clks[TEGRA114_CLK_CLK_32K] = clk; /* clk_m_div2 */ diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index 7a48e986c4c97f5a052513ecc600bf5a1979ba8b..7ad63837694f66c60440d548633294948a55dea2 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -837,15 +837,13 @@ static void __init tegra20_periph_clk_init(void) clks[TEGRA20_CLK_PEX] = clk; /* cdev1 */ - clk = clk_register_fixed_rate(NULL, "cdev1_fixed", NULL, CLK_IS_ROOT, - 26000000); + clk = clk_register_fixed_rate(NULL, "cdev1_fixed", NULL, 0, 26000000); clk = tegra_clk_register_periph_gate("cdev1", "cdev1_fixed", 0, clk_base, 0, 94, periph_clk_enb_refcnt); clks[TEGRA20_CLK_CDEV1] = clk; /* cdev2 */ - clk = clk_register_fixed_rate(NULL, "cdev2_fixed", NULL, CLK_IS_ROOT, - 26000000); + clk = clk_register_fixed_rate(NULL, "cdev2_fixed", NULL, 0, 26000000); clk = tegra_clk_register_periph_gate("cdev2", "cdev2_fixed", 0, clk_base, 0, 93, periph_clk_enb_refcnt); clks[TEGRA20_CLK_CDEV2] = clk; @@ -879,8 +877,8 @@ static void __init tegra20_osc_clk_init(void) input_freq = tegra20_clk_measure_input_freq(); /* clk_m */ - clk = clk_register_fixed_rate(NULL, "clk_m", NULL, CLK_IS_ROOT | - CLK_IGNORE_UNUSED, input_freq); + clk = clk_register_fixed_rate(NULL, "clk_m", NULL, CLK_IGNORE_UNUSED, + input_freq); clks[TEGRA20_CLK_CLK_M] = clk; /* pll_ref */ diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c index 2a3a4fe803d6d27e16c7de373f0ec1b8f2164264..f60fe2e344ca0a5828f643e7623ed14e619f760e 100644 --- a/drivers/clk/tegra/clk.c +++ b/drivers/clk/tegra/clk.c @@ -271,7 +271,7 @@ void __init tegra_init_from_table(struct tegra_clk_init_table *tbl, } } -static struct reset_control_ops rst_ops = { +static const struct reset_control_ops rst_ops = { .assert = tegra_clk_rst_assert, .deassert = tegra_clk_rst_deassert, }; diff --git a/drivers/clk/ti/Kconfig b/drivers/clk/ti/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..271341787e67ed669e7b700f24ed9783b5888db7 --- /dev/null +++ b/drivers/clk/ti/Kconfig @@ -0,0 +1,6 @@ +config COMMON_CLK_TI_ADPLL + tristate "Clock driver for dm814x ADPLL" + depends on ARCH_OMAP2PLUS || COMPILE_TEST + default y if SOC_TI81XX + ---help--- + ADPLL clock driver for the dm814x SoC using common clock framework. diff --git a/drivers/clk/ti/Makefile b/drivers/clk/ti/Makefile index d4ac96087ccd01c3ae83f0218fd16d42f78a7ec5..0deac98210392c8098e281c980cad5d271c2c992 100644 --- a/drivers/clk/ti/Makefile +++ b/drivers/clk/ti/Makefile @@ -1,3 +1,5 @@ +ifeq ($(CONFIG_ARCH_OMAP2PLUS), y) + obj-y += clk.o autoidle.o clockdomain.o clk-common = dpll.o composite.o divider.o gate.o \ fixed-factor.o mux.o apll.o \ @@ -18,3 +20,7 @@ obj-$(CONFIG_SOC_AM43XX) += $(clk-common) dpll3xxx.o clk-43xx.o ifdef CONFIG_ATAGS obj-$(CONFIG_ARCH_OMAP3) += clk-3xxx-legacy.o endif + +endif # CONFIG_ARCH_OMAP2PLUS + +obj-$(CONFIG_COMMON_CLK_TI_ADPLL) += adpll.o diff --git a/drivers/clk/ti/adpll.c b/drivers/clk/ti/adpll.c new file mode 100644 index 0000000000000000000000000000000000000000..255cafb18336aba5f2e7935daa6825d7e7123012 --- /dev/null +++ b/drivers/clk/ti/adpll.c @@ -0,0 +1,983 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ADPLL_PLLSS_MMR_LOCK_OFFSET 0x00 /* Managed by MPPULL */ +#define ADPLL_PLLSS_MMR_LOCK_ENABLED 0x1f125B64 +#define ADPLL_PLLSS_MMR_UNLOCK_MAGIC 0x1eda4c3d + +#define ADPLL_PWRCTRL_OFFSET 0x00 +#define ADPLL_PWRCTRL_PONIN 5 +#define ADPLL_PWRCTRL_PGOODIN 4 +#define ADPLL_PWRCTRL_RET 3 +#define ADPLL_PWRCTRL_ISORET 2 +#define ADPLL_PWRCTRL_ISOSCAN 1 +#define ADPLL_PWRCTRL_OFFMODE 0 + +#define ADPLL_CLKCTRL_OFFSET 0x04 +#define ADPLL_CLKCTRL_CLKDCOLDOEN 29 +#define ADPLL_CLKCTRL_IDLE 23 +#define ADPLL_CLKCTRL_CLKOUTEN 20 +#define ADPLL_CLKINPHIFSEL_ADPLL_S 19 /* REVISIT: which bit? */ +#define ADPLL_CLKCTRL_CLKOUTLDOEN_ADPLL_LJ 19 +#define ADPLL_CLKCTRL_ULOWCLKEN 18 +#define ADPLL_CLKCTRL_CLKDCOLDOPWDNZ 17 +#define ADPLL_CLKCTRL_M2PWDNZ 16 +#define ADPLL_CLKCTRL_M3PWDNZ_ADPLL_S 15 +#define ADPLL_CLKCTRL_LOWCURRSTDBY_ADPLL_S 13 +#define ADPLL_CLKCTRL_LPMODE_ADPLL_S 12 +#define ADPLL_CLKCTRL_REGM4XEN_ADPLL_S 10 +#define ADPLL_CLKCTRL_SELFREQDCO_ADPLL_LJ 10 +#define ADPLL_CLKCTRL_TINITZ 0 + +#define ADPLL_TENABLE_OFFSET 0x08 +#define ADPLL_TENABLEDIV_OFFSET 0x8c + +#define ADPLL_M2NDIV_OFFSET 0x10 +#define ADPLL_M2NDIV_M2 16 +#define ADPLL_M2NDIV_M2_ADPLL_S_WIDTH 5 +#define ADPLL_M2NDIV_M2_ADPLL_LJ_WIDTH 7 + +#define ADPLL_MN2DIV_OFFSET 0x14 +#define ADPLL_MN2DIV_N2 16 + +#define ADPLL_FRACDIV_OFFSET 0x18 +#define ADPLL_FRACDIV_REGSD 24 +#define ADPLL_FRACDIV_FRACTIONALM 0 +#define ADPLL_FRACDIV_FRACTIONALM_MASK 0x3ffff + +#define ADPLL_BWCTRL_OFFSET 0x1c +#define ADPLL_BWCTRL_BWCONTROL 1 +#define ADPLL_BWCTRL_BW_INCR_DECRZ 0 + +#define ADPLL_RESERVED_OFFSET 0x20 + +#define ADPLL_STATUS_OFFSET 0x24 +#define ADPLL_STATUS_PONOUT 31 +#define ADPLL_STATUS_PGOODOUT 30 +#define ADPLL_STATUS_LDOPWDN 29 +#define ADPLL_STATUS_RECAL_BSTATUS3 28 +#define ADPLL_STATUS_RECAL_OPPIN 27 +#define ADPLL_STATUS_PHASELOCK 10 +#define ADPLL_STATUS_FREQLOCK 9 +#define ADPLL_STATUS_BYPASSACK 8 +#define ADPLL_STATUS_LOSSREF 6 +#define ADPLL_STATUS_CLKOUTENACK 5 +#define ADPLL_STATUS_LOCK2 4 +#define ADPLL_STATUS_M2CHANGEACK 3 +#define ADPLL_STATUS_HIGHJITTER 1 +#define ADPLL_STATUS_BYPASS 0 +#define ADPLL_STATUS_PREPARED_MASK (BIT(ADPLL_STATUS_PHASELOCK) | \ + BIT(ADPLL_STATUS_FREQLOCK)) + +#define ADPLL_M3DIV_OFFSET 0x28 /* Only on MPUPLL */ +#define ADPLL_M3DIV_M3 0 +#define ADPLL_M3DIV_M3_WIDTH 5 +#define ADPLL_M3DIV_M3_MASK 0x1f + +#define ADPLL_RAMPCTRL_OFFSET 0x2c /* Only on MPUPLL */ +#define ADPLL_RAMPCTRL_CLKRAMPLEVEL 19 +#define ADPLL_RAMPCTRL_CLKRAMPRATE 16 +#define ADPLL_RAMPCTRL_RELOCK_RAMP_EN 0 + +#define MAX_ADPLL_INPUTS 3 +#define MAX_ADPLL_OUTPUTS 4 +#define ADPLL_MAX_RETRIES 5 + +#define to_dco(_hw) container_of(_hw, struct ti_adpll_dco_data, hw) +#define to_adpll(_hw) container_of(_hw, struct ti_adpll_data, dco) +#define to_clkout(_hw) container_of(_hw, struct ti_adpll_clkout_data, hw) + +enum ti_adpll_clocks { + TI_ADPLL_DCO, + TI_ADPLL_DCO_GATE, + TI_ADPLL_N2, + TI_ADPLL_M2, + TI_ADPLL_M2_GATE, + TI_ADPLL_BYPASS, + TI_ADPLL_HIF, + TI_ADPLL_DIV2, + TI_ADPLL_CLKOUT, + TI_ADPLL_CLKOUT2, + TI_ADPLL_M3, +}; + +#define TI_ADPLL_NR_CLOCKS (TI_ADPLL_M3 + 1) + +enum ti_adpll_inputs { + TI_ADPLL_CLKINP, + TI_ADPLL_CLKINPULOW, + TI_ADPLL_CLKINPHIF, +}; + +enum ti_adpll_s_outputs { + TI_ADPLL_S_DCOCLKLDO, + TI_ADPLL_S_CLKOUT, + TI_ADPLL_S_CLKOUTX2, + TI_ADPLL_S_CLKOUTHIF, +}; + +enum ti_adpll_lj_outputs { + TI_ADPLL_LJ_CLKDCOLDO, + TI_ADPLL_LJ_CLKOUT, + TI_ADPLL_LJ_CLKOUTLDO, +}; + +struct ti_adpll_platform_data { + const bool is_type_s; + const int nr_max_inputs; + const int nr_max_outputs; + const int output_index; +}; + +struct ti_adpll_clock { + struct clk *clk; + struct clk_lookup *cl; + void (*unregister)(struct clk *clk); +}; + +struct ti_adpll_dco_data { + struct clk_hw hw; +}; + +struct ti_adpll_clkout_data { + struct ti_adpll_data *adpll; + struct clk_gate gate; + struct clk_hw hw; +}; + +struct ti_adpll_data { + struct device *dev; + const struct ti_adpll_platform_data *c; + struct device_node *np; + unsigned long pa; + void __iomem *iobase; + void __iomem *regs; + spinlock_t lock; /* For ADPLL shared register access */ + const char *parent_names[MAX_ADPLL_INPUTS]; + struct clk *parent_clocks[MAX_ADPLL_INPUTS]; + struct ti_adpll_clock *clocks; + struct clk_onecell_data outputs; + struct ti_adpll_dco_data dco; +}; + +static const char *ti_adpll_clk_get_name(struct ti_adpll_data *d, + int output_index, + const char *postfix) +{ + const char *name; + int err; + + if (output_index >= 0) { + err = of_property_read_string_index(d->np, + "clock-output-names", + output_index, + &name); + if (err) + return NULL; + } else { + const char *base_name = "adpll"; + char *buf; + + buf = devm_kzalloc(d->dev, 8 + 1 + strlen(base_name) + 1 + + strlen(postfix), GFP_KERNEL); + if (!buf) + return NULL; + sprintf(buf, "%08lx.%s.%s", d->pa, base_name, postfix); + name = buf; + } + + return name; +} + +#define ADPLL_MAX_CON_ID 16 /* See MAX_CON_ID */ + +static int ti_adpll_setup_clock(struct ti_adpll_data *d, struct clk *clock, + int index, int output_index, const char *name, + void (*unregister)(struct clk *clk)) +{ + struct clk_lookup *cl; + const char *postfix = NULL; + char con_id[ADPLL_MAX_CON_ID]; + + d->clocks[index].clk = clock; + d->clocks[index].unregister = unregister; + + /* Separate con_id in format "pll040dcoclkldo" to fit MAX_CON_ID */ + postfix = strrchr(name, '.'); + if (strlen(postfix) > 1) { + if (strlen(postfix) > ADPLL_MAX_CON_ID) + dev_warn(d->dev, "clock %s con_id lookup may fail\n", + name); + snprintf(con_id, 16, "pll%03lx%s", d->pa & 0xfff, postfix + 1); + cl = clkdev_create(clock, con_id, NULL); + if (!cl) + return -ENOMEM; + d->clocks[index].cl = cl; + } else { + dev_warn(d->dev, "no con_id for clock %s\n", name); + } + + if (output_index < 0) + return 0; + + d->outputs.clks[output_index] = clock; + d->outputs.clk_num++; + + return 0; +} + +static int ti_adpll_init_divider(struct ti_adpll_data *d, + enum ti_adpll_clocks index, + int output_index, char *name, + struct clk *parent_clock, + void __iomem *reg, + u8 shift, u8 width, + u8 clk_divider_flags) +{ + const char *child_name; + const char *parent_name; + struct clk *clock; + + child_name = ti_adpll_clk_get_name(d, output_index, name); + if (!child_name) + return -EINVAL; + + parent_name = __clk_get_name(parent_clock); + clock = clk_register_divider(d->dev, child_name, parent_name, 0, + reg, shift, width, clk_divider_flags, + &d->lock); + if (IS_ERR(clock)) { + dev_err(d->dev, "failed to register divider %s: %li\n", + name, PTR_ERR(clock)); + return PTR_ERR(clock); + } + + return ti_adpll_setup_clock(d, clock, index, output_index, child_name, + clk_unregister_divider); +} + +static int ti_adpll_init_mux(struct ti_adpll_data *d, + enum ti_adpll_clocks index, + char *name, struct clk *clk0, + struct clk *clk1, + void __iomem *reg, + u8 shift) +{ + const char *child_name; + const char *parents[2]; + struct clk *clock; + + child_name = ti_adpll_clk_get_name(d, -ENODEV, name); + if (!child_name) + return -ENOMEM; + parents[0] = __clk_get_name(clk0); + parents[1] = __clk_get_name(clk1); + clock = clk_register_mux(d->dev, child_name, parents, 2, 0, + reg, shift, 1, 0, &d->lock); + if (IS_ERR(clock)) { + dev_err(d->dev, "failed to register mux %s: %li\n", + name, PTR_ERR(clock)); + return PTR_ERR(clock); + } + + return ti_adpll_setup_clock(d, clock, index, -ENODEV, child_name, + clk_unregister_mux); +} + +static int ti_adpll_init_gate(struct ti_adpll_data *d, + enum ti_adpll_clocks index, + int output_index, char *name, + struct clk *parent_clock, + void __iomem *reg, + u8 bit_idx, + u8 clk_gate_flags) +{ + const char *child_name; + const char *parent_name; + struct clk *clock; + + child_name = ti_adpll_clk_get_name(d, output_index, name); + if (!child_name) + return -EINVAL; + + parent_name = __clk_get_name(parent_clock); + clock = clk_register_gate(d->dev, child_name, parent_name, 0, + reg, bit_idx, clk_gate_flags, + &d->lock); + if (IS_ERR(clock)) { + dev_err(d->dev, "failed to register gate %s: %li\n", + name, PTR_ERR(clock)); + return PTR_ERR(clock); + } + + return ti_adpll_setup_clock(d, clock, index, output_index, child_name, + clk_unregister_gate); +} + +static int ti_adpll_init_fixed_factor(struct ti_adpll_data *d, + enum ti_adpll_clocks index, + char *name, + struct clk *parent_clock, + unsigned int mult, + unsigned int div) +{ + const char *child_name; + const char *parent_name; + struct clk *clock; + + child_name = ti_adpll_clk_get_name(d, -ENODEV, name); + if (!child_name) + return -ENOMEM; + + parent_name = __clk_get_name(parent_clock); + clock = clk_register_fixed_factor(d->dev, child_name, parent_name, + 0, mult, div); + if (IS_ERR(clock)) + return PTR_ERR(clock); + + return ti_adpll_setup_clock(d, clock, index, -ENODEV, child_name, + clk_unregister); +} + +static void ti_adpll_set_idle_bypass(struct ti_adpll_data *d) +{ + unsigned long flags; + u32 v; + + spin_lock_irqsave(&d->lock, flags); + v = readl_relaxed(d->regs + ADPLL_CLKCTRL_OFFSET); + v |= BIT(ADPLL_CLKCTRL_IDLE); + writel_relaxed(v, d->regs + ADPLL_CLKCTRL_OFFSET); + spin_unlock_irqrestore(&d->lock, flags); +} + +static void ti_adpll_clear_idle_bypass(struct ti_adpll_data *d) +{ + unsigned long flags; + u32 v; + + spin_lock_irqsave(&d->lock, flags); + v = readl_relaxed(d->regs + ADPLL_CLKCTRL_OFFSET); + v &= ~BIT(ADPLL_CLKCTRL_IDLE); + writel_relaxed(v, d->regs + ADPLL_CLKCTRL_OFFSET); + spin_unlock_irqrestore(&d->lock, flags); +} + +static bool ti_adpll_clock_is_bypass(struct ti_adpll_data *d) +{ + u32 v; + + v = readl_relaxed(d->regs + ADPLL_STATUS_OFFSET); + + return v & BIT(ADPLL_STATUS_BYPASS); +} + +/* + * Locked and bypass are not actually mutually exclusive: if you only care + * about the DCO clock and not CLKOUT you can clear M2PWDNZ before enabling + * the PLL, resulting in status (FREQLOCK | PHASELOCK | BYPASS) after lock. + */ +static bool ti_adpll_is_locked(struct ti_adpll_data *d) +{ + u32 v = readl_relaxed(d->regs + ADPLL_STATUS_OFFSET); + + return (v & ADPLL_STATUS_PREPARED_MASK) == ADPLL_STATUS_PREPARED_MASK; +} + +static int ti_adpll_wait_lock(struct ti_adpll_data *d) +{ + int retries = ADPLL_MAX_RETRIES; + + do { + if (ti_adpll_is_locked(d)) + return 0; + usleep_range(200, 300); + } while (retries--); + + dev_err(d->dev, "pll failed to lock\n"); + return -ETIMEDOUT; +} + +static int ti_adpll_prepare(struct clk_hw *hw) +{ + struct ti_adpll_dco_data *dco = to_dco(hw); + struct ti_adpll_data *d = to_adpll(dco); + + ti_adpll_clear_idle_bypass(d); + ti_adpll_wait_lock(d); + + return 0; +} + +static void ti_adpll_unprepare(struct clk_hw *hw) +{ + struct ti_adpll_dco_data *dco = to_dco(hw); + struct ti_adpll_data *d = to_adpll(dco); + + ti_adpll_set_idle_bypass(d); +} + +static int ti_adpll_is_prepared(struct clk_hw *hw) +{ + struct ti_adpll_dco_data *dco = to_dco(hw); + struct ti_adpll_data *d = to_adpll(dco); + + return ti_adpll_is_locked(d); +} + +/* + * Note that the DCO clock is never subject to bypass: if the PLL is off, + * dcoclk is low. + */ +static unsigned long ti_adpll_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct ti_adpll_dco_data *dco = to_dco(hw); + struct ti_adpll_data *d = to_adpll(dco); + u32 frac_m, divider, v; + u64 rate; + unsigned long flags; + + if (ti_adpll_clock_is_bypass(d)) + return 0; + + spin_lock_irqsave(&d->lock, flags); + frac_m = readl_relaxed(d->regs + ADPLL_FRACDIV_OFFSET); + frac_m &= ADPLL_FRACDIV_FRACTIONALM_MASK; + rate = (u64)readw_relaxed(d->regs + ADPLL_MN2DIV_OFFSET) << 18; + rate += frac_m; + rate *= parent_rate; + divider = (readw_relaxed(d->regs + ADPLL_M2NDIV_OFFSET) + 1) << 18; + spin_unlock_irqrestore(&d->lock, flags); + + do_div(rate, divider); + + if (d->c->is_type_s) { + v = readl_relaxed(d->regs + ADPLL_CLKCTRL_OFFSET); + if (v & BIT(ADPLL_CLKCTRL_REGM4XEN_ADPLL_S)) + rate *= 4; + rate *= 2; + } + + return rate; +} + +/* PLL parent is always clkinp, bypass only affects the children */ +static u8 ti_adpll_get_parent(struct clk_hw *hw) +{ + return 0; +} + +static struct clk_ops ti_adpll_ops = { + .prepare = ti_adpll_prepare, + .unprepare = ti_adpll_unprepare, + .is_prepared = ti_adpll_is_prepared, + .recalc_rate = ti_adpll_recalc_rate, + .get_parent = ti_adpll_get_parent, +}; + +static int ti_adpll_init_dco(struct ti_adpll_data *d) +{ + struct clk_init_data init; + struct clk *clock; + const char *postfix; + int width, err; + + d->outputs.clks = devm_kzalloc(d->dev, sizeof(struct clk *) * + MAX_ADPLL_OUTPUTS, + GFP_KERNEL); + if (!d->outputs.clks) + return -ENOMEM; + + if (d->c->output_index < 0) + postfix = "dco"; + else + postfix = NULL; + + init.name = ti_adpll_clk_get_name(d, d->c->output_index, postfix); + if (!init.name) + return -EINVAL; + + init.parent_names = d->parent_names; + init.num_parents = d->c->nr_max_inputs; + init.ops = &ti_adpll_ops; + init.flags = CLK_GET_RATE_NOCACHE; + d->dco.hw.init = &init; + + if (d->c->is_type_s) + width = 5; + else + width = 4; + + /* Internal input clock divider N2 */ + err = ti_adpll_init_divider(d, TI_ADPLL_N2, -ENODEV, "n2", + d->parent_clocks[TI_ADPLL_CLKINP], + d->regs + ADPLL_MN2DIV_OFFSET, + ADPLL_MN2DIV_N2, width, 0); + if (err) + return err; + + clock = devm_clk_register(d->dev, &d->dco.hw); + if (IS_ERR(clock)) + return PTR_ERR(clock); + + return ti_adpll_setup_clock(d, clock, TI_ADPLL_DCO, d->c->output_index, + init.name, NULL); +} + +static int ti_adpll_clkout_enable(struct clk_hw *hw) +{ + struct ti_adpll_clkout_data *co = to_clkout(hw); + struct clk_hw *gate_hw = &co->gate.hw; + + __clk_hw_set_clk(gate_hw, hw); + + return clk_gate_ops.enable(gate_hw); +} + +static void ti_adpll_clkout_disable(struct clk_hw *hw) +{ + struct ti_adpll_clkout_data *co = to_clkout(hw); + struct clk_hw *gate_hw = &co->gate.hw; + + __clk_hw_set_clk(gate_hw, hw); + clk_gate_ops.disable(gate_hw); +} + +static int ti_adpll_clkout_is_enabled(struct clk_hw *hw) +{ + struct ti_adpll_clkout_data *co = to_clkout(hw); + struct clk_hw *gate_hw = &co->gate.hw; + + __clk_hw_set_clk(gate_hw, hw); + + return clk_gate_ops.is_enabled(gate_hw); +} + +/* Setting PLL bypass puts clkout and clkoutx2 into bypass */ +static u8 ti_adpll_clkout_get_parent(struct clk_hw *hw) +{ + struct ti_adpll_clkout_data *co = to_clkout(hw); + struct ti_adpll_data *d = co->adpll; + + return ti_adpll_clock_is_bypass(d); +} + +static int ti_adpll_init_clkout(struct ti_adpll_data *d, + enum ti_adpll_clocks index, + int output_index, int gate_bit, + char *name, struct clk *clk0, + struct clk *clk1) +{ + struct ti_adpll_clkout_data *co; + struct clk_init_data init; + struct clk_ops *ops; + const char *parent_names[2]; + const char *child_name; + struct clk *clock; + int err; + + co = devm_kzalloc(d->dev, sizeof(*co), GFP_KERNEL); + if (!co) + return -ENOMEM; + co->adpll = d; + + err = of_property_read_string_index(d->np, + "clock-output-names", + output_index, + &child_name); + if (err) + return err; + + ops = devm_kzalloc(d->dev, sizeof(*ops), GFP_KERNEL); + if (!ops) + return -ENOMEM; + + init.name = child_name; + init.ops = ops; + init.flags = CLK_IS_BASIC; + co->hw.init = &init; + parent_names[0] = __clk_get_name(clk0); + parent_names[1] = __clk_get_name(clk1); + init.parent_names = parent_names; + init.num_parents = 2; + + ops->get_parent = ti_adpll_clkout_get_parent; + ops->determine_rate = __clk_mux_determine_rate; + if (gate_bit) { + co->gate.lock = &d->lock; + co->gate.reg = d->regs + ADPLL_CLKCTRL_OFFSET; + co->gate.bit_idx = gate_bit; + ops->enable = ti_adpll_clkout_enable; + ops->disable = ti_adpll_clkout_disable; + ops->is_enabled = ti_adpll_clkout_is_enabled; + } + + clock = devm_clk_register(d->dev, &co->hw); + if (IS_ERR(clock)) { + dev_err(d->dev, "failed to register output %s: %li\n", + name, PTR_ERR(clock)); + return PTR_ERR(clock); + } + + return ti_adpll_setup_clock(d, clock, index, output_index, child_name, + NULL); +} + +static int ti_adpll_init_children_adpll_s(struct ti_adpll_data *d) +{ + int err; + + if (!d->c->is_type_s) + return 0; + + /* Internal mux, sources from divider N2 or clkinpulow */ + err = ti_adpll_init_mux(d, TI_ADPLL_BYPASS, "bypass", + d->clocks[TI_ADPLL_N2].clk, + d->parent_clocks[TI_ADPLL_CLKINPULOW], + d->regs + ADPLL_CLKCTRL_OFFSET, + ADPLL_CLKCTRL_ULOWCLKEN); + if (err) + return err; + + /* Internal divider M2, sources DCO */ + err = ti_adpll_init_divider(d, TI_ADPLL_M2, -ENODEV, "m2", + d->clocks[TI_ADPLL_DCO].clk, + d->regs + ADPLL_M2NDIV_OFFSET, + ADPLL_M2NDIV_M2, + ADPLL_M2NDIV_M2_ADPLL_S_WIDTH, + CLK_DIVIDER_ONE_BASED); + if (err) + return err; + + /* Internal fixed divider, after M2 before clkout */ + err = ti_adpll_init_fixed_factor(d, TI_ADPLL_DIV2, "div2", + d->clocks[TI_ADPLL_M2].clk, + 1, 2); + if (err) + return err; + + /* Output clkout with a mux and gate, sources from div2 or bypass */ + err = ti_adpll_init_clkout(d, TI_ADPLL_CLKOUT, TI_ADPLL_S_CLKOUT, + ADPLL_CLKCTRL_CLKOUTEN, "clkout", + d->clocks[TI_ADPLL_DIV2].clk, + d->clocks[TI_ADPLL_BYPASS].clk); + if (err) + return err; + + /* Output clkoutx2 with a mux and gate, sources from M2 or bypass */ + err = ti_adpll_init_clkout(d, TI_ADPLL_CLKOUT2, TI_ADPLL_S_CLKOUTX2, 0, + "clkout2", d->clocks[TI_ADPLL_M2].clk, + d->clocks[TI_ADPLL_BYPASS].clk); + if (err) + return err; + + /* Internal mux, sources from DCO and clkinphif */ + if (d->parent_clocks[TI_ADPLL_CLKINPHIF]) { + err = ti_adpll_init_mux(d, TI_ADPLL_HIF, "hif", + d->clocks[TI_ADPLL_DCO].clk, + d->parent_clocks[TI_ADPLL_CLKINPHIF], + d->regs + ADPLL_CLKCTRL_OFFSET, + ADPLL_CLKINPHIFSEL_ADPLL_S); + if (err) + return err; + } + + /* Output clkouthif with a divider M3, sources from hif */ + err = ti_adpll_init_divider(d, TI_ADPLL_M3, TI_ADPLL_S_CLKOUTHIF, "m3", + d->clocks[TI_ADPLL_HIF].clk, + d->regs + ADPLL_M3DIV_OFFSET, + ADPLL_M3DIV_M3, + ADPLL_M3DIV_M3_WIDTH, + CLK_DIVIDER_ONE_BASED); + if (err) + return err; + + /* Output clock dcoclkldo is the DCO */ + + return 0; +} + +static int ti_adpll_init_children_adpll_lj(struct ti_adpll_data *d) +{ + int err; + + if (d->c->is_type_s) + return 0; + + /* Output clkdcoldo, gated output of DCO */ + err = ti_adpll_init_gate(d, TI_ADPLL_DCO_GATE, TI_ADPLL_LJ_CLKDCOLDO, + "clkdcoldo", d->clocks[TI_ADPLL_DCO].clk, + d->regs + ADPLL_CLKCTRL_OFFSET, + ADPLL_CLKCTRL_CLKDCOLDOEN, 0); + if (err) + return err; + + /* Internal divider M2, sources from DCO */ + err = ti_adpll_init_divider(d, TI_ADPLL_M2, -ENODEV, + "m2", d->clocks[TI_ADPLL_DCO].clk, + d->regs + ADPLL_M2NDIV_OFFSET, + ADPLL_M2NDIV_M2, + ADPLL_M2NDIV_M2_ADPLL_LJ_WIDTH, + CLK_DIVIDER_ONE_BASED); + if (err) + return err; + + /* Output clkoutldo, gated output of M2 */ + err = ti_adpll_init_gate(d, TI_ADPLL_M2_GATE, TI_ADPLL_LJ_CLKOUTLDO, + "clkoutldo", d->clocks[TI_ADPLL_M2].clk, + d->regs + ADPLL_CLKCTRL_OFFSET, + ADPLL_CLKCTRL_CLKOUTLDOEN_ADPLL_LJ, + 0); + if (err) + return err; + + /* Internal mux, sources from divider N2 or clkinpulow */ + err = ti_adpll_init_mux(d, TI_ADPLL_BYPASS, "bypass", + d->clocks[TI_ADPLL_N2].clk, + d->parent_clocks[TI_ADPLL_CLKINPULOW], + d->regs + ADPLL_CLKCTRL_OFFSET, + ADPLL_CLKCTRL_ULOWCLKEN); + if (err) + return err; + + /* Output clkout, sources M2 or bypass */ + err = ti_adpll_init_clkout(d, TI_ADPLL_CLKOUT, TI_ADPLL_S_CLKOUT, + ADPLL_CLKCTRL_CLKOUTEN, "clkout", + d->clocks[TI_ADPLL_M2].clk, + d->clocks[TI_ADPLL_BYPASS].clk); + if (err) + return err; + + return 0; +} + +static void ti_adpll_free_resources(struct ti_adpll_data *d) +{ + int i; + + for (i = TI_ADPLL_M3; i >= 0; i--) { + struct ti_adpll_clock *ac = &d->clocks[i]; + + if (!ac || IS_ERR_OR_NULL(ac->clk)) + continue; + if (ac->cl) + clkdev_drop(ac->cl); + if (ac->unregister) + ac->unregister(ac->clk); + } +} + +/* MPU PLL manages the lock register for all PLLs */ +static void ti_adpll_unlock_all(void __iomem *reg) +{ + u32 v; + + v = readl_relaxed(reg); + if (v == ADPLL_PLLSS_MMR_LOCK_ENABLED) + writel_relaxed(ADPLL_PLLSS_MMR_UNLOCK_MAGIC, reg); +} + +static int ti_adpll_init_registers(struct ti_adpll_data *d) +{ + int register_offset = 0; + + if (d->c->is_type_s) { + register_offset = 8; + ti_adpll_unlock_all(d->iobase + ADPLL_PLLSS_MMR_LOCK_OFFSET); + } + + d->regs = d->iobase + register_offset + ADPLL_PWRCTRL_OFFSET; + + return 0; +} + +static int ti_adpll_init_inputs(struct ti_adpll_data *d) +{ + const char *error = "need at least %i inputs"; + struct clk *clock; + int nr_inputs; + + nr_inputs = of_clk_get_parent_count(d->np); + if (nr_inputs < d->c->nr_max_inputs) { + dev_err(d->dev, error, nr_inputs); + return -EINVAL; + } + of_clk_parent_fill(d->np, d->parent_names, nr_inputs); + + clock = devm_clk_get(d->dev, d->parent_names[0]); + if (IS_ERR(clock)) { + dev_err(d->dev, "could not get clkinp\n"); + return PTR_ERR(clock); + } + d->parent_clocks[TI_ADPLL_CLKINP] = clock; + + clock = devm_clk_get(d->dev, d->parent_names[1]); + if (IS_ERR(clock)) { + dev_err(d->dev, "could not get clkinpulow clock\n"); + return PTR_ERR(clock); + } + d->parent_clocks[TI_ADPLL_CLKINPULOW] = clock; + + if (d->c->is_type_s) { + clock = devm_clk_get(d->dev, d->parent_names[2]); + if (IS_ERR(clock)) { + dev_err(d->dev, "could not get clkinphif clock\n"); + return PTR_ERR(clock); + } + d->parent_clocks[TI_ADPLL_CLKINPHIF] = clock; + } + + return 0; +} + +static const struct ti_adpll_platform_data ti_adpll_type_s = { + .is_type_s = true, + .nr_max_inputs = MAX_ADPLL_INPUTS, + .nr_max_outputs = MAX_ADPLL_OUTPUTS, + .output_index = TI_ADPLL_S_DCOCLKLDO, +}; + +static const struct ti_adpll_platform_data ti_adpll_type_lj = { + .is_type_s = false, + .nr_max_inputs = MAX_ADPLL_INPUTS - 1, + .nr_max_outputs = MAX_ADPLL_OUTPUTS - 1, + .output_index = -EINVAL, +}; + +static const struct of_device_id ti_adpll_match[] = { + { .compatible = "ti,dm814-adpll-s-clock", &ti_adpll_type_s }, + { .compatible = "ti,dm814-adpll-lj-clock", &ti_adpll_type_lj }, + {}, +}; +MODULE_DEVICE_TABLE(of, ti_adpll_match); + +static int ti_adpll_probe(struct platform_device *pdev) +{ + struct device_node *node = pdev->dev.of_node; + struct device *dev = &pdev->dev; + const struct of_device_id *match; + const struct ti_adpll_platform_data *pdata; + struct ti_adpll_data *d; + struct resource *res; + int err; + + match = of_match_device(ti_adpll_match, dev); + if (match) + pdata = match->data; + else + return -ENODEV; + + d = devm_kzalloc(dev, sizeof(*d), GFP_KERNEL); + if (!d) + return -ENOMEM; + d->dev = dev; + d->np = node; + d->c = pdata; + dev_set_drvdata(d->dev, d); + spin_lock_init(&d->lock); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + d->pa = res->start; + + d->iobase = devm_ioremap_resource(dev, res); + if (IS_ERR(d->iobase)) { + dev_err(dev, "could not get IO base: %li\n", + PTR_ERR(d->iobase)); + return PTR_ERR(d->iobase); + } + + err = ti_adpll_init_registers(d); + if (err) + return err; + + err = ti_adpll_init_inputs(d); + if (err) + return err; + + d->clocks = devm_kzalloc(d->dev, sizeof(struct ti_adpll_clock) * + TI_ADPLL_NR_CLOCKS, + GFP_KERNEL); + if (!d->clocks) + return -ENOMEM; + + err = ti_adpll_init_dco(d); + if (err) { + dev_err(dev, "could not register dco: %i\n", err); + goto free; + } + + err = ti_adpll_init_children_adpll_s(d); + if (err) + goto free; + err = ti_adpll_init_children_adpll_lj(d); + if (err) + goto free; + + err = of_clk_add_provider(d->np, of_clk_src_onecell_get, &d->outputs); + if (err) + goto free; + + return 0; + +free: + WARN_ON(1); + ti_adpll_free_resources(d); + + return err; +} + +static int ti_adpll_remove(struct platform_device *pdev) +{ + struct ti_adpll_data *d = dev_get_drvdata(&pdev->dev); + + ti_adpll_free_resources(d); + + return 0; +} + +static struct platform_driver ti_adpll_driver = { + .driver = { + .name = "ti-adpll", + .of_match_table = ti_adpll_match, + }, + .probe = ti_adpll_probe, + .remove = ti_adpll_remove, +}; + +static int __init ti_adpll_init(void) +{ + return platform_driver_register(&ti_adpll_driver); +} +core_initcall(ti_adpll_init); + +static void __exit ti_adpll_exit(void) +{ + platform_driver_unregister(&ti_adpll_driver); +} +module_exit(ti_adpll_exit); + +MODULE_DESCRIPTION("Clock driver for dm814x ADPLL"); +MODULE_ALIAS("platform:dm814-adpll-clock"); +MODULE_AUTHOR("Tony LIndgren "); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/ti/apll.c b/drivers/clk/ti/apll.c index b336a8c11e2a6e442fe30022f0264d91cdcdef80..6411e132faa2b01e25598edbdd2139b3e6185a5d 100644 --- a/drivers/clk/ti/apll.c +++ b/drivers/clk/ti/apll.c @@ -140,11 +140,21 @@ static void __init omap_clk_register_apll(struct clk_hw *hw, struct dpll_data *ad = clk_hw->dpll_data; struct clk *clk; - ad->clk_ref = of_clk_get(node, 0); - ad->clk_bypass = of_clk_get(node, 1); + clk = of_clk_get(node, 0); + if (IS_ERR(clk)) { + pr_debug("clk-ref for %s not ready, retry\n", + node->name); + if (!ti_clk_retry_init(node, hw, omap_clk_register_apll)) + return; + + goto cleanup; + } - if (IS_ERR(ad->clk_ref) || IS_ERR(ad->clk_bypass)) { - pr_debug("clk-ref or clk-bypass for %s not ready, retry\n", + ad->clk_ref = __clk_get_hw(clk); + + clk = of_clk_get(node, 1); + if (IS_ERR(clk)) { + pr_debug("clk-bypass for %s not ready, retry\n", node->name); if (!ti_clk_retry_init(node, hw, omap_clk_register_apll)) return; @@ -152,6 +162,8 @@ static void __init omap_clk_register_apll(struct clk_hw *hw, goto cleanup; } + ad->clk_bypass = __clk_get_hw(clk); + clk = clk_register(NULL, &clk_hw->hw); if (!IS_ERR(clk)) { of_clk_add_provider(node, of_clk_src_simple_get, clk); diff --git a/drivers/clk/ti/clk-814x.c b/drivers/clk/ti/clk-814x.c index 9e85fcc74cc947399fcdaea76527737cab640cc6..52c6efc53731881b8ddbc3686e2227594697d841 100644 --- a/drivers/clk/ti/clk-814x.c +++ b/drivers/clk/ti/clk-814x.c @@ -5,8 +5,10 @@ */ #include +#include #include #include +#include #include "clock.h" @@ -27,11 +29,62 @@ static struct ti_dt_clk dm814_clks[] = { { .node_name = NULL }, }; +static bool timer_clocks_initialized; + +static int __init dm814x_adpll_early_init(void) +{ + struct device_node *np; + + if (!timer_clocks_initialized) + return -ENODEV; + + np = of_find_node_by_name(NULL, "pllss"); + if (!np) { + pr_err("Could not find node for plls\n"); + return -ENODEV; + } + + of_platform_populate(np, NULL, NULL, NULL); + + return 0; +} +core_initcall(dm814x_adpll_early_init); + +static const char * const init_clocks[] = { + "pll040clkout", /* MPU 481c5040.adpll.clkout */ + "pll290clkout", /* DDR 481c5290.adpll.clkout */ +}; + +static int __init dm814x_adpll_enable_init_clocks(void) +{ + int i, err; + + if (!timer_clocks_initialized) + return -ENODEV; + + for (i = 0; i < ARRAY_SIZE(init_clocks); i++) { + struct clk *clock; + + clock = clk_get(NULL, init_clocks[i]); + if (WARN(IS_ERR(clock), "could not find init clock %s\n", + init_clocks[i])) + continue; + err = clk_prepare_enable(clock); + if (WARN(err, "could not enable init clock %s\n", + init_clocks[i])) + continue; + } + + return 0; +} +postcore_initcall(dm814x_adpll_enable_init_clocks); + int __init dm814x_dt_clk_init(void) { ti_dt_clocks_register(dm814_clks); omap2_clk_disable_autoidle_all(); omap2_clk_enable_init_clocks(NULL, 0); + timer_clocks_initialized = true; return 0; } diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c index b5bcd77e8d0f5e31b3887ebdd3a4f441c7909a46..5fcf247759ac413a94c155571d8833bc8261a974 100644 --- a/drivers/clk/ti/clk.c +++ b/drivers/clk/ti/clk.c @@ -305,8 +305,8 @@ struct clk __init *ti_clk_register_clk(struct ti_clk *setup) case TI_CLK_FIXED: fixed = setup->data; - clk = clk_register_fixed_rate(NULL, setup->name, NULL, - CLK_IS_ROOT, fixed->frequency); + clk = clk_register_fixed_rate(NULL, setup->name, NULL, 0, + fixed->frequency); break; case TI_CLK_MUX: clk = ti_clk_register_mux(setup); diff --git a/drivers/clk/ti/clkt_dpll.c b/drivers/clk/ti/clkt_dpll.c index b5cc6f66ae5df5e1725dc21ebfd3b18ca5eac1fa..032c658a5f5ef6619108f66458f119ad924160a3 100644 --- a/drivers/clk/ti/clkt_dpll.c +++ b/drivers/clk/ti/clkt_dpll.c @@ -254,7 +254,7 @@ unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk) v >>= __ffs(dd->enable_mask); if (_omap2_dpll_is_in_bypass(v)) - return clk_get_rate(dd->clk_bypass); + return clk_hw_get_rate(dd->clk_bypass); v = ti_clk_ll_ops->clk_readl(dd->mult_div1_reg); dpll_mult = v & dd->mult_mask; @@ -262,7 +262,7 @@ unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk) dpll_div = v & dd->div1_mask; dpll_div >>= __ffs(dd->div1_mask); - dpll_clk = (u64)clk_get_rate(dd->clk_ref) * dpll_mult; + dpll_clk = (u64)clk_hw_get_rate(dd->clk_ref) * dpll_mult; do_div(dpll_clk, dpll_div + 1); return dpll_clk; @@ -301,7 +301,7 @@ long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate, dd = clk->dpll_data; - ref_rate = clk_get_rate(dd->clk_ref); + ref_rate = clk_hw_get_rate(dd->clk_ref); clk_name = clk_hw_get_name(hw); pr_debug("clock: %s: starting DPLL round_rate, target rate %lu\n", clk_name, target_rate); diff --git a/drivers/clk/ti/clockdomain.c b/drivers/clk/ti/clockdomain.c index b9bc3b8df659d853ba0a51a631f98d9a0f1c33c1..6cf9dd189a924e9d74472a260f7e816585b0d43b 100644 --- a/drivers/clk/ti/clockdomain.c +++ b/drivers/clk/ti/clockdomain.c @@ -109,7 +109,7 @@ static void __init of_ti_clockdomain_setup(struct device_node *node) struct clk_hw *clk_hw; const char *clkdm_name = node->name; int i; - int num_clks; + unsigned int num_clks; num_clks = of_clk_get_parent_count(node); diff --git a/drivers/clk/ti/composite.c b/drivers/clk/ti/composite.c index dbef218fe5ecd3ad64319700ac1b142d9c42a89c..1cf70f452e1e660b594a5a92b99db21008abc28d 100644 --- a/drivers/clk/ti/composite.c +++ b/drivers/clk/ti/composite.c @@ -28,8 +28,6 @@ #undef pr_fmt #define pr_fmt(fmt) "%s: " fmt, __func__ -#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw) - static unsigned long ti_composite_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { @@ -236,14 +234,14 @@ static void __init _register_composite(struct clk_hw *hw, static void __init of_ti_composite_clk_setup(struct device_node *node) { - int num_clks; + unsigned int num_clks; int i; struct clk_hw_omap_comp *cclk; /* Number of component clocks to be put inside this clock */ num_clks = of_clk_get_parent_count(node); - if (num_clks < 1) { + if (!num_clks) { pr_err("composite clk %s must have component(s)\n", node->name); return; } @@ -273,13 +271,13 @@ CLK_OF_DECLARE(ti_composite_clock, "ti,composite-clock", int __init ti_clk_add_component(struct device_node *node, struct clk_hw *hw, int type) { - int num_parents; + unsigned int num_parents; const char **parent_names; struct component_clk *clk; num_parents = of_clk_get_parent_count(node); - if (num_parents < 1) { + if (!num_parents) { pr_err("component-clock %s must have parent(s)\n", node->name); return -EINVAL; } diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c index df2558350fc1d6be681d818c361339acd2afaba3..b4e5de16e561e05a3d2e9ff41d38beb52f48555f 100644 --- a/drivers/clk/ti/divider.c +++ b/drivers/clk/ti/divider.c @@ -26,8 +26,6 @@ #undef pr_fmt #define pr_fmt(fmt) "%s: " fmt, __func__ -#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw) - #define div_mask(d) ((1 << ((d)->width)) - 1) static unsigned int _get_table_maxdiv(const struct clk_div_table *table) diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c index 5519b386edc02f74992620d99d8d32921523b5b0..3bc9959f71c39f78a8e28772fe4ae7548ca030bb 100644 --- a/drivers/clk/ti/dpll.c +++ b/drivers/clk/ti/dpll.c @@ -147,11 +147,22 @@ static void __init _register_dpll(struct clk_hw *hw, struct dpll_data *dd = clk_hw->dpll_data; struct clk *clk; - dd->clk_ref = of_clk_get(node, 0); - dd->clk_bypass = of_clk_get(node, 1); + clk = of_clk_get(node, 0); + if (IS_ERR(clk)) { + pr_debug("clk-ref missing for %s, retry later\n", + node->name); + if (!ti_clk_retry_init(node, hw, _register_dpll)) + return; - if (IS_ERR(dd->clk_ref) || IS_ERR(dd->clk_bypass)) { - pr_debug("clk-ref or clk-bypass missing for %s, retry later\n", + goto cleanup; + } + + dd->clk_ref = __clk_get_hw(clk); + + clk = of_clk_get(node, 1); + + if (IS_ERR(clk)) { + pr_debug("clk-bypass missing for %s, retry later\n", node->name); if (!ti_clk_retry_init(node, hw, _register_dpll)) return; @@ -159,6 +170,8 @@ static void __init _register_dpll(struct clk_hw *hw, goto cleanup; } + dd->clk_bypass = __clk_get_hw(clk); + /* register the clock */ clk = clk_register(NULL, &clk_hw->hw); @@ -251,8 +264,8 @@ struct clk *ti_clk_register_dpll(struct ti_clk *setup) dd->recal_en_bit = dpll->recal_en_bit; dd->recal_st_bit = dpll->recal_st_bit; - dd->clk_ref = clk_ref; - dd->clk_bypass = clk_bypass; + dd->clk_ref = __clk_get_hw(clk_ref); + dd->clk_bypass = __clk_get_hw(clk_bypass); if (dpll->flags & CLKF_CORE) ops = &omap3_dpll_core_ck_ops; @@ -361,7 +374,7 @@ static void __init of_ti_dpll_setup(struct device_node *node, init->ops = ops; init->num_parents = of_clk_get_parent_count(node); - if (init->num_parents < 1) { + if (!init->num_parents) { pr_err("%s must have parent(s)\n", node->name); goto cleanup; } diff --git a/drivers/clk/ti/dpll3xxx.c b/drivers/clk/ti/dpll3xxx.c index cc739291a3ce47466e87023c2bdfd56951e7bf2f..88f2ce81ba55988164c9e77657b78b65ac65a3a8 100644 --- a/drivers/clk/ti/dpll3xxx.c +++ b/drivers/clk/ti/dpll3xxx.c @@ -98,7 +98,7 @@ static u16 _omap3_dpll_compute_freqsel(struct clk_hw_omap *clk, u8 n) unsigned long fint; u16 f = 0; - fint = clk_get_rate(clk->dpll_data->clk_ref) / n; + fint = clk_hw_get_rate(clk->dpll_data->clk_ref) / n; pr_debug("clock: fint is %lu\n", fint); @@ -460,12 +460,11 @@ int omap3_noncore_dpll_enable(struct clk_hw *hw) parent = clk_hw_get_parent(hw); - if (clk_hw_get_rate(hw) == - clk_hw_get_rate(__clk_get_hw(dd->clk_bypass))) { - WARN_ON(parent != __clk_get_hw(dd->clk_bypass)); + if (clk_hw_get_rate(hw) == clk_hw_get_rate(dd->clk_bypass)) { + WARN_ON(parent != dd->clk_bypass); r = _omap3_noncore_dpll_bypass(clk); } else { - WARN_ON(parent != __clk_get_hw(dd->clk_ref)); + WARN_ON(parent != dd->clk_ref); r = _omap3_noncore_dpll_lock(clk); } @@ -513,13 +512,13 @@ int omap3_noncore_dpll_determine_rate(struct clk_hw *hw, if (!dd) return -EINVAL; - if (clk_get_rate(dd->clk_bypass) == req->rate && + if (clk_hw_get_rate(dd->clk_bypass) == req->rate && (dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) { - req->best_parent_hw = __clk_get_hw(dd->clk_bypass); + req->best_parent_hw = dd->clk_bypass; } else { req->rate = omap2_dpll_round_rate(hw, req->rate, &req->best_parent_rate); - req->best_parent_hw = __clk_get_hw(dd->clk_ref); + req->best_parent_hw = dd->clk_ref; } req->best_parent_rate = req->rate; @@ -577,7 +576,7 @@ int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate, if (!dd) return -EINVAL; - if (clk_hw_get_parent(hw) != __clk_get_hw(dd->clk_ref)) + if (clk_hw_get_parent(hw) != dd->clk_ref) return -EINVAL; if (dd->last_rounded_rate == 0) diff --git a/drivers/clk/ti/dpll44xx.c b/drivers/clk/ti/dpll44xx.c index 660d7436ac243a89a2ac2573a8b67a019bac0301..82c05b55a7be83808b20e5da172900ba63c0a26e 100644 --- a/drivers/clk/ti/dpll44xx.c +++ b/drivers/clk/ti/dpll44xx.c @@ -94,7 +94,7 @@ static void omap4_dpll_lpmode_recalc(struct dpll_data *dd) { long fint, fout; - fint = clk_get_rate(dd->clk_ref) / (dd->last_rounded_n + 1); + fint = clk_hw_get_rate(dd->clk_ref) / (dd->last_rounded_n + 1); fout = fint * dd->last_rounded_m; if ((fint < OMAP4_DPLL_LP_FINT_MAX) && (fout < OMAP4_DPLL_LP_FOUT_MAX)) @@ -212,13 +212,13 @@ int omap4_dpll_regm4xen_determine_rate(struct clk_hw *hw, if (!dd) return -EINVAL; - if (clk_get_rate(dd->clk_bypass) == req->rate && + if (clk_hw_get_rate(dd->clk_bypass) == req->rate && (dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) { - req->best_parent_hw = __clk_get_hw(dd->clk_bypass); + req->best_parent_hw = dd->clk_bypass; } else { req->rate = omap4_dpll_regm4xen_round_rate(hw, req->rate, &req->best_parent_rate); - req->best_parent_hw = __clk_get_hw(dd->clk_ref); + req->best_parent_hw = dd->clk_ref; } req->best_parent_rate = req->rate; diff --git a/drivers/clk/ti/gate.c b/drivers/clk/ti/gate.c index 5429d35343639632a821548ef7837ccacd172a31..bc05f276f32b90039a0eed1879d7a1201930ea97 100644 --- a/drivers/clk/ti/gate.c +++ b/drivers/clk/ti/gate.c @@ -24,8 +24,6 @@ #include "clock.h" -#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw) - #undef pr_fmt #define pr_fmt(fmt) "%s: " fmt, __func__ diff --git a/drivers/clk/ti/mux.c b/drivers/clk/ti/mux.c index dab9ba88b9d6d2b1b97e2472694bbb588997d8de..44777ab6fdeb3b6f8d0fcd5386790c506f39d300 100644 --- a/drivers/clk/ti/mux.c +++ b/drivers/clk/ti/mux.c @@ -26,8 +26,6 @@ #undef pr_fmt #define pr_fmt(fmt) "%s: " fmt, __func__ -#define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw) - static u8 ti_clk_mux_get_parent(struct clk_hw *hw) { struct clk_mux *mux = to_clk_mux(hw); @@ -180,7 +178,7 @@ static void of_mux_clk_setup(struct device_node *node) { struct clk *clk; void __iomem *reg; - int num_parents; + unsigned int num_parents; const char **parent_names; u8 clk_mux_flags = 0; u32 mask = 0; @@ -263,7 +261,7 @@ struct clk_hw *ti_clk_build_component_mux(struct ti_clk_mux *setup) static void __init of_ti_composite_mux_clk_setup(struct device_node *node) { struct clk_mux *mux; - int num_parents; + unsigned int num_parents; u32 val; mux = kzalloc(sizeof(*mux), GFP_KERNEL); diff --git a/drivers/clk/ux500/abx500-clk.c b/drivers/clk/ux500/abx500-clk.c index 222425d08ab6ac3faf05b6385d51c2df1b33713f..a07c31e6f26d2f926add57cc63520dceef610c3d 100644 --- a/drivers/clk/ux500/abx500-clk.c +++ b/drivers/clk/ux500/abx500-clk.c @@ -40,8 +40,7 @@ static int ab8500_reg_clks(struct device *dev) return ret; /* ab8500_sysclk */ - clk = clk_reg_prcmu_gate("ab8500_sysclk", NULL, PRCMU_SYSCLK, - CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("ab8500_sysclk", NULL, PRCMU_SYSCLK, 0); clk_register_clkdev(clk, "sysclk", "ab8500-usb.0"); clk_register_clkdev(clk, "sysclk", "ab-iddet.0"); clk_register_clkdev(clk, "sysclk", "snd-soc-mop500.0"); @@ -68,7 +67,7 @@ static int ab8500_reg_clks(struct device *dev) clk = clk_reg_sysctrl_gate_fixed_rate(dev, "ulpclk", NULL, AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_ULPCLKREQ, AB8500_SYSULPCLKCTRL1_ULPCLKREQ, - 38400000, 9000, CLK_IS_ROOT); + 38400000, 9000, 0); clk_register_clkdev(clk, "ulpclk", "snd-soc-mop500.0"); /* ab8500_intclk */ diff --git a/drivers/clk/ux500/u8500_of_clk.c b/drivers/clk/ux500/u8500_of_clk.c index 271c09644652c72e3f057e8d90b2ebcb1d1f258c..9a736d939806e998c2cb42d674f6e8935dc9f35c 100644 --- a/drivers/clk/ux500/u8500_of_clk.c +++ b/drivers/clk/ux500/u8500_of_clk.c @@ -91,21 +91,21 @@ void u8500_clk_init(void) /* Clock sources */ clk = clk_reg_prcmu_gate("soc0_pll", NULL, PRCMU_PLLSOC0, - CLK_IS_ROOT|CLK_IGNORE_UNUSED); + CLK_IGNORE_UNUSED); prcmu_clk[PRCMU_PLLSOC0] = clk; clk = clk_reg_prcmu_gate("soc1_pll", NULL, PRCMU_PLLSOC1, - CLK_IS_ROOT|CLK_IGNORE_UNUSED); + CLK_IGNORE_UNUSED); prcmu_clk[PRCMU_PLLSOC1] = clk; clk = clk_reg_prcmu_gate("ddr_pll", NULL, PRCMU_PLLDDR, - CLK_IS_ROOT|CLK_IGNORE_UNUSED); + CLK_IGNORE_UNUSED); prcmu_clk[PRCMU_PLLDDR] = clk; /* FIXME: Add sys, ulp and int clocks here. */ rtc_clk = clk_register_fixed_rate(NULL, "rtc32k", "NULL", - CLK_IS_ROOT|CLK_IGNORE_UNUSED, + CLK_IGNORE_UNUSED, 32768); /* PRCMU clocks */ @@ -126,105 +126,101 @@ void u8500_clk_init(void) clk = clk_reg_prcmu_gate("sgclk", sgaclk_parent, PRCMU_SGACLK, 0); else - clk = clk_reg_prcmu_gate("sgclk", NULL, - PRCMU_SGACLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("sgclk", NULL, PRCMU_SGACLK, 0); prcmu_clk[PRCMU_SGACLK] = clk; - clk = clk_reg_prcmu_gate("uartclk", NULL, PRCMU_UARTCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("uartclk", NULL, PRCMU_UARTCLK, 0); prcmu_clk[PRCMU_UARTCLK] = clk; - clk = clk_reg_prcmu_gate("msp02clk", NULL, PRCMU_MSP02CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("msp02clk", NULL, PRCMU_MSP02CLK, 0); prcmu_clk[PRCMU_MSP02CLK] = clk; - clk = clk_reg_prcmu_gate("msp1clk", NULL, PRCMU_MSP1CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("msp1clk", NULL, PRCMU_MSP1CLK, 0); prcmu_clk[PRCMU_MSP1CLK] = clk; - clk = clk_reg_prcmu_gate("i2cclk", NULL, PRCMU_I2CCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("i2cclk", NULL, PRCMU_I2CCLK, 0); prcmu_clk[PRCMU_I2CCLK] = clk; - clk = clk_reg_prcmu_gate("slimclk", NULL, PRCMU_SLIMCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("slimclk", NULL, PRCMU_SLIMCLK, 0); prcmu_clk[PRCMU_SLIMCLK] = clk; - clk = clk_reg_prcmu_gate("per1clk", NULL, PRCMU_PER1CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("per1clk", NULL, PRCMU_PER1CLK, 0); prcmu_clk[PRCMU_PER1CLK] = clk; - clk = clk_reg_prcmu_gate("per2clk", NULL, PRCMU_PER2CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("per2clk", NULL, PRCMU_PER2CLK, 0); prcmu_clk[PRCMU_PER2CLK] = clk; - clk = clk_reg_prcmu_gate("per3clk", NULL, PRCMU_PER3CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("per3clk", NULL, PRCMU_PER3CLK, 0); prcmu_clk[PRCMU_PER3CLK] = clk; - clk = clk_reg_prcmu_gate("per5clk", NULL, PRCMU_PER5CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("per5clk", NULL, PRCMU_PER5CLK, 0); prcmu_clk[PRCMU_PER5CLK] = clk; - clk = clk_reg_prcmu_gate("per6clk", NULL, PRCMU_PER6CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("per6clk", NULL, PRCMU_PER6CLK, 0); prcmu_clk[PRCMU_PER6CLK] = clk; - clk = clk_reg_prcmu_gate("per7clk", NULL, PRCMU_PER7CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("per7clk", NULL, PRCMU_PER7CLK, 0); prcmu_clk[PRCMU_PER7CLK] = clk; clk = clk_reg_prcmu_scalable("lcdclk", NULL, PRCMU_LCDCLK, 0, - CLK_IS_ROOT|CLK_SET_RATE_GATE); + CLK_SET_RATE_GATE); prcmu_clk[PRCMU_LCDCLK] = clk; - clk = clk_reg_prcmu_opp_gate("bmlclk", NULL, PRCMU_BMLCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_opp_gate("bmlclk", NULL, PRCMU_BMLCLK, 0); prcmu_clk[PRCMU_BMLCLK] = clk; clk = clk_reg_prcmu_scalable("hsitxclk", NULL, PRCMU_HSITXCLK, 0, - CLK_IS_ROOT|CLK_SET_RATE_GATE); + CLK_SET_RATE_GATE); prcmu_clk[PRCMU_HSITXCLK] = clk; clk = clk_reg_prcmu_scalable("hsirxclk", NULL, PRCMU_HSIRXCLK, 0, - CLK_IS_ROOT|CLK_SET_RATE_GATE); + CLK_SET_RATE_GATE); prcmu_clk[PRCMU_HSIRXCLK] = clk; clk = clk_reg_prcmu_scalable("hdmiclk", NULL, PRCMU_HDMICLK, 0, - CLK_IS_ROOT|CLK_SET_RATE_GATE); + CLK_SET_RATE_GATE); prcmu_clk[PRCMU_HDMICLK] = clk; - clk = clk_reg_prcmu_gate("apeatclk", NULL, PRCMU_APEATCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("apeatclk", NULL, PRCMU_APEATCLK, 0); prcmu_clk[PRCMU_APEATCLK] = clk; clk = clk_reg_prcmu_scalable("apetraceclk", NULL, PRCMU_APETRACECLK, 0, - CLK_IS_ROOT|CLK_SET_RATE_GATE); + CLK_SET_RATE_GATE); prcmu_clk[PRCMU_APETRACECLK] = clk; - clk = clk_reg_prcmu_gate("mcdeclk", NULL, PRCMU_MCDECLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("mcdeclk", NULL, PRCMU_MCDECLK, 0); prcmu_clk[PRCMU_MCDECLK] = clk; - clk = clk_reg_prcmu_opp_gate("ipi2cclk", NULL, PRCMU_IPI2CCLK, - CLK_IS_ROOT); + clk = clk_reg_prcmu_opp_gate("ipi2cclk", NULL, PRCMU_IPI2CCLK, 0); prcmu_clk[PRCMU_IPI2CCLK] = clk; - clk = clk_reg_prcmu_gate("dsialtclk", NULL, PRCMU_DSIALTCLK, - CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("dsialtclk", NULL, PRCMU_DSIALTCLK, 0); prcmu_clk[PRCMU_DSIALTCLK] = clk; - clk = clk_reg_prcmu_gate("dmaclk", NULL, PRCMU_DMACLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("dmaclk", NULL, PRCMU_DMACLK, 0); prcmu_clk[PRCMU_DMACLK] = clk; - clk = clk_reg_prcmu_gate("b2r2clk", NULL, PRCMU_B2R2CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("b2r2clk", NULL, PRCMU_B2R2CLK, 0); prcmu_clk[PRCMU_B2R2CLK] = clk; clk = clk_reg_prcmu_scalable("tvclk", NULL, PRCMU_TVCLK, 0, - CLK_IS_ROOT|CLK_SET_RATE_GATE); + CLK_SET_RATE_GATE); prcmu_clk[PRCMU_TVCLK] = clk; - clk = clk_reg_prcmu_gate("sspclk", NULL, PRCMU_SSPCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("sspclk", NULL, PRCMU_SSPCLK, 0); prcmu_clk[PRCMU_SSPCLK] = clk; - clk = clk_reg_prcmu_gate("rngclk", NULL, PRCMU_RNGCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("rngclk", NULL, PRCMU_RNGCLK, 0); prcmu_clk[PRCMU_RNGCLK] = clk; - clk = clk_reg_prcmu_gate("uiccclk", NULL, PRCMU_UICCCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("uiccclk", NULL, PRCMU_UICCCLK, 0); prcmu_clk[PRCMU_UICCCLK] = clk; - clk = clk_reg_prcmu_gate("timclk", NULL, PRCMU_TIMCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("timclk", NULL, PRCMU_TIMCLK, 0); prcmu_clk[PRCMU_TIMCLK] = clk; clk = clk_reg_prcmu_opp_volt_scalable("sdmmcclk", NULL, PRCMU_SDMMCCLK, - 100000000, - CLK_IS_ROOT|CLK_SET_RATE_GATE); + 100000000, CLK_SET_RATE_GATE); prcmu_clk[PRCMU_SDMMCCLK] = clk; clk = clk_reg_prcmu_scalable("dsi_pll", "hdmiclk", @@ -252,7 +248,7 @@ void u8500_clk_init(void) prcmu_clk[PRCMU_DSI2ESCCLK] = clk; clk = clk_reg_prcmu_scalable_rate("armss", NULL, - PRCMU_ARMSS, 0, CLK_IS_ROOT|CLK_IGNORE_UNUSED); + PRCMU_ARMSS, 0, CLK_IGNORE_UNUSED); prcmu_clk[PRCMU_ARMSS] = clk; twd_clk = clk_register_fixed_factor(NULL, "smp_twd", "armss", diff --git a/drivers/clk/ux500/u8540_clk.c b/drivers/clk/ux500/u8540_clk.c index d7bcb7a86615f91f518c1719f812b29f783c23d3..86549e59fb42b5e0853cd936d2fc90a75cd204c8 100644 --- a/drivers/clk/ux500/u8540_clk.c +++ b/drivers/clk/ux500/u8540_clk.c @@ -56,28 +56,28 @@ void u8540_clk_init(void) /* Clock sources. */ /* Fixed ClockGen */ clk = clk_reg_prcmu_gate("soc0_pll", NULL, PRCMU_PLLSOC0, - CLK_IS_ROOT|CLK_IGNORE_UNUSED); + CLK_IGNORE_UNUSED); clk_register_clkdev(clk, "soc0_pll", NULL); clk = clk_reg_prcmu_gate("soc1_pll", NULL, PRCMU_PLLSOC1, - CLK_IS_ROOT|CLK_IGNORE_UNUSED); + CLK_IGNORE_UNUSED); clk_register_clkdev(clk, "soc1_pll", NULL); clk = clk_reg_prcmu_gate("ddr_pll", NULL, PRCMU_PLLDDR, - CLK_IS_ROOT|CLK_IGNORE_UNUSED); + CLK_IGNORE_UNUSED); clk_register_clkdev(clk, "ddr_pll", NULL); clk = clk_register_fixed_rate(NULL, "rtc32k", NULL, - CLK_IS_ROOT|CLK_IGNORE_UNUSED, + CLK_IGNORE_UNUSED, 32768); clk_register_clkdev(clk, "clk32k", NULL); clk_register_clkdev(clk, "apb_pclk", "rtc-pl031"); clk = clk_register_fixed_rate(NULL, "ulp38m4", NULL, - CLK_IS_ROOT|CLK_IGNORE_UNUSED, + CLK_IGNORE_UNUSED, 38400000); - clk = clk_reg_prcmu_gate("uartclk", NULL, PRCMU_UARTCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("uartclk", NULL, PRCMU_UARTCLK, 0); clk_register_clkdev(clk, NULL, "UART"); /* msp02clk needs a abx500 clk as parent. Handle by abx500 clk driver */ @@ -85,120 +85,116 @@ void u8540_clk_init(void) PRCMU_MSP02CLK, 0); clk_register_clkdev(clk, NULL, "MSP02"); - clk = clk_reg_prcmu_gate("msp1clk", NULL, PRCMU_MSP1CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("msp1clk", NULL, PRCMU_MSP1CLK, 0); clk_register_clkdev(clk, NULL, "MSP1"); - clk = clk_reg_prcmu_gate("i2cclk", NULL, PRCMU_I2CCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("i2cclk", NULL, PRCMU_I2CCLK, 0); clk_register_clkdev(clk, NULL, "I2C"); - clk = clk_reg_prcmu_gate("slimclk", NULL, PRCMU_SLIMCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("slimclk", NULL, PRCMU_SLIMCLK, 0); clk_register_clkdev(clk, NULL, "slim"); - clk = clk_reg_prcmu_gate("per1clk", NULL, PRCMU_PER1CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("per1clk", NULL, PRCMU_PER1CLK, 0); clk_register_clkdev(clk, NULL, "PERIPH1"); - clk = clk_reg_prcmu_gate("per2clk", NULL, PRCMU_PER2CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("per2clk", NULL, PRCMU_PER2CLK, 0); clk_register_clkdev(clk, NULL, "PERIPH2"); - clk = clk_reg_prcmu_gate("per3clk", NULL, PRCMU_PER3CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("per3clk", NULL, PRCMU_PER3CLK, 0); clk_register_clkdev(clk, NULL, "PERIPH3"); - clk = clk_reg_prcmu_gate("per5clk", NULL, PRCMU_PER5CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("per5clk", NULL, PRCMU_PER5CLK, 0); clk_register_clkdev(clk, NULL, "PERIPH5"); - clk = clk_reg_prcmu_gate("per6clk", NULL, PRCMU_PER6CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("per6clk", NULL, PRCMU_PER6CLK, 0); clk_register_clkdev(clk, NULL, "PERIPH6"); - clk = clk_reg_prcmu_gate("per7clk", NULL, PRCMU_PER7CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("per7clk", NULL, PRCMU_PER7CLK, 0); clk_register_clkdev(clk, NULL, "PERIPH7"); clk = clk_reg_prcmu_scalable("lcdclk", NULL, PRCMU_LCDCLK, 0, - CLK_IS_ROOT|CLK_SET_RATE_GATE); + CLK_SET_RATE_GATE); clk_register_clkdev(clk, NULL, "lcd"); clk_register_clkdev(clk, "lcd", "mcde"); - clk = clk_reg_prcmu_opp_gate("bmlclk", NULL, PRCMU_BMLCLK, - CLK_IS_ROOT); + clk = clk_reg_prcmu_opp_gate("bmlclk", NULL, PRCMU_BMLCLK, 0); clk_register_clkdev(clk, NULL, "bml"); clk = clk_reg_prcmu_scalable("hsitxclk", NULL, PRCMU_HSITXCLK, 0, - CLK_IS_ROOT|CLK_SET_RATE_GATE); + CLK_SET_RATE_GATE); clk = clk_reg_prcmu_scalable("hsirxclk", NULL, PRCMU_HSIRXCLK, 0, - CLK_IS_ROOT|CLK_SET_RATE_GATE); + CLK_SET_RATE_GATE); clk = clk_reg_prcmu_scalable("hdmiclk", NULL, PRCMU_HDMICLK, 0, - CLK_IS_ROOT|CLK_SET_RATE_GATE); + CLK_SET_RATE_GATE); clk_register_clkdev(clk, NULL, "hdmi"); clk_register_clkdev(clk, "hdmi", "mcde"); - clk = clk_reg_prcmu_gate("apeatclk", NULL, PRCMU_APEATCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("apeatclk", NULL, PRCMU_APEATCLK, 0); clk_register_clkdev(clk, NULL, "apeat"); - clk = clk_reg_prcmu_gate("apetraceclk", NULL, PRCMU_APETRACECLK, - CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("apetraceclk", NULL, PRCMU_APETRACECLK, 0); clk_register_clkdev(clk, NULL, "apetrace"); - clk = clk_reg_prcmu_gate("mcdeclk", NULL, PRCMU_MCDECLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("mcdeclk", NULL, PRCMU_MCDECLK, 0); clk_register_clkdev(clk, NULL, "mcde"); clk_register_clkdev(clk, "mcde", "mcde"); clk_register_clkdev(clk, NULL, "dsilink.0"); clk_register_clkdev(clk, NULL, "dsilink.1"); clk_register_clkdev(clk, NULL, "dsilink.2"); - clk = clk_reg_prcmu_opp_gate("ipi2cclk", NULL, PRCMU_IPI2CCLK, - CLK_IS_ROOT); + clk = clk_reg_prcmu_opp_gate("ipi2cclk", NULL, PRCMU_IPI2CCLK, 0); clk_register_clkdev(clk, NULL, "ipi2"); - clk = clk_reg_prcmu_gate("dsialtclk", NULL, PRCMU_DSIALTCLK, - CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("dsialtclk", NULL, PRCMU_DSIALTCLK, 0); clk_register_clkdev(clk, NULL, "dsialt"); - clk = clk_reg_prcmu_gate("dmaclk", NULL, PRCMU_DMACLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("dmaclk", NULL, PRCMU_DMACLK, 0); clk_register_clkdev(clk, NULL, "dma40.0"); - clk = clk_reg_prcmu_gate("b2r2clk", NULL, PRCMU_B2R2CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("b2r2clk", NULL, PRCMU_B2R2CLK, 0); clk_register_clkdev(clk, NULL, "b2r2"); clk_register_clkdev(clk, NULL, "b2r2_core"); clk_register_clkdev(clk, NULL, "U8500-B2R2.0"); clk_register_clkdev(clk, NULL, "b2r2_1_core"); clk = clk_reg_prcmu_scalable("tvclk", NULL, PRCMU_TVCLK, 0, - CLK_IS_ROOT|CLK_SET_RATE_GATE); + CLK_SET_RATE_GATE); clk_register_clkdev(clk, NULL, "tv"); clk_register_clkdev(clk, "tv", "mcde"); - clk = clk_reg_prcmu_gate("sspclk", NULL, PRCMU_SSPCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("sspclk", NULL, PRCMU_SSPCLK, 0); clk_register_clkdev(clk, NULL, "SSP"); - clk = clk_reg_prcmu_gate("rngclk", NULL, PRCMU_RNGCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("rngclk", NULL, PRCMU_RNGCLK, 0); clk_register_clkdev(clk, NULL, "rngclk"); - clk = clk_reg_prcmu_gate("uiccclk", NULL, PRCMU_UICCCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("uiccclk", NULL, PRCMU_UICCCLK, 0); clk_register_clkdev(clk, NULL, "uicc"); - clk = clk_reg_prcmu_gate("timclk", NULL, PRCMU_TIMCLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("timclk", NULL, PRCMU_TIMCLK, 0); clk_register_clkdev(clk, NULL, "mtu0"); clk_register_clkdev(clk, NULL, "mtu1"); clk = clk_reg_prcmu_opp_volt_scalable("sdmmcclk", NULL, PRCMU_SDMMCCLK, 100000000, - CLK_IS_ROOT|CLK_SET_RATE_GATE); + CLK_SET_RATE_GATE); clk_register_clkdev(clk, NULL, "sdmmc"); clk = clk_reg_prcmu_opp_volt_scalable("sdmmchclk", NULL, PRCMU_SDMMCHCLK, 400000000, - CLK_IS_ROOT|CLK_SET_RATE_GATE); + CLK_SET_RATE_GATE); clk_register_clkdev(clk, NULL, "sdmmchclk"); - clk = clk_reg_prcmu_gate("hvaclk", NULL, PRCMU_HVACLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("hvaclk", NULL, PRCMU_HVACLK, 0); clk_register_clkdev(clk, NULL, "hva"); - clk = clk_reg_prcmu_gate("g1clk", NULL, PRCMU_G1CLK, CLK_IS_ROOT); + clk = clk_reg_prcmu_gate("g1clk", NULL, PRCMU_G1CLK, 0); clk_register_clkdev(clk, NULL, "g1"); clk = clk_reg_prcmu_scalable("spare1clk", NULL, PRCMU_SPARE1CLK, 0, - CLK_IS_ROOT|CLK_SET_RATE_GATE); + CLK_SET_RATE_GATE); clk_register_clkdev(clk, "dsilcd", "mcde"); clk = clk_reg_prcmu_scalable("dsi_pll", "hdmiclk", @@ -244,7 +240,7 @@ void u8540_clk_init(void) clk_register_clkdev(clk, "dsilp2", "mcde"); clk = clk_reg_prcmu_scalable_rate("armss", NULL, - PRCMU_ARMSS, 0, CLK_IS_ROOT|CLK_IGNORE_UNUSED); + PRCMU_ARMSS, 0, CLK_IGNORE_UNUSED); clk_register_clkdev(clk, "armss", NULL); clk = clk_register_fixed_factor(NULL, "smp_twd", "armss", diff --git a/drivers/clk/versatile/clk-icst.c b/drivers/clk/versatile/clk-icst.c index 3bca438ecd19dabbc3df761dedb81c96a463b449..5e9b65278e4ccf8bb5ac85198deabb07a0ae040d 100644 --- a/drivers/clk/versatile/clk-icst.c +++ b/drivers/clk/versatile/clk-icst.c @@ -170,7 +170,7 @@ static struct clk *icst_clk_setup(struct device *dev, init.name = name; init.ops = &icst_ops; - init.flags = CLK_IS_ROOT; + init.flags = 0; init.parent_names = (parent_name ? &parent_name : NULL); init.num_parents = (parent_name ? 1 : 0); icst->map = map; diff --git a/drivers/clk/versatile/clk-impd1.c b/drivers/clk/versatile/clk-impd1.c index 65c842a21c6243149d8d3740cacbd270792bfa0d..74c3216dbb0045273cc40793caa88bc78e9d4c8e 100644 --- a/drivers/clk/versatile/clk-impd1.c +++ b/drivers/clk/versatile/clk-impd1.c @@ -98,8 +98,7 @@ void integrator_impd1_clk_init(void __iomem *base, unsigned int id) /* Register the fixed rate PCLK */ imc->pclkname = kasprintf(GFP_KERNEL, "lm%x-pclk", id); - pclk = clk_register_fixed_rate(NULL, imc->pclkname, NULL, - CLK_IS_ROOT, 0); + pclk = clk_register_fixed_rate(NULL, imc->pclkname, NULL, 0, 0); imc->pclk = pclk; imc->vco1name = kasprintf(GFP_KERNEL, "lm%x-vco1", id); diff --git a/drivers/clk/versatile/clk-realview.c b/drivers/clk/versatile/clk-realview.c index bd4dd2463e23c99082345fd58104aae6268ea6e3..c56efc70ac16c40502aeccb0e5bf459d40659682 100644 --- a/drivers/clk/versatile/clk-realview.c +++ b/drivers/clk/versatile/clk-realview.c @@ -56,12 +56,11 @@ void __init realview_clk_init(void __iomem *sysbase, bool is_pb1176) struct clk *clk; /* APB clock dummy */ - clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 0); + clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, 0, 0); clk_register_clkdev(clk, "apb_pclk", NULL); /* 24 MHz clock */ - clk = clk_register_fixed_rate(NULL, "clk24mhz", NULL, CLK_IS_ROOT, - 24000000); + clk = clk_register_fixed_rate(NULL, "clk24mhz", NULL, 0, 24000000); clk_register_clkdev(clk, NULL, "dev:uart0"); clk_register_clkdev(clk, NULL, "dev:uart1"); clk_register_clkdev(clk, NULL, "dev:uart2"); @@ -81,8 +80,7 @@ void __init realview_clk_init(void __iomem *sysbase, bool is_pb1176) /* 1 MHz clock */ - clk = clk_register_fixed_rate(NULL, "clk1mhz", NULL, CLK_IS_ROOT, - 1000000); + clk = clk_register_fixed_rate(NULL, "clk1mhz", NULL, 0, 1000000); clk_register_clkdev(clk, NULL, "sp804"); /* ICST VCO clock */ diff --git a/drivers/clk/versatile/clk-sp810.c b/drivers/clk/versatile/clk-sp810.c index e78755e0ef7809fc4575fe082e1ff02d69c37a46..1fe1e8d970cf3e757592872fb6f1eb53592ba4c9 100644 --- a/drivers/clk/versatile/clk-sp810.c +++ b/drivers/clk/versatile/clk-sp810.c @@ -92,6 +92,7 @@ static void __init clk_sp810_of_setup(struct device_node *node) int num = ARRAY_SIZE(parent_names); char name[12]; struct clk_init_data init; + static int instance; int i; bool deprecated; @@ -117,7 +118,7 @@ static void __init clk_sp810_of_setup(struct device_node *node) deprecated = !of_find_property(node, "assigned-clock-parents", NULL); for (i = 0; i < ARRAY_SIZE(sp810->timerclken); i++) { - snprintf(name, ARRAY_SIZE(name), "timerclken%d", i); + snprintf(name, sizeof(name), "sp810_%d_%d", instance, i); sp810->timerclken[i].sp810 = sp810; sp810->timerclken[i].channel = i; @@ -138,5 +139,6 @@ static void __init clk_sp810_of_setup(struct device_node *node) } of_clk_add_provider(node, clk_sp810_timerclken_of_get, sp810); + instance++; } CLK_OF_DECLARE(sp810, "arm,sp810", clk_sp810_of_setup); diff --git a/drivers/clk/versatile/clk-vexpress-osc.c b/drivers/clk/versatile/clk-vexpress-osc.c index 89c0609e180b1f40ed1cb8e66fb09f629eac3d8e..7e5add7d77528a5fbf7021fd69020a58b79db652 100644 --- a/drivers/clk/versatile/clk-vexpress-osc.c +++ b/drivers/clk/versatile/clk-vexpress-osc.c @@ -94,7 +94,7 @@ static int vexpress_osc_probe(struct platform_device *pdev) init.name = dev_name(&pdev->dev); init.ops = &vexpress_osc_ops; - init.flags = CLK_IS_ROOT; + init.flags = 0; init.num_parents = 0; osc->hw.init = &init; diff --git a/drivers/clk/x86/clk-lpt.c b/drivers/clk/x86/clk-lpt.c index f827083defc4a7e05f6ede023623c67ba0bb4fe8..6b40eb89ae190c7c05b3d12d235346662d162e3a 100644 --- a/drivers/clk/x86/clk-lpt.c +++ b/drivers/clk/x86/clk-lpt.c @@ -10,8 +10,6 @@ * published by the Free Software Foundation. */ -#include -#include #include #include #include @@ -30,7 +28,7 @@ static int lpt_clk_probe(struct platform_device *pdev) /* LPSS free running clock */ drvdata->name = "lpss_clk"; clk = clk_register_fixed_rate(&pdev->dev, drvdata->name, NULL, - CLK_IS_ROOT, 100000000); + 0, 100000000); if (IS_ERR(clk)) return PTR_ERR(clk); diff --git a/drivers/clk/zynq/clkc.c b/drivers/clk/zynq/clkc.c index 38a65c3e62fc247c39ecaff4853cfd45c3148168..88a2cab37f627b86bebe9512ffee9db720b327e1 100644 --- a/drivers/clk/zynq/clkc.c +++ b/drivers/clk/zynq/clkc.c @@ -265,8 +265,7 @@ static void __init zynq_clk_setup(struct device_node *np) pr_warn("ps_clk frequency not specified, using 33 MHz.\n"); tmp = 33333333; } - ps_clk = clk_register_fixed_rate(NULL, "ps_clk", NULL, CLK_IS_ROOT, - tmp); + ps_clk = clk_register_fixed_rate(NULL, "ps_clk", NULL, 0, tmp); /* PLLs */ clk = clk_register_zynq_pll("armpll_int", "ps_clk", SLCR_ARMPLL_CTRL, diff --git a/drivers/clocksource/time-pistachio.c b/drivers/clocksource/time-pistachio.c index 3269d9ef7a18a1d0f1e505ea77878b87c529d5f7..376e59bc5fa06585baa9799558a451e27e3cdd6d 100644 --- a/drivers/clocksource/time-pistachio.c +++ b/drivers/clocksource/time-pistachio.c @@ -163,7 +163,7 @@ static void __init pistachio_clksrc_of_init(struct device_node *node) periph_regs = syscon_regmap_lookup_by_phandle(node, "img,cr-periph"); if (IS_ERR(periph_regs)) { - pr_err("cannot get peripheral regmap (%lu)\n", + pr_err("cannot get peripheral regmap (%ld)\n", PTR_ERR(periph_regs)); return; } @@ -176,7 +176,7 @@ static void __init pistachio_clksrc_of_init(struct device_node *node) sys_clk = of_clk_get_by_name(node, "sys"); if (IS_ERR(sys_clk)) { - pr_err("clock get failed (%lu)\n", PTR_ERR(sys_clk)); + pr_err("clock get failed (%ld)\n", PTR_ERR(sys_clk)); return; } diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index 59a7b380fbe28fcc242e3aa641ff1eac1a09ebcb..fb5712141040abd750829f6a212c98044ddda52f 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c @@ -245,7 +245,7 @@ static unsigned extract_freq(u32 val, struct acpi_cpufreq_data *data) } } -u32 cpu_freq_read_intel(struct acpi_pct_register *not_used) +static u32 cpu_freq_read_intel(struct acpi_pct_register *not_used) { u32 val, dummy; @@ -253,7 +253,7 @@ u32 cpu_freq_read_intel(struct acpi_pct_register *not_used) return val; } -void cpu_freq_write_intel(struct acpi_pct_register *not_used, u32 val) +static void cpu_freq_write_intel(struct acpi_pct_register *not_used, u32 val) { u32 lo, hi; @@ -262,7 +262,7 @@ void cpu_freq_write_intel(struct acpi_pct_register *not_used, u32 val) wrmsr(MSR_IA32_PERF_CTL, lo, hi); } -u32 cpu_freq_read_amd(struct acpi_pct_register *not_used) +static u32 cpu_freq_read_amd(struct acpi_pct_register *not_used) { u32 val, dummy; @@ -270,12 +270,12 @@ u32 cpu_freq_read_amd(struct acpi_pct_register *not_used) return val; } -void cpu_freq_write_amd(struct acpi_pct_register *not_used, u32 val) +static void cpu_freq_write_amd(struct acpi_pct_register *not_used, u32 val) { wrmsr(MSR_AMD_PERF_CTL, val, 0); } -u32 cpu_freq_read_io(struct acpi_pct_register *reg) +static u32 cpu_freq_read_io(struct acpi_pct_register *reg) { u32 val; @@ -283,7 +283,7 @@ u32 cpu_freq_read_io(struct acpi_pct_register *reg) return val; } -void cpu_freq_write_io(struct acpi_pct_register *reg, u32 val) +static void cpu_freq_write_io(struct acpi_pct_register *reg, u32 val) { acpi_os_write_port(reg->address, val, reg->bit_width); } @@ -514,8 +514,10 @@ static int boost_notify(struct notifier_block *nb, unsigned long action, */ switch (action) { - case CPU_UP_PREPARE: - case CPU_UP_PREPARE_FROZEN: + case CPU_DOWN_FAILED: + case CPU_DOWN_FAILED_FROZEN: + case CPU_ONLINE: + case CPU_ONLINE_FROZEN: boost_set_msrs(acpi_cpufreq_driver.boost_enabled, cpumask); break; diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c index f951f911786e086b2b6dc9d615018eb235347dbe..5f8dbe640a202baa2b12d26267ca78b983c8b7fc 100644 --- a/drivers/cpufreq/cpufreq-dt.c +++ b/drivers/cpufreq/cpufreq-dt.c @@ -4,9 +4,6 @@ * Copyright (C) 2014 Linaro. * Viresh Kumar * - * The OPP code in function set_target() is reused from - * drivers/cpufreq/omap-cpufreq.c - * * 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. diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 4c7825856eabebde799913257e936f12b29ec387..b87596b591b3ca9fdf332884700e5a3cc96ebf10 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -76,6 +76,7 @@ static inline bool has_target(void) /* internal prototypes */ static int cpufreq_governor(struct cpufreq_policy *policy, unsigned int event); static unsigned int __cpufreq_get(struct cpufreq_policy *policy); +static int cpufreq_start_governor(struct cpufreq_policy *policy); /** * Two notifier lists: the "policy" list is involved in the @@ -964,10 +965,7 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, unsigned int cp cpumask_set_cpu(cpu, policy->cpus); if (has_target()) { - ret = cpufreq_governor(policy, CPUFREQ_GOV_START); - if (!ret) - ret = cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); - + ret = cpufreq_start_governor(policy); if (ret) pr_err("%s: Failed to start governor\n", __func__); } @@ -1308,10 +1306,7 @@ static void cpufreq_offline(unsigned int cpu) /* Start governor again for active policy */ if (!policy_is_inactive(policy)) { if (has_target()) { - ret = cpufreq_governor(policy, CPUFREQ_GOV_START); - if (!ret) - ret = cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); - + ret = cpufreq_start_governor(policy); if (ret) pr_err("%s: Failed to start governor\n", __func__); } @@ -1401,9 +1396,17 @@ unsigned int cpufreq_quick_get(unsigned int cpu) { struct cpufreq_policy *policy; unsigned int ret_freq = 0; + unsigned long flags; - if (cpufreq_driver && cpufreq_driver->setpolicy && cpufreq_driver->get) - return cpufreq_driver->get(cpu); + read_lock_irqsave(&cpufreq_driver_lock, flags); + + if (cpufreq_driver && cpufreq_driver->setpolicy && cpufreq_driver->get) { + ret_freq = cpufreq_driver->get(cpu); + read_unlock_irqrestore(&cpufreq_driver_lock, flags); + return ret_freq; + } + + read_unlock_irqrestore(&cpufreq_driver_lock, flags); policy = cpufreq_cpu_get(cpu); if (policy) { @@ -1484,6 +1487,24 @@ unsigned int cpufreq_get(unsigned int cpu) } EXPORT_SYMBOL(cpufreq_get); +static unsigned int cpufreq_update_current_freq(struct cpufreq_policy *policy) +{ + unsigned int new_freq; + + new_freq = cpufreq_driver->get(policy->cpu); + if (!new_freq) + return 0; + + if (!policy->cur) { + pr_debug("cpufreq: Driver did not initialize current freq\n"); + policy->cur = new_freq; + } else if (policy->cur != new_freq && has_target()) { + cpufreq_out_of_sync(policy, new_freq); + } + + return new_freq; +} + static struct subsys_interface cpufreq_interface = { .name = "cpufreq", .subsys = &cpu_subsys, @@ -1583,9 +1604,7 @@ void cpufreq_resume(void) policy); } else { down_write(&policy->rwsem); - ret = cpufreq_governor(policy, CPUFREQ_GOV_START); - if (!ret) - cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); + ret = cpufreq_start_governor(policy); up_write(&policy->rwsem); if (ret) @@ -1593,17 +1612,6 @@ void cpufreq_resume(void) __func__, policy); } } - - /* - * schedule call cpufreq_update_policy() for first-online CPU, as that - * wouldn't be hotplugged-out on suspend. It will verify that the - * current freq is in sync with what we believe it to be. - */ - policy = cpufreq_cpu_get_raw(cpumask_first(cpu_online_mask)); - if (WARN_ON(!policy)) - return; - - schedule_work(&policy->update); } /** @@ -1927,6 +1935,17 @@ static int cpufreq_governor(struct cpufreq_policy *policy, unsigned int event) return ret; } +static int cpufreq_start_governor(struct cpufreq_policy *policy) +{ + int ret; + + if (cpufreq_driver->get && !cpufreq_driver->setpolicy) + cpufreq_update_current_freq(policy); + + ret = cpufreq_governor(policy, CPUFREQ_GOV_START); + return ret ? ret : cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); +} + int cpufreq_register_governor(struct cpufreq_governor *governor) { int err; @@ -2063,8 +2082,10 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, return cpufreq_driver->setpolicy(new_policy); } - if (new_policy->governor == policy->governor) - goto out; + if (new_policy->governor == policy->governor) { + pr_debug("cpufreq: governor limits update\n"); + return cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); + } pr_debug("governor switch\n"); @@ -2092,10 +2113,11 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, policy->governor = new_policy->governor; ret = cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT); if (!ret) { - ret = cpufreq_governor(policy, CPUFREQ_GOV_START); - if (!ret) - goto out; - + ret = cpufreq_start_governor(policy); + if (!ret) { + pr_debug("cpufreq: governor change\n"); + return 0; + } cpufreq_governor(policy, CPUFREQ_GOV_POLICY_EXIT); } @@ -2106,14 +2128,10 @@ static int cpufreq_set_policy(struct cpufreq_policy *policy, if (cpufreq_governor(policy, CPUFREQ_GOV_POLICY_INIT)) policy->governor = NULL; else - cpufreq_governor(policy, CPUFREQ_GOV_START); + cpufreq_start_governor(policy); } return ret; - - out: - pr_debug("governor: change or update limits\n"); - return cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); } /** @@ -2144,19 +2162,11 @@ int cpufreq_update_policy(unsigned int cpu) * -> ask driver for current freq and notify governors about a change */ if (cpufreq_driver->get && !cpufreq_driver->setpolicy) { - new_policy.cur = cpufreq_driver->get(cpu); + new_policy.cur = cpufreq_update_current_freq(policy); if (WARN_ON(!new_policy.cur)) { ret = -EIO; goto unlock; } - - if (!policy->cur) { - pr_debug("Driver did not initialize current freq\n"); - policy->cur = new_policy.cur; - } else { - if (policy->cur != new_policy.cur && has_target()) - cpufreq_out_of_sync(policy, new_policy.cur); - } } ret = cpufreq_set_policy(policy, &new_policy); diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c index 1c25ef4056164b2cb7ddc587441637a1973612c1..10a5cfeae8c5e34317805402c63d0c11e3aaac5e 100644 --- a/drivers/cpufreq/cpufreq_governor.c +++ b/drivers/cpufreq/cpufreq_governor.c @@ -329,7 +329,7 @@ static void dbs_irq_work(struct irq_work *irq_work) struct policy_dbs_info *policy_dbs; policy_dbs = container_of(irq_work, struct policy_dbs_info, irq_work); - schedule_work(&policy_dbs->work); + schedule_work_on(smp_processor_id(), &policy_dbs->work); } static void dbs_update_util_handler(struct update_util_data *data, u64 time, diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index cb5607495816d73bfa33e3579962aa5a68ff3af4..8b5a415ee14a53d21e9358e2b6707df852e827b8 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -64,6 +64,25 @@ static inline int ceiling_fp(int32_t x) return ret; } +/** + * struct sample - Store performance sample + * @core_pct_busy: Ratio of APERF/MPERF in percent, which is actual + * performance during last sample period + * @busy_scaled: Scaled busy value which is used to calculate next + * P state. This can be different than core_pct_busy + * to account for cpu idle period + * @aperf: Difference of actual performance frequency clock count + * read from APERF MSR between last and current sample + * @mperf: Difference of maximum performance frequency clock count + * read from MPERF MSR between last and current sample + * @tsc: Difference of time stamp counter between last and + * current sample + * @freq: Effective frequency calculated from APERF/MPERF + * @time: Current time from scheduler + * + * This structure is used in the cpudata structure to store performance sample + * data for choosing next P State. + */ struct sample { int32_t core_pct_busy; int32_t busy_scaled; @@ -74,6 +93,20 @@ struct sample { u64 time; }; +/** + * struct pstate_data - Store P state data + * @current_pstate: Current requested P state + * @min_pstate: Min P state possible for this platform + * @max_pstate: Max P state possible for this platform + * @max_pstate_physical:This is physical Max P state for a processor + * This can be higher than the max_pstate which can + * be limited by platform thermal design power limits + * @scaling: Scaling factor to convert frequency to cpufreq + * frequency units + * @turbo_pstate: Max Turbo P state possible for this platform + * + * Stores the per cpu model P state limits and current P state. + */ struct pstate_data { int current_pstate; int min_pstate; @@ -83,6 +116,19 @@ struct pstate_data { int turbo_pstate; }; +/** + * struct vid_data - Stores voltage information data + * @min: VID data for this platform corresponding to + * the lowest P state + * @max: VID data corresponding to the highest P State. + * @turbo: VID data for turbo P state + * @ratio: Ratio of (vid max - vid min) / + * (max P state - Min P State) + * + * Stores the voltage data for DVFS (Dynamic Voltage and Frequency Scaling) + * This data is used in Atom platforms, where in addition to target P state, + * the voltage data needs to be specified to select next P State. + */ struct vid_data { int min; int max; @@ -90,6 +136,18 @@ struct vid_data { int32_t ratio; }; +/** + * struct _pid - Stores PID data + * @setpoint: Target set point for busyness or performance + * @integral: Storage for accumulated error values + * @p_gain: PID proportional gain + * @i_gain: PID integral gain + * @d_gain: PID derivative gain + * @deadband: PID deadband + * @last_err: Last error storage for integral part of PID calculation + * + * Stores PID coefficients and last error for PID controller. + */ struct _pid { int setpoint; int32_t integral; @@ -100,6 +158,23 @@ struct _pid { int32_t last_err; }; +/** + * struct cpudata - Per CPU instance data storage + * @cpu: CPU number for this instance data + * @update_util: CPUFreq utility callback information + * @pstate: Stores P state limits for this CPU + * @vid: Stores VID limits for this CPU + * @pid: Stores PID parameters for this CPU + * @last_sample_time: Last Sample time + * @prev_aperf: Last APERF value read from APERF MSR + * @prev_mperf: Last MPERF value read from MPERF MSR + * @prev_tsc: Last timestamp counter (TSC) value + * @prev_cummulative_iowait: IO Wait time difference from last and + * current sample + * @sample: Storage for storing last Sample data + * + * This structure stores per CPU instance data for all CPUs. + */ struct cpudata { int cpu; @@ -118,6 +193,19 @@ struct cpudata { }; static struct cpudata **all_cpu_data; + +/** + * struct pid_adjust_policy - Stores static PID configuration data + * @sample_rate_ms: PID calculation sample rate in ms + * @sample_rate_ns: Sample rate calculation in ns + * @deadband: PID deadband + * @setpoint: PID Setpoint + * @p_gain_pct: PID proportional gain + * @i_gain_pct: PID integral gain + * @d_gain_pct: PID derivative gain + * + * Stores per CPU model static PID configuration data. + */ struct pstate_adjust_policy { int sample_rate_ms; s64 sample_rate_ns; @@ -128,17 +216,36 @@ struct pstate_adjust_policy { int i_gain_pct; }; +/** + * struct pstate_funcs - Per CPU model specific callbacks + * @get_max: Callback to get maximum non turbo effective P state + * @get_max_physical: Callback to get maximum non turbo physical P state + * @get_min: Callback to get minimum P state + * @get_turbo: Callback to get turbo P state + * @get_scaling: Callback to get frequency scaling factor + * @get_val: Callback to convert P state to actual MSR write value + * @get_vid: Callback to get VID data for Atom platforms + * @get_target_pstate: Callback to a function to calculate next P state to use + * + * Core and Atom CPU models have different way to get P State limits. This + * structure is used to store those callbacks. + */ struct pstate_funcs { int (*get_max)(void); int (*get_max_physical)(void); int (*get_min)(void); int (*get_turbo)(void); int (*get_scaling)(void); - void (*set)(struct cpudata*, int pstate); + u64 (*get_val)(struct cpudata*, int pstate); void (*get_vid)(struct cpudata *); int32_t (*get_target_pstate)(struct cpudata *); }; +/** + * struct cpu_defaults- Per CPU model default config data + * @pid_policy: PID config data + * @funcs: Callback function data + */ struct cpu_defaults { struct pstate_adjust_policy pid_policy; struct pstate_funcs funcs; @@ -151,6 +258,34 @@ static struct pstate_adjust_policy pid_params; static struct pstate_funcs pstate_funcs; static int hwp_active; + +/** + * struct perf_limits - Store user and policy limits + * @no_turbo: User requested turbo state from intel_pstate sysfs + * @turbo_disabled: Platform turbo status either from msr + * MSR_IA32_MISC_ENABLE or when maximum available pstate + * matches the maximum turbo pstate + * @max_perf_pct: Effective maximum performance limit in percentage, this + * is minimum of either limits enforced by cpufreq policy + * or limits from user set limits via intel_pstate sysfs + * @min_perf_pct: Effective minimum performance limit in percentage, this + * is maximum of either limits enforced by cpufreq policy + * or limits from user set limits via intel_pstate sysfs + * @max_perf: This is a scaled value between 0 to 255 for max_perf_pct + * This value is used to limit max pstate + * @min_perf: This is a scaled value between 0 to 255 for min_perf_pct + * This value is used to limit min pstate + * @max_policy_pct: The maximum performance in percentage enforced by + * cpufreq setpolicy interface + * @max_sysfs_pct: The maximum performance in percentage enforced by + * intel pstate sysfs interface + * @min_policy_pct: The minimum performance in percentage enforced by + * cpufreq setpolicy interface + * @min_sysfs_pct: The minimum performance in percentage enforced by + * intel pstate sysfs interface + * + * Storage for user and policy defined limits. + */ struct perf_limits { int no_turbo; int turbo_disabled; @@ -565,7 +700,7 @@ static int atom_get_turbo_pstate(void) return value & 0x7F; } -static void atom_set_pstate(struct cpudata *cpudata, int pstate) +static u64 atom_get_val(struct cpudata *cpudata, int pstate) { u64 val; int32_t vid_fp; @@ -585,9 +720,7 @@ static void atom_set_pstate(struct cpudata *cpudata, int pstate) if (pstate > cpudata->pstate.max_pstate) vid = cpudata->vid.turbo; - val |= vid; - - wrmsrl_on_cpu(cpudata->cpu, MSR_IA32_PERF_CTL, val); + return val | vid; } static int silvermont_get_scaling(void) @@ -711,7 +844,7 @@ static inline int core_get_scaling(void) return 100000; } -static void core_set_pstate(struct cpudata *cpudata, int pstate) +static u64 core_get_val(struct cpudata *cpudata, int pstate) { u64 val; @@ -719,7 +852,7 @@ static void core_set_pstate(struct cpudata *cpudata, int pstate) if (limits->no_turbo && !limits->turbo_disabled) val |= (u64)1 << 32; - wrmsrl(MSR_IA32_PERF_CTL, val); + return val; } static int knl_get_turbo_pstate(void) @@ -750,7 +883,7 @@ static struct cpu_defaults core_params = { .get_min = core_get_min_pstate, .get_turbo = core_get_turbo_pstate, .get_scaling = core_get_scaling, - .set = core_set_pstate, + .get_val = core_get_val, .get_target_pstate = get_target_pstate_use_performance, }, }; @@ -769,7 +902,7 @@ static struct cpu_defaults silvermont_params = { .get_max_physical = atom_get_max_pstate, .get_min = atom_get_min_pstate, .get_turbo = atom_get_turbo_pstate, - .set = atom_set_pstate, + .get_val = atom_get_val, .get_scaling = silvermont_get_scaling, .get_vid = atom_get_vid, .get_target_pstate = get_target_pstate_use_cpu_load, @@ -790,7 +923,7 @@ static struct cpu_defaults airmont_params = { .get_max_physical = atom_get_max_pstate, .get_min = atom_get_min_pstate, .get_turbo = atom_get_turbo_pstate, - .set = atom_set_pstate, + .get_val = atom_get_val, .get_scaling = airmont_get_scaling, .get_vid = atom_get_vid, .get_target_pstate = get_target_pstate_use_cpu_load, @@ -812,7 +945,7 @@ static struct cpu_defaults knl_params = { .get_min = core_get_min_pstate, .get_turbo = knl_get_turbo_pstate, .get_scaling = core_get_scaling, - .set = core_set_pstate, + .get_val = core_get_val, .get_target_pstate = get_target_pstate_use_performance, }, }; @@ -839,25 +972,24 @@ static void intel_pstate_get_min_max(struct cpudata *cpu, int *min, int *max) *min = clamp_t(int, min_perf, cpu->pstate.min_pstate, max_perf); } -static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate, bool force) +static inline void intel_pstate_record_pstate(struct cpudata *cpu, int pstate) { - int max_perf, min_perf; - - if (force) { - update_turbo_state(); - - intel_pstate_get_min_max(cpu, &min_perf, &max_perf); - - pstate = clamp_t(int, pstate, min_perf, max_perf); - - if (pstate == cpu->pstate.current_pstate) - return; - } trace_cpu_frequency(pstate * cpu->pstate.scaling, cpu->cpu); - cpu->pstate.current_pstate = pstate; +} - pstate_funcs.set(cpu, pstate); +static void intel_pstate_set_min_pstate(struct cpudata *cpu) +{ + int pstate = cpu->pstate.min_pstate; + + intel_pstate_record_pstate(cpu, pstate); + /* + * Generally, there is no guarantee that this code will always run on + * the CPU being updated, so force the register update to run on the + * right CPU. + */ + wrmsrl_on_cpu(cpu->cpu, MSR_IA32_PERF_CTL, + pstate_funcs.get_val(cpu, pstate)); } static void intel_pstate_get_cpu_pstates(struct cpudata *cpu) @@ -870,7 +1002,8 @@ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu) if (pstate_funcs.get_vid) pstate_funcs.get_vid(cpu); - intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate, false); + + intel_pstate_set_min_pstate(cpu); } static inline void intel_pstate_calc_busy(struct cpudata *cpu) @@ -912,7 +1045,14 @@ static inline bool intel_pstate_sample(struct cpudata *cpu, u64 time) cpu->prev_aperf = aperf; cpu->prev_mperf = mperf; cpu->prev_tsc = tsc; - return true; + /* + * First time this function is invoked in a given cycle, all of the + * previous sample data fields are equal to zero or stale and they must + * be populated with meaningful numbers for things to work, so assume + * that sample.time will always be reset before setting the utilization + * update hook and make the caller skip the sample then. + */ + return !!cpu->last_sample_time; } static inline int32_t get_avg_frequency(struct cpudata *cpu) @@ -986,8 +1126,7 @@ static inline int32_t get_target_pstate_use_performance(struct cpudata *cpu) * enough period of time to adjust our busyness. */ duration_ns = cpu->sample.time - cpu->last_sample_time; - if ((s64)duration_ns > pid_params.sample_rate_ns * 3 - && cpu->last_sample_time > 0) { + if ((s64)duration_ns > pid_params.sample_rate_ns * 3) { sample_ratio = div_fp(int_tofp(pid_params.sample_rate_ns), int_tofp(duration_ns)); core_busy = mul_fp(core_busy, sample_ratio); @@ -997,6 +1136,21 @@ static inline int32_t get_target_pstate_use_performance(struct cpudata *cpu) return cpu->pstate.current_pstate - pid_calc(&cpu->pid, core_busy); } +static inline void intel_pstate_update_pstate(struct cpudata *cpu, int pstate) +{ + int max_perf, min_perf; + + update_turbo_state(); + + intel_pstate_get_min_max(cpu, &min_perf, &max_perf); + pstate = clamp_t(int, pstate, min_perf, max_perf); + if (pstate == cpu->pstate.current_pstate) + return; + + intel_pstate_record_pstate(cpu, pstate); + wrmsrl(MSR_IA32_PERF_CTL, pstate_funcs.get_val(cpu, pstate)); +} + static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu) { int from, target_pstate; @@ -1006,7 +1160,7 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu) target_pstate = pstate_funcs.get_target_pstate(cpu); - intel_pstate_set_pstate(cpu, target_pstate, true); + intel_pstate_update_pstate(cpu, target_pstate); sample = &cpu->sample; trace_pstate_sample(fp_toint(sample->core_pct_busy), @@ -1087,10 +1241,8 @@ static int intel_pstate_init_cpu(unsigned int cpunum) intel_pstate_get_cpu_pstates(cpu); intel_pstate_busy_pid_reset(cpu); - intel_pstate_sample(cpu, 0); cpu->update_util.func = intel_pstate_update_util; - cpufreq_set_update_util_data(cpunum, &cpu->update_util); pr_debug("intel_pstate: controlling: cpu %d\n", cpunum); @@ -1109,22 +1261,54 @@ static unsigned int intel_pstate_get(unsigned int cpu_num) return get_avg_frequency(cpu); } +static void intel_pstate_set_update_util_hook(unsigned int cpu_num) +{ + struct cpudata *cpu = all_cpu_data[cpu_num]; + + /* Prevent intel_pstate_update_util() from using stale data. */ + cpu->sample.time = 0; + cpufreq_set_update_util_data(cpu_num, &cpu->update_util); +} + +static void intel_pstate_clear_update_util_hook(unsigned int cpu) +{ + cpufreq_set_update_util_data(cpu, NULL); + synchronize_sched(); +} + +static void intel_pstate_set_performance_limits(struct perf_limits *limits) +{ + limits->no_turbo = 0; + limits->turbo_disabled = 0; + limits->max_perf_pct = 100; + limits->max_perf = int_tofp(1); + limits->min_perf_pct = 100; + limits->min_perf = int_tofp(1); + limits->max_policy_pct = 100; + limits->max_sysfs_pct = 100; + limits->min_policy_pct = 0; + limits->min_sysfs_pct = 0; +} + static int intel_pstate_set_policy(struct cpufreq_policy *policy) { if (!policy->cpuinfo.max_freq) return -ENODEV; - if (policy->policy == CPUFREQ_POLICY_PERFORMANCE && - policy->max >= policy->cpuinfo.max_freq) { - pr_debug("intel_pstate: set performance\n"); + intel_pstate_clear_update_util_hook(policy->cpu); + + if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) { limits = &performance_limits; - if (hwp_active) - intel_pstate_hwp_set(policy->cpus); - return 0; + if (policy->max >= policy->cpuinfo.max_freq) { + pr_debug("intel_pstate: set performance\n"); + intel_pstate_set_performance_limits(limits); + goto out; + } + } else { + pr_debug("intel_pstate: set powersave\n"); + limits = &powersave_limits; } - pr_debug("intel_pstate: set powersave\n"); - limits = &powersave_limits; limits->min_policy_pct = (policy->min * 100) / policy->cpuinfo.max_freq; limits->min_policy_pct = clamp_t(int, limits->min_policy_pct, 0 , 100); limits->max_policy_pct = DIV_ROUND_UP(policy->max * 100, @@ -1150,6 +1334,9 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy) limits->max_perf = div_fp(int_tofp(limits->max_perf_pct), int_tofp(100)); + out: + intel_pstate_set_update_util_hook(policy->cpu); + if (hwp_active) intel_pstate_hwp_set(policy->cpus); @@ -1174,13 +1361,12 @@ static void intel_pstate_stop_cpu(struct cpufreq_policy *policy) pr_debug("intel_pstate: CPU %d exiting\n", cpu_num); - cpufreq_set_update_util_data(cpu_num, NULL); - synchronize_sched(); + intel_pstate_clear_update_util_hook(cpu_num); if (hwp_active) return; - intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate, false); + intel_pstate_set_min_pstate(cpu); } static int intel_pstate_cpu_init(struct cpufreq_policy *policy) @@ -1255,7 +1441,7 @@ static void copy_cpu_funcs(struct pstate_funcs *funcs) pstate_funcs.get_min = funcs->get_min; pstate_funcs.get_turbo = funcs->get_turbo; pstate_funcs.get_scaling = funcs->get_scaling; - pstate_funcs.set = funcs->set; + pstate_funcs.get_val = funcs->get_val; pstate_funcs.get_vid = funcs->get_vid; pstate_funcs.get_target_pstate = funcs->get_target_pstate; @@ -1442,8 +1628,7 @@ static int __init intel_pstate_init(void) get_online_cpus(); for_each_online_cpu(cpu) { if (all_cpu_data[cpu]) { - cpufreq_set_update_util_data(cpu, NULL); - synchronize_sched(); + intel_pstate_clear_update_util_hook(cpu); kfree(all_cpu_data[cpu]); } } diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c index 50bf12033bbc080c70b5de72de3f89c2dc8bd3a6..39ac78c94be0f3c191aaf5868cd3c2154ab5fb59 100644 --- a/drivers/cpufreq/powernv-cpufreq.c +++ b/drivers/cpufreq/powernv-cpufreq.c @@ -44,7 +44,6 @@ static struct cpufreq_frequency_table powernv_freqs[POWERNV_MAX_PSTATES+1]; static bool rebooting, throttled, occ_reset; -static unsigned int *core_to_chip_map; static const char * const throttle_reason[] = { "No throttling", @@ -55,6 +54,16 @@ static const char * const throttle_reason[] = { "OCC Reset" }; +enum throttle_reason_type { + NO_THROTTLE = 0, + POWERCAP, + CPU_OVERTEMP, + POWER_SUPPLY_FAILURE, + OVERCURRENT, + OCC_RESET_THROTTLE, + OCC_MAX_REASON +}; + static struct chip { unsigned int id; bool throttled; @@ -62,9 +71,13 @@ static struct chip { u8 throttle_reason; cpumask_t mask; struct work_struct throttle; + int throttle_turbo; + int throttle_sub_turbo; + int reason[OCC_MAX_REASON]; } *chips; static int nr_chips; +static DEFINE_PER_CPU(struct chip *, chip_info); /* * Note: The set of pstates consists of contiguous integers, the @@ -196,6 +209,42 @@ static struct freq_attr *powernv_cpu_freq_attr[] = { NULL, }; +#define throttle_attr(name, member) \ +static ssize_t name##_show(struct cpufreq_policy *policy, char *buf) \ +{ \ + struct chip *chip = per_cpu(chip_info, policy->cpu); \ + \ + return sprintf(buf, "%u\n", chip->member); \ +} \ + \ +static struct freq_attr throttle_attr_##name = __ATTR_RO(name) \ + +throttle_attr(unthrottle, reason[NO_THROTTLE]); +throttle_attr(powercap, reason[POWERCAP]); +throttle_attr(overtemp, reason[CPU_OVERTEMP]); +throttle_attr(supply_fault, reason[POWER_SUPPLY_FAILURE]); +throttle_attr(overcurrent, reason[OVERCURRENT]); +throttle_attr(occ_reset, reason[OCC_RESET_THROTTLE]); +throttle_attr(turbo_stat, throttle_turbo); +throttle_attr(sub_turbo_stat, throttle_sub_turbo); + +static struct attribute *throttle_attrs[] = { + &throttle_attr_unthrottle.attr, + &throttle_attr_powercap.attr, + &throttle_attr_overtemp.attr, + &throttle_attr_supply_fault.attr, + &throttle_attr_overcurrent.attr, + &throttle_attr_occ_reset.attr, + &throttle_attr_turbo_stat.attr, + &throttle_attr_sub_turbo_stat.attr, + NULL, +}; + +static const struct attribute_group throttle_attr_grp = { + .name = "throttle_stats", + .attrs = throttle_attrs, +}; + /* Helper routines */ /* Access helpers to power mgt SPR */ @@ -324,34 +373,35 @@ static inline unsigned int get_nominal_index(void) static void powernv_cpufreq_throttle_check(void *data) { + struct chip *chip; unsigned int cpu = smp_processor_id(); - unsigned int chip_id = core_to_chip_map[cpu_core_index_of_thread(cpu)]; unsigned long pmsr; - int pmsr_pmax, i; + int pmsr_pmax; pmsr = get_pmspr(SPRN_PMSR); - - for (i = 0; i < nr_chips; i++) - if (chips[i].id == chip_id) - break; + chip = this_cpu_read(chip_info); /* Check for Pmax Capping */ pmsr_pmax = (s8)PMSR_MAX(pmsr); if (pmsr_pmax != powernv_pstate_info.max) { - if (chips[i].throttled) + if (chip->throttled) goto next; - chips[i].throttled = true; - if (pmsr_pmax < powernv_pstate_info.nominal) + chip->throttled = true; + if (pmsr_pmax < powernv_pstate_info.nominal) { pr_warn_once("CPU %d on Chip %u has Pmax reduced below nominal frequency (%d < %d)\n", - cpu, chips[i].id, pmsr_pmax, + cpu, chip->id, pmsr_pmax, powernv_pstate_info.nominal); - trace_powernv_throttle(chips[i].id, - throttle_reason[chips[i].throttle_reason], + chip->throttle_sub_turbo++; + } else { + chip->throttle_turbo++; + } + trace_powernv_throttle(chip->id, + throttle_reason[chip->throttle_reason], pmsr_pmax); - } else if (chips[i].throttled) { - chips[i].throttled = false; - trace_powernv_throttle(chips[i].id, - throttle_reason[chips[i].throttle_reason], + } else if (chip->throttled) { + chip->throttled = false; + trace_powernv_throttle(chip->id, + throttle_reason[chip->throttle_reason], pmsr_pmax); } @@ -411,6 +461,21 @@ static int powernv_cpufreq_cpu_init(struct cpufreq_policy *policy) for (i = 0; i < threads_per_core; i++) cpumask_set_cpu(base + i, policy->cpus); + if (!policy->driver_data) { + int ret; + + ret = sysfs_create_group(&policy->kobj, &throttle_attr_grp); + if (ret) { + pr_info("Failed to create throttle stats directory for cpu %d\n", + policy->cpu); + return ret; + } + /* + * policy->driver_data is used as a flag for one-time + * creation of throttle sysfs files. + */ + policy->driver_data = policy; + } return cpufreq_table_validate_and_show(policy, powernv_freqs); } @@ -517,8 +582,10 @@ static int powernv_cpufreq_occ_msg(struct notifier_block *nb, break; if (omsg.throttle_status >= 0 && - omsg.throttle_status <= OCC_MAX_THROTTLE_STATUS) + omsg.throttle_status <= OCC_MAX_THROTTLE_STATUS) { chips[i].throttle_reason = omsg.throttle_status; + chips[i].reason[omsg.throttle_status]++; + } if (!omsg.throttle_status) chips[i].restore = true; @@ -558,47 +625,34 @@ static int init_chip_info(void) unsigned int chip[256]; unsigned int cpu, i; unsigned int prev_chip_id = UINT_MAX; - cpumask_t cpu_mask; - int ret = -ENOMEM; - - core_to_chip_map = kcalloc(cpu_nr_cores(), sizeof(unsigned int), - GFP_KERNEL); - if (!core_to_chip_map) - goto out; - cpumask_copy(&cpu_mask, cpu_possible_mask); - for_each_cpu(cpu, &cpu_mask) { + for_each_possible_cpu(cpu) { unsigned int id = cpu_to_chip_id(cpu); if (prev_chip_id != id) { prev_chip_id = id; chip[nr_chips++] = id; } - core_to_chip_map[cpu_core_index_of_thread(cpu)] = id; - cpumask_andnot(&cpu_mask, &cpu_mask, cpu_sibling_mask(cpu)); } chips = kcalloc(nr_chips, sizeof(struct chip), GFP_KERNEL); if (!chips) - goto free_chip_map; + return -ENOMEM; for (i = 0; i < nr_chips; i++) { chips[i].id = chip[i]; cpumask_copy(&chips[i].mask, cpumask_of_node(chip[i])); INIT_WORK(&chips[i].throttle, powernv_cpufreq_work_fn); + for_each_cpu(cpu, &chips[i].mask) + per_cpu(chip_info, cpu) = &chips[i]; } return 0; -free_chip_map: - kfree(core_to_chip_map); -out: - return ret; } static inline void clean_chip_info(void) { kfree(chips); - kfree(core_to_chip_map); } static inline void unregister_all_notifiers(void) diff --git a/drivers/cpufreq/pxa2xx-cpufreq.c b/drivers/cpufreq/pxa2xx-cpufreq.c index 096377232747652f99d8a89e0681da7134b716fe..46fee1539cc87d3eeada498408090a2ebad77875 100644 --- a/drivers/cpufreq/pxa2xx-cpufreq.c +++ b/drivers/cpufreq/pxa2xx-cpufreq.c @@ -319,7 +319,7 @@ static int pxa_set_target(struct cpufreq_policy *policy, unsigned int idx) local_irq_save(flags); /* Set new the CCCR and prepare CCLKCFG */ - CCCR = pxa_freq_settings[idx].cccr; + writel(pxa_freq_settings[idx].cccr, CCCR); cclkcfg = pxa_freq_settings[idx].cclkcfg; asm volatile(" \n\ diff --git a/drivers/cpufreq/s5pv210-cpufreq.c b/drivers/cpufreq/s5pv210-cpufreq.c index 051a8a8224cd7ade8b846e62fc27d0733ba8f73b..a145b319d1717a996fb193dc3f382a22030d5327 100644 --- a/drivers/cpufreq/s5pv210-cpufreq.c +++ b/drivers/cpufreq/s5pv210-cpufreq.c @@ -576,10 +576,8 @@ static struct cpufreq_driver s5pv210_driver = { .get = cpufreq_generic_get, .init = s5pv210_cpu_init, .name = "s5pv210", -#ifdef CONFIG_PM .suspend = cpufreq_generic_suspend, .resume = cpufreq_generic_suspend, /* We need to set SLEEP FREQ again */ -#endif }; static struct notifier_block s5pv210_cpufreq_reboot_notifier = { diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index 27fc733cb5b97382b458744432e9c9c348170e84..03d38c291de62d7f6503f13855142fb5948b64a0 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c @@ -196,7 +196,7 @@ static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev); * of points is below a threshold. If it is... then use the * average of these 8 points as the estimated value. */ -static void get_typical_interval(struct menu_device *data) +static unsigned int get_typical_interval(struct menu_device *data) { int i, divisor; unsigned int max, thresh, avg; @@ -253,9 +253,7 @@ static void get_typical_interval(struct menu_device *data) if (likely(variance <= U64_MAX/36)) { if ((((u64)avg*avg > variance*36) && (divisor * 4 >= INTERVALS * 3)) || variance <= 400) { - if (data->next_timer_us > avg) - data->predicted_us = avg; - return; + return avg; } } @@ -269,7 +267,7 @@ static void get_typical_interval(struct menu_device *data) * with sporadic activity with a bunch of short pauses. */ if ((divisor * 4) <= INTERVALS * 3) - return; + return UINT_MAX; thresh = max - 1; goto again; @@ -286,6 +284,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) int latency_req = pm_qos_request(PM_QOS_CPU_DMA_LATENCY); int i; unsigned int interactivity_req; + unsigned int expected_interval; unsigned long nr_iowaiters, cpu_load; if (data->needs_update) { @@ -312,31 +311,42 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev) data->correction_factor[data->bucket], RESOLUTION * DECAY); - get_typical_interval(data); - - /* - * Performance multiplier defines a minimum predicted idle - * duration / latency ratio. Adjust the latency limit if - * necessary. - */ - interactivity_req = data->predicted_us / performance_multiplier(nr_iowaiters, cpu_load); - if (latency_req > interactivity_req) - latency_req = interactivity_req; + expected_interval = get_typical_interval(data); + expected_interval = min(expected_interval, data->next_timer_us); if (CPUIDLE_DRIVER_STATE_START > 0) { - data->last_state_idx = CPUIDLE_DRIVER_STATE_START - 1; + struct cpuidle_state *s = &drv->states[CPUIDLE_DRIVER_STATE_START]; + unsigned int polling_threshold; + /* * We want to default to C1 (hlt), not to busy polling - * unless the timer is happening really really soon. + * unless the timer is happening really really soon, or + * C1's exit latency exceeds the user configured limit. */ - if (interactivity_req > 20 && - !drv->states[CPUIDLE_DRIVER_STATE_START].disabled && - dev->states_usage[CPUIDLE_DRIVER_STATE_START].disable == 0) + polling_threshold = max_t(unsigned int, 20, s->target_residency); + if (data->next_timer_us > polling_threshold && + latency_req > s->exit_latency && !s->disabled && + !dev->states_usage[CPUIDLE_DRIVER_STATE_START].disable) data->last_state_idx = CPUIDLE_DRIVER_STATE_START; + else + data->last_state_idx = CPUIDLE_DRIVER_STATE_START - 1; } else { data->last_state_idx = CPUIDLE_DRIVER_STATE_START; } + /* + * Use the lowest expected idle interval to pick the idle state. + */ + data->predicted_us = min(data->predicted_us, expected_interval); + + /* + * Use the performance multiplier and the user-configurable + * latency_req to determine the maximum exit latency. + */ + interactivity_req = data->predicted_us / performance_multiplier(nr_iowaiters, cpu_load); + if (latency_req > interactivity_req) + latency_req = interactivity_req; + /* * Find the idle state with the lowest power while satisfying * our constraints. diff --git a/drivers/crypto/ccp/ccp-dev.c b/drivers/crypto/ccp/ccp-dev.c index 336e5b780fcb791c732abe2dc443ee3992809d59..4dbc187272358414e108143a0561940676de0341 100644 --- a/drivers/crypto/ccp/ccp-dev.c +++ b/drivers/crypto/ccp/ccp-dev.c @@ -53,7 +53,7 @@ static DEFINE_RWLOCK(ccp_unit_lock); static LIST_HEAD(ccp_units); /* Round-robin counter */ -static DEFINE_RWLOCK(ccp_rr_lock); +static DEFINE_SPINLOCK(ccp_rr_lock); static struct ccp_device *ccp_rr; /* Ever-increasing value to produce unique unit numbers */ @@ -128,14 +128,14 @@ static struct ccp_device *ccp_get_device(void) */ read_lock_irqsave(&ccp_unit_lock, flags); if (!list_empty(&ccp_units)) { - write_lock_irqsave(&ccp_rr_lock, flags); + spin_lock(&ccp_rr_lock); dp = ccp_rr; if (list_is_last(&ccp_rr->entry, &ccp_units)) ccp_rr = list_first_entry(&ccp_units, struct ccp_device, entry); else ccp_rr = list_next_entry(ccp_rr, entry); - write_unlock_irqrestore(&ccp_rr_lock, flags); + spin_unlock(&ccp_rr_lock); } read_unlock_irqrestore(&ccp_unit_lock, flags); diff --git a/drivers/crypto/marvell/cesa.c b/drivers/crypto/marvell/cesa.c index c0656e7f37b5993672002a8a192dc1c9dcf0c4bd..80239ae69527210ef9cabf53267d40907a8df871 100644 --- a/drivers/crypto/marvell/cesa.c +++ b/drivers/crypto/marvell/cesa.c @@ -420,7 +420,7 @@ static int mv_cesa_probe(struct platform_device *pdev) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); cesa->regs = devm_ioremap_resource(dev, res); if (IS_ERR(cesa->regs)) - return -ENOMEM; + return PTR_ERR(cesa->regs); ret = mv_cesa_dev_dma_init(cesa); if (ret) diff --git a/drivers/crypto/marvell/cesa.h b/drivers/crypto/marvell/cesa.h index bd985e72520b56428af796e1531cfb8771099a9c..74071e45ada0d07fbc98ccf5f61fa482b1b2166b 100644 --- a/drivers/crypto/marvell/cesa.h +++ b/drivers/crypto/marvell/cesa.h @@ -588,6 +588,7 @@ struct mv_cesa_ahash_dma_req { struct mv_cesa_tdma_req base; u8 *padding; dma_addr_t padding_dma; + u8 *cache; dma_addr_t cache_dma; }; @@ -609,7 +610,7 @@ struct mv_cesa_ahash_req { struct mv_cesa_ahash_std_req std; } req; struct mv_cesa_op_ctx op_tmpl; - u8 *cache; + u8 cache[CESA_MAX_HASH_BLOCK_SIZE]; unsigned int cache_ptr; u64 len; int src_nents; diff --git a/drivers/crypto/marvell/hash.c b/drivers/crypto/marvell/hash.c index 683cca9ac3c46bbf8625042f2c4b5c91e7eec51f..7ca2e0f9dc2ef983d47e1a67f1cb142ef35e2e3a 100644 --- a/drivers/crypto/marvell/hash.c +++ b/drivers/crypto/marvell/hash.c @@ -45,69 +45,25 @@ mv_cesa_ahash_req_iter_next_op(struct mv_cesa_ahash_dma_iter *iter) return mv_cesa_req_dma_iter_next_op(&iter->base); } -static inline int mv_cesa_ahash_dma_alloc_cache(struct mv_cesa_ahash_req *creq, - gfp_t flags) +static inline int +mv_cesa_ahash_dma_alloc_cache(struct mv_cesa_ahash_dma_req *req, gfp_t flags) { - struct mv_cesa_ahash_dma_req *dreq = &creq->req.dma; - - creq->cache = dma_pool_alloc(cesa_dev->dma->cache_pool, flags, - &dreq->cache_dma); - if (!creq->cache) - return -ENOMEM; - - return 0; -} - -static inline int mv_cesa_ahash_std_alloc_cache(struct mv_cesa_ahash_req *creq, - gfp_t flags) -{ - creq->cache = kzalloc(CESA_MAX_HASH_BLOCK_SIZE, flags); - if (!creq->cache) + req->cache = dma_pool_alloc(cesa_dev->dma->cache_pool, flags, + &req->cache_dma); + if (!req->cache) return -ENOMEM; return 0; } -static int mv_cesa_ahash_alloc_cache(struct ahash_request *req) -{ - struct mv_cesa_ahash_req *creq = ahash_request_ctx(req); - gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? - GFP_KERNEL : GFP_ATOMIC; - int ret; - - if (creq->cache) - return 0; - - if (creq->req.base.type == CESA_DMA_REQ) - ret = mv_cesa_ahash_dma_alloc_cache(creq, flags); - else - ret = mv_cesa_ahash_std_alloc_cache(creq, flags); - - return ret; -} - -static inline void mv_cesa_ahash_dma_free_cache(struct mv_cesa_ahash_req *creq) -{ - dma_pool_free(cesa_dev->dma->cache_pool, creq->cache, - creq->req.dma.cache_dma); -} - -static inline void mv_cesa_ahash_std_free_cache(struct mv_cesa_ahash_req *creq) -{ - kfree(creq->cache); -} - -static void mv_cesa_ahash_free_cache(struct mv_cesa_ahash_req *creq) +static inline void +mv_cesa_ahash_dma_free_cache(struct mv_cesa_ahash_dma_req *req) { - if (!creq->cache) + if (!req->cache) return; - if (creq->req.base.type == CESA_DMA_REQ) - mv_cesa_ahash_dma_free_cache(creq); - else - mv_cesa_ahash_std_free_cache(creq); - - creq->cache = NULL; + dma_pool_free(cesa_dev->dma->cache_pool, req->cache, + req->cache_dma); } static int mv_cesa_ahash_dma_alloc_padding(struct mv_cesa_ahash_dma_req *req, @@ -146,6 +102,7 @@ static inline void mv_cesa_ahash_dma_cleanup(struct ahash_request *req) struct mv_cesa_ahash_req *creq = ahash_request_ctx(req); dma_unmap_sg(cesa_dev->dev, req->src, creq->src_nents, DMA_TO_DEVICE); + mv_cesa_ahash_dma_free_cache(&creq->req.dma); mv_cesa_dma_cleanup(&creq->req.dma.base); } @@ -161,8 +118,6 @@ static void mv_cesa_ahash_last_cleanup(struct ahash_request *req) { struct mv_cesa_ahash_req *creq = ahash_request_ctx(req); - mv_cesa_ahash_free_cache(creq); - if (creq->req.base.type == CESA_DMA_REQ) mv_cesa_ahash_dma_last_cleanup(req); } @@ -445,14 +400,6 @@ static inline int mv_cesa_ahash_cra_init(struct crypto_tfm *tfm) static int mv_cesa_ahash_cache_req(struct ahash_request *req, bool *cached) { struct mv_cesa_ahash_req *creq = ahash_request_ctx(req); - int ret; - - if (((creq->cache_ptr + req->nbytes) & CESA_HASH_BLOCK_SIZE_MSK) && - !creq->last_req) { - ret = mv_cesa_ahash_alloc_cache(req); - if (ret) - return ret; - } if (creq->cache_ptr + req->nbytes < 64 && !creq->last_req) { *cached = true; @@ -505,10 +452,17 @@ mv_cesa_ahash_dma_add_cache(struct mv_cesa_tdma_chain *chain, gfp_t flags) { struct mv_cesa_ahash_dma_req *ahashdreq = &creq->req.dma; + int ret; if (!creq->cache_ptr) return 0; + ret = mv_cesa_ahash_dma_alloc_cache(ahashdreq, flags); + if (ret) + return ret; + + memcpy(ahashdreq->cache, creq->cache, creq->cache_ptr); + return mv_cesa_dma_add_data_transfer(chain, CESA_SA_DATA_SRAM_OFFSET, ahashdreq->cache_dma, @@ -848,10 +802,6 @@ static int mv_cesa_ahash_import(struct ahash_request *req, const void *hash, if (!cache_ptr) return 0; - ret = mv_cesa_ahash_alloc_cache(req); - if (ret) - return ret; - memcpy(creq->cache, cache, cache_ptr); creq->cache_ptr = cache_ptr; @@ -860,9 +810,14 @@ static int mv_cesa_ahash_import(struct ahash_request *req, const void *hash, static int mv_cesa_md5_init(struct ahash_request *req) { + struct mv_cesa_ahash_req *creq = ahash_request_ctx(req); struct mv_cesa_op_ctx tmpl = { }; mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_MACM_MD5); + creq->state[0] = MD5_H0; + creq->state[1] = MD5_H1; + creq->state[2] = MD5_H2; + creq->state[3] = MD5_H3; mv_cesa_ahash_init(req, &tmpl, true); @@ -923,9 +878,15 @@ struct ahash_alg mv_md5_alg = { static int mv_cesa_sha1_init(struct ahash_request *req) { + struct mv_cesa_ahash_req *creq = ahash_request_ctx(req); struct mv_cesa_op_ctx tmpl = { }; mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_MACM_SHA1); + creq->state[0] = SHA1_H0; + creq->state[1] = SHA1_H1; + creq->state[2] = SHA1_H2; + creq->state[3] = SHA1_H3; + creq->state[4] = SHA1_H4; mv_cesa_ahash_init(req, &tmpl, false); @@ -986,9 +947,18 @@ struct ahash_alg mv_sha1_alg = { static int mv_cesa_sha256_init(struct ahash_request *req) { + struct mv_cesa_ahash_req *creq = ahash_request_ctx(req); struct mv_cesa_op_ctx tmpl = { }; mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_MACM_SHA256); + creq->state[0] = SHA256_H0; + creq->state[1] = SHA256_H1; + creq->state[2] = SHA256_H2; + creq->state[3] = SHA256_H3; + creq->state[4] = SHA256_H4; + creq->state[5] = SHA256_H5; + creq->state[6] = SHA256_H6; + creq->state[7] = SHA256_H7; mv_cesa_ahash_init(req, &tmpl, false); diff --git a/drivers/crypto/nx/nx-842.c b/drivers/crypto/nx/nx-842.c index 046c1c45411bbc7fe21b5207479644130183ac68..d94e25df503b91fc873c6b12f74d5d83192b0c02 100644 --- a/drivers/crypto/nx/nx-842.c +++ b/drivers/crypto/nx/nx-842.c @@ -308,7 +308,7 @@ int nx842_crypto_compress(struct crypto_tfm *tfm, h = !n && add_header ? hdrsize : 0; if (ignore) - pr_warn("interal error, ignore is set %x\n", ignore); + pr_warn("internal error, ignore is set %x\n", ignore); ret = compress(ctx, &p, &hdr->group[n], &c, &ignore, h); if (ret) diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig index 64281bb2f6503c5a63d605ca7249ca86434d5aaf..4de78c552251a5a58803f74957e82f41a76307e8 100644 --- a/drivers/devfreq/Kconfig +++ b/drivers/devfreq/Kconfig @@ -61,7 +61,7 @@ config DEVFREQ_GOV_USERSPACE Sets the frequency at the user specified one. This governor returns the user configured frequency if there has been an input to /sys/devices/.../power/devfreq_set_freq. - Otherwise, the governor does not change the frequnecy + Otherwise, the governor does not change the frequency given at the initialization. comment "DEVFREQ Drivers" diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 155c1464948e7ad02f885302754353725775b3be..4a2c07ee667773bf02b1ece356c60089ccffb867 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -34,6 +34,8 @@ #include #include +#include + static inline int is_dma_buf_file(struct file *); struct dma_buf_list { @@ -251,11 +253,55 @@ static unsigned int dma_buf_poll(struct file *file, poll_table *poll) return events; } +static long dma_buf_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct dma_buf *dmabuf; + struct dma_buf_sync sync; + enum dma_data_direction direction; + int ret; + + dmabuf = file->private_data; + + switch (cmd) { + case DMA_BUF_IOCTL_SYNC: + if (copy_from_user(&sync, (void __user *) arg, sizeof(sync))) + return -EFAULT; + + if (sync.flags & ~DMA_BUF_SYNC_VALID_FLAGS_MASK) + return -EINVAL; + + switch (sync.flags & DMA_BUF_SYNC_RW) { + case DMA_BUF_SYNC_READ: + direction = DMA_FROM_DEVICE; + break; + case DMA_BUF_SYNC_WRITE: + direction = DMA_TO_DEVICE; + break; + case DMA_BUF_SYNC_RW: + direction = DMA_BIDIRECTIONAL; + break; + default: + return -EINVAL; + } + + if (sync.flags & DMA_BUF_SYNC_END) + ret = dma_buf_end_cpu_access(dmabuf, direction); + else + ret = dma_buf_begin_cpu_access(dmabuf, direction); + + return ret; + default: + return -ENOTTY; + } +} + static const struct file_operations dma_buf_fops = { .release = dma_buf_release, .mmap = dma_buf_mmap_internal, .llseek = dma_buf_llseek, .poll = dma_buf_poll, + .unlocked_ioctl = dma_buf_ioctl, }; /* @@ -539,13 +585,11 @@ EXPORT_SYMBOL_GPL(dma_buf_unmap_attachment); * preparations. Coherency is only guaranteed in the specified range for the * specified access direction. * @dmabuf: [in] buffer to prepare cpu access for. - * @start: [in] start of range for cpu access. - * @len: [in] length of range for cpu access. * @direction: [in] length of range for cpu access. * * Can return negative error values, returns 0 on success. */ -int dma_buf_begin_cpu_access(struct dma_buf *dmabuf, size_t start, size_t len, +int dma_buf_begin_cpu_access(struct dma_buf *dmabuf, enum dma_data_direction direction) { int ret = 0; @@ -554,8 +598,7 @@ int dma_buf_begin_cpu_access(struct dma_buf *dmabuf, size_t start, size_t len, return -EINVAL; if (dmabuf->ops->begin_cpu_access) - ret = dmabuf->ops->begin_cpu_access(dmabuf, start, - len, direction); + ret = dmabuf->ops->begin_cpu_access(dmabuf, direction); return ret; } @@ -567,19 +610,21 @@ EXPORT_SYMBOL_GPL(dma_buf_begin_cpu_access); * actions. Coherency is only guaranteed in the specified range for the * specified access direction. * @dmabuf: [in] buffer to complete cpu access for. - * @start: [in] start of range for cpu access. - * @len: [in] length of range for cpu access. * @direction: [in] length of range for cpu access. * - * This call must always succeed. + * Can return negative error values, returns 0 on success. */ -void dma_buf_end_cpu_access(struct dma_buf *dmabuf, size_t start, size_t len, - enum dma_data_direction direction) +int dma_buf_end_cpu_access(struct dma_buf *dmabuf, + enum dma_data_direction direction) { + int ret = 0; + WARN_ON(!dmabuf); if (dmabuf->ops->end_cpu_access) - dmabuf->ops->end_cpu_access(dmabuf, start, len, direction); + ret = dmabuf->ops->end_cpu_access(dmabuf, direction); + + return ret; } EXPORT_SYMBOL_GPL(dma_buf_end_cpu_access); diff --git a/drivers/dma/idma64.h b/drivers/dma/idma64.h index dc687442418836d963d7cf70d5502c8369920d24..6b816878e5e7a79d9e4fb14f982e3aa21e3e34a2 100644 --- a/drivers/dma/idma64.h +++ b/drivers/dma/idma64.h @@ -16,7 +16,7 @@ #include #include -#include +#include #include "virt-dma.h" diff --git a/drivers/dma/pxa_dma.c b/drivers/dma/pxa_dma.c index debca824bed676f0ecacc9e71476ecc33a477298..77c1c44009d87115f2c44d5fd698dc8a1626ec51 100644 --- a/drivers/dma/pxa_dma.c +++ b/drivers/dma/pxa_dma.c @@ -122,6 +122,7 @@ struct pxad_chan { struct pxad_device { struct dma_device slave; int nr_chans; + int nr_requestors; void __iomem *base; struct pxad_phy *phys; spinlock_t phy_lock; /* Phy association */ @@ -473,7 +474,7 @@ static void pxad_free_phy(struct pxad_chan *chan) return; /* clear the channel mapping in DRCMR */ - if (chan->drcmr <= DRCMR_CHLNUM) { + if (chan->drcmr <= pdev->nr_requestors) { reg = pxad_drcmr(chan->drcmr); writel_relaxed(0, chan->phy->base + reg); } @@ -509,6 +510,7 @@ static bool is_running_chan_misaligned(struct pxad_chan *chan) static void phy_enable(struct pxad_phy *phy, bool misaligned) { + struct pxad_device *pdev; u32 reg, dalgn; if (!phy->vchan) @@ -518,7 +520,8 @@ static void phy_enable(struct pxad_phy *phy, bool misaligned) "%s(); phy=%p(%d) misaligned=%d\n", __func__, phy, phy->idx, misaligned); - if (phy->vchan->drcmr <= DRCMR_CHLNUM) { + pdev = to_pxad_dev(phy->vchan->vc.chan.device); + if (phy->vchan->drcmr <= pdev->nr_requestors) { reg = pxad_drcmr(phy->vchan->drcmr); writel_relaxed(DRCMR_MAPVLD | phy->idx, phy->base + reg); } @@ -914,6 +917,7 @@ static void pxad_get_config(struct pxad_chan *chan, { u32 maxburst = 0, dev_addr = 0; enum dma_slave_buswidth width = DMA_SLAVE_BUSWIDTH_UNDEFINED; + struct pxad_device *pdev = to_pxad_dev(chan->vc.chan.device); *dcmd = 0; if (dir == DMA_DEV_TO_MEM) { @@ -922,7 +926,7 @@ static void pxad_get_config(struct pxad_chan *chan, dev_addr = chan->cfg.src_addr; *dev_src = dev_addr; *dcmd |= PXA_DCMD_INCTRGADDR; - if (chan->drcmr <= DRCMR_CHLNUM) + if (chan->drcmr <= pdev->nr_requestors) *dcmd |= PXA_DCMD_FLOWSRC; } if (dir == DMA_MEM_TO_DEV) { @@ -931,7 +935,7 @@ static void pxad_get_config(struct pxad_chan *chan, dev_addr = chan->cfg.dst_addr; *dev_dst = dev_addr; *dcmd |= PXA_DCMD_INCSRCADDR; - if (chan->drcmr <= DRCMR_CHLNUM) + if (chan->drcmr <= pdev->nr_requestors) *dcmd |= PXA_DCMD_FLOWTRG; } if (dir == DMA_MEM_TO_MEM) @@ -1341,13 +1345,15 @@ static struct dma_chan *pxad_dma_xlate(struct of_phandle_args *dma_spec, static int pxad_init_dmadev(struct platform_device *op, struct pxad_device *pdev, - unsigned int nr_phy_chans) + unsigned int nr_phy_chans, + unsigned int nr_requestors) { int ret; unsigned int i; struct pxad_chan *c; pdev->nr_chans = nr_phy_chans; + pdev->nr_requestors = nr_requestors; INIT_LIST_HEAD(&pdev->slave.channels); pdev->slave.device_alloc_chan_resources = pxad_alloc_chan_resources; pdev->slave.device_free_chan_resources = pxad_free_chan_resources; @@ -1382,7 +1388,7 @@ static int pxad_probe(struct platform_device *op) const struct of_device_id *of_id; struct mmp_dma_platdata *pdata = dev_get_platdata(&op->dev); struct resource *iores; - int ret, dma_channels = 0; + int ret, dma_channels = 0, nb_requestors = 0; const enum dma_slave_buswidth widths = DMA_SLAVE_BUSWIDTH_1_BYTE | DMA_SLAVE_BUSWIDTH_2_BYTES | DMA_SLAVE_BUSWIDTH_4_BYTES; @@ -1399,13 +1405,23 @@ static int pxad_probe(struct platform_device *op) return PTR_ERR(pdev->base); of_id = of_match_device(pxad_dt_ids, &op->dev); - if (of_id) + if (of_id) { of_property_read_u32(op->dev.of_node, "#dma-channels", &dma_channels); - else if (pdata && pdata->dma_channels) + ret = of_property_read_u32(op->dev.of_node, "#dma-requests", + &nb_requestors); + if (ret) { + dev_warn(pdev->slave.dev, + "#dma-requests set to default 32 as missing in OF: %d", + ret); + nb_requestors = 32; + }; + } else if (pdata && pdata->dma_channels) { dma_channels = pdata->dma_channels; - else + nb_requestors = pdata->nb_requestors; + } else { dma_channels = 32; /* default 32 channel */ + } dma_cap_set(DMA_SLAVE, pdev->slave.cap_mask); dma_cap_set(DMA_MEMCPY, pdev->slave.cap_mask); @@ -1423,7 +1439,7 @@ static int pxad_probe(struct platform_device *op) pdev->slave.descriptor_reuse = true; pdev->slave.dev = &op->dev; - ret = pxad_init_dmadev(op, pdev, dma_channels); + ret = pxad_init_dmadev(op, pdev, dma_channels, nb_requestors); if (ret) { dev_err(pdev->slave.dev, "unable to register\n"); return ret; @@ -1442,7 +1458,8 @@ static int pxad_probe(struct platform_device *op) platform_set_drvdata(op, pdev); pxad_init_debugfs(pdev); - dev_info(pdev->slave.dev, "initialized %d channels\n", dma_channels); + dev_info(pdev->slave.dev, "initialized %d channels on %d requestors\n", + dma_channels, nb_requestors); return 0; } diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index 36a7c2d89a010e7a567224c89a01a2ebe0c8fd20..aee149bdf4c0339169d939eed797ef9e6ab521bf 100644 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c @@ -221,7 +221,7 @@ struct inbound_phy_packet_event { #ifdef CONFIG_COMPAT static void __user *u64_to_uptr(u64 value) { - if (is_compat_task()) + if (in_compat_syscall()) return compat_ptr(value); else return (void __user *)(unsigned long)value; @@ -229,7 +229,7 @@ static void __user *u64_to_uptr(u64 value) static u64 uptr_to_u64(void __user *ptr) { - if (is_compat_task()) + if (in_compat_syscall()) return ptr_to_compat(ptr); else return (u64)(unsigned long)ptr; diff --git a/drivers/firewire/nosy.c b/drivers/firewire/nosy.c index 76b2d390f6ec95aeedf1596e751f7ad055509c65..631c977b0da5f817b7ecf950d94f90198a53abbe 100644 --- a/drivers/firewire/nosy.c +++ b/drivers/firewire/nosy.c @@ -33,6 +33,7 @@ #include /* required for linux/wait.h */ #include #include +#include #include #include #include @@ -413,17 +414,18 @@ static void packet_irq_handler(struct pcilynx *lynx) { struct client *client; - u32 tcode_mask, tcode; + u32 tcode_mask, tcode, timestamp; size_t length; - struct timeval tv; + struct timespec64 ts64; /* FIXME: Also report rcv_speed. */ length = __le32_to_cpu(lynx->rcv_pcl->pcl_status) & 0x00001fff; tcode = __le32_to_cpu(lynx->rcv_buffer[1]) >> 4 & 0xf; - do_gettimeofday(&tv); - lynx->rcv_buffer[0] = (__force __le32)tv.tv_usec; + ktime_get_real_ts64(&ts64); + timestamp = ts64.tv_nsec / NSEC_PER_USEC; + lynx->rcv_buffer[0] = (__force __le32)timestamp; if (length == PHY_PACKET_SIZE) tcode_mask = 1 << TCODE_PHY_PACKET; @@ -444,14 +446,16 @@ static void bus_reset_irq_handler(struct pcilynx *lynx) { struct client *client; - struct timeval tv; + struct timespec64 ts64; + u32 timestamp; - do_gettimeofday(&tv); + ktime_get_real_ts64(&ts64); + timestamp = ts64.tv_nsec / NSEC_PER_USEC; spin_lock(&lynx->client_list_lock); list_for_each_entry(client, &lynx->client_list, link) - packet_buffer_put(&client->buffer, &tv.tv_usec, 4); + packet_buffer_put(&client->buffer, ×tamp, 4); spin_unlock(&lynx->client_list_lock); } diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index c2f5117fd8cb00c48f42784dcef9c97ebaa92080..8bf89267dc252f260a3fc6e640c0c1809f04ef2d 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -2278,9 +2278,10 @@ static int ohci_enable(struct fw_card *card, u32 lps, version, irqs; int i, ret; - if (software_reset(ohci)) { + ret = software_reset(ohci); + if (ret < 0) { ohci_err(ohci, "failed to reset ohci card\n"); - return -EBUSY; + return ret; } /* diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c index 6174db80c66361d2046a3548c6f5b14d36f8c999..7e3e595c9f3011602cb08293fa38a29e94021e8a 100644 --- a/drivers/firmware/arm_scpi.c +++ b/drivers/firmware/arm_scpi.c @@ -80,7 +80,7 @@ #define FW_REV_MINOR(x) (((x) & FW_REV_MINOR_MASK) >> FW_REV_MINOR_BITS) #define FW_REV_PATCH(x) ((x) & FW_REV_PATCH_MASK) -#define MAX_RX_TIMEOUT (msecs_to_jiffies(20)) +#define MAX_RX_TIMEOUT (msecs_to_jiffies(30)) enum scpi_error_codes { SCPI_SUCCESS = 0, /* Success */ @@ -231,7 +231,8 @@ struct _scpi_sensor_info { }; struct sensor_value { - __le32 val; + __le32 lo_val; + __le32 hi_val; } __packed; static struct scpi_drvinfo *scpi_info; @@ -373,7 +374,7 @@ static int scpi_send_message(u8 cmd, void *tx_buf, unsigned int tx_len, ret = -ETIMEDOUT; else /* first status word */ - ret = le32_to_cpu(msg->status); + ret = msg->status; out: if (ret < 0 && rx_buf) /* remove entry from the list if timed-out */ scpi_process_cmd(scpi_chan, msg->cmd); @@ -525,15 +526,17 @@ static int scpi_sensor_get_info(u16 sensor_id, struct scpi_sensor_info *info) return ret; } -int scpi_sensor_get_value(u16 sensor, u32 *val) +int scpi_sensor_get_value(u16 sensor, u64 *val) { + __le16 id = cpu_to_le16(sensor); struct sensor_value buf; int ret; - ret = scpi_send_message(SCPI_CMD_SENSOR_VALUE, &sensor, sizeof(sensor), + ret = scpi_send_message(SCPI_CMD_SENSOR_VALUE, &id, sizeof(id), &buf, sizeof(buf)); if (!ret) - *val = le32_to_cpu(buf.val); + *val = (u64)le32_to_cpu(buf.hi_val) << 32 | + le32_to_cpu(buf.lo_val); return ret; } @@ -699,7 +702,7 @@ static int scpi_probe(struct platform_device *pdev) cl->rx_callback = scpi_handle_remote_msg; cl->tx_prepare = scpi_tx_prepare; cl->tx_block = true; - cl->tx_tout = 50; + cl->tx_tout = 20; cl->knows_txdone = false; /* controller can't ack */ INIT_LIST_HEAD(&pchan->rx_pending); diff --git a/drivers/firmware/broadcom/bcm47xx_nvram.c b/drivers/firmware/broadcom/bcm47xx_nvram.c index 0c2f0a61b0ea021872f27705b53ae784f1be3f61..0b631e5b5b843f158ea675f0cd86a081fa541729 100644 --- a/drivers/firmware/broadcom/bcm47xx_nvram.c +++ b/drivers/firmware/broadcom/bcm47xx_nvram.c @@ -94,15 +94,14 @@ static int nvram_find_and_copy(void __iomem *iobase, u32 lim) found: __ioread32_copy(nvram_buf, header, sizeof(*header) / 4); - header = (struct nvram_header *)nvram_buf; - nvram_len = header->len; + nvram_len = ((struct nvram_header *)(nvram_buf))->len; if (nvram_len > size) { pr_err("The nvram size according to the header seems to be bigger than the partition on flash\n"); nvram_len = size; } if (nvram_len >= NVRAM_SPACE) { pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n", - header->len, NVRAM_SPACE - 1); + nvram_len, NVRAM_SPACE - 1); nvram_len = NVRAM_SPACE - 1; } /* proceed reading data after header */ diff --git a/drivers/firmware/efi/arm-init.c b/drivers/firmware/efi/arm-init.c index 9e15d571b53c2bd759e1b0e6c0d0bda0795740a9..aa1f743152a2fd317a82c8ac7ca3daf36e865b46 100644 --- a/drivers/firmware/efi/arm-init.c +++ b/drivers/firmware/efi/arm-init.c @@ -61,8 +61,8 @@ static int __init uefi_init(void) char vendor[100] = "unknown"; int i, retval; - efi.systab = early_memremap(efi_system_table, - sizeof(efi_system_table_t)); + efi.systab = early_memremap_ro(efi_system_table, + sizeof(efi_system_table_t)); if (efi.systab == NULL) { pr_warn("Unable to map EFI system table.\n"); return -ENOMEM; @@ -86,8 +86,8 @@ static int __init uefi_init(void) efi.systab->hdr.revision & 0xffff); /* Show what we know for posterity */ - c16 = early_memremap(efi_to_phys(efi.systab->fw_vendor), - sizeof(vendor) * sizeof(efi_char16_t)); + c16 = early_memremap_ro(efi_to_phys(efi.systab->fw_vendor), + sizeof(vendor) * sizeof(efi_char16_t)); if (c16) { for (i = 0; i < (int) sizeof(vendor) - 1 && *c16; ++i) vendor[i] = c16[i]; @@ -100,8 +100,8 @@ static int __init uefi_init(void) efi.systab->hdr.revision & 0xffff, vendor); table_size = sizeof(efi_config_table_64_t) * efi.systab->nr_tables; - config_tables = early_memremap(efi_to_phys(efi.systab->tables), - table_size); + config_tables = early_memremap_ro(efi_to_phys(efi.systab->tables), + table_size); if (config_tables == NULL) { pr_warn("Unable to map EFI config table array.\n"); retval = -ENOMEM; @@ -185,7 +185,7 @@ void __init efi_init(void) efi_system_table = params.system_table; memmap.phys_map = params.mmap; - memmap.map = early_memremap(params.mmap, params.mmap_size); + memmap.map = early_memremap_ro(params.mmap, params.mmap_size); if (memmap.map == NULL) { /* * If we are booting via UEFI, the UEFI memory map is the only diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 2cd37dad67a63645b15d9f2f496630a1e820ce19..3a69ed5ecfcb5f1254eaf1b0c3fb53cbdbcc61fb 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -182,6 +182,7 @@ static int generic_ops_register(void) { generic_ops.get_variable = efi.get_variable; generic_ops.set_variable = efi.set_variable; + generic_ops.set_variable_nonblocking = efi.set_variable_nonblocking; generic_ops.get_next_variable = efi.get_next_variable; generic_ops.query_variable_store = efi_query_variable_store; @@ -326,38 +327,6 @@ u64 __init efi_mem_desc_end(efi_memory_desc_t *md) return end; } -/* - * We can't ioremap data in EFI boot services RAM, because we've already mapped - * it as RAM. So, look it up in the existing EFI memory map instead. Only - * callable after efi_enter_virtual_mode and before efi_free_boot_services. - */ -void __iomem *efi_lookup_mapped_addr(u64 phys_addr) -{ - struct efi_memory_map *map; - void *p; - map = efi.memmap; - if (!map) - return NULL; - if (WARN_ON(!map->map)) - return NULL; - for (p = map->map; p < map->map_end; p += map->desc_size) { - efi_memory_desc_t *md = p; - u64 size = md->num_pages << EFI_PAGE_SHIFT; - u64 end = md->phys_addr + size; - if (!(md->attribute & EFI_MEMORY_RUNTIME) && - md->type != EFI_BOOT_SERVICES_CODE && - md->type != EFI_BOOT_SERVICES_DATA) - continue; - if (!md->virt_addr) - continue; - if (phys_addr >= md->phys_addr && phys_addr < end) { - phys_addr += md->virt_addr - md->phys_addr; - return (__force void __iomem *)(unsigned long)phys_addr; - } - } - return NULL; -} - static __initdata efi_config_table_type_t common_tables[] = { {ACPI_20_TABLE_GUID, "ACPI 2.0", &efi.acpi20}, {ACPI_TABLE_GUID, "ACPI", &efi.acpi}, @@ -586,7 +555,8 @@ static __initdata char memory_type_name[][20] = { "ACPI Memory NVS", "Memory Mapped I/O", "MMIO Port Space", - "PAL Code" + "PAL Code", + "Persistent Memory", }; char * __init efi_md_typeattr_format(char *buf, size_t size, @@ -613,13 +583,16 @@ char * __init efi_md_typeattr_format(char *buf, size_t size, if (attr & ~(EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_RO | EFI_MEMORY_WP | EFI_MEMORY_RP | EFI_MEMORY_XP | + EFI_MEMORY_NV | EFI_MEMORY_RUNTIME | EFI_MEMORY_MORE_RELIABLE)) snprintf(pos, size, "|attr=0x%016llx]", (unsigned long long)attr); else - snprintf(pos, size, "|%3s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]", + snprintf(pos, size, + "|%3s|%2s|%2s|%2s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]", attr & EFI_MEMORY_RUNTIME ? "RUN" : "", attr & EFI_MEMORY_MORE_RELIABLE ? "MR" : "", + attr & EFI_MEMORY_NV ? "NV" : "", attr & EFI_MEMORY_XP ? "XP" : "", attr & EFI_MEMORY_RP ? "RP" : "", attr & EFI_MEMORY_WP ? "WP" : "", diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c index 10e6774ab2a2248d0a04d935b773c15a38519f46..096adcbcb5a99720c77bc69af458bf5f9628dbd4 100644 --- a/drivers/firmware/efi/efivars.c +++ b/drivers/firmware/efi/efivars.c @@ -231,7 +231,7 @@ sanity_check(struct efi_variable *var, efi_char16_t *name, efi_guid_t vendor, static inline bool is_compat(void) { - if (IS_ENABLED(CONFIG_COMPAT) && is_compat_task()) + if (IS_ENABLED(CONFIG_COMPAT) && in_compat_syscall()) return true; return false; @@ -386,7 +386,7 @@ static const struct sysfs_ops efivar_attr_ops = { static void efivar_release(struct kobject *kobj) { - struct efivar_entry *var = container_of(kobj, struct efivar_entry, kobj); + struct efivar_entry *var = to_efivar_entry(kobj); kfree(var); } diff --git a/drivers/firmware/efi/esrt.c b/drivers/firmware/efi/esrt.c index 22c5285f77050f27d2d96a22b5ade945bae54316..75feb3f5829bab96067054dc7063400a723569f6 100644 --- a/drivers/firmware/efi/esrt.c +++ b/drivers/firmware/efi/esrt.c @@ -167,14 +167,11 @@ static struct kset *esrt_kset; static int esre_create_sysfs_entry(void *esre, int entry_num) { struct esre_entry *entry; - char name[20]; entry = kzalloc(sizeof(*entry), GFP_KERNEL); if (!entry) return -ENOMEM; - sprintf(name, "entry%d", entry_num); - entry->kobj.kset = esrt_kset; if (esrt->fw_resource_version == 1) { @@ -182,7 +179,7 @@ static int esre_create_sysfs_entry(void *esre, int entry_num) entry->esre.esre1 = esre; rc = kobject_init_and_add(&entry->kobj, &esre1_ktype, NULL, - "%s", name); + "entry%d", entry_num); if (rc) { kfree(entry); return rc; diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile index ad077944aa0eca1a4a6d0f3d0ce2f8d3ac0820dd..da99bbb74aebde62fc62128bed5d4ba2ee801212 100644 --- a/drivers/firmware/efi/libstub/Makefile +++ b/drivers/firmware/efi/libstub/Makefile @@ -23,6 +23,10 @@ KBUILD_CFLAGS := $(cflags-y) -DDISABLE_BRANCH_PROFILING \ GCOV_PROFILE := n KASAN_SANITIZE := n UBSAN_SANITIZE := n +OBJECT_FILES_NON_STANDARD := y + +# Prevents link failures: __sanitizer_cov_trace_pc() is not linked in. +KCOV_INSTRUMENT := n lib-y := efi-stub-helper.o diff --git a/drivers/firmware/efi/libstub/arm-stub.c b/drivers/firmware/efi/libstub/arm-stub.c index 4deb3e7faa0ea622bce16d9877bb445bb3246399..414deb85c2e5214d4dc3a4cb85f4f8a20eb2df05 100644 --- a/drivers/firmware/efi/libstub/arm-stub.c +++ b/drivers/firmware/efi/libstub/arm-stub.c @@ -192,6 +192,10 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table, pr_efi(sys_table, "Booting Linux Kernel...\n"); + status = check_platform_features(sys_table); + if (status != EFI_SUCCESS) + goto fail; + /* * Get a handle to the loaded image protocol. This is used to get * information about the running image, such as size and the command diff --git a/drivers/firmware/efi/libstub/arm32-stub.c b/drivers/firmware/efi/libstub/arm32-stub.c index 495ebd657e380eb1e0f8c3c162dd3e9685f902db..6f42be4d0084f1befcceb329758513b5f2c50781 100644 --- a/drivers/firmware/efi/libstub/arm32-stub.c +++ b/drivers/firmware/efi/libstub/arm32-stub.c @@ -9,6 +9,23 @@ #include #include +efi_status_t check_platform_features(efi_system_table_t *sys_table_arg) +{ + int block; + + /* non-LPAE kernels can run anywhere */ + if (!IS_ENABLED(CONFIG_ARM_LPAE)) + return EFI_SUCCESS; + + /* LPAE kernels need compatible hardware */ + block = cpuid_feature_extract(CPUID_EXT_MMFR0, 0); + if (block < 5) { + pr_efi_err(sys_table_arg, "This LPAE kernel is not supported by your CPU\n"); + return EFI_UNSUPPORTED; + } + return EFI_SUCCESS; +} + efi_status_t handle_kernel_image(efi_system_table_t *sys_table, unsigned long *image_addr, unsigned long *image_size, diff --git a/drivers/firmware/efi/libstub/arm64-stub.c b/drivers/firmware/efi/libstub/arm64-stub.c index e0e6b74fef8f7becdef4c0481919ead298023250..a90f6459f5c6d16535f026d1fcf54719b0a96878 100644 --- a/drivers/firmware/efi/libstub/arm64-stub.c +++ b/drivers/firmware/efi/libstub/arm64-stub.c @@ -12,18 +12,38 @@ #include #include #include +#include #include "efistub.h" extern bool __nokaslr; -efi_status_t __init handle_kernel_image(efi_system_table_t *sys_table_arg, - unsigned long *image_addr, - unsigned long *image_size, - unsigned long *reserve_addr, - unsigned long *reserve_size, - unsigned long dram_base, - efi_loaded_image_t *image) +efi_status_t check_platform_features(efi_system_table_t *sys_table_arg) +{ + u64 tg; + + /* UEFI mandates support for 4 KB granularity, no need to check */ + if (IS_ENABLED(CONFIG_ARM64_4K_PAGES)) + return EFI_SUCCESS; + + tg = (read_cpuid(ID_AA64MMFR0_EL1) >> ID_AA64MMFR0_TGRAN_SHIFT) & 0xf; + if (tg != ID_AA64MMFR0_TGRAN_SUPPORTED) { + if (IS_ENABLED(CONFIG_ARM64_64K_PAGES)) + pr_efi_err(sys_table_arg, "This 64 KB granular kernel is not supported by your CPU\n"); + else + pr_efi_err(sys_table_arg, "This 16 KB granular kernel is not supported by your CPU\n"); + return EFI_UNSUPPORTED; + } + return EFI_SUCCESS; +} + +efi_status_t handle_kernel_image(efi_system_table_t *sys_table_arg, + unsigned long *image_addr, + unsigned long *image_size, + unsigned long *reserve_addr, + unsigned long *reserve_size, + unsigned long dram_base, + efi_loaded_image_t *image) { efi_status_t status; unsigned long kernel_size, kernel_memsize = 0; diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h index 5ed3d3f3816637cd10d007f381797320f0567305..ee49cd23ee636d96b7d340ee74577ff8aef50822 100644 --- a/drivers/firmware/efi/libstub/efistub.h +++ b/drivers/firmware/efi/libstub/efistub.h @@ -5,6 +5,16 @@ /* error code which can't be mistaken for valid address */ #define EFI_ERROR (~0UL) +/* + * __init annotations should not be used in the EFI stub, since the code is + * either included in the decompressor (x86, ARM) where they have no effect, + * or the whole stub is __init annotated at the section level (arm64), by + * renaming the sections, in which case the __init annotation will be + * redundant, and will result in section names like .init.init.text, and our + * linker script does not expect that. + */ +#undef __init + void efi_char16_printk(efi_system_table_t *, efi_char16_t *); efi_status_t efi_open_volume(efi_system_table_t *sys_table_arg, void *__image, @@ -50,4 +60,6 @@ efi_status_t efi_random_alloc(efi_system_table_t *sys_table_arg, unsigned long size, unsigned long align, unsigned long *addr, unsigned long random_seed); +efi_status_t check_platform_features(efi_system_table_t *sys_table_arg); + #endif diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c index 228bbf91046137de619a4f8f89825e8ccc34b5ab..de6953039af65255b1afe36d059fb2893fdcd6f9 100644 --- a/drivers/firmware/efi/runtime-wrappers.c +++ b/drivers/firmware/efi/runtime-wrappers.c @@ -61,63 +61,23 @@ */ static DEFINE_SPINLOCK(efi_runtime_lock); -/* - * Some runtime services calls can be reentrant under NMI, even if the table - * above says they are not. (source: UEFI Specification v2.4A) - * - * Table 32. Functions that may be called after Machine Check, INIT and NMI - * +----------------------------+------------------------------------------+ - * | Function | Called after Machine Check, INIT and NMI | - * +----------------------------+------------------------------------------+ - * | GetTime() | Yes, even if previously busy. | - * | GetVariable() | Yes, even if previously busy | - * | GetNextVariableName() | Yes, even if previously busy | - * | QueryVariableInfo() | Yes, even if previously busy | - * | SetVariable() | Yes, even if previously busy | - * | UpdateCapsule() | Yes, even if previously busy | - * | QueryCapsuleCapabilities() | Yes, even if previously busy | - * | ResetSystem() | Yes, even if previously busy | - * +----------------------------+------------------------------------------+ - * - * In order to prevent deadlocks under NMI, the wrappers for these functions - * may only grab the efi_runtime_lock or rtc_lock spinlocks if !efi_in_nmi(). - * However, not all of the services listed are reachable through NMI code paths, - * so the the special handling as suggested by the UEFI spec is only implemented - * for QueryVariableInfo() and SetVariable(), as these can be reached in NMI - * context through efi_pstore_write(). - */ - -/* - * As per commit ef68c8f87ed1 ("x86: Serialize EFI time accesses on rtc_lock"), - * the EFI specification requires that callers of the time related runtime - * functions serialize with other CMOS accesses in the kernel, as the EFI time - * functions may choose to also use the legacy CMOS RTC. - */ -__weak DEFINE_SPINLOCK(rtc_lock); - static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc) { - unsigned long flags; efi_status_t status; - spin_lock_irqsave(&rtc_lock, flags); spin_lock(&efi_runtime_lock); status = efi_call_virt(get_time, tm, tc); spin_unlock(&efi_runtime_lock); - spin_unlock_irqrestore(&rtc_lock, flags); return status; } static efi_status_t virt_efi_set_time(efi_time_t *tm) { - unsigned long flags; efi_status_t status; - spin_lock_irqsave(&rtc_lock, flags); spin_lock(&efi_runtime_lock); status = efi_call_virt(set_time, tm); spin_unlock(&efi_runtime_lock); - spin_unlock_irqrestore(&rtc_lock, flags); return status; } @@ -125,27 +85,21 @@ static efi_status_t virt_efi_get_wakeup_time(efi_bool_t *enabled, efi_bool_t *pending, efi_time_t *tm) { - unsigned long flags; efi_status_t status; - spin_lock_irqsave(&rtc_lock, flags); spin_lock(&efi_runtime_lock); status = efi_call_virt(get_wakeup_time, enabled, pending, tm); spin_unlock(&efi_runtime_lock); - spin_unlock_irqrestore(&rtc_lock, flags); return status; } static efi_status_t virt_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm) { - unsigned long flags; efi_status_t status; - spin_lock_irqsave(&rtc_lock, flags); spin_lock(&efi_runtime_lock); status = efi_call_virt(set_wakeup_time, enabled, tm); spin_unlock(&efi_runtime_lock); - spin_unlock_irqrestore(&rtc_lock, flags); return status; } @@ -155,13 +109,12 @@ static efi_status_t virt_efi_get_variable(efi_char16_t *name, unsigned long *data_size, void *data) { - unsigned long flags; efi_status_t status; - spin_lock_irqsave(&efi_runtime_lock, flags); + spin_lock(&efi_runtime_lock); status = efi_call_virt(get_variable, name, vendor, attr, data_size, data); - spin_unlock_irqrestore(&efi_runtime_lock, flags); + spin_unlock(&efi_runtime_lock); return status; } @@ -169,12 +122,11 @@ static efi_status_t virt_efi_get_next_variable(unsigned long *name_size, efi_char16_t *name, efi_guid_t *vendor) { - unsigned long flags; efi_status_t status; - spin_lock_irqsave(&efi_runtime_lock, flags); + spin_lock(&efi_runtime_lock); status = efi_call_virt(get_next_variable, name_size, name, vendor); - spin_unlock_irqrestore(&efi_runtime_lock, flags); + spin_unlock(&efi_runtime_lock); return status; } @@ -184,13 +136,12 @@ static efi_status_t virt_efi_set_variable(efi_char16_t *name, unsigned long data_size, void *data) { - unsigned long flags; efi_status_t status; - spin_lock_irqsave(&efi_runtime_lock, flags); + spin_lock(&efi_runtime_lock); status = efi_call_virt(set_variable, name, vendor, attr, data_size, data); - spin_unlock_irqrestore(&efi_runtime_lock, flags); + spin_unlock(&efi_runtime_lock); return status; } @@ -199,15 +150,14 @@ virt_efi_set_variable_nonblocking(efi_char16_t *name, efi_guid_t *vendor, u32 attr, unsigned long data_size, void *data) { - unsigned long flags; efi_status_t status; - if (!spin_trylock_irqsave(&efi_runtime_lock, flags)) + if (!spin_trylock(&efi_runtime_lock)) return EFI_NOT_READY; status = efi_call_virt(set_variable, name, vendor, attr, data_size, data); - spin_unlock_irqrestore(&efi_runtime_lock, flags); + spin_unlock(&efi_runtime_lock); return status; } @@ -217,27 +167,45 @@ static efi_status_t virt_efi_query_variable_info(u32 attr, u64 *remaining_space, u64 *max_variable_size) { - unsigned long flags; efi_status_t status; if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION) return EFI_UNSUPPORTED; - spin_lock_irqsave(&efi_runtime_lock, flags); + spin_lock(&efi_runtime_lock); status = efi_call_virt(query_variable_info, attr, storage_space, remaining_space, max_variable_size); - spin_unlock_irqrestore(&efi_runtime_lock, flags); + spin_unlock(&efi_runtime_lock); + return status; +} + +static efi_status_t +virt_efi_query_variable_info_nonblocking(u32 attr, + u64 *storage_space, + u64 *remaining_space, + u64 *max_variable_size) +{ + efi_status_t status; + + if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION) + return EFI_UNSUPPORTED; + + if (!spin_trylock(&efi_runtime_lock)) + return EFI_NOT_READY; + + status = efi_call_virt(query_variable_info, attr, storage_space, + remaining_space, max_variable_size); + spin_unlock(&efi_runtime_lock); return status; } static efi_status_t virt_efi_get_next_high_mono_count(u32 *count) { - unsigned long flags; efi_status_t status; - spin_lock_irqsave(&efi_runtime_lock, flags); + spin_lock(&efi_runtime_lock); status = efi_call_virt(get_next_high_mono_count, count); - spin_unlock_irqrestore(&efi_runtime_lock, flags); + spin_unlock(&efi_runtime_lock); return status; } @@ -246,26 +214,23 @@ static void virt_efi_reset_system(int reset_type, unsigned long data_size, efi_char16_t *data) { - unsigned long flags; - - spin_lock_irqsave(&efi_runtime_lock, flags); + spin_lock(&efi_runtime_lock); __efi_call_virt(reset_system, reset_type, status, data_size, data); - spin_unlock_irqrestore(&efi_runtime_lock, flags); + spin_unlock(&efi_runtime_lock); } static efi_status_t virt_efi_update_capsule(efi_capsule_header_t **capsules, unsigned long count, unsigned long sg_list) { - unsigned long flags; efi_status_t status; if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION) return EFI_UNSUPPORTED; - spin_lock_irqsave(&efi_runtime_lock, flags); + spin_lock(&efi_runtime_lock); status = efi_call_virt(update_capsule, capsules, count, sg_list); - spin_unlock_irqrestore(&efi_runtime_lock, flags); + spin_unlock(&efi_runtime_lock); return status; } @@ -274,16 +239,15 @@ static efi_status_t virt_efi_query_capsule_caps(efi_capsule_header_t **capsules, u64 *max_size, int *reset_type) { - unsigned long flags; efi_status_t status; if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION) return EFI_UNSUPPORTED; - spin_lock_irqsave(&efi_runtime_lock, flags); + spin_lock(&efi_runtime_lock); status = efi_call_virt(query_capsule_caps, capsules, count, max_size, reset_type); - spin_unlock_irqrestore(&efi_runtime_lock, flags); + spin_unlock(&efi_runtime_lock); return status; } @@ -300,6 +264,7 @@ void efi_native_runtime_setup(void) efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count; efi.reset_system = virt_efi_reset_system; efi.query_variable_info = virt_efi_query_variable_info; + efi.query_variable_info_nonblocking = virt_efi_query_variable_info_nonblocking; efi.update_capsule = virt_efi_update_capsule; efi.query_capsule_caps = virt_efi_query_capsule_caps; } diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c index 7f2ea21c730dd76a86f3ab5a1e253878878960a7..0ac594c0a234c81e025a0ee980c92a8596a2c017 100644 --- a/drivers/firmware/efi/vars.c +++ b/drivers/firmware/efi/vars.c @@ -300,7 +300,18 @@ check_var_size(u32 attributes, unsigned long size) if (!fops->query_variable_store) return EFI_UNSUPPORTED; - return fops->query_variable_store(attributes, size); + return fops->query_variable_store(attributes, size, false); +} + +static efi_status_t +check_var_size_nonblocking(u32 attributes, unsigned long size) +{ + const struct efivar_operations *fops = __efivars->ops; + + if (!fops->query_variable_store) + return EFI_UNSUPPORTED; + + return fops->query_variable_store(attributes, size, true); } static int efi_status_to_err(efi_status_t status) @@ -681,7 +692,8 @@ efivar_entry_set_nonblocking(efi_char16_t *name, efi_guid_t vendor, if (!spin_trylock_irqsave(&__efivars->lock, flags)) return -EBUSY; - status = check_var_size(attributes, size + ucs2_strsize(name, 1024)); + status = check_var_size_nonblocking(attributes, + size + ucs2_strsize(name, 1024)); if (status != EFI_SUCCESS) { spin_unlock_irqrestore(&__efivars->lock, flags); return -ENOSPC; diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c index f25cd79c8a79f834f8d3e169684d20ee4ced08e6..11bfee8b79a9f65418bcbe53dfc708edb220e69d 100644 --- a/drivers/firmware/psci.c +++ b/drivers/firmware/psci.c @@ -14,6 +14,7 @@ #define pr_fmt(fmt) "psci: " fmt #include +#include #include #include #include @@ -21,10 +22,12 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -244,6 +247,123 @@ static int __init psci_features(u32 psci_func_id) psci_func_id, 0, 0); } +#ifdef CONFIG_CPU_IDLE +static DEFINE_PER_CPU_READ_MOSTLY(u32 *, psci_power_state); + +static int psci_dt_cpu_init_idle(struct device_node *cpu_node, int cpu) +{ + int i, ret, count = 0; + u32 *psci_states; + struct device_node *state_node; + + /* + * If the PSCI cpu_suspend function hook has not been initialized + * idle states must not be enabled, so bail out + */ + if (!psci_ops.cpu_suspend) + return -EOPNOTSUPP; + + /* Count idle states */ + while ((state_node = of_parse_phandle(cpu_node, "cpu-idle-states", + count))) { + count++; + of_node_put(state_node); + } + + if (!count) + return -ENODEV; + + psci_states = kcalloc(count, sizeof(*psci_states), GFP_KERNEL); + if (!psci_states) + return -ENOMEM; + + for (i = 0; i < count; i++) { + u32 state; + + state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i); + + ret = of_property_read_u32(state_node, + "arm,psci-suspend-param", + &state); + if (ret) { + pr_warn(" * %s missing arm,psci-suspend-param property\n", + state_node->full_name); + of_node_put(state_node); + goto free_mem; + } + + of_node_put(state_node); + pr_debug("psci-power-state %#x index %d\n", state, i); + if (!psci_power_state_is_valid(state)) { + pr_warn("Invalid PSCI power state %#x\n", state); + ret = -EINVAL; + goto free_mem; + } + psci_states[i] = state; + } + /* Idle states parsed correctly, initialize per-cpu pointer */ + per_cpu(psci_power_state, cpu) = psci_states; + return 0; + +free_mem: + kfree(psci_states); + return ret; +} + +int psci_cpu_init_idle(unsigned int cpu) +{ + struct device_node *cpu_node; + int ret; + + cpu_node = of_get_cpu_node(cpu, NULL); + if (!cpu_node) + return -ENODEV; + + ret = psci_dt_cpu_init_idle(cpu_node, cpu); + + of_node_put(cpu_node); + + return ret; +} + +static int psci_suspend_finisher(unsigned long index) +{ + u32 *state = __this_cpu_read(psci_power_state); + + return psci_ops.cpu_suspend(state[index - 1], + virt_to_phys(cpu_resume)); +} + +int psci_cpu_suspend_enter(unsigned long index) +{ + int ret; + u32 *state = __this_cpu_read(psci_power_state); + /* + * idle state index 0 corresponds to wfi, should never be called + * from the cpu_suspend operations + */ + if (WARN_ON_ONCE(!index)) + return -EINVAL; + + if (!psci_power_state_loses_context(state[index - 1])) + ret = psci_ops.cpu_suspend(state[index - 1], 0); + else + ret = cpu_suspend(index, psci_suspend_finisher); + + return ret; +} + +/* ARM specific CPU idle operations */ +#ifdef CONFIG_ARM +static struct cpuidle_ops psci_cpuidle_ops __initdata = { + .suspend = psci_cpu_suspend_enter, + .init = psci_dt_cpu_init_idle, +}; + +CPUIDLE_METHOD_OF_DECLARE(psci, "arm,psci", &psci_cpuidle_ops); +#endif +#endif + static int psci_system_suspend(unsigned long unused) { return invoke_psci_fn(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND), diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c index fedbff55a7f3848872b7d0196086bc0f56caa0c7..815c4a5cae543e228a634eae28241bc6f24ac1ed 100644 --- a/drivers/firmware/qemu_fw_cfg.c +++ b/drivers/firmware/qemu_fw_cfg.c @@ -77,12 +77,28 @@ static inline u16 fw_cfg_sel_endianness(u16 key) static inline void fw_cfg_read_blob(u16 key, void *buf, loff_t pos, size_t count) { + u32 glk; + acpi_status status; + + /* If we have ACPI, ensure mutual exclusion against any potential + * device access by the firmware, e.g. via AML methods: + */ + status = acpi_acquire_global_lock(ACPI_WAIT_FOREVER, &glk); + if (ACPI_FAILURE(status) && status != AE_NOT_CONFIGURED) { + /* Should never get here */ + WARN(1, "fw_cfg_read_blob: Failed to lock ACPI!\n"); + memset(buf, 0, count); + return; + } + mutex_lock(&fw_cfg_dev_lock); iowrite16(fw_cfg_sel_endianness(key), fw_cfg_reg_ctrl); while (pos-- > 0) ioread8(fw_cfg_reg_data); ioread8_rep(fw_cfg_reg_data, buf, count); mutex_unlock(&fw_cfg_dev_lock); + + acpi_release_global_lock(glk); } /* clean up fw_cfg device i/o */ @@ -727,12 +743,18 @@ device_param_cb(mmio, &fw_cfg_cmdline_param_ops, NULL, S_IRUSR); static int __init fw_cfg_sysfs_init(void) { + int ret; + /* create /sys/firmware/qemu_fw_cfg/ top level directory */ fw_cfg_top_ko = kobject_create_and_add("qemu_fw_cfg", firmware_kobj); if (!fw_cfg_top_ko) return -ENOMEM; - return platform_driver_register(&fw_cfg_sysfs_driver); + ret = platform_driver_register(&fw_cfg_sysfs_driver); + if (ret) + fw_cfg_kobj_cleanup(fw_cfg_top_ko); + + return ret; } static void __exit fw_cfg_sysfs_exit(void) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 4808e4657de56821ed37ea84d257aef08772d475..5f3429f0bf46970fcf376c79dca6633cd7469d5a 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -898,6 +898,12 @@ config GPIO_TIMBERDALE ---help--- Add support for the GPIO IP in the timberdale FPGA. +config GPIO_TPS65086 + tristate "TI TPS65086 GPO" + depends on MFD_TPS65086 + help + This driver supports the GPO on TI TPS65086x PMICs. + config GPIO_TPS65218 tristate "TPS65218 GPIO" depends on MFD_TPS65218 diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 25decedba94334e7f0f6136bd790918e238ea437..1e0b74f3b1ed98021f3d05b067b749b7cb1c652d 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -99,6 +99,7 @@ obj-$(CONFIG_ARCH_TEGRA) += gpio-tegra.o obj-$(CONFIG_GPIO_TIMBERDALE) += gpio-timberdale.o obj-$(CONFIG_GPIO_PALMAS) += gpio-palmas.o obj-$(CONFIG_GPIO_TPIC2810) += gpio-tpic2810.o +obj-$(CONFIG_GPIO_TPS65086) += gpio-tps65086.o obj-$(CONFIG_GPIO_TPS65218) += gpio-tps65218.o obj-$(CONFIG_GPIO_TPS6586X) += gpio-tps6586x.o obj-$(CONFIG_GPIO_TPS65910) += gpio-tps65910.o diff --git a/drivers/gpio/gpio-menz127.c b/drivers/gpio/gpio-menz127.c index a68e199d579d58c099203886eaabd3479c0e35cf..c5c9599a3a71b3182d2e269fa01173b6cdf570cc 100644 --- a/drivers/gpio/gpio-menz127.c +++ b/drivers/gpio/gpio-menz127.c @@ -37,7 +37,6 @@ struct men_z127_gpio { void __iomem *reg_base; struct mcb_device *mdev; struct resource *mem; - spinlock_t lock; }; static int men_z127_debounce(struct gpio_chip *gc, unsigned gpio, @@ -69,7 +68,7 @@ static int men_z127_debounce(struct gpio_chip *gc, unsigned gpio, debounce /= 50; } - spin_lock(&priv->lock); + spin_lock(&gc->bgpio_lock); db_en = readl(priv->reg_base + MEN_Z127_DBER); @@ -84,7 +83,7 @@ static int men_z127_debounce(struct gpio_chip *gc, unsigned gpio, writel(db_en, priv->reg_base + MEN_Z127_DBER); writel(db_cnt, priv->reg_base + GPIO_TO_DBCNT_REG(gpio)); - spin_unlock(&priv->lock); + spin_unlock(&gc->bgpio_lock); return 0; } @@ -97,7 +96,7 @@ static int men_z127_request(struct gpio_chip *gc, unsigned gpio_pin) if (gpio_pin >= gc->ngpio) return -EINVAL; - spin_lock(&priv->lock); + spin_lock(&gc->bgpio_lock); od_en = readl(priv->reg_base + MEN_Z127_ODER); if (gpiochip_line_is_open_drain(gc, gpio_pin)) @@ -106,7 +105,7 @@ static int men_z127_request(struct gpio_chip *gc, unsigned gpio_pin) od_en &= ~BIT(gpio_pin); writel(od_en, priv->reg_base + MEN_Z127_ODER); - spin_unlock(&priv->lock); + spin_unlock(&gc->bgpio_lock); return 0; } diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index d0d3065a755767dcfeec9108921ac431fc490235..e66084c295fbff18a115927ecc28822aae6b3e63 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -159,7 +160,7 @@ static int pca953x_write_regs(struct pca953x_chip *chip, int reg, u8 *val) switch (chip->chip_type) { case PCA953X_TYPE: ret = i2c_smbus_write_word_data(chip->client, - reg << 1, (u16) *val); + reg << 1, cpu_to_le16(get_unaligned((u16 *)val))); break; case PCA957X_TYPE: ret = i2c_smbus_write_byte_data(chip->client, reg << 1, diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index b2b7b78664b8058d9be9314e2298765fe772c0e9..76ac906b4d78d262ab5473771e377c9c244b76b3 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c @@ -283,8 +283,8 @@ static int pxa_gpio_direction_output(struct gpio_chip *chip, writel_relaxed(mask, base + (value ? GPSR_OFFSET : GPCR_OFFSET)); ret = pinctrl_gpio_direction_output(chip->base + offset); - if (!ret) - return 0; + if (ret) + return ret; spin_lock_irqsave(&gpio_lock, flags); diff --git a/drivers/gpio/gpio-tps65086.c b/drivers/gpio/gpio-tps65086.c new file mode 100644 index 0000000000000000000000000000000000000000..8e25f01ac314c3e0a7970e62f0881b8851fccb5e --- /dev/null +++ b/drivers/gpio/gpio-tps65086.c @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ + * Andrew F. Davis + * + * 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 "as is" WITHOUT ANY WARRANTY of any + * kind, whether expressed or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License version 2 for more details. + * + * Based on the TPS65912 driver + */ + +#include +#include +#include + +#include + +struct tps65086_gpio { + struct gpio_chip chip; + struct tps65086 *tps; +}; + +static int tps65086_gpio_get_direction(struct gpio_chip *chip, + unsigned offset) +{ + /* This device is output only */ + return 0; +} + +static int tps65086_gpio_direction_input(struct gpio_chip *chip, + unsigned offset) +{ + /* This device is output only */ + return -EINVAL; +} + +static int tps65086_gpio_direction_output(struct gpio_chip *chip, + unsigned offset, int value) +{ + struct tps65086_gpio *gpio = gpiochip_get_data(chip); + + /* Set the initial value */ + regmap_update_bits(gpio->tps->regmap, TPS65086_GPOCTRL, + BIT(4 + offset), value ? BIT(4 + offset) : 0); + + return 0; +} + +static int tps65086_gpio_get(struct gpio_chip *chip, unsigned offset) +{ + struct tps65086_gpio *gpio = gpiochip_get_data(chip); + int ret, val; + + ret = regmap_read(gpio->tps->regmap, TPS65086_GPOCTRL, &val); + if (ret < 0) + return ret; + + return val & BIT(4 + offset); +} + +static void tps65086_gpio_set(struct gpio_chip *chip, unsigned offset, + int value) +{ + struct tps65086_gpio *gpio = gpiochip_get_data(chip); + + regmap_update_bits(gpio->tps->regmap, TPS65086_GPOCTRL, + BIT(4 + offset), value ? BIT(4 + offset) : 0); +} + +static struct gpio_chip template_chip = { + .label = "tps65086-gpio", + .owner = THIS_MODULE, + .get_direction = tps65086_gpio_get_direction, + .direction_input = tps65086_gpio_direction_input, + .direction_output = tps65086_gpio_direction_output, + .get = tps65086_gpio_get, + .set = tps65086_gpio_set, + .base = -1, + .ngpio = 4, + .can_sleep = true, +}; + +static int tps65086_gpio_probe(struct platform_device *pdev) +{ + struct tps65086_gpio *gpio; + int ret; + + gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); + if (!gpio) + return -ENOMEM; + + platform_set_drvdata(pdev, gpio); + + gpio->tps = dev_get_drvdata(pdev->dev.parent); + gpio->chip = template_chip; + gpio->chip.parent = gpio->tps->dev; + + ret = gpiochip_add_data(&gpio->chip, gpio); + if (ret < 0) { + dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); + return ret; + } + + return 0; +} + +static int tps65086_gpio_remove(struct platform_device *pdev) +{ + struct tps65086_gpio *gpio = platform_get_drvdata(pdev); + + gpiochip_remove(&gpio->chip); + + return 0; +} + +static const struct platform_device_id tps65086_gpio_id_table[] = { + { "tps65086-gpio", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(platform, tps65086_gpio_id_table); + +static struct platform_driver tps65086_gpio_driver = { + .driver = { + .name = "tps65086-gpio", + }, + .probe = tps65086_gpio_probe, + .remove = tps65086_gpio_remove, + .id_table = tps65086_gpio_id_table, +}; +module_platform_driver(tps65086_gpio_driver); + +MODULE_AUTHOR("Andrew F. Davis "); +MODULE_DESCRIPTION("TPS65086 GPIO driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/gpio/gpio-xgene.c b/drivers/gpio/gpio-xgene.c index c0aa387664bf50bda637a928574c0667f5b76a43..0dc916191689e9f72e4e737157ca1ad4aae7ef5c 100644 --- a/drivers/gpio/gpio-xgene.c +++ b/drivers/gpio/gpio-xgene.c @@ -173,6 +173,11 @@ static int xgene_gpio_probe(struct platform_device *pdev) } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + err = -EINVAL; + goto err; + } + gpio->base = devm_ioremap_nocache(&pdev->dev, res->start, resource_size(res)); if (!gpio->base) { diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 72065532c1c7bfda9796c55e2d350d2a1da00349..b747c76fd2b1f4f8f1e117b6ce2836525b1166fd 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -68,6 +68,7 @@ LIST_HEAD(gpio_devices); static void gpiochip_free_hogs(struct gpio_chip *chip); static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip); +static bool gpiolib_initialized; static inline void desc_set_label(struct gpio_desc *d, const char *label) { @@ -440,9 +441,63 @@ static void gpiodevice_release(struct device *dev) cdev_del(&gdev->chrdev); list_del(&gdev->list); ida_simple_remove(&gpio_ida, gdev->id); + kfree(gdev->label); + kfree(gdev->descs); kfree(gdev); } +static int gpiochip_setup_dev(struct gpio_device *gdev) +{ + int status; + + cdev_init(&gdev->chrdev, &gpio_fileops); + gdev->chrdev.owner = THIS_MODULE; + gdev->chrdev.kobj.parent = &gdev->dev.kobj; + gdev->dev.devt = MKDEV(MAJOR(gpio_devt), gdev->id); + status = cdev_add(&gdev->chrdev, gdev->dev.devt, 1); + if (status < 0) + chip_warn(gdev->chip, "failed to add char device %d:%d\n", + MAJOR(gpio_devt), gdev->id); + else + chip_dbg(gdev->chip, "added GPIO chardev (%d:%d)\n", + MAJOR(gpio_devt), gdev->id); + status = device_add(&gdev->dev); + if (status) + goto err_remove_chardev; + + status = gpiochip_sysfs_register(gdev); + if (status) + goto err_remove_device; + + /* From this point, the .release() function cleans up gpio_device */ + gdev->dev.release = gpiodevice_release; + get_device(&gdev->dev); + pr_debug("%s: registered GPIOs %d to %d on device: %s (%s)\n", + __func__, gdev->base, gdev->base + gdev->ngpio - 1, + dev_name(&gdev->dev), gdev->chip->label ? : "generic"); + + return 0; + +err_remove_device: + device_del(&gdev->dev); +err_remove_chardev: + cdev_del(&gdev->chrdev); + return status; +} + +static void gpiochip_setup_devs(void) +{ + struct gpio_device *gdev; + int err; + + list_for_each_entry(gdev, &gpio_devices, list) { + err = gpiochip_setup_dev(gdev); + if (err) + pr_err("%s: Failed to initialize gpio device (%d)\n", + dev_name(&gdev->dev), err); + } +} + /** * gpiochip_add_data() - register a gpio_chip * @chip: the chip to register, with chip->base initialized @@ -457,6 +512,9 @@ static void gpiodevice_release(struct device *dev) * the gpio framework's arch_initcall(). Otherwise sysfs initialization * for GPIOs will fail rudely. * + * gpiochip_add_data() must only be called after gpiolib initialization, + * ie after core_initcall(). + * * If chip->base is negative, this requests dynamic assignment of * a range of valid GPIOs. */ @@ -504,8 +562,7 @@ int gpiochip_add_data(struct gpio_chip *chip, void *data) else gdev->owner = THIS_MODULE; - gdev->descs = devm_kcalloc(&gdev->dev, chip->ngpio, - sizeof(gdev->descs[0]), GFP_KERNEL); + gdev->descs = kcalloc(chip->ngpio, sizeof(gdev->descs[0]), GFP_KERNEL); if (!gdev->descs) { status = -ENOMEM; goto err_free_gdev; @@ -514,16 +571,16 @@ int gpiochip_add_data(struct gpio_chip *chip, void *data) if (chip->ngpio == 0) { chip_err(chip, "tried to insert a GPIO chip with zero lines\n"); status = -EINVAL; - goto err_free_gdev; + goto err_free_descs; } if (chip->label) - gdev->label = devm_kstrdup(&gdev->dev, chip->label, GFP_KERNEL); + gdev->label = kstrdup(chip->label, GFP_KERNEL); else - gdev->label = devm_kstrdup(&gdev->dev, "unknown", GFP_KERNEL); + gdev->label = kstrdup("unknown", GFP_KERNEL); if (!gdev->label) { status = -ENOMEM; - goto err_free_gdev; + goto err_free_descs; } gdev->ngpio = chip->ngpio; @@ -543,7 +600,7 @@ int gpiochip_add_data(struct gpio_chip *chip, void *data) if (base < 0) { status = base; spin_unlock_irqrestore(&gpio_lock, flags); - goto err_free_gdev; + goto err_free_label; } /* * TODO: it should not be necessary to reflect the assigned @@ -558,7 +615,7 @@ int gpiochip_add_data(struct gpio_chip *chip, void *data) status = gpiodev_add_to_list(gdev); if (status) { spin_unlock_irqrestore(&gpio_lock, flags); - goto err_free_gdev; + goto err_free_label; } for (i = 0; i < chip->ngpio; i++) { @@ -596,39 +653,16 @@ int gpiochip_add_data(struct gpio_chip *chip, void *data) * we get a device node entry in sysfs under * /sys/bus/gpio/devices/gpiochipN/dev that can be used for * coldplug of device nodes and other udev business. + * We can do this only if gpiolib has been initialized. + * Otherwise, defer until later. */ - cdev_init(&gdev->chrdev, &gpio_fileops); - gdev->chrdev.owner = THIS_MODULE; - gdev->chrdev.kobj.parent = &gdev->dev.kobj; - gdev->dev.devt = MKDEV(MAJOR(gpio_devt), gdev->id); - status = cdev_add(&gdev->chrdev, gdev->dev.devt, 1); - if (status < 0) - chip_warn(chip, "failed to add char device %d:%d\n", - MAJOR(gpio_devt), gdev->id); - else - chip_dbg(chip, "added GPIO chardev (%d:%d)\n", - MAJOR(gpio_devt), gdev->id); - status = device_add(&gdev->dev); - if (status) - goto err_remove_chardev; - - status = gpiochip_sysfs_register(gdev); - if (status) - goto err_remove_device; - - /* From this point, the .release() function cleans up gpio_device */ - gdev->dev.release = gpiodevice_release; - get_device(&gdev->dev); - pr_debug("%s: registered GPIOs %d to %d on device: %s (%s)\n", - __func__, gdev->base, gdev->base + gdev->ngpio - 1, - dev_name(&gdev->dev), chip->label ? : "generic"); - + if (gpiolib_initialized) { + status = gpiochip_setup_dev(gdev); + if (status) + goto err_remove_chip; + } return 0; -err_remove_device: - device_del(&gdev->dev); -err_remove_chardev: - cdev_del(&gdev->chrdev); err_remove_chip: acpi_gpiochip_remove(chip); gpiochip_free_hogs(chip); @@ -637,6 +671,10 @@ int gpiochip_add_data(struct gpio_chip *chip, void *data) spin_lock_irqsave(&gpio_lock, flags); list_del(&gdev->list); spin_unlock_irqrestore(&gpio_lock, flags); +err_free_label: + kfree(gdev->label); +err_free_descs: + kfree(gdev->descs); err_free_gdev: ida_simple_remove(&gpio_ida, gdev->id); /* failures here can mean systems won't boot... */ @@ -2231,9 +2269,11 @@ static struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id, return desc; } -static struct gpio_desc *acpi_find_gpio(struct device *dev, const char *con_id, +static struct gpio_desc *acpi_find_gpio(struct device *dev, + const char *con_id, unsigned int idx, - enum gpio_lookup_flags *flags) + enum gpiod_flags flags, + enum gpio_lookup_flags *lookupflags) { struct acpi_device *adev = ACPI_COMPANION(dev); struct acpi_gpio_info info; @@ -2264,10 +2304,16 @@ static struct gpio_desc *acpi_find_gpio(struct device *dev, const char *con_id, desc = acpi_get_gpiod_by_index(adev, NULL, idx, &info); if (IS_ERR(desc)) return desc; + + if ((flags == GPIOD_OUT_LOW || flags == GPIOD_OUT_HIGH) && + info.gpioint) { + dev_dbg(dev, "refusing GpioInt() entry when doing GPIOD_OUT_* lookup\n"); + return ERR_PTR(-ENOENT); + } } if (info.polarity == GPIO_ACTIVE_LOW) - *flags |= GPIO_ACTIVE_LOW; + *lookupflags |= GPIO_ACTIVE_LOW; return desc; } @@ -2530,7 +2576,7 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev, desc = of_find_gpio(dev, con_id, idx, &lookupflags); } else if (ACPI_COMPANION(dev)) { dev_dbg(dev, "using ACPI for GPIO lookup\n"); - desc = acpi_find_gpio(dev, con_id, idx, &lookupflags); + desc = acpi_find_gpio(dev, con_id, idx, flags, &lookupflags); } } @@ -2829,6 +2875,9 @@ static int __init gpiolib_dev_init(void) if (ret < 0) { pr_err("gpiolib: failed to allocate char dev region\n"); bus_unregister(&gpio_bus_type); + } else { + gpiolib_initialized = true; + gpiochip_setup_devs(); } return ret; } diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 8ae7ab68cb9781fd04f176136564aa841e16fd20..f2a74d0b68ae679a38c5cf8fb254c13ec20fde2c 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -25,6 +25,14 @@ config DRM_MIPI_DSI bool depends on DRM +config DRM_DP_AUX_CHARDEV + bool "DRM DP AUX Interface" + depends on DRM + help + Choose this option to enable a /dev/drm_dp_auxN node that allows to + read and write values to arbitrary DPCD registers on the DP aux + channel. + config DRM_KMS_HELPER tristate depends on DRM @@ -106,6 +114,8 @@ config DRM_TDFX Choose this option if you have a 3dfx Banshee or Voodoo3 (or later), graphics card. If M is selected, the module will be called tdfx. +source "drivers/gpu/drm/arm/Kconfig" + config DRM_R128 tristate "ATI Rage 128" depends on DRM && PCI @@ -162,6 +172,8 @@ config DRM_AMDGPU source "drivers/gpu/drm/amd/amdgpu/Kconfig" source "drivers/gpu/drm/amd/powerplay/Kconfig" +source "drivers/gpu/drm/amd/acp/Kconfig" + source "drivers/gpu/drm/nouveau/Kconfig" config DRM_I810 diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 61766dec6a8d3d7a4e9282b740161145818a51bc..6eb94fc561dc29ba187baefb8a1368db2b550dbb 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -22,10 +22,13 @@ drm-$(CONFIG_OF) += drm_of.o drm-$(CONFIG_AGP) += drm_agpsupport.o drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \ - drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o + drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \ + drm_kms_helper_common.o + drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o +drm_kms_helper-$(CONFIG_DRM_DP_AUX_CHARDEV) += drm_dp_aux_dev.o obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o @@ -33,6 +36,7 @@ CFLAGS_drm_trace_points.o := -I$(src) obj-$(CONFIG_DRM) += drm.o obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o +obj-$(CONFIG_DRM_ARM) += arm/ obj-$(CONFIG_DRM_TTM) += ttm/ obj-$(CONFIG_DRM_TDFX) += tdfx/ obj-$(CONFIG_DRM_R128) += r128/ diff --git a/drivers/gpu/drm/amd/acp/Kconfig b/drivers/gpu/drm/amd/acp/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..ca77ec10147c4b30c47bb41c5444becfc796b117 --- /dev/null +++ b/drivers/gpu/drm/amd/acp/Kconfig @@ -0,0 +1,14 @@ +menu "ACP (Audio CoProcessor) Configuration" + +config DRM_AMD_ACP + bool "Enable AMD Audio CoProcessor IP support" + select MFD_CORE + select PM_GENERIC_DOMAINS if PM + help + Choose this option to enable ACP IP support for AMD SOCs. + This adds the ACP (Audio CoProcessor) IP driver and wires + it up into the amdgpu driver. The ACP block provides the DMA + engine for the i2s-based ALSA driver. It is required for audio + on APUs which utilize an i2s codec. + +endmenu diff --git a/drivers/gpu/drm/amd/acp/Makefile b/drivers/gpu/drm/amd/acp/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..8363cb57915b0b726c704b8be37805ecef2a18ee --- /dev/null +++ b/drivers/gpu/drm/amd/acp/Makefile @@ -0,0 +1,8 @@ +# +# Makefile for the ACP, which is a sub-component +# of AMDSOC/AMDGPU drm driver. +# It provides the HW control for ACP related functionalities. + +subdir-ccflags-y += -I$(AMDACPPATH)/ -I$(AMDACPPATH)/include + +AMD_ACP_FILES := $(AMDACPPATH)/acp_hw.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm206.c b/drivers/gpu/drm/amd/acp/acp_hw.c similarity index 64% rename from drivers/gpu/drm/nouveau/nvkm/engine/gr/gm206.c rename to drivers/gpu/drm/amd/acp/acp_hw.c index 341dc560acbbf12da7d83828e2e94919298d8fec..7af83f142b4b8798bf86bd632a8ea0c5f3626423 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm206.c +++ b/drivers/gpu/drm/amd/acp/acp_hw.c @@ -1,5 +1,5 @@ /* - * Copyright 2015 Red Hat Inc. + * Copyright 2015 Advanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -19,30 +19,32 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * - * Authors: Ben Skeggs */ -#include "gf100.h" -#include "ctxgf100.h" - -#include - -static const struct gf100_gr_func -gm206_gr = { - .init = gm204_gr_init, - .mmio = gm204_gr_pack_mmio, - .ppc_nr = 2, - .grctx = &gm206_grctx, - .sclass = { - { -1, -1, FERMI_TWOD_A }, - { -1, -1, KEPLER_INLINE_TO_MEMORY_B }, - { -1, -1, MAXWELL_B, &gf100_fermi }, - { -1, -1, MAXWELL_COMPUTE_B }, - {} - } -}; - -int -gm206_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr) + +#include +#include +#include +#include +#include + +#include "acp_gfx_if.h" + +#define ACP_MODE_I2S 0 +#define ACP_MODE_AZ 1 + +#define mmACP_AZALIA_I2S_SELECT 0x51d4 + +int amd_acp_hw_init(void *cgs_device, + unsigned acp_version_major, unsigned acp_version_minor) { - return gf100_gr_new_(&gm206_gr, device, index, pgr); + unsigned int acp_mode = ACP_MODE_I2S; + + if ((acp_version_major == 2) && (acp_version_minor == 2)) + acp_mode = cgs_read_register(cgs_device, + mmACP_AZALIA_I2S_SELECT); + + if (acp_mode != ACP_MODE_I2S) + return -ENODEV; + + return 0; } diff --git a/drivers/gpu/drm/amd/acp/include/acp_gfx_if.h b/drivers/gpu/drm/amd/acp/include/acp_gfx_if.h new file mode 100644 index 0000000000000000000000000000000000000000..bccf47b63899130ca4c10fc1e7d51820d1edeb06 --- /dev/null +++ b/drivers/gpu/drm/amd/acp/include/acp_gfx_if.h @@ -0,0 +1,34 @@ +/* + * Copyright 2015 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * +*/ + +#ifndef _ACP_GFX_IF_H +#define _ACP_GFX_IF_H + +#include +#include "cgs_linux.h" +#include "cgs_common.h" + +int amd_acp_hw_init(void *cgs_device, + unsigned acp_version_major, unsigned acp_version_minor); + +#endif /* _ACP_GFX_IF_H */ diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile index 20c9539abc36e887dea47d00982e308be412d93e..c7fcdcedaadbf5b98a333ad6e87796bccb653812 100644 --- a/drivers/gpu/drm/amd/amdgpu/Makefile +++ b/drivers/gpu/drm/amd/amdgpu/Makefile @@ -8,7 +8,8 @@ ccflags-y := -Iinclude/drm -I$(FULL_AMD_PATH)/include/asic_reg \ -I$(FULL_AMD_PATH)/include \ -I$(FULL_AMD_PATH)/amdgpu \ -I$(FULL_AMD_PATH)/scheduler \ - -I$(FULL_AMD_PATH)/powerplay/inc + -I$(FULL_AMD_PATH)/powerplay/inc \ + -I$(FULL_AMD_PATH)/acp/include amdgpu-y := amdgpu_drv.o @@ -20,7 +21,7 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \ amdgpu_fb.o amdgpu_gem.o amdgpu_ring.o \ amdgpu_cs.o amdgpu_bios.o amdgpu_benchmark.o amdgpu_test.o \ amdgpu_pm.o atombios_dp.o amdgpu_afmt.o amdgpu_trace_points.o \ - atombios_encoders.o amdgpu_semaphore.o amdgpu_sa.o atombios_i2c.o \ + atombios_encoders.o amdgpu_sa.o atombios_i2c.o \ amdgpu_prime.o amdgpu_vm.o amdgpu_ib.o amdgpu_pll.o \ amdgpu_ucode.o amdgpu_bo_list.o amdgpu_ctx.o amdgpu_sync.o @@ -92,7 +93,17 @@ amdgpu-y += amdgpu_cgs.o amdgpu-y += \ ../scheduler/gpu_scheduler.o \ ../scheduler/sched_fence.o \ - amdgpu_sched.o + amdgpu_job.o + +# ACP componet +ifneq ($(CONFIG_DRM_AMD_ACP),) +amdgpu-y += amdgpu_acp.o + +AMDACPPATH := ../acp +include $(FULL_AMD_PATH)/acp/Makefile + +amdgpu-y += $(AMD_ACP_FILES) +endif amdgpu-$(CONFIG_COMPAT) += amdgpu_ioc32.o amdgpu-$(CONFIG_VGA_SWITCHEROO) += amdgpu_atpx_handler.o diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 5e7770f9a415be24140df77708e9d9d39dee7faa..62a778012fe06cc572964b463f873c987ca34755 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -53,6 +53,7 @@ #include "amdgpu_ucode.h" #include "amdgpu_gds.h" #include "amd_powerplay.h" +#include "amdgpu_acp.h" #include "gpu_scheduler.h" @@ -74,7 +75,6 @@ extern int amdgpu_dpm; extern int amdgpu_smc_load_fw; extern int amdgpu_aspm; extern int amdgpu_runtime_pm; -extern int amdgpu_hard_reset; extern unsigned amdgpu_ip_block_mask; extern int amdgpu_bapm; extern int amdgpu_deep_color; @@ -82,10 +82,8 @@ extern int amdgpu_vm_size; extern int amdgpu_vm_block_size; extern int amdgpu_vm_fault_stop; extern int amdgpu_vm_debug; -extern int amdgpu_enable_scheduler; extern int amdgpu_sched_jobs; extern int amdgpu_sched_hw_submission; -extern int amdgpu_enable_semaphores; extern int amdgpu_powerplay; extern unsigned amdgpu_pcie_gen_cap; extern unsigned amdgpu_pcie_lane_cap; @@ -108,9 +106,6 @@ extern unsigned amdgpu_pcie_lane_cap; /* max number of IP instances */ #define AMDGPU_MAX_SDMA_INSTANCES 2 -/* number of hw syncs before falling back on blocking */ -#define AMDGPU_NUM_SYNCS 4 - /* hardcode that limit for now */ #define AMDGPU_VA_RESERVED_SIZE (8 << 20) @@ -146,11 +141,9 @@ extern unsigned amdgpu_pcie_lane_cap; #define CIK_CURSOR_HEIGHT 128 struct amdgpu_device; -struct amdgpu_fence; struct amdgpu_ib; struct amdgpu_vm; struct amdgpu_ring; -struct amdgpu_semaphore; struct amdgpu_cs_parser; struct amdgpu_job; struct amdgpu_irq_src; @@ -248,7 +241,7 @@ struct amdgpu_vm_pte_funcs { unsigned count); /* write pte one entry at a time with addr mapping */ void (*write_pte)(struct amdgpu_ib *ib, - uint64_t pe, + const dma_addr_t *pages_addr, uint64_t pe, uint64_t addr, unsigned count, uint32_t incr, uint32_t flags); /* for linear pte/pde updates without addr mapping */ @@ -256,8 +249,6 @@ struct amdgpu_vm_pte_funcs { uint64_t pe, uint64_t addr, unsigned count, uint32_t incr, uint32_t flags); - /* pad the indirect buffer to the necessary number of dw */ - void (*pad_ib)(struct amdgpu_ib *ib); }; /* provided by the gmc block */ @@ -295,12 +286,11 @@ struct amdgpu_ring_funcs { struct amdgpu_ib *ib); void (*emit_fence)(struct amdgpu_ring *ring, uint64_t addr, uint64_t seq, unsigned flags); - bool (*emit_semaphore)(struct amdgpu_ring *ring, - struct amdgpu_semaphore *semaphore, - bool emit_wait); + void (*emit_pipeline_sync)(struct amdgpu_ring *ring); void (*emit_vm_flush)(struct amdgpu_ring *ring, unsigned vm_id, uint64_t pd_addr); void (*emit_hdp_flush)(struct amdgpu_ring *ring); + void (*emit_hdp_invalidate)(struct amdgpu_ring *ring); void (*emit_gds_switch)(struct amdgpu_ring *ring, uint32_t vmid, uint32_t gds_base, uint32_t gds_size, uint32_t gws_base, uint32_t gws_size, @@ -310,6 +300,8 @@ struct amdgpu_ring_funcs { int (*test_ib)(struct amdgpu_ring *ring); /* insert NOP packets */ void (*insert_nop)(struct amdgpu_ring *ring, uint32_t count); + /* pad the indirect buffer to the necessary number of dw */ + void (*pad_ib)(struct amdgpu_ring *ring, struct amdgpu_ib *ib); }; /* @@ -355,13 +347,15 @@ struct amdgpu_fence_driver { uint64_t gpu_addr; volatile uint32_t *cpu_addr; /* sync_seq is protected by ring emission lock */ - uint64_t sync_seq[AMDGPU_MAX_RINGS]; - atomic64_t last_seq; + uint32_t sync_seq; + atomic_t last_seq; bool initialized; struct amdgpu_irq_src *irq_src; unsigned irq_type; struct timer_list fallback_timer; - wait_queue_head_t fence_queue; + unsigned num_fences_mask; + spinlock_t lock; + struct fence **fences; }; /* some special values for the owner field */ @@ -371,19 +365,6 @@ struct amdgpu_fence_driver { #define AMDGPU_FENCE_FLAG_64BIT (1 << 0) #define AMDGPU_FENCE_FLAG_INT (1 << 1) -struct amdgpu_fence { - struct fence base; - - /* RB, DMA, etc. */ - struct amdgpu_ring *ring; - uint64_t seq; - - /* filp or special value for fence creator */ - void *owner; - - wait_queue_t fence_wake; -}; - struct amdgpu_user_fence { /* write-back bo */ struct amdgpu_bo *bo; @@ -395,24 +376,18 @@ int amdgpu_fence_driver_init(struct amdgpu_device *adev); void amdgpu_fence_driver_fini(struct amdgpu_device *adev); void amdgpu_fence_driver_force_completion(struct amdgpu_device *adev); -int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring); +int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring, + unsigned num_hw_submission); int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring, struct amdgpu_irq_src *irq_src, unsigned irq_type); void amdgpu_fence_driver_suspend(struct amdgpu_device *adev); void amdgpu_fence_driver_resume(struct amdgpu_device *adev); -int amdgpu_fence_emit(struct amdgpu_ring *ring, void *owner, - struct amdgpu_fence **fence); +int amdgpu_fence_emit(struct amdgpu_ring *ring, struct fence **fence); void amdgpu_fence_process(struct amdgpu_ring *ring); -int amdgpu_fence_wait_next(struct amdgpu_ring *ring); int amdgpu_fence_wait_empty(struct amdgpu_ring *ring); unsigned amdgpu_fence_count_emitted(struct amdgpu_ring *ring); -bool amdgpu_fence_need_sync(struct amdgpu_fence *fence, - struct amdgpu_ring *ring); -void amdgpu_fence_note_sync(struct amdgpu_fence *fence, - struct amdgpu_ring *ring); - /* * TTM. */ @@ -431,6 +406,8 @@ struct amdgpu_mman { /* buffer handling */ const struct amdgpu_buffer_funcs *buffer_funcs; struct amdgpu_ring *buffer_funcs_ring; + /* Scheduler entity for buffer moves */ + struct amd_sched_entity entity; }; int amdgpu_copy_buffer(struct amdgpu_ring *ring, @@ -445,9 +422,9 @@ struct amdgpu_bo_list_entry { struct amdgpu_bo *robj; struct ttm_validate_buffer tv; struct amdgpu_bo_va *bo_va; - unsigned prefered_domains; - unsigned allowed_domains; uint32_t priority; + struct page **user_pages; + int user_invalidated; }; struct amdgpu_bo_va_mapping { @@ -459,7 +436,6 @@ struct amdgpu_bo_va_mapping { /* bo virtual addresses in a specific vm */ struct amdgpu_bo_va { - struct mutex mutex; /* protected by bo being reserved */ struct list_head bo_list; struct fence *last_pt_update; @@ -483,7 +459,8 @@ struct amdgpu_bo { /* Protected by gem.mutex */ struct list_head list; /* Protected by tbo.reserved */ - u32 initial_domain; + u32 prefered_domains; + u32 allowed_domains; struct ttm_place placements[AMDGPU_GEM_DOMAIN_MAX + 1]; struct ttm_placement placement; struct ttm_buffer_object tbo; @@ -505,7 +482,6 @@ struct amdgpu_bo { struct amdgpu_bo *parent; struct ttm_bo_kmap_obj dma_buf_vmap; - pid_t pid; struct amdgpu_mn *mn; struct list_head mn_list; }; @@ -554,11 +530,14 @@ int amdgpu_gem_debugfs_init(struct amdgpu_device *adev); * Assumption is that there won't be hole (all object on same * alignment). */ + +#define AMDGPU_SA_NUM_FENCE_LISTS 32 + struct amdgpu_sa_manager { wait_queue_head_t wq; struct amdgpu_bo *bo; struct list_head *hole; - struct list_head flist[AMDGPU_MAX_RINGS]; + struct list_head flist[AMDGPU_SA_NUM_FENCE_LISTS]; struct list_head olist; unsigned size; uint64_t gpu_addr; @@ -580,13 +559,7 @@ struct amdgpu_sa_bo { /* * GEM objects. */ -struct amdgpu_gem { - struct mutex mutex; - struct list_head objects; -}; - -int amdgpu_gem_init(struct amdgpu_device *adev); -void amdgpu_gem_fini(struct amdgpu_device *adev); +void amdgpu_gem_force_release(struct amdgpu_device *adev); int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size, int alignment, u32 initial_domain, u64 flags, bool kernel, @@ -598,32 +571,10 @@ int amdgpu_mode_dumb_create(struct drm_file *file_priv, int amdgpu_mode_dumb_mmap(struct drm_file *filp, struct drm_device *dev, uint32_t handle, uint64_t *offset_p); - -/* - * Semaphores. - */ -struct amdgpu_semaphore { - struct amdgpu_sa_bo *sa_bo; - signed waiters; - uint64_t gpu_addr; -}; - -int amdgpu_semaphore_create(struct amdgpu_device *adev, - struct amdgpu_semaphore **semaphore); -bool amdgpu_semaphore_emit_signal(struct amdgpu_ring *ring, - struct amdgpu_semaphore *semaphore); -bool amdgpu_semaphore_emit_wait(struct amdgpu_ring *ring, - struct amdgpu_semaphore *semaphore); -void amdgpu_semaphore_free(struct amdgpu_device *adev, - struct amdgpu_semaphore **semaphore, - struct fence *fence); - /* * Synchronization */ struct amdgpu_sync { - struct amdgpu_semaphore *semaphores[AMDGPU_NUM_SYNCS]; - struct fence *sync_to[AMDGPU_MAX_RINGS]; DECLARE_HASHTABLE(fences, 4); struct fence *last_vm_update; }; @@ -635,12 +586,11 @@ int amdgpu_sync_resv(struct amdgpu_device *adev, struct amdgpu_sync *sync, struct reservation_object *resv, void *owner); -int amdgpu_sync_rings(struct amdgpu_sync *sync, - struct amdgpu_ring *ring); struct fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync); int amdgpu_sync_wait(struct amdgpu_sync *sync); -void amdgpu_sync_free(struct amdgpu_device *adev, struct amdgpu_sync *sync, - struct fence *fence); +void amdgpu_sync_free(struct amdgpu_sync *sync); +int amdgpu_sync_init(void); +void amdgpu_sync_fini(void); /* * GART structures, functions & helpers @@ -758,6 +708,7 @@ struct amdgpu_flip_work { struct fence *excl; unsigned shared_count; struct fence **shared; + struct fence_cb cb; }; @@ -770,12 +721,11 @@ struct amdgpu_ib { uint32_t length_dw; uint64_t gpu_addr; uint32_t *ptr; - struct amdgpu_ring *ring; - struct amdgpu_fence *fence; struct amdgpu_user_fence *user; struct amdgpu_vm *vm; + unsigned vm_id; + uint64_t vm_pd_addr; struct amdgpu_ctx *ctx; - struct amdgpu_sync sync; uint32_t gds_base, gds_size; uint32_t gws_base, gws_size; uint32_t oa_base, oa_size; @@ -794,13 +744,14 @@ enum amdgpu_ring_type { extern struct amd_sched_backend_ops amdgpu_sched_ops; -int amdgpu_sched_ib_submit_kernel_helper(struct amdgpu_device *adev, - struct amdgpu_ring *ring, - struct amdgpu_ib *ibs, - unsigned num_ibs, - int (*free_job)(struct amdgpu_job *), - void *owner, - struct fence **fence); +int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, + struct amdgpu_job **job); +int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size, + struct amdgpu_job **job); +void amdgpu_job_free(struct amdgpu_job *job); +int amdgpu_job_submit(struct amdgpu_job *job, struct amdgpu_ring *ring, + struct amd_sched_entity *entity, void *owner, + struct fence **f); struct amdgpu_ring { struct amdgpu_device *adev; @@ -809,7 +760,6 @@ struct amdgpu_ring { struct amd_gpu_scheduler sched; spinlock_t fence_lock; - struct mutex *ring_lock; struct amdgpu_bo *ring_obj; volatile uint32_t *ring; unsigned rptr_offs; @@ -818,7 +768,7 @@ struct amdgpu_ring { unsigned wptr; unsigned wptr_old; unsigned ring_size; - unsigned ring_free_dw; + unsigned max_dw; int count_dw; uint64_t gpu_addr; uint32_t align_mask; @@ -826,8 +776,6 @@ struct amdgpu_ring { bool ready; u32 nop; u32 idx; - u64 last_semaphore_signal_addr; - u64 last_semaphore_wait_addr; u32 me; u32 pipe; u32 queue; @@ -840,7 +788,6 @@ struct amdgpu_ring { struct amdgpu_ctx *current_ctx; enum amdgpu_ring_type type; char name[16]; - bool is_pte_ring; }; /* @@ -884,13 +831,14 @@ struct amdgpu_vm_pt { }; struct amdgpu_vm_id { - unsigned id; - uint64_t pd_gpu_addr; + struct amdgpu_vm_manager_id *mgr_id; + uint64_t pd_gpu_addr; /* last flushed PD/PT update */ - struct fence *flushed_updates; + struct fence *flushed_updates; }; struct amdgpu_vm { + /* tree of virtual addresses mapped */ struct rb_root va; /* protecting invalidated */ @@ -915,30 +863,47 @@ struct amdgpu_vm { /* for id and flush management per ring */ struct amdgpu_vm_id ids[AMDGPU_MAX_RINGS]; - /* for interval tree */ - spinlock_t it_lock; + /* protecting freed */ spinlock_t freed_lock; + + /* Scheduler entity for page table updates */ + struct amd_sched_entity entity; +}; + +struct amdgpu_vm_manager_id { + struct list_head list; + struct fence *active; + atomic_long_t owner; + + uint32_t gds_base; + uint32_t gds_size; + uint32_t gws_base; + uint32_t gws_size; + uint32_t oa_base; + uint32_t oa_size; }; struct amdgpu_vm_manager { - struct { - struct fence *active; - atomic_long_t owner; - } ids[AMDGPU_NUM_VM]; + /* Handling of VMIDs */ + struct mutex lock; + unsigned num_ids; + struct list_head ids_lru; + struct amdgpu_vm_manager_id ids[AMDGPU_NUM_VM]; uint32_t max_pfn; - /* number of VMIDs */ - unsigned nvm; /* vram base address for page table entry */ u64 vram_base_offset; /* is vm enabled? */ bool enabled; /* vm pte handling */ const struct amdgpu_vm_pte_funcs *vm_pte_funcs; - struct amdgpu_ring *vm_pte_funcs_ring; + struct amdgpu_ring *vm_pte_rings[AMDGPU_MAX_RINGS]; + unsigned vm_pte_num_rings; + atomic_t vm_pte_next_ring; }; +void amdgpu_vm_manager_init(struct amdgpu_device *adev); void amdgpu_vm_manager_fini(struct amdgpu_device *adev); int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm); void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm); @@ -949,14 +914,15 @@ void amdgpu_vm_get_pt_bos(struct amdgpu_vm *vm, struct list_head *duplicates); void amdgpu_vm_move_pt_bos_in_lru(struct amdgpu_device *adev, struct amdgpu_vm *vm); int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, - struct amdgpu_sync *sync); + struct amdgpu_sync *sync, struct fence *fence, + unsigned *vm_id, uint64_t *vm_pd_addr); void amdgpu_vm_flush(struct amdgpu_ring *ring, - struct amdgpu_vm *vm, - struct fence *updates); -void amdgpu_vm_fence(struct amdgpu_device *adev, - struct amdgpu_vm *vm, - struct fence *fence); -uint64_t amdgpu_vm_map_gart(struct amdgpu_device *adev, uint64_t addr); + unsigned vm_id, uint64_t pd_addr, + uint32_t gds_base, uint32_t gds_size, + uint32_t gws_base, uint32_t gws_size, + uint32_t oa_base, uint32_t oa_size); +void amdgpu_vm_reset_id(struct amdgpu_device *adev, unsigned vm_id); +uint64_t amdgpu_vm_map_gart(const dma_addr_t *pages_addr, uint64_t addr); int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, struct amdgpu_vm *vm); int amdgpu_vm_clear_freed(struct amdgpu_device *adev, @@ -982,7 +948,6 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev, uint64_t addr); void amdgpu_vm_bo_rmv(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va); -int amdgpu_vm_free_job(struct amdgpu_job *job); /* * context related structures @@ -1010,10 +975,6 @@ struct amdgpu_ctx_mgr { struct idr ctx_handles; }; -int amdgpu_ctx_init(struct amdgpu_device *adev, enum amd_sched_priority pri, - struct amdgpu_ctx *ctx); -void amdgpu_ctx_fini(struct amdgpu_ctx *ctx); - struct amdgpu_ctx *amdgpu_ctx_get(struct amdgpu_fpriv *fpriv, uint32_t id); int amdgpu_ctx_put(struct amdgpu_ctx *ctx); @@ -1048,13 +1009,15 @@ struct amdgpu_bo_list { struct amdgpu_bo *gds_obj; struct amdgpu_bo *gws_obj; struct amdgpu_bo *oa_obj; - bool has_userptr; + unsigned first_userptr; unsigned num_entries; struct amdgpu_bo_list_entry *array; }; struct amdgpu_bo_list * amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id); +void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list, + struct list_head *validated); void amdgpu_bo_list_put(struct amdgpu_bo_list *list); void amdgpu_bo_list_free(struct amdgpu_bo_list *list); @@ -1128,6 +1091,7 @@ struct amdgpu_gca_config { unsigned multi_gpu_tile_size; unsigned mc_arb_ramcfg; unsigned gb_addr_config; + unsigned num_rbs; uint32_t tile_mode_array[32]; uint32_t macrotile_mode_array[16]; @@ -1170,23 +1134,20 @@ struct amdgpu_gfx { unsigned ce_ram_size; }; -int amdgpu_ib_get(struct amdgpu_ring *ring, struct amdgpu_vm *vm, +int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm, unsigned size, struct amdgpu_ib *ib); -void amdgpu_ib_free(struct amdgpu_device *adev, struct amdgpu_ib *ib); -int amdgpu_ib_schedule(struct amdgpu_device *adev, unsigned num_ibs, - struct amdgpu_ib *ib, void *owner); +void amdgpu_ib_free(struct amdgpu_device *adev, struct amdgpu_ib *ib, struct fence *f); +int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, + struct amdgpu_ib *ib, struct fence *last_vm_update, + struct fence **f); int amdgpu_ib_pool_init(struct amdgpu_device *adev); void amdgpu_ib_pool_fini(struct amdgpu_device *adev); int amdgpu_ib_ring_tests(struct amdgpu_device *adev); -/* Ring access between begin & end cannot sleep */ -void amdgpu_ring_free_size(struct amdgpu_ring *ring); int amdgpu_ring_alloc(struct amdgpu_ring *ring, unsigned ndw); -int amdgpu_ring_lock(struct amdgpu_ring *ring, unsigned ndw); void amdgpu_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count); +void amdgpu_ring_generic_pad_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib); void amdgpu_ring_commit(struct amdgpu_ring *ring); -void amdgpu_ring_unlock_commit(struct amdgpu_ring *ring); void amdgpu_ring_undo(struct amdgpu_ring *ring); -void amdgpu_ring_unlock_undo(struct amdgpu_ring *ring); unsigned amdgpu_ring_backup(struct amdgpu_ring *ring, uint32_t **data); int amdgpu_ring_restore(struct amdgpu_ring *ring, @@ -1196,7 +1157,6 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, struct amdgpu_irq_src *irq_src, unsigned irq_type, enum amdgpu_ring_type ring_type); void amdgpu_ring_fini(struct amdgpu_ring *ring); -struct amdgpu_ring *amdgpu_ring_from_fence(struct fence *f); /* * CS. @@ -1205,47 +1165,58 @@ struct amdgpu_cs_chunk { uint32_t chunk_id; uint32_t length_dw; uint32_t *kdata; - void __user *user_ptr; }; struct amdgpu_cs_parser { struct amdgpu_device *adev; struct drm_file *filp; struct amdgpu_ctx *ctx; - struct amdgpu_bo_list *bo_list; + /* chunks */ unsigned nchunks; struct amdgpu_cs_chunk *chunks; - /* relocations */ - struct amdgpu_bo_list_entry vm_pd; - struct list_head validated; - struct fence *fence; - struct amdgpu_ib *ibs; - uint32_t num_ibs; + /* scheduler job object */ + struct amdgpu_job *job; - struct ww_acquire_ctx ticket; + /* buffer objects */ + struct ww_acquire_ctx ticket; + struct amdgpu_bo_list *bo_list; + struct amdgpu_bo_list_entry vm_pd; + struct list_head validated; + struct fence *fence; + uint64_t bytes_moved_threshold; + uint64_t bytes_moved; /* user fence */ - struct amdgpu_user_fence uf; struct amdgpu_bo_list_entry uf_entry; }; struct amdgpu_job { struct amd_sched_job base; struct amdgpu_device *adev; + struct amdgpu_ring *ring; + struct amdgpu_sync sync; struct amdgpu_ib *ibs; + struct fence *fence; /* the hw fence */ uint32_t num_ibs; void *owner; struct amdgpu_user_fence uf; - int (*free_job)(struct amdgpu_job *job); }; #define to_amdgpu_job(sched_job) \ container_of((sched_job), struct amdgpu_job, base) -static inline u32 amdgpu_get_ib_value(struct amdgpu_cs_parser *p, uint32_t ib_idx, int idx) +static inline u32 amdgpu_get_ib_value(struct amdgpu_cs_parser *p, + uint32_t ib_idx, int idx) +{ + return p->job->ibs[ib_idx].ptr[idx]; +} + +static inline void amdgpu_set_ib_value(struct amdgpu_cs_parser *p, + uint32_t ib_idx, int idx, + uint32_t value) { - return p->ibs[ib_idx].ptr[idx]; + p->job->ibs[ib_idx].ptr[idx] = value; } /* @@ -1497,6 +1468,7 @@ enum amdgpu_dpm_forced_level { AMDGPU_DPM_FORCED_LEVEL_AUTO = 0, AMDGPU_DPM_FORCED_LEVEL_LOW = 1, AMDGPU_DPM_FORCED_LEVEL_HIGH = 2, + AMDGPU_DPM_FORCED_LEVEL_MANUAL = 3, }; struct amdgpu_vce_state { @@ -1619,6 +1591,7 @@ struct amdgpu_uvd { struct amdgpu_bo *vcpu_bo; void *cpu_addr; uint64_t gpu_addr; + void *saved_bo; atomic_t handles[AMDGPU_MAX_UVD_HANDLES]; struct drm_file *filp[AMDGPU_MAX_UVD_HANDLES]; struct delayed_work idle_work; @@ -1626,6 +1599,7 @@ struct amdgpu_uvd { struct amdgpu_ring ring; struct amdgpu_irq_src irq; bool address_64_bit; + struct amd_sched_entity entity; }; /* @@ -1650,6 +1624,7 @@ struct amdgpu_vce { struct amdgpu_ring ring[AMDGPU_MAX_VCE_RINGS]; struct amdgpu_irq_src irq; unsigned harvest_config; + struct amd_sched_entity entity; }; /* @@ -1883,6 +1858,18 @@ void *amdgpu_cgs_create_device(struct amdgpu_device *adev); void amdgpu_cgs_destroy_device(void *cgs_device); +/* + * CGS + */ +void *amdgpu_cgs_create_device(struct amdgpu_device *adev); +void amdgpu_cgs_destroy_device(void *cgs_device); + + +/* GPU virtualization */ +struct amdgpu_virtualization { + bool supports_sr_iov; +}; + /* * Core structure, functions and helpers. */ @@ -1903,6 +1890,10 @@ struct amdgpu_device { struct drm_device *ddev; struct pci_dev *pdev; +#ifdef CONFIG_DRM_AMD_ACP + struct amdgpu_acp acp; +#endif + /* ASIC */ enum amd_asic_type asic_type; uint32_t family; @@ -1979,7 +1970,6 @@ struct amdgpu_device { /* memory management */ struct amdgpu_mman mman; - struct amdgpu_gem gem; struct amdgpu_vram_scratch vram_scratch; struct amdgpu_wb wb; atomic64_t vram_usage; @@ -1997,7 +1987,6 @@ struct amdgpu_device { /* rings */ unsigned fence_context; - struct mutex ring_lock; unsigned num_rings; struct amdgpu_ring *rings[AMDGPU_MAX_RINGS]; bool ib_pool_ready; @@ -2009,6 +1998,7 @@ struct amdgpu_device { /* powerplay */ struct amd_powerplay powerplay; bool pp_enabled; + bool pp_force_state_enabled; /* dpm */ struct amdgpu_pm pm; @@ -2025,7 +2015,6 @@ struct amdgpu_device { struct amdgpu_sdma sdma; /* uvd */ - bool has_uvd; struct amdgpu_uvd uvd; /* vce */ @@ -2050,8 +2039,7 @@ struct amdgpu_device { /* amdkfd interface */ struct kfd_dev *kfd; - /* kernel conext for IB submission */ - struct amdgpu_ctx kernel_ctx; + struct amdgpu_virtualization virtualization; }; bool amdgpu_device_is_px(struct drm_device *dev); @@ -2072,20 +2060,6 @@ void amdgpu_io_wreg(struct amdgpu_device *adev, u32 reg, u32 v); u32 amdgpu_mm_rdoorbell(struct amdgpu_device *adev, u32 index); void amdgpu_mm_wdoorbell(struct amdgpu_device *adev, u32 index, u32 v); -/* - * Cast helper - */ -extern const struct fence_ops amdgpu_fence_ops; -static inline struct amdgpu_fence *to_amdgpu_fence(struct fence *f) -{ - struct amdgpu_fence *__f = container_of(f, struct amdgpu_fence, base); - - if (__f->base.ops == &amdgpu_fence_ops) - return __f; - - return NULL; -} - /* * Registers read & write functions. */ @@ -2156,7 +2130,6 @@ static inline void amdgpu_ring_write(struct amdgpu_ring *ring, uint32_t v) ring->ring[ring->wptr++] = v; ring->wptr &= ring->ptr_mask; ring->count_dw--; - ring->ring_free_dw--; } static inline struct amdgpu_sdma_instance * @@ -2192,9 +2165,8 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring) #define amdgpu_gart_flush_gpu_tlb(adev, vmid) (adev)->gart.gart_funcs->flush_gpu_tlb((adev), (vmid)) #define amdgpu_gart_set_pte_pde(adev, pt, idx, addr, flags) (adev)->gart.gart_funcs->set_pte_pde((adev), (pt), (idx), (addr), (flags)) #define amdgpu_vm_copy_pte(adev, ib, pe, src, count) ((adev)->vm_manager.vm_pte_funcs->copy_pte((ib), (pe), (src), (count))) -#define amdgpu_vm_write_pte(adev, ib, pe, addr, count, incr, flags) ((adev)->vm_manager.vm_pte_funcs->write_pte((ib), (pe), (addr), (count), (incr), (flags))) +#define amdgpu_vm_write_pte(adev, ib, pa, pe, addr, count, incr, flags) ((adev)->vm_manager.vm_pte_funcs->write_pte((ib), (pa), (pe), (addr), (count), (incr), (flags))) #define amdgpu_vm_set_pte_pde(adev, ib, pe, addr, count, incr, flags) ((adev)->vm_manager.vm_pte_funcs->set_pte_pde((ib), (pe), (addr), (count), (incr), (flags))) -#define amdgpu_vm_pad_ib(adev, ib) ((adev)->vm_manager.vm_pte_funcs->pad_ib((ib))) #define amdgpu_ring_parse_cs(r, p, ib) ((r)->funcs->parse_cs((p), (ib))) #define amdgpu_ring_test_ring(r) (r)->funcs->test_ring((r)) #define amdgpu_ring_test_ib(r) (r)->funcs->test_ib((r)) @@ -2202,11 +2174,13 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring) #define amdgpu_ring_get_wptr(r) (r)->funcs->get_wptr((r)) #define amdgpu_ring_set_wptr(r) (r)->funcs->set_wptr((r)) #define amdgpu_ring_emit_ib(r, ib) (r)->funcs->emit_ib((r), (ib)) +#define amdgpu_ring_emit_pipeline_sync(r) (r)->funcs->emit_pipeline_sync((r)) #define amdgpu_ring_emit_vm_flush(r, vmid, addr) (r)->funcs->emit_vm_flush((r), (vmid), (addr)) #define amdgpu_ring_emit_fence(r, addr, seq, flags) (r)->funcs->emit_fence((r), (addr), (seq), (flags)) -#define amdgpu_ring_emit_semaphore(r, semaphore, emit_wait) (r)->funcs->emit_semaphore((r), (semaphore), (emit_wait)) #define amdgpu_ring_emit_gds_switch(r, v, db, ds, wb, ws, ab, as) (r)->funcs->emit_gds_switch((r), (v), (db), (ds), (wb), (ws), (ab), (as)) #define amdgpu_ring_emit_hdp_flush(r) (r)->funcs->emit_hdp_flush((r)) +#define amdgpu_ring_emit_hdp_invalidate(r) (r)->funcs->emit_hdp_invalidate((r)) +#define amdgpu_ring_pad_ib(r, ib) ((r)->funcs->pad_ib((r), (ib))) #define amdgpu_ih_get_wptr(adev) (adev)->irq.ih_funcs->get_wptr((adev)) #define amdgpu_ih_decode_iv(adev, iv) (adev)->irq.ih_funcs->decode_iv((adev), (iv)) #define amdgpu_ih_set_rptr(adev) (adev)->irq.ih_funcs->set_rptr((adev)) @@ -2298,6 +2272,21 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring) #define amdgpu_dpm_get_performance_level(adev) \ (adev)->powerplay.pp_funcs->get_performance_level((adev)->powerplay.pp_handle) +#define amdgpu_dpm_get_pp_num_states(adev, data) \ + (adev)->powerplay.pp_funcs->get_pp_num_states((adev)->powerplay.pp_handle, data) + +#define amdgpu_dpm_get_pp_table(adev, table) \ + (adev)->powerplay.pp_funcs->get_pp_table((adev)->powerplay.pp_handle, table) + +#define amdgpu_dpm_set_pp_table(adev, buf, size) \ + (adev)->powerplay.pp_funcs->set_pp_table((adev)->powerplay.pp_handle, buf, size) + +#define amdgpu_dpm_print_clock_levels(adev, type, buf) \ + (adev)->powerplay.pp_funcs->print_clock_levels((adev)->powerplay.pp_handle, type, buf) + +#define amdgpu_dpm_force_clock_level(adev, type, level) \ + (adev)->powerplay.pp_funcs->force_clock_level((adev)->powerplay.pp_handle, type, level) + #define amdgpu_dpm_dispatch_task(adev, event_id, input, output) \ (adev)->powerplay.pp_funcs->dispatch_tasks((adev)->powerplay.pp_handle, (event_id), (input), (output)) @@ -2308,7 +2297,6 @@ int amdgpu_gpu_reset(struct amdgpu_device *adev); void amdgpu_pci_config_reset(struct amdgpu_device *adev); bool amdgpu_card_posted(struct amdgpu_device *adev); void amdgpu_update_display_priority(struct amdgpu_device *adev); -bool amdgpu_boot_test_post_card(struct amdgpu_device *adev); int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data); int amdgpu_cs_get_ring(struct amdgpu_device *adev, u32 ip_type, @@ -2316,11 +2304,15 @@ int amdgpu_cs_get_ring(struct amdgpu_device *adev, u32 ip_type, struct amdgpu_ring **out_ring); void amdgpu_ttm_placement_from_domain(struct amdgpu_bo *rbo, u32 domain); bool amdgpu_ttm_bo_is_amdgpu_bo(struct ttm_buffer_object *bo); +int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages); int amdgpu_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr, uint32_t flags); bool amdgpu_ttm_tt_has_userptr(struct ttm_tt *ttm); +struct mm_struct *amdgpu_ttm_tt_get_usermm(struct ttm_tt *ttm); bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start, unsigned long end); +bool amdgpu_ttm_tt_userptr_invalidated(struct ttm_tt *ttm, + int *last_invalidated); bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm); uint32_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm, struct ttm_mem_reg *mem); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c new file mode 100644 index 0000000000000000000000000000000000000000..d6b0bff510aaa719dbb0f9cce269645b06716127 --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c @@ -0,0 +1,500 @@ +/* + * Copyright 2015 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#include +#include +#include +#include +#include + +#include "amdgpu.h" +#include "atom.h" +#include "amdgpu_acp.h" + +#include "acp_gfx_if.h" + +#define ACP_TILE_ON_MASK 0x03 +#define ACP_TILE_OFF_MASK 0x02 +#define ACP_TILE_ON_RETAIN_REG_MASK 0x1f +#define ACP_TILE_OFF_RETAIN_REG_MASK 0x20 + +#define ACP_TILE_P1_MASK 0x3e +#define ACP_TILE_P2_MASK 0x3d +#define ACP_TILE_DSP0_MASK 0x3b +#define ACP_TILE_DSP1_MASK 0x37 + +#define ACP_TILE_DSP2_MASK 0x2f + +#define ACP_DMA_REGS_END 0x146c0 +#define ACP_I2S_PLAY_REGS_START 0x14840 +#define ACP_I2S_PLAY_REGS_END 0x148b4 +#define ACP_I2S_CAP_REGS_START 0x148b8 +#define ACP_I2S_CAP_REGS_END 0x1496c + +#define ACP_I2S_COMP1_CAP_REG_OFFSET 0xac +#define ACP_I2S_COMP2_CAP_REG_OFFSET 0xa8 +#define ACP_I2S_COMP1_PLAY_REG_OFFSET 0x6c +#define ACP_I2S_COMP2_PLAY_REG_OFFSET 0x68 + +#define mmACP_PGFSM_RETAIN_REG 0x51c9 +#define mmACP_PGFSM_CONFIG_REG 0x51ca +#define mmACP_PGFSM_READ_REG_0 0x51cc + +#define mmACP_MEM_SHUT_DOWN_REQ_LO 0x51f8 +#define mmACP_MEM_SHUT_DOWN_REQ_HI 0x51f9 +#define mmACP_MEM_SHUT_DOWN_STS_LO 0x51fa +#define mmACP_MEM_SHUT_DOWN_STS_HI 0x51fb + +#define ACP_TIMEOUT_LOOP 0x000000FF +#define ACP_DEVS 3 +#define ACP_SRC_ID 162 + +enum { + ACP_TILE_P1 = 0, + ACP_TILE_P2, + ACP_TILE_DSP0, + ACP_TILE_DSP1, + ACP_TILE_DSP2, +}; + +static int acp_sw_init(void *handle) +{ + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + + adev->acp.parent = adev->dev; + + adev->acp.cgs_device = + amdgpu_cgs_create_device(adev); + if (!adev->acp.cgs_device) + return -EINVAL; + + return 0; +} + +static int acp_sw_fini(void *handle) +{ + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + + if (adev->acp.cgs_device) + amdgpu_cgs_destroy_device(adev->acp.cgs_device); + + return 0; +} + +/* power off a tile/block within ACP */ +static int acp_suspend_tile(void *cgs_dev, int tile) +{ + u32 val = 0; + u32 count = 0; + + if ((tile < ACP_TILE_P1) || (tile > ACP_TILE_DSP2)) { + pr_err("Invalid ACP tile : %d to suspend\n", tile); + return -1; + } + + val = cgs_read_register(cgs_dev, mmACP_PGFSM_READ_REG_0 + tile); + val &= ACP_TILE_ON_MASK; + + if (val == 0x0) { + val = cgs_read_register(cgs_dev, mmACP_PGFSM_RETAIN_REG); + val = val | (1 << tile); + cgs_write_register(cgs_dev, mmACP_PGFSM_RETAIN_REG, val); + cgs_write_register(cgs_dev, mmACP_PGFSM_CONFIG_REG, + 0x500 + tile); + + count = ACP_TIMEOUT_LOOP; + while (true) { + val = cgs_read_register(cgs_dev, mmACP_PGFSM_READ_REG_0 + + tile); + val = val & ACP_TILE_ON_MASK; + if (val == ACP_TILE_OFF_MASK) + break; + if (--count == 0) { + pr_err("Timeout reading ACP PGFSM status\n"); + return -ETIMEDOUT; + } + udelay(100); + } + + val = cgs_read_register(cgs_dev, mmACP_PGFSM_RETAIN_REG); + + val |= ACP_TILE_OFF_RETAIN_REG_MASK; + cgs_write_register(cgs_dev, mmACP_PGFSM_RETAIN_REG, val); + } + return 0; +} + +/* power on a tile/block within ACP */ +static int acp_resume_tile(void *cgs_dev, int tile) +{ + u32 val = 0; + u32 count = 0; + + if ((tile < ACP_TILE_P1) || (tile > ACP_TILE_DSP2)) { + pr_err("Invalid ACP tile to resume\n"); + return -1; + } + + val = cgs_read_register(cgs_dev, mmACP_PGFSM_READ_REG_0 + tile); + val = val & ACP_TILE_ON_MASK; + + if (val != 0x0) { + cgs_write_register(cgs_dev, mmACP_PGFSM_CONFIG_REG, + 0x600 + tile); + count = ACP_TIMEOUT_LOOP; + while (true) { + val = cgs_read_register(cgs_dev, mmACP_PGFSM_READ_REG_0 + + tile); + val = val & ACP_TILE_ON_MASK; + if (val == 0x0) + break; + if (--count == 0) { + pr_err("Timeout reading ACP PGFSM status\n"); + return -ETIMEDOUT; + } + udelay(100); + } + val = cgs_read_register(cgs_dev, mmACP_PGFSM_RETAIN_REG); + if (tile == ACP_TILE_P1) + val = val & (ACP_TILE_P1_MASK); + else if (tile == ACP_TILE_P2) + val = val & (ACP_TILE_P2_MASK); + + cgs_write_register(cgs_dev, mmACP_PGFSM_RETAIN_REG, val); + } + return 0; +} + +struct acp_pm_domain { + void *cgs_dev; + struct generic_pm_domain gpd; +}; + +static int acp_poweroff(struct generic_pm_domain *genpd) +{ + int i, ret; + struct acp_pm_domain *apd; + + apd = container_of(genpd, struct acp_pm_domain, gpd); + if (apd != NULL) { + /* Donot return abruptly if any of power tile fails to suspend. + * Log it and continue powering off other tile + */ + for (i = 4; i >= 0 ; i--) { + ret = acp_suspend_tile(apd->cgs_dev, ACP_TILE_P1 + i); + if (ret) + pr_err("ACP tile %d tile suspend failed\n", i); + } + } + return 0; +} + +static int acp_poweron(struct generic_pm_domain *genpd) +{ + int i, ret; + struct acp_pm_domain *apd; + + apd = container_of(genpd, struct acp_pm_domain, gpd); + if (apd != NULL) { + for (i = 0; i < 2; i++) { + ret = acp_resume_tile(apd->cgs_dev, ACP_TILE_P1 + i); + if (ret) { + pr_err("ACP tile %d resume failed\n", i); + break; + } + } + + /* Disable DSPs which are not going to be used */ + for (i = 0; i < 3; i++) { + ret = acp_suspend_tile(apd->cgs_dev, ACP_TILE_DSP0 + i); + /* Continue suspending other DSP, even if one fails */ + if (ret) + pr_err("ACP DSP %d suspend failed\n", i); + } + } + return 0; +} + +static struct device *get_mfd_cell_dev(const char *device_name, int r) +{ + char auto_dev_name[25]; + struct device *dev; + + snprintf(auto_dev_name, sizeof(auto_dev_name), + "%s.%d.auto", device_name, r); + dev = bus_find_device_by_name(&platform_bus_type, NULL, auto_dev_name); + dev_info(dev, "device %s added to pm domain\n", auto_dev_name); + + return dev; +} + +/** + * acp_hw_init - start and test ACP block + * + * @adev: amdgpu_device pointer + * + */ +static int acp_hw_init(void *handle) +{ + int r, i; + uint64_t acp_base; + struct device *dev; + struct i2s_platform_data *i2s_pdata; + + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + + const struct amdgpu_ip_block_version *ip_version = + amdgpu_get_ip_block(adev, AMD_IP_BLOCK_TYPE_ACP); + + if (!ip_version) + return -EINVAL; + + r = amd_acp_hw_init(adev->acp.cgs_device, + ip_version->major, ip_version->minor); + /* -ENODEV means board uses AZ rather than ACP */ + if (r == -ENODEV) + return 0; + else if (r) + return r; + + r = cgs_get_pci_resource(adev->acp.cgs_device, CGS_RESOURCE_TYPE_MMIO, + 0x5289, 0, &acp_base); + if (r == -ENODEV) + return 0; + else if (r) + return r; + + adev->acp.acp_genpd = kzalloc(sizeof(struct acp_pm_domain), GFP_KERNEL); + if (adev->acp.acp_genpd == NULL) + return -ENOMEM; + + adev->acp.acp_genpd->gpd.name = "ACP_AUDIO"; + adev->acp.acp_genpd->gpd.power_off = acp_poweroff; + adev->acp.acp_genpd->gpd.power_on = acp_poweron; + + + adev->acp.acp_genpd->cgs_dev = adev->acp.cgs_device; + + pm_genpd_init(&adev->acp.acp_genpd->gpd, NULL, false); + + adev->acp.acp_cell = kzalloc(sizeof(struct mfd_cell) * ACP_DEVS, + GFP_KERNEL); + + if (adev->acp.acp_cell == NULL) + return -ENOMEM; + + adev->acp.acp_res = kzalloc(sizeof(struct resource) * 4, GFP_KERNEL); + + if (adev->acp.acp_res == NULL) { + kfree(adev->acp.acp_cell); + return -ENOMEM; + } + + i2s_pdata = kzalloc(sizeof(struct i2s_platform_data) * 2, GFP_KERNEL); + if (i2s_pdata == NULL) { + kfree(adev->acp.acp_res); + kfree(adev->acp.acp_cell); + return -ENOMEM; + } + + i2s_pdata[0].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET; + i2s_pdata[0].cap = DWC_I2S_PLAY; + i2s_pdata[0].snd_rates = SNDRV_PCM_RATE_8000_96000; + i2s_pdata[0].i2s_reg_comp1 = ACP_I2S_COMP1_PLAY_REG_OFFSET; + i2s_pdata[0].i2s_reg_comp2 = ACP_I2S_COMP2_PLAY_REG_OFFSET; + + i2s_pdata[1].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET | + DW_I2S_QUIRK_COMP_PARAM1; + i2s_pdata[1].cap = DWC_I2S_RECORD; + i2s_pdata[1].snd_rates = SNDRV_PCM_RATE_8000_96000; + i2s_pdata[1].i2s_reg_comp1 = ACP_I2S_COMP1_CAP_REG_OFFSET; + i2s_pdata[1].i2s_reg_comp2 = ACP_I2S_COMP2_CAP_REG_OFFSET; + + adev->acp.acp_res[0].name = "acp2x_dma"; + adev->acp.acp_res[0].flags = IORESOURCE_MEM; + adev->acp.acp_res[0].start = acp_base; + adev->acp.acp_res[0].end = acp_base + ACP_DMA_REGS_END; + + adev->acp.acp_res[1].name = "acp2x_dw_i2s_play"; + adev->acp.acp_res[1].flags = IORESOURCE_MEM; + adev->acp.acp_res[1].start = acp_base + ACP_I2S_PLAY_REGS_START; + adev->acp.acp_res[1].end = acp_base + ACP_I2S_PLAY_REGS_END; + + adev->acp.acp_res[2].name = "acp2x_dw_i2s_cap"; + adev->acp.acp_res[2].flags = IORESOURCE_MEM; + adev->acp.acp_res[2].start = acp_base + ACP_I2S_CAP_REGS_START; + adev->acp.acp_res[2].end = acp_base + ACP_I2S_CAP_REGS_END; + + adev->acp.acp_res[3].name = "acp2x_dma_irq"; + adev->acp.acp_res[3].flags = IORESOURCE_IRQ; + adev->acp.acp_res[3].start = amdgpu_irq_create_mapping(adev, 162); + adev->acp.acp_res[3].end = adev->acp.acp_res[3].start; + + adev->acp.acp_cell[0].name = "acp_audio_dma"; + adev->acp.acp_cell[0].num_resources = 4; + adev->acp.acp_cell[0].resources = &adev->acp.acp_res[0]; + + adev->acp.acp_cell[1].name = "designware-i2s"; + adev->acp.acp_cell[1].num_resources = 1; + adev->acp.acp_cell[1].resources = &adev->acp.acp_res[1]; + adev->acp.acp_cell[1].platform_data = &i2s_pdata[0]; + adev->acp.acp_cell[1].pdata_size = sizeof(struct i2s_platform_data); + + adev->acp.acp_cell[2].name = "designware-i2s"; + adev->acp.acp_cell[2].num_resources = 1; + adev->acp.acp_cell[2].resources = &adev->acp.acp_res[2]; + adev->acp.acp_cell[2].platform_data = &i2s_pdata[1]; + adev->acp.acp_cell[2].pdata_size = sizeof(struct i2s_platform_data); + + r = mfd_add_hotplug_devices(adev->acp.parent, adev->acp.acp_cell, + ACP_DEVS); + if (r) + return r; + + for (i = 0; i < ACP_DEVS ; i++) { + dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i); + r = pm_genpd_add_device(&adev->acp.acp_genpd->gpd, dev); + if (r) { + dev_err(dev, "Failed to add dev to genpd\n"); + return r; + } + } + + return 0; +} + +/** + * acp_hw_fini - stop the hardware block + * + * @adev: amdgpu_device pointer + * + */ +static int acp_hw_fini(void *handle) +{ + int i, ret; + struct device *dev; + + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + + for (i = 0; i < ACP_DEVS ; i++) { + dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i); + ret = pm_genpd_remove_device(&adev->acp.acp_genpd->gpd, dev); + /* If removal fails, dont giveup and try rest */ + if (ret) + dev_err(dev, "remove dev from genpd failed\n"); + } + + mfd_remove_devices(adev->acp.parent); + kfree(adev->acp.acp_res); + kfree(adev->acp.acp_genpd); + kfree(adev->acp.acp_cell); + + return 0; +} + +static int acp_suspend(void *handle) +{ + return 0; +} + +static int acp_resume(void *handle) +{ + int i, ret; + struct acp_pm_domain *apd; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + + /* SMU block will power on ACP irrespective of ACP runtime status. + * Power off explicitly based on genpd ACP runtime status so that ACP + * hw and ACP-genpd status are in sync. + * 'suspend_power_off' represents "Power status before system suspend" + */ + if (adev->acp.acp_genpd->gpd.suspend_power_off == true) { + apd = container_of(&adev->acp.acp_genpd->gpd, + struct acp_pm_domain, gpd); + + for (i = 4; i >= 0 ; i--) { + ret = acp_suspend_tile(apd->cgs_dev, ACP_TILE_P1 + i); + if (ret) + pr_err("ACP tile %d tile suspend failed\n", i); + } + } + return 0; +} + +static int acp_early_init(void *handle) +{ + return 0; +} + +static bool acp_is_idle(void *handle) +{ + return true; +} + +static int acp_wait_for_idle(void *handle) +{ + return 0; +} + +static int acp_soft_reset(void *handle) +{ + return 0; +} + +static void acp_print_status(void *handle) +{ + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + + dev_info(adev->dev, "ACP STATUS\n"); +} + +static int acp_set_clockgating_state(void *handle, + enum amd_clockgating_state state) +{ + return 0; +} + +static int acp_set_powergating_state(void *handle, + enum amd_powergating_state state) +{ + return 0; +} + +const struct amd_ip_funcs acp_ip_funcs = { + .early_init = acp_early_init, + .late_init = NULL, + .sw_init = acp_sw_init, + .sw_fini = acp_sw_fini, + .hw_init = acp_hw_init, + .hw_fini = acp_hw_fini, + .suspend = acp_suspend, + .resume = acp_resume, + .is_idle = acp_is_idle, + .wait_for_idle = acp_wait_for_idle, + .soft_reset = acp_soft_reset, + .print_status = acp_print_status, + .set_clockgating_state = acp_set_clockgating_state, + .set_powergating_state = acp_set_powergating_state, +}; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.h new file mode 100644 index 0000000000000000000000000000000000000000..f6e32a63910749d47fe852ebd57aa666241dad79 --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.h @@ -0,0 +1,42 @@ +/* + * Copyright 2015 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: AMD + * + */ + +#ifndef __AMDGPU_ACP_H__ +#define __AMDGPU_ACP_H__ + +#include + +struct amdgpu_acp { + struct device *parent; + void *cgs_device; + struct amd_acp_private *private; + struct mfd_cell *acp_cell; + struct resource *acp_res; + struct acp_pm_domain *acp_genpd; +}; + +extern const struct amd_ip_funcs acp_ip_funcs; + +#endif /* __AMDGPU_ACP_H__ */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c index 84d68d658f8a03653f3a60898671f775a210e904..32809f749903c2196cdd2a2fe2006a1bf3f2a0a9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c @@ -30,25 +30,38 @@ const struct kfd2kgd_calls *kfd2kgd; const struct kgd2kfd_calls *kgd2kfd; bool (*kgd2kfd_init_p)(unsigned, const struct kgd2kfd_calls**); -bool amdgpu_amdkfd_init(void) +int amdgpu_amdkfd_init(void) { + int ret; + #if defined(CONFIG_HSA_AMD_MODULE) - bool (*kgd2kfd_init_p)(unsigned, const struct kgd2kfd_calls**); + int (*kgd2kfd_init_p)(unsigned, const struct kgd2kfd_calls**); kgd2kfd_init_p = symbol_request(kgd2kfd_init); if (kgd2kfd_init_p == NULL) - return false; + return -ENOENT; + + ret = kgd2kfd_init_p(KFD_INTERFACE_VERSION, &kgd2kfd); + if (ret) { + symbol_put(kgd2kfd_init); + kgd2kfd = NULL; + } + +#elif defined(CONFIG_HSA_AMD) + ret = kgd2kfd_init(KFD_INTERFACE_VERSION, &kgd2kfd); + if (ret) + kgd2kfd = NULL; + +#else + ret = -ENOENT; #endif - return true; + + return ret; } bool amdgpu_amdkfd_load_interface(struct amdgpu_device *rdev) { -#if defined(CONFIG_HSA_AMD_MODULE) - bool (*kgd2kfd_init_p)(unsigned, const struct kgd2kfd_calls**); -#endif - switch (rdev->asic_type) { #ifdef CONFIG_DRM_AMDGPU_CIK case CHIP_KAVERI: @@ -62,35 +75,7 @@ bool amdgpu_amdkfd_load_interface(struct amdgpu_device *rdev) return false; } -#if defined(CONFIG_HSA_AMD_MODULE) - kgd2kfd_init_p = symbol_request(kgd2kfd_init); - - if (kgd2kfd_init_p == NULL) { - kfd2kgd = NULL; - return false; - } - - if (!kgd2kfd_init_p(KFD_INTERFACE_VERSION, &kgd2kfd)) { - symbol_put(kgd2kfd_init); - kfd2kgd = NULL; - kgd2kfd = NULL; - - return false; - } - return true; -#elif defined(CONFIG_HSA_AMD) - if (!kgd2kfd_init(KFD_INTERFACE_VERSION, &kgd2kfd)) { - kfd2kgd = NULL; - kgd2kfd = NULL; - return false; - } - - return true; -#else - kfd2kgd = NULL; - return false; -#endif } void amdgpu_amdkfd_fini(void) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h index a8be765542e64570762cd4c4d2f9e65dc329eac0..de530f68d4e3950d6ec4caf0a874945e79e116e0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h @@ -36,7 +36,7 @@ struct kgd_mem { void *cpu_ptr; }; -bool amdgpu_amdkfd_init(void); +int amdgpu_amdkfd_init(void); void amdgpu_amdkfd_fini(void); bool amdgpu_amdkfd_load_interface(struct amdgpu_device *rdev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c index 9416e0f5c1db2bf8c5601ddee999b1ade5efabc0..84b0ce39ee14d51014148e8b7a7f9f143e7b28d2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c @@ -1514,6 +1514,19 @@ int amdgpu_atombios_init_mc_reg_table(struct amdgpu_device *adev, return -EINVAL; } +bool amdgpu_atombios_has_gpu_virtualization_table(struct amdgpu_device *adev) +{ + int index = GetIndexIntoMasterTable(DATA, GPUVirtualizationInfo); + u8 frev, crev; + u16 data_offset, size; + + if (amdgpu_atom_parse_data_header(adev->mode_info.atom_context, index, &size, + &frev, &crev, &data_offset)) + return true; + + return false; +} + void amdgpu_atombios_scratch_regs_lock(struct amdgpu_device *adev, bool lock) { uint32_t bios_6_scratch; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h index 0ebb959ea43587d11fa4feb4f5b97ce248a2aa7f..9e1442053fe4ffb72e1ff47c6a8fb5bc91d09533 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h @@ -196,6 +196,8 @@ int amdgpu_atombios_init_mc_reg_table(struct amdgpu_device *adev, u8 module_index, struct atom_mc_reg_table *reg_table); +bool amdgpu_atombios_has_gpu_virtualization_table(struct amdgpu_device *adev); + void amdgpu_atombios_scratch_regs_lock(struct amdgpu_device *adev, bool lock); void amdgpu_atombios_scratch_regs_init(struct amdgpu_device *adev); void amdgpu_atombios_scratch_regs_save(struct amdgpu_device *adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c index 3c895863fcf50e9d4cbe15cd23d51b10b8da6f3c..0020a0ea43ffbfe029e0501f955a3054c2480881 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c @@ -63,6 +63,10 @@ bool amdgpu_has_atpx(void) { return amdgpu_atpx_priv.atpx_detected; } +bool amdgpu_has_atpx_dgpu_power_cntl(void) { + return amdgpu_atpx_priv.atpx.functions.power_cntl; +} + /** * amdgpu_atpx_call - call an ATPX method * @@ -142,10 +146,6 @@ static void amdgpu_atpx_parse_functions(struct amdgpu_atpx_functions *f, u32 mas */ static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx) { - /* make sure required functions are enabled */ - /* dGPU power control is required */ - atpx->functions.power_cntl = true; - if (atpx->functions.px_params) { union acpi_object *info; struct atpx_px_params output; @@ -552,13 +552,14 @@ static bool amdgpu_atpx_detect(void) void amdgpu_register_atpx_handler(void) { bool r; + enum vga_switcheroo_handler_flags_t handler_flags = 0; /* detect if we have any ATPX + 2 VGA in the system */ r = amdgpu_atpx_detect(); if (!r) return; - vga_switcheroo_register_handler(&amdgpu_atpx_handler); + vga_switcheroo_register_handler(&amdgpu_atpx_handler, handler_flags); } /** diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c index f82a2dd83874dea20c7e7b2a6ddf8aee74e0fe1d..eacd810fc09b12d43607e0f00e77acdd87a5b768 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c @@ -32,6 +32,9 @@ #include "amdgpu.h" #include "amdgpu_trace.h" +#define AMDGPU_BO_LIST_MAX_PRIORITY 32u +#define AMDGPU_BO_LIST_NUM_BUCKETS (AMDGPU_BO_LIST_MAX_PRIORITY + 1) + static int amdgpu_bo_list_create(struct amdgpu_fpriv *fpriv, struct amdgpu_bo_list **result, int *id) @@ -88,8 +91,9 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev, struct amdgpu_bo *gws_obj = adev->gds.gws_gfx_bo; struct amdgpu_bo *oa_obj = adev->gds.oa_gfx_bo; - bool has_userptr = false; + unsigned last_entry = 0, first_userptr = num_entries; unsigned i; + int r; array = drm_malloc_ab(num_entries, sizeof(struct amdgpu_bo_list_entry)); if (!array) @@ -97,33 +101,43 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev, memset(array, 0, num_entries * sizeof(struct amdgpu_bo_list_entry)); for (i = 0; i < num_entries; ++i) { - struct amdgpu_bo_list_entry *entry = &array[i]; + struct amdgpu_bo_list_entry *entry; struct drm_gem_object *gobj; + struct amdgpu_bo *bo; + struct mm_struct *usermm; gobj = drm_gem_object_lookup(adev->ddev, filp, info[i].bo_handle); - if (!gobj) + if (!gobj) { + r = -ENOENT; goto error_free; + } - entry->robj = amdgpu_bo_ref(gem_to_amdgpu_bo(gobj)); + bo = amdgpu_bo_ref(gem_to_amdgpu_bo(gobj)); drm_gem_object_unreference_unlocked(gobj); - entry->priority = info[i].bo_priority; - entry->prefered_domains = entry->robj->initial_domain; - entry->allowed_domains = entry->prefered_domains; - if (entry->allowed_domains == AMDGPU_GEM_DOMAIN_VRAM) - entry->allowed_domains |= AMDGPU_GEM_DOMAIN_GTT; - if (amdgpu_ttm_tt_has_userptr(entry->robj->tbo.ttm)) { - has_userptr = true; - entry->prefered_domains = AMDGPU_GEM_DOMAIN_GTT; - entry->allowed_domains = AMDGPU_GEM_DOMAIN_GTT; + + usermm = amdgpu_ttm_tt_get_usermm(bo->tbo.ttm); + if (usermm) { + if (usermm != current->mm) { + amdgpu_bo_unref(&bo); + r = -EPERM; + goto error_free; + } + entry = &array[--first_userptr]; + } else { + entry = &array[last_entry++]; } + + entry->robj = bo; + entry->priority = min(info[i].bo_priority, + AMDGPU_BO_LIST_MAX_PRIORITY); entry->tv.bo = &entry->robj->tbo; entry->tv.shared = true; - if (entry->prefered_domains == AMDGPU_GEM_DOMAIN_GDS) + if (entry->robj->prefered_domains == AMDGPU_GEM_DOMAIN_GDS) gds_obj = entry->robj; - if (entry->prefered_domains == AMDGPU_GEM_DOMAIN_GWS) + if (entry->robj->prefered_domains == AMDGPU_GEM_DOMAIN_GWS) gws_obj = entry->robj; - if (entry->prefered_domains == AMDGPU_GEM_DOMAIN_OA) + if (entry->robj->prefered_domains == AMDGPU_GEM_DOMAIN_OA) oa_obj = entry->robj; trace_amdgpu_bo_list_set(list, entry->robj); @@ -137,15 +151,17 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev, list->gds_obj = gds_obj; list->gws_obj = gws_obj; list->oa_obj = oa_obj; - list->has_userptr = has_userptr; + list->first_userptr = first_userptr; list->array = array; list->num_entries = num_entries; return 0; error_free: + while (i--) + amdgpu_bo_unref(&array[i].robj); drm_free_large(array); - return -ENOENT; + return r; } struct amdgpu_bo_list * @@ -161,6 +177,37 @@ amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id) return result; } +void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list, + struct list_head *validated) +{ + /* This is based on the bucket sort with O(n) time complexity. + * An item with priority "i" is added to bucket[i]. The lists are then + * concatenated in descending order. + */ + struct list_head bucket[AMDGPU_BO_LIST_NUM_BUCKETS]; + unsigned i; + + for (i = 0; i < AMDGPU_BO_LIST_NUM_BUCKETS; i++) + INIT_LIST_HEAD(&bucket[i]); + + /* Since buffers which appear sooner in the relocation list are + * likely to be used more often than buffers which appear later + * in the list, the sort mustn't change the ordering of buffers + * with the same priority, i.e. it must be stable. + */ + for (i = 0; i < list->num_entries; i++) { + unsigned priority = list->array[i].priority; + + list_add_tail(&list->array[i].tv.head, + &bucket[priority]); + list->array[i].user_pages = NULL; + } + + /* Connect the sorted buckets in the output list. */ + for (i = 0; i < AMDGPU_BO_LIST_NUM_BUCKETS; i++) + list_splice(&bucket[i], validated); +} + void amdgpu_bo_list_put(struct amdgpu_bo_list *list) { mutex_unlock(&list->lock); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c index 7a4b101e10c63564aa3b0b8fffc638c171c1d199..6043dc7c3a94d75350a6e8760376b772f0fc4baf 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c @@ -816,10 +816,13 @@ static int amdgpu_cgs_get_active_displays_info(void *cgs_device, struct drm_device *ddev = adev->ddev; struct drm_crtc *crtc; uint32_t line_time_us, vblank_lines; + struct cgs_mode_info *mode_info; if (info == NULL) return -EINVAL; + mode_info = info->mode_info; + if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) { list_for_each_entry(crtc, &ddev->mode_config.crtc_list, head) { @@ -828,7 +831,7 @@ static int amdgpu_cgs_get_active_displays_info(void *cgs_device, info->active_display_mask |= (1 << amdgpu_crtc->crtc_id); info->display_count++; } - if (info->mode_info != NULL && + if (mode_info != NULL && crtc->enabled && amdgpu_crtc->enabled && amdgpu_crtc->hw_mode.clock) { line_time_us = (amdgpu_crtc->hw_mode.crtc_htotal * 1000) / @@ -836,10 +839,10 @@ static int amdgpu_cgs_get_active_displays_info(void *cgs_device, vblank_lines = amdgpu_crtc->hw_mode.crtc_vblank_end - amdgpu_crtc->hw_mode.crtc_vdisplay + (amdgpu_crtc->v_border * 2); - info->mode_info->vblank_time_us = vblank_lines * line_time_us; - info->mode_info->refresh_rate = drm_mode_vrefresh(&amdgpu_crtc->hw_mode); - info->mode_info->ref_clock = adev->clock.spll.reference_freq; - info->mode_info++; + mode_info->vblank_time_us = vblank_lines * line_time_us; + mode_info->refresh_rate = drm_mode_vrefresh(&amdgpu_crtc->hw_mode); + mode_info->ref_clock = adev->clock.spll.reference_freq; + mode_info = NULL; } } } @@ -847,6 +850,16 @@ static int amdgpu_cgs_get_active_displays_info(void *cgs_device, return 0; } + +static int amdgpu_cgs_notify_dpm_enabled(void *cgs_device, bool enabled) +{ + CGS_FUNC_ADEV; + + adev->pm.dpm_enabled = enabled; + + return 0; +} + /** \brief evaluate acpi namespace object, handle or pathname must be valid * \param cgs_device * \param info input/output arguments for the control method @@ -1097,6 +1110,7 @@ static const struct cgs_ops amdgpu_cgs_ops = { amdgpu_cgs_set_powergating_state, amdgpu_cgs_set_clockgating_state, amdgpu_cgs_get_active_displays_info, + amdgpu_cgs_notify_dpm_enabled, amdgpu_cgs_call_acpi_method, amdgpu_cgs_query_system_info, }; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index b882e8175615fba482ac9c8b8f29561e7549dc18..9392e50a7ba48243ad0d26e3385e57f3603bdd83 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -25,52 +25,12 @@ * Jerome Glisse */ #include +#include #include #include #include "amdgpu.h" #include "amdgpu_trace.h" -#define AMDGPU_CS_MAX_PRIORITY 32u -#define AMDGPU_CS_NUM_BUCKETS (AMDGPU_CS_MAX_PRIORITY + 1) - -/* This is based on the bucket sort with O(n) time complexity. - * An item with priority "i" is added to bucket[i]. The lists are then - * concatenated in descending order. - */ -struct amdgpu_cs_buckets { - struct list_head bucket[AMDGPU_CS_NUM_BUCKETS]; -}; - -static void amdgpu_cs_buckets_init(struct amdgpu_cs_buckets *b) -{ - unsigned i; - - for (i = 0; i < AMDGPU_CS_NUM_BUCKETS; i++) - INIT_LIST_HEAD(&b->bucket[i]); -} - -static void amdgpu_cs_buckets_add(struct amdgpu_cs_buckets *b, - struct list_head *item, unsigned priority) -{ - /* Since buffers which appear sooner in the relocation list are - * likely to be used more often than buffers which appear later - * in the list, the sort mustn't change the ordering of buffers - * with the same priority, i.e. it must be stable. - */ - list_add_tail(item, &b->bucket[min(priority, AMDGPU_CS_MAX_PRIORITY)]); -} - -static void amdgpu_cs_buckets_get_list(struct amdgpu_cs_buckets *b, - struct list_head *out_list) -{ - unsigned i; - - /* Connect the sorted buckets in the output list. */ - for (i = 0; i < AMDGPU_CS_NUM_BUCKETS; i++) { - list_splice(&b->bucket[i], out_list); - } -} - int amdgpu_cs_get_ring(struct amdgpu_device *adev, u32 ip_type, u32 ip_instance, u32 ring, struct amdgpu_ring **out_ring) @@ -128,6 +88,7 @@ int amdgpu_cs_get_ring(struct amdgpu_device *adev, u32 ip_type, } static int amdgpu_cs_user_fence_chunk(struct amdgpu_cs_parser *p, + struct amdgpu_user_fence *uf, struct drm_amdgpu_cs_chunk_fence *fence_data) { struct drm_gem_object *gobj; @@ -139,20 +100,19 @@ static int amdgpu_cs_user_fence_chunk(struct amdgpu_cs_parser *p, if (gobj == NULL) return -EINVAL; - p->uf.bo = amdgpu_bo_ref(gem_to_amdgpu_bo(gobj)); - p->uf.offset = fence_data->offset; + uf->bo = amdgpu_bo_ref(gem_to_amdgpu_bo(gobj)); + uf->offset = fence_data->offset; - if (amdgpu_ttm_tt_has_userptr(p->uf.bo->tbo.ttm)) { + if (amdgpu_ttm_tt_get_usermm(uf->bo->tbo.ttm)) { drm_gem_object_unreference_unlocked(gobj); return -EINVAL; } - p->uf_entry.robj = amdgpu_bo_ref(p->uf.bo); - p->uf_entry.prefered_domains = AMDGPU_GEM_DOMAIN_GTT; - p->uf_entry.allowed_domains = AMDGPU_GEM_DOMAIN_GTT; + p->uf_entry.robj = amdgpu_bo_ref(uf->bo); p->uf_entry.priority = 0; p->uf_entry.tv.bo = &p->uf_entry.robj->tbo; p->uf_entry.tv.shared = true; + p->uf_entry.user_pages = NULL; drm_gem_object_unreference_unlocked(gobj); return 0; @@ -160,11 +120,12 @@ static int amdgpu_cs_user_fence_chunk(struct amdgpu_cs_parser *p, int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) { + struct amdgpu_fpriv *fpriv = p->filp->driver_priv; union drm_amdgpu_cs *cs = data; uint64_t *chunk_array_user; uint64_t *chunk_array; - struct amdgpu_fpriv *fpriv = p->filp->driver_priv; - unsigned size; + struct amdgpu_user_fence uf = {}; + unsigned size, num_ibs = 0; int i; int ret; @@ -181,15 +142,12 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) goto free_chunk; } - p->bo_list = amdgpu_bo_list_get(fpriv, cs->in.bo_list_handle); - /* get chunks */ - INIT_LIST_HEAD(&p->validated); chunk_array_user = (uint64_t __user *)(unsigned long)(cs->in.chunks); if (copy_from_user(chunk_array, chunk_array_user, sizeof(uint64_t)*cs->in.num_chunks)) { ret = -EFAULT; - goto put_bo_list; + goto put_ctx; } p->nchunks = cs->in.num_chunks; @@ -197,7 +155,7 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) GFP_KERNEL); if (!p->chunks) { ret = -ENOMEM; - goto put_bo_list; + goto put_ctx; } for (i = 0; i < p->nchunks; i++) { @@ -217,7 +175,6 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) size = p->chunks[i].length_dw; cdata = (void __user *)(unsigned long)user_chunk.chunk_data; - p->chunks[i].user_ptr = cdata; p->chunks[i].kdata = drm_malloc_ab(size, sizeof(uint32_t)); if (p->chunks[i].kdata == NULL) { @@ -233,7 +190,7 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) switch (p->chunks[i].chunk_id) { case AMDGPU_CHUNK_ID_IB: - p->num_ibs++; + ++num_ibs; break; case AMDGPU_CHUNK_ID_FENCE: @@ -243,7 +200,7 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) goto free_partial_kdata; } - ret = amdgpu_cs_user_fence_chunk(p, (void *)p->chunks[i].kdata); + ret = amdgpu_cs_user_fence_chunk(p, &uf, (void *)p->chunks[i].kdata); if (ret) goto free_partial_kdata; @@ -258,12 +215,11 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) } } - - p->ibs = kcalloc(p->num_ibs, sizeof(struct amdgpu_ib), GFP_KERNEL); - if (!p->ibs) { - ret = -ENOMEM; + ret = amdgpu_job_alloc(p->adev, num_ibs, &p->job); + if (ret) goto free_all_kdata; - } + + p->job->uf = uf; kfree(chunk_array); return 0; @@ -274,9 +230,7 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) for (; i >= 0; i--) drm_free_large(p->chunks[i].kdata); kfree(p->chunks); -put_bo_list: - if (p->bo_list) - amdgpu_bo_list_put(p->bo_list); +put_ctx: amdgpu_ctx_put(p->ctx); free_chunk: kfree(chunk_array); @@ -336,96 +290,198 @@ static u64 amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev) return max(bytes_moved_threshold, 1024*1024ull); } -int amdgpu_cs_list_validate(struct amdgpu_device *adev, - struct amdgpu_vm *vm, +int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p, struct list_head *validated) { struct amdgpu_bo_list_entry *lobj; - struct amdgpu_bo *bo; - u64 bytes_moved = 0, initial_bytes_moved; - u64 bytes_moved_threshold = amdgpu_cs_get_threshold_for_moves(adev); + u64 initial_bytes_moved; int r; list_for_each_entry(lobj, validated, tv.head) { - bo = lobj->robj; - if (!bo->pin_count) { - u32 domain = lobj->prefered_domains; - u32 current_domain = - amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type); - - /* Check if this buffer will be moved and don't move it - * if we have moved too many buffers for this IB already. - * - * Note that this allows moving at least one buffer of - * any size, because it doesn't take the current "bo" - * into account. We don't want to disallow buffer moves - * completely. - */ - if ((lobj->allowed_domains & current_domain) != 0 && - (domain & current_domain) == 0 && /* will be moved */ - bytes_moved > bytes_moved_threshold) { - /* don't move it */ - domain = current_domain; - } + struct amdgpu_bo *bo = lobj->robj; + bool binding_userptr = false; + struct mm_struct *usermm; + uint32_t domain; + + usermm = amdgpu_ttm_tt_get_usermm(bo->tbo.ttm); + if (usermm && usermm != current->mm) + return -EPERM; + + /* Check if we have user pages and nobody bound the BO already */ + if (lobj->user_pages && bo->tbo.ttm->state != tt_bound) { + size_t size = sizeof(struct page *); + + size *= bo->tbo.ttm->num_pages; + memcpy(bo->tbo.ttm->pages, lobj->user_pages, size); + binding_userptr = true; + } - retry: - amdgpu_ttm_placement_from_domain(bo, domain); - initial_bytes_moved = atomic64_read(&adev->num_bytes_moved); - r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false); - bytes_moved += atomic64_read(&adev->num_bytes_moved) - - initial_bytes_moved; - - if (unlikely(r)) { - if (r != -ERESTARTSYS && domain != lobj->allowed_domains) { - domain = lobj->allowed_domains; - goto retry; - } - return r; + if (bo->pin_count) + continue; + + /* Avoid moving this one if we have moved too many buffers + * for this IB already. + * + * Note that this allows moving at least one buffer of + * any size, because it doesn't take the current "bo" + * into account. We don't want to disallow buffer moves + * completely. + */ + if (p->bytes_moved <= p->bytes_moved_threshold) + domain = bo->prefered_domains; + else + domain = bo->allowed_domains; + + retry: + amdgpu_ttm_placement_from_domain(bo, domain); + initial_bytes_moved = atomic64_read(&bo->adev->num_bytes_moved); + r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false); + p->bytes_moved += atomic64_read(&bo->adev->num_bytes_moved) - + initial_bytes_moved; + + if (unlikely(r)) { + if (r != -ERESTARTSYS && domain != bo->allowed_domains) { + domain = bo->allowed_domains; + goto retry; } + return r; + } + + if (binding_userptr) { + drm_free_large(lobj->user_pages); + lobj->user_pages = NULL; } - lobj->bo_va = amdgpu_vm_bo_find(vm, bo); } return 0; } -static int amdgpu_cs_parser_relocs(struct amdgpu_cs_parser *p) +static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, + union drm_amdgpu_cs *cs) { struct amdgpu_fpriv *fpriv = p->filp->driver_priv; - struct amdgpu_cs_buckets buckets; + struct amdgpu_bo_list_entry *e; struct list_head duplicates; bool need_mmap_lock = false; - int i, r; + unsigned i, tries = 10; + int r; - if (p->bo_list) { - need_mmap_lock = p->bo_list->has_userptr; - amdgpu_cs_buckets_init(&buckets); - for (i = 0; i < p->bo_list->num_entries; i++) - amdgpu_cs_buckets_add(&buckets, &p->bo_list->array[i].tv.head, - p->bo_list->array[i].priority); + INIT_LIST_HEAD(&p->validated); - amdgpu_cs_buckets_get_list(&buckets, &p->validated); + p->bo_list = amdgpu_bo_list_get(fpriv, cs->in.bo_list_handle); + if (p->bo_list) { + need_mmap_lock = p->bo_list->first_userptr != + p->bo_list->num_entries; + amdgpu_bo_list_get_list(p->bo_list, &p->validated); } INIT_LIST_HEAD(&duplicates); amdgpu_vm_get_pd_bo(&fpriv->vm, &p->validated, &p->vm_pd); - if (p->uf.bo) + if (p->job->uf.bo) list_add(&p->uf_entry.tv.head, &p->validated); if (need_mmap_lock) down_read(¤t->mm->mmap_sem); - r = ttm_eu_reserve_buffers(&p->ticket, &p->validated, true, &duplicates); - if (unlikely(r != 0)) - goto error_reserve; + while (1) { + struct list_head need_pages; + unsigned i; + + r = ttm_eu_reserve_buffers(&p->ticket, &p->validated, true, + &duplicates); + if (unlikely(r != 0)) + goto error_free_pages; + + /* Without a BO list we don't have userptr BOs */ + if (!p->bo_list) + break; + + INIT_LIST_HEAD(&need_pages); + for (i = p->bo_list->first_userptr; + i < p->bo_list->num_entries; ++i) { + + e = &p->bo_list->array[i]; + + if (amdgpu_ttm_tt_userptr_invalidated(e->robj->tbo.ttm, + &e->user_invalidated) && e->user_pages) { + + /* We acquired a page array, but somebody + * invalidated it. Free it an try again + */ + release_pages(e->user_pages, + e->robj->tbo.ttm->num_pages, + false); + drm_free_large(e->user_pages); + e->user_pages = NULL; + } + + if (e->robj->tbo.ttm->state != tt_bound && + !e->user_pages) { + list_del(&e->tv.head); + list_add(&e->tv.head, &need_pages); + + amdgpu_bo_unreserve(e->robj); + } + } + + if (list_empty(&need_pages)) + break; + + /* Unreserve everything again. */ + ttm_eu_backoff_reservation(&p->ticket, &p->validated); + + /* We tried to often, just abort */ + if (!--tries) { + r = -EDEADLK; + goto error_free_pages; + } + + /* Fill the page arrays for all useptrs. */ + list_for_each_entry(e, &need_pages, tv.head) { + struct ttm_tt *ttm = e->robj->tbo.ttm; + + e->user_pages = drm_calloc_large(ttm->num_pages, + sizeof(struct page*)); + if (!e->user_pages) { + r = -ENOMEM; + goto error_free_pages; + } + + r = amdgpu_ttm_tt_get_user_pages(ttm, e->user_pages); + if (r) { + drm_free_large(e->user_pages); + e->user_pages = NULL; + goto error_free_pages; + } + } + + /* And try again. */ + list_splice(&need_pages, &p->validated); + } amdgpu_vm_get_pt_bos(&fpriv->vm, &duplicates); - r = amdgpu_cs_list_validate(p->adev, &fpriv->vm, &duplicates); + p->bytes_moved_threshold = amdgpu_cs_get_threshold_for_moves(p->adev); + p->bytes_moved = 0; + + r = amdgpu_cs_list_validate(p, &duplicates); + if (r) + goto error_validate; + + r = amdgpu_cs_list_validate(p, &p->validated); if (r) goto error_validate; - r = amdgpu_cs_list_validate(p->adev, &fpriv->vm, &p->validated); + if (p->bo_list) { + struct amdgpu_vm *vm = &fpriv->vm; + unsigned i; + + for (i = 0; i < p->bo_list->num_entries; i++) { + struct amdgpu_bo *bo = p->bo_list->array[i].robj; + + p->bo_list->array[i].bo_va = amdgpu_vm_bo_find(vm, bo); + } + } error_validate: if (r) { @@ -433,10 +489,26 @@ static int amdgpu_cs_parser_relocs(struct amdgpu_cs_parser *p) ttm_eu_backoff_reservation(&p->ticket, &p->validated); } -error_reserve: +error_free_pages: + if (need_mmap_lock) up_read(¤t->mm->mmap_sem); + if (p->bo_list) { + for (i = p->bo_list->first_userptr; + i < p->bo_list->num_entries; ++i) { + e = &p->bo_list->array[i]; + + if (!e->user_pages) + continue; + + release_pages(e->user_pages, + e->robj->tbo.ttm->num_pages, + false); + drm_free_large(e->user_pages); + } + } + return r; } @@ -447,7 +519,7 @@ static int amdgpu_cs_sync_rings(struct amdgpu_cs_parser *p) list_for_each_entry(e, &p->validated, tv.head) { struct reservation_object *resv = e->robj->tbo.resv; - r = amdgpu_sync_resv(p->adev, &p->ibs[0].sync, resv, p->filp); + r = amdgpu_sync_resv(p->adev, &p->job->sync, resv, p->filp); if (r) return r; @@ -510,11 +582,8 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bo for (i = 0; i < parser->nchunks; i++) drm_free_large(parser->chunks[i].kdata); kfree(parser->chunks); - if (parser->ibs) - for (i = 0; i < parser->num_ibs; i++) - amdgpu_ib_free(parser->adev, &parser->ibs[i]); - kfree(parser->ibs); - amdgpu_bo_unref(&parser->uf.bo); + if (parser->job) + amdgpu_job_free(parser->job); amdgpu_bo_unref(&parser->uf_entry.robj); } @@ -530,7 +599,7 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p, if (r) return r; - r = amdgpu_sync_fence(adev, &p->ibs[0].sync, vm->page_directory_fence); + r = amdgpu_sync_fence(adev, &p->job->sync, vm->page_directory_fence); if (r) return r; @@ -556,14 +625,14 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p, return r; f = bo_va->last_pt_update; - r = amdgpu_sync_fence(adev, &p->ibs[0].sync, f); + r = amdgpu_sync_fence(adev, &p->job->sync, f); if (r) return r; } } - r = amdgpu_vm_clear_invalids(adev, vm, &p->ibs[0].sync); + r = amdgpu_vm_clear_invalids(adev, vm, &p->job->sync); if (amdgpu_vm_debug && p->bo_list) { /* Invalidate all BOs to test for userspace bugs */ @@ -581,29 +650,25 @@ static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p, } static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev, - struct amdgpu_cs_parser *parser) + struct amdgpu_cs_parser *p) { - struct amdgpu_fpriv *fpriv = parser->filp->driver_priv; + struct amdgpu_fpriv *fpriv = p->filp->driver_priv; struct amdgpu_vm *vm = &fpriv->vm; - struct amdgpu_ring *ring; + struct amdgpu_ring *ring = p->job->ring; int i, r; - if (parser->num_ibs == 0) - return 0; - /* Only for UVD/VCE VM emulation */ - for (i = 0; i < parser->num_ibs; i++) { - ring = parser->ibs[i].ring; - if (ring->funcs->parse_cs) { - r = amdgpu_ring_parse_cs(ring, parser, i); + if (ring->funcs->parse_cs) { + for (i = 0; i < p->job->num_ibs; i++) { + r = amdgpu_ring_parse_cs(ring, p, i); if (r) return r; } } - r = amdgpu_bo_vm_update_pte(parser, vm); + r = amdgpu_bo_vm_update_pte(p, vm); if (!r) - amdgpu_cs_sync_rings(parser); + amdgpu_cs_sync_rings(p); return r; } @@ -626,14 +691,14 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev, int i, j; int r; - for (i = 0, j = 0; i < parser->nchunks && j < parser->num_ibs; i++) { + for (i = 0, j = 0; i < parser->nchunks && j < parser->job->num_ibs; i++) { struct amdgpu_cs_chunk *chunk; struct amdgpu_ib *ib; struct drm_amdgpu_cs_chunk_ib *chunk_ib; struct amdgpu_ring *ring; chunk = &parser->chunks[i]; - ib = &parser->ibs[j]; + ib = &parser->job->ibs[j]; chunk_ib = (struct drm_amdgpu_cs_chunk_ib *)chunk->kdata; if (chunk->chunk_id != AMDGPU_CHUNK_ID_IB) @@ -645,6 +710,11 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev, if (r) return r; + if (parser->job->ring && parser->job->ring != ring) + return -EINVAL; + + parser->job->ring = ring; + if (ring->funcs->parse_cs) { struct amdgpu_bo_va_mapping *m; struct amdgpu_bo *aobj = NULL; @@ -673,7 +743,7 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev, offset = ((uint64_t)m->it.start) * AMDGPU_GPU_PAGE_SIZE; kptr += chunk_ib->va_start - offset; - r = amdgpu_ib_get(ring, NULL, chunk_ib->ib_bytes, ib); + r = amdgpu_ib_get(adev, NULL, chunk_ib->ib_bytes, ib); if (r) { DRM_ERROR("Failed to get ib !\n"); return r; @@ -682,7 +752,7 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev, memcpy(ib->ptr, kptr, chunk_ib->ib_bytes); amdgpu_bo_kunmap(aobj); } else { - r = amdgpu_ib_get(ring, vm, 0, ib); + r = amdgpu_ib_get(adev, vm, 0, ib); if (r) { DRM_ERROR("Failed to get ib !\n"); return r; @@ -697,15 +767,12 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev, j++; } - if (!parser->num_ibs) - return 0; - /* add GDS resources to first IB */ if (parser->bo_list) { struct amdgpu_bo *gds = parser->bo_list->gds_obj; struct amdgpu_bo *gws = parser->bo_list->gws_obj; struct amdgpu_bo *oa = parser->bo_list->oa_obj; - struct amdgpu_ib *ib = &parser->ibs[0]; + struct amdgpu_ib *ib = &parser->job->ibs[0]; if (gds) { ib->gds_base = amdgpu_bo_gpu_offset(gds); @@ -721,15 +788,15 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev, } } /* wrap the last IB with user fence */ - if (parser->uf.bo) { - struct amdgpu_ib *ib = &parser->ibs[parser->num_ibs - 1]; + if (parser->job->uf.bo) { + struct amdgpu_ib *ib = &parser->job->ibs[parser->job->num_ibs - 1]; /* UVD & VCE fw doesn't support user fences */ - if (ib->ring->type == AMDGPU_RING_TYPE_UVD || - ib->ring->type == AMDGPU_RING_TYPE_VCE) + if (parser->job->ring->type == AMDGPU_RING_TYPE_UVD || + parser->job->ring->type == AMDGPU_RING_TYPE_VCE) return -EINVAL; - ib->user = &parser->uf; + ib->user = &parser->job->uf; } return 0; @@ -739,14 +806,8 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev, struct amdgpu_cs_parser *p) { struct amdgpu_fpriv *fpriv = p->filp->driver_priv; - struct amdgpu_ib *ib; int i, j, r; - if (!p->num_ibs) - return 0; - - /* Add dependencies to first IB */ - ib = &p->ibs[0]; for (i = 0; i < p->nchunks; ++i) { struct drm_amdgpu_cs_chunk_dep *deps; struct amdgpu_cs_chunk *chunk; @@ -784,7 +845,8 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev, return r; } else if (fence) { - r = amdgpu_sync_fence(adev, &ib->sync, fence); + r = amdgpu_sync_fence(adev, &p->job->sync, + fence); fence_put(fence); amdgpu_ctx_put(ctx); if (r) @@ -796,15 +858,36 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev, return 0; } -static int amdgpu_cs_free_job(struct amdgpu_job *job) +static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, + union drm_amdgpu_cs *cs) { - int i; - if (job->ibs) - for (i = 0; i < job->num_ibs; i++) - amdgpu_ib_free(job->adev, &job->ibs[i]); - kfree(job->ibs); - if (job->uf.bo) - amdgpu_bo_unref(&job->uf.bo); + struct amdgpu_ring *ring = p->job->ring; + struct amd_sched_fence *fence; + struct amdgpu_job *job; + + job = p->job; + p->job = NULL; + + job->base.sched = &ring->sched; + job->base.s_entity = &p->ctx->rings[ring->idx].entity; + job->owner = p->filp; + + fence = amd_sched_fence_create(job->base.s_entity, p->filp); + if (!fence) { + amdgpu_job_free(job); + return -ENOMEM; + } + + job->base.s_fence = fence; + p->fence = fence_get(&fence->base); + + cs->out.handle = amdgpu_ctx_add_fence(p->ctx, ring, + &fence->base); + job->ibs[job->num_ibs - 1].sequence = cs->out.handle; + + trace_amdgpu_cs_ioctl(job); + amd_sched_entity_push_job(&job->base); + return 0; } @@ -829,7 +912,7 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) r = amdgpu_cs_handle_lockup(adev, r); return r; } - r = amdgpu_cs_parser_relocs(&parser); + r = amdgpu_cs_parser_bos(&parser, data); if (r == -ENOMEM) DRM_ERROR("Not enough memory for command submission!\n"); else if (r && r != -ERESTARTSYS) @@ -848,68 +931,14 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) if (r) goto out; - for (i = 0; i < parser.num_ibs; i++) + for (i = 0; i < parser.job->num_ibs; i++) trace_amdgpu_cs(&parser, i); r = amdgpu_cs_ib_vm_chunk(adev, &parser); if (r) goto out; - if (amdgpu_enable_scheduler && parser.num_ibs) { - struct amdgpu_ring * ring = parser.ibs->ring; - struct amd_sched_fence *fence; - struct amdgpu_job *job; - - job = kzalloc(sizeof(struct amdgpu_job), GFP_KERNEL); - if (!job) { - r = -ENOMEM; - goto out; - } - - job->base.sched = &ring->sched; - job->base.s_entity = &parser.ctx->rings[ring->idx].entity; - job->adev = parser.adev; - job->owner = parser.filp; - job->free_job = amdgpu_cs_free_job; - - job->ibs = parser.ibs; - job->num_ibs = parser.num_ibs; - parser.ibs = NULL; - parser.num_ibs = 0; - - if (job->ibs[job->num_ibs - 1].user) { - job->uf = parser.uf; - job->ibs[job->num_ibs - 1].user = &job->uf; - parser.uf.bo = NULL; - } - - fence = amd_sched_fence_create(job->base.s_entity, - parser.filp); - if (!fence) { - r = -ENOMEM; - amdgpu_cs_free_job(job); - kfree(job); - goto out; - } - job->base.s_fence = fence; - parser.fence = fence_get(&fence->base); - - cs->out.handle = amdgpu_ctx_add_fence(parser.ctx, ring, - &fence->base); - job->ibs[job->num_ibs - 1].sequence = cs->out.handle; - - trace_amdgpu_cs_ioctl(job); - amd_sched_entity_push_job(&job->base); - - } else { - struct amdgpu_fence *fence; - - r = amdgpu_ib_schedule(adev, parser.num_ibs, parser.ibs, - parser.filp); - fence = parser.ibs[parser.num_ibs - 1].fence; - parser.fence = fence_get(&fence->base); - cs->out.handle = parser.ibs[parser.num_ibs - 1].sequence; - } + r = amdgpu_cs_submit(&parser, cs); out: amdgpu_cs_parser_fini(&parser, r, reserved_buffers); @@ -980,30 +1009,36 @@ struct amdgpu_bo_va_mapping * amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser, uint64_t addr, struct amdgpu_bo **bo) { - struct amdgpu_bo_list_entry *reloc; struct amdgpu_bo_va_mapping *mapping; + unsigned i; + + if (!parser->bo_list) + return NULL; addr /= AMDGPU_GPU_PAGE_SIZE; - list_for_each_entry(reloc, &parser->validated, tv.head) { - if (!reloc->bo_va) + for (i = 0; i < parser->bo_list->num_entries; i++) { + struct amdgpu_bo_list_entry *lobj; + + lobj = &parser->bo_list->array[i]; + if (!lobj->bo_va) continue; - list_for_each_entry(mapping, &reloc->bo_va->valids, list) { + list_for_each_entry(mapping, &lobj->bo_va->valids, list) { if (mapping->it.start > addr || addr > mapping->it.last) continue; - *bo = reloc->bo_va->bo; + *bo = lobj->bo_va->bo; return mapping; } - list_for_each_entry(mapping, &reloc->bo_va->invalids, list) { + list_for_each_entry(mapping, &lobj->bo_va->invalids, list) { if (mapping->it.start > addr || addr > mapping->it.last) continue; - *bo = reloc->bo_va->bo; + *bo = lobj->bo_va->bo; return mapping; } } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index 17d1fb12128a26dafbb0c9cd8bbf3ee2f0e05feb..17e13621fae96e3c9eef313cb9121c42ebc308ad 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c @@ -25,8 +25,7 @@ #include #include "amdgpu.h" -int amdgpu_ctx_init(struct amdgpu_device *adev, enum amd_sched_priority pri, - struct amdgpu_ctx *ctx) +static int amdgpu_ctx_init(struct amdgpu_device *adev, struct amdgpu_ctx *ctx) { unsigned i, j; int r; @@ -35,44 +34,38 @@ int amdgpu_ctx_init(struct amdgpu_device *adev, enum amd_sched_priority pri, ctx->adev = adev; kref_init(&ctx->refcount); spin_lock_init(&ctx->ring_lock); - ctx->fences = kzalloc(sizeof(struct fence *) * amdgpu_sched_jobs * - AMDGPU_MAX_RINGS, GFP_KERNEL); + ctx->fences = kcalloc(amdgpu_sched_jobs * AMDGPU_MAX_RINGS, + sizeof(struct fence*), GFP_KERNEL); if (!ctx->fences) return -ENOMEM; for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { ctx->rings[i].sequence = 1; - ctx->rings[i].fences = (void *)ctx->fences + sizeof(struct fence *) * - amdgpu_sched_jobs * i; + ctx->rings[i].fences = &ctx->fences[amdgpu_sched_jobs * i]; } - if (amdgpu_enable_scheduler) { - /* create context entity for each ring */ - for (i = 0; i < adev->num_rings; i++) { - struct amd_sched_rq *rq; - if (pri >= AMD_SCHED_MAX_PRIORITY) { - kfree(ctx->fences); - return -EINVAL; - } - rq = &adev->rings[i]->sched.sched_rq[pri]; - r = amd_sched_entity_init(&adev->rings[i]->sched, - &ctx->rings[i].entity, - rq, amdgpu_sched_jobs); - if (r) - break; - } - - if (i < adev->num_rings) { - for (j = 0; j < i; j++) - amd_sched_entity_fini(&adev->rings[j]->sched, - &ctx->rings[j].entity); - kfree(ctx->fences); - return r; - } + /* create context entity for each ring */ + for (i = 0; i < adev->num_rings; i++) { + struct amdgpu_ring *ring = adev->rings[i]; + struct amd_sched_rq *rq; + + rq = &ring->sched.sched_rq[AMD_SCHED_PRIORITY_NORMAL]; + r = amd_sched_entity_init(&ring->sched, &ctx->rings[i].entity, + rq, amdgpu_sched_jobs); + if (r) + break; + } + + if (i < adev->num_rings) { + for (j = 0; j < i; j++) + amd_sched_entity_fini(&adev->rings[j]->sched, + &ctx->rings[j].entity); + kfree(ctx->fences); + return r; } return 0; } -void amdgpu_ctx_fini(struct amdgpu_ctx *ctx) +static void amdgpu_ctx_fini(struct amdgpu_ctx *ctx) { struct amdgpu_device *adev = ctx->adev; unsigned i, j; @@ -85,11 +78,9 @@ void amdgpu_ctx_fini(struct amdgpu_ctx *ctx) fence_put(ctx->rings[i].fences[j]); kfree(ctx->fences); - if (amdgpu_enable_scheduler) { - for (i = 0; i < adev->num_rings; i++) - amd_sched_entity_fini(&adev->rings[i]->sched, - &ctx->rings[i].entity); - } + for (i = 0; i < adev->num_rings; i++) + amd_sched_entity_fini(&adev->rings[i]->sched, + &ctx->rings[i].entity); } static int amdgpu_ctx_alloc(struct amdgpu_device *adev, @@ -112,7 +103,7 @@ static int amdgpu_ctx_alloc(struct amdgpu_device *adev, return r; } *id = (uint32_t)r; - r = amdgpu_ctx_init(adev, AMD_SCHED_PRIORITY_NORMAL, ctx); + r = amdgpu_ctx_init(adev, ctx); if (r) { idr_remove(&mgr->ctx_handles, *id); *id = 0; @@ -200,18 +191,18 @@ int amdgpu_ctx_ioctl(struct drm_device *dev, void *data, id = args->in.ctx_id; switch (args->in.op) { - case AMDGPU_CTX_OP_ALLOC_CTX: - r = amdgpu_ctx_alloc(adev, fpriv, &id); - args->out.alloc.ctx_id = id; - break; - case AMDGPU_CTX_OP_FREE_CTX: - r = amdgpu_ctx_free(fpriv, id); - break; - case AMDGPU_CTX_OP_QUERY_STATE: - r = amdgpu_ctx_query(adev, fpriv, id, &args->out); - break; - default: - return -EINVAL; + case AMDGPU_CTX_OP_ALLOC_CTX: + r = amdgpu_ctx_alloc(adev, fpriv, &id); + args->out.alloc.ctx_id = id; + break; + case AMDGPU_CTX_OP_FREE_CTX: + r = amdgpu_ctx_free(fpriv, id); + break; + case AMDGPU_CTX_OP_QUERY_STATE: + r = amdgpu_ctx_query(adev, fpriv, id, &args->out); + break; + default: + return -EINVAL; } return r; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 51bfc114584ed5e2fcd086efed40b57f344d2c4f..612117478b5701a8b0ddbd76f3bdd36ea4099797 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -62,6 +62,12 @@ static const char *amdgpu_asic_name[] = { "LAST", }; +#if defined(CONFIG_VGA_SWITCHEROO) +bool amdgpu_has_atpx_dgpu_power_cntl(void); +#else +static inline bool amdgpu_has_atpx_dgpu_power_cntl(void) { return false; } +#endif + bool amdgpu_device_is_px(struct drm_device *dev) { struct amdgpu_device *adev = dev->dev_private; @@ -635,31 +641,6 @@ bool amdgpu_card_posted(struct amdgpu_device *adev) } -/** - * amdgpu_boot_test_post_card - check and possibly initialize the hw - * - * @adev: amdgpu_device pointer - * - * Check if the asic is initialized and if not, attempt to initialize - * it (all asics). - * Returns true if initialized or false if not. - */ -bool amdgpu_boot_test_post_card(struct amdgpu_device *adev) -{ - if (amdgpu_card_posted(adev)) - return true; - - if (adev->bios) { - DRM_INFO("GPU not posted. posting now...\n"); - if (adev->is_atom_bios) - amdgpu_atom_asic_init(adev->mode_info.atom_context); - return true; - } else { - dev_err(adev->dev, "Card not posted and no BIOS - ignoring\n"); - return false; - } -} - /** * amdgpu_dummy_page_init - init dummy page used by the driver * @@ -959,12 +940,6 @@ static void amdgpu_check_arguments(struct amdgpu_device *adev) amdgpu_sched_jobs); amdgpu_sched_jobs = roundup_pow_of_two(amdgpu_sched_jobs); } - /* vramlimit must be a power of two */ - if (!amdgpu_check_pot_argument(amdgpu_vram_limit)) { - dev_warn(adev->dev, "vram limit (%d) must be a power of 2\n", - amdgpu_vram_limit); - amdgpu_vram_limit = 0; - } if (amdgpu_gart_size != -1) { /* gtt size must be power of two and greater or equal to 32M */ @@ -1434,7 +1409,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, adev->mman.buffer_funcs = NULL; adev->mman.buffer_funcs_ring = NULL; adev->vm_manager.vm_pte_funcs = NULL; - adev->vm_manager.vm_pte_funcs_ring = NULL; + adev->vm_manager.vm_pte_num_rings = 0; adev->gart.gart_funcs = NULL; adev->fence_context = fence_context_alloc(AMDGPU_MAX_RINGS); @@ -1455,9 +1430,8 @@ int amdgpu_device_init(struct amdgpu_device *adev, /* mutex initialization are all done here so we * can recall function without having locking issues */ - mutex_init(&adev->ring_lock); + mutex_init(&adev->vm_manager.lock); atomic_set(&adev->irq.ih.lock, 0); - mutex_init(&adev->gem.mutex); mutex_init(&adev->pm.mutex); mutex_init(&adev->gfx.gpu_clock_mutex); mutex_init(&adev->srbm_mutex); @@ -1511,7 +1485,7 @@ int amdgpu_device_init(struct amdgpu_device *adev, if (amdgpu_runtime_pm == 1) runtime = true; - if (amdgpu_device_is_px(ddev)) + if (amdgpu_device_is_px(ddev) && amdgpu_has_atpx_dgpu_power_cntl()) runtime = true; vga_switcheroo_register_client(adev->pdev, &amdgpu_switcheroo_ops, runtime); if (runtime) @@ -1531,8 +1505,13 @@ int amdgpu_device_init(struct amdgpu_device *adev, return r; } + /* See if the asic supports SR-IOV */ + adev->virtualization.supports_sr_iov = + amdgpu_atombios_has_gpu_virtualization_table(adev); + /* Post card if necessary */ - if (!amdgpu_card_posted(adev)) { + if (!amdgpu_card_posted(adev) || + adev->virtualization.supports_sr_iov) { if (!adev->bios) { dev_err(adev->dev, "Card not posted and no BIOS - ignoring\n"); return -EINVAL; @@ -1577,11 +1556,6 @@ int amdgpu_device_init(struct amdgpu_device *adev, return r; } - r = amdgpu_ctx_init(adev, AMD_SCHED_PRIORITY_KERNEL, &adev->kernel_ctx); - if (r) { - dev_err(adev->dev, "failed to create kernel context (%d).\n", r); - return r; - } r = amdgpu_ib_ring_tests(adev); if (r) DRM_ERROR("ib ring test failed (%d).\n", r); @@ -1645,7 +1619,6 @@ void amdgpu_device_fini(struct amdgpu_device *adev) adev->shutdown = true; /* evict vram memory */ amdgpu_bo_evict_vram(adev); - amdgpu_ctx_fini(&adev->kernel_ctx); amdgpu_ib_pool_fini(adev); amdgpu_fence_driver_fini(adev); amdgpu_fbdev_fini(adev); @@ -1894,6 +1867,9 @@ int amdgpu_gpu_reset(struct amdgpu_device *adev) retry: r = amdgpu_asic_reset(adev); + /* post card */ + amdgpu_atom_asic_init(adev->mode_info.atom_context); + if (!r) { dev_info(adev->dev, "GPU reset succeeded, trying to resume\n"); r = amdgpu_resume(adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index 1846d65b72859284b31c536dc2fdc1a29cae0d9e..3fb405b3a61457e4622dfe4b788ac3925d088f4a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -35,32 +35,30 @@ #include #include -static void amdgpu_flip_wait_fence(struct amdgpu_device *adev, - struct fence **f) +static void amdgpu_flip_callback(struct fence *f, struct fence_cb *cb) { - struct amdgpu_fence *fence; - long r; + struct amdgpu_flip_work *work = + container_of(cb, struct amdgpu_flip_work, cb); - if (*f == NULL) - return; + fence_put(f); + schedule_work(&work->flip_work); +} - fence = to_amdgpu_fence(*f); - if (fence) { - r = fence_wait(&fence->base, false); - if (r == -EDEADLK) - r = amdgpu_gpu_reset(adev); - } else - r = fence_wait(*f, false); +static bool amdgpu_flip_handle_fence(struct amdgpu_flip_work *work, + struct fence **f) +{ + struct fence *fence= *f; - if (r) - DRM_ERROR("failed to wait on page flip fence (%ld)!\n", r); + if (fence == NULL) + return false; - /* We continue with the page flip even if we failed to wait on - * the fence, otherwise the DRM core and userspace will be - * confused about which BO the CRTC is scanning out - */ - fence_put(*f); *f = NULL; + + if (!fence_add_callback(fence, &work->cb, amdgpu_flip_callback)) + return true; + + fence_put(fence); + return false; } static void amdgpu_flip_work_func(struct work_struct *__work) @@ -76,9 +74,12 @@ static void amdgpu_flip_work_func(struct work_struct *__work) int vpos, hpos, stat, min_udelay = 0; struct drm_vblank_crtc *vblank = &crtc->dev->vblank[work->crtc_id]; - amdgpu_flip_wait_fence(adev, &work->excl); + if (amdgpu_flip_handle_fence(work, &work->excl)) + return; + for (i = 0; i < work->shared_count; ++i) - amdgpu_flip_wait_fence(adev, &work->shared[i]); + if (amdgpu_flip_handle_fence(work, &work->shared[i])) + return; /* We borrow the event spin lock for protecting flip_status */ spin_lock_irqsave(&crtc->dev->event_lock, flags); @@ -130,12 +131,12 @@ static void amdgpu_flip_work_func(struct work_struct *__work) vblank->framedur_ns / 1000, vblank->linedur_ns / 1000, stat, vpos, hpos); - /* do the flip (mmio) */ - adev->mode_info.funcs->page_flip(adev, work->crtc_id, work->base); /* set the flip status */ amdgpuCrtc->pflip_status = AMDGPU_FLIP_SUBMITTED; - spin_unlock_irqrestore(&crtc->dev->event_lock, flags); + + /* Do the flip (mmio) */ + adev->mode_info.funcs->page_flip(adev, work->crtc_id, work->base); } /* @@ -254,7 +255,7 @@ int amdgpu_crtc_page_flip(struct drm_crtc *crtc, /* update crtc fb */ crtc->primary->fb = fb; spin_unlock_irqrestore(&crtc->dev->event_lock, flags); - queue_work(amdgpu_crtc->pflip_queue, &work->flip_work); + amdgpu_flip_work_func(&work->flip_work); return 0; vblank_cleanup: diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 9ef1db87cf260c2a6a8abd423dde4be313f355ae..f1e17d60055a4b3c9cbcb2982d5d0e2227506bd8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -69,7 +69,6 @@ int amdgpu_dpm = -1; int amdgpu_smc_load_fw = 1; int amdgpu_aspm = -1; int amdgpu_runtime_pm = -1; -int amdgpu_hard_reset = 0; unsigned amdgpu_ip_block_mask = 0xffffffff; int amdgpu_bapm = -1; int amdgpu_deep_color = 0; @@ -78,10 +77,8 @@ int amdgpu_vm_block_size = -1; int amdgpu_vm_fault_stop = 0; int amdgpu_vm_debug = 0; int amdgpu_exp_hw_support = 0; -int amdgpu_enable_scheduler = 1; int amdgpu_sched_jobs = 32; int amdgpu_sched_hw_submission = 2; -int amdgpu_enable_semaphores = 0; int amdgpu_powerplay = -1; unsigned amdgpu_pcie_gen_cap = 0; unsigned amdgpu_pcie_lane_cap = 0; @@ -128,9 +125,6 @@ module_param_named(aspm, amdgpu_aspm, int, 0444); MODULE_PARM_DESC(runpm, "PX runtime pm (1 = force enable, 0 = disable, -1 = PX only default)"); module_param_named(runpm, amdgpu_runtime_pm, int, 0444); -MODULE_PARM_DESC(hard_reset, "PCI config reset (1 = force enable, 0 = disable (default))"); -module_param_named(hard_reset, amdgpu_hard_reset, int, 0444); - MODULE_PARM_DESC(ip_block_mask, "IP Block Mask (all blocks enabled (default))"); module_param_named(ip_block_mask, amdgpu_ip_block_mask, uint, 0444); @@ -155,18 +149,12 @@ module_param_named(vm_debug, amdgpu_vm_debug, int, 0644); MODULE_PARM_DESC(exp_hw_support, "experimental hw support (1 = enable, 0 = disable (default))"); module_param_named(exp_hw_support, amdgpu_exp_hw_support, int, 0444); -MODULE_PARM_DESC(enable_scheduler, "enable SW GPU scheduler (1 = enable (default), 0 = disable)"); -module_param_named(enable_scheduler, amdgpu_enable_scheduler, int, 0444); - MODULE_PARM_DESC(sched_jobs, "the max number of jobs supported in the sw queue (default 32)"); module_param_named(sched_jobs, amdgpu_sched_jobs, int, 0444); MODULE_PARM_DESC(sched_hw_submission, "the max number of HW submissions (default 2)"); module_param_named(sched_hw_submission, amdgpu_sched_hw_submission, int, 0444); -MODULE_PARM_DESC(enable_semaphores, "Enable semaphores (1 = enable, 0 = disable (default))"); -module_param_named(enable_semaphores, amdgpu_enable_semaphores, int, 0644); - #ifdef CONFIG_DRM_AMD_POWERPLAY MODULE_PARM_DESC(powerplay, "Powerplay component (1 = enable, 0 = disable, -1 = auto (default))"); module_param_named(powerplay, amdgpu_powerplay, int, 0444); @@ -330,6 +318,14 @@ static int amdgpu_pci_probe(struct pci_dev *pdev, return -ENODEV; } + /* + * Initialize amdkfd before starting radeon. If it was not loaded yet, + * defer radeon probing + */ + ret = amdgpu_amdkfd_init(); + if (ret == -EPROBE_DEFER) + return ret; + /* Get rid of things like offb */ ret = amdgpu_kick_out_firmware_fb(pdev); if (ret) @@ -559,6 +555,7 @@ static struct pci_driver amdgpu_kms_pci_driver = { static int __init amdgpu_init(void) { + amdgpu_sync_init(); #ifdef CONFIG_VGA_CONSOLE if (vgacon_text_force()) { DRM_ERROR("VGACON disables amdgpu kernel modesetting.\n"); @@ -572,8 +569,6 @@ static int __init amdgpu_init(void) driver->num_ioctls = amdgpu_max_kms_ioctl; amdgpu_register_atpx_handler(); - amdgpu_amdkfd_init(); - /* let modprobe override vga console setting */ return drm_pci_init(driver, pdriver); } @@ -583,6 +578,7 @@ static void __exit amdgpu_exit(void) amdgpu_amdkfd_fini(); drm_pci_exit(driver, pdriver); amdgpu_unregister_atpx_handler(); + amdgpu_sync_fini(); } module_init(amdgpu_init); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c index 3671f9f220bd47617d0cd3761543cedcae581d5e..d81f1f4883a6c4b1adff92ba0c32b52f1999b2fd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c @@ -47,9 +47,30 @@ * that the the relevant GPU caches have been flushed. */ +struct amdgpu_fence { + struct fence base; + + /* RB, DMA, etc. */ + struct amdgpu_ring *ring; +}; + static struct kmem_cache *amdgpu_fence_slab; static atomic_t amdgpu_fence_slab_ref = ATOMIC_INIT(0); +/* + * Cast helper + */ +static const struct fence_ops amdgpu_fence_ops; +static inline struct amdgpu_fence *to_amdgpu_fence(struct fence *f) +{ + struct amdgpu_fence *__f = container_of(f, struct amdgpu_fence, base); + + if (__f->base.ops == &amdgpu_fence_ops) + return __f; + + return NULL; +} + /** * amdgpu_fence_write - write a fence value * @@ -82,7 +103,7 @@ static u32 amdgpu_fence_read(struct amdgpu_ring *ring) if (drv->cpu_addr) seq = le32_to_cpu(*drv->cpu_addr); else - seq = lower_32_bits(atomic64_read(&drv->last_seq)); + seq = atomic_read(&drv->last_seq); return seq; } @@ -91,32 +112,45 @@ static u32 amdgpu_fence_read(struct amdgpu_ring *ring) * amdgpu_fence_emit - emit a fence on the requested ring * * @ring: ring the fence is associated with - * @owner: creator of the fence - * @fence: amdgpu fence object + * @f: resulting fence object * * Emits a fence command on the requested ring (all asics). * Returns 0 on success, -ENOMEM on failure. */ -int amdgpu_fence_emit(struct amdgpu_ring *ring, void *owner, - struct amdgpu_fence **fence) +int amdgpu_fence_emit(struct amdgpu_ring *ring, struct fence **f) { struct amdgpu_device *adev = ring->adev; + struct amdgpu_fence *fence; + struct fence *old, **ptr; + uint32_t seq; - /* we are protected by the ring emission mutex */ - *fence = kmem_cache_alloc(amdgpu_fence_slab, GFP_KERNEL); - if ((*fence) == NULL) { + fence = kmem_cache_alloc(amdgpu_fence_slab, GFP_KERNEL); + if (fence == NULL) return -ENOMEM; - } - (*fence)->seq = ++ring->fence_drv.sync_seq[ring->idx]; - (*fence)->ring = ring; - (*fence)->owner = owner; - fence_init(&(*fence)->base, &amdgpu_fence_ops, - &ring->fence_drv.fence_queue.lock, - adev->fence_context + ring->idx, - (*fence)->seq); + + seq = ++ring->fence_drv.sync_seq; + fence->ring = ring; + fence_init(&fence->base, &amdgpu_fence_ops, + &ring->fence_drv.lock, + adev->fence_context + ring->idx, + seq); amdgpu_ring_emit_fence(ring, ring->fence_drv.gpu_addr, - (*fence)->seq, - AMDGPU_FENCE_FLAG_INT); + seq, AMDGPU_FENCE_FLAG_INT); + + ptr = &ring->fence_drv.fences[seq & ring->fence_drv.num_fences_mask]; + /* This function can't be called concurrently anyway, otherwise + * emitting the fence would mess up the hardware ring buffer. + */ + old = rcu_dereference_protected(*ptr, 1); + if (old && !fence_is_signaled(old)) { + DRM_INFO("rcu slot is busy\n"); + fence_wait(old, false); + } + + rcu_assign_pointer(*ptr, fence_get(&fence->base)); + + *f = &fence->base; + return 0; } @@ -134,89 +168,48 @@ static void amdgpu_fence_schedule_fallback(struct amdgpu_ring *ring) } /** - * amdgpu_fence_activity - check for fence activity + * amdgpu_fence_process - check for fence activity * * @ring: pointer to struct amdgpu_ring * * Checks the current fence value and calculates the last - * signalled fence value. Returns true if activity occured - * on the ring, and the fence_queue should be waken up. + * signalled fence value. Wakes the fence queue if the + * sequence number has increased. */ -static bool amdgpu_fence_activity(struct amdgpu_ring *ring) +void amdgpu_fence_process(struct amdgpu_ring *ring) { - uint64_t seq, last_seq, last_emitted; - unsigned count_loop = 0; - bool wake = false; - - /* Note there is a scenario here for an infinite loop but it's - * very unlikely to happen. For it to happen, the current polling - * process need to be interrupted by another process and another - * process needs to update the last_seq btw the atomic read and - * xchg of the current process. - * - * More over for this to go in infinite loop there need to be - * continuously new fence signaled ie amdgpu_fence_read needs - * to return a different value each time for both the currently - * polling process and the other process that xchg the last_seq - * btw atomic read and xchg of the current process. And the - * value the other process set as last seq must be higher than - * the seq value we just read. Which means that current process - * need to be interrupted after amdgpu_fence_read and before - * atomic xchg. - * - * To be even more safe we count the number of time we loop and - * we bail after 10 loop just accepting the fact that we might - * have temporarly set the last_seq not to the true real last - * seq but to an older one. - */ - last_seq = atomic64_read(&ring->fence_drv.last_seq); + struct amdgpu_fence_driver *drv = &ring->fence_drv; + uint32_t seq, last_seq; + int r; + do { - last_emitted = ring->fence_drv.sync_seq[ring->idx]; + last_seq = atomic_read(&ring->fence_drv.last_seq); seq = amdgpu_fence_read(ring); - seq |= last_seq & 0xffffffff00000000LL; - if (seq < last_seq) { - seq &= 0xffffffff; - seq |= last_emitted & 0xffffffff00000000LL; - } - if (seq <= last_seq || seq > last_emitted) { - break; - } - /* If we loop over we don't want to return without - * checking if a fence is signaled as it means that the - * seq we just read is different from the previous on. - */ - wake = true; - last_seq = seq; - if ((count_loop++) > 10) { - /* We looped over too many time leave with the - * fact that we might have set an older fence - * seq then the current real last seq as signaled - * by the hw. - */ - break; - } - } while (atomic64_xchg(&ring->fence_drv.last_seq, seq) > seq); + } while (atomic_cmpxchg(&drv->last_seq, last_seq, seq) != last_seq); - if (seq < last_emitted) + if (seq != ring->fence_drv.sync_seq) amdgpu_fence_schedule_fallback(ring); - return wake; -} + while (last_seq != seq) { + struct fence *fence, **ptr; -/** - * amdgpu_fence_process - process a fence - * - * @adev: amdgpu_device pointer - * @ring: ring index the fence is associated with - * - * Checks the current fence value and wakes the fence queue - * if the sequence number has increased (all asics). - */ -void amdgpu_fence_process(struct amdgpu_ring *ring) -{ - if (amdgpu_fence_activity(ring)) - wake_up_all(&ring->fence_drv.fence_queue); + ptr = &drv->fences[++last_seq & drv->num_fences_mask]; + + /* There is always exactly one thread signaling this fence slot */ + fence = rcu_dereference_protected(*ptr, 1); + rcu_assign_pointer(*ptr, NULL); + + BUG_ON(!fence); + + r = fence_signal(fence); + if (!r) + FENCE_TRACE(fence, "signaled from irq context\n"); + else + BUG(); + + fence_put(fence); + } } /** @@ -233,83 +226,6 @@ static void amdgpu_fence_fallback(unsigned long arg) amdgpu_fence_process(ring); } -/** - * amdgpu_fence_seq_signaled - check if a fence sequence number has signaled - * - * @ring: ring the fence is associated with - * @seq: sequence number - * - * Check if the last signaled fence sequnce number is >= the requested - * sequence number (all asics). - * Returns true if the fence has signaled (current fence value - * is >= requested value) or false if it has not (current fence - * value is < the requested value. Helper function for - * amdgpu_fence_signaled(). - */ -static bool amdgpu_fence_seq_signaled(struct amdgpu_ring *ring, u64 seq) -{ - if (atomic64_read(&ring->fence_drv.last_seq) >= seq) - return true; - - /* poll new last sequence at least once */ - amdgpu_fence_process(ring); - if (atomic64_read(&ring->fence_drv.last_seq) >= seq) - return true; - - return false; -} - -/* - * amdgpu_ring_wait_seq_timeout - wait for seq of the specific ring to signal - * @ring: ring to wait on for the seq number - * @seq: seq number wait for - * - * return value: - * 0: seq signaled, and gpu not hang - * -EDEADL: GPU hang detected - * -EINVAL: some paramter is not valid - */ -static int amdgpu_fence_ring_wait_seq(struct amdgpu_ring *ring, uint64_t seq) -{ - bool signaled = false; - - BUG_ON(!ring); - if (seq > ring->fence_drv.sync_seq[ring->idx]) - return -EINVAL; - - if (atomic64_read(&ring->fence_drv.last_seq) >= seq) - return 0; - - amdgpu_fence_schedule_fallback(ring); - wait_event(ring->fence_drv.fence_queue, ( - (signaled = amdgpu_fence_seq_signaled(ring, seq)))); - - if (signaled) - return 0; - else - return -EDEADLK; -} - -/** - * amdgpu_fence_wait_next - wait for the next fence to signal - * - * @adev: amdgpu device pointer - * @ring: ring index the fence is associated with - * - * Wait for the next fence on the requested ring to signal (all asics). - * Returns 0 if the next fence has passed, error for all other cases. - * Caller must hold ring lock. - */ -int amdgpu_fence_wait_next(struct amdgpu_ring *ring) -{ - uint64_t seq = atomic64_read(&ring->fence_drv.last_seq) + 1ULL; - - if (seq >= ring->fence_drv.sync_seq[ring->idx]) - return -ENOENT; - - return amdgpu_fence_ring_wait_seq(ring, seq); -} - /** * amdgpu_fence_wait_empty - wait for all fences to signal * @@ -318,16 +234,28 @@ int amdgpu_fence_wait_next(struct amdgpu_ring *ring) * * Wait for all fences on the requested ring to signal (all asics). * Returns 0 if the fences have passed, error for all other cases. - * Caller must hold ring lock. */ int amdgpu_fence_wait_empty(struct amdgpu_ring *ring) { - uint64_t seq = ring->fence_drv.sync_seq[ring->idx]; + uint64_t seq = ACCESS_ONCE(ring->fence_drv.sync_seq); + struct fence *fence, **ptr; + int r; if (!seq) return 0; - return amdgpu_fence_ring_wait_seq(ring, seq); + ptr = &ring->fence_drv.fences[seq & ring->fence_drv.num_fences_mask]; + rcu_read_lock(); + fence = rcu_dereference(*ptr); + if (!fence || !fence_get_rcu(fence)) { + rcu_read_unlock(); + return 0; + } + rcu_read_unlock(); + + r = fence_wait(fence, false); + fence_put(fence); + return r; } /** @@ -347,75 +275,10 @@ unsigned amdgpu_fence_count_emitted(struct amdgpu_ring *ring) * but it's ok to report slightly wrong fence count here. */ amdgpu_fence_process(ring); - emitted = ring->fence_drv.sync_seq[ring->idx] - - atomic64_read(&ring->fence_drv.last_seq); - /* to avoid 32bits warp around */ - if (emitted > 0x10000000) - emitted = 0x10000000; - - return (unsigned)emitted; -} - -/** - * amdgpu_fence_need_sync - do we need a semaphore - * - * @fence: amdgpu fence object - * @dst_ring: which ring to check against - * - * Check if the fence needs to be synced against another ring - * (all asics). If so, we need to emit a semaphore. - * Returns true if we need to sync with another ring, false if - * not. - */ -bool amdgpu_fence_need_sync(struct amdgpu_fence *fence, - struct amdgpu_ring *dst_ring) -{ - struct amdgpu_fence_driver *fdrv; - - if (!fence) - return false; - - if (fence->ring == dst_ring) - return false; - - /* we are protected by the ring mutex */ - fdrv = &dst_ring->fence_drv; - if (fence->seq <= fdrv->sync_seq[fence->ring->idx]) - return false; - - return true; -} - -/** - * amdgpu_fence_note_sync - record the sync point - * - * @fence: amdgpu fence object - * @dst_ring: which ring to check against - * - * Note the sequence number at which point the fence will - * be synced with the requested ring (all asics). - */ -void amdgpu_fence_note_sync(struct amdgpu_fence *fence, - struct amdgpu_ring *dst_ring) -{ - struct amdgpu_fence_driver *dst, *src; - unsigned i; - - if (!fence) - return; - - if (fence->ring == dst_ring) - return; - - /* we are protected by the ring mutex */ - src = &fence->ring->fence_drv; - dst = &dst_ring->fence_drv; - for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { - if (i == dst_ring->idx) - continue; - - dst->sync_seq[i] = max(dst->sync_seq[i], src->sync_seq[i]); - } + emitted = 0x100000000ull; + emitted -= atomic_read(&ring->fence_drv.last_seq); + emitted += ACCESS_ONCE(ring->fence_drv.sync_seq); + return lower_32_bits(emitted); } /** @@ -447,7 +310,7 @@ int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring, ring->fence_drv.cpu_addr = adev->uvd.cpu_addr + index; ring->fence_drv.gpu_addr = adev->uvd.gpu_addr + index; } - amdgpu_fence_write(ring, atomic64_read(&ring->fence_drv.last_seq)); + amdgpu_fence_write(ring, atomic_read(&ring->fence_drv.last_seq)); amdgpu_irq_get(adev, irq_src, irq_type); ring->fence_drv.irq_src = irq_src; @@ -465,47 +328,55 @@ int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring, * for the requested ring. * * @ring: ring to init the fence driver on + * @num_hw_submission: number of entries on the hardware queue * * Init the fence driver for the requested ring (all asics). * Helper function for amdgpu_fence_driver_init(). */ -int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring) +int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring, + unsigned num_hw_submission) { - int i, r; + long timeout; + int r; + + /* Check that num_hw_submission is a power of two */ + if ((num_hw_submission & (num_hw_submission - 1)) != 0) + return -EINVAL; ring->fence_drv.cpu_addr = NULL; ring->fence_drv.gpu_addr = 0; - for (i = 0; i < AMDGPU_MAX_RINGS; ++i) - ring->fence_drv.sync_seq[i] = 0; - - atomic64_set(&ring->fence_drv.last_seq, 0); + ring->fence_drv.sync_seq = 0; + atomic_set(&ring->fence_drv.last_seq, 0); ring->fence_drv.initialized = false; setup_timer(&ring->fence_drv.fallback_timer, amdgpu_fence_fallback, (unsigned long)ring); - init_waitqueue_head(&ring->fence_drv.fence_queue); - - if (amdgpu_enable_scheduler) { - long timeout = msecs_to_jiffies(amdgpu_lockup_timeout); - if (timeout == 0) { - /* - * FIXME: - * Delayed workqueue cannot use it directly, - * so the scheduler will not use delayed workqueue if - * MAX_SCHEDULE_TIMEOUT is set. - * Currently keep it simple and silly. - */ - timeout = MAX_SCHEDULE_TIMEOUT; - } - r = amd_sched_init(&ring->sched, &amdgpu_sched_ops, - amdgpu_sched_hw_submission, - timeout, ring->name); - if (r) { - DRM_ERROR("Failed to create scheduler on ring %s.\n", - ring->name); - return r; - } + ring->fence_drv.num_fences_mask = num_hw_submission - 1; + spin_lock_init(&ring->fence_drv.lock); + ring->fence_drv.fences = kcalloc(num_hw_submission, sizeof(void *), + GFP_KERNEL); + if (!ring->fence_drv.fences) + return -ENOMEM; + + timeout = msecs_to_jiffies(amdgpu_lockup_timeout); + if (timeout == 0) { + /* + * FIXME: + * Delayed workqueue cannot use it directly, + * so the scheduler will not use delayed workqueue if + * MAX_SCHEDULE_TIMEOUT is set. + * Currently keep it simple and silly. + */ + timeout = MAX_SCHEDULE_TIMEOUT; + } + r = amd_sched_init(&ring->sched, &amdgpu_sched_ops, + num_hw_submission, + timeout, ring->name); + if (r) { + DRM_ERROR("Failed to create scheduler on ring %s.\n", + ring->name); + return r; } return 0; @@ -548,11 +419,9 @@ int amdgpu_fence_driver_init(struct amdgpu_device *adev) */ void amdgpu_fence_driver_fini(struct amdgpu_device *adev) { - int i, r; + unsigned i, j; + int r; - if (atomic_dec_and_test(&amdgpu_fence_slab_ref)) - kmem_cache_destroy(amdgpu_fence_slab); - mutex_lock(&adev->ring_lock); for (i = 0; i < AMDGPU_MAX_RINGS; i++) { struct amdgpu_ring *ring = adev->rings[i]; @@ -563,14 +432,18 @@ void amdgpu_fence_driver_fini(struct amdgpu_device *adev) /* no need to trigger GPU reset as we are unloading */ amdgpu_fence_driver_force_completion(adev); } - wake_up_all(&ring->fence_drv.fence_queue); amdgpu_irq_put(adev, ring->fence_drv.irq_src, ring->fence_drv.irq_type); amd_sched_fini(&ring->sched); del_timer_sync(&ring->fence_drv.fallback_timer); + for (j = 0; j <= ring->fence_drv.num_fences_mask; ++j) + fence_put(ring->fence_drv.fences[i]); + kfree(ring->fence_drv.fences); ring->fence_drv.initialized = false; } - mutex_unlock(&adev->ring_lock); + + if (atomic_dec_and_test(&amdgpu_fence_slab_ref)) + kmem_cache_destroy(amdgpu_fence_slab); } /** @@ -585,7 +458,6 @@ void amdgpu_fence_driver_suspend(struct amdgpu_device *adev) { int i, r; - mutex_lock(&adev->ring_lock); for (i = 0; i < AMDGPU_MAX_RINGS; i++) { struct amdgpu_ring *ring = adev->rings[i]; if (!ring || !ring->fence_drv.initialized) @@ -602,7 +474,6 @@ void amdgpu_fence_driver_suspend(struct amdgpu_device *adev) amdgpu_irq_put(adev, ring->fence_drv.irq_src, ring->fence_drv.irq_type); } - mutex_unlock(&adev->ring_lock); } /** @@ -621,7 +492,6 @@ void amdgpu_fence_driver_resume(struct amdgpu_device *adev) { int i; - mutex_lock(&adev->ring_lock); for (i = 0; i < AMDGPU_MAX_RINGS; i++) { struct amdgpu_ring *ring = adev->rings[i]; if (!ring || !ring->fence_drv.initialized) @@ -631,7 +501,6 @@ void amdgpu_fence_driver_resume(struct amdgpu_device *adev) amdgpu_irq_get(adev, ring->fence_drv.irq_src, ring->fence_drv.irq_type); } - mutex_unlock(&adev->ring_lock); } /** @@ -651,7 +520,7 @@ void amdgpu_fence_driver_force_completion(struct amdgpu_device *adev) if (!ring || !ring->fence_drv.initialized) continue; - amdgpu_fence_write(ring, ring->fence_drv.sync_seq[i]); + amdgpu_fence_write(ring, ring->fence_drv.sync_seq); } } @@ -671,103 +540,57 @@ static const char *amdgpu_fence_get_timeline_name(struct fence *f) } /** - * amdgpu_fence_is_signaled - test if fence is signaled - * - * @f: fence to test + * amdgpu_fence_enable_signaling - enable signalling on fence + * @fence: fence * - * Test the fence sequence number if it is already signaled. If it isn't - * signaled start fence processing. Returns True if the fence is signaled. + * This function is called with fence_queue lock held, and adds a callback + * to fence_queue that checks if this fence is signaled, and if so it + * signals the fence and removes itself. */ -static bool amdgpu_fence_is_signaled(struct fence *f) +static bool amdgpu_fence_enable_signaling(struct fence *f) { struct amdgpu_fence *fence = to_amdgpu_fence(f); struct amdgpu_ring *ring = fence->ring; - if (atomic64_read(&ring->fence_drv.last_seq) >= fence->seq) - return true; - - amdgpu_fence_process(ring); + if (!timer_pending(&ring->fence_drv.fallback_timer)) + amdgpu_fence_schedule_fallback(ring); - if (atomic64_read(&ring->fence_drv.last_seq) >= fence->seq) - return true; + FENCE_TRACE(&fence->base, "armed on ring %i!\n", ring->idx); - return false; + return true; } /** - * amdgpu_fence_check_signaled - callback from fence_queue + * amdgpu_fence_free - free up the fence memory + * + * @rcu: RCU callback head * - * this function is called with fence_queue lock held, which is also used - * for the fence locking itself, so unlocked variants are used for - * fence_signal, and remove_wait_queue. + * Free up the fence memory after the RCU grace period. */ -static int amdgpu_fence_check_signaled(wait_queue_t *wait, unsigned mode, int flags, void *key) +static void amdgpu_fence_free(struct rcu_head *rcu) { - struct amdgpu_fence *fence; - struct amdgpu_device *adev; - u64 seq; - int ret; - - fence = container_of(wait, struct amdgpu_fence, fence_wake); - adev = fence->ring->adev; - - /* - * We cannot use amdgpu_fence_process here because we're already - * in the waitqueue, in a call from wake_up_all. - */ - seq = atomic64_read(&fence->ring->fence_drv.last_seq); - if (seq >= fence->seq) { - ret = fence_signal_locked(&fence->base); - if (!ret) - FENCE_TRACE(&fence->base, "signaled from irq context\n"); - else - FENCE_TRACE(&fence->base, "was already signaled\n"); - - __remove_wait_queue(&fence->ring->fence_drv.fence_queue, &fence->fence_wake); - fence_put(&fence->base); - } else - FENCE_TRACE(&fence->base, "pending\n"); - return 0; + struct fence *f = container_of(rcu, struct fence, rcu); + struct amdgpu_fence *fence = to_amdgpu_fence(f); + kmem_cache_free(amdgpu_fence_slab, fence); } /** - * amdgpu_fence_enable_signaling - enable signalling on fence + * amdgpu_fence_release - callback that fence can be freed + * * @fence: fence * - * This function is called with fence_queue lock held, and adds a callback - * to fence_queue that checks if this fence is signaled, and if so it - * signals the fence and removes itself. + * This function is called when the reference count becomes zero. + * It just RCU schedules freeing up the fence. */ -static bool amdgpu_fence_enable_signaling(struct fence *f) -{ - struct amdgpu_fence *fence = to_amdgpu_fence(f); - struct amdgpu_ring *ring = fence->ring; - - if (atomic64_read(&ring->fence_drv.last_seq) >= fence->seq) - return false; - - fence->fence_wake.flags = 0; - fence->fence_wake.private = NULL; - fence->fence_wake.func = amdgpu_fence_check_signaled; - __add_wait_queue(&ring->fence_drv.fence_queue, &fence->fence_wake); - fence_get(f); - if (!timer_pending(&ring->fence_drv.fallback_timer)) - amdgpu_fence_schedule_fallback(ring); - FENCE_TRACE(&fence->base, "armed on ring %i!\n", ring->idx); - return true; -} - static void amdgpu_fence_release(struct fence *f) { - struct amdgpu_fence *fence = to_amdgpu_fence(f); - kmem_cache_free(amdgpu_fence_slab, fence); + call_rcu(&f->rcu, amdgpu_fence_free); } -const struct fence_ops amdgpu_fence_ops = { +static const struct fence_ops amdgpu_fence_ops = { .get_driver_name = amdgpu_fence_get_driver_name, .get_timeline_name = amdgpu_fence_get_timeline_name, .enable_signaling = amdgpu_fence_enable_signaling, - .signaled = amdgpu_fence_is_signaled, .wait = fence_default_wait, .release = amdgpu_fence_release, }; @@ -781,7 +604,7 @@ static int amdgpu_debugfs_fence_info(struct seq_file *m, void *data) struct drm_info_node *node = (struct drm_info_node *)m->private; struct drm_device *dev = node->minor->dev; struct amdgpu_device *adev = dev->dev_private; - int i, j; + int i; for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { struct amdgpu_ring *ring = adev->rings[i]; @@ -791,31 +614,41 @@ static int amdgpu_debugfs_fence_info(struct seq_file *m, void *data) amdgpu_fence_process(ring); seq_printf(m, "--- ring %d (%s) ---\n", i, ring->name); - seq_printf(m, "Last signaled fence 0x%016llx\n", - (unsigned long long)atomic64_read(&ring->fence_drv.last_seq)); - seq_printf(m, "Last emitted 0x%016llx\n", - ring->fence_drv.sync_seq[i]); - - for (j = 0; j < AMDGPU_MAX_RINGS; ++j) { - struct amdgpu_ring *other = adev->rings[j]; - if (i != j && other && other->fence_drv.initialized && - ring->fence_drv.sync_seq[j]) - seq_printf(m, "Last sync to ring %d 0x%016llx\n", - j, ring->fence_drv.sync_seq[j]); - } + seq_printf(m, "Last signaled fence 0x%08x\n", + atomic_read(&ring->fence_drv.last_seq)); + seq_printf(m, "Last emitted 0x%08x\n", + ring->fence_drv.sync_seq); } return 0; } +/** + * amdgpu_debugfs_gpu_reset - manually trigger a gpu reset + * + * Manually trigger a gpu reset at the next fence wait. + */ +static int amdgpu_debugfs_gpu_reset(struct seq_file *m, void *data) +{ + struct drm_info_node *node = (struct drm_info_node *) m->private; + struct drm_device *dev = node->minor->dev; + struct amdgpu_device *adev = dev->dev_private; + + seq_printf(m, "gpu reset\n"); + amdgpu_gpu_reset(adev); + + return 0; +} + static struct drm_info_list amdgpu_debugfs_fence_list[] = { {"amdgpu_fence_info", &amdgpu_debugfs_fence_info, 0, NULL}, + {"amdgpu_gpu_reset", &amdgpu_debugfs_gpu_reset, 0, NULL} }; #endif int amdgpu_debugfs_fence_init(struct amdgpu_device *adev) { #if defined(CONFIG_DEBUG_FS) - return amdgpu_debugfs_add_files(adev, amdgpu_debugfs_fence_list, 1); + return amdgpu_debugfs_add_files(adev, amdgpu_debugfs_fence_list, 2); #else return 0; #endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index d20c2a8929cbdaf39164e6c709df67d36b352f35..fa6a27bff298b7ad11649f5a790b131c478702e0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -26,6 +26,7 @@ * Jerome Glisse */ #include +#include #include #include #include "amdgpu.h" @@ -83,24 +84,32 @@ int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size, return r; } *obj = &robj->gem_base; - robj->pid = task_pid_nr(current); - - mutex_lock(&adev->gem.mutex); - list_add_tail(&robj->list, &adev->gem.objects); - mutex_unlock(&adev->gem.mutex); return 0; } -int amdgpu_gem_init(struct amdgpu_device *adev) +void amdgpu_gem_force_release(struct amdgpu_device *adev) { - INIT_LIST_HEAD(&adev->gem.objects); - return 0; -} + struct drm_device *ddev = adev->ddev; + struct drm_file *file; -void amdgpu_gem_fini(struct amdgpu_device *adev) -{ - amdgpu_bo_force_delete(adev); + mutex_lock(&ddev->struct_mutex); + + list_for_each_entry(file, &ddev->filelist, lhead) { + struct drm_gem_object *gobj; + int handle; + + WARN_ONCE(1, "Still active user space clients!\n"); + spin_lock(&file->table_lock); + idr_for_each_entry(&file->object_idr, gobj, handle) { + WARN_ONCE(1, "And also active allocations!\n"); + drm_gem_object_unreference(gobj); + } + idr_destroy(&file->object_idr); + spin_unlock(&file->table_lock); + } + + mutex_unlock(&ddev->struct_mutex); } /* @@ -132,25 +141,40 @@ int amdgpu_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_pri void amdgpu_gem_object_close(struct drm_gem_object *obj, struct drm_file *file_priv) { - struct amdgpu_bo *rbo = gem_to_amdgpu_bo(obj); - struct amdgpu_device *adev = rbo->adev; + struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); + struct amdgpu_device *adev = bo->adev; struct amdgpu_fpriv *fpriv = file_priv->driver_priv; struct amdgpu_vm *vm = &fpriv->vm; + + struct amdgpu_bo_list_entry vm_pd; + struct list_head list, duplicates; + struct ttm_validate_buffer tv; + struct ww_acquire_ctx ticket; struct amdgpu_bo_va *bo_va; int r; - r = amdgpu_bo_reserve(rbo, true); + + INIT_LIST_HEAD(&list); + INIT_LIST_HEAD(&duplicates); + + tv.bo = &bo->tbo; + tv.shared = true; + list_add(&tv.head, &list); + + amdgpu_vm_get_pd_bo(vm, &list, &vm_pd); + + r = ttm_eu_reserve_buffers(&ticket, &list, false, &duplicates); if (r) { dev_err(adev->dev, "leaking bo va because " "we fail to reserve bo (%d)\n", r); return; } - bo_va = amdgpu_vm_bo_find(vm, rbo); + bo_va = amdgpu_vm_bo_find(vm, bo); if (bo_va) { if (--bo_va->ref_count == 0) { amdgpu_vm_bo_rmv(adev, bo_va); } } - amdgpu_bo_unreserve(rbo); + ttm_eu_backoff_reservation(&ticket, &list); } static int amdgpu_gem_handle_lockup(struct amdgpu_device *adev, int r) @@ -235,12 +259,10 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data, AMDGPU_GEM_USERPTR_REGISTER)) return -EINVAL; - if (!(args->flags & AMDGPU_GEM_USERPTR_READONLY) && ( - !(args->flags & AMDGPU_GEM_USERPTR_ANONONLY) || - !(args->flags & AMDGPU_GEM_USERPTR_REGISTER))) { + if (!(args->flags & AMDGPU_GEM_USERPTR_READONLY) && + !(args->flags & AMDGPU_GEM_USERPTR_REGISTER)) { - /* if we want to write to it we must require anonymous - memory and install a MMU notifier */ + /* if we want to write to it we must install a MMU notifier */ return -EACCES; } @@ -252,6 +274,8 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data, goto handle_lockup; bo = gem_to_amdgpu_bo(gobj); + bo->prefered_domains = AMDGPU_GEM_DOMAIN_GTT; + bo->allowed_domains = AMDGPU_GEM_DOMAIN_GTT; r = amdgpu_ttm_tt_set_userptr(bo->tbo.ttm, args->addr, args->flags); if (r) goto release_object; @@ -264,18 +288,23 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data, if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE) { down_read(¤t->mm->mmap_sem); + + r = amdgpu_ttm_tt_get_user_pages(bo->tbo.ttm, + bo->tbo.ttm->pages); + if (r) + goto unlock_mmap_sem; + r = amdgpu_bo_reserve(bo, true); - if (r) { - up_read(¤t->mm->mmap_sem); - goto release_object; - } + if (r) + goto free_pages; amdgpu_ttm_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_GTT); r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false); amdgpu_bo_unreserve(bo); - up_read(¤t->mm->mmap_sem); if (r) - goto release_object; + goto free_pages; + + up_read(¤t->mm->mmap_sem); } r = drm_gem_handle_create(filp, gobj, &handle); @@ -287,6 +316,12 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data, args->handle = handle; return 0; +free_pages: + release_pages(bo->tbo.ttm->pages, bo->tbo.ttm->num_pages, false); + +unlock_mmap_sem: + up_read(¤t->mm->mmap_sem); + release_object: drm_gem_object_unreference_unlocked(gobj); @@ -308,7 +343,7 @@ int amdgpu_mode_dumb_mmap(struct drm_file *filp, return -ENOENT; } robj = gem_to_amdgpu_bo(gobj); - if (amdgpu_ttm_tt_has_userptr(robj->tbo.ttm) || + if (amdgpu_ttm_tt_get_usermm(robj->tbo.ttm) || (robj->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS)) { drm_gem_object_unreference_unlocked(gobj); return -EPERM; @@ -559,11 +594,10 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, tv.shared = true; list_add(&tv.head, &list); - if (args->operation == AMDGPU_VA_OP_MAP) { - tv_pd.bo = &fpriv->vm.page_directory->tbo; - tv_pd.shared = true; - list_add(&tv_pd.head, &list); - } + tv_pd.bo = &fpriv->vm.page_directory->tbo; + tv_pd.shared = true; + list_add(&tv_pd.head, &list); + r = ttm_eu_reserve_buffers(&ticket, &list, true, &duplicates); if (r) { drm_gem_object_unreference_unlocked(gobj); @@ -629,7 +663,7 @@ int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data, info.bo_size = robj->gem_base.size; info.alignment = robj->tbo.mem.page_alignment << PAGE_SHIFT; - info.domains = robj->initial_domain; + info.domains = robj->prefered_domains; info.domain_flags = robj->flags; amdgpu_bo_unreserve(robj); if (copy_to_user(out, &info, sizeof(info))) @@ -637,14 +671,18 @@ int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data, break; } case AMDGPU_GEM_OP_SET_PLACEMENT: - if (amdgpu_ttm_tt_has_userptr(robj->tbo.ttm)) { + if (amdgpu_ttm_tt_get_usermm(robj->tbo.ttm)) { r = -EPERM; amdgpu_bo_unreserve(robj); break; } - robj->initial_domain = args->value & (AMDGPU_GEM_DOMAIN_VRAM | - AMDGPU_GEM_DOMAIN_GTT | - AMDGPU_GEM_DOMAIN_CPU); + robj->prefered_domains = args->value & (AMDGPU_GEM_DOMAIN_VRAM | + AMDGPU_GEM_DOMAIN_GTT | + AMDGPU_GEM_DOMAIN_CPU); + robj->allowed_domains = robj->prefered_domains; + if (robj->allowed_domains == AMDGPU_GEM_DOMAIN_VRAM) + robj->allowed_domains |= AMDGPU_GEM_DOMAIN_GTT; + amdgpu_bo_unreserve(robj); break; default: @@ -689,38 +727,73 @@ int amdgpu_mode_dumb_create(struct drm_file *file_priv, } #if defined(CONFIG_DEBUG_FS) +static int amdgpu_debugfs_gem_bo_info(int id, void *ptr, void *data) +{ + struct drm_gem_object *gobj = ptr; + struct amdgpu_bo *bo = gem_to_amdgpu_bo(gobj); + struct seq_file *m = data; + + unsigned domain; + const char *placement; + unsigned pin_count; + + domain = amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type); + switch (domain) { + case AMDGPU_GEM_DOMAIN_VRAM: + placement = "VRAM"; + break; + case AMDGPU_GEM_DOMAIN_GTT: + placement = " GTT"; + break; + case AMDGPU_GEM_DOMAIN_CPU: + default: + placement = " CPU"; + break; + } + seq_printf(m, "\t0x%08x: %12ld byte %s @ 0x%010Lx", + id, amdgpu_bo_size(bo), placement, + amdgpu_bo_gpu_offset(bo)); + + pin_count = ACCESS_ONCE(bo->pin_count); + if (pin_count) + seq_printf(m, " pin count %d", pin_count); + seq_printf(m, "\n"); + + return 0; +} + static int amdgpu_debugfs_gem_info(struct seq_file *m, void *data) { struct drm_info_node *node = (struct drm_info_node *)m->private; struct drm_device *dev = node->minor->dev; - struct amdgpu_device *adev = dev->dev_private; - struct amdgpu_bo *rbo; - unsigned i = 0; + struct drm_file *file; + int r; + + r = mutex_lock_interruptible(&dev->struct_mutex); + if (r) + return r; - mutex_lock(&adev->gem.mutex); - list_for_each_entry(rbo, &adev->gem.objects, list) { - unsigned domain; - const char *placement; + list_for_each_entry(file, &dev->filelist, lhead) { + struct task_struct *task; - domain = amdgpu_mem_type_to_domain(rbo->tbo.mem.mem_type); - switch (domain) { - case AMDGPU_GEM_DOMAIN_VRAM: - placement = "VRAM"; - break; - case AMDGPU_GEM_DOMAIN_GTT: - placement = " GTT"; - break; - case AMDGPU_GEM_DOMAIN_CPU: - default: - placement = " CPU"; - break; - } - seq_printf(m, "bo[0x%08x] %8ldkB %8ldMB %s pid %8ld\n", - i, amdgpu_bo_size(rbo) >> 10, amdgpu_bo_size(rbo) >> 20, - placement, (unsigned long)rbo->pid); - i++; + /* + * Although we have a valid reference on file->pid, that does + * not guarantee that the task_struct who called get_pid() is + * still alive (e.g. get_pid(current) => fork() => exit()). + * Therefore, we need to protect this ->comm access using RCU. + */ + rcu_read_lock(); + task = pid_task(file->pid, PIDTYPE_PID); + seq_printf(m, "pid %8d command %s:\n", pid_nr(file->pid), + task ? task->comm : ""); + rcu_read_unlock(); + + spin_lock(&file->table_lock); + idr_for_each(&file->object_idr, amdgpu_debugfs_gem_bo_info, m); + spin_unlock(&file->table_lock); } - mutex_unlock(&adev->gem.mutex); + + mutex_unlock(&dev->struct_mutex); return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index 9e25edafa7210000d1bfad1959f82725228e91df..8443cea6821ad00cad2181d16ac450b8045223ec 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c @@ -55,10 +55,9 @@ static int amdgpu_debugfs_sa_init(struct amdgpu_device *adev); * suballocator. * Returns 0 on success, error on failure. */ -int amdgpu_ib_get(struct amdgpu_ring *ring, struct amdgpu_vm *vm, +int amdgpu_ib_get(struct amdgpu_device *adev, struct amdgpu_vm *vm, unsigned size, struct amdgpu_ib *ib) { - struct amdgpu_device *adev = ring->adev; int r; if (size) { @@ -75,10 +74,8 @@ int amdgpu_ib_get(struct amdgpu_ring *ring, struct amdgpu_vm *vm, ib->gpu_addr = amdgpu_sa_bo_gpu_addr(ib->sa_bo); } - amdgpu_sync_create(&ib->sync); - - ib->ring = ring; ib->vm = vm; + ib->vm_id = 0; return 0; } @@ -88,15 +85,13 @@ int amdgpu_ib_get(struct amdgpu_ring *ring, struct amdgpu_vm *vm, * * @adev: amdgpu_device pointer * @ib: IB object to free + * @f: the fence SA bo need wait on for the ib alloation * * Free an IB (all asics). */ -void amdgpu_ib_free(struct amdgpu_device *adev, struct amdgpu_ib *ib) +void amdgpu_ib_free(struct amdgpu_device *adev, struct amdgpu_ib *ib, struct fence *f) { - amdgpu_sync_free(adev, &ib->sync, &ib->fence->base); - amdgpu_sa_bo_free(adev, &ib->sa_bo, &ib->fence->base); - if (ib->fence) - fence_put(&ib->fence->base); + amdgpu_sa_bo_free(adev, &ib->sa_bo, f); } /** @@ -105,7 +100,7 @@ void amdgpu_ib_free(struct amdgpu_device *adev, struct amdgpu_ib *ib) * @adev: amdgpu_device pointer * @num_ibs: number of IBs to schedule * @ibs: IB objects to schedule - * @owner: owner for creating the fences + * @f: fence created during this submission * * Schedule an IB on the associated ring (all asics). * Returns 0 on success, error on failure. @@ -120,20 +115,21 @@ void amdgpu_ib_free(struct amdgpu_device *adev, struct amdgpu_ib *ib) * a CONST_IB), it will be put on the ring prior to the DE IB. Prior * to SI there was just a DE IB. */ -int amdgpu_ib_schedule(struct amdgpu_device *adev, unsigned num_ibs, - struct amdgpu_ib *ibs, void *owner) +int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, + struct amdgpu_ib *ibs, struct fence *last_vm_update, + struct fence **f) { + struct amdgpu_device *adev = ring->adev; struct amdgpu_ib *ib = &ibs[0]; - struct amdgpu_ring *ring; struct amdgpu_ctx *ctx, *old_ctx; struct amdgpu_vm *vm; + struct fence *hwf; unsigned i; int r = 0; if (num_ibs == 0) return -EINVAL; - ring = ibs->ring; ctx = ibs->ctx; vm = ibs->vm; @@ -141,42 +137,24 @@ int amdgpu_ib_schedule(struct amdgpu_device *adev, unsigned num_ibs, dev_err(adev->dev, "couldn't schedule ib\n"); return -EINVAL; } - r = amdgpu_sync_wait(&ibs->sync); - if (r) { - dev_err(adev->dev, "IB sync failed (%d).\n", r); - return r; - } - r = amdgpu_ring_lock(ring, (256 + AMDGPU_NUM_SYNCS * 8) * num_ibs); - if (r) { - dev_err(adev->dev, "scheduling IB failed (%d).\n", r); - return r; - } - if (vm) { - /* grab a vm id if necessary */ - r = amdgpu_vm_grab_id(ibs->vm, ibs->ring, &ibs->sync); - if (r) { - amdgpu_ring_unlock_undo(ring); - return r; - } + if (vm && !ibs->vm_id) { + dev_err(adev->dev, "VM IB without ID\n"); + return -EINVAL; } - r = amdgpu_sync_rings(&ibs->sync, ring); + r = amdgpu_ring_alloc(ring, 256 * num_ibs); if (r) { - amdgpu_ring_unlock_undo(ring); - dev_err(adev->dev, "failed to sync rings (%d)\n", r); + dev_err(adev->dev, "scheduling IB failed (%d).\n", r); return r; } if (vm) { /* do context switch */ - amdgpu_vm_flush(ring, vm, ib->sync.last_vm_update); - - if (ring->funcs->emit_gds_switch) - amdgpu_ring_emit_gds_switch(ring, ib->vm->ids[ring->idx].id, - ib->gds_base, ib->gds_size, - ib->gws_base, ib->gws_size, - ib->oa_base, ib->oa_size); + amdgpu_vm_flush(ring, ib->vm_id, ib->vm_pd_addr, + ib->gds_base, ib->gds_size, + ib->gws_base, ib->gws_size, + ib->oa_base, ib->oa_size); if (ring->funcs->emit_hdp_flush) amdgpu_ring_emit_hdp_flush(ring); @@ -186,27 +164,32 @@ int amdgpu_ib_schedule(struct amdgpu_device *adev, unsigned num_ibs, for (i = 0; i < num_ibs; ++i) { ib = &ibs[i]; - if (ib->ring != ring || ib->ctx != ctx || ib->vm != vm) { + if (ib->ctx != ctx || ib->vm != vm) { ring->current_ctx = old_ctx; - amdgpu_ring_unlock_undo(ring); + if (ib->vm_id) + amdgpu_vm_reset_id(adev, ib->vm_id); + amdgpu_ring_undo(ring); return -EINVAL; } amdgpu_ring_emit_ib(ring, ib); ring->current_ctx = ctx; } - r = amdgpu_fence_emit(ring, owner, &ib->fence); + if (vm) { + if (ring->funcs->emit_hdp_invalidate) + amdgpu_ring_emit_hdp_invalidate(ring); + } + + r = amdgpu_fence_emit(ring, &hwf); if (r) { dev_err(adev->dev, "failed to emit fence (%d)\n", r); ring->current_ctx = old_ctx; - amdgpu_ring_unlock_undo(ring); + if (ib->vm_id) + amdgpu_vm_reset_id(adev, ib->vm_id); + amdgpu_ring_undo(ring); return r; } - if (!amdgpu_enable_scheduler && ib->ctx) - ib->sequence = amdgpu_ctx_add_fence(ib->ctx, ring, - &ib->fence->base); - /* wrap the last IB with fence */ if (ib->user) { uint64_t addr = amdgpu_bo_gpu_offset(ib->user->bo); @@ -215,10 +198,10 @@ int amdgpu_ib_schedule(struct amdgpu_device *adev, unsigned num_ibs, AMDGPU_FENCE_FLAG_64BIT); } - if (ib->vm) - amdgpu_vm_fence(adev, ib->vm, &ib->fence->base); + if (f) + *f = fence_get(hwf); - amdgpu_ring_unlock_commit(ring); + amdgpu_ring_commit(ring); return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c index f594cfaa97e513f0bc6d436e26430abc8783e5ce..762cfdb85147471855418fff997877951d4aca6d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c @@ -219,6 +219,8 @@ int amdgpu_irq_init(struct amdgpu_device *adev) if (r) { return r; } + adev->ddev->vblank_disable_allowed = true; + /* enable msi */ adev->irq.msi_enabled = false; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c new file mode 100644 index 0000000000000000000000000000000000000000..9c9b19e2f353b4f1d52a405164038078262c74f7 --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c @@ -0,0 +1,171 @@ +/* + * Copyright 2015 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * + */ +#include +#include +#include +#include +#include "amdgpu.h" +#include "amdgpu_trace.h" + +int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, + struct amdgpu_job **job) +{ + size_t size = sizeof(struct amdgpu_job); + + if (num_ibs == 0) + return -EINVAL; + + size += sizeof(struct amdgpu_ib) * num_ibs; + + *job = kzalloc(size, GFP_KERNEL); + if (!*job) + return -ENOMEM; + + (*job)->adev = adev; + (*job)->ibs = (void *)&(*job)[1]; + (*job)->num_ibs = num_ibs; + + amdgpu_sync_create(&(*job)->sync); + + return 0; +} + +int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size, + struct amdgpu_job **job) +{ + int r; + + r = amdgpu_job_alloc(adev, 1, job); + if (r) + return r; + + r = amdgpu_ib_get(adev, NULL, size, &(*job)->ibs[0]); + if (r) + kfree(*job); + + return r; +} + +void amdgpu_job_free(struct amdgpu_job *job) +{ + unsigned i; + struct fence *f; + /* use sched fence if available */ + f = (job->base.s_fence)? &job->base.s_fence->base : job->fence; + + for (i = 0; i < job->num_ibs; ++i) + amdgpu_sa_bo_free(job->adev, &job->ibs[i].sa_bo, f); + fence_put(job->fence); + + amdgpu_bo_unref(&job->uf.bo); + amdgpu_sync_free(&job->sync); + kfree(job); +} + +int amdgpu_job_submit(struct amdgpu_job *job, struct amdgpu_ring *ring, + struct amd_sched_entity *entity, void *owner, + struct fence **f) +{ + job->ring = ring; + job->base.sched = &ring->sched; + job->base.s_entity = entity; + job->base.s_fence = amd_sched_fence_create(job->base.s_entity, owner); + if (!job->base.s_fence) + return -ENOMEM; + + *f = fence_get(&job->base.s_fence->base); + + job->owner = owner; + amd_sched_entity_push_job(&job->base); + + return 0; +} + +static struct fence *amdgpu_job_dependency(struct amd_sched_job *sched_job) +{ + struct amdgpu_job *job = to_amdgpu_job(sched_job); + struct amdgpu_vm *vm = job->ibs->vm; + + struct fence *fence = amdgpu_sync_get_fence(&job->sync); + + if (fence == NULL && vm && !job->ibs->vm_id) { + struct amdgpu_ring *ring = job->ring; + unsigned i, vm_id; + uint64_t vm_pd_addr; + int r; + + r = amdgpu_vm_grab_id(vm, ring, &job->sync, + &job->base.s_fence->base, + &vm_id, &vm_pd_addr); + if (r) + DRM_ERROR("Error getting VM ID (%d)\n", r); + else { + for (i = 0; i < job->num_ibs; ++i) { + job->ibs[i].vm_id = vm_id; + job->ibs[i].vm_pd_addr = vm_pd_addr; + } + } + + fence = amdgpu_sync_get_fence(&job->sync); + } + + return fence; +} + +static struct fence *amdgpu_job_run(struct amd_sched_job *sched_job) +{ + struct fence *fence = NULL; + struct amdgpu_job *job; + int r; + + if (!sched_job) { + DRM_ERROR("job is null\n"); + return NULL; + } + job = to_amdgpu_job(sched_job); + + r = amdgpu_sync_wait(&job->sync); + if (r) { + DRM_ERROR("failed to sync wait (%d)\n", r); + return NULL; + } + + trace_amdgpu_sched_run_job(job); + r = amdgpu_ib_schedule(job->ring, job->num_ibs, job->ibs, + job->sync.last_vm_update, &fence); + if (r) { + DRM_ERROR("Error scheduling IBs (%d)\n", r); + goto err; + } + +err: + job->fence = fence; + amdgpu_job_free(job); + return fence; +} + +struct amd_sched_backend_ops amdgpu_sched_ops = { + .dependency = amdgpu_job_dependency, + .run_job = amdgpu_job_run, +}; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index e23843f4d877be7813a1574db0f855847f9aa591..598eb0cd5aab6a1b437ad04d0c58dce24adc8d9d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -382,6 +382,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file struct drm_amdgpu_info_vram_gtt vram_gtt; vram_gtt.vram_size = adev->mc.real_vram_size; + vram_gtt.vram_size -= adev->vram_pin_size; vram_gtt.vram_cpu_accessible_size = adev->mc.visible_vram_size; vram_gtt.vram_cpu_accessible_size -= adev->vram_pin_size; vram_gtt.gtt_size = adev->mc.gtt_size; @@ -447,8 +448,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file dev_info.max_memory_clock = adev->pm.default_mclk * 10; } dev_info.enabled_rb_pipes_mask = adev->gfx.config.backend_enable_mask; - dev_info.num_rb_pipes = adev->gfx.config.max_backends_per_se * - adev->gfx.config.max_shader_engines; + dev_info.num_rb_pipes = adev->gfx.config.num_rbs; dev_info.num_hw_gfx_contexts = adev->gfx.config.max_hw_contexts; dev_info._pad = 0; dev_info.ids_flags = 0; @@ -727,6 +727,12 @@ int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, /* Get associated drm_crtc: */ crtc = &adev->mode_info.crtcs[pipe]->base; + if (!crtc) { + /* This can occur on driver load if some component fails to + * initialize completely and driver is unloaded */ + DRM_ERROR("Uninitialized crtc %d\n", pipe); + return -EINVAL; + } /* Helper routine in DRM core does all the work: */ return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c index d4e2780c079663a643bddeaa7e2da5e15a2ff47d..9f4a45cd2aab8f5db8c2ce6e086e472697e2f4fe 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c @@ -77,8 +77,6 @@ static void amdgpu_mn_destroy(struct work_struct *work) hash_del(&rmn->node); rbtree_postorder_for_each_entry_safe(node, next_node, &rmn->objects, it.rb) { - - interval_tree_remove(&node->it, &rmn->objects); list_for_each_entry_safe(bo, next_bo, &node->bos, mn_list) { bo->mn = NULL; list_del_init(&bo->mn_list); @@ -87,7 +85,7 @@ static void amdgpu_mn_destroy(struct work_struct *work) } mutex_unlock(&rmn->lock); mutex_unlock(&adev->mn_lock); - mmu_notifier_unregister(&rmn->mn, rmn->mm); + mmu_notifier_unregister_no_release(&rmn->mn, rmn->mm); kfree(rmn); } @@ -107,6 +105,76 @@ static void amdgpu_mn_release(struct mmu_notifier *mn, schedule_work(&rmn->work); } +/** + * amdgpu_mn_invalidate_node - unmap all BOs of a node + * + * @node: the node with the BOs to unmap + * + * We block for all BOs and unmap them by move them + * into system domain again. + */ +static void amdgpu_mn_invalidate_node(struct amdgpu_mn_node *node, + unsigned long start, + unsigned long end) +{ + struct amdgpu_bo *bo; + long r; + + list_for_each_entry(bo, &node->bos, mn_list) { + + if (!amdgpu_ttm_tt_affect_userptr(bo->tbo.ttm, start, end)) + continue; + + r = amdgpu_bo_reserve(bo, true); + if (r) { + DRM_ERROR("(%ld) failed to reserve user bo\n", r); + continue; + } + + r = reservation_object_wait_timeout_rcu(bo->tbo.resv, + true, false, MAX_SCHEDULE_TIMEOUT); + if (r <= 0) + DRM_ERROR("(%ld) failed to wait for user bo\n", r); + + amdgpu_ttm_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_CPU); + r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false); + if (r) + DRM_ERROR("(%ld) failed to validate user bo\n", r); + + amdgpu_bo_unreserve(bo); + } +} + +/** + * amdgpu_mn_invalidate_page - callback to notify about mm change + * + * @mn: our notifier + * @mn: the mm this callback is about + * @address: address of invalidate page + * + * Invalidation of a single page. Blocks for all BOs mapping it + * and unmap them by move them into system domain again. + */ +static void amdgpu_mn_invalidate_page(struct mmu_notifier *mn, + struct mm_struct *mm, + unsigned long address) +{ + struct amdgpu_mn *rmn = container_of(mn, struct amdgpu_mn, mn); + struct interval_tree_node *it; + + mutex_lock(&rmn->lock); + + it = interval_tree_iter_first(&rmn->objects, address, address); + if (it) { + struct amdgpu_mn_node *node; + + node = container_of(it, struct amdgpu_mn_node, it); + amdgpu_mn_invalidate_node(node, address, address); + } + + mutex_unlock(&rmn->lock); +} + /** * amdgpu_mn_invalidate_range_start - callback to notify about mm change * @@ -134,36 +202,11 @@ static void amdgpu_mn_invalidate_range_start(struct mmu_notifier *mn, it = interval_tree_iter_first(&rmn->objects, start, end); while (it) { struct amdgpu_mn_node *node; - struct amdgpu_bo *bo; - long r; node = container_of(it, struct amdgpu_mn_node, it); it = interval_tree_iter_next(it, start, end); - list_for_each_entry(bo, &node->bos, mn_list) { - - if (!amdgpu_ttm_tt_affect_userptr(bo->tbo.ttm, start, - end)) - continue; - - r = amdgpu_bo_reserve(bo, true); - if (r) { - DRM_ERROR("(%ld) failed to reserve user bo\n", r); - continue; - } - - r = reservation_object_wait_timeout_rcu(bo->tbo.resv, - true, false, MAX_SCHEDULE_TIMEOUT); - if (r <= 0) - DRM_ERROR("(%ld) failed to wait for user bo\n", r); - - amdgpu_ttm_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_CPU); - r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false); - if (r) - DRM_ERROR("(%ld) failed to validate user bo\n", r); - - amdgpu_bo_unreserve(bo); - } + amdgpu_mn_invalidate_node(node, start, end); } mutex_unlock(&rmn->lock); @@ -171,6 +214,7 @@ static void amdgpu_mn_invalidate_range_start(struct mmu_notifier *mn, static const struct mmu_notifier_ops amdgpu_mn_ops = { .release = amdgpu_mn_release, + .invalidate_page = amdgpu_mn_invalidate_page, .invalidate_range_start = amdgpu_mn_invalidate_range_start, }; @@ -187,8 +231,8 @@ static struct amdgpu_mn *amdgpu_mn_get(struct amdgpu_device *adev) struct amdgpu_mn *rmn; int r; - down_write(&mm->mmap_sem); mutex_lock(&adev->mn_lock); + down_write(&mm->mmap_sem); hash_for_each_possible(adev->mn_hash, rmn, node, (unsigned long)mm) if (rmn->mm == mm) @@ -213,14 +257,14 @@ static struct amdgpu_mn *amdgpu_mn_get(struct amdgpu_device *adev) hash_add(adev->mn_hash, &rmn->node, (unsigned long)mm); release_locks: - mutex_unlock(&adev->mn_lock); up_write(&mm->mmap_sem); + mutex_unlock(&adev->mn_lock); return rmn; free_rmn: - mutex_unlock(&adev->mn_lock); up_write(&mm->mmap_sem); + mutex_unlock(&adev->mn_lock); kfree(rmn); return ERR_PTR(r); @@ -298,6 +342,7 @@ void amdgpu_mn_unregister(struct amdgpu_bo *bo) struct list_head *head; mutex_lock(&adev->mn_lock); + rmn = bo->mn; if (rmn == NULL) { mutex_unlock(&adev->mn_lock); @@ -305,6 +350,7 @@ void amdgpu_mn_unregister(struct amdgpu_bo *bo) } mutex_lock(&rmn->lock); + /* save the next list entry for later */ head = bo->mn_list.next; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index fdc1be8550da688051ade337fb26225ccb7db39e..8d432e6901af50d2267089757685f2e6f16f4f40 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h @@ -390,7 +390,6 @@ struct amdgpu_crtc { struct drm_display_mode native_mode; u32 pll_id; /* page flipping */ - struct workqueue_struct *pflip_queue; struct amdgpu_flip_work *pflip_works; enum amdgpu_flip_status pflip_status; int deferred_flip_completion; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index b8fbbd7699e4586e13e57905b0cef818f6e43e6b..5b6639faa731e83b1b14c07bf673aa30deff52c8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -97,9 +97,6 @@ static void amdgpu_ttm_bo_destroy(struct ttm_buffer_object *tbo) amdgpu_update_memory_usage(bo->adev, &bo->tbo.mem, NULL); - mutex_lock(&bo->adev->gem.mutex); - list_del_init(&bo->list); - mutex_unlock(&bo->adev->gem.mutex); drm_gem_object_release(&bo->gem_base); amdgpu_bo_unref(&bo->parent); kfree(bo->metadata); @@ -254,12 +251,15 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev, bo->adev = adev; INIT_LIST_HEAD(&bo->list); INIT_LIST_HEAD(&bo->va); - bo->initial_domain = domain & (AMDGPU_GEM_DOMAIN_VRAM | - AMDGPU_GEM_DOMAIN_GTT | - AMDGPU_GEM_DOMAIN_CPU | - AMDGPU_GEM_DOMAIN_GDS | - AMDGPU_GEM_DOMAIN_GWS | - AMDGPU_GEM_DOMAIN_OA); + bo->prefered_domains = domain & (AMDGPU_GEM_DOMAIN_VRAM | + AMDGPU_GEM_DOMAIN_GTT | + AMDGPU_GEM_DOMAIN_CPU | + AMDGPU_GEM_DOMAIN_GDS | + AMDGPU_GEM_DOMAIN_GWS | + AMDGPU_GEM_DOMAIN_OA); + bo->allowed_domains = bo->prefered_domains; + if (!kernel && bo->allowed_domains == AMDGPU_GEM_DOMAIN_VRAM) + bo->allowed_domains |= AMDGPU_GEM_DOMAIN_GTT; bo->flags = flags; @@ -308,7 +308,7 @@ int amdgpu_bo_create(struct amdgpu_device *adev, int amdgpu_bo_kmap(struct amdgpu_bo *bo, void **ptr) { bool is_iomem; - int r; + long r; if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS) return -EPERM; @@ -319,14 +319,20 @@ int amdgpu_bo_kmap(struct amdgpu_bo *bo, void **ptr) } return 0; } + + r = reservation_object_wait_timeout_rcu(bo->tbo.resv, false, false, + MAX_SCHEDULE_TIMEOUT); + if (r < 0) + return r; + r = ttm_bo_kmap(&bo->tbo, 0, bo->tbo.num_pages, &bo->kmap); - if (r) { + if (r) return r; - } + bo->kptr = ttm_kmap_obj_virtual(&bo->kmap, &is_iomem); - if (ptr) { + if (ptr) *ptr = bo->kptr; - } + return 0; } @@ -367,7 +373,7 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, int r, i; unsigned fpfn, lpfn; - if (amdgpu_ttm_tt_has_userptr(bo->tbo.ttm)) + if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm)) return -EPERM; if (WARN_ON_ONCE(min_offset > max_offset)) @@ -470,25 +476,16 @@ int amdgpu_bo_evict_vram(struct amdgpu_device *adev) return ttm_bo_evict_mm(&adev->mman.bdev, TTM_PL_VRAM); } -void amdgpu_bo_force_delete(struct amdgpu_device *adev) -{ - struct amdgpu_bo *bo, *n; - - if (list_empty(&adev->gem.objects)) { - return; - } - dev_err(adev->dev, "Userspace still has active objects !\n"); - list_for_each_entry_safe(bo, n, &adev->gem.objects, list) { - dev_err(adev->dev, "%p %p %lu %lu force free\n", - &bo->gem_base, bo, (unsigned long)bo->gem_base.size, - *((unsigned long *)&bo->gem_base.refcount)); - mutex_lock(&bo->adev->gem.mutex); - list_del_init(&bo->list); - mutex_unlock(&bo->adev->gem.mutex); - /* this should unref the ttm bo */ - drm_gem_object_unreference_unlocked(&bo->gem_base); - } -} +static const char *amdgpu_vram_names[] = { + "UNKNOWN", + "GDDR1", + "DDR2", + "GDDR3", + "GDDR4", + "GDDR5", + "HBM", + "DDR3" +}; int amdgpu_bo_init(struct amdgpu_device *adev) { @@ -498,8 +495,8 @@ int amdgpu_bo_init(struct amdgpu_device *adev) DRM_INFO("Detected VRAM RAM=%lluM, BAR=%lluM\n", adev->mc.mc_vram_size >> 20, (unsigned long long)adev->mc.aper_size >> 20); - DRM_INFO("RAM width %dbits DDR\n", - adev->mc.vram_width); + DRM_INFO("RAM width %dbits %s\n", + adev->mc.vram_width, amdgpu_vram_names[adev->mc.vram_type]); return amdgpu_ttm_init(adev); } @@ -622,6 +619,10 @@ int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo) if ((offset + size) <= adev->mc.visible_vram_size) return 0; + /* Can't move a pinned BO to visible VRAM */ + if (abo->pin_count > 0) + return -EINVAL; + /* hurrah the memory is not visible ! */ amdgpu_ttm_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_VRAM); lpfn = adev->mc.visible_vram_size >> PAGE_SHIFT; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h index 5107fb291bdbe9980a64e025bf1d88da4f1f046c..acc08018c6cc1ebfb50493b4e6a6080ab04de49a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h @@ -149,7 +149,6 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain, u64 *gpu_addr); int amdgpu_bo_unpin(struct amdgpu_bo *bo); int amdgpu_bo_evict_vram(struct amdgpu_device *adev); -void amdgpu_bo_force_delete(struct amdgpu_device *adev); int amdgpu_bo_init(struct amdgpu_device *adev); void amdgpu_bo_fini(struct amdgpu_device *adev); int amdgpu_bo_fbdev_mmap(struct amdgpu_bo *bo, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c index 95a4a25d8df9e8d37e1ec06d2d566e337353f222..ff9597ce268c69dc868f313ed0d2ab9255bea546 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c @@ -123,7 +123,9 @@ static ssize_t amdgpu_get_dpm_forced_performance_level(struct device *dev, level = amdgpu_dpm_get_performance_level(adev); return snprintf(buf, PAGE_SIZE, "%s\n", (level == AMD_DPM_FORCED_LEVEL_AUTO) ? "auto" : - (level == AMD_DPM_FORCED_LEVEL_LOW) ? "low" : "high"); + (level == AMD_DPM_FORCED_LEVEL_LOW) ? "low" : + (level == AMD_DPM_FORCED_LEVEL_HIGH) ? "high" : + (level == AMD_DPM_FORCED_LEVEL_MANUAL) ? "manual" : "unknown"); } else { enum amdgpu_dpm_forced_level level; @@ -155,6 +157,8 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev, level = AMDGPU_DPM_FORCED_LEVEL_HIGH; } else if (strncmp("auto", buf, strlen("auto")) == 0) { level = AMDGPU_DPM_FORCED_LEVEL_AUTO; + } else if (strncmp("manual", buf, strlen("manual")) == 0) { + level = AMDGPU_DPM_FORCED_LEVEL_MANUAL; } else { count = -EINVAL; goto fail; @@ -180,10 +184,293 @@ static ssize_t amdgpu_set_dpm_forced_performance_level(struct device *dev, return count; } +static ssize_t amdgpu_get_pp_num_states(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct drm_device *ddev = dev_get_drvdata(dev); + struct amdgpu_device *adev = ddev->dev_private; + struct pp_states_info data; + int i, buf_len; + + if (adev->pp_enabled) + amdgpu_dpm_get_pp_num_states(adev, &data); + + buf_len = snprintf(buf, PAGE_SIZE, "states: %d\n", data.nums); + for (i = 0; i < data.nums; i++) + buf_len += snprintf(buf + buf_len, PAGE_SIZE, "%d %s\n", i, + (data.states[i] == POWER_STATE_TYPE_INTERNAL_BOOT) ? "boot" : + (data.states[i] == POWER_STATE_TYPE_BATTERY) ? "battery" : + (data.states[i] == POWER_STATE_TYPE_BALANCED) ? "balanced" : + (data.states[i] == POWER_STATE_TYPE_PERFORMANCE) ? "performance" : "default"); + + return buf_len; +} + +static ssize_t amdgpu_get_pp_cur_state(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct drm_device *ddev = dev_get_drvdata(dev); + struct amdgpu_device *adev = ddev->dev_private; + struct pp_states_info data; + enum amd_pm_state_type pm = 0; + int i = 0; + + if (adev->pp_enabled) { + + pm = amdgpu_dpm_get_current_power_state(adev); + amdgpu_dpm_get_pp_num_states(adev, &data); + + for (i = 0; i < data.nums; i++) { + if (pm == data.states[i]) + break; + } + + if (i == data.nums) + i = -EINVAL; + } + + return snprintf(buf, PAGE_SIZE, "%d\n", i); +} + +static ssize_t amdgpu_get_pp_force_state(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct drm_device *ddev = dev_get_drvdata(dev); + struct amdgpu_device *adev = ddev->dev_private; + struct pp_states_info data; + enum amd_pm_state_type pm = 0; + int i; + + if (adev->pp_force_state_enabled && adev->pp_enabled) { + pm = amdgpu_dpm_get_current_power_state(adev); + amdgpu_dpm_get_pp_num_states(adev, &data); + + for (i = 0; i < data.nums; i++) { + if (pm == data.states[i]) + break; + } + + if (i == data.nums) + i = -EINVAL; + + return snprintf(buf, PAGE_SIZE, "%d\n", i); + + } else + return snprintf(buf, PAGE_SIZE, "\n"); +} + +static ssize_t amdgpu_set_pp_force_state(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct drm_device *ddev = dev_get_drvdata(dev); + struct amdgpu_device *adev = ddev->dev_private; + enum amd_pm_state_type state = 0; + long idx; + int ret; + + if (strlen(buf) == 1) + adev->pp_force_state_enabled = false; + else { + ret = kstrtol(buf, 0, &idx); + + if (ret) { + count = -EINVAL; + goto fail; + } + + if (adev->pp_enabled) { + struct pp_states_info data; + amdgpu_dpm_get_pp_num_states(adev, &data); + state = data.states[idx]; + /* only set user selected power states */ + if (state != POWER_STATE_TYPE_INTERNAL_BOOT && + state != POWER_STATE_TYPE_DEFAULT) { + amdgpu_dpm_dispatch_task(adev, + AMD_PP_EVENT_ENABLE_USER_STATE, &state, NULL); + adev->pp_force_state_enabled = true; + } + } + } +fail: + return count; +} + +static ssize_t amdgpu_get_pp_table(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct drm_device *ddev = dev_get_drvdata(dev); + struct amdgpu_device *adev = ddev->dev_private; + char *table = NULL; + int size, i; + + if (adev->pp_enabled) + size = amdgpu_dpm_get_pp_table(adev, &table); + else + return 0; + + if (size >= PAGE_SIZE) + size = PAGE_SIZE - 1; + + for (i = 0; i < size; i++) { + sprintf(buf + i, "%02x", table[i]); + } + sprintf(buf + i, "\n"); + + return size; +} + +static ssize_t amdgpu_set_pp_table(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct drm_device *ddev = dev_get_drvdata(dev); + struct amdgpu_device *adev = ddev->dev_private; + + if (adev->pp_enabled) + amdgpu_dpm_set_pp_table(adev, buf, count); + + return count; +} + +static ssize_t amdgpu_get_pp_dpm_sclk(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct drm_device *ddev = dev_get_drvdata(dev); + struct amdgpu_device *adev = ddev->dev_private; + ssize_t size = 0; + + if (adev->pp_enabled) + size = amdgpu_dpm_print_clock_levels(adev, PP_SCLK, buf); + + return size; +} + +static ssize_t amdgpu_set_pp_dpm_sclk(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct drm_device *ddev = dev_get_drvdata(dev); + struct amdgpu_device *adev = ddev->dev_private; + int ret; + long level; + + ret = kstrtol(buf, 0, &level); + + if (ret) { + count = -EINVAL; + goto fail; + } + + if (adev->pp_enabled) + amdgpu_dpm_force_clock_level(adev, PP_SCLK, level); +fail: + return count; +} + +static ssize_t amdgpu_get_pp_dpm_mclk(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct drm_device *ddev = dev_get_drvdata(dev); + struct amdgpu_device *adev = ddev->dev_private; + ssize_t size = 0; + + if (adev->pp_enabled) + size = amdgpu_dpm_print_clock_levels(adev, PP_MCLK, buf); + + return size; +} + +static ssize_t amdgpu_set_pp_dpm_mclk(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct drm_device *ddev = dev_get_drvdata(dev); + struct amdgpu_device *adev = ddev->dev_private; + int ret; + long level; + + ret = kstrtol(buf, 0, &level); + + if (ret) { + count = -EINVAL; + goto fail; + } + + if (adev->pp_enabled) + amdgpu_dpm_force_clock_level(adev, PP_MCLK, level); +fail: + return count; +} + +static ssize_t amdgpu_get_pp_dpm_pcie(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct drm_device *ddev = dev_get_drvdata(dev); + struct amdgpu_device *adev = ddev->dev_private; + ssize_t size = 0; + + if (adev->pp_enabled) + size = amdgpu_dpm_print_clock_levels(adev, PP_PCIE, buf); + + return size; +} + +static ssize_t amdgpu_set_pp_dpm_pcie(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct drm_device *ddev = dev_get_drvdata(dev); + struct amdgpu_device *adev = ddev->dev_private; + int ret; + long level; + + ret = kstrtol(buf, 0, &level); + + if (ret) { + count = -EINVAL; + goto fail; + } + + if (adev->pp_enabled) + amdgpu_dpm_force_clock_level(adev, PP_PCIE, level); +fail: + return count; +} + static DEVICE_ATTR(power_dpm_state, S_IRUGO | S_IWUSR, amdgpu_get_dpm_state, amdgpu_set_dpm_state); static DEVICE_ATTR(power_dpm_force_performance_level, S_IRUGO | S_IWUSR, amdgpu_get_dpm_forced_performance_level, amdgpu_set_dpm_forced_performance_level); +static DEVICE_ATTR(pp_num_states, S_IRUGO, amdgpu_get_pp_num_states, NULL); +static DEVICE_ATTR(pp_cur_state, S_IRUGO, amdgpu_get_pp_cur_state, NULL); +static DEVICE_ATTR(pp_force_state, S_IRUGO | S_IWUSR, + amdgpu_get_pp_force_state, + amdgpu_set_pp_force_state); +static DEVICE_ATTR(pp_table, S_IRUGO | S_IWUSR, + amdgpu_get_pp_table, + amdgpu_set_pp_table); +static DEVICE_ATTR(pp_dpm_sclk, S_IRUGO | S_IWUSR, + amdgpu_get_pp_dpm_sclk, + amdgpu_set_pp_dpm_sclk); +static DEVICE_ATTR(pp_dpm_mclk, S_IRUGO | S_IWUSR, + amdgpu_get_pp_dpm_mclk, + amdgpu_set_pp_dpm_mclk); +static DEVICE_ATTR(pp_dpm_pcie, S_IRUGO | S_IWUSR, + amdgpu_get_pp_dpm_pcie, + amdgpu_set_pp_dpm_pcie); static ssize_t amdgpu_hwmon_show_temp(struct device *dev, struct device_attribute *attr, @@ -637,14 +924,12 @@ static void amdgpu_dpm_change_power_state_locked(struct amdgpu_device *adev) amdgpu_dpm_print_power_state(adev, adev->pm.dpm.requested_ps); } - mutex_lock(&adev->ring_lock); - /* update whether vce is active */ ps->vce_active = adev->pm.dpm.vce_active; ret = amdgpu_dpm_pre_set_power_state(adev); if (ret) - goto done; + return; /* update display watermarks based on new power state */ amdgpu_display_bandwidth_update(adev); @@ -682,9 +967,6 @@ static void amdgpu_dpm_change_power_state_locked(struct amdgpu_device *adev) amdgpu_dpm_force_performance_level(adev, adev->pm.dpm.forced_level); } } - -done: - mutex_unlock(&adev->ring_lock); } void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable) @@ -785,6 +1067,44 @@ int amdgpu_pm_sysfs_init(struct amdgpu_device *adev) DRM_ERROR("failed to create device file for dpm state\n"); return ret; } + + if (adev->pp_enabled) { + ret = device_create_file(adev->dev, &dev_attr_pp_num_states); + if (ret) { + DRM_ERROR("failed to create device file pp_num_states\n"); + return ret; + } + ret = device_create_file(adev->dev, &dev_attr_pp_cur_state); + if (ret) { + DRM_ERROR("failed to create device file pp_cur_state\n"); + return ret; + } + ret = device_create_file(adev->dev, &dev_attr_pp_force_state); + if (ret) { + DRM_ERROR("failed to create device file pp_force_state\n"); + return ret; + } + ret = device_create_file(adev->dev, &dev_attr_pp_table); + if (ret) { + DRM_ERROR("failed to create device file pp_table\n"); + return ret; + } + ret = device_create_file(adev->dev, &dev_attr_pp_dpm_sclk); + if (ret) { + DRM_ERROR("failed to create device file pp_dpm_sclk\n"); + return ret; + } + ret = device_create_file(adev->dev, &dev_attr_pp_dpm_mclk); + if (ret) { + DRM_ERROR("failed to create device file pp_dpm_mclk\n"); + return ret; + } + ret = device_create_file(adev->dev, &dev_attr_pp_dpm_pcie); + if (ret) { + DRM_ERROR("failed to create device file pp_dpm_pcie\n"); + return ret; + } + } ret = amdgpu_debugfs_pm_init(adev); if (ret) { DRM_ERROR("Failed to register debugfs file for dpm!\n"); @@ -802,6 +1122,15 @@ void amdgpu_pm_sysfs_fini(struct amdgpu_device *adev) hwmon_device_unregister(adev->pm.int_hwmon_dev); device_remove_file(adev->dev, &dev_attr_power_dpm_state); device_remove_file(adev->dev, &dev_attr_power_dpm_force_performance_level); + if (adev->pp_enabled) { + device_remove_file(adev->dev, &dev_attr_pp_num_states); + device_remove_file(adev->dev, &dev_attr_pp_cur_state); + device_remove_file(adev->dev, &dev_attr_pp_force_state); + device_remove_file(adev->dev, &dev_attr_pp_table); + device_remove_file(adev->dev, &dev_attr_pp_dpm_sclk); + device_remove_file(adev->dev, &dev_attr_pp_dpm_mclk); + device_remove_file(adev->dev, &dev_attr_pp_dpm_pcie); + } } void amdgpu_pm_compute_clocks(struct amdgpu_device *adev) @@ -817,13 +1146,11 @@ void amdgpu_pm_compute_clocks(struct amdgpu_device *adev) int i = 0; amdgpu_display_bandwidth_update(adev); - mutex_lock(&adev->ring_lock); - for (i = 0; i < AMDGPU_MAX_RINGS; i++) { - struct amdgpu_ring *ring = adev->rings[i]; - if (ring && ring->ready) - amdgpu_fence_wait_empty(ring); - } - mutex_unlock(&adev->ring_lock); + for (i = 0; i < AMDGPU_MAX_RINGS; i++) { + struct amdgpu_ring *ring = adev->rings[i]; + if (ring && ring->ready) + amdgpu_fence_wait_empty(ring); + } amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_DISPLAY_CONFIG_CHANGE, NULL, NULL); } else { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c index 3cb6d6c413c71b0207fe1766d26ca190a083e880..e9c6ae6ed2f73357d762f9aa75406c010238dd4a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_powerplay.c @@ -143,7 +143,7 @@ static int amdgpu_pp_late_init(void *handle) adev->powerplay.pp_handle); #ifdef CONFIG_DRM_AMD_POWERPLAY - if (adev->pp_enabled) { + if (adev->pp_enabled && adev->pm.dpm_enabled) { amdgpu_pm_sysfs_init(adev); amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_COMPLETE_INIT, NULL, NULL); } @@ -161,12 +161,8 @@ static int amdgpu_pp_sw_init(void *handle) adev->powerplay.pp_handle); #ifdef CONFIG_DRM_AMD_POWERPLAY - if (adev->pp_enabled) { - if (amdgpu_dpm == 0) - adev->pm.dpm_enabled = false; - else - adev->pm.dpm_enabled = true; - } + if (adev->pp_enabled) + adev->pm.dpm_enabled = true; #endif return ret; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c index 59f735a933a939480e4e000190fe5fc042b1b395..be6388f73ba27a4caa0097954d245a38a4a73527 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c @@ -73,10 +73,6 @@ struct drm_gem_object *amdgpu_gem_prime_import_sg_table(struct drm_device *dev, if (ret) return ERR_PTR(ret); - mutex_lock(&adev->gem.mutex); - list_add_tail(&bo->list, &adev->gem.objects); - mutex_unlock(&adev->gem.mutex); - return &bo->gem_base; } @@ -121,7 +117,7 @@ struct dma_buf *amdgpu_gem_prime_export(struct drm_device *dev, { struct amdgpu_bo *bo = gem_to_amdgpu_bo(gobj); - if (amdgpu_ttm_tt_has_userptr(bo->tbo.ttm)) + if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm)) return ERR_PTR(-EPERM); return drm_gem_prime_export(dev, gobj, flags); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c index d1f234dd21261e06764b9e5b623d11ff08f20fe4..972eed2ef787eff5a49028ae58f60f3a85c47690 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c @@ -48,28 +48,6 @@ */ static int amdgpu_debugfs_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring); -/** - * amdgpu_ring_free_size - update the free size - * - * @adev: amdgpu_device pointer - * @ring: amdgpu_ring structure holding ring information - * - * Update the free dw slots in the ring buffer (all asics). - */ -void amdgpu_ring_free_size(struct amdgpu_ring *ring) -{ - uint32_t rptr = amdgpu_ring_get_rptr(ring); - - /* This works because ring_size is a power of 2 */ - ring->ring_free_dw = rptr + (ring->ring_size / 4); - ring->ring_free_dw -= ring->wptr; - ring->ring_free_dw &= ring->ptr_mask; - if (!ring->ring_free_dw) { - /* this is an empty ring */ - ring->ring_free_dw = ring->ring_size / 4; - } -} - /** * amdgpu_ring_alloc - allocate space on the ring buffer * @@ -82,50 +60,18 @@ void amdgpu_ring_free_size(struct amdgpu_ring *ring) */ int amdgpu_ring_alloc(struct amdgpu_ring *ring, unsigned ndw) { - int r; - - /* make sure we aren't trying to allocate more space than there is on the ring */ - if (ndw > (ring->ring_size / 4)) - return -ENOMEM; /* Align requested size with padding so unlock_commit can * pad safely */ - amdgpu_ring_free_size(ring); ndw = (ndw + ring->align_mask) & ~ring->align_mask; - while (ndw > (ring->ring_free_dw - 1)) { - amdgpu_ring_free_size(ring); - if (ndw < ring->ring_free_dw) { - break; - } - r = amdgpu_fence_wait_next(ring); - if (r) - return r; - } - ring->count_dw = ndw; - ring->wptr_old = ring->wptr; - return 0; -} -/** - * amdgpu_ring_lock - lock the ring and allocate space on it - * - * @adev: amdgpu_device pointer - * @ring: amdgpu_ring structure holding ring information - * @ndw: number of dwords to allocate in the ring buffer - * - * Lock the ring and allocate @ndw dwords in the ring buffer - * (all asics). - * Returns 0 on success, error on failure. - */ -int amdgpu_ring_lock(struct amdgpu_ring *ring, unsigned ndw) -{ - int r; + /* Make sure we aren't trying to allocate more space + * than the maximum for one submission + */ + if (WARN_ON_ONCE(ndw > ring->max_dw)) + return -ENOMEM; - mutex_lock(ring->ring_lock); - r = amdgpu_ring_alloc(ring, ndw); - if (r) { - mutex_unlock(ring->ring_lock); - return r; - } + ring->count_dw = ndw; + ring->wptr_old = ring->wptr; return 0; } @@ -144,6 +90,19 @@ void amdgpu_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count) amdgpu_ring_write(ring, ring->nop); } +/** amdgpu_ring_generic_pad_ib - pad IB with NOP packets + * + * @ring: amdgpu_ring structure holding ring information + * @ib: IB to add NOP packets to + * + * This is the generic pad_ib function for rings except SDMA + */ +void amdgpu_ring_generic_pad_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib) +{ + while (ib->length_dw & ring->align_mask) + ib->ptr[ib->length_dw++] = ring->nop; +} + /** * amdgpu_ring_commit - tell the GPU to execute the new * commands on the ring buffer @@ -167,20 +126,6 @@ void amdgpu_ring_commit(struct amdgpu_ring *ring) amdgpu_ring_set_wptr(ring); } -/** - * amdgpu_ring_unlock_commit - tell the GPU to execute the new - * commands on the ring buffer and unlock it - * - * @ring: amdgpu_ring structure holding ring information - * - * Call amdgpu_ring_commit() then unlock the ring (all asics). - */ -void amdgpu_ring_unlock_commit(struct amdgpu_ring *ring) -{ - amdgpu_ring_commit(ring); - mutex_unlock(ring->ring_lock); -} - /** * amdgpu_ring_undo - reset the wptr * @@ -193,19 +138,6 @@ void amdgpu_ring_undo(struct amdgpu_ring *ring) ring->wptr = ring->wptr_old; } -/** - * amdgpu_ring_unlock_undo - reset the wptr and unlock the ring - * - * @ring: amdgpu_ring structure holding ring information - * - * Call amdgpu_ring_undo() then unlock the ring (all asics). - */ -void amdgpu_ring_unlock_undo(struct amdgpu_ring *ring) -{ - amdgpu_ring_undo(ring); - mutex_unlock(ring->ring_lock); -} - /** * amdgpu_ring_backup - Back up the content of a ring * @@ -218,43 +150,32 @@ unsigned amdgpu_ring_backup(struct amdgpu_ring *ring, { unsigned size, ptr, i; - /* just in case lock the ring */ - mutex_lock(ring->ring_lock); *data = NULL; - if (ring->ring_obj == NULL) { - mutex_unlock(ring->ring_lock); + if (ring->ring_obj == NULL) return 0; - } /* it doesn't make sense to save anything if all fences are signaled */ - if (!amdgpu_fence_count_emitted(ring)) { - mutex_unlock(ring->ring_lock); + if (!amdgpu_fence_count_emitted(ring)) return 0; - } ptr = le32_to_cpu(*ring->next_rptr_cpu_addr); size = ring->wptr + (ring->ring_size / 4); size -= ptr; size &= ring->ptr_mask; - if (size == 0) { - mutex_unlock(ring->ring_lock); + if (size == 0) return 0; - } /* and then save the content of the ring */ *data = kmalloc_array(size, sizeof(uint32_t), GFP_KERNEL); - if (!*data) { - mutex_unlock(ring->ring_lock); + if (!*data) return 0; - } for (i = 0; i < size; ++i) { (*data)[i] = ring->ring[ptr++]; ptr &= ring->ptr_mask; } - mutex_unlock(ring->ring_lock); return size; } @@ -276,7 +197,7 @@ int amdgpu_ring_restore(struct amdgpu_ring *ring, return 0; /* restore the saved ring content */ - r = amdgpu_ring_lock(ring, size); + r = amdgpu_ring_alloc(ring, size); if (r) return r; @@ -284,7 +205,7 @@ int amdgpu_ring_restore(struct amdgpu_ring *ring, amdgpu_ring_write(ring, data[i]); } - amdgpu_ring_unlock_commit(ring); + amdgpu_ring_commit(ring); kfree(data); return 0; } @@ -315,7 +236,8 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, ring->adev = adev; ring->idx = adev->num_rings++; adev->rings[ring->idx] = ring; - r = amdgpu_fence_driver_init_ring(ring); + r = amdgpu_fence_driver_init_ring(ring, + amdgpu_sched_hw_submission); if (r) return r; } @@ -352,7 +274,6 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, return r; } - ring->ring_lock = &adev->ring_lock; /* Align ring size */ rb_bufsz = order_base_2(ring_size / 8); ring_size = (1 << (rb_bufsz + 1)) * 4; @@ -389,7 +310,8 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring, } } ring->ptr_mask = (ring->ring_size / 4) - 1; - ring->ring_free_dw = ring->ring_size / 4; + ring->max_dw = DIV_ROUND_UP(ring->ring_size / 4, + amdgpu_sched_hw_submission); if (amdgpu_debugfs_ring_init(adev, ring)) { DRM_ERROR("Failed to register debugfs file for rings !\n"); @@ -410,15 +332,10 @@ void amdgpu_ring_fini(struct amdgpu_ring *ring) int r; struct amdgpu_bo *ring_obj; - if (ring->ring_lock == NULL) - return; - - mutex_lock(ring->ring_lock); ring_obj = ring->ring_obj; ring->ready = false; ring->ring = NULL; ring->ring_obj = NULL; - mutex_unlock(ring->ring_lock); amdgpu_wb_free(ring->adev, ring->fence_offs); amdgpu_wb_free(ring->adev, ring->rptr_offs); @@ -436,30 +353,6 @@ void amdgpu_ring_fini(struct amdgpu_ring *ring) } } -/** - * amdgpu_ring_from_fence - get ring from fence - * - * @f: fence structure - * - * Extract the ring a fence belongs to. Handles both scheduler as - * well as hardware fences. - */ -struct amdgpu_ring *amdgpu_ring_from_fence(struct fence *f) -{ - struct amdgpu_fence *a_fence; - struct amd_sched_fence *s_fence; - - s_fence = to_amd_sched_fence(f); - if (s_fence) - return container_of(s_fence->sched, struct amdgpu_ring, sched); - - a_fence = to_amdgpu_fence(f); - if (a_fence) - return a_fence->ring; - - return NULL; -} - /* * Debugfs info */ @@ -474,29 +367,18 @@ static int amdgpu_debugfs_ring_info(struct seq_file *m, void *data) struct amdgpu_ring *ring = (void *)(((uint8_t*)adev) + roffset); uint32_t rptr, wptr, rptr_next; - unsigned count, i, j; - - amdgpu_ring_free_size(ring); - count = (ring->ring_size / 4) - ring->ring_free_dw; + unsigned i; wptr = amdgpu_ring_get_wptr(ring); - seq_printf(m, "wptr: 0x%08x [%5d]\n", - wptr, wptr); + seq_printf(m, "wptr: 0x%08x [%5d]\n", wptr, wptr); rptr = amdgpu_ring_get_rptr(ring); - seq_printf(m, "rptr: 0x%08x [%5d]\n", - rptr, rptr); - rptr_next = le32_to_cpu(*ring->next_rptr_cpu_addr); + seq_printf(m, "rptr: 0x%08x [%5d]\n", rptr, rptr); + seq_printf(m, "driver's copy of the wptr: 0x%08x [%5d]\n", ring->wptr, ring->wptr); - seq_printf(m, "last semaphore signal addr : 0x%016llx\n", - ring->last_semaphore_signal_addr); - seq_printf(m, "last semaphore wait addr : 0x%016llx\n", - ring->last_semaphore_wait_addr); - seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw); - seq_printf(m, "%u dwords in ring\n", count); if (!ring->ready) return 0; @@ -505,11 +387,20 @@ static int amdgpu_debugfs_ring_info(struct seq_file *m, void *data) * packet that is the root issue */ i = (rptr + ring->ptr_mask + 1 - 32) & ring->ptr_mask; - for (j = 0; j <= (count + 32); j++) { + while (i != rptr) { + seq_printf(m, "r[%5d]=0x%08x", i, ring->ring[i]); + if (i == rptr) + seq_puts(m, " *"); + if (i == rptr_next) + seq_puts(m, " #"); + seq_puts(m, "\n"); + i = (i + 1) & ring->ptr_mask; + } + while (i != wptr) { seq_printf(m, "r[%5d]=0x%08x", i, ring->ring[i]); - if (rptr == i) + if (i == rptr) seq_puts(m, " *"); - if (rptr_next == i) + if (i == rptr_next) seq_puts(m, " #"); seq_puts(m, "\n"); i = (i + 1) & ring->ptr_mask; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c index ca72a2e487b9b9d846b65479e9b865dd1ef71281..8bf84efafb049cd693e156a8dbf2dff396c70164 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c @@ -60,9 +60,8 @@ int amdgpu_sa_bo_manager_init(struct amdgpu_device *adev, sa_manager->align = align; sa_manager->hole = &sa_manager->olist; INIT_LIST_HEAD(&sa_manager->olist); - for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { + for (i = 0; i < AMDGPU_SA_NUM_FENCE_LISTS; ++i) INIT_LIST_HEAD(&sa_manager->flist[i]); - } r = amdgpu_bo_create(adev, size, align, true, domain, 0, NULL, NULL, &sa_manager->bo); @@ -228,11 +227,9 @@ static bool amdgpu_sa_event(struct amdgpu_sa_manager *sa_manager, unsigned soffset, eoffset, wasted; int i; - for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { - if (!list_empty(&sa_manager->flist[i])) { + for (i = 0; i < AMDGPU_SA_NUM_FENCE_LISTS; ++i) + if (!list_empty(&sa_manager->flist[i])) return true; - } - } soffset = amdgpu_sa_bo_hole_soffset(sa_manager); eoffset = amdgpu_sa_bo_hole_eoffset(sa_manager); @@ -265,12 +262,11 @@ static bool amdgpu_sa_bo_next_hole(struct amdgpu_sa_manager *sa_manager, /* go over all fence list and try to find the closest sa_bo * of the current last */ - for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { + for (i = 0; i < AMDGPU_SA_NUM_FENCE_LISTS; ++i) { struct amdgpu_sa_bo *sa_bo; - if (list_empty(&sa_manager->flist[i])) { + if (list_empty(&sa_manager->flist[i])) continue; - } sa_bo = list_first_entry(&sa_manager->flist[i], struct amdgpu_sa_bo, flist); @@ -299,7 +295,9 @@ static bool amdgpu_sa_bo_next_hole(struct amdgpu_sa_manager *sa_manager, } if (best_bo) { - uint32_t idx = amdgpu_ring_from_fence(best_bo->fence)->idx; + uint32_t idx = best_bo->fence->context; + + idx %= AMDGPU_SA_NUM_FENCE_LISTS; ++tries[idx]; sa_manager->hole = best_bo->olist.prev; @@ -315,14 +313,17 @@ int amdgpu_sa_bo_new(struct amdgpu_sa_manager *sa_manager, struct amdgpu_sa_bo **sa_bo, unsigned size, unsigned align) { - struct fence *fences[AMDGPU_MAX_RINGS]; - unsigned tries[AMDGPU_MAX_RINGS]; + struct fence *fences[AMDGPU_SA_NUM_FENCE_LISTS]; + unsigned tries[AMDGPU_SA_NUM_FENCE_LISTS]; unsigned count; int i, r; signed long t; - BUG_ON(align > sa_manager->align); - BUG_ON(size > sa_manager->size); + if (WARN_ON_ONCE(align > sa_manager->align)) + return -EINVAL; + + if (WARN_ON_ONCE(size > sa_manager->size)) + return -EINVAL; *sa_bo = kmalloc(sizeof(struct amdgpu_sa_bo), GFP_KERNEL); if ((*sa_bo) == NULL) { @@ -335,7 +336,7 @@ int amdgpu_sa_bo_new(struct amdgpu_sa_manager *sa_manager, spin_lock(&sa_manager->wq.lock); do { - for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { + for (i = 0; i < AMDGPU_SA_NUM_FENCE_LISTS; ++i) { fences[i] = NULL; tries[i] = 0; } @@ -352,7 +353,7 @@ int amdgpu_sa_bo_new(struct amdgpu_sa_manager *sa_manager, /* see if we can skip over some allocations */ } while (amdgpu_sa_bo_next_hole(sa_manager, fences, tries)); - for (i = 0, count = 0; i < AMDGPU_MAX_RINGS; ++i) + for (i = 0, count = 0; i < AMDGPU_SA_NUM_FENCE_LISTS; ++i) if (fences[i]) fences[count++] = fence_get(fences[i]); @@ -394,8 +395,9 @@ void amdgpu_sa_bo_free(struct amdgpu_device *adev, struct amdgpu_sa_bo **sa_bo, spin_lock(&sa_manager->wq.lock); if (fence && !fence_is_signaled(fence)) { uint32_t idx; + (*sa_bo)->fence = fence_get(fence); - idx = amdgpu_ring_from_fence(fence)->idx; + idx = fence->context % AMDGPU_SA_NUM_FENCE_LISTS; list_add_tail(&(*sa_bo)->flist, &sa_manager->flist[idx]); } else { amdgpu_sa_bo_remove_locked(*sa_bo); @@ -407,25 +409,6 @@ void amdgpu_sa_bo_free(struct amdgpu_device *adev, struct amdgpu_sa_bo **sa_bo, #if defined(CONFIG_DEBUG_FS) -static void amdgpu_sa_bo_dump_fence(struct fence *fence, struct seq_file *m) -{ - struct amdgpu_fence *a_fence = to_amdgpu_fence(fence); - struct amd_sched_fence *s_fence = to_amd_sched_fence(fence); - - if (a_fence) - seq_printf(m, " protected by 0x%016llx on ring %d", - a_fence->seq, a_fence->ring->idx); - - if (s_fence) { - struct amdgpu_ring *ring; - - - ring = container_of(s_fence->sched, struct amdgpu_ring, sched); - seq_printf(m, " protected by 0x%016x on ring %d", - s_fence->base.seqno, ring->idx); - } -} - void amdgpu_sa_bo_dump_debug_info(struct amdgpu_sa_manager *sa_manager, struct seq_file *m) { @@ -442,8 +425,11 @@ void amdgpu_sa_bo_dump_debug_info(struct amdgpu_sa_manager *sa_manager, } seq_printf(m, "[0x%010llx 0x%010llx] size %8lld", soffset, eoffset, eoffset - soffset); + if (i->fence) - amdgpu_sa_bo_dump_fence(i->fence, m); + seq_printf(m, " protected by 0x%08x on context %d", + i->fence->seqno, i->fence->context); + seq_printf(m, "\n"); } spin_unlock(&sa_manager->wq.lock); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c deleted file mode 100644 index 438c05254695586bb95a9e3caa2ea356aa4b941f..0000000000000000000000000000000000000000 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2015 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * - */ -#include -#include -#include -#include -#include "amdgpu.h" -#include "amdgpu_trace.h" - -static struct fence *amdgpu_sched_dependency(struct amd_sched_job *sched_job) -{ - struct amdgpu_job *job = to_amdgpu_job(sched_job); - return amdgpu_sync_get_fence(&job->ibs->sync); -} - -static struct fence *amdgpu_sched_run_job(struct amd_sched_job *sched_job) -{ - struct amdgpu_fence *fence = NULL; - struct amdgpu_job *job; - int r; - - if (!sched_job) { - DRM_ERROR("job is null\n"); - return NULL; - } - job = to_amdgpu_job(sched_job); - trace_amdgpu_sched_run_job(job); - r = amdgpu_ib_schedule(job->adev, job->num_ibs, job->ibs, job->owner); - if (r) { - DRM_ERROR("Error scheduling IBs (%d)\n", r); - goto err; - } - - fence = job->ibs[job->num_ibs - 1].fence; - fence_get(&fence->base); - -err: - if (job->free_job) - job->free_job(job); - - kfree(job); - return fence ? &fence->base : NULL; -} - -struct amd_sched_backend_ops amdgpu_sched_ops = { - .dependency = amdgpu_sched_dependency, - .run_job = amdgpu_sched_run_job, -}; - -int amdgpu_sched_ib_submit_kernel_helper(struct amdgpu_device *adev, - struct amdgpu_ring *ring, - struct amdgpu_ib *ibs, - unsigned num_ibs, - int (*free_job)(struct amdgpu_job *), - void *owner, - struct fence **f) -{ - int r = 0; - if (amdgpu_enable_scheduler) { - struct amdgpu_job *job = - kzalloc(sizeof(struct amdgpu_job), GFP_KERNEL); - if (!job) - return -ENOMEM; - job->base.sched = &ring->sched; - job->base.s_entity = &adev->kernel_ctx.rings[ring->idx].entity; - job->base.s_fence = amd_sched_fence_create(job->base.s_entity, owner); - if (!job->base.s_fence) { - kfree(job); - return -ENOMEM; - } - *f = fence_get(&job->base.s_fence->base); - - job->adev = adev; - job->ibs = ibs; - job->num_ibs = num_ibs; - job->owner = owner; - job->free_job = free_job; - amd_sched_entity_push_job(&job->base); - } else { - r = amdgpu_ib_schedule(adev, num_ibs, ibs, owner); - if (r) - return r; - *f = fence_get(&ibs[num_ibs - 1].fence->base); - } - - return 0; -} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_semaphore.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_semaphore.c deleted file mode 100644 index 1caaf201b708a0487db721fc5bb9b341370d26df..0000000000000000000000000000000000000000 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_semaphore.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2011 Christian König. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - */ -/* - * Authors: - * Christian König - */ -#include -#include "amdgpu.h" -#include "amdgpu_trace.h" - -int amdgpu_semaphore_create(struct amdgpu_device *adev, - struct amdgpu_semaphore **semaphore) -{ - int r; - - *semaphore = kmalloc(sizeof(struct amdgpu_semaphore), GFP_KERNEL); - if (*semaphore == NULL) { - return -ENOMEM; - } - r = amdgpu_sa_bo_new(&adev->ring_tmp_bo, - &(*semaphore)->sa_bo, 8, 8); - if (r) { - kfree(*semaphore); - *semaphore = NULL; - return r; - } - (*semaphore)->waiters = 0; - (*semaphore)->gpu_addr = amdgpu_sa_bo_gpu_addr((*semaphore)->sa_bo); - - *((uint64_t *)amdgpu_sa_bo_cpu_addr((*semaphore)->sa_bo)) = 0; - - return 0; -} - -bool amdgpu_semaphore_emit_signal(struct amdgpu_ring *ring, - struct amdgpu_semaphore *semaphore) -{ - trace_amdgpu_semaphore_signale(ring->idx, semaphore); - - if (amdgpu_ring_emit_semaphore(ring, semaphore, false)) { - --semaphore->waiters; - - /* for debugging lockup only, used by sysfs debug files */ - ring->last_semaphore_signal_addr = semaphore->gpu_addr; - return true; - } - return false; -} - -bool amdgpu_semaphore_emit_wait(struct amdgpu_ring *ring, - struct amdgpu_semaphore *semaphore) -{ - trace_amdgpu_semaphore_wait(ring->idx, semaphore); - - if (amdgpu_ring_emit_semaphore(ring, semaphore, true)) { - ++semaphore->waiters; - - /* for debugging lockup only, used by sysfs debug files */ - ring->last_semaphore_wait_addr = semaphore->gpu_addr; - return true; - } - return false; -} - -void amdgpu_semaphore_free(struct amdgpu_device *adev, - struct amdgpu_semaphore **semaphore, - struct fence *fence) -{ - if (semaphore == NULL || *semaphore == NULL) { - return; - } - if ((*semaphore)->waiters > 0) { - dev_err(adev->dev, "semaphore %p has more waiters than signalers," - " hardware lockup imminent!\n", *semaphore); - } - amdgpu_sa_bo_free(adev, &(*semaphore)->sa_bo, fence); - kfree(*semaphore); - *semaphore = NULL; -} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c index 181ce39ef5e59f8e4d4fbf2feeb617af63deb611..c48b4fce5e57af9196eb2887f9969d49dec1a7ed 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c @@ -37,6 +37,8 @@ struct amdgpu_sync_entry { struct fence *fence; }; +static struct kmem_cache *amdgpu_sync_slab; + /** * amdgpu_sync_create - zero init sync object * @@ -46,26 +48,22 @@ struct amdgpu_sync_entry { */ void amdgpu_sync_create(struct amdgpu_sync *sync) { - unsigned i; - - for (i = 0; i < AMDGPU_NUM_SYNCS; ++i) - sync->semaphores[i] = NULL; - - for (i = 0; i < AMDGPU_MAX_RINGS; ++i) - sync->sync_to[i] = NULL; - hash_init(sync->fences); sync->last_vm_update = NULL; } +/** + * amdgpu_sync_same_dev - test if fence belong to us + * + * @adev: amdgpu device to use for the test + * @f: fence to test + * + * Test if the fence was issued by us. + */ static bool amdgpu_sync_same_dev(struct amdgpu_device *adev, struct fence *f) { - struct amdgpu_fence *a_fence = to_amdgpu_fence(f); struct amd_sched_fence *s_fence = to_amd_sched_fence(f); - if (a_fence) - return a_fence->ring->adev == adev; - if (s_fence) { struct amdgpu_ring *ring; @@ -76,17 +74,31 @@ static bool amdgpu_sync_same_dev(struct amdgpu_device *adev, struct fence *f) return false; } -static bool amdgpu_sync_test_owner(struct fence *f, void *owner) +/** + * amdgpu_sync_get_owner - extract the owner of a fence + * + * @fence: fence get the owner from + * + * Extract who originally created the fence. + */ +static void *amdgpu_sync_get_owner(struct fence *f) { - struct amdgpu_fence *a_fence = to_amdgpu_fence(f); struct amd_sched_fence *s_fence = to_amd_sched_fence(f); + if (s_fence) - return s_fence->owner == owner; - if (a_fence) - return a_fence->owner == owner; - return false; + return s_fence->owner; + + return AMDGPU_FENCE_OWNER_UNDEFINED; } +/** + * amdgpu_sync_keep_later - Keep the later fence + * + * @keep: existing fence to test + * @fence: new fence + * + * Either keep the existing fence or the new one, depending which one is later. + */ static void amdgpu_sync_keep_later(struct fence **keep, struct fence *fence) { if (*keep && fence_is_later(*keep, fence)) @@ -107,59 +119,39 @@ int amdgpu_sync_fence(struct amdgpu_device *adev, struct amdgpu_sync *sync, struct fence *f) { struct amdgpu_sync_entry *e; - struct amdgpu_fence *fence; if (!f) return 0; if (amdgpu_sync_same_dev(adev, f) && - amdgpu_sync_test_owner(f, AMDGPU_FENCE_OWNER_VM)) + amdgpu_sync_get_owner(f) == AMDGPU_FENCE_OWNER_VM) amdgpu_sync_keep_later(&sync->last_vm_update, f); - fence = to_amdgpu_fence(f); - if (!fence || fence->ring->adev != adev) { - hash_for_each_possible(sync->fences, e, node, f->context) { - if (unlikely(e->fence->context != f->context)) - continue; - - amdgpu_sync_keep_later(&e->fence, f); - return 0; - } - - e = kmalloc(sizeof(struct amdgpu_sync_entry), GFP_KERNEL); - if (!e) - return -ENOMEM; + hash_for_each_possible(sync->fences, e, node, f->context) { + if (unlikely(e->fence->context != f->context)) + continue; - hash_add(sync->fences, &e->node, f->context); - e->fence = fence_get(f); + amdgpu_sync_keep_later(&e->fence, f); return 0; } - amdgpu_sync_keep_later(&sync->sync_to[fence->ring->idx], f); + e = kmem_cache_alloc(amdgpu_sync_slab, GFP_KERNEL); + if (!e) + return -ENOMEM; + hash_add(sync->fences, &e->node, f->context); + e->fence = fence_get(f); return 0; } -static void *amdgpu_sync_get_owner(struct fence *f) -{ - struct amdgpu_fence *a_fence = to_amdgpu_fence(f); - struct amd_sched_fence *s_fence = to_amd_sched_fence(f); - - if (s_fence) - return s_fence->owner; - else if (a_fence) - return a_fence->owner; - return AMDGPU_FENCE_OWNER_UNDEFINED; -} - /** - * amdgpu_sync_resv - use the semaphores to sync to a reservation object + * amdgpu_sync_resv - sync to a reservation object * * @sync: sync object to add fences from reservation object to * @resv: reservation object with embedded fence * @shared: true if we should only sync to the exclusive fence * - * Sync to the fence using the semaphore objects + * Sync to the fence */ int amdgpu_sync_resv(struct amdgpu_device *adev, struct amdgpu_sync *sync, @@ -224,7 +216,7 @@ struct fence *amdgpu_sync_get_fence(struct amdgpu_sync *sync) f = e->fence; hash_del(&e->node); - kfree(e); + kmem_cache_free(amdgpu_sync_slab, e); if (!fence_is_signaled(f)) return f; @@ -247,109 +239,7 @@ int amdgpu_sync_wait(struct amdgpu_sync *sync) hash_del(&e->node); fence_put(e->fence); - kfree(e); - } - - if (amdgpu_enable_semaphores) - return 0; - - for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { - struct fence *fence = sync->sync_to[i]; - if (!fence) - continue; - - r = fence_wait(fence, false); - if (r) - return r; - } - - return 0; -} - -/** - * amdgpu_sync_rings - sync ring to all registered fences - * - * @sync: sync object to use - * @ring: ring that needs sync - * - * Ensure that all registered fences are signaled before letting - * the ring continue. The caller must hold the ring lock. - */ -int amdgpu_sync_rings(struct amdgpu_sync *sync, - struct amdgpu_ring *ring) -{ - struct amdgpu_device *adev = ring->adev; - unsigned count = 0; - int i, r; - - for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { - struct amdgpu_ring *other = adev->rings[i]; - struct amdgpu_semaphore *semaphore; - struct amdgpu_fence *fence; - - if (!sync->sync_to[i]) - continue; - - fence = to_amdgpu_fence(sync->sync_to[i]); - - /* check if we really need to sync */ - if (!amdgpu_enable_scheduler && - !amdgpu_fence_need_sync(fence, ring)) - continue; - - /* prevent GPU deadlocks */ - if (!other->ready) { - dev_err(adev->dev, "Syncing to a disabled ring!"); - return -EINVAL; - } - - if (amdgpu_enable_scheduler || !amdgpu_enable_semaphores) { - r = fence_wait(sync->sync_to[i], true); - if (r) - return r; - continue; - } - - if (count >= AMDGPU_NUM_SYNCS) { - /* not enough room, wait manually */ - r = fence_wait(&fence->base, false); - if (r) - return r; - continue; - } - r = amdgpu_semaphore_create(adev, &semaphore); - if (r) - return r; - - sync->semaphores[count++] = semaphore; - - /* allocate enough space for sync command */ - r = amdgpu_ring_alloc(other, 16); - if (r) - return r; - - /* emit the signal semaphore */ - if (!amdgpu_semaphore_emit_signal(other, semaphore)) { - /* signaling wasn't successful wait manually */ - amdgpu_ring_undo(other); - r = fence_wait(&fence->base, false); - if (r) - return r; - continue; - } - - /* we assume caller has already allocated space on waiters ring */ - if (!amdgpu_semaphore_emit_wait(ring, semaphore)) { - /* waiting wasn't successful wait manually */ - amdgpu_ring_undo(other); - r = fence_wait(&fence->base, false); - if (r) - return r; - continue; - } - - amdgpu_ring_commit(other); - amdgpu_fence_note_sync(fence, ring); + kmem_cache_free(amdgpu_sync_slab, e); } return 0; @@ -358,15 +248,11 @@ int amdgpu_sync_rings(struct amdgpu_sync *sync, /** * amdgpu_sync_free - free the sync object * - * @adev: amdgpu_device pointer * @sync: sync object to use - * @fence: fence to use for the free * - * Free the sync object by freeing all semaphores in it. + * Free the sync object. */ -void amdgpu_sync_free(struct amdgpu_device *adev, - struct amdgpu_sync *sync, - struct fence *fence) +void amdgpu_sync_free(struct amdgpu_sync *sync) { struct amdgpu_sync_entry *e; struct hlist_node *tmp; @@ -375,14 +261,34 @@ void amdgpu_sync_free(struct amdgpu_device *adev, hash_for_each_safe(sync->fences, i, tmp, e, node) { hash_del(&e->node); fence_put(e->fence); - kfree(e); + kmem_cache_free(amdgpu_sync_slab, e); } - for (i = 0; i < AMDGPU_NUM_SYNCS; ++i) - amdgpu_semaphore_free(adev, &sync->semaphores[i], fence); + fence_put(sync->last_vm_update); +} + +/** + * amdgpu_sync_init - init sync object subsystem + * + * Allocate the slab allocator. + */ +int amdgpu_sync_init(void) +{ + amdgpu_sync_slab = kmem_cache_create( + "amdgpu_sync", sizeof(struct amdgpu_sync_entry), 0, + SLAB_HWCACHE_ALIGN, NULL); + if (!amdgpu_sync_slab) + return -ENOMEM; - for (i = 0; i < AMDGPU_MAX_RINGS; ++i) - fence_put(sync->sync_to[i]); + return 0; +} - fence_put(sync->last_vm_update); +/** + * amdgpu_sync_fini - fini sync object subsystem + * + * Free the slab allocator. + */ +void amdgpu_sync_fini(void) +{ + kmem_cache_destroy(amdgpu_sync_slab); } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c index 4865615e9c0669d0c2699c7ffd0ae8d11f69b527..05a53f4fc3349e8b5075d56e37c45dcc5da49cf7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_test.c @@ -238,144 +238,10 @@ void amdgpu_test_moves(struct amdgpu_device *adev) amdgpu_do_test_moves(adev); } -static int amdgpu_test_create_and_emit_fence(struct amdgpu_device *adev, - struct amdgpu_ring *ring, - struct fence **fence) -{ - uint32_t handle = ring->idx ^ 0xdeafbeef; - int r; - - if (ring == &adev->uvd.ring) { - r = amdgpu_uvd_get_create_msg(ring, handle, NULL); - if (r) { - DRM_ERROR("Failed to get dummy create msg\n"); - return r; - } - - r = amdgpu_uvd_get_destroy_msg(ring, handle, fence); - if (r) { - DRM_ERROR("Failed to get dummy destroy msg\n"); - return r; - } - - } else if (ring == &adev->vce.ring[0] || - ring == &adev->vce.ring[1]) { - r = amdgpu_vce_get_create_msg(ring, handle, NULL); - if (r) { - DRM_ERROR("Failed to get dummy create msg\n"); - return r; - } - - r = amdgpu_vce_get_destroy_msg(ring, handle, fence); - if (r) { - DRM_ERROR("Failed to get dummy destroy msg\n"); - return r; - } - } else { - struct amdgpu_fence *a_fence = NULL; - r = amdgpu_ring_lock(ring, 64); - if (r) { - DRM_ERROR("Failed to lock ring A %d\n", ring->idx); - return r; - } - amdgpu_fence_emit(ring, AMDGPU_FENCE_OWNER_UNDEFINED, &a_fence); - amdgpu_ring_unlock_commit(ring); - *fence = &a_fence->base; - } - return 0; -} - void amdgpu_test_ring_sync(struct amdgpu_device *adev, struct amdgpu_ring *ringA, struct amdgpu_ring *ringB) { - struct fence *fence1 = NULL, *fence2 = NULL; - struct amdgpu_semaphore *semaphore = NULL; - int r; - - r = amdgpu_semaphore_create(adev, &semaphore); - if (r) { - DRM_ERROR("Failed to create semaphore\n"); - goto out_cleanup; - } - - r = amdgpu_ring_lock(ringA, 64); - if (r) { - DRM_ERROR("Failed to lock ring A %d\n", ringA->idx); - goto out_cleanup; - } - amdgpu_semaphore_emit_wait(ringA, semaphore); - amdgpu_ring_unlock_commit(ringA); - - r = amdgpu_test_create_and_emit_fence(adev, ringA, &fence1); - if (r) - goto out_cleanup; - - r = amdgpu_ring_lock(ringA, 64); - if (r) { - DRM_ERROR("Failed to lock ring A %d\n", ringA->idx); - goto out_cleanup; - } - amdgpu_semaphore_emit_wait(ringA, semaphore); - amdgpu_ring_unlock_commit(ringA); - - r = amdgpu_test_create_and_emit_fence(adev, ringA, &fence2); - if (r) - goto out_cleanup; - - mdelay(1000); - - if (fence_is_signaled(fence1)) { - DRM_ERROR("Fence 1 signaled without waiting for semaphore.\n"); - goto out_cleanup; - } - - r = amdgpu_ring_lock(ringB, 64); - if (r) { - DRM_ERROR("Failed to lock ring B %p\n", ringB); - goto out_cleanup; - } - amdgpu_semaphore_emit_signal(ringB, semaphore); - amdgpu_ring_unlock_commit(ringB); - - r = fence_wait(fence1, false); - if (r) { - DRM_ERROR("Failed to wait for sync fence 1\n"); - goto out_cleanup; - } - - mdelay(1000); - - if (fence_is_signaled(fence2)) { - DRM_ERROR("Fence 2 signaled without waiting for semaphore.\n"); - goto out_cleanup; - } - - r = amdgpu_ring_lock(ringB, 64); - if (r) { - DRM_ERROR("Failed to lock ring B %p\n", ringB); - goto out_cleanup; - } - amdgpu_semaphore_emit_signal(ringB, semaphore); - amdgpu_ring_unlock_commit(ringB); - - r = fence_wait(fence2, false); - if (r) { - DRM_ERROR("Failed to wait for sync fence 1\n"); - goto out_cleanup; - } - -out_cleanup: - amdgpu_semaphore_free(adev, &semaphore, NULL); - - if (fence1) - fence_put(fence1); - - if (fence2) - fence_put(fence2); - - if (r) - printk(KERN_WARNING "Error while testing ring sync (%d).\n", r); } static void amdgpu_test_ring_sync2(struct amdgpu_device *adev, @@ -383,109 +249,6 @@ static void amdgpu_test_ring_sync2(struct amdgpu_device *adev, struct amdgpu_ring *ringB, struct amdgpu_ring *ringC) { - struct fence *fenceA = NULL, *fenceB = NULL; - struct amdgpu_semaphore *semaphore = NULL; - bool sigA, sigB; - int i, r; - - r = amdgpu_semaphore_create(adev, &semaphore); - if (r) { - DRM_ERROR("Failed to create semaphore\n"); - goto out_cleanup; - } - - r = amdgpu_ring_lock(ringA, 64); - if (r) { - DRM_ERROR("Failed to lock ring A %d\n", ringA->idx); - goto out_cleanup; - } - amdgpu_semaphore_emit_wait(ringA, semaphore); - amdgpu_ring_unlock_commit(ringA); - - r = amdgpu_test_create_and_emit_fence(adev, ringA, &fenceA); - if (r) - goto out_cleanup; - - r = amdgpu_ring_lock(ringB, 64); - if (r) { - DRM_ERROR("Failed to lock ring B %d\n", ringB->idx); - goto out_cleanup; - } - amdgpu_semaphore_emit_wait(ringB, semaphore); - amdgpu_ring_unlock_commit(ringB); - r = amdgpu_test_create_and_emit_fence(adev, ringB, &fenceB); - if (r) - goto out_cleanup; - - mdelay(1000); - - if (fence_is_signaled(fenceA)) { - DRM_ERROR("Fence A signaled without waiting for semaphore.\n"); - goto out_cleanup; - } - if (fence_is_signaled(fenceB)) { - DRM_ERROR("Fence B signaled without waiting for semaphore.\n"); - goto out_cleanup; - } - - r = amdgpu_ring_lock(ringC, 64); - if (r) { - DRM_ERROR("Failed to lock ring B %p\n", ringC); - goto out_cleanup; - } - amdgpu_semaphore_emit_signal(ringC, semaphore); - amdgpu_ring_unlock_commit(ringC); - - for (i = 0; i < 30; ++i) { - mdelay(100); - sigA = fence_is_signaled(fenceA); - sigB = fence_is_signaled(fenceB); - if (sigA || sigB) - break; - } - - if (!sigA && !sigB) { - DRM_ERROR("Neither fence A nor B has been signaled\n"); - goto out_cleanup; - } else if (sigA && sigB) { - DRM_ERROR("Both fence A and B has been signaled\n"); - goto out_cleanup; - } - - DRM_INFO("Fence %c was first signaled\n", sigA ? 'A' : 'B'); - - r = amdgpu_ring_lock(ringC, 64); - if (r) { - DRM_ERROR("Failed to lock ring B %p\n", ringC); - goto out_cleanup; - } - amdgpu_semaphore_emit_signal(ringC, semaphore); - amdgpu_ring_unlock_commit(ringC); - - mdelay(1000); - - r = fence_wait(fenceA, false); - if (r) { - DRM_ERROR("Failed to wait for sync fence A\n"); - goto out_cleanup; - } - r = fence_wait(fenceB, false); - if (r) { - DRM_ERROR("Failed to wait for sync fence B\n"); - goto out_cleanup; - } - -out_cleanup: - amdgpu_semaphore_free(adev, &semaphore, NULL); - - if (fenceA) - fence_put(fenceA); - - if (fenceB) - fence_put(fenceB); - - if (r) - printk(KERN_WARNING "Error while testing ring sync (%d).\n", r); } static bool amdgpu_test_sync_possible(struct amdgpu_ring *ringA, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h index 8f9834ab1bd5a6ad2e0908dfeb0aa6ff5206fc31..26a5f4acf5840ed6218a49cd654b678005431481 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h @@ -38,10 +38,10 @@ TRACE_EVENT(amdgpu_cs, TP_fast_assign( __entry->bo_list = p->bo_list; - __entry->ring = p->ibs[i].ring->idx; - __entry->dw = p->ibs[i].length_dw; + __entry->ring = p->job->ring->idx; + __entry->dw = p->job->ibs[i].length_dw; __entry->fences = amdgpu_fence_count_emitted( - p->ibs[i].ring); + p->job->ring); ), TP_printk("bo_list=%p, ring=%u, dw=%u, fences=%u", __entry->bo_list, __entry->ring, __entry->dw, @@ -65,7 +65,7 @@ TRACE_EVENT(amdgpu_cs_ioctl, __entry->sched_job = &job->base; __entry->ib = job->ibs; __entry->fence = &job->base.s_fence->base; - __entry->ring_name = job->ibs[0].ring->name; + __entry->ring_name = job->ring->name; __entry->num_ibs = job->num_ibs; ), TP_printk("adev=%p, sched_job=%p, first ib=%p, sched fence=%p, ring name:%s, num_ibs:%u", @@ -90,7 +90,7 @@ TRACE_EVENT(amdgpu_sched_run_job, __entry->sched_job = &job->base; __entry->ib = job->ibs; __entry->fence = &job->base.s_fence->base; - __entry->ring_name = job->ibs[0].ring->name; + __entry->ring_name = job->ring->name; __entry->num_ibs = job->num_ibs; ), TP_printk("adev=%p, sched_job=%p, first ib=%p, sched fence=%p, ring name:%s, num_ibs:%u", @@ -100,18 +100,24 @@ TRACE_EVENT(amdgpu_sched_run_job, TRACE_EVENT(amdgpu_vm_grab_id, - TP_PROTO(unsigned vmid, int ring), - TP_ARGS(vmid, ring), + TP_PROTO(struct amdgpu_vm *vm, int ring, unsigned vmid, + uint64_t pd_addr), + TP_ARGS(vm, ring, vmid, pd_addr), TP_STRUCT__entry( - __field(u32, vmid) + __field(struct amdgpu_vm *, vm) __field(u32, ring) + __field(u32, vmid) + __field(u64, pd_addr) ), TP_fast_assign( - __entry->vmid = vmid; + __entry->vm = vm; __entry->ring = ring; + __entry->vmid = vmid; + __entry->pd_addr = pd_addr; ), - TP_printk("vmid=%u, ring=%u", __entry->vmid, __entry->ring) + TP_printk("vm=%p, ring=%u, id=%u, pd_addr=%010Lx", __entry->vm, + __entry->ring, __entry->vmid, __entry->pd_addr) ); TRACE_EVENT(amdgpu_vm_bo_map, @@ -228,8 +234,8 @@ TRACE_EVENT(amdgpu_vm_flush, __entry->ring = ring; __entry->id = id; ), - TP_printk("pd_addr=%010Lx, ring=%u, id=%u", - __entry->pd_addr, __entry->ring, __entry->id) + TP_printk("ring=%u, id=%u, pd_addr=%010Lx", + __entry->ring, __entry->id, __entry->pd_addr) ); TRACE_EVENT(amdgpu_bo_list_set, @@ -247,42 +253,6 @@ TRACE_EVENT(amdgpu_bo_list_set, TP_printk("list=%p, bo=%p", __entry->list, __entry->bo) ); -DECLARE_EVENT_CLASS(amdgpu_semaphore_request, - - TP_PROTO(int ring, struct amdgpu_semaphore *sem), - - TP_ARGS(ring, sem), - - TP_STRUCT__entry( - __field(int, ring) - __field(signed, waiters) - __field(uint64_t, gpu_addr) - ), - - TP_fast_assign( - __entry->ring = ring; - __entry->waiters = sem->waiters; - __entry->gpu_addr = sem->gpu_addr; - ), - - TP_printk("ring=%u, waiters=%d, addr=%010Lx", __entry->ring, - __entry->waiters, __entry->gpu_addr) -); - -DEFINE_EVENT(amdgpu_semaphore_request, amdgpu_semaphore_signale, - - TP_PROTO(int ring, struct amdgpu_semaphore *sem), - - TP_ARGS(ring, sem) -); - -DEFINE_EVENT(amdgpu_semaphore_request, amdgpu_semaphore_wait, - - TP_PROTO(int ring, struct amdgpu_semaphore *sem), - - TP_ARGS(ring, sem) -); - #endif /* This part must be outside protection */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 1cbb16e153079e7463a0ac070d1a19461deb588e..6f3369de232fe5f545382a6cc2ca528bdf8c1026 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -77,6 +77,8 @@ static void amdgpu_ttm_mem_global_release(struct drm_global_reference *ref) static int amdgpu_ttm_global_init(struct amdgpu_device *adev) { struct drm_global_reference *global_ref; + struct amdgpu_ring *ring; + struct amd_sched_rq *rq; int r; adev->mman.mem_global_referenced = false; @@ -106,13 +108,27 @@ static int amdgpu_ttm_global_init(struct amdgpu_device *adev) return r; } + ring = adev->mman.buffer_funcs_ring; + rq = &ring->sched.sched_rq[AMD_SCHED_PRIORITY_KERNEL]; + r = amd_sched_entity_init(&ring->sched, &adev->mman.entity, + rq, amdgpu_sched_jobs); + if (r != 0) { + DRM_ERROR("Failed setting up TTM BO move run queue.\n"); + drm_global_item_unref(&adev->mman.mem_global_ref); + drm_global_item_unref(&adev->mman.bo_global_ref.ref); + return r; + } + adev->mman.mem_global_referenced = true; + return 0; } static void amdgpu_ttm_global_fini(struct amdgpu_device *adev) { if (adev->mman.mem_global_referenced) { + amd_sched_entity_fini(adev->mman.entity.sched, + &adev->mman.entity); drm_global_item_unref(&adev->mman.bo_global_ref.ref); drm_global_item_unref(&adev->mman.mem_global_ref); adev->mman.mem_global_referenced = false; @@ -368,9 +384,15 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem) { struct amdgpu_device *adev; + struct amdgpu_bo *abo; struct ttm_mem_reg *old_mem = &bo->mem; int r; + /* Can't move a pinned BO */ + abo = container_of(bo, struct amdgpu_bo, tbo); + if (WARN_ON_ONCE(abo->pin_count > 0)) + return -EINVAL; + adev = amdgpu_get_adev(bo->bdev); if (old_mem->mem_type == TTM_PL_SYSTEM && bo->ttm == NULL) { amdgpu_move_null(bo, new_mem); @@ -478,32 +500,32 @@ static void amdgpu_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_re /* * TTM backend functions. */ +struct amdgpu_ttm_gup_task_list { + struct list_head list; + struct task_struct *task; +}; + struct amdgpu_ttm_tt { - struct ttm_dma_tt ttm; - struct amdgpu_device *adev; - u64 offset; - uint64_t userptr; - struct mm_struct *usermm; - uint32_t userflags; + struct ttm_dma_tt ttm; + struct amdgpu_device *adev; + u64 offset; + uint64_t userptr; + struct mm_struct *usermm; + uint32_t userflags; + spinlock_t guptasklock; + struct list_head guptasks; + atomic_t mmu_invalidations; }; -/* prepare the sg table with the user pages */ -static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm) +int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages) { - struct amdgpu_device *adev = amdgpu_get_adev(ttm->bdev); struct amdgpu_ttm_tt *gtt = (void *)ttm; - unsigned pinned = 0, nents; - int r; - int write = !(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY); - enum dma_data_direction direction = write ? - DMA_BIDIRECTIONAL : DMA_TO_DEVICE; - - if (current->mm != gtt->usermm) - return -EPERM; + unsigned pinned = 0; + int r; if (gtt->userflags & AMDGPU_GEM_USERPTR_ANONONLY) { - /* check that we only pin down anonymous memory + /* check that we only use anonymous memory to prevent problems with writeback */ unsigned long end = gtt->userptr + ttm->num_pages * PAGE_SIZE; struct vm_area_struct *vma; @@ -516,10 +538,20 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm) do { unsigned num_pages = ttm->num_pages - pinned; uint64_t userptr = gtt->userptr + pinned * PAGE_SIZE; - struct page **pages = ttm->pages + pinned; + struct page **p = pages + pinned; + struct amdgpu_ttm_gup_task_list guptask; + + guptask.task = current; + spin_lock(>t->guptasklock); + list_add(&guptask.list, >t->guptasks); + spin_unlock(>t->guptasklock); + + r = get_user_pages(userptr, num_pages, write, 0, p, NULL); + + spin_lock(>t->guptasklock); + list_del(&guptask.list); + spin_unlock(>t->guptasklock); - r = get_user_pages(current, current->mm, userptr, num_pages, - write, 0, pages, NULL); if (r < 0) goto release_pages; @@ -527,6 +559,25 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm) } while (pinned < ttm->num_pages); + return 0; + +release_pages: + release_pages(pages, pinned, 0); + return r; +} + +/* prepare the sg table with the user pages */ +static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm) +{ + struct amdgpu_device *adev = amdgpu_get_adev(ttm->bdev); + struct amdgpu_ttm_tt *gtt = (void *)ttm; + unsigned nents; + int r; + + int write = !(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY); + enum dma_data_direction direction = write ? + DMA_BIDIRECTIONAL : DMA_TO_DEVICE; + r = sg_alloc_table_from_pages(ttm->sg, ttm->pages, ttm->num_pages, 0, ttm->num_pages << PAGE_SHIFT, GFP_KERNEL); @@ -545,9 +596,6 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm) release_sg: kfree(ttm->sg); - -release_pages: - release_pages(ttm->pages, pinned, 0); return r; } @@ -574,7 +622,7 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_tt *ttm) set_page_dirty(page); mark_page_accessed(page); - page_cache_release(page); + put_page(page); } sg_free_table(ttm->sg); @@ -770,38 +818,61 @@ int amdgpu_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr, gtt->userptr = addr; gtt->usermm = current->mm; gtt->userflags = flags; + spin_lock_init(>t->guptasklock); + INIT_LIST_HEAD(>t->guptasks); + atomic_set(>t->mmu_invalidations, 0); + return 0; } -bool amdgpu_ttm_tt_has_userptr(struct ttm_tt *ttm) +struct mm_struct *amdgpu_ttm_tt_get_usermm(struct ttm_tt *ttm) { struct amdgpu_ttm_tt *gtt = (void *)ttm; if (gtt == NULL) - return false; + return NULL; - return !!gtt->userptr; + return gtt->usermm; } bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start, unsigned long end) { struct amdgpu_ttm_tt *gtt = (void *)ttm; + struct amdgpu_ttm_gup_task_list *entry; unsigned long size; - if (gtt == NULL) - return false; - - if (gtt->ttm.ttm.state != tt_bound || !gtt->userptr) + if (gtt == NULL || !gtt->userptr) return false; size = (unsigned long)gtt->ttm.ttm.num_pages * PAGE_SIZE; if (gtt->userptr > end || gtt->userptr + size <= start) return false; + spin_lock(>t->guptasklock); + list_for_each_entry(entry, >t->guptasks, list) { + if (entry->task == current) { + spin_unlock(>t->guptasklock); + return false; + } + } + spin_unlock(>t->guptasklock); + + atomic_inc(>t->mmu_invalidations); + return true; } +bool amdgpu_ttm_tt_userptr_invalidated(struct ttm_tt *ttm, + int *last_invalidated) +{ + struct amdgpu_ttm_tt *gtt = (void *)ttm; + int prev_invalidated = *last_invalidated; + + *last_invalidated = atomic_read(>t->mmu_invalidations); + return prev_invalidated != *last_invalidated; +} + bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm) { struct amdgpu_ttm_tt *gtt = (void *)ttm; @@ -1015,9 +1086,10 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring, struct fence **fence) { struct amdgpu_device *adev = ring->adev; + struct amdgpu_job *job; + uint32_t max_bytes; unsigned num_loops, num_dw; - struct amdgpu_ib *ib; unsigned i; int r; @@ -1029,20 +1101,12 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring, while (num_dw & 0x7) num_dw++; - ib = kzalloc(sizeof(struct amdgpu_ib), GFP_KERNEL); - if (!ib) - return -ENOMEM; - - r = amdgpu_ib_get(ring, NULL, num_dw * 4, ib); - if (r) { - kfree(ib); + r = amdgpu_job_alloc_with_ib(adev, num_dw * 4, &job); + if (r) return r; - } - - ib->length_dw = 0; if (resv) { - r = amdgpu_sync_resv(adev, &ib->sync, resv, + r = amdgpu_sync_resv(adev, &job->sync, resv, AMDGPU_FENCE_OWNER_UNDEFINED); if (r) { DRM_ERROR("sync failed (%d).\n", r); @@ -1053,31 +1117,25 @@ int amdgpu_copy_buffer(struct amdgpu_ring *ring, for (i = 0; i < num_loops; i++) { uint32_t cur_size_in_bytes = min(byte_count, max_bytes); - amdgpu_emit_copy_buffer(adev, ib, src_offset, dst_offset, - cur_size_in_bytes); + amdgpu_emit_copy_buffer(adev, &job->ibs[0], src_offset, + dst_offset, cur_size_in_bytes); src_offset += cur_size_in_bytes; dst_offset += cur_size_in_bytes; byte_count -= cur_size_in_bytes; } - amdgpu_vm_pad_ib(adev, ib); - WARN_ON(ib->length_dw > num_dw); - r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, ib, 1, - &amdgpu_vm_free_job, - AMDGPU_FENCE_OWNER_UNDEFINED, - fence); + amdgpu_ring_pad_ib(ring, &job->ibs[0]); + WARN_ON(job->ibs[0].length_dw > num_dw); + r = amdgpu_job_submit(job, ring, &adev->mman.entity, + AMDGPU_FENCE_OWNER_UNDEFINED, fence); if (r) goto error_free; - if (!amdgpu_enable_scheduler) { - amdgpu_ib_free(adev, ib); - kfree(ib); - } return 0; + error_free: - amdgpu_ib_free(adev, ib); - kfree(ib); + amdgpu_job_free(job); return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c index 53f987aeeacff5a4b48663850c7a413d64a9ba76..338da80006b66ced7671b5ed63fabb02750355ba 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c @@ -91,6 +91,8 @@ static void amdgpu_uvd_idle_work_handler(struct work_struct *work); int amdgpu_uvd_sw_init(struct amdgpu_device *adev) { + struct amdgpu_ring *ring; + struct amd_sched_rq *rq; unsigned long bo_size; const char *fw_name; const struct common_firmware_header *hdr; @@ -191,6 +193,15 @@ int amdgpu_uvd_sw_init(struct amdgpu_device *adev) amdgpu_bo_unreserve(adev->uvd.vcpu_bo); + ring = &adev->uvd.ring; + rq = &ring->sched.sched_rq[AMD_SCHED_PRIORITY_NORMAL]; + r = amd_sched_entity_init(&ring->sched, &adev->uvd.entity, + rq, amdgpu_sched_jobs); + if (r != 0) { + DRM_ERROR("Failed setting up UVD run queue.\n"); + return r; + } + for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) { atomic_set(&adev->uvd.handles[i], 0); adev->uvd.filp[i] = NULL; @@ -210,6 +221,8 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev) if (adev->uvd.vcpu_bo == NULL) return 0; + amd_sched_entity_fini(&adev->uvd.ring.sched, &adev->uvd.entity); + r = amdgpu_bo_reserve(adev->uvd.vcpu_bo, false); if (!r) { amdgpu_bo_kunmap(adev->uvd.vcpu_bo); @@ -228,32 +241,28 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev) int amdgpu_uvd_suspend(struct amdgpu_device *adev) { - struct amdgpu_ring *ring = &adev->uvd.ring; - int i, r; + unsigned size; + void *ptr; + int i; if (adev->uvd.vcpu_bo == NULL) return 0; - for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) { - uint32_t handle = atomic_read(&adev->uvd.handles[i]); - if (handle != 0) { - struct fence *fence; + for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) + if (atomic_read(&adev->uvd.handles[i])) + break; - amdgpu_uvd_note_usage(adev); + if (i == AMDGPU_MAX_UVD_HANDLES) + return 0; - r = amdgpu_uvd_get_destroy_msg(ring, handle, &fence); - if (r) { - DRM_ERROR("Error destroying UVD (%d)!\n", r); - continue; - } + size = amdgpu_bo_size(adev->uvd.vcpu_bo); + ptr = adev->uvd.cpu_addr; - fence_wait(fence, false); - fence_put(fence); + adev->uvd.saved_bo = kmalloc(size, GFP_KERNEL); + if (!adev->uvd.saved_bo) + return -ENOMEM; - adev->uvd.filp[i] = NULL; - atomic_set(&adev->uvd.handles[i], 0); - } - } + memcpy(adev->uvd.saved_bo, ptr, size); return 0; } @@ -262,23 +271,29 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev) { unsigned size; void *ptr; - const struct common_firmware_header *hdr; - unsigned offset; if (adev->uvd.vcpu_bo == NULL) return -EINVAL; - hdr = (const struct common_firmware_header *)adev->uvd.fw->data; - offset = le32_to_cpu(hdr->ucode_array_offset_bytes); - memcpy(adev->uvd.cpu_addr, (adev->uvd.fw->data) + offset, - (adev->uvd.fw->size) - offset); - size = amdgpu_bo_size(adev->uvd.vcpu_bo); - size -= le32_to_cpu(hdr->ucode_size_bytes); ptr = adev->uvd.cpu_addr; - ptr += le32_to_cpu(hdr->ucode_size_bytes); - memset(ptr, 0, size); + if (adev->uvd.saved_bo != NULL) { + memcpy(ptr, adev->uvd.saved_bo, size); + kfree(adev->uvd.saved_bo); + adev->uvd.saved_bo = NULL; + } else { + const struct common_firmware_header *hdr; + unsigned offset; + + hdr = (const struct common_firmware_header *)adev->uvd.fw->data; + offset = le32_to_cpu(hdr->ucode_array_offset_bytes); + memcpy(adev->uvd.cpu_addr, (adev->uvd.fw->data) + offset, + (adev->uvd.fw->size) - offset); + size -= le32_to_cpu(hdr->ucode_size_bytes); + ptr += le32_to_cpu(hdr->ucode_size_bytes); + memset(ptr, 0, size); + } return 0; } @@ -295,7 +310,8 @@ void amdgpu_uvd_free_handles(struct amdgpu_device *adev, struct drm_file *filp) amdgpu_uvd_note_usage(adev); - r = amdgpu_uvd_get_destroy_msg(ring, handle, &fence); + r = amdgpu_uvd_get_destroy_msg(ring, handle, + false, &fence); if (r) { DRM_ERROR("Error destroying UVD (%d)!\n", r); continue; @@ -525,13 +541,6 @@ static int amdgpu_uvd_cs_msg(struct amdgpu_uvd_cs_ctx *ctx, return -EINVAL; } - r = reservation_object_wait_timeout_rcu(bo->tbo.resv, true, false, - MAX_SCHEDULE_TIMEOUT); - if (r < 0) { - DRM_ERROR("Failed waiting for UVD message (%ld)!\n", r); - return r; - } - r = amdgpu_bo_kmap(bo, &ptr); if (r) { DRM_ERROR("Failed mapping the UVD message (%ld)!\n", r); @@ -616,7 +625,6 @@ static int amdgpu_uvd_cs_pass2(struct amdgpu_uvd_cs_ctx *ctx) { struct amdgpu_bo_va_mapping *mapping; struct amdgpu_bo *bo; - struct amdgpu_ib *ib; uint32_t cmd, lo, hi; uint64_t start, end; uint64_t addr; @@ -638,9 +646,10 @@ static int amdgpu_uvd_cs_pass2(struct amdgpu_uvd_cs_ctx *ctx) addr -= ((uint64_t)mapping->it.start) * AMDGPU_GPU_PAGE_SIZE; start += addr; - ib = &ctx->parser->ibs[ctx->ib_idx]; - ib->ptr[ctx->data0] = start & 0xFFFFFFFF; - ib->ptr[ctx->data1] = start >> 32; + amdgpu_set_ib_value(ctx->parser, ctx->ib_idx, ctx->data0, + lower_32_bits(start)); + amdgpu_set_ib_value(ctx->parser, ctx->ib_idx, ctx->data1, + upper_32_bits(start)); cmd = amdgpu_get_ib_value(ctx->parser, ctx->ib_idx, ctx->idx) >> 1; if (cmd < 0x4) { @@ -702,7 +711,7 @@ static int amdgpu_uvd_cs_pass2(struct amdgpu_uvd_cs_ctx *ctx) static int amdgpu_uvd_cs_reg(struct amdgpu_uvd_cs_ctx *ctx, int (*cb)(struct amdgpu_uvd_cs_ctx *ctx)) { - struct amdgpu_ib *ib = &ctx->parser->ibs[ctx->ib_idx]; + struct amdgpu_ib *ib = &ctx->parser->job->ibs[ctx->ib_idx]; int i, r; ctx->idx++; @@ -748,7 +757,7 @@ static int amdgpu_uvd_cs_reg(struct amdgpu_uvd_cs_ctx *ctx, static int amdgpu_uvd_cs_packets(struct amdgpu_uvd_cs_ctx *ctx, int (*cb)(struct amdgpu_uvd_cs_ctx *ctx)) { - struct amdgpu_ib *ib = &ctx->parser->ibs[ctx->ib_idx]; + struct amdgpu_ib *ib = &ctx->parser->job->ibs[ctx->ib_idx]; int r; for (ctx->idx = 0 ; ctx->idx < ib->length_dw; ) { @@ -790,7 +799,7 @@ int amdgpu_uvd_ring_parse_cs(struct amdgpu_cs_parser *parser, uint32_t ib_idx) [0x00000003] = 2048, [0x00000004] = 0xFFFFFFFF, }; - struct amdgpu_ib *ib = &parser->ibs[ib_idx]; + struct amdgpu_ib *ib = &parser->job->ibs[ib_idx]; int r; if (ib->length_dw % 16) { @@ -823,22 +832,14 @@ int amdgpu_uvd_ring_parse_cs(struct amdgpu_cs_parser *parser, uint32_t ib_idx) return 0; } -static int amdgpu_uvd_free_job( - struct amdgpu_job *job) -{ - amdgpu_ib_free(job->adev, job->ibs); - kfree(job->ibs); - return 0; -} - -static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, - struct amdgpu_bo *bo, - struct fence **fence) +static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, struct amdgpu_bo *bo, + bool direct, struct fence **fence) { struct ttm_validate_buffer tv; struct ww_acquire_ctx ticket; struct list_head head; - struct amdgpu_ib *ib = NULL; + struct amdgpu_job *job; + struct amdgpu_ib *ib; struct fence *f = NULL; struct amdgpu_device *adev = ring->adev; uint64_t addr; @@ -862,15 +863,12 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false); if (r) goto err; - ib = kzalloc(sizeof(struct amdgpu_ib), GFP_KERNEL); - if (!ib) { - r = -ENOMEM; - goto err; - } - r = amdgpu_ib_get(ring, NULL, 64, ib); + + r = amdgpu_job_alloc_with_ib(adev, 64, &job); if (r) - goto err1; + goto err; + ib = &job->ibs[0]; addr = amdgpu_bo_gpu_offset(bo); ib->ptr[0] = PACKET0(mmUVD_GPCOM_VCPU_DATA0, 0); ib->ptr[1] = addr; @@ -882,12 +880,19 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, ib->ptr[i] = PACKET2(0); ib->length_dw = 16; - r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, ib, 1, - &amdgpu_uvd_free_job, - AMDGPU_FENCE_OWNER_UNDEFINED, - &f); - if (r) - goto err2; + if (direct) { + r = amdgpu_ib_schedule(ring, 1, ib, NULL, &f); + job->fence = f; + if (r) + goto err_free; + + amdgpu_job_free(job); + } else { + r = amdgpu_job_submit(job, ring, &adev->uvd.entity, + AMDGPU_FENCE_OWNER_UNDEFINED, &f); + if (r) + goto err_free; + } ttm_eu_fence_buffer_objects(&ticket, &head, f); @@ -895,16 +900,12 @@ static int amdgpu_uvd_send_msg(struct amdgpu_ring *ring, *fence = fence_get(f); amdgpu_bo_unref(&bo); fence_put(f); - if (amdgpu_enable_scheduler) - return 0; - amdgpu_ib_free(ring->adev, ib); - kfree(ib); return 0; -err2: - amdgpu_ib_free(ring->adev, ib); -err1: - kfree(ib); + +err_free: + amdgpu_job_free(job); + err: ttm_eu_backoff_reservation(&ticket, &head); return r; @@ -959,11 +960,11 @@ int amdgpu_uvd_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, amdgpu_bo_kunmap(bo); amdgpu_bo_unreserve(bo); - return amdgpu_uvd_send_msg(ring, bo, fence); + return amdgpu_uvd_send_msg(ring, bo, true, fence); } int amdgpu_uvd_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, - struct fence **fence) + bool direct, struct fence **fence) { struct amdgpu_device *adev = ring->adev; struct amdgpu_bo *bo; @@ -1001,7 +1002,7 @@ int amdgpu_uvd_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, amdgpu_bo_kunmap(bo); amdgpu_bo_unreserve(bo); - return amdgpu_uvd_send_msg(ring, bo, fence); + return amdgpu_uvd_send_msg(ring, bo, direct, fence); } static void amdgpu_uvd_idle_work_handler(struct work_struct *work) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h index 1724c2c861516eea61b7d23f7521e7c8c834a5e6..9a3b449081a72fd9c9ac79c9b3c9c5e28614d4ec 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h @@ -31,7 +31,7 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev); int amdgpu_uvd_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, struct fence **fence); int amdgpu_uvd_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, - struct fence **fence); + bool direct, struct fence **fence); void amdgpu_uvd_free_handles(struct amdgpu_device *adev, struct drm_file *filp); int amdgpu_uvd_ring_parse_cs(struct amdgpu_cs_parser *parser, uint32_t ib_idx); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c index a745eeeb5d8200f6b92e259c655b10b658c4cad5..4bec0c108cea9887ed612b252fc6b990547f029a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c @@ -74,6 +74,8 @@ static void amdgpu_vce_idle_work_handler(struct work_struct *work); */ int amdgpu_vce_sw_init(struct amdgpu_device *adev, unsigned long size) { + struct amdgpu_ring *ring; + struct amd_sched_rq *rq; const char *fw_name; const struct common_firmware_header *hdr; unsigned ucode_version, version_major, version_minor, binary_id; @@ -170,6 +172,16 @@ int amdgpu_vce_sw_init(struct amdgpu_device *adev, unsigned long size) return r; } + + ring = &adev->vce.ring[0]; + rq = &ring->sched.sched_rq[AMD_SCHED_PRIORITY_NORMAL]; + r = amd_sched_entity_init(&ring->sched, &adev->vce.entity, + rq, amdgpu_sched_jobs); + if (r != 0) { + DRM_ERROR("Failed setting up VCE run queue.\n"); + return r; + } + for (i = 0; i < AMDGPU_MAX_VCE_HANDLES; ++i) { atomic_set(&adev->vce.handles[i], 0); adev->vce.filp[i] = NULL; @@ -190,6 +202,8 @@ int amdgpu_vce_sw_fini(struct amdgpu_device *adev) if (adev->vce.vcpu_bo == NULL) return 0; + amd_sched_entity_fini(&adev->vce.ring[0].sched, &adev->vce.entity); + amdgpu_bo_unref(&adev->vce.vcpu_bo); amdgpu_ring_fini(&adev->vce.ring[0]); @@ -337,7 +351,7 @@ void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp) amdgpu_vce_note_usage(adev); - r = amdgpu_vce_get_destroy_msg(ring, handle, NULL); + r = amdgpu_vce_get_destroy_msg(ring, handle, false, NULL); if (r) DRM_ERROR("Error destroying VCE handle (%d)!\n", r); @@ -346,14 +360,6 @@ void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp) } } -static int amdgpu_vce_free_job( - struct amdgpu_job *job) -{ - amdgpu_ib_free(job->adev, job->ibs); - kfree(job->ibs); - return 0; -} - /** * amdgpu_vce_get_create_msg - generate a VCE create msg * @@ -368,21 +374,17 @@ int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, struct fence **fence) { const unsigned ib_size_dw = 1024; - struct amdgpu_ib *ib = NULL; + struct amdgpu_job *job; + struct amdgpu_ib *ib; struct fence *f = NULL; - struct amdgpu_device *adev = ring->adev; uint64_t dummy; int i, r; - ib = kzalloc(sizeof(struct amdgpu_ib), GFP_KERNEL); - if (!ib) - return -ENOMEM; - r = amdgpu_ib_get(ring, NULL, ib_size_dw * 4, ib); - if (r) { - DRM_ERROR("amdgpu: failed to get ib (%d).\n", r); - kfree(ib); + r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); + if (r) return r; - } + + ib = &job->ibs[0]; dummy = ib->gpu_addr + 1024; @@ -423,20 +425,19 @@ int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, for (i = ib->length_dw; i < ib_size_dw; ++i) ib->ptr[i] = 0x0; - r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, ib, 1, - &amdgpu_vce_free_job, - AMDGPU_FENCE_OWNER_UNDEFINED, - &f); + r = amdgpu_ib_schedule(ring, 1, ib, NULL, &f); + job->fence = f; if (r) goto err; + + amdgpu_job_free(job); if (fence) *fence = fence_get(f); fence_put(f); - if (amdgpu_enable_scheduler) - return 0; + return 0; + err: - amdgpu_ib_free(adev, ib); - kfree(ib); + amdgpu_job_free(job); return r; } @@ -451,26 +452,20 @@ int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, * Close up a stream for HW test or if userspace failed to do so */ int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, - struct fence **fence) + bool direct, struct fence **fence) { const unsigned ib_size_dw = 1024; - struct amdgpu_ib *ib = NULL; + struct amdgpu_job *job; + struct amdgpu_ib *ib; struct fence *f = NULL; - struct amdgpu_device *adev = ring->adev; uint64_t dummy; int i, r; - ib = kzalloc(sizeof(struct amdgpu_ib), GFP_KERNEL); - if (!ib) - return -ENOMEM; - - r = amdgpu_ib_get(ring, NULL, ib_size_dw * 4, ib); - if (r) { - kfree(ib); - DRM_ERROR("amdgpu: failed to get ib (%d).\n", r); + r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); + if (r) return r; - } + ib = &job->ibs[0]; dummy = ib->gpu_addr + 1024; /* stitch together an VCE destroy msg */ @@ -490,20 +485,28 @@ int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, for (i = ib->length_dw; i < ib_size_dw; ++i) ib->ptr[i] = 0x0; - r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, ib, 1, - &amdgpu_vce_free_job, - AMDGPU_FENCE_OWNER_UNDEFINED, - &f); - if (r) - goto err; + + if (direct) { + r = amdgpu_ib_schedule(ring, 1, ib, NULL, &f); + job->fence = f; + if (r) + goto err; + + amdgpu_job_free(job); + } else { + r = amdgpu_job_submit(job, ring, &ring->adev->vce.entity, + AMDGPU_FENCE_OWNER_UNDEFINED, &f); + if (r) + goto err; + } + if (fence) *fence = fence_get(f); fence_put(f); - if (amdgpu_enable_scheduler) - return 0; + return 0; + err: - amdgpu_ib_free(adev, ib); - kfree(ib); + amdgpu_job_free(job); return r; } @@ -521,7 +524,6 @@ static int amdgpu_vce_cs_reloc(struct amdgpu_cs_parser *p, uint32_t ib_idx, int lo, int hi, unsigned size, uint32_t index) { struct amdgpu_bo_va_mapping *mapping; - struct amdgpu_ib *ib = &p->ibs[ib_idx]; struct amdgpu_bo *bo; uint64_t addr; @@ -550,8 +552,8 @@ static int amdgpu_vce_cs_reloc(struct amdgpu_cs_parser *p, uint32_t ib_idx, addr += amdgpu_bo_gpu_offset(bo); addr -= ((uint64_t)size) * ((uint64_t)index); - ib->ptr[lo] = addr & 0xFFFFFFFF; - ib->ptr[hi] = addr >> 32; + amdgpu_set_ib_value(p, ib_idx, lo, lower_32_bits(addr)); + amdgpu_set_ib_value(p, ib_idx, hi, upper_32_bits(addr)); return 0; } @@ -606,7 +608,7 @@ static int amdgpu_vce_validate_handle(struct amdgpu_cs_parser *p, */ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx) { - struct amdgpu_ib *ib = &p->ibs[ib_idx]; + struct amdgpu_ib *ib = &p->job->ibs[ib_idx]; unsigned fb_idx = 0, bs_idx = 0; int session_idx = -1; bool destroyed = false; @@ -742,30 +744,6 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx) return r; } -/** - * amdgpu_vce_ring_emit_semaphore - emit a semaphore command - * - * @ring: engine to use - * @semaphore: address of semaphore - * @emit_wait: true=emit wait, false=emit signal - * - */ -bool amdgpu_vce_ring_emit_semaphore(struct amdgpu_ring *ring, - struct amdgpu_semaphore *semaphore, - bool emit_wait) -{ - uint64_t addr = semaphore->gpu_addr; - - amdgpu_ring_write(ring, VCE_CMD_SEMAPHORE); - amdgpu_ring_write(ring, (addr >> 3) & 0x000FFFFF); - amdgpu_ring_write(ring, (addr >> 23) & 0x000FFFFF); - amdgpu_ring_write(ring, 0x01003000 | (emit_wait ? 1 : 0)); - if (!emit_wait) - amdgpu_ring_write(ring, VCE_CMD_END); - - return true; -} - /** * amdgpu_vce_ring_emit_ib - execute indirect buffer * @@ -814,14 +792,14 @@ int amdgpu_vce_ring_test_ring(struct amdgpu_ring *ring) unsigned i; int r; - r = amdgpu_ring_lock(ring, 16); + r = amdgpu_ring_alloc(ring, 16); if (r) { DRM_ERROR("amdgpu: vce failed to lock ring %d (%d).\n", ring->idx, r); return r; } amdgpu_ring_write(ring, VCE_CMD_END); - amdgpu_ring_unlock_commit(ring); + amdgpu_ring_commit(ring); for (i = 0; i < adev->usec_timeout; i++) { if (amdgpu_ring_get_rptr(ring) != rptr) @@ -862,7 +840,7 @@ int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring) goto error; } - r = amdgpu_vce_get_destroy_msg(ring, 1, &fence); + r = amdgpu_vce_get_destroy_msg(ring, 1, true, &fence); if (r) { DRM_ERROR("amdgpu: failed to get destroy ib (%d).\n", r); goto error; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h index ba2da8ee59067c9e03cf5f02fab64a8a3ef21042..ef99d237018259bf95489977f3ff6c5fc4a7c767 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h @@ -31,12 +31,9 @@ int amdgpu_vce_resume(struct amdgpu_device *adev); int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, struct fence **fence); int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, - struct fence **fence); + bool direct, struct fence **fence); void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp); int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx); -bool amdgpu_vce_ring_emit_semaphore(struct amdgpu_ring *ring, - struct amdgpu_semaphore *semaphore, - bool emit_wait); void amdgpu_vce_ring_emit_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib); void amdgpu_vce_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq, unsigned flags); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 9599f7559b3dc86308d2c375739d0cd20ee60941..b6c011b83641205b5a7466d499017a80b8d2275a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -50,12 +50,15 @@ * SI supports 16. */ +/* Special value that no flush is necessary */ +#define AMDGPU_VM_NO_FLUSH (~0ll) + /** * amdgpu_vm_num_pde - return the number of page directory entries * * @adev: amdgpu_device pointer * - * Calculate the number of page directory entries (cayman+). + * Calculate the number of page directory entries. */ static unsigned amdgpu_vm_num_pdes(struct amdgpu_device *adev) { @@ -67,7 +70,7 @@ static unsigned amdgpu_vm_num_pdes(struct amdgpu_device *adev) * * @adev: amdgpu_device pointer * - * Calculate the size of the page directory in bytes (cayman+). + * Calculate the size of the page directory in bytes. */ static unsigned amdgpu_vm_directory_size(struct amdgpu_device *adev) { @@ -89,11 +92,10 @@ void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm, struct amdgpu_bo_list_entry *entry) { entry->robj = vm->page_directory; - entry->prefered_domains = AMDGPU_GEM_DOMAIN_VRAM; - entry->allowed_domains = AMDGPU_GEM_DOMAIN_VRAM; entry->priority = 0; entry->tv.bo = &vm->page_directory->tbo; entry->tv.shared = true; + entry->user_pages = NULL; list_add(&entry->tv.head, validated); } @@ -154,133 +156,154 @@ void amdgpu_vm_move_pt_bos_in_lru(struct amdgpu_device *adev, * @vm: vm to allocate id for * @ring: ring we want to submit job to * @sync: sync object where we add dependencies + * @fence: fence protecting ID from reuse * * Allocate an id for the vm, adding fences to the sync obj as necessary. - * - * Global mutex must be locked! */ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, - struct amdgpu_sync *sync) + struct amdgpu_sync *sync, struct fence *fence, + unsigned *vm_id, uint64_t *vm_pd_addr) { - struct fence *best[AMDGPU_MAX_RINGS] = {}; - struct amdgpu_vm_id *vm_id = &vm->ids[ring->idx]; + uint64_t pd_addr = amdgpu_bo_gpu_offset(vm->page_directory); struct amdgpu_device *adev = ring->adev; + struct amdgpu_vm_id *id = &vm->ids[ring->idx]; + struct fence *updates = sync->last_vm_update; + int r; - unsigned choices[2] = {}; - unsigned i; + mutex_lock(&adev->vm_manager.lock); /* check if the id is still valid */ - if (vm_id->id) { - unsigned id = vm_id->id; + if (id->mgr_id) { + struct fence *flushed = id->flushed_updates; + bool is_later; long owner; - owner = atomic_long_read(&adev->vm_manager.ids[id].owner); - if (owner == (long)vm) { - trace_amdgpu_vm_grab_id(vm_id->id, ring->idx); + if (!flushed) + is_later = true; + else if (!updates) + is_later = false; + else + is_later = fence_is_later(updates, flushed); + + owner = atomic_long_read(&id->mgr_id->owner); + if (!is_later && owner == (long)id && + pd_addr == id->pd_gpu_addr) { + + r = amdgpu_sync_fence(ring->adev, sync, + id->mgr_id->active); + if (r) { + mutex_unlock(&adev->vm_manager.lock); + return r; + } + + fence_put(id->mgr_id->active); + id->mgr_id->active = fence_get(fence); + + list_move_tail(&id->mgr_id->list, + &adev->vm_manager.ids_lru); + + *vm_id = id->mgr_id - adev->vm_manager.ids; + *vm_pd_addr = AMDGPU_VM_NO_FLUSH; + trace_amdgpu_vm_grab_id(vm, ring->idx, *vm_id, + *vm_pd_addr); + + mutex_unlock(&adev->vm_manager.lock); return 0; } } - /* we definately need to flush */ - vm_id->pd_gpu_addr = ~0ll; + id->mgr_id = list_first_entry(&adev->vm_manager.ids_lru, + struct amdgpu_vm_manager_id, + list); - /* skip over VMID 0, since it is the system VM */ - for (i = 1; i < adev->vm_manager.nvm; ++i) { - struct fence *fence = adev->vm_manager.ids[i].active; - struct amdgpu_ring *fring; - - if (fence == NULL) { - /* found a free one */ - vm_id->id = i; - trace_amdgpu_vm_grab_id(i, ring->idx); - return 0; - } + r = amdgpu_sync_fence(ring->adev, sync, id->mgr_id->active); + if (!r) { + fence_put(id->mgr_id->active); + id->mgr_id->active = fence_get(fence); - fring = amdgpu_ring_from_fence(fence); - if (best[fring->idx] == NULL || - fence_is_later(best[fring->idx], fence)) { - best[fring->idx] = fence; - choices[fring == ring ? 0 : 1] = i; - } - } + fence_put(id->flushed_updates); + id->flushed_updates = fence_get(updates); - for (i = 0; i < 2; ++i) { - if (choices[i]) { - struct fence *fence; + id->pd_gpu_addr = pd_addr; - fence = adev->vm_manager.ids[choices[i]].active; - vm_id->id = choices[i]; + list_move_tail(&id->mgr_id->list, &adev->vm_manager.ids_lru); + atomic_long_set(&id->mgr_id->owner, (long)id); - trace_amdgpu_vm_grab_id(choices[i], ring->idx); - return amdgpu_sync_fence(ring->adev, sync, fence); - } + *vm_id = id->mgr_id - adev->vm_manager.ids; + *vm_pd_addr = pd_addr; + trace_amdgpu_vm_grab_id(vm, ring->idx, *vm_id, *vm_pd_addr); } - /* should never happen */ - BUG(); - return -EINVAL; + mutex_unlock(&adev->vm_manager.lock); + return r; } /** * amdgpu_vm_flush - hardware flush the vm * * @ring: ring to use for flush - * @vm: vm we want to flush - * @updates: last vm update that we waited for + * @vm_id: vmid number to use + * @pd_addr: address of the page directory * - * Flush the vm (cayman+). - * - * Global and local mutex must be locked! + * Emit a VM flush when it is necessary. */ void amdgpu_vm_flush(struct amdgpu_ring *ring, - struct amdgpu_vm *vm, - struct fence *updates) + unsigned vm_id, uint64_t pd_addr, + uint32_t gds_base, uint32_t gds_size, + uint32_t gws_base, uint32_t gws_size, + uint32_t oa_base, uint32_t oa_size) { - uint64_t pd_addr = amdgpu_bo_gpu_offset(vm->page_directory); - struct amdgpu_vm_id *vm_id = &vm->ids[ring->idx]; - struct fence *flushed_updates = vm_id->flushed_updates; - bool is_later; - - if (!flushed_updates) - is_later = true; - else if (!updates) - is_later = false; - else - is_later = fence_is_later(updates, flushed_updates); + struct amdgpu_device *adev = ring->adev; + struct amdgpu_vm_manager_id *mgr_id = &adev->vm_manager.ids[vm_id]; + bool gds_switch_needed = ring->funcs->emit_gds_switch && ( + mgr_id->gds_base != gds_base || + mgr_id->gds_size != gds_size || + mgr_id->gws_base != gws_base || + mgr_id->gws_size != gws_size || + mgr_id->oa_base != oa_base || + mgr_id->oa_size != oa_size); + + if (ring->funcs->emit_pipeline_sync && ( + pd_addr != AMDGPU_VM_NO_FLUSH || gds_switch_needed)) + amdgpu_ring_emit_pipeline_sync(ring); + + if (pd_addr != AMDGPU_VM_NO_FLUSH) { + trace_amdgpu_vm_flush(pd_addr, ring->idx, vm_id); + amdgpu_ring_emit_vm_flush(ring, vm_id, pd_addr); + } - if (pd_addr != vm_id->pd_gpu_addr || is_later) { - trace_amdgpu_vm_flush(pd_addr, ring->idx, vm_id->id); - if (is_later) { - vm_id->flushed_updates = fence_get(updates); - fence_put(flushed_updates); - } - vm_id->pd_gpu_addr = pd_addr; - amdgpu_ring_emit_vm_flush(ring, vm_id->id, vm_id->pd_gpu_addr); + if (gds_switch_needed) { + mgr_id->gds_base = gds_base; + mgr_id->gds_size = gds_size; + mgr_id->gws_base = gws_base; + mgr_id->gws_size = gws_size; + mgr_id->oa_base = oa_base; + mgr_id->oa_size = oa_size; + amdgpu_ring_emit_gds_switch(ring, vm_id, + gds_base, gds_size, + gws_base, gws_size, + oa_base, oa_size); } } /** - * amdgpu_vm_fence - remember fence for vm + * amdgpu_vm_reset_id - reset VMID to zero * - * @adev: amdgpu_device pointer - * @vm: vm we want to fence - * @fence: fence to remember - * - * Fence the vm (cayman+). - * Set the fence used to protect page table and id. + * @adev: amdgpu device structure + * @vm_id: vmid number to use * - * Global and local mutex must be locked! + * Reset saved GDW, GWS and OA to force switch on next flush. */ -void amdgpu_vm_fence(struct amdgpu_device *adev, - struct amdgpu_vm *vm, - struct fence *fence) +void amdgpu_vm_reset_id(struct amdgpu_device *adev, unsigned vm_id) { - struct amdgpu_ring *ring = amdgpu_ring_from_fence(fence); - unsigned vm_id = vm->ids[ring->idx].id; - - fence_put(adev->vm_manager.ids[vm_id].active); - adev->vm_manager.ids[vm_id].active = fence_get(fence); - atomic_long_set(&adev->vm_manager.ids[vm_id].owner, (long)vm); + struct amdgpu_vm_manager_id *mgr_id = &adev->vm_manager.ids[vm_id]; + + mgr_id->gds_base = 0; + mgr_id->gds_size = 0; + mgr_id->gws_base = 0; + mgr_id->gws_size = 0; + mgr_id->oa_base = 0; + mgr_id->oa_size = 0; } /** @@ -289,7 +312,7 @@ void amdgpu_vm_fence(struct amdgpu_device *adev, * @vm: requested vm * @bo: requested buffer object * - * Find @bo inside the requested vm (cayman+). + * Find @bo inside the requested vm. * Search inside the @bos vm list for the requested vm * Returns the found bo_va or NULL if none is found * @@ -312,32 +335,40 @@ struct amdgpu_bo_va *amdgpu_vm_bo_find(struct amdgpu_vm *vm, * amdgpu_vm_update_pages - helper to call the right asic function * * @adev: amdgpu_device pointer + * @gtt: GART instance to use for mapping + * @gtt_flags: GTT hw access flags * @ib: indirect buffer to fill with commands * @pe: addr of the page entry * @addr: dst addr to write into pe * @count: number of page entries to update * @incr: increase next addr by incr bytes * @flags: hw access flags - * @gtt_flags: GTT hw access flags * * Traces the parameters and calls the right asic functions * to setup the page table using the DMA. */ static void amdgpu_vm_update_pages(struct amdgpu_device *adev, + struct amdgpu_gart *gtt, + uint32_t gtt_flags, struct amdgpu_ib *ib, uint64_t pe, uint64_t addr, unsigned count, uint32_t incr, - uint32_t flags, uint32_t gtt_flags) + uint32_t flags) { trace_amdgpu_vm_set_page(pe, addr, count, incr, flags); - if ((flags & AMDGPU_PTE_SYSTEM) && (flags == gtt_flags)) { - uint64_t src = adev->gart.table_addr + (addr >> 12) * 8; + if ((gtt == &adev->gart) && (flags == gtt_flags)) { + uint64_t src = gtt->table_addr + (addr >> 12) * 8; amdgpu_vm_copy_pte(adev, ib, pe, src, count); - } else if ((flags & AMDGPU_PTE_SYSTEM) || (count < 3)) { - amdgpu_vm_write_pte(adev, ib, pe, addr, - count, incr, flags); + } else if (gtt) { + dma_addr_t *pages_addr = gtt->pages_addr; + amdgpu_vm_write_pte(adev, ib, pages_addr, pe, addr, + count, incr, flags); + + } else if (count < 3) { + amdgpu_vm_write_pte(adev, ib, NULL, pe, addr, + count, incr, flags); } else { amdgpu_vm_set_pte_pde(adev, ib, pe, addr, @@ -345,15 +376,6 @@ static void amdgpu_vm_update_pages(struct amdgpu_device *adev, } } -int amdgpu_vm_free_job(struct amdgpu_job *job) -{ - int i; - for (i = 0; i < job->num_ibs; i++) - amdgpu_ib_free(job->adev, &job->ibs[i]); - kfree(job->ibs); - return 0; -} - /** * amdgpu_vm_clear_bo - initially clear the page dir/table * @@ -363,15 +385,18 @@ int amdgpu_vm_free_job(struct amdgpu_job *job) * need to reserve bo first before calling it. */ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev, + struct amdgpu_vm *vm, struct amdgpu_bo *bo) { - struct amdgpu_ring *ring = adev->vm_manager.vm_pte_funcs_ring; + struct amdgpu_ring *ring; struct fence *fence = NULL; - struct amdgpu_ib *ib; + struct amdgpu_job *job; unsigned entries; uint64_t addr; int r; + ring = container_of(vm->entity.sched, struct amdgpu_ring, sched); + r = reservation_object_reserve_shared(bo->tbo.resv); if (r) return r; @@ -383,56 +408,57 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev, addr = amdgpu_bo_gpu_offset(bo); entries = amdgpu_bo_size(bo) / 8; - ib = kzalloc(sizeof(struct amdgpu_ib), GFP_KERNEL); - if (!ib) + r = amdgpu_job_alloc_with_ib(adev, 64, &job); + if (r) goto error; - r = amdgpu_ib_get(ring, NULL, entries * 2 + 64, ib); + amdgpu_vm_update_pages(adev, NULL, 0, &job->ibs[0], addr, 0, entries, + 0, 0); + amdgpu_ring_pad_ib(ring, &job->ibs[0]); + + WARN_ON(job->ibs[0].length_dw > 64); + r = amdgpu_job_submit(job, ring, &vm->entity, + AMDGPU_FENCE_OWNER_VM, &fence); if (r) goto error_free; - ib->length_dw = 0; - - amdgpu_vm_update_pages(adev, ib, addr, 0, entries, 0, 0, 0); - amdgpu_vm_pad_ib(adev, ib); - WARN_ON(ib->length_dw > 64); - r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, ib, 1, - &amdgpu_vm_free_job, - AMDGPU_FENCE_OWNER_VM, - &fence); - if (!r) - amdgpu_bo_fence(bo, fence, true); + amdgpu_bo_fence(bo, fence, true); fence_put(fence); - if (amdgpu_enable_scheduler) - return 0; + return 0; error_free: - amdgpu_ib_free(adev, ib); - kfree(ib); + amdgpu_job_free(job); error: return r; } /** - * amdgpu_vm_map_gart - get the physical address of a gart page + * amdgpu_vm_map_gart - Resolve gart mapping of addr * - * @adev: amdgpu_device pointer + * @pages_addr: optional DMA address to use for lookup * @addr: the unmapped addr * * Look up the physical address of the page that the pte resolves - * to (cayman+). - * Returns the physical address of the page. + * to and return the pointer for the page table entry. */ -uint64_t amdgpu_vm_map_gart(struct amdgpu_device *adev, uint64_t addr) +uint64_t amdgpu_vm_map_gart(const dma_addr_t *pages_addr, uint64_t addr) { uint64_t result; - /* page table offset */ - result = adev->gart.pages_addr[addr >> PAGE_SHIFT]; + if (pages_addr) { + /* page table offset */ + result = pages_addr[addr >> PAGE_SHIFT]; + + /* in case cpu page size != gpu page size*/ + result |= addr & (~PAGE_MASK); - /* in case cpu page size != gpu page size*/ - result |= addr & (~PAGE_MASK); + } else { + /* No mapping required */ + result = addr; + } + + result &= 0xFFFFFFFFFFFFF000ULL; return result; } @@ -446,45 +472,37 @@ uint64_t amdgpu_vm_map_gart(struct amdgpu_device *adev, uint64_t addr) * @end: end of GPU address range * * Allocates new page tables if necessary - * and updates the page directory (cayman+). + * and updates the page directory. * Returns 0 for success, error for failure. - * - * Global and local mutex must be locked! */ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, struct amdgpu_vm *vm) { - struct amdgpu_ring *ring = adev->vm_manager.vm_pte_funcs_ring; + struct amdgpu_ring *ring; struct amdgpu_bo *pd = vm->page_directory; uint64_t pd_addr = amdgpu_bo_gpu_offset(pd); uint32_t incr = AMDGPU_VM_PTE_COUNT * 8; uint64_t last_pde = ~0, last_pt = ~0; unsigned count = 0, pt_idx, ndw; + struct amdgpu_job *job; struct amdgpu_ib *ib; struct fence *fence = NULL; int r; + ring = container_of(vm->entity.sched, struct amdgpu_ring, sched); + /* padding, etc. */ ndw = 64; /* assume the worst case */ ndw += vm->max_pde_used * 6; - /* update too big for an IB */ - if (ndw > 0xfffff) - return -ENOMEM; - - ib = kzalloc(sizeof(struct amdgpu_ib), GFP_KERNEL); - if (!ib) - return -ENOMEM; - - r = amdgpu_ib_get(ring, NULL, ndw * 4, ib); - if (r) { - kfree(ib); + r = amdgpu_job_alloc_with_ib(adev, ndw * 4, &job); + if (r) return r; - } - ib->length_dw = 0; + + ib = &job->ibs[0]; /* walk over the address space and update the page directory */ for (pt_idx = 0; pt_idx <= vm->max_pde_used; ++pt_idx) { @@ -504,9 +522,10 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, ((last_pt + incr * count) != pt)) { if (count) { - amdgpu_vm_update_pages(adev, ib, last_pde, - last_pt, count, incr, - AMDGPU_PTE_VALID, 0); + amdgpu_vm_update_pages(adev, NULL, 0, ib, + last_pde, last_pt, + count, incr, + AMDGPU_PTE_VALID); } count = 1; @@ -518,17 +537,16 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, } if (count) - amdgpu_vm_update_pages(adev, ib, last_pde, last_pt, count, - incr, AMDGPU_PTE_VALID, 0); + amdgpu_vm_update_pages(adev, NULL, 0, ib, last_pde, last_pt, + count, incr, AMDGPU_PTE_VALID); if (ib->length_dw != 0) { - amdgpu_vm_pad_ib(adev, ib); - amdgpu_sync_resv(adev, &ib->sync, pd->tbo.resv, AMDGPU_FENCE_OWNER_VM); + amdgpu_ring_pad_ib(ring, ib); + amdgpu_sync_resv(adev, &job->sync, pd->tbo.resv, + AMDGPU_FENCE_OWNER_VM); WARN_ON(ib->length_dw > ndw); - r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, ib, 1, - &amdgpu_vm_free_job, - AMDGPU_FENCE_OWNER_VM, - &fence); + r = amdgpu_job_submit(job, ring, &vm->entity, + AMDGPU_FENCE_OWNER_VM, &fence); if (r) goto error_free; @@ -536,18 +554,15 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, fence_put(vm->page_directory_fence); vm->page_directory_fence = fence_get(fence); fence_put(fence); - } - if (!amdgpu_enable_scheduler || ib->length_dw == 0) { - amdgpu_ib_free(adev, ib); - kfree(ib); + } else { + amdgpu_job_free(job); } return 0; error_free: - amdgpu_ib_free(adev, ib); - kfree(ib); + amdgpu_job_free(job); return r; } @@ -555,20 +570,20 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, * amdgpu_vm_frag_ptes - add fragment information to PTEs * * @adev: amdgpu_device pointer + * @gtt: GART instance to use for mapping + * @gtt_flags: GTT hw mapping flags * @ib: IB for the update * @pe_start: first PTE to handle * @pe_end: last PTE to handle * @addr: addr those PTEs should point to * @flags: hw mapping flags - * @gtt_flags: GTT hw mapping flags - * - * Global and local mutex must be locked! */ static void amdgpu_vm_frag_ptes(struct amdgpu_device *adev, + struct amdgpu_gart *gtt, + uint32_t gtt_flags, struct amdgpu_ib *ib, uint64_t pe_start, uint64_t pe_end, - uint64_t addr, uint32_t flags, - uint32_t gtt_flags) + uint64_t addr, uint32_t flags) { /** * The MC L1 TLB supports variable sized pages, based on a fragment @@ -598,36 +613,39 @@ static void amdgpu_vm_frag_ptes(struct amdgpu_device *adev, unsigned count; + /* Abort early if there isn't anything to do */ + if (pe_start == pe_end) + return; + /* system pages are non continuously */ - if ((flags & AMDGPU_PTE_SYSTEM) || !(flags & AMDGPU_PTE_VALID) || - (frag_start >= frag_end)) { + if (gtt || !(flags & AMDGPU_PTE_VALID) || (frag_start >= frag_end)) { count = (pe_end - pe_start) / 8; - amdgpu_vm_update_pages(adev, ib, pe_start, addr, count, - AMDGPU_GPU_PAGE_SIZE, flags, gtt_flags); + amdgpu_vm_update_pages(adev, gtt, gtt_flags, ib, pe_start, + addr, count, AMDGPU_GPU_PAGE_SIZE, + flags); return; } /* handle the 4K area at the beginning */ if (pe_start != frag_start) { count = (frag_start - pe_start) / 8; - amdgpu_vm_update_pages(adev, ib, pe_start, addr, count, - AMDGPU_GPU_PAGE_SIZE, flags, gtt_flags); + amdgpu_vm_update_pages(adev, NULL, 0, ib, pe_start, addr, + count, AMDGPU_GPU_PAGE_SIZE, flags); addr += AMDGPU_GPU_PAGE_SIZE * count; } /* handle the area in the middle */ count = (frag_end - frag_start) / 8; - amdgpu_vm_update_pages(adev, ib, frag_start, addr, count, - AMDGPU_GPU_PAGE_SIZE, flags | frag_flags, - gtt_flags); + amdgpu_vm_update_pages(adev, NULL, 0, ib, frag_start, addr, count, + AMDGPU_GPU_PAGE_SIZE, flags | frag_flags); /* handle the 4K area at the end */ if (frag_end != pe_end) { addr += AMDGPU_GPU_PAGE_SIZE * count; count = (pe_end - frag_end) / 8; - amdgpu_vm_update_pages(adev, ib, frag_end, addr, count, - AMDGPU_GPU_PAGE_SIZE, flags, gtt_flags); + amdgpu_vm_update_pages(adev, NULL, 0, ib, frag_end, addr, + count, AMDGPU_GPU_PAGE_SIZE, flags); } } @@ -635,122 +653,105 @@ static void amdgpu_vm_frag_ptes(struct amdgpu_device *adev, * amdgpu_vm_update_ptes - make sure that page tables are valid * * @adev: amdgpu_device pointer + * @gtt: GART instance to use for mapping + * @gtt_flags: GTT hw mapping flags * @vm: requested vm * @start: start of GPU address range * @end: end of GPU address range * @dst: destination address to map to * @flags: mapping flags * - * Update the page tables in the range @start - @end (cayman+). - * - * Global and local mutex must be locked! + * Update the page tables in the range @start - @end. */ -static int amdgpu_vm_update_ptes(struct amdgpu_device *adev, - struct amdgpu_vm *vm, - struct amdgpu_ib *ib, - uint64_t start, uint64_t end, - uint64_t dst, uint32_t flags, - uint32_t gtt_flags) +static void amdgpu_vm_update_ptes(struct amdgpu_device *adev, + struct amdgpu_gart *gtt, + uint32_t gtt_flags, + struct amdgpu_vm *vm, + struct amdgpu_ib *ib, + uint64_t start, uint64_t end, + uint64_t dst, uint32_t flags) { - uint64_t mask = AMDGPU_VM_PTE_COUNT - 1; - uint64_t last_pte = ~0, last_dst = ~0; - void *owner = AMDGPU_FENCE_OWNER_VM; - unsigned count = 0; - uint64_t addr; + const uint64_t mask = AMDGPU_VM_PTE_COUNT - 1; - /* sync to everything on unmapping */ - if (!(flags & AMDGPU_PTE_VALID)) - owner = AMDGPU_FENCE_OWNER_UNDEFINED; + uint64_t last_pe_start = ~0, last_pe_end = ~0, last_dst = ~0; + uint64_t addr; /* walk over the address space and update the page tables */ for (addr = start; addr < end; ) { uint64_t pt_idx = addr >> amdgpu_vm_block_size; struct amdgpu_bo *pt = vm->page_tables[pt_idx].entry.robj; unsigned nptes; - uint64_t pte; - int r; - - amdgpu_sync_resv(adev, &ib->sync, pt->tbo.resv, owner); - r = reservation_object_reserve_shared(pt->tbo.resv); - if (r) - return r; + uint64_t pe_start; if ((addr & ~mask) == (end & ~mask)) nptes = end - addr; else nptes = AMDGPU_VM_PTE_COUNT - (addr & mask); - pte = amdgpu_bo_gpu_offset(pt); - pte += (addr & mask) * 8; + pe_start = amdgpu_bo_gpu_offset(pt); + pe_start += (addr & mask) * 8; - if ((last_pte + 8 * count) != pte) { + if (last_pe_end != pe_start) { - if (count) { - amdgpu_vm_frag_ptes(adev, ib, last_pte, - last_pte + 8 * count, - last_dst, flags, - gtt_flags); - } + amdgpu_vm_frag_ptes(adev, gtt, gtt_flags, ib, + last_pe_start, last_pe_end, + last_dst, flags); - count = nptes; - last_pte = pte; + last_pe_start = pe_start; + last_pe_end = pe_start + 8 * nptes; last_dst = dst; } else { - count += nptes; + last_pe_end += 8 * nptes; } addr += nptes; dst += nptes * AMDGPU_GPU_PAGE_SIZE; } - if (count) { - amdgpu_vm_frag_ptes(adev, ib, last_pte, - last_pte + 8 * count, - last_dst, flags, gtt_flags); - } - - return 0; + amdgpu_vm_frag_ptes(adev, gtt, gtt_flags, ib, + last_pe_start, last_pe_end, + last_dst, flags); } /** * amdgpu_vm_bo_update_mapping - update a mapping in the vm page table * * @adev: amdgpu_device pointer + * @gtt: GART instance to use for mapping + * @gtt_flags: flags as they are used for GTT * @vm: requested vm - * @mapping: mapped range and flags to use for the update + * @start: start of mapped range + * @last: last mapped entry + * @flags: flags for the entries * @addr: addr to set the area to - * @gtt_flags: flags as they are used for GTT * @fence: optional resulting fence * - * Fill in the page table entries for @mapping. + * Fill in the page table entries between @start and @last. * Returns 0 for success, -EINVAL for failure. - * - * Object have to be reserved and mutex must be locked! */ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, + struct amdgpu_gart *gtt, + uint32_t gtt_flags, struct amdgpu_vm *vm, - struct amdgpu_bo_va_mapping *mapping, - uint64_t addr, uint32_t gtt_flags, + uint64_t start, uint64_t last, + uint32_t flags, uint64_t addr, struct fence **fence) { - struct amdgpu_ring *ring = adev->vm_manager.vm_pte_funcs_ring; + struct amdgpu_ring *ring; + void *owner = AMDGPU_FENCE_OWNER_VM; unsigned nptes, ncmds, ndw; - uint32_t flags = gtt_flags; + struct amdgpu_job *job; struct amdgpu_ib *ib; struct fence *f = NULL; int r; - /* normally,bo_va->flags only contians READABLE and WIRTEABLE bit go here - * but in case of something, we filter the flags in first place - */ - if (!(mapping->flags & AMDGPU_PTE_READABLE)) - flags &= ~AMDGPU_PTE_READABLE; - if (!(mapping->flags & AMDGPU_PTE_WRITEABLE)) - flags &= ~AMDGPU_PTE_WRITEABLE; + ring = container_of(vm->entity.sched, struct amdgpu_ring, sched); - trace_amdgpu_vm_bo_update(mapping); + /* sync to everything on unmapping */ + if (!(flags & AMDGPU_PTE_VALID)) + owner = AMDGPU_FENCE_OWNER_UNDEFINED; - nptes = mapping->it.last - mapping->it.start + 1; + nptes = last - start + 1; /* * reserve space for one command every (1 << BLOCK_SIZE) @@ -761,11 +762,11 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, /* padding, etc. */ ndw = 64; - if ((flags & AMDGPU_PTE_SYSTEM) && (flags == gtt_flags)) { + if ((gtt == &adev->gart) && (flags == gtt_flags)) { /* only copy commands needed */ ndw += ncmds * 7; - } else if (flags & AMDGPU_PTE_SYSTEM) { + } else if (gtt) { /* header for write data commands */ ndw += ncmds * 4; @@ -780,38 +781,28 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, ndw += 2 * 10; } - /* update too big for an IB */ - if (ndw > 0xfffff) - return -ENOMEM; - - ib = kzalloc(sizeof(struct amdgpu_ib), GFP_KERNEL); - if (!ib) - return -ENOMEM; - - r = amdgpu_ib_get(ring, NULL, ndw * 4, ib); - if (r) { - kfree(ib); + r = amdgpu_job_alloc_with_ib(adev, ndw * 4, &job); + if (r) return r; - } - ib->length_dw = 0; + ib = &job->ibs[0]; - r = amdgpu_vm_update_ptes(adev, vm, ib, mapping->it.start, - mapping->it.last + 1, addr + mapping->offset, - flags, gtt_flags); + r = amdgpu_sync_resv(adev, &job->sync, vm->page_directory->tbo.resv, + owner); + if (r) + goto error_free; - if (r) { - amdgpu_ib_free(adev, ib); - kfree(ib); - return r; - } + r = reservation_object_reserve_shared(vm->page_directory->tbo.resv); + if (r) + goto error_free; + + amdgpu_vm_update_ptes(adev, gtt, gtt_flags, vm, ib, start, last + 1, + addr, flags); - amdgpu_vm_pad_ib(adev, ib); + amdgpu_ring_pad_ib(ring, ib); WARN_ON(ib->length_dw > ndw); - r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, ib, 1, - &amdgpu_vm_free_job, - AMDGPU_FENCE_OWNER_VM, - &f); + r = amdgpu_job_submit(job, ring, &vm->entity, + AMDGPU_FENCE_OWNER_VM, &f); if (r) goto error_free; @@ -821,18 +812,75 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, *fence = fence_get(f); } fence_put(f); - if (!amdgpu_enable_scheduler) { - amdgpu_ib_free(adev, ib); - kfree(ib); - } return 0; error_free: - amdgpu_ib_free(adev, ib); - kfree(ib); + amdgpu_job_free(job); return r; } +/** + * amdgpu_vm_bo_split_mapping - split a mapping into smaller chunks + * + * @adev: amdgpu_device pointer + * @gtt: GART instance to use for mapping + * @vm: requested vm + * @mapping: mapped range and flags to use for the update + * @addr: addr to set the area to + * @gtt_flags: flags as they are used for GTT + * @fence: optional resulting fence + * + * Split the mapping into smaller chunks so that each update fits + * into a SDMA IB. + * Returns 0 for success, -EINVAL for failure. + */ +static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev, + struct amdgpu_gart *gtt, + uint32_t gtt_flags, + struct amdgpu_vm *vm, + struct amdgpu_bo_va_mapping *mapping, + uint64_t addr, struct fence **fence) +{ + const uint64_t max_size = 64ULL * 1024ULL * 1024ULL / AMDGPU_GPU_PAGE_SIZE; + + uint64_t start = mapping->it.start; + uint32_t flags = gtt_flags; + int r; + + /* normally,bo_va->flags only contians READABLE and WIRTEABLE bit go here + * but in case of something, we filter the flags in first place + */ + if (!(mapping->flags & AMDGPU_PTE_READABLE)) + flags &= ~AMDGPU_PTE_READABLE; + if (!(mapping->flags & AMDGPU_PTE_WRITEABLE)) + flags &= ~AMDGPU_PTE_WRITEABLE; + + trace_amdgpu_vm_bo_update(mapping); + + addr += mapping->offset; + + if (!gtt || ((gtt == &adev->gart) && (flags == gtt_flags))) + return amdgpu_vm_bo_update_mapping(adev, gtt, gtt_flags, vm, + start, mapping->it.last, + flags, addr, fence); + + while (start != mapping->it.last + 1) { + uint64_t last; + + last = min((uint64_t)mapping->it.last, start + max_size - 1); + r = amdgpu_vm_bo_update_mapping(adev, gtt, gtt_flags, vm, + start, last, flags, addr, + fence); + if (r) + return r; + + start = last + 1; + addr += max_size * AMDGPU_GPU_PAGE_SIZE; + } + + return 0; +} + /** * amdgpu_vm_bo_update - update all BO mappings in the vm page table * @@ -851,14 +899,25 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, { struct amdgpu_vm *vm = bo_va->vm; struct amdgpu_bo_va_mapping *mapping; + struct amdgpu_gart *gtt = NULL; uint32_t flags; uint64_t addr; int r; if (mem) { addr = (u64)mem->start << PAGE_SHIFT; - if (mem->mem_type != TTM_PL_TT) + switch (mem->mem_type) { + case TTM_PL_TT: + gtt = &bo_va->bo->adev->gart; + break; + + case TTM_PL_VRAM: addr += adev->vm_manager.vram_base_offset; + break; + + default: + break; + } } else { addr = 0; } @@ -871,8 +930,8 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, spin_unlock(&vm->status_lock); list_for_each_entry(mapping, &bo_va->invalids, list) { - r = amdgpu_vm_bo_update_mapping(adev, vm, mapping, addr, - flags, &bo_va->last_pt_update); + r = amdgpu_vm_bo_split_mapping(adev, gtt, flags, vm, mapping, addr, + &bo_va->last_pt_update); if (r) return r; } @@ -912,21 +971,18 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev, struct amdgpu_bo_va_mapping *mapping; int r; - spin_lock(&vm->freed_lock); while (!list_empty(&vm->freed)) { mapping = list_first_entry(&vm->freed, struct amdgpu_bo_va_mapping, list); list_del(&mapping->list); - spin_unlock(&vm->freed_lock); - r = amdgpu_vm_bo_update_mapping(adev, vm, mapping, 0, 0, NULL); + + r = amdgpu_vm_bo_split_mapping(adev, NULL, 0, vm, mapping, + 0, NULL); kfree(mapping); if (r) return r; - spin_lock(&vm->freed_lock); } - spin_unlock(&vm->freed_lock); - return 0; } @@ -953,9 +1009,8 @@ int amdgpu_vm_clear_invalids(struct amdgpu_device *adev, bo_va = list_first_entry(&vm->invalidated, struct amdgpu_bo_va, vm_status); spin_unlock(&vm->status_lock); - mutex_lock(&bo_va->mutex); + r = amdgpu_vm_bo_update(adev, bo_va, NULL); - mutex_unlock(&bo_va->mutex); if (r) return r; @@ -976,7 +1031,7 @@ int amdgpu_vm_clear_invalids(struct amdgpu_device *adev, * @vm: requested vm * @bo: amdgpu buffer object * - * Add @bo into the requested vm (cayman+). + * Add @bo into the requested vm. * Add @bo to the list of bos associated with the vm * Returns newly added bo_va or NULL for failure * @@ -999,7 +1054,7 @@ struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev, INIT_LIST_HEAD(&bo_va->valids); INIT_LIST_HEAD(&bo_va->invalids); INIT_LIST_HEAD(&bo_va->vm_status); - mutex_init(&bo_va->mutex); + list_add_tail(&bo_va->bo_list, &bo->va); return bo_va; @@ -1051,9 +1106,7 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev, saddr /= AMDGPU_GPU_PAGE_SIZE; eaddr /= AMDGPU_GPU_PAGE_SIZE; - spin_lock(&vm->it_lock); it = interval_tree_iter_first(&vm->va, saddr, eaddr); - spin_unlock(&vm->it_lock); if (it) { struct amdgpu_bo_va_mapping *tmp; tmp = container_of(it, struct amdgpu_bo_va_mapping, it); @@ -1077,13 +1130,8 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev, mapping->offset = offset; mapping->flags = flags; - mutex_lock(&bo_va->mutex); list_add(&mapping->list, &bo_va->invalids); - mutex_unlock(&bo_va->mutex); - spin_lock(&vm->it_lock); interval_tree_insert(&mapping->it, &vm->va); - spin_unlock(&vm->it_lock); - trace_amdgpu_vm_bo_map(bo_va, mapping); /* Make sure the page tables are allocated */ saddr >>= amdgpu_vm_block_size; @@ -1117,18 +1165,17 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev, */ pt->parent = amdgpu_bo_ref(vm->page_directory); - r = amdgpu_vm_clear_bo(adev, pt); + r = amdgpu_vm_clear_bo(adev, vm, pt); if (r) { amdgpu_bo_unref(&pt); goto error_free; } entry->robj = pt; - entry->prefered_domains = AMDGPU_GEM_DOMAIN_VRAM; - entry->allowed_domains = AMDGPU_GEM_DOMAIN_VRAM; entry->priority = 0; entry->tv.bo = &entry->robj->tbo; entry->tv.shared = true; + entry->user_pages = NULL; vm->page_tables[pt_idx].addr = 0; } @@ -1136,9 +1183,7 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev, error_free: list_del(&mapping->list); - spin_lock(&vm->it_lock); interval_tree_remove(&mapping->it, &vm->va); - spin_unlock(&vm->it_lock); trace_amdgpu_vm_bo_unmap(bo_va, mapping); kfree(mapping); @@ -1167,7 +1212,7 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev, bool valid = true; saddr /= AMDGPU_GPU_PAGE_SIZE; - mutex_lock(&bo_va->mutex); + list_for_each_entry(mapping, &bo_va->valids, list) { if (mapping->it.start == saddr) break; @@ -1181,25 +1226,18 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev, break; } - if (&mapping->list == &bo_va->invalids) { - mutex_unlock(&bo_va->mutex); + if (&mapping->list == &bo_va->invalids) return -ENOENT; - } } - mutex_unlock(&bo_va->mutex); + list_del(&mapping->list); - spin_lock(&vm->it_lock); interval_tree_remove(&mapping->it, &vm->va); - spin_unlock(&vm->it_lock); trace_amdgpu_vm_bo_unmap(bo_va, mapping); - if (valid) { - spin_lock(&vm->freed_lock); + if (valid) list_add(&mapping->list, &vm->freed); - spin_unlock(&vm->freed_lock); - } else { + else kfree(mapping); - } return 0; } @@ -1210,7 +1248,7 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev, * @adev: amdgpu_device pointer * @bo_va: requested bo_va * - * Remove @bo_va->bo from the requested vm (cayman+). + * Remove @bo_va->bo from the requested vm. * * Object have to be reserved! */ @@ -1228,23 +1266,17 @@ void amdgpu_vm_bo_rmv(struct amdgpu_device *adev, list_for_each_entry_safe(mapping, next, &bo_va->valids, list) { list_del(&mapping->list); - spin_lock(&vm->it_lock); interval_tree_remove(&mapping->it, &vm->va); - spin_unlock(&vm->it_lock); trace_amdgpu_vm_bo_unmap(bo_va, mapping); - spin_lock(&vm->freed_lock); list_add(&mapping->list, &vm->freed); - spin_unlock(&vm->freed_lock); } list_for_each_entry_safe(mapping, next, &bo_va->invalids, list) { list_del(&mapping->list); - spin_lock(&vm->it_lock); interval_tree_remove(&mapping->it, &vm->va); - spin_unlock(&vm->it_lock); kfree(mapping); } + fence_put(bo_va->last_pt_update); - mutex_destroy(&bo_va->mutex); kfree(bo_va); } @@ -1255,7 +1287,7 @@ void amdgpu_vm_bo_rmv(struct amdgpu_device *adev, * @vm: requested vm * @bo: amdgpu buffer object * - * Mark @bo as invalid (cayman+). + * Mark @bo as invalid. */ void amdgpu_vm_bo_invalidate(struct amdgpu_device *adev, struct amdgpu_bo *bo) @@ -1276,17 +1308,20 @@ void amdgpu_vm_bo_invalidate(struct amdgpu_device *adev, * @adev: amdgpu_device pointer * @vm: requested vm * - * Init @vm fields (cayman+). + * Init @vm fields. */ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm) { const unsigned align = min(AMDGPU_VM_PTB_ALIGN_SIZE, AMDGPU_VM_PTE_COUNT * 8); unsigned pd_size, pd_entries; + unsigned ring_instance; + struct amdgpu_ring *ring; + struct amd_sched_rq *rq; int i, r; for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { - vm->ids[i].id = 0; + vm->ids[i].mgr_id = NULL; vm->ids[i].flushed_updates = NULL; } vm->va = RB_ROOT; @@ -1294,8 +1329,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm) INIT_LIST_HEAD(&vm->invalidated); INIT_LIST_HEAD(&vm->cleared); INIT_LIST_HEAD(&vm->freed); - spin_lock_init(&vm->it_lock); - spin_lock_init(&vm->freed_lock); + pd_size = amdgpu_vm_directory_size(adev); pd_entries = amdgpu_vm_num_pdes(adev); @@ -1306,6 +1340,17 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm) return -ENOMEM; } + /* create scheduler entity for page table updates */ + + ring_instance = atomic_inc_return(&adev->vm_manager.vm_pte_next_ring); + ring_instance %= adev->vm_manager.vm_pte_num_rings; + ring = adev->vm_manager.vm_pte_rings[ring_instance]; + rq = &ring->sched.sched_rq[AMD_SCHED_PRIORITY_KERNEL]; + r = amd_sched_entity_init(&ring->sched, &vm->entity, + rq, amdgpu_sched_jobs); + if (r) + return r; + vm->page_directory_fence = NULL; r = amdgpu_bo_create(adev, pd_size, align, true, @@ -1313,22 +1358,27 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm) AMDGPU_GEM_CREATE_NO_CPU_ACCESS, NULL, NULL, &vm->page_directory); if (r) - return r; + goto error_free_sched_entity; + r = amdgpu_bo_reserve(vm->page_directory, false); - if (r) { - amdgpu_bo_unref(&vm->page_directory); - vm->page_directory = NULL; - return r; - } - r = amdgpu_vm_clear_bo(adev, vm->page_directory); + if (r) + goto error_free_page_directory; + + r = amdgpu_vm_clear_bo(adev, vm, vm->page_directory); amdgpu_bo_unreserve(vm->page_directory); - if (r) { - amdgpu_bo_unref(&vm->page_directory); - vm->page_directory = NULL; - return r; - } + if (r) + goto error_free_page_directory; return 0; + +error_free_page_directory: + amdgpu_bo_unref(&vm->page_directory); + vm->page_directory = NULL; + +error_free_sched_entity: + amd_sched_entity_fini(&ring->sched, &vm->entity); + + return r; } /** @@ -1337,7 +1387,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm) * @adev: amdgpu_device pointer * @vm: requested vm * - * Tear down @vm (cayman+). + * Tear down @vm. * Unbind the VM and remove all bos from the vm bo list */ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) @@ -1345,6 +1395,8 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) struct amdgpu_bo_va_mapping *mapping, *tmp; int i; + amd_sched_entity_fini(vm->entity.sched, &vm->entity); + if (!RB_EMPTY_ROOT(&vm->va)) { dev_err(adev->dev, "still active bo inside vm\n"); } @@ -1364,14 +1416,38 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) amdgpu_bo_unref(&vm->page_directory); fence_put(vm->page_directory_fence); + for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { - unsigned id = vm->ids[i].id; + struct amdgpu_vm_id *id = &vm->ids[i]; - atomic_long_cmpxchg(&adev->vm_manager.ids[id].owner, - (long)vm, 0); - fence_put(vm->ids[i].flushed_updates); + if (id->mgr_id) + atomic_long_cmpxchg(&id->mgr_id->owner, + (long)id, 0); + fence_put(id->flushed_updates); + } +} + +/** + * amdgpu_vm_manager_init - init the VM manager + * + * @adev: amdgpu_device pointer + * + * Initialize the VM manager structures + */ +void amdgpu_vm_manager_init(struct amdgpu_device *adev) +{ + unsigned i; + + INIT_LIST_HEAD(&adev->vm_manager.ids_lru); + + /* skip over VMID 0, since it is the system VM */ + for (i = 1; i < adev->vm_manager.num_ids; ++i) { + amdgpu_vm_reset_id(adev, i); + list_add_tail(&adev->vm_manager.ids[i].list, + &adev->vm_manager.ids_lru); } + atomic_set(&adev->vm_manager.vm_pte_next_ring, 0); } /** diff --git a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c index 474ca02b094935283c3548534a2502cd01412665..1f9109d3348bf63baf6b687de63d620d763bac18 100644 --- a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c @@ -3017,7 +3017,6 @@ static int ci_populate_single_memory_level(struct amdgpu_device *adev, &memory_level->MinVddcPhases); memory_level->EnabledForThrottle = 1; - memory_level->EnabledForActivity = 1; memory_level->UpH = 0; memory_level->DownH = 100; memory_level->VoltageDownH = 0; @@ -3376,7 +3375,6 @@ static int ci_populate_single_graphic_level(struct amdgpu_device *adev, graphic_level->SpllSpreadSpectrum2 = cpu_to_be32(graphic_level->SpllSpreadSpectrum2); graphic_level->CcPwrDynRm = cpu_to_be32(graphic_level->CcPwrDynRm); graphic_level->CcPwrDynRm1 = cpu_to_be32(graphic_level->CcPwrDynRm1); - graphic_level->EnabledForActivity = 1; return 0; } @@ -3407,6 +3405,7 @@ static int ci_populate_all_graphic_levels(struct amdgpu_device *adev) pi->smc_state_table.GraphicsLevel[i].DisplayWatermark = PPSMC_DISPLAY_WATERMARK_HIGH; } + pi->smc_state_table.GraphicsLevel[0].EnabledForActivity = 1; pi->smc_state_table.GraphicsDpmLevelCount = (u8)dpm_table->sclk_table.count; pi->dpm_level_enable_mask.sclk_dpm_enable_mask = @@ -3450,6 +3449,8 @@ static int ci_populate_all_memory_levels(struct amdgpu_device *adev) return ret; } + pi->smc_state_table.MemoryLevel[0].EnabledForActivity = 1; + if ((dpm_table->mclk_table.count >= 2) && ((adev->pdev->device == 0x67B0) || (adev->pdev->device == 0x67B1))) { pi->smc_state_table.MemoryLevel[1].MinVddc = @@ -4381,26 +4382,6 @@ static int ci_dpm_force_performance_level(struct amdgpu_device *adev, } } } - if ((!pi->pcie_dpm_key_disabled) && - pi->dpm_level_enable_mask.pcie_dpm_enable_mask) { - levels = 0; - tmp = pi->dpm_level_enable_mask.pcie_dpm_enable_mask; - while (tmp >>= 1) - levels++; - if (levels) { - ret = ci_dpm_force_state_pcie(adev, level); - if (ret) - return ret; - for (i = 0; i < adev->usec_timeout; i++) { - tmp = (RREG32_SMC(ixTARGET_AND_CURRENT_PROFILE_INDEX_1) & - TARGET_AND_CURRENT_PROFILE_INDEX_1__CURR_PCIE_INDEX_MASK) >> - TARGET_AND_CURRENT_PROFILE_INDEX_1__CURR_PCIE_INDEX__SHIFT; - if (tmp == levels) - break; - udelay(1); - } - } - } } else if (level == AMDGPU_DPM_FORCED_LEVEL_LOW) { if ((!pi->sclk_dpm_key_disabled) && pi->dpm_level_enable_mask.sclk_dpm_enable_mask) { @@ -5395,30 +5376,6 @@ static int ci_dpm_enable(struct amdgpu_device *adev) ci_update_current_ps(adev, boot_ps); - if (adev->irq.installed && - amdgpu_is_internal_thermal_sensor(adev->pm.int_thermal_type)) { -#if 0 - PPSMC_Result result; -#endif - ret = ci_thermal_set_temperature_range(adev, CISLANDS_TEMP_RANGE_MIN, - CISLANDS_TEMP_RANGE_MAX); - if (ret) { - DRM_ERROR("ci_thermal_set_temperature_range failed\n"); - return ret; - } - amdgpu_irq_get(adev, &adev->pm.dpm.thermal.irq, - AMDGPU_THERMAL_IRQ_LOW_TO_HIGH); - amdgpu_irq_get(adev, &adev->pm.dpm.thermal.irq, - AMDGPU_THERMAL_IRQ_HIGH_TO_LOW); - -#if 0 - result = amdgpu_ci_send_msg_to_smc(adev, PPSMC_MSG_EnableThermalInterrupt); - - if (result != PPSMC_Result_OK) - DRM_DEBUG_KMS("Could not enable thermal interrupts.\n"); -#endif - } - return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c b/drivers/gpu/drm/amd/amdgpu/cik.c index 155965ed14a3bee05d745b5e25fccf03546dc4ae..bddc9ba11495543fb3d021dc6b9ff384547b73be 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik.c +++ b/drivers/gpu/drm/amd/amdgpu/cik.c @@ -1059,257 +1059,6 @@ static int cik_read_register(struct amdgpu_device *adev, u32 se_num, return -EINVAL; } -static void cik_print_gpu_status_regs(struct amdgpu_device *adev) -{ - dev_info(adev->dev, " GRBM_STATUS=0x%08X\n", - RREG32(mmGRBM_STATUS)); - dev_info(adev->dev, " GRBM_STATUS2=0x%08X\n", - RREG32(mmGRBM_STATUS2)); - dev_info(adev->dev, " GRBM_STATUS_SE0=0x%08X\n", - RREG32(mmGRBM_STATUS_SE0)); - dev_info(adev->dev, " GRBM_STATUS_SE1=0x%08X\n", - RREG32(mmGRBM_STATUS_SE1)); - dev_info(adev->dev, " GRBM_STATUS_SE2=0x%08X\n", - RREG32(mmGRBM_STATUS_SE2)); - dev_info(adev->dev, " GRBM_STATUS_SE3=0x%08X\n", - RREG32(mmGRBM_STATUS_SE3)); - dev_info(adev->dev, " SRBM_STATUS=0x%08X\n", - RREG32(mmSRBM_STATUS)); - dev_info(adev->dev, " SRBM_STATUS2=0x%08X\n", - RREG32(mmSRBM_STATUS2)); - dev_info(adev->dev, " SDMA0_STATUS_REG = 0x%08X\n", - RREG32(mmSDMA0_STATUS_REG + SDMA0_REGISTER_OFFSET)); - dev_info(adev->dev, " SDMA1_STATUS_REG = 0x%08X\n", - RREG32(mmSDMA0_STATUS_REG + SDMA1_REGISTER_OFFSET)); - dev_info(adev->dev, " CP_STAT = 0x%08x\n", RREG32(mmCP_STAT)); - dev_info(adev->dev, " CP_STALLED_STAT1 = 0x%08x\n", - RREG32(mmCP_STALLED_STAT1)); - dev_info(adev->dev, " CP_STALLED_STAT2 = 0x%08x\n", - RREG32(mmCP_STALLED_STAT2)); - dev_info(adev->dev, " CP_STALLED_STAT3 = 0x%08x\n", - RREG32(mmCP_STALLED_STAT3)); - dev_info(adev->dev, " CP_CPF_BUSY_STAT = 0x%08x\n", - RREG32(mmCP_CPF_BUSY_STAT)); - dev_info(adev->dev, " CP_CPF_STALLED_STAT1 = 0x%08x\n", - RREG32(mmCP_CPF_STALLED_STAT1)); - dev_info(adev->dev, " CP_CPF_STATUS = 0x%08x\n", RREG32(mmCP_CPF_STATUS)); - dev_info(adev->dev, " CP_CPC_BUSY_STAT = 0x%08x\n", RREG32(mmCP_CPC_BUSY_STAT)); - dev_info(adev->dev, " CP_CPC_STALLED_STAT1 = 0x%08x\n", - RREG32(mmCP_CPC_STALLED_STAT1)); - dev_info(adev->dev, " CP_CPC_STATUS = 0x%08x\n", RREG32(mmCP_CPC_STATUS)); -} - -/** - * cik_gpu_check_soft_reset - check which blocks are busy - * - * @adev: amdgpu_device pointer - * - * Check which blocks are busy and return the relevant reset - * mask to be used by cik_gpu_soft_reset(). - * Returns a mask of the blocks to be reset. - */ -u32 amdgpu_cik_gpu_check_soft_reset(struct amdgpu_device *adev) -{ - u32 reset_mask = 0; - u32 tmp; - - /* GRBM_STATUS */ - tmp = RREG32(mmGRBM_STATUS); - if (tmp & (GRBM_STATUS__PA_BUSY_MASK | GRBM_STATUS__SC_BUSY_MASK | - GRBM_STATUS__BCI_BUSY_MASK | GRBM_STATUS__SX_BUSY_MASK | - GRBM_STATUS__TA_BUSY_MASK | GRBM_STATUS__VGT_BUSY_MASK | - GRBM_STATUS__DB_BUSY_MASK | GRBM_STATUS__CB_BUSY_MASK | - GRBM_STATUS__GDS_BUSY_MASK | GRBM_STATUS__SPI_BUSY_MASK | - GRBM_STATUS__IA_BUSY_MASK | GRBM_STATUS__IA_BUSY_NO_DMA_MASK)) - reset_mask |= AMDGPU_RESET_GFX; - - if (tmp & (GRBM_STATUS__CP_BUSY_MASK | GRBM_STATUS__CP_COHERENCY_BUSY_MASK)) - reset_mask |= AMDGPU_RESET_CP; - - /* GRBM_STATUS2 */ - tmp = RREG32(mmGRBM_STATUS2); - if (tmp & GRBM_STATUS2__RLC_BUSY_MASK) - reset_mask |= AMDGPU_RESET_RLC; - - /* SDMA0_STATUS_REG */ - tmp = RREG32(mmSDMA0_STATUS_REG + SDMA0_REGISTER_OFFSET); - if (!(tmp & SDMA0_STATUS_REG__IDLE_MASK)) - reset_mask |= AMDGPU_RESET_DMA; - - /* SDMA1_STATUS_REG */ - tmp = RREG32(mmSDMA0_STATUS_REG + SDMA1_REGISTER_OFFSET); - if (!(tmp & SDMA0_STATUS_REG__IDLE_MASK)) - reset_mask |= AMDGPU_RESET_DMA1; - - /* SRBM_STATUS2 */ - tmp = RREG32(mmSRBM_STATUS2); - if (tmp & SRBM_STATUS2__SDMA_BUSY_MASK) - reset_mask |= AMDGPU_RESET_DMA; - - if (tmp & SRBM_STATUS2__SDMA1_BUSY_MASK) - reset_mask |= AMDGPU_RESET_DMA1; - - /* SRBM_STATUS */ - tmp = RREG32(mmSRBM_STATUS); - - if (tmp & SRBM_STATUS__IH_BUSY_MASK) - reset_mask |= AMDGPU_RESET_IH; - - if (tmp & SRBM_STATUS__SEM_BUSY_MASK) - reset_mask |= AMDGPU_RESET_SEM; - - if (tmp & SRBM_STATUS__GRBM_RQ_PENDING_MASK) - reset_mask |= AMDGPU_RESET_GRBM; - - if (tmp & SRBM_STATUS__VMC_BUSY_MASK) - reset_mask |= AMDGPU_RESET_VMC; - - if (tmp & (SRBM_STATUS__MCB_BUSY_MASK | SRBM_STATUS__MCB_NON_DISPLAY_BUSY_MASK | - SRBM_STATUS__MCC_BUSY_MASK | SRBM_STATUS__MCD_BUSY_MASK)) - reset_mask |= AMDGPU_RESET_MC; - - if (amdgpu_display_is_display_hung(adev)) - reset_mask |= AMDGPU_RESET_DISPLAY; - - /* Skip MC reset as it's mostly likely not hung, just busy */ - if (reset_mask & AMDGPU_RESET_MC) { - DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask); - reset_mask &= ~AMDGPU_RESET_MC; - } - - return reset_mask; -} - -/** - * cik_gpu_soft_reset - soft reset GPU - * - * @adev: amdgpu_device pointer - * @reset_mask: mask of which blocks to reset - * - * Soft reset the blocks specified in @reset_mask. - */ -static void cik_gpu_soft_reset(struct amdgpu_device *adev, u32 reset_mask) -{ - struct amdgpu_mode_mc_save save; - u32 grbm_soft_reset = 0, srbm_soft_reset = 0; - u32 tmp; - - if (reset_mask == 0) - return; - - dev_info(adev->dev, "GPU softreset: 0x%08X\n", reset_mask); - - cik_print_gpu_status_regs(adev); - dev_info(adev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", - RREG32(mmVM_CONTEXT1_PROTECTION_FAULT_ADDR)); - dev_info(adev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", - RREG32(mmVM_CONTEXT1_PROTECTION_FAULT_STATUS)); - - /* disable CG/PG */ - - /* stop the rlc */ - gfx_v7_0_rlc_stop(adev); - - /* Disable GFX parsing/prefetching */ - WREG32(mmCP_ME_CNTL, CP_ME_CNTL__ME_HALT_MASK | CP_ME_CNTL__PFP_HALT_MASK | CP_ME_CNTL__CE_HALT_MASK); - - /* Disable MEC parsing/prefetching */ - WREG32(mmCP_MEC_CNTL, CP_MEC_CNTL__MEC_ME1_HALT_MASK | CP_MEC_CNTL__MEC_ME2_HALT_MASK); - - if (reset_mask & AMDGPU_RESET_DMA) { - /* sdma0 */ - tmp = RREG32(mmSDMA0_F32_CNTL + SDMA0_REGISTER_OFFSET); - tmp |= SDMA0_F32_CNTL__HALT_MASK; - WREG32(mmSDMA0_F32_CNTL + SDMA0_REGISTER_OFFSET, tmp); - } - if (reset_mask & AMDGPU_RESET_DMA1) { - /* sdma1 */ - tmp = RREG32(mmSDMA0_F32_CNTL + SDMA1_REGISTER_OFFSET); - tmp |= SDMA0_F32_CNTL__HALT_MASK; - WREG32(mmSDMA0_F32_CNTL + SDMA1_REGISTER_OFFSET, tmp); - } - - gmc_v7_0_mc_stop(adev, &save); - if (amdgpu_asic_wait_for_mc_idle(adev)) { - dev_warn(adev->dev, "Wait for MC idle timedout !\n"); - } - - if (reset_mask & (AMDGPU_RESET_GFX | AMDGPU_RESET_COMPUTE | AMDGPU_RESET_CP)) - grbm_soft_reset = GRBM_SOFT_RESET__SOFT_RESET_CP_MASK | - GRBM_SOFT_RESET__SOFT_RESET_GFX_MASK; - - if (reset_mask & AMDGPU_RESET_CP) { - grbm_soft_reset |= GRBM_SOFT_RESET__SOFT_RESET_CP_MASK; - - srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_GRBM_MASK; - } - - if (reset_mask & AMDGPU_RESET_DMA) - srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_SDMA_MASK; - - if (reset_mask & AMDGPU_RESET_DMA1) - srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_SDMA1_MASK; - - if (reset_mask & AMDGPU_RESET_DISPLAY) - srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_DC_MASK; - - if (reset_mask & AMDGPU_RESET_RLC) - grbm_soft_reset |= GRBM_SOFT_RESET__SOFT_RESET_RLC_MASK; - - if (reset_mask & AMDGPU_RESET_SEM) - srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_SEM_MASK; - - if (reset_mask & AMDGPU_RESET_IH) - srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_IH_MASK; - - if (reset_mask & AMDGPU_RESET_GRBM) - srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_GRBM_MASK; - - if (reset_mask & AMDGPU_RESET_VMC) - srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_VMC_MASK; - - if (!(adev->flags & AMD_IS_APU)) { - if (reset_mask & AMDGPU_RESET_MC) - srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_MC_MASK; - } - - if (grbm_soft_reset) { - tmp = RREG32(mmGRBM_SOFT_RESET); - tmp |= grbm_soft_reset; - dev_info(adev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp); - WREG32(mmGRBM_SOFT_RESET, tmp); - tmp = RREG32(mmGRBM_SOFT_RESET); - - udelay(50); - - tmp &= ~grbm_soft_reset; - WREG32(mmGRBM_SOFT_RESET, tmp); - tmp = RREG32(mmGRBM_SOFT_RESET); - } - - if (srbm_soft_reset) { - tmp = RREG32(mmSRBM_SOFT_RESET); - tmp |= srbm_soft_reset; - dev_info(adev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp); - WREG32(mmSRBM_SOFT_RESET, tmp); - tmp = RREG32(mmSRBM_SOFT_RESET); - - udelay(50); - - tmp &= ~srbm_soft_reset; - WREG32(mmSRBM_SOFT_RESET, tmp); - tmp = RREG32(mmSRBM_SOFT_RESET); - } - - /* Wait a little for things to settle down */ - udelay(50); - - gmc_v7_0_mc_resume(adev, &save); - udelay(50); - - cik_print_gpu_status_regs(adev); -} - struct kv_reset_save_regs { u32 gmcon_reng_execute; u32 gmcon_misc; @@ -1405,45 +1154,11 @@ static void kv_restore_regs_for_reset(struct amdgpu_device *adev, static void cik_gpu_pci_config_reset(struct amdgpu_device *adev) { - struct amdgpu_mode_mc_save save; struct kv_reset_save_regs kv_save = { 0 }; - u32 tmp, i; + u32 i; dev_info(adev->dev, "GPU pci config reset\n"); - /* disable dpm? */ - - /* disable cg/pg */ - - /* Disable GFX parsing/prefetching */ - WREG32(mmCP_ME_CNTL, CP_ME_CNTL__ME_HALT_MASK | - CP_ME_CNTL__PFP_HALT_MASK | CP_ME_CNTL__CE_HALT_MASK); - - /* Disable MEC parsing/prefetching */ - WREG32(mmCP_MEC_CNTL, - CP_MEC_CNTL__MEC_ME1_HALT_MASK | CP_MEC_CNTL__MEC_ME2_HALT_MASK); - - /* sdma0 */ - tmp = RREG32(mmSDMA0_F32_CNTL + SDMA0_REGISTER_OFFSET); - tmp |= SDMA0_F32_CNTL__HALT_MASK; - WREG32(mmSDMA0_F32_CNTL + SDMA0_REGISTER_OFFSET, tmp); - /* sdma1 */ - tmp = RREG32(mmSDMA0_F32_CNTL + SDMA1_REGISTER_OFFSET); - tmp |= SDMA0_F32_CNTL__HALT_MASK; - WREG32(mmSDMA0_F32_CNTL + SDMA1_REGISTER_OFFSET, tmp); - /* XXX other engines? */ - - /* halt the rlc, disable cp internal ints */ - gfx_v7_0_rlc_stop(adev); - - udelay(50); - - /* disable mem access */ - gmc_v7_0_mc_stop(adev, &save); - if (amdgpu_asic_wait_for_mc_idle(adev)) { - dev_warn(adev->dev, "Wait for MC idle timed out !\n"); - } - if (adev->flags & AMD_IS_APU) kv_save_regs_for_reset(adev, &kv_save); @@ -1489,26 +1204,11 @@ static void cik_set_bios_scratch_engine_hung(struct amdgpu_device *adev, bool hu */ static int cik_asic_reset(struct amdgpu_device *adev) { - u32 reset_mask; - - reset_mask = amdgpu_cik_gpu_check_soft_reset(adev); + cik_set_bios_scratch_engine_hung(adev, true); - if (reset_mask) - cik_set_bios_scratch_engine_hung(adev, true); + cik_gpu_pci_config_reset(adev); - /* try soft reset */ - cik_gpu_soft_reset(adev, reset_mask); - - reset_mask = amdgpu_cik_gpu_check_soft_reset(adev); - - /* try pci config reset */ - if (reset_mask && amdgpu_hard_reset) - cik_gpu_pci_config_reset(adev); - - reset_mask = amdgpu_cik_gpu_check_soft_reset(adev); - - if (!reset_mask) - cik_set_bios_scratch_engine_hung(adev, false); + cik_set_bios_scratch_engine_hung(adev, false); return 0; } @@ -2328,8 +2028,6 @@ static int cik_common_early_init(void *handle) adev->asic_funcs = &cik_asic_funcs; - adev->has_uvd = true; - adev->rev_id = cik_get_rev_id(adev); adev->external_rev_id = 0xFF; switch (adev->asic_type) { diff --git a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c index c55ecf0ea8454822a07711c3b85479a9e51e214d..d3ac3298fba8bafb77bb333f1056f4d449ed404a 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c +++ b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c @@ -212,7 +212,7 @@ static void cik_sdma_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count) static void cik_sdma_ring_emit_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib) { - u32 extra_bits = (ib->vm ? ib->vm->ids[ring->idx].id : 0) & 0xf; + u32 extra_bits = ib->vm_id & 0xf; u32 next_rptr = ring->wptr + 5; while ((next_rptr & 7) != 4) @@ -261,6 +261,13 @@ static void cik_sdma_ring_emit_hdp_flush(struct amdgpu_ring *ring) amdgpu_ring_write(ring, (0xfff << 16) | 10); /* retry count, poll interval */ } +static void cik_sdma_ring_emit_hdp_invalidate(struct amdgpu_ring *ring) +{ + amdgpu_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000)); + amdgpu_ring_write(ring, mmHDP_DEBUG0); + amdgpu_ring_write(ring, 1); +} + /** * cik_sdma_ring_emit_fence - emit a fence on the DMA ring * @@ -294,30 +301,6 @@ static void cik_sdma_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq amdgpu_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_TRAP, 0, 0)); } -/** - * cik_sdma_ring_emit_semaphore - emit a semaphore on the dma ring - * - * @ring: amdgpu_ring structure holding ring information - * @semaphore: amdgpu semaphore object - * @emit_wait: wait or signal semaphore - * - * Add a DMA semaphore packet to the ring wait on or signal - * other rings (CIK). - */ -static bool cik_sdma_ring_emit_semaphore(struct amdgpu_ring *ring, - struct amdgpu_semaphore *semaphore, - bool emit_wait) -{ - u64 addr = semaphore->gpu_addr; - u32 extra_bits = emit_wait ? 0 : SDMA_SEMAPHORE_EXTRA_S; - - amdgpu_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SEMAPHORE, 0, extra_bits)); - amdgpu_ring_write(ring, addr & 0xfffffff8); - amdgpu_ring_write(ring, upper_32_bits(addr) & 0xffffffff); - - return true; -} - /** * cik_sdma_gfx_stop - stop the gfx async dma engines * @@ -417,6 +400,9 @@ static int cik_sdma_gfx_resume(struct amdgpu_device *adev) cik_srbm_select(adev, 0, 0, 0, 0); mutex_unlock(&adev->srbm_mutex); + WREG32(mmSDMA0_TILING_CONFIG + sdma_offsets[i], + adev->gfx.config.gb_addr_config & 0x70); + WREG32(mmSDMA0_SEM_INCOMPLETE_TIMER_CNTL + sdma_offsets[i], 0); WREG32(mmSDMA0_SEM_WAIT_FAIL_TIMER_CNTL + sdma_offsets[i], 0); @@ -584,7 +570,7 @@ static int cik_sdma_ring_test_ring(struct amdgpu_ring *ring) tmp = 0xCAFEDEAD; adev->wb.wb[index] = cpu_to_le32(tmp); - r = amdgpu_ring_lock(ring, 5); + r = amdgpu_ring_alloc(ring, 5); if (r) { DRM_ERROR("amdgpu: dma failed to lock ring %d (%d).\n", ring->idx, r); amdgpu_wb_free(adev, index); @@ -595,7 +581,7 @@ static int cik_sdma_ring_test_ring(struct amdgpu_ring *ring) amdgpu_ring_write(ring, upper_32_bits(gpu_addr)); amdgpu_ring_write(ring, 1); /* number of DWs to follow */ amdgpu_ring_write(ring, 0xDEADBEEF); - amdgpu_ring_unlock_commit(ring); + amdgpu_ring_commit(ring); for (i = 0; i < adev->usec_timeout; i++) { tmp = le32_to_cpu(adev->wb.wb[index]); @@ -645,7 +631,7 @@ static int cik_sdma_ring_test_ib(struct amdgpu_ring *ring) tmp = 0xCAFEDEAD; adev->wb.wb[index] = cpu_to_le32(tmp); memset(&ib, 0, sizeof(ib)); - r = amdgpu_ib_get(ring, NULL, 256, &ib); + r = amdgpu_ib_get(adev, NULL, 256, &ib); if (r) { DRM_ERROR("amdgpu: failed to get ib (%d).\n", r); goto err0; @@ -657,9 +643,7 @@ static int cik_sdma_ring_test_ib(struct amdgpu_ring *ring) ib.ptr[3] = 1; ib.ptr[4] = 0xDEADBEEF; ib.length_dw = 5; - r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, &ib, 1, NULL, - AMDGPU_FENCE_OWNER_UNDEFINED, - &f); + r = amdgpu_ib_schedule(ring, 1, &ib, NULL, &f); if (r) goto err1; @@ -685,7 +669,8 @@ static int cik_sdma_ring_test_ib(struct amdgpu_ring *ring) err1: fence_put(f); - amdgpu_ib_free(adev, &ib); + amdgpu_ib_free(adev, &ib, NULL); + fence_put(f); err0: amdgpu_wb_free(adev, index); return r; @@ -738,7 +723,7 @@ static void cik_sdma_vm_copy_pte(struct amdgpu_ib *ib, * Update PTEs by writing them manually using sDMA (CIK). */ static void cik_sdma_vm_write_pte(struct amdgpu_ib *ib, - uint64_t pe, + const dma_addr_t *pages_addr, uint64_t pe, uint64_t addr, unsigned count, uint32_t incr, uint32_t flags) { @@ -757,14 +742,7 @@ static void cik_sdma_vm_write_pte(struct amdgpu_ib *ib, ib->ptr[ib->length_dw++] = upper_32_bits(pe); ib->ptr[ib->length_dw++] = ndw; for (; ndw > 0; ndw -= 2, --count, pe += 8) { - if (flags & AMDGPU_PTE_SYSTEM) { - value = amdgpu_vm_map_gart(ib->ring->adev, addr); - value &= 0xFFFFFFFFFFFFF000ULL; - } else if (flags & AMDGPU_PTE_VALID) { - value = addr; - } else { - value = 0; - } + value = amdgpu_vm_map_gart(pages_addr, addr); addr += incr; value |= flags; ib->ptr[ib->length_dw++] = value; @@ -827,9 +805,9 @@ static void cik_sdma_vm_set_pte_pde(struct amdgpu_ib *ib, * @ib: indirect buffer to fill with padding * */ -static void cik_sdma_vm_pad_ib(struct amdgpu_ib *ib) +static void cik_sdma_ring_pad_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib) { - struct amdgpu_sdma_instance *sdma = amdgpu_get_sdma_instance(ib->ring); + struct amdgpu_sdma_instance *sdma = amdgpu_get_sdma_instance(ring); u32 pad_count; int i; @@ -844,6 +822,30 @@ static void cik_sdma_vm_pad_ib(struct amdgpu_ib *ib) SDMA_PACKET(SDMA_OPCODE_NOP, 0, 0); } +/** + * cik_sdma_ring_emit_pipeline_sync - sync the pipeline + * + * @ring: amdgpu_ring pointer + * + * Make sure all previous operations are completed (CIK). + */ +static void cik_sdma_ring_emit_pipeline_sync(struct amdgpu_ring *ring) +{ + uint32_t seq = ring->fence_drv.sync_seq; + uint64_t addr = ring->fence_drv.gpu_addr; + + /* wait for idle */ + amdgpu_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_POLL_REG_MEM, 0, + SDMA_POLL_REG_MEM_EXTRA_OP(0) | + SDMA_POLL_REG_MEM_EXTRA_FUNC(3) | /* equal */ + SDMA_POLL_REG_MEM_EXTRA_M)); + amdgpu_ring_write(ring, addr & 0xfffffffc); + amdgpu_ring_write(ring, upper_32_bits(addr) & 0xffffffff); + amdgpu_ring_write(ring, seq); /* reference */ + amdgpu_ring_write(ring, 0xfffffff); /* mask */ + amdgpu_ring_write(ring, (0xfff << 16) | 4); /* retry count, poll interval */ +} + /** * cik_sdma_ring_emit_vm_flush - cik vm flush using sDMA * @@ -1097,6 +1099,8 @@ static void cik_sdma_print_status(void *handle) i, RREG32(mmSDMA0_GFX_RB_BASE + sdma_offsets[i])); dev_info(adev->dev, " SDMA%d_GFX_RB_BASE_HI=0x%08X\n", i, RREG32(mmSDMA0_GFX_RB_BASE_HI + sdma_offsets[i])); + dev_info(adev->dev, " SDMA%d_TILING_CONFIG=0x%08X\n", + i, RREG32(mmSDMA0_TILING_CONFIG + sdma_offsets[i])); mutex_lock(&adev->srbm_mutex); for (j = 0; j < 16; j++) { cik_srbm_select(adev, 0, 0, 0, j); @@ -1297,12 +1301,14 @@ static const struct amdgpu_ring_funcs cik_sdma_ring_funcs = { .parse_cs = NULL, .emit_ib = cik_sdma_ring_emit_ib, .emit_fence = cik_sdma_ring_emit_fence, - .emit_semaphore = cik_sdma_ring_emit_semaphore, + .emit_pipeline_sync = cik_sdma_ring_emit_pipeline_sync, .emit_vm_flush = cik_sdma_ring_emit_vm_flush, .emit_hdp_flush = cik_sdma_ring_emit_hdp_flush, + .emit_hdp_invalidate = cik_sdma_ring_emit_hdp_invalidate, .test_ring = cik_sdma_ring_test_ring, .test_ib = cik_sdma_ring_test_ib, .insert_nop = cik_sdma_ring_insert_nop, + .pad_ib = cik_sdma_ring_pad_ib, }; static void cik_sdma_set_ring_funcs(struct amdgpu_device *adev) @@ -1399,14 +1405,18 @@ static const struct amdgpu_vm_pte_funcs cik_sdma_vm_pte_funcs = { .copy_pte = cik_sdma_vm_copy_pte, .write_pte = cik_sdma_vm_write_pte, .set_pte_pde = cik_sdma_vm_set_pte_pde, - .pad_ib = cik_sdma_vm_pad_ib, }; static void cik_sdma_set_vm_pte_funcs(struct amdgpu_device *adev) { + unsigned i; + if (adev->vm_manager.vm_pte_funcs == NULL) { adev->vm_manager.vm_pte_funcs = &cik_sdma_vm_pte_funcs; - adev->vm_manager.vm_pte_funcs_ring = &adev->sdma.instance[0].ring; - adev->vm_manager.vm_pte_funcs_ring->is_pte_ring = true; + for (i = 0; i < adev->sdma.num_instances; i++) + adev->vm_manager.vm_pte_rings[i] = + &adev->sdma.instance[i].ring; + + adev->vm_manager.vm_pte_num_rings = adev->sdma.num_instances; } } diff --git a/drivers/gpu/drm/amd/amdgpu/cikd.h b/drivers/gpu/drm/amd/amdgpu/cikd.h index 7f6d457f250a477cbfc9cb82b0efecd0207a0ea4..60d4493206dd11fef954d3a757a140d7ce1ab54d 100644 --- a/drivers/gpu/drm/amd/amdgpu/cikd.h +++ b/drivers/gpu/drm/amd/amdgpu/cikd.h @@ -46,9 +46,6 @@ #define BONAIRE_GB_ADDR_CONFIG_GOLDEN 0x12010001 #define HAWAII_GB_ADDR_CONFIG_GOLDEN 0x12011003 -#define CIK_RB_BITMAP_WIDTH_PER_SH 2 -#define HAWAII_RB_BITMAP_WIDTH_PER_SH 4 - #define AMDGPU_NUM_OF_VMIDS 8 #define PIPEID(x) ((x) << 0) diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c index 093599aba64b9e0ff0e0a4ba1f43e936903707fa..6de2ce535e370a149f18d82c006b6e1ef72a64b3 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c @@ -1668,6 +1668,9 @@ static void dce_v10_0_audio_fini(struct amdgpu_device *adev) { int i; + if (!amdgpu_audio) + return; + if (!adev->mode_info.audio.enabled) return; @@ -1973,7 +1976,7 @@ static void dce_v10_0_afmt_enable(struct drm_encoder *encoder, bool enable) enable ? "En" : "Dis", dig->afmt->offset, amdgpu_encoder->encoder_id); } -static void dce_v10_0_afmt_init(struct amdgpu_device *adev) +static int dce_v10_0_afmt_init(struct amdgpu_device *adev) { int i; @@ -1986,8 +1989,16 @@ static void dce_v10_0_afmt_init(struct amdgpu_device *adev) if (adev->mode_info.afmt[i]) { adev->mode_info.afmt[i]->offset = dig_offsets[i]; adev->mode_info.afmt[i]->id = i; + } else { + int j; + for (j = 0; j < i; j++) { + kfree(adev->mode_info.afmt[j]); + adev->mode_info.afmt[j] = NULL; + } + return -ENOMEM; } } + return 0; } static void dce_v10_0_afmt_fini(struct amdgpu_device *adev) @@ -2064,8 +2075,7 @@ static int dce_v10_0_crtc_do_set_base(struct drm_crtc *crtc, if (atomic) { amdgpu_fb = to_amdgpu_framebuffer(fb); target_fb = fb; - } - else { + } else { amdgpu_fb = to_amdgpu_framebuffer(crtc->primary->fb); target_fb = crtc->primary->fb; } @@ -2079,9 +2089,9 @@ static int dce_v10_0_crtc_do_set_base(struct drm_crtc *crtc, if (unlikely(r != 0)) return r; - if (atomic) + if (atomic) { fb_location = amdgpu_bo_gpu_offset(rbo); - else { + } else { r = amdgpu_bo_pin(rbo, AMDGPU_GEM_DOMAIN_VRAM, &fb_location); if (unlikely(r != 0)) { amdgpu_bo_unreserve(rbo); @@ -2670,7 +2680,6 @@ static void dce_v10_0_crtc_destroy(struct drm_crtc *crtc) struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); drm_crtc_cleanup(crtc); - destroy_workqueue(amdgpu_crtc->pflip_queue); kfree(amdgpu_crtc); } @@ -2701,13 +2710,13 @@ static void dce_v10_0_crtc_dpms(struct drm_crtc *crtc, int mode) type = amdgpu_crtc_idx_to_irq_type(adev, amdgpu_crtc->crtc_id); amdgpu_irq_update(adev, &adev->crtc_irq, type); amdgpu_irq_update(adev, &adev->pageflip_irq, type); - drm_vblank_post_modeset(dev, amdgpu_crtc->crtc_id); + drm_vblank_on(dev, amdgpu_crtc->crtc_id); dce_v10_0_crtc_load_lut(crtc); break; case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_OFF: - drm_vblank_pre_modeset(dev, amdgpu_crtc->crtc_id); + drm_vblank_off(dev, amdgpu_crtc->crtc_id); if (amdgpu_crtc->enabled) { dce_v10_0_vga_enable(crtc, true); amdgpu_atombios_crtc_blank(crtc, ATOM_ENABLE); @@ -2890,7 +2899,6 @@ static int dce_v10_0_crtc_init(struct amdgpu_device *adev, int index) drm_mode_crtc_set_gamma_size(&amdgpu_crtc->base, 256); amdgpu_crtc->crtc_id = index; - amdgpu_crtc->pflip_queue = create_singlethread_workqueue("amdgpu-pageflip-queue"); adev->mode_info.crtcs[index] = amdgpu_crtc; amdgpu_crtc->max_cursor_width = 128; @@ -2982,8 +2990,6 @@ static int dce_v10_0_sw_init(void *handle) if (r) return r; - adev->mode_info.mode_config_initialized = true; - adev->ddev->mode_config.funcs = &amdgpu_mode_funcs; adev->ddev->mode_config.max_width = 16384; @@ -3014,7 +3020,9 @@ static int dce_v10_0_sw_init(void *handle) return -EINVAL; /* setup afmt */ - dce_v10_0_afmt_init(adev); + r = dce_v10_0_afmt_init(adev); + if (r) + return r; r = dce_v10_0_audio_init(adev); if (r) @@ -3022,7 +3030,8 @@ static int dce_v10_0_sw_init(void *handle) drm_kms_helper_poll_init(adev->ddev); - return r; + adev->mode_info.mode_config_initialized = true; + return 0; } static int dce_v10_0_sw_fini(void *handle) @@ -3366,7 +3375,7 @@ static int dce_v10_0_pageflip_irq(struct amdgpu_device *adev, spin_unlock_irqrestore(&adev->ddev->event_lock, flags); drm_vblank_put(adev->ddev, amdgpu_crtc->crtc_id); - queue_work(amdgpu_crtc->pflip_queue, &works->unpin_work); + schedule_work(&works->unpin_work); return 0; } @@ -3624,16 +3633,8 @@ dce_v10_0_ext_dpms(struct drm_encoder *encoder, int mode) } -static bool dce_v10_0_ext_mode_fixup(struct drm_encoder *encoder, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - return true; -} - static const struct drm_encoder_helper_funcs dce_v10_0_ext_helper_funcs = { .dpms = dce_v10_0_ext_dpms, - .mode_fixup = dce_v10_0_ext_mode_fixup, .prepare = dce_v10_0_ext_prepare, .mode_set = dce_v10_0_ext_mode_set, .commit = dce_v10_0_ext_commit, diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c index 8e67249d4367d1aff0737c8ea3b48369b8019bc4..e9ccc6b787f3e3071c244aa8caeb69745c3c7733 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c @@ -1658,6 +1658,9 @@ static void dce_v11_0_audio_fini(struct amdgpu_device *adev) { int i; + if (!amdgpu_audio) + return; + if (!adev->mode_info.audio.enabled) return; @@ -1963,7 +1966,7 @@ static void dce_v11_0_afmt_enable(struct drm_encoder *encoder, bool enable) enable ? "En" : "Dis", dig->afmt->offset, amdgpu_encoder->encoder_id); } -static void dce_v11_0_afmt_init(struct amdgpu_device *adev) +static int dce_v11_0_afmt_init(struct amdgpu_device *adev) { int i; @@ -1976,8 +1979,16 @@ static void dce_v11_0_afmt_init(struct amdgpu_device *adev) if (adev->mode_info.afmt[i]) { adev->mode_info.afmt[i]->offset = dig_offsets[i]; adev->mode_info.afmt[i]->id = i; + } else { + int j; + for (j = 0; j < i; j++) { + kfree(adev->mode_info.afmt[j]); + adev->mode_info.afmt[j] = NULL; + } + return -ENOMEM; } } + return 0; } static void dce_v11_0_afmt_fini(struct amdgpu_device *adev) @@ -2054,8 +2065,7 @@ static int dce_v11_0_crtc_do_set_base(struct drm_crtc *crtc, if (atomic) { amdgpu_fb = to_amdgpu_framebuffer(fb); target_fb = fb; - } - else { + } else { amdgpu_fb = to_amdgpu_framebuffer(crtc->primary->fb); target_fb = crtc->primary->fb; } @@ -2069,9 +2079,9 @@ static int dce_v11_0_crtc_do_set_base(struct drm_crtc *crtc, if (unlikely(r != 0)) return r; - if (atomic) + if (atomic) { fb_location = amdgpu_bo_gpu_offset(rbo); - else { + } else { r = amdgpu_bo_pin(rbo, AMDGPU_GEM_DOMAIN_VRAM, &fb_location); if (unlikely(r != 0)) { amdgpu_bo_unreserve(rbo); @@ -2661,7 +2671,6 @@ static void dce_v11_0_crtc_destroy(struct drm_crtc *crtc) struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); drm_crtc_cleanup(crtc); - destroy_workqueue(amdgpu_crtc->pflip_queue); kfree(amdgpu_crtc); } @@ -2692,13 +2701,13 @@ static void dce_v11_0_crtc_dpms(struct drm_crtc *crtc, int mode) type = amdgpu_crtc_idx_to_irq_type(adev, amdgpu_crtc->crtc_id); amdgpu_irq_update(adev, &adev->crtc_irq, type); amdgpu_irq_update(adev, &adev->pageflip_irq, type); - drm_vblank_post_modeset(dev, amdgpu_crtc->crtc_id); + drm_vblank_on(dev, amdgpu_crtc->crtc_id); dce_v11_0_crtc_load_lut(crtc); break; case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_OFF: - drm_vblank_pre_modeset(dev, amdgpu_crtc->crtc_id); + drm_vblank_off(dev, amdgpu_crtc->crtc_id); if (amdgpu_crtc->enabled) { dce_v11_0_vga_enable(crtc, true); amdgpu_atombios_crtc_blank(crtc, ATOM_ENABLE); @@ -2881,7 +2890,6 @@ static int dce_v11_0_crtc_init(struct amdgpu_device *adev, int index) drm_mode_crtc_set_gamma_size(&amdgpu_crtc->base, 256); amdgpu_crtc->crtc_id = index; - amdgpu_crtc->pflip_queue = create_singlethread_workqueue("amdgpu-pageflip-queue"); adev->mode_info.crtcs[index] = amdgpu_crtc; amdgpu_crtc->max_cursor_width = 128; @@ -2963,7 +2971,7 @@ static int dce_v11_0_sw_init(void *handle) for (i = 0; i < adev->mode_info.num_crtc; i++) { r = amdgpu_irq_add_id(adev, i + 1, &adev->crtc_irq); if (r) - return r; + return r; } for (i = 8; i < 20; i += 2) { @@ -2975,9 +2983,7 @@ static int dce_v11_0_sw_init(void *handle) /* HPD hotplug */ r = amdgpu_irq_add_id(adev, 42, &adev->hpd_irq); if (r) - return r; - - adev->mode_info.mode_config_initialized = true; + return r; adev->ddev->mode_config.funcs = &amdgpu_mode_funcs; @@ -2996,6 +3002,7 @@ static int dce_v11_0_sw_init(void *handle) adev->ddev->mode_config.max_width = 16384; adev->ddev->mode_config.max_height = 16384; + /* allocate crtcs */ for (i = 0; i < adev->mode_info.num_crtc; i++) { r = dce_v11_0_crtc_init(adev, i); @@ -3009,7 +3016,9 @@ static int dce_v11_0_sw_init(void *handle) return -EINVAL; /* setup afmt */ - dce_v11_0_afmt_init(adev); + r = dce_v11_0_afmt_init(adev); + if (r) + return r; r = dce_v11_0_audio_init(adev); if (r) @@ -3017,7 +3026,8 @@ static int dce_v11_0_sw_init(void *handle) drm_kms_helper_poll_init(adev->ddev); - return r; + adev->mode_info.mode_config_initialized = true; + return 0; } static int dce_v11_0_sw_fini(void *handle) @@ -3361,7 +3371,7 @@ static int dce_v11_0_pageflip_irq(struct amdgpu_device *adev, spin_unlock_irqrestore(&adev->ddev->event_lock, flags); drm_vblank_put(adev->ddev, amdgpu_crtc->crtc_id); - queue_work(amdgpu_crtc->pflip_queue, &works->unpin_work); + schedule_work(&works->unpin_work); return 0; } @@ -3619,16 +3629,8 @@ dce_v11_0_ext_dpms(struct drm_encoder *encoder, int mode) } -static bool dce_v11_0_ext_mode_fixup(struct drm_encoder *encoder, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - return true; -} - static const struct drm_encoder_helper_funcs dce_v11_0_ext_helper_funcs = { .dpms = dce_v11_0_ext_dpms, - .mode_fixup = dce_v11_0_ext_mode_fixup, .prepare = dce_v11_0_ext_prepare, .mode_set = dce_v11_0_ext_mode_set, .commit = dce_v11_0_ext_commit, diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c index d0e128c248134e8a6fb9c9e4311e52bd7af0aceb..e56b55d8c280202a8f65f5fa55edaa489c19ead3 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c @@ -1639,6 +1639,9 @@ static void dce_v8_0_audio_fini(struct amdgpu_device *adev) { int i; + if (!amdgpu_audio) + return; + if (!adev->mode_info.audio.enabled) return; @@ -1910,7 +1913,7 @@ static void dce_v8_0_afmt_enable(struct drm_encoder *encoder, bool enable) enable ? "En" : "Dis", dig->afmt->offset, amdgpu_encoder->encoder_id); } -static void dce_v8_0_afmt_init(struct amdgpu_device *adev) +static int dce_v8_0_afmt_init(struct amdgpu_device *adev) { int i; @@ -1923,8 +1926,16 @@ static void dce_v8_0_afmt_init(struct amdgpu_device *adev) if (adev->mode_info.afmt[i]) { adev->mode_info.afmt[i]->offset = dig_offsets[i]; adev->mode_info.afmt[i]->id = i; + } else { + int j; + for (j = 0; j < i; j++) { + kfree(adev->mode_info.afmt[j]); + adev->mode_info.afmt[j] = NULL; + } + return -ENOMEM; } } + return 0; } static void dce_v8_0_afmt_fini(struct amdgpu_device *adev) @@ -2001,8 +2012,7 @@ static int dce_v8_0_crtc_do_set_base(struct drm_crtc *crtc, if (atomic) { amdgpu_fb = to_amdgpu_framebuffer(fb); target_fb = fb; - } - else { + } else { amdgpu_fb = to_amdgpu_framebuffer(crtc->primary->fb); target_fb = crtc->primary->fb; } @@ -2016,9 +2026,9 @@ static int dce_v8_0_crtc_do_set_base(struct drm_crtc *crtc, if (unlikely(r != 0)) return r; - if (atomic) + if (atomic) { fb_location = amdgpu_bo_gpu_offset(rbo); - else { + } else { r = amdgpu_bo_pin(rbo, AMDGPU_GEM_DOMAIN_VRAM, &fb_location); if (unlikely(r != 0)) { amdgpu_bo_unreserve(rbo); @@ -2582,7 +2592,6 @@ static void dce_v8_0_crtc_destroy(struct drm_crtc *crtc) struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); drm_crtc_cleanup(crtc); - destroy_workqueue(amdgpu_crtc->pflip_queue); kfree(amdgpu_crtc); } @@ -2613,13 +2622,13 @@ static void dce_v8_0_crtc_dpms(struct drm_crtc *crtc, int mode) type = amdgpu_crtc_idx_to_irq_type(adev, amdgpu_crtc->crtc_id); amdgpu_irq_update(adev, &adev->crtc_irq, type); amdgpu_irq_update(adev, &adev->pageflip_irq, type); - drm_vblank_post_modeset(dev, amdgpu_crtc->crtc_id); + drm_vblank_on(dev, amdgpu_crtc->crtc_id); dce_v8_0_crtc_load_lut(crtc); break; case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_OFF: - drm_vblank_pre_modeset(dev, amdgpu_crtc->crtc_id); + drm_vblank_off(dev, amdgpu_crtc->crtc_id); if (amdgpu_crtc->enabled) { dce_v8_0_vga_enable(crtc, true); amdgpu_atombios_crtc_blank(crtc, ATOM_ENABLE); @@ -2809,7 +2818,6 @@ static int dce_v8_0_crtc_init(struct amdgpu_device *adev, int index) drm_mode_crtc_set_gamma_size(&amdgpu_crtc->base, 256); amdgpu_crtc->crtc_id = index; - amdgpu_crtc->pflip_queue = create_singlethread_workqueue("amdgpu-pageflip-queue"); adev->mode_info.crtcs[index] = amdgpu_crtc; amdgpu_crtc->max_cursor_width = CIK_CURSOR_WIDTH; @@ -2892,8 +2900,6 @@ static int dce_v8_0_sw_init(void *handle) if (r) return r; - adev->mode_info.mode_config_initialized = true; - adev->ddev->mode_config.funcs = &amdgpu_mode_funcs; adev->ddev->mode_config.max_width = 16384; @@ -2924,7 +2930,9 @@ static int dce_v8_0_sw_init(void *handle) return -EINVAL; /* setup afmt */ - dce_v8_0_afmt_init(adev); + r = dce_v8_0_afmt_init(adev); + if (r) + return r; r = dce_v8_0_audio_init(adev); if (r) @@ -2932,7 +2940,8 @@ static int dce_v8_0_sw_init(void *handle) drm_kms_helper_poll_init(adev->ddev); - return r; + adev->mode_info.mode_config_initialized = true; + return 0; } static int dce_v8_0_sw_fini(void *handle) @@ -3375,7 +3384,7 @@ static int dce_v8_0_pageflip_irq(struct amdgpu_device *adev, spin_unlock_irqrestore(&adev->ddev->event_lock, flags); drm_vblank_put(adev->ddev, amdgpu_crtc->crtc_id); - queue_work(amdgpu_crtc->pflip_queue, &works->unpin_work); + schedule_work(&works->unpin_work); return 0; } @@ -3554,16 +3563,8 @@ dce_v8_0_ext_dpms(struct drm_encoder *encoder, int mode) } -static bool dce_v8_0_ext_mode_fixup(struct drm_encoder *encoder, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - return true; -} - static const struct drm_encoder_helper_funcs dce_v8_0_ext_helper_funcs = { .dpms = dce_v8_0_ext_dpms, - .mode_fixup = dce_v8_0_ext_mode_fixup, .prepare = dce_v8_0_ext_prepare, .mode_set = dce_v8_0_ext_mode_set, .commit = dce_v8_0_ext_commit, diff --git a/drivers/gpu/drm/amd/amdgpu/fiji_smc.c b/drivers/gpu/drm/amd/amdgpu/fiji_smc.c index e35340afd3db1afec984e4bfb4ca7e4ba04d666c..b336c918d6a7984fcb8bb6060bb2339ebb78e636 100644 --- a/drivers/gpu/drm/amd/amdgpu/fiji_smc.c +++ b/drivers/gpu/drm/amd/amdgpu/fiji_smc.c @@ -272,6 +272,12 @@ static int fiji_smu_upload_firmware_image(struct amdgpu_device *adev) if (!adev->pm.fw) return -EINVAL; + /* Skip SMC ucode loading on SR-IOV capable boards. + * vbios does this for us in asic_init in that case. + */ + if (adev->virtualization.supports_sr_iov) + return 0; + hdr = (const struct smc_firmware_header_v1_0 *)adev->pm.fw->data; amdgpu_ucode_print_smc_hdr(&hdr->header); diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c index 06602df707f86375d8db781db550d6db160e06e0..bb8709066fd8707338663b119f4c7c62f8662716 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c @@ -31,8 +31,6 @@ #include "amdgpu_ucode.h" #include "clearstate_ci.h" -#include "uvd/uvd_4_2_d.h" - #include "dce/dce_8_0_d.h" #include "dce/dce_8_0_sh_mask.h" @@ -1006,9 +1004,15 @@ static int gfx_v7_0_init_microcode(struct amdgpu_device *adev) */ static void gfx_v7_0_tiling_mode_table_init(struct amdgpu_device *adev) { - const u32 num_tile_mode_states = 32; - const u32 num_secondary_tile_mode_states = 16; - u32 reg_offset, gb_tile_moden, split_equal_to_row_size; + const u32 num_tile_mode_states = + ARRAY_SIZE(adev->gfx.config.tile_mode_array); + const u32 num_secondary_tile_mode_states = + ARRAY_SIZE(adev->gfx.config.macrotile_mode_array); + u32 reg_offset, split_equal_to_row_size; + uint32_t *tile, *macrotile; + + tile = adev->gfx.config.tile_mode_array; + macrotile = adev->gfx.config.macrotile_mode_array; switch (adev->gfx.config.mem_row_size_in_kb) { case 1: @@ -1023,832 +1027,531 @@ static void gfx_v7_0_tiling_mode_table_init(struct amdgpu_device *adev) break; } + for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) + tile[reg_offset] = 0; + for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++) + macrotile[reg_offset] = 0; + switch (adev->asic_type) { case CHIP_BONAIRE: - for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) { - switch (reg_offset) { - case 0: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 1: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 2: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 3: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 4: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | - TILE_SPLIT(split_equal_to_row_size)); - break; - case 5: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 6: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | - TILE_SPLIT(split_equal_to_row_size)); - break; - case 7: - gb_tile_moden = (TILE_SPLIT(split_equal_to_row_size)); - break; - - case 8: - gb_tile_moden = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) | - PIPE_CONFIG(ADDR_SURF_P4_16x16)); - break; - case 9: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING)); - break; - case 10: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 11: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); - break; - case 12: - gb_tile_moden = (TILE_SPLIT(split_equal_to_row_size)); - break; - case 13: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING)); - break; - case 14: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 15: - gb_tile_moden = (ARRAY_MODE(ARRAY_3D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 16: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); - break; - case 17: - gb_tile_moden = (TILE_SPLIT(split_equal_to_row_size)); - break; - case 18: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 19: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING)); - break; - case 20: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 21: - gb_tile_moden = (ARRAY_MODE(ARRAY_3D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 22: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 23: - gb_tile_moden = (TILE_SPLIT(split_equal_to_row_size)); - break; - case 24: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 25: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_XTHICK) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 26: - gb_tile_moden = (ARRAY_MODE(ARRAY_3D_TILED_XTHICK) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 27: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING)); - break; - case 28: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 29: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); - break; - case 30: - gb_tile_moden = (TILE_SPLIT(split_equal_to_row_size)); - break; - default: - gb_tile_moden = 0; - break; - } - adev->gfx.config.tile_mode_array[reg_offset] = gb_tile_moden; - WREG32(mmGB_TILE_MODE0 + reg_offset, gb_tile_moden); - } - for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++) { - switch (reg_offset) { - case 0: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 1: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 2: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 3: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 4: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 5: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 6: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | - NUM_BANKS(ADDR_SURF_4_BANK)); - break; - case 8: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_8) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 9: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 10: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 11: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 12: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 13: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 14: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | - NUM_BANKS(ADDR_SURF_4_BANK)); - break; - default: - gb_tile_moden = 0; - break; - } - adev->gfx.config.macrotile_mode_array[reg_offset] = gb_tile_moden; - WREG32(mmGB_MACROTILE_MODE0 + reg_offset, gb_tile_moden); - } + tile[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + tile[1] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + tile[2] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + tile[3] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + tile[4] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | + TILE_SPLIT(split_equal_to_row_size)); + tile[5] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + tile[6] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | + TILE_SPLIT(split_equal_to_row_size)); + tile[7] = (TILE_SPLIT(split_equal_to_row_size)); + tile[8] = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) | + PIPE_CONFIG(ADDR_SURF_P4_16x16)); + tile[9] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING)); + tile[10] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + tile[11] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); + tile[12] = (TILE_SPLIT(split_equal_to_row_size)); + tile[13] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING)); + tile[14] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + tile[15] = (ARRAY_MODE(ARRAY_3D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + tile[16] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); + tile[17] = (TILE_SPLIT(split_equal_to_row_size)); + tile[18] = (ARRAY_MODE(ARRAY_1D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + tile[19] = (ARRAY_MODE(ARRAY_1D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING)); + tile[20] = (ARRAY_MODE(ARRAY_2D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + tile[21] = (ARRAY_MODE(ARRAY_3D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + tile[22] = (ARRAY_MODE(ARRAY_PRT_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + tile[23] = (TILE_SPLIT(split_equal_to_row_size)); + tile[24] = (ARRAY_MODE(ARRAY_2D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + tile[25] = (ARRAY_MODE(ARRAY_2D_TILED_XTHICK) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + tile[26] = (ARRAY_MODE(ARRAY_3D_TILED_XTHICK) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + tile[27] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING)); + tile[28] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + tile[29] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); + tile[30] = (TILE_SPLIT(split_equal_to_row_size)); + + macrotile[0] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + macrotile[1] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + macrotile[2] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_16_BANK)); + macrotile[3] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_16_BANK)); + macrotile[4] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_16_BANK)); + macrotile[5] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + macrotile[6] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_4_BANK)); + macrotile[8] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_8) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + macrotile[9] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + macrotile[10] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + macrotile[11] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + macrotile[12] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_16_BANK)); + macrotile[13] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + macrotile[14] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_4_BANK)); + + for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) + WREG32(mmGB_TILE_MODE0 + reg_offset, tile[reg_offset]); + for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++) + if (reg_offset != 7) + WREG32(mmGB_MACROTILE_MODE0 + reg_offset, macrotile[reg_offset]); break; case CHIP_HAWAII: - for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) { - switch (reg_offset) { - case 0: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 1: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 2: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 3: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 4: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | - TILE_SPLIT(split_equal_to_row_size)); - break; - case 5: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | - TILE_SPLIT(split_equal_to_row_size)); - break; - case 6: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | - TILE_SPLIT(split_equal_to_row_size)); - break; - case 7: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | - TILE_SPLIT(split_equal_to_row_size)); - break; - - case 8: - gb_tile_moden = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) | - PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16)); - break; - case 9: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING)); - break; - case 10: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 11: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); - break; - case 12: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); - break; - case 13: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING)); - break; - case 14: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 15: - gb_tile_moden = (ARRAY_MODE(ARRAY_3D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 16: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); - break; - case 17: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); - break; - case 18: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 19: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING)); - break; - case 20: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 21: - gb_tile_moden = (ARRAY_MODE(ARRAY_3D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 22: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 23: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 24: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 25: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_XTHICK) | - PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 26: - gb_tile_moden = (ARRAY_MODE(ARRAY_3D_TILED_XTHICK) | - PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 27: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING)); - break; - case 28: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 29: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); - break; - case 30: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P4_16x16) | - MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); - break; - default: - gb_tile_moden = 0; - break; - } - adev->gfx.config.tile_mode_array[reg_offset] = gb_tile_moden; - WREG32(mmGB_TILE_MODE0 + reg_offset, gb_tile_moden); - } - for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++) { - switch (reg_offset) { - case 0: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 1: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 2: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 3: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 4: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 5: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | - NUM_BANKS(ADDR_SURF_4_BANK)); - break; - case 6: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | - NUM_BANKS(ADDR_SURF_4_BANK)); - break; - case 8: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 9: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 10: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 11: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 12: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 13: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 14: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | - NUM_BANKS(ADDR_SURF_4_BANK)); - break; - default: - gb_tile_moden = 0; - break; - } - adev->gfx.config.macrotile_mode_array[reg_offset] = gb_tile_moden; - WREG32(mmGB_MACROTILE_MODE0 + reg_offset, gb_tile_moden); - } + tile[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + tile[1] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + tile[2] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + tile[3] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + tile[4] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | + TILE_SPLIT(split_equal_to_row_size)); + tile[5] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | + TILE_SPLIT(split_equal_to_row_size)); + tile[6] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | + TILE_SPLIT(split_equal_to_row_size)); + tile[7] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | + TILE_SPLIT(split_equal_to_row_size)); + tile[8] = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16)); + tile[9] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING)); + tile[10] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + tile[11] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); + tile[12] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); + tile[13] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING)); + tile[14] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + tile[15] = (ARRAY_MODE(ARRAY_3D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + tile[16] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); + tile[17] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); + tile[18] = (ARRAY_MODE(ARRAY_1D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + tile[19] = (ARRAY_MODE(ARRAY_1D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING)); + tile[20] = (ARRAY_MODE(ARRAY_2D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + tile[21] = (ARRAY_MODE(ARRAY_3D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + tile[22] = (ARRAY_MODE(ARRAY_PRT_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + tile[23] = (ARRAY_MODE(ARRAY_PRT_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + tile[24] = (ARRAY_MODE(ARRAY_2D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + tile[25] = (ARRAY_MODE(ARRAY_2D_TILED_XTHICK) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + tile[26] = (ARRAY_MODE(ARRAY_3D_TILED_XTHICK) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + tile[27] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING)); + tile[28] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + tile[29] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); + tile[30] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P4_16x16) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); + + macrotile[0] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_16_BANK)); + macrotile[1] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_16_BANK)); + macrotile[2] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_16_BANK)); + macrotile[3] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_16_BANK)); + macrotile[4] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_8_BANK)); + macrotile[5] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_4_BANK)); + macrotile[6] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_4_BANK)); + macrotile[8] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_16_BANK)); + macrotile[9] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_16_BANK)); + macrotile[10] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_16_BANK)); + macrotile[11] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_8_BANK)); + macrotile[12] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_16_BANK)); + macrotile[13] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + macrotile[14] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | + NUM_BANKS(ADDR_SURF_4_BANK)); + + for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) + WREG32(mmGB_TILE_MODE0 + reg_offset, tile[reg_offset]); + for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++) + if (reg_offset != 7) + WREG32(mmGB_MACROTILE_MODE0 + reg_offset, macrotile[reg_offset]); break; case CHIP_KABINI: case CHIP_KAVERI: case CHIP_MULLINS: default: - for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) { - switch (reg_offset) { - case 0: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 1: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 2: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 3: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 4: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | - TILE_SPLIT(split_equal_to_row_size)); - break; - case 5: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); - break; - case 6: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | - TILE_SPLIT(split_equal_to_row_size)); - break; - case 7: - gb_tile_moden = (TILE_SPLIT(split_equal_to_row_size)); - break; - - case 8: - gb_tile_moden = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) | - PIPE_CONFIG(ADDR_SURF_P2)); - break; - case 9: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING)); - break; - case 10: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 11: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); - break; - case 12: - gb_tile_moden = (TILE_SPLIT(split_equal_to_row_size)); - break; - case 13: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING)); - break; - case 14: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 15: - gb_tile_moden = (ARRAY_MODE(ARRAY_3D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 16: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); - break; - case 17: - gb_tile_moden = (TILE_SPLIT(split_equal_to_row_size)); - break; - case 18: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 19: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING)); - break; - case 20: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 21: - gb_tile_moden = (ARRAY_MODE(ARRAY_3D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 22: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 23: - gb_tile_moden = (TILE_SPLIT(split_equal_to_row_size)); - break; - case 24: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THICK) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 25: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_XTHICK) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 26: - gb_tile_moden = (ARRAY_MODE(ARRAY_3D_TILED_XTHICK) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); - break; - case 27: - gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING)); - break; - case 28: - gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); - break; - case 29: - gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | - PIPE_CONFIG(ADDR_SURF_P2) | - MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | - SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); - break; - case 30: - gb_tile_moden = (TILE_SPLIT(split_equal_to_row_size)); - break; - default: - gb_tile_moden = 0; - break; - } - adev->gfx.config.tile_mode_array[reg_offset] = gb_tile_moden; - WREG32(mmGB_TILE_MODE0 + reg_offset, gb_tile_moden); - } - for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++) { - switch (reg_offset) { - case 0: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 1: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 2: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 3: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 4: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 5: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 6: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - case 8: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_4) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_8) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 9: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_4) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 10: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 11: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 12: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 13: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | - NUM_BANKS(ADDR_SURF_16_BANK)); - break; - case 14: - gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | - BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | - MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | - NUM_BANKS(ADDR_SURF_8_BANK)); - break; - default: - gb_tile_moden = 0; - break; - } - adev->gfx.config.macrotile_mode_array[reg_offset] = gb_tile_moden; - WREG32(mmGB_MACROTILE_MODE0 + reg_offset, gb_tile_moden); - } + tile[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + tile[1] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + tile[2] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + tile[3] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + tile[4] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | + TILE_SPLIT(split_equal_to_row_size)); + tile[5] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); + tile[6] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | + TILE_SPLIT(split_equal_to_row_size)); + tile[7] = (TILE_SPLIT(split_equal_to_row_size)); + tile[8] = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) | + PIPE_CONFIG(ADDR_SURF_P2)); + tile[9] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING)); + tile[10] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + tile[11] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); + tile[12] = (TILE_SPLIT(split_equal_to_row_size)); + tile[13] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING)); + tile[14] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + tile[15] = (ARRAY_MODE(ARRAY_3D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + tile[16] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); + tile[17] = (TILE_SPLIT(split_equal_to_row_size)); + tile[18] = (ARRAY_MODE(ARRAY_1D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + tile[19] = (ARRAY_MODE(ARRAY_1D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING)); + tile[20] = (ARRAY_MODE(ARRAY_2D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + tile[21] = (ARRAY_MODE(ARRAY_3D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + tile[22] = (ARRAY_MODE(ARRAY_PRT_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + tile[23] = (TILE_SPLIT(split_equal_to_row_size)); + tile[24] = (ARRAY_MODE(ARRAY_2D_TILED_THICK) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + tile[25] = (ARRAY_MODE(ARRAY_2D_TILED_XTHICK) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + tile[26] = (ARRAY_MODE(ARRAY_3D_TILED_XTHICK) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_THICK_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_1)); + tile[27] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING)); + tile[28] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); + tile[29] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | + PIPE_CONFIG(ADDR_SURF_P2) | + MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | + SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_8)); + tile[30] = (TILE_SPLIT(split_equal_to_row_size)); + + macrotile[0] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_8_BANK)); + macrotile[1] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_8_BANK)); + macrotile[2] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + macrotile[3] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + macrotile[4] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + macrotile[5] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + macrotile[6] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + macrotile[8] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_4) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_8) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + macrotile[9] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_4) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + macrotile[10] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + macrotile[11] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + macrotile[12] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + macrotile[13] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | + NUM_BANKS(ADDR_SURF_16_BANK)); + macrotile[14] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | + BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | + MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | + NUM_BANKS(ADDR_SURF_8_BANK)); + + for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) + WREG32(mmGB_TILE_MODE0 + reg_offset, tile[reg_offset]); + for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++) + if (reg_offset != 7) + WREG32(mmGB_MACROTILE_MODE0 + reg_offset, macrotile[reg_offset]); break; } } @@ -1893,45 +1596,31 @@ void gfx_v7_0_select_se_sh(struct amdgpu_device *adev, u32 se_num, u32 sh_num) */ static u32 gfx_v7_0_create_bitmask(u32 bit_width) { - u32 i, mask = 0; - - for (i = 0; i < bit_width; i++) { - mask <<= 1; - mask |= 1; - } - return mask; + return (u32)((1ULL << bit_width) - 1); } /** - * gfx_v7_0_get_rb_disabled - computes the mask of disabled RBs + * gfx_v7_0_get_rb_active_bitmap - computes the mask of enabled RBs * * @adev: amdgpu_device pointer - * @max_rb_num: max RBs (render backends) for the asic - * @se_num: number of SEs (shader engines) for the asic - * @sh_per_se: number of SH blocks per SE for the asic * - * Calculates the bitmask of disabled RBs (CIK). - * Returns the disabled RB bitmask. + * Calculates the bitmask of enabled RBs (CIK). + * Returns the enabled RB bitmask. */ -static u32 gfx_v7_0_get_rb_disabled(struct amdgpu_device *adev, - u32 max_rb_num_per_se, - u32 sh_per_se) +static u32 gfx_v7_0_get_rb_active_bitmap(struct amdgpu_device *adev) { u32 data, mask; data = RREG32(mmCC_RB_BACKEND_DISABLE); - if (data & 1) - data &= CC_RB_BACKEND_DISABLE__BACKEND_DISABLE_MASK; - else - data = 0; - data |= RREG32(mmGC_USER_RB_BACKEND_DISABLE); + data &= CC_RB_BACKEND_DISABLE__BACKEND_DISABLE_MASK; data >>= GC_USER_RB_BACKEND_DISABLE__BACKEND_DISABLE__SHIFT; - mask = gfx_v7_0_create_bitmask(max_rb_num_per_se / sh_per_se); + mask = gfx_v7_0_create_bitmask(adev->gfx.config.max_backends_per_se / + adev->gfx.config.max_sh_per_se); - return data & mask; + return (~data) & mask; } /** @@ -1940,73 +1629,31 @@ static u32 gfx_v7_0_get_rb_disabled(struct amdgpu_device *adev, * @adev: amdgpu_device pointer * @se_num: number of SEs (shader engines) for the asic * @sh_per_se: number of SH blocks per SE for the asic - * @max_rb_num: max RBs (render backends) for the asic * * Configures per-SE/SH RB registers (CIK). */ -static void gfx_v7_0_setup_rb(struct amdgpu_device *adev, - u32 se_num, u32 sh_per_se, - u32 max_rb_num_per_se) +static void gfx_v7_0_setup_rb(struct amdgpu_device *adev) { int i, j; - u32 data, mask; - u32 disabled_rbs = 0; - u32 enabled_rbs = 0; + u32 data; + u32 active_rbs = 0; + u32 rb_bitmap_width_per_sh = adev->gfx.config.max_backends_per_se / + adev->gfx.config.max_sh_per_se; mutex_lock(&adev->grbm_idx_mutex); - for (i = 0; i < se_num; i++) { - for (j = 0; j < sh_per_se; j++) { + for (i = 0; i < adev->gfx.config.max_shader_engines; i++) { + for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) { gfx_v7_0_select_se_sh(adev, i, j); - data = gfx_v7_0_get_rb_disabled(adev, max_rb_num_per_se, sh_per_se); - if (adev->asic_type == CHIP_HAWAII) - disabled_rbs |= data << ((i * sh_per_se + j) * HAWAII_RB_BITMAP_WIDTH_PER_SH); - else - disabled_rbs |= data << ((i * sh_per_se + j) * CIK_RB_BITMAP_WIDTH_PER_SH); + data = gfx_v7_0_get_rb_active_bitmap(adev); + active_rbs |= data << ((i * adev->gfx.config.max_sh_per_se + j) * + rb_bitmap_width_per_sh); } } gfx_v7_0_select_se_sh(adev, 0xffffffff, 0xffffffff); mutex_unlock(&adev->grbm_idx_mutex); - mask = 1; - for (i = 0; i < max_rb_num_per_se * se_num; i++) { - if (!(disabled_rbs & mask)) - enabled_rbs |= mask; - mask <<= 1; - } - - adev->gfx.config.backend_enable_mask = enabled_rbs; - - mutex_lock(&adev->grbm_idx_mutex); - for (i = 0; i < se_num; i++) { - gfx_v7_0_select_se_sh(adev, i, 0xffffffff); - data = 0; - for (j = 0; j < sh_per_se; j++) { - switch (enabled_rbs & 3) { - case 0: - if (j == 0) - data |= (RASTER_CONFIG_RB_MAP_3 << - PA_SC_RASTER_CONFIG__PKR_MAP__SHIFT); - else - data |= (RASTER_CONFIG_RB_MAP_0 << - PA_SC_RASTER_CONFIG__PKR_MAP__SHIFT); - break; - case 1: - data |= (RASTER_CONFIG_RB_MAP_0 << (i * sh_per_se + j) * 2); - break; - case 2: - data |= (RASTER_CONFIG_RB_MAP_3 << (i * sh_per_se + j) * 2); - break; - case 3: - default: - data |= (RASTER_CONFIG_RB_MAP_2 << (i * sh_per_se + j) * 2); - break; - } - enabled_rbs >>= 2; - } - WREG32(mmPA_SC_RASTER_CONFIG, data); - } - gfx_v7_0_select_se_sh(adev, 0xffffffff, 0xffffffff); - mutex_unlock(&adev->grbm_idx_mutex); + adev->gfx.config.backend_enable_mask = active_rbs; + adev->gfx.config.num_rbs = hweight32(active_rbs); } /** @@ -2059,192 +1706,23 @@ static void gmc_v7_0_init_compute_vmid(struct amdgpu_device *adev) */ static void gfx_v7_0_gpu_init(struct amdgpu_device *adev) { - u32 gb_addr_config; - u32 mc_shared_chmap, mc_arb_ramcfg; - u32 dimm00_addr_map, dimm01_addr_map, dimm10_addr_map, dimm11_addr_map; - u32 sh_mem_cfg; - u32 tmp; - int i; - - switch (adev->asic_type) { - case CHIP_BONAIRE: - adev->gfx.config.max_shader_engines = 2; - adev->gfx.config.max_tile_pipes = 4; - adev->gfx.config.max_cu_per_sh = 7; - adev->gfx.config.max_sh_per_se = 1; - adev->gfx.config.max_backends_per_se = 2; - adev->gfx.config.max_texture_channel_caches = 4; - adev->gfx.config.max_gprs = 256; - adev->gfx.config.max_gs_threads = 32; - adev->gfx.config.max_hw_contexts = 8; - - adev->gfx.config.sc_prim_fifo_size_frontend = 0x20; - adev->gfx.config.sc_prim_fifo_size_backend = 0x100; - adev->gfx.config.sc_hiz_tile_fifo_size = 0x30; - adev->gfx.config.sc_earlyz_tile_fifo_size = 0x130; - gb_addr_config = BONAIRE_GB_ADDR_CONFIG_GOLDEN; - break; - case CHIP_HAWAII: - adev->gfx.config.max_shader_engines = 4; - adev->gfx.config.max_tile_pipes = 16; - adev->gfx.config.max_cu_per_sh = 11; - adev->gfx.config.max_sh_per_se = 1; - adev->gfx.config.max_backends_per_se = 4; - adev->gfx.config.max_texture_channel_caches = 16; - adev->gfx.config.max_gprs = 256; - adev->gfx.config.max_gs_threads = 32; - adev->gfx.config.max_hw_contexts = 8; - - adev->gfx.config.sc_prim_fifo_size_frontend = 0x20; - adev->gfx.config.sc_prim_fifo_size_backend = 0x100; - adev->gfx.config.sc_hiz_tile_fifo_size = 0x30; - adev->gfx.config.sc_earlyz_tile_fifo_size = 0x130; - gb_addr_config = HAWAII_GB_ADDR_CONFIG_GOLDEN; - break; - case CHIP_KAVERI: - adev->gfx.config.max_shader_engines = 1; - adev->gfx.config.max_tile_pipes = 4; - if ((adev->pdev->device == 0x1304) || - (adev->pdev->device == 0x1305) || - (adev->pdev->device == 0x130C) || - (adev->pdev->device == 0x130F) || - (adev->pdev->device == 0x1310) || - (adev->pdev->device == 0x1311) || - (adev->pdev->device == 0x131C)) { - adev->gfx.config.max_cu_per_sh = 8; - adev->gfx.config.max_backends_per_se = 2; - } else if ((adev->pdev->device == 0x1309) || - (adev->pdev->device == 0x130A) || - (adev->pdev->device == 0x130D) || - (adev->pdev->device == 0x1313) || - (adev->pdev->device == 0x131D)) { - adev->gfx.config.max_cu_per_sh = 6; - adev->gfx.config.max_backends_per_se = 2; - } else if ((adev->pdev->device == 0x1306) || - (adev->pdev->device == 0x1307) || - (adev->pdev->device == 0x130B) || - (adev->pdev->device == 0x130E) || - (adev->pdev->device == 0x1315) || - (adev->pdev->device == 0x131B)) { - adev->gfx.config.max_cu_per_sh = 4; - adev->gfx.config.max_backends_per_se = 1; - } else { - adev->gfx.config.max_cu_per_sh = 3; - adev->gfx.config.max_backends_per_se = 1; - } - adev->gfx.config.max_sh_per_se = 1; - adev->gfx.config.max_texture_channel_caches = 4; - adev->gfx.config.max_gprs = 256; - adev->gfx.config.max_gs_threads = 16; - adev->gfx.config.max_hw_contexts = 8; - - adev->gfx.config.sc_prim_fifo_size_frontend = 0x20; - adev->gfx.config.sc_prim_fifo_size_backend = 0x100; - adev->gfx.config.sc_hiz_tile_fifo_size = 0x30; - adev->gfx.config.sc_earlyz_tile_fifo_size = 0x130; - gb_addr_config = BONAIRE_GB_ADDR_CONFIG_GOLDEN; - break; - case CHIP_KABINI: - case CHIP_MULLINS: - default: - adev->gfx.config.max_shader_engines = 1; - adev->gfx.config.max_tile_pipes = 2; - adev->gfx.config.max_cu_per_sh = 2; - adev->gfx.config.max_sh_per_se = 1; - adev->gfx.config.max_backends_per_se = 1; - adev->gfx.config.max_texture_channel_caches = 2; - adev->gfx.config.max_gprs = 256; - adev->gfx.config.max_gs_threads = 16; - adev->gfx.config.max_hw_contexts = 8; - - adev->gfx.config.sc_prim_fifo_size_frontend = 0x20; - adev->gfx.config.sc_prim_fifo_size_backend = 0x100; - adev->gfx.config.sc_hiz_tile_fifo_size = 0x30; - adev->gfx.config.sc_earlyz_tile_fifo_size = 0x130; - gb_addr_config = BONAIRE_GB_ADDR_CONFIG_GOLDEN; - break; - } - - WREG32(mmGRBM_CNTL, (0xff << GRBM_CNTL__READ_TIMEOUT__SHIFT)); - - mc_shared_chmap = RREG32(mmMC_SHARED_CHMAP); - adev->gfx.config.mc_arb_ramcfg = RREG32(mmMC_ARB_RAMCFG); - mc_arb_ramcfg = adev->gfx.config.mc_arb_ramcfg; - - adev->gfx.config.num_tile_pipes = adev->gfx.config.max_tile_pipes; - adev->gfx.config.mem_max_burst_length_bytes = 256; - if (adev->flags & AMD_IS_APU) { - /* Get memory bank mapping mode. */ - tmp = RREG32(mmMC_FUS_DRAM0_BANK_ADDR_MAPPING); - dimm00_addr_map = REG_GET_FIELD(tmp, MC_FUS_DRAM0_BANK_ADDR_MAPPING, DIMM0ADDRMAP); - dimm01_addr_map = REG_GET_FIELD(tmp, MC_FUS_DRAM0_BANK_ADDR_MAPPING, DIMM1ADDRMAP); - - tmp = RREG32(mmMC_FUS_DRAM1_BANK_ADDR_MAPPING); - dimm10_addr_map = REG_GET_FIELD(tmp, MC_FUS_DRAM1_BANK_ADDR_MAPPING, DIMM0ADDRMAP); - dimm11_addr_map = REG_GET_FIELD(tmp, MC_FUS_DRAM1_BANK_ADDR_MAPPING, DIMM1ADDRMAP); - - /* Validate settings in case only one DIMM installed. */ - if ((dimm00_addr_map == 0) || (dimm00_addr_map == 3) || (dimm00_addr_map == 4) || (dimm00_addr_map > 12)) - dimm00_addr_map = 0; - if ((dimm01_addr_map == 0) || (dimm01_addr_map == 3) || (dimm01_addr_map == 4) || (dimm01_addr_map > 12)) - dimm01_addr_map = 0; - if ((dimm10_addr_map == 0) || (dimm10_addr_map == 3) || (dimm10_addr_map == 4) || (dimm10_addr_map > 12)) - dimm10_addr_map = 0; - if ((dimm11_addr_map == 0) || (dimm11_addr_map == 3) || (dimm11_addr_map == 4) || (dimm11_addr_map > 12)) - dimm11_addr_map = 0; - - /* If DIMM Addr map is 8GB, ROW size should be 2KB. Otherwise 1KB. */ - /* If ROW size(DIMM1) != ROW size(DMIMM0), ROW size should be larger one. */ - if ((dimm00_addr_map == 11) || (dimm01_addr_map == 11) || (dimm10_addr_map == 11) || (dimm11_addr_map == 11)) - adev->gfx.config.mem_row_size_in_kb = 2; - else - adev->gfx.config.mem_row_size_in_kb = 1; - } else { - tmp = (mc_arb_ramcfg & MC_ARB_RAMCFG__NOOFCOLS_MASK) >> MC_ARB_RAMCFG__NOOFCOLS__SHIFT; - adev->gfx.config.mem_row_size_in_kb = (4 * (1 << (8 + tmp))) / 1024; - if (adev->gfx.config.mem_row_size_in_kb > 4) - adev->gfx.config.mem_row_size_in_kb = 4; - } - /* XXX use MC settings? */ - adev->gfx.config.shader_engine_tile_size = 32; - adev->gfx.config.num_gpus = 1; - adev->gfx.config.multi_gpu_tile_size = 64; - - /* fix up row size */ - gb_addr_config &= ~GB_ADDR_CONFIG__ROW_SIZE_MASK; - switch (adev->gfx.config.mem_row_size_in_kb) { - case 1: - default: - gb_addr_config |= (0 << GB_ADDR_CONFIG__ROW_SIZE__SHIFT); - break; - case 2: - gb_addr_config |= (1 << GB_ADDR_CONFIG__ROW_SIZE__SHIFT); - break; - case 4: - gb_addr_config |= (2 << GB_ADDR_CONFIG__ROW_SIZE__SHIFT); - break; - } - adev->gfx.config.gb_addr_config = gb_addr_config; + u32 tmp, sh_mem_cfg; + int i; + + WREG32(mmGRBM_CNTL, (0xff << GRBM_CNTL__READ_TIMEOUT__SHIFT)); - WREG32(mmGB_ADDR_CONFIG, gb_addr_config); - WREG32(mmHDP_ADDR_CONFIG, gb_addr_config); - WREG32(mmDMIF_ADDR_CALC, gb_addr_config); - WREG32(mmSDMA0_TILING_CONFIG + SDMA0_REGISTER_OFFSET, gb_addr_config & 0x70); - WREG32(mmSDMA0_TILING_CONFIG + SDMA1_REGISTER_OFFSET, gb_addr_config & 0x70); - WREG32(mmUVD_UDEC_ADDR_CONFIG, gb_addr_config); - WREG32(mmUVD_UDEC_DB_ADDR_CONFIG, gb_addr_config); - WREG32(mmUVD_UDEC_DBW_ADDR_CONFIG, gb_addr_config); + WREG32(mmGB_ADDR_CONFIG, adev->gfx.config.gb_addr_config); + WREG32(mmHDP_ADDR_CONFIG, adev->gfx.config.gb_addr_config); + WREG32(mmDMIF_ADDR_CALC, adev->gfx.config.gb_addr_config); gfx_v7_0_tiling_mode_table_init(adev); - gfx_v7_0_setup_rb(adev, adev->gfx.config.max_shader_engines, - adev->gfx.config.max_sh_per_se, - adev->gfx.config.max_backends_per_se); + gfx_v7_0_setup_rb(adev); /* set HW defaults for 3D engine */ WREG32(mmCP_MEQ_THRESHOLDS, - (0x30 << CP_MEQ_THRESHOLDS__MEQ1_START__SHIFT) | - (0x60 << CP_MEQ_THRESHOLDS__MEQ2_START__SHIFT)); + (0x30 << CP_MEQ_THRESHOLDS__MEQ1_START__SHIFT) | + (0x60 << CP_MEQ_THRESHOLDS__MEQ2_START__SHIFT)); mutex_lock(&adev->grbm_idx_mutex); /* @@ -2255,7 +1733,7 @@ static void gfx_v7_0_gpu_init(struct amdgpu_device *adev) /* XXX SH_MEM regs */ /* where to put LDS, scratch, GPUVM in FSA64 space */ - sh_mem_cfg = REG_SET_FIELD(0, SH_MEM_CONFIG, ALIGNMENT_MODE, + sh_mem_cfg = REG_SET_FIELD(0, SH_MEM_CONFIG, ALIGNMENT_MODE, SH_MEM_ALIGNMENT_MODE_UNALIGNED); mutex_lock(&adev->srbm_mutex); @@ -2379,7 +1857,7 @@ static int gfx_v7_0_ring_test_ring(struct amdgpu_ring *ring) return r; } WREG32(scratch, 0xCAFEDEAD); - r = amdgpu_ring_lock(ring, 3); + r = amdgpu_ring_alloc(ring, 3); if (r) { DRM_ERROR("amdgpu: cp failed to lock ring %d (%d).\n", ring->idx, r); amdgpu_gfx_scratch_free(adev, scratch); @@ -2388,7 +1866,7 @@ static int gfx_v7_0_ring_test_ring(struct amdgpu_ring *ring) amdgpu_ring_write(ring, PACKET3(PACKET3_SET_UCONFIG_REG, 1)); amdgpu_ring_write(ring, (scratch - PACKET3_SET_UCONFIG_REG_START)); amdgpu_ring_write(ring, 0xDEADBEEF); - amdgpu_ring_unlock_commit(ring); + amdgpu_ring_commit(ring); for (i = 0; i < adev->usec_timeout; i++) { tmp = RREG32(scratch); @@ -2446,6 +1924,25 @@ static void gfx_v7_0_ring_emit_hdp_flush(struct amdgpu_ring *ring) amdgpu_ring_write(ring, 0x20); /* poll interval */ } +/** + * gfx_v7_0_ring_emit_hdp_invalidate - emit an hdp invalidate on the cp + * + * @adev: amdgpu_device pointer + * @ridx: amdgpu ring index + * + * Emits an hdp invalidate on the cp. + */ +static void gfx_v7_0_ring_emit_hdp_invalidate(struct amdgpu_ring *ring) +{ + amdgpu_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); + amdgpu_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) | + WRITE_DATA_DST_SEL(0) | + WR_CONFIRM)); + amdgpu_ring_write(ring, mmHDP_DEBUG0); + amdgpu_ring_write(ring, 0); + amdgpu_ring_write(ring, 1); +} + /** * gfx_v7_0_ring_emit_fence_gfx - emit a fence on the gfx ring * @@ -2516,36 +2013,6 @@ static void gfx_v7_0_ring_emit_fence_compute(struct amdgpu_ring *ring, amdgpu_ring_write(ring, upper_32_bits(seq)); } -/** - * gfx_v7_0_ring_emit_semaphore - emit a semaphore on the CP ring - * - * @ring: amdgpu ring buffer object - * @semaphore: amdgpu semaphore object - * @emit_wait: Is this a sempahore wait? - * - * Emits a semaphore signal/wait packet to the CP ring and prevents the PFP - * from running ahead of semaphore waits. - */ -static bool gfx_v7_0_ring_emit_semaphore(struct amdgpu_ring *ring, - struct amdgpu_semaphore *semaphore, - bool emit_wait) -{ - uint64_t addr = semaphore->gpu_addr; - unsigned sel = emit_wait ? PACKET3_SEM_SEL_WAIT : PACKET3_SEM_SEL_SIGNAL; - - amdgpu_ring_write(ring, PACKET3(PACKET3_MEM_SEMAPHORE, 1)); - amdgpu_ring_write(ring, addr & 0xffffffff); - amdgpu_ring_write(ring, (upper_32_bits(addr) & 0xffff) | sel); - - if (emit_wait && (ring->type == AMDGPU_RING_TYPE_GFX)) { - /* Prevent the PFP from running ahead of the semaphore wait */ - amdgpu_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); - amdgpu_ring_write(ring, 0x0); - } - - return true; -} - /* * IB stuff */ @@ -2593,8 +2060,7 @@ static void gfx_v7_0_ring_emit_ib_gfx(struct amdgpu_ring *ring, else header = PACKET3(PACKET3_INDIRECT_BUFFER, 2); - control |= ib->length_dw | - (ib->vm ? (ib->vm->ids[ring->idx].id << 24) : 0); + control |= ib->length_dw | (ib->vm_id << 24); amdgpu_ring_write(ring, header); amdgpu_ring_write(ring, @@ -2622,8 +2088,7 @@ static void gfx_v7_0_ring_emit_ib_compute(struct amdgpu_ring *ring, header = PACKET3(PACKET3_INDIRECT_BUFFER, 2); - control |= ib->length_dw | - (ib->vm ? (ib->vm->ids[ring->idx].id << 24) : 0); + control |= ib->length_dw | (ib->vm_id << 24); amdgpu_ring_write(ring, header); amdgpu_ring_write(ring, @@ -2661,7 +2126,7 @@ static int gfx_v7_0_ring_test_ib(struct amdgpu_ring *ring) } WREG32(scratch, 0xCAFEDEAD); memset(&ib, 0, sizeof(ib)); - r = amdgpu_ib_get(ring, NULL, 256, &ib); + r = amdgpu_ib_get(adev, NULL, 256, &ib); if (r) { DRM_ERROR("amdgpu: failed to get ib (%d).\n", r); goto err1; @@ -2671,9 +2136,7 @@ static int gfx_v7_0_ring_test_ib(struct amdgpu_ring *ring) ib.ptr[2] = 0xDEADBEEF; ib.length_dw = 3; - r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, &ib, 1, NULL, - AMDGPU_FENCE_OWNER_UNDEFINED, - &f); + r = amdgpu_ib_schedule(ring, 1, &ib, NULL, &f); if (r) goto err2; @@ -2700,7 +2163,8 @@ static int gfx_v7_0_ring_test_ib(struct amdgpu_ring *ring) err2: fence_put(f); - amdgpu_ib_free(adev, &ib); + amdgpu_ib_free(adev, &ib, NULL); + fence_put(f); err1: amdgpu_gfx_scratch_free(adev, scratch); return r; @@ -2842,7 +2306,7 @@ static int gfx_v7_0_cp_gfx_start(struct amdgpu_device *adev) gfx_v7_0_cp_gfx_enable(adev, true); - r = amdgpu_ring_lock(ring, gfx_v7_0_get_csb_size(adev) + 8); + r = amdgpu_ring_alloc(ring, gfx_v7_0_get_csb_size(adev) + 8); if (r) { DRM_ERROR("amdgpu: cp failed to lock ring (%d).\n", r); return r; @@ -2911,7 +2375,7 @@ static int gfx_v7_0_cp_gfx_start(struct amdgpu_device *adev) amdgpu_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */ amdgpu_ring_write(ring, 0x00000010); /* VGT_OUT_DEALLOC_CNTL */ - amdgpu_ring_unlock_commit(ring); + amdgpu_ring_commit(ring); return 0; } @@ -2989,21 +2453,14 @@ static int gfx_v7_0_cp_gfx_resume(struct amdgpu_device *adev) static u32 gfx_v7_0_ring_get_rptr_gfx(struct amdgpu_ring *ring) { - u32 rptr; - - rptr = ring->adev->wb.wb[ring->rptr_offs]; - - return rptr; + return ring->adev->wb.wb[ring->rptr_offs]; } static u32 gfx_v7_0_ring_get_wptr_gfx(struct amdgpu_ring *ring) { struct amdgpu_device *adev = ring->adev; - u32 wptr; - - wptr = RREG32(mmCP_RB0_WPTR); - return wptr; + return RREG32(mmCP_RB0_WPTR); } static void gfx_v7_0_ring_set_wptr_gfx(struct amdgpu_ring *ring) @@ -3016,21 +2473,13 @@ static void gfx_v7_0_ring_set_wptr_gfx(struct amdgpu_ring *ring) static u32 gfx_v7_0_ring_get_rptr_compute(struct amdgpu_ring *ring) { - u32 rptr; - - rptr = ring->adev->wb.wb[ring->rptr_offs]; - - return rptr; + return ring->adev->wb.wb[ring->rptr_offs]; } static u32 gfx_v7_0_ring_get_wptr_compute(struct amdgpu_ring *ring) { - u32 wptr; - /* XXX check if swapping is necessary on BE */ - wptr = ring->adev->wb.wb[ring->wptr_offs]; - - return wptr; + return ring->adev->wb.wb[ring->wptr_offs]; } static void gfx_v7_0_ring_set_wptr_compute(struct amdgpu_ring *ring) @@ -3125,21 +2574,6 @@ static int gfx_v7_0_cp_compute_load_microcode(struct amdgpu_device *adev) return 0; } -/** - * gfx_v7_0_cp_compute_start - start the compute queues - * - * @adev: amdgpu_device pointer - * - * Enable the compute queues. - * Returns 0 for success, error for failure. - */ -static int gfx_v7_0_cp_compute_start(struct amdgpu_device *adev) -{ - gfx_v7_0_cp_compute_enable(adev, true); - - return 0; -} - /** * gfx_v7_0_cp_compute_fini - stop the compute queues * @@ -3330,9 +2764,7 @@ static int gfx_v7_0_cp_compute_resume(struct amdgpu_device *adev) u32 *buf; struct bonaire_mqd *mqd; - r = gfx_v7_0_cp_compute_start(adev); - if (r) - return r; + gfx_v7_0_cp_compute_enable(adev, true); /* fix up chicken bits */ tmp = RREG32(mmCP_CPF_DEBUG); @@ -3610,6 +3042,26 @@ static int gfx_v7_0_cp_resume(struct amdgpu_device *adev) return 0; } +/** + * gfx_v7_0_ring_emit_vm_flush - cik vm flush using the CP + * + * @ring: the ring to emmit the commands to + * + * Sync the command pipeline with the PFP. E.g. wait for everything + * to be completed. + */ +static void gfx_v7_0_ring_emit_pipeline_sync(struct amdgpu_ring *ring) +{ + int usepfp = (ring->type == AMDGPU_RING_TYPE_GFX); + if (usepfp) { + /* synce CE with ME to prevent CE fetch CEIB before context switch done */ + amdgpu_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 0)); + amdgpu_ring_write(ring, 0); + amdgpu_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 0)); + amdgpu_ring_write(ring, 0); + } +} + /* * vm * VMID 0 is the physical GPU addresses as used by the kernel. @@ -3641,14 +3093,6 @@ static void gfx_v7_0_ring_emit_vm_flush(struct amdgpu_ring *ring, amdgpu_ring_write(ring, 0xffffffff); amdgpu_ring_write(ring, 4); /* poll interval */ - if (usepfp) { - /* synce CE with ME to prevent CE fetch CEIB before context switch done */ - amdgpu_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 0)); - amdgpu_ring_write(ring, 0); - amdgpu_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 0)); - amdgpu_ring_write(ring, 0); - } - amdgpu_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); amdgpu_ring_write(ring, (WRITE_DATA_ENGINE_SEL(usepfp) | WRITE_DATA_DST_SEL(0))); @@ -4408,28 +3852,19 @@ static void gfx_v7_0_enable_gfx_cgpg(struct amdgpu_device *adev, } } -static u32 gfx_v7_0_get_cu_active_bitmap(struct amdgpu_device *adev, - u32 se, u32 sh) +static u32 gfx_v7_0_get_cu_active_bitmap(struct amdgpu_device *adev) { - u32 mask = 0, tmp, tmp1; - int i; - - gfx_v7_0_select_se_sh(adev, se, sh); - tmp = RREG32(mmCC_GC_SHADER_ARRAY_CONFIG); - tmp1 = RREG32(mmGC_USER_SHADER_ARRAY_CONFIG); - gfx_v7_0_select_se_sh(adev, 0xffffffff, 0xffffffff); + u32 data, mask; - tmp &= 0xffff0000; + data = RREG32(mmCC_GC_SHADER_ARRAY_CONFIG); + data |= RREG32(mmGC_USER_SHADER_ARRAY_CONFIG); - tmp |= tmp1; - tmp >>= 16; + data &= CC_GC_SHADER_ARRAY_CONFIG__INACTIVE_CUS_MASK; + data >>= CC_GC_SHADER_ARRAY_CONFIG__INACTIVE_CUS__SHIFT; - for (i = 0; i < adev->gfx.config.max_cu_per_sh; i ++) { - mask <<= 1; - mask |= 1; - } + mask = gfx_v7_0_create_bitmask(adev->gfx.config.max_cu_per_sh); - return (~tmp) & mask; + return (~data) & mask; } static void gfx_v7_0_init_ao_cu_mask(struct amdgpu_device *adev) @@ -4767,6 +4202,172 @@ static int gfx_v7_0_late_init(void *handle) return 0; } +static void gfx_v7_0_gpu_early_init(struct amdgpu_device *adev) +{ + u32 gb_addr_config; + u32 mc_shared_chmap, mc_arb_ramcfg; + u32 dimm00_addr_map, dimm01_addr_map, dimm10_addr_map, dimm11_addr_map; + u32 tmp; + + switch (adev->asic_type) { + case CHIP_BONAIRE: + adev->gfx.config.max_shader_engines = 2; + adev->gfx.config.max_tile_pipes = 4; + adev->gfx.config.max_cu_per_sh = 7; + adev->gfx.config.max_sh_per_se = 1; + adev->gfx.config.max_backends_per_se = 2; + adev->gfx.config.max_texture_channel_caches = 4; + adev->gfx.config.max_gprs = 256; + adev->gfx.config.max_gs_threads = 32; + adev->gfx.config.max_hw_contexts = 8; + + adev->gfx.config.sc_prim_fifo_size_frontend = 0x20; + adev->gfx.config.sc_prim_fifo_size_backend = 0x100; + adev->gfx.config.sc_hiz_tile_fifo_size = 0x30; + adev->gfx.config.sc_earlyz_tile_fifo_size = 0x130; + gb_addr_config = BONAIRE_GB_ADDR_CONFIG_GOLDEN; + break; + case CHIP_HAWAII: + adev->gfx.config.max_shader_engines = 4; + adev->gfx.config.max_tile_pipes = 16; + adev->gfx.config.max_cu_per_sh = 11; + adev->gfx.config.max_sh_per_se = 1; + adev->gfx.config.max_backends_per_se = 4; + adev->gfx.config.max_texture_channel_caches = 16; + adev->gfx.config.max_gprs = 256; + adev->gfx.config.max_gs_threads = 32; + adev->gfx.config.max_hw_contexts = 8; + + adev->gfx.config.sc_prim_fifo_size_frontend = 0x20; + adev->gfx.config.sc_prim_fifo_size_backend = 0x100; + adev->gfx.config.sc_hiz_tile_fifo_size = 0x30; + adev->gfx.config.sc_earlyz_tile_fifo_size = 0x130; + gb_addr_config = HAWAII_GB_ADDR_CONFIG_GOLDEN; + break; + case CHIP_KAVERI: + adev->gfx.config.max_shader_engines = 1; + adev->gfx.config.max_tile_pipes = 4; + if ((adev->pdev->device == 0x1304) || + (adev->pdev->device == 0x1305) || + (adev->pdev->device == 0x130C) || + (adev->pdev->device == 0x130F) || + (adev->pdev->device == 0x1310) || + (adev->pdev->device == 0x1311) || + (adev->pdev->device == 0x131C)) { + adev->gfx.config.max_cu_per_sh = 8; + adev->gfx.config.max_backends_per_se = 2; + } else if ((adev->pdev->device == 0x1309) || + (adev->pdev->device == 0x130A) || + (adev->pdev->device == 0x130D) || + (adev->pdev->device == 0x1313) || + (adev->pdev->device == 0x131D)) { + adev->gfx.config.max_cu_per_sh = 6; + adev->gfx.config.max_backends_per_se = 2; + } else if ((adev->pdev->device == 0x1306) || + (adev->pdev->device == 0x1307) || + (adev->pdev->device == 0x130B) || + (adev->pdev->device == 0x130E) || + (adev->pdev->device == 0x1315) || + (adev->pdev->device == 0x131B)) { + adev->gfx.config.max_cu_per_sh = 4; + adev->gfx.config.max_backends_per_se = 1; + } else { + adev->gfx.config.max_cu_per_sh = 3; + adev->gfx.config.max_backends_per_se = 1; + } + adev->gfx.config.max_sh_per_se = 1; + adev->gfx.config.max_texture_channel_caches = 4; + adev->gfx.config.max_gprs = 256; + adev->gfx.config.max_gs_threads = 16; + adev->gfx.config.max_hw_contexts = 8; + + adev->gfx.config.sc_prim_fifo_size_frontend = 0x20; + adev->gfx.config.sc_prim_fifo_size_backend = 0x100; + adev->gfx.config.sc_hiz_tile_fifo_size = 0x30; + adev->gfx.config.sc_earlyz_tile_fifo_size = 0x130; + gb_addr_config = BONAIRE_GB_ADDR_CONFIG_GOLDEN; + break; + case CHIP_KABINI: + case CHIP_MULLINS: + default: + adev->gfx.config.max_shader_engines = 1; + adev->gfx.config.max_tile_pipes = 2; + adev->gfx.config.max_cu_per_sh = 2; + adev->gfx.config.max_sh_per_se = 1; + adev->gfx.config.max_backends_per_se = 1; + adev->gfx.config.max_texture_channel_caches = 2; + adev->gfx.config.max_gprs = 256; + adev->gfx.config.max_gs_threads = 16; + adev->gfx.config.max_hw_contexts = 8; + + adev->gfx.config.sc_prim_fifo_size_frontend = 0x20; + adev->gfx.config.sc_prim_fifo_size_backend = 0x100; + adev->gfx.config.sc_hiz_tile_fifo_size = 0x30; + adev->gfx.config.sc_earlyz_tile_fifo_size = 0x130; + gb_addr_config = BONAIRE_GB_ADDR_CONFIG_GOLDEN; + break; + } + + mc_shared_chmap = RREG32(mmMC_SHARED_CHMAP); + adev->gfx.config.mc_arb_ramcfg = RREG32(mmMC_ARB_RAMCFG); + mc_arb_ramcfg = adev->gfx.config.mc_arb_ramcfg; + + adev->gfx.config.num_tile_pipes = adev->gfx.config.max_tile_pipes; + adev->gfx.config.mem_max_burst_length_bytes = 256; + if (adev->flags & AMD_IS_APU) { + /* Get memory bank mapping mode. */ + tmp = RREG32(mmMC_FUS_DRAM0_BANK_ADDR_MAPPING); + dimm00_addr_map = REG_GET_FIELD(tmp, MC_FUS_DRAM0_BANK_ADDR_MAPPING, DIMM0ADDRMAP); + dimm01_addr_map = REG_GET_FIELD(tmp, MC_FUS_DRAM0_BANK_ADDR_MAPPING, DIMM1ADDRMAP); + + tmp = RREG32(mmMC_FUS_DRAM1_BANK_ADDR_MAPPING); + dimm10_addr_map = REG_GET_FIELD(tmp, MC_FUS_DRAM1_BANK_ADDR_MAPPING, DIMM0ADDRMAP); + dimm11_addr_map = REG_GET_FIELD(tmp, MC_FUS_DRAM1_BANK_ADDR_MAPPING, DIMM1ADDRMAP); + + /* Validate settings in case only one DIMM installed. */ + if ((dimm00_addr_map == 0) || (dimm00_addr_map == 3) || (dimm00_addr_map == 4) || (dimm00_addr_map > 12)) + dimm00_addr_map = 0; + if ((dimm01_addr_map == 0) || (dimm01_addr_map == 3) || (dimm01_addr_map == 4) || (dimm01_addr_map > 12)) + dimm01_addr_map = 0; + if ((dimm10_addr_map == 0) || (dimm10_addr_map == 3) || (dimm10_addr_map == 4) || (dimm10_addr_map > 12)) + dimm10_addr_map = 0; + if ((dimm11_addr_map == 0) || (dimm11_addr_map == 3) || (dimm11_addr_map == 4) || (dimm11_addr_map > 12)) + dimm11_addr_map = 0; + + /* If DIMM Addr map is 8GB, ROW size should be 2KB. Otherwise 1KB. */ + /* If ROW size(DIMM1) != ROW size(DMIMM0), ROW size should be larger one. */ + if ((dimm00_addr_map == 11) || (dimm01_addr_map == 11) || (dimm10_addr_map == 11) || (dimm11_addr_map == 11)) + adev->gfx.config.mem_row_size_in_kb = 2; + else + adev->gfx.config.mem_row_size_in_kb = 1; + } else { + tmp = (mc_arb_ramcfg & MC_ARB_RAMCFG__NOOFCOLS_MASK) >> MC_ARB_RAMCFG__NOOFCOLS__SHIFT; + adev->gfx.config.mem_row_size_in_kb = (4 * (1 << (8 + tmp))) / 1024; + if (adev->gfx.config.mem_row_size_in_kb > 4) + adev->gfx.config.mem_row_size_in_kb = 4; + } + /* XXX use MC settings? */ + adev->gfx.config.shader_engine_tile_size = 32; + adev->gfx.config.num_gpus = 1; + adev->gfx.config.multi_gpu_tile_size = 64; + + /* fix up row size */ + gb_addr_config &= ~GB_ADDR_CONFIG__ROW_SIZE_MASK; + switch (adev->gfx.config.mem_row_size_in_kb) { + case 1: + default: + gb_addr_config |= (0 << GB_ADDR_CONFIG__ROW_SIZE__SHIFT); + break; + case 2: + gb_addr_config |= (1 << GB_ADDR_CONFIG__ROW_SIZE__SHIFT); + break; + case 4: + gb_addr_config |= (2 << GB_ADDR_CONFIG__ROW_SIZE__SHIFT); + break; + } + adev->gfx.config.gb_addr_config = gb_addr_config; +} + static int gfx_v7_0_sw_init(void *handle) { struct amdgpu_ring *ring; @@ -4870,6 +4471,10 @@ static int gfx_v7_0_sw_init(void *handle) if (r) return r; + adev->gfx.ce_ram_size = 0x8000; + + gfx_v7_0_gpu_early_init(adev); + return r; } @@ -4910,8 +4515,6 @@ static int gfx_v7_0_hw_init(void *handle) if (r) return r; - adev->gfx.ce_ram_size = 0x8000; - return r; } @@ -5028,16 +4631,6 @@ static void gfx_v7_0_print_status(void *handle) RREG32(mmHDP_ADDR_CONFIG)); dev_info(adev->dev, " DMIF_ADDR_CALC=0x%08X\n", RREG32(mmDMIF_ADDR_CALC)); - dev_info(adev->dev, " SDMA0_TILING_CONFIG=0x%08X\n", - RREG32(mmSDMA0_TILING_CONFIG + SDMA0_REGISTER_OFFSET)); - dev_info(adev->dev, " SDMA1_TILING_CONFIG=0x%08X\n", - RREG32(mmSDMA0_TILING_CONFIG + SDMA1_REGISTER_OFFSET)); - dev_info(adev->dev, " UVD_UDEC_ADDR_CONFIG=0x%08X\n", - RREG32(mmUVD_UDEC_ADDR_CONFIG)); - dev_info(adev->dev, " UVD_UDEC_DB_ADDR_CONFIG=0x%08X\n", - RREG32(mmUVD_UDEC_DB_ADDR_CONFIG)); - dev_info(adev->dev, " UVD_UDEC_DBW_ADDR_CONFIG=0x%08X\n", - RREG32(mmUVD_UDEC_DBW_ADDR_CONFIG)); dev_info(adev->dev, " CP_MEQ_THRESHOLDS=0x%08X\n", RREG32(mmCP_MEQ_THRESHOLDS)); @@ -5580,13 +5173,15 @@ static const struct amdgpu_ring_funcs gfx_v7_0_ring_funcs_gfx = { .parse_cs = NULL, .emit_ib = gfx_v7_0_ring_emit_ib_gfx, .emit_fence = gfx_v7_0_ring_emit_fence_gfx, - .emit_semaphore = gfx_v7_0_ring_emit_semaphore, + .emit_pipeline_sync = gfx_v7_0_ring_emit_pipeline_sync, .emit_vm_flush = gfx_v7_0_ring_emit_vm_flush, .emit_gds_switch = gfx_v7_0_ring_emit_gds_switch, .emit_hdp_flush = gfx_v7_0_ring_emit_hdp_flush, + .emit_hdp_invalidate = gfx_v7_0_ring_emit_hdp_invalidate, .test_ring = gfx_v7_0_ring_test_ring, .test_ib = gfx_v7_0_ring_test_ib, .insert_nop = amdgpu_ring_insert_nop, + .pad_ib = amdgpu_ring_generic_pad_ib, }; static const struct amdgpu_ring_funcs gfx_v7_0_ring_funcs_compute = { @@ -5596,13 +5191,15 @@ static const struct amdgpu_ring_funcs gfx_v7_0_ring_funcs_compute = { .parse_cs = NULL, .emit_ib = gfx_v7_0_ring_emit_ib_compute, .emit_fence = gfx_v7_0_ring_emit_fence_compute, - .emit_semaphore = gfx_v7_0_ring_emit_semaphore, + .emit_pipeline_sync = gfx_v7_0_ring_emit_pipeline_sync, .emit_vm_flush = gfx_v7_0_ring_emit_vm_flush, .emit_gds_switch = gfx_v7_0_ring_emit_gds_switch, .emit_hdp_flush = gfx_v7_0_ring_emit_hdp_flush, + .emit_hdp_invalidate = gfx_v7_0_ring_emit_hdp_invalidate, .test_ring = gfx_v7_0_ring_test_ring, .test_ib = gfx_v7_0_ring_test_ib, .insert_nop = amdgpu_ring_insert_nop, + .pad_ib = amdgpu_ring_generic_pad_ib, }; static void gfx_v7_0_set_ring_funcs(struct amdgpu_device *adev) @@ -5672,7 +5269,7 @@ static void gfx_v7_0_set_gds_init(struct amdgpu_device *adev) int gfx_v7_0_get_cu_info(struct amdgpu_device *adev, - struct amdgpu_cu_info *cu_info) + struct amdgpu_cu_info *cu_info) { int i, j, k, counter, active_cu_number = 0; u32 mask, bitmap, ao_bitmap, ao_cu_mask = 0; @@ -5680,16 +5277,19 @@ int gfx_v7_0_get_cu_info(struct amdgpu_device *adev, if (!adev || !cu_info) return -EINVAL; + memset(cu_info, 0, sizeof(*cu_info)); + mutex_lock(&adev->grbm_idx_mutex); for (i = 0; i < adev->gfx.config.max_shader_engines; i++) { for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) { mask = 1; ao_bitmap = 0; counter = 0; - bitmap = gfx_v7_0_get_cu_active_bitmap(adev, i, j); + gfx_v7_0_select_se_sh(adev, i, j); + bitmap = gfx_v7_0_get_cu_active_bitmap(adev); cu_info->bitmap[i][j] = bitmap; - for (k = 0; k < adev->gfx.config.max_cu_per_sh; k ++) { + for (k = 0; k < 16; k ++) { if (bitmap & mask) { if (counter < 2) ao_bitmap |= mask; @@ -5701,9 +5301,11 @@ int gfx_v7_0_get_cu_info(struct amdgpu_device *adev, ao_cu_mask |= (ao_bitmap << (i * 16 + j * 8)); } } + gfx_v7_0_select_se_sh(adev, 0xffffffff, 0xffffffff); + mutex_unlock(&adev->grbm_idx_mutex); cu_info->number = active_cu_number; cu_info->ao_cu_mask = ao_cu_mask; - mutex_unlock(&adev->grbm_idx_mutex); + return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 7086ac17abee11aa68e6a863099c73b273db1717..f0c7b3596480995afca643caa42a93827c04f841 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -43,9 +43,6 @@ #include "gca/gfx_8_0_sh_mask.h" #include "gca/gfx_8_0_enum.h" -#include "uvd/uvd_5_0_d.h" -#include "uvd/uvd_5_0_sh_mask.h" - #include "dce/dce_10_0_d.h" #include "dce/dce_10_0_sh_mask.h" @@ -652,7 +649,7 @@ static int gfx_v8_0_ring_test_ring(struct amdgpu_ring *ring) return r; } WREG32(scratch, 0xCAFEDEAD); - r = amdgpu_ring_lock(ring, 3); + r = amdgpu_ring_alloc(ring, 3); if (r) { DRM_ERROR("amdgpu: cp failed to lock ring %d (%d).\n", ring->idx, r); @@ -662,7 +659,7 @@ static int gfx_v8_0_ring_test_ring(struct amdgpu_ring *ring) amdgpu_ring_write(ring, PACKET3(PACKET3_SET_UCONFIG_REG, 1)); amdgpu_ring_write(ring, (scratch - PACKET3_SET_UCONFIG_REG_START)); amdgpu_ring_write(ring, 0xDEADBEEF); - amdgpu_ring_unlock_commit(ring); + amdgpu_ring_commit(ring); for (i = 0; i < adev->usec_timeout; i++) { tmp = RREG32(scratch); @@ -699,7 +696,7 @@ static int gfx_v8_0_ring_test_ib(struct amdgpu_ring *ring) } WREG32(scratch, 0xCAFEDEAD); memset(&ib, 0, sizeof(ib)); - r = amdgpu_ib_get(ring, NULL, 256, &ib); + r = amdgpu_ib_get(adev, NULL, 256, &ib); if (r) { DRM_ERROR("amdgpu: failed to get ib (%d).\n", r); goto err1; @@ -709,9 +706,7 @@ static int gfx_v8_0_ring_test_ib(struct amdgpu_ring *ring) ib.ptr[2] = 0xDEADBEEF; ib.length_dw = 3; - r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, &ib, 1, NULL, - AMDGPU_FENCE_OWNER_UNDEFINED, - &f); + r = amdgpu_ib_schedule(ring, 1, &ib, NULL, &f); if (r) goto err2; @@ -737,7 +732,8 @@ static int gfx_v8_0_ring_test_ib(struct amdgpu_ring *ring) } err2: fence_put(f); - amdgpu_ib_free(adev, &ib); + amdgpu_ib_free(adev, &ib, NULL); + fence_put(f); err1: amdgpu_gfx_scratch_free(adev, scratch); return r; @@ -1171,7 +1167,7 @@ static int gfx_v8_0_do_edc_gpr_workarounds(struct amdgpu_device *adev) /* allocate an indirect buffer to put the commands in */ memset(&ib, 0, sizeof(ib)); - r = amdgpu_ib_get(ring, NULL, total_size, &ib); + r = amdgpu_ib_get(adev, NULL, total_size, &ib); if (r) { DRM_ERROR("amdgpu: failed to get ib (%d).\n", r); return r; @@ -1266,9 +1262,7 @@ static int gfx_v8_0_do_edc_gpr_workarounds(struct amdgpu_device *adev) ib.ptr[ib.length_dw++] = EVENT_TYPE(7) | EVENT_INDEX(4); /* shedule the ib on the ring */ - r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, &ib, 1, NULL, - AMDGPU_FENCE_OWNER_UNDEFINED, - &f); + r = amdgpu_ib_schedule(ring, 1, &ib, NULL, &f); if (r) { DRM_ERROR("amdgpu: ib submit failed (%d).\n", r); goto fail; @@ -1296,7 +1290,8 @@ static int gfx_v8_0_do_edc_gpr_workarounds(struct amdgpu_device *adev) fail: fence_put(f); - amdgpu_ib_free(adev, &ib); + amdgpu_ib_free(adev, &ib, NULL); + fence_put(f); return r; } @@ -2574,11 +2569,6 @@ static void gfx_v8_0_tiling_mode_table_init(struct amdgpu_device *adev) } } -static u32 gfx_v8_0_create_bitmask(u32 bit_width) -{ - return (u32)((1ULL << bit_width) - 1); -} - void gfx_v8_0_select_se_sh(struct amdgpu_device *adev, u32 se_num, u32 sh_num) { u32 data = REG_SET_FIELD(0, GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES, 1); @@ -2599,89 +2589,49 @@ void gfx_v8_0_select_se_sh(struct amdgpu_device *adev, u32 se_num, u32 sh_num) WREG32(mmGRBM_GFX_INDEX, data); } -static u32 gfx_v8_0_get_rb_disabled(struct amdgpu_device *adev, - u32 max_rb_num_per_se, - u32 sh_per_se) +static u32 gfx_v8_0_create_bitmask(u32 bit_width) +{ + return (u32)((1ULL << bit_width) - 1); +} + +static u32 gfx_v8_0_get_rb_active_bitmap(struct amdgpu_device *adev) { u32 data, mask; data = RREG32(mmCC_RB_BACKEND_DISABLE); - data &= CC_RB_BACKEND_DISABLE__BACKEND_DISABLE_MASK; - data |= RREG32(mmGC_USER_RB_BACKEND_DISABLE); + data &= CC_RB_BACKEND_DISABLE__BACKEND_DISABLE_MASK; data >>= GC_USER_RB_BACKEND_DISABLE__BACKEND_DISABLE__SHIFT; - mask = gfx_v8_0_create_bitmask(max_rb_num_per_se / sh_per_se); + mask = gfx_v8_0_create_bitmask(adev->gfx.config.max_backends_per_se / + adev->gfx.config.max_sh_per_se); - return data & mask; + return (~data) & mask; } -static void gfx_v8_0_setup_rb(struct amdgpu_device *adev, - u32 se_num, u32 sh_per_se, - u32 max_rb_num_per_se) +static void gfx_v8_0_setup_rb(struct amdgpu_device *adev) { int i, j; - u32 data, mask; - u32 disabled_rbs = 0; - u32 enabled_rbs = 0; + u32 data; + u32 active_rbs = 0; + u32 rb_bitmap_width_per_sh = adev->gfx.config.max_backends_per_se / + adev->gfx.config.max_sh_per_se; mutex_lock(&adev->grbm_idx_mutex); - for (i = 0; i < se_num; i++) { - for (j = 0; j < sh_per_se; j++) { + for (i = 0; i < adev->gfx.config.max_shader_engines; i++) { + for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) { gfx_v8_0_select_se_sh(adev, i, j); - data = gfx_v8_0_get_rb_disabled(adev, - max_rb_num_per_se, sh_per_se); - disabled_rbs |= data << ((i * sh_per_se + j) * - RB_BITMAP_WIDTH_PER_SH); + data = gfx_v8_0_get_rb_active_bitmap(adev); + active_rbs |= data << ((i * adev->gfx.config.max_sh_per_se + j) * + rb_bitmap_width_per_sh); } } gfx_v8_0_select_se_sh(adev, 0xffffffff, 0xffffffff); mutex_unlock(&adev->grbm_idx_mutex); - mask = 1; - for (i = 0; i < max_rb_num_per_se * se_num; i++) { - if (!(disabled_rbs & mask)) - enabled_rbs |= mask; - mask <<= 1; - } - - adev->gfx.config.backend_enable_mask = enabled_rbs; - - mutex_lock(&adev->grbm_idx_mutex); - for (i = 0; i < se_num; i++) { - gfx_v8_0_select_se_sh(adev, i, 0xffffffff); - data = RREG32(mmPA_SC_RASTER_CONFIG); - for (j = 0; j < sh_per_se; j++) { - switch (enabled_rbs & 3) { - case 0: - if (j == 0) - data |= (RASTER_CONFIG_RB_MAP_3 << - PA_SC_RASTER_CONFIG__PKR_MAP__SHIFT); - else - data |= (RASTER_CONFIG_RB_MAP_0 << - PA_SC_RASTER_CONFIG__PKR_MAP__SHIFT); - break; - case 1: - data |= (RASTER_CONFIG_RB_MAP_0 << - (i * sh_per_se + j) * 2); - break; - case 2: - data |= (RASTER_CONFIG_RB_MAP_3 << - (i * sh_per_se + j) * 2); - break; - case 3: - default: - data |= (RASTER_CONFIG_RB_MAP_2 << - (i * sh_per_se + j) * 2); - break; - } - enabled_rbs >>= 2; - } - WREG32(mmPA_SC_RASTER_CONFIG, data); - } - gfx_v8_0_select_se_sh(adev, 0xffffffff, 0xffffffff); - mutex_unlock(&adev->grbm_idx_mutex); + adev->gfx.config.backend_enable_mask = active_rbs; + adev->gfx.config.num_rbs = hweight32(active_rbs); } /** @@ -2741,19 +2691,10 @@ static void gfx_v8_0_gpu_init(struct amdgpu_device *adev) WREG32(mmGB_ADDR_CONFIG, adev->gfx.config.gb_addr_config); WREG32(mmHDP_ADDR_CONFIG, adev->gfx.config.gb_addr_config); WREG32(mmDMIF_ADDR_CALC, adev->gfx.config.gb_addr_config); - WREG32(mmSDMA0_TILING_CONFIG + SDMA0_REGISTER_OFFSET, - adev->gfx.config.gb_addr_config & 0x70); - WREG32(mmSDMA0_TILING_CONFIG + SDMA1_REGISTER_OFFSET, - adev->gfx.config.gb_addr_config & 0x70); - WREG32(mmUVD_UDEC_ADDR_CONFIG, adev->gfx.config.gb_addr_config); - WREG32(mmUVD_UDEC_DB_ADDR_CONFIG, adev->gfx.config.gb_addr_config); - WREG32(mmUVD_UDEC_DBW_ADDR_CONFIG, adev->gfx.config.gb_addr_config); gfx_v8_0_tiling_mode_table_init(adev); - gfx_v8_0_setup_rb(adev, adev->gfx.config.max_shader_engines, - adev->gfx.config.max_sh_per_se, - adev->gfx.config.max_backends_per_se); + gfx_v8_0_setup_rb(adev); /* XXX SH_MEM regs */ /* where to put LDS, scratch, GPUVM in FSA64 space */ @@ -3062,7 +3003,7 @@ static int gfx_v8_0_cp_gfx_start(struct amdgpu_device *adev) gfx_v8_0_cp_gfx_enable(adev, true); - r = amdgpu_ring_lock(ring, gfx_v8_0_get_csb_size(adev) + 4); + r = amdgpu_ring_alloc(ring, gfx_v8_0_get_csb_size(adev) + 4); if (r) { DRM_ERROR("amdgpu: cp failed to lock ring (%d).\n", r); return r; @@ -3126,7 +3067,7 @@ static int gfx_v8_0_cp_gfx_start(struct amdgpu_device *adev) amdgpu_ring_write(ring, 0x8000); amdgpu_ring_write(ring, 0x8000); - amdgpu_ring_unlock_commit(ring); + amdgpu_ring_commit(ring); return 0; } @@ -3226,13 +3167,6 @@ static void gfx_v8_0_cp_compute_enable(struct amdgpu_device *adev, bool enable) udelay(50); } -static int gfx_v8_0_cp_compute_start(struct amdgpu_device *adev) -{ - gfx_v8_0_cp_compute_enable(adev, true); - - return 0; -} - static int gfx_v8_0_cp_compute_load_microcode(struct amdgpu_device *adev) { const struct gfx_firmware_header_v1_0 *mec_hdr; @@ -3802,9 +3736,7 @@ static int gfx_v8_0_cp_compute_resume(struct amdgpu_device *adev) WREG32(mmCP_PQ_STATUS, tmp); } - r = gfx_v8_0_cp_compute_start(adev); - if (r) - return r; + gfx_v8_0_cp_compute_enable(adev, true); for (i = 0; i < adev->gfx.num_compute_rings; i++) { struct amdgpu_ring *ring = &adev->gfx.compute_ring[i]; @@ -4016,16 +3948,6 @@ static void gfx_v8_0_print_status(void *handle) RREG32(mmHDP_ADDR_CONFIG)); dev_info(adev->dev, " DMIF_ADDR_CALC=0x%08X\n", RREG32(mmDMIF_ADDR_CALC)); - dev_info(adev->dev, " SDMA0_TILING_CONFIG=0x%08X\n", - RREG32(mmSDMA0_TILING_CONFIG + SDMA0_REGISTER_OFFSET)); - dev_info(adev->dev, " SDMA1_TILING_CONFIG=0x%08X\n", - RREG32(mmSDMA0_TILING_CONFIG + SDMA1_REGISTER_OFFSET)); - dev_info(adev->dev, " UVD_UDEC_ADDR_CONFIG=0x%08X\n", - RREG32(mmUVD_UDEC_ADDR_CONFIG)); - dev_info(adev->dev, " UVD_UDEC_DB_ADDR_CONFIG=0x%08X\n", - RREG32(mmUVD_UDEC_DB_ADDR_CONFIG)); - dev_info(adev->dev, " UVD_UDEC_DBW_ADDR_CONFIG=0x%08X\n", - RREG32(mmUVD_UDEC_DBW_ADDR_CONFIG)); dev_info(adev->dev, " CP_MEQ_THRESHOLDS=0x%08X\n", RREG32(mmCP_MEQ_THRESHOLDS)); @@ -4667,6 +4589,18 @@ static void gfx_v8_0_ring_emit_hdp_flush(struct amdgpu_ring *ring) amdgpu_ring_write(ring, 0x20); /* poll interval */ } +static void gfx_v8_0_ring_emit_hdp_invalidate(struct amdgpu_ring *ring) +{ + amdgpu_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); + amdgpu_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) | + WRITE_DATA_DST_SEL(0) | + WR_CONFIRM)); + amdgpu_ring_write(ring, mmHDP_DEBUG0); + amdgpu_ring_write(ring, 0); + amdgpu_ring_write(ring, 1); + +} + static void gfx_v8_0_ring_emit_ib_gfx(struct amdgpu_ring *ring, struct amdgpu_ib *ib) { @@ -4699,8 +4633,7 @@ static void gfx_v8_0_ring_emit_ib_gfx(struct amdgpu_ring *ring, else header = PACKET3(PACKET3_INDIRECT_BUFFER, 2); - control |= ib->length_dw | - (ib->vm ? (ib->vm->ids[ring->idx].id << 24) : 0); + control |= ib->length_dw | (ib->vm_id << 24); amdgpu_ring_write(ring, header); amdgpu_ring_write(ring, @@ -4729,8 +4662,7 @@ static void gfx_v8_0_ring_emit_ib_compute(struct amdgpu_ring *ring, header = PACKET3(PACKET3_INDIRECT_BUFFER, 2); - control |= ib->length_dw | - (ib->vm ? (ib->vm->ids[ring->idx].id << 24) : 0); + control |= ib->length_dw | (ib->vm_id << 24); amdgpu_ring_write(ring, header); amdgpu_ring_write(ring, @@ -4762,49 +4694,10 @@ static void gfx_v8_0_ring_emit_fence_gfx(struct amdgpu_ring *ring, u64 addr, } -/** - * gfx_v8_0_ring_emit_semaphore - emit a semaphore on the CP ring - * - * @ring: amdgpu ring buffer object - * @semaphore: amdgpu semaphore object - * @emit_wait: Is this a sempahore wait? - * - * Emits a semaphore signal/wait packet to the CP ring and prevents the PFP - * from running ahead of semaphore waits. - */ -static bool gfx_v8_0_ring_emit_semaphore(struct amdgpu_ring *ring, - struct amdgpu_semaphore *semaphore, - bool emit_wait) -{ - uint64_t addr = semaphore->gpu_addr; - unsigned sel = emit_wait ? PACKET3_SEM_SEL_WAIT : PACKET3_SEM_SEL_SIGNAL; - - if (ring->adev->asic_type == CHIP_TOPAZ || - ring->adev->asic_type == CHIP_TONGA || - ring->adev->asic_type == CHIP_FIJI) - /* we got a hw semaphore bug in VI TONGA, return false to switch back to sw fence wait */ - return false; - else { - amdgpu_ring_write(ring, PACKET3(PACKET3_MEM_SEMAPHORE, 2)); - amdgpu_ring_write(ring, lower_32_bits(addr)); - amdgpu_ring_write(ring, upper_32_bits(addr)); - amdgpu_ring_write(ring, sel); - } - - if (emit_wait && (ring->type == AMDGPU_RING_TYPE_GFX)) { - /* Prevent the PFP from running ahead of the semaphore wait */ - amdgpu_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); - amdgpu_ring_write(ring, 0x0); - } - - return true; -} - -static void gfx_v8_0_ring_emit_vm_flush(struct amdgpu_ring *ring, - unsigned vm_id, uint64_t pd_addr) +static void gfx_v8_0_ring_emit_pipeline_sync(struct amdgpu_ring *ring) { int usepfp = (ring->type == AMDGPU_RING_TYPE_GFX); - uint32_t seq = ring->fence_drv.sync_seq[ring->idx]; + uint32_t seq = ring->fence_drv.sync_seq; uint64_t addr = ring->fence_drv.gpu_addr; amdgpu_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5)); @@ -4824,6 +4717,12 @@ static void gfx_v8_0_ring_emit_vm_flush(struct amdgpu_ring *ring, amdgpu_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 0)); amdgpu_ring_write(ring, 0); } +} + +static void gfx_v8_0_ring_emit_vm_flush(struct amdgpu_ring *ring, + unsigned vm_id, uint64_t pd_addr) +{ + int usepfp = (ring->type == AMDGPU_RING_TYPE_GFX); amdgpu_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); amdgpu_ring_write(ring, (WRITE_DATA_ENGINE_SEL(usepfp) | @@ -5146,13 +5045,15 @@ static const struct amdgpu_ring_funcs gfx_v8_0_ring_funcs_gfx = { .parse_cs = NULL, .emit_ib = gfx_v8_0_ring_emit_ib_gfx, .emit_fence = gfx_v8_0_ring_emit_fence_gfx, - .emit_semaphore = gfx_v8_0_ring_emit_semaphore, + .emit_pipeline_sync = gfx_v8_0_ring_emit_pipeline_sync, .emit_vm_flush = gfx_v8_0_ring_emit_vm_flush, .emit_gds_switch = gfx_v8_0_ring_emit_gds_switch, .emit_hdp_flush = gfx_v8_0_ring_emit_hdp_flush, + .emit_hdp_invalidate = gfx_v8_0_ring_emit_hdp_invalidate, .test_ring = gfx_v8_0_ring_test_ring, .test_ib = gfx_v8_0_ring_test_ib, .insert_nop = amdgpu_ring_insert_nop, + .pad_ib = amdgpu_ring_generic_pad_ib, }; static const struct amdgpu_ring_funcs gfx_v8_0_ring_funcs_compute = { @@ -5162,13 +5063,15 @@ static const struct amdgpu_ring_funcs gfx_v8_0_ring_funcs_compute = { .parse_cs = NULL, .emit_ib = gfx_v8_0_ring_emit_ib_compute, .emit_fence = gfx_v8_0_ring_emit_fence_compute, - .emit_semaphore = gfx_v8_0_ring_emit_semaphore, + .emit_pipeline_sync = gfx_v8_0_ring_emit_pipeline_sync, .emit_vm_flush = gfx_v8_0_ring_emit_vm_flush, .emit_gds_switch = gfx_v8_0_ring_emit_gds_switch, .emit_hdp_flush = gfx_v8_0_ring_emit_hdp_flush, + .emit_hdp_invalidate = gfx_v8_0_ring_emit_hdp_invalidate, .test_ring = gfx_v8_0_ring_test_ring, .test_ib = gfx_v8_0_ring_test_ib, .insert_nop = amdgpu_ring_insert_nop, + .pad_ib = amdgpu_ring_generic_pad_ib, }; static void gfx_v8_0_set_ring_funcs(struct amdgpu_device *adev) @@ -5237,32 +5140,23 @@ static void gfx_v8_0_set_gds_init(struct amdgpu_device *adev) } } -static u32 gfx_v8_0_get_cu_active_bitmap(struct amdgpu_device *adev, - u32 se, u32 sh) +static u32 gfx_v8_0_get_cu_active_bitmap(struct amdgpu_device *adev) { - u32 mask = 0, tmp, tmp1; - int i; - - gfx_v8_0_select_se_sh(adev, se, sh); - tmp = RREG32(mmCC_GC_SHADER_ARRAY_CONFIG); - tmp1 = RREG32(mmGC_USER_SHADER_ARRAY_CONFIG); - gfx_v8_0_select_se_sh(adev, 0xffffffff, 0xffffffff); + u32 data, mask; - tmp &= 0xffff0000; + data = RREG32(mmCC_GC_SHADER_ARRAY_CONFIG); + data |= RREG32(mmGC_USER_SHADER_ARRAY_CONFIG); - tmp |= tmp1; - tmp >>= 16; + data &= CC_GC_SHADER_ARRAY_CONFIG__INACTIVE_CUS_MASK; + data >>= CC_GC_SHADER_ARRAY_CONFIG__INACTIVE_CUS__SHIFT; - for (i = 0; i < adev->gfx.config.max_cu_per_sh; i ++) { - mask <<= 1; - mask |= 1; - } + mask = gfx_v8_0_create_bitmask(adev->gfx.config.max_cu_per_sh); - return (~tmp) & mask; + return (~data) & mask; } int gfx_v8_0_get_cu_info(struct amdgpu_device *adev, - struct amdgpu_cu_info *cu_info) + struct amdgpu_cu_info *cu_info) { int i, j, k, counter, active_cu_number = 0; u32 mask, bitmap, ao_bitmap, ao_cu_mask = 0; @@ -5270,16 +5164,19 @@ int gfx_v8_0_get_cu_info(struct amdgpu_device *adev, if (!adev || !cu_info) return -EINVAL; + memset(cu_info, 0, sizeof(*cu_info)); + mutex_lock(&adev->grbm_idx_mutex); for (i = 0; i < adev->gfx.config.max_shader_engines; i++) { for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) { mask = 1; ao_bitmap = 0; counter = 0; - bitmap = gfx_v8_0_get_cu_active_bitmap(adev, i, j); + gfx_v8_0_select_se_sh(adev, i, j); + bitmap = gfx_v8_0_get_cu_active_bitmap(adev); cu_info->bitmap[i][j] = bitmap; - for (k = 0; k < adev->gfx.config.max_cu_per_sh; k ++) { + for (k = 0; k < 16; k ++) { if (bitmap & mask) { if (counter < 2) ao_bitmap |= mask; @@ -5291,9 +5188,11 @@ int gfx_v8_0_get_cu_info(struct amdgpu_device *adev, ao_cu_mask |= (ao_bitmap << (i * 16 + j * 8)); } } + gfx_v8_0_select_se_sh(adev, 0xffffffff, 0xffffffff); + mutex_unlock(&adev->grbm_idx_mutex); cu_info->number = active_cu_number; cu_info->ao_cu_mask = ao_cu_mask; - mutex_unlock(&adev->grbm_idx_mutex); + return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c index b8060795b27b96409a37ce213a3f6076127c7d71..05b0353d3880092271da1115007ae7ce91e4e69b 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c @@ -339,7 +339,7 @@ static void gmc_v7_0_mc_program(struct amdgpu_device *adev) WREG32(mmBIF_FB_EN, BIF_FB_EN__FB_READ_EN_MASK | BIF_FB_EN__FB_WRITE_EN_MASK); tmp = RREG32(mmHDP_MISC_CNTL); - tmp = REG_SET_FIELD(tmp, HDP_MISC_CNTL, FLUSH_INVALIDATE_CACHE, 1); + tmp = REG_SET_FIELD(tmp, HDP_MISC_CNTL, FLUSH_INVALIDATE_CACHE, 0); WREG32(mmHDP_MISC_CNTL, tmp); tmp = RREG32(mmHDP_HOST_PATH_CNTL); @@ -694,7 +694,8 @@ static int gmc_v7_0_vm_init(struct amdgpu_device *adev) * amdgpu graphics/compute will use VMIDs 1-7 * amdkfd will use VMIDs 8-15 */ - adev->vm_manager.nvm = AMDGPU_NUM_OF_VMIDS; + adev->vm_manager.num_ids = AMDGPU_NUM_OF_VMIDS; + amdgpu_vm_manager_init(adev); /* base offset of vram pages */ if (adev->flags & AMD_IS_APU) { @@ -902,14 +903,6 @@ static int gmc_v7_0_early_init(void *handle) gmc_v7_0_set_gart_funcs(adev); gmc_v7_0_set_irq_funcs(adev); - if (adev->flags & AMD_IS_APU) { - adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN; - } else { - u32 tmp = RREG32(mmMC_SEQ_MISC0); - tmp &= MC_SEQ_MISC0__MT__MASK; - adev->mc.vram_type = gmc_v7_0_convert_vram_type(tmp); - } - return 0; } @@ -926,9 +919,13 @@ static int gmc_v7_0_sw_init(void *handle) int dma_bits; struct amdgpu_device *adev = (struct amdgpu_device *)handle; - r = amdgpu_gem_init(adev); - if (r) - return r; + if (adev->flags & AMD_IS_APU) { + adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN; + } else { + u32 tmp = RREG32(mmMC_SEQ_MISC0); + tmp &= MC_SEQ_MISC0__MT__MASK; + adev->mc.vram_type = gmc_v7_0_convert_vram_type(tmp); + } r = amdgpu_irq_add_id(adev, 146, &adev->mc.vm_fault); if (r) @@ -1010,7 +1007,7 @@ static int gmc_v7_0_sw_fini(void *handle) adev->vm_manager.enabled = false; } gmc_v7_0_gart_fini(adev); - amdgpu_gem_fini(adev); + amdgpu_gem_force_release(adev); amdgpu_bo_fini(adev); return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c index 3efd45546241afc65e5d7db1fbc541fda946857b..02deb322940565baa6d1d3e3f648fe7cf152e6aa 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c @@ -252,6 +252,12 @@ static int gmc_v8_0_mc_load_microcode(struct amdgpu_device *adev) if (!adev->mc.fw) return -EINVAL; + /* Skip MC ucode loading on SR-IOV capable boards. + * vbios does this for us in asic_init in that case. + */ + if (adev->virtualization.supports_sr_iov) + return 0; + hdr = (const struct mc_firmware_header_v1_0 *)adev->mc.fw->data; amdgpu_ucode_print_mc_hdr(&hdr->header); @@ -380,7 +386,7 @@ static void gmc_v8_0_mc_program(struct amdgpu_device *adev) WREG32(mmBIF_FB_EN, BIF_FB_EN__FB_READ_EN_MASK | BIF_FB_EN__FB_WRITE_EN_MASK); tmp = RREG32(mmHDP_MISC_CNTL); - tmp = REG_SET_FIELD(tmp, HDP_MISC_CNTL, FLUSH_INVALIDATE_CACHE, 1); + tmp = REG_SET_FIELD(tmp, HDP_MISC_CNTL, FLUSH_INVALIDATE_CACHE, 0); WREG32(mmHDP_MISC_CNTL, tmp); tmp = RREG32(mmHDP_HOST_PATH_CNTL); @@ -774,7 +780,8 @@ static int gmc_v8_0_vm_init(struct amdgpu_device *adev) * amdgpu graphics/compute will use VMIDs 1-7 * amdkfd will use VMIDs 8-15 */ - adev->vm_manager.nvm = AMDGPU_NUM_OF_VMIDS; + adev->vm_manager.num_ids = AMDGPU_NUM_OF_VMIDS; + amdgpu_vm_manager_init(adev); /* base offset of vram pages */ if (adev->flags & AMD_IS_APU) { @@ -856,14 +863,6 @@ static int gmc_v8_0_early_init(void *handle) gmc_v8_0_set_gart_funcs(adev); gmc_v8_0_set_irq_funcs(adev); - if (adev->flags & AMD_IS_APU) { - adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN; - } else { - u32 tmp = RREG32(mmMC_SEQ_MISC0); - tmp &= MC_SEQ_MISC0__MT__MASK; - adev->mc.vram_type = gmc_v8_0_convert_vram_type(tmp); - } - return 0; } @@ -874,15 +873,26 @@ static int gmc_v8_0_late_init(void *handle) return amdgpu_irq_get(adev, &adev->mc.vm_fault, 0); } +#define mmMC_SEQ_MISC0_FIJI 0xA71 + static int gmc_v8_0_sw_init(void *handle) { int r; int dma_bits; struct amdgpu_device *adev = (struct amdgpu_device *)handle; - r = amdgpu_gem_init(adev); - if (r) - return r; + if (adev->flags & AMD_IS_APU) { + adev->mc.vram_type = AMDGPU_VRAM_TYPE_UNKNOWN; + } else { + u32 tmp; + + if (adev->asic_type == CHIP_FIJI) + tmp = RREG32(mmMC_SEQ_MISC0_FIJI); + else + tmp = RREG32(mmMC_SEQ_MISC0); + tmp &= MC_SEQ_MISC0__MT__MASK; + adev->mc.vram_type = gmc_v8_0_convert_vram_type(tmp); + } r = amdgpu_irq_add_id(adev, 146, &adev->mc.vm_fault); if (r) @@ -964,7 +974,7 @@ static int gmc_v8_0_sw_fini(void *handle) adev->vm_manager.enabled = false; } gmc_v8_0_gart_fini(adev); - amdgpu_gem_fini(adev); + amdgpu_gem_force_release(adev); amdgpu_bo_fini(adev); return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/iceland_smc.c b/drivers/gpu/drm/amd/amdgpu/iceland_smc.c index 090486c182497ba8de2aaa7840242be9cf4750aa..52ee08193295f434c46fb7f89e082b20df46abfd 100644 --- a/drivers/gpu/drm/amd/amdgpu/iceland_smc.c +++ b/drivers/gpu/drm/amd/amdgpu/iceland_smc.c @@ -279,6 +279,12 @@ static int iceland_smu_upload_firmware_image(struct amdgpu_device *adev) if (!adev->pm.fw) return -EINVAL; + /* Skip SMC ucode loading on SR-IOV capable boards. + * vbios does this for us in asic_init in that case. + */ + if (adev->virtualization.supports_sr_iov) + return 0; + hdr = (const struct smc_firmware_header_v1_0 *)adev->pm.fw->data; amdgpu_ucode_print_smc_hdr(&hdr->header); diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c index 2cf50180cc51bd496289feb892a2a56b6d81abe0..6e0a86a563f3e8d35e7bf907bdaaa845aca5d55c 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c @@ -32,8 +32,8 @@ #include "oss/oss_2_4_d.h" #include "oss/oss_2_4_sh_mask.h" -#include "gmc/gmc_8_1_d.h" -#include "gmc/gmc_8_1_sh_mask.h" +#include "gmc/gmc_7_1_d.h" +#include "gmc/gmc_7_1_sh_mask.h" #include "gca/gfx_8_0_d.h" #include "gca/gfx_8_0_enum.h" @@ -244,7 +244,7 @@ static void sdma_v2_4_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count) static void sdma_v2_4_ring_emit_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib) { - u32 vmid = (ib->vm ? ib->vm->ids[ring->idx].id : 0) & 0xf; + u32 vmid = ib->vm_id & 0xf; u32 next_rptr = ring->wptr + 5; while ((next_rptr & 7) != 2) @@ -300,6 +300,13 @@ static void sdma_v2_4_ring_emit_hdp_flush(struct amdgpu_ring *ring) SDMA_PKT_POLL_REGMEM_DW5_INTERVAL(10)); /* retry count, poll interval */ } +static void sdma_v2_4_ring_emit_hdp_invalidate(struct amdgpu_ring *ring) +{ + amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_SRBM_WRITE) | + SDMA_PKT_SRBM_WRITE_HEADER_BYTE_EN(0xf)); + amdgpu_ring_write(ring, mmHDP_DEBUG0); + amdgpu_ring_write(ring, 1); +} /** * sdma_v2_4_ring_emit_fence - emit a fence on the DMA ring * @@ -334,31 +341,6 @@ static void sdma_v2_4_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 se amdgpu_ring_write(ring, SDMA_PKT_TRAP_INT_CONTEXT_INT_CONTEXT(0)); } -/** - * sdma_v2_4_ring_emit_semaphore - emit a semaphore on the dma ring - * - * @ring: amdgpu_ring structure holding ring information - * @semaphore: amdgpu semaphore object - * @emit_wait: wait or signal semaphore - * - * Add a DMA semaphore packet to the ring wait on or signal - * other rings (VI). - */ -static bool sdma_v2_4_ring_emit_semaphore(struct amdgpu_ring *ring, - struct amdgpu_semaphore *semaphore, - bool emit_wait) -{ - u64 addr = semaphore->gpu_addr; - u32 sig = emit_wait ? 0 : 1; - - amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_SEM) | - SDMA_PKT_SEMAPHORE_HEADER_SIGNAL(sig)); - amdgpu_ring_write(ring, lower_32_bits(addr) & 0xfffffff8); - amdgpu_ring_write(ring, upper_32_bits(addr)); - - return true; -} - /** * sdma_v2_4_gfx_stop - stop the gfx async dma engines * @@ -459,6 +441,9 @@ static int sdma_v2_4_gfx_resume(struct amdgpu_device *adev) vi_srbm_select(adev, 0, 0, 0, 0); mutex_unlock(&adev->srbm_mutex); + WREG32(mmSDMA0_TILING_CONFIG + sdma_offsets[i], + adev->gfx.config.gb_addr_config & 0x70); + WREG32(mmSDMA0_SEM_WAIT_FAIL_TIMER_CNTL + sdma_offsets[i], 0); /* Set ring buffer size in dwords */ @@ -636,7 +621,7 @@ static int sdma_v2_4_ring_test_ring(struct amdgpu_ring *ring) tmp = 0xCAFEDEAD; adev->wb.wb[index] = cpu_to_le32(tmp); - r = amdgpu_ring_lock(ring, 5); + r = amdgpu_ring_alloc(ring, 5); if (r) { DRM_ERROR("amdgpu: dma failed to lock ring %d (%d).\n", ring->idx, r); amdgpu_wb_free(adev, index); @@ -649,7 +634,7 @@ static int sdma_v2_4_ring_test_ring(struct amdgpu_ring *ring) amdgpu_ring_write(ring, upper_32_bits(gpu_addr)); amdgpu_ring_write(ring, SDMA_PKT_WRITE_UNTILED_DW_3_COUNT(1)); amdgpu_ring_write(ring, 0xDEADBEEF); - amdgpu_ring_unlock_commit(ring); + amdgpu_ring_commit(ring); for (i = 0; i < adev->usec_timeout; i++) { tmp = le32_to_cpu(adev->wb.wb[index]); @@ -699,7 +684,7 @@ static int sdma_v2_4_ring_test_ib(struct amdgpu_ring *ring) tmp = 0xCAFEDEAD; adev->wb.wb[index] = cpu_to_le32(tmp); memset(&ib, 0, sizeof(ib)); - r = amdgpu_ib_get(ring, NULL, 256, &ib); + r = amdgpu_ib_get(adev, NULL, 256, &ib); if (r) { DRM_ERROR("amdgpu: failed to get ib (%d).\n", r); goto err0; @@ -716,9 +701,7 @@ static int sdma_v2_4_ring_test_ib(struct amdgpu_ring *ring) ib.ptr[7] = SDMA_PKT_HEADER_OP(SDMA_OP_NOP); ib.length_dw = 8; - r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, &ib, 1, NULL, - AMDGPU_FENCE_OWNER_UNDEFINED, - &f); + r = amdgpu_ib_schedule(ring, 1, &ib, NULL, &f); if (r) goto err1; @@ -744,7 +727,8 @@ static int sdma_v2_4_ring_test_ib(struct amdgpu_ring *ring) err1: fence_put(f); - amdgpu_ib_free(adev, &ib); + amdgpu_ib_free(adev, &ib, NULL); + fence_put(f); err0: amdgpu_wb_free(adev, index); return r; @@ -797,7 +781,7 @@ static void sdma_v2_4_vm_copy_pte(struct amdgpu_ib *ib, * Update PTEs by writing them manually using sDMA (CIK). */ static void sdma_v2_4_vm_write_pte(struct amdgpu_ib *ib, - uint64_t pe, + const dma_addr_t *pages_addr, uint64_t pe, uint64_t addr, unsigned count, uint32_t incr, uint32_t flags) { @@ -816,14 +800,7 @@ static void sdma_v2_4_vm_write_pte(struct amdgpu_ib *ib, ib->ptr[ib->length_dw++] = upper_32_bits(pe); ib->ptr[ib->length_dw++] = ndw; for (; ndw > 0; ndw -= 2, --count, pe += 8) { - if (flags & AMDGPU_PTE_SYSTEM) { - value = amdgpu_vm_map_gart(ib->ring->adev, addr); - value &= 0xFFFFFFFFFFFFF000ULL; - } else if (flags & AMDGPU_PTE_VALID) { - value = addr; - } else { - value = 0; - } + value = amdgpu_vm_map_gart(pages_addr, addr); addr += incr; value |= flags; ib->ptr[ib->length_dw++] = value; @@ -881,14 +858,14 @@ static void sdma_v2_4_vm_set_pte_pde(struct amdgpu_ib *ib, } /** - * sdma_v2_4_vm_pad_ib - pad the IB to the required number of dw + * sdma_v2_4_ring_pad_ib - pad the IB to the required number of dw * * @ib: indirect buffer to fill with padding * */ -static void sdma_v2_4_vm_pad_ib(struct amdgpu_ib *ib) +static void sdma_v2_4_ring_pad_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib) { - struct amdgpu_sdma_instance *sdma = amdgpu_get_sdma_instance(ib->ring); + struct amdgpu_sdma_instance *sdma = amdgpu_get_sdma_instance(ring); u32 pad_count; int i; @@ -903,6 +880,31 @@ static void sdma_v2_4_vm_pad_ib(struct amdgpu_ib *ib) SDMA_PKT_HEADER_OP(SDMA_OP_NOP); } +/** + * sdma_v2_4_ring_emit_pipeline_sync - sync the pipeline + * + * @ring: amdgpu_ring pointer + * + * Make sure all previous operations are completed (CIK). + */ +static void sdma_v2_4_ring_emit_pipeline_sync(struct amdgpu_ring *ring) +{ + uint32_t seq = ring->fence_drv.sync_seq; + uint64_t addr = ring->fence_drv.gpu_addr; + + /* wait for idle */ + amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_POLL_REGMEM) | + SDMA_PKT_POLL_REGMEM_HEADER_HDP_FLUSH(0) | + SDMA_PKT_POLL_REGMEM_HEADER_FUNC(3) | /* equal */ + SDMA_PKT_POLL_REGMEM_HEADER_MEM_POLL(1)); + amdgpu_ring_write(ring, addr & 0xfffffffc); + amdgpu_ring_write(ring, upper_32_bits(addr) & 0xffffffff); + amdgpu_ring_write(ring, seq); /* reference */ + amdgpu_ring_write(ring, 0xfffffff); /* mask */ + amdgpu_ring_write(ring, SDMA_PKT_POLL_REGMEM_DW5_RETRY_COUNT(0xfff) | + SDMA_PKT_POLL_REGMEM_DW5_INTERVAL(4)); /* retry count, poll interval */ +} + /** * sdma_v2_4_ring_emit_vm_flush - cik vm flush using sDMA * @@ -1111,6 +1113,8 @@ static void sdma_v2_4_print_status(void *handle) i, RREG32(mmSDMA0_GFX_RB_BASE + sdma_offsets[i])); dev_info(adev->dev, " SDMA%d_GFX_RB_BASE_HI=0x%08X\n", i, RREG32(mmSDMA0_GFX_RB_BASE_HI + sdma_offsets[i])); + dev_info(adev->dev, " SDMA%d_TILING_CONFIG=0x%08X\n", + i, RREG32(mmSDMA0_TILING_CONFIG + sdma_offsets[i])); mutex_lock(&adev->srbm_mutex); for (j = 0; j < 16; j++) { vi_srbm_select(adev, 0, 0, 0, j); @@ -1302,12 +1306,14 @@ static const struct amdgpu_ring_funcs sdma_v2_4_ring_funcs = { .parse_cs = NULL, .emit_ib = sdma_v2_4_ring_emit_ib, .emit_fence = sdma_v2_4_ring_emit_fence, - .emit_semaphore = sdma_v2_4_ring_emit_semaphore, + .emit_pipeline_sync = sdma_v2_4_ring_emit_pipeline_sync, .emit_vm_flush = sdma_v2_4_ring_emit_vm_flush, .emit_hdp_flush = sdma_v2_4_ring_emit_hdp_flush, + .emit_hdp_invalidate = sdma_v2_4_ring_emit_hdp_invalidate, .test_ring = sdma_v2_4_ring_test_ring, .test_ib = sdma_v2_4_ring_test_ib, .insert_nop = sdma_v2_4_ring_insert_nop, + .pad_ib = sdma_v2_4_ring_pad_ib, }; static void sdma_v2_4_set_ring_funcs(struct amdgpu_device *adev) @@ -1405,14 +1411,18 @@ static const struct amdgpu_vm_pte_funcs sdma_v2_4_vm_pte_funcs = { .copy_pte = sdma_v2_4_vm_copy_pte, .write_pte = sdma_v2_4_vm_write_pte, .set_pte_pde = sdma_v2_4_vm_set_pte_pde, - .pad_ib = sdma_v2_4_vm_pad_ib, }; static void sdma_v2_4_set_vm_pte_funcs(struct amdgpu_device *adev) { + unsigned i; + if (adev->vm_manager.vm_pte_funcs == NULL) { adev->vm_manager.vm_pte_funcs = &sdma_v2_4_vm_pte_funcs; - adev->vm_manager.vm_pte_funcs_ring = &adev->sdma.instance[0].ring; - adev->vm_manager.vm_pte_funcs_ring->is_pte_ring = true; + for (i = 0; i < adev->sdma.num_instances; i++) + adev->vm_manager.vm_pte_rings[i] = + &adev->sdma.instance[i].ring; + + adev->vm_manager.vm_pte_num_rings = adev->sdma.num_instances; } } diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c index ad54c46751b00b3133599ee8bbf47da3afdd93e1..8c8ca98dd1298af2a1e7b397eb8f9d964e4b81fe 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c @@ -355,7 +355,7 @@ static void sdma_v3_0_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count) static void sdma_v3_0_ring_emit_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib) { - u32 vmid = (ib->vm ? ib->vm->ids[ring->idx].id : 0) & 0xf; + u32 vmid = ib->vm_id & 0xf; u32 next_rptr = ring->wptr + 5; while ((next_rptr & 7) != 2) @@ -410,6 +410,14 @@ static void sdma_v3_0_ring_emit_hdp_flush(struct amdgpu_ring *ring) SDMA_PKT_POLL_REGMEM_DW5_INTERVAL(10)); /* retry count, poll interval */ } +static void sdma_v3_0_ring_emit_hdp_invalidate(struct amdgpu_ring *ring) +{ + amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_SRBM_WRITE) | + SDMA_PKT_SRBM_WRITE_HEADER_BYTE_EN(0xf)); + amdgpu_ring_write(ring, mmHDP_DEBUG0); + amdgpu_ring_write(ring, 1); +} + /** * sdma_v3_0_ring_emit_fence - emit a fence on the DMA ring * @@ -444,32 +452,6 @@ static void sdma_v3_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 se amdgpu_ring_write(ring, SDMA_PKT_TRAP_INT_CONTEXT_INT_CONTEXT(0)); } - -/** - * sdma_v3_0_ring_emit_semaphore - emit a semaphore on the dma ring - * - * @ring: amdgpu_ring structure holding ring information - * @semaphore: amdgpu semaphore object - * @emit_wait: wait or signal semaphore - * - * Add a DMA semaphore packet to the ring wait on or signal - * other rings (VI). - */ -static bool sdma_v3_0_ring_emit_semaphore(struct amdgpu_ring *ring, - struct amdgpu_semaphore *semaphore, - bool emit_wait) -{ - u64 addr = semaphore->gpu_addr; - u32 sig = emit_wait ? 0 : 1; - - amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_SEM) | - SDMA_PKT_SEMAPHORE_HEADER_SIGNAL(sig)); - amdgpu_ring_write(ring, lower_32_bits(addr) & 0xfffffff8); - amdgpu_ring_write(ring, upper_32_bits(addr)); - - return true; -} - /** * sdma_v3_0_gfx_stop - stop the gfx async dma engines * @@ -596,6 +578,9 @@ static int sdma_v3_0_gfx_resume(struct amdgpu_device *adev) vi_srbm_select(adev, 0, 0, 0, 0); mutex_unlock(&adev->srbm_mutex); + WREG32(mmSDMA0_TILING_CONFIG + sdma_offsets[i], + adev->gfx.config.gb_addr_config & 0x70); + WREG32(mmSDMA0_SEM_WAIT_FAIL_TIMER_CNTL + sdma_offsets[i], 0); /* Set ring buffer size in dwords */ @@ -788,7 +773,7 @@ static int sdma_v3_0_ring_test_ring(struct amdgpu_ring *ring) tmp = 0xCAFEDEAD; adev->wb.wb[index] = cpu_to_le32(tmp); - r = amdgpu_ring_lock(ring, 5); + r = amdgpu_ring_alloc(ring, 5); if (r) { DRM_ERROR("amdgpu: dma failed to lock ring %d (%d).\n", ring->idx, r); amdgpu_wb_free(adev, index); @@ -801,7 +786,7 @@ static int sdma_v3_0_ring_test_ring(struct amdgpu_ring *ring) amdgpu_ring_write(ring, upper_32_bits(gpu_addr)); amdgpu_ring_write(ring, SDMA_PKT_WRITE_UNTILED_DW_3_COUNT(1)); amdgpu_ring_write(ring, 0xDEADBEEF); - amdgpu_ring_unlock_commit(ring); + amdgpu_ring_commit(ring); for (i = 0; i < adev->usec_timeout; i++) { tmp = le32_to_cpu(adev->wb.wb[index]); @@ -851,7 +836,7 @@ static int sdma_v3_0_ring_test_ib(struct amdgpu_ring *ring) tmp = 0xCAFEDEAD; adev->wb.wb[index] = cpu_to_le32(tmp); memset(&ib, 0, sizeof(ib)); - r = amdgpu_ib_get(ring, NULL, 256, &ib); + r = amdgpu_ib_get(adev, NULL, 256, &ib); if (r) { DRM_ERROR("amdgpu: failed to get ib (%d).\n", r); goto err0; @@ -868,9 +853,7 @@ static int sdma_v3_0_ring_test_ib(struct amdgpu_ring *ring) ib.ptr[7] = SDMA_PKT_NOP_HEADER_OP(SDMA_OP_NOP); ib.length_dw = 8; - r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, &ib, 1, NULL, - AMDGPU_FENCE_OWNER_UNDEFINED, - &f); + r = amdgpu_ib_schedule(ring, 1, &ib, NULL, &f); if (r) goto err1; @@ -895,7 +878,8 @@ static int sdma_v3_0_ring_test_ib(struct amdgpu_ring *ring) } err1: fence_put(f); - amdgpu_ib_free(adev, &ib); + amdgpu_ib_free(adev, &ib, NULL); + fence_put(f); err0: amdgpu_wb_free(adev, index); return r; @@ -948,7 +932,7 @@ static void sdma_v3_0_vm_copy_pte(struct amdgpu_ib *ib, * Update PTEs by writing them manually using sDMA (CIK). */ static void sdma_v3_0_vm_write_pte(struct amdgpu_ib *ib, - uint64_t pe, + const dma_addr_t *pages_addr, uint64_t pe, uint64_t addr, unsigned count, uint32_t incr, uint32_t flags) { @@ -967,14 +951,7 @@ static void sdma_v3_0_vm_write_pte(struct amdgpu_ib *ib, ib->ptr[ib->length_dw++] = upper_32_bits(pe); ib->ptr[ib->length_dw++] = ndw; for (; ndw > 0; ndw -= 2, --count, pe += 8) { - if (flags & AMDGPU_PTE_SYSTEM) { - value = amdgpu_vm_map_gart(ib->ring->adev, addr); - value &= 0xFFFFFFFFFFFFF000ULL; - } else if (flags & AMDGPU_PTE_VALID) { - value = addr; - } else { - value = 0; - } + value = amdgpu_vm_map_gart(pages_addr, addr); addr += incr; value |= flags; ib->ptr[ib->length_dw++] = value; @@ -1032,14 +1009,14 @@ static void sdma_v3_0_vm_set_pte_pde(struct amdgpu_ib *ib, } /** - * sdma_v3_0_vm_pad_ib - pad the IB to the required number of dw + * sdma_v3_0_ring_pad_ib - pad the IB to the required number of dw * * @ib: indirect buffer to fill with padding * */ -static void sdma_v3_0_vm_pad_ib(struct amdgpu_ib *ib) +static void sdma_v3_0_ring_pad_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib) { - struct amdgpu_sdma_instance *sdma = amdgpu_get_sdma_instance(ib->ring); + struct amdgpu_sdma_instance *sdma = amdgpu_get_sdma_instance(ring); u32 pad_count; int i; @@ -1054,6 +1031,31 @@ static void sdma_v3_0_vm_pad_ib(struct amdgpu_ib *ib) SDMA_PKT_HEADER_OP(SDMA_OP_NOP); } +/** + * sdma_v3_0_ring_emit_pipeline_sync - sync the pipeline + * + * @ring: amdgpu_ring pointer + * + * Make sure all previous operations are completed (CIK). + */ +static void sdma_v3_0_ring_emit_pipeline_sync(struct amdgpu_ring *ring) +{ + uint32_t seq = ring->fence_drv.sync_seq; + uint64_t addr = ring->fence_drv.gpu_addr; + + /* wait for idle */ + amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_POLL_REGMEM) | + SDMA_PKT_POLL_REGMEM_HEADER_HDP_FLUSH(0) | + SDMA_PKT_POLL_REGMEM_HEADER_FUNC(3) | /* equal */ + SDMA_PKT_POLL_REGMEM_HEADER_MEM_POLL(1)); + amdgpu_ring_write(ring, addr & 0xfffffffc); + amdgpu_ring_write(ring, upper_32_bits(addr) & 0xffffffff); + amdgpu_ring_write(ring, seq); /* reference */ + amdgpu_ring_write(ring, 0xfffffff); /* mask */ + amdgpu_ring_write(ring, SDMA_PKT_POLL_REGMEM_DW5_RETRY_COUNT(0xfff) | + SDMA_PKT_POLL_REGMEM_DW5_INTERVAL(4)); /* retry count, poll interval */ +} + /** * sdma_v3_0_ring_emit_vm_flush - cik vm flush using sDMA * @@ -1275,6 +1277,8 @@ static void sdma_v3_0_print_status(void *handle) i, RREG32(mmSDMA0_GFX_RB_BASE_HI + sdma_offsets[i])); dev_info(adev->dev, " SDMA%d_GFX_DOORBELL=0x%08X\n", i, RREG32(mmSDMA0_GFX_DOORBELL + sdma_offsets[i])); + dev_info(adev->dev, " SDMA%d_TILING_CONFIG=0x%08X\n", + i, RREG32(mmSDMA0_TILING_CONFIG + sdma_offsets[i])); mutex_lock(&adev->srbm_mutex); for (j = 0; j < 16; j++) { vi_srbm_select(adev, 0, 0, 0, j); @@ -1570,12 +1574,14 @@ static const struct amdgpu_ring_funcs sdma_v3_0_ring_funcs = { .parse_cs = NULL, .emit_ib = sdma_v3_0_ring_emit_ib, .emit_fence = sdma_v3_0_ring_emit_fence, - .emit_semaphore = sdma_v3_0_ring_emit_semaphore, + .emit_pipeline_sync = sdma_v3_0_ring_emit_pipeline_sync, .emit_vm_flush = sdma_v3_0_ring_emit_vm_flush, .emit_hdp_flush = sdma_v3_0_ring_emit_hdp_flush, + .emit_hdp_invalidate = sdma_v3_0_ring_emit_hdp_invalidate, .test_ring = sdma_v3_0_ring_test_ring, .test_ib = sdma_v3_0_ring_test_ib, .insert_nop = sdma_v3_0_ring_insert_nop, + .pad_ib = sdma_v3_0_ring_pad_ib, }; static void sdma_v3_0_set_ring_funcs(struct amdgpu_device *adev) @@ -1673,14 +1679,18 @@ static const struct amdgpu_vm_pte_funcs sdma_v3_0_vm_pte_funcs = { .copy_pte = sdma_v3_0_vm_copy_pte, .write_pte = sdma_v3_0_vm_write_pte, .set_pte_pde = sdma_v3_0_vm_set_pte_pde, - .pad_ib = sdma_v3_0_vm_pad_ib, }; static void sdma_v3_0_set_vm_pte_funcs(struct amdgpu_device *adev) { + unsigned i; + if (adev->vm_manager.vm_pte_funcs == NULL) { adev->vm_manager.vm_pte_funcs = &sdma_v3_0_vm_pte_funcs; - adev->vm_manager.vm_pte_funcs_ring = &adev->sdma.instance[0].ring; - adev->vm_manager.vm_pte_funcs_ring->is_pte_ring = true; + for (i = 0; i < adev->sdma.num_instances; i++) + adev->vm_manager.vm_pte_rings[i] = + &adev->sdma.instance[i].ring; + + adev->vm_manager.vm_pte_num_rings = adev->sdma.num_instances; } } diff --git a/drivers/gpu/drm/amd/amdgpu/tonga_smc.c b/drivers/gpu/drm/amd/amdgpu/tonga_smc.c index 361c49a8232305194af12c1aaa9ec00971f92b30..083893dd68c063db6059fee335a8667247132b14 100644 --- a/drivers/gpu/drm/amd/amdgpu/tonga_smc.c +++ b/drivers/gpu/drm/amd/amdgpu/tonga_smc.c @@ -272,6 +272,12 @@ static int tonga_smu_upload_firmware_image(struct amdgpu_device *adev) if (!adev->pm.fw) return -EINVAL; + /* Skip SMC ucode loading on SR-IOV capable boards. + * vbios does this for us in asic_init in that case. + */ + if (adev->virtualization.supports_sr_iov) + return 0; + hdr = (const struct smc_firmware_header_v1_0 *)adev->pm.fw->data; amdgpu_ucode_print_smc_hdr(&hdr->header); diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c index fbd3767671bb9266d68ac6229a41194aa5a184ac..cb463753115b8d4f8266464a9d69956be21a5750 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c @@ -164,7 +164,7 @@ static int uvd_v4_2_hw_init(void *handle) goto done; } - r = amdgpu_ring_lock(ring, 10); + r = amdgpu_ring_alloc(ring, 10); if (r) { DRM_ERROR("amdgpu: ring failed to lock UVD ring (%d).\n", r); goto done; @@ -189,7 +189,7 @@ static int uvd_v4_2_hw_init(void *handle) amdgpu_ring_write(ring, PACKET0(mmUVD_SEMA_CNTL, 0)); amdgpu_ring_write(ring, 3); - amdgpu_ring_unlock_commit(ring); + amdgpu_ring_commit(ring); done: /* lower clocks again */ @@ -224,11 +224,11 @@ static int uvd_v4_2_suspend(void *handle) int r; struct amdgpu_device *adev = (struct amdgpu_device *)handle; - r = amdgpu_uvd_suspend(adev); + r = uvd_v4_2_hw_fini(adev); if (r) return r; - r = uvd_v4_2_hw_fini(adev); + r = amdgpu_uvd_suspend(adev); if (r) return r; @@ -438,33 +438,6 @@ static void uvd_v4_2_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq amdgpu_ring_write(ring, 2); } -/** - * uvd_v4_2_ring_emit_semaphore - emit semaphore command - * - * @ring: amdgpu_ring pointer - * @semaphore: semaphore to emit commands for - * @emit_wait: true if we should emit a wait command - * - * Emit a semaphore command (either wait or signal) to the UVD ring. - */ -static bool uvd_v4_2_ring_emit_semaphore(struct amdgpu_ring *ring, - struct amdgpu_semaphore *semaphore, - bool emit_wait) -{ - uint64_t addr = semaphore->gpu_addr; - - amdgpu_ring_write(ring, PACKET0(mmUVD_SEMA_ADDR_LOW, 0)); - amdgpu_ring_write(ring, (addr >> 3) & 0x000FFFFF); - - amdgpu_ring_write(ring, PACKET0(mmUVD_SEMA_ADDR_HIGH, 0)); - amdgpu_ring_write(ring, (addr >> 23) & 0x000FFFFF); - - amdgpu_ring_write(ring, PACKET0(mmUVD_SEMA_CMD, 0)); - amdgpu_ring_write(ring, 0x80 | (emit_wait ? 1 : 0)); - - return true; -} - /** * uvd_v4_2_ring_test_ring - register write test * @@ -480,7 +453,7 @@ static int uvd_v4_2_ring_test_ring(struct amdgpu_ring *ring) int r; WREG32(mmUVD_CONTEXT_ID, 0xCAFEDEAD); - r = amdgpu_ring_lock(ring, 3); + r = amdgpu_ring_alloc(ring, 3); if (r) { DRM_ERROR("amdgpu: cp failed to lock ring %d (%d).\n", ring->idx, r); @@ -488,7 +461,7 @@ static int uvd_v4_2_ring_test_ring(struct amdgpu_ring *ring) } amdgpu_ring_write(ring, PACKET0(mmUVD_CONTEXT_ID, 0)); amdgpu_ring_write(ring, 0xDEADBEEF); - amdgpu_ring_unlock_commit(ring); + amdgpu_ring_commit(ring); for (i = 0; i < adev->usec_timeout; i++) { tmp = RREG32(mmUVD_CONTEXT_ID); if (tmp == 0xDEADBEEF) @@ -549,7 +522,7 @@ static int uvd_v4_2_ring_test_ib(struct amdgpu_ring *ring) goto error; } - r = amdgpu_uvd_get_destroy_msg(ring, 1, &fence); + r = amdgpu_uvd_get_destroy_msg(ring, 1, true, &fence); if (r) { DRM_ERROR("amdgpu: failed to get destroy ib (%d).\n", r); goto error; @@ -603,6 +576,10 @@ static void uvd_v4_2_mc_resume(struct amdgpu_device *adev) addr = (adev->uvd.gpu_addr >> 32) & 0xFF; WREG32(mmUVD_LMI_EXT40_ADDR, addr | (0x9 << 16) | (0x1 << 31)); + WREG32(mmUVD_UDEC_ADDR_CONFIG, adev->gfx.config.gb_addr_config); + WREG32(mmUVD_UDEC_DB_ADDR_CONFIG, adev->gfx.config.gb_addr_config); + WREG32(mmUVD_UDEC_DBW_ADDR_CONFIG, adev->gfx.config.gb_addr_config); + uvd_v4_2_init_cg(adev); } @@ -804,6 +781,13 @@ static void uvd_v4_2_print_status(void *handle) RREG32(mmUVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL)); dev_info(adev->dev, " UVD_CONTEXT_ID=0x%08X\n", RREG32(mmUVD_CONTEXT_ID)); + dev_info(adev->dev, " UVD_UDEC_ADDR_CONFIG=0x%08X\n", + RREG32(mmUVD_UDEC_ADDR_CONFIG)); + dev_info(adev->dev, " UVD_UDEC_DB_ADDR_CONFIG=0x%08X\n", + RREG32(mmUVD_UDEC_DB_ADDR_CONFIG)); + dev_info(adev->dev, " UVD_UDEC_DBW_ADDR_CONFIG=0x%08X\n", + RREG32(mmUVD_UDEC_DBW_ADDR_CONFIG)); + } static int uvd_v4_2_set_interrupt_state(struct amdgpu_device *adev, @@ -888,10 +872,10 @@ static const struct amdgpu_ring_funcs uvd_v4_2_ring_funcs = { .parse_cs = amdgpu_uvd_ring_parse_cs, .emit_ib = uvd_v4_2_ring_emit_ib, .emit_fence = uvd_v4_2_ring_emit_fence, - .emit_semaphore = uvd_v4_2_ring_emit_semaphore, .test_ring = uvd_v4_2_ring_test_ring, .test_ib = uvd_v4_2_ring_test_ib, .insert_nop = amdgpu_ring_insert_nop, + .pad_ib = amdgpu_ring_generic_pad_ib, }; static void uvd_v4_2_set_ring_funcs(struct amdgpu_device *adev) diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c index 57f1c5bf3bf19a107c2c35d1b9fb653e2d37ac8d..16476d80f475a77c17ae4bb8a5f60aa05c4562c8 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c @@ -160,7 +160,7 @@ static int uvd_v5_0_hw_init(void *handle) goto done; } - r = amdgpu_ring_lock(ring, 10); + r = amdgpu_ring_alloc(ring, 10); if (r) { DRM_ERROR("amdgpu: ring failed to lock UVD ring (%d).\n", r); goto done; @@ -185,7 +185,7 @@ static int uvd_v5_0_hw_init(void *handle) amdgpu_ring_write(ring, PACKET0(mmUVD_SEMA_CNTL, 0)); amdgpu_ring_write(ring, 3); - amdgpu_ring_unlock_commit(ring); + amdgpu_ring_commit(ring); done: /* lower clocks again */ @@ -220,11 +220,11 @@ static int uvd_v5_0_suspend(void *handle) int r; struct amdgpu_device *adev = (struct amdgpu_device *)handle; - r = amdgpu_uvd_suspend(adev); + r = uvd_v5_0_hw_fini(adev); if (r) return r; - r = uvd_v5_0_hw_fini(adev); + r = amdgpu_uvd_suspend(adev); if (r) return r; @@ -279,6 +279,10 @@ static void uvd_v5_0_mc_resume(struct amdgpu_device *adev) size = AMDGPU_UVD_HEAP_SIZE; WREG32(mmUVD_VCPU_CACHE_OFFSET2, offset >> 3); WREG32(mmUVD_VCPU_CACHE_SIZE2, size); + + WREG32(mmUVD_UDEC_ADDR_CONFIG, adev->gfx.config.gb_addr_config); + WREG32(mmUVD_UDEC_DB_ADDR_CONFIG, adev->gfx.config.gb_addr_config); + WREG32(mmUVD_UDEC_DBW_ADDR_CONFIG, adev->gfx.config.gb_addr_config); } /** @@ -482,33 +486,6 @@ static void uvd_v5_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq amdgpu_ring_write(ring, 2); } -/** - * uvd_v5_0_ring_emit_semaphore - emit semaphore command - * - * @ring: amdgpu_ring pointer - * @semaphore: semaphore to emit commands for - * @emit_wait: true if we should emit a wait command - * - * Emit a semaphore command (either wait or signal) to the UVD ring. - */ -static bool uvd_v5_0_ring_emit_semaphore(struct amdgpu_ring *ring, - struct amdgpu_semaphore *semaphore, - bool emit_wait) -{ - uint64_t addr = semaphore->gpu_addr; - - amdgpu_ring_write(ring, PACKET0(mmUVD_SEMA_ADDR_LOW, 0)); - amdgpu_ring_write(ring, (addr >> 3) & 0x000FFFFF); - - amdgpu_ring_write(ring, PACKET0(mmUVD_SEMA_ADDR_HIGH, 0)); - amdgpu_ring_write(ring, (addr >> 23) & 0x000FFFFF); - - amdgpu_ring_write(ring, PACKET0(mmUVD_SEMA_CMD, 0)); - amdgpu_ring_write(ring, 0x80 | (emit_wait ? 1 : 0)); - - return true; -} - /** * uvd_v5_0_ring_test_ring - register write test * @@ -524,7 +501,7 @@ static int uvd_v5_0_ring_test_ring(struct amdgpu_ring *ring) int r; WREG32(mmUVD_CONTEXT_ID, 0xCAFEDEAD); - r = amdgpu_ring_lock(ring, 3); + r = amdgpu_ring_alloc(ring, 3); if (r) { DRM_ERROR("amdgpu: cp failed to lock ring %d (%d).\n", ring->idx, r); @@ -532,7 +509,7 @@ static int uvd_v5_0_ring_test_ring(struct amdgpu_ring *ring) } amdgpu_ring_write(ring, PACKET0(mmUVD_CONTEXT_ID, 0)); amdgpu_ring_write(ring, 0xDEADBEEF); - amdgpu_ring_unlock_commit(ring); + amdgpu_ring_commit(ring); for (i = 0; i < adev->usec_timeout; i++) { tmp = RREG32(mmUVD_CONTEXT_ID); if (tmp == 0xDEADBEEF) @@ -595,7 +572,7 @@ static int uvd_v5_0_ring_test_ib(struct amdgpu_ring *ring) goto error; } - r = amdgpu_uvd_get_destroy_msg(ring, 1, &fence); + r = amdgpu_uvd_get_destroy_msg(ring, 1, true, &fence); if (r) { DRM_ERROR("amdgpu: failed to get destroy ib (%d).\n", r); goto error; @@ -751,6 +728,12 @@ static void uvd_v5_0_print_status(void *handle) RREG32(mmUVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL)); dev_info(adev->dev, " UVD_CONTEXT_ID=0x%08X\n", RREG32(mmUVD_CONTEXT_ID)); + dev_info(adev->dev, " UVD_UDEC_ADDR_CONFIG=0x%08X\n", + RREG32(mmUVD_UDEC_ADDR_CONFIG)); + dev_info(adev->dev, " UVD_UDEC_DB_ADDR_CONFIG=0x%08X\n", + RREG32(mmUVD_UDEC_DB_ADDR_CONFIG)); + dev_info(adev->dev, " UVD_UDEC_DBW_ADDR_CONFIG=0x%08X\n", + RREG32(mmUVD_UDEC_DBW_ADDR_CONFIG)); } static int uvd_v5_0_set_interrupt_state(struct amdgpu_device *adev, @@ -829,10 +812,10 @@ static const struct amdgpu_ring_funcs uvd_v5_0_ring_funcs = { .parse_cs = amdgpu_uvd_ring_parse_cs, .emit_ib = uvd_v5_0_ring_emit_ib, .emit_fence = uvd_v5_0_ring_emit_fence, - .emit_semaphore = uvd_v5_0_ring_emit_semaphore, .test_ring = uvd_v5_0_ring_test_ring, .test_ib = uvd_v5_0_ring_test_ib, .insert_nop = amdgpu_ring_insert_nop, + .pad_ib = amdgpu_ring_generic_pad_ib, }; static void uvd_v5_0_set_ring_funcs(struct amdgpu_device *adev) diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c index 0b365b7651ffbac65324701a13da702306e27467..d49379145ef22e8468866a1b60bb17d40ebb5e70 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c @@ -157,7 +157,7 @@ static int uvd_v6_0_hw_init(void *handle) goto done; } - r = amdgpu_ring_lock(ring, 10); + r = amdgpu_ring_alloc(ring, 10); if (r) { DRM_ERROR("amdgpu: ring failed to lock UVD ring (%d).\n", r); goto done; @@ -182,7 +182,7 @@ static int uvd_v6_0_hw_init(void *handle) amdgpu_ring_write(ring, PACKET0(mmUVD_SEMA_CNTL, 0)); amdgpu_ring_write(ring, 3); - amdgpu_ring_unlock_commit(ring); + amdgpu_ring_commit(ring); done: if (!r) @@ -214,15 +214,16 @@ static int uvd_v6_0_suspend(void *handle) int r; struct amdgpu_device *adev = (struct amdgpu_device *)handle; + r = uvd_v6_0_hw_fini(adev); + if (r) + return r; + /* Skip this for APU for now */ if (!(adev->flags & AMD_IS_APU)) { r = amdgpu_uvd_suspend(adev); if (r) return r; } - r = uvd_v6_0_hw_fini(adev); - if (r) - return r; return r; } @@ -277,6 +278,10 @@ static void uvd_v6_0_mc_resume(struct amdgpu_device *adev) size = AMDGPU_UVD_HEAP_SIZE; WREG32(mmUVD_VCPU_CACHE_OFFSET2, offset >> 3); WREG32(mmUVD_VCPU_CACHE_SIZE2, size); + + WREG32(mmUVD_UDEC_ADDR_CONFIG, adev->gfx.config.gb_addr_config); + WREG32(mmUVD_UDEC_DB_ADDR_CONFIG, adev->gfx.config.gb_addr_config); + WREG32(mmUVD_UDEC_DBW_ADDR_CONFIG, adev->gfx.config.gb_addr_config); } static void cz_set_uvd_clock_gating_branches(struct amdgpu_device *adev, @@ -721,33 +726,6 @@ static void uvd_v6_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq amdgpu_ring_write(ring, 2); } -/** - * uvd_v6_0_ring_emit_semaphore - emit semaphore command - * - * @ring: amdgpu_ring pointer - * @semaphore: semaphore to emit commands for - * @emit_wait: true if we should emit a wait command - * - * Emit a semaphore command (either wait or signal) to the UVD ring. - */ -static bool uvd_v6_0_ring_emit_semaphore(struct amdgpu_ring *ring, - struct amdgpu_semaphore *semaphore, - bool emit_wait) -{ - uint64_t addr = semaphore->gpu_addr; - - amdgpu_ring_write(ring, PACKET0(mmUVD_SEMA_ADDR_LOW, 0)); - amdgpu_ring_write(ring, (addr >> 3) & 0x000FFFFF); - - amdgpu_ring_write(ring, PACKET0(mmUVD_SEMA_ADDR_HIGH, 0)); - amdgpu_ring_write(ring, (addr >> 23) & 0x000FFFFF); - - amdgpu_ring_write(ring, PACKET0(mmUVD_SEMA_CMD, 0)); - amdgpu_ring_write(ring, 0x80 | (emit_wait ? 1 : 0)); - - return true; -} - /** * uvd_v6_0_ring_test_ring - register write test * @@ -763,7 +741,7 @@ static int uvd_v6_0_ring_test_ring(struct amdgpu_ring *ring) int r; WREG32(mmUVD_CONTEXT_ID, 0xCAFEDEAD); - r = amdgpu_ring_lock(ring, 3); + r = amdgpu_ring_alloc(ring, 3); if (r) { DRM_ERROR("amdgpu: cp failed to lock ring %d (%d).\n", ring->idx, r); @@ -771,7 +749,7 @@ static int uvd_v6_0_ring_test_ring(struct amdgpu_ring *ring) } amdgpu_ring_write(ring, PACKET0(mmUVD_CONTEXT_ID, 0)); amdgpu_ring_write(ring, 0xDEADBEEF); - amdgpu_ring_unlock_commit(ring); + amdgpu_ring_commit(ring); for (i = 0; i < adev->usec_timeout; i++) { tmp = RREG32(mmUVD_CONTEXT_ID); if (tmp == 0xDEADBEEF) @@ -827,7 +805,7 @@ static int uvd_v6_0_ring_test_ib(struct amdgpu_ring *ring) goto error; } - r = amdgpu_uvd_get_destroy_msg(ring, 1, &fence); + r = amdgpu_uvd_get_destroy_msg(ring, 1, true, &fence); if (r) { DRM_ERROR("amdgpu: failed to get destroy ib (%d).\n", r); goto error; @@ -974,6 +952,12 @@ static void uvd_v6_0_print_status(void *handle) RREG32(mmUVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL)); dev_info(adev->dev, " UVD_CONTEXT_ID=0x%08X\n", RREG32(mmUVD_CONTEXT_ID)); + dev_info(adev->dev, " UVD_UDEC_ADDR_CONFIG=0x%08X\n", + RREG32(mmUVD_UDEC_ADDR_CONFIG)); + dev_info(adev->dev, " UVD_UDEC_DB_ADDR_CONFIG=0x%08X\n", + RREG32(mmUVD_UDEC_DB_ADDR_CONFIG)); + dev_info(adev->dev, " UVD_UDEC_DBW_ADDR_CONFIG=0x%08X\n", + RREG32(mmUVD_UDEC_DBW_ADDR_CONFIG)); } static int uvd_v6_0_set_interrupt_state(struct amdgpu_device *adev, @@ -1065,10 +1049,10 @@ static const struct amdgpu_ring_funcs uvd_v6_0_ring_funcs = { .parse_cs = amdgpu_uvd_ring_parse_cs, .emit_ib = uvd_v6_0_ring_emit_ib, .emit_fence = uvd_v6_0_ring_emit_fence, - .emit_semaphore = uvd_v6_0_ring_emit_semaphore, .test_ring = uvd_v6_0_ring_test_ring, .test_ib = uvd_v6_0_ring_test_ib, .insert_nop = amdgpu_ring_insert_nop, + .pad_ib = amdgpu_ring_generic_pad_ib, }; static void uvd_v6_0_set_ring_funcs(struct amdgpu_device *adev) diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c index a822edacfa95c979a60cb49eb6e4bb51239e05f0..c7e885bcfd41700112dfc7ab7102cf300b33b74a 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c @@ -642,10 +642,10 @@ static const struct amdgpu_ring_funcs vce_v2_0_ring_funcs = { .parse_cs = amdgpu_vce_ring_parse_cs, .emit_ib = amdgpu_vce_ring_emit_ib, .emit_fence = amdgpu_vce_ring_emit_fence, - .emit_semaphore = amdgpu_vce_ring_emit_semaphore, .test_ring = amdgpu_vce_ring_test_ring, .test_ib = amdgpu_vce_ring_test_ib, .insert_nop = amdgpu_ring_insert_nop, + .pad_ib = amdgpu_ring_generic_pad_ib, }; static void vce_v2_0_set_ring_funcs(struct amdgpu_device *adev) diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c index d662fa9f9091a33c51eefa8b0ae5d753229e195b..ce468ee5da2a769b755438700922d371ad592eeb 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c @@ -762,10 +762,10 @@ static const struct amdgpu_ring_funcs vce_v3_0_ring_funcs = { .parse_cs = amdgpu_vce_ring_parse_cs, .emit_ib = amdgpu_vce_ring_emit_ib, .emit_fence = amdgpu_vce_ring_emit_fence, - .emit_semaphore = amdgpu_vce_ring_emit_semaphore, .test_ring = amdgpu_vce_ring_test_ring, .test_ib = amdgpu_vce_ring_test_ib, .insert_nop = amdgpu_ring_insert_nop, + .pad_ib = amdgpu_ring_generic_pad_ib, }; static void vce_v3_0_set_ring_funcs(struct amdgpu_device *adev) diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c index 0d14d108a6c4adf7a152edcff56cafa4b219cf1a..1c120efa292cef9f1c718cc0705cfe83414995b4 100644 --- a/drivers/gpu/drm/amd/amdgpu/vi.c +++ b/drivers/gpu/drm/amd/amdgpu/vi.c @@ -74,6 +74,9 @@ #include "uvd_v6_0.h" #include "vce_v3_0.h" #include "amdgpu_powerplay.h" +#if defined(CONFIG_DRM_AMD_ACP) +#include "amdgpu_acp.h" +#endif /* * Indirect registers accessor @@ -571,374 +574,12 @@ static int vi_read_register(struct amdgpu_device *adev, u32 se_num, return -EINVAL; } -static void vi_print_gpu_status_regs(struct amdgpu_device *adev) -{ - dev_info(adev->dev, " GRBM_STATUS=0x%08X\n", - RREG32(mmGRBM_STATUS)); - dev_info(adev->dev, " GRBM_STATUS2=0x%08X\n", - RREG32(mmGRBM_STATUS2)); - dev_info(adev->dev, " GRBM_STATUS_SE0=0x%08X\n", - RREG32(mmGRBM_STATUS_SE0)); - dev_info(adev->dev, " GRBM_STATUS_SE1=0x%08X\n", - RREG32(mmGRBM_STATUS_SE1)); - dev_info(adev->dev, " GRBM_STATUS_SE2=0x%08X\n", - RREG32(mmGRBM_STATUS_SE2)); - dev_info(adev->dev, " GRBM_STATUS_SE3=0x%08X\n", - RREG32(mmGRBM_STATUS_SE3)); - dev_info(adev->dev, " SRBM_STATUS=0x%08X\n", - RREG32(mmSRBM_STATUS)); - dev_info(adev->dev, " SRBM_STATUS2=0x%08X\n", - RREG32(mmSRBM_STATUS2)); - dev_info(adev->dev, " SDMA0_STATUS_REG = 0x%08X\n", - RREG32(mmSDMA0_STATUS_REG + SDMA0_REGISTER_OFFSET)); - if (adev->sdma.num_instances > 1) { - dev_info(adev->dev, " SDMA1_STATUS_REG = 0x%08X\n", - RREG32(mmSDMA0_STATUS_REG + SDMA1_REGISTER_OFFSET)); - } - dev_info(adev->dev, " CP_STAT = 0x%08x\n", RREG32(mmCP_STAT)); - dev_info(adev->dev, " CP_STALLED_STAT1 = 0x%08x\n", - RREG32(mmCP_STALLED_STAT1)); - dev_info(adev->dev, " CP_STALLED_STAT2 = 0x%08x\n", - RREG32(mmCP_STALLED_STAT2)); - dev_info(adev->dev, " CP_STALLED_STAT3 = 0x%08x\n", - RREG32(mmCP_STALLED_STAT3)); - dev_info(adev->dev, " CP_CPF_BUSY_STAT = 0x%08x\n", - RREG32(mmCP_CPF_BUSY_STAT)); - dev_info(adev->dev, " CP_CPF_STALLED_STAT1 = 0x%08x\n", - RREG32(mmCP_CPF_STALLED_STAT1)); - dev_info(adev->dev, " CP_CPF_STATUS = 0x%08x\n", RREG32(mmCP_CPF_STATUS)); - dev_info(adev->dev, " CP_CPC_BUSY_STAT = 0x%08x\n", RREG32(mmCP_CPC_BUSY_STAT)); - dev_info(adev->dev, " CP_CPC_STALLED_STAT1 = 0x%08x\n", - RREG32(mmCP_CPC_STALLED_STAT1)); - dev_info(adev->dev, " CP_CPC_STATUS = 0x%08x\n", RREG32(mmCP_CPC_STATUS)); -} - -/** - * vi_gpu_check_soft_reset - check which blocks are busy - * - * @adev: amdgpu_device pointer - * - * Check which blocks are busy and return the relevant reset - * mask to be used by vi_gpu_soft_reset(). - * Returns a mask of the blocks to be reset. - */ -u32 vi_gpu_check_soft_reset(struct amdgpu_device *adev) -{ - u32 reset_mask = 0; - u32 tmp; - - /* GRBM_STATUS */ - tmp = RREG32(mmGRBM_STATUS); - if (tmp & (GRBM_STATUS__PA_BUSY_MASK | GRBM_STATUS__SC_BUSY_MASK | - GRBM_STATUS__BCI_BUSY_MASK | GRBM_STATUS__SX_BUSY_MASK | - GRBM_STATUS__TA_BUSY_MASK | GRBM_STATUS__VGT_BUSY_MASK | - GRBM_STATUS__DB_BUSY_MASK | GRBM_STATUS__CB_BUSY_MASK | - GRBM_STATUS__GDS_BUSY_MASK | GRBM_STATUS__SPI_BUSY_MASK | - GRBM_STATUS__IA_BUSY_MASK | GRBM_STATUS__IA_BUSY_NO_DMA_MASK)) - reset_mask |= AMDGPU_RESET_GFX; - - if (tmp & (GRBM_STATUS__CP_BUSY_MASK | GRBM_STATUS__CP_COHERENCY_BUSY_MASK)) - reset_mask |= AMDGPU_RESET_CP; - - /* GRBM_STATUS2 */ - tmp = RREG32(mmGRBM_STATUS2); - if (tmp & GRBM_STATUS2__RLC_BUSY_MASK) - reset_mask |= AMDGPU_RESET_RLC; - - if (tmp & (GRBM_STATUS2__CPF_BUSY_MASK | - GRBM_STATUS2__CPC_BUSY_MASK | - GRBM_STATUS2__CPG_BUSY_MASK)) - reset_mask |= AMDGPU_RESET_CP; - - /* SRBM_STATUS2 */ - tmp = RREG32(mmSRBM_STATUS2); - if (tmp & SRBM_STATUS2__SDMA_BUSY_MASK) - reset_mask |= AMDGPU_RESET_DMA; - - if (tmp & SRBM_STATUS2__SDMA1_BUSY_MASK) - reset_mask |= AMDGPU_RESET_DMA1; - - /* SRBM_STATUS */ - tmp = RREG32(mmSRBM_STATUS); - - if (tmp & SRBM_STATUS__IH_BUSY_MASK) - reset_mask |= AMDGPU_RESET_IH; - - if (tmp & SRBM_STATUS__SEM_BUSY_MASK) - reset_mask |= AMDGPU_RESET_SEM; - - if (tmp & SRBM_STATUS__GRBM_RQ_PENDING_MASK) - reset_mask |= AMDGPU_RESET_GRBM; - - if (adev->asic_type != CHIP_TOPAZ) { - if (tmp & (SRBM_STATUS__UVD_RQ_PENDING_MASK | - SRBM_STATUS__UVD_BUSY_MASK)) - reset_mask |= AMDGPU_RESET_UVD; - } - - if (tmp & SRBM_STATUS__VMC_BUSY_MASK) - reset_mask |= AMDGPU_RESET_VMC; - - if (tmp & (SRBM_STATUS__MCB_BUSY_MASK | SRBM_STATUS__MCB_NON_DISPLAY_BUSY_MASK | - SRBM_STATUS__MCC_BUSY_MASK | SRBM_STATUS__MCD_BUSY_MASK)) - reset_mask |= AMDGPU_RESET_MC; - - /* SDMA0_STATUS_REG */ - tmp = RREG32(mmSDMA0_STATUS_REG + SDMA0_REGISTER_OFFSET); - if (!(tmp & SDMA0_STATUS_REG__IDLE_MASK)) - reset_mask |= AMDGPU_RESET_DMA; - - /* SDMA1_STATUS_REG */ - if (adev->sdma.num_instances > 1) { - tmp = RREG32(mmSDMA0_STATUS_REG + SDMA1_REGISTER_OFFSET); - if (!(tmp & SDMA0_STATUS_REG__IDLE_MASK)) - reset_mask |= AMDGPU_RESET_DMA1; - } -#if 0 - /* VCE_STATUS */ - if (adev->asic_type != CHIP_TOPAZ) { - tmp = RREG32(mmVCE_STATUS); - if (tmp & VCE_STATUS__VCPU_REPORT_RB0_BUSY_MASK) - reset_mask |= AMDGPU_RESET_VCE; - if (tmp & VCE_STATUS__VCPU_REPORT_RB1_BUSY_MASK) - reset_mask |= AMDGPU_RESET_VCE1; - - } - - if (adev->asic_type != CHIP_TOPAZ) { - if (amdgpu_display_is_display_hung(adev)) - reset_mask |= AMDGPU_RESET_DISPLAY; - } -#endif - - /* Skip MC reset as it's mostly likely not hung, just busy */ - if (reset_mask & AMDGPU_RESET_MC) { - DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask); - reset_mask &= ~AMDGPU_RESET_MC; - } - - return reset_mask; -} - -/** - * vi_gpu_soft_reset - soft reset GPU - * - * @adev: amdgpu_device pointer - * @reset_mask: mask of which blocks to reset - * - * Soft reset the blocks specified in @reset_mask. - */ -static void vi_gpu_soft_reset(struct amdgpu_device *adev, u32 reset_mask) -{ - struct amdgpu_mode_mc_save save; - u32 grbm_soft_reset = 0, srbm_soft_reset = 0; - u32 tmp; - - if (reset_mask == 0) - return; - - dev_info(adev->dev, "GPU softreset: 0x%08X\n", reset_mask); - - vi_print_gpu_status_regs(adev); - dev_info(adev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", - RREG32(mmVM_CONTEXT1_PROTECTION_FAULT_ADDR)); - dev_info(adev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", - RREG32(mmVM_CONTEXT1_PROTECTION_FAULT_STATUS)); - - /* disable CG/PG */ - - /* stop the rlc */ - //XXX - //gfx_v8_0_rlc_stop(adev); - - /* Disable GFX parsing/prefetching */ - tmp = RREG32(mmCP_ME_CNTL); - tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, ME_HALT, 1); - tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, PFP_HALT, 1); - tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, CE_HALT, 1); - WREG32(mmCP_ME_CNTL, tmp); - - /* Disable MEC parsing/prefetching */ - tmp = RREG32(mmCP_MEC_CNTL); - tmp = REG_SET_FIELD(tmp, CP_MEC_CNTL, MEC_ME1_HALT, 1); - tmp = REG_SET_FIELD(tmp, CP_MEC_CNTL, MEC_ME2_HALT, 1); - WREG32(mmCP_MEC_CNTL, tmp); - - if (reset_mask & AMDGPU_RESET_DMA) { - /* sdma0 */ - tmp = RREG32(mmSDMA0_F32_CNTL + SDMA0_REGISTER_OFFSET); - tmp = REG_SET_FIELD(tmp, SDMA0_F32_CNTL, HALT, 1); - WREG32(mmSDMA0_F32_CNTL + SDMA0_REGISTER_OFFSET, tmp); - } - if (reset_mask & AMDGPU_RESET_DMA1) { - /* sdma1 */ - tmp = RREG32(mmSDMA0_F32_CNTL + SDMA1_REGISTER_OFFSET); - tmp = REG_SET_FIELD(tmp, SDMA0_F32_CNTL, HALT, 1); - WREG32(mmSDMA0_F32_CNTL + SDMA1_REGISTER_OFFSET, tmp); - } - - gmc_v8_0_mc_stop(adev, &save); - if (amdgpu_asic_wait_for_mc_idle(adev)) { - dev_warn(adev->dev, "Wait for MC idle timedout !\n"); - } - - if (reset_mask & (AMDGPU_RESET_GFX | AMDGPU_RESET_COMPUTE | AMDGPU_RESET_CP)) { - grbm_soft_reset = - REG_SET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, SOFT_RESET_CP, 1); - grbm_soft_reset = - REG_SET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, SOFT_RESET_GFX, 1); - } - - if (reset_mask & AMDGPU_RESET_CP) { - grbm_soft_reset = - REG_SET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, SOFT_RESET_CP, 1); - srbm_soft_reset = - REG_SET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_GRBM, 1); - } - - if (reset_mask & AMDGPU_RESET_DMA) - srbm_soft_reset = - REG_SET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_SDMA, 1); - - if (reset_mask & AMDGPU_RESET_DMA1) - srbm_soft_reset = - REG_SET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_SDMA1, 1); - - if (reset_mask & AMDGPU_RESET_DISPLAY) - srbm_soft_reset = - REG_SET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_DC, 1); - - if (reset_mask & AMDGPU_RESET_RLC) - grbm_soft_reset = - REG_SET_FIELD(grbm_soft_reset, GRBM_SOFT_RESET, SOFT_RESET_RLC, 1); - - if (reset_mask & AMDGPU_RESET_SEM) - srbm_soft_reset = - REG_SET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_SEM, 1); - - if (reset_mask & AMDGPU_RESET_IH) - srbm_soft_reset = - REG_SET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_IH, 1); - - if (reset_mask & AMDGPU_RESET_GRBM) - srbm_soft_reset = - REG_SET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_GRBM, 1); - - if (reset_mask & AMDGPU_RESET_VMC) - srbm_soft_reset = - REG_SET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_VMC, 1); - - if (reset_mask & AMDGPU_RESET_UVD) - srbm_soft_reset = - REG_SET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_UVD, 1); - - if (reset_mask & AMDGPU_RESET_VCE) - srbm_soft_reset = - REG_SET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_VCE0, 1); - - if (reset_mask & AMDGPU_RESET_VCE) - srbm_soft_reset = - REG_SET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_VCE1, 1); - - if (!(adev->flags & AMD_IS_APU)) { - if (reset_mask & AMDGPU_RESET_MC) - srbm_soft_reset = - REG_SET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_MC, 1); - } - - if (grbm_soft_reset) { - tmp = RREG32(mmGRBM_SOFT_RESET); - tmp |= grbm_soft_reset; - dev_info(adev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp); - WREG32(mmGRBM_SOFT_RESET, tmp); - tmp = RREG32(mmGRBM_SOFT_RESET); - - udelay(50); - - tmp &= ~grbm_soft_reset; - WREG32(mmGRBM_SOFT_RESET, tmp); - tmp = RREG32(mmGRBM_SOFT_RESET); - } - - if (srbm_soft_reset) { - tmp = RREG32(mmSRBM_SOFT_RESET); - tmp |= srbm_soft_reset; - dev_info(adev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp); - WREG32(mmSRBM_SOFT_RESET, tmp); - tmp = RREG32(mmSRBM_SOFT_RESET); - - udelay(50); - - tmp &= ~srbm_soft_reset; - WREG32(mmSRBM_SOFT_RESET, tmp); - tmp = RREG32(mmSRBM_SOFT_RESET); - } - - /* Wait a little for things to settle down */ - udelay(50); - - gmc_v8_0_mc_resume(adev, &save); - udelay(50); - - vi_print_gpu_status_regs(adev); -} - static void vi_gpu_pci_config_reset(struct amdgpu_device *adev) { - struct amdgpu_mode_mc_save save; - u32 tmp, i; + u32 i; dev_info(adev->dev, "GPU pci config reset\n"); - /* disable dpm? */ - - /* disable cg/pg */ - - /* Disable GFX parsing/prefetching */ - tmp = RREG32(mmCP_ME_CNTL); - tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, ME_HALT, 1); - tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, PFP_HALT, 1); - tmp = REG_SET_FIELD(tmp, CP_ME_CNTL, CE_HALT, 1); - WREG32(mmCP_ME_CNTL, tmp); - - /* Disable MEC parsing/prefetching */ - tmp = RREG32(mmCP_MEC_CNTL); - tmp = REG_SET_FIELD(tmp, CP_MEC_CNTL, MEC_ME1_HALT, 1); - tmp = REG_SET_FIELD(tmp, CP_MEC_CNTL, MEC_ME2_HALT, 1); - WREG32(mmCP_MEC_CNTL, tmp); - - /* Disable GFX parsing/prefetching */ - WREG32(mmCP_ME_CNTL, CP_ME_CNTL__ME_HALT_MASK | - CP_ME_CNTL__PFP_HALT_MASK | CP_ME_CNTL__CE_HALT_MASK); - - /* Disable MEC parsing/prefetching */ - WREG32(mmCP_MEC_CNTL, - CP_MEC_CNTL__MEC_ME1_HALT_MASK | CP_MEC_CNTL__MEC_ME2_HALT_MASK); - - /* sdma0 */ - tmp = RREG32(mmSDMA0_F32_CNTL + SDMA0_REGISTER_OFFSET); - tmp = REG_SET_FIELD(tmp, SDMA0_F32_CNTL, HALT, 1); - WREG32(mmSDMA0_F32_CNTL + SDMA0_REGISTER_OFFSET, tmp); - - /* sdma1 */ - tmp = RREG32(mmSDMA0_F32_CNTL + SDMA1_REGISTER_OFFSET); - tmp = REG_SET_FIELD(tmp, SDMA0_F32_CNTL, HALT, 1); - WREG32(mmSDMA0_F32_CNTL + SDMA1_REGISTER_OFFSET, tmp); - - /* XXX other engines? */ - - /* halt the rlc, disable cp internal ints */ - //XXX - //gfx_v8_0_rlc_stop(adev); - - udelay(50); - - /* disable mem access */ - gmc_v8_0_mc_stop(adev, &save); - if (amdgpu_asic_wait_for_mc_idle(adev)) { - dev_warn(adev->dev, "Wait for MC idle timed out !\n"); - } - /* disable BM */ pci_clear_master(adev->pdev); /* reset */ @@ -978,26 +619,11 @@ static void vi_set_bios_scratch_engine_hung(struct amdgpu_device *adev, bool hun */ static int vi_asic_reset(struct amdgpu_device *adev) { - u32 reset_mask; - - reset_mask = vi_gpu_check_soft_reset(adev); - - if (reset_mask) - vi_set_bios_scratch_engine_hung(adev, true); - - /* try soft reset */ - vi_gpu_soft_reset(adev, reset_mask); - - reset_mask = vi_gpu_check_soft_reset(adev); + vi_set_bios_scratch_engine_hung(adev, true); - /* try pci config reset */ - if (reset_mask && amdgpu_hard_reset) - vi_gpu_pci_config_reset(adev); + vi_gpu_pci_config_reset(adev); - reset_mask = vi_gpu_check_soft_reset(adev); - - if (!reset_mask) - vi_set_bios_scratch_engine_hung(adev, false); + vi_set_bios_scratch_engine_hung(adev, false); return 0; } @@ -1347,6 +973,15 @@ static const struct amdgpu_ip_block_version cz_ip_blocks[] = .rev = 0, .funcs = &vce_v3_0_ip_funcs, }, +#if defined(CONFIG_DRM_AMD_ACP) + { + .type = AMD_IP_BLOCK_TYPE_ACP, + .major = 2, + .minor = 2, + .rev = 0, + .funcs = &acp_ip_funcs, + }, +#endif }; int vi_set_ip_blocks(struct amdgpu_device *adev) @@ -1436,26 +1071,22 @@ static int vi_common_early_init(void *handle) adev->external_rev_id = 0xFF; switch (adev->asic_type) { case CHIP_TOPAZ: - adev->has_uvd = false; adev->cg_flags = 0; adev->pg_flags = 0; adev->external_rev_id = 0x1; break; case CHIP_FIJI: - adev->has_uvd = true; adev->cg_flags = 0; adev->pg_flags = 0; adev->external_rev_id = adev->rev_id + 0x3c; break; case CHIP_TONGA: - adev->has_uvd = true; adev->cg_flags = 0; adev->pg_flags = 0; adev->external_rev_id = adev->rev_id + 0x14; break; case CHIP_CARRIZO: case CHIP_STONEY: - adev->has_uvd = true; adev->cg_flags = 0; adev->pg_flags = 0; adev->external_rev_id = adev->rev_id + 0x1; diff --git a/drivers/gpu/drm/amd/amdgpu/vid.h b/drivers/gpu/drm/amd/amdgpu/vid.h index d98aa9d82fa193dc5e13a98a34df6ab87733e597..ace49976f7be08efe9d6ea6e246fb83bc4727ab2 100644 --- a/drivers/gpu/drm/amd/amdgpu/vid.h +++ b/drivers/gpu/drm/amd/amdgpu/vid.h @@ -71,8 +71,6 @@ #define VMID(x) ((x) << 4) #define QUEUEID(x) ((x) << 8) -#define RB_BITMAP_WIDTH_PER_SH 2 - #define MC_SEQ_MISC0__MT__MASK 0xf0000000 #define MC_SEQ_MISC0__MT__GDDR1 0x10000000 #define MC_SEQ_MISC0__MT__DDR2 0x20000000 diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index d2b49c026cf685a92dbb57b203f5ecdc04cfb653..07ac724e3ec909102c22d0fc47ce4be19c8606ab 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -107,7 +107,7 @@ static int kfd_open(struct inode *inode, struct file *filep) if (iminor(inode) != 0) return -ENODEV; - is_32bit_user_mode = is_compat_task(); + is_32bit_user_mode = in_compat_syscall(); if (is_32bit_user_mode == true) { dev_warn(kfd_device, diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c b/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c index c34c393e9aea0c2dfe3442c28a72f2206fbcd7fb..d5e19b5fbbfb00d1fbbcd1066da0ac4f12424ec3 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_dbgdev.c @@ -513,7 +513,7 @@ static int dbgdev_wave_control_set_registers( union SQ_CMD_BITS *in_reg_sq_cmd, union GRBM_GFX_INDEX_BITS *in_reg_gfx_index) { - int status; + int status = 0; union SQ_CMD_BITS reg_sq_cmd; union GRBM_GFX_INDEX_BITS reg_gfx_index; struct HsaDbgWaveMsgAMDGen2 *pMsg; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_module.c b/drivers/gpu/drm/amd/amdkfd/kfd_module.c index ca8410e8683d396b2cb2f4d872dfc065aa8943c2..850a5623661f83be1dcb2c2108fdf824a2002f94 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_module.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_module.c @@ -59,18 +59,23 @@ module_param(send_sigterm, int, 0444); MODULE_PARM_DESC(send_sigterm, "Send sigterm to HSA process on unhandled exception (0 = disable, 1 = enable)"); -bool kgd2kfd_init(unsigned interface_version, const struct kgd2kfd_calls **g2f) +static int amdkfd_init_completed; + +int kgd2kfd_init(unsigned interface_version, const struct kgd2kfd_calls **g2f) { + if (!amdkfd_init_completed) + return -EPROBE_DEFER; + /* * Only one interface version is supported, * no kfd/kgd version skew allowed. */ if (interface_version != KFD_INTERFACE_VERSION) - return false; + return -EINVAL; *g2f = &kgd2kfd; - return true; + return 0; } EXPORT_SYMBOL(kgd2kfd_init); @@ -111,6 +116,8 @@ static int __init kfd_module_init(void) kfd_process_create_wq(); + amdkfd_init_completed = 1; + dev_info(kfd_device, "Initialized module\n"); return 0; @@ -125,6 +132,8 @@ static int __init kfd_module_init(void) static void __exit kfd_module_exit(void) { + amdkfd_init_completed = 0; + kfd_process_destroy_wq(); kfd_topology_shutdown(); kfd_chardev_exit(); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index a902ae037398389cf6e19c1ab7379ca64e6a46ed..ac005796b71c1491fb509bc3705b6e5f5c75442a 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -311,7 +311,7 @@ static struct kfd_process *create_process(const struct task_struct *thread) goto err_process_pqm_init; /* init process apertures*/ - process->is_32bit_user_mode = is_compat_task(); + process->is_32bit_user_mode = in_compat_syscall(); if (kfd_init_apertures(process) != 0) goto err_init_apretures; diff --git a/drivers/gpu/drm/amd/include/amd_acpi.h b/drivers/gpu/drm/amd/include/amd_acpi.h index 496360eb3fba2395c6ef027f3ed54a70a9065f20..50e8933251410ada6591f488806f979582eca523 100644 --- a/drivers/gpu/drm/amd/include/amd_acpi.h +++ b/drivers/gpu/drm/amd/include/amd_acpi.h @@ -340,6 +340,8 @@ struct atcs_pref_req_output { # define ATPX_FIXED_NOT_SUPPORTED (1 << 9) # define ATPX_DYNAMIC_DGPU_POWER_OFF_SUPPORTED (1 << 10) # define ATPX_DGPU_REQ_POWER_FOR_DISPLAYS (1 << 11) +# define ATPX_DGPU_CAN_DRIVE_DISPLAYS (1 << 12) +# define ATPX_MS_HYBRID_GFX_SUPPORTED (1 << 14) #define ATPX_FUNCTION_POWER_CONTROL 0x2 /* ARG0: ATPX_FUNCTION_POWER_CONTROL * ARG1: diff --git a/drivers/gpu/drm/amd/include/amd_shared.h b/drivers/gpu/drm/amd/include/amd_shared.h index dbf7e6413cab4207940659b81ceb02095b4ae515..04e4090666fb2257307b50018729c18c3bc3b48e 100644 --- a/drivers/gpu/drm/amd/include/amd_shared.h +++ b/drivers/gpu/drm/amd/include/amd_shared.h @@ -73,6 +73,7 @@ enum amd_ip_block_type { AMD_IP_BLOCK_TYPE_SDMA, AMD_IP_BLOCK_TYPE_UVD, AMD_IP_BLOCK_TYPE_VCE, + AMD_IP_BLOCK_TYPE_ACP, }; enum amd_clockgating_state { diff --git a/drivers/gpu/drm/amd/include/asic_reg/dce/dce_8_0_d.h b/drivers/gpu/drm/amd/include/asic_reg/dce/dce_8_0_d.h index dc52ea0df4b4179df11967c966304514d4e19265..d3ccf5a86de03a03b6de77af13db8ca513e7766b 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/dce/dce_8_0_d.h +++ b/drivers/gpu/drm/amd/include/asic_reg/dce/dce_8_0_d.h @@ -1379,6 +1379,7 @@ #define mmDC_GPIO_PAD_STRENGTH_1 0x1978 #define mmDC_GPIO_PAD_STRENGTH_2 0x1979 #define mmPHY_AUX_CNTL 0x197f +#define mmDC_GPIO_I2CPAD_MASK 0x1974 #define mmDC_GPIO_I2CPAD_A 0x1975 #define mmDC_GPIO_I2CPAD_EN 0x1976 #define mmDC_GPIO_I2CPAD_Y 0x1977 diff --git a/drivers/gpu/drm/amd/include/asic_reg/dce/dce_8_0_enum.h b/drivers/gpu/drm/amd/include/asic_reg/dce/dce_8_0_enum.h new file mode 100644 index 0000000000000000000000000000000000000000..6bea30ef3df5b1541c9d5567430d0949dc757f87 --- /dev/null +++ b/drivers/gpu/drm/amd/include/asic_reg/dce/dce_8_0_enum.h @@ -0,0 +1,1117 @@ +/* + * DCE_8_0 Register documentation + * + * Copyright (C) 2016 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef DCE_8_0_ENUM_H +#define DCE_8_0_ENUM_H + +typedef enum SurfaceEndian { + ENDIAN_NONE = 0x0, + ENDIAN_8IN16 = 0x1, + ENDIAN_8IN32 = 0x2, + ENDIAN_8IN64 = 0x3, +} SurfaceEndian; +typedef enum ArrayMode { + ARRAY_LINEAR_GENERAL = 0x0, + ARRAY_LINEAR_ALIGNED = 0x1, + ARRAY_1D_TILED_THIN1 = 0x2, + ARRAY_1D_TILED_THICK = 0x3, + ARRAY_2D_TILED_THIN1 = 0x4, + ARRAY_PRT_TILED_THIN1 = 0x5, + ARRAY_PRT_2D_TILED_THIN1 = 0x6, + ARRAY_2D_TILED_THICK = 0x7, + ARRAY_2D_TILED_XTHICK = 0x8, + ARRAY_PRT_TILED_THICK = 0x9, + ARRAY_PRT_2D_TILED_THICK = 0xa, + ARRAY_PRT_3D_TILED_THIN1 = 0xb, + ARRAY_3D_TILED_THIN1 = 0xc, + ARRAY_3D_TILED_THICK = 0xd, + ARRAY_3D_TILED_XTHICK = 0xe, + ARRAY_PRT_3D_TILED_THICK = 0xf, +} ArrayMode; +typedef enum PipeTiling { + CONFIG_1_PIPE = 0x0, + CONFIG_2_PIPE = 0x1, + CONFIG_4_PIPE = 0x2, + CONFIG_8_PIPE = 0x3, +} PipeTiling; +typedef enum BankTiling { + CONFIG_4_BANK = 0x0, + CONFIG_8_BANK = 0x1, +} BankTiling; +typedef enum GroupInterleave { + CONFIG_256B_GROUP = 0x0, + CONFIG_512B_GROUP = 0x1, +} GroupInterleave; +typedef enum RowTiling { + CONFIG_1KB_ROW = 0x0, + CONFIG_2KB_ROW = 0x1, + CONFIG_4KB_ROW = 0x2, + CONFIG_8KB_ROW = 0x3, + CONFIG_1KB_ROW_OPT = 0x4, + CONFIG_2KB_ROW_OPT = 0x5, + CONFIG_4KB_ROW_OPT = 0x6, + CONFIG_8KB_ROW_OPT = 0x7, +} RowTiling; +typedef enum BankSwapBytes { + CONFIG_128B_SWAPS = 0x0, + CONFIG_256B_SWAPS = 0x1, + CONFIG_512B_SWAPS = 0x2, + CONFIG_1KB_SWAPS = 0x3, +} BankSwapBytes; +typedef enum SampleSplitBytes { + CONFIG_1KB_SPLIT = 0x0, + CONFIG_2KB_SPLIT = 0x1, + CONFIG_4KB_SPLIT = 0x2, + CONFIG_8KB_SPLIT = 0x3, +} SampleSplitBytes; +typedef enum NumPipes { + ADDR_CONFIG_1_PIPE = 0x0, + ADDR_CONFIG_2_PIPE = 0x1, + ADDR_CONFIG_4_PIPE = 0x2, + ADDR_CONFIG_8_PIPE = 0x3, +} NumPipes; +typedef enum PipeInterleaveSize { + ADDR_CONFIG_PIPE_INTERLEAVE_256B = 0x0, + ADDR_CONFIG_PIPE_INTERLEAVE_512B = 0x1, +} PipeInterleaveSize; +typedef enum BankInterleaveSize { + ADDR_CONFIG_BANK_INTERLEAVE_1 = 0x0, + ADDR_CONFIG_BANK_INTERLEAVE_2 = 0x1, + ADDR_CONFIG_BANK_INTERLEAVE_4 = 0x2, + ADDR_CONFIG_BANK_INTERLEAVE_8 = 0x3, +} BankInterleaveSize; +typedef enum NumShaderEngines { + ADDR_CONFIG_1_SHADER_ENGINE = 0x0, + ADDR_CONFIG_2_SHADER_ENGINE = 0x1, +} NumShaderEngines; +typedef enum ShaderEngineTileSize { + ADDR_CONFIG_SE_TILE_16 = 0x0, + ADDR_CONFIG_SE_TILE_32 = 0x1, +} ShaderEngineTileSize; +typedef enum NumGPUs { + ADDR_CONFIG_1_GPU = 0x0, + ADDR_CONFIG_2_GPU = 0x1, + ADDR_CONFIG_4_GPU = 0x2, +} NumGPUs; +typedef enum MultiGPUTileSize { + ADDR_CONFIG_GPU_TILE_16 = 0x0, + ADDR_CONFIG_GPU_TILE_32 = 0x1, + ADDR_CONFIG_GPU_TILE_64 = 0x2, + ADDR_CONFIG_GPU_TILE_128 = 0x3, +} MultiGPUTileSize; +typedef enum RowSize { + ADDR_CONFIG_1KB_ROW = 0x0, + ADDR_CONFIG_2KB_ROW = 0x1, + ADDR_CONFIG_4KB_ROW = 0x2, +} RowSize; +typedef enum NumLowerPipes { + ADDR_CONFIG_1_LOWER_PIPES = 0x0, + ADDR_CONFIG_2_LOWER_PIPES = 0x1, +} NumLowerPipes; +typedef enum DebugBlockId { + DBG_CLIENT_BLKID_RESERVED = 0x0, + DBG_CLIENT_BLKID_dbg = 0x1, + DBG_CLIENT_BLKID_uvdu_0 = 0x2, + DBG_CLIENT_BLKID_uvdu_1 = 0x3, + DBG_CLIENT_BLKID_uvdu_2 = 0x4, + DBG_CLIENT_BLKID_uvdu_3 = 0x5, + DBG_CLIENT_BLKID_uvdu_4 = 0x6, + DBG_CLIENT_BLKID_uvdu_5 = 0x7, + DBG_CLIENT_BLKID_uvdu_6 = 0x8, + DBG_CLIENT_BLKID_uvdm_0 = 0x9, + DBG_CLIENT_BLKID_uvdm_1 = 0xa, + DBG_CLIENT_BLKID_uvdm_2 = 0xb, + DBG_CLIENT_BLKID_uvdm_3 = 0xc, + DBG_CLIENT_BLKID_vcea_0 = 0xd, + DBG_CLIENT_BLKID_vcea_1 = 0xe, + DBG_CLIENT_BLKID_vcea_2 = 0xf, + DBG_CLIENT_BLKID_vcea_3 = 0x10, + DBG_CLIENT_BLKID_vcea_4 = 0x11, + DBG_CLIENT_BLKID_vcea_5 = 0x12, + DBG_CLIENT_BLKID_vcea_6 = 0x13, + DBG_CLIENT_BLKID_vceb_0 = 0x14, + DBG_CLIENT_BLKID_vceb_1 = 0x15, + DBG_CLIENT_BLKID_vceb_2 = 0x16, + DBG_CLIENT_BLKID_dco = 0x17, + DBG_CLIENT_BLKID_xdma = 0x18, + DBG_CLIENT_BLKID_smu_0 = 0x19, + DBG_CLIENT_BLKID_smu_1 = 0x1a, + DBG_CLIENT_BLKID_smu_2 = 0x1b, + DBG_CLIENT_BLKID_gck = 0x1c, + DBG_CLIENT_BLKID_tmonw0 = 0x1d, + DBG_CLIENT_BLKID_tmonw1 = 0x1e, + DBG_CLIENT_BLKID_grbm = 0x1f, + DBG_CLIENT_BLKID_rlc = 0x20, + DBG_CLIENT_BLKID_ds0 = 0x21, + DBG_CLIENT_BLKID_cpg_0 = 0x22, + DBG_CLIENT_BLKID_cpg_1 = 0x23, + DBG_CLIENT_BLKID_cpc_0 = 0x24, + DBG_CLIENT_BLKID_cpc_1 = 0x25, + DBG_CLIENT_BLKID_cpf = 0x26, + DBG_CLIENT_BLKID_scf0 = 0x27, + DBG_CLIENT_BLKID_scf1 = 0x28, + DBG_CLIENT_BLKID_scf2 = 0x29, + DBG_CLIENT_BLKID_scf3 = 0x2a, + DBG_CLIENT_BLKID_pc0 = 0x2b, + DBG_CLIENT_BLKID_pc1 = 0x2c, + DBG_CLIENT_BLKID_pc2 = 0x2d, + DBG_CLIENT_BLKID_pc3 = 0x2e, + DBG_CLIENT_BLKID_vgt0 = 0x2f, + DBG_CLIENT_BLKID_vgt1 = 0x30, + DBG_CLIENT_BLKID_vgt2 = 0x31, + DBG_CLIENT_BLKID_vgt3 = 0x32, + DBG_CLIENT_BLKID_sx00 = 0x33, + DBG_CLIENT_BLKID_sx10 = 0x34, + DBG_CLIENT_BLKID_sx20 = 0x35, + DBG_CLIENT_BLKID_sx30 = 0x36, + DBG_CLIENT_BLKID_cb001 = 0x37, + DBG_CLIENT_BLKID_cb200 = 0x38, + DBG_CLIENT_BLKID_cb201 = 0x39, + DBG_CLIENT_BLKID_cbr0 = 0x3a, + DBG_CLIENT_BLKID_cb000 = 0x3b, + DBG_CLIENT_BLKID_cb101 = 0x3c, + DBG_CLIENT_BLKID_cb300 = 0x3d, + DBG_CLIENT_BLKID_cb301 = 0x3e, + DBG_CLIENT_BLKID_cbr1 = 0x3f, + DBG_CLIENT_BLKID_cb100 = 0x40, + DBG_CLIENT_BLKID_ia0 = 0x41, + DBG_CLIENT_BLKID_ia1 = 0x42, + DBG_CLIENT_BLKID_bci0 = 0x43, + DBG_CLIENT_BLKID_bci1 = 0x44, + DBG_CLIENT_BLKID_bci2 = 0x45, + DBG_CLIENT_BLKID_bci3 = 0x46, + DBG_CLIENT_BLKID_pa0 = 0x47, + DBG_CLIENT_BLKID_pa1 = 0x48, + DBG_CLIENT_BLKID_spim0 = 0x49, + DBG_CLIENT_BLKID_spim1 = 0x4a, + DBG_CLIENT_BLKID_spim2 = 0x4b, + DBG_CLIENT_BLKID_spim3 = 0x4c, + DBG_CLIENT_BLKID_sdma = 0x4d, + DBG_CLIENT_BLKID_ih = 0x4e, + DBG_CLIENT_BLKID_sem = 0x4f, + DBG_CLIENT_BLKID_srbm = 0x50, + DBG_CLIENT_BLKID_hdp = 0x51, + DBG_CLIENT_BLKID_acp_0 = 0x52, + DBG_CLIENT_BLKID_acp_1 = 0x53, + DBG_CLIENT_BLKID_sam = 0x54, + DBG_CLIENT_BLKID_mcc0 = 0x55, + DBG_CLIENT_BLKID_mcc1 = 0x56, + DBG_CLIENT_BLKID_mcc2 = 0x57, + DBG_CLIENT_BLKID_mcc3 = 0x58, + DBG_CLIENT_BLKID_mcd0 = 0x59, + DBG_CLIENT_BLKID_mcd1 = 0x5a, + DBG_CLIENT_BLKID_mcd2 = 0x5b, + DBG_CLIENT_BLKID_mcd3 = 0x5c, + DBG_CLIENT_BLKID_mcb = 0x5d, + DBG_CLIENT_BLKID_vmc = 0x5e, + DBG_CLIENT_BLKID_gmcon = 0x5f, + DBG_CLIENT_BLKID_gdc_0 = 0x60, + DBG_CLIENT_BLKID_gdc_1 = 0x61, + DBG_CLIENT_BLKID_gdc_2 = 0x62, + DBG_CLIENT_BLKID_gdc_3 = 0x63, + DBG_CLIENT_BLKID_gdc_4 = 0x64, + DBG_CLIENT_BLKID_gdc_5 = 0x65, + DBG_CLIENT_BLKID_gdc_6 = 0x66, + DBG_CLIENT_BLKID_gdc_7 = 0x67, + DBG_CLIENT_BLKID_gdc_8 = 0x68, + DBG_CLIENT_BLKID_gdc_9 = 0x69, + DBG_CLIENT_BLKID_gdc_10 = 0x6a, + DBG_CLIENT_BLKID_gdc_11 = 0x6b, + DBG_CLIENT_BLKID_gdc_12 = 0x6c, + DBG_CLIENT_BLKID_gdc_13 = 0x6d, + DBG_CLIENT_BLKID_gdc_14 = 0x6e, + DBG_CLIENT_BLKID_gdc_15 = 0x6f, + DBG_CLIENT_BLKID_gdc_16 = 0x70, + DBG_CLIENT_BLKID_gdc_17 = 0x71, + DBG_CLIENT_BLKID_gdc_18 = 0x72, + DBG_CLIENT_BLKID_gdc_19 = 0x73, + DBG_CLIENT_BLKID_gdc_20 = 0x74, + DBG_CLIENT_BLKID_gdc_21 = 0x75, + DBG_CLIENT_BLKID_gdc_22 = 0x76, + DBG_CLIENT_BLKID_wd = 0x77, + DBG_CLIENT_BLKID_sdma_0 = 0x78, + DBG_CLIENT_BLKID_sdma_1 = 0x79, +} DebugBlockId; +typedef enum DebugBlockId_OLD { + DBG_BLOCK_ID_RESERVED = 0x0, + DBG_BLOCK_ID_DBG = 0x1, + DBG_BLOCK_ID_VMC = 0x2, + DBG_BLOCK_ID_PDMA = 0x3, + DBG_BLOCK_ID_CG = 0x4, + DBG_BLOCK_ID_SRBM = 0x5, + DBG_BLOCK_ID_GRBM = 0x6, + DBG_BLOCK_ID_RLC = 0x7, + DBG_BLOCK_ID_CSC = 0x8, + DBG_BLOCK_ID_SEM = 0x9, + DBG_BLOCK_ID_IH = 0xa, + DBG_BLOCK_ID_SC = 0xb, + DBG_BLOCK_ID_SQ = 0xc, + DBG_BLOCK_ID_AVP = 0xd, + DBG_BLOCK_ID_GMCON = 0xe, + DBG_BLOCK_ID_SMU = 0xf, + DBG_BLOCK_ID_DMA0 = 0x10, + DBG_BLOCK_ID_DMA1 = 0x11, + DBG_BLOCK_ID_SPIM = 0x12, + DBG_BLOCK_ID_GDS = 0x13, + DBG_BLOCK_ID_SPIS = 0x14, + DBG_BLOCK_ID_UNUSED0 = 0x15, + DBG_BLOCK_ID_PA0 = 0x16, + DBG_BLOCK_ID_PA1 = 0x17, + DBG_BLOCK_ID_CP0 = 0x18, + DBG_BLOCK_ID_CP1 = 0x19, + DBG_BLOCK_ID_CP2 = 0x1a, + DBG_BLOCK_ID_UNUSED1 = 0x1b, + DBG_BLOCK_ID_UVDU = 0x1c, + DBG_BLOCK_ID_UVDM = 0x1d, + DBG_BLOCK_ID_VCE = 0x1e, + DBG_BLOCK_ID_UNUSED2 = 0x1f, + DBG_BLOCK_ID_VGT0 = 0x20, + DBG_BLOCK_ID_VGT1 = 0x21, + DBG_BLOCK_ID_IA = 0x22, + DBG_BLOCK_ID_UNUSED3 = 0x23, + DBG_BLOCK_ID_SCT0 = 0x24, + DBG_BLOCK_ID_SCT1 = 0x25, + DBG_BLOCK_ID_SPM0 = 0x26, + DBG_BLOCK_ID_SPM1 = 0x27, + DBG_BLOCK_ID_TCAA = 0x28, + DBG_BLOCK_ID_TCAB = 0x29, + DBG_BLOCK_ID_TCCA = 0x2a, + DBG_BLOCK_ID_TCCB = 0x2b, + DBG_BLOCK_ID_MCC0 = 0x2c, + DBG_BLOCK_ID_MCC1 = 0x2d, + DBG_BLOCK_ID_MCC2 = 0x2e, + DBG_BLOCK_ID_MCC3 = 0x2f, + DBG_BLOCK_ID_SX0 = 0x30, + DBG_BLOCK_ID_SX1 = 0x31, + DBG_BLOCK_ID_SX2 = 0x32, + DBG_BLOCK_ID_SX3 = 0x33, + DBG_BLOCK_ID_UNUSED4 = 0x34, + DBG_BLOCK_ID_UNUSED5 = 0x35, + DBG_BLOCK_ID_UNUSED6 = 0x36, + DBG_BLOCK_ID_UNUSED7 = 0x37, + DBG_BLOCK_ID_PC0 = 0x38, + DBG_BLOCK_ID_PC1 = 0x39, + DBG_BLOCK_ID_UNUSED8 = 0x3a, + DBG_BLOCK_ID_UNUSED9 = 0x3b, + DBG_BLOCK_ID_UNUSED10 = 0x3c, + DBG_BLOCK_ID_UNUSED11 = 0x3d, + DBG_BLOCK_ID_MCB = 0x3e, + DBG_BLOCK_ID_UNUSED12 = 0x3f, + DBG_BLOCK_ID_SCB0 = 0x40, + DBG_BLOCK_ID_SCB1 = 0x41, + DBG_BLOCK_ID_UNUSED13 = 0x42, + DBG_BLOCK_ID_UNUSED14 = 0x43, + DBG_BLOCK_ID_SCF0 = 0x44, + DBG_BLOCK_ID_SCF1 = 0x45, + DBG_BLOCK_ID_UNUSED15 = 0x46, + DBG_BLOCK_ID_UNUSED16 = 0x47, + DBG_BLOCK_ID_BCI0 = 0x48, + DBG_BLOCK_ID_BCI1 = 0x49, + DBG_BLOCK_ID_BCI2 = 0x4a, + DBG_BLOCK_ID_BCI3 = 0x4b, + DBG_BLOCK_ID_UNUSED17 = 0x4c, + DBG_BLOCK_ID_UNUSED18 = 0x4d, + DBG_BLOCK_ID_UNUSED19 = 0x4e, + DBG_BLOCK_ID_UNUSED20 = 0x4f, + DBG_BLOCK_ID_CB00 = 0x50, + DBG_BLOCK_ID_CB01 = 0x51, + DBG_BLOCK_ID_CB02 = 0x52, + DBG_BLOCK_ID_CB03 = 0x53, + DBG_BLOCK_ID_CB04 = 0x54, + DBG_BLOCK_ID_UNUSED21 = 0x55, + DBG_BLOCK_ID_UNUSED22 = 0x56, + DBG_BLOCK_ID_UNUSED23 = 0x57, + DBG_BLOCK_ID_CB10 = 0x58, + DBG_BLOCK_ID_CB11 = 0x59, + DBG_BLOCK_ID_CB12 = 0x5a, + DBG_BLOCK_ID_CB13 = 0x5b, + DBG_BLOCK_ID_CB14 = 0x5c, + DBG_BLOCK_ID_UNUSED24 = 0x5d, + DBG_BLOCK_ID_UNUSED25 = 0x5e, + DBG_BLOCK_ID_UNUSED26 = 0x5f, + DBG_BLOCK_ID_TCP0 = 0x60, + DBG_BLOCK_ID_TCP1 = 0x61, + DBG_BLOCK_ID_TCP2 = 0x62, + DBG_BLOCK_ID_TCP3 = 0x63, + DBG_BLOCK_ID_TCP4 = 0x64, + DBG_BLOCK_ID_TCP5 = 0x65, + DBG_BLOCK_ID_TCP6 = 0x66, + DBG_BLOCK_ID_TCP7 = 0x67, + DBG_BLOCK_ID_TCP8 = 0x68, + DBG_BLOCK_ID_TCP9 = 0x69, + DBG_BLOCK_ID_TCP10 = 0x6a, + DBG_BLOCK_ID_TCP11 = 0x6b, + DBG_BLOCK_ID_TCP12 = 0x6c, + DBG_BLOCK_ID_TCP13 = 0x6d, + DBG_BLOCK_ID_TCP14 = 0x6e, + DBG_BLOCK_ID_TCP15 = 0x6f, + DBG_BLOCK_ID_TCP16 = 0x70, + DBG_BLOCK_ID_TCP17 = 0x71, + DBG_BLOCK_ID_TCP18 = 0x72, + DBG_BLOCK_ID_TCP19 = 0x73, + DBG_BLOCK_ID_TCP20 = 0x74, + DBG_BLOCK_ID_TCP21 = 0x75, + DBG_BLOCK_ID_TCP22 = 0x76, + DBG_BLOCK_ID_TCP23 = 0x77, + DBG_BLOCK_ID_TCP_RESERVED0 = 0x78, + DBG_BLOCK_ID_TCP_RESERVED1 = 0x79, + DBG_BLOCK_ID_TCP_RESERVED2 = 0x7a, + DBG_BLOCK_ID_TCP_RESERVED3 = 0x7b, + DBG_BLOCK_ID_TCP_RESERVED4 = 0x7c, + DBG_BLOCK_ID_TCP_RESERVED5 = 0x7d, + DBG_BLOCK_ID_TCP_RESERVED6 = 0x7e, + DBG_BLOCK_ID_TCP_RESERVED7 = 0x7f, + DBG_BLOCK_ID_DB00 = 0x80, + DBG_BLOCK_ID_DB01 = 0x81, + DBG_BLOCK_ID_DB02 = 0x82, + DBG_BLOCK_ID_DB03 = 0x83, + DBG_BLOCK_ID_DB04 = 0x84, + DBG_BLOCK_ID_UNUSED27 = 0x85, + DBG_BLOCK_ID_UNUSED28 = 0x86, + DBG_BLOCK_ID_UNUSED29 = 0x87, + DBG_BLOCK_ID_DB10 = 0x88, + DBG_BLOCK_ID_DB11 = 0x89, + DBG_BLOCK_ID_DB12 = 0x8a, + DBG_BLOCK_ID_DB13 = 0x8b, + DBG_BLOCK_ID_DB14 = 0x8c, + DBG_BLOCK_ID_UNUSED30 = 0x8d, + DBG_BLOCK_ID_UNUSED31 = 0x8e, + DBG_BLOCK_ID_UNUSED32 = 0x8f, + DBG_BLOCK_ID_TCC0 = 0x90, + DBG_BLOCK_ID_TCC1 = 0x91, + DBG_BLOCK_ID_TCC2 = 0x92, + DBG_BLOCK_ID_TCC3 = 0x93, + DBG_BLOCK_ID_TCC4 = 0x94, + DBG_BLOCK_ID_TCC5 = 0x95, + DBG_BLOCK_ID_TCC6 = 0x96, + DBG_BLOCK_ID_TCC7 = 0x97, + DBG_BLOCK_ID_SPS00 = 0x98, + DBG_BLOCK_ID_SPS01 = 0x99, + DBG_BLOCK_ID_SPS02 = 0x9a, + DBG_BLOCK_ID_SPS10 = 0x9b, + DBG_BLOCK_ID_SPS11 = 0x9c, + DBG_BLOCK_ID_SPS12 = 0x9d, + DBG_BLOCK_ID_UNUSED33 = 0x9e, + DBG_BLOCK_ID_UNUSED34 = 0x9f, + DBG_BLOCK_ID_TA00 = 0xa0, + DBG_BLOCK_ID_TA01 = 0xa1, + DBG_BLOCK_ID_TA02 = 0xa2, + DBG_BLOCK_ID_TA03 = 0xa3, + DBG_BLOCK_ID_TA04 = 0xa4, + DBG_BLOCK_ID_TA05 = 0xa5, + DBG_BLOCK_ID_TA06 = 0xa6, + DBG_BLOCK_ID_TA07 = 0xa7, + DBG_BLOCK_ID_TA08 = 0xa8, + DBG_BLOCK_ID_TA09 = 0xa9, + DBG_BLOCK_ID_TA0A = 0xaa, + DBG_BLOCK_ID_TA0B = 0xab, + DBG_BLOCK_ID_UNUSED35 = 0xac, + DBG_BLOCK_ID_UNUSED36 = 0xad, + DBG_BLOCK_ID_UNUSED37 = 0xae, + DBG_BLOCK_ID_UNUSED38 = 0xaf, + DBG_BLOCK_ID_TA10 = 0xb0, + DBG_BLOCK_ID_TA11 = 0xb1, + DBG_BLOCK_ID_TA12 = 0xb2, + DBG_BLOCK_ID_TA13 = 0xb3, + DBG_BLOCK_ID_TA14 = 0xb4, + DBG_BLOCK_ID_TA15 = 0xb5, + DBG_BLOCK_ID_TA16 = 0xb6, + DBG_BLOCK_ID_TA17 = 0xb7, + DBG_BLOCK_ID_TA18 = 0xb8, + DBG_BLOCK_ID_TA19 = 0xb9, + DBG_BLOCK_ID_TA1A = 0xba, + DBG_BLOCK_ID_TA1B = 0xbb, + DBG_BLOCK_ID_UNUSED39 = 0xbc, + DBG_BLOCK_ID_UNUSED40 = 0xbd, + DBG_BLOCK_ID_UNUSED41 = 0xbe, + DBG_BLOCK_ID_UNUSED42 = 0xbf, + DBG_BLOCK_ID_TD00 = 0xc0, + DBG_BLOCK_ID_TD01 = 0xc1, + DBG_BLOCK_ID_TD02 = 0xc2, + DBG_BLOCK_ID_TD03 = 0xc3, + DBG_BLOCK_ID_TD04 = 0xc4, + DBG_BLOCK_ID_TD05 = 0xc5, + DBG_BLOCK_ID_TD06 = 0xc6, + DBG_BLOCK_ID_TD07 = 0xc7, + DBG_BLOCK_ID_TD08 = 0xc8, + DBG_BLOCK_ID_TD09 = 0xc9, + DBG_BLOCK_ID_TD0A = 0xca, + DBG_BLOCK_ID_TD0B = 0xcb, + DBG_BLOCK_ID_UNUSED43 = 0xcc, + DBG_BLOCK_ID_UNUSED44 = 0xcd, + DBG_BLOCK_ID_UNUSED45 = 0xce, + DBG_BLOCK_ID_UNUSED46 = 0xcf, + DBG_BLOCK_ID_TD10 = 0xd0, + DBG_BLOCK_ID_TD11 = 0xd1, + DBG_BLOCK_ID_TD12 = 0xd2, + DBG_BLOCK_ID_TD13 = 0xd3, + DBG_BLOCK_ID_TD14 = 0xd4, + DBG_BLOCK_ID_TD15 = 0xd5, + DBG_BLOCK_ID_TD16 = 0xd6, + DBG_BLOCK_ID_TD17 = 0xd7, + DBG_BLOCK_ID_TD18 = 0xd8, + DBG_BLOCK_ID_TD19 = 0xd9, + DBG_BLOCK_ID_TD1A = 0xda, + DBG_BLOCK_ID_TD1B = 0xdb, + DBG_BLOCK_ID_UNUSED47 = 0xdc, + DBG_BLOCK_ID_UNUSED48 = 0xdd, + DBG_BLOCK_ID_UNUSED49 = 0xde, + DBG_BLOCK_ID_UNUSED50 = 0xdf, + DBG_BLOCK_ID_MCD0 = 0xe0, + DBG_BLOCK_ID_MCD1 = 0xe1, + DBG_BLOCK_ID_MCD2 = 0xe2, + DBG_BLOCK_ID_MCD3 = 0xe3, + DBG_BLOCK_ID_MCD4 = 0xe4, + DBG_BLOCK_ID_MCD5 = 0xe5, + DBG_BLOCK_ID_UNUSED51 = 0xe6, + DBG_BLOCK_ID_UNUSED52 = 0xe7, +} DebugBlockId_OLD; +typedef enum DebugBlockId_BY2 { + DBG_BLOCK_ID_RESERVED_BY2 = 0x0, + DBG_BLOCK_ID_VMC_BY2 = 0x1, + DBG_BLOCK_ID_CG_BY2 = 0x2, + DBG_BLOCK_ID_GRBM_BY2 = 0x3, + DBG_BLOCK_ID_CSC_BY2 = 0x4, + DBG_BLOCK_ID_IH_BY2 = 0x5, + DBG_BLOCK_ID_SQ_BY2 = 0x6, + DBG_BLOCK_ID_GMCON_BY2 = 0x7, + DBG_BLOCK_ID_DMA0_BY2 = 0x8, + DBG_BLOCK_ID_SPIM_BY2 = 0x9, + DBG_BLOCK_ID_SPIS_BY2 = 0xa, + DBG_BLOCK_ID_PA0_BY2 = 0xb, + DBG_BLOCK_ID_CP0_BY2 = 0xc, + DBG_BLOCK_ID_CP2_BY2 = 0xd, + DBG_BLOCK_ID_UVDU_BY2 = 0xe, + DBG_BLOCK_ID_VCE_BY2 = 0xf, + DBG_BLOCK_ID_VGT0_BY2 = 0x10, + DBG_BLOCK_ID_IA_BY2 = 0x11, + DBG_BLOCK_ID_SCT0_BY2 = 0x12, + DBG_BLOCK_ID_SPM0_BY2 = 0x13, + DBG_BLOCK_ID_TCAA_BY2 = 0x14, + DBG_BLOCK_ID_TCCA_BY2 = 0x15, + DBG_BLOCK_ID_MCC0_BY2 = 0x16, + DBG_BLOCK_ID_MCC2_BY2 = 0x17, + DBG_BLOCK_ID_SX0_BY2 = 0x18, + DBG_BLOCK_ID_SX2_BY2 = 0x19, + DBG_BLOCK_ID_UNUSED4_BY2 = 0x1a, + DBG_BLOCK_ID_UNUSED6_BY2 = 0x1b, + DBG_BLOCK_ID_PC0_BY2 = 0x1c, + DBG_BLOCK_ID_UNUSED8_BY2 = 0x1d, + DBG_BLOCK_ID_UNUSED10_BY2 = 0x1e, + DBG_BLOCK_ID_MCB_BY2 = 0x1f, + DBG_BLOCK_ID_SCB0_BY2 = 0x20, + DBG_BLOCK_ID_UNUSED13_BY2 = 0x21, + DBG_BLOCK_ID_SCF0_BY2 = 0x22, + DBG_BLOCK_ID_UNUSED15_BY2 = 0x23, + DBG_BLOCK_ID_BCI0_BY2 = 0x24, + DBG_BLOCK_ID_BCI2_BY2 = 0x25, + DBG_BLOCK_ID_UNUSED17_BY2 = 0x26, + DBG_BLOCK_ID_UNUSED19_BY2 = 0x27, + DBG_BLOCK_ID_CB00_BY2 = 0x28, + DBG_BLOCK_ID_CB02_BY2 = 0x29, + DBG_BLOCK_ID_CB04_BY2 = 0x2a, + DBG_BLOCK_ID_UNUSED22_BY2 = 0x2b, + DBG_BLOCK_ID_CB10_BY2 = 0x2c, + DBG_BLOCK_ID_CB12_BY2 = 0x2d, + DBG_BLOCK_ID_CB14_BY2 = 0x2e, + DBG_BLOCK_ID_UNUSED25_BY2 = 0x2f, + DBG_BLOCK_ID_TCP0_BY2 = 0x30, + DBG_BLOCK_ID_TCP2_BY2 = 0x31, + DBG_BLOCK_ID_TCP4_BY2 = 0x32, + DBG_BLOCK_ID_TCP6_BY2 = 0x33, + DBG_BLOCK_ID_TCP8_BY2 = 0x34, + DBG_BLOCK_ID_TCP10_BY2 = 0x35, + DBG_BLOCK_ID_TCP12_BY2 = 0x36, + DBG_BLOCK_ID_TCP14_BY2 = 0x37, + DBG_BLOCK_ID_TCP16_BY2 = 0x38, + DBG_BLOCK_ID_TCP18_BY2 = 0x39, + DBG_BLOCK_ID_TCP20_BY2 = 0x3a, + DBG_BLOCK_ID_TCP22_BY2 = 0x3b, + DBG_BLOCK_ID_TCP_RESERVED0_BY2 = 0x3c, + DBG_BLOCK_ID_TCP_RESERVED2_BY2 = 0x3d, + DBG_BLOCK_ID_TCP_RESERVED4_BY2 = 0x3e, + DBG_BLOCK_ID_TCP_RESERVED6_BY2 = 0x3f, + DBG_BLOCK_ID_DB00_BY2 = 0x40, + DBG_BLOCK_ID_DB02_BY2 = 0x41, + DBG_BLOCK_ID_DB04_BY2 = 0x42, + DBG_BLOCK_ID_UNUSED28_BY2 = 0x43, + DBG_BLOCK_ID_DB10_BY2 = 0x44, + DBG_BLOCK_ID_DB12_BY2 = 0x45, + DBG_BLOCK_ID_DB14_BY2 = 0x46, + DBG_BLOCK_ID_UNUSED31_BY2 = 0x47, + DBG_BLOCK_ID_TCC0_BY2 = 0x48, + DBG_BLOCK_ID_TCC2_BY2 = 0x49, + DBG_BLOCK_ID_TCC4_BY2 = 0x4a, + DBG_BLOCK_ID_TCC6_BY2 = 0x4b, + DBG_BLOCK_ID_SPS00_BY2 = 0x4c, + DBG_BLOCK_ID_SPS02_BY2 = 0x4d, + DBG_BLOCK_ID_SPS11_BY2 = 0x4e, + DBG_BLOCK_ID_UNUSED33_BY2 = 0x4f, + DBG_BLOCK_ID_TA00_BY2 = 0x50, + DBG_BLOCK_ID_TA02_BY2 = 0x51, + DBG_BLOCK_ID_TA04_BY2 = 0x52, + DBG_BLOCK_ID_TA06_BY2 = 0x53, + DBG_BLOCK_ID_TA08_BY2 = 0x54, + DBG_BLOCK_ID_TA0A_BY2 = 0x55, + DBG_BLOCK_ID_UNUSED35_BY2 = 0x56, + DBG_BLOCK_ID_UNUSED37_BY2 = 0x57, + DBG_BLOCK_ID_TA10_BY2 = 0x58, + DBG_BLOCK_ID_TA12_BY2 = 0x59, + DBG_BLOCK_ID_TA14_BY2 = 0x5a, + DBG_BLOCK_ID_TA16_BY2 = 0x5b, + DBG_BLOCK_ID_TA18_BY2 = 0x5c, + DBG_BLOCK_ID_TA1A_BY2 = 0x5d, + DBG_BLOCK_ID_UNUSED39_BY2 = 0x5e, + DBG_BLOCK_ID_UNUSED41_BY2 = 0x5f, + DBG_BLOCK_ID_TD00_BY2 = 0x60, + DBG_BLOCK_ID_TD02_BY2 = 0x61, + DBG_BLOCK_ID_TD04_BY2 = 0x62, + DBG_BLOCK_ID_TD06_BY2 = 0x63, + DBG_BLOCK_ID_TD08_BY2 = 0x64, + DBG_BLOCK_ID_TD0A_BY2 = 0x65, + DBG_BLOCK_ID_UNUSED43_BY2 = 0x66, + DBG_BLOCK_ID_UNUSED45_BY2 = 0x67, + DBG_BLOCK_ID_TD10_BY2 = 0x68, + DBG_BLOCK_ID_TD12_BY2 = 0x69, + DBG_BLOCK_ID_TD14_BY2 = 0x6a, + DBG_BLOCK_ID_TD16_BY2 = 0x6b, + DBG_BLOCK_ID_TD18_BY2 = 0x6c, + DBG_BLOCK_ID_TD1A_BY2 = 0x6d, + DBG_BLOCK_ID_UNUSED47_BY2 = 0x6e, + DBG_BLOCK_ID_UNUSED49_BY2 = 0x6f, + DBG_BLOCK_ID_MCD0_BY2 = 0x70, + DBG_BLOCK_ID_MCD2_BY2 = 0x71, + DBG_BLOCK_ID_MCD4_BY2 = 0x72, + DBG_BLOCK_ID_UNUSED51_BY2 = 0x73, +} DebugBlockId_BY2; +typedef enum DebugBlockId_BY4 { + DBG_BLOCK_ID_RESERVED_BY4 = 0x0, + DBG_BLOCK_ID_CG_BY4 = 0x1, + DBG_BLOCK_ID_CSC_BY4 = 0x2, + DBG_BLOCK_ID_SQ_BY4 = 0x3, + DBG_BLOCK_ID_DMA0_BY4 = 0x4, + DBG_BLOCK_ID_SPIS_BY4 = 0x5, + DBG_BLOCK_ID_CP0_BY4 = 0x6, + DBG_BLOCK_ID_UVDU_BY4 = 0x7, + DBG_BLOCK_ID_VGT0_BY4 = 0x8, + DBG_BLOCK_ID_SCT0_BY4 = 0x9, + DBG_BLOCK_ID_TCAA_BY4 = 0xa, + DBG_BLOCK_ID_MCC0_BY4 = 0xb, + DBG_BLOCK_ID_SX0_BY4 = 0xc, + DBG_BLOCK_ID_UNUSED4_BY4 = 0xd, + DBG_BLOCK_ID_PC0_BY4 = 0xe, + DBG_BLOCK_ID_UNUSED10_BY4 = 0xf, + DBG_BLOCK_ID_SCB0_BY4 = 0x10, + DBG_BLOCK_ID_SCF0_BY4 = 0x11, + DBG_BLOCK_ID_BCI0_BY4 = 0x12, + DBG_BLOCK_ID_UNUSED17_BY4 = 0x13, + DBG_BLOCK_ID_CB00_BY4 = 0x14, + DBG_BLOCK_ID_CB04_BY4 = 0x15, + DBG_BLOCK_ID_CB10_BY4 = 0x16, + DBG_BLOCK_ID_CB14_BY4 = 0x17, + DBG_BLOCK_ID_TCP0_BY4 = 0x18, + DBG_BLOCK_ID_TCP4_BY4 = 0x19, + DBG_BLOCK_ID_TCP8_BY4 = 0x1a, + DBG_BLOCK_ID_TCP12_BY4 = 0x1b, + DBG_BLOCK_ID_TCP16_BY4 = 0x1c, + DBG_BLOCK_ID_TCP20_BY4 = 0x1d, + DBG_BLOCK_ID_TCP_RESERVED0_BY4 = 0x1e, + DBG_BLOCK_ID_TCP_RESERVED4_BY4 = 0x1f, + DBG_BLOCK_ID_DB_BY4 = 0x20, + DBG_BLOCK_ID_DB04_BY4 = 0x21, + DBG_BLOCK_ID_DB10_BY4 = 0x22, + DBG_BLOCK_ID_DB14_BY4 = 0x23, + DBG_BLOCK_ID_TCC0_BY4 = 0x24, + DBG_BLOCK_ID_TCC4_BY4 = 0x25, + DBG_BLOCK_ID_SPS00_BY4 = 0x26, + DBG_BLOCK_ID_SPS11_BY4 = 0x27, + DBG_BLOCK_ID_TA00_BY4 = 0x28, + DBG_BLOCK_ID_TA04_BY4 = 0x29, + DBG_BLOCK_ID_TA08_BY4 = 0x2a, + DBG_BLOCK_ID_UNUSED35_BY4 = 0x2b, + DBG_BLOCK_ID_TA10_BY4 = 0x2c, + DBG_BLOCK_ID_TA14_BY4 = 0x2d, + DBG_BLOCK_ID_TA18_BY4 = 0x2e, + DBG_BLOCK_ID_UNUSED39_BY4 = 0x2f, + DBG_BLOCK_ID_TD00_BY4 = 0x30, + DBG_BLOCK_ID_TD04_BY4 = 0x31, + DBG_BLOCK_ID_TD08_BY4 = 0x32, + DBG_BLOCK_ID_UNUSED43_BY4 = 0x33, + DBG_BLOCK_ID_TD10_BY4 = 0x34, + DBG_BLOCK_ID_TD14_BY4 = 0x35, + DBG_BLOCK_ID_TD18_BY4 = 0x36, + DBG_BLOCK_ID_UNUSED47_BY4 = 0x37, + DBG_BLOCK_ID_MCD0_BY4 = 0x38, + DBG_BLOCK_ID_MCD4_BY4 = 0x39, +} DebugBlockId_BY4; +typedef enum DebugBlockId_BY8 { + DBG_BLOCK_ID_RESERVED_BY8 = 0x0, + DBG_BLOCK_ID_CSC_BY8 = 0x1, + DBG_BLOCK_ID_DMA0_BY8 = 0x2, + DBG_BLOCK_ID_CP0_BY8 = 0x3, + DBG_BLOCK_ID_VGT0_BY8 = 0x4, + DBG_BLOCK_ID_TCAA_BY8 = 0x5, + DBG_BLOCK_ID_SX0_BY8 = 0x6, + DBG_BLOCK_ID_PC0_BY8 = 0x7, + DBG_BLOCK_ID_SCB0_BY8 = 0x8, + DBG_BLOCK_ID_BCI0_BY8 = 0x9, + DBG_BLOCK_ID_CB00_BY8 = 0xa, + DBG_BLOCK_ID_CB10_BY8 = 0xb, + DBG_BLOCK_ID_TCP0_BY8 = 0xc, + DBG_BLOCK_ID_TCP8_BY8 = 0xd, + DBG_BLOCK_ID_TCP16_BY8 = 0xe, + DBG_BLOCK_ID_TCP_RESERVED0_BY8 = 0xf, + DBG_BLOCK_ID_DB00_BY8 = 0x10, + DBG_BLOCK_ID_DB10_BY8 = 0x11, + DBG_BLOCK_ID_TCC0_BY8 = 0x12, + DBG_BLOCK_ID_SPS00_BY8 = 0x13, + DBG_BLOCK_ID_TA00_BY8 = 0x14, + DBG_BLOCK_ID_TA08_BY8 = 0x15, + DBG_BLOCK_ID_TA10_BY8 = 0x16, + DBG_BLOCK_ID_TA18_BY8 = 0x17, + DBG_BLOCK_ID_TD00_BY8 = 0x18, + DBG_BLOCK_ID_TD08_BY8 = 0x19, + DBG_BLOCK_ID_TD10_BY8 = 0x1a, + DBG_BLOCK_ID_TD18_BY8 = 0x1b, + DBG_BLOCK_ID_MCD0_BY8 = 0x1c, +} DebugBlockId_BY8; +typedef enum DebugBlockId_BY16 { + DBG_BLOCK_ID_RESERVED_BY16 = 0x0, + DBG_BLOCK_ID_DMA0_BY16 = 0x1, + DBG_BLOCK_ID_VGT0_BY16 = 0x2, + DBG_BLOCK_ID_SX0_BY16 = 0x3, + DBG_BLOCK_ID_SCB0_BY16 = 0x4, + DBG_BLOCK_ID_CB00_BY16 = 0x5, + DBG_BLOCK_ID_TCP0_BY16 = 0x6, + DBG_BLOCK_ID_TCP16_BY16 = 0x7, + DBG_BLOCK_ID_DB00_BY16 = 0x8, + DBG_BLOCK_ID_TCC0_BY16 = 0x9, + DBG_BLOCK_ID_TA00_BY16 = 0xa, + DBG_BLOCK_ID_TA10_BY16 = 0xb, + DBG_BLOCK_ID_TD00_BY16 = 0xc, + DBG_BLOCK_ID_TD10_BY16 = 0xd, + DBG_BLOCK_ID_MCD0_BY16 = 0xe, +} DebugBlockId_BY16; +typedef enum CompareRef { + REF_NEVER = 0x0, + REF_LESS = 0x1, + REF_EQUAL = 0x2, + REF_LEQUAL = 0x3, + REF_GREATER = 0x4, + REF_NOTEQUAL = 0x5, + REF_GEQUAL = 0x6, + REF_ALWAYS = 0x7, +} CompareRef; +typedef enum ReadSize { + READ_256_BITS = 0x0, + READ_512_BITS = 0x1, +} ReadSize; +typedef enum DepthFormat { + DEPTH_INVALID = 0x0, + DEPTH_16 = 0x1, + DEPTH_X8_24 = 0x2, + DEPTH_8_24 = 0x3, + DEPTH_X8_24_FLOAT = 0x4, + DEPTH_8_24_FLOAT = 0x5, + DEPTH_32_FLOAT = 0x6, + DEPTH_X24_8_32_FLOAT = 0x7, +} DepthFormat; +typedef enum ZFormat { + Z_INVALID = 0x0, + Z_16 = 0x1, + Z_24 = 0x2, + Z_32_FLOAT = 0x3, +} ZFormat; +typedef enum StencilFormat { + STENCIL_INVALID = 0x0, + STENCIL_8 = 0x1, +} StencilFormat; +typedef enum CmaskMode { + CMASK_CLEAR_NONE = 0x0, + CMASK_CLEAR_ONE = 0x1, + CMASK_CLEAR_ALL = 0x2, + CMASK_ANY_EXPANDED = 0x3, + CMASK_ALPHA0_FRAG1 = 0x4, + CMASK_ALPHA0_FRAG2 = 0x5, + CMASK_ALPHA0_FRAG4 = 0x6, + CMASK_ALPHA0_FRAGS = 0x7, + CMASK_ALPHA1_FRAG1 = 0x8, + CMASK_ALPHA1_FRAG2 = 0x9, + CMASK_ALPHA1_FRAG4 = 0xa, + CMASK_ALPHA1_FRAGS = 0xb, + CMASK_ALPHAX_FRAG1 = 0xc, + CMASK_ALPHAX_FRAG2 = 0xd, + CMASK_ALPHAX_FRAG4 = 0xe, + CMASK_ALPHAX_FRAGS = 0xf, +} CmaskMode; +typedef enum QuadExportFormat { + EXPORT_UNUSED = 0x0, + EXPORT_32_R = 0x1, + EXPORT_32_GR = 0x2, + EXPORT_32_AR = 0x3, + EXPORT_FP16_ABGR = 0x4, + EXPORT_UNSIGNED16_ABGR = 0x5, + EXPORT_SIGNED16_ABGR = 0x6, + EXPORT_32_ABGR = 0x7, +} QuadExportFormat; +typedef enum QuadExportFormatOld { + EXPORT_4P_32BPC_ABGR = 0x0, + EXPORT_4P_16BPC_ABGR = 0x1, + EXPORT_4P_32BPC_GR = 0x2, + EXPORT_4P_32BPC_AR = 0x3, + EXPORT_2P_32BPC_ABGR = 0x4, + EXPORT_8P_32BPC_R = 0x5, +} QuadExportFormatOld; +typedef enum ColorFormat { + COLOR_INVALID = 0x0, + COLOR_8 = 0x1, + COLOR_16 = 0x2, + COLOR_8_8 = 0x3, + COLOR_32 = 0x4, + COLOR_16_16 = 0x5, + COLOR_10_11_11 = 0x6, + COLOR_11_11_10 = 0x7, + COLOR_10_10_10_2 = 0x8, + COLOR_2_10_10_10 = 0x9, + COLOR_8_8_8_8 = 0xa, + COLOR_32_32 = 0xb, + COLOR_16_16_16_16 = 0xc, + COLOR_RESERVED_13 = 0xd, + COLOR_32_32_32_32 = 0xe, + COLOR_RESERVED_15 = 0xf, + COLOR_5_6_5 = 0x10, + COLOR_1_5_5_5 = 0x11, + COLOR_5_5_5_1 = 0x12, + COLOR_4_4_4_4 = 0x13, + COLOR_8_24 = 0x14, + COLOR_24_8 = 0x15, + COLOR_X24_8_32_FLOAT = 0x16, + COLOR_RESERVED_23 = 0x17, +} ColorFormat; +typedef enum SurfaceFormat { + FMT_INVALID = 0x0, + FMT_8 = 0x1, + FMT_16 = 0x2, + FMT_8_8 = 0x3, + FMT_32 = 0x4, + FMT_16_16 = 0x5, + FMT_10_11_11 = 0x6, + FMT_11_11_10 = 0x7, + FMT_10_10_10_2 = 0x8, + FMT_2_10_10_10 = 0x9, + FMT_8_8_8_8 = 0xa, + FMT_32_32 = 0xb, + FMT_16_16_16_16 = 0xc, + FMT_32_32_32 = 0xd, + FMT_32_32_32_32 = 0xe, + FMT_RESERVED_4 = 0xf, + FMT_5_6_5 = 0x10, + FMT_1_5_5_5 = 0x11, + FMT_5_5_5_1 = 0x12, + FMT_4_4_4_4 = 0x13, + FMT_8_24 = 0x14, + FMT_24_8 = 0x15, + FMT_X24_8_32_FLOAT = 0x16, + FMT_RESERVED_33 = 0x17, + FMT_11_11_10_FLOAT = 0x18, + FMT_16_FLOAT = 0x19, + FMT_32_FLOAT = 0x1a, + FMT_16_16_FLOAT = 0x1b, + FMT_8_24_FLOAT = 0x1c, + FMT_24_8_FLOAT = 0x1d, + FMT_32_32_FLOAT = 0x1e, + FMT_10_11_11_FLOAT = 0x1f, + FMT_16_16_16_16_FLOAT = 0x20, + FMT_3_3_2 = 0x21, + FMT_6_5_5 = 0x22, + FMT_32_32_32_32_FLOAT = 0x23, + FMT_RESERVED_36 = 0x24, + FMT_1 = 0x25, + FMT_1_REVERSED = 0x26, + FMT_GB_GR = 0x27, + FMT_BG_RG = 0x28, + FMT_32_AS_8 = 0x29, + FMT_32_AS_8_8 = 0x2a, + FMT_5_9_9_9_SHAREDEXP = 0x2b, + FMT_8_8_8 = 0x2c, + FMT_16_16_16 = 0x2d, + FMT_16_16_16_FLOAT = 0x2e, + FMT_4_4 = 0x2f, + FMT_32_32_32_FLOAT = 0x30, + FMT_BC1 = 0x31, + FMT_BC2 = 0x32, + FMT_BC3 = 0x33, + FMT_BC4 = 0x34, + FMT_BC5 = 0x35, + FMT_BC6 = 0x36, + FMT_BC7 = 0x37, + FMT_32_AS_32_32_32_32 = 0x38, + FMT_APC3 = 0x39, + FMT_APC4 = 0x3a, + FMT_APC5 = 0x3b, + FMT_APC6 = 0x3c, + FMT_APC7 = 0x3d, + FMT_CTX1 = 0x3e, + FMT_RESERVED_63 = 0x3f, +} SurfaceFormat; +typedef enum BUF_DATA_FORMAT { + BUF_DATA_FORMAT_INVALID = 0x0, + BUF_DATA_FORMAT_8 = 0x1, + BUF_DATA_FORMAT_16 = 0x2, + BUF_DATA_FORMAT_8_8 = 0x3, + BUF_DATA_FORMAT_32 = 0x4, + BUF_DATA_FORMAT_16_16 = 0x5, + BUF_DATA_FORMAT_10_11_11 = 0x6, + BUF_DATA_FORMAT_11_11_10 = 0x7, + BUF_DATA_FORMAT_10_10_10_2 = 0x8, + BUF_DATA_FORMAT_2_10_10_10 = 0x9, + BUF_DATA_FORMAT_8_8_8_8 = 0xa, + BUF_DATA_FORMAT_32_32 = 0xb, + BUF_DATA_FORMAT_16_16_16_16 = 0xc, + BUF_DATA_FORMAT_32_32_32 = 0xd, + BUF_DATA_FORMAT_32_32_32_32 = 0xe, + BUF_DATA_FORMAT_RESERVED_15 = 0xf, +} BUF_DATA_FORMAT; +typedef enum IMG_DATA_FORMAT { + IMG_DATA_FORMAT_INVALID = 0x0, + IMG_DATA_FORMAT_8 = 0x1, + IMG_DATA_FORMAT_16 = 0x2, + IMG_DATA_FORMAT_8_8 = 0x3, + IMG_DATA_FORMAT_32 = 0x4, + IMG_DATA_FORMAT_16_16 = 0x5, + IMG_DATA_FORMAT_10_11_11 = 0x6, + IMG_DATA_FORMAT_11_11_10 = 0x7, + IMG_DATA_FORMAT_10_10_10_2 = 0x8, + IMG_DATA_FORMAT_2_10_10_10 = 0x9, + IMG_DATA_FORMAT_8_8_8_8 = 0xa, + IMG_DATA_FORMAT_32_32 = 0xb, + IMG_DATA_FORMAT_16_16_16_16 = 0xc, + IMG_DATA_FORMAT_32_32_32 = 0xd, + IMG_DATA_FORMAT_32_32_32_32 = 0xe, + IMG_DATA_FORMAT_RESERVED_15 = 0xf, + IMG_DATA_FORMAT_5_6_5 = 0x10, + IMG_DATA_FORMAT_1_5_5_5 = 0x11, + IMG_DATA_FORMAT_5_5_5_1 = 0x12, + IMG_DATA_FORMAT_4_4_4_4 = 0x13, + IMG_DATA_FORMAT_8_24 = 0x14, + IMG_DATA_FORMAT_24_8 = 0x15, + IMG_DATA_FORMAT_X24_8_32 = 0x16, + IMG_DATA_FORMAT_RESERVED_23 = 0x17, + IMG_DATA_FORMAT_RESERVED_24 = 0x18, + IMG_DATA_FORMAT_RESERVED_25 = 0x19, + IMG_DATA_FORMAT_RESERVED_26 = 0x1a, + IMG_DATA_FORMAT_RESERVED_27 = 0x1b, + IMG_DATA_FORMAT_RESERVED_28 = 0x1c, + IMG_DATA_FORMAT_RESERVED_29 = 0x1d, + IMG_DATA_FORMAT_RESERVED_30 = 0x1e, + IMG_DATA_FORMAT_RESERVED_31 = 0x1f, + IMG_DATA_FORMAT_GB_GR = 0x20, + IMG_DATA_FORMAT_BG_RG = 0x21, + IMG_DATA_FORMAT_5_9_9_9 = 0x22, + IMG_DATA_FORMAT_BC1 = 0x23, + IMG_DATA_FORMAT_BC2 = 0x24, + IMG_DATA_FORMAT_BC3 = 0x25, + IMG_DATA_FORMAT_BC4 = 0x26, + IMG_DATA_FORMAT_BC5 = 0x27, + IMG_DATA_FORMAT_BC6 = 0x28, + IMG_DATA_FORMAT_BC7 = 0x29, + IMG_DATA_FORMAT_RESERVED_42 = 0x2a, + IMG_DATA_FORMAT_RESERVED_43 = 0x2b, + IMG_DATA_FORMAT_FMASK8_S2_F1 = 0x2c, + IMG_DATA_FORMAT_FMASK8_S4_F1 = 0x2d, + IMG_DATA_FORMAT_FMASK8_S8_F1 = 0x2e, + IMG_DATA_FORMAT_FMASK8_S2_F2 = 0x2f, + IMG_DATA_FORMAT_FMASK8_S4_F2 = 0x30, + IMG_DATA_FORMAT_FMASK8_S4_F4 = 0x31, + IMG_DATA_FORMAT_FMASK16_S16_F1 = 0x32, + IMG_DATA_FORMAT_FMASK16_S8_F2 = 0x33, + IMG_DATA_FORMAT_FMASK32_S16_F2 = 0x34, + IMG_DATA_FORMAT_FMASK32_S8_F4 = 0x35, + IMG_DATA_FORMAT_FMASK32_S8_F8 = 0x36, + IMG_DATA_FORMAT_FMASK64_S16_F4 = 0x37, + IMG_DATA_FORMAT_FMASK64_S16_F8 = 0x38, + IMG_DATA_FORMAT_4_4 = 0x39, + IMG_DATA_FORMAT_6_5_5 = 0x3a, + IMG_DATA_FORMAT_1 = 0x3b, + IMG_DATA_FORMAT_1_REVERSED = 0x3c, + IMG_DATA_FORMAT_32_AS_8 = 0x3d, + IMG_DATA_FORMAT_32_AS_8_8 = 0x3e, + IMG_DATA_FORMAT_32_AS_32_32_32_32 = 0x3f, +} IMG_DATA_FORMAT; +typedef enum BUF_NUM_FORMAT { + BUF_NUM_FORMAT_UNORM = 0x0, + BUF_NUM_FORMAT_SNORM = 0x1, + BUF_NUM_FORMAT_USCALED = 0x2, + BUF_NUM_FORMAT_SSCALED = 0x3, + BUF_NUM_FORMAT_UINT = 0x4, + BUF_NUM_FORMAT_SINT = 0x5, + BUF_NUM_FORMAT_SNORM_OGL = 0x6, + BUF_NUM_FORMAT_FLOAT = 0x7, +} BUF_NUM_FORMAT; +typedef enum IMG_NUM_FORMAT { + IMG_NUM_FORMAT_UNORM = 0x0, + IMG_NUM_FORMAT_SNORM = 0x1, + IMG_NUM_FORMAT_USCALED = 0x2, + IMG_NUM_FORMAT_SSCALED = 0x3, + IMG_NUM_FORMAT_UINT = 0x4, + IMG_NUM_FORMAT_SINT = 0x5, + IMG_NUM_FORMAT_SNORM_OGL = 0x6, + IMG_NUM_FORMAT_FLOAT = 0x7, + IMG_NUM_FORMAT_RESERVED_8 = 0x8, + IMG_NUM_FORMAT_SRGB = 0x9, + IMG_NUM_FORMAT_UBNORM = 0xa, + IMG_NUM_FORMAT_UBNORM_OGL = 0xb, + IMG_NUM_FORMAT_UBINT = 0xc, + IMG_NUM_FORMAT_UBSCALED = 0xd, + IMG_NUM_FORMAT_RESERVED_14 = 0xe, + IMG_NUM_FORMAT_RESERVED_15 = 0xf, +} IMG_NUM_FORMAT; +typedef enum TileType { + ARRAY_COLOR_TILE = 0x0, + ARRAY_DEPTH_TILE = 0x1, +} TileType; +typedef enum NonDispTilingOrder { + ADDR_SURF_MICRO_TILING_DISPLAY = 0x0, + ADDR_SURF_MICRO_TILING_NON_DISPLAY = 0x1, +} NonDispTilingOrder; +typedef enum MicroTileMode { + ADDR_SURF_DISPLAY_MICRO_TILING = 0x0, + ADDR_SURF_THIN_MICRO_TILING = 0x1, + ADDR_SURF_DEPTH_MICRO_TILING = 0x2, + ADDR_SURF_ROTATED_MICRO_TILING = 0x3, + ADDR_SURF_THICK_MICRO_TILING = 0x4, +} MicroTileMode; +typedef enum TileSplit { + ADDR_SURF_TILE_SPLIT_64B = 0x0, + ADDR_SURF_TILE_SPLIT_128B = 0x1, + ADDR_SURF_TILE_SPLIT_256B = 0x2, + ADDR_SURF_TILE_SPLIT_512B = 0x3, + ADDR_SURF_TILE_SPLIT_1KB = 0x4, + ADDR_SURF_TILE_SPLIT_2KB = 0x5, + ADDR_SURF_TILE_SPLIT_4KB = 0x6, +} TileSplit; +typedef enum SampleSplit { + ADDR_SURF_SAMPLE_SPLIT_1 = 0x0, + ADDR_SURF_SAMPLE_SPLIT_2 = 0x1, + ADDR_SURF_SAMPLE_SPLIT_4 = 0x2, + ADDR_SURF_SAMPLE_SPLIT_8 = 0x3, +} SampleSplit; +typedef enum PipeConfig { + ADDR_SURF_P2 = 0x0, + ADDR_SURF_P2_RESERVED0 = 0x1, + ADDR_SURF_P2_RESERVED1 = 0x2, + ADDR_SURF_P2_RESERVED2 = 0x3, + ADDR_SURF_P4_8x16 = 0x4, + ADDR_SURF_P4_16x16 = 0x5, + ADDR_SURF_P4_16x32 = 0x6, + ADDR_SURF_P4_32x32 = 0x7, + ADDR_SURF_P8_16x16_8x16 = 0x8, + ADDR_SURF_P8_16x32_8x16 = 0x9, + ADDR_SURF_P8_32x32_8x16 = 0xa, + ADDR_SURF_P8_16x32_16x16 = 0xb, + ADDR_SURF_P8_32x32_16x16 = 0xc, + ADDR_SURF_P8_32x32_16x32 = 0xd, + ADDR_SURF_P8_32x64_32x32 = 0xe, +} PipeConfig; +typedef enum NumBanks { + ADDR_SURF_2_BANK = 0x0, + ADDR_SURF_4_BANK = 0x1, + ADDR_SURF_8_BANK = 0x2, + ADDR_SURF_16_BANK = 0x3, +} NumBanks; +typedef enum BankWidth { + ADDR_SURF_BANK_WIDTH_1 = 0x0, + ADDR_SURF_BANK_WIDTH_2 = 0x1, + ADDR_SURF_BANK_WIDTH_4 = 0x2, + ADDR_SURF_BANK_WIDTH_8 = 0x3, +} BankWidth; +typedef enum BankHeight { + ADDR_SURF_BANK_HEIGHT_1 = 0x0, + ADDR_SURF_BANK_HEIGHT_2 = 0x1, + ADDR_SURF_BANK_HEIGHT_4 = 0x2, + ADDR_SURF_BANK_HEIGHT_8 = 0x3, +} BankHeight; +typedef enum BankWidthHeight { + ADDR_SURF_BANK_WH_1 = 0x0, + ADDR_SURF_BANK_WH_2 = 0x1, + ADDR_SURF_BANK_WH_4 = 0x2, + ADDR_SURF_BANK_WH_8 = 0x3, +} BankWidthHeight; +typedef enum MacroTileAspect { + ADDR_SURF_MACRO_ASPECT_1 = 0x0, + ADDR_SURF_MACRO_ASPECT_2 = 0x1, + ADDR_SURF_MACRO_ASPECT_4 = 0x2, + ADDR_SURF_MACRO_ASPECT_8 = 0x3, +} MacroTileAspect; +typedef enum TCC_CACHE_POLICIES { + TCC_CACHE_POLICY_LRU = 0x0, + TCC_CACHE_POLICY_STREAM = 0x1, + TCC_CACHE_POLICY_BYPASS = 0x2, +} TCC_CACHE_POLICIES; +typedef enum PERFMON_COUNTER_MODE { + PERFMON_COUNTER_MODE_ACCUM = 0x0, + PERFMON_COUNTER_MODE_ACTIVE_CYCLES = 0x1, + PERFMON_COUNTER_MODE_MAX = 0x2, + PERFMON_COUNTER_MODE_DIRTY = 0x3, + PERFMON_COUNTER_MODE_SAMPLE = 0x4, + PERFMON_COUNTER_MODE_CYCLES_SINCE_FIRST_EVENT = 0x5, + PERFMON_COUNTER_MODE_CYCLES_SINCE_LAST_EVENT = 0x6, + PERFMON_COUNTER_MODE_CYCLES_GE_HI = 0x7, + PERFMON_COUNTER_MODE_CYCLES_EQ_HI = 0x8, + PERFMON_COUNTER_MODE_INACTIVE_CYCLES = 0x9, + PERFMON_COUNTER_MODE_RESERVED = 0xf, +} PERFMON_COUNTER_MODE; +typedef enum PERFMON_SPM_MODE { + PERFMON_SPM_MODE_OFF = 0x0, + PERFMON_SPM_MODE_16BIT_CLAMP = 0x1, + PERFMON_SPM_MODE_16BIT_NO_CLAMP = 0x2, + PERFMON_SPM_MODE_32BIT_CLAMP = 0x3, + PERFMON_SPM_MODE_32BIT_NO_CLAMP = 0x4, + PERFMON_SPM_MODE_RESERVED_5 = 0x5, + PERFMON_SPM_MODE_RESERVED_6 = 0x6, + PERFMON_SPM_MODE_RESERVED_7 = 0x7, + PERFMON_SPM_MODE_TEST_MODE_0 = 0x8, + PERFMON_SPM_MODE_TEST_MODE_1 = 0x9, + PERFMON_SPM_MODE_TEST_MODE_2 = 0xa, +} PERFMON_SPM_MODE; +typedef enum SurfaceTiling { + ARRAY_LINEAR = 0x0, + ARRAY_TILED = 0x1, +} SurfaceTiling; +typedef enum SurfaceArray { + ARRAY_1D = 0x0, + ARRAY_2D = 0x1, + ARRAY_3D = 0x2, + ARRAY_3D_SLICE = 0x3, +} SurfaceArray; +typedef enum ColorArray { + ARRAY_2D_ALT_COLOR = 0x0, + ARRAY_2D_COLOR = 0x1, + ARRAY_3D_SLICE_COLOR = 0x3, +} ColorArray; +typedef enum DepthArray { + ARRAY_2D_ALT_DEPTH = 0x0, + ARRAY_2D_DEPTH = 0x1, +} DepthArray; + +#endif /* DCE_8_0_ENUM_H */ diff --git a/drivers/gpu/drm/amd/include/asic_reg/dce/dce_8_0_sh_mask.h b/drivers/gpu/drm/amd/include/asic_reg/dce/dce_8_0_sh_mask.h index 8a29307344776d60e30274224583c9f6af95e8bf..c331c9fe7b81c8cbc8a7036f0420ac334aba773f 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/dce/dce_8_0_sh_mask.h +++ b/drivers/gpu/drm/amd/include/asic_reg/dce/dce_8_0_sh_mask.h @@ -4130,6 +4130,18 @@ #define PHY_AUX_CNTL__AUX_PAD_WAKE__SHIFT 0xe #define PHY_AUX_CNTL__AUX_PAD_RXSEL_MASK 0x10000 #define PHY_AUX_CNTL__AUX_PAD_RXSEL__SHIFT 0x10 +#define DC_GPIO_I2CPAD_MASK__DC_GPIO_SCL_MASK_MASK 0x1 +#define DC_GPIO_I2CPAD_MASK__DC_GPIO_SCL_MASK__SHIFT 0x0 +#define DC_GPIO_I2CPAD_MASK__DC_GPIO_SCL_PD_DIS_MASK 0x2 +#define DC_GPIO_I2CPAD_MASK__DC_GPIO_SCL_PD_DIS__SHIFT 0x1 +#define DC_GPIO_I2CPAD_MASK__DC_GPIO_SCL_RECV_MASK 0x4 +#define DC_GPIO_I2CPAD_MASK__DC_GPIO_SCL_RECV__SHIFT 0x2 +#define DC_GPIO_I2CPAD_MASK__DC_GPIO_SDA_MASK_MASK 0x10 +#define DC_GPIO_I2CPAD_MASK__DC_GPIO_SDA_MASK__SHIFT 0x4 +#define DC_GPIO_I2CPAD_MASK__DC_GPIO_SDA_PD_DIS_MASK 0x20 +#define DC_GPIO_I2CPAD_MASK__DC_GPIO_SDA_PD_DIS__SHIFT 0x5 +#define DC_GPIO_I2CPAD_MASK__DC_GPIO_SDA_RECV_MASK 0x40 +#define DC_GPIO_I2CPAD_MASK__DC_GPIO_SDA_RECV__SHIFT 0x6 #define DC_GPIO_I2CPAD_A__DC_GPIO_SCL_A_MASK 0x1 #define DC_GPIO_I2CPAD_A__DC_GPIO_SCL_A__SHIFT 0x0 #define DC_GPIO_I2CPAD_A__DC_GPIO_SDA_A_MASK 0x2 diff --git a/drivers/gpu/drm/amd/include/asic_reg/gca/gfx_7_2_enum.h b/drivers/gpu/drm/amd/include/asic_reg/gca/gfx_7_2_enum.h index 9d4347dd612548bd672d41cdb17c1dbbb1cf2b2f..dfe78799100d710dff431c6da4c5e60927f57be5 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/gca/gfx_7_2_enum.h +++ b/drivers/gpu/drm/amd/include/asic_reg/gca/gfx_7_2_enum.h @@ -6225,6 +6225,12 @@ typedef enum TCC_CACHE_POLICIES { TCC_CACHE_POLICY_STREAM = 0x1, TCC_CACHE_POLICY_BYPASS = 0x2, } TCC_CACHE_POLICIES; +typedef enum MTYPE { + MTYPE_NC_NV = 0x0, + MTYPE_NC = 0x1, + MTYPE_CC = 0x2, + MTYPE_UC = 0x3, +} MTYPE; typedef enum PERFMON_COUNTER_MODE { PERFMON_COUNTER_MODE_ACCUM = 0x0, PERFMON_COUNTER_MODE_ACTIVE_CYCLES = 0x1, diff --git a/drivers/gpu/drm/amd/include/cgs_common.h b/drivers/gpu/drm/amd/include/cgs_common.h index aec38fc3834f9d867b4477c2f1d1d1166285f1fe..ab84d494724774d77100756c85c6d2a689b25516 100644 --- a/drivers/gpu/drm/amd/include/cgs_common.h +++ b/drivers/gpu/drm/amd/include/cgs_common.h @@ -589,6 +589,8 @@ typedef int(*cgs_get_active_displays_info)( void *cgs_device, struct cgs_display_info *info); +typedef int (*cgs_notify_dpm_enabled)(void *cgs_device, bool enabled); + typedef int (*cgs_call_acpi_method)(void *cgs_device, uint32_t acpi_method, uint32_t acpi_function, @@ -644,6 +646,8 @@ struct cgs_ops { cgs_set_clockgating_state set_clockgating_state; /* display manager */ cgs_get_active_displays_info get_active_displays_info; + /* notify dpm enabled */ + cgs_notify_dpm_enabled notify_dpm_enabled; /* ACPI */ cgs_call_acpi_method call_acpi_method; /* get system info */ @@ -734,8 +738,12 @@ struct cgs_device CGS_CALL(set_powergating_state, dev, block_type, state) #define cgs_set_clockgating_state(dev, block_type, state) \ CGS_CALL(set_clockgating_state, dev, block_type, state) +#define cgs_notify_dpm_enabled(dev, enabled) \ + CGS_CALL(notify_dpm_enabled, dev, enabled) + #define cgs_get_active_displays_info(dev, info) \ CGS_CALL(get_active_displays_info, dev, info) + #define cgs_call_acpi_method(dev, acpi_method, acpi_function, pintput, poutput, output_count, input_size, output_size) \ CGS_CALL(call_acpi_method, dev, acpi_method, acpi_function, pintput, poutput, output_count, input_size, output_size) #define cgs_query_system_info(dev, sys_info) \ diff --git a/drivers/gpu/drm/amd/include/ivsrcid/ivsrcid_vislands30.h b/drivers/gpu/drm/amd/include/ivsrcid/ivsrcid_vislands30.h new file mode 100644 index 0000000000000000000000000000000000000000..d21c6b14662f368ef8c2f3ea1a71514d068522d0 --- /dev/null +++ b/drivers/gpu/drm/amd/include/ivsrcid/ivsrcid_vislands30.h @@ -0,0 +1,102 @@ +/* + * Volcanic Islands IV SRC Register documentation + * + * Copyright (C) 2015 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _IVSRCID_VISLANDS30_H_ +#define _IVSRCID_VISLANDS30_H_ + + +// IV Source IDs + +#define VISLANDS30_IV_SRCID_D1_V_UPDATE_INT 7 // 0x07 +#define VISLANDS30_IV_EXTID_D1_V_UPDATE_INT 0 + +#define VISLANDS30_IV_SRCID_D1_GRPH_PFLIP 8 // 0x08 +#define VISLANDS30_IV_EXTID_D1_GRPH_PFLIP 0 + +#define VISLANDS30_IV_SRCID_D2_V_UPDATE_INT 9 // 0x09 +#define VISLANDS30_IV_EXTID_D2_V_UPDATE_INT 0 + +#define VISLANDS30_IV_SRCID_D2_GRPH_PFLIP 10 // 0x0a +#define VISLANDS30_IV_EXTID_D2_GRPH_PFLIP 0 + +#define VISLANDS30_IV_SRCID_D3_V_UPDATE_INT 11 // 0x0b +#define VISLANDS30_IV_EXTID_D3_V_UPDATE_INT 0 + +#define VISLANDS30_IV_SRCID_D3_GRPH_PFLIP 12 // 0x0c +#define VISLANDS30_IV_EXTID_D3_GRPH_PFLIP 0 + +#define VISLANDS30_IV_SRCID_D4_V_UPDATE_INT 13 // 0x0d +#define VISLANDS30_IV_EXTID_D4_V_UPDATE_INT 0 + +#define VISLANDS30_IV_SRCID_D4_GRPH_PFLIP 14 // 0x0e +#define VISLANDS30_IV_EXTID_D4_GRPH_PFLIP 0 + +#define VISLANDS30_IV_SRCID_D5_V_UPDATE_INT 15 // 0x0f +#define VISLANDS30_IV_EXTID_D5_V_UPDATE_INT 0 + +#define VISLANDS30_IV_SRCID_D5_GRPH_PFLIP 16 // 0x10 +#define VISLANDS30_IV_EXTID_D5_GRPH_PFLIP 0 + +#define VISLANDS30_IV_SRCID_D6_V_UPDATE_INT 17 // 0x11 +#define VISLANDS30_IV_EXTID_D6_V_UPDATE_INT 0 + +#define VISLANDS30_IV_SRCID_D6_GRPH_PFLIP 18 // 0x12 +#define VISLANDS30_IV_EXTID_D6_GRPH_PFLIP 0 + +#define VISLANDS30_IV_SRCID_HOTPLUG_DETECT_A 42 // 0x2a +#define VISLANDS30_IV_EXTID_HOTPLUG_DETECT_A 0 + +#define VISLANDS30_IV_SRCID_HOTPLUG_DETECT_B 42 // 0x2a +#define VISLANDS30_IV_EXTID_HOTPLUG_DETECT_B 1 + +#define VISLANDS30_IV_SRCID_HOTPLUG_DETECT_C 42 // 0x2a +#define VISLANDS30_IV_EXTID_HOTPLUG_DETECT_C 2 + +#define VISLANDS30_IV_SRCID_HOTPLUG_DETECT_D 42 // 0x2a +#define VISLANDS30_IV_EXTID_HOTPLUG_DETECT_D 3 + +#define VISLANDS30_IV_SRCID_HOTPLUG_DETECT_E 42 // 0x2a +#define VISLANDS30_IV_EXTID_HOTPLUG_DETECT_E 4 + +#define VISLANDS30_IV_SRCID_HOTPLUG_DETECT_F 42 // 0x2a +#define VISLANDS30_IV_EXTID_HOTPLUG_DETECT_F 5 + +#define VISLANDS30_IV_SRCID_HPD_RX_A 42 // 0x2a +#define VISLANDS30_IV_EXTID_HPD_RX_A 6 + +#define VISLANDS30_IV_SRCID_HPD_RX_B 42 // 0x2a +#define VISLANDS30_IV_EXTID_HPD_RX_B 7 + +#define VISLANDS30_IV_SRCID_HPD_RX_C 42 // 0x2a +#define VISLANDS30_IV_EXTID_HPD_RX_C 8 + +#define VISLANDS30_IV_SRCID_HPD_RX_D 42 // 0x2a +#define VISLANDS30_IV_EXTID_HPD_RX_D 9 + +#define VISLANDS30_IV_SRCID_HPD_RX_E 42 // 0x2a +#define VISLANDS30_IV_EXTID_HPD_RX_E 10 + +#define VISLANDS30_IV_SRCID_HPD_RX_F 42 // 0x2a +#define VISLANDS30_IV_EXTID_HPD_RX_F 11 + +#endif // _IVSRCID_VISLANDS30_H_ diff --git a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h index 888250b33ea8993683538abed3de77bda023e5a4..a09d9f352871e4e36469ffba26abc32be6c90235 100644 --- a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h @@ -221,7 +221,7 @@ struct kgd2kfd_calls { int (*resume)(struct kfd_dev *kfd); }; -bool kgd2kfd_init(unsigned interface_version, +int kgd2kfd_init(unsigned interface_version, const struct kgd2kfd_calls **g2f); #endif /* KGD_KFD_INTERFACE_H_INCLUDED */ diff --git a/drivers/gpu/drm/amd/powerplay/Makefile b/drivers/gpu/drm/amd/powerplay/Makefile index e195bf59da86151f9b8a16436d769f6d6be7c170..043e6ebab5757915ed964aca20bc537158866da2 100644 --- a/drivers/gpu/drm/amd/powerplay/Makefile +++ b/drivers/gpu/drm/amd/powerplay/Makefile @@ -1,17 +1,17 @@ subdir-ccflags-y += -Iinclude/drm \ - -Idrivers/gpu/drm/amd/powerplay/inc/ \ - -Idrivers/gpu/drm/amd/include/asic_reg \ - -Idrivers/gpu/drm/amd/include \ - -Idrivers/gpu/drm/amd/powerplay/smumgr\ - -Idrivers/gpu/drm/amd/powerplay/hwmgr \ - -Idrivers/gpu/drm/amd/powerplay/eventmgr + -I$(FULL_AMD_PATH)/powerplay/inc/ \ + -I$(FULL_AMD_PATH)/include/asic_reg \ + -I$(FULL_AMD_PATH)/include \ + -I$(FULL_AMD_PATH)/powerplay/smumgr\ + -I$(FULL_AMD_PATH)/powerplay/hwmgr \ + -I$(FULL_AMD_PATH)/powerplay/eventmgr AMD_PP_PATH = ../powerplay PP_LIBS = smumgr hwmgr eventmgr -AMD_POWERPLAY = $(addsuffix /Makefile,$(addprefix drivers/gpu/drm/amd/powerplay/,$(PP_LIBS))) +AMD_POWERPLAY = $(addsuffix /Makefile,$(addprefix $(FULL_AMD_PATH)/powerplay/,$(PP_LIBS))) include $(AMD_POWERPLAY) diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index 589599f66fcce851e9ce5b94b2c5617544165022..9d2290044708d7f2119c702ddc45d15c77b6b808 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c @@ -29,6 +29,7 @@ #include "pp_instance.h" #include "power_state.h" #include "eventmanager.h" +#include "pp_debug.h" #define PP_CHECK(handle) \ do { \ @@ -436,7 +437,10 @@ enum amd_pm_state_type pp_dpm_get_current_power_state(void *handle) case PP_StateUILabel_Performance: return POWER_STATE_TYPE_PERFORMANCE; default: - return POWER_STATE_TYPE_DEFAULT; + if (state->classification.flags & PP_StateClassificationFlag_Boot) + return POWER_STATE_TYPE_INTERNAL_BOOT; + else + return POWER_STATE_TYPE_DEFAULT; } } @@ -538,6 +542,112 @@ static int pp_dpm_get_temperature(void *handle) return hwmgr->hwmgr_func->get_temperature(hwmgr); } +static int pp_dpm_get_pp_num_states(void *handle, + struct pp_states_info *data) +{ + struct pp_hwmgr *hwmgr; + int i; + + if (!handle) + return -EINVAL; + + hwmgr = ((struct pp_instance *)handle)->hwmgr; + + if (hwmgr == NULL || hwmgr->ps == NULL) + return -EINVAL; + + data->nums = hwmgr->num_ps; + + for (i = 0; i < hwmgr->num_ps; i++) { + struct pp_power_state *state = (struct pp_power_state *) + ((unsigned long)hwmgr->ps + i * hwmgr->ps_size); + switch (state->classification.ui_label) { + case PP_StateUILabel_Battery: + data->states[i] = POWER_STATE_TYPE_BATTERY; + break; + case PP_StateUILabel_Balanced: + data->states[i] = POWER_STATE_TYPE_BALANCED; + break; + case PP_StateUILabel_Performance: + data->states[i] = POWER_STATE_TYPE_PERFORMANCE; + break; + default: + if (state->classification.flags & PP_StateClassificationFlag_Boot) + data->states[i] = POWER_STATE_TYPE_INTERNAL_BOOT; + else + data->states[i] = POWER_STATE_TYPE_DEFAULT; + } + } + + return 0; +} + +static int pp_dpm_get_pp_table(void *handle, char **table) +{ + struct pp_hwmgr *hwmgr; + + if (!handle) + return -EINVAL; + + hwmgr = ((struct pp_instance *)handle)->hwmgr; + + if (hwmgr == NULL || hwmgr->hwmgr_func == NULL || + hwmgr->hwmgr_func->get_pp_table == NULL) + return -EINVAL; + + return hwmgr->hwmgr_func->get_pp_table(hwmgr, table); +} + +static int pp_dpm_set_pp_table(void *handle, const char *buf, size_t size) +{ + struct pp_hwmgr *hwmgr; + + if (!handle) + return -EINVAL; + + hwmgr = ((struct pp_instance *)handle)->hwmgr; + + if (hwmgr == NULL || hwmgr->hwmgr_func == NULL || + hwmgr->hwmgr_func->set_pp_table == NULL) + return -EINVAL; + + return hwmgr->hwmgr_func->set_pp_table(hwmgr, buf, size); +} + +static int pp_dpm_force_clock_level(void *handle, + enum pp_clock_type type, int level) +{ + struct pp_hwmgr *hwmgr; + + if (!handle) + return -EINVAL; + + hwmgr = ((struct pp_instance *)handle)->hwmgr; + + if (hwmgr == NULL || hwmgr->hwmgr_func == NULL || + hwmgr->hwmgr_func->force_clock_level == NULL) + return -EINVAL; + + return hwmgr->hwmgr_func->force_clock_level(hwmgr, type, level); +} + +static int pp_dpm_print_clock_levels(void *handle, + enum pp_clock_type type, char *buf) +{ + struct pp_hwmgr *hwmgr; + + if (!handle) + return -EINVAL; + + hwmgr = ((struct pp_instance *)handle)->hwmgr; + + if (hwmgr == NULL || hwmgr->hwmgr_func == NULL || + hwmgr->hwmgr_func->print_clock_levels == NULL) + return -EINVAL; + + return hwmgr->hwmgr_func->print_clock_levels(hwmgr, type, buf); +} + const struct amd_powerplay_funcs pp_dpm_funcs = { .get_temperature = pp_dpm_get_temperature, .load_firmware = pp_dpm_load_fw, @@ -555,6 +665,11 @@ const struct amd_powerplay_funcs pp_dpm_funcs = { .get_fan_control_mode = pp_dpm_get_fan_control_mode, .set_fan_speed_percent = pp_dpm_set_fan_speed_percent, .get_fan_speed_percent = pp_dpm_get_fan_speed_percent, + .get_pp_num_states = pp_dpm_get_pp_num_states, + .get_pp_table = pp_dpm_get_pp_table, + .set_pp_table = pp_dpm_set_pp_table, + .force_clock_level = pp_dpm_force_clock_level, + .print_clock_levels = pp_dpm_print_clock_levels, }; static int amd_pp_instance_init(struct amd_pp_init *pp_init, @@ -638,10 +753,10 @@ int amd_powerplay_fini(void *handle) /* export this function to DAL */ -int amd_powerplay_display_configuration_change(void *handle, const void *input) +int amd_powerplay_display_configuration_change(void *handle, + const struct amd_pp_display_configuration *display_config) { struct pp_hwmgr *hwmgr; - const struct amd_pp_display_configuration *display_config = input; PP_CHECK((struct pp_instance *)handle); @@ -653,7 +768,7 @@ int amd_powerplay_display_configuration_change(void *handle, const void *input) } int amd_powerplay_get_display_power_level(void *handle, - struct amd_pp_dal_clock_info *output) + struct amd_pp_simple_clock_info *output) { struct pp_hwmgr *hwmgr; @@ -666,3 +781,86 @@ int amd_powerplay_get_display_power_level(void *handle, return phm_get_dal_power_level(hwmgr, output); } + +int amd_powerplay_get_current_clocks(void *handle, + struct amd_pp_clock_info *clocks) +{ + struct pp_hwmgr *hwmgr; + struct amd_pp_simple_clock_info simple_clocks; + struct pp_clock_info hw_clocks; + + PP_CHECK((struct pp_instance *)handle); + + if (clocks == NULL) + return -EINVAL; + + hwmgr = ((struct pp_instance *)handle)->hwmgr; + + phm_get_dal_power_level(hwmgr, &simple_clocks); + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PowerContainment)) { + if (0 != phm_get_clock_info(hwmgr, &hwmgr->current_ps->hardware, &hw_clocks, PHM_PerformanceLevelDesignation_PowerContainment)) + PP_ASSERT_WITH_CODE(0, "Error in PHM_GetPowerContainmentClockInfo", return -1); + } else { + if (0 != phm_get_clock_info(hwmgr, &hwmgr->current_ps->hardware, &hw_clocks, PHM_PerformanceLevelDesignation_Activity)) + PP_ASSERT_WITH_CODE(0, "Error in PHM_GetClockInfo", return -1); + } + + clocks->min_engine_clock = hw_clocks.min_eng_clk; + clocks->max_engine_clock = hw_clocks.max_eng_clk; + clocks->min_memory_clock = hw_clocks.min_mem_clk; + clocks->max_memory_clock = hw_clocks.max_mem_clk; + clocks->min_bus_bandwidth = hw_clocks.min_bus_bandwidth; + clocks->max_bus_bandwidth = hw_clocks.max_bus_bandwidth; + + clocks->max_engine_clock_in_sr = hw_clocks.max_eng_clk; + clocks->min_engine_clock_in_sr = hw_clocks.min_eng_clk; + + clocks->max_clocks_state = simple_clocks.level; + + if (0 == phm_get_current_shallow_sleep_clocks(hwmgr, &hwmgr->current_ps->hardware, &hw_clocks)) { + clocks->max_engine_clock_in_sr = hw_clocks.max_eng_clk; + clocks->min_engine_clock_in_sr = hw_clocks.min_eng_clk; + } + + return 0; + +} + +int amd_powerplay_get_clock_by_type(void *handle, enum amd_pp_clock_type type, struct amd_pp_clocks *clocks) +{ + int result = -1; + + struct pp_hwmgr *hwmgr; + + PP_CHECK((struct pp_instance *)handle); + + if (clocks == NULL) + return -EINVAL; + + hwmgr = ((struct pp_instance *)handle)->hwmgr; + + result = phm_get_clock_by_type(hwmgr, type, clocks); + + return result; +} + +int amd_powerplay_get_display_mode_validation_clocks(void *handle, + struct amd_pp_simple_clock_info *clocks) +{ + int result = -1; + struct pp_hwmgr *hwmgr; + + PP_CHECK((struct pp_instance *)handle); + + if (clocks == NULL) + return -EINVAL; + + hwmgr = ((struct pp_instance *)handle)->hwmgr; + + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DynamicPatchPowerState)) + result = phm_get_max_high_clocks(hwmgr, clocks); + + return result; +} + diff --git a/drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c b/drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c index 6b52c78cb404870ae019b3cd262f7d9711b590b3..56856a2864d108c89cb2a961398f8f3613159fcc 100644 --- a/drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c +++ b/drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c @@ -137,14 +137,14 @@ static const pem_event_action *resume_event[] = { reset_display_configCounter_tasks, update_dal_configuration_tasks, vari_bright_resume_tasks, - block_adjust_power_state_tasks, setup_asic_tasks, enable_stutter_mode_tasks, /*must do this in boot state and before SMC is started */ enable_dynamic_state_management_tasks, enable_clock_power_gatings_tasks, enable_disable_bapm_tasks, initialize_thermal_controller_tasks, - reset_boot_state_tasks, + get_2d_performance_state_tasks, + set_performance_state_tasks, adjust_power_state_tasks, enable_disable_fps_tasks, notify_hw_power_source_tasks, diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c index cf01177ca3b5e36eb845fe187f13b7135cde03b6..5682490337e3dda03f8e7b2d10774b2e67ea3bdc 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c @@ -241,6 +241,11 @@ static int cz_initialize_dpm_defaults(struct pp_hwmgr *hwmgr) phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DynamicUVDState); + phm_cap_set(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_UVDDPM); + phm_cap_set(hwmgr->platform_descriptor.platformCaps, + PHM_PlatformCaps_VCEDPM); + cz_hwmgr->cc6_settings.cpu_cc6_disable = false; cz_hwmgr->cc6_settings.cpu_pstate_disable = false; cz_hwmgr->cc6_settings.nb_pstate_switch_disable = false; @@ -733,7 +738,6 @@ static int cz_tf_update_sclk_limit(struct pp_hwmgr *hwmgr, unsigned long clock = 0; unsigned long level; unsigned long stable_pstate_sclk; - struct PP_Clocks clocks; unsigned long percentage; cz_hwmgr->sclk_dpm.soft_min_clk = table->entries[0].clk; @@ -744,8 +748,10 @@ static int cz_tf_update_sclk_limit(struct pp_hwmgr *hwmgr, else cz_hwmgr->sclk_dpm.soft_max_clk = table->entries[table->count - 1].clk; - /*PECI_GetMinClockSettings(pHwMgr->pPECI, &clocks);*/ - clock = clocks.engineClock; + clock = hwmgr->display_config.min_core_set_clock; +; + if (clock == 0) + printk(KERN_INFO "[ powerplay ] min_core_set_clock not set\n"); if (cz_hwmgr->sclk_dpm.hard_min_clk != clock) { cz_hwmgr->sclk_dpm.hard_min_clk = clock; @@ -901,9 +907,9 @@ static int cz_tf_update_low_mem_pstate(struct pp_hwmgr *hwmgr, if (pnew_state->action == FORCE_HIGH) cz_nbdpm_pstate_enable_disable(hwmgr, false, disable_switch); - else if(pnew_state->action == CANCEL_FORCE_HIGH) - cz_nbdpm_pstate_enable_disable(hwmgr, false, disable_switch); - else + else if (pnew_state->action == CANCEL_FORCE_HIGH) + cz_nbdpm_pstate_enable_disable(hwmgr, true, disable_switch); + else cz_nbdpm_pstate_enable_disable(hwmgr, enable_low_mem_state, disable_switch); } return 0; @@ -1128,9 +1134,10 @@ static int cz_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, cast_const_PhwCzPowerState(&pcurrent_ps->hardware); struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend); - struct PP_Clocks clocks; + struct PP_Clocks clocks = {0, 0, 0, 0}; bool force_high; - unsigned long num_of_active_displays = 4; + uint32_t num_of_active_displays = 0; + struct cgs_display_info info = {0}; cz_ps->evclk = hwmgr->vce_arbiter.evclk; cz_ps->ecclk = hwmgr->vce_arbiter.ecclk; @@ -1142,12 +1149,15 @@ static int cz_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, cz_hwmgr->battery_state = (PP_StateUILabel_Battery == prequest_ps->classification.ui_label); - /* to do PECI_GetMinClockSettings(pHwMgr->pPECI, &clocks); */ - /* PECI_GetNumberOfActiveDisplays(pHwMgr->pPECI, &numOfActiveDisplays); */ + clocks.memoryClock = hwmgr->display_config.min_mem_set_clock != 0 ? + hwmgr->display_config.min_mem_set_clock : + cz_hwmgr->sys_info.nbp_memory_clock[1]; + + cgs_get_active_displays_info(hwmgr->device, &info); + num_of_active_displays = info.display_count; + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_StablePState)) clocks.memoryClock = hwmgr->dyn_state.max_clock_voltage_on_ac.mclk; - else - clocks.memoryClock = 0; if (clocks.memoryClock < hwmgr->gfx_arbiter.mclk) clocks.memoryClock = hwmgr->gfx_arbiter.mclk; @@ -1217,6 +1227,7 @@ static int cz_hwmgr_backend_init(struct pp_hwmgr *hwmgr) printk(KERN_ERR "[ powerplay ] Fail to construct set_power_state\n"); return result; } + hwmgr->platform_descriptor.hardwareActivityPerformanceLevels = CZ_MAX_HARDWARE_POWERLEVELS; result = phm_construct_table(hwmgr, &cz_phm_enable_clock_power_gatings_master, &(hwmgr->enable_clock_power_gatings)); if (result != 0) { @@ -1648,10 +1659,10 @@ static void cz_hw_print_display_cfg( & PWRMGT_SEPARATION_TIME_MASK) << PWRMGT_SEPARATION_TIME_SHIFT; - data|= (hw_data->cc6_settings.cpu_cc6_disable ? 0x1 : 0x0) + data |= (hw_data->cc6_settings.cpu_cc6_disable ? 0x1 : 0x0) << PWRMGT_DISABLE_CPU_CSTATES_SHIFT; - data|= (hw_data->cc6_settings.cpu_pstate_disable ? 0x1 : 0x0) + data |= (hw_data->cc6_settings.cpu_pstate_disable ? 0x1 : 0x0) << PWRMGT_DISABLE_CPU_PSTATES_SHIFT; PP_DBG_LOG("SetDisplaySizePowerParams data: 0x%X\n", @@ -1666,9 +1677,9 @@ static void cz_hw_print_display_cfg( } - static int cz_store_cc6_data(struct pp_hwmgr *hwmgr, uint32_t separation_time, +static int cz_store_cc6_data(struct pp_hwmgr *hwmgr, uint32_t separation_time, bool cc6_disable, bool pstate_disable, bool pstate_switch_disable) - { +{ struct cz_hwmgr *hw_data = (struct cz_hwmgr *)(hwmgr->backend); if (separation_time != @@ -1696,20 +1707,19 @@ static void cz_hw_print_display_cfg( return 0; } - static int cz_get_dal_power_level(struct pp_hwmgr *hwmgr, - struct amd_pp_dal_clock_info*info) +static int cz_get_dal_power_level(struct pp_hwmgr *hwmgr, + struct amd_pp_simple_clock_info *info) { uint32_t i; - const struct phm_clock_voltage_dependency_table * table = + const struct phm_clock_voltage_dependency_table *table = hwmgr->dyn_state.vddc_dep_on_dal_pwrl; - const struct phm_clock_and_voltage_limits* limits = + const struct phm_clock_and_voltage_limits *limits = &hwmgr->dyn_state.max_clock_voltage_on_ac; info->engine_max_clock = limits->sclk; info->memory_max_clock = limits->mclk; for (i = table->count - 1; i > 0; i--) { - if (limits->vddc >= table->entries[i].v) { info->level = table->entries[i].clk; return 0; @@ -1718,6 +1728,158 @@ static void cz_hw_print_display_cfg( return -EINVAL; } +static int cz_force_clock_level(struct pp_hwmgr *hwmgr, + enum pp_clock_type type, int level) +{ + if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) + return -EINVAL; + + switch (type) { + case PP_SCLK: + smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, + PPSMC_MSG_SetSclkSoftMin, + (1 << level)); + smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, + PPSMC_MSG_SetSclkSoftMax, + (1 << level)); + break; + default: + break; + } + + return 0; +} + +static int cz_print_clock_levels(struct pp_hwmgr *hwmgr, + enum pp_clock_type type, char *buf) +{ + struct phm_clock_voltage_dependency_table *sclk_table = + hwmgr->dyn_state.vddc_dependency_on_sclk; + int i, now, size = 0; + + switch (type) { + case PP_SCLK: + now = PHM_GET_FIELD(cgs_read_ind_register(hwmgr->device, + CGS_IND_REG__SMC, + ixTARGET_AND_CURRENT_PROFILE_INDEX), + TARGET_AND_CURRENT_PROFILE_INDEX, + CURR_SCLK_INDEX); + + for (i = 0; i < sclk_table->count; i++) + size += sprintf(buf + size, "%d: %uMhz %s\n", + i, sclk_table->entries[i].clk / 100, + (i == now) ? "*" : ""); + break; + default: + break; + } + return size; +} + +static int cz_get_performance_level(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *state, + PHM_PerformanceLevelDesignation designation, uint32_t index, + PHM_PerformanceLevel *level) +{ + const struct cz_power_state *ps; + struct cz_hwmgr *data; + uint32_t level_index; + uint32_t i; + + if (level == NULL || hwmgr == NULL || state == NULL) + return -EINVAL; + + data = (struct cz_hwmgr *)(hwmgr->backend); + ps = cast_const_PhwCzPowerState(state); + + level_index = index > ps->level - 1 ? ps->level - 1 : index; + + level->coreClock = ps->levels[level_index].engineClock; + + if (designation == PHM_PerformanceLevelDesignation_PowerContainment) { + for (i = 1; i < ps->level; i++) { + if (ps->levels[i].engineClock > data->dce_slow_sclk_threshold) { + level->coreClock = ps->levels[i].engineClock; + break; + } + } + } + + if (level_index == 0) + level->memory_clock = data->sys_info.nbp_memory_clock[CZ_NUM_NBPMEMORYCLOCK - 1]; + else + level->memory_clock = data->sys_info.nbp_memory_clock[0]; + + level->vddc = (cz_convert_8Bit_index_to_voltage(hwmgr, ps->levels[level_index].vddcIndex) + 2) / 4; + level->nonLocalMemoryFreq = 0; + level->nonLocalMemoryWidth = 0; + + return 0; +} + +static int cz_get_current_shallow_sleep_clocks(struct pp_hwmgr *hwmgr, + const struct pp_hw_power_state *state, struct pp_clock_info *clock_info) +{ + const struct cz_power_state *ps = cast_const_PhwCzPowerState(state); + + clock_info->min_eng_clk = ps->levels[0].engineClock / (1 << (ps->levels[0].ssDividerIndex)); + clock_info->max_eng_clk = ps->levels[ps->level - 1].engineClock / (1 << (ps->levels[ps->level - 1].ssDividerIndex)); + + return 0; +} + +static int cz_get_clock_by_type(struct pp_hwmgr *hwmgr, enum amd_pp_clock_type type, + struct amd_pp_clocks *clocks) +{ + struct cz_hwmgr *data = (struct cz_hwmgr *)(hwmgr->backend); + int i; + struct phm_clock_voltage_dependency_table *table; + + clocks->count = cz_get_max_sclk_level(hwmgr); + switch (type) { + case amd_pp_disp_clock: + for (i = 0; i < clocks->count; i++) + clocks->clock[i] = data->sys_info.display_clock[i]; + break; + case amd_pp_sys_clock: + table = hwmgr->dyn_state.vddc_dependency_on_sclk; + for (i = 0; i < clocks->count; i++) + clocks->clock[i] = table->entries[i].clk; + break; + case amd_pp_mem_clock: + clocks->count = CZ_NUM_NBPMEMORYCLOCK; + for (i = 0; i < clocks->count; i++) + clocks->clock[i] = data->sys_info.nbp_memory_clock[clocks->count - 1 - i]; + break; + default: + return -1; + } + + return 0; +} + +static int cz_get_max_high_clocks(struct pp_hwmgr *hwmgr, struct amd_pp_simple_clock_info *clocks) +{ + struct phm_clock_voltage_dependency_table *table = + hwmgr->dyn_state.vddc_dependency_on_sclk; + unsigned long level; + const struct phm_clock_and_voltage_limits *limits = + &hwmgr->dyn_state.max_clock_voltage_on_ac; + + if ((NULL == table) || (table->count <= 0) || (clocks == NULL)) + return -EINVAL; + + level = cz_get_max_sclk_level(hwmgr) - 1; + + if (level < table->count) + clocks->engine_max_clock = table->entries[level].clk; + else + clocks->engine_max_clock = table->entries[table->count - 1].clk; + + clocks->memory_max_clock = limits->mclk; + + return 0; +} + static const struct pp_hwmgr_func cz_hwmgr_funcs = { .backend_init = cz_hwmgr_backend_init, .backend_fini = cz_hwmgr_backend_fini, @@ -1736,7 +1898,13 @@ static const struct pp_hwmgr_func cz_hwmgr_funcs = { .print_current_perforce_level = cz_print_current_perforce_level, .set_cpu_power_state = cz_set_cpu_power_state, .store_cc6_data = cz_store_cc6_data, - .get_dal_power_level= cz_get_dal_power_level, + .force_clock_level = cz_force_clock_level, + .print_clock_levels = cz_print_clock_levels, + .get_dal_power_level = cz_get_dal_power_level, + .get_performance_level = cz_get_performance_level, + .get_current_shallow_sleep_clocks = cz_get_current_shallow_sleep_clocks, + .get_clock_by_type = cz_get_clock_by_type, + .get_max_high_clocks = cz_get_max_high_clocks, }; int cz_hwmgr_init(struct pp_hwmgr *hwmgr) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c index 28031a7eddba6cbb524066bd8277536da7533907..89f31bc5b68b9e061d31a2fb2494c7e4f60d276f 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c @@ -2389,6 +2389,7 @@ static int fiji_populate_smc_vce_level(struct pp_hwmgr *hwmgr, for(count = 0; count < table->VceLevelCount; count++) { table->VceLevel[count].Frequency = mm_table->entries[count].eclk; + table->VceLevel[count].MinVoltage = 0; table->VceLevel[count].MinVoltage |= (mm_table->entries[count].vddc * VOLTAGE_SCALE) << VDDC_SHIFT; table->VceLevel[count].MinVoltage |= @@ -2465,6 +2466,7 @@ static int fiji_populate_smc_samu_level(struct pp_hwmgr *hwmgr, for (count = 0; count < table->SamuLevelCount; count++) { /* not sure whether we need evclk or not */ + table->SamuLevel[count].MinVoltage = 0; table->SamuLevel[count].Frequency = mm_table->entries[count].samclock; table->SamuLevel[count].MinVoltage |= (mm_table->entries[count].vddc * VOLTAGE_SCALE) << VDDC_SHIFT; @@ -2562,6 +2564,7 @@ static int fiji_populate_smc_uvd_level(struct pp_hwmgr *hwmgr, table->UvdBootLevel = 0; for (count = 0; count < table->UvdLevelCount; count++) { + table->UvdLevel[count].MinVoltage = 0; table->UvdLevel[count].VclkFrequency = mm_table->entries[count].vclk; table->UvdLevel[count].DclkFrequency = mm_table->entries[count].dclk; table->UvdLevel[count].MinVoltage |= (mm_table->entries[count].vddc * @@ -2900,6 +2903,8 @@ static int fiji_init_smc_table(struct pp_hwmgr *hwmgr) if(FIJI_VOLTAGE_CONTROL_NONE != data->voltage_control) fiji_populate_smc_voltage_tables(hwmgr, table); + table->SystemFlags = 0; + if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_AutomaticDCTransition)) table->SystemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC; @@ -2997,6 +3002,7 @@ static int fiji_init_smc_table(struct pp_hwmgr *hwmgr) table->MemoryThermThrottleEnable = 1; table->PCIeBootLinkLevel = 0; /* 0:Gen1 1:Gen2 2:Gen3*/ table->PCIeGenInterval = 1; + table->VRConfig = 0; result = fiji_populate_vr_config(hwmgr, table); PP_ASSERT_WITH_CODE(0 == result, @@ -4275,7 +4281,6 @@ static int fiji_populate_and_upload_sclk_mclk_dpm_levels( if (data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_MCLK) { dpm_table->mclk_table.dpm_levels [dpm_table->mclk_table.count - 1].value = mclk; - if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_OD6PlusinACSupport) || phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, @@ -4886,6 +4891,10 @@ static void fiji_print_current_perforce_level( activity_percent >>= 8; seq_printf(m, "\n [GPU load]: %u%%\n\n", activity_percent > 100 ? 100 : activity_percent); + + seq_printf(m, "uvd %sabled\n", data->uvd_power_gated ? "dis" : "en"); + + seq_printf(m, "vce %sabled\n", data->vce_power_gated ? "dis" : "en"); } static int fiji_program_display_gap(struct pp_hwmgr *hwmgr) @@ -5073,6 +5082,186 @@ static int fiji_get_fan_control_mode(struct pp_hwmgr *hwmgr) CG_FDO_CTRL2, FDO_PWM_MODE); } +static int fiji_get_pp_table(struct pp_hwmgr *hwmgr, char **table) +{ + struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); + + *table = (char *)&data->smc_state_table; + + return sizeof(struct SMU73_Discrete_DpmTable); +} + +static int fiji_set_pp_table(struct pp_hwmgr *hwmgr, const char *buf, size_t size) +{ + struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); + + void *table = (void *)&data->smc_state_table; + + memcpy(table, buf, size); + + return 0; +} + +static int fiji_force_clock_level(struct pp_hwmgr *hwmgr, + enum pp_clock_type type, int level) +{ + struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); + + if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) + return -EINVAL; + + switch (type) { + case PP_SCLK: + if (!data->sclk_dpm_key_disabled) + smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, + PPSMC_MSG_SCLKDPM_SetEnabledMask, + (1 << level)); + break; + case PP_MCLK: + if (!data->mclk_dpm_key_disabled) + smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, + PPSMC_MSG_MCLKDPM_SetEnabledMask, + (1 << level)); + break; + case PP_PCIE: + if (!data->pcie_dpm_key_disabled) + smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, + PPSMC_MSG_PCIeDPM_ForceLevel, + (1 << level)); + break; + default: + break; + } + + return 0; +} + +static int fiji_print_clock_levels(struct pp_hwmgr *hwmgr, + enum pp_clock_type type, char *buf) +{ + struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); + struct fiji_single_dpm_table *sclk_table = &(data->dpm_table.sclk_table); + struct fiji_single_dpm_table *mclk_table = &(data->dpm_table.mclk_table); + struct fiji_single_dpm_table *pcie_table = &(data->dpm_table.pcie_speed_table); + int i, now, size = 0; + uint32_t clock, pcie_speed; + + switch (type) { + case PP_SCLK: + smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_API_GetSclkFrequency); + clock = cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0); + + for (i = 0; i < sclk_table->count; i++) { + if (clock > sclk_table->dpm_levels[i].value) + continue; + break; + } + now = i; + + for (i = 0; i < sclk_table->count; i++) + size += sprintf(buf + size, "%d: %uMhz %s\n", + i, sclk_table->dpm_levels[i].value / 100, + (i == now) ? "*" : ""); + break; + case PP_MCLK: + smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_API_GetMclkFrequency); + clock = cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0); + + for (i = 0; i < mclk_table->count; i++) { + if (clock > mclk_table->dpm_levels[i].value) + continue; + break; + } + now = i; + + for (i = 0; i < mclk_table->count; i++) + size += sprintf(buf + size, "%d: %uMhz %s\n", + i, mclk_table->dpm_levels[i].value / 100, + (i == now) ? "*" : ""); + break; + case PP_PCIE: + pcie_speed = fiji_get_current_pcie_speed(hwmgr); + for (i = 0; i < pcie_table->count; i++) { + if (pcie_speed != pcie_table->dpm_levels[i].value) + continue; + break; + } + now = i; + + for (i = 0; i < pcie_table->count; i++) + size += sprintf(buf + size, "%d: %s %s\n", i, + (pcie_table->dpm_levels[i].value == 0) ? "2.5GB, x1" : + (pcie_table->dpm_levels[i].value == 1) ? "5.0GB, x16" : + (pcie_table->dpm_levels[i].value == 2) ? "8.0GB, x16" : "", + (i == now) ? "*" : ""); + break; + default: + break; + } + return size; +} + +static inline bool fiji_are_power_levels_equal(const struct fiji_performance_level *pl1, + const struct fiji_performance_level *pl2) +{ + return ((pl1->memory_clock == pl2->memory_clock) && + (pl1->engine_clock == pl2->engine_clock) && + (pl1->pcie_gen == pl2->pcie_gen) && + (pl1->pcie_lane == pl2->pcie_lane)); +} + +int fiji_check_states_equal(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *pstate1, const struct pp_hw_power_state *pstate2, bool *equal) +{ + const struct fiji_power_state *psa = cast_const_phw_fiji_power_state(pstate1); + const struct fiji_power_state *psb = cast_const_phw_fiji_power_state(pstate2); + int i; + + if (equal == NULL || psa == NULL || psb == NULL) + return -EINVAL; + + /* If the two states don't even have the same number of performance levels they cannot be the same state. */ + if (psa->performance_level_count != psb->performance_level_count) { + *equal = false; + return 0; + } + + for (i = 0; i < psa->performance_level_count; i++) { + if (!fiji_are_power_levels_equal(&(psa->performance_levels[i]), &(psb->performance_levels[i]))) { + /* If we have found even one performance level pair that is different the states are different. */ + *equal = false; + return 0; + } + } + + /* If all performance levels are the same try to use the UVD clocks to break the tie.*/ + *equal = ((psa->uvd_clks.vclk == psb->uvd_clks.vclk) && (psa->uvd_clks.dclk == psb->uvd_clks.dclk)); + *equal &= ((psa->vce_clks.evclk == psb->vce_clks.evclk) && (psa->vce_clks.ecclk == psb->vce_clks.ecclk)); + *equal &= (psa->sclk_threshold == psb->sclk_threshold); + *equal &= (psa->acp_clk == psb->acp_clk); + + return 0; +} + +bool fiji_check_smc_update_required_for_display_configuration(struct pp_hwmgr *hwmgr) +{ + struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); + bool is_update_required = false; + struct cgs_display_info info = {0,0,NULL}; + + cgs_get_active_displays_info(hwmgr->device, &info); + + if (data->display_timing.num_existing_displays != info.display_count) + is_update_required = true; +/* TO DO NEED TO GET DEEP SLEEP CLOCK FROM DAL + if (phm_cap_enabled(hwmgr->hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SclkDeepSleep)) { + cgs_get_min_clock_settings(hwmgr->device, &min_clocks); + if(min_clocks.engineClockInSR != data->display_timing.minClockInSR) + is_update_required = true; +*/ + return is_update_required; +} + + static const struct pp_hwmgr_func fiji_hwmgr_funcs = { .backend_init = &fiji_hwmgr_backend_init, .backend_fini = &tonga_hwmgr_backend_fini, @@ -5108,6 +5297,12 @@ static const struct pp_hwmgr_func fiji_hwmgr_funcs = { .register_internal_thermal_interrupt = fiji_register_internal_thermal_interrupt, .set_fan_control_mode = fiji_set_fan_control_mode, .get_fan_control_mode = fiji_get_fan_control_mode, + .check_states_equal = fiji_check_states_equal, + .check_smc_update_required_for_display_configuration = fiji_check_smc_update_required_for_display_configuration, + .get_pp_table = fiji_get_pp_table, + .set_pp_table = fiji_set_pp_table, + .force_clock_level = fiji_force_clock_level, + .print_clock_levels = fiji_print_clock_levels, }; int fiji_hwmgr_init(struct pp_hwmgr *hwmgr) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.h index 22e273b1c1c572bcac3375c5292e7405acf39922..a16f7cd4c238fed39f60a366dc5cb3f86f329656 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.h @@ -29,6 +29,7 @@ #include "smu73_discrete.h" #include "ppatomctrl.h" #include "fiji_ppsmc.h" +#include "pp_endian.h" #define FIJI_MAX_HARDWARE_POWERLEVELS 2 #define FIJI_AT_DFLT 30 @@ -347,15 +348,4 @@ int fiji_update_samu_dpm(struct pp_hwmgr *hwmgr, bool bgate); int fiji_update_acp_dpm(struct pp_hwmgr *hwmgr, bool bgate); int fiji_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable); -#define PP_HOST_TO_SMC_UL(X) cpu_to_be32(X) -#define PP_SMC_TO_HOST_UL(X) be32_to_cpu(X) - -#define PP_HOST_TO_SMC_US(X) cpu_to_be16(X) -#define PP_SMC_TO_HOST_US(X) be16_to_cpu(X) - -#define CONVERT_FROM_HOST_TO_SMC_UL(X) ((X) = PP_HOST_TO_SMC_UL(X)) -#define CONVERT_FROM_SMC_TO_HOST_UL(X) ((X) = PP_SMC_TO_HOST_UL(X)) - -#define CONVERT_FROM_HOST_TO_SMC_US(X) ((X) = PP_HOST_TO_SMC_US(X)) - #endif /* _FIJI_HWMGR_H_ */ diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/functiontables.c b/drivers/gpu/drm/amd/powerplay/hwmgr/functiontables.c index 9deadabbc81c62acabf34faafcf3690f4334c244..72cfecc4f9f729426e602ce6a09db56f10eb8527 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/functiontables.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/functiontables.c @@ -34,6 +34,11 @@ static int phm_run_table(struct pp_hwmgr *hwmgr, int result = 0; phm_table_function *function; + if (rt_table->function_list == NULL) { + printk(KERN_INFO "[ powerplay ] this function not implement!\n"); + return 0; + } + for (function = rt_table->function_list; NULL != *function; function++) { int tmp = (*function)(hwmgr, input, output, temp_storage, result); @@ -57,9 +62,9 @@ int phm_dispatch_table(struct pp_hwmgr *hwmgr, int result = 0; void *temp_storage = NULL; - if (hwmgr == NULL || rt_table == NULL || rt_table->function_list == NULL) { + if (hwmgr == NULL || rt_table == NULL) { printk(KERN_ERR "[ powerplay ] Invalid Parameter!\n"); - return 0; /*temp return ture because some function not implement on some asic */ + return -EINVAL; } if (0 != rt_table->storage_size) { diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c index 0f2d5e4bc241a46042b1182f4524781d47ab42a4..fa208ada689219f4eb072ebb5e655e0a03cc9ab7 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c @@ -26,7 +26,7 @@ #include "power_state.h" #include "pp_acpi.h" #include "amd_acpi.h" -#include "amd_powerplay.h" +#include "pp_debug.h" #define PHM_FUNC_CHECK(hw) \ do { \ @@ -58,6 +58,9 @@ void phm_init_dynamic_caps(struct pp_hwmgr *hwmgr) phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_VpuRecoveryInProgress); + phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_UVDDPM); + phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_VCEDPM); + if (acpi_atcs_functions_supported(hwmgr->device, ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST) && acpi_atcs_functions_supported(hwmgr->device, ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION)) phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PCIEPerformanceRequest); @@ -130,18 +133,25 @@ int phm_set_power_state(struct pp_hwmgr *hwmgr, int phm_enable_dynamic_state_management(struct pp_hwmgr *hwmgr) { + int ret = 1; + bool enabled; PHM_FUNC_CHECK(hwmgr); if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_TablelessHardwareInterface)) { if (NULL != hwmgr->hwmgr_func->dynamic_state_management_enable) - return hwmgr->hwmgr_func->dynamic_state_management_enable(hwmgr); + ret = hwmgr->hwmgr_func->dynamic_state_management_enable(hwmgr); } else { - return phm_dispatch_table(hwmgr, + ret = phm_dispatch_table(hwmgr, &(hwmgr->enable_dynamic_state_management), NULL, NULL); } - return 0; + + enabled = ret == 0 ? true : false; + + cgs_notify_dpm_enabled(hwmgr->device, enabled); + + return ret; } int phm_force_dpm_levels(struct pp_hwmgr *hwmgr, enum amd_dpm_forced_level level) @@ -313,13 +323,12 @@ int phm_store_dal_configuration_data(struct pp_hwmgr *hwmgr, } int phm_get_dal_power_level(struct pp_hwmgr *hwmgr, - struct amd_pp_dal_clock_info *info) + struct amd_pp_simple_clock_info *info) { PHM_FUNC_CHECK(hwmgr); if (info == NULL || hwmgr->hwmgr_func->get_dal_power_level == NULL) return -EINVAL; - return hwmgr->hwmgr_func->get_dal_power_level(hwmgr, info); } @@ -332,3 +341,91 @@ int phm_set_cpu_power_state(struct pp_hwmgr *hwmgr) return 0; } + + +int phm_get_performance_level(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *state, + PHM_PerformanceLevelDesignation designation, uint32_t index, + PHM_PerformanceLevel *level) +{ + PHM_FUNC_CHECK(hwmgr); + if (hwmgr->hwmgr_func->get_performance_level == NULL) + return -EINVAL; + + return hwmgr->hwmgr_func->get_performance_level(hwmgr, state, designation, index, level); + + +} + + +/** +* Gets Clock Info. +* +* @param pHwMgr the address of the powerplay hardware manager. +* @param pPowerState the address of the Power State structure. +* @param pClockInfo the address of PP_ClockInfo structure where the result will be returned. +* @exception PP_Result_Failed if any of the paramters is NULL, otherwise the return value from the back-end. +*/ +int phm_get_clock_info(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *state, struct pp_clock_info *pclock_info, + PHM_PerformanceLevelDesignation designation) +{ + int result; + PHM_PerformanceLevel performance_level; + + PHM_FUNC_CHECK(hwmgr); + + PP_ASSERT_WITH_CODE((NULL != state), "Invalid Input!", return -EINVAL); + PP_ASSERT_WITH_CODE((NULL != pclock_info), "Invalid Input!", return -EINVAL); + + result = phm_get_performance_level(hwmgr, state, PHM_PerformanceLevelDesignation_Activity, 0, &performance_level); + + PP_ASSERT_WITH_CODE((0 == result), "Failed to retrieve minimum clocks.", return result); + + + pclock_info->min_mem_clk = performance_level.memory_clock; + pclock_info->min_eng_clk = performance_level.coreClock; + pclock_info->min_bus_bandwidth = performance_level.nonLocalMemoryFreq * performance_level.nonLocalMemoryWidth; + + + result = phm_get_performance_level(hwmgr, state, designation, + (hwmgr->platform_descriptor.hardwareActivityPerformanceLevels - 1), &performance_level); + + PP_ASSERT_WITH_CODE((0 == result), "Failed to retrieve maximum clocks.", return result); + + pclock_info->max_mem_clk = performance_level.memory_clock; + pclock_info->max_eng_clk = performance_level.coreClock; + pclock_info->max_bus_bandwidth = performance_level.nonLocalMemoryFreq * performance_level.nonLocalMemoryWidth; + + return 0; +} + +int phm_get_current_shallow_sleep_clocks(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *state, struct pp_clock_info *clock_info) +{ + PHM_FUNC_CHECK(hwmgr); + + if (hwmgr->hwmgr_func->get_current_shallow_sleep_clocks == NULL) + return -EINVAL; + + return hwmgr->hwmgr_func->get_current_shallow_sleep_clocks(hwmgr, state, clock_info); + +} + +int phm_get_clock_by_type(struct pp_hwmgr *hwmgr, enum amd_pp_clock_type type, struct amd_pp_clocks *clocks) +{ + PHM_FUNC_CHECK(hwmgr); + + if (hwmgr->hwmgr_func->get_clock_by_type == NULL) + return -EINVAL; + + return hwmgr->hwmgr_func->get_clock_by_type(hwmgr, type, clocks); + +} + +int phm_get_max_high_clocks(struct pp_hwmgr *hwmgr, struct amd_pp_simple_clock_info *clocks) +{ + PHM_FUNC_CHECK(hwmgr); + + if (hwmgr->hwmgr_func->get_max_high_clocks == NULL) + return -EINVAL; + + return hwmgr->hwmgr_func->get_max_high_clocks(hwmgr, clocks); +} diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/ppevvmath.h b/drivers/gpu/drm/amd/powerplay/hwmgr/ppevvmath.h index b7429a5278289f35d7a40b76063add4ad916b34f..b10df328d58cd10d4055084bf389286f680d810f 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/ppevvmath.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/ppevvmath.h @@ -293,7 +293,7 @@ fInt GetScaledFraction(int X, int factor) } if (factor == 1) - return (ConvertToFraction(X)); + return ConvertToFraction(X); fValue = fDivide(ConvertToFraction(X * uPow(-1, bNEGATED)), ConvertToFraction(factor)); @@ -371,7 +371,7 @@ fInt fDivide (fInt X, fInt Y) fZERO = ConvertToFraction(0); if (Equal(Y, fZERO)) - return fZERO; + return fZERO; longlongX = (int64_t)X.full; longlongY = (int64_t)Y.full; diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c index 980d3bf8ea768e161ffbba4cde1b960ea46e7819..0d5d8372953ee21363c83faf9beec4056d8c2f13 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c @@ -5185,7 +5185,6 @@ tonga_print_current_perforce_level(struct pp_hwmgr *hwmgr, struct seq_file *m) mclk = cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0); seq_printf(m, "\n [ mclk ]: %u MHz\n\n [ sclk ]: %u MHz\n", mclk/100, sclk/100); - offset = data->soft_regs_start + offsetof(SMU72_SoftRegisters, AverageGraphicsActivity); activity_percent = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, offset); activity_percent += 0x80; @@ -5193,6 +5192,9 @@ tonga_print_current_perforce_level(struct pp_hwmgr *hwmgr, struct seq_file *m) seq_printf(m, "\n [GPU load]: %u%%\n\n", activity_percent > 100 ? 100 : activity_percent); + seq_printf(m, "uvd %sabled\n", data->uvd_power_gated ? "dis" : "en"); + + seq_printf(m, "vce %sabled\n", data->vce_power_gated ? "dis" : "en"); } static int tonga_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, const void *input) @@ -6033,6 +6035,125 @@ static int tonga_get_fan_control_mode(struct pp_hwmgr *hwmgr) CG_FDO_CTRL2, FDO_PWM_MODE); } +static int tonga_get_pp_table(struct pp_hwmgr *hwmgr, char **table) +{ + struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); + + *table = (char *)&data->smc_state_table; + + return sizeof(struct SMU72_Discrete_DpmTable); +} + +static int tonga_set_pp_table(struct pp_hwmgr *hwmgr, const char *buf, size_t size) +{ + struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); + + void *table = (void *)&data->smc_state_table; + + memcpy(table, buf, size); + + return 0; +} + +static int tonga_force_clock_level(struct pp_hwmgr *hwmgr, + enum pp_clock_type type, int level) +{ + struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); + + if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) + return -EINVAL; + + switch (type) { + case PP_SCLK: + if (!data->sclk_dpm_key_disabled) + smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, + PPSMC_MSG_SCLKDPM_SetEnabledMask, + (1 << level)); + break; + case PP_MCLK: + if (!data->mclk_dpm_key_disabled) + smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, + PPSMC_MSG_MCLKDPM_SetEnabledMask, + (1 << level)); + break; + case PP_PCIE: + if (!data->pcie_dpm_key_disabled) + smum_send_msg_to_smc_with_parameter(hwmgr->smumgr, + PPSMC_MSG_PCIeDPM_ForceLevel, + (1 << level)); + break; + default: + break; + } + + return 0; +} + +static int tonga_print_clock_levels(struct pp_hwmgr *hwmgr, + enum pp_clock_type type, char *buf) +{ + struct tonga_hwmgr *data = (struct tonga_hwmgr *)(hwmgr->backend); + struct tonga_single_dpm_table *sclk_table = &(data->dpm_table.sclk_table); + struct tonga_single_dpm_table *mclk_table = &(data->dpm_table.mclk_table); + struct tonga_single_dpm_table *pcie_table = &(data->dpm_table.pcie_speed_table); + int i, now, size = 0; + uint32_t clock, pcie_speed; + + switch (type) { + case PP_SCLK: + smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_API_GetSclkFrequency); + clock = cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0); + + for (i = 0; i < sclk_table->count; i++) { + if (clock > sclk_table->dpm_levels[i].value) + continue; + break; + } + now = i; + + for (i = 0; i < sclk_table->count; i++) + size += sprintf(buf + size, "%d: %uMhz %s\n", + i, sclk_table->dpm_levels[i].value / 100, + (i == now) ? "*" : ""); + break; + case PP_MCLK: + smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_API_GetMclkFrequency); + clock = cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0); + + for (i = 0; i < mclk_table->count; i++) { + if (clock > mclk_table->dpm_levels[i].value) + continue; + break; + } + now = i; + + for (i = 0; i < mclk_table->count; i++) + size += sprintf(buf + size, "%d: %uMhz %s\n", + i, mclk_table->dpm_levels[i].value / 100, + (i == now) ? "*" : ""); + break; + case PP_PCIE: + pcie_speed = tonga_get_current_pcie_speed(hwmgr); + for (i = 0; i < pcie_table->count; i++) { + if (pcie_speed != pcie_table->dpm_levels[i].value) + continue; + break; + } + now = i; + + for (i = 0; i < pcie_table->count; i++) + size += sprintf(buf + size, "%d: %s %s\n", i, + (pcie_table->dpm_levels[i].value == 0) ? "2.5GB, x8" : + (pcie_table->dpm_levels[i].value == 1) ? "5.0GB, x16" : + (pcie_table->dpm_levels[i].value == 2) ? "8.0GB, x16" : "", + (i == now) ? "*" : ""); + break; + default: + break; + } + return size; +} + static const struct pp_hwmgr_func tonga_hwmgr_funcs = { .backend_init = &tonga_hwmgr_backend_init, .backend_fini = &tonga_hwmgr_backend_fini, @@ -6070,6 +6191,10 @@ static const struct pp_hwmgr_func tonga_hwmgr_funcs = { .check_states_equal = tonga_check_states_equal, .set_fan_control_mode = tonga_set_fan_control_mode, .get_fan_control_mode = tonga_get_fan_control_mode, + .get_pp_table = tonga_get_pp_table, + .set_pp_table = tonga_set_pp_table, + .force_clock_level = tonga_force_clock_level, + .print_clock_levels = tonga_print_clock_levels, }; int tonga_hwmgr_init(struct pp_hwmgr *hwmgr) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.h index 49168d262cccf2601c6b6d62a914e77b6eb38487..f88d3bbe667120b2319c68b5287eb47ec6d31cb4 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.h @@ -28,6 +28,7 @@ #include "ppatomctrl.h" #include "ppinterrupt.h" #include "tonga_powertune.h" +#include "pp_endian.h" #define TONGA_MAX_HARDWARE_POWERLEVELS 2 #define TONGA_DYNCLK_NUMBER_OF_TREND_COEFFICIENTS 15 @@ -386,17 +387,6 @@ typedef struct tonga_hwmgr tonga_hwmgr; #define TONGA_UNUSED_GPIO_PIN 0x7F -#define PP_HOST_TO_SMC_UL(X) cpu_to_be32(X) -#define PP_SMC_TO_HOST_UL(X) be32_to_cpu(X) - -#define PP_HOST_TO_SMC_US(X) cpu_to_be16(X) -#define PP_SMC_TO_HOST_US(X) be16_to_cpu(X) - -#define CONVERT_FROM_HOST_TO_SMC_UL(X) ((X) = PP_HOST_TO_SMC_UL(X)) -#define CONVERT_FROM_SMC_TO_HOST_UL(X) ((X) = PP_SMC_TO_HOST_UL(X)) - -#define CONVERT_FROM_HOST_TO_SMC_US(X) ((X) = PP_HOST_TO_SMC_US(X)) - int tonga_hwmgr_init(struct pp_hwmgr *hwmgr); int tonga_update_vce_dpm(struct pp_hwmgr *hwmgr, const void *input); int tonga_update_uvd_dpm(struct pp_hwmgr *hwmgr, bool bgate); diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c index 34f4bef3691f863ad581ea34697ccfc3d9628af9..b156481b50e8ee43076abf2de1fdcb8df46f3990 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c @@ -512,8 +512,10 @@ static int get_cac_tdp_table( hwmgr->dyn_state.cac_dtp_table = kzalloc(table_size, GFP_KERNEL); - if (NULL == hwmgr->dyn_state.cac_dtp_table) + if (NULL == hwmgr->dyn_state.cac_dtp_table) { + kfree(tdp_table); return -ENOMEM; + } memset(hwmgr->dyn_state.cac_dtp_table, 0x00, table_size); diff --git a/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h b/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h index e61a3e67852e27bffef8210f372dd916f21e5066..7255f7ddf93a288feb6c6f4166c5f3d3a7187cae 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h +++ b/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h @@ -29,6 +29,7 @@ #include "amd_shared.h" #include "cgs_common.h" + enum amd_pp_event { AMD_PP_EVENT_INITIALIZE = 0, AMD_PP_EVENT_UNINITIALIZE, @@ -123,6 +124,7 @@ enum amd_dpm_forced_level { AMD_DPM_FORCED_LEVEL_AUTO = 0, AMD_DPM_FORCED_LEVEL_LOW = 1, AMD_DPM_FORCED_LEVEL_HIGH = 2, + AMD_DPM_FORCED_LEVEL_MANUAL = 3, }; struct amd_pp_init { @@ -212,12 +214,55 @@ struct amd_pp_display_configuration { uint32_t dce_tolerable_mclk_in_active_latency; }; -struct amd_pp_dal_clock_info { +struct amd_pp_simple_clock_info { uint32_t engine_max_clock; uint32_t memory_max_clock; uint32_t level; }; +enum PP_DAL_POWERLEVEL { + PP_DAL_POWERLEVEL_INVALID = 0, + PP_DAL_POWERLEVEL_ULTRALOW, + PP_DAL_POWERLEVEL_LOW, + PP_DAL_POWERLEVEL_NOMINAL, + PP_DAL_POWERLEVEL_PERFORMANCE, + + PP_DAL_POWERLEVEL_0 = PP_DAL_POWERLEVEL_ULTRALOW, + PP_DAL_POWERLEVEL_1 = PP_DAL_POWERLEVEL_LOW, + PP_DAL_POWERLEVEL_2 = PP_DAL_POWERLEVEL_NOMINAL, + PP_DAL_POWERLEVEL_3 = PP_DAL_POWERLEVEL_PERFORMANCE, + PP_DAL_POWERLEVEL_4 = PP_DAL_POWERLEVEL_3+1, + PP_DAL_POWERLEVEL_5 = PP_DAL_POWERLEVEL_4+1, + PP_DAL_POWERLEVEL_6 = PP_DAL_POWERLEVEL_5+1, + PP_DAL_POWERLEVEL_7 = PP_DAL_POWERLEVEL_6+1, +}; + +struct amd_pp_clock_info { + uint32_t min_engine_clock; + uint32_t max_engine_clock; + uint32_t min_memory_clock; + uint32_t max_memory_clock; + uint32_t min_bus_bandwidth; + uint32_t max_bus_bandwidth; + uint32_t max_engine_clock_in_sr; + uint32_t min_engine_clock_in_sr; + enum PP_DAL_POWERLEVEL max_clocks_state; +}; + +enum amd_pp_clock_type { + amd_pp_disp_clock = 1, + amd_pp_sys_clock, + amd_pp_mem_clock +}; + +#define MAX_NUM_CLOCKS 16 + +struct amd_pp_clocks { + uint32_t count; + uint32_t clock[MAX_NUM_CLOCKS]; +}; + + enum { PP_GROUP_UNKNOWN = 0, PP_GROUP_GFX = 1, @@ -225,6 +270,17 @@ enum { PP_GROUP_MAX }; +enum pp_clock_type { + PP_SCLK, + PP_MCLK, + PP_PCIE, +}; + +struct pp_states_info { + uint32_t nums; + uint32_t states[16]; +}; + #define PP_GROUP_MASK 0xF0000000 #define PP_GROUP_SHIFT 28 @@ -278,6 +334,11 @@ struct amd_powerplay_funcs { int (*get_fan_control_mode)(void *handle); int (*set_fan_speed_percent)(void *handle, uint32_t percent); int (*get_fan_speed_percent)(void *handle, uint32_t *speed); + int (*get_pp_num_states)(void *handle, struct pp_states_info *data); + int (*get_pp_table)(void *handle, char **table); + int (*set_pp_table)(void *handle, const char *buf, size_t size); + int (*force_clock_level)(void *handle, enum pp_clock_type type, int level); + int (*print_clock_levels)(void *handle, enum pp_clock_type type, char *buf); }; struct amd_powerplay { @@ -288,12 +349,23 @@ struct amd_powerplay { int amd_powerplay_init(struct amd_pp_init *pp_init, struct amd_powerplay *amd_pp); + int amd_powerplay_fini(void *handle); -int amd_powerplay_display_configuration_change(void *handle, const void *input); +int amd_powerplay_display_configuration_change(void *handle, + const struct amd_pp_display_configuration *input); int amd_powerplay_get_display_power_level(void *handle, - struct amd_pp_dal_clock_info *output); + struct amd_pp_simple_clock_info *output); + +int amd_powerplay_get_current_clocks(void *handle, + struct amd_pp_clock_info *output); + +int amd_powerplay_get_clock_by_type(void *handle, + enum amd_pp_clock_type type, + struct amd_pp_clocks *clocks); +int amd_powerplay_get_display_mode_validation_clocks(void *handle, + struct amd_pp_simple_clock_info *output); #endif /* _AMD_POWERPLAY_H_ */ diff --git a/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h b/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h index 91795efe13365a5a55c79b47bab02ae70a52669d..040d3f7cbf490da7a06cc13ae952e34cf84830c5 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h +++ b/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h @@ -31,6 +31,7 @@ struct pp_power_state; enum amd_dpm_forced_level; struct PP_TemperatureRange; + struct phm_fan_speed_info { uint32_t min_percent; uint32_t max_percent; @@ -290,6 +291,15 @@ struct PP_Clocks { uint32_t engineClockInSR; }; +struct pp_clock_info { + uint32_t min_mem_clk; + uint32_t max_mem_clk; + uint32_t min_eng_clk; + uint32_t max_eng_clk; + uint32_t min_bus_bandwidth; + uint32_t max_bus_bandwidth; +}; + struct phm_platform_descriptor { uint32_t platformCaps[PHM_MAX_NUM_CAPS_ULONG_ENTRIES]; uint32_t vbiosInterruptId; @@ -323,24 +333,6 @@ struct phm_clocks { uint32_t clock[MAX_NUM_CLOCKS]; }; -enum PP_DAL_POWERLEVEL { - PP_DAL_POWERLEVEL_INVALID = 0, - PP_DAL_POWERLEVEL_ULTRALOW, - PP_DAL_POWERLEVEL_LOW, - PP_DAL_POWERLEVEL_NOMINAL, - PP_DAL_POWERLEVEL_PERFORMANCE, - - PP_DAL_POWERLEVEL_0 = PP_DAL_POWERLEVEL_ULTRALOW, - PP_DAL_POWERLEVEL_1 = PP_DAL_POWERLEVEL_LOW, - PP_DAL_POWERLEVEL_2 = PP_DAL_POWERLEVEL_NOMINAL, - PP_DAL_POWERLEVEL_3 = PP_DAL_POWERLEVEL_PERFORMANCE, - PP_DAL_POWERLEVEL_4 = PP_DAL_POWERLEVEL_3+1, - PP_DAL_POWERLEVEL_5 = PP_DAL_POWERLEVEL_4+1, - PP_DAL_POWERLEVEL_6 = PP_DAL_POWERLEVEL_5+1, - PP_DAL_POWERLEVEL_7 = PP_DAL_POWERLEVEL_6+1, -}; - - extern int phm_enable_clock_power_gatings(struct pp_hwmgr *hwmgr); extern int phm_powergate_uvd(struct pp_hwmgr *hwmgr, bool gate); extern int phm_powergate_vce(struct pp_hwmgr *hwmgr, bool gate); @@ -375,11 +367,25 @@ extern int phm_store_dal_configuration_data(struct pp_hwmgr *hwmgr, const struct amd_pp_display_configuration *display_config); extern int phm_get_dal_power_level(struct pp_hwmgr *hwmgr, - struct amd_pp_dal_clock_info*info); + struct amd_pp_simple_clock_info *info); extern int phm_set_cpu_power_state(struct pp_hwmgr *hwmgr); extern int phm_power_down_asic(struct pp_hwmgr *hwmgr); +extern int phm_get_performance_level(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *state, + PHM_PerformanceLevelDesignation designation, uint32_t index, + PHM_PerformanceLevel *level); + +extern int phm_get_clock_info(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *state, + struct pp_clock_info *pclock_info, + PHM_PerformanceLevelDesignation designation); + +extern int phm_get_current_shallow_sleep_clocks(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *state, struct pp_clock_info *clock_info); + +extern int phm_get_clock_by_type(struct pp_hwmgr *hwmgr, enum amd_pp_clock_type type, struct amd_pp_clocks *clocks); + +extern int phm_get_max_high_clocks(struct pp_hwmgr *hwmgr, struct amd_pp_simple_clock_info *clocks); + #endif /* _HARDWARE_MANAGER_H_ */ diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h index aeaa3dbba525ce98dfaf4cb4c006f9ddabbc6c7d..928f5a740cba77b92ab28ff1e0428d4dea6fb6f5 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h @@ -325,8 +325,18 @@ struct pp_hwmgr_func { bool cc6_disable, bool pstate_disable, bool pstate_switch_disable); int (*get_dal_power_level)(struct pp_hwmgr *hwmgr, - struct amd_pp_dal_clock_info *info); + struct amd_pp_simple_clock_info *info); + int (*get_performance_level)(struct pp_hwmgr *, const struct pp_hw_power_state *, + PHM_PerformanceLevelDesignation, uint32_t, PHM_PerformanceLevel *); + int (*get_current_shallow_sleep_clocks)(struct pp_hwmgr *hwmgr, + const struct pp_hw_power_state *state, struct pp_clock_info *clock_info); + int (*get_clock_by_type)(struct pp_hwmgr *hwmgr, enum amd_pp_clock_type type, struct amd_pp_clocks *clocks); + int (*get_max_high_clocks)(struct pp_hwmgr *hwmgr, struct amd_pp_simple_clock_info *clocks); int (*power_off_asic)(struct pp_hwmgr *hwmgr); + int (*get_pp_table)(struct pp_hwmgr *hwmgr, char **table); + int (*set_pp_table)(struct pp_hwmgr *hwmgr, const char *buf, size_t size); + int (*force_clock_level)(struct pp_hwmgr *hwmgr, enum pp_clock_type type, int level); + int (*print_clock_levels)(struct pp_hwmgr *hwmgr, enum pp_clock_type type, char *buf); }; struct pp_table_func { diff --git a/drivers/gpu/drm/amd/powerplay/inc/pp_endian.h b/drivers/gpu/drm/amd/powerplay/inc/pp_endian.h new file mode 100644 index 0000000000000000000000000000000000000000..f49d1963fe85b0ff5d57036a0d46de0d4be71a0c --- /dev/null +++ b/drivers/gpu/drm/amd/powerplay/inc/pp_endian.h @@ -0,0 +1,38 @@ +/* + * Copyright 2016 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef _PP_ENDIAN_H_ +#define _PP_ENDIAN_H_ + +#define PP_HOST_TO_SMC_UL(X) cpu_to_be32(X) +#define PP_SMC_TO_HOST_UL(X) be32_to_cpu(X) + +#define PP_HOST_TO_SMC_US(X) cpu_to_be16(X) +#define PP_SMC_TO_HOST_US(X) be16_to_cpu(X) + +#define CONVERT_FROM_HOST_TO_SMC_UL(X) ((X) = PP_HOST_TO_SMC_UL(X)) +#define CONVERT_FROM_SMC_TO_HOST_UL(X) ((X) = PP_SMC_TO_HOST_UL(X)) + +#define CONVERT_FROM_HOST_TO_SMC_US(X) ((X) = PP_HOST_TO_SMC_US(X)) + +#endif /* _PP_ENDIAN_H_ */ diff --git a/drivers/gpu/drm/amd/powerplay/inc/smumgr.h b/drivers/gpu/drm/amd/powerplay/inc/smumgr.h index 504f035d1843d09552a10607fd7fef0a290f8f96..fc9e3d1dd4098fe4115c19099c6e98e52dea1c1d 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/smumgr.h +++ b/drivers/gpu/drm/amd/powerplay/inc/smumgr.h @@ -32,6 +32,27 @@ struct pp_instance; #define smu_lower_32_bits(n) ((uint32_t)(n)) #define smu_upper_32_bits(n) ((uint32_t)(((n)>>16)>>16)) +enum AVFS_BTC_STATUS { + AVFS_BTC_BOOT = 0, + AVFS_BTC_BOOT_STARTEDSMU, + AVFS_LOAD_VIRUS, + AVFS_BTC_VIRUS_LOADED, + AVFS_BTC_VIRUS_FAIL, + AVFS_BTC_COMPLETED_PREVIOUSLY, + AVFS_BTC_ENABLEAVFS, + AVFS_BTC_STARTED, + AVFS_BTC_FAILED, + AVFS_BTC_RESTOREVFT_FAILED, + AVFS_BTC_SAVEVFT_FAILED, + AVFS_BTC_DPMTABLESETUP_FAILED, + AVFS_BTC_COMPLETED_UNSAVED, + AVFS_BTC_COMPLETED_SAVED, + AVFS_BTC_COMPLETED_RESTORED, + AVFS_BTC_DISABLED, + AVFS_BTC_NOTSUPPORTED, + AVFS_BTC_SMUMSG_ERROR +}; + struct pp_smumgr_func { int (*smu_init)(struct pp_smumgr *smumgr); int (*smu_fini)(struct pp_smumgr *smumgr); diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.h b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.h index 8cd22d9c914015145ac1160b57fe1606be794940..b4eb483215b1783ada3f31b459edbb21fbafb7e4 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.h +++ b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.h @@ -23,24 +23,6 @@ #ifndef _FIJI_SMUMANAGER_H_ #define _FIJI_SMUMANAGER_H_ -enum AVFS_BTC_STATUS { - AVFS_BTC_BOOT = 0, - AVFS_BTC_BOOT_STARTEDSMU, - AVFS_LOAD_VIRUS, - AVFS_BTC_VIRUS_LOADED, - AVFS_BTC_VIRUS_FAIL, - AVFS_BTC_STARTED, - AVFS_BTC_FAILED, - AVFS_BTC_RESTOREVFT_FAILED, - AVFS_BTC_SAVEVFT_FAILED, - AVFS_BTC_DPMTABLESETUP_FAILED, - AVFS_BTC_COMPLETED_UNSAVED, - AVFS_BTC_COMPLETED_SAVED, - AVFS_BTC_COMPLETED_RESTORED, - AVFS_BTC_DISABLED, - AVFS_BTC_NOTSUPPORTED, - AVFS_BTC_SMUMSG_ERROR -}; struct fiji_smu_avfs { enum AVFS_BTC_STATUS AvfsBtcStatus; diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c index 8b2becd1aa079977525a2c513005fa67f2ad0ca5..a5ff9458d359099ce5b57a033351b54219af4c54 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c +++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c @@ -229,6 +229,14 @@ static void amd_sched_entity_wakeup(struct fence *f, struct fence_cb *cb) amd_sched_wakeup(entity->sched); } +static void amd_sched_entity_clear_dep(struct fence *f, struct fence_cb *cb) +{ + struct amd_sched_entity *entity = + container_of(cb, struct amd_sched_entity, cb); + entity->dependency = NULL; + fence_put(f); +} + static bool amd_sched_entity_add_dependency_cb(struct amd_sched_entity *entity) { struct amd_gpu_scheduler *sched = entity->sched; @@ -251,7 +259,7 @@ static bool amd_sched_entity_add_dependency_cb(struct amd_sched_entity *entity) } /* Wait for fence to be scheduled */ - entity->cb.func = amd_sched_entity_wakeup; + entity->cb.func = amd_sched_entity_clear_dep; list_add_tail(&entity->cb.node, &s_fence->scheduled_cb); return true; } diff --git a/drivers/gpu/drm/amd/scheduler/sched_fence.c b/drivers/gpu/drm/amd/scheduler/sched_fence.c index 87c78eecea649a2112035db7fb66bb467cf6f457..dc115aea352bc9771e30605ab9c83f90f03e8df8 100644 --- a/drivers/gpu/drm/amd/scheduler/sched_fence.c +++ b/drivers/gpu/drm/amd/scheduler/sched_fence.c @@ -84,12 +84,33 @@ static bool amd_sched_fence_enable_signaling(struct fence *f) return true; } -static void amd_sched_fence_release(struct fence *f) +/** + * amd_sched_fence_free - free up the fence memory + * + * @rcu: RCU callback head + * + * Free up the fence memory after the RCU grace period. + */ +static void amd_sched_fence_free(struct rcu_head *rcu) { + struct fence *f = container_of(rcu, struct fence, rcu); struct amd_sched_fence *fence = to_amd_sched_fence(f); kmem_cache_free(sched_fence_slab, fence); } +/** + * amd_sched_fence_release - callback that fence can be freed + * + * @fence: fence + * + * This function is called when the reference count becomes zero. + * It just RCU schedules freeing up the fence. + */ +static void amd_sched_fence_release(struct fence *f) +{ + call_rcu(&f->rcu, amd_sched_fence_free); +} + const struct fence_ops amd_sched_fence_ops = { .get_driver_name = amd_sched_fence_get_driver_name, .get_timeline_name = amd_sched_fence_get_timeline_name, diff --git a/drivers/gpu/drm/arm/Kconfig b/drivers/gpu/drm/arm/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..eaed454e043c73d2008403ec20936c8fcd240ed1 --- /dev/null +++ b/drivers/gpu/drm/arm/Kconfig @@ -0,0 +1,27 @@ +config DRM_ARM + bool + help + Choose this option to select drivers for ARM's devices + +config DRM_HDLCD + tristate "ARM HDLCD" + depends on DRM && OF && (ARM || ARM64) + depends on COMMON_CLK + select DRM_ARM + select DRM_KMS_HELPER + select DRM_KMS_FB_HELPER + select DRM_KMS_CMA_HELPER + help + Choose this option if you have an ARM High Definition Colour LCD + controller. + + If M is selected the module will be called hdlcd. + +config DRM_HDLCD_SHOW_UNDERRUN + bool "Show underrun conditions" + depends on DRM_HDLCD + default n + help + Enable this option to show in red colour the pixels that the + HDLCD device did not fetch from framebuffer due to underrun + conditions. diff --git a/drivers/gpu/drm/arm/Makefile b/drivers/gpu/drm/arm/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..89dcb7bab93a065646af357c13deff8b8572bde8 --- /dev/null +++ b/drivers/gpu/drm/arm/Makefile @@ -0,0 +1,2 @@ +hdlcd-y := hdlcd_drv.o hdlcd_crtc.o +obj-$(CONFIG_DRM_HDLCD) += hdlcd.o diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c new file mode 100644 index 0000000000000000000000000000000000000000..fef1b04c2aab4fef4411ac0cc10249c98caab0f5 --- /dev/null +++ b/drivers/gpu/drm/arm/hdlcd_crtc.c @@ -0,0 +1,327 @@ +/* + * Copyright (C) 2013-2015 ARM Limited + * Author: Liviu Dudau + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + * + * Implementation of a CRTC class for the HDLCD driver. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include