diff --git a/.mailmap b/.mailmap index 7e6c5334c337a..90c0aefc276d4 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/Documentation/ABI/stable/firewire-cdev b/Documentation/ABI/stable/firewire-cdev index 16d030827368b..f72ed653878a6 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-fs-orangefs b/Documentation/ABI/stable/sysfs-fs-orangefs new file mode 100644 index 0000000000000..affdb114bd331 --- /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-class-cxl b/Documentation/ABI/testing/sysfs-class-cxl index b07e86d4597f2..7fd737eed38ac 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-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu index b683e8ee69ecc..16501334b99fe 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 eed922ef42e53..f34221b52b14b 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 e5200f354abfe..a809f6005f146 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 0000000000000..7ac7d7262bb71 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-platform-i2c-demux-pinctrl @@ -0,0 +1,23 @@ +What: /sys/devices/platform//cur_master +Date: January 2016 +KernelVersion: 4.6 +Contact: Wolfram Sang +Description: + +This file selects the active I2C master for a demultiplexed bus. + +Write 0 there for the first master, 1 for the second etc. Reading the file will +give you a list with the active master marked. Example from a Renesas Lager +board: + +root@Lager:~# cat /sys/devices/platform/i2c@8/cur_master +* 0 - /i2c@9 + 1 - /i2c@e6520000 + 2 - /i2c@e6530000 + +root@Lager:~# echo 2 > /sys/devices/platform/i2c@8/cur_master + +root@Lager:~# cat /sys/devices/platform/i2c@8/cur_master + 0 - /i2c@9 + 1 - /i2c@e6520000 +* 2 - /i2c@e6530000 diff --git a/Documentation/DMA-attributes.txt b/Documentation/DMA-attributes.txt index 18dc52c4f2a0b..e8cf9cf873b37 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/80211.tmpl b/Documentation/DocBook/80211.tmpl index f9b9ad7894f58..f2a312b35875d 100644 --- a/Documentation/DocBook/80211.tmpl +++ b/Documentation/DocBook/80211.tmpl @@ -75,7 +75,6 @@ Device registration !Pinclude/net/cfg80211.h Device registration -!Finclude/net/cfg80211.h ieee80211_band !Finclude/net/cfg80211.h ieee80211_channel_flags !Finclude/net/cfg80211.h ieee80211_channel !Finclude/net/cfg80211.h ieee80211_rate_flags diff --git a/Documentation/DocBook/gpu.tmpl b/Documentation/DocBook/gpu.tmpl index a8669330b456e..1692c4dd54872 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 ae89b67d8e23c..b5bb7f5188406 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 430d279a8df37..e5a115f244717 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/cgroup-v2.txt b/Documentation/cgroup-v2.txt index bdc6773277be5..4cc07ce3b8dd0 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 @@ -1114,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 diff --git a/Documentation/devicetree/bindings/arm/amlogic.txt b/Documentation/devicetree/bindings/arm/amlogic.txt index 1dfee20eee744..8a5122ab19b02 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 1a709970e7f78..0226bc2cc1f6e 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 0000000000000..ae345e1c8d2b8 --- /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 0000000000000..223ed3471c084 --- /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 aef1d200a9b28..a1a5a7ecc2fb0 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 ae9be074d09f6..ccc62f1453066 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 3090a8a008c03..48f6703a28c8f 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 0000000000000..51336e5fc7612 --- /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 0000000000000..df98a9c82a8c7 --- /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 ab0c9cdf388e9..7d28fe4bf654e 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 54f43bc2df443..d9c2a37a4090b 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 66422d6631841..21e71a5e866e0 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 56518839f52a7..6eb73be9433e8 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 0000000000000..3e24518c6678d --- /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 bb9b0faa919d0..7e79fcc36b0db 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 3d84dcae8475e..30df832a6f2f5 100644 --- a/Documentation/devicetree/bindings/ata/ahci-platform.txt +++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt @@ -14,6 +14,7 @@ Required properties: - "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 704be9306c9fb..01683707060bf 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 20e1704e7df21..fb40da303d25c 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 0b35e71b39e89..6f66e9aa354c1 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 0000000000000..6f1c7b4e4d2ca --- /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 e0fc2c11dd00b..241fb0545b9ee 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 72f82f4440913..9a60fde32b02c 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 59297d34b2084..fefb8023020f1 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 e59f57b24777c..834436fbe83d5 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 0000000000000..4c8a2ce2cd701 --- /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 1c4ef773feea1..82f9638121dbf 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 0000000000000..78bc24296f3e4 --- /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 56a961aa50613..9f97df4d51524 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 0e6f0c0248587..22756b3dede2a 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 27c3ce0db16a3..c7c6b9af87ac4 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 e7423bea1424a..f5948c48b9a23 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 379ee2ea9a3d8..b63f614e0c045 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 0000000000000..8c5de692c55ce --- /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 0000000000000..088a6cea5015f --- /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 eccd4f4867b29..0d30e42e40bea 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 0000000000000..8096a29f9776a --- /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 7a802f64e5bd8..8f7364a7b349e 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/i2c/i2c-demux-pinctrl.txt b/Documentation/devicetree/bindings/i2c/i2c-demux-pinctrl.txt new file mode 100644 index 0000000000000..6078aefe7ed48 --- /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 eab5836ba7f98..b967544590e80 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 95e97223a71c8..cf8bfc956cdce 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 7baf9e133fa86..2701eefb00f77 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 ceabbe91ae449..caf42e9894625 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/input/ads7846.txt b/Documentation/devicetree/bindings/input/ads7846.txt index 33a1638b61d6b..c6cfe2e3ed411 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/interrupt-controller/hisilicon,mbigen-v2.txt b/Documentation/devicetree/bindings/interrupt-controller/hisilicon,mbigen-v2.txt index 720f7c92e9a10..3b2f4c43ad8d2 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 0000000000000..cd1b1cd7b5c48 --- /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 48ffb38f699e1..3ed027cfca95c 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 bc620fe32a707..85f068805dd8a 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 0000000000000..044b17f3a77a6 --- /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 0000000000000..b6bb84acf5be6 --- /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 b61eec9203590..351f612673fc5 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 0000000000000..b449d025049f0 --- /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 0000000000000..e46451bb242f3 --- /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 0000000000000..06a83ceebba73 --- /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 0000000000000..55ff3b7e0bb9d --- /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/mmc/arasan,sdhci.txt b/Documentation/devicetree/bindings/mmc/arasan,sdhci.txt index da541c3631f81..31b35c3a5e478 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 72cc9cc95880a..be56d2bd474a0 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 0000000000000..71ad57e050b1e --- /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 3dc13b68fc3ff..ea5614b6f6130 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 400b640fabc76..7fb746dd1a68c 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 7d4c8eb775a5f..d53aba98fbc98 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 00c587b3d3ae7..0333ec87dc496 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 0000000000000..70dd5118a3247 --- /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/stmmac.txt b/Documentation/devicetree/bindings/net/stmmac.txt index 6605d19601c2a..4d302db657c0b 100644 --- a/Documentation/devicetree/bindings/net/stmmac.txt +++ b/Documentation/devicetree/bindings/net/stmmac.txt @@ -59,6 +59,8 @@ Optional properties: - snps,fb: fixed-burst - snps,mb: mixed-burst - snps,rb: rebuild INCRx Burst + - snps,tso: this enables the TSO feature otherwise it will be managed by + MAC HW capability register. - mdio: with compatible = "snps,dwmac-mdio", create and register mdio bus. Examples: diff --git a/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt b/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt index 96aae6b4f7368..74d7f0af209c8 100644 --- a/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt +++ b/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt @@ -5,12 +5,18 @@ Required properties: * "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. +PCI based devices uses compatible string "qcom,ath10k" and takes calibration +data along with board specific 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. +and also uses most of the properties defined in this doc (except +"qcom,ath10k-calibration-data"). It uses "qcom,ath10k-pre-calibration-data" +to carry pre calibration data. + +In general, entry "qcom,ath10k-pre-calibration-data" and +"qcom,ath10k-calibration-data" conflict with each other and only one +can be provided per device. Optional properties: - reg: Address and length of the register set for the device. @@ -35,8 +41,11 @@ Optional properties: - 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 +- qcom,ath10k-calibration-data : calibration data + board specific data + as an array, the length can vary between + hw versions. +- qcom,ath10k-pre-calibration-data : pre calibration data as an array, + the length can vary between hw versions. Example (to supply the calibration data alone): @@ -105,5 +114,5 @@ wifi0: wifi@a000000 { "legacy"; qcom,msi_addr = <0x0b006040>; qcom,msi_base = <0x40>; - qcom,ath10k-calibration-data = [ 01 02 03 ... ]; + qcom,ath10k-pre-calibration-data = [ 01 02 03 ... ]; }; diff --git a/Documentation/devicetree/bindings/pci/layerscape-pci.txt b/Documentation/devicetree/bindings/pci/layerscape-pci.txt index e3767857d30df..ef683b2fd23a4 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 08a4a32c8eb0d..0326154c79254 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 add7c38ec7d88..8662f3aaf312d 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 b8627e763dba0..c84fb47265ebc 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 1fc5328c0651b..55c2c03fc81e2 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 0000000000000..12278d79f6c04 --- /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 0000000000000..8c05d16367df8 --- /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 0000000000000..a59fdd8c236d2 --- /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 a833a016f6567..e99e10ab9ecbb 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 0000000000000..e284e4e1ccd54 --- /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 112756e11802c..13dc6a3fdb4a1 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/thermal/exynos-thermal.txt b/Documentation/devicetree/bindings/thermal/exynos-thermal.txt index 695150a4136bb..70b4c16c7ed83 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 0000000000000..81f9a512bc2a9 --- /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 8ff54eb464dc6..b1fe7e9de1b47 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 03c0e989e020a..66f6adf8d44da 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 156731cc649cd..86740d4a270d3 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. @@ -72,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) @@ -88,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. @@ -245,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 0000000000000..ca99d64e62118 --- /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 0000000000000..6f2d5f91964d5 --- /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 04d34f6a58f35..3f1437fbca6b4 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 480c8de3c2c44..ca44c58205858 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 92d86f7271b4d..453053f1661f4 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 7747024d3bb70..e157469882614 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 c772b47e7ef06..f9dad22d95ceb 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 31f53f0ab9575..4006298f67070 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 0000000000000..5bef7268bd9fb --- /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 0000000000000..1ab07860430d5 --- /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 0000000000000..e1a0056a365ff --- /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/tmpfs.txt b/Documentation/filesystems/tmpfs.txt index d392e1505f170..d9c11d25bf021 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 223c32171dcc2..cf51360e3a9fb 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 b02a7d5982585..4164bd6397a28 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 9028b025501a6..3ecf0c3a133fb 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/kasan.txt b/Documentation/kasan.txt index aa1e0c91e3688..7dd95b35cd7cd 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 0000000000000..779ff4ab1c1da --- /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 eef242ee576bf..ecc74fa4bfde8 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -987,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 @@ -2620,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 904ee42d078e5..3729cbe60e416 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/Documentation/networking/dsa/dsa.txt b/Documentation/networking/dsa/dsa.txt index 3b196c304b732..ba698c56919d2 100644 --- a/Documentation/networking/dsa/dsa.txt +++ b/Documentation/networking/dsa/dsa.txt @@ -533,7 +533,7 @@ Bridge layer out at the switch hardware for the switch to (re) learn MAC addresses behind this port. -- port_stp_update: bridge layer function invoked when a given switch port STP +- port_stp_state_set: bridge layer function invoked when a given switch port STP state is computed by the bridge layer and should be propagated to switch hardware to forward/block/learn traffic. The switch driver is responsible for computing a STP state change based on current and asked parameters and perform @@ -542,6 +542,12 @@ Bridge layer Bridge VLAN filtering --------------------- +- port_vlan_prepare: bridge layer function invoked when the bridge prepares the + configuration of a VLAN on the given port. If the operation is not supported + by the hardware, this function should return -EOPNOTSUPP to inform the bridge + code to fallback to a software implementation. No hardware setup must be done + in this function. See port_vlan_add for this and details. + - port_vlan_add: bridge layer function invoked when a VLAN is configured (tagged or untagged) for the given switch port @@ -552,6 +558,12 @@ Bridge VLAN filtering 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_prepare: bridge layer function invoked when the bridge prepares the + installation of a Forwarding Database entry. If the operation is not + supported, this function should return -EOPNOTSUPP to inform the bridge code + to fallback to a software implementation. No hardware setup must be done in + this function. See port_fdb_add for this and details. + - 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 specified address in the specified VLAN Id in the forwarding database @@ -565,6 +577,10 @@ of DSA, would be the its port-based VLAN, used by the associated bridge device. the specified MAC address from the specified VLAN ID if it was mapped into this port forwarding database +- port_fdb_dump: bridge layer function invoked with a switchdev callback + function that the driver has to call for each MAC address known to be behind + the given port. A switchdev object is used to carry the VID and FDB info. + TODO ==== diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index d5df40c75aa4e..b183e2b606c8a 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. diff --git a/Documentation/networking/mac80211-injection.txt b/Documentation/networking/mac80211-injection.txt index ec8f934c2eb24..d58d78df9ca2d 100644 --- a/Documentation/networking/mac80211-injection.txt +++ b/Documentation/networking/mac80211-injection.txt @@ -37,14 +37,27 @@ radiotap headers and used to control injection: 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_MCS_SGI: use short guard interval + IEEE80211_RADIOTAP_MCS_BW_40: send in HT40 mode * IEEE80211_RADIOTAP_DATA_RETRIES number of retries when either IEEE80211_RADIOTAP_RATE or IEEE80211_RADIOTAP_MCS was used + * IEEE80211_RADIOTAP_VHT + + VHT mcs and number of streams used in the transmission (only for devices + without own rate control). Also other fields are parsed + + flags field + IEEE80211_RADIOTAP_VHT_FLAG_SGI: use short guard interval + + bandwidth field + 1: send using 40MHz channel width + 4: send using 80MHz channel width + 11: send using 160MHz channel width + The injection code can also skip all other currently defined radiotap fields facilitating replay of captured radiotap headers directly. diff --git a/Documentation/networking/stmmac.txt b/Documentation/networking/stmmac.txt index d64a147142364..671fe3dd56d3c 100644 --- a/Documentation/networking/stmmac.txt +++ b/Documentation/networking/stmmac.txt @@ -1,6 +1,6 @@ STMicroelectronics 10/100/1000 Synopsys Ethernet driver -Copyright (C) 2007-2014 STMicroelectronics Ltd +Copyright (C) 2007-2015 STMicroelectronics Ltd Author: Giuseppe Cavallaro This is the driver for the MAC 10/100/1000 on-chip Ethernet controllers @@ -138,6 +138,8 @@ struct plat_stmmacenet_data { int (*init)(struct platform_device *pdev, void *priv); void (*exit)(struct platform_device *pdev, void *priv); void *bsp_priv; + int has_gmac4; + bool tso_en; }; Where: @@ -181,6 +183,8 @@ Where: registers. init/exit callbacks should not use or modify platform data. o bsp_priv: another private pointer. + o has_gmac4: uses GMAC4 core. + o tso_en: Enables TSO (TCP Segmentation Offload) feature. For MDIO bus The we have: @@ -278,6 +282,13 @@ Please see the following document: o stmmac_ethtool.c: to implement the ethtool support; o stmmac.h: private driver structure; o common.h: common definitions and VFTs; + o mmc_core.c/mmc.h: Management MAC Counters; + o stmmac_hwtstamp.c: HW timestamp support for PTP; + o stmmac_ptp.c: PTP 1588 clock; + o dwmac-.c: these are for the platform glue-logic file; e.g. dwmac-sti.c + for STMicroelectronics SoCs. + +- GMAC 3.x o descs.h: descriptor structure definitions; o dwmac1000_core.c: dwmac GiGa core functions; o dwmac1000_dma.c: dma functions for the GMAC chip; @@ -289,11 +300,32 @@ Please see the following document: o enh_desc.c: functions for handling enhanced descriptors; o norm_desc.c: functions for handling normal descriptors; o chain_mode.c/ring_mode.c:: functions to manage RING/CHAINED modes; - o mmc_core.c/mmc.h: Management MAC Counters; - o stmmac_hwtstamp.c: HW timestamp support for PTP; - o stmmac_ptp.c: PTP 1588 clock; - o dwmac-.c: these are for the platform glue-logic file; e.g. dwmac-sti.c - for STMicroelectronics SoCs. + +- GMAC4.x generation + o dwmac4_core.c: dwmac GMAC4.x core functions; + o dwmac4_desc.c: functions for handling GMAC4.x descriptors; + o dwmac4_descs.h: descriptor definitions; + o dwmac4_dma.c: dma functions for the GMAC4.x chip; + o dwmac4_dma.h: dma definitions for the GMAC4.x chip; + o dwmac4.h: core definitions for the GMAC4.x chip; + o dwmac4_lib.c: generic GMAC4.x functions; + +4.12) TSO support (GMAC4.x) + +TSO (Tcp Segmentation Offload) feature is supported by GMAC 4.x chip family. +When a packet is sent through TCP protocol, the TCP stack ensures that +the SKB provided to the low level driver (stmmac in our case) matches with +the maximum frame len (IP header + TCP header + payload <= 1500 bytes (for +MTU set to 1500)). It means that if an application using TCP want to send a +packet which will have a length (after adding headers) > 1514 the packet +will be split in several TCP packets: The data payload is split and headers +(TCP/IP ..) are added. It is done by software. + +When TSO is enabled, the TCP stack doesn't care about the maximum frame +length and provide SKB packet to stmmac as it is. The GMAC IP will have to +perform the segmentation by it self to match with maximum frame length. + +This feature can be enabled in device tree through "snps,tso" entry. 5) Debug Information diff --git a/Documentation/networking/switchdev.txt b/Documentation/networking/switchdev.txt index fad63136ee3eb..31c39115834d6 100644 --- a/Documentation/networking/switchdev.txt +++ b/Documentation/networking/switchdev.txt @@ -89,6 +89,18 @@ Typically, the management port is not participating in offloaded data plane and is loaded with a different driver, such as a NIC driver, on the management port device. +Switch ID +^^^^^^^^^ + +The switchdev driver must implement the switchdev op switchdev_port_attr_get +for SWITCHDEV_ATTR_ID_PORT_PARENT_ID for each port netdev, returning the same +physical ID for each port of a switch. The ID must be unique between switches +on the same system. The ID does not need to be unique between switches on +different systems. + +The switch ID is used to locate ports on a switch and to know if aggregated +ports belong to the same switch. + Port Netdev Naming ^^^^^^^^^^^^^^^^^^ @@ -104,25 +116,13 @@ external configuration. For example, if a physical 40G port is split logically into 4 10G ports, resulting in 4 port netdevs, the device can give a unique name for each port using port PHYS name. The udev rule would be: -SUBSYSTEM=="net", ACTION=="add", DRIVER="", ATTR{phys_port_name}!="", \ - NAME="$attr{phys_port_name}" +SUBSYSTEM=="net", ACTION=="add", ATTR{phys_switch_id}=="", \ + ATTR{phys_port_name}!="", NAME="swX$attr{phys_port_name}" Suggested naming convention is "swXpYsZ", where X is the switch name or ID, Y is the port name or ID, and Z is the sub-port name or ID. For example, sw1p1s0 would be sub-port 0 on port 1 on switch 1. -Switch ID -^^^^^^^^^ - -The switchdev driver must implement the switchdev op switchdev_port_attr_get -for SWITCHDEV_ATTR_ID_PORT_PARENT_ID for each port netdev, returning the same -physical ID for each port of a switch. The ID must be unique between switches -on the same system. The ID does not need to be unique between switches on -different systems. - -The switch ID is used to locate ports on a switch and to know if aggregated -ports belong to the same switch. - Port Features ^^^^^^^^^^^^^ @@ -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/networking/timestamping.txt b/Documentation/networking/timestamping.txt index a977339fbe0a5..671cccf0dcd26 100644 --- a/Documentation/networking/timestamping.txt +++ b/Documentation/networking/timestamping.txt @@ -44,11 +44,17 @@ timeval of SO_TIMESTAMP (ms). Supports multiple types of timestamp requests. As a result, this socket option takes a bitmap of flags, not a boolean. In - err = setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPING, (void *) val, &val); + err = setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPING, (void *) val, + sizeof(val)); val is an integer with any of the following bits set. Setting other bit returns EINVAL and does not change the current state. +The socket option configures timestamp generation for individual +sk_buffs (1.3.1), timestamp reporting to the socket's error +queue (1.3.2) and options (1.3.3). Timestamp generation can also +be enabled for individual sendmsg calls using cmsg (1.3.4). + 1.3.1 Timestamp Generation @@ -71,13 +77,16 @@ SOF_TIMESTAMPING_RX_SOFTWARE: kernel receive stack. SOF_TIMESTAMPING_TX_HARDWARE: - Request tx timestamps generated by the network adapter. + Request tx timestamps generated by the network adapter. This flag + can be enabled via both socket options and control messages. SOF_TIMESTAMPING_TX_SOFTWARE: Request tx timestamps when data leaves the kernel. These timestamps are generated in the device driver as close as possible, but always prior to, passing the packet to the network interface. Hence, they require driver support and may not be available for all devices. + This flag can be enabled via both socket options and control messages. + SOF_TIMESTAMPING_TX_SCHED: Request tx timestamps prior to entering the packet scheduler. Kernel @@ -90,7 +99,8 @@ SOF_TIMESTAMPING_TX_SCHED: machines with virtual devices where a transmitted packet travels through multiple devices and, hence, multiple packet schedulers, a timestamp is generated at each layer. This allows for fine - grained measurement of queuing delay. + grained measurement of queuing delay. This flag can be enabled + via both socket options and control messages. SOF_TIMESTAMPING_TX_ACK: Request tx timestamps when all data in the send buffer has been @@ -99,6 +109,7 @@ SOF_TIMESTAMPING_TX_ACK: over-report measurement, because the timestamp is generated when all data up to and including the buffer at send() was acknowledged: the cumulative acknowledgment. The mechanism ignores SACK and FACK. + This flag can be enabled via both socket options and control messages. 1.3.2 Timestamp Reporting @@ -183,6 +194,37 @@ having access to the contents of the original packet, so cannot be combined with SOF_TIMESTAMPING_OPT_TSONLY. +1.3.4. Enabling timestamps via control messages + +In addition to socket options, timestamp generation can be requested +per write via cmsg, only for SOF_TIMESTAMPING_TX_* (see Section 1.3.1). +Using this feature, applications can sample timestamps per sendmsg() +without paying the overhead of enabling and disabling timestamps via +setsockopt: + + struct msghdr *msg; + ... + cmsg = CMSG_FIRSTHDR(msg); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SO_TIMESTAMPING; + cmsg->cmsg_len = CMSG_LEN(sizeof(__u32)); + *((__u32 *) CMSG_DATA(cmsg)) = SOF_TIMESTAMPING_TX_SCHED | + SOF_TIMESTAMPING_TX_SOFTWARE | + SOF_TIMESTAMPING_TX_ACK; + err = sendmsg(fd, msg, 0); + +The SOF_TIMESTAMPING_TX_* flags set via cmsg will override +the SOF_TIMESTAMPING_TX_* flags set via setsockopt. + +Moreover, applications must still enable timestamp reporting via +setsockopt to receive timestamps: + + __u32 val = SOF_TIMESTAMPING_SOFTWARE | + SOF_TIMESTAMPING_OPT_ID /* or any other flag */; + err = setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPING, (void *) val, + sizeof(val)); + + 1.4 Bytestream Timestamps The SO_TIMESTAMPING interface supports timestamping of bytes in a diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt index 7328cf85236c2..1fd1fbe9ce95a 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 205c1b81625c3..d5506ba0fef71 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 0000000000000..20c120d4b3b80 --- /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 626052f403bb3..7c1c7bf48ec0a 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/target/tcmu-design.txt b/Documentation/target/tcmu-design.txt index bef81e42788f2..4cebc1ebf99a6 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 8c745c8931da0..ed419d6c8dec8 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/watchdog/watchdog-kernel-api.txt b/Documentation/watchdog/watchdog-kernel-api.txt index 55120a055a14d..917eeeabfa5ea 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 4e4b6f10d8410..c161399a6b5c1 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 05712ac83e382..c518dce7da4d6 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 74acd99f19c42..4851f02281d63 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -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 @@ -798,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 @@ -839,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 @@ -951,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 @@ -1297,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 @@ -1515,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/ @@ -1812,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 @@ -1837,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 @@ -1930,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 @@ -2406,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 @@ -2540,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 @@ -3058,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 @@ -3312,6 +3348,7 @@ F: Documentation/powerpc/cxlflash.txt STMMAC ETHERNET DRIVER M: Giuseppe Cavallaro +M: Alexandre Torgue L: netdev@vger.kernel.org W: http://www.stlinux.com S: Supported @@ -3647,7 +3684,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 @@ -3726,7 +3763,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 @@ -3734,6 +3771,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 @@ -3778,7 +3817,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 @@ -4250,13 +4289,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 @@ -4271,7 +4303,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 @@ -4333,6 +4365,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 @@ -4344,7 +4382,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 @@ -4423,7 +4461,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 @@ -4984,8 +5022,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 @@ -5005,6 +5043,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 @@ -5233,6 +5272,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 @@ -5507,7 +5556,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 @@ -5515,7 +5564,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 @@ -5703,7 +5752,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/ @@ -5723,6 +5772,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 @@ -6010,7 +6069,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 @@ -6046,7 +6105,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 @@ -6096,18 +6155,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 @@ -6331,7 +6404,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 @@ -6636,27 +6709,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 @@ -6664,7 +6737,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 @@ -6730,7 +6803,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 @@ -6900,28 +6973,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 @@ -7490,7 +7563,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 @@ -7504,7 +7577,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 @@ -7844,6 +7917,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 @@ -7894,7 +7972,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* @@ -7998,7 +8076,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 @@ -8175,6 +8253,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 @@ -8275,7 +8361,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 @@ -8287,7 +8373,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 @@ -8315,6 +8401,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 @@ -8618,6 +8713,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 @@ -8658,8 +8755,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 @@ -8864,7 +8961,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 @@ -9046,6 +9143,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 @@ -9163,6 +9267,12 @@ 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" M: Josh Triplett @@ -9215,6 +9325,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/ @@ -9224,6 +9335,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/ @@ -9625,9 +9737,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-* @@ -9793,10 +9905,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 @@ -10046,7 +10160,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 @@ -10177,28 +10291,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 @@ -10248,7 +10362,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/ @@ -10482,6 +10596,14 @@ L: linux-tegra@vger.kernel.org S: Maintained F: drivers/staging/nvec/ +STAGING - OLPC SECONDARY DISPLAY CONTROLLER (DCON) +M: Jens Frederich +M: Daniel Drake +M: Jon Nettleton +W: http://wiki.laptop.org/go/DCON +S: Maintained +F: drivers/staging/olpc_dcon/ + STAGING - REALTEK RTL8712U DRIVERS M: Larry Finger M: Florian Schilhabel . @@ -11036,8 +11158,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/ @@ -11126,7 +11248,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 @@ -11247,12 +11369,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/ @@ -11878,14 +12001,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 @@ -11904,21 +12027,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 @@ -11963,6 +12086,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 @@ -12094,9 +12223,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 @@ -12108,16 +12237,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 6798c6b4775de..173437debc873 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 4 -PATCHLEVEL = 5 +PATCHLEVEL = 6 SUBLEVEL = 0 -EXTRAVERSION = +EXTRAVERSION = -rc2 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/arch/Kconfig b/arch/Kconfig index f6b649d88ec82..81869a5e7e174 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/uaccess.h b/arch/alpha/include/asm/uaccess.h index 9b0d40093c9a3..c419b43c461dc 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/kernel/pci-noop.c b/arch/alpha/kernel/pci-noop.c index 2b1f4a1e92723..8e735b5e56bd3 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/mm/Makefile b/arch/alpha/mm/Makefile index c993d3f93cf6a..5a98079364110 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 813c9b63c0e17..0000000000000 --- 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 07a5cb944d4ff..208aae071b378 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 diff --git a/arch/arc/Makefile b/arch/arc/Makefile index c8230f3395f28..def69e347b2da 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/axs10x_mb.dtsi b/arch/arc/boot/dts/axs10x_mb.dtsi index 44a578c10732c..ab5d5701e11d4 100644 --- a/arch/arc/boot/dts/axs10x_mb.dtsi +++ b/arch/arc/boot/dts/axs10x_mb.dtsi @@ -47,6 +47,14 @@ clocks = <&apbclk>; clock-names = "stmmaceth"; max-speed = <100>; + mdio0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,dwmac-mdio"; + phy1: ethernet-phy@1 { + reg = <1>; + }; + }; }; ehci@0x40000 { diff --git a/arch/arc/boot/dts/nsim_hs.dts b/arch/arc/boot/dts/nsim_hs.dts index fc81879bc1f58..f46633eeb06b8 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 1c169dc74ad13..d94b4ce516ad4 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 d64a96f8515ad..034a3139c1e23 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 f6bf0ca95a572..8a1297e025405 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 5d4e2a07ad3eb..6cdffea3a9146 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 87ee46b237ef7..f8b396c9aedb7 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 diff --git a/arch/arc/configs/axs103_smp_defconfig b/arch/arc/configs/axs103_smp_defconfig index d80daf4f7e735..56128ea2b7487 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 diff --git a/arch/arc/configs/nsim_700_defconfig b/arch/arc/configs/nsim_700_defconfig index f41095340b6a7..7314f538847bd 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 cfaa33cb59217..a99dc7a3f0af5 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 bb2a8dc778b5b..59f221fc9a41c 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 646182e93753a..42bafa552498f 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 ceca2541950d1..4bb60c1cd4a2f 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 4b6da90f6f261..7e88f4c720f80 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 9b342eaf95aec..4c5118384eb5f 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 a07f20de221ba..c0d6a010751a9 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 735985974a313..52ec315dc5c95 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 f9f4c6f59fdbb..7fbaea00a3366 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 57c1f33844d44..0352fb8d21b99 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 210ef3e723322..23706c635c30a 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 fbe3587c4f36f..a093adbdb0175 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/cmpxchg.h b/arch/arc/include/asm/cmpxchg.h index af7a2db139c96..a444be67cd53e 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 660205414f1da..266f11c9bd593 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 1aff3be910756..1d8f57cd60577 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/io.h b/arch/arc/include/asm/io.h index 947bf0cfdec00..17f85c9c73cfe 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 429957f1c2365..36da89e2c853e 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 d426d42155133..7d6c93e63adf3 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 1fe9c8c80280b..f0d42f1e83f5a 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 cdc821df18092..151acf0c9383f 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 001de4ce711ea..e0efff15a5aec 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 156d9833ff84b..7d9a736fc7e5c 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 b65f797e9ad67..9e5eddbb856f1 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 01eaf88bf8213..8c8e36fa56594 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 92dd92cad7f92..04f83322c9fda 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 739e65f355dea..49b8abd1115c2 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 daf2bf52b984c..7046c12c58edd 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 1d00da16d9807..cdfa6c2b7626f 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 c6b6175d02032..1098e91d6d3f3 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 fe254108d1d92..8c3ce2ac44c4a 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 9eca7aee927f3..48fab15cfc021 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 0714e0334e33c..86b2f5d28240b 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 43788b1a1ac5e..d50430c40045d 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.lzo.S b/arch/arm/boot/compressed/piggy.S similarity index 67% rename from arch/arm/boot/compressed/piggy.lzo.S rename to arch/arm/boot/compressed/piggy.S index a425ad95959a7..f72088495f439 100644 --- a/arch/arm/boot/compressed/piggy.lzo.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.lzo" + .incbin "arch/arm/boot/compressed/piggy_data" .globl input_data_end input_data_end: diff --git a/arch/arm/boot/compressed/piggy.gzip.S b/arch/arm/boot/compressed/piggy.gzip.S deleted file mode 100644 index a68adf91a1655..0000000000000 --- a/arch/arm/boot/compressed/piggy.gzip.S +++ /dev/null @@ -1,6 +0,0 @@ - .section .piggydata,#alloc - .globl input_data -input_data: - .incbin "arch/arm/boot/compressed/piggy.gzip" - .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 3d9a575618a3e..0000000000000 --- 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 d7e69cffbc0a5..0000000000000 --- 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.xzkern.S b/arch/arm/boot/compressed/piggy.xzkern.S deleted file mode 100644 index 5703f300d0278..0000000000000 --- 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 36e53ef9200f2..6894674487367 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 a4a6d70e8b26c..95c1923ce6fa3 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 9af2d60e9a7f6..db8752fc480e7 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 ded1eb64ea521..6c667fb354492 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 857d9894103a9..95461a28bc987 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 42e9b665582ab..e835644c5054d 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 0d6a68ce434a4..28b9162102712 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 54f113546ecc0..6c3a9bf3638a1 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 c20ae6c6f6c7c..d4b7f3bd553fd 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 3303c281697b0..a6efbe6eda3b9 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 1fafaad516ba0..55ca9c7dcf6aa 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 92068fbf8b577..6e4f5af3d8f8b 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 8677f4cce9e9e..9551c4713173b 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 ecd09ab6d581b..8889be1ca1c31 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 d580e2b70f9a6..83dfafaaba1bc 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 592e65c3a4e0c..0a5fc5d02ce2b 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 1c06cb76da07c..14f912a1b4fd7 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 1bc64cda819e0..652d85b28aaa2 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 da755c9851a73..63d6a051839f5 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 bb280de511dad..2364fc56ae139 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 3aa980ad64f0c..d5e19cd4d256b 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 faa474874cb8e..11565752b9f6b 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 836bcc07afc5b..8ca7a4340c0ff 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 7ccce7529b0c8..cc952cf8ec300 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 5f9451be21ffe..2d3fd6e76e2c3 100644 --- a/arch/arm/boot/dts/armada-385-db-ap.dts +++ b/arch/arm/boot/dts/armada-385-db-ap.dts @@ -135,6 +135,7 @@ }; }; + /* CON3 */ ethernet@30000 { status = "okay"; phy = <&phy2>; @@ -144,6 +145,7 @@ bm,pool-short = <3>; }; + /* CON2 */ ethernet@34000 { status = "okay"; phy = <&phy1>; @@ -153,6 +155,7 @@ bm,pool-short = <3>; }; + /* CON4 */ ethernet@70000 { pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/armada-388-gp.dts b/arch/arm/boot/dts/armada-388-gp.dts index 466b01eb10389..fd75e5e9550fc 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"; @@ -240,13 +240,13 @@ /* 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"; }; }; @@ -288,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>; }; @@ -314,7 +323,6 @@ regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; enable-active-high; - regulator-always-on; gpio = <&expander0 4 GPIO_ACTIVE_HIGH>; }; @@ -324,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>; }; @@ -333,7 +341,6 @@ regulator-name = "v5.0-sata0"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; - regulator-always-on; vin-supply = <®_sata0>; }; @@ -342,7 +349,6 @@ regulator-name = "v12.0-sata0"; regulator-min-microvolt = <12000000>; regulator-max-microvolt = <12000000>; - regulator-always-on; vin-supply = <®_sata0>; }; @@ -352,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>; }; @@ -361,7 +367,6 @@ regulator-name = "v5.0-sata1"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; - regulator-always-on; vin-supply = <®_sata1>; }; @@ -370,7 +375,6 @@ regulator-name = "v12.0-sata1"; regulator-min-microvolt = <12000000>; regulator-max-microvolt = <12000000>; - regulator-always-on; vin-supply = <®_sata1>; }; @@ -378,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>; }; @@ -387,7 +391,6 @@ regulator-name = "v5.0-sata2"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; - regulator-always-on; vin-supply = <®_sata2>; }; @@ -396,7 +399,6 @@ regulator-name = "v12.0-sata2"; regulator-min-microvolt = <12000000>; regulator-max-microvolt = <12000000>; - regulator-always-on; vin-supply = <®_sata2>; }; @@ -404,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>; }; @@ -413,7 +415,6 @@ regulator-name = "v5.0-sata3"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; - regulator-always-on; vin-supply = <®_sata3>; }; @@ -422,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.dtsi b/arch/arm/boot/dts/armada-38x.dtsi index 066a8f06405cd..3312be6c82cc6 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>; diff --git a/arch/arm/boot/dts/armada-xp-db.dts b/arch/arm/boot/dts/armada-xp-db.dts index cca3665905610..62422a90aeb25 100644 --- a/arch/arm/boot/dts/armada-xp-db.dts +++ b/arch/arm/boot/dts/armada-xp-db.dts @@ -242,6 +242,34 @@ 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 { diff --git a/arch/arm/boot/dts/artpec6-devboard.dts b/arch/arm/boot/dts/artpec6-devboard.dts new file mode 100644 index 0000000000000..f823ed382ac7c --- /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 0000000000000..30430162b8867 --- /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 e683856c507c8..21c780fab7612 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 ff888d21c786a..f3e2b96c06a36 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 569026e8f96ca..da84e65b56ef1 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 ea288f0a1d390..a9d6d593fc8a7 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 32bcd45ef22b3..80b6ba4ca50c9 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 10bdef557ba05..def9e783b5c69 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 0000000000000..ddbbbbd42ddab --- /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 3afb9fefe2d1f..76bdbcafab18e 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 971e741e5467b..8aaf193711bfe 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 0000000000000..6c83538bc2d77 --- /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 4e42f30cb318d..c0451051777ea 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 e070862b10383..cbc17b0794b10 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 26001585673ad..e0ea6a93a22ed 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 a25cd51e39ab0..4a6ce8c8bf8f8 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 169a85578fc93..f50348bdd8574 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 c3b8811a3e587..d9309a0161171 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 79008069020da..f820573f4a4a1 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 0000000000000..1c39a8459b39c --- /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 cfc24e52244e1..d9b87236019d8 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 0000000000000..dd74a5337d1fd --- /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 f82aa44c3ceed..13ac882794270 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 00b12002c07c0..6affe2d137da8 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 8bcc47db1cd18..4220eeffc65ae 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 357bedeebfac4..d0bae06b7eb7e 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 57795da616cb4..bcce6f50c93d9 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 0000000000000..09a2040054edc --- /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 443a350858460..9e2840b59ae85 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 3e64d5dcdd60c..1f102f3a1ab11 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 18e3deffbf480..137f9015d4e87 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 045785c44c048..c679b3cc3c488 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 5821ad87e32c7..ad7394c1d67a9 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 104cbb33d2bb0..94ca7d36ab378 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 a50be640f1b03..1df2f0bc1d76d 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 4f5d37920c8db..9a75e3effbc98 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 395c3ca9601ea..5e5d3fecb04cd 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 b44bb682e9767..bf7b21b817e48 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 9e2e24c6177a6..8bca699b7f208 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 a130ab39fa775..a51069f3c03b7 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 a6f78c3da9350..ed017cc7b14fc 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 ad764842fff52..28b04b6795c99 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 e2439e87ee4ab..92313cac035e4 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 c000532c14446..8b2acc74aa76f 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 5cb33ba5e2962..95210ef6a6b51 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 c1edd6d038a90..0f500cb1eb2dd 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 33e2d5f7315b5..e653ae04015a0 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 0000000000000..f9aa6bb55464b --- /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 cebeaab3abecd..a731fbe28ebc0 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 fad0779b1b6e8..fa558674ac763 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 4ecef6981d5c4..a103ce8c39858 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 0000000000000..5c052d7ff5546 --- /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 35cfb07dc4bb7..3981ddb25036a 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 ac35aefd320ff..0785fedf441e8 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 48a0a55314f5d..7b99cb58d82d3 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 2b289d7c0d13d..3e4c4ad96d637 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 b7f60c8554591..bf3c6f1ec4ee3 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 9134217446b8e..1bd507bfa7501 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 f18b51f2eeaa8..b9342ec5b9cff 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 064176f201e74..6e9edc1610c49 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 c0bb3563cac14..8213016803e5d 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 6cbb62e5c6a9e..c85d07e6db612 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 33130f8461c37..4e9562f806a21 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 c52722b14e4a0..fdcc23d203e5d 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 ed1d0b4578ef9..cda6907a27b9b 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 cde329e9b9e3f..6b1f4bbe6ec6e 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 7ac4f1af16ac8..1eaa131e2d180 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 927b391d2058d..88594747f454f 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 4ea89344a5fff..fd20e99c777e9 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 75b036700d314..4727bbb804e12 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 ed3dc3391d1c5..14e1320d9f843 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 649befeb2cf96..018d24eb9965f 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 321662f53e330..16fc69c69ab2e 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 34599c547459a..d270df3e58917 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 9eb92abaeb6dc..82eae3c8a3ce2 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 3bc18835fb4bb..4486bc47d1400 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 53fd75c8ffcfd..c05e7cfd0cbcb 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 13e842b0c7857..0ecb43d885223 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 64804719f0f44..3cf682a681f40 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 d3e50b22064f2..bd3dfefa5778a 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 c275eecc94720..d35a5cdc32296 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 f607d4f1d2448..8c314eee4fdd7 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 0000000000000..2cba82d0d859b --- /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 0000000000000..3101be5bafa7d --- /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 0000000000000..823f55ccb60fb --- /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 0000000000000..984d00000403d --- /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 0000000000000..8f6e6035f3f7a --- /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 0000000000000..bb66dfd5294c5 --- /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 0000000000000..4fa56019225e6 --- /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 00bd63e63d0cd..b715deb4ea466 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 0000000000000..005318865f66a --- /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 5645d52850a7e..0da81bc2c68a4 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 88aa1e4c792d2..2792da93db1fc 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 20bf3c2826230..9207d80f9cfb6 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 0d93c0e8f9baf..cd10c8de19048 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 0000000000000..b33e5a95a0f0b --- /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 e26ebeb5b45c0..a8f3500ee522b 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 5cd16f2178b80..9d7ab6cdc9a60 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 9fa8a10c7cc88..8dd74e98ffd69 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 e8375e173873e..ec3fe7444e154 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 66983dc5cbdae..367cc49eea0d6 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 cca39f194017c..f27f184558fb4 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 6dd0b764e036d..d6c2358ffad44 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 0000000000000..f8d945a565257 --- /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 6d4069cc9419e..86460e46d0559 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 a35d54fd9cd32..dc74aa395ff54 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 caeed56b74a39..c6c590d1e9409 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 1a69a3420ac8d..0f1aca450fe6a 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 a6d445c17779c..0b5c4de74485c 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 13cb7ccfea44d..efd06b576f1da 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 1211da894ee99..d3e54e40a0172 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 f74d3db4846da..b42822aa14f29 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 0000000000000..5ce3840d83d3f --- /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 0000000000000..b23458062f5e6 --- /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 0000000000000..1ada71437e49f --- /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 10c69963100fa..058bcdceb81aa 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 115f3fd789718..96ea936eeeb0a 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 94ac4005d9cd3..f1d37306e8bf4 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 6aaa5ec3d846e..720728001d3c6 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 20c7da1affce0..0034eeb84542f 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 99b646506fc91..71778992f03d9 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 d63c597c07835..f8a8685527071 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 b2c453662905e..b267f79e30590 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 25ad309787401..b5a50e0e7ff19 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 3807d4f46ef7c..b82f0e6d9a637 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 0000000000000..5bfd9e7845f2b --- /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 0000000000000..7ff2796ae925a --- /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 0000000000000..6548e68a20d00 --- /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 0000000000000..cf2e69f0d54ff --- /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 0000000000000..6dc0df2969f04 --- /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 0000000000000..edcba5c44b05f --- /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 0000000000000..4b6450186af59 --- /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 0000000000000..954ec1d5b6dc2 --- /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 0000000000000..ecd5c12a805db --- /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 0000000000000..69061b6e987b8 --- /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 36eec7392ab49..0000000000000 --- 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 b13ec20a70887..0000000000000 --- 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 887b9c1fee438..96ff59d68f445 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 d3330dadf7edd..24f1d30970a06 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 7b5a4a18f49cb..7445a15e259d0 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 0000000000000..da8598402ab8b --- /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 0000000000000..365f39ff58bb8 --- /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 fb13f18c08cc3..015f795a8d193 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 00805322367e7..5e9a13c0eaf7f 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 c85cf979725e0..c58d8da9ea2a1 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 ecf12dc225953..726372d3adc02 100644 --- a/arch/arm/boot/dts/ls1021a.dtsi +++ b/arch/arm/boot/dts/ls1021a.dtsi @@ -572,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 3766904b60f38..83437683aa60a 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 0000000000000..a9ee2d64c6f74 --- /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 0000000000000..fd2b614ae6f3d --- /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 0000000000000..e211a3c47a76c --- /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 0000000000000..68d75e79a360b --- /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 8ba465d57635f..4602866792be3 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 e5f7f5c92c1a9..a8127bc31fd92 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 86850bb311ebb..b1b8ebf90c1cc 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 ac188657a95d1..76056ba92cedc 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 5e2d6433d9394..ab9fb8f49ff38 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 3caf062f882c6..41f5d386f21f3 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 d90f12c39307a..d6f839cab6499 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 640f066039669..e94d9427450ca 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 540163025dd3e..2f353dadfa400 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 93f8dfe20f132..eff816e0bc0a4 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 f2e213931e09a..5c67429a4da75 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 e3bdcf819643e..b3c26a96a7262 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 a2c2b8d8dd2c7..858a25048102d 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 0885b34d5d7da..7f219a9dc5be0 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 a29ad16cc9bbd..de256fa8da487 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 13e9d1f987afe..bcf39d606b65a 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 0000000000000..78a1184cb312a --- /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 ae5dbbd9d5692..644d3c8ea66ab 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 d1ffabb7c74fc..b41d07e8e765e 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 16b0cdfbee9cb..a0dc8d854142d 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 4f6b2d5b1902e..387dc31822fe9 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 86253de5a97a9..f19c87bd6bf35 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 ca3c17fde5a0f..38805ebbe2ba4 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 0000000000000..1cf644bfd7ea1 --- /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 aae8a7aceab75..0eead400f4277 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 0000000000000..ed456ab35fd84 --- /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 7d253bb6265ac..a00d7ce7802b7 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 7f68a1ee7073c..210192c38df3c 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 cf6998a0804d4..fec47bcd8292f 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 0000000000000..c535b3f0e5cfd --- /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 21095dad77419..35f1d46edded1 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 fd4d49ef9ef25..2eeb0904eaa79 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 0000000000000..b57c59d5bc00b --- /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 ed521e85e208e..65d0e8d982594 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 08214cbae16da..a33a09f6821ed 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 fa698635eea0d..2601a907947b9 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 e5f7f33aa4677..cd214030b84a5 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 51a40d84145c5..da05e28a81a76 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 dfdafdcb8aae9..ef53305784318 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 9f357f68713c4..0512f645922e2 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 ca53a59474375..d95edb6f62653 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 4657d7fb5bcee..89e46ebef1bca 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 cb4f7b2798fe2..6583a1dfca1f6 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 6ef954766eef7..995fbda74b7a0 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 a52b359e2ae24..21e3b9dda2dab 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 791aafd310a5d..f83a348fc07a4 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 fe396c8d58db7..e111d35d02aeb 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 6afa909865b52..a0cc08e6295b0 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 052dcee4790dd..aa6ca92a9485b 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 7dfd393bfc7e7..38b706399a6b1 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 45256f3cc8356..0ad71b81d3a25 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 01d239c3eaaaa..6c08314427d6a 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 2a369ddcb6fd8..6439f0569fe2c 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 baa59fe842986..87e89ec9dd47e 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 aef9e69d6c26a..b482159452412 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 2394e4883786f..ca9bc4fff2875 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 5153e3af25d94..66f077a3ca41d 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 6c78f1fae90f7..eacb2b291361e 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-kylin.dts b/arch/arm/boot/dts/rk3036-kylin.dts index 6b4ffc3cd5904..6251d109eff42 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"; @@ -271,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 { @@ -278,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 { @@ -300,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 609319ce916a3..d0f4bb7e1e50a 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 = ; @@ -232,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; @@ -262,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"; @@ -348,7 +350,7 @@ }; i2c1: i2c@20056000 { - compatible = "rockchip,rk3288-i2c"; + compatible = "rockchip,rk3036-i2c", "rockchip,rk3288-i2c"; reg = <0x20056000 0x1000>; interrupts = ; #address-cells = <1>; @@ -361,7 +363,7 @@ }; i2c2: i2c@2005a000 { - compatible = "rockchip,rk3288-i2c"; + compatible = "rockchip,rk3036-i2c", "rockchip,rk3288-i2c"; reg = <0x2005a000 0x1000>; interrupts = ; #address-cells = <1>; @@ -416,7 +418,7 @@ }; i2c0: i2c@20072000 { - compatible = "rockchip,rk3288-i2c"; + compatible = "rockchip,rk3036-i2c", "rockchip,rk3288-i2c"; reg = <0x20072000 0x1000>; interrupts = ; #address-cells = <1>; @@ -428,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>; @@ -618,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>; }; }; @@ -657,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 38c91a839795f..6d2a5b3a84a86 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 7cdc308bfac54..a2b763e949b46 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 341c1f87936a7..05533005a809c 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 58bac5053858b..cb0a552e0b181 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 66fa87d1e2c24..0b6924c97b6bf 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 348d46b7ada5a..9271833958f9d 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 119ff12ab4408..4dae42a015098 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 4faabdb65868e..78d47f7d29385 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 4e3fd9aefe349..98c586a43c730 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 65c475642d5a7..2ff9689d2e1b8 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 17f13c73fe5e0..510a1d0d7abb5 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 1ece66f3e1627..e1ee9f949035c 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 c5453a0b07fca..dd3ad2e93a6d5 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 136d650dd05fa..610769d99522e 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 9fce91ffff6fd..412809c60d019 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 8ac49f3efc178..31f7e20ef418d 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 99eeea70223b9..99bbcc2c9b897 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 aa64faa729701..da24ab570b0e8 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 3b76eeeb8410a..0a33d402138e1 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 da7d210df6704..54fcc3fc82e20 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 8344a0ee2b86f..ffc36bd24d2f1 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 3f750f6170f2f..78996bdbd3df3 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 3a6056f9f0d23..bf825ca4f6f79 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 15cbc747c2425..b89cbde3b289a 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 cce9e50acf68a..1c5e139e4d059 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 e48857249ce7b..84101e4eebbf8 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 c611f5606dfea..6565f3cb866f7 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 0aa6fef5ce226..0d0da1f65f0e6 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 b7b4211c5353e..55f9d0cc90f3a 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 27a333eb89870..e2be533430642 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 9c73ac2842ad1..2f5107ffeef04 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 6964fc9e97cfa..6bfc5959dac36 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 f0b731db6f530..01408073dd530 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 5e1e234e8c0a1..35df462559cad 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 0000000000000..e911af8364714 --- /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 53660894ea95e..023b03efa5fff 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 43f58fbe161ce..9103864fef90a 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 77c31dab86b13..04b0d2d1ae6c1 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 ca49b0d0ce1e0..bba4f9cf9bf5d 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 985e15503378f..4e798f014c992 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 ddf0683cbc6a4..ee46ea8548326 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 530ab28e9ca23..f6898c6b84d42 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 b6ad7850fac69..1867af24ff529 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 ea69fb8ad4d80..4ec0c8679b2e2 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 0000000000000..661c21d9bdbd5 --- /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 0000000000000..5ee43d8bf1748 --- /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 c9e648d17a1e8..90ff4a2670259 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 c3c626b2cfa21..23aacce4d6c7a 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 6f88fb0ddbc7d..7e05e09e61c7e 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 13ce68f06dd6e..fef6abc0a7038 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 0000000000000..342e1d33fa1c3 --- /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 0000000000000..88b1e0970b8d8 --- /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 0000000000000..d3473f81b12f7 --- /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 e67df590535fa..79f40c3e6101e 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 1524130e43c94..dadb7f60c0623 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 1a69231d2da57..9d2b7e2f5975e 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 382bd9fc5647a..eb2ccd0a3bd5d 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 c0060e4f7379f..d7a20d92b1143 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 e838f206f2a0f..f68b3242b33a0 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 0000000000000..2565d5137a17e --- /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 ea9301aaa461b..61a0955982064 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 f1e9d40149ab8..ec94b7a661f2a 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 34f0d8dcd8147..dadd86070c983 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 5baa9fc9c8886..b8134c6e094b1 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 0000000000000..d34358632bec1 --- /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 24626687d4df5..95f631a3de355 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 0000000000000..7c3a1fcc9f3cc --- /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 d78142fb35c42..20f3f2ae7fa41 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 2f389ea75e015..24f6f664b2692 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 b7a032156789f..acb420492b36f 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 691a17d765c25..03292f443305e 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 fc7250c61674f..d594f40e7f762 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 7d06a1c487d8c..6bfd29a055759 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 f67445f4f10da..24592798a3688 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 9d7ec5c204dd7..bf2619e4d4892 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 6bd353f2d77ef..4ac484c6ce4eb 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 3d29d2806cc0c..f7df0881c5e00 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 da271e3b922ab..51ecc9b9c0ceb 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 6fd7efbead344..d23320af5ea79 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 21b02874bea3c..7a556b92e55c0 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 e712c0af149b9..47e4a115adef4 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 ed65e0f7dfc0a..4d8b7f6935355 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 6e556be42ccdc..fda7f28101e1c 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 c3173fc9e8336..b3aeab58f718d 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 84f091d1fcf29..3fe1f48c2aecd 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 e976d2fa15274..9d372720ad3f9 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 10ebe99e2751e..dbca4f86fdbb9 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 2d7eab7552100..ab4a29f95593d 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 5438ee4be2ecf..cdc1007325144 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 58bc6e448be56..0cfc060f94d7d 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 4539f8d909a53..5c0975451d4ef 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 9efd16cb2859d..307ed201d6589 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 cb64209bca08c..e96959b2e67ad 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 abf5d238ae04a..be6a986bbbd80 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 b9f2522012e8c..7250c1eac7f9d 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 16c9cacd668d4..d9e0f3e706711 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 3d224941b5419..fb0a0a4dfea4d 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 72def201c4fd5..1ef69fcbdf2e2 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 0000000000000..db96dcb420ceb --- /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 24dcd2bb1215d..6ffd7e76f3ce0 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 d3a8018639de2..9083399a8ab15 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 2d5253dcc2266..978c5deeb47c0 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 9c93f56552481..0b02e4f43c6a9 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 afb1f62fb05e3..e11d99d529ee9 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 @@ -97,9 +98,9 @@ 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 8e8b2ace9b7c5..28234906a0646 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 6c4c54037bc4c..4562006aae68a 100644 --- a/arch/arm/configs/mvebu_v5_defconfig +++ b/arch/arm/configs/mvebu_v5_defconfig @@ -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 c6729bf0a8ddb..dc5797a2efab5 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 b47e7c6628c9f..6e0f751be2293 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 d18d6b42fcf52..156bc88b8523f 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/pxa_defconfig b/arch/arm/configs/pxa_defconfig index 0cb724b5c6392..dc5517eaf09fb 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 93efdcfcf98fb..0000000000000 --- 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 8f56fb3ff51db..9e77dc7b828fc 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 f3142369f594a..b3ade552a2a53 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 c11bab735125f..afbda413d61aa 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 969738324a5d5..b7b714c3958c2 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 f7f4e2e3cc33d..753f1a5defc75 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 ec5250547d145..1e5ec2a0e4cf4 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 a9a81a714be46..81a1b92fd4e6a 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 16da6380eb850..55e0e3ea9cb6b 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/clkdev.h b/arch/arm/include/asm/clkdev.h deleted file mode 100644 index 4e8a4b27d7c79..0000000000000 --- 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 e1f07764b0d6b..7d919a9b32e5f 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 5abaf5bbd985f..bf1991263d2df 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 c79b57bf71c40..9427fd6325527 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 432ce8176498e..fa5b42d44985f 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 d1b162a18dcb1..503f488053de6 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 0000000000000..803bbf2b20b87 --- /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 00098615c6f0c..73e5e85137515 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/xen/hypercall.h b/arch/arm/include/asm/xen/hypercall.h index d769972db8cbe..b6b962d70db98 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 43243be94cfcb..d4ae3b8e2426e 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 619d8cc1ac125..92c44760d6569 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 0000000000000..6824b2d1c38e6 --- /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 de86b92475640..060cb5b49bfd8 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/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 3ce377f7251f3..e2550500486d4 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 a71501ff6f187..b09561a6d06a0 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 2a55373f49bfb..0b1e4a93d67ed 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 1d45320ee125d..ece04a457486c 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 8bf3b7c098881..59fd0e24c56b1 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 efdddcb97dd14..4f14b5ce6535f 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 4152158f6e6a5..15063851cd108 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 38269358fd252..71a2ff9ec4900 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/topology.c b/arch/arm/kernel/topology.c index 08b7847bf9124..ec279d161b328 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 0000000000000..cba1ec899a693 --- /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 b4139cbbbdd98..e2c6da096cefa 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 23be2e4330977..08047afdf38ea 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 c1a7c6cc00e10..63b4fa25b48a8 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 7eb64f763034f..cada2a6412b3b 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 b0fa7dc7286d9..28ca57a2060f0 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 23726fb31741e..f06270198bf12 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 d9cf6799aec00..df8fdf1cf66d6 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 de061ec5a4796..41dcf5d65630c 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 575defcc53f93..cfae9c71fb741 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 d079de0b6e3b5..0000000000000 --- 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 a0f5b60662ae5..a642ba5feb647 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 47905a50e0757..318394ed5c7a9 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 bcaf1d0255057..36c8f5324e438 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 7a20507a3eefb..68cc099078289 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 ee6ab7e8d3b0c..f702d4fc8eb81 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 62ebac51bab93..d97c588550ad4 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 e88b7a5cde994..725e693639d24 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 c7c1458df23cf..a0ecf499c2f22 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 01843fbcc9ea7..384d3674dd9b1 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 b28071ae3a571..b4b3a8b9ca202 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 cf80786e24714..a43db0f5fbaa7 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 8fb97b93b6bb3..53b456a5bbe03 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 d8c439c89ea93..0bd6d894c5970 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 652a0bb115789..207fa2c737a6d 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 2f306767cdfe4..34d29df3e0062 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 b9862e22bf10a..0000000000000 --- 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 e349a038976d6..5365bf1f586a7 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 1c47aee31e9cc..bbf51a46f772d 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 111cfbf66fdb9..1bfd1b0bd9dca 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 de3ae59e1cfbb..c88325d56743e 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 56978199c4798..f086bf615b297 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 5bd9559786ba7..85c3be63d6444 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 9c1506b499bca..c43b776a51a30 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 dbf9fe98d479a..0000000000000 --- 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 0b04b6b0fa302..8ef1f3ee4e986 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 c169cc3049aa3..fee2b003e6622 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 07152d00fc505..cbbdd84cf49ad 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 16496a071ecb8..cda330c93d610 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 15df34fbdf44c..8973fae25436b 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 fb689d813b098..9fbe624a5ef98 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 231bb250c5719..649a84c251ad6 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 1a8932335b213..7fa176e792bd1 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 32b83f09da18b..58a38464480d3 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 fe8d36f7e30ed..8d2ae4091465b 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 fde1860a25216..3daf1959a2f0a 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 ec3aaa098c170..8a54234df23b5 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 5b0f752d5507f..6a96b7cf468ff 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 08ce20771bb3f..fb9a73a57d00d 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 b5e976816b63c..6c28d28b3c647 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 0b5ba4bf572a2..3982e91b2f3ea 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 ecd5436646441..7aa90c863ad99 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 a53b2e64f98d5..ca59d5f2ec92e 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 f2060523ba489..eaee47a2fcc0f 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 9379fd0a7b4de..32dcb5e99e233 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 b015129e40458..6883fbaf9484b 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 3878494bd1182..cb27d566d5aba 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 f510c43981d3a..a4c389eae31a2 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 2b147e4bf9c91..4f2c56d44ba14 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 bb6f8a52a6b8b..4f2d99888afd2 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 5c27646047270..34df64f133ed2 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 a5b1af6d7441e..d327042567817 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 0000000000000..8bba9fcd96f66 --- /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 56d02d064fbf9..43096c8990d4c 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 6a07006ff0f48..94c0898751d85 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 532d4b08276dc..868781fd460c7 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 4470376af5f81..58924b3844df5 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 45f7f4e0a447c..70b083fe934a8 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 51c35013b673b..105d1ce4ed9d1 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 4de65eeda1eb1..ae23d50f7861b 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 b01bdc9baf895..b2a85ba13f088 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 ff0a4b5b0a82b..0000000000000 --- 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 f3835c43af61f..0000000000000 --- 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 c279293f084cb..e6b9cb1e67097 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 1f4f2f4f25bb0..478ebd1f2b0f2 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 474a050da85b9..7a1c4caa1ab5a 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 c089a1aea674e..a001c7c34df22 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 f5db805ab9587..c70709ada692e 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 661c8f4b23102..0000000000000 --- 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 716e83eb1db8e..5b7a1e78c3a5e 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 1cd8853b2f9b7..2d90801ed1e13 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 ee06fabdf60e6..b2f9e226febee 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 05621a29fba22..1931229a1eaa6 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 ff3499d1fb1a2..0000000000000 --- 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 0abcc51afff53..8ced4ad94af0f 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 2f9f09ac51bd0..9c2e38d30f472 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 a1b07eeaaf5b6..b821e34474b6f 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 5edf03e2beede..0000000000000 --- 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 a32575fa3fba4..c32f85559c650 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 760a0efe7580b..0000000000000 --- 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 a1a04df9c05c5..99cc93900a243 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 b003e3afd6930..348044ea650c6 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 55348ee5a3522..7e989d61159c3 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 f9597b701028a..46c742d3bd41e 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 3d90ef19be2b4..2da8e5dfcf24d 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 5cb1051b58313..033875dbc32b8 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-nspire/Makefile.boot b/arch/arm/mach-nspire/Makefile.boot deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/arch/arm/mach-omap1/dma.c b/arch/arm/mach-omap1/dma.c index 7b02ed218a42f..f6ba589cd312e 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 4869633de8cd3..9cca6a56788fe 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 b03e562acc607..0000000000000 --- 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 cf5855174c93c..1662071bb2cc8 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 aa7b379e26614..2a3db0bd9e15c 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 1ed4be184a29b..e58c13a9bea5e 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 0a985325cd645..9869a75c5d96d 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 e97a894b5f883..97fd399202dcb 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 848356e38b745..9442d89bd2292 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 e493ae3729103..39736ad2a7548 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 cc1e6a2b97f66..294deed956f36 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 79ca3c3eb2afe..70df8f6cddccb 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 a9ad95f000a15..a2af15822fcb8 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 760a0efe7580b..0000000000000 --- 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 f998eb1c698ec..0cf4426183cff 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 c77a4883a4eeb..0000000000000 --- 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 f096836879634..7ee4652b4c61d 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 37d8d85662f0f..913a319c7b005 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 0b00b226f54bc..e838b11fb8c7d 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 6815a9357774e..9c5b2fb054f96 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 f1dd62946b369..5537d5601d705 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 f4d48d20754ea..888bf7ade15ac 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 51558bcee999e..3aab90d8d2b72 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 8e0e62ccdcedf..f128133a8f309 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 a177bf45feefa..823504f48f806 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 8dfd1755c6594..2eaa341dd3f82 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 a1c4c888f246e..3c9184d1d6b9b 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/spitz.c b/arch/arm/mach-pxa/spitz.c index 825f903ab77eb..d9578bc49fdc6 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 515b7ddda8aaa..3b94ecfb94265 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 d2c3d788f6880..0000000000000 --- 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 0fd4b0b8ef22e..654a6f3f2547d 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 ef68ecb273964..b91aee406c74c 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 5dd1db4e26772..235c53647aa49 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 444793f0f5f1b..adc39043aa218 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 6d1e0b9c5b27c..27ae6877550f7 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 7c0c420c3016a..e5c1888fc67bb 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 c642333af3ed3..0000000000000 --- 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 8a894ee3ee76d..92ec8c3b42b9b 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 73093dc898299..a1a041b9740bc 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 cd5f171f83ce6..f2bc5c353119e 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 b3a4ed5289ec7..5464b7a75e302 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 57fbff024dcd5..634d701c56a74 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 0000000000000..916d25f6780e8 --- /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 5e503d91ad70d..936d7011c3141 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 081a097c9219f..8d478f1da265d 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 46d0a1ddce755..c0b05e9e64420 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 10b7cb5dcb3af..3c99aaf65325c 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 0c8f80c5b04df..db6dbfbaf9f10 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 fab95d1271bc7..cf236db686a9d 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 1e572a903f8e4..0007ff51d1803 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 9eccde3c7b137..1c6fd11c2f824 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 adbac6963f2b9..3a732199cf5e9 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 0b024a9dbd439..f5c31fbc10b2e 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 ee1a4b70604bd..41137404382e2 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 5d92b5dd486b0..74b30bade2c15 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 c17d4d3881ffc..ad008e4b0c49a 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 cbb0a54df80ac..07945748b5714 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 4674a4c221dbc..0000000000000 --- 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 f2ad7723d0349..ceee47735eecc 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 c2be98f38e73b..3c156190a1d44 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-u300/Makefile.boot b/arch/arm/mach-u300/Makefile.boot deleted file mode 100644 index 87811de0bd947..0000000000000 --- 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 e1cfc1d6e2f47..69141357afe81 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 760a0efe7580b..0000000000000 --- 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 a0ffaad1fb612..a557955472ea0 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 e40f777ccf7d0..b0cc26284fc97 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 c448718512552..dff1c0595b672 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 4b7c324ff664c..3855ecebda6e6 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 760a0efe7580b..0000000000000 --- 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 6f39d03cc27ea..860ffb663f02b 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 26320ebf34934..f0292a30e6f69 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 549f6d3aec5b6..55347662e5eda 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 1e373d268c04c..88255bea65e41 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 0eca3812527e6..deac58d5f1f7c 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/flush.c b/arch/arm/mm/flush.c index d0ba3551d49a4..3cced84557279 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 d65909697165b..bd274a05b8ffa 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 49bd08178008a..370581aeb8710 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 88fbe0d23ca61..62f4d01941f71 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -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/proc-v7.S b/arch/arm/mm/proc-v7.S index 0f92d575a3040..0f8963a7e7d9d 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -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 8085a8aac8124..ffb93db68e9c8 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 28848b344e2d9..ceba3e4184fc4 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 efa6e85619ad8..daf3db9f0058f 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 b53d4ff3befb6..84baa16f4c0b6 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 c0c70a895ca83..6feedd47d8754 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 f5cf2bd208e0c..4ec9a7050185f 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 49b8ef91584af..98b9b8e9f6987 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 03c4900ac3f4d..bff3ba889882e 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 5c8b6564fdc22..0000000000000 --- 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 21074f674bdeb..efa77c146415b 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 f832b8a7453a3..330fae966cf3a 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 0000000000000..8a6cde4f9b238 --- /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 0000000000000..a079d7b3063ec --- /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 0000000000000..5b7bef6842568 --- /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 cfdf701e05dfd..ba84770f789f5 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 0000000000000..8e3074a4947d0 --- /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 0000000000000..ed5e043f37aaf --- /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 2874d92881fda..bd3adeac374f4 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 0000000000000..8e8631952497f --- /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 0000000000000..1381d4b2bf1bb --- /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 0000000000000..eb672f38f89ea --- /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 0000000000000..399aff9e79754 --- /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 0000000000000..ac5a241b5ec2f --- /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 0000000000000..fff7bfa2aa39b --- /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 0000000000000..c1fa2667ec5c6 --- /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 0000000000000..eaa0a45537349 --- /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 e5ba8d5d0cae6..387c6a8d0da9f 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 178aef2cdd096..44db32ec5e9c3 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 278f106a0054c..a055a5d443b76 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 { diff --git a/arch/arm64/boot/dts/apm/apm-storm.dtsi b/arch/arm64/boot/dts/apm/apm-storm.dtsi index b7d7109e73049..ae4a173df493a 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 { diff --git a/arch/arm64/boot/dts/arm/Makefile b/arch/arm64/boot/dts/arm/Makefile index bb3c072096760..75cc2aa101013 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 0000000000000..35588dfa095c2 --- /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 4eac8dcea423e..71168077312d5 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 0000000000000..7cfa8e414e7f5 --- /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 e5b59ca9debb1..68ccc39a7a666 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 413f1b9ebcd45..3ad4c30006115 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 8826f834f54f2..d95d9e7e2dc08 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 0000000000000..88ecd6182b676 --- /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 20addabbd127c..a852e28a40e17 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 88a7583ed7a72..161ac98418a30 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 bb3c26d1154da..e3a171162bb47 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 e21fe66f18372..bec1f8b36f601 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 6bb3d4d9efa91..ce0ab84e0f2da 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 a510d3a8e6473..6f81c9d7fb067 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 0000000000000..9ee8d3da0e3f1 --- /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 0000000000000..c49b5a85809c5 --- /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 9cb7cf94284a6..2eb9b225f0bcc 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 20310e5b6d6f0..50c9b9383cfa6 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 42a61549afd45..be72bf5b58b5b 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 2b23d03606839..9d746c69a7896 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 ae34e250456fe..e9436c0d81f7b 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 c1ea999c7be14..6319ff3b03ea4 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 348f4db4f3139..308468d377d05 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 0000000000000..c9e5325b8ac3a --- /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 0000000000000..3590501545116 --- /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 0000000000000..f292a00ce97cb --- /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 0000000000000..ba9df7ff2a725 --- /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 0000000000000..52575756d0be4 --- /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 0000000000000..064a251346dd9 --- /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 0000000000000..7a2de8bf79074 --- /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 0000000000000..73d69d99513f5 --- /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 0000000000000..a1406a40959ef --- /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 0000000000000..f25c5c17fad75 --- /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 0000000000000..baa7d9a516b3c --- /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 0000000000000..556a92bcc2f60 --- /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 e427f04a9f450..7453a47b3047e 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 ec135eae31f54..eab7efc2302d1 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 8e94af64ee945..fa1f661ccccfb 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 e03c11d9d8344..f881437d53c5f 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 cbeee0bcdf523..ee828a8a82361 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 db17c5d5689c6..205ef89b8ca0b 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 955c6f174d4cb..10c83e11c272f 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 915321479998d..96812007850ec 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 0000000000000..619af44a595da --- /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 0000000000000..9bab5c011c070 --- /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 0000000000000..0506fb808c560 --- /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 0000000000000..ef2207afa86b4 --- /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 37432451ee4c0..f71679b15d544 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 0000000000000..1222d2e904f6b --- /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 0000000000000..d3879a4e8076d --- /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 265d12ff60222..b992b1a3d9569 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 bb353cde12533..a7315ebe3883f 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 8c219ccf67a3b..6e27b22704df5 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 104cbee762bb1..1f2b642e794ae 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 122777b1441e8..49d119103e31f 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 8d727717c24ef..299b67ec4d449 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 3e533178ba2f2..727ae5f8c4e71 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 0296af9cbbdb6..e682a3f52791b 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 0000000000000..cdc6a437dcc73 --- /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 ce5d848251fab..acb0527fdc4ad 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 200fb588d0f54..e595f22e7e4b6 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 86581f793e398..a44ef995d8ae8 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 22dda613f9c91..c64268dbff64c 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 f2309a25d14c8..87e1985f3be8c 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 6cb7e1a6bc02a..0c2eec490abf6 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 0e391dbfc4202..4150fd8bae014 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 226f49d69ea98..eb7490d232a0f 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 227ed475dbd3c..b7e82a795ac9e 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 a46b019ebcf5a..44eaff70da6ae 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 c18fdebb8f66d..0000000000000 --- 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 4e603ea36ad3f..123f45d92cd1f 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 7bd3cdb533ea8..2065f46fa7407 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 1a78d6e2a78b5..12874164b0ae5 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 1f7f5a2b61bf0..12e8d2bcb3f9d 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 6ebd204da16ab..4203d5f257bcf 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 1b52269ffa87e..f419a7c075a47 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 f67f35b6edb12..42816bebb1e0f 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 4c56e7a0621bc..5a1939a74ff35 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 b6a8fc5ad1afa..778d0effa2afd 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 bfc54fd82797b..5a9f3bf542b09 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/flush.c b/arch/arm64/mm/flush.c index 60585bde1264a..dbd12ea8ce684 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/init.c b/arch/arm64/mm/init.c index 61a38eaf0895c..ea989d83ea9ba 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 d2d8b8c2e17f7..f3e5c74233f30 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/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S index c9eec84aa2586..d920b959ff3a4 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/c6x/kernel/vmlinux.lds.S b/arch/c6x/kernel/vmlinux.lds.S index 5a6e141d1641b..50bc10f97bcb4 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 877da1908234b..617645d21b20c 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/frv/include/asm/page.h b/arch/frv/include/asm/page.h index 688d8076a43a8..ec5eebce4fb3c 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/h8300/boot/dts/edosk2674.dts b/arch/h8300/boot/dts/edosk2674.dts index 4ce9fa874a577..6ae884bf66a52 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 545bfb57af9a9..9c733d920f1f0 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 bcedba5a3ce7e..97e1f4b17ef06 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 067bfe9c49b3a..80624f46b0ed4 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 e4985dfa91dc8..c8c25a4e9e489 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 a15edf0565d9e..46138f55a9ea7 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/ia64/include/asm/uaccess.h b/arch/ia64/include/asm/uaccess.h index 4f3fb6ccbf213..2189d5ddc1eee 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 6a8685051b676..8c85209753abc 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 bce9bc1a66c4c..f72bf0172bb23 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/unistd.h b/arch/ia64/include/uapi/asm/unistd.h index 41369a103838a..ea5363daa7bd1 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 477c55e244ecd..cfaa7b25084c5 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 0c161ed6d18e6..09f845793d12c 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/mm/extable.c b/arch/ia64/mm/extable.c index c99a41e29fe81..8f70bb2d0c37b 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/m68k/include/asm/page_mm.h b/arch/m68k/include/asm/page_mm.h index 5029f73e62947..e7a1946455a88 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 ef209169579a9..fa7f32d9836b3 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/metag/kernel/vmlinux.lds.S b/arch/metag/kernel/vmlinux.lds.S index e12055e88bfe5..150ace92c7ade 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/microblaze/kernel/vmlinux.lds.S b/arch/microblaze/kernel/vmlinux.lds.S index be9488d697347..0a47f04105541 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 7c4a4ce356033..2018c2b0e078f 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 745695db5ba06..f2f264b5aafe2 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 bdeed9d13c6fe..433c4b9a9f0a9 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 b518f029f5e7b..1c01d6eadb08d 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 eb5117ced95ac..618dfd735eede 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 959c145a0a2c1..ca7ad131d0570 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 4eff1ef02eff9..309d2ad67e4d6 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 adb33e3550430..56035e5b70084 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 3ad4ba9b12fd6..3c2ed9ee5b2f8 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 e535ee3c26a4e..4f1540e5f9634 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 e59d1b79f24cd..2f415d9d0f3c1 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 87be167a7a6ae..676fab50dd2b0 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 b7fa9ae28c365..42412ba0f3bfd 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 4e36b6e1869c8..43e0ba24470cd 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 8c6f508e59de1..d7b99180c6e18 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 5537b94572b2d..0d75b5a0bad42 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/cpu-info.h b/arch/mips/include/asm/cpu-info.h index e7dc785a91ca6..af12c1f9f1a89 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 cf92fe7339952..c4873e8594ef1 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 13b0751b010a7..a229297c880b5 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 cf4384bfa8460..b0b7261ff3ad2 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 b087cb83da3a5..f992c1db876b5 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 bf8c3e1860e71..7c7708a23baa6 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 79cff26d8b36f..398733e3e2cf6 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 b196825a1de9c..d4635391c36a2 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 1f6ea8352ca90..20621e1ca2383 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 f7dd17d0dc22d..f4f1996e0fac3 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 19e139c9f3379..3e982e0c397e8 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)); diff --git a/arch/mips/include/asm/pci/bridge.h b/arch/mips/include/asm/pci/bridge.h index 8d7a63b52ac73..3206245d1ed64 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 59920b3459420..4a9c99050c139 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 26ddfff28c8e2..105a9479ac5f7 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 e33f0363235b7..feb385180f874 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 5998b13e97649..57ece90f8cf1e 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 095ecafe6bd35..7f109d4f64a40 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 2cb7fdead5702..cc49dc240d671 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/unistd.h b/arch/mips/include/uapi/asm/unistd.h index 3129795de940b..24ad815c7f38d 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 1448c1f43d4e4..760217bbb2fa5 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 1f5aac7f9ec35..3fff89ae760ba 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 2b70723071c32..9083d63b765cf 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 1833f5171ccda..f9b2936d598de 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 d7b8dd43147a4..9bc1191b1ab0d 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 f63a289977cc5..fa3f9ebad8f40 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 eddd5fd6fdfa2..92880cee449e1 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 a56317444bdad..d01fe53a66385 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 2b2dc14610d02..6b73ecc02597c 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 2bf5c8593d91d..71f99d5f7a068 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 c5b759e584c75..91b43eea2d5a0 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 37708d9af6381..27cb638f08241 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 bf14da9f3e33b..ae0c89d23ad7d 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 490cea569d57d..5c62065cbf22d 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 0a93e83cd0147..54d653ee17e1a 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 a08c439462472..e0e1d0a611fc2 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 ad988000563f2..c4038d2a724c0 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 ad3c73436777f..47d26c805eac5 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 def00ffc50fcc..e0b2c450b9634 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 6cdffc76735c5..42d124fb64744 100644 --- a/arch/mips/mm/gup.c +++ b/arch/mips/mm/gup.c @@ -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 dc7c5a5214a9e..026cb59a914db 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 5037d5868cef7..c17d7627f872b 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 5a04b6f5c6fb8..84c6e3fda84af 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 fde56a8b85cae..1985971b98906 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 8d0eb26432480..f1f88291451ec 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/nios2/kernel/prom.c b/arch/nios2/kernel/prom.c index 718dd197909fa..367c5426157ba 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 326fab40a9de0..e23e895399677 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 108906f991d67..e613d36730341 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 2d69a853b742e..d936de4c07cad 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 14f655cf542e1..bd3c873951a1a 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 b3069fd83468c..60e6f07b7e326 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/compat.h b/arch/parisc/include/asm/compat.h index 0448a2c8eafbc..3387307cc33e1 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 a5eba95d87feb..637ce8d6f3752 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 0abdd4c607ed9..d4dd6e58682ce 100644 --- a/arch/parisc/include/asm/uaccess.h +++ b/arch/parisc/include/asm/uaccess.h @@ -60,14 +60,15 @@ static inline long access_ok(int type, const void __user * addr, * use a 32bit (unsigned int) address here. */ +#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" /* diff --git a/arch/parisc/include/uapi/asm/unistd.h b/arch/parisc/include/uapi/asm/unistd.h index b75039f921164..cc0ce92c93c78 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/cache.c b/arch/parisc/kernel/cache.c index 91c2a39cd5aab..67001277256c6 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/ptrace.c b/arch/parisc/kernel/ptrace.c index ce0b2b4075c70..8fb81a3915990 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 984abbee71ca2..c342b2e17492e 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 5aba01ac457ff..0a393a04e8918 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 fbafa0d0e2bf8..c976ebfe2269d 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 585d50fc75c0f..3cfef1de8061a 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 553b09855cfd8..16e0735e2f46b 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); diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S index 308f29081d461..f3ead0b6ce461 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/mm/fault.c b/arch/parisc/mm/fault.c index a762864ec92e9..26fac9c671c93 100644 --- a/arch/parisc/mm/fault.c +++ b/arch/parisc/mm/fault.c @@ -140,12 +140,6 @@ 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; @@ -154,7 +148,8 @@ int fixup_exception(struct pt_regs *regs) 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/init.c b/arch/parisc/mm/init.c index 3c07d6b968772..6b3e7c6ee096e 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 a030e5ecb10b7..7cd32c0382860 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 @@ -304,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" @@ -374,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 @@ -390,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 96efd8213c1c1..709a22a3e824e 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 ba8c9bea33acb..a8bc419959ca6 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 64557742fb999..3785ef826d073 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 f4d96d277ed5b..53f8b956340f4 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 7a13bf2aa439e..fead484a8180f 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 53ab4db9e79cb..66709788429da 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 0000000000000..0424fc2bd0e0e --- /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 0000000000000..84b3d38f880ed --- /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 0000000000000..974446acce23c --- /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 6858ec9ef2958..2d4b64fcee884 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 937ad7e461196..a925fe49a73ec 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 1c03060dd0b85..554001f2e96a3 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 bb575e28042a2..fec58671a6d6e 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 0000000000000..70889d8e88500 --- /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 0000000000000..9e03328561d34 --- /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 c7bc1a0c71940..69559e970e998 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 14b6295050389..a8e4ba070104e 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 c952cd37cf6dd..25f81eea60e09 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 740553c090a37..f2dc6c09be522 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 1fb7e0e0940f0..703142ee66279 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 27fdfd7dc7c73..291454c75ddad 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 e8a0f95fb24a5..18f9b31602d0b 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 149da0f123eeb..ddefbf64f7f8b 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 04c16337268a7..d505d7c51903b 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 b05dcb40f8002..b4d05867f707c 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 f502564822971..d44bb12debb01 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 ad2e242365cca..03c9afc82436c 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 70cf09019ce54..435a319958cb1 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 e9bd89406c4cb..e50fea95a853c 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 f2b1d40334d44..40748e415adba 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 28a55c5e70998..816b9788d5f67 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 920dc77b9c43f..cd6f37386111a 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 e169cc297ea3e..45084738cf4e5 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 2f227b1345adc..e2bd9313e6320 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 0659d5bb69b89..dbd57750fc02d 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 2e441fab6d8f5..e1a961f05dcd5 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 0b8f87f79d150..c288f3c6c6378 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 ba6f2275d3f61..94f3e71750124 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 8860038055929..94a76982d214b 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 ace9c13648ce3..b5ff5f71c6b8b 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 a4fc28654b317..ee44182c63485 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 78596faadf993..f05f0d775039b 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 af93abd86d78a..a9114ec510759 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 97cffd74bf3df..44dd00ac7367f 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 232c5c277bdbf..5b1b84b58602f 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 89d64ee282b09..0e1daaef9e74b 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 7fa9260889c62..68c5ef779266a 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 3d236662bf074..605363cc1117f 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 97dc2eedd462e..1955dfa136348 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 f084dd2f0bec7..2c1476454ee01 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 bb627b3bf3db2..b8b541ff5fb03 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 821ed12225d4e..4b2cfddd1b155 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 e245f1a1e42a8..0a52ddf7cc171 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 0000000000000..0a9733cd418db --- /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 6bd842beb1dcf..29757623e5baf 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 6a3581b8e1f85..772143da367ff 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 0ccc7d03335eb..302cdd22b4bbb 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 cf194154bbdce..621f2c6ee6ad5 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 8d908e795e4db..2c138627b1b43 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 98c001019d6a3..8ec3ff45e6fc7 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 3f6d7c6a106b7..8c7ea6c05de93 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 1498d1e4aecf6..977af355b3881 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 830ea484295b8..72691ef102ee7 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 9c8e10fe04cbb..8d190e8c62cef 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 33205bf08919f..836e4c965b227 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 b81213596dbfa..fc5c4a30f7ad7 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 869f9159b4d14..ec080bd01b097 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 693d2a8fa01cd..dc9326875778c 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 c067a6533809f..9573ceada07c2 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 6e820a875621a..cc0a264b8acb3 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 83eb0fda26660..0000000000000 --- 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 d426dd3de9ef7..0000000000000 --- 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 5db3399b76b74..0000000000000 --- 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 68f0ed7626bd9..0000000000000 --- 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 433f45084e416..d70517ccc0f79 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 b73174c34fe45..bcc5902f8462a 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 925ae43b74671..303d2074ee563 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 329e710feda26..733f8bf25184f 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 2a5fdcbabcddb..87fc15bce4077 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 3be85c5f1a2a1..6f753a71fe5d9 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 f66d16ba8c589..b45190556c0ca 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 0000000000000..f91f8895fc930 --- /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 0000000000000..40ac38d3038c1 --- /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 9792a2cb9b207..0000000000000 --- 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 cadc36682bb4f..0000000000000 --- 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 2aa7d9737e43c..0000000000000 --- 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 e32207de2b77d..0000000000000 --- 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 a36e11ddaebd5..0000000000000 --- 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 db79bdee844b9..0000000000000 --- 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 0000000000000..33af5c5de105d --- /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 a4572563681c7..0000000000000 --- 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 0000000000000..045031048f8d4 --- /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 5dc6bce90a77d..bc6ff43a9889e 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 ab113198ed20d..748fc00c5e19c 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 55f106ed12bf2..ae0751ef8788f 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 ea0414d6659e0..5f08a08322385 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 849bbec80f7bb..0a7956a80a081 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 8d1c8162f0c10..d0ee6fcef8230 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 7352d3f212df9..0cea4807e26fd 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 ac07a30a79342..77d3ce05798e3 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 0000000000000..1b753f96b3744 --- /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 5f8229e24fe65..ffbafbf76b193 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 6229e6b6037b9..69fb16d7a8117 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 e8d9ef4755a49..ee655ed1ff1bc 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 d1a8d93cccfd4..44efe739b6b9b 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 840a5509b3f19..994c60a857cef 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 b118072670fb1..df4fb5faba436 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 ba42e46ea58ee..666bef4ebfae7 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 867c39b45df6c..fb9f376ae27bf 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 0000000000000..47df55e36d4fb --- /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 ef89b14655731..50ca7585abe25 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 7eac89b9f02e5..42814f0567cc4 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 e3b54dd4f7307..0bc9c284aa105 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 1cb39c96d1558..b3b0f2d020f0c 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 6c1297ec374cc..2fd1690b79d21 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 3f191f573d4f1..fd22442d30a97 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 8565c254151ab..2563c435a4b16 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 f05500a29a60d..0a566f15f9850 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 3d5abfe6ba675..8ca1c983bf6c3 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 878c277717172..4eaab40e3ade3 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 dcfcad139bccc..cd4ffd86765f3 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 c82cbf52d19ea..7808475975141 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 b9f734dd5b81c..10debb93c4a48 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 07a99e638449a..9d86c66517169 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 e34124f6fbf27..ab3d8977bacd6 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 68d73b2a7bfc9..6a8e1797f2232 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 78968c1ff9319..f5056e3394b46 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 814622146d5a1..e157489ee7a12 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 69ef28a817335..8d5fc3ac43da5 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 0000000000000..43140f8b05923 --- /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 10902c9375d09..9256979689469 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 ac2330820b9ae..009fab130cd85 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 c4cb2ffc624ea..f5f4c66bbbc91 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 e8ea346b21d38..94d01f81e6687 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 2fef74b474f0a..737e012ef56e1 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 a5e930aca8043..abf5866e08c64 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 78083ed20792f..e1afd4c4f695f 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 37d2da6feabf7..f280dd11243fe 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 5b268b6be74c7..17c8380673a60 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 2d7109a8d2961..1092fdd7e7372 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 23d351ca03034..9f77f85e3e99b 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 d12b11d7641e6..a1d112979fd28 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 254604856e69e..04ef3ae511da8 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 7f9c74b46704e..b4504f3944278 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/kernel/Makefile b/arch/powerpc/kernel/Makefile index 794f22adf99d4..2da380fcc34c6 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 07cebc3514f34..0d0183d3180a4 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 dddba3e942606..462aed9bcf512 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 9c9b7411b28bb..584e119fa8b01 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 7d80bfdfb15ee..6c662b8de90d6 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 40e4d4a276635..6544017eb90b8 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 a1e86e172e3cc..ddbcfab7efdfb 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 aabba94ff9cbd..7815095fe3d8a 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 650cfb31ea3d9..fb6207d2c604b 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 98f81800e00c1..eea48d8baf494 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 0d525ce3717fb..9916d150b28c1 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 2117eaca3d288..15da2b5df85e6 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 44d4d8eb3c85c..9dac18dabd03c 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 b5061abbd2e0c..9cdf5c71e4263 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 1b779560728f9..4286775cbde9c 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 78c1eba4c04a4..80c69472314ea 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 f705171b924b9..3bfa3150911f7 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 cf4fb5429cf12..470ceebd2d237 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 e77c3ccf8dcfe..dbf098121ce63 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 2c647b1e62e4b..ee62b197502d7 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 be8edd67f05be..bf5160fbf9d84 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 9547381b631a5..d1f1b35bf0c72 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 2c01665eb410a..5a7a78f125629 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 08b7a40de5f85..9ce9a25f58b55 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 01ea0edf0579a..93dae296b6be6 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 7f9ed0c1f6b93..59c436189f466 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 b3b4df91b792c..38102cb9baa96 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 41e1607e800ca..9f01e28ecef35 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 30ddd8a24eee9..2bfaafe5be99e 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 3c5736e52a14b..b8500b4ac7fea 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/signal.c b/arch/powerpc/kernel/signal.c index cf8c7e4e0b21b..cb64d6feb45ac 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 51b274199dd9f..be305c858e513 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 b7dea05f07259..8cac1eb414661 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 33c47fcc455ae..9229ba63c3708 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -1147,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)) @@ -1157,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; } @@ -1393,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 162d0f7149419..1c2e7a343bf5f 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 d41fd0af89807..2dd91f79de05a 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 7f7b6d86ac731..eba0bea6e032b 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 55c4d51ea3e2b..999106991a76d 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 9bf7031a67ffc..b9131aa1aedf0 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 913cd2198fa6d..114edace6cddf 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 fb37290a57b41..c7b78d8336b26 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 2c2d1030843ac..18cf6d1f81748 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 44be73e6aa26b..d461c440889aa 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 91700518bbf30..4cb8db05f3e55 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 85b32f16fa74e..e571ad277398f 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 905e94a1370f4..46871d554057a 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 778ef86e187ec..4d66f44a16578 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 cda695de8aa7b..f48a0c22e8f90 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 19aa59b0850cf..6a68730774ee7 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 a47e14277fd8a..ba21be15310f3 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 6d67e057f15ec..d90870a66b60b 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 f3ef35436612b..8e6e51016cc51 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 c7f8e95863161..c422812f74054 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 0000000000000..949100577db53 --- /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 1ffeda85c0861..adfee3f1aeb9e 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 169aba446a740..2dc74e5c64584 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 f3afe3d97f6b3..a1b2713f6e96a 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 e7c04542ba622..47d1b26effc6a 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 edb09912f0c9b..b2d659cf51c66 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 1005281be9a67..7635b1c6b5dac 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; @@ -265,28 +265,32 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend, 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, @@ -607,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 @@ -620,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 */ diff --git a/arch/powerpc/mm/hugetlbpage-hash64.c b/arch/powerpc/mm/hugetlbpage-hash64.c index e2138c7ae70fe..8555fce902fea 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 744e24bcb85c4..d991b9e80dbbc 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 c2b771614d4fe..c899fe340bbd2 100644 --- a/arch/powerpc/mm/init_32.c +++ b/arch/powerpc/mm/init_32.c @@ -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 379a6a90644be..ba655666186d9 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 f078a1f94fc26..ac79dbde1015b 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_decl.h b/arch/powerpc/mm/mmu_decl.h index 9f58ff44a0750..bfb7c0bcabd57 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 7692d1bb1bc6a..bf7bf32b54f8a 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 d9cc66cbdbb76..347106080bb1e 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; @@ -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 6b2f3e457171a..2a049fb8523d5 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 29d6987c37ba4..eb82d787d99a1 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 bb04e4df31008..f4668488512c4 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 68c477592e436..eabecfcaef7cf 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 863d89386f607..c82497a31c54f 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 d1e65ce545b31..97a1d40d8696c 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 3b09ecfd0aee2..2da41b78cb6da 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 0f9fa21a29f23..791455e7f5cf7 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 856fe6e03c2a8..7aa37236bb70b 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 5b62f23892900..a383c23a90704 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 0000000000000..741b77edd03e7 --- /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 9958ba8bf0d27..690d9186a8552 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/52xx/mpc52xx_pci.c b/arch/powerpc/platforms/52xx/mpc52xx_pci.c index 6eb3b2abae908..00282c2b0cae9 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 97915feffd42d..e626461a63bd1 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 1fe7fb95175a5..7bc86dae95176 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 949f22c86e61c..28720a4ded7ba 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 5ac70de3e48ac..d7e87ff912d7d 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 0000000000000..f05325f0cc03b --- /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 6b107cea1c08e..fe9f19e5e935f 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 e2b44933ff197..0b20ae315c539 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 ede815d6489db..2d889ad7dc89d 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 0000000000000..0f7b7fcf1ba26 --- /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 bf17933b20f32..8e63b752712c8 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 8facf5873866a..0e0be94f551fb 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 8c9058df5642d..e8292b492d7e6 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 437a9c372ae1e..957473e5c8e51 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 08efb57559d1c..53500db6b6443 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 07ccb1b0cc7de..e5084811b9c62 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 6810b71d54a79..2a9cf278c12a7 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 dfa8638767781..6ca5f0525e570 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 b290b63661f17..5ad12023e5628 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 52c6ce1cc985b..1eb7b45e017d1 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 6be1a4af33597..cc5347eb16622 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 4882bfd90e27c..1e02328c3f2d4 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 f1516b5ecec94..cd9711e72df68 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 87f47e55aab65..950b3e539057a 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 15bfbcd5debc2..fcc8b6861b63e 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 e85aa900f5c07..7229acd9bb3af 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 44ed78af1a0dd..39d6ff9e56309 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 4e0da5af94a12..0256d07292524 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 f90dc04395bf4..c5baaf3cc4e5e 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 f2bdfea3b68d0..0000000000000 --- 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 b1ef84a6c9d13..73c8dc2a353fd 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 00691a9b99af6..3f814f382b2e7 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 503a73f593599..0babef11136fc 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 20b46a19a48fc..09bf24d616a57 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 638c4060938e3..b831638e6f4a7 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/hvconsole.c b/arch/powerpc/platforms/pseries/hvconsole.c index 849b29b3e9ae0..74da18de853af 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 477290ad855e5..2415a0d31f8fd 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 36df46eaba249..6e944fc6e5f97 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 0000000000000..c658d8cf760bf --- /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 a19332a387155..52dc165c0efb6 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 bd6bd729969c8..a254824719f15 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 5e6ff38ea69f1..8ed65365be508 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 47f781059eeb6..424b67fdb57f7 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 c69e88e91459f..85729f49764fc 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 0000000000000..9259a94f70e1d --- /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 c1cd3698f534e..f5bf38b945958 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 d53407a34f328..12dd18fd47956 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 b48197ae44d0f..c1826de4e749d 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 6f99ed3967fde..aa2c186d31158 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 2a0452e364ba7..afe3c7cd395d3 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 07a8508cb7fae..942796fa47675 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 7e3e8a8338d6c..aad23e3dff2c1 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 b8045b97f4fbd..d750cc0dfe301 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 0f3da2cb2bd63..255c7eec44810 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 4d7ccac5fd1d6..22da3b34c6557 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/device.h b/arch/s390/include/asm/device.h index d8f9872b0e2dc..4a9f35e0973ff 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 e64bfcb9702f6..3249b74648896 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/mmu_context.h b/arch/s390/include/asm/mmu_context.h index e485817f7b1a9..d321469eeda73 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 9dd4cc47ddc79..e0900ddf91dd0 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/unistd.h b/arch/s390/include/uapi/asm/unistd.h index ab3aa6875a59c..4384bc797a54f 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 58bf4572d457f..62f066b5259e3 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 1a43474df541a..eaab9a7cb3be6 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 293d8b98fd525..9b59e6212d8fd 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/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S index 445657fe658cc..0f41a82863785 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 2ae54cad2b6ab..0aa0ad165d8b9 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 18c8b819b0aa9..0000000000000 --- 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 69247b4dcc43a..cace818d86eb9 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 13dab0c1645c1..a8a6765f1a519 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 73e2903370928..c7b0451397d6f 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 9fd59a7cfcd3c..871af75c69c24 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 21591ddb4c1fd..1a4512c8544ad 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 a06ce8037cec0..e595e89eac65d 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/sh/Kconfig b/arch/sh/Kconfig index 17a4f1593d656..7ed20fc3fc81b 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 89963d13f930a..5e52d5362292b 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 975a0f64ff20a..cea300362035b 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 0000000000000..bf3a166a5407f --- /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 23bc849d9c64a..6df826ee73163 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 aac452b26aa89..a319745a7b635 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/clkdev.h b/arch/sh/include/asm/clkdev.h deleted file mode 100644 index c41901465fb06..0000000000000 --- 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 78b0d0f4b24b2..1baf0ba962426 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 2ccf36c824c65..09040fd07d2ef 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 c8a4331d9b8d7..a1505956ef28b 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 222742ddc0d6a..da77a8ef4696e 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 13047a4facd2e..c001f782c5f1c 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 7db248936b60e..974bc152cc843 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 cbb7d4636ec0a..0000000000000 --- 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 3f1c18b28e8af..5d34605b58b5d 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 d77f2f6c7ff07..0b30b9dfc87f2 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 13f633add29ac..38e7860845db1 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 db88cbf9eafdc..235a4101999fe 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 bd47e9b403a5b..70a6434945ab8 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 6f3cf46b77c2c..602599d802091 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 1e7aaa5571303..f2a6959f526d3 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 e7af6a65baab9..40fa6c8adc43a 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/kmap.c b/arch/sh/mm/kmap.c index ec29e14ec5a85..bf25d7c79a2d8 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/include/asm/compat.h b/arch/sparc/include/asm/compat.h index 830502fe62b4e..6f251c4d613ef 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 9ed1f128b4d1c..4b027b1044fad 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 910c1d9af1f80..426ad75103fb5 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 47eaafad15ceb..63374c4413a85 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 7a38d6a576c5e..f089cfa249f33 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 6924bdefe1484..ce2595c894711 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 fc2df1e892cbb..f4eb630a58ed4 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 49f71fd5b56ee..1757cd6c521bc 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 ecb49cfa3be9f..c6a155c3904ec 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/stat.h b/arch/sparc/include/uapi/asm/stat.h index a232e9e1f4e51..2f0583a2c689b 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 24361b494a935..2585c1e14bccf 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 7062263d09c19..e5611cd428f11 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 a83707c83be80..51aa6e86a5f88 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 28fed53b13a0d..ffd5ff4678cf5 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 e7f652be9e61e..5057ec2e4af65 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 42efcf85f721b..33cd171d933ee 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 46a59643bb1ce..c16ef1af1843c 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 baef495c06bdb..69d75ff1c25c3 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 f3185e2b028b8..26db95b54ee94 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 4eed773a77358..3c25241fa5cbd 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 b489e97595181..fe8b8ee8e6602 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 7f41d40b7e6e8..fa8e21abb5e03 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 d89e97b374cf4..9aacb91592621 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 f1a2f688b28a3..aadd321aa05db 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 c399e7b3b0352..b6c559cbd64da 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 eb3d8e8ebc6b0..4e06750a5d295 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/net/bpf_jit_comp.c b/arch/sparc/net/bpf_jit_comp.c index 3e6e05a7c4c22..a6d9204a6a0bd 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/include/hv/drv_mpipe_intf.h b/arch/tile/include/hv/drv_mpipe_intf.h index c97e416dd963b..ff7f50f970a58 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 a506c2c289437..9247d6b562f49 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 4c017d0d2de8c..aa2b44cd8fd34 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 0e059a0101ea3..378f5d8d1ec8a 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/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index b821b13d343a7..8a6b57108ac26 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 941527e507f76..1a60e1328e2fa 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/unicore32/include/asm/mmu_context.h b/arch/unicore32/include/asm/mmu_context.h index 1cb5220afaf9d..e35632ef23c75 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/x86/Kconfig b/arch/x86/Kconfig index 3c74b549ea9a3..2dc18605831f6 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 bbe1a62efc021..b1ef9e4890847 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 f9ce75d80101c..6915ff2bd9962 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 6bd2c6c95373f..383a6f84a060f 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 ce71f9212409f..aa9e8bd163f61 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 0e0b8863a34bd..16186c18656df 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 c35fd5d6ecd26..14fa1966bf01d 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 e3531f833951b..c419389889cdd 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 4fe27e0741948..dc05f010ca9b6 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 5d1e0075ac24f..eed55c8cca4f8 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 2f202f49872b2..8be571808342b 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 b222085cccac7..97c48add33ed9 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 85c4e1cf71723..96df6a39d7e24 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 c420d89b175f0..63a0d9c8e31f7 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 05058134c4431..dc66273e610d9 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 bd55dedd7614a..fe91c25092da2 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 cb713df81180b..b30dd8154cc24 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 2e5b565adacc5..cac6d17ce5db0 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 efb2b932b7483..98df1fa8825cd 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 c854541d93ff6..6874da5f67fcf 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 1a50e09c945bd..03c3eb77bfceb 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 fdfea1511cc0e..f59618a399905 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 049ada8d4e9c9..86a9bec18dab5 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 51087c29b2c23..feb90f6730e8a 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 635e5eba0caf8..40625ca7a1909 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 0000000000000..55a3529dbf127 --- /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 9b6ad08aa51a7..041e442a3e280 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 ); diff --git a/arch/x86/events/intel/cqm.c b/arch/x86/events/intel/cqm.c index 93cb412a55792..7b5fd811ef456 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 ce7211a07c0b8..8584b90d8e0bb 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 69dd11887dd1e..6c3b7c1780c98 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 b834a3f55a015..70c93f9b03acc 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 93f6bd9bf7610..ab2bcaaebe38d 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 68155cafa8a13..ad4dc7ffffb5e 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 0899cfc8dfe8f..98f25bbafac4c 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/compat.h b/arch/x86/include/asm/compat.h index acdee09228b30..ebb102e1bbc7a 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 68e4e8258b841..3636ec06c8875 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 074b7604bd512..8f9afefd2dc5a 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 f226df0646604..39343be7d4f43 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 08b1f2f6ea50c..53748c45e4885 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 a2124343edf54..31ac8e6d9f366 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 1c6f6ac52ad0a..36b90bbfc69fa 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 f23cd8c80b1c8..38951b0fcc5a4 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 24938852db301..a4820d4df617d 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 1815b736269d1..b90e1053049bd 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 01c8b501cb6d5..b7e394485a5f2 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/mmu_context.h b/arch/x86/include/asm/mmu_context.h index bfd9b2a35a0b1..84280029cafd7 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 2da46ac16e375..5b3c9a55f51cb 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 93fb7c1cffda7..7a79ee2778b3b 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 f6192502149e5..601f1b8f9961a 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 77db5616a4739..e8c2326478c8f 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 0687c4748b8f8..97f3242e133cc 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 4432ab7f407cc..7b5efe264eff2 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 0000000000000..7b84565c916c7 --- /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 bf8b35d2035a8..fbc5e92e1ecc4 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 01bcde84d3e40..d397deb581467 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 983738ac014c6..9264476f3d578 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 9f92c180ed2fb..9d55f9b6e167c 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 5c6e4fb370f5a..4916144e3c426 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 cad82c9c2fdef..ceec86eb68e96 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 20a3de5cb3b0d..66b057306f404 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 2270e41b32fd8..d96d043777656 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/string_64.h b/arch/x86/include/asm/string_64.h index ca6ba36077054..90dbbd9666d43 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 82866697fcf18..ffae84df8a931 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 c24b4224d4392..1fde8d580a5ba 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 c0f27d7ea7ff9..a969ae607be83 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 3bcdcc84259d9..a12a047184ee4 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 8b2d4bea99627..39171b3646bba 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 513b05f15bb4f..39bca7fac0870 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 79887abcb5e1f..567de50a4c2a5 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 b1b78ffe01d06..616ebd22ef9a2 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 e75907601a41c..8c2f1ef6ca236 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 8c35df4681041..169963f471bbb 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 29fa475ec5182..a147e676fc7b3 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 222a57076039f..cefacbad15311 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/apic/Makefile b/arch/x86/kernel/apic/Makefile index 8bb12ddc5db8c..8e63ebdcbd0b4 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 531b9611c51d5..d356987a04e97 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 3b670df4ba7b4..ad59d70bcb1a6 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 624db00583f44..8f4942e2bcbb2 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 052c9c3026cce..9307f182fe304 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 0d373d7affc8d..4a8697f7d4ef8 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 97c59fd60702f..7b76eb67a9b3d 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 249461f958516..8394b3d1f94fc 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 0b445c2ff735d..ac780cad3b860 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 fcbcb2f678ca4..19f57360dfd25 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 31f0f335ed224..1dd8294fd7301 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/early_printk.c b/arch/x86/kernel/early_printk.c index 21bf92490a7b9..8a121991e5ba9 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 0b1b9abd4d5fe..8e37cc8a539ad 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 0bc3490420c55..8bd1c003942aa 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 6e8354f5a5935..b48ef35b28d4f 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 702547ce33c9c..d036cfb4495db 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 be0ebbb6d1d14..a1f0e4a5c47e3 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 37dae792dbbed..589b3193f1020 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 0f8a6bbaaa443..2af478e3fd4e2 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 ed15cd486d063..2da6ee9ae69b7 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 0f05deeff5ce2..ae703acb85c18 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 47190bd399e7e..807950860fb70 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 72cef58693c73..1d39bfbd26bb3 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 6acc9dd91f368..6707039b9032d 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 b9d99e0f82c4f..6cbab31ac23a2 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 aa52c10094755..319b08a5b6ed3 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 643dbdccf4bc9..a2065d3b3b396 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/tsc.c b/arch/x86/kernel/tsc.c index 56380440d8622..c9c4c7ce3eb23 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 5af9958cbdb6b..4c941f88d405f 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 0029644bf09c3..8efb839948e51 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 66a6581724ad2..e17a74b1d8525 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 b9b09fec173bf..0f6294376fbdc 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 5ff3485acb60b..01bd7b7a6866e 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 e1e89ee4af750..762cdf2595f99 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 443d2a57ad3d9..1a2da0e5a3732 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 c512f095cdac8..1ff4dbb73fb7a 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 58fe98a0a526c..b70df72e2b33d 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 11f76436f74f0..b431539c3714b 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 e159a8185ad9a..1d971c7553c38 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 95070386d5991..31346a3f20a5c 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 5e45c2731a5d6..ee1c8a93871c5 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 7236bd3a4c3d7..0a2c70e43bc88 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 007940faa5c63..7ce3634ab5fe6 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 a501fa25da41f..72a576752a7ec 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/insn.c b/arch/x86/lib/insn.c index 8f72b334aea03..1a416935bac98 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 cbb8ee5830ff1..2ec0b0abbfaa8 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 c9c81227ea37d..e1229ecd2a820 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 40027db991405..be110efa00966 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 f9d38a48e3c84..f98913258c639 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 9dd7e4b7fcdee..82447b3fba380 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 03898aea6e0f2..5ce1ed02f7e80 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 f8d0b5e8bdfd8..b8b6a60b32cf4 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; } @@ -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 ef05755a19006..80476878eb4ca 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 4d0b26253042d..01be9ec3bf792 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 04e2e7144beee..faec01e7a17d2 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 0000000000000..e8c474451928a --- /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 8f4cc3dfac322..fe9b9f7763616 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 4093216b37913..f2a7faf4706eb 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/nmi_int.c b/arch/x86/oprofile/nmi_int.c index 1d2e6392f5faa..0e07e0968c3a0 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 2846aaab51035..066619b0700c9 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 ea48449b2e63d..a2433817c9878 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 ad285404ea7f5..994a7df84a7bc 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 ed5b67338294f..338402b91d2e5 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 a0ac0f9c307f6..49e4dd4a1f582 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 86d0f9e08dd95..92723aeae0f96 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 ed30e79347e86..ab50ada1d56e4 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 0ae7f2ae22968..c26cf393d35aa 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 69a783689d21b..c259fb6c8f4f8 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 dccae6b0413f8..52534ec297653 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 54226de7541a7..a35cf912de432 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 2c8acbc1e9ad9..6e075afa7877b 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 cfe9a47a1e877..ee22864bbc2f7 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 9f4a775a69d6a..e421106c11cf4 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 29629397d2b3e..cb3490ecb3412 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 f446c33df1a80..4f72193939a68 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 2a4f7b1dd9170..70de5b531ba0b 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 6497111ddb549..3d7c2011b6cfe 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 83a3459bc3377..038f618fbc525 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 a351878b96bcf..114a5755b1e49 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 65c2a9a19db4d..e30cb62e33002 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 740fc757050cf..b1526b95fd43a 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 33be0b3be6e12..4f41372ce400c 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 e2386cb4e0c31..4400a43b9e28f 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 2c835e356349b..92e3e1d84c1d7 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 3cefba1fefc80..50a4147f91fb8 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 55d38cfa46c26..9e02dcaef6831 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 e02c2c6c56a57..682c895753d96 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 3e75fcf6b8362..b95964610ea7f 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/video/fbdev.c b/arch/x86/video/fbdev.c index d5644bbe8cbac..9fd24846d0943 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 abf4901c917ba..db52a7fafcc2c 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 2c261082eadf8..880862c7d9ddb 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 c913ca4f69586..478a2de543a59 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 3c6d17fd423a8..719cf291dcdf1 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 3e45aa000718a..eff224df813fd 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 cc8acc410ddb8..c3df43141e706 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 b65f59a358a22..7f8d8abf4c1ab 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 7e9464b0fc00b..e832d3e9835ef 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 709b5748a2d7e..e54189427b315 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 c4d17a34ab86c..b1f4ee8c9a223 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 cd0b9e34adc8b..cd45f9c2c4484 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/hw_breakpoint.h b/arch/xtensa/include/asm/hw_breakpoint.h new file mode 100644 index 0000000000000..dbe3053b284a4 --- /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 74fed0b4e2c2b..c38e5a732d86f 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 8e090c709046f..407606e576f89 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 83e2e4bc01ba2..d2e40d39c6158 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 4ba9f516b0e27..881a1134a4b40 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 9ad12c6171842..7be2400f745a0 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 28f33a8b7f5f5..2e69aa4b843f6 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 ee17aa842fdff..6ccbd9e38e351 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/kernel/Makefile b/arch/xtensa/kernel/Makefile index 4db730290d2dd..c31f5d5afc7d2 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 b123ace3b67c7..8e10e357ee329 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 db5c1765b4137..fe8f7e7efb9dc 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 9ed55649ac8ef..bc4f4bf050999 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 0000000000000..b35656ab7dbd1 --- /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 1c85323f01d7d..5bbfed81c97be 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 4d54b481123b6..a651f3a628eec 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 42d441f7898b9..d02fc304b31c1 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 fc25318e75ad0..332e9d635fb6f 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 e601e2fbe8e6e..0b3d296a016a3 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 d75aa1476da75..1a804a2f9a5be 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/ioremap.c b/arch/xtensa/mm/ioremap.c new file mode 100644 index 0000000000000..d89c3c5fd962d --- /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 c54505dcf4db9..c68f1e6158aa6 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 e9f65f79cf2ea..b509d1f55ed5c 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 0000000000000..4a2222979f866 --- /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 0000000000000..378163c0a7ade --- /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 0000000000000..e39fea64391e8 --- /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 0000000000000..7c5d3a22da12b --- /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 0000000000000..6e9d69caf7e69 --- /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 0000000000000..fb1f5f004c92a --- /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 f124a0a624fcb..807d25e466ec2 100644 --- a/block/bio.c +++ b/block/bio.c @@ -1339,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); @@ -1365,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); @@ -1385,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); @@ -1615,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); @@ -1658,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++; diff --git a/block/blk-core.c b/block/blk-core.c index 827f8badd143f..b60537b2c35b4 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; diff --git a/block/blk-mq-sysfs.c b/block/blk-mq-sysfs.c index 431fdda21737c..4ea4dd8a1eed5 100644 --- a/block/blk-mq-sysfs.c +++ b/block/blk-mq-sysfs.c @@ -416,12 +416,14 @@ void blk_mq_hctx_kobj_init(struct blk_mq_hw_ctx *hctx) static void blk_mq_sysfs_init(struct request_queue *q) { struct blk_mq_ctx *ctx; - int i; + int cpu; kobject_init(&q->mq_kobj, &blk_mq_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 050f7a13021ba..1699baf39b78a 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -1798,11 +1798,12 @@ 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); diff --git a/block/blk-settings.c b/block/blk-settings.c index c7bb666aafd10..331e4eee0dda0 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 dd93763057ce0..995b58d46ed10 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 e3c591dd8f19d..4a349787bc628 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -4075,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 f678c733df404..556826ac7cb48 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 d8996bbd7f128..4ff1f92f89ca0 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 5d87019410542..2c6ae2aed2c47 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 3bbdcc79a3d34..7d7a39b47c623 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/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c index d0aad06b38720..f245bf35bedb5 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 b5e54f2da53de..0d92d0f915e9a 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 0e8567846f1af..c068c829b4537 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 a37508ef66c1b..7c188472d9c27 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 2aee41655ce92..f2fd3fee588a8 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 d02fd53042a5d..56241eb341f4b 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 fbfcce3b5227e..2a8b596442975 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 f12a72428aacc..050673f0c0b3e 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/base/dd.c b/drivers/base/dd.c index c4da2df62e025..16688f50729cf 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 87b8083748885..bdf28f7dd5e86 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 272a52ebafc09..0e64a1b5e62a0 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 a1e0b9ab847a3..5fb7718f256cf 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/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c index dd73e1ff1759c..ec9d8610b25f7 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/brd.c b/drivers/block/brd.c index f7ecc287d733b..51a071e322213 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c @@ -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/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index c227fd4cad75f..7a1cf7eaa71dc 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 226eb0c9f0fb3..1fd1dccebb6bc 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/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index cc2e71d0a77f0..25824c1697c50 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -2051,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; } @@ -2068,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; } diff --git a/drivers/block/null_blk.c b/drivers/block/null_blk.c index 64a7b5971b570..cab97593ba549 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 4a876785b68cd..94a1843b0426d 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 6ca35495a5bec..28cff0d23d829 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/bus/Kconfig b/drivers/bus/Kconfig index 9a92c072a485d..d4a3a3133da54 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 577cc4bf6a9d1..a49b28378d599 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 e98d15eaa7994..1827fc4d15c1a 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/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c index 25996e2561105..795c9d9c96a6d 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 09f17eb734863..0f64d149c98dc 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 1341a94cc7793..aef87fdbd1879 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_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index 096f0cef4da14..4facc7517a6a2 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 d23368874710f..f8a483c67b077 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 eca8e019e0054..16f7d33421d8b 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 bae4be6501dfb..46869d696e4d7 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 abc80949e1ddb..e1aa210dd7aa6 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 61566bcefa533..819f5842fa660 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 fd7247deabdc3..58b5baca670c3 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 620ea323356b6..d1021e106191d 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 58f3b568e9cb9..fd160728e9902 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 18b60f4895a68..fb2e0b56d4b7f 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 ea226562bb40b..2bed26481027f 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 14b270b85fec2..10f846cc8db17 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 6f99a530ead60..61090b1146cfd 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 a7f8501cfa056..3c04b069d5b8f 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 3f5314344286e..8f35d8172909a 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 8ab8502778a28..d80bdb0a8b029 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 ca561e90a60f4..61fcf399e58ce 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 8476b570779b2..526df5ba042dd 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 f65739272779d..5771fff0ee3fd 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 e4f89e28b5ecf..3a177ade6e6cc 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 015e687ffabe1..c74ed3fd496db 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 3a228b6d4feef..464fdc4bc66b3 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 afd5891ac9e6a..fd492a5dad12b 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 8988de70a98cc..2148b4ea9f289 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 3bcd42fbb55e3..3294db3b4e4e7 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 4735de0660cc9..1f903e1f86a28 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 ded3ff4b91b9a..00e035b51c695 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 bac4553f04b85..22e4c659704e4 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 83de57aeceea5..053448e2453d7 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 f85ec8d1711fb..cd9dc925b3f85 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 5c4955e33f7a2..1abcd76b49938 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 de0b322f5f58d..d0d8ec8e1f1b0 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 7b09a265d79fc..08f65acc5d57b 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 446c2fe76dc28..9b6f2772e948f 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 4a89f7979ba07..355dd2e522c38 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 f39c25a22f430..e0817754ca3eb 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 fe7806506bf34..9e449c7b751c3 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 5ed03c8a8df9e..252188fd8bcdf 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 8e3039f0c3f95..9c0b8e6b1ab32 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 328fcfcefd8c5..883045814dac2 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 d266299dfdb1a..f8c83977c7fa8 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 89e9ca78bb947..6962ee5d1e9a8 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 6af7dce542411..ceef25b0990bb 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 850316ac88317..b1bc12c045d34 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 cf478aa9fa5d9..d56648521a958 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 37e928846ec5b..b0f76a84f1e9f 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 10224b01b97c5..d73450b60b280 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 b4db67a446c81..fb74dc1f75205 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 779b6ff0c7ad4..eb20b941154ba 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 d71d01157dbb0..4bf44a25d950d 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 6cf38dc1c9291..c9c2fd575ef7d 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 7d03fe17d66f5..d04a104ce1b4d 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 8afb40ef40ce8..329a09214d126 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 4563343b64209..f02cb41d40a44 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 8ca9673083431..b38e03da1d028 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 0aaf29da84918..14b05efa3c2ae 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 4bb1bc419b798..5cc99590f9a33 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 21db020b1f2dc..ce57227327153 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 0d40b35c557cb..c9b327e0a8dd9 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 c12f5f2e04dc1..3bd9dee618b2c 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 f0efc6feeec2b..02e18182fcb55 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 08692d74b8847..0f1f17a8f3ed3 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 c94ac5c26226d..d942f5748d08e 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 576bdb7c98b8c..2a76901bf04bf 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 11e25c992948f..b1821603b887f 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 cf08db6c130c9..5ada644e62007 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 9e9fe4b19ac47..309049d41f1ba 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 c83ae1367abc1..d920d410b51d2 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 b54da1fe73f07..b4e4d6aa26319 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 27696255486de..eaee8f099c8c5 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 28aac67e7b92b..66be2e0c82b48 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 3e0b52daa35f8..4091f3cfee19f 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 99550f25975ea..a2a8d614039da 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 049ee27d5a22e..f75e989c578ff 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 a4590956d2a28..5a264a486ad90 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 607bd48c65630..d456ee6cc3d33 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 13aabbb3acbec..f7136b94fd0ea 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 c924572fc9bc1..2531174b399ea 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 0000000000000..d44b61afa2dc5 --- /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 10dd0fdaa474b..481b2646b4964 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 b7747229db9ac..a98b98e2a9e44 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 5b82d30baf9f3..c40b1804f58ca 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 4af4eed5f89f0..42bdaa772be06 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 b552eceec2beb..95e3b3e0fa1c6 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 dc4280b85db1f..2a25f4e75f49f 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 bfbb28f450c2e..67ce7c146a6ac 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 c112ebaba70d1..f7c226ab4307d 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 0000000000000..3cd1af0af0d97 --- /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 dd5402bac6202..52a7d3959875b 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 ad413036f7c78..6dc55864979c8 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 8cc9b2868b41a..9c29080a84d83 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 983dd7dc89a79..eb551c75fba6a 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 335952db309bd..00915209e7c54 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 16d7c323db498..c9b96f318d9c8 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 da9fad8b642b8..f12d7b2bddd70 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 5ded26884f08e..3bf497c36bdf8 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 00e36192a1def..7f21421c87d6b 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 9d790bcadf25a..715e7cd94125e 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 064f3eaa39d01..6df7ff36b4161 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 6c977d3a85906..0324d8daab9bc 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 0e11e2130f97c..cda877927d43a 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 9999947694509..0627860233cbf 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 9a85a95188daa..567b31d2bfa52 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 3b09716ebda28..3d44e183aedd6 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 9326204bed9d6..28d204bb659e7 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 1e6b1da580658..2f7ce6696b6c0 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 b1741551fff2a..40e3a501a50e2 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 92275c5f2c603..cf2a37df03b15 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 841977240305d..00e6aba4b9c09 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 9766e3cb595fd..f6312c62f16bb 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 8966f8bbfd726..eea38f6ea77e9 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 13e994772dfd0..b2198aef5ed42 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 9a4d888164bb3..58e24b326a48b 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 e09f03cbf086b..952b6957233b4 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 d07374f48caf7..4e73ed5cab580 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 7cbf43beb3c68..dcb6e37f3da1e 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 2685644826a06..e0dc7e83403a9 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 b7e66c9dd9f2e..5de797e34d545 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 53e9c39f5103c..7cdb2d61f3e06 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, @@ -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), @@ -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 7f7444cbf6fcc..40bab39014915 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 981a502053396..7702d2855e9cf 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 984fc187d12ec..3cb72163a5122 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 21f3ea909fabd..a2bb12200465c 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 d9a0b5d4d47f9..ec06350c78c48 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 ff8bd23a93ec2..39c198bbcbee7 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 552f7bb15bc5b..21218987bbc3d 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 84196ecdaa12f..20c5fe92ab4ad 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 5f6833ea355d6..fc367d4b2902b 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 ac03e4fe28714..7b3d0f9759874 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 92c39f6efec82..86ee06b226bdb 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 5bebf8cb0d70f..837197db4ffbb 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 d1a29f6c10849..7a7ed075a573d 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 d048dedd8b72a..be03ed0fcb6be 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 cee062c588dec..128527b8fbeb8 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 590813871ffe2..c57cff1e17980 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 55f8e2e24ab85..ad68d463b12c6 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 0945a8852299d..d7b011c1fcf88 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 44d6a9f4f5b2f..effe3736ec6b6 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 2c0a1ea3c80c7..37562783b25e1 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 d325ed1e196bf..60aa775bd3745 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 759aaf342bea9..52302262045d4 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 957aae63e7cce..d0c6c9a2d06ae 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 1cebf253e8fd4..c2d5727481671 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 1f397cb72e89a..70993f1e88bcb 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 402d630bd531e..35fabe1a32c30 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 009bd1410cfa8..2f86e3f94efa6 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 9c7abfd951baa..cbb19a90f2d61 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 404a55edd613d..c403c66b6583d 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 e24f85cd4300f..7c9383c3c2c60 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 24d99594c0b30..627267c7ec5c0 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 ccb324d97160d..dec4eaaecc000 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 5dc5ce2179606..b1e10ffe7a443 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 0481d5d673d68..6b598c6a02136 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 044c1717b762a..d9ea22ec4e258 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 1611b036421c2..3437f734c9bf1 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 59428dbd607a8..ddefe9668863b 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 171085ab5513e..1e63c5b2d5f4c 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 d167e1efb9276..b38d71cec74c7 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 f4da52b5ca0e8..a085c3bc127c5 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 23d042aabb4f7..68021fa5ecd9a 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 20887686bdbee..84a187e55360f 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 7ba61103a6f53..2ea61debffc18 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 e32d18ba252be..63fdb790df293 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 bf117a636d239..411d3033a96e9 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 6c4c98324d3cc..43f014f858031 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 a9b176139aca8..028dd832a39f6 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 5ba2188ee99cc..91de0a0067734 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 67b8e38f4ee96..fe0c3d1693772 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 c0f7843e80e61..92d04ce2dee6b 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 86a307b17eb0a..19bfa07e24b1b 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 da0b5941c89ff..d64ec7a1b9767 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 4a24aa4bbdea5..df47ec3169c34 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 7a48e986c4c97..7ad63837694f6 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 2a3a4fe803d6d..f60fe2e344ca0 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 0000000000000..271341787e67e --- /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 d4ac96087ccd0..0deac98210392 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 0000000000000..255cafb18336a --- /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 b336a8c11e2a6..6411e132faa2b 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 9e85fcc74cc94..52c6efc537318 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 b5bcd77e8d0f5..5fcf247759ac4 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 b5cc6f66ae5df..032c658a5f5ef 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 b9bc3b8df659d..6cf9dd189a924 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 dbef218fe5ecd..1cf70f452e1e6 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 df2558350fc1d..b4e5de16e561e 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 5519b386edc02..3bc9959f71c39 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 cc739291a3ce4..88f2ce81ba559 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 660d7436ac243..82c05b55a7be8 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 5429d35343639..bc05f276f32b9 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 dab9ba88b9d6d..44777ab6fdeb3 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 222425d08ab6a..a07c31e6f26d2 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 271c09644652c..9a736d939806e 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 d7bcb7a86615f..86549e59fb42b 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 3bca438ecd19d..5e9b65278e4cc 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 65c842a21c624..74c3216dbb004 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 bd4dd2463e23c..c56efc70ac16c 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 e78755e0ef780..1fe1e8d970cf3 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 89c0609e180b1..7e5add7d77528 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 f827083defc4a..6b40eb89ae190 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 38a65c3e62fc2..88a2cab37f627 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 3269d9ef7a18a..376e59bc5fa06 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 59a7b380fbe28..fb5712141040a 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 f951f911786e0..5f8dbe640a202 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 4c7825856eabe..b87596b591b3c 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 1c25ef4056164..10a5cfeae8c5e 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 cb5607495816d..8b5a415ee14a5 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 50bf12033bbc0..39ac78c94be0f 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 0963772327476..46fee1539cc87 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 051a8a8224cd7..a145b319d1717 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 27fc733cb5b97..03d38c291de62 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 336e5b780fcb7..4dbc187272358 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 c0656e7f37b59..80239ae695272 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 bd985e72520b5..74071e45ada0d 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 683cca9ac3c46..7ca2e0f9dc2ef 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/devfreq/Kconfig b/drivers/devfreq/Kconfig index 64281bb2f6503..4de78c552251a 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 155c1464948e7..4a2c07ee66777 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 dc68744241883..6b816878e5e7a 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 debca824bed67..77c1c44009d87 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 36a7c2d89a010..aee149bdf4c03 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 76b2d390f6ec9..631c977b0da5f 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 c2f5117fd8cb0..8bf89267dc252 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 6174db80c6636..7e3e595c9f301 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/efi/arm-init.c b/drivers/firmware/efi/arm-init.c index 9e15d571b53c2..aa1f743152a2f 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 2cd37dad67a63..3a69ed5ecfcb5 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 10e6774ab2a22..096adcbcb5a99 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 22c5285f77050..75feb3f5829ba 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 ad077944aa0ec..da99bbb74aebd 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 4deb3e7faa0ea..414deb85c2e52 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 495ebd657e380..6f42be4d0084f 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 e0e6b74fef8f7..a90f6459f5c6d 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 5ed3d3f381663..ee49cd23ee636 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 228bbf9104613..de6953039af65 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 7f2ea21c730dd..0ac594c0a234c 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 f25cd79c8a79f..11bfee8b79a9f 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 fedbff55a7f38..815c4a5cae543 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/gpio-menz127.c b/drivers/gpio/gpio-menz127.c index a68e199d579d5..c5c9599a3a71b 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-xgene.c b/drivers/gpio/gpio-xgene.c index c0aa387664bf5..0dc916191689e 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/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 8ae7ab68cb978..f2a74d0b68ae6 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 61766dec6a8d3..6eb94fc561dc2 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 0000000000000..ca77ec10147c4 --- /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 0000000000000..8363cb57915b0 --- /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 341dc560acbbf..7af83f142b4b8 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 0000000000000..bccf47b638991 --- /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 20c9539abc36e..c7fcdcedaadbf 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 5e7770f9a415b..62a778012fe06 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 0000000000000..d6b0bff510aaa --- /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 0000000000000..f6e32a6391074 --- /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 84d68d658f8a0..32809f749903c 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 a8be765542e64..de530f68d4e39 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 9416e0f5c1db2..84b0ce39ee14d 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 0ebb959ea4358..9e1442053fe4f 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 3c895863fcf50..0020a0ea43ffb 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 f82a2dd83874d..eacd810fc09b1 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 7a4b101e10c63..6043dc7c3a94d 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 b882e8175615f..9392e50a7ba48 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 17d1fb12128a2..17e13621fae96 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 51bfc114584ed..612117478b570 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 1846d65b72859..3fb405b3a6145 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 9ef1db87cf260..f1e17d60055a4 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 3671f9f220bd4..d81f1f4883a6c 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 d20c2a8929cbd..fa6a27bff298b 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 9e25edafa7210..8443cea6821ad 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 f594cfaa97e51..762cfdb851474 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 0000000000000..9c9b19e2f353b --- /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 e23843f4d877b..598eb0cd5aab6 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 d4e2780c07966..9f4a45cd2aab8 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 fdc1be8550da6..8d432e6901af5 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 b8fbbd7699e45..5b6639faa731e 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 5107fb291bdbe..acc08018c6cc1 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 95a4a25d8df9e..ff9597ce268c6 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 3cb6d6c413c71..e9c6ae6ed2f73 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 59f735a933a93..be6388f73ba27 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 d1f234dd21261..972eed2ef787e 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 ca72a2e487b9b..8bf84efafb049 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 438c052546955..0000000000000 --- 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 1caaf201b708a..0000000000000 --- 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 181ce39ef5e59..c48b4fce5e57a 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 4865615e9c066..05a53f4fc3349 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 8f9834ab1bd5a..26a5f4acf5840 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 1cbb16e153079..6f3369de232fe 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 53f987aeeacff..338da80006b66 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 1724c2c861516..9a3b449081a72 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 a745eeeb5d820..4bec0c108cea9 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 ba2da8ee59067..ef99d23701825 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 9599f7559b3dc..b6c011b836412 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 474ca02b09493..1f9109d3348bf 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 155965ed14a3b..bddc9ba114955 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 c55ecf0ea8454..d3ac3298fba8b 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 7f6d457f250a4..60d4493206dd1 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 093599aba64b9..6de2ce535e370 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 8e67249d4367d..e9ccc6b787f3e 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 d0e128c248134..e56b55d8c2802 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 e35340afd3db1..b336c918d6a79 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 06602df707f86..bb8709066fd87 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 7086ac17abee1..f0c7b35964809 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 b8060795b27b9..05b0353d38800 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 3efd45546241a..02deb32294056 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 090486c182497..52ee08193295f 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 2cf50180cc51b..6e0a86a563f3e 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 ad54c46751b00..8c8ca98dd1298 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 361c49a823230..083893dd68c06 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 fbd3767671bb9..cb463753115b8 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 57f1c5bf3bf19..16476d80f475a 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 0b365b7651ffb..d49379145ef22 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 a822edacfa95c..c7e885bcfd417 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 d662fa9f9091a..ce468ee5da2a7 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 0d14d108a6c4a..1c120efa292ce 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 d98aa9d82fa19..ace49976f7be0 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 d2b49c026cf68..07ac724e3ec90 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 c34c393e9aea0..d5e19b5fbbfb0 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 ca8410e8683d3..850a5623661f8 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 a902ae0373983..ac005796b71c1 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 496360eb3fba2..50e8933251410 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 dbf7e6413cab4..04e4090666fb2 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 dc52ea0df4b41..d3ccf5a86de03 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 0000000000000..6bea30ef3df5b --- /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 8a29307344776..c331c9fe7b81c 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 9d4347dd61254..dfe78799100d7 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 aec38fc3834f9..ab84d49472477 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 0000000000000..d21c6b14662f3 --- /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 888250b33ea89..a09d9f352871e 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 e195bf59da861..043e6ebab5757 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 589599f66fcce..9d2290044708d 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 6b52c78cb4048..56856a2864d10 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 cf01177ca3b5e..5682490337e3d 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 28031a7eddba6..89f31bc5b68b9 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 22e273b1c1c57..a16f7cd4c238f 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 9deadabbc81c6..72cfecc4f9f72 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 0f2d5e4bc241a..fa208ada68921 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 b7429a5278289..b10df328d58cd 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 980d3bf8ea768..0d5d8372953ee 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 49168d262cccf..f88d3bbe66712 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 34f4bef3691f8..b156481b50e8e 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 e61a3e67852e2..7255f7ddf93a2 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 91795efe13365..040d3f7cbf490 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 aeaa3dbba525c..928f5a740cba7 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 0000000000000..f49d1963fe85b --- /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 504f035d1843d..fc9e3d1dd4098 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 8cd22d9c91401..b4eb483215b17 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 8b2becd1aa079..a5ff9458d3590 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 87c78eecea649..dc115aea352bc 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 0000000000000..eaed454e043c7 --- /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 0000000000000..89dcb7bab93a0 --- /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 0000000000000..fef1b04c2aab4 --- /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