diff --git a/.gitignore b/.gitignore index 2b1e4601399f0..183499e0a8500 100644 --- a/.gitignore +++ b/.gitignore @@ -45,6 +45,7 @@ Module.symvers /boot.img /kernel.img /resource.img +/zboot.img /tags /TAGS /linux diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu index ea6a043f5beb8..50f95689ab387 100644 --- a/Documentation/ABI/testing/sysfs-devices-system-cpu +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu @@ -276,6 +276,7 @@ What: /sys/devices/system/cpu/vulnerabilities /sys/devices/system/cpu/vulnerabilities/meltdown /sys/devices/system/cpu/vulnerabilities/spectre_v1 /sys/devices/system/cpu/vulnerabilities/spectre_v2 + /sys/devices/system/cpu/vulnerabilities/spec_store_bypass Date: January 2018 Contact: Linux kernel mailing list Description: Information about CPU vulnerabilities diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs index b8d0a30f16445..f82da9bbb1fd7 100644 --- a/Documentation/ABI/testing/sysfs-fs-f2fs +++ b/Documentation/ABI/testing/sysfs-fs-f2fs @@ -101,6 +101,7 @@ Date: February 2015 Contact: "Jaegeuk Kim" Description: Controls the trimming rate in batch mode. + What: /sys/fs/f2fs//cp_interval Date: October 2015 diff --git a/Documentation/Changes b/Documentation/Changes index ec97b77c8b007..f25649ffb8929 100644 --- a/Documentation/Changes +++ b/Documentation/Changes @@ -25,7 +25,7 @@ o GNU C 3.2 # gcc --version o GNU make 3.80 # make --version o binutils 2.12 # ld -v o util-linux 2.10o # fdformat --version -o module-init-tools 0.9.10 # depmod -V +o kmod 13 # depmod -V o e2fsprogs 1.41.4 # e2fsck -V o jfsutils 1.1.3 # fsck.jfs -V o reiserfsprogs 3.6.3 # reiserfsck -V @@ -132,12 +132,6 @@ is not build with CONFIG_KALLSYMS and you have no way to rebuild and reproduce the Oops with that option, then you can still decode that Oops with ksymoops. -Module-Init-Tools ------------------ - -A new module loader is now in the kernel that requires module-init-tools -to use. It is backward compatible with the 2.4.x series kernels. - Mkinitrd -------- @@ -319,14 +313,15 @@ Util-linux ---------- o +Kmod +---- +o +o + Ksymoops -------- o -Module-Init-Tools ------------------ -o - Mkinitrd -------- o diff --git a/Documentation/device-mapper/thin-provisioning.txt b/Documentation/device-mapper/thin-provisioning.txt index 1699a55b7b709..ef639960b272d 100644 --- a/Documentation/device-mapper/thin-provisioning.txt +++ b/Documentation/device-mapper/thin-provisioning.txt @@ -112,9 +112,11 @@ $low_water_mark is expressed in blocks of size $data_block_size. If free space on the data device drops below this level then a dm event will be triggered which a userspace daemon should catch allowing it to extend the pool device. Only one such event will be sent. -Resuming a device with a new table itself triggers an event so the -userspace daemon can use this to detect a situation where a new table -already exceeds the threshold. + +No special event is triggered if a just resumed device's free space is below +the low water mark. However, resuming a device always triggers an +event; a userspace daemon should verify that free space exceeds the low +water mark when handling this event. A low water mark for the metadata device is maintained in the kernel and will trigger a dm event if free space on the metadata device drops below diff --git a/Documentation/devicetree/bindings/arm/rockchip.txt b/Documentation/devicetree/bindings/arm/rockchip.txt index d34e8fe9fca87..6833a9f7e5c32 100644 --- a/Documentation/devicetree/bindings/arm/rockchip.txt +++ b/Documentation/devicetree/bindings/arm/rockchip.txt @@ -115,17 +115,33 @@ Rockchip platforms device tree bindings Required root node properties: - compatible = "rockchip,rk3399-evb", "rockchip,rk3399"; +- Rockchip RK3399 Rock960 version ab board: + Required root node properties: + - compatible = "rockchip,rock960", "rockchip,rk3399"; + - Rockchip RK3326 f863 board: Required root node properties: - compatible = "rockchip,rk3326-863-lp3-v10", "rockchip,rk3326"; +- Rockchip RK3326 f863 avb board: + Required root node properties: + - compatible = "rockchip,rk3326-863-lp3-v10-avb", "rockchip,rk3326"; + +- Rockchip RK3326 86v board: + Required root node properties: + - compatible = "rockchip,rk3326-86v-v10", "rockchip,rk3326"; + - Rockchip RK3326 evb board: Required root node properties: - compatible = "rockchip,rk3326-evb-lp3-v10", "rockchip,rk3326"; + Or + - compatible = "rockchip,rk3326-evb-lp3-v10-linux", "rockchip,rk3326"; - Rockchip PX30 evb ddr3 board: Required root node properties: - compatible = "rockchip,px30-evb-ddr3-v10", "rockchip,px30"; + Or + - compatible = "rockchip,px30-evb-ddr3-v10-linux", "rockchip,px30"; - Rockchip PX30 evb ddr4 board: Required root node properties: diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-rockchip.txt b/Documentation/devicetree/bindings/cpufreq/cpufreq-rockchip.txt index 06b4c2f5a608f..617572aa2d152 100644 --- a/Documentation/devicetree/bindings/cpufreq/cpufreq-rockchip.txt +++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-rockchip.txt @@ -49,6 +49,8 @@ In 'operating-points-v2' table: current temperature is above reference temperature. - rockchip,pvtm-thermal-zone: A thermal zone node containing thermal sensor, it's used to get the current temperature. +- rockchip,thermal-zone: A thermal zone node containing thermal sensor, + it's used to get the current temperature. - nvmem-cells: A phandle to cpu_leakage data provided by a nvmem device. - nvmem-cell-names: Should be "cpu_leakage" diff --git a/Documentation/devicetree/bindings/display/bridge/analogix_dp.txt b/Documentation/devicetree/bindings/display/bridge/analogix_dp.txt index 4a0f4f7682ad4..797c6ded735d8 100644 --- a/Documentation/devicetree/bindings/display/bridge/analogix_dp.txt +++ b/Documentation/devicetree/bindings/display/bridge/analogix_dp.txt @@ -23,6 +23,8 @@ Required properties for dp-controller: from general PHY binding: Should be "dp". Optional properties for dp-controller: + -analogix,video-bist-enable: + Enable video bist pattern for DP_TX debugging. -force-hpd: Indicate driver need force hpd when hpd detect failed, this is used for some eDP screen which don't have hpd signal. diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,rk618.txt b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk618.txt index 112d5f57aa30a..e94ca4b90ff28 100644 --- a/Documentation/devicetree/bindings/display/rockchip/rockchip,rk618.txt +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk618.txt @@ -114,3 +114,75 @@ Example: }; }; }; + +RGB Encoder +------------ + +Required properties: +- compatible: value should be one of the following: + "rockchip,rk618-rgb" +- clocks: must include clock specifiers corresponding to entries in the + clock-names property. + See ../clocks/clock-bindings.txt for details. +- clock-names: list of clock names sorted in the same order as the clocks + property. Must contain "rgb", "dither", "vif", "scaler". + +Required nodes: + +The connections to the video ports are modeled using the OF graph +bindings specified in Documentation/devicetree/bindings/graph.txt. + +Example: + +&rk618 { + status = "okay"; + + rgb { + compatible = "rockchip,rk618-rgb"; + clocks = <&CRU RGB_CLK>, <&CRU DITHER_CLK>, + <&CRU VIF0_CLK>, <&CRU SCALER_CLK>; + clock-names = "rgb", "dither", "vif", "scaler"; + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + rgb_input_vop: endpoint@0 { + reg = <0>; + remote-endpoint = <&vop_output_rgb>; + }; + + rgb_input_vif: endpoint@1 { + reg = <1>; + remote-endpoint = <&vif_output_rgb>; + }; + + rgb_input_hdmi: endpoint@2 { + reg = <2>; + remote-endpoint = <&hdmi_output_rgb>; + }; + }; + + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + rgb_lcdc1_out_tve: endpoint@0 { + reg = <0>; + remote-endpoint = <&tve_in_rgb_lcdc1>; + }; + rgb_out_tve: endpoint@1 { + status = "disabled"; + reg = <1>; + remote-endpoint = <&tve_in_rgb>; + }; + }; + }; + }; +}; \ No newline at end of file diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip-rgb.txt b/Documentation/devicetree/bindings/display/rockchip/rockchip-rgb.txt index a53b1f6dea89f..346bfd3e3379a 100644 --- a/Documentation/devicetree/bindings/display/rockchip/rockchip-rgb.txt +++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-rgb.txt @@ -9,8 +9,9 @@ Required properties: - "rockchip,rk3308-rgb"; Optional properties: -- pinctrl-names: must contain a "lcdc" entry. -- pinctrl-0: pin control group to be used for this interface. +- pinctrl-names: the pin control state names; should contain "default" +- pinctrl-0: the default pinctrl state (active) +- pinctrl-1: the "sleep" pinctrl state The rgb has two video ports described by: Documentation/devicetree/bindings/media/video-interfaces.txt @@ -22,8 +23,6 @@ Their connections are modeled using the OF graph bindings specified in the panel described by: Documentation/devicetree/bindings/display/panel/simple-panel.txt -rgb-mode nodes described by: - Documentation/devicetree/bindings/display/panel/panel-rgb.txt Panel other required properties: - ports for remote rgb output. @@ -32,7 +31,7 @@ Example: panel: panel { compatible = "auo,b101ean01"; enable-gpios = <&gpio7 21 GPIO_ACTIVE_HIGH>; - rgb-mode = "p888"; + bus-format = ; ports { panel_in_rgb: endpoint { @@ -45,7 +44,7 @@ For Rockchip RV1108: rgb: rgb { compatible = "rockchip,rv1108-rgb"; - pinctrl-names = "lcdc"; + pinctrl-names = "default"; pinctrl-0 = <&lcdc_ctl>; ports { diff --git a/Documentation/devicetree/bindings/media/rockchip-cif.txt b/Documentation/devicetree/bindings/media/rockchip-cif.txt new file mode 100644 index 0000000000000..8494cf749a8bf --- /dev/null +++ b/Documentation/devicetree/bindings/media/rockchip-cif.txt @@ -0,0 +1,85 @@ +Rockchip SoC Camera Interface +---------------------------------------------- + +Rockchip CIF is a camera interface for the Rockchip series of SoCs +like px30, rk3288, rk312x, RV1108 to receive frame data from camera or CCIR656 encoder, +and transfer the data into system main memory by AXI bus. + +Required properties: +- compatible: value should be one of the following + "rockchip,px30-cif"; + "rockchip,rk3128-cif"; + "rockchip,rk3288-cif"; +- reg : offset and length of the register set for the device. +- interrupts: should contain cif interrupt. +- clocks: phandle to the required clocks. +- clock-names: required clock name. + +Optional properties: +- iommus: iommu node attached to cif if exist. +- resets: CRU reset of cif if exist. + +port node +------------------- + +The device node should contain one 'port' child node with child 'endpoint' +nodes, according to the bindings defined in Documentation/devicetree/bindings/ +media/video-interfaces.txt. + +- endpoint(parallel): + - remote-endpoint: Connecting to a sensor with a parallel video bus. + - parallel_bus properties: Refer to Documentation/devicetree/bindings/ + media/video-interfaces.txt. + +The port node must contain at least one endpoint. +It could have multiple endpoints, but please note the hardware don't support +two sensors work at a time, they are supposed to work asynchronously. + +Device node example +------------------- + + cif: cif@ff490000 { + compatible = "rockchip,px30-cif"; + reg = <0x0 0xff490000 0x0 0x200>; + interrupts = ; + clocks = <&cru ACLK_CIF>, <&cru HCLK_CIF>, <&cru PCLK_CIF>, <&cru SCLK_CIF_OUT>; + clock-names = "aclk_cif", "hclk_cif", "pclk_cif", "cif_out"; + resets = <&cru SRST_CIF_A>, <&cru SRST_CIF_H>, <&cru SRST_CIF_PCLKIN>; + reset-names = "rst_cif_a", "rst_cif_h", "rst_cif_pclkin"; + power-domains = <&power PX30_PD_VI>; + iommus = <&vip_mmu>; + status = "okay"; + port { + cif_in: endpoint { + remote-endpoint = <&gc2155_out>; + vsync-active = <0>; + hsync-active = <1>; + }; + }; + }; + + cif: cif@1010a000 { + compatible = "rockchip,rk3128-cif"; + reg = <0x1010a000 0x200>; + + clocks = <&cru ACLK_CIF>, <&cru HCLK_CIF>, + <&cru SCLK_CIF_OUT>; + clock-names = "aclk_cif", "hclk_cif", + "sclk_cif_out"; + resets = <&cru SRST_CIF0>; + reset-names = "rst_cif"; + interrupts = ; + /* px3se has not iommu attached */ + /* iommus = <&cif_mmu>; */ + power-domains = <&power RK3128_PD_VIO>; + + status = "okay"; + + port { + cif_in: endpoint { + remote-endpoint = <&adv7181_out>; + vsync-active = <0>; + hsync-active = <1>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt b/Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt index 6289506dfe001..12f8f0871933e 100644 --- a/Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt +++ b/Documentation/devicetree/bindings/phy/phy-rockchip-typec.txt @@ -20,6 +20,13 @@ Required properties: <&tcphy0 1> and <&tcphy1 1> for USB3 PHY. See ./phy-bindings.txt for details. +Optional properties: + - rockchip,phy-config : A list of voltage swing(mV) and pre-emphasis + (dB) pairs. They are 3 blocks of 4 entries and + correspond to s0p0 ~ s0p3, s1p0 ~ s1p3, + s2p0 ~ s2p3, s3p0 ~ s2p3 swing and pre-emphasis + values. + Note, there are 2 type-c phys for RK3399, and they are almost identical, except these registers(description below), every register node contains 3 sections: offset, enable bit, write mask bit. @@ -62,6 +69,21 @@ Example: rockchip,external-psm = <0xe588 14 30>; rockchip,pipe-status = <0xe5c0 0 0>; rockchip,uphy-dp-sel = <0x6268 19 19>; + + rockchip,phy-config = <0x2a 0x00>, + <0x1f 0x15>, + <0x14 0x22>, + <0x02 0x2b>, + + <0x21 0x00>, + <0x12 0x15>, + <0x02 0x22>, + <0 0>, + + <0x15 0x00>, + <0x00 0x15>, + <0 0>, + <0 0>; }; tcphy1: phy@ff800000 { @@ -84,4 +106,19 @@ Example: rockchip,external-psm = <0xe594 14 30>; rockchip,pipe-status = <0xe5c0 16 16>; rockchip,uphy-dp-sel = <0x6268 3 19>; + + rockchip,phy-config = <0x2a 0x00>, + <0x1f 0x15>, + <0x14 0x22>, + <0x02 0x2b>, + + <0x21 0x00>, + <0x12 0x15>, + <0x02 0x22>, + <0 0>, + + <0x15 0x00>, + <0x00 0x15>, + <0 0>, + <0 0>; }; diff --git a/Documentation/devicetree/bindings/regulator/regulator.txt b/Documentation/devicetree/bindings/regulator/regulator.txt index 653a1237c721c..53931649e4d53 100644 --- a/Documentation/devicetree/bindings/regulator/regulator.txt +++ b/Documentation/devicetree/bindings/regulator/regulator.txt @@ -5,9 +5,8 @@ Optional properties: - regulator-min-microvolt: smallest voltage consumers may set - regulator-max-microvolt: largest voltage consumers may set - regulator-microvolt-offset: Offset applied to voltages to compensate for voltage drops -- regulator-init-microvolt: Set by bootloader or when initialising, in order to - make sure the voltage can suit the needs of all regulator consumers during - system startup. +- regulator-early-min-microvolt: minimum voltage during system startup, make sure we + select a voltage that suits the needs of all regulator consumers - regulator-min-microamp: smallest current consumers may set - regulator-max-microamp: largest current consumers may set - regulator-input-current-limit-microamp: maximum input current regulator allows diff --git a/Documentation/devicetree/bindings/rkflash/sfc.txt b/Documentation/devicetree/bindings/rkflash/sfc.txt index d8e69d76d77be..e5c2ab1534702 100644 --- a/Documentation/devicetree/bindings/rkflash/sfc.txt +++ b/Documentation/devicetree/bindings/rkflash/sfc.txt @@ -5,9 +5,11 @@ Required properties: - reg : shall contain registers location and length for data and reg. - interrupts : shall define the nand controller interrupt. - clocks : shall reference sfc controller clocks. -- clock-names : nand controller internal clock names. Shall contain : +- clock-names : sfc controller internal clock names. Shall contain : * "clk_sfc" : sfc controller clock * "hclk_sfc" : sfc ahb clock gate +- assigned-clocks : sclk preset by dts +- assigned-clock-frequency : sclk frequency, io clk = sclk/2; Examples: sfc: sfc@301c0000 { @@ -16,5 +18,7 @@ sfc: sfc@301c0000 { interrupts = ; clocks = <&clk_sfc>, <&clk_gates15 10>; clock-names = "clk_sfc", "hclk_sfc"; + assigned-clocks = <&cru SCLK_SFC>; + assigned-clock-frequency = <100000000>; status = "okay"; }; diff --git a/Documentation/devicetree/bindings/rng/rockchip,rng.txt b/Documentation/devicetree/bindings/rng/rockchip,rng.txt new file mode 100644 index 0000000000000..b184cb25113bd --- /dev/null +++ b/Documentation/devicetree/bindings/rng/rockchip,rng.txt @@ -0,0 +1,32 @@ +Rockchip Hardware Random Number Generator + +Required properties: + +- compatible : should be one of the following. + "rockchip,cryptov2-rng" for crypto v2 +- reg : Specifies base physical address and size of the registers map. +- clocks : Phandle to clock-controller plus clock-specifier pair. +- clock-names : "clk_crypto", "clk_crypto_apk", "aclk_crypto", "hclk_crypto" as a clock name. +- assigned-clocks: Main clock, should be <&cru SCLK_CRYPTO>, <&cru SCLK_CRYPTO_APK>, + <&cru ACLK_CRYPTO>, <&cru HCLK_CRYPTO> +- assigned-clock-rates : The rng core clk frequency, shall be: <150000000>, <150000000>, + <200000000>, <100000000> +- resets : Used for module reset +- reset-names : Reset names, should be "reset" +Example: + + rng: rng@ff2f0000 { + compatible = "rockchip,cryptov2-rng"; + reg = <0x0 0xff2f0000 0x0 0x4000>; + clocks = <&cru SCLK_CRYPTO>, <&cru SCLK_CRYPTO_APK>, + <&cru ACLK_CRYPTO>, <&cru HCLK_CRYPTO>; + clock-names = "clk_crypto", "clk_crypto_apk", + "aclk_crypto", "hclk_crypto"; + assigned-clocks = <&cru SCLK_CRYPTO>, <&cru SCLK_CRYPTO_APK>, + <&cru ACLK_CRYPTO>, <&cru HCLK_CRYPTO>; + assigned-clock-rates = <150000000>, <150000000>, + <200000000>, <100000000>; + resets = <&cru SRST_CRYPTO>; + reset-names = "reset"; + }; + diff --git a/Documentation/devicetree/bindings/rtc/rtc-rk-timer.txt b/Documentation/devicetree/bindings/rtc/rtc-rk-timer.txt new file mode 100644 index 0000000000000..115124f68a860 --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/rtc-rk-timer.txt @@ -0,0 +1,19 @@ +Rockchip rk timer RTC + +Required properties: +- compatible: should be: + "rockchip,rk3308-timer-rtc": for Rockchip RK3308 +- reg: base address of the timer register and length of memory mapped region. +- interrupts: should contain the interrupts for the timer +- clocks : must contain an entry for each entry in clock-names +- clock-names : must include the following entries: + "timer", "pclk" + +Example: + rk_timer_rtc: rk-timer-rtc@ff1a0020 { + compatible = "rockchip,rk3308-timer-rtc"; + reg = <0x0 0xff1a0020 0x0 0x20>; + interrupts = ; + clocks = <&cru PCLK_TIMER>, <&cru SCLK_TIMER1>; + clock-names = "pclk", "timer"; + }; diff --git a/Documentation/devicetree/bindings/sound/rockchip,multicodecs.txt b/Documentation/devicetree/bindings/sound/rockchip,multicodecs.txt index f2d1fe583695b..194bbb60d3a8b 100644 --- a/Documentation/devicetree/bindings/sound/rockchip,multicodecs.txt +++ b/Documentation/devicetree/bindings/sound/rockchip,multicodecs.txt @@ -5,12 +5,29 @@ Required properties: - rockchip,cpu: The phandle of the Rockchip I2S/PDM controller that's connected to the CODEC - rockchip,codec: The phandle of audio codecs -- rockchip,mclk-fs: Multiplication factor between stream rate and codec mclk, - applied only for the dai-link. Optional properties: - rockchip,card-name: User specified audio sound card name, one string property. - rockchip,codec-hp-det : Detect the headphone via internal codec. +- rockchip,wait-card-locked : This is a variable length array, user specified + these sound cards need to be prepared and locked, + otherwise the local slave card can be probed. + +Optional dai-link subnode properties: +- rockchip,format : CPU/CODEC common audio format. + "i2s", "right_j", "left_j" , "dsp_a" + "dsp_b", "ac97", "pdm", "msb", "lsb". +- rockchip,frame-master : Indicates dai-link frame master. + phandle to a cpu or codec subnode. +- rockchip,bitclock-master : Indicates dai-link bit clock master. + phandle to a cpu or codec subnode. +- rockchip,bitclock-inversion : bool property. Add this if the + dai-link uses bit clock inversion. +- rockchip,frame-inversion : bool property. Add this if the + dai-link uses frame clock inversion. +- rockchip,mclk-fs : Multiplication factor between stream + rate and codec mclk, applied only for + the dai-link. Example: diff --git a/Documentation/devicetree/bindings/sound/rockchip,rk3308-codec.txt b/Documentation/devicetree/bindings/sound/rockchip,rk3308-codec.txt index fbd3049d74c90..484564d912d9d 100644 --- a/Documentation/devicetree/bindings/sound/rockchip,rk3308-codec.txt +++ b/Documentation/devicetree/bindings/sound/rockchip,rk3308-codec.txt @@ -38,10 +38,21 @@ Optional properties: You need to add the property on dts: - rockchip,adc-grps-route = <3 0 2 1>; +- rockchip,delay-loopback-handle-ms: This property points out that the delay for + handling ADC after enable PAs during loopback. +- rockchip,delay-start-play-ms: This property points out the delay ms of start + playback according to different amplifier performance. +- rockchip,en-always-grps: This property will keep the needed ADCs enabled + always after enabling once. - rockchip,loopback-grp: It points out the ADC group which is the loopback used. - rockchip,no-deep-low-power: The codec will not enter deep low power mode during suspend. +- rockchip,no-hp-det: If there is no headphone on boards, we don't need to + enable headphone detection. - hp-ctl-gpios: The gpio of head phone controller. +- pa-drv-gpios: The gpio of poweramplifier controller +- rockchip,delay-pa-drv-ms: This property points out that the delay for + power on amplifier - spk-ctl-gpios: The gpio of speak controller. Example for rk3308 internal codec: @@ -56,6 +67,7 @@ acodec: acodec@ff560000 { reset-names = "acodec-reset"; rockchip,loopback-grp = <0>; hp-ctl-gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; + pa-drv-gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>; spk-ctl-gpios = <&gpio0 5 GPIO_ACTIVE_HIGH>; status = "okay"; }; diff --git a/Documentation/devicetree/bindings/sound/rockchip,spdifrx.txt b/Documentation/devicetree/bindings/sound/rockchip,spdifrx.txt new file mode 100644 index 0000000000000..db718ec8fae13 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/rockchip,spdifrx.txt @@ -0,0 +1,38 @@ +* Rockchip SPDIF Receiver + +The S/PDIF audio block is a stereo receiver that allows the +processor to receive and digital audio via an coaxial cable or +a fibre cable. + +Required properties: + +- compatible: should be one of the following: + - "rockchip,rk3308-spdifrx" +- reg: physical base address of the controller and length of memory mapped + region. +- interrupts: should contain the SPDIF interrupt. +- dmas: DMA specifiers for rx dma. See the DMA client binding, + Documentation/devicetree/bindings/dma/dma.txt +- dma-names: should be "rx" +- clocks: a list of phandle + clock-specifier pairs, one for each entry + in clock-names. +- clock-names: should contain following: + - "hclk": clock for SPDIF controller + - "mclk" : clock for SPDIF bus +- resets: a list of phandle + reset-specifer paris, one for each entry in reset-names. +- reset-names: reset names, should include "spdifrx-m". + +Example for the rk3308 SPDIF-RX controller: + +spdif_rx: spdif-rx@ff3b0000 { + compatible = "rockchip,rk3308-spdifrx"; + reg = <0x0 0xff3b0000 0x0 0x1000>; + interrupts = ; + clocks = <&cru SCLK_SPDIF_RX>, <&cru HCLK_SPDIFRX>; + clock-names = "mclk", "hclk"; + dmas = <&dmac1 14>; + dma-names = "rx"; + resets = <&cru SRST_SPDIFRX_M>; + reset-names = "spdifrx-m"; + status = "disabled"; +}; diff --git a/Documentation/devicetree/bindings/sound/rockchip,vad.txt b/Documentation/devicetree/bindings/sound/rockchip,vad.txt index 83ffa22608eb6..549a30216f835 100644 --- a/Documentation/devicetree/bindings/sound/rockchip,vad.txt +++ b/Documentation/devicetree/bindings/sound/rockchip,vad.txt @@ -16,6 +16,9 @@ Required properties: - 1: begin to store the data after vad is enabled. - 2: don't store the data. +Optional properties: +- rockchip,acodec-cfg: boolean, config acodec after voice activity detection. + Example for rk3308 VAD controller: vad: vad@ff3c0000 { diff --git a/Documentation/devicetree/bindings/sound/rockchip-i2s.txt b/Documentation/devicetree/bindings/sound/rockchip-i2s.txt index 9ebd9df63d6c8..728553f4fa278 100644 --- a/Documentation/devicetree/bindings/sound/rockchip-i2s.txt +++ b/Documentation/devicetree/bindings/sound/rockchip-i2s.txt @@ -28,6 +28,10 @@ Required properties: - rockchip,playback-channels: max playback channels, if not set, 8 channels default. - rockchip,capture-channels: max capture channels, if not set, 2 channels default. - rockchip,bclk-fs: configure the i2s bclk fs. +- rockchip,clk-trcm: tx and rx lrck/bclk common use. + - 0: both tx_lrck/bclk and rx_lrck/bclk are used + - 1: only tx_lrck/bclk is used + - 2: only rx_lrck/bclk is used - rockchip,no-dmaengine: This is a boolean property. If present, driver will do not register pcm dmaengine, only just register dai. if the dai is part of multi-dais, the property should be present. Please refer to rockchip,multidais.txt about diff --git a/Documentation/devicetree/bindings/sound/tas571x.txt b/Documentation/devicetree/bindings/sound/tas571x.txt index 0ac31d8d5ac46..b820370bce627 100644 --- a/Documentation/devicetree/bindings/sound/tas571x.txt +++ b/Documentation/devicetree/bindings/sound/tas571x.txt @@ -1,4 +1,4 @@ -Texas Instruments TAS5711/TAS5717/TAS5719 stereo power amplifiers +Texas Instruments TAS5711/TAS5717/TAS5719/TAS5731 stereo power amplifiers The codec is controlled through an I2C interface. It also has two other signals that can be wired up to GPIOs: reset (strongly recommended), and @@ -6,7 +6,7 @@ powerdown (optional). Required properties: -- compatible: "ti,tas5711", "ti,tas5717", or "ti,tas5719" +- compatible: "ti,tas5711", "ti,tas5717", "ti,tas5719", or "ti,tas5731" - reg: The I2C address of the device - #sound-dai-cells: must be equal to 0 diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt index 408639c20c8ca..31ddca7b41ebb 100644 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ b/Documentation/devicetree/bindings/usb/dwc3.txt @@ -60,6 +60,8 @@ Optional properties: register for post-silicon frame length adjustment when the fladj_30mhz_sdbnd signal is invalid or incorrect. - snps,usb3-warm-reset-on-resume-quirk: when set, need warm reset on resume. + - snps,grx-threshold-cfg: global Rx threshold config + - snps,gtx-threshold-cfg: global Tx threshold config - tx-fifo-resize: determines if the FIFO *has* to be reallocated. diff --git a/Documentation/devicetree/bindings/usb/rockchip-usb.txt b/Documentation/devicetree/bindings/usb/rockchip-usb.txt index e014cbc7388df..ace71f3941510 100644 --- a/Documentation/devicetree/bindings/usb/rockchip-usb.txt +++ b/Documentation/devicetree/bindings/usb/rockchip-usb.txt @@ -23,6 +23,10 @@ Optional properties: from PMIC. - rockchip,hc-halt-quirk: when set, force to halt a host channel even if it's used for a non-split periodic transfer. + - rockchip,high-bandwidth: If present, support high bandwidth + endpoints. + - rockchip,usb-pd-off: when set, support turning off usb pd at + PM suspend. Example: - RK3288 diff --git a/Documentation/devicetree/bindings/usb/usb-ehci.txt b/Documentation/devicetree/bindings/usb/usb-ehci.txt index a12d6012a40fd..11ff62e0de2d6 100644 --- a/Documentation/devicetree/bindings/usb/usb-ehci.txt +++ b/Documentation/devicetree/bindings/usb/usb-ehci.txt @@ -15,6 +15,7 @@ Optional properties: - needs-reset-on-resume : boolean, set this to force EHCI reset after resume - has-transaction-translator : boolean, set this if EHCI have a Transaction Translator built into the root hub. + - rockchip-has-usic : boolean, set this if EHCI use usic phy. - clocks : a list of phandle + clock specifier pairs - phys : phandle + phy specifier pair - phy-names : "usb" diff --git a/Documentation/filesystems/f2fs.txt b/Documentation/filesystems/f2fs.txt index 1f52baea2f698..ecccb51c7279a 100644 --- a/Documentation/filesystems/f2fs.txt +++ b/Documentation/filesystems/f2fs.txt @@ -180,13 +180,15 @@ whint_mode=%s Control which write hints are passed down to block passes down hints with its policy. alloc_mode=%s Adjust block allocation policy, which supports "reuse" and "default". -fsync_mode=%s Control the policy of fsync. Currently supports "posix" - and "strict". In "posix" mode, which is default, fsync - will follow POSIX semantics and does a light operation - to improve the filesystem performance. In "strict" mode, - fsync will be heavy and behaves in line with xfs, ext4 - and btrfs, where xfstest generic/342 will pass, but the - performance will regress. +fsync_mode=%s Control the policy of fsync. Currently supports "posix", + "strict", and "nobarrier". In "posix" mode, which is + default, fsync will follow POSIX semantics and does a + light operation to improve the filesystem performance. + In "strict" mode, fsync will be heavy and behaves in line + with xfs, ext4 and btrfs, where xfstest generic/342 will + pass, but the performance will regress. "nobarrier" is + based on "posix", but doesn't issue flush command for + non-atomic files likewise "nobarrier" mount option. test_dummy_encryption Enable dummy encryption, which provides a fake fscrypt context. The fake fscrypt context is used by xfstests. diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index fe5a4133dd5e9..f93b9c5d1ac02 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -653,7 +653,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted. clearcpuid=BITNUM [X86] Disable CPUID feature X for the kernel. See - arch/x86/include/asm/cpufeature.h for the valid bit + arch/x86/include/asm/cpufeatures.h for the valid bit numbers. Note the Linux specific bits are not necessarily stable over kernel options, but the vendor specific ones should be. @@ -2520,6 +2520,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted. allow data leaks with this option, which is equivalent to spectre_v2=off. + nospec_store_bypass_disable + [HW] Disable all mitigations for the Speculative Store Bypass vulnerability + noxsave [BUGS=X86] Disables x86 extended register state save and restore using xsave. The kernel will fallback to enabling legacy floating-point and sse state. @@ -3693,6 +3696,48 @@ bytes respectively. Such letter suffixes can also be entirely omitted. Not specifying this option is equivalent to spectre_v2=auto. + spec_store_bypass_disable= + [HW] Control Speculative Store Bypass (SSB) Disable mitigation + (Speculative Store Bypass vulnerability) + + Certain CPUs are vulnerable to an exploit against a + a common industry wide performance optimization known + as "Speculative Store Bypass" in which recent stores + to the same memory location may not be observed by + later loads during speculative execution. The idea + is that such stores are unlikely and that they can + be detected prior to instruction retirement at the + end of a particular speculation execution window. + + In vulnerable processors, the speculatively forwarded + store can be used in a cache side channel attack, for + example to read memory to which the attacker does not + directly have access (e.g. inside sandboxed code). + + This parameter controls whether the Speculative Store + Bypass optimization is used. + + on - Unconditionally disable Speculative Store Bypass + off - Unconditionally enable Speculative Store Bypass + auto - Kernel detects whether the CPU model contains an + implementation of Speculative Store Bypass and + picks the most appropriate mitigation. If the + CPU is not vulnerable, "off" is selected. If the + CPU is vulnerable the default mitigation is + architecture and Kconfig dependent. See below. + prctl - Control Speculative Store Bypass per thread + via prctl. Speculative Store Bypass is enabled + for a process by default. The state of the control + is inherited on fork. + seccomp - Same as "prctl" above, but all seccomp threads + will disable SSB unless they explicitly opt out. + + Not specifying this option is equivalent to + spec_store_bypass_disable=auto. + + Default mitigations: + X86: If CONFIG_SECCOMP=y "seccomp", otherwise "prctl" + spia_io_base= [HW,MTD] spia_fio_base= spia_pedr= diff --git a/Documentation/media/uapi/v4l/meta-formats.rst b/Documentation/media/uapi/v4l/meta-formats.rst new file mode 100644 index 0000000000000..386feadbd1c35 --- /dev/null +++ b/Documentation/media/uapi/v4l/meta-formats.rst @@ -0,0 +1,15 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _meta-formats: + +**************** +Metadata Formats +**************** + +These formats are used for the :ref:`metadata` interface only. + + +.. toctree:: + :maxdepth: 1 + + pixfmt-meta-uvc diff --git a/Documentation/media/uapi/v4l/pixfmt-meta-uvc.rst b/Documentation/media/uapi/v4l/pixfmt-meta-uvc.rst new file mode 100644 index 0000000000000..b5165dc090c2f --- /dev/null +++ b/Documentation/media/uapi/v4l/pixfmt-meta-uvc.rst @@ -0,0 +1,51 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _v4l2-meta-fmt-uvc: + +******************************* +V4L2_META_FMT_UVC ('UVCH') +******************************* + +UVC Payload Header Data + + +Description +=========== + +This format describes standard UVC metadata, extracted from UVC packet headers +and provided by the UVC driver through metadata video nodes. That data includes +exact copies of the standard part of UVC Payload Header contents and auxiliary +timing information, required for precise interpretation of timestamps, contained +in those headers. See section "2.4.3.3 Video and Still Image Payload Headers" of +the "UVC 1.5 Class specification" for details. + +Each UVC payload header can be between 2 and 12 bytes large. Buffers can +contain multiple headers, if multiple such headers have been transmitted by the +camera for the respective frame. However, the driver may drop headers when the +buffer is full, when they contain no useful information (e.g. those without the +SCR field or with that field identical to the previous header), or generally to +perform rate limiting when the device sends a large number of headers. + +Each individual block contains the following fields: + +.. flat-table:: UVC Metadata Block + :widths: 1 4 + :header-rows: 1 + :stub-columns: 0 + + * - Field + - Description + * - __u64 ts; + - system timestamp in host byte order, measured by the driver upon + reception of the payload + * - __u16 sof; + - USB Frame Number in host byte order, also obtained by the driver as + close as possible to the above timestamp to enable correlation between + them + * - :cspan:`1` *The rest is an exact copy of the UVC payload header:* + * - __u8 length; + - length of the rest of the block, including this field + * - __u8 flags; + - Flags, indicating presence of other standard UVC fields + * - __u8 buf[]; + - The rest of the header, possibly including UVC PTS and SCR fields diff --git a/Documentation/networking/netdev-FAQ.txt b/Documentation/networking/netdev-FAQ.txt index 0fe1c6e0dbcd5..bfc6b3e68cc40 100644 --- a/Documentation/networking/netdev-FAQ.txt +++ b/Documentation/networking/netdev-FAQ.txt @@ -168,6 +168,15 @@ A: No. See above answer. In short, if you think it really belongs in dash marker line as described in Documentation/SubmittingPatches to temporarily embed that information into the patch that you send. +Q: Are all networking bug fixes backported to all stable releases? + +A: Due to capacity, Dave could only take care of the backports for the last + 2 stable releases. For earlier stable releases, each stable branch maintainer + is supposed to take care of them. If you find any patch is missing from an + earlier stable branch, please notify stable@vger.kernel.org with either a + commit ID or a formal patch backported, and CC Dave and other relevant + networking developers. + Q: Someone said that the comment style and coding convention is different for the networking content. Is this true? diff --git a/Documentation/printk-formats.txt b/Documentation/printk-formats.txt index b784c270105f4..ed6f6abaad577 100644 --- a/Documentation/printk-formats.txt +++ b/Documentation/printk-formats.txt @@ -273,11 +273,10 @@ struct clk: %pC pll1 %pCn pll1 - %pCr 1560000000 For printing struct clk structures. '%pC' and '%pCn' print the name (Common Clock Framework) or address (legacy clock framework) of the - structure; '%pCr' prints the current clock rate. + structure. Passed by reference. diff --git a/Documentation/spec_ctrl.txt b/Documentation/spec_ctrl.txt new file mode 100644 index 0000000000000..32f3d55c54b75 --- /dev/null +++ b/Documentation/spec_ctrl.txt @@ -0,0 +1,94 @@ +=================== +Speculation Control +=================== + +Quite some CPUs have speculation-related misfeatures which are in +fact vulnerabilities causing data leaks in various forms even across +privilege domains. + +The kernel provides mitigation for such vulnerabilities in various +forms. Some of these mitigations are compile-time configurable and some +can be supplied on the kernel command line. + +There is also a class of mitigations which are very expensive, but they can +be restricted to a certain set of processes or tasks in controlled +environments. The mechanism to control these mitigations is via +:manpage:`prctl(2)`. + +There are two prctl options which are related to this: + + * PR_GET_SPECULATION_CTRL + + * PR_SET_SPECULATION_CTRL + +PR_GET_SPECULATION_CTRL +----------------------- + +PR_GET_SPECULATION_CTRL returns the state of the speculation misfeature +which is selected with arg2 of prctl(2). The return value uses bits 0-3 with +the following meaning: + +==== ===================== =================================================== +Bit Define Description +==== ===================== =================================================== +0 PR_SPEC_PRCTL Mitigation can be controlled per task by + PR_SET_SPECULATION_CTRL. +1 PR_SPEC_ENABLE The speculation feature is enabled, mitigation is + disabled. +2 PR_SPEC_DISABLE The speculation feature is disabled, mitigation is + enabled. +3 PR_SPEC_FORCE_DISABLE Same as PR_SPEC_DISABLE, but cannot be undone. A + subsequent prctl(..., PR_SPEC_ENABLE) will fail. +==== ===================== =================================================== + +If all bits are 0 the CPU is not affected by the speculation misfeature. + +If PR_SPEC_PRCTL is set, then the per-task control of the mitigation is +available. If not set, prctl(PR_SET_SPECULATION_CTRL) for the speculation +misfeature will fail. + +PR_SET_SPECULATION_CTRL +----------------------- + +PR_SET_SPECULATION_CTRL allows to control the speculation misfeature, which +is selected by arg2 of :manpage:`prctl(2)` per task. arg3 is used to hand +in the control value, i.e. either PR_SPEC_ENABLE or PR_SPEC_DISABLE or +PR_SPEC_FORCE_DISABLE. + +Common error codes +------------------ +======= ================================================================= +Value Meaning +======= ================================================================= +EINVAL The prctl is not implemented by the architecture or unused + prctl(2) arguments are not 0. + +ENODEV arg2 is selecting a not supported speculation misfeature. +======= ================================================================= + +PR_SET_SPECULATION_CTRL error codes +----------------------------------- +======= ================================================================= +Value Meaning +======= ================================================================= +0 Success + +ERANGE arg3 is incorrect, i.e. it's neither PR_SPEC_ENABLE nor + PR_SPEC_DISABLE nor PR_SPEC_FORCE_DISABLE. + +ENXIO Control of the selected speculation misfeature is not possible. + See PR_GET_SPECULATION_CTRL. + +EPERM Speculation was disabled with PR_SPEC_FORCE_DISABLE and caller + tried to enable it again. +======= ================================================================= + +Speculation misfeature controls +------------------------------- +- PR_SPEC_STORE_BYPASS: Speculative Store Bypass + + Invocations: + * prctl(PR_GET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, 0, 0, 0); + * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_ENABLE, 0, 0); + * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_DISABLE, 0, 0); + * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_FORCE_DISABLE, 0, 0); diff --git a/Makefile b/Makefile index 6b0c49d2d4440..c033e03a5a33a 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 4 PATCHLEVEL = 4 -SUBLEVEL = 132 +SUBLEVEL = 154 EXTRAVERSION = NAME = Blurry Fish Butt @@ -442,7 +442,9 @@ 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_KCOV CFLAGS_KASAN +export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE CFLAGS_GCOV +export CFLAGS_KASAN CFLAGS_KASAN_NOSANITIZE +export CFLAGS_KCOV export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_LDFLAGS_MODULE export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL @@ -648,6 +650,7 @@ KBUILD_CFLAGS += $(call cc-disable-warning,frame-address,) KBUILD_CFLAGS += $(call cc-disable-warning, format-truncation) KBUILD_CFLAGS += $(call cc-disable-warning, format-overflow) KBUILD_CFLAGS += $(call cc-disable-warning, int-in-bool-context) +KBUILD_CFLAGS += $(call cc-disable-warning, attribute-alias) ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE KBUILD_CFLAGS += $(call cc-option,-Oz,-Os) diff --git a/arch/alpha/include/asm/futex.h b/arch/alpha/include/asm/futex.h index f939794363ac6..56474690e6855 100644 --- a/arch/alpha/include/asm/futex.h +++ b/arch/alpha/include/asm/futex.h @@ -29,18 +29,10 @@ : "r" (uaddr), "r"(oparg) \ : "memory") -static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) +static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, + u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; pagefault_disable(); @@ -66,17 +58,9 @@ static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/alpha/include/asm/xchg.h b/arch/alpha/include/asm/xchg.h index 0ca9724597c16..7081e52291d07 100644 --- a/arch/alpha/include/asm/xchg.h +++ b/arch/alpha/include/asm/xchg.h @@ -11,6 +11,10 @@ * Atomic exchange. * Since it can be used to implement critical sections * it must clobber "memory" (also for interrupts in UP). + * + * The leading and the trailing memory barriers guarantee that these + * operations are fully ordered. + * */ static inline unsigned long @@ -18,6 +22,7 @@ ____xchg(_u8, volatile char *m, unsigned long val) { unsigned long ret, tmp, addr64; + smp_mb(); __asm__ __volatile__( " andnot %4,7,%3\n" " insbl %1,%4,%1\n" @@ -42,6 +47,7 @@ ____xchg(_u16, volatile short *m, unsigned long val) { unsigned long ret, tmp, addr64; + smp_mb(); __asm__ __volatile__( " andnot %4,7,%3\n" " inswl %1,%4,%1\n" @@ -66,6 +72,7 @@ ____xchg(_u32, volatile int *m, unsigned long val) { unsigned long dummy; + smp_mb(); __asm__ __volatile__( "1: ldl_l %0,%4\n" " bis $31,%3,%1\n" @@ -86,6 +93,7 @@ ____xchg(_u64, volatile long *m, unsigned long val) { unsigned long dummy; + smp_mb(); __asm__ __volatile__( "1: ldq_l %0,%4\n" " bis $31,%3,%1\n" @@ -127,10 +135,12 @@ ____xchg(, volatile void *ptr, unsigned long x, int size) * store NEW in MEM. Return the initial value in MEM. Success is * indicated by comparing RETURN with OLD. * - * The memory barrier should be placed in SMP only when we actually - * make the change. If we don't change anything (so if the returned - * prev is equal to old) then we aren't acquiring anything new and - * we don't need any memory barrier as far I can tell. + * The leading and the trailing memory barriers guarantee that these + * operations are fully ordered. + * + * The trailing memory barrier is placed in SMP unconditionally, in + * order to guarantee that dependency ordering is preserved when a + * dependency is headed by an unsuccessful operation. */ static inline unsigned long @@ -138,6 +148,7 @@ ____cmpxchg(_u8, volatile char *m, unsigned char old, unsigned char new) { unsigned long prev, tmp, cmp, addr64; + smp_mb(); __asm__ __volatile__( " andnot %5,7,%4\n" " insbl %1,%5,%1\n" @@ -149,8 +160,8 @@ ____cmpxchg(_u8, volatile char *m, unsigned char old, unsigned char new) " or %1,%2,%2\n" " stq_c %2,0(%4)\n" " beq %2,3f\n" - __ASM__MB "2:\n" + __ASM__MB ".subsection 2\n" "3: br 1b\n" ".previous" @@ -165,6 +176,7 @@ ____cmpxchg(_u16, volatile short *m, unsigned short old, unsigned short new) { unsigned long prev, tmp, cmp, addr64; + smp_mb(); __asm__ __volatile__( " andnot %5,7,%4\n" " inswl %1,%5,%1\n" @@ -176,8 +188,8 @@ ____cmpxchg(_u16, volatile short *m, unsigned short old, unsigned short new) " or %1,%2,%2\n" " stq_c %2,0(%4)\n" " beq %2,3f\n" - __ASM__MB "2:\n" + __ASM__MB ".subsection 2\n" "3: br 1b\n" ".previous" @@ -192,6 +204,7 @@ ____cmpxchg(_u32, volatile int *m, int old, int new) { unsigned long prev, cmp; + smp_mb(); __asm__ __volatile__( "1: ldl_l %0,%5\n" " cmpeq %0,%3,%1\n" @@ -199,8 +212,8 @@ ____cmpxchg(_u32, volatile int *m, int old, int new) " mov %4,%1\n" " stl_c %1,%2\n" " beq %1,3f\n" - __ASM__MB "2:\n" + __ASM__MB ".subsection 2\n" "3: br 1b\n" ".previous" @@ -215,6 +228,7 @@ ____cmpxchg(_u64, volatile long *m, unsigned long old, unsigned long new) { unsigned long prev, cmp; + smp_mb(); __asm__ __volatile__( "1: ldq_l %0,%5\n" " cmpeq %0,%3,%1\n" @@ -222,8 +236,8 @@ ____cmpxchg(_u64, volatile long *m, unsigned long old, unsigned long new) " mov %4,%1\n" " stq_c %1,%2\n" " beq %1,3f\n" - __ASM__MB "2:\n" + __ASM__MB ".subsection 2\n" "3: br 1b\n" ".previous" diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index 2d785f5a30418..c4ee25e88a7b0 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -479,7 +479,6 @@ config ARC_CURR_IN_REG config ARC_EMUL_UNALIGNED bool "Emulate unaligned memory access (userspace only)" - default N select SYSCTL_ARCH_UNALIGN_NO_WARN select SYSCTL_ARCH_UNALIGN_ALLOW depends on ISA_ARCOMPACT diff --git a/arch/arc/Makefile b/arch/arc/Makefile index c05ea2b542762..b9f7306412e58 100644 --- a/arch/arc/Makefile +++ b/arch/arc/Makefile @@ -14,7 +14,7 @@ endif KBUILD_DEFCONFIG := nsim_700_defconfig -cflags-y += -fno-common -pipe -fno-builtin -D__linux__ +cflags-y += -fno-common -pipe -fno-builtin -mmedium-calls -D__linux__ cflags-$(CONFIG_ISA_ARCOMPACT) += -mA7 cflags-$(CONFIG_ISA_ARCV2) += -mcpu=archs @@ -137,16 +137,3 @@ dtbs: scripts archclean: $(Q)$(MAKE) $(clean)=$(boot) - -# Hacks to enable final link due to absence of link-time branch relexation -# and gcc choosing optimal(shorter) branches at -O3 -# -# vineetg Feb 2010: -mlong-calls switched off for overall kernel build -# However lib/decompress_inflate.o (.init.text) calls -# zlib_inflate_workspacesize (.text) causing relocation errors. -# Thus forcing all exten calls in this file to be long calls -export CFLAGS_decompress_inflate.o = -mmedium-calls -export CFLAGS_initramfs.o = -mmedium-calls -ifdef CONFIG_SMP -export CFLAGS_core.o = -mmedium-calls -endif diff --git a/arch/arc/include/asm/delay.h b/arch/arc/include/asm/delay.h index d5da2115d78a6..03d6bb0f4e13a 100644 --- a/arch/arc/include/asm/delay.h +++ b/arch/arc/include/asm/delay.h @@ -17,8 +17,11 @@ #ifndef __ASM_ARC_UDELAY_H #define __ASM_ARC_UDELAY_H +#include #include /* HZ */ +extern unsigned long loops_per_jiffy; + static inline void __delay(unsigned long loops) { __asm__ __volatile__( diff --git a/arch/arc/include/asm/futex.h b/arch/arc/include/asm/futex.h index 11e1b1f3acda7..eb887dd13e748 100644 --- a/arch/arc/include/asm/futex.h +++ b/arch/arc/include/asm/futex.h @@ -73,20 +73,11 @@ #endif -static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) +static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, + u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) - return -EFAULT; - #ifndef CONFIG_ARC_HAS_LLSC preempt_disable(); /* to guarantee atomic r-m-w of futex op */ #endif @@ -118,30 +109,9 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) preempt_enable(); #endif - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: - ret = (oldval == cmparg); - break; - case FUTEX_OP_CMP_NE: - ret = (oldval != cmparg); - break; - case FUTEX_OP_CMP_LT: - ret = (oldval < cmparg); - break; - case FUTEX_OP_CMP_GE: - ret = (oldval >= cmparg); - break; - case FUTEX_OP_CMP_LE: - ret = (oldval <= cmparg); - break; - case FUTEX_OP_CMP_GT: - ret = (oldval > cmparg); - break; - default: - ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/arc/include/asm/mach_desc.h b/arch/arc/include/asm/mach_desc.h index c28e6c347b490..871f3cb16af9f 100644 --- a/arch/arc/include/asm/mach_desc.h +++ b/arch/arc/include/asm/mach_desc.h @@ -34,9 +34,7 @@ struct machine_desc { const char *name; const char **dt_compat; void (*init_early)(void); -#ifdef CONFIG_SMP void (*init_per_cpu)(unsigned int); -#endif void (*init_machine)(void); void (*init_late)(void); diff --git a/arch/arc/include/asm/page.h b/arch/arc/include/asm/page.h index 429957f1c2365..8f1145ed0046f 100644 --- a/arch/arc/include/asm/page.h +++ b/arch/arc/include/asm/page.h @@ -102,7 +102,7 @@ typedef pte_t * pgtable_t; #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) /* Default Permissions for stack/heaps pages (Non Executable) */ -#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE) +#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) #define WANT_PAGE_VIRTUAL 1 diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h index e5fec320f158e..c07d7b0a40580 100644 --- a/arch/arc/include/asm/pgtable.h +++ b/arch/arc/include/asm/pgtable.h @@ -372,7 +372,7 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, /* Decode a PTE containing swap "identifier "into constituents */ #define __swp_type(pte_lookalike) (((pte_lookalike).val) & 0x1f) -#define __swp_offset(pte_lookalike) ((pte_lookalike).val << 13) +#define __swp_offset(pte_lookalike) ((pte_lookalike).val >> 13) /* NOPs, to keep generic kernel happy */ #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) diff --git a/arch/arc/kernel/irq.c b/arch/arc/kernel/irq.c index ba17f85285cfe..dd42c6feaba5e 100644 --- a/arch/arc/kernel/irq.c +++ b/arch/arc/kernel/irq.c @@ -31,10 +31,10 @@ void __init init_IRQ(void) /* a SMP H/w block could do IPI IRQ request here */ if (plat_smp_ops.init_per_cpu) plat_smp_ops.init_per_cpu(smp_processor_id()); +#endif if (machine_desc->init_per_cpu) machine_desc->init_per_cpu(smp_processor_id()); -#endif } /* diff --git a/arch/arc/mm/cache.c b/arch/arc/mm/cache.c index 9a84cbdd44b01..017fb440bba4b 100644 --- a/arch/arc/mm/cache.c +++ b/arch/arc/mm/cache.c @@ -821,7 +821,7 @@ void flush_cache_mm(struct mm_struct *mm) void flush_cache_page(struct vm_area_struct *vma, unsigned long u_vaddr, unsigned long pfn) { - unsigned int paddr = pfn << PAGE_SHIFT; + phys_addr_t paddr = pfn << PAGE_SHIFT; u_vaddr &= PAGE_MASK; @@ -841,8 +841,9 @@ void flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long u_vaddr) { /* TBD: do we really need to clear the kernel mapping */ - __flush_dcache_page(page_address(page), u_vaddr); - __flush_dcache_page(page_address(page), page_address(page)); + __flush_dcache_page((phys_addr_t)page_address(page), u_vaddr); + __flush_dcache_page((phys_addr_t)page_address(page), + (phys_addr_t)page_address(page)); } diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 612277d81704a..2c908f4d8190e 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -382,10 +382,10 @@ define archhelp endef kernel.img: zImage - $(Q)$(srctree)/scripts/mkkrnlimg $(objtree)/arch/arm/boot/zImage $(objtree)/kernel.img >/dev/null + $(Q)scripts/mkkrnlimg $(objtree)/arch/arm/boot/zImage $(objtree)/kernel.img >/dev/null @echo ' Image: kernel.img (with zImage) is ready' ifdef CONFIG_MODULES - $(Q)$(MAKE) modules + $(Q)if [ "$(srctree)" = "$(objtree)" ]; then $(MAKE) modules; fi endif ifdef CONFIG_FB @@ -395,7 +395,7 @@ endif %.img: %.dtb kernel.img $(LOGO) $(LOGO_KERNEL) $(Q) if [ -f $(srctree)/$(LOGO) -a "$(srctree)" != "$(objtree)" ]; then cp -a $(srctree)/$(LOGO) $(objtree)/; fi $(Q) if [ -f $(srctree)/$(LOGO_KERNEL) -a "$(srctree)" != "$(objtree)" ]; then cp -a $(srctree)/$(LOGO_KERNEL) $(objtree)/; fi - $(Q)$(srctree)/scripts/resource_tool $(objtree)/arch/arm/boot/dts/$*.dtb $(LOGO) $(LOGO_KERNEL) + $(Q)scripts/resource_tool $(objtree)/arch/arm/boot/dts/$*.dtb $(LOGO) $(LOGO_KERNEL) @echo ' Image: resource.img (with $*.dtb $(LOGO) $(LOGO_KERNEL)) is ready' $(Q) if [ -x $(srctree)/scripts/mkbootimg ]; then \ $(srctree)/scripts/mkbootimg \ diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 438a703d88252..2d803866a0af9 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -524,6 +524,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \ rk3126-evb.dtb \ rk3128-fireprime.dtb \ rk3128h-box.dtb \ + rk3128h-box-avb.dtb \ rk3188-radxarock.dtb \ rk3228-evb.dtb \ rk3229-at-3nod.dtb \ @@ -565,6 +566,8 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \ rk3288-veyron-pinky.dtb \ rk3288-veyron-speedy.dtb \ rk3288-x7811-rk818-dual-dsi.dtb \ + rk3308-dot-v10-aarch32.dtb \ + rk3308-dot-rk816-v10-aarch32.dtb \ rk3308-evb-dmic-i2s-v10-aarch32.dtb \ rk3308-voice-module-board-v10-aarch32.dtb \ rk3308-voice-module-amic-mainboard-v10-aarch32.dtb \ diff --git a/arch/arm/boot/dts/am3517.dtsi b/arch/arm/boot/dts/am3517.dtsi index 5e3f5e86ffcfe..cfcbf5baba4f3 100644 --- a/arch/arm/boot/dts/am3517.dtsi +++ b/arch/arm/boot/dts/am3517.dtsi @@ -74,6 +74,11 @@ }; }; +/* Table Table 5-79 of the TRM shows 480ab000 is reserved */ +&usb_otg_hs { + status = "disabled"; +}; + &iva { status = "disabled"; }; diff --git a/arch/arm/boot/dts/am437x-sk-evm.dts b/arch/arm/boot/dts/am437x-sk-evm.dts index 63de2a1b4315e..648236c5281b9 100644 --- a/arch/arm/boot/dts/am437x-sk-evm.dts +++ b/arch/arm/boot/dts/am437x-sk-evm.dts @@ -508,6 +508,8 @@ touchscreen-size-x = <480>; touchscreen-size-y = <272>; + + wakeup-source; }; tlv320aic3106: tlv320aic3106@1b { diff --git a/arch/arm/boot/dts/bcm-cygnus.dtsi b/arch/arm/boot/dts/bcm-cygnus.dtsi index 2778533502d9b..5ce200860c893 100644 --- a/arch/arm/boot/dts/bcm-cygnus.dtsi +++ b/arch/arm/boot/dts/bcm-cygnus.dtsi @@ -110,7 +110,7 @@ reg = <0x18008000 0x100>; #address-cells = <1>; #size-cells = <0>; - interrupts = ; + interrupts = ; clock-frequency = <100000>; status = "disabled"; }; @@ -138,7 +138,7 @@ reg = <0x1800b000 0x100>; #address-cells = <1>; #size-cells = <0>; - interrupts = ; + interrupts = ; clock-frequency = <100000>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi index 0bd98cd00816c..4ef5c3410fcce 100644 --- a/arch/arm/boot/dts/da850.dtsi +++ b/arch/arm/boot/dts/da850.dtsi @@ -267,11 +267,7 @@ compatible = "ti,dm6441-gpio"; gpio-controller; reg = <0x226000 0x1000>; - interrupts = <42 IRQ_TYPE_EDGE_BOTH - 43 IRQ_TYPE_EDGE_BOTH 44 IRQ_TYPE_EDGE_BOTH - 45 IRQ_TYPE_EDGE_BOTH 46 IRQ_TYPE_EDGE_BOTH - 47 IRQ_TYPE_EDGE_BOTH 48 IRQ_TYPE_EDGE_BOTH - 49 IRQ_TYPE_EDGE_BOTH 50 IRQ_TYPE_EDGE_BOTH>; + interrupts = <42 43 44 45 46 47 48 49 50>; ti,ngpio = <144>; ti,davinci-gpio-unbanked = <0>; status = "disabled"; diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi index 399103b8e2c94..c81fb8fdc41ff 100644 --- a/arch/arm/boot/dts/imx6q.dtsi +++ b/arch/arm/boot/dts/imx6q.dtsi @@ -95,7 +95,7 @@ clocks = <&clks IMX6Q_CLK_ECSPI5>, <&clks IMX6Q_CLK_ECSPI5>; clock-names = "ipg", "per"; - dmas = <&sdma 11 7 1>, <&sdma 12 7 2>; + dmas = <&sdma 11 8 1>, <&sdma 12 8 2>; dma-names = "rx", "tx"; status = "disabled"; }; diff --git a/arch/arm/boot/dts/imx6qdl-wandboard.dtsi b/arch/arm/boot/dts/imx6qdl-wandboard.dtsi index 7a032dd84bb22..9e096d811beda 100644 --- a/arch/arm/boot/dts/imx6qdl-wandboard.dtsi +++ b/arch/arm/boot/dts/imx6qdl-wandboard.dtsi @@ -88,7 +88,6 @@ clocks = <&clks 201>; VDDA-supply = <®_2p5v>; VDDIO-supply = <®_3p3v>; - lrclk-strength = <3>; }; }; diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi index 167f77b3bd436..6963dff815dc8 100644 --- a/arch/arm/boot/dts/imx6sx.dtsi +++ b/arch/arm/boot/dts/imx6sx.dtsi @@ -1250,7 +1250,7 @@ /* non-prefetchable memory */ 0x82000000 0 0x08000000 0x08000000 0 0x00f00000>; num-lanes = <1>; - interrupts = ; + interrupts = ; clocks = <&clks IMX6SX_CLK_PCIE_REF_125M>, <&clks IMX6SX_CLK_PCIE_AXI>, <&clks IMX6SX_CLK_LVDS1_OUT>, diff --git a/arch/arm/boot/dts/px3se-evb.dts b/arch/arm/boot/dts/px3se-evb.dts index 1204818423016..a5eb2b543ca0f 100644 --- a/arch/arm/boot/dts/px3se-evb.dts +++ b/arch/arm/boot/dts/px3se-evb.dts @@ -84,6 +84,10 @@ fiq-debugger { compatible = "rockchip,fiq-debugger"; + + pinctrl-names = "default"; + pinctrl-0 = <&uart1_xfer>; + rockchip,serial-id = <1>; rockchip,wake-irq = <0>; /* If enable uart uses irq instead of fiq */ @@ -109,6 +113,45 @@ reset-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>; }; + sound-rk312x { + compatible = "simple-audio-card"; + status = "disabled"; + + simple-audio-card,format = "i2s"; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,name = "rockchip,rk312x-codec"; + simple-audio-card,cpu { + sound-dai = <&i2s_8ch>; + }; + simple-audio-card,codec { + sound-dai = <&codec>; + }; + }; + + sound-es8396 { + compatible = "simple-audio-card"; + status = "okay"; + + simple-audio-card,format = "i2s"; + simple-audio-card,name = "rockchip,es8396-codec"; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,widgets = + "Microphone", "Microphone Jack", + "Line", "Microphone Headset", + "Headphone", "Headphone Jack"; + simple-audio-card,routing = + "MIC", "Microphone Jack", + "DMIC", "Microphone Headset", + "Headphone Jack", "LOUTP", + "Headphone Jack", "ROUTN"; + simple-audio-card,cpu { + sound-dai = <&i2s_2ch>; + }; + simple-audio-card,codec { + sound-dai = <&es8396>; + }; + }; + usb_control { compatible = "rockchip,rk3126-usb-control"; @@ -141,6 +184,14 @@ vin-supply = <&vcc_io>; }; + vcc_cvbs_33: vcc-cvbs-33 { + compatible = "regulator-fixed"; + regulator-name= "vcc-cvbs-33"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&pmic_vcc_cvbs_33>; + }; + vcc_sys: vcc-sys { compatible = "regulator-fixed"; regulator-name = "vcc_sys"; @@ -169,6 +220,22 @@ vin-supply = <&vcc_io>; }; + dvdd_1v8: dvdd-1v8 { + compatible = "regulator-fixed"; + regulator-name = "dvdd-1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc_18>; + }; + + dvdd_3v3: dvdd-3v3 { + compatible = "regulator-fixed"; + regulator-name = "dvdd-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_cvbs_33>; + }; + wireless-bluetooth { compatible = "bluetooth-platdata"; @@ -231,6 +298,32 @@ }; }; +&cif_new { + status = "okay"; + + port { + cif_in: endpoint { + remote-endpoint = <&adv7181_out>; + vsync-active = <0>; + hsync-active = <1>; + }; + }; +}; + +&codec { + #sound-dai-cells = <0>; + hp-ctl-gpios = <&gpio3 20 GPIO_ACTIVE_HIGH>; + spk-ctl-gpios = <&gpio0 30 GPIO_ACTIVE_HIGH>; + spk-mute-delay = <200>; + hp-mute-delay = <100>; + spk_volume = <25>; + hp_volume = <25>; + capture_volume = <26>; + gpio_debug = <1>; + codec_hp_det = <1>; + status = "disabled"; +}; + &cpu0 { cpu-supply = <&vdd_arm>; }; @@ -285,6 +378,14 @@ mali-supply = <&vdd_log>; }; +&hevc { + status = "okay"; +}; + +&hevc_mmu { + status = "okay"; +}; + &hdmi { status = "okay"; }; @@ -411,8 +512,6 @@ regulator-name= "pmic-vcc-cvbs-33"; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; - regulator-always-on; - regulator-boot-on; regulator-state-mem { regulator-off-in-suspend; }; @@ -445,7 +544,8 @@ &i2c2 { status = "okay"; clock-frequency = <400000>; - ts@14 { + + touchscreen: ts@14 { compatible = "goodix,gt9xx"; reg = <0x14>; touch-gpio = <&gpio1 8 IRQ_TYPE_LEVEL_LOW>; @@ -457,6 +557,49 @@ tp-supply = <&pmic_vcc_tp_33>; status = "okay"; }; + + camera: adv7181@21 { + compatible = "adi,adv7181"; + reg = <0x21>; + + pinctrl-names = "default"; + pinctrl-0 = <&cif_rst>; + + dvdd-supply = <&dvdd_1v8>; + dvddio-supply = <&dvdd_3v3>; + reset-gpios = <&gpio3 11 GPIO_ACTIVE_LOW>; + + status = "okay"; + + port { + adv7181_out: endpoint { + remote-endpoint = <&cif_in>; + }; + }; + }; + + es8396: es8396@11 { + status = "okay"; + #sound-dai-cells = <0>; + compatible = "es8396"; + reg = <0x11>; + clock-names = "mclk"; + clocks = <&cru SCLK_I2S_OUT>; + spk-con-gpio = <&gpio0 30 GPIO_ACTIVE_HIGH>; + lineout-con-gpio = <&gpio3 20 GPIO_ACTIVE_HIGH>; + }; +}; + +&i2s_2ch { + pinctrl-names = "default"; + pinctrl-0 = <&i2s_bus>; + #sound-dai-cells = <0>; + status = "okay"; +}; + +&i2s_8ch { + #sound-dai-cells = <0>; + status = "disabled"; }; &pwm0 { @@ -514,7 +657,8 @@ }; &uart1 { - status = "okay"; + /* disable uart1 explicitly since fiq-debugger is on uart1 */ + status = "disabled"; }; &usb_host_ehci { @@ -537,7 +681,25 @@ status = "okay"; }; +&vpu { + status = "okay"; +}; + +&vpu_combo { + status = "okay"; +}; + +&vpu_mmu { + status = "okay"; +}; + &pinctrl { + camera { + cif_rst: cif-rst { + rockchip,pins = <3 11 RK_FUNC_GPIO &pcfg_pull_default>; + }; + }; + pmic { pmic_int_l: pmic-int-l { rockchip,pins = <1 11 RK_FUNC_GPIO &pcfg_pull_default>; diff --git a/arch/arm/boot/dts/rk3126-bnd-d708-avb.dts b/arch/arm/boot/dts/rk3126-bnd-d708-avb.dts new file mode 100644 index 0000000000000..c207c9df28dc0 --- /dev/null +++ b/arch/arm/boot/dts/rk3126-bnd-d708-avb.dts @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd + */ + +/dts-v1/; +#include "rk3126-bnd-d708.dtsi" + +/ { + model = "Rockchip RK3126 bnd-d708 board"; + compatible = "rockchip,rk3126"; +}; + +&firmware_android { + compatible = "android,firmware"; + boot_devices = "10500000.nandc"; + vbmeta { + compatible = "android,vbmeta"; + parts = "vbmeta,boot,system,vendor,dtbo"; + }; + fstab { + compatible = "android,fstab"; + vendor { + compatible = "android,vendor"; + dev = "/dev/block/by-name/vendor"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait"; + }; + }; +}; diff --git a/arch/arm/boot/dts/rk3126-bnd-d708.dts b/arch/arm/boot/dts/rk3126-bnd-d708.dts index 6428c7d5a9793..94f81e7bd0e49 100644 --- a/arch/arm/boot/dts/rk3126-bnd-d708.dts +++ b/arch/arm/boot/dts/rk3126-bnd-d708.dts @@ -1,644 +1,33 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) /* - * 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. + * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd */ /dts-v1/; -#include -#include -#include -#include -#include -#include "rk3126.dtsi" -#include "rk312x-android.dtsi" -#include "rk3126-m708-cif-sensor.dtsi" +#include "rk3126-bnd-d708.dtsi" / { model = "Rockchip RK3126 bnd-d708 board"; compatible = "rockchip,rk3126"; - - adc-keys { - compatible = "adc-keys"; - io-channels = <&saradc 2>; - io-channel-names = "buttons"; - poll-interval = <100>; - keyup-threshold-microvolt = <3300000>; - - button-up { - label = "Volume Up"; - linux,code = ; - press-threshold-microvolt = <0>; - }; - - button-down { - label = "Volume Down"; - linux,code = ; - press-threshold-microvolt = <1650000>; - }; - }; - - backlight: backlight { - compatible = "pwm-backlight"; - pwms = <&pwm0 0 25000 0>; - brightness-levels = < - 255 169 168 168 167 166 166 165 - 164 164 163 162 162 161 160 160 - 159 158 158 157 156 156 155 154 - 154 153 152 152 151 150 150 149 - 148 148 147 146 146 145 144 144 - 143 142 142 141 140 140 139 138 - 138 137 136 136 135 134 134 133 - 132 132 131 130 130 129 128 128 - 127 126 126 125 124 124 123 122 - 122 121 120 120 119 118 118 117 - 116 116 115 114 114 113 112 112 - 111 110 110 109 108 108 107 106 - 106 105 104 104 103 102 102 101 - 100 100 99 98 98 97 96 96 - 95 94 94 93 92 92 91 90 - 90 89 88 88 87 86 86 85 - 84 84 83 82 82 81 80 80 - 79 78 78 77 76 76 75 74 - 74 73 72 72 71 70 70 69 - 68 68 67 66 66 65 64 64 - 63 62 62 61 60 60 59 58 - 58 57 56 56 55 54 54 53 - 52 52 51 50 50 49 48 48 - 47 46 46 45 44 44 43 42 - 42 41 40 40 39 38 38 37 - 36 36 35 34 34 33 32 32 - 31 30 30 29 28 28 27 26 - 26 25 24 24 23 22 22 21 - 20 20 19 18 18 17 16 16 - 15 14 14 13 12 12 11 10 - 10 9 8 8 7 6 6 5 - 4 4 3 2 1 1 1 0>; - default-brightness-level = <128>; - enable-gpios = <&gpio2 RK_PB6 GPIO_ACTIVE_HIGH>; - }; - - firmware { - android { - compatible = "android,firmware"; - fstab { - compatible = "android,fstab"; - system { - compatible = "android,system"; - dev = "/dev/block/by-name/system"; - type = "ext4"; - mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; - fsmgr_flags = "wait"; - }; - vendor { - compatible = "android,vendor"; - dev = "/dev/block/by-name/vendor"; - type = "ext4"; - mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; - fsmgr_flags = "wait"; - }; - }; - }; - }; - - rockchip_headset { - compatible = "rockchip_headset"; - headset_gpio = <&gpio2 18 GPIO_ACTIVE_LOW>; - }; - - sound { - compatible = "simple-audio-card"; - simple-audio-card,format = "i2s"; - simple-audio-card,mclk-fs = <256>; - simple-audio-card,name = "rockchip,rk312x"; - simple-audio-card,cpu { - sound-dai = <&i2s_2ch>; - }; - simple-audio-card,codec { - sound-dai = <&codec>; - }; - }; - - vccadc_ref: vccadc-ref { - compatible = "regulator-fixed"; - regulator-name = "SARADC_AVDD33"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - }; - - vcc_sys: vcc-sys { - compatible = "regulator-fixed"; - regulator-name = "vcc_sys"; - regulator-min-microvolt = <4000000>; - regulator-max-microvolt = <4000000>; - regulator-always-on; - }; - - xin32k: xin32k { - compatible = "fixed-clock"; - clock-frequency = <32768>; - clock-output-names = "xin32k"; - #clock-cells = <0>; - }; - - wireless-bluetooth { - compatible = "bluetooth-platdata"; - /* wifi-bt-power-toggle; */ - - keep_wifi_power_on = <1>; - uart_rts_gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; /* GPIO1_B3 */ - pinctrl-names = "default","rts_gpio"; - pinctrl-0 = <&uart1_rts>; - pinctrl-1 = <&uart1_rts_gpio>; - BT,reset_gpio = <&gpio2 9 GPIO_ACTIVE_HIGH>; /* GPIO2_B1 */ - BT,wake_gpio = <&gpio0 27 GPIO_ACTIVE_HIGH>; /* GPIO0_D3 */ - BT,wake_host_irq = <&gpio2 21 GPIO_ACTIVE_LOW>; /* GPIO2_C5 */ - status = "okay"; - }; - - wireless-wlan { - compatible = "wlan-platdata"; - - wifi_chip_type = "rtl8723cs"; - WIFI,host_wake_irq = <&gpio2 13 GPIO_ACTIVE_HIGH>; - status = "okay"; - }; -}; - -&codec { - #sound-dai-cells = <0>; - hp-ctl-gpios = <&gpio2 17 GPIO_ACTIVE_HIGH>; - spk-ctl-gpios = <&gpio2 10 GPIO_ACTIVE_HIGH>; - spk-mute-delay = <200>; - hp-mute-delay = <100>; - is_rk3128 = <0>; - spk_volume = <25>; - hp_volume = <25>; - capture_volume = <26>; - gpio_debug = <1>; - codec_hp_det = <0>; - status = "okay"; -}; - -&cif { - status = "okay"; -}; - -&cif_sensor { - status = "okay"; -}; - -&cpu0 { - cpu-supply = <&vdd_arm>; -}; - -&dsi { - status = "okay"; - - panel@0 { - compatible = "fc,fy07018dh26d372-d", "simple-panel-dsi"; - reg = <0>; - backlight = <&backlight>; - power-supply = <&ldo6>; - power-invert; - enable-gpios = <&gpio2 RK_PC3 GPIO_ACTIVE_HIGH>; - reset-gpios = <&gpio2 RK_PC0 GPIO_ACTIVE_LOW>; - prepare-delay-ms = <20>; - reset-delay-ms = <20>; - init-delay-ms = <20>; - enable-delay-ms = <120>; - disable-delay-ms = <20>; - unprepare-delay-ms = <20>; - - width-mm = <153>; - height-mm = <85>; - - dsi,flags = <(MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | - MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_EOT_PACKET)>; - dsi,format = ; - dsi,lanes = <4>; - - panel-init-sequence = [ - 05 1e 01 01 - 15 00 02 80 47 - 15 00 02 81 40 - 15 00 02 82 04 - 15 00 02 83 77 - 15 00 02 84 0f - 15 00 02 85 70 - 15 78 02 86 70 - ]; - - display-timings { - native-mode = <&timing0>; - - timing0: timing0 { - clock-frequency = <49500000>; - hactive = <1024>; - hfront-porch = <120>; - hsync-len = <40>; - hback-porch = <120>; - vactive = <600>; - vfront-porch = <14>; - vsync-len = <4>; - vback-porch = <14>; - hsync-active = <0>; - vsync-active = <0>; - de-active = <0>; - pixelclk-active = <0>; - }; - }; - }; -}; - -&dmc { - center-supply = <&vdd_log>; -}; - -&emmc { - bus-width = <8>; - cap-mmc-highspeed; - supports-emmc; - disable-wp; - non-removable; - num-slots = <1>; - status = "okay"; -}; - -&gpu { - status = "okay"; - mali-supply = <&vdd_log>; }; -&i2c0 { - status = "okay"; - clock-frequency = <400000>; - - ts@40 { - compatible = "gslX680-d708"; - reg = <0x40>; - touch-gpio = <&gpio2 20 IRQ_TYPE_LEVEL_LOW>; - wake-gpio = <&gpio2 12 IRQ_TYPE_LEVEL_LOW>; - screen_max_x = <800>; - screen_max_y = <480>; - status = "okay"; - }; - - rk816: pmic@1a { - compatible = "rockchip,rk816"; - reg = <0x1a>; - interrupt-parent = <&gpio0>; - interrupts = <2 IRQ_TYPE_LEVEL_LOW>; - pinctrl-names = "default"; - pinctrl-0 = <&pmic_int_l>; - rockchip,system-power-controller; - wakeup-source; - gpio-controller; - #gpio-cells = <2>; - #clock-cells = <1>; - clock-output-names = "rk816-clkout1", "rk816-clkout2"; - extcon = <&u2phy>; - - vcc1-supply = <&vcc_sys>; - vcc2-supply = <&vcc_sys>; - vcc3-supply = <&vcc_sys>; - vcc4-supply = <&vcc_sys>; - vcc5-supply = <&vcc_io>; - vcc6-supply = <&vcc_sys>; - - gpio { - status = "okay"; - }; - - pwrkey { - status = "okay"; +&firmware_android { + compatible = "android,firmware"; + fstab { + compatible = "android,fstab"; + system { + compatible = "android,system"; + dev = "/dev/block/by-name/system"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait"; }; - - rtc { - status = "okay"; - }; - - battery { - compatible = "rk816-battery"; - ocv_table = < 3500 3625 3685 3697 3718 3735 3748 - 3760 3774 3788 3802 3816 3834 3853 - 3877 3908 3946 3975 4018 4071 4106>; - design_capacity = <2500>; - design_qmax = <2750>; - bat_res = <100>; - max_input_current = <1500>; - max_chrg_current = <1300>; - max_chrg_voltage = <4200>; - sleep_enter_current = <300>; - sleep_exit_current = <300>; - sleep_filter_current = <100>; - power_off_thresd = <3500>; - zero_algorithm_vol = <3850>; - max_soc_offset = <60>; - monitor_sec = <5>; - virtual_power = <0>; - power_dc2otg = <0>; - dc_det_adc = <0>; - }; - - regulators { - - vdd_arm: DCDC_REG1{ - regulator-name= "vdd_arm"; - regulator-min-microvolt = <750000>; - regulator-max-microvolt = <1500000>; - regulator-ramp-delay = <6001>; - regulator-initial-mode = <1>; - regulator-always-on; - regulator-boot-on; - regulator-state-mem { - regulator-off-in-suspend; - regulator-suspend-microvolt = <900000>; - }; - }; - - vdd_log: DCDC_REG2 { - regulator-name= "vdd_logic"; - regulator-min-microvolt = <750000>; - regulator-max-microvolt = <1500000>; - regulator-ramp-delay = <6001>; - regulator-initial-mode = <1>; - regulator-always-on; - regulator-boot-on; - regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <1000000>; - }; - }; - - vcc_ddr: DCDC_REG3 { - regulator-name = "vcc_ddr"; - regulator-always-on; - regulator-boot-on; - regulator-initial-mode = <1>; - }; - - vcc_io: DCDC_REG4 { - regulator-name = "vcc_io"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-initial-mode = <1>; - regulator-always-on; - regulator-boot-on; - regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <3000000>; - }; - }; - - vcc28_cif: LDO_REG1 { - regulator-name = "vcc28_cif"; - regulator-min-microvolt = <2800000>; - regulator-max-microvolt = <2800000>; - regulator-always-on; - regulator-boot-on; - regulator-state-mem { - regulator-off-in-suspend; - }; - }; - - vcc18_cif: LDO_REG2 { - regulator-name = "vcc18_cif"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-always-on; - regulator-boot-on; - regulator-state-mem { - regulator-off-in-suspend; - }; - }; - - vdd_11: LDO_REG3 { - regulator-name = "vdd_11"; - regulator-min-microvolt = <1100000>; - regulator-max-microvolt = <1100000>; - regulator-always-on; - regulator-boot-on; - regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <1100000>; - }; - }; - - ldo4: LDO_REG4 { - regulator-name= "ldo4"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-always-on; - regulator-boot-on; - regulator-state-mem { - regulator-off-in-suspend; - }; - }; - - ldo5: LDO_REG5 { - regulator-name= "ldo5"; - regulator-min-microvolt = <3000000>; - regulator-max-microvolt = <3000000>; - regulator-always-on; - regulator-boot-on; - regulator-state-mem { - regulator-on-in-suspend; - }; - }; - - ldo6: LDO_REG6 { - regulator-name= "ldo6"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <3300000>; - }; - }; - }; - }; - - sensor@4c { - compatible = "gs_mc3230"; - reg = <0x4c>; - type = ; - irq_enable = <0>; - poll_delay_ms = <30>; - layout = <3>; - reprobe_en = <1>; - }; -}; - -&i2s_2ch { - #sound-dai-cells = <0>; - status = "okay"; -}; - -&iep { - status = "okay"; -}; - -&iep_mmu { - status = "okay"; -}; - -&mipi_dphy { - status = "okay"; -}; - -&nandc { - status = "okay"; -}; - -&pinctrl { - lcdc { - lcdc_lcdc: lcdc-lcdc { - rockchip,pins = - /* depend on the hardware */ - <2 RK_PB0 1 &pcfg_pull_none>, /* DCLK */ - /* <2 RK_PB1 1 &pcfg_pull_none>, /* HSYNC */ - /* <2 RK_PB2 1 &pcfg_pull_none>, /* VSYNC */ - <2 RK_PB3 1 &pcfg_pull_none>, /* DEN */ - <2 RK_PB4 1 &pcfg_pull_none>, /* DATA10 */ - <2 RK_PB5 1 &pcfg_pull_none>, /* DATA11 */ - <2 RK_PB6 1 &pcfg_pull_none>, /* DATA12 */ - <2 RK_PB7 1 &pcfg_pull_none>, /* DATA13 */ - <2 RK_PC0 1 &pcfg_pull_none>, /* DATA14 */ - <2 RK_PC1 1 &pcfg_pull_none>, /* DATA15 */ - <2 RK_PC2 1 &pcfg_pull_none>, /* DATA16 */ - <2 RK_PC3 1 &pcfg_pull_none>; /* DATA17 */ - /* <2 RK_PC4 1 &pcfg_pull_none>, /* DATA18 */ - /* <2 RK_PC5 1 &pcfg_pull_none>, /* DATA19 */ - /* <2 RK_PC6 1 &pcfg_pull_none>, /* DATA20 */ - /* <2 RK_PC7 1 &pcfg_pull_none>, /* DATA21 */ - /* <2 RK_PD0 1 &pcfg_pull_none>, /* DATA22 */ - /* <2 RK_PD1 1 &pcfg_pull_none>; /* DATA23 */ - }; - }; - - pmic { - pmic_int_l: pmic-int-l { - rockchip,pins = - <0 2 RK_FUNC_GPIO &pcfg_pull_default>; + vendor { + compatible = "android,vendor"; + dev = "/dev/block/by-name/vendor"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait"; }; }; - - wireless-bluetooth { - uart1_rts_gpio: uart1-rts-gpio { - rockchip,pins = <1 11 RK_FUNC_GPIO &pcfg_pull_none>; - }; - }; -}; - -&pwm0 { - status = "okay"; -}; - -&rga { - status = "okay"; -}; - -&route_dsi { - status = "okay"; -}; - -&saradc { - status = "okay"; - vref-supply = <&vccadc_ref>; -}; - -&sdmmc { - cap-mmc-highspeed; - supports-sd; - card-detect-delay = <800>; - ignore-pm-notify; - keep-power-in-suspend; - cd-gpios = <&gpio2 7 GPIO_ACTIVE_LOW>; /* CD GPIO */ - status = "disabled"; -}; - -&sdio { - max-frequency = <50000000>; - cap-sd-highspeed; - supports-sdio; - ignore-pm-notify; - keep-power-in-suspend; - non-removable; - vmmc-supply = <&ldo5>; - status = "okay"; -}; - -&tsadc { - status = "okay"; -}; - -&u2phy { - status = "okay"; - - u2phy_otg: otg-port { - status = "okay"; - }; - - u2phy_host: host-port { - status = "okay"; - }; -}; - -&uart1 { - pinctrl-names = "default"; - pinctrl-0 = <&uart1_xfer &uart1_cts>; - status = "okay"; -}; - -&usb_otg { - status = "okay"; -}; - -&vop { - status = "okay"; -}; - -&vop_mmu { - status = "okay"; -}; - -&vpu { - status = "okay"; }; diff --git a/arch/arm/boot/dts/rk3126-bnd-d708.dtsi b/arch/arm/boot/dts/rk3126-bnd-d708.dtsi new file mode 100644 index 0000000000000..11eb72f07e94d --- /dev/null +++ b/arch/arm/boot/dts/rk3126-bnd-d708.dtsi @@ -0,0 +1,648 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd + */ + +/dts-v1/; +#include +#include +#include +#include +#include +#include "rk3126.dtsi" +#include "rk312x-android.dtsi" + +/ { + adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 2>; + io-channel-names = "buttons"; + poll-interval = <100>; + keyup-threshold-microvolt = <3300000>; + + button-up { + label = "Volume Up"; + linux,code = ; + press-threshold-microvolt = <0>; + }; + + button-down { + label = "Volume Down"; + linux,code = ; + press-threshold-microvolt = <1650000>; + }; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&pwm0 0 25000 0>; + brightness-levels = < + 255 169 168 168 167 166 166 165 + 164 164 163 162 162 161 160 160 + 159 158 158 157 156 156 155 154 + 154 153 152 152 151 150 150 149 + 148 148 147 146 146 145 144 144 + 143 142 142 141 140 140 139 138 + 138 137 136 136 135 134 134 133 + 132 132 131 130 130 129 128 128 + 127 126 126 125 124 124 123 122 + 122 121 120 120 119 118 118 117 + 116 116 115 114 114 113 112 112 + 111 110 110 109 108 108 107 106 + 106 105 104 104 103 102 102 101 + 100 100 99 98 98 97 96 96 + 95 94 94 93 92 92 91 90 + 90 89 88 88 87 86 86 85 + 84 84 83 82 82 81 80 80 + 79 78 78 77 76 76 75 74 + 74 73 72 72 71 70 70 69 + 68 68 67 66 66 65 64 64 + 63 62 62 61 60 60 59 58 + 58 57 56 56 55 54 54 53 + 52 52 51 50 50 49 48 48 + 47 46 46 45 44 44 43 42 + 42 41 40 40 39 38 38 37 + 36 36 35 34 34 33 32 32 + 31 30 30 29 28 28 27 26 + 26 25 24 24 23 22 22 21 + 20 20 19 18 18 17 16 16 + 15 14 14 13 12 12 11 10 + 10 9 8 8 7 6 6 5 + 4 4 3 2 1 1 1 0>; + default-brightness-level = <128>; + enable-gpios = <&gpio2 RK_PB6 GPIO_ACTIVE_HIGH>; + }; + + rockchip_headset { + compatible = "rockchip_headset"; + headset_gpio = <&gpio2 18 GPIO_ACTIVE_LOW>; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,name = "rockchip,rk312x"; + simple-audio-card,cpu { + sound-dai = <&i2s_2ch>; + }; + simple-audio-card,codec { + sound-dai = <&codec>; + }; + }; + + vccadc_ref: vccadc-ref { + compatible = "regulator-fixed"; + regulator-name = "SARADC_AVDD33"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + vcc_sys: vcc-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc_sys"; + regulator-min-microvolt = <4000000>; + regulator-max-microvolt = <4000000>; + regulator-always-on; + }; + + xin32k: xin32k { + compatible = "fixed-clock"; + clock-frequency = <32768>; + clock-output-names = "xin32k"; + #clock-cells = <0>; + }; + + wireless-bluetooth { + compatible = "bluetooth-platdata"; + /* wifi-bt-power-toggle; */ + + keep_wifi_power_on = <1>; + uart_rts_gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; /* GPIO1_B3 */ + pinctrl-names = "default","rts_gpio"; + pinctrl-0 = <&uart1_rts>; + pinctrl-1 = <&uart1_rts_gpio>; + BT,reset_gpio = <&gpio2 9 GPIO_ACTIVE_HIGH>; /* GPIO2_B1 */ + BT,wake_gpio = <&gpio0 27 GPIO_ACTIVE_HIGH>; /* GPIO0_D3 */ + BT,wake_host_irq = <&gpio2 21 GPIO_ACTIVE_LOW>; /* GPIO2_C5 */ + status = "okay"; + }; + + wireless-wlan { + compatible = "wlan-platdata"; + + wifi_chip_type = "rtl8723cs"; + WIFI,host_wake_irq = <&gpio2 13 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; +}; + +&codec { + #sound-dai-cells = <0>; + hp-ctl-gpios = <&gpio2 17 GPIO_ACTIVE_HIGH>; + spk-ctl-gpios = <&gpio2 10 GPIO_ACTIVE_HIGH>; + spk-mute-delay = <200>; + hp-mute-delay = <100>; + is_rk3128 = <0>; + spk_volume = <25>; + hp_volume = <25>; + capture_volume = <26>; + gpio_debug = <1>; + codec_hp_det = <0>; + status = "okay"; +}; + +&cif_new { + status = "okay"; + + ports { + port@0 { + cif_in_fcam: endpoint@0 { + remote-endpoint = <&gc0329_out>; + vsync-active = <1>; + hsync-active = <1>; + }; + + cif_in_bcam: endpoint@1 { + remote-endpoint = <&gc2145_out>; + vsync-active = <0>; + hsync-active = <1>; + }; + }; + }; +}; + +&cpu0 { + cpu-supply = <&vdd_arm>; +}; + +&dsi { + status = "okay"; + + panel@0 { + compatible = "fc,fy07018dh26d372-d", "simple-panel-dsi"; + reg = <0>; + backlight = <&backlight>; + power-supply = <&ldo6>; + power-invert; + enable-gpios = <&gpio2 RK_PC3 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio2 RK_PC0 GPIO_ACTIVE_LOW>; + prepare-delay-ms = <20>; + reset-delay-ms = <20>; + init-delay-ms = <20>; + enable-delay-ms = <120>; + disable-delay-ms = <20>; + unprepare-delay-ms = <20>; + + width-mm = <153>; + height-mm = <85>; + + dsi,flags = <(MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | + MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_EOT_PACKET)>; + dsi,format = ; + dsi,lanes = <4>; + + panel-init-sequence = [ + 05 1e 01 01 + 15 00 02 80 47 + 15 00 02 81 40 + 15 00 02 82 04 + 15 00 02 83 77 + 15 00 02 84 0f + 15 00 02 85 70 + 15 78 02 86 70 + ]; + + display-timings { + native-mode = <&timing0>; + + timing0: timing0 { + clock-frequency = <49500000>; + hactive = <1024>; + hfront-porch = <120>; + hsync-len = <40>; + hback-porch = <120>; + vactive = <600>; + vfront-porch = <14>; + vsync-len = <4>; + vback-porch = <14>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <0>; + pixelclk-active = <0>; + }; + }; + }; +}; + +&dmc { + center-supply = <&vdd_log>; +}; + +&emmc { + bus-width = <8>; + cap-mmc-highspeed; + supports-emmc; + disable-wp; + non-removable; + num-slots = <1>; + status = "okay"; +}; + +&gpu { + status = "okay"; + mali-supply = <&vdd_log>; +}; + +&i2c0 { + status = "okay"; + clock-frequency = <400000>; + + gc0329@31 { + compatible = "galaxycore,gc0329"; + reg = <0x31>; + pinctrl-names = "default"; + pinctrl-0 = <&fcam_pd>; + + clocks = <&cru SCLK_CIF_OUT>; + clock-names = "xvclk"; + + avdd-supply = <&vcc28_cif>; + dovdd-supply = <&vcc18_cif>; + dvdd-supply = <&vcc18_cif>; + + pwdn-gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_HIGH>; + + port { + gc0329_out: endpoint { + remote-endpoint = <&cif_in_fcam>; + }; + }; + }; + + gc2145@3c { + compatible = "galaxycore,gc2145"; + reg = <0x3c>; + pinctrl-names = "default"; + pinctrl-0 = <&bcam_pd>; + + clocks = <&cru SCLK_CIF_OUT>; + clock-names = "xvclk"; + + avdd-supply = <&vcc28_cif>; + dovdd-supply = <&vcc18_cif>; + dvdd-supply = <&vcc18_cif>; + + pwdn-gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>; + + port { + gc2145_out: endpoint { + remote-endpoint = <&cif_in_bcam>; + }; + }; + }; + + ts@40 { + compatible = "gslX680-d708"; + reg = <0x40>; + touch-gpio = <&gpio2 20 IRQ_TYPE_LEVEL_LOW>; + wake-gpio = <&gpio2 12 IRQ_TYPE_LEVEL_LOW>; + screen_max_x = <800>; + screen_max_y = <480>; + status = "okay"; + }; + + rk816: pmic@1a { + compatible = "rockchip,rk816"; + reg = <0x1a>; + interrupt-parent = <&gpio0>; + interrupts = <2 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int_l>; + rockchip,system-power-controller; + wakeup-source; + gpio-controller; + #gpio-cells = <2>; + #clock-cells = <1>; + clock-output-names = "rk816-clkout1", "rk816-clkout2"; + extcon = <&u2phy>; + + vcc1-supply = <&vcc_sys>; + vcc2-supply = <&vcc_sys>; + vcc3-supply = <&vcc_sys>; + vcc4-supply = <&vcc_sys>; + vcc5-supply = <&vcc_io>; + vcc6-supply = <&vcc_sys>; + + gpio { + status = "okay"; + }; + + pwrkey { + status = "okay"; + }; + + rtc { + status = "okay"; + }; + + battery { + compatible = "rk816-battery"; + ocv_table = < 3500 3625 3685 3697 3718 3735 3748 + 3760 3774 3788 3802 3816 3834 3853 + 3877 3908 3946 3975 4018 4071 4106>; + design_capacity = <2500>; + design_qmax = <2750>; + bat_res = <100>; + max_input_current = <1500>; + max_chrg_current = <1300>; + max_chrg_voltage = <4200>; + sleep_enter_current = <300>; + sleep_exit_current = <300>; + sleep_filter_current = <100>; + power_off_thresd = <3500>; + zero_algorithm_vol = <3850>; + max_soc_offset = <60>; + monitor_sec = <5>; + virtual_power = <0>; + power_dc2otg = <0>; + dc_det_adc = <0>; + }; + + regulators { + + vdd_arm: DCDC_REG1{ + regulator-name= "vdd_arm"; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1500000>; + regulator-ramp-delay = <6001>; + regulator-initial-mode = <1>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <900000>; + }; + }; + + vdd_log: DCDC_REG2 { + regulator-name= "vdd_logic"; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1500000>; + regulator-ramp-delay = <6001>; + regulator-initial-mode = <1>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <1>; + }; + + vcc_io: DCDC_REG4 { + regulator-name = "vcc_io"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-initial-mode = <1>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vcc28_cif: LDO_REG1 { + regulator-name = "vcc28_cif"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc18_cif: LDO_REG2 { + regulator-name = "vcc18_cif"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_11: LDO_REG3 { + regulator-name = "vdd_11"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1100000>; + }; + }; + + ldo4: LDO_REG4 { + regulator-name= "ldo4"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + ldo5: LDO_REG5 { + regulator-name= "ldo5"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + ldo6: LDO_REG6 { + regulator-name= "ldo6"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + }; + }; + + sensor@4c { + compatible = "gs_mc3230"; + reg = <0x4c>; + type = ; + irq_enable = <0>; + poll_delay_ms = <30>; + layout = <3>; + reprobe_en = <1>; + }; +}; + +&i2s_2ch { + #sound-dai-cells = <0>; + status = "okay"; +}; + +&iep { + status = "okay"; +}; + +&iep_mmu { + status = "okay"; +}; + +&mipi_dphy { + status = "okay"; +}; + +&nandc { + status = "okay"; +}; + +&pinctrl { + camera { + fcam_pd: fcam-pd { + rockchip,pins = <3 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + bcam_pd: bcam-pd { + rockchip,pins = <2 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + lcdc { + lcdc_lcdc: lcdc-lcdc { + rockchip,pins = + /* depend on the hardware */ + <2 RK_PB0 1 &pcfg_pull_none>, /* DCLK */ + /* <2 RK_PB1 1 &pcfg_pull_none>, /* HSYNC */ + /* <2 RK_PB2 1 &pcfg_pull_none>, /* VSYNC */ + <2 RK_PB3 1 &pcfg_pull_none>, /* DEN */ + <2 RK_PB4 1 &pcfg_pull_none>, /* DATA10 */ + <2 RK_PB5 1 &pcfg_pull_none>, /* DATA11 */ + <2 RK_PB6 1 &pcfg_pull_none>, /* DATA12 */ + <2 RK_PB7 1 &pcfg_pull_none>, /* DATA13 */ + <2 RK_PC0 1 &pcfg_pull_none>, /* DATA14 */ + <2 RK_PC1 1 &pcfg_pull_none>, /* DATA15 */ + <2 RK_PC2 1 &pcfg_pull_none>, /* DATA16 */ + <2 RK_PC3 1 &pcfg_pull_none>; /* DATA17 */ + /* <2 RK_PC4 1 &pcfg_pull_none>, /* DATA18 */ + /* <2 RK_PC5 1 &pcfg_pull_none>, /* DATA19 */ + /* <2 RK_PC6 1 &pcfg_pull_none>, /* DATA20 */ + /* <2 RK_PC7 1 &pcfg_pull_none>, /* DATA21 */ + /* <2 RK_PD0 1 &pcfg_pull_none>, /* DATA22 */ + /* <2 RK_PD1 1 &pcfg_pull_none>; /* DATA23 */ + }; + }; + + pmic { + pmic_int_l: pmic-int-l { + rockchip,pins = + <0 2 RK_FUNC_GPIO &pcfg_pull_default>; + }; + }; + + wireless-bluetooth { + uart1_rts_gpio: uart1-rts-gpio { + rockchip,pins = <1 11 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&pwm0 { + status = "okay"; +}; + +&rga { + status = "okay"; +}; + +&route_dsi { + status = "okay"; +}; + +&saradc { + status = "okay"; + vref-supply = <&vccadc_ref>; +}; + +&sdmmc { + cap-mmc-highspeed; + supports-sd; + card-detect-delay = <800>; + ignore-pm-notify; + keep-power-in-suspend; + cd-gpios = <&gpio2 7 GPIO_ACTIVE_LOW>; /* CD GPIO */ + status = "disabled"; +}; + +&sdio { + max-frequency = <50000000>; + cap-sd-highspeed; + supports-sdio; + ignore-pm-notify; + keep-power-in-suspend; + non-removable; + vmmc-supply = <&ldo5>; + status = "okay"; +}; + +&tsadc { + status = "okay"; +}; + +&u2phy { + status = "okay"; + + u2phy_otg: otg-port { + status = "okay"; + }; + + u2phy_host: host-port { + status = "okay"; + }; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_xfer &uart1_cts>; + status = "okay"; +}; + +&usb_otg { + status = "okay"; +}; + +&vop { + status = "okay"; +}; + +&vop_mmu { + status = "okay"; +}; + +&vpu { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/rk3128h-box-avb.dts b/arch/arm/boot/dts/rk3128h-box-avb.dts new file mode 100644 index 0000000000000..a480ba5134179 --- /dev/null +++ b/arch/arm/boot/dts/rk3128h-box-avb.dts @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd + */ + +/dts-v1/; + +#include "rk3128h-box.dtsi" + +/ { + model = "Rockchip RK3128h box avb board"; + compatible = "rockchip,rk3128h-box-avb", "rockchip,rk3128h"; +}; + +&dmc_opp_table { + opp-300000000 { + status = "disabled"; + }; + opp-330000000 { + status = "disabled"; + }; + opp-588000000 { + opp-hz = /bits/ 64 <588000000>; + opp-microvolt = <1100000>; + opp-microvolt-L0 = <1100000>; + opp-microvolt-L1 = <1050000>; + }; +}; + +&dmc { + system-status-freq = < + /*system status freq(KHz)*/ + SYS_STATUS_NORMAL 588000 + >; +}; + +&firmware_android { + compatible = "android,firmware"; + vbmeta { + compatible = "android,vbmeta"; + parts = "vbmeta,boot,system,vendor,dtbo"; + }; + fstab { + compatible = "android,fstab"; + vendor { + compatible = "android,vendor"; + dev = "/dev/block/platform/30020000.dwmmc/by-name/vendor"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait,avb"; + }; + }; +}; + +&pinctrl { + sdmmc { + sdmmc_det: sdmmc-det { + rockchip,pins = <1 RK_PC1 RK_FUNC_1 &pcfg_pull_none>; + }; + }; +}; + +&secure_memory { + /* + * enable like this: + * reg = <0x80000000 0x10000000>; + */ + reg = <0x80000000 0x8000000>; +}; + +&sdmmc { + pinctrl-0 = <&sdmmc_pwr &sdmmc_clk &sdmmc_cmd &sdmmc_bus4 &sdmmc_det>; +}; diff --git a/arch/arm/boot/dts/rk3128h-box.dts b/arch/arm/boot/dts/rk3128h-box.dts index a8816cbae5982..f82043f7fe423 100644 --- a/arch/arm/boot/dts/rk3128h-box.dts +++ b/arch/arm/boot/dts/rk3128h-box.dts @@ -1,681 +1,34 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) /* * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd - * - * SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ /dts-v1/; -#include "rk3128x.dtsi" -#include -#include +#include "rk3128h-box.dtsi" / { model = "Rockchip RK3128h box board"; compatible = "rockchip,rk3128h-box", "rockchip,rk3128h"; - - chosen { - bootargs = "earlycon=uart8250,mmio32,0x11030000"; - }; - - fiq-debugger { - compatible = "rockchip,fiq-debugger"; - interrupts = ; - rockchip,serial-id = <2>; - rockchip,signal-irq = <159>; - rockchip,wake-irq = <0>; - rockchip,irq-mode-enable = <0>; /* If enable uart uses irq instead of fiq */ - rockchip,baudrate = <1500000>; /* Only 115200 and 1500000 */ - pinctrl-names = "default"; - pinctrl-0 = <&uart21_xfer>; - }; - - firmware { - android { - compatible = "android,firmware"; - fstab { - compatible = "android,fstab"; - system { - compatible = "android,system"; - dev = "/dev/block/by-name/system"; - type = "ext4"; - mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; - fsmgr_flags = "wait,verify"; - }; - vendor { - compatible = "android,vendor"; - dev = "/dev/block/by-name/vendor"; - type = "ext4"; - mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; - fsmgr_flags = "wait,verify"; - }; - }; - }; - }; - - reserved-memory { - #address-cells = <1>; - #size-cells = <1>; - ranges; - - drm_logo: drm-logo@00000000 { - compatible = "rockchip,drm-logo"; - reg = <0x0 0x0>; - }; - - ramoops_mem: ramoops@62e00000 { - reg = <0x62e00000 0xf0000>; - }; - }; - - ramoops { - compatible = "ramoops"; - record-size = <0x0 0x20000>; - console-size = <0x0 0x80000>; - ftrace-size = <0x0 0x00000>; - pmsg-size = <0x0 0x50000>; - memory-region = <&ramoops_mem>; - }; - - gpio_keys { - compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; - autorepeat; - - pinctrl-names = "default"; - pinctrl-0 = <&pwr_key>; - - power_key: power-key { - label = "GPIO Key Power"; - gpios = <&gpio3 23 GPIO_ACTIVE_LOW>; - linux,code = ; - debounce-interval = <100>; - wakeup-source; - }; - }; - - sound { - compatible = "simple-audio-card"; - simple-audio-card,format = "i2s"; - simple-audio-card,mclk-fs = <256>; - simple-audio-card,name = "rockchip,rk3229"; - simple-audio-card,cpu { - sound-dai = <&i2s1>; - }; - simple-audio-card,codec { - sound-dai = <&codec>; - }; - }; - - hdmi_sound: hdmi-sound { - status = "okay"; - compatible = "simple-audio-card"; - simple-audio-card,format = "i2s"; - simple-audio-card,mclk-fs = <128>; - simple-audio-card,name = "rockchip,hdmi"; - simple-audio-card,cpu { - sound-dai = <&i2s0>; - }; - simple-audio-card,codec { - sound-dai = <&hdmi>; - }; - }; - - regulators { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <0>; - - vccio_1v8_reg: regulator@0 { - compatible = "regulator-fixed"; - regulator-name = "vccio_1v8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-always-on; - }; - - vccio_3v3_reg: regulator@1 { - compatible = "regulator-fixed"; - regulator-name = "vccio_3v3"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-always-on; - }; - }; - - sdio_pwrseq: sdio-pwrseq { - compatible = "mmc-pwrseq-simple"; - clocks = <&hym8563>; - /* clock-names = "ext_clock"; */ - pinctrl-names = "default"; - pinctrl-0 = <&wifi_enable_h>; - - /* - * On the module itself this is one of these (depending - * on the actual card populated): - * - SDIO_RESET_L_WL_REG_ON - * - PDN (power down when low) - */ - reset-gpios = <&gpio2 26 GPIO_ACTIVE_LOW>; /* GPIO2_D2 */ - }; - - spdif_out: spdif-out { - status = "okay"; - compatible = "linux,spdif-dit"; - #sound-dai-cells = <0>; - }; - - spdif-sound { - status = "okay"; - compatible = "simple-audio-card"; - simple-audio-card,name = "ROCKCHIP,SPDIF"; - simple-audio-card,cpu { - sound-dai = <&spdif>; - }; - simple-audio-card,codec { - sound-dai = <&spdif_out>; - }; - }; - - vcc_host: vcc-host-regulator { - compatible = "regulator-fixed"; - enable-active-high; - gpio = <&gpio3 20 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; - pinctrl-0 = <&host_vbus_drv>; - regulator-name = "vcc_host"; - regulator-always-on; - regulator-boot-on; - }; - - vcc_otg_vbus: otg-vbus-regulator { - compatible = "regulator-fixed"; - gpio = <&gpio3 RK_PC6 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; - pinctrl-0 = <&otg_vbus_drv>; - regulator-name = "vcc_otg_vbus"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - enable-active-high; - }; - - vcc_phy: vcc-phy-regulator { - compatible = "regulator-fixed"; - enable-active-high; - regulator-name = "vcc_phy"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-always-on; - regulator-boot-on; - }; - - vdd_arm: vdd-arm-regulator { - compatible = "pwm-regulator"; - rockchip,pwm_id = <1>; - regulator-init-microvolt = <1200000>; - pwms = <&pwm1 0 5000 1>; - regulator-name = "vdd_arm"; - regulator-min-microvolt = <950000>; - regulator-max-microvolt = <1400000>; - regulator-settling-time-up-us = <250>; - regulator-always-on; - regulator-boot-on; - }; - - wireless-bluetooth { - compatible = "bluetooth-platdata"; - clocks = <&hym8563>; - clock-names = "ext_clock"; - uart_rts_gpios = <&gpio3 6 GPIO_ACTIVE_LOW>; - pinctrl-names = "default", "rts_gpio"; - pinctrl-0 = <&uart11_rts>; - pinctrl-1 = <&uart11_rts_gpio>; - BT,power_gpio = <&gpio2 29 GPIO_ACTIVE_HIGH>; - BT,wake_host_irq = <&gpio3 26 GPIO_ACTIVE_HIGH>; - status = "disabled"; - }; - - wireless-wlan { - compatible = "wlan-platdata"; - rockchip,grf = <&grf>; - wifi_chip_type = "ap6335"; - sdio_vref = <1800>; - WIFI,host_wake_irq = <&gpio0 28 GPIO_ACTIVE_HIGH>; - status = "okay"; - }; }; -&codec { - #sound-dai-cells = <0>; - status = "okay"; -}; - -&cpu0 { - cpu-supply = <&vdd_arm>; -}; - -&display_subsystem { - logo-memory-region = <&drm_logo>; - status = "okay"; - - route { - route_hdmi: route-hdmi { - status = "okay"; - logo,uboot = "logo.bmp"; - logo,kernel = "logo_kernel.bmp"; - logo,mode = "center"; - charge_logo,mode = "center"; - connect = <&vop_out_hdmi>; +&firmware_android { + compatible = "android,firmware"; + fstab { + compatible = "android,fstab"; + system { + compatible = "android,system"; + dev = "/dev/block/by-name/system"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait,verify"; }; - - route_tve: route-tve { - status = "okay"; - logo,uboot = "logo.bmp"; - logo,kernel = "logo_kernel.bmp"; - logo,mode = "center"; - charge_logo,mode = "center"; - connect = <&vop_out_tve>; + vendor { + compatible = "android,vendor"; + dev = "/dev/block/by-name/vendor"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait,verify"; }; }; }; - -&dmc { - center-supply = <&vdd_arm>; - status = "okay"; -}; - -&emmc { - broken-cd; - bus-width = <8>; - cap-mmc-highspeed; - mmc-hs200-1_8v; - supports-emmc; - disable-wp; - non-removable; - num-slots = <1>; - /delete-property/ default-sample-phase; - /delete-property/ pinctrl-names; - /delete-property/ pinctrl-0; - status = "okay"; -}; - -&gmac { - assigned-clocks = <&cru SCLK_MAC_SRC>; - assigned-clock-rates = <50000000>; - clock_in_out = "output"; - phy-supply = <&vcc_phy>; - phy-mode = "rmii"; - phy-is-integrated; - status = "okay"; -}; - -&gpu { - status = "okay"; - mali-supply = <&vdd_arm>; -}; - -&hdmi { - status = "okay"; - #sound-dai-cells = <0>; - ddc-i2c-scl-high-time-ns = <9625>; - ddc-i2c-scl-low-time-ns = <10000>; -}; - -&hdmi_phy { - status = "okay"; -}; - -&io_domains { - status = "okay"; - - vccio1-supply = <&vccio_3v3_reg>; - vccio2-supply = <&vccio_3v3_reg>; - vccio4-supply = <&vccio_3v3_reg>; -}; - -&i2c0 { - status = "okay"; - - hym8563: hym8563@51 { - compatible = "haoyu,hym8563"; - reg = <0x51>; - #clock-cells = <0>; - clock-frequency = <32768>; - clock-output-names = "xin32k"; - }; -}; - -&i2s0 { - status = "okay"; - rockchip,bclk-fs = <128>; - #sound-dai-cells = <0>; -}; - -&i2s1 { - #sound-dai-cells = <0>; - status = "okay"; -}; - -&iep { - status = "okay"; -}; - -&iep_mmu { - status = "okay"; -}; - -&nandc { - status = "okay"; -}; - -&pinctrl { - keys { - pwr_key: pwr-key { - rockchip,pins = <3 23 RK_FUNC_GPIO &pcfg_pull_up>; - }; - }; - - sdmmc { - sdmmc_pwr: sdmmc-pwr { - rockchip,pins = <1 14 RK_FUNC_GPIO &pcfg_pull_none>; - }; - }; - - sdio-pwrseq { - wifi_enable_h: wifi-enable-h { - rockchip,pins = <2 26 RK_FUNC_GPIO &pcfg_pull_none>; - }; - }; - - usb { - host_vbus_drv: host-vbus-drv { - rockchip,pins = <3 20 RK_FUNC_GPIO &pcfg_pull_none>; - }; - - otg_vbus_drv: otg-vbus-drv { - rockchip,pins = <3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; - }; - }; -}; - -&pwm1 { - status = "okay"; - pinctrl-names = "active"; - pinctrl-0 = <&pwm1_pin_pull_down>; -}; - -&pwm2 { - status = "okay"; -}; - -&pwm3 { - status = "okay"; - compatible = "rockchip,remotectl-pwm"; - remote_pwm_id = <3>; - handle_cpu_id = <1>; - remote_support_psci = <1>; - - ir_key1 { - rockchip,usercode = <0x4040>; - rockchip,key_table = - <0xf2 KEY_REPLY>, - <0xba KEY_BACK>, - <0xf4 KEY_UP>, - <0xf1 KEY_DOWN>, - <0xef KEY_LEFT>, - <0xee KEY_RIGHT>, - <0xbd KEY_HOME>, - <0xea KEY_VOLUMEUP>, - <0xe3 KEY_VOLUMEDOWN>, - <0xe2 KEY_SEARCH>, - <0xb2 KEY_POWER>, - <0xbc KEY_MUTE>, - <0xec KEY_MENU>, - <0xbf 0x190>, - <0xe0 0x191>, - <0xe1 0x192>, - <0xe9 183>, - <0xe6 248>, - <0xe8 185>, - <0xe7 186>, - <0xf0 388>, - <0xbe 0x175>; - }; - - ir_key2 { - rockchip,usercode = <0xff00>; - rockchip,key_table = - <0xf9 KEY_HOME>, - <0xbf KEY_BACK>, - <0xfb KEY_MENU>, - <0xaa KEY_REPLY>, - <0xb9 KEY_UP>, - <0xe9 KEY_DOWN>, - <0xb8 KEY_LEFT>, - <0xea KEY_RIGHT>, - <0xeb KEY_VOLUMEDOWN>, - <0xef KEY_VOLUMEUP>, - <0xf7 KEY_MUTE>, - <0xe7 KEY_POWER>, - <0xfc KEY_POWER>, - <0xa9 KEY_VOLUMEDOWN>, - <0xa8 KEY_PLAYPAUSE>, - <0xe0 KEY_VOLUMEDOWN>, - <0xa5 KEY_VOLUMEDOWN>, - <0xab 183>, - <0xb7 388>, - <0xe8 388>, - <0xf8 184>, - <0xaf 185>, - <0xed KEY_VOLUMEDOWN>, - <0xee 186>, - <0xb3 KEY_VOLUMEDOWN>, - <0xf1 KEY_VOLUMEDOWN>, - <0xf2 KEY_VOLUMEDOWN>, - <0xf3 KEY_SEARCH>, - <0xb4 KEY_VOLUMEDOWN>, - <0xa4 KEY_SETUP>, - <0xbe KEY_SEARCH>; - }; - - ir_key3 { - rockchip,usercode = <0x1dcc>; - rockchip,key_table = - <0xee KEY_REPLY>, - <0xf0 KEY_BACK>, - <0xf8 KEY_UP>, - <0xbb KEY_DOWN>, - <0xef KEY_LEFT>, - <0xed KEY_RIGHT>, - <0xfc KEY_HOME>, - <0xf1 KEY_VOLUMEUP>, - <0xfd KEY_VOLUMEDOWN>, - <0xb7 KEY_SEARCH>, - <0xff KEY_POWER>, - <0xf3 KEY_MUTE>, - <0xbf KEY_MENU>, - <0xf9 0x191>, - <0xf5 0x192>, - <0xb3 388>, - <0xbe KEY_1>, - <0xba KEY_2>, - <0xb2 KEY_3>, - <0xbd KEY_4>, - <0xf9 KEY_5>, - <0xb1 KEY_6>, - <0xfc KEY_7>, - <0xf8 KEY_8>, - <0xb0 KEY_9>, - <0xb6 KEY_0>, - <0xb5 KEY_BACKSPACE>; - }; -}; - -&rockchip_suspend { - status = "okay"; - rockchip,virtual-poweroff = <1>; - rockchip,sleep-mode-config = < - (0 - |RKPM_CTR_GTCLKS - |RKPM_CTR_IDLESRAM_MD - |RKPM_CTR_PMIC - ) - >; -}; - -&sdio { - status = "okay"; - mmc-pwrseq = <&sdio_pwrseq>; - bus-width = <4>; - cap-mmc-highspeed; - cap-sd-highspeed; - cap-sdio-irq; - non-removable; - ignore-pm-notify; - keep-power-in-suspend; - max-frequency = <150000000>; - supports-sdio; -}; - -&sdmmc { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&sdmmc_pwr &sdmmc_clk &sdmmc_cmd &sdmmc_bus4>; - bus-width = <4>; - cap-mmc-highspeed; - cap-sd-highspeed; - card-detect-delay = <200>; - disable-wp; - max-frequency = <50000000>; - num-slots = <1>; - supports-sd; -}; - -&spdif { - status = "okay"; - #sound-dai-cells = <0>; -}; - -&threshold { - temperature = <90000>; /* millicelsius */ -}; - -&target { - temperature = <105000>; /* millicelsius */ -}; - -&soc_crit { - temperature = <115000>; /* millicelsius */ -}; - -&tsadc { - rockchip,hw-tshut-mode = <0>; /* tshut mode 0:CRU 1:GPIO */ - rockchip,hw-tshut-temp = <120000>; - status = "okay"; -}; - -&tve { - status = "okay"; -}; - -&u2phy0 { - status = "okay"; - - u2phy0_otg: otg-port { - status = "okay"; - }; - - u2phy0_host: host-port { - status = "okay"; - }; -}; - -&u2phy1 { - status = "okay"; - - u2phy1_otg: otg-port { - status = "okay"; - }; - - u2phy1_host: host-port { - status = "okay"; - }; -}; - -&uart1 { - pinctrl-names = "default"; - pinctrl-0 = <&uart11_xfer &uart11_cts>; - status = "okay"; -}; - -&usb_otg { - status = "okay"; -}; - -&u2phy0_host { - phy-supply = <&vcc_host>; -}; - -&u2phy1_host { - phy-supply = <&vcc_host>; -}; - -&u2phy0_otg { - vbus-supply = <&vcc_otg_vbus>; -}; - -&usb_host0_ehci { - status = "okay"; -}; - -&usb_host0_ohci { - status = "okay"; -}; - -&usb_host1_ehci { - status = "okay"; -}; - -&usb_host1_ohci { - status = "okay"; -}; - -&usb_host2_ehci { - status = "okay"; -}; - -&usb_host2_ohci { - status = "okay"; -}; - -&vop { - assigned-clocks = <&cru DCLK_VOP>; - assigned-clock-parents = <&cru HDMIPHY>; - status = "okay"; -}; - -&vop_mmu { - status = "okay"; -}; - -&vpu_service { - status = "okay"; -}; - -&vpu_mmu { - status = "okay"; -}; - -&rkvdec { - vcodec-supply = <&vdd_arm>; - status = "okay"; -}; - -&rkvdec_mmu { - status = "okay"; -}; - -&rk_rga { - status = "okay"; -}; diff --git a/arch/arm/boot/dts/rk3128h-box.dtsi b/arch/arm/boot/dts/rk3128h-box.dtsi new file mode 100644 index 0000000000000..44a077469fb2f --- /dev/null +++ b/arch/arm/boot/dts/rk3128h-box.dtsi @@ -0,0 +1,688 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd + */ + +/dts-v1/; + +#include "rk3128x.dtsi" +#include +#include + +/ { + chosen: chosen { + bootargs = "earlycon=uart8250,mmio32,0x11030000"; + }; + + fiq_debugger: fiq-debugger { + compatible = "rockchip,fiq-debugger"; + interrupts = ; + rockchip,serial-id = <2>; + rockchip,signal-irq = <159>; + rockchip,wake-irq = <0>; + rockchip,irq-mode-enable = <0>; /* If enable uart uses irq instead of fiq */ + rockchip,baudrate = <1500000>; /* Only 115200 and 1500000 */ + pinctrl-names = "default"; + pinctrl-0 = <&uart21_xfer>; + }; + + firmware { + firmware_android: android {}; + }; + + reserved_memory: reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + drm_logo: drm-logo@00000000 { + compatible = "rockchip,drm-logo"; + reg = <0x0 0x0>; + }; + + secure_memory: secure-memory@80000000 { + compatible = "rockchip,secure-memory"; + reg = <0x80000000 0x0>; + }; + + ramoops_mem: ramoops@62e00000 { + reg = <0x62e00000 0xf0000>; + }; + }; + + ramoops: ramoops { + compatible = "ramoops"; + record-size = <0x0 0x20000>; + console-size = <0x0 0x80000>; + ftrace-size = <0x0 0x00000>; + pmsg-size = <0x0 0x50000>; + memory-region = <&ramoops_mem>; + }; + + gpio_keys: gpio-keys { + status = "okay"; + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + autorepeat; + + pinctrl-names = "default"; + pinctrl-0 = <&pwr_key &volume_up_key>; + + power_key: power-key { + label = "GPIO Key Power"; + gpios = <&gpio3 23 GPIO_ACTIVE_LOW>; + linux,code = ; + debounce-interval = <100>; + wakeup-source; + }; + + volume_up: volume-up-key { + label = "GPIO Key Power"; + gpios = <&gpio3 25 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + sound: sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,name = "rockchip-rk3229"; + simple-audio-card,cpu { + sound-dai = <&i2s1>; + }; + simple-audio-card,codec { + sound-dai = <&codec>; + }; + }; + + hdmi_sound: hdmi-sound { + status = "okay"; + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,mclk-fs = <128>; + simple-audio-card,name = "rockchip-hdmi"; + simple-audio-card,cpu { + sound-dai = <&i2s0>; + }; + simple-audio-card,codec { + sound-dai = <&hdmi>; + }; + }; + + regulators: regulators { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + vccio_1v8_reg: regulator@0 { + compatible = "regulator-fixed"; + regulator-name = "vccio_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + vccio_3v3_reg: regulator@1 { + compatible = "regulator-fixed"; + regulator-name = "vccio_3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + }; + + rtc_fake: rtc-fake { + compatible = "rtc-fake"; + status = "okay"; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + clocks = <&hym8563>; + /* clock-names = "ext_clock"; */ + pinctrl-names = "default"; + pinctrl-0 = <&wifi_enable_h>; + + /* + * On the module itself this is one of these (depending + * on the actual card populated): + * - SDIO_RESET_L_WL_REG_ON + * - PDN (power down when low) + */ + reset-gpios = <&gpio2 26 GPIO_ACTIVE_LOW>; /* GPIO2_D2 */ + }; + + spdif_out: spdif-out { + status = "okay"; + compatible = "linux,spdif-dit"; + #sound-dai-cells = <0>; + }; + + spdif_sound: spdif-sound { + status = "okay"; + compatible = "simple-audio-card"; + simple-audio-card,name = "ROCKCHIP-SPDIF"; + simple-audio-card,cpu { + sound-dai = <&spdif>; + }; + simple-audio-card,codec { + sound-dai = <&spdif_out>; + }; + }; + + vcc_host: vcc-host-regulator { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio3 20 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&host_vbus_drv>; + regulator-name = "vcc_host"; + regulator-always-on; + regulator-boot-on; + }; + + vcc_otg_vbus: otg-vbus-regulator { + compatible = "regulator-fixed"; + gpio = <&gpio3 RK_PC6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&otg_vbus_drv>; + regulator-name = "vcc_otg_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + }; + + vcc_phy: vcc-phy-regulator { + compatible = "regulator-fixed"; + enable-active-high; + regulator-name = "vcc_phy"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + }; + + vdd_arm: vdd-arm-regulator { + compatible = "pwm-regulator"; + rockchip,pwm_id = <1>; + regulator-init-microvolt = <1200000>; + regulator-early-min-microvolt = <1200000>; + pwms = <&pwm1 0 5000 1>; + regulator-name = "vdd_arm"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1400000>; + regulator-settling-time-up-us = <250>; + regulator-always-on; + regulator-boot-on; + }; + + wireless_bluetooth: wireless-bluetooth { + compatible = "bluetooth-platdata"; + clocks = <&hym8563>; + clock-names = "ext_clock"; + uart_rts_gpios = <&gpio3 6 GPIO_ACTIVE_LOW>; + pinctrl-names = "default", "rts_gpio"; + pinctrl-0 = <&uart11_rts>; + pinctrl-1 = <&uart11_rts_gpio>; + BT,power_gpio = <&gpio2 29 GPIO_ACTIVE_HIGH>; + BT,wake_host_irq = <&gpio3 26 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; + + wireless_wlan: wireless-wlan { + compatible = "wlan-platdata"; + rockchip,grf = <&grf>; + wifi_chip_type = "ssv6051"; + sdio_vref = <1800>; + WIFI,host_wake_irq = <&gpio0 28 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; +}; + +&codec { + #sound-dai-cells = <0>; + status = "okay"; +}; + +&cpu0 { + cpu-supply = <&vdd_arm>; +}; + +&display_subsystem { + logo-memory-region = <&drm_logo>; + secure-memory-region = <&secure_memory>; + status = "okay"; + + route { + route_hdmi: route-hdmi { + status = "okay"; + logo,uboot = "logo.bmp"; + logo,kernel = "logo_kernel.bmp"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <&vop_out_hdmi>; + }; + + route_tve: route-tve { + status = "okay"; + logo,uboot = "logo.bmp"; + logo,kernel = "logo_kernel.bmp"; + logo,mode = "center"; + charge_logo,mode = "center"; + connect = <&vop_out_tve>; + }; + }; +}; + +&dmc { + center-supply = <&vdd_arm>; + status = "okay"; +}; + +&emmc { + broken-cd; + bus-width = <8>; + cap-mmc-highspeed; + mmc-hs200-1_8v; + supports-emmc; + disable-wp; + non-removable; + num-slots = <1>; + /delete-property/ default-sample-phase; + /delete-property/ pinctrl-names; + /delete-property/ pinctrl-0; + status = "okay"; +}; + +&gmac { + assigned-clocks = <&cru SCLK_MAC_SRC>; + assigned-clock-rates = <50000000>; + clock_in_out = "output"; + phy-supply = <&vcc_phy>; + phy-mode = "rmii"; + phy-is-integrated; + status = "okay"; +}; + +&gpu { + status = "okay"; + mali-supply = <&vdd_arm>; +}; + +&hdmi { + status = "okay"; + #sound-dai-cells = <0>; + ddc-i2c-scl-high-time-ns = <9625>; + ddc-i2c-scl-low-time-ns = <10000>; +}; + +&hdmi_phy { + status = "okay"; +}; + +&io_domains { + status = "okay"; + + vccio1-supply = <&vccio_3v3_reg>; + vccio2-supply = <&vccio_3v3_reg>; + vccio4-supply = <&vccio_3v3_reg>; +}; + +&i2c0 { + status = "okay"; + + hym8563: hym8563@51 { + compatible = "haoyu,hym8563"; + reg = <0x51>; + #clock-cells = <0>; + clock-frequency = <32768>; + clock-output-names = "xin32k"; + }; +}; + +&i2s0 { + status = "okay"; + rockchip,bclk-fs = <128>; + #sound-dai-cells = <0>; +}; + +&i2s1 { + #sound-dai-cells = <0>; + status = "okay"; +}; + +&iep { + status = "okay"; +}; + +&iep_mmu { + status = "okay"; +}; + +&nandc { + status = "okay"; +}; + +&pinctrl { + keys { + pwr_key: pwr-key { + rockchip,pins = <3 23 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + volume_up_key: volume-up { + rockchip,pins = <3 25 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + sdmmc { + sdmmc_pwr: sdmmc-pwr { + rockchip,pins = <1 14 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + sdio-pwrseq { + wifi_enable_h: wifi-enable-h { + rockchip,pins = <2 26 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + usb { + host_vbus_drv: host-vbus-drv { + rockchip,pins = <3 20 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + otg_vbus_drv: otg-vbus-drv { + rockchip,pins = <3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&pwm1 { + status = "okay"; + pinctrl-names = "active"; + pinctrl-0 = <&pwm1_pin_pull_down>; +}; + +&pwm2 { + status = "okay"; +}; + +&pwm3 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pwm3_pin>; + compatible = "rockchip,remotectl-pwm"; + remote_pwm_id = <3>; + handle_cpu_id = <1>; + remote_support_psci = <1>; + + ir_key1 { + rockchip,usercode = <0x4040>; + rockchip,key_table = + <0xf2 KEY_REPLY>, + <0xba KEY_BACK>, + <0xf4 KEY_UP>, + <0xf1 KEY_DOWN>, + <0xef KEY_LEFT>, + <0xee KEY_RIGHT>, + <0xbd KEY_HOME>, + <0xea KEY_VOLUMEUP>, + <0xe3 KEY_VOLUMEDOWN>, + <0xe2 KEY_SEARCH>, + <0xb2 KEY_POWER>, + <0xbc KEY_MUTE>, + <0xec KEY_MENU>, + <0xbf 0x190>, + <0xe0 0x191>, + <0xe1 0x192>, + <0xe9 183>, + <0xe6 248>, + <0xe8 185>, + <0xe7 186>, + <0xf0 388>, + <0xbe 0x175>; + }; + + ir_key2 { + rockchip,usercode = <0xff00>; + rockchip,key_table = + <0xf9 KEY_HOME>, + <0xbf KEY_BACK>, + <0xfb KEY_MENU>, + <0xaa KEY_REPLY>, + <0xb9 KEY_UP>, + <0xe9 KEY_DOWN>, + <0xb8 KEY_LEFT>, + <0xea KEY_RIGHT>, + <0xeb KEY_VOLUMEDOWN>, + <0xef KEY_VOLUMEUP>, + <0xf7 KEY_MUTE>, + <0xe7 KEY_POWER>, + <0xfc KEY_POWER>, + <0xa9 KEY_VOLUMEDOWN>, + <0xa8 KEY_PLAYPAUSE>, + <0xe0 KEY_VOLUMEDOWN>, + <0xa5 KEY_VOLUMEDOWN>, + <0xab 183>, + <0xb7 388>, + <0xe8 388>, + <0xf8 184>, + <0xaf 185>, + <0xed KEY_VOLUMEDOWN>, + <0xee 186>, + <0xb3 KEY_VOLUMEDOWN>, + <0xf1 KEY_VOLUMEDOWN>, + <0xf2 KEY_VOLUMEDOWN>, + <0xf3 KEY_SEARCH>, + <0xb4 KEY_VOLUMEDOWN>, + <0xa4 KEY_SETUP>, + <0xbe KEY_SEARCH>; + }; + + ir_key3 { + rockchip,usercode = <0x1dcc>; + rockchip,key_table = + <0xee KEY_REPLY>, + <0xf0 KEY_BACK>, + <0xf8 KEY_UP>, + <0xbb KEY_DOWN>, + <0xef KEY_LEFT>, + <0xed KEY_RIGHT>, + <0xfc KEY_HOME>, + <0xf1 KEY_VOLUMEUP>, + <0xfd KEY_VOLUMEDOWN>, + <0xb7 KEY_SEARCH>, + <0xff KEY_POWER>, + <0xf3 KEY_MUTE>, + <0xbf KEY_MENU>, + <0xf9 0x191>, + <0xf5 0x192>, + <0xb3 388>, + <0xbe KEY_1>, + <0xba KEY_2>, + <0xb2 KEY_3>, + <0xbd KEY_4>, + <0xf9 KEY_5>, + <0xb1 KEY_6>, + <0xfc KEY_7>, + <0xf8 KEY_8>, + <0xb0 KEY_9>, + <0xb6 KEY_0>, + <0xb5 KEY_BACKSPACE>; + }; + + ir_key80{ + rockchip,usercode = <0x7f00>; + rockchip,key_table = <0xed KEY_POWER>; + }; +}; + +&rockchip_suspend { + status = "okay"; + rockchip,virtual-poweroff = <1>; + rockchip,sleep-mode-config = < + (0 + |RKPM_CTR_GTCLKS + |RKPM_CTR_IDLESRAM_MD + |RKPM_CTR_PMIC + ) + >; +}; + +&sdio { + status = "okay"; + mmc-pwrseq = <&sdio_pwrseq>; + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + cap-sdio-irq; + non-removable; + ignore-pm-notify; + keep-power-in-suspend; + max-frequency = <37500000>; + supports-sdio; +}; + +&sdmmc { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_pwr &sdmmc_clk &sdmmc_cmd &sdmmc_bus4>; + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + card-detect-delay = <200>; + disable-wp; + max-frequency = <50000000>; + num-slots = <1>; + supports-sd; +}; + +&spdif { + status = "okay"; + #sound-dai-cells = <0>; +}; + +&threshold { + temperature = <90000>; /* millicelsius */ +}; + +&target { + temperature = <105000>; /* millicelsius */ +}; + +&soc_crit { + temperature = <115000>; /* millicelsius */ +}; + +&tsadc { + rockchip,hw-tshut-mode = <0>; /* tshut mode 0:CRU 1:GPIO */ + rockchip,hw-tshut-temp = <120000>; + status = "okay"; +}; + +&tve { + status = "okay"; +}; + +&u2phy0 { + status = "okay"; + + u2phy0_otg: otg-port { + status = "okay"; + }; + + u2phy0_host: host-port { + status = "okay"; + }; +}; + +&u2phy1 { + status = "okay"; + + u2phy1_otg: otg-port { + status = "okay"; + }; + + u2phy1_host: host-port { + status = "okay"; + }; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart11_xfer &uart11_cts>; + status = "okay"; +}; + +&usb_otg { + status = "okay"; +}; + +&u2phy0_host { + phy-supply = <&vcc_host>; +}; + +&u2phy1_host { + phy-supply = <&vcc_host>; +}; + +&u2phy0_otg { + vbus-supply = <&vcc_otg_vbus>; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; + +&usb_host1_ehci { + status = "okay"; +}; + +&usb_host1_ohci { + status = "okay"; +}; + +&usb_host2_ehci { + status = "okay"; +}; + +&usb_host2_ohci { + status = "okay"; +}; + +&vop { + assigned-clocks = <&cru DCLK_VOP>; + assigned-clock-parents = <&cru HDMIPHY>; + status = "okay"; +}; + +&vop_mmu { + status = "okay"; +}; + +&vpu_service { + status = "okay"; +}; + +&vpu_mmu { + status = "okay"; +}; + +&rkvdec { + vcodec-supply = <&vdd_arm>; + status = "okay"; +}; + +&rkvdec_mmu { + status = "okay"; +}; + +&rk_rga { + status = "okay"; +}; diff --git a/arch/arm/boot/dts/rk3128x.dtsi b/arch/arm/boot/dts/rk3128x.dtsi index bed1a10079bb5..25ebcb0f296a9 100644 --- a/arch/arm/boot/dts/rk3128x.dtsi +++ b/arch/arm/boot/dts/rk3128x.dtsi @@ -76,6 +76,7 @@ compatible = "operating-points-v2"; opp-shared; + rockchip,avs = <1>; rockchip,leakage-scaling-sel = < 0 254 20 >; @@ -90,35 +91,35 @@ opp-408000000 { opp-hz = /bits/ 64 <408000000>; - opp-microvolt = <950000>; - opp-microvolt-L0 = <950000 950000 1175000>; - opp-microvolt-L1 = <950000 950000 1125000>; + opp-microvolt = <950000 950000 1200000>; + opp-microvolt-L0 = <950000 950000 1200000>; + opp-microvolt-L1 = <950000 950000 1200000>; clock-latency-ns = <40000>; opp-suspend; }; opp-600000000 { opp-hz = /bits/ 64 <600000000>; - opp-microvolt = <975000>; - opp-microvolt-L0 = <975000 975000 1175000>; - opp-microvolt-L1 = <975000 975000 1125000>; + opp-microvolt = <975000 975000 1200000>; + opp-microvolt-L0 = <975000 975000 1200000>; + opp-microvolt-L1 = <975000 975000 1200000>; }; opp-816000000 { opp-hz = /bits/ 64 <816000000>; - opp-microvolt = <1000000>; - opp-microvolt-L0 = <1000000 1000000 1175000>; - opp-microvolt-L1 = <1000000 1000000 1125000>; + opp-microvolt = <1000000 1000000 1200000>; + opp-microvolt-L0 = <1000000 1000000 1200000>; + opp-microvolt-L1 = <1000000 1000000 1200000>; }; opp-1008000000 { opp-hz = /bits/ 64 <1008000000>; - opp-microvolt = <1175000>; - opp-microvolt-L0 = <1175000 1175000 1175000>; - opp-microvolt-L1 = <1125000 1125000 1125000>; + opp-microvolt = <1175000 1175000 1200000>; + opp-microvolt-L0 = <1175000 1175000 1200000>; + opp-microvolt-L1 = <1125000 1125000 1200000>; }; opp-1200000000 { opp-hz = /bits/ 64 <1200000000>; - opp-microvolt = <1175000>; - opp-microvolt-L0 = <1175000 1175000 1175000>; - opp-microvolt-L1 = <1125000 1125000 1125000>; + opp-microvolt = <1175000 1175000 1200000>; + opp-microvolt-L0 = <1175000 1175000 1200000>; + opp-microvolt-L1 = <1125000 1125000 1200000>; }; }; diff --git a/arch/arm/boot/dts/rk312x-android.dtsi b/arch/arm/boot/dts/rk312x-android.dtsi index 1cda2dc70a4ad..745025573b65a 100644 --- a/arch/arm/boot/dts/rk312x-android.dtsi +++ b/arch/arm/boot/dts/rk312x-android.dtsi @@ -1,43 +1,6 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) /* * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., 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 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 @@ -67,6 +30,10 @@ status = "okay"; }; + firmware { + firmware_android: android {}; + }; + reserved-memory { #address-cells = <1>; #size-cells = <1>; @@ -98,6 +65,10 @@ }; }; +&cif_new { + memory-region = <&cma_region>; +}; + &dfi { status = "okay"; }; diff --git a/arch/arm/boot/dts/rk312x.dtsi b/arch/arm/boot/dts/rk312x.dtsi index f21ea5fc051c2..52b2306bfe92e 100644 --- a/arch/arm/boot/dts/rk312x.dtsi +++ b/arch/arm/boot/dts/rk312x.dtsi @@ -465,14 +465,34 @@ }; }; - vpu: vpu_service@10104000 { - compatible = "rockchip,vpu_service"; + hevc: hevc_service@10104000 { + compatible = "rockchip,sub"; + reg = <0x10104000 0x400>; + interrupts = ; + interrupt-names = "irq_dec"; + power-domains = <&power RK3128_PD_VIDEO>; + dev_mode = <1>; + name = "hevc_service"; + iommus = <&hevc_mmu>; + status = "disabled"; + }; + + hevc_mmu: iommu@10104440 { + compatible = "rockchip,iommu"; + reg = <0x10104440 0x40>, <0x10104480 0x40>; + interrupts = ; + interrupt-names = "hevc_mmu"; + power-domains = <&power RK3128_PD_VIDEO>; + #iommu-cells = <0>; + status = "disabled"; + }; + + vpu: vpu_service@10106000 { + compatible = "rockchip,sub"; + reg = <0x10106000 0x800>; rockchip,grf = <&grf>; - iommus = <&vpu_mmu>; - iommu_enabled = <1>; - reg = <0x10104000 0x800>; interrupts = , - ; + ; interrupt-names = "irq_enc", "irq_dec"; clocks = <&cru ACLK_VDPU>, <&cru HCLK_VDPU>; clock-names = "aclk_vcodec", "hclk_vcodec"; @@ -481,20 +501,40 @@ power-domains = <&power RK3128_PD_VIDEO>; name = "vpu_service"; dev_mode = <0>; + iommus = <&vpu_mmu>; /* 0 means ion, 1 means drm */ allocator = <1>; status = "disabled"; }; - vpu_mmu: iommu@10104800 { + vpu_mmu: iommu@10106800 { compatible = "rockchip,iommu"; - reg = <0x10104800 0x40>; + reg = <0x10106800 0x40>; interrupts = ; interrupt-names = "vpu_mmu"; clocks = <&cru ACLK_VDPU>, <&cru HCLK_VDPU>; clock-names = "aclk", "hclk"; power-domains = <&power RK3128_PD_VIDEO>; #iommu-cells = <0>; + status = "disabled"; + }; + + vpu_combo: vpu_combo { + compatible = "rockchip,vpu_combo"; + subcnt = <2>; + rockchip,sub = <&vpu>, <&hevc>; + rockchip,grf = <&grf>; + clocks = <&cru ACLK_VDPU>, <&cru HCLK_VDPU>, + <&cru SCLK_HEVC_CORE>; + clock-names = "aclk_vcodec", "hclk_vcodec", + "clk_core"; + resets = <&cru SRST_VCODEC_H>, <&cru SRST_VCODEC_A>, + <&cru SRST_HEVC_CORE>; + reset-names = "video_h", "video_a", "video"; + mode_bit = <15>; + mode_ctrl = <0x144>; + name = "vpu_combo"; + status = "disabled"; }; iep: iep@10108000 { @@ -537,6 +577,24 @@ status = "disabled"; }; + cif_new: cif-new@1010a000 { + compatible = "rockchip,rk3128-cif"; + reg = <0x1010a000 0x200>; + + clocks = <&cru ACLK_CIF>, <&cru HCLK_CIF>, + <&cru SCLK_CIF_OUT>; + clock-names = "aclk_cif", "hclk_cif", + "sclk_cif_out"; + resets = <&cru SRST_CIF0>; + reset-names = "rst_cif"; + interrupts = ; + /* rk312x has not iommu attached */ + /* iommus = <&cif_mmu>; */ + power-domains = <&power RK3128_PD_VIO>; + + status = "disabled"; + }; + rga: rga@1010c000 { compatible = "rockchip,rk312x-rga"; reg = <0x1010c000 0x1000>; @@ -802,11 +860,11 @@ rockchip,grf = <&grf>; #clock-cells = <1>; #reset-cells = <1>; - assigned-clocks = <&cru PLL_GPLL>, <&cru PLL_CPLL>, + assigned-clocks = <&cru PLL_GPLL>, <&cru ACLK_CPU>, <&cru HCLK_CPU>, <&cru PCLK_CPU>, <&cru ACLK_PERI>, <&cru HCLK_PERI>, <&cru PCLK_PERI>; - assigned-clock-rates = <594000000>, <400000000>, + assigned-clock-rates = <594000000>, <300000000>, <150000000>, <75000000>, <300000000>, <150000000>, <75000000>; @@ -1393,7 +1451,7 @@ pwm2 { pwm2_pin: pwm2-pin { - rockchip,pins = <1 RK_PD4 1 &pcfg_pull_none>; + rockchip,pins = <0 RK_PD4 1 &pcfg_pull_none>; }; }; diff --git a/arch/arm/boot/dts/rk3288-evb-act8846.dts b/arch/arm/boot/dts/rk3288-evb-act8846.dts index 280f3c385d13a..9059dbed4e9cd 100644 --- a/arch/arm/boot/dts/rk3288-evb-act8846.dts +++ b/arch/arm/boot/dts/rk3288-evb-act8846.dts @@ -96,7 +96,7 @@ button-up { label = "Volume Up"; linux,code = ; - press-threshold-microvolt = <100000>; + press-threshold-microvolt = <18000>; }; button-down { diff --git a/arch/arm/boot/dts/rk3288-evb-rk808-linux.dts b/arch/arm/boot/dts/rk3288-evb-rk808-linux.dts index d40270752a405..d0487f8b794f0 100644 --- a/arch/arm/boot/dts/rk3288-evb-rk808-linux.dts +++ b/arch/arm/boot/dts/rk3288-evb-rk808-linux.dts @@ -41,6 +41,7 @@ /dts-v1/; #include "rk3288-evb.dtsi" #include "rk3288-linux.dtsi" +#include "rk3288-rkisp1.dtsi" / { compatible = "rockchip,rk3288-evb-rk808-linux", "rockchip,rk3288"; @@ -87,6 +88,44 @@ pwms = <&pwm0 0 1000000 PWM_POLARITY_INVERTED>; }; + adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 1>; + io-channel-names = "buttons"; + poll-interval = <100>; + keyup-threshold-microvolt = <1800000>; + + button-up { + label = "Volume Up"; + linux,code = ; + press-threshold-microvolt = <18000>; + }; + + button-down { + label = "Volume Down"; + linux,code = ; + press-threshold-microvolt = <300000>; + }; + + menu { + label = "Menu"; + linux,code = ; + press-threshold-microvolt = <640000>; + }; + + esc { + label = "Esc"; + linux,code = ; + press-threshold-microvolt = <1000000>; + }; + + home { + label = "Home"; + linux,code = ; + press-threshold-microvolt = <1300000>; + }; + }; + gpio-keys { compatible = "gpio-keys"; #address-cells = <1>; @@ -129,6 +168,17 @@ /delete-node/ sdmmc-regulator; + vcc18_dvp: vcc18-dvp { + compatible = "regulator-fixed"; + regulator-name = "vcc18_dvp"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + gpio = <&gpio0 RK_PC1 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-always-on; + vin-supply = <&vcc_io>; + }; + vdd_log: vdd-logic { compatible = "pwm-regulator"; rockchip,pwm_id = <1>; @@ -428,7 +478,7 @@ status = "okay"; audio-supply = <&vcc_io>; bb-supply = <&vcc_io>; - dvp-supply = <&vcc_io>; + dvp-supply = <&vcc18_dvp>; flash0-supply = <&vcc_18>; flash1-supply = <&vcc_io>; gpio30-supply = <&vcc_io>; @@ -441,48 +491,65 @@ &i2c3 { status = "okay"; - camera0: camera-module@10 { + ov13850: ov13850@10 { + compatible = "ovti,ov13850"; status = "okay"; - compatible = "omnivision,ov13850-v4l2-i2c-subdev"; reg = <0x10>; - device_type = "v4l2-i2c-subdev"; clocks = <&cru SCLK_VIP_OUT>; - clock-names = "clk_cif_out"; - pinctrl-names = "rockchip,camera_default", - "rockchip,camera_sleep"; - pinctrl-0 = <&cam0_default_pins>; - pinctrl-1 = <&cam0_sleep_pins>; - rockchip,pd-gpio = <&gpio2 15 GPIO_ACTIVE_LOW>; - rockchip,pwr-gpio = <&gpio0 17 GPIO_ACTIVE_HIGH>; - rockchip,rst-gpio = <&gpio7 21 GPIO_ACTIVE_LOW>; - rockchip,camera-module-mclk-name = "clk_cif_out"; - rockchip,camera-module-facing = "back"; - rockchip,camera-module-name = "cmk-cb0695-fv1"; - rockchip,camera-module-len-name = "lg9569a2"; - rockchip,camera-module-fov-h = "66.0"; - rockchip,camera-module-fov-v = "50.1"; - rockchip,camera-module-orientation = <0>; - rockchip,camera-module-iq-flip = <0>; - rockchip,camera-module-iq-mirror = <0>; - rockchip,camera-module-flip = <1>; - rockchip,camera-module-mirror = <0>; - rockchip,camera-module-defrect0 = <2112 1568 0 0 2112 1568>; - rockchip,camera-module-defrect1 = <4224 3136 0 0 4224 3136>; - rockchip,camera-module-defrect3 = <3264 2448 0 0 3264 2448>; - rockchip,camera-module-flash-support = <1>; - rockchip,camera-module-mipi-dphy-index = <0>; + clock-names = "xvclk"; + + reset-gpios = <&gpio7 21 GPIO_ACTIVE_HIGH>; + pwdn-gpios = <&gpio2 15 GPIO_ACTIVE_HIGH>; + + port { + cam_out: endpoint { + remote-endpoint = <&mipi_in_cam>; + data-lanes = <1 2>; + }; + }; }; }; -&cif_isp0 { - rockchip,camera-modules-attached = <&camera0>; +&isp { status = "okay"; + + port { + isp_mipi_in: endpoint { + remote-endpoint = <&dphy_rx0_out>; + }; + }; }; &isp_mmu { status = "okay"; }; +&mipi_phy_rx0 { + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + mipi_in_cam: endpoint { + remote-endpoint = <&cam_out>; + data-lanes = <1 2>; + }; + }; + + port@1 { + reg = <1>; + + dphy_rx0_out: endpoint { + remote-endpoint = <&isp_mipi_in>; + }; + }; + }; +}; + &rga { status = "okay"; }; @@ -517,17 +584,4 @@ rockchip,pins = <8 0 RK_FUNC_GPIO &pcfg_pull_none>; }; }; - - cam_pins { - cam0_default_pins: cam0-default-pins { - rockchip,pins = <0 17 RK_FUNC_GPIO &pcfg_pull_none>, - <2 15 RK_FUNC_GPIO &pcfg_pull_none>, - <2 11 RK_FUNC_1 &pcfg_pull_none>; - }; - cam0_sleep_pins: cam0-sleep-pins { - rockchip,pins = <0 17 RK_FUNC_GPIO &pcfg_pull_none>, - <2 15 RK_FUNC_GPIO &pcfg_pull_none>, - <2 11 RK_FUNC_GPIO &pcfg_pull_none>; - }; - }; }; diff --git a/arch/arm/boot/dts/rk3288-th804.dts b/arch/arm/boot/dts/rk3288-th804.dts index d92996b881d4b..8e26104313819 100644 --- a/arch/arm/boot/dts/rk3288-th804.dts +++ b/arch/arm/boot/dts/rk3288-th804.dts @@ -238,7 +238,8 @@ regulator-max-microvolt = <3300000>; regulator-name = "vcc_tp"; regulator-state-mem { - regulator-off-in-suspend; + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; }; }; @@ -574,10 +575,27 @@ status = "okay"; }; +&dsi0_in_vopl { + status = "disabled"; +}; + +&dsi0_in_vopb { + status = "okay"; +}; + &route_dsi0 { + connect = <&vopb_out_dsi0>; status = "okay"; }; +&hdmi_in_vopl { + status = "okay"; +}; + +&hdmi_in_vopb { + status = "disabled"; +}; + &hdmi { #address-cells = <1>; #size-cells = <0>; @@ -585,6 +603,11 @@ status = "okay"; }; +&route_hdmi { + connect = <&vopl_out_hdmi>; + status = "okay"; +}; + &hdmi_analog_sound { status = "okay"; compatible = "rockchip,rk3288-hdmi-analog", diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index cc19625d64bad..1b7602f25f343 100644 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -135,9 +135,11 @@ rockchip,avs-scale = <17>; rockchip,max-volt = <1350000>; nvmem-cells = <&cpu_leakage>, <&special_function>, - <&performance>, <&process_version>; + <&performance>, <&process_version>, + <&performance_w>; nvmem-cell-names = "leakage", "special", - "performance", "process"; + "performance", "process", + "performance-w"; rockchip,bin-scaling-sel = < 0 17 1 25 @@ -158,7 +160,7 @@ rockchip,pvtm-error = <1000>; rockchip,pvtm-ref-temp = <35>; rockchip,pvtm-temp-prop = <(-18) (-18)>; - rockchip,pvtm-thermal-zone = "soc-thermal"; + rockchip,thermal-zone = "soc-thermal"; opp-126000000 { opp-hz = /bits/ 64 <126000000>; @@ -1049,7 +1051,7 @@ <&cru ACLK_PERI>, <&cru HCLK_PERI>, <&cru PCLK_PERI>; assigned-clock-rates = <594000000>, - <500000000>, <300000000>, + <1250000000>, <300000000>, <150000000>, <75000000>, <300000000>, <150000000>, <75000000>; @@ -1726,8 +1728,8 @@ opp-hz = /bits/ 64 <300000000>; opp-microvolt = <1000000>; }; - opp-400000000 { - opp-hz = /bits/ 64 <400000000>; + opp-420000000 { + opp-hz = /bits/ 64 <420000000>; opp-microvolt = <1100000>; }; opp-500000000 { @@ -1798,6 +1800,10 @@ cpu_leakage: cpu-leakage@17 { reg = <0x17 0x1>; }; + performance_w: performance@1c { + reg = <0x1c 0x1>; + bits = <4 3>; + }; performance: performance@1d { reg = <0x1d 0x1>; bits = <4 3>; diff --git a/arch/arm/boot/dts/rk3308-dot-rk816-v10-aarch32.dts b/arch/arm/boot/dts/rk3308-dot-rk816-v10-aarch32.dts new file mode 100644 index 0000000000000..7f9ea8f041098 --- /dev/null +++ b/arch/arm/boot/dts/rk3308-dot-rk816-v10-aarch32.dts @@ -0,0 +1,493 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd + */ + +/dts-v1/; + +#include +#include "arm64/rockchip/rk3308.dtsi" + +/ { + model = "Rockchip RK3308 Dot Rk816-3 V10 (AArch32)"; + compatible = "rockchip,rk3308-dot-rk816-v10-aarch32", "rockchip,rk3308"; + + chosen { + bootargs = "earlycon=uart8250,mmio32,0xff0c0000 swiotlb=1 console=ttyFIQ0 root=PARTUUID=614e0000-0000 rootfstype=squashfs rootwait snd_aloop.index=7"; + }; + + acodec_sound: acodec-sound { + compatible = "rockchip,multicodecs-card"; + rockchip,card-name = "rockchip,rk3308-acodec"; + rockchip,codec-hp-det; + rockchip,mclk-fs = <256>; + rockchip,cpu = <&i2s_8ch_2>; + rockchip,codec = <&acodec>; + status = "okay"; + }; + + adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 1>; + io-channel-names = "buttons"; + poll-interval = <100>; + keyup-threshold-microvolt = <1800000>; + + esc-key { + linux,code = ; + label = "micmute"; + press-threshold-microvolt = <1130000>; + }; + + menu-key { + linux,code = ; + label = "play"; + press-threshold-microvolt = <624000>; + }; + + vol-down-key { + linux,code = ; + label = "volume down"; + press-threshold-microvolt = <300000>; + }; + + vol-up-key { + linux,code = ; + label = "volume up"; + press-threshold-microvolt = <18000>; + }; + }; + + charge-animation { + compatible = "rockchip,uboot-charge"; + status = "okay"; + }; + + dummy_codec: dummy-codec { + compatible = "rockchip,dummy-codec"; + #sound-dai-cells = <0>; + }; + + leds { + status = "okay"; + compatible = "gpio-leds"; + + red-led { + gpios = <&gpio2 RK_PA1 GPIO_ACTIVE_LOW>; + label = "redled"; + default-state = "off"; + linux,default-trigger = "default-off"; + }; + + green-led { + gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>; + label = "greenled"; + default-state = "off"; + linux,default-trigger = "default-off"; + }; + + blue-led { + gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>; + label = "blueled"; + default-state = "on"; + linux,default-trigger = "default-on"; + }; + }; + + pcm_codec: pcm-codec { + compatible = "delta,dfbmcs320"; + #sound-dai-cells = <0>; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_enable_h>; + + /* + * On the module itself this is one of these (depending + * on the actual card populated): + * - SDIO_RESET_L_WL_REG_ON + * - PDN (power down when low) + */ + reset-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>; + }; + + sound_pcm { + compatible = "simple-audio-card"; + simple-audio-card,format = "dsp_b"; + simple-audio-card,name = "rockchip,rk3308-pcm"; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,cpu { + sound-dai = <&i2s_2ch_0>; + }; + simple-audio-card,codec { + sound-dai = <&pcm_codec>; + }; + }; + + vad-sound { + status = "disabled"; + compatible = "rockchip,multicodecs-card"; + rockchip,card-name = "rockchip,rk3308-vad"; + rockchip,codec-hp-det; + rockchip,cpu = <&i2s_8ch_2>; + rockchip,codec = <&acodec>, <&vad>; + }; + + vcc_sys: vcc-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc_sys"; + regulator-min-microvolt = <4000000>; + regulator-max-microvolt = <4000000>; + regulator-always-on; + }; + + wireless-bluetooth { + compatible = "bluetooth-platdata"; + uart_rts_gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_LOW>; + pinctrl-names = "default", "rts_gpio"; + pinctrl-0 = <&uart4_rts>; + pinctrl-1 = <&uart4_rts_gpio>; + BT,power_gpio = <&gpio4 RK_PB3 GPIO_ACTIVE_HIGH>; + BT,wake_host_irq = <&gpio4 RK_PB4 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; + + wireless-wlan { + compatible = "wlan-platdata"; + rockchip,grf = <&grf>; + clocks = <&cru SCLK_WIFI>; + clock-names = "clk_wifi"; + ref-clock-frequency = <24000000>; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_wake_host>; + wifi_chip_type = "rtl8723ds"; + WIFI,host_wake_irq = <&gpio0 RK_PA0 GPIO_ACTIVE_LOW>; + status = "okay"; + }; +}; + +&i2c1 { + status = "okay"; + clock-frequency = <400000>; + + rk816: pmic@1a { + status = "okay"; + compatible = "rockchip,rk816"; + reg = <0x1a>; + interrupt-parent = <&gpio0>; + interrupts = <6 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int_l>; + rockchip,system-power-controller; + wakeup-source; + gpio-controller; + #gpio-cells = <2>; + #clock-cells = <1>; + clock-output-names = "rk816-clkout1", "rk816-clkout2"; + extcon = <&u2phy>; + + vcc1-supply = <&vcc_sys>; + vcc2-supply = <&vcc_sys>; + vcc3-supply = <&vcc_sys>; + vcc4-supply = <&vcc_sys>; + vcc5-supply = <&vcc_io>; + vcc6-supply = <&vcc_sys>; + + pwrkey { + status = "okay"; + }; + + gpio { + status = "okay"; + }; + + rtc { + status = "okay"; + }; + + battery { + compatible = "rk816-battery"; + ocv_table = <3400 3625 3685 3697 3718 3735 3748 + 3760 3774 3788 3802 3816 3834 3853 + 3877 3908 3946 3975 4018 4071 4106>; + design_capacity = <2750>; + design_qmax = <3000>; + bat_res = <110>; + max_input_current = <2000>; + max_chrg_current = <1800>; + max_chrg_voltage = <4200>; + sleep_enter_current = <300>; + sleep_exit_current = <300>; + sleep_filter_current = <100>; + power_off_thresd = <3400>; + zero_algorithm_vol = <3850>; + max_soc_offset = <80>; + monitor_sec = <5>; + virtual_power = <0>; + power_dc2otg = <0>; + dc_det_adc = <0>; + }; + + regulators { + vdd_core: DCDC_REG1{ + regulator-name = "vdd_core"; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1500000>; + regulator-ramp-delay = <6001>; + regulator-initial-mode = <1>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_log: DCDC_REG2 { + regulator-name = "vdd_logic"; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1500000>; + regulator-ramp-delay = <6001>; + regulator-initial-mode = <1>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <1>; + }; + + vcc_io: DCDC_REG4 { + regulator-name = "vcc_io"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-initial-mode = <1>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vcc_1v8_codec: LDO_REG1 { + regulator-name = "vcc_1v8_codec"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vccio_sdio: vcc_1v8: LDO_REG2 { + regulator-name = "vcc_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd_10: LDO_REG3 { + regulator-name = "vdd_10"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1800000>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + ldo4: LDO_REG4 { + regulator-name = "ldo4"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vccio_3v3: LDO_REG5 { + regulator-name = "vccio_3v3"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + ldo6: LDO_REG6 { + regulator-name = "ldo6"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + }; + }; +}; + +&acodec { + status = "okay"; + rockchip,no-deep-low-power; + rockchip,no-hp-det; + rockchip,loopback-grp = <1>; + pa-drv-gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>; + rockchip,delay-pa-drv-ms = <5>; + spk-ctl-gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>; + /* ADC5-8 for 4ch capture, loopback to ADC3-4 */ + rockchip,adc-grps-route = <2 3 1 0>; +}; + +&cpu0 { + cpu-supply = <&vdd_core>; +}; + +&cpu0_opp_table { + opp-1200000000 { + status = "okay"; + }; +}; + +&dmc { + center-supply = <&vdd_log>; + status = "okay"; +}; + +&fiq_debugger { + status = "okay"; +}; + +&i2s_2ch_0 { + status = "okay"; + #sound-dai-cells = <0>; +}; + +&i2s_8ch_2 { + status = "okay"; +}; + +&io_domains { + status = "okay"; + + vccio0-supply = <&vcc_io>; + vccio1-supply = <&vcc_io>; + vccio2-supply = <&vcc_io>; + vccio3-supply = <&vcc_io>; + vccio4-supply = <&vccio_sdio>; + vccio5-supply = <&vcc_io>; +}; + +&nandc { + status = "okay"; +}; + +&pinctrl { + sdio-pwrseq { + wifi_enable_h: wifi-enable-h { + rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + wireless-wlan { + wifi_wake_host: wifi-wake-host { + rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + pmic { + pmic_int_l: pmic-int-l { + rockchip,pins = + <0 6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&ramoops_mem { + reg = <0x0 0x30000 0x0 0x20000>; +}; + +&ramoops { + record-size = <0x0 0x00000>; + console-size = <0x0 0x20000>; +}; + +&rockchip_suspend { + rockchip,sleep-mode-config = < + (0 + | RKPM_ARMOFF + | RKPM_PMU_HW_PLLS_PD + | RKPM_DBG_FSM_SOUT + ) + >; + + status = "okay"; +}; + +&saradc { + status = "okay"; + vref-supply = <&vcc_1v8>; +}; + +&sdio { + max-frequency = <110000000>; + bus-width = <4>; + cap-sd-highspeed; + supports-sdio; + ignore-pm-notify; + keep-power-in-suspend; + non-removable; + mmc-pwrseq = <&sdio_pwrseq>; + sd-uhs-sdr104; + status = "okay"; +}; + +&sfc { + status = "okay"; +}; + +&tsadc { + rockchip,hw-tshut-mode = <0>; /* tshut mode 0:CRU 1:GPIO */ + rockchip,hw-tshut-polarity = <1>; /* tshut polarity 0:LOW 1:HIGH */ + status = "okay"; +}; + +&u2phy { + status = "okay"; + u2phy_otg: otg-port { + status = "okay"; + }; +}; + +&uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&uart4_xfer &uart4_cts>; + status = "okay"; +}; + +&usb20_otg { + status = "okay"; +}; + +&vad { + status = "disabled"; + rockchip,audio-src = <&i2s_8ch_2>; + rockchip,det-channel = <0>; + rockchip,mode = <1>; + rockchip,buffer-time-ms = <500>; + #sound-dai-cells = <0>; +}; diff --git a/arch/arm/boot/dts/rk3308-dot-v10-aarch32.dts b/arch/arm/boot/dts/rk3308-dot-v10-aarch32.dts new file mode 100644 index 0000000000000..02d0c48006b88 --- /dev/null +++ b/arch/arm/boot/dts/rk3308-dot-v10-aarch32.dts @@ -0,0 +1,303 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd + */ + +/dts-v1/; + +#include +#include "arm64/rockchip/rk3308.dtsi" + +/ { + model = "Rockchip RK3308 Dot V10 (AArch32)"; + compatible = "rockchip,rk3308-dot-v10-aarch32", "rockchip,rk3308"; + + chosen { + bootargs = "earlycon=uart8250,mmio32,0xff0c0000 swiotlb=1 console=ttyFIQ0 root=PARTUUID=614e0000-0000 rootfstype=squashfs rootwait snd_aloop.index=7"; + }; + + acodec_sound: acodec-sound { + compatible = "rockchip,multicodecs-card"; + rockchip,card-name = "rockchip,rk3308-acodec"; + rockchip,codec-hp-det; + rockchip,mclk-fs = <256>; + rockchip,cpu = <&i2s_8ch_2>; + rockchip,codec = <&acodec>; + status = "okay"; + }; + + adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 1>; + io-channel-names = "buttons"; + poll-interval = <100>; + keyup-threshold-microvolt = <1800000>; + + esc-key { + linux,code = ; + label = "micmute"; + press-threshold-microvolt = <1130000>; + }; + + menu-key { + linux,code = ; + label = "play"; + press-threshold-microvolt = <624000>; + }; + + vol-down-key { + linux,code = ; + label = "volume down"; + press-threshold-microvolt = <300000>; + }; + + vol-up-key { + linux,code = ; + label = "volume up"; + press-threshold-microvolt = <18000>; + }; + }; + + dummy_codec: dummy-codec { + compatible = "rockchip,dummy-codec"; + #sound-dai-cells = <0>; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_enable_h>; + + /* + * On the module itself this is one of these (depending + * on the actual card populated): + * - SDIO_RESET_L_WL_REG_ON + * - PDN (power down when low) + */ + reset-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>; + }; + + spdif_tx_sound: spdif-tx-sound { + status = "disabled"; + compatible = "simple-audio-card"; + simple-audio-card,name = "rockchip,spdif-tx-sound"; + simple-audio-card,cpu { + sound-dai = <&spdif_tx>; + }; + simple-audio-card,codec { + sound-dai = <&dummy_codec>; + }; + }; + + vad-sound { + status = "disabled"; + compatible = "rockchip,multicodecs-card"; + rockchip,card-name = "rockchip,rk3308-vad"; + rockchip,codec-hp-det; + rockchip,cpu = <&i2s_8ch_2>; + rockchip,codec = <&acodec>, <&vad>; + }; + + vdd_log: vdd_core: vdd-core { + compatible = "pwm-regulator"; + pwms = <&pwm0 0 5000 1>; + regulator-name = "vdd_core"; + regulator-min-microvolt = <827000>; + regulator-max-microvolt = <1340000>; + regulator-init-microvolt = <1015000>; + regulator-always-on; + regulator-boot-on; + regulator-settling-time-up-us = <250>; + status = "okay"; + }; + + vdd_1v0: vdd-1v0 { + compatible = "regulator-fixed"; + regulator-name = "vdd_1v0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + }; + + vcc_1v8: vcc-1v8 { + compatible = "regulator-fixed"; + regulator-name = "vcc_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc_io>; + }; + + vcc_ddr: vcc-ddr { + compatible = "regulator-fixed"; + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + }; + + vccio_sdio: vcc_io: vcc-io { + compatible = "regulator-fixed"; + regulator-name = "vcc_io"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + wireless-bluetooth { + compatible = "bluetooth-platdata"; + uart_rts_gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_LOW>; + pinctrl-names = "default", "rts_gpio"; + pinctrl-0 = <&uart4_rts>; + pinctrl-1 = <&uart4_rts_gpio>; + BT,power_gpio = <&gpio4 RK_PB3 GPIO_ACTIVE_HIGH>; + BT,wake_host_irq = <&gpio4 RK_PB4 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; + + wireless-wlan { + compatible = "wlan-platdata"; + rockchip,grf = <&grf>; + clocks = <&cru SCLK_WIFI>; + clock-names = "clk_wifi"; + ref-clock-frequency = <24000000>; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_wake_host>; + wifi_chip_type = "rtl8723ds"; + WIFI,host_wake_irq = <&gpio0 RK_PA0 GPIO_ACTIVE_LOW>; + status = "okay"; + }; +}; + +&acodec { + status = "okay"; + rockchip,no-deep-low-power; + rockchip,no-hp-det; + rockchip,loopback-grp = <1>; + spk-ctl-gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>; + /* ADC5-8 for 4ch capture, loopback to ADC3-4 */ + rockchip,adc-grps-route = <2 3 1 0>; +}; + +&cpu0 { + cpu-supply = <&vdd_core>; +}; + +&dmc { + center-supply = <&vdd_log>; + status = "okay"; +}; + +&fiq_debugger { + status = "okay"; +}; + +&i2s_8ch_2 { + status = "okay"; +}; + +&io_domains { + status = "okay"; + + vccio0-supply = <&vcc_io>; + vccio1-supply = <&vcc_io>; + vccio2-supply = <&vcc_1v8>; + vccio3-supply = <&vcc_io>; + vccio4-supply = <&vccio_sdio>; + vccio5-supply = <&vcc_io>; +}; + +&nandc { + status = "okay"; +}; + +&pinctrl { + sdio-pwrseq { + wifi_enable_h: wifi-enable-h { + rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + wireless-wlan { + wifi_wake_host: wifi-wake-host { + rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; + +&pwm0 { + status = "okay"; + pinctrl-names = "active"; + pinctrl-0 = <&pwm0_pin_pull_down>; +}; + +&ramoops_mem { + reg = <0x0 0x30000 0x0 0x20000>; +}; + +&ramoops { + record-size = <0x0 0x00000>; + console-size = <0x0 0x20000>; +}; + +&rockchip_suspend { + rockchip,pwm-regulator-config = < + (0 + | RKPM_PWM_REGULATOR + ) + >; + + status = "okay"; +}; + +&saradc { + status = "okay"; + vref-supply = <&vcc_1v8>; +}; + +&sdio { + max-frequency = <110000000>; + bus-width = <4>; + cap-sd-highspeed; + supports-sdio; + ignore-pm-notify; + keep-power-in-suspend; + non-removable; + mmc-pwrseq = <&sdio_pwrseq>; + sd-uhs-sdr104; + status = "okay"; +}; + +&sfc { + status = "okay"; +}; + +&tsadc { + rockchip,hw-tshut-mode = <0>; /* tshut mode 0:CRU 1:GPIO */ + rockchip,hw-tshut-polarity = <1>; /* tshut polarity 0:LOW 1:HIGH */ + status = "okay"; +}; + +&u2phy { + status = "okay"; + u2phy_otg: otg-port { + status = "okay"; + }; +}; + +&usb20_otg { + status = "okay"; +}; + +&vad { + status = "disabled"; + rockchip,audio-src = <&i2s_8ch_2>; + rockchip,det-channel = <0>; + rockchip,mode = <1>; + rockchip,buffer-time-ms = <500>; + #sound-dai-cells = <0>; +}; diff --git a/arch/arm/boot/dts/rk3308-voice-module-amic-mainboard-v10-aarch32.dts b/arch/arm/boot/dts/rk3308-voice-module-amic-mainboard-v10-aarch32.dts index a05ecdb37d727..f7d21cc7e6d0b 100644 --- a/arch/arm/boot/dts/rk3308-voice-module-amic-mainboard-v10-aarch32.dts +++ b/arch/arm/boot/dts/rk3308-voice-module-amic-mainboard-v10-aarch32.dts @@ -13,6 +13,15 @@ compatible = "rockchip,rk3308-voice-module-amic-mainboard-v10-aarch32", "rockchip,rk3308"; }; +&acodec { + /* The grp2/3 (ADC5-8) keeps enabled always for VAD */ + rockchip,en-always-grps = <2 3>; +}; + +&bluetooth_sound { + status = "okay"; +}; + &is31fl3236 { reg = <0x3f>; }; diff --git a/arch/arm/boot/dts/rk3308-voice-module-board-v10-aarch32.dts b/arch/arm/boot/dts/rk3308-voice-module-board-v10-aarch32.dts index f80efd24bdbd2..4b96198a4615c 100644 --- a/arch/arm/boot/dts/rk3308-voice-module-board-v10-aarch32.dts +++ b/arch/arm/boot/dts/rk3308-voice-module-board-v10-aarch32.dts @@ -24,14 +24,9 @@ &acodec { status = "okay"; - + rockchip,no-deep-low-power; /* ADC5-6 for 2ch capture, loopback to ADC3-4 */ rockchip,adc-grps-route = <2 1 3 0>; -}; - -&vad { - status = "disabled"; - rockchip,audio-src = <&i2s_8ch_2>; - rockchip,mode = <1>; - #sound-dai-cells = <0>; + /* The grp2 (ADC5-6) keeps enabled always for VAD */ + rockchip,en-always-grps = <2>; }; diff --git a/arch/arm/boot/dts/rk3308-voice-module-mainboard-v10-aarch32.dtsi b/arch/arm/boot/dts/rk3308-voice-module-mainboard-v10-aarch32.dtsi index 20c96fab67c31..36b1defbb57cb 100644 --- a/arch/arm/boot/dts/rk3308-voice-module-mainboard-v10-aarch32.dtsi +++ b/arch/arm/boot/dts/rk3308-voice-module-mainboard-v10-aarch32.dtsi @@ -26,6 +26,9 @@ wireless-wlan { compatible = "wlan-platdata"; rockchip,grf = <&grf>; + clocks = <&cru SCLK_WIFI>; + clock-names = "clk_wifi"; + ref-clock-frequency = <24000000>; pinctrl-names = "default"; pinctrl-0 = <&wifi_wake_host>; wifi_chip_type = "rtl8723ds"; @@ -36,8 +39,8 @@ &acodec { status = "okay"; - - /* ADC5-8 for 4ch capture, loopback to ADC3-4 */ + rockchip,no-deep-low-power; + /* ADC3-6 for 4ch capture, loopback to ADC7 */ rockchip,adc-grps-route = <2 3 1 0>; }; @@ -402,10 +405,3 @@ pinctrl-0 = <&uart4_xfer &uart4_cts>; status = "okay"; }; - -&vad { - status = "disabled"; - rockchip,audio-src = <&i2s_8ch_2>; - rockchip,mode = <1>; - #sound-dai-cells = <0>; -}; diff --git a/arch/arm/boot/dts/rk3308-voice-module-v10-aarch32.dtsi b/arch/arm/boot/dts/rk3308-voice-module-v10-aarch32.dtsi index 38ed89ede13f3..92c63ec178398 100644 --- a/arch/arm/boot/dts/rk3308-voice-module-v10-aarch32.dtsi +++ b/arch/arm/boot/dts/rk3308-voice-module-v10-aarch32.dtsi @@ -11,7 +11,7 @@ compatible = "rockchip,rk3308-vmb-v10", "rockchip,rk3308"; chosen { - bootargs = "earlycon=uart8250,mmio32,0xff0c0000 swiotlb=1 console=ttyFIQ0 root=PARTUUID=614e0000-0000 rootfstype=squashfs rootwait"; + bootargs = "earlycon=uart8250,mmio32,0xff0c0000 swiotlb=1 console=ttyFIQ0 root=PARTUUID=614e0000-0000 rootfstype=squashfs rootwait snd_aloop.index=7"; }; adc-keys { @@ -21,9 +21,33 @@ poll-interval = <100>; keyup-threshold-microvolt = <1800000>; - recovery-key { - linux,code = ; - label = "recovery"; + esc-key { + linux,code = ; + label = "micmute"; + press-threshold-microvolt = <1130000>; + }; + + home-key { + linux,code = ; + label = "mode"; + press-threshold-microvolt = <901000>; + }; + + menu-key { + linux,code = ; + label = "play"; + press-threshold-microvolt = <624000>; + }; + + vol-down-key { + linux,code = ; + label = "volume down"; + press-threshold-microvolt = <300000>; + }; + + vol-up-key { + linux,code = ; + label = "volume up"; press-threshold-microvolt = <18000>; }; }; @@ -70,6 +94,18 @@ rockchip,mclk-fs = <256>; rockchip,cpu = <&i2s_8ch_2>; rockchip,codec = <&acodec>; + status = "disabled"; + }; + + bluetooth_sound: bluetooth-sound { + status = "disabled"; + compatible = "rockchip,multicodecs-card"; + rockchip,card-name = "rockchip,rk3308-pcm"; + rockchip,mclk-fs = <128>; + rockchip,cpu = <&i2s_2ch_0>; + rockchip,codec = <&dummy_codec>; + rockchip,format = "dsp_b"; + rockchip,wait-card-locked = <0>; }; spdif_tx_sound: spdif-tx-sound { @@ -84,6 +120,15 @@ }; }; + vad-sound { + status = "okay"; + compatible = "rockchip,multicodecs-card"; + rockchip,card-name = "rockchip,rk3308-vad"; + rockchip,codec-hp-det; + rockchip,cpu = <&i2s_8ch_2>; + rockchip,codec = <&acodec>, <&vad>; + }; + vdd_log: vdd_core: vdd-core { compatible = "pwm-regulator"; pwms = <&pwm0 0 5000 1>; @@ -147,6 +192,8 @@ &acodec { status = "disabled"; + rockchip,no-hp-det; + rockchip,delay-start-play-ms = <200>; rockchip,loopback-grp = <1>; spk-ctl-gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>; }; @@ -175,6 +222,10 @@ vccio5-supply = <&vcc_io>; }; +&i2s_2ch_0 { + status = "okay"; +}; + &i2s_8ch_2 { status = "okay"; }; @@ -192,6 +243,10 @@ console-size = <0x0 0x20000>; }; +&rk_timer_rtc { + status = "okay"; +}; + &rockchip_suspend { rockchip,pwm-regulator-config = < (0 @@ -199,6 +254,17 @@ ) >; + rockchip,wakeup-config = < + (0 + | RKPM_GPIO0_WAKEUP_EN + | RKPM_TIMER_WAKEUP_EN + ) + >; + + status = "okay"; +}; + +&rng { status = "okay"; }; @@ -261,6 +327,11 @@ pinctrl-0 = <&pwm0_pin_pull_down>; }; +&sfc { + u-boot,dm-pre-reloc; + status = "okay"; +}; + &tsadc { rockchip,hw-tshut-mode = <0>; /* tshut mode 0:CRU 1:GPIO */ rockchip,hw-tshut-polarity = <1>; /* tshut polarity 0:LOW 1:HIGH */ @@ -291,3 +362,12 @@ &usb_host0_ohci{ status = "okay"; }; + +&vad { + status = "okay"; + rockchip,audio-src = <&i2s_8ch_2>; + rockchip,det-channel = <0>; + rockchip,mode = <1>; + rockchip,buffer-time-ms = <500>; + #sound-dai-cells = <0>; +}; diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi index 39c470e291f96..69381deeb7036 100644 --- a/arch/arm/boot/dts/socfpga.dtsi +++ b/arch/arm/boot/dts/socfpga.dtsi @@ -738,7 +738,7 @@ timer@fffec600 { compatible = "arm,cortex-a9-twd-timer"; reg = <0xfffec600 0x100>; - interrupts = <1 13 0xf04>; + interrupts = <1 13 0xf01>; clocks = <&mpu_periph_clk>; }; diff --git a/arch/arm/configs/imx_v4_v5_defconfig b/arch/arm/configs/imx_v4_v5_defconfig index d3a8018639de2..f4a2d28936e1e 100644 --- a/arch/arm/configs/imx_v4_v5_defconfig +++ b/arch/arm/configs/imx_v4_v5_defconfig @@ -145,9 +145,11 @@ CONFIG_USB_STORAGE=y CONFIG_USB_CHIPIDEA=y CONFIG_USB_CHIPIDEA_UDC=y CONFIG_USB_CHIPIDEA_HOST=y +CONFIG_USB_CHIPIDEA_ULPI=y CONFIG_NOP_USB_XCEIV=y CONFIG_USB_GADGET=y CONFIG_USB_ETH=m +CONFIG_USB_ULPI_BUS=y CONFIG_MMC=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig index 4187f69f66304..b3490c1c49d1b 100644 --- a/arch/arm/configs/imx_v6_v7_defconfig +++ b/arch/arm/configs/imx_v6_v7_defconfig @@ -261,6 +261,7 @@ CONFIG_USB_STORAGE=y CONFIG_USB_CHIPIDEA=y CONFIG_USB_CHIPIDEA_UDC=y CONFIG_USB_CHIPIDEA_HOST=y +CONFIG_USB_CHIPIDEA_ULPI=y CONFIG_USB_SERIAL=m CONFIG_USB_SERIAL_GENERIC=y CONFIG_USB_SERIAL_FTDI_SIO=m @@ -287,6 +288,7 @@ CONFIG_USB_G_NCM=m CONFIG_USB_GADGETFS=m CONFIG_USB_MASS_STORAGE=m CONFIG_USB_G_SERIAL=m +CONFIG_USB_ULPI_BUS=y CONFIG_MMC=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y diff --git a/arch/arm/configs/rk3308_linux_aarch32_debug_defconfig b/arch/arm/configs/rk3308_linux_aarch32_debug_defconfig index 648ace1e8a38e..afa6ac27b3e1a 100644 --- a/arch/arm/configs/rk3308_linux_aarch32_debug_defconfig +++ b/arch/arm/configs/rk3308_linux_aarch32_debug_defconfig @@ -1,11 +1,17 @@ # CONFIG_LOCALVERSION_AUTO is not set +CONFIG_KERNEL_LZ4=y CONFIG_DEFAULT_HOSTNAME="localhost" -# CONFIG_SWAP is not set CONFIG_SYSVIPC=y CONFIG_FHANDLE=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_LOG_CPU_MAX_BUF_SHIFT=0 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_XZ is not set +# CONFIG_RD_LZO is not set +# CONFIG_RD_LZ4 is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y # CONFIG_BASE_FULL is not set CONFIG_EMBEDDED=y @@ -29,10 +35,13 @@ CONFIG_ARM_PSCI=y CONFIG_PREEMPT=y CONFIG_HZ_1000=y CONFIG_THUMB2_KERNEL=y +# CONFIG_CPU_SW_DOMAIN_PAN is not set # CONFIG_COMPACTION is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=32768 +CONFIG_ZSMALLOC=y +CONFIG_UACCESS_WITH_MEMCPY=y # CONFIG_SWIOTLB is not set -CONFIG_CMDLINE="coherent_pool=0 user_debug=31" +CONFIG_CMDLINE="coherent_pool=4k user_debug=31" CONFIG_CMDLINE_EXTEND=y CONFIG_CPU_FREQ=y # CONFIG_CPU_FREQ_TIMES is not set @@ -74,7 +83,8 @@ CONFIG_RFKILL=y CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y # CONFIG_ALLOW_DEV_COREDUMP is not set -# CONFIG_BLK_DEV is not set +CONFIG_ZRAM=y +CONFIG_ZRAM_LZ4_COMPRESS=y CONFIG_NETDEVICES=y # CONFIG_NET_CORE is not set # CONFIG_ETHERNET is not set @@ -89,6 +99,7 @@ CONFIG_KEYBOARD_ADC=y CONFIG_KEYBOARD_GPIO=y # CONFIG_INPUT_MOUSE is not set CONFIG_INPUT_MISC=y +CONFIG_INPUT_RK8XX_PWRKEY=y CONFIG_INPUT_GPIO_ROTARY_ENCODER=y # CONFIG_SERIO is not set # CONFIG_VT is not set @@ -100,7 +111,8 @@ CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=5 CONFIG_SERIAL_8250_RUNTIME_UARTS=5 CONFIG_SERIAL_8250_DW=y -# CONFIG_HW_RANDOM is not set +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_ROCKCHIP=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_MUX=y @@ -111,6 +123,7 @@ CONFIG_SPI_SPIDEV=y CONFIG_DEBUG_GPIO=y CONFIG_GPIO_SYSFS=y CONFIG_POWER_SUPPLY=y +CONFIG_BATTERY_RK816=y CONFIG_POWER_RESET=y CONFIG_SYSCON_REBOOT_MODE=y CONFIG_POWER_AVS=y @@ -125,14 +138,16 @@ CONFIG_DEVFREQ_THERMAL=y CONFIG_ROCKCHIP_THERMAL=y CONFIG_WATCHDOG=y CONFIG_DW_WATCHDOG=y +CONFIG_MFD_RK808=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_GPIO=y CONFIG_REGULATOR_PWM=y +CONFIG_REGULATOR_RK808=y CONFIG_SOUND=y CONFIG_SND=y CONFIG_SND_HRTIMER=y # CONFIG_SND_SUPPORT_OLD_API is not set -# CONFIG_SND_DRIVERS is not set +CONFIG_SND_ALOOP=y # CONFIG_SND_SPI is not set CONFIG_SND_SOC=y CONFIG_SND_SOC_ROCKCHIP=y @@ -170,6 +185,8 @@ CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_LEDS_TRIGGER_DEFAULT_ON=y CONFIG_LEDS_TRIGGER_MULTI_CTRL=y CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_RK808=y +CONFIG_RTC_DRV_RK_TIMER=y CONFIG_DMADEVICES=y CONFIG_PL330_DMA=y CONFIG_STAGING=y @@ -209,7 +226,10 @@ CONFIG_PHY_ROCKCHIP_INNO_USB2=y CONFIG_ANDROID=y CONFIG_NVMEM=y CONFIG_ROCKCHIP_OTP=y -CONFIG_RK_NAND=y +CONFIG_RK_FLASH=y +CONFIG_RK_NANDC_NAND=y +CONFIG_RK_SFC_NAND=y +CONFIG_RK_SFC_NOR=y CONFIG_ROCKCHIP_SIP=y CONFIG_EXT2_FS=y CONFIG_EXT4_FS=m @@ -220,6 +240,7 @@ CONFIG_NTFS_FS=m CONFIG_TMPFS=y CONFIG_SQUASHFS=y CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y +CONFIG_SQUASHFS_LZ4=y CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y CONFIG_PSTORE=y CONFIG_PSTORE_CONSOLE=y diff --git a/arch/arm/configs/rk3308_linux_aarch32_defconfig b/arch/arm/configs/rk3308_linux_aarch32_defconfig index 3631d4ac3cfba..c149cf09562dc 100644 --- a/arch/arm/configs/rk3308_linux_aarch32_defconfig +++ b/arch/arm/configs/rk3308_linux_aarch32_defconfig @@ -1,11 +1,17 @@ # CONFIG_LOCALVERSION_AUTO is not set +CONFIG_KERNEL_LZ4=y CONFIG_DEFAULT_HOSTNAME="localhost" -# CONFIG_SWAP is not set CONFIG_SYSVIPC=y CONFIG_FHANDLE=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_LOG_CPU_MAX_BUF_SHIFT=0 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_XZ is not set +# CONFIG_RD_LZO is not set +# CONFIG_RD_LZ4 is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y # CONFIG_BASE_FULL is not set CONFIG_EMBEDDED=y @@ -29,10 +35,13 @@ CONFIG_ARM_PSCI=y CONFIG_PREEMPT=y CONFIG_HZ_1000=y CONFIG_THUMB2_KERNEL=y +# CONFIG_CPU_SW_DOMAIN_PAN is not set # CONFIG_COMPACTION is not set CONFIG_DEFAULT_MMAP_MIN_ADDR=32768 +CONFIG_ZSMALLOC=y +CONFIG_UACCESS_WITH_MEMCPY=y # CONFIG_SWIOTLB is not set -CONFIG_CMDLINE="coherent_pool=0 loglevel=0" +CONFIG_CMDLINE="coherent_pool=4k loglevel=0" CONFIG_CMDLINE_EXTEND=y CONFIG_CPU_FREQ=y # CONFIG_CPU_FREQ_TIMES is not set @@ -74,7 +83,8 @@ CONFIG_RFKILL=y CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y # CONFIG_ALLOW_DEV_COREDUMP is not set -# CONFIG_BLK_DEV is not set +CONFIG_ZRAM=y +CONFIG_ZRAM_LZ4_COMPRESS=y CONFIG_NETDEVICES=y # CONFIG_NET_CORE is not set # CONFIG_ETHERNET is not set @@ -100,7 +110,8 @@ CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=5 CONFIG_SERIAL_8250_RUNTIME_UARTS=5 CONFIG_SERIAL_8250_DW=y -# CONFIG_HW_RANDOM is not set +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_ROCKCHIP=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_MUX=y @@ -132,7 +143,7 @@ CONFIG_SOUND=y CONFIG_SND=y CONFIG_SND_HRTIMER=y # CONFIG_SND_SUPPORT_OLD_API is not set -# CONFIG_SND_DRIVERS is not set +CONFIG_SND_ALOOP=y # CONFIG_SND_SPI is not set CONFIG_SND_SOC=y CONFIG_SND_SOC_ROCKCHIP=y @@ -170,6 +181,7 @@ CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_LEDS_TRIGGER_DEFAULT_ON=y CONFIG_LEDS_TRIGGER_MULTI_CTRL=y CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_RK_TIMER=y CONFIG_DMADEVICES=y CONFIG_PL330_DMA=y CONFIG_STAGING=y @@ -209,7 +221,10 @@ CONFIG_PHY_ROCKCHIP_INNO_USB2=m CONFIG_ANDROID=y CONFIG_NVMEM=y CONFIG_ROCKCHIP_OTP=y -CONFIG_RK_NAND=y +CONFIG_RK_FLASH=y +CONFIG_RK_NANDC_NAND=y +CONFIG_RK_SFC_NAND=y +CONFIG_RK_SFC_NOR=y CONFIG_ROCKCHIP_SIP=y CONFIG_EXT2_FS=y CONFIG_EXT4_FS=m @@ -220,6 +235,7 @@ CONFIG_NTFS_FS=m CONFIG_TMPFS=y CONFIG_SQUASHFS=y CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y +CONFIG_SQUASHFS_LZ4=y CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y CONFIG_PSTORE=y CONFIG_PSTORE_CONSOLE=y diff --git a/arch/arm/configs/rockchip_defconfig b/arch/arm/configs/rockchip_defconfig index c69c1a0e1a81f..a5c7dbbaa3dcb 100644 --- a/arch/arm/configs/rockchip_defconfig +++ b/arch/arm/configs/rockchip_defconfig @@ -74,7 +74,7 @@ CONFIG_CPU_IDLE=y CONFIG_VFP=y CONFIG_NEON=y CONFIG_KERNEL_MODE_NEON=y -# CONFIG_COREDUMP is not set +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_PM_AUTOSLEEP=y CONFIG_PM_WAKELOCKS=y CONFIG_PM_WAKELOCKS_LIMIT=0 @@ -93,6 +93,7 @@ CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_VERBOSE=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y +CONFIG_NET_IPVTI=y CONFIG_INET_AH=y CONFIG_INET_ESP=y CONFIG_INET_IPCOMP=y @@ -105,6 +106,7 @@ CONFIG_INET6_AH=y CONFIG_INET6_ESP=y CONFIG_INET6_IPCOMP=y CONFIG_IPV6_MIP6=y +CONFIG_IPV6_VTI=y CONFIG_IPV6_MULTIPLE_TABLES=y CONFIG_IPV6_SUBTREES=y CONFIG_NETFILTER=y @@ -242,6 +244,7 @@ CONFIG_DM_CRYPT=y CONFIG_DM_UEVENT=y CONFIG_DM_VERITY=y CONFIG_DM_VERITY_FEC=y +CONFIG_DM_VERITY_AVB=y CONFIG_NETDEVICES=y CONFIG_TUN=y # CONFIG_NET_VENDOR_ARC is not set @@ -319,6 +322,7 @@ CONFIG_RTL8723BS=m CONFIG_RTL8723BU=m CONFIG_RTL8723CS=m CONFIG_RTL8723DS=m +CONFIG_SSV6051=m # CONFIG_INPUT_MOUSEDEV is not set CONFIG_INPUT_EVDEV=y CONFIG_INPUT_KEYRESET=y @@ -376,8 +380,8 @@ CONFIG_BATTERY_EC=y CONFIG_BATTERY_CW2015=y CONFIG_BATTERY_RK816=y CONFIG_BATTERY_RK818=y -CONFIG_POWER_RESET=y CONFIG_CHARGER_RK818=y +CONFIG_POWER_RESET=y CONFIG_SYSCON_REBOOT_MODE=y CONFIG_POWER_AVS=y CONFIG_ROCKCHIP_IODOMAIN=y @@ -403,8 +407,6 @@ CONFIG_REGULATOR_RK808=y CONFIG_REGULATOR_RK818=y CONFIG_REGULATOR_SYR82X=y CONFIG_REGULATOR_XZ3216=y -CONFIG_CEC_CORE=y -CONFIG_CEC_NOTIFIER=y CONFIG_MEDIA_SUPPORT=y CONFIG_MEDIA_CAMERA_SUPPORT=y CONFIG_MEDIA_RC_SUPPORT=y @@ -414,6 +416,10 @@ CONFIG_VIDEO_V4L2_SUBDEV_API=y CONFIG_MEDIA_USB_SUPPORT=y CONFIG_USB_VIDEO_CLASS=y CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_VIDEO_ROCKCHIP_CIF=y +# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set +CONFIG_VIDEO_GC2145=y +CONFIG_VIDEO_GC0329=y CONFIG_CAMSYS_DRV=y CONFIG_FLASHLIGHT=y CONFIG_LEDS_RT8547=y @@ -588,6 +594,7 @@ CONFIG_USB_CONFIGFS_F_ACC=y CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y CONFIG_USB_CONFIGFS_UEVENT=y CONFIG_USB_CONFIGFS_F_MIDI=y +CONFIG_USB_CONFIGFS_F_UVC=y CONFIG_USB20_HOST=y CONFIG_USB20_OTG=y CONFIG_MMC=y @@ -693,6 +700,7 @@ CONFIG_SCHEDSTATS=y CONFIG_TIMER_STATS=y # CONFIG_DEBUG_PREEMPT is not set CONFIG_ENABLE_DEFAULT_TRACERS=y +CONFIG_DEBUG_SET_MODULE_RONX=y CONFIG_KEYS=y CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y @@ -701,7 +709,6 @@ CONFIG_LSM_MMAP_MIN_ADDR=4096 CONFIG_HARDENED_USERCOPY=y CONFIG_SECURITY_SELINUX=y CONFIG_TEE_SUPPORT=y -CONFIG_CRYPTO_ECHAINIV=y CONFIG_CRYPTO_SHA512=y CONFIG_CRYPTO_TWOFISH=y CONFIG_CRYPTO_ANSI_CPRNG=y diff --git a/arch/arm/configs/rockchip_linux_defconfig b/arch/arm/configs/rockchip_linux_defconfig index f1cec6866df35..4eb7c9023b32c 100644 --- a/arch/arm/configs/rockchip_linux_defconfig +++ b/arch/arm/configs/rockchip_linux_defconfig @@ -232,6 +232,7 @@ CONFIG_TOUCHSCREEN_GT9XX=y CONFIG_TOUCHSCREEN_ELAN=y CONFIG_TOUCHSCREEN_USB_COMPOSITE=y CONFIG_INPUT_MISC=y +CONFIG_INPUT_RK8XX_PWRKEY=y CONFIG_INPUT_UINPUT=y CONFIG_INPUT_GPIO_ROTARY_ENCODER=y CONFIG_SERIO_RAW=y @@ -294,13 +295,14 @@ CONFIG_USB_VIDEO_CLASS=y # CONFIG_USB_GSPCA is not set CONFIG_V4L_PLATFORM_DRIVERS=y CONFIG_SOC_CAMERA=y -CONFIG_VIDEO_RK_CIF_ISP10=y +CONFIG_VIDEO_ROCKCHIP_CIF=y CONFIG_VIDEO_ROCKCHIP_ISP1=y CONFIG_V4L_MEM2MEM_DRIVERS=y CONFIG_VIDEO_ROCKCHIP_RGA=y CONFIG_VIDEO_ROCKCHIP_VPU=y CONFIG_V4L_TEST_DRIVERS=y # CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set +CONFIG_VIDEO_ADV7181D=y CONFIG_VIDEO_TC35874X=y CONFIG_VIDEO_IMX219=y CONFIG_VIDEO_OV5647=y diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index 2c16d9e7c03ca..4a275fba6059d 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h @@ -530,4 +530,14 @@ THUMB( orr \reg , \reg , #PSR_T_BIT ) #endif .endm +#ifdef CONFIG_KPROBES +#define _ASM_NOKPROBE(entry) \ + .pushsection "_kprobe_blacklist", "aw" ; \ + .balign 4 ; \ + .long entry; \ + .popsection +#else +#define _ASM_NOKPROBE(entry) +#endif + #endif /* __ASM_ASSEMBLER_H__ */ diff --git a/arch/arm/include/asm/futex.h b/arch/arm/include/asm/futex.h index 6795368ad0238..cc414382dab4b 100644 --- a/arch/arm/include/asm/futex.h +++ b/arch/arm/include/asm/futex.h @@ -128,20 +128,10 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, #endif /* !SMP */ static inline int -futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) +arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret, tmp; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; - #ifndef CONFIG_SMP preempt_disable(); #endif @@ -172,17 +162,9 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) preempt_enable(); #endif - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/arm/include/asm/kgdb.h b/arch/arm/include/asm/kgdb.h index 0a9d5dd932941..6949c7d4481c4 100644 --- a/arch/arm/include/asm/kgdb.h +++ b/arch/arm/include/asm/kgdb.h @@ -76,7 +76,7 @@ extern int kgdb_fault_expected; #define KGDB_MAX_NO_CPUS 1 #define BUFMAX 400 -#define NUMREGBYTES (DBG_MAX_REG_NUM << 2) +#define NUMREGBYTES (GDB_MAX_REGS << 2) #define NUMCRITREGBYTES (32 << 2) #define _R0 0 diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h index 7fb59199c6bbb..7665bd2f48718 100644 --- a/arch/arm/include/asm/uaccess.h +++ b/arch/arm/include/asm/uaccess.h @@ -251,7 +251,7 @@ extern int __put_user_8(void *, unsigned long long); ({ \ unsigned long __limit = current_thread_info()->addr_limit - 1; \ const typeof(*(p)) __user *__tmp_p = (p); \ - register const typeof(*(p)) __r2 asm("r2") = (x); \ + register typeof(*(p)) __r2 asm("r2") = (x); \ register const typeof(*(p)) __user *__p asm("r0") = __tmp_p; \ register unsigned long __l asm("r1") = __limit; \ register int __e asm("r0"); \ diff --git a/arch/arm/include/asm/vdso.h b/arch/arm/include/asm/vdso.h index d0295f1dd1a38..ff65b6d96c7ef 100644 --- a/arch/arm/include/asm/vdso.h +++ b/arch/arm/include/asm/vdso.h @@ -11,8 +11,6 @@ struct mm_struct; void arm_install_vdso(struct mm_struct *mm, unsigned long addr); -extern char vdso_start, vdso_end; - extern unsigned int vdso_total_pages; #else /* CONFIG_VDSO */ diff --git a/arch/arm/include/uapi/asm/setup.h b/arch/arm/include/uapi/asm/setup.h index b4d1bea21a2d2..ebe54c5963ae5 100644 --- a/arch/arm/include/uapi/asm/setup.h +++ b/arch/arm/include/uapi/asm/setup.h @@ -16,7 +16,7 @@ #include -#define COMMAND_LINE_SIZE 2048 +#define COMMAND_LINE_SIZE 4096 /* The list ends with an ATAG_NONE node. */ #define ATAG_NONE 0x00000000 diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index c92b535150a0e..306a2a5817854 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -395,7 +396,8 @@ void unregister_undef_hook(struct undef_hook *hook) raw_spin_unlock_irqrestore(&undef_lock, flags); } -static int call_undef_hook(struct pt_regs *regs, unsigned int instr) +static nokprobe_inline +int call_undef_hook(struct pt_regs *regs, unsigned int instr) { struct undef_hook *hook; unsigned long flags; @@ -468,6 +470,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs) arm_notify_die("Oops - undefined instruction", regs, &info, 0, 6); } +NOKPROBE_SYMBOL(do_undefinstr) /* * Handle FIQ similarly to NMI on x86 systems. diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c index bbbffe9461221..6f7772feababf 100644 --- a/arch/arm/kernel/vdso.c +++ b/arch/arm/kernel/vdso.c @@ -39,6 +39,8 @@ static struct page **vdso_text_pagelist; +extern char vdso_start[], vdso_end[]; + /* Total number of pages needed for the data and text portions of the VDSO. */ unsigned int vdso_total_pages __ro_after_init; @@ -179,13 +181,13 @@ static int __init vdso_init(void) unsigned int text_pages; int i; - if (memcmp(&vdso_start, "\177ELF", 4)) { + if (memcmp(vdso_start, "\177ELF", 4)) { pr_err("VDSO is not a valid ELF object!\n"); return -ENOEXEC; } - text_pages = (&vdso_end - &vdso_start) >> PAGE_SHIFT; - pr_debug("vdso: %i text pages at base %p\n", text_pages, &vdso_start); + text_pages = (vdso_end - vdso_start) >> PAGE_SHIFT; + pr_debug("vdso: %i text pages at base %p\n", text_pages, vdso_start); /* Allocate the VDSO text pagelist */ vdso_text_pagelist = kcalloc(text_pages, sizeof(struct page *), @@ -200,7 +202,7 @@ static int __init vdso_init(void) for (i = 0; i < text_pages; i++) { struct page *page; - page = virt_to_page(&vdso_start + i * PAGE_SIZE); + page = virt_to_page(vdso_start + i * PAGE_SIZE); vdso_text_pagelist[i] = page; } @@ -211,7 +213,7 @@ static int __init vdso_init(void) cntvct_ok = cntvct_functional(); - patch_vdso(&vdso_start); + patch_vdso(vdso_start); return 0; } diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index 4c055a63c9c65..f2c4207ac70a5 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c @@ -899,19 +899,35 @@ static int stage2_set_pmd_huge(struct kvm *kvm, struct kvm_mmu_memory_cache pmd = stage2_get_pmd(kvm, cache, addr); VM_BUG_ON(!pmd); - /* - * Mapping in huge pages should only happen through a fault. If a - * page is merged into a transparent huge page, the individual - * subpages of that huge page should be unmapped through MMU - * notifiers before we get here. - * - * Merging of CompoundPages is not supported; they should become - * splitting first, unmapped, merged, and mapped back in on-demand. - */ - VM_BUG_ON(pmd_present(*pmd) && pmd_pfn(*pmd) != pmd_pfn(*new_pmd)); - old_pmd = *pmd; if (pmd_present(old_pmd)) { + /* + * Multiple vcpus faulting on the same PMD entry, can + * lead to them sequentially updating the PMD with the + * same value. Following the break-before-make + * (pmd_clear() followed by tlb_flush()) process can + * hinder forward progress due to refaults generated + * on missing translations. + * + * Skip updating the page table if the entry is + * unchanged. + */ + if (pmd_val(old_pmd) == pmd_val(*new_pmd)) + return 0; + + /* + * Mapping in huge pages should only happen through a + * fault. If a page is merged into a transparent huge + * page, the individual subpages of that huge page + * should be unmapped through MMU notifiers before we + * get here. + * + * Merging of CompoundPages is not supported; they + * should become splitting first, unmapped, merged, + * and mapped back in on-demand. + */ + VM_BUG_ON(pmd_pfn(old_pmd) != pmd_pfn(*new_pmd)); + pmd_clear(pmd); kvm_tlb_flush_vmid_ipa(kvm, addr); } else { @@ -968,6 +984,10 @@ static int stage2_set_pte(struct kvm *kvm, struct kvm_mmu_memory_cache *cache, /* Create 2nd stage page table mapping - Level 3 */ old_pte = *pte; if (pte_present(old_pte)) { + /* Skip page table update if there is no change */ + if (pte_val(old_pte) == pte_val(*new_pte)) + return 0; + kvm_set_pte(pte, __pte(0)); kvm_tlb_flush_vmid_ipa(kvm, addr); } else { diff --git a/arch/arm/lib/getuser.S b/arch/arm/lib/getuser.S index df73914e81c83..746e7801dcdf7 100644 --- a/arch/arm/lib/getuser.S +++ b/arch/arm/lib/getuser.S @@ -38,6 +38,7 @@ ENTRY(__get_user_1) mov r0, #0 ret lr ENDPROC(__get_user_1) +_ASM_NOKPROBE(__get_user_1) ENTRY(__get_user_2) check_uaccess r0, 2, r1, r2, __get_user_bad @@ -58,6 +59,7 @@ rb .req r0 mov r0, #0 ret lr ENDPROC(__get_user_2) +_ASM_NOKPROBE(__get_user_2) ENTRY(__get_user_4) check_uaccess r0, 4, r1, r2, __get_user_bad @@ -65,6 +67,7 @@ ENTRY(__get_user_4) mov r0, #0 ret lr ENDPROC(__get_user_4) +_ASM_NOKPROBE(__get_user_4) ENTRY(__get_user_8) check_uaccess r0, 8, r1, r2, __get_user_bad8 @@ -78,6 +81,7 @@ ENTRY(__get_user_8) mov r0, #0 ret lr ENDPROC(__get_user_8) +_ASM_NOKPROBE(__get_user_8) #ifdef __ARMEB__ ENTRY(__get_user_32t_8) @@ -91,6 +95,7 @@ ENTRY(__get_user_32t_8) mov r0, #0 ret lr ENDPROC(__get_user_32t_8) +_ASM_NOKPROBE(__get_user_32t_8) ENTRY(__get_user_64t_1) check_uaccess r0, 1, r1, r2, __get_user_bad8 @@ -98,6 +103,7 @@ ENTRY(__get_user_64t_1) mov r0, #0 ret lr ENDPROC(__get_user_64t_1) +_ASM_NOKPROBE(__get_user_64t_1) ENTRY(__get_user_64t_2) check_uaccess r0, 2, r1, r2, __get_user_bad8 @@ -114,6 +120,7 @@ rb .req r0 mov r0, #0 ret lr ENDPROC(__get_user_64t_2) +_ASM_NOKPROBE(__get_user_64t_2) ENTRY(__get_user_64t_4) check_uaccess r0, 4, r1, r2, __get_user_bad8 @@ -121,6 +128,7 @@ ENTRY(__get_user_64t_4) mov r0, #0 ret lr ENDPROC(__get_user_64t_4) +_ASM_NOKPROBE(__get_user_64t_4) #endif __get_user_bad8: @@ -131,6 +139,8 @@ __get_user_bad: ret lr ENDPROC(__get_user_bad) ENDPROC(__get_user_bad8) +_ASM_NOKPROBE(__get_user_bad) +_ASM_NOKPROBE(__get_user_bad8) .pushsection __ex_table, "a" .long 1b, __get_user_bad diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c index 4f5fd4a084c06..034b89499bd72 100644 --- a/arch/arm/mach-omap1/clock.c +++ b/arch/arm/mach-omap1/clock.c @@ -1031,17 +1031,17 @@ static int clk_debugfs_register_one(struct clk *c) return -ENOMEM; c->dent = d; - d = debugfs_create_u8("usecount", S_IRUGO, c->dent, (u8 *)&c->usecount); + d = debugfs_create_u8("usecount", S_IRUGO, c->dent, &c->usecount); if (!d) { err = -ENOMEM; goto err_out; } - d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate); + d = debugfs_create_ulong("rate", S_IRUGO, c->dent, &c->rate); if (!d) { err = -ENOMEM; goto err_out; } - d = debugfs_create_x32("flags", S_IRUGO, c->dent, (u32 *)&c->flags); + d = debugfs_create_x8("flags", S_IRUGO, c->dent, &c->flags); if (!d) { err = -ENOMEM; goto err_out; diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index 58920bc8807bc..3d876bde8c859 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -231,7 +231,7 @@ static void omap_pm_end(void) cpu_idle_poll_ctrl(false); } -static void omap_pm_finish(void) +static void omap_pm_wake(void) { if (cpu_is_omap34xx()) omap_prcm_irq_complete(); @@ -241,7 +241,7 @@ static const struct platform_suspend_ops omap_pm_ops = { .begin = omap_pm_begin, .end = omap_pm_end, .enter = omap_pm_enter, - .finish = omap_pm_finish, + .wake = omap_pm_wake, .valid = suspend_valid_only_mem, }; diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 83fc403aec3c9..1f774ec4ab272 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -136,12 +136,6 @@ static struct clock_event_device clockevent_gpt = { .tick_resume = omap2_gp_timer_shutdown, }; -static struct property device_disabled = { - .name = "status", - .length = sizeof("disabled"), - .value = "disabled", -}; - static const struct of_device_id omap_timer_match[] __initconst = { { .compatible = "ti,omap2420-timer", }, { .compatible = "ti,omap3430-timer", }, @@ -183,8 +177,17 @@ static struct device_node * __init omap_get_timer_dt(const struct of_device_id * of_get_property(np, "ti,timer-secure", NULL))) continue; - if (!of_device_is_compatible(np, "ti,omap-counter32k")) - of_add_property(np, &device_disabled); + if (!of_device_is_compatible(np, "ti,omap-counter32k")) { + struct property *prop; + + prop = kzalloc(sizeof(*prop), GFP_KERNEL); + if (!prop) + return NULL; + prop->name = "status"; + prop->value = "disabled"; + prop->length = strlen(prop->value); + of_add_property(np, prop); + } return np; } diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c index 9c10248fadccc..4e8c2116808ec 100644 --- a/arch/arm/mach-pxa/irq.c +++ b/arch/arm/mach-pxa/irq.c @@ -185,7 +185,7 @@ static int pxa_irq_suspend(void) { int i; - for (i = 0; i < pxa_internal_irq_nr / 32; i++) { + for (i = 0; i < DIV_ROUND_UP(pxa_internal_irq_nr, 32); i++) { void __iomem *base = irq_base(i); saved_icmr[i] = __raw_readl(base + ICMR); @@ -204,7 +204,7 @@ static void pxa_irq_resume(void) { int i; - for (i = 0; i < pxa_internal_irq_nr / 32; i++) { + for (i = 0; i < DIV_ROUND_UP(pxa_internal_irq_nr, 32); i++) { void __iomem *base = irq_base(i); __raw_writel(saved_icmr[i], base + ICMR); diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index ea4b5ef7f2870..d539dee3c78d4 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -338,9 +338,6 @@ static int __init atomic_pool_init(void) struct page *page; void *ptr; - if (!atomic_pool_size) - return 0; - atomic_pool = gen_pool_create(PAGE_SHIFT, -1); if (!atomic_pool) goto out; diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index c29ad610311b4..a9f6705aea238 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -716,19 +716,28 @@ int __mark_rodata_ro(void *unused) return 0; } +static int kernel_set_to_readonly __read_mostly; + void mark_rodata_ro(void) { + kernel_set_to_readonly = 1; stop_machine(__mark_rodata_ro, NULL, NULL); } void set_kernel_text_rw(void) { + if (!kernel_set_to_readonly) + return; + set_section_perms(ro_perms, ARRAY_SIZE(ro_perms), false, current->active_mm); } void set_kernel_text_ro(void) { + if (!kernel_set_to_readonly) + return; + set_section_perms(ro_perms, ARRAY_SIZE(ro_perms), true, current->active_mm); } diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index 8ca94d379bc35..6f75c32dc3bf0 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c @@ -854,11 +854,8 @@ static int omap_dm_timer_probe(struct platform_device *pdev) timer->irq = irq->start; timer->pdev = pdev; - /* Skip pm_runtime_enable for OMAP1 */ - if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) { - pm_runtime_enable(dev); - pm_runtime_irq_safe(dev); - } + pm_runtime_enable(dev); + pm_runtime_irq_safe(dev); if (!timer->reserved) { ret = pm_runtime_get_sync(dev); diff --git a/arch/arm/probes/kprobes/opt-arm.c b/arch/arm/probes/kprobes/opt-arm.c index bcdecc25461bc..b2aa9b32bff2b 100644 --- a/arch/arm/probes/kprobes/opt-arm.c +++ b/arch/arm/probes/kprobes/opt-arm.c @@ -165,13 +165,14 @@ optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs) { unsigned long flags; struct kprobe *p = &op->kp; - struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); + struct kprobe_ctlblk *kcb; /* Save skipped registers */ regs->ARM_pc = (unsigned long)op->kp.addr; regs->ARM_ORIG_r0 = ~0UL; local_irq_save(flags); + kcb = get_kprobe_ctlblk(); if (kprobe_running()) { kprobes_inc_nmissed_count(&op->kp); @@ -191,6 +192,7 @@ optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs) local_irq_restore(flags); } +NOKPROBE_SYMBOL(optimized_callback) int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *orig) { diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 2cbb42f7366a4..986e1d3c96f60 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -426,6 +426,20 @@ config ARM64_ERRATUM_843419 If unsure, say Y. +config ARM64_ERRATUM_1024718 + bool "Cortex-A55: 1024718: Update of DBM/AP bits without break before make might result in incorrect update" + default y if !ARCH_ROCKCHIP + help + This option adds work around for Arm Cortex-A55 Erratum 1024718. + + Affected Cortex-A55 cores (r0p0, r0p1, r1p0) could cause incorrect + update of the hardware dirty bit when the DBM/AP bits are updated + without a break-before-make. The work around is to disable the usage + of hardware DBM locally on the affected cores. CPUs not affected by + erratum will continue to use the feature. + + If unsure, say Y. + config CAVIUM_ERRATUM_22375 bool "Cavium erratum 22375, 24313" default y diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index 53cde97203a2d..6edd48b23f1b0 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -163,11 +163,11 @@ define archhelp echo ' install to $$(INSTALL_PATH) and run lilo' endef -kernel.img: Image - $(Q)$(srctree)/scripts/mkkrnlimg $(objtree)/arch/arm64/boot/Image $(objtree)/kernel.img >/dev/null +kernel.img: Image.lz4 + $(Q)scripts/mkkrnlimg $(objtree)/arch/arm64/boot/Image $(objtree)/kernel.img >/dev/null @echo ' Image: kernel.img is ready' ifdef CONFIG_MODULES - $(Q)$(MAKE) modules + $(Q)if [ "$(srctree)" = "$(objtree)" ]; then $(MAKE) modules; fi endif LOGO := $(notdir $(wildcard $(srctree)/logo.bmp)) @@ -175,8 +175,19 @@ LOGO_KERNEL := $(notdir $(wildcard $(srctree)/logo_kernel.bmp)) %.img: rockchip/%.dtb kernel.img $(LOGO) $(LOGO_KERNEL) $(Q) if [ -f $(srctree)/$(LOGO) -a "$(srctree)" != "$(objtree)" ]; then cp -a $(srctree)/$(LOGO) $(objtree)/; fi $(Q) if [ -f $(srctree)/$(LOGO_KERNEL) -a "$(srctree)" != "$(objtree)" ]; then cp -a $(srctree)/$(LOGO_KERNEL) $(objtree)/; fi - $(Q)$(srctree)/scripts/resource_tool $(objtree)/arch/arm64/boot/dts/rockchip/$*.dtb $(LOGO) $(LOGO_KERNEL) + $(Q)scripts/resource_tool $(objtree)/arch/arm64/boot/dts/rockchip/$*.dtb $(LOGO) $(LOGO_KERNEL) @echo ' Image: resource.img (with $*.dtb $(LOGO) $(LOGO_KERNEL)) is ready' - $(Q) if [ -x $(srctree)/scripts/mkbootimg ]; then $(srctree)/scripts/mkbootimg --kernel $(objtree)/arch/arm64/boot/Image --second resource.img -o boot.img && echo ' Image: boot.img (with Image resource.img) is ready'; fi - -CLEAN_FILES += boot.img kernel.img resource.img + $(Q) if [ -x $(srctree)/scripts/mkbootimg ]; then \ + $(srctree)/scripts/mkbootimg \ + --kernel $(objtree)/arch/arm64/boot/Image \ + --second resource.img \ + -o boot.img && \ + echo ' Image: boot.img (with Image resource.img) is ready'; \ + $(srctree)/scripts/mkbootimg \ + --kernel $(objtree)/arch/arm64/boot/Image.lz4 \ + --second resource.img \ + -o zboot.img && \ + echo ' Image: zboot.img (with Image.lz4 resource.img) is ready'; \ + fi + +CLEAN_FILES += boot.img kernel.img resource.img zboot.img diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile index ce0a5a0d137c7..0ab5d7138f376 100644 --- a/arch/arm64/boot/dts/rockchip/Makefile +++ b/arch/arm64/boot/dts/rockchip/Makefile @@ -1,4 +1,5 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-evb-ddr3-v10.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-evb-ddr3-v10-linux.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-evb-ddr3-lvds-v10.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += px30-evb-ddr4-v10.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-ai-va-v10.dtb @@ -9,11 +10,15 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-evb-dmic-i2s-v11.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-evb-dmic-pdm-v10.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-evb-dmic-pdm-v11.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-fpga.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-voice-module-board-v10.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-evb-ai-va-v10.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-evb-ai-va-v11.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-evb-ai-va-v11-i2s-dmic.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-evb-lp3-v10.dtb -dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-evb-linux-lp3-v10.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-evb-lp3-v10-linux.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-863-lp3-v10.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-863-lp3-v10-avb.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-86v-v10.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-box-liantong.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-evb.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-evb-android.dtb @@ -61,6 +66,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-gru-kevin-r0.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-gru-kevin-r1.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-mid-818-android-6.0.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-mid-818-android.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rock960-ab.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rockpro64.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rv1-android.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-sapphire-excavator-box-android-6.0.dtb diff --git a/arch/arm64/boot/dts/rockchip/px30-android.dtsi b/arch/arm64/boot/dts/rockchip/px30-android.dtsi index f2884e8e991d5..2fc90ef99cd55 100644 --- a/arch/arm64/boot/dts/rockchip/px30-android.dtsi +++ b/arch/arm64/boot/dts/rockchip/px30-android.dtsi @@ -5,8 +5,8 @@ */ / { - chosen { - bootargs = "earlyprintk=uart8250,mmio32,0xff160000 swiotlb=1 console=ttyFIQ0 androidboot.baseband=N/A androidboot.selinux=permissive androidboot.veritymode=/dev/block/by-name/metadata androidboot.hardware=rk30board androidboot.console=ttyFIQ0 init=/init kpti=0"; + chosen: chosen { + bootargs = "earlyprintk=uart8250,mmio32,0xff160000 swiotlb=1 console=ttyFIQ0 androidboot.baseband=N/A androidboot.veritymode=enforcing androidboot.hardware=rk30board androidboot.console=ttyFIQ0 init=/init kpti=0"; }; fiq-debugger { @@ -23,26 +23,7 @@ }; firmware { - android { - compatible = "android,firmware"; - fstab { - compatible = "android,fstab"; - system { - compatible = "android,system"; - dev = "/dev/block/by-name/system"; - type = "ext4"; - mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; - fsmgr_flags = "wait"; - }; - vendor { - compatible = "android,vendor"; - dev = "/dev/block/by-name/vendor"; - type = "ext4"; - mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; - fsmgr_flags = "wait"; - }; - }; - }; + firmware_android: android {}; }; reserved-memory { diff --git a/arch/arm64/boot/dts/rockchip/px30-evb-ddr3-lvds-v10.dts b/arch/arm64/boot/dts/rockchip/px30-evb-ddr3-lvds-v10.dts index 88ff87354b19d..b8dad00dd9f4e 100644 --- a/arch/arm64/boot/dts/rockchip/px30-evb-ddr3-lvds-v10.dts +++ b/arch/arm64/boot/dts/rockchip/px30-evb-ddr3-lvds-v10.dts @@ -641,3 +641,24 @@ &vpu_combo { status = "okay"; }; + +&firmware_android { + compatible = "android,firmware"; + fstab { + compatible = "android,fstab"; + system { + compatible = "android,system"; + dev = "/dev/block/by-name/system"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait"; + }; + vendor { + compatible = "android,vendor"; + dev = "/dev/block/by-name/vendor"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/rockchip/px30-evb-ddr3-v10-linux.dts b/arch/arm64/boot/dts/rockchip/px30-evb-ddr3-v10-linux.dts new file mode 100644 index 0000000000000..d066f8abca5a3 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/px30-evb-ddr3-v10-linux.dts @@ -0,0 +1,888 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd + */ + +/dts-v1/; +#include +#include +#include +#include +#include +#include "px30.dtsi" +#include "rk3326-linux.dtsi" + +/ { + model = "Rockchip linux PX30 evb ddr3 board"; + compatible = "rockchip,px30-evb-ddr3-v10-linux", "rockchip,px30"; + + adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 2>; + io-channel-names = "buttons"; + poll-interval = <100>; + keyup-threshold-microvolt = <1800000>; + + esc-key { + linux,code = ; + label = "esc"; + press-threshold-microvolt = <1310000>; + }; + + home-key { + linux,code = ; + label = "home"; + press-threshold-microvolt = <624000>; + }; + + menu-key { + linux,code = ; + label = "menu"; + press-threshold-microvolt = <987000>; + }; + + vol-down-key { + linux,code = ; + label = "volume down"; + press-threshold-microvolt = <300000>; + }; + + vol-up-key { + linux,code = ; + label = "volume up"; + press-threshold-microvolt = <17000>; + }; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&pwm1 0 25000 0>; + 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 = <200>; + }; + + charge-animation { + compatible = "rockchip,uboot-charge"; + rockchip,uboot-charge-on = <0>; + rockchip,android-charge-on = <1>; + rockchip,uboot-low-power-voltage = <3500>; + rockchip,screen-on-voltage = <3600>; + status = "okay"; + }; + + rk809-sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,name = "rockchip,rk809-codec"; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,widgets = + "Microphone", "Mic Jack", + "Headphone", "Headphone Jack"; + simple-audio-card,routing = + "Mic Jack", "MICBIAS1", + "IN1P", "Mic Jack", + "Headphone Jack", "HPOL", + "Headphone Jack", "HPOR"; + simple-audio-card,cpu { + sound-dai = <&i2s1_2ch>; + }; + simple-audio-card,codec { + sound-dai = <&rk809_codec>; + }; + }; + + rk_headset { + compatible = "rockchip_headset"; + headset_gpio = <&gpio2 RK_PB0 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&hp_det>; + io-channels = <&saradc 1>; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + /*clocks = <&rk809 1>;*/ + /*clock-names = "ext_clock";*/ + pinctrl-names = "default"; + pinctrl-0 = <&wifi_enable_h>; + + /* + * On the module itself this is one of these (depending + * on the actual card populated): + * - SDIO_RESET_L_WL_REG_ON + * - PDN (power down when low) + */ + reset-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>; /* GPIO3_A4 */ + }; + + vcc_phy: vcc-phy-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc_phy"; + regulator-always-on; + regulator-boot-on; + }; + + vcc5v0_sys: vccsys { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + wireless-wlan { + compatible = "wlan-platdata"; + wifi_chip_type = "AP6210"; + WIFI,host_wake_irq = <&gpio0 RK_PB2 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; + + wireless-bluetooth { + compatible = "bluetooth-platdata"; + clocks = <&rk809 1>; + clock-names = "ext_clock"; + uart_rts_gpios = <&gpio1 RK_PC3 GPIO_ACTIVE_LOW>; + pinctrl-names = "default","rts_gpio"; + pinctrl-0 = <&uart1_rts>; + pinctrl-1 = <&uart1_rts_gpio>; + BT,reset_gpio = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>; + BT,wake_gpio = <&gpio2 RK_PB0 GPIO_ACTIVE_HIGH>; + BT,wake_host_irq = <&gpio0 RK_PB3 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; +}; + +&display_subsystem { + status = "okay"; +}; + +&dsi { + status = "okay"; + + panel@0 { + compatible = "sitronix,st7703", "simple-panel-dsi"; + reg = <0>; + power-supply = <&vcc3v3_lcd>; + backlight = <&backlight>; + prepare-delay-ms = <2>; + reset-delay-ms = <1>; + init-delay-ms = <20>; + enable-delay-ms = <120>; + disable-delay-ms = <50>; + unprepare-delay-ms = <20>; + + width-mm = <68>; + height-mm = <121>; + + dsi,flags = <(MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | + MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_EOT_PACKET)>; + dsi,format = ; + dsi,lanes = <4>; + + panel-init-sequence = [ + 05 fa 01 11 + 39 00 04 b9 f1 12 83 + 39 00 1c ba 33 81 05 f9 0e 0e 00 00 00 + 00 00 00 00 00 44 25 00 91 0a + 00 00 02 4f 01 00 00 37 + 15 00 02 b8 25 + 39 00 04 bf 02 11 00 + 39 00 0b b3 0c 10 0a 50 03 ff 00 00 00 + 00 + 39 00 0a c0 73 73 50 50 00 00 08 70 00 + 15 00 02 bc 46 + 15 00 02 cc 0b + 15 00 02 b4 80 + 39 00 04 b2 c8 12 30 + 39 00 0f e3 07 07 0b 0b 03 0b 00 00 00 + 00 ff 00 c0 10 + 39 00 0d c1 53 00 1e 1e 77 e1 cc dd 67 + 77 33 33 + 39 00 07 c6 00 00 ff ff 01 ff + 39 00 03 b5 09 09 + 39 00 03 b6 87 95 + 39 00 40 e9 c2 10 05 05 10 05 a0 12 31 + 23 3f 81 0a a0 37 18 00 80 01 + 00 00 00 00 80 01 00 00 00 48 + f8 86 42 08 88 88 80 88 88 88 + 58 f8 87 53 18 88 88 81 88 88 + 88 00 00 00 01 00 00 00 00 00 + 00 00 00 00 + 39 00 3e ea 00 1a 00 00 00 00 02 00 00 + 00 00 00 1f 88 81 35 78 88 88 + 85 88 88 88 0f 88 80 24 68 88 + 88 84 88 88 88 23 10 00 00 1c + 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 30 05 a0 00 00 + 00 00 + 39 00 23 e0 00 06 08 2a 31 3f 38 36 07 + 0c 0d 11 13 12 13 11 18 00 06 + 08 2a 31 3f 38 36 07 0c 0d 11 + 13 12 13 11 18 + 05 32 01 29 + ]; + + panel-exit-sequence = [ + 05 00 01 28 + 05 00 01 10 + ]; + + display-timings { + native-mode = <&timing0>; + + timing0: timing0 { + clock-frequency = <64000000>; + hactive = <720>; + vactive = <1280>; + hfront-porch = <40>; + hsync-len = <10>; + hback-porch = <40>; + vfront-porch = <22>; + vsync-len = <4>; + vback-porch = <11>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <0>; + pixelclk-active = <0>; + }; + }; + }; +}; + +&bus_apll { + bus-supply = <&vdd_logic>; + status = "okay"; +}; + +&cpu0 { + cpu-supply = <&vdd_arm>; +}; + +&dsi_in_vopl { + status = "disabled"; +}; + +&dfi { + status = "okay"; +}; + +&dmc { + center-supply = <&vdd_logic>; + status = "okay"; +}; + +&emmc { + bus-width = <8>; + cap-mmc-highspeed; + mmc-hs200-1_8v; + supports-emmc; + disable-wp; + non-removable; + num-slots = <1>; + status = "okay"; +}; + +&gmac { + phy-supply = <&vcc_phy>; + clock_in_out = "output"; + snps,reset-gpio = <&gpio2 13 GPIO_ACTIVE_LOW>; + snps,reset-active-low; + snps,reset-delays-us = <0 50000 50000>; + status = "okay"; +}; + +&gpu { + mali-supply = <&vdd_logic>; + status = "okay"; +}; + +&i2c0 { + status = "okay"; + + rk809: pmic@20 { + compatible = "rockchip,rk809"; + reg = <0x20>; + interrupt-parent = <&gpio0>; + interrupts = <7 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default", "pmic-sleep", + "pmic-power-off", "pmic-reset"; + pinctrl-0 = <&pmic_int>; + pinctrl-1 = <&soc_slppin_slp>, <&rk817_slppin_slp>; + pinctrl-2 = <&soc_slppin_gpio>, <&rk817_slppin_pwrdn>; + pinctrl-3 = <&soc_slppin_rst>, <&rk817_slppin_rst>; + rockchip,system-power-controller; + wakeup-source; + #clock-cells = <1>; + clock-output-names = "rk808-clkout1", "rk808-clkout2"; + //fb-inner-reg-idxs = <2>; + /* 1: rst regs (default in codes), 0: rst the pmic */ + pmic-reset-func = <1>; + + vcc1-supply = <&vcc5v0_sys>; + vcc2-supply = <&vcc5v0_sys>; + vcc3-supply = <&vcc5v0_sys>; + vcc4-supply = <&vcc5v0_sys>; + vcc5-supply = <&vcc3v3_sys>; + vcc6-supply = <&vcc3v3_sys>; + vcc7-supply = <&vcc3v3_sys>; + vcc8-supply = <&vcc3v3_sys>; + vcc9-supply = <&vcc5v0_sys>; + + pwrkey { + status = "okay"; + }; + + pinctrl_rk8xx: pinctrl_rk8xx { + gpio-controller; + #gpio-cells = <2>; + + rk817_slppin_null: rk817_slppin_null { + pins = "gpio_slp"; + function = "pin_fun0"; + }; + + rk817_slppin_slp: rk817_slppin_slp { + pins = "gpio_slp"; + function = "pin_fun1"; + }; + + rk817_slppin_pwrdn: rk817_slppin_pwrdn { + pins = "gpio_slp"; + function = "pin_fun2"; + }; + + rk817_slppin_rst: rk817_slppin_rst { + pins = "gpio_slp"; + function = "pin_fun3"; + }; + }; + + regulators { + vdd_logic: DCDC_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-initial-mode = <0x2>; + regulator-name = "vdd_logic"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vdd_arm: DCDC_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-initial-mode = <0x2>; + regulator-name = "vdd_arm"; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-name = "vcc_ddr"; + regulator-initial-mode = <0x2>; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_3v0: DCDC_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-initial-mode = <0x2>; + regulator-name = "vcc_3v0"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vcc_1v0: LDO_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-name = "vcc_1v0"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc1v8_soc: LDO_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-name = "vcc1v8_soc"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd1v0_soc: LDO_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + + regulator-name = "vcc1v0_soc"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc3v0_pmu: LDO_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + + regulator-name = "vcc3v0_pmu"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + + }; + }; + + vccio_sd: LDO_REG5 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + + regulator-name = "vccio_sd"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_sd: LDO_REG6 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-name = "vcc_sd"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + + }; + }; + + vcc2v8_dvp: LDO_REG7 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + + regulator-name = "vcc2v8_dvp"; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <2800000>; + }; + }; + + vcc1v8_dvp: LDO_REG8 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-name = "vcc1v8_dvp"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd1v5_dvp: LDO_REG9 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + + regulator-name = "vdd1v5_dvp"; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <1500000>; + }; + }; + + vcc3v3_sys: DCDC_REG5 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc3v3_sys"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc3v3_lcd: SWITCH_REG1 { + regulator-boot-on; + regulator-name = "vcc3v3_lcd"; + }; + + vcc5v0_host: SWITCH_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-name = "vcc5v0_host"; + }; + }; + + rk809_codec: codec { + #sound-dai-cells = <0>; + compatible = "rockchip,rk809-codec", "rockchip,rk817-codec"; + clocks = <&cru SCLK_I2S1_OUT>; + clock-names = "mclk"; + pinctrl-names = "default"; + pinctrl-0 = <&i2s1_2ch_mclk>; + hp-volume = <20>; + spk-volume = <3>; + status = "okay"; + }; + }; +}; + +&i2c1 { + status = "okay"; + + sensor@f { + status = "okay"; + compatible = "ak8963"; + reg = <0x0f>; + type = ; + irq_enable = <0>; + poll_delay_ms = <30>; + layout = <1>; + reprobe_en = <1>; + }; + + gt1x: gt1x@14 { + compatible = "goodix,gt1x"; + reg = <0x14>; + power-supply = <&vcc3v3_lcd>; + goodix,rst-gpio = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>; + goodix,irq-gpio = <&gpio0 RK_PA5 IRQ_TYPE_LEVEL_LOW>; + }; + + sensor@4c { + status = "okay"; + compatible = "gs_mma7660"; + reg = <0x4c>; + type = ; + irq-gpio = <&gpio0 RK_PB7 IRQ_TYPE_LEVEL_LOW>; + irq_enable = <0>; + poll_delay_ms = <30>; + layout = <2>; + reprobe_en = <1>; + }; +}; + +&i2c2 { + status = "okay"; + + clock-frequency = <100000>; + + /* These are relatively safe rise/fall times; TODO: measure */ + i2c-scl-falling-time-ns = <50>; + i2c-scl-rising-time-ns = <300>; + + ov5695: ov5695@36 { + compatible = "ovti,ov5695"; + reg = <0x36>; + clocks = <&cru SCLK_CIF_OUT>; + clock-names = "xvclk"; + /*reset-gpios = <&gpio2 14 GPIO_ACTIVE_HIGH>;*/ + pwdn-gpios = <&gpio2 14 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&cif_clkout_m0>; + port { + ucam_out: endpoint { + remote-endpoint = <&mipi_in_ucam>; + data-lanes = <1 2>; + }; + }; + }; +}; + +&i2s1_2ch { + status = "okay"; + #sound-dai-cells = <0>; +}; + +&io_domains { + status = "okay"; + + vccio1-supply = <&vcc1v8_soc>; + vccio2-supply = <&vccio_sd>; + vccio3-supply = <&vcc_3v0>; + vccio4-supply = <&vcc3v0_pmu>; + vccio5-supply = <&vcc_3v0>; +}; + +&isp_mmu { + status = "okay"; +}; + +&mipi_dphy { + status = "okay"; +}; + +&mipi_dphy_rx0 { + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + mipi_in_ucam: endpoint@1 { + reg = <1>; + remote-endpoint = <&ucam_out>; + data-lanes = <1 2>; + }; + }; + + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + dphy_rx0_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&isp0_mipi_in>; + }; + }; + }; +}; + +&nandc0 { + status = "okay"; +}; + +&pmu_io_domains { + status = "okay"; + + pmuio1-supply = <&vcc3v0_pmu>; + pmuio2-supply = <&vcc3v0_pmu>; +}; + +&pwm1 { + status = "okay"; +}; + +&rk_rga { + status = "okay"; +}; + +&rkisp1 { + status = "okay"; + + port { + #address-cells = <1>; + #size-cells = <0>; + + isp0_mipi_in: endpoint@0 { + reg = <0>; + remote-endpoint = <&dphy_rx0_out>; + }; + }; +}; + +&rockchip_suspend { + status = "okay"; + rockchip,sleep-debug-en = <1>; +}; + +&route_dsi { + status = "okay"; +}; + +&saradc { + status = "okay"; + vref-supply = <&vcc1v8_soc>; +}; + +&sdmmc { + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + supports-sd; + card-detect-delay = <800>; + ignore-pm-notify; + /*cd-gpios = <&gpio2 4 GPIO_ACTIVE_HIGH>; [> CD GPIO <]*/ + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vqmmc-supply = <&vccio_sd>; + vmmc-supply = <&vcc_sd>; + status = "okay"; +}; + +&sdio { + bus-width = <4>; + cap-sd-highspeed; + supports-sdio; + ignore-pm-notify; + keep-power-in-suspend; + non-removable; + mmc-pwrseq = <&sdio_pwrseq>; + sd-uhs-sdr104; + status = "okay"; +}; + +&tsadc { + pinctrl-names = "init", "default"; + pinctrl-0 = <&tsadc_otp_gpio>; + pinctrl-1 = <&tsadc_otp_out>; + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_xfer &uart1_cts>; + status = "okay"; +}; + +&u2phy { + status = "okay"; + + u2phy_host: host-port { + status = "okay"; + }; + + u2phy_otg: otg-port { + status = "okay"; + }; +}; + +&usb20_otg { + status = "okay"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; + +&vopb { + status = "okay"; +}; + +&vopb_mmu { + status = "okay"; +}; + +&vopl { + status = "okay"; +}; + +&vopl_mmu { + status = "okay"; +}; + +&vpu_combo { + status = "okay"; +}; + +&pinctrl { + headphone { + hp_det: hp-det { + rockchip,pins = <2 RK_PB0 RK_FUNC_GPIO &pcfg_pull_down>; + }; + }; + + pmic { + pmic_int: pmic_int { + rockchip,pins = + <0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + soc_slppin_gpio: soc_slppin_gpio { + rockchip,pins = + <0 RK_PA4 RK_FUNC_GPIO &pcfg_output_low>; + }; + + soc_slppin_slp: soc_slppin_slp { + rockchip,pins = + <0 RK_PA4 RK_FUNC_1 &pcfg_pull_none>; + }; + + soc_slppin_rst: soc_slppin_rst { + rockchip,pins = + <0 RK_PA4 RK_FUNC_2 &pcfg_pull_none>; + }; + }; + + sdio-pwrseq { + wifi_enable_h: wifi-enable-h { + rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +/* DON'T PUT ANYTHING BELOW HERE. PUT IT ABOVE PINCTRL */ +/* DON'T PUT ANYTHING BELOW HERE. PUT IT ABOVE PINCTRL */ +/* DON'T PUT ANYTHING BELOW HERE. PUT IT ABOVE PINCTRL */ + diff --git a/arch/arm64/boot/dts/rockchip/px30-evb-ddr3-v10.dts b/arch/arm64/boot/dts/rockchip/px30-evb-ddr3-v10.dts index 507b9eeff63df..2e474a950c627 100644 --- a/arch/arm64/boot/dts/rockchip/px30-evb-ddr3-v10.dts +++ b/arch/arm64/boot/dts/rockchip/px30-evb-ddr3-v10.dts @@ -94,6 +94,15 @@ default-brightness-level = <200>; }; + charge-animation { + compatible = "rockchip,uboot-charge"; + rockchip,uboot-charge-on = <0>; + rockchip,android-charge-on = <1>; + rockchip,uboot-low-power-voltage = <3500>; + rockchip,screen-on-voltage = <3600>; + status = "okay"; + }; + rk809-sound { compatible = "simple-audio-card"; simple-audio-card,format = "i2s"; @@ -164,14 +173,14 @@ wireless-bluetooth { compatible = "bluetooth-platdata"; - /*clocks = <&rk809 1>;*/ - /*clock-names = "ext_clock";*/ + clocks = <&rk809 1>; + clock-names = "ext_clock"; uart_rts_gpios = <&gpio1 RK_PC3 GPIO_ACTIVE_LOW>; pinctrl-names = "default","rts_gpio"; pinctrl-0 = <&uart1_rts>; pinctrl-1 = <&uart1_rts_gpio>; - BT,reset_gpio = <&gpio0 RK_PC1 GPIO_ACTIVE_HIGH>; - BT,wake_gpio = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>; + BT,reset_gpio = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>; + BT,wake_gpio = <&gpio2 RK_PB0 GPIO_ACTIVE_HIGH>; BT,wake_host_irq = <&gpio0 RK_PB3 GPIO_ACTIVE_HIGH>; status = "okay"; }; @@ -309,11 +318,7 @@ &gmac { phy-supply = <&vcc_phy>; - assigned-clocks = <&cru SCLK_GMAC>; - assigned-clock-parents = <&gmac_clkin>; - clock_in_out = "input"; - pinctrl-names = "default"; - pinctrl-0 = <&rmii_pins &mac_refclk>; + clock_in_out = "output"; snps,reset-gpio = <&gpio2 13 GPIO_ACTIVE_LOW>; snps,reset-active-low; snps,reset-delays-us = <0 50000 50000>; @@ -433,7 +438,7 @@ regulator-initial-mode = <0x2>; regulator-name = "vcc_3v0"; regulator-state-mem { - regulator-off-in-suspend; + regulator-on-in-suspend; regulator-suspend-microvolt = <3000000>; }; }; @@ -566,15 +571,13 @@ }; }; - vcc3v3_lcd: SWITCH_REG1 { - regulator-boot-on; - regulator-name = "vcc3v3_lcd"; + vcc5v0_host: SWITCH_REG1 { + regulator-name = "vcc5v0_host"; }; - vcc5v0_host: SWITCH_REG2 { - regulator-always-on; + vcc3v3_lcd: SWITCH_REG2 { regulator-boot-on; - regulator-name = "vcc5v0_host"; + regulator-name = "vcc3v3_lcd"; }; }; @@ -877,3 +880,24 @@ &vpu_combo { status = "okay"; }; + +&firmware_android { + compatible = "android,firmware"; + fstab { + compatible = "android,fstab"; + system { + compatible = "android,system"; + dev = "/dev/block/by-name/system"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait"; + }; + vendor { + compatible = "android,vendor"; + dev = "/dev/block/by-name/vendor"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/rockchip/px30-evb-ddr4-v10.dts b/arch/arm64/boot/dts/rockchip/px30-evb-ddr4-v10.dts index d0c29b68d842e..f7cea779f39ce 100644 --- a/arch/arm64/boot/dts/rockchip/px30-evb-ddr4-v10.dts +++ b/arch/arm64/boot/dts/rockchip/px30-evb-ddr4-v10.dts @@ -558,15 +558,13 @@ }; }; - vcc3v3_lcd: SWITCH_REG1 { - regulator-boot-on; - regulator-name = "vcc3v3_lcd"; + vcc5v0_host: SWITCH_REG1 { + regulator-name = "vcc5v0_host"; }; - vcc5v0_host: SWITCH_REG2 { - regulator-always-on; + vcc3v3_lcd: SWITCH_REG2 { regulator-boot-on; - regulator-name = "vcc5v0_host"; + regulator-name = "vcc3v3_lcd"; }; }; @@ -790,3 +788,24 @@ &vpu_combo { status = "okay"; }; + +&firmware_android { + compatible = "android,firmware"; + fstab { + compatible = "android,fstab"; + system { + compatible = "android,system"; + dev = "/dev/block/by-name/system"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait"; + }; + vendor { + compatible = "android,vendor"; + dev = "/dev/block/by-name/vendor"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/rockchip/px30.dtsi b/arch/arm64/boot/dts/rockchip/px30.dtsi index 049e344ec54d3..4f3e5bf83a3c2 100644 --- a/arch/arm64/boot/dts/rockchip/px30.dtsi +++ b/arch/arm64/boot/dts/rockchip/px30.dtsi @@ -112,12 +112,18 @@ rockchip,avs-scale = <4>; rockchip,max-volt = <1350000>; rockchip,evb-irdrop = <25000>; - nvmem-cells = <&cpu_leakage>; - nvmem-cell-names = "cpu_leakage"; + nvmem-cells = <&cpu_leakage>, <&performance>; + nvmem-cell-names = "cpu_leakage", "performance"; + rockchip,bin-scaling-sel = < + 0 13 + 1 15 + >; rockchip,pvtm-voltage-sel = < 0 50000 0 - 50001 99999 1 + 50001 54000 1 + 54001 60000 2 + 60001 99999 3 >; rockchip,pvtm-freq = <408000>; rockchip,pvtm-volt = <1000000>; @@ -127,13 +133,15 @@ rockchip,pvtm-error = <1000>; rockchip,pvtm-ref-temp = <40>; rockchip,pvtm-temp-prop = <(-56) (-56)>; - rockchip,pvtm-thermal-zone = "soc-thermal"; + rockchip,thermal-zone = "soc-thermal"; opp-408000000 { opp-hz = /bits/ 64 <408000000>; opp-microvolt = <950000 950000 1350000>; opp-microvolt-L0 = <950000 950000 1350000>; opp-microvolt-L1 = <950000 950000 1350000>; + opp-microvolt-L2 = <950000 950000 1350000>; + opp-microvolt-L3 = <950000 950000 1350000>; clock-latency-ns = <40000>; opp-suspend; }; @@ -142,6 +150,8 @@ opp-microvolt = <950000 950000 1350000>; opp-microvolt-L0 = <950000 950000 1350000>; opp-microvolt-L1 = <950000 950000 1350000>; + opp-microvolt-L2 = <950000 950000 1350000>; + opp-microvolt-L3 = <950000 950000 1350000>; clock-latency-ns = <40000>; }; opp-816000000 { @@ -149,6 +159,8 @@ opp-microvolt = <1050000 1050000 1350000>; opp-microvolt-L0 = <1050000 1050000 1350000>; opp-microvolt-L1 = <1000000 1000000 1350000>; + opp-microvolt-L2 = <1000000 1000000 1350000>; + opp-microvolt-L3 = <950000 950000 1350000>; clock-latency-ns = <40000>; }; opp-1008000000 { @@ -156,6 +168,8 @@ opp-microvolt = <1175000 1175000 1350000>; opp-microvolt-L0 = <1175000 1175000 1350000>; opp-microvolt-L1 = <1125000 1125000 1350000>; + opp-microvolt-L2 = <1125000 1125000 1350000>; + opp-microvolt-L3 = <1050000 1050000 1350000>; clock-latency-ns = <40000>; }; opp-1200000000 { @@ -163,6 +177,8 @@ opp-microvolt = <1300000 1300000 1350000>; opp-microvolt-L0 = <1300000 1300000 1350000>; opp-microvolt-L1 = <1275000 1275000 1350000>; + opp-microvolt-L2 = <1250000 1250000 1350000>; + opp-microvolt-L3 = <1200000 1200000 1350000>; clock-latency-ns = <40000>; }; opp-1248000000 { @@ -170,6 +186,8 @@ opp-microvolt = <1350000 1350000 1350000>; opp-microvolt-L0 = <1350000 1350000 1350000>; opp-microvolt-L1 = <1300000 1300000 1350000>; + opp-microvolt-L2 = <1275000 1275000 1350000>; + opp-microvolt-L3 = <1225000 1225000 1350000>; clock-latency-ns = <40000>; }; opp-1296000000 { @@ -177,6 +195,8 @@ opp-microvolt = <1350000 1350000 1350000>; opp-microvolt-L0 = <1350000 1350000 1350000>; opp-microvolt-L1 = <1350000 1350000 1350000>; + opp-microvolt-L2 = <1300000 1300000 1350000>; + opp-microvolt-L3 = <1250000 1250000 1350000>; clock-latency-ns = <40000>; }; opp-1416000000 { @@ -184,6 +204,8 @@ opp-microvolt = <1350000 1350000 1350000>; opp-microvolt-L0 = <1350000 1350000 1350000>; opp-microvolt-L1 = <1350000 1350000 1350000>; + opp-microvolt-L2 = <1300000 1300000 1350000>; + opp-microvolt-L3 = <1250000 1250000 1350000>; clock-latency-ns = <40000>; }; opp-1512000000 { @@ -191,6 +213,8 @@ opp-microvolt = <1350000 1350000 1350000>; opp-microvolt-L0 = <1350000 1350000 1350000>; opp-microvolt-L1 = <1350000 1350000 1350000>; + opp-microvolt-L2 = <1300000 1300000 1350000>; + opp-microvolt-L3 = <1250000 1250000 1350000>; clock-latency-ns = <40000>; }; }; @@ -452,7 +476,6 @@ reg-shift = <2>; reg-io-width = <4>; dmas = <&dmac 0>, <&dmac 1>; - #dma-cells = <2>; pinctrl-names = "default"; pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>; status = "disabled"; @@ -610,7 +633,6 @@ reg-shift = <2>; reg-io-width = <4>; dmas = <&dmac 2>, <&dmac 3>; - #dma-cells = <2>; pinctrl-names = "default"; pinctrl-0 = <&uart1_xfer &uart1_cts &uart1_rts>; status = "disabled"; @@ -625,7 +647,6 @@ reg-shift = <2>; reg-io-width = <4>; dmas = <&dmac 4>, <&dmac 5>; - #dma-cells = <2>; pinctrl-names = "default"; pinctrl-0 = <&uart2m0_xfer>; status = "disabled"; @@ -640,7 +661,6 @@ reg-shift = <2>; reg-io-width = <4>; dmas = <&dmac 6>, <&dmac 7>; - #dma-cells = <2>; pinctrl-names = "default"; pinctrl-0 = <&uart3m1_xfer &uart3m1_cts &uart3m1_rts>; status = "disabled"; @@ -655,7 +675,6 @@ reg-shift = <2>; reg-io-width = <4>; dmas = <&dmac 8>, <&dmac 9>; - #dma-cells = <2>; pinctrl-names = "default"; pinctrl-0 = <&uart4_xfer &uart4_cts &uart4_rts>; status = "disabled"; @@ -670,7 +689,6 @@ reg-shift = <2>; reg-io-width = <4>; dmas = <&dmac 10>, <&dmac 11>; - #dma-cells = <2>; pinctrl-names = "default"; pinctrl-0 = <&uart5_xfer &uart5_cts &uart5_rts>; status = "disabled"; @@ -737,7 +755,6 @@ clocks = <&cru SCLK_SPI0>, <&cru PCLK_SPI0>; clock-names = "spiclk", "apb_pclk"; dmas = <&dmac 12>, <&dmac 13>; - #dma-cells = <2>; dma-names = "tx", "rx"; pinctrl-names = "default", "high_speed"; pinctrl-0 = <&spi0_clk &spi0_csn &spi0_miso &spi0_mosi>; @@ -754,7 +771,6 @@ clocks = <&cru SCLK_SPI1>, <&cru PCLK_SPI1>; clock-names = "spiclk", "apb_pclk"; dmas = <&dmac 14>, <&dmac 15>; - #dma-cells = <2>; dma-names = "tx", "rx"; pinctrl-names = "default", "high_speed"; pinctrl-0 = <&spi1_clk &spi1_csn0 &spi1_csn1 &spi1_miso &spi1_mosi>; @@ -979,6 +995,10 @@ cpu_leakage: cpu-leakage@17 { reg = <0x17 0x1>; }; + performance: performance@1e { + reg = <0x1e 0x1>; + bits = <4 3>; + }; }; cru: clock-controller@ff2b0000 { @@ -988,14 +1008,21 @@ rockchip,boost = <&cpu_boost>; #clock-cells = <1>; #reset-cells = <1>; - - assigned-clocks = <&cru PLL_NPLL>; - assigned-clock-rates = <1188000000>; }; cpu_boost: cpu-boost@ff2b8000 { compatible = "syscon"; reg = <0x0 0xff2b8000 0x0 0x1000>; + rockchip,boost-low-con0 = <0x1032>; + rockchip,boost-low-con1 = <0x1441>; + rockchip,boost-high-con0 = <0x1036>; + rockchip,boost-high-con1 = <0x1441>; + rockchip,boost-backup-pll = <1>; + rockchip,boost-backup-pll-usage = <0>; + rockchip,boost-switch-threshold = <0x249f00>; + rockchip,boost-statis-threshold = <0x100>; + rockchip,boost-statis-enable = <0>; + rockchip,boost-enable = <0>; }; pmucru: pmu-clock-controller@ff2bc000 { @@ -1185,6 +1212,8 @@ clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>, <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>; clock-names = "biu", "ciu", "ciu-drv", "ciu-sample"; + assigned-clocks = <&cru SCLK_SDMMC>; + assigned-clock-parents = <&cru SCLK_SDMMC_DIV50>; power-domains = <&power PX30_PD_SDCARD>; fifo-depth = <0x100>; interrupts = ; @@ -1200,6 +1229,8 @@ clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>, <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>; clock-names = "biu", "ciu", "ciu-drv", "ciu-sample"; + assigned-clocks = <&cru SCLK_SDIO>; + assigned-clock-parents = <&cru SCLK_SDIO_DIV50>; power-domains = <&power PX30_PD_MMC_NAND>; fifo-depth = <0x100>; interrupts = ; @@ -1215,6 +1246,8 @@ clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>, <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>; clock-names = "biu", "ciu", "ciu-drv", "ciu-sample"; + assigned-clocks = <&cru SCLK_EMMC>; + assigned-clock-parents = <&cru SCLK_EMMC_DIV50>; power-domains = <&power PX30_PD_MMC_NAND>; fifo-depth = <0x100>; interrupts = ; @@ -1228,6 +1261,8 @@ nandc_id = <0>; clocks = <&cru SCLK_NANDC>, <&cru HCLK_NANDC>; clock-names = "clk_nandc", "hclk_nandc"; + assigned-clocks = <&cru SCLK_NANDC>; + assigned-clock-parents = <&cru SCLK_NANDC_DIV50>; power-domains = <&power PX30_PD_MMC_NAND>; status = "disabled"; }; @@ -1266,7 +1301,9 @@ rockchip,pvtm-voltage-sel = < 0 50000 0 - 50001 99999 1 + 50001 54000 1 + 54001 60000 2 + 60001 99999 3 >; rockchip,pvtm-ch = <0 0>; @@ -1275,24 +1312,32 @@ opp-microvolt = <950000>; opp-microvolt-L0 = <950000>; opp-microvolt-L1 = <950000>; + opp-microvolt-L2 = <950000>; + opp-microvolt-L3 = <950000>; }; opp-300000000 { opp-hz = /bits/ 64 <300000000>; opp-microvolt = <975000>; opp-microvolt-L0 = <975000>; opp-microvolt-L1 = <950000>; + opp-microvolt-L2 = <950000>; + opp-microvolt-L3 = <950000>; }; opp-400000000 { opp-hz = /bits/ 64 <400000000>; opp-microvolt = <1050000>; opp-microvolt-L0 = <1050000>; opp-microvolt-L1 = <1025000>; + opp-microvolt-L2 = <975000>; + opp-microvolt-L3 = <950000>; }; opp-480000000 { opp-hz = /bits/ 64 <480000000>; opp-microvolt = <1125000>; opp-microvolt-L0 = <1125000>; opp-microvolt-L1 = <1100000>; + opp-microvolt-L2 = <1050000>; + opp-microvolt-L3 = <1000000>; }; }; @@ -1515,6 +1560,19 @@ status = "disabled"; }; + cif_new: cif-new@ff490000 { + compatible = "rockchip,px30-cif"; + reg = <0x0 0xff490000 0x0 0x200>; + interrupts = ; + clocks = <&cru ACLK_CIF>, <&cru HCLK_CIF>, <&cru PCLK_CIF>, <&cru SCLK_CIF_OUT>; + clock-names = "aclk_cif", "hclk_cif", "pclk_cif", "cif_out"; + resets = <&cru SRST_CIF_A>, <&cru SRST_CIF_H>, <&cru SRST_CIF_PCLKIN>; + reset-names = "rst_cif_a", "rst_cif_h", "rst_cif_pclkin"; + power-domains = <&power PX30_PD_VI>; + iommus = <&vip_mmu>; + status = "disabled"; + }; + vip_mmu: iommu@ff490800{ compatible = "rockchip,iommu"; reg = <0x0 0xff490800 0x0 0x100>; @@ -1730,7 +1788,9 @@ rockchip,pvtm-voltage-sel = < 0 50000 0 - 50001 99999 1 + 50001 54000 1 + 54001 60000 2 + 60001 99999 3 >; rockchip,pvtm-ch = <0 0>; @@ -1739,36 +1799,48 @@ opp-microvolt = <950000>; opp-microvolt-L0 = <950000>; opp-microvolt-L1 = <950000>; + opp-microvolt-L2 = <950000>; + opp-microvolt-L3 = <950000>; }; opp-328000000 { opp-hz = /bits/ 64 <328000000>; opp-microvolt = <950000>; opp-microvolt-L0 = <950000>; opp-microvolt-L1 = <950000>; + opp-microvolt-L2 = <950000>; + opp-microvolt-L3 = <950000>; }; opp-450000000 { opp-hz = /bits/ 64 <450000000>; opp-microvolt = <950000>; opp-microvolt-L0 = <950000>; opp-microvolt-L1 = <950000>; + opp-microvolt-L2 = <950000>; + opp-microvolt-L3 = <950000>; }; opp-528000000 { opp-hz = /bits/ 64 <528000000>; opp-microvolt = <975000>; opp-microvolt-L0 = <975000>; opp-microvolt-L1 = <975000>; + opp-microvolt-L2 = <950000>; + opp-microvolt-L3 = <950000>; }; opp-666000000 { opp-hz = /bits/ 64 <666000000>; opp-microvolt = <1050000>; opp-microvolt-L0 = <1050000>; opp-microvolt-L1 = <1000000>; + opp-microvolt-L2 = <975000>; + opp-microvolt-L3 = <950000>; }; opp-786000000 { opp-hz = /bits/ 64 <786000000>; opp-microvolt = <1100000>; opp-microvolt-L0 = <1100000>; opp-microvolt-L1 = <1050000>; + opp-microvolt-L2 = <1025000>; + opp-microvolt-L3 = <1000000>; status = "disabled"; }; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3308-ai-va-v10.dts b/arch/arm64/boot/dts/rockchip/rk3308-ai-va-v10.dts index f416d59b0ccdc..dd519ce7763dd 100644 --- a/arch/arm64/boot/dts/rockchip/rk3308-ai-va-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3308-ai-va-v10.dts @@ -13,7 +13,7 @@ compatible = "rockchip,rk3308-ai-va-v10", "rockchip,rk3308"; chosen { - bootargs = "earlycon=uart8250,mmio32,0xff0c0000 swiotlb=1 console=ttyFIQ0 root=PARTUUID=614e0000-0000 rootfstype=squashfs rootwait"; + bootargs = "earlycon=uart8250,mmio32,0xff0c0000 swiotlb=1 console=ttyFIQ0 root=PARTUUID=614e0000-0000 rootfstype=squashfs rootwait snd_aloop.index=7"; }; adc-keys0 { diff --git a/arch/arm64/boot/dts/rockchip/rk3308-evb-amic-v10.dts b/arch/arm64/boot/dts/rockchip/rk3308-evb-amic-v10.dts index 1546848258b44..871f1785340f2 100644 --- a/arch/arm64/boot/dts/rockchip/rk3308-evb-amic-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3308-evb-amic-v10.dts @@ -13,7 +13,7 @@ compatible = "rockchip,rk3308-evb-amic-v10", "rockchip,rk3308"; vad_acodec_sound: vad-acodec-sound { - status = "disabled"; + status = "okay"; compatible = "rockchip,multicodecs-card"; rockchip,card-name = "rockchip,rk3308-vad"; rockchip,codec-hp-det; @@ -23,13 +23,32 @@ }; }; +&acodec { + rockchip,en-always-grps = <0 1 2>; +}; + +&acodec_sound { + status = "disabled"; +}; + +&bluetooth_sound { + status = "okay"; +}; + +&i2s_2ch_0 { + status = "okay"; + #sound-dai-cells = <0>; + rockchip,clk-trcm = <1>; +}; + &is31fl3236 { reg = <0x3f>; }; &vad { - status = "disabled"; + status = "okay"; rockchip,audio-src = <&i2s_8ch_2>; + rockchip,buffer-time-ms = <200>; rockchip,mode = <1>; #sound-dai-cells = <0>; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3308-evb-amic-v11.dts b/arch/arm64/boot/dts/rockchip/rk3308-evb-amic-v11.dts index 30356481da9a6..c82a7f4d5ee8f 100644 --- a/arch/arm64/boot/dts/rockchip/rk3308-evb-amic-v11.dts +++ b/arch/arm64/boot/dts/rockchip/rk3308-evb-amic-v11.dts @@ -12,7 +12,7 @@ compatible = "rockchip,rk3308-evb-amic-v11", "rockchip,rk3308"; vad_acodec_sound: vad-acodec-sound { - status = "disabled"; + status = "okay"; compatible = "rockchip,multicodecs-card"; rockchip,card-name = "rockchip,rk3308-vad"; rockchip,codec-hp-det; @@ -22,13 +22,34 @@ }; }; +&acodec { + rockchip,en-always-grps = <1 2 3>; + rockchip,adc-grps-route = <1 2 3 0>; +}; + +&acodec_sound { + status = "disabled"; +}; + +&bluetooth_sound { + status = "okay"; +}; + +&i2s_2ch_0 { + status = "okay"; + #sound-dai-cells = <0>; + rockchip,clk-trcm = <1>; +}; + &is31fl3236 { reg = <0x3f>; }; &vad { - status = "disabled"; + status = "okay"; rockchip,audio-src = <&i2s_8ch_2>; + rockchip,det-channel = <0>; + rockchip,buffer-time-ms = <200>; rockchip,mode = <1>; #sound-dai-cells = <0>; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3308-evb-dmic-i2s-v10.dts b/arch/arm64/boot/dts/rockchip/rk3308-evb-dmic-i2s-v10.dts index 94abbecba79a7..616ae24ed2252 100644 --- a/arch/arm64/boot/dts/rockchip/rk3308-evb-dmic-i2s-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3308-evb-dmic-i2s-v10.dts @@ -58,9 +58,14 @@ status = "disabled"; }; -&dummy_codec { - status = "disabled"; +&bluetooth_sound { + status = "okay"; +}; + +&i2s_2ch_0 { + status = "okay"; #sound-dai-cells = <0>; + rockchip,clk-trcm = <1>; }; &i2s_8ch_0 { diff --git a/arch/arm64/boot/dts/rockchip/rk3308-evb-dmic-i2s-v11.dts b/arch/arm64/boot/dts/rockchip/rk3308-evb-dmic-i2s-v11.dts index e7676ef61e795..fb66021313012 100644 --- a/arch/arm64/boot/dts/rockchip/rk3308-evb-dmic-i2s-v11.dts +++ b/arch/arm64/boot/dts/rockchip/rk3308-evb-dmic-i2s-v11.dts @@ -46,9 +46,14 @@ status = "disabled"; }; -&dummy_codec { - status = "disabled"; +&bluetooth_sound { + status = "okay"; +}; + +&i2s_2ch_0 { + status = "okay"; #sound-dai-cells = <0>; + rockchip,clk-trcm = <1>; }; &i2s_8ch_0 { diff --git a/arch/arm64/boot/dts/rockchip/rk3308-evb-dmic-pdm-v10.dts b/arch/arm64/boot/dts/rockchip/rk3308-evb-dmic-pdm-v10.dts index 7a2e837138cae..acd306428c49c 100644 --- a/arch/arm64/boot/dts/rockchip/rk3308-evb-dmic-pdm-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3308-evb-dmic-pdm-v10.dts @@ -45,9 +45,14 @@ status = "disabled"; }; -&dummy_codec { - status = "disabled"; +&bluetooth_sound { + status = "okay"; +}; + +&i2s_2ch_0 { + status = "okay"; #sound-dai-cells = <0>; + rockchip,clk-trcm = <1>; }; &pdm_8ch { diff --git a/arch/arm64/boot/dts/rockchip/rk3308-evb-dmic-pdm-v11.dts b/arch/arm64/boot/dts/rockchip/rk3308-evb-dmic-pdm-v11.dts index 7932d0a8545d9..8644d443f58c6 100644 --- a/arch/arm64/boot/dts/rockchip/rk3308-evb-dmic-pdm-v11.dts +++ b/arch/arm64/boot/dts/rockchip/rk3308-evb-dmic-pdm-v11.dts @@ -45,9 +45,14 @@ status = "disabled"; }; -&dummy_codec { - status = "disabled"; +&bluetooth_sound { + status = "okay"; +}; + +&i2s_2ch_0 { + status = "okay"; #sound-dai-cells = <0>; + rockchip,clk-trcm = <1>; }; &pdm_8ch { diff --git a/arch/arm64/boot/dts/rockchip/rk3308-evb-ext-v10.dtsi b/arch/arm64/boot/dts/rockchip/rk3308-evb-ext-v10.dtsi index 16a1b50762d48..1c0e66384c16b 100644 --- a/arch/arm64/boot/dts/rockchip/rk3308-evb-ext-v10.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3308-evb-ext-v10.dtsi @@ -52,7 +52,6 @@ enable-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; enable-delay-ms = <20>; reset-gpios = <&gpio0 RK_PC4 GPIO_ACTIVE_LOW>; - reset-value = <0>; reset-delay-ms = <10>; prepare-delay-ms = <20>; unprepare-delay-ms = <20>; @@ -63,10 +62,6 @@ spi-cs-gpios = <&gpio1 RK_PD1 GPIO_ACTIVE_HIGH>; width-mm = <217>; height-mm = <136>; - rockchip,data-mapping = "vesa"; - rockchip,data-width = <24>; - rockchip,output = "rgb"; - rgb-mode = "p666"; status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&spi_init_cmd>; diff --git a/arch/arm64/boot/dts/rockchip/rk3308-evb-v10.dtsi b/arch/arm64/boot/dts/rockchip/rk3308-evb-v10.dtsi index cf8a61b0945c5..c772b8aed2636 100644 --- a/arch/arm64/boot/dts/rockchip/rk3308-evb-v10.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3308-evb-v10.dtsi @@ -12,7 +12,7 @@ compatible = "rockchip,rk3308-evb", "rockchip,rk3308"; chosen { - bootargs = "earlycon=uart8250,mmio32,0xff0c0000 swiotlb=1 console=ttyFIQ0 root=PARTUUID=614e0000-0000 rootfstype=squashfs rootwait"; + bootargs = "earlycon=uart8250,mmio32,0xff0c0000 swiotlb=1 console=ttyFIQ0 root=PARTUUID=614e0000-0000 rootfstype=squashfs rootwait snd_aloop.index=7"; }; adc-keys0 { @@ -111,6 +111,30 @@ rockchip,codec = <&acodec>; }; + bluetooth_sound: bluetooth-sound { + status = "disabled"; + compatible = "rockchip,multicodecs-card"; + rockchip,card-name = "rockchip,rk3308-pcm"; + rockchip,mclk-fs = <128>; + rockchip,cpu = <&i2s_2ch_0>; + rockchip,codec = <&dummy_codec>; + rockchip,format = "dsp_b"; + rockchip,bitclock-inversion = <0>; + rockchip,wait-card-locked = <0>; + }; + + spdif_rx_sound: spdif-rx-sound { + status = "disabled"; + compatible = "simple-audio-card"; + simple-audio-card,name = "rockchip,spdif-rx-sound"; + simple-audio-card,cpu { + sound-dai = <&spdif_rx>; + }; + simple-audio-card,codec { + sound-dai = <&dummy_codec>; + }; + }; + spdif_tx_sound: spdif-tx-sound { status = "disabled"; compatible = "simple-audio-card"; @@ -130,6 +154,7 @@ regulator-min-microvolt = <827000>; regulator-max-microvolt = <1340000>; regulator-init-microvolt = <1015000>; + regulator-early-min-microvolt = <1015000>; regulator-always-on; regulator-boot-on; regulator-settling-time-up-us = <250>; @@ -239,6 +264,7 @@ &acodec { status = "okay"; + rockchip,no-deep-low-power; rockchip,loopback-grp = <3>; hp-ctl-gpios = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>; spk-ctl-gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>; @@ -648,6 +674,10 @@ status = "okay"; }; +&rng { + status = "okay"; +}; + &saradc { status = "okay"; vref-supply = <&vcc_1v8>; @@ -675,6 +705,10 @@ status = "disabled"; }; +&sfc { + status = "okay"; +}; + &tsadc { rockchip,hw-tshut-mode = <0>; /* tshut mode 0:CRU 1:GPIO */ rockchip,hw-tshut-polarity = <1>; /* tshut polarity 0:LOW 1:HIGH */ diff --git a/arch/arm64/boot/dts/rockchip/rk3308-evb-v11.dtsi b/arch/arm64/boot/dts/rockchip/rk3308-evb-v11.dtsi index 0c8d9f3ab7d63..8b12bfea0835c 100644 --- a/arch/arm64/boot/dts/rockchip/rk3308-evb-v11.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3308-evb-v11.dtsi @@ -11,7 +11,7 @@ compatible = "rockchip,rk3308-evb-v11", "rockchip,rk3308"; chosen { - bootargs = "earlycon=uart8250,mmio32,0xff0c0000 swiotlb=1 console=ttyFIQ0 root=PARTUUID=614e0000-0000 rootfstype=squashfs rootwait"; + bootargs = "earlycon=uart8250,mmio32,0xff0c0000 swiotlb=1 console=ttyFIQ0 root=PARTUUID=614e0000-0000 rootfstype=squashfs rootwait snd_aloop.index=7"; }; adc-keys { @@ -96,6 +96,30 @@ rockchip,codec = <&acodec>; }; + bluetooth_sound: bluetooth-sound { + status = "disabled"; + compatible = "rockchip,multicodecs-card"; + rockchip,card-name = "rockchip,rk3308-pcm"; + rockchip,mclk-fs = <128>; + rockchip,cpu = <&i2s_2ch_0>; + rockchip,codec = <&dummy_codec>; + rockchip,format = "dsp_b"; + rockchip,bitclock-inversion = <0>; + rockchip,wait-card-locked = <0>; + }; + + spdif_rx_sound: spdif-rx-sound { + status = "disabled"; + compatible = "simple-audio-card"; + simple-audio-card,name = "rockchip,spdif-rx-sound"; + simple-audio-card,cpu { + sound-dai = <&spdif_rx>; + }; + simple-audio-card,codec { + sound-dai = <&dummy_codec>; + }; + }; + spdif_tx_sound: spdif-tx-sound { status = "disabled"; compatible = "simple-audio-card"; @@ -108,6 +132,20 @@ }; }; + tas5731_sound: tas5731-sound { + status = "disabled"; + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,name = "rockchip,tas5731"; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,cpu { + sound-dai = <&i2s_8ch_1>; + }; + simple-audio-card,codec { + sound-dai = <&tas5731>; + }; + }; + vdd_core: vdd-core { compatible = "pwm-regulator"; pwms = <&pwm0 0 5000 1>; @@ -245,6 +283,7 @@ &acodec { status = "okay"; + rockchip,no-deep-low-power; rockchip,loopback-grp = <0>; hp-ctl-gpios = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>; spk-ctl-gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>; @@ -254,6 +293,15 @@ cpu-supply = <&vdd_core>; }; +&cpu0_opp_table { + opp-1200000000 { + status = "okay"; + }; + opp-1296000000 { + status = "okay"; + }; +}; + &dmc { center-supply = <&vdd_log>; status = "okay"; @@ -302,6 +350,18 @@ clock-frequency = <400000>; status = "okay"; + tas5731: tas5731@1a { + #sound-dai-cells = <0>; + compatible = "ti,tas5731"; + reg = <0x1a>; + clocks = <&cru SCLK_I2S1_8CH_TX_OUT>; + clock-names = "mclk"; + pinctrl-names = "default"; + pinctrl-0 = <&i2s_8ch_1_m0_mclk>; + pdn-gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>; + reset-gpios = <&gpio1 RK_PA1 GPIO_ACTIVE_LOW>; + }; + is31fl3236: led-controller@3c { compatible = "issi,is31fl3236"; reg = <0x3c>; @@ -636,6 +696,16 @@ }; }; +&i2s_8ch_1 { + status = "disabled"; + #sound-dai-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&i2s_8ch_1_m0_sclktx + &i2s_8ch_1_m0_lrcktx + &i2s_8ch_1_m0_sdo0 + &i2s_8ch_1_m0_mclk>; +}; + &i2s_8ch_2 { status = "okay"; }; @@ -654,6 +724,10 @@ status = "okay"; }; +&rng { + status = "okay"; +}; + &saradc { status = "okay"; vref-supply = <&vcc_1v8>; diff --git a/arch/arm64/boot/dts/rockchip/rk3308-voice-module-board-v10.dts b/arch/arm64/boot/dts/rockchip/rk3308-voice-module-board-v10.dts new file mode 100644 index 0000000000000..9f94c3579ff76 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3308-voice-module-board-v10.dts @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd + */ + +/dts-v1/; + +#include "arm/rk3308-voice-module-board-v10-aarch32.dts" + +/ { + model = "Rockchip RK3308 Voice Module Board V10"; + compatible = "rockchip,rk3308-voice-module-board-v10", "rockchip,rk3308"; +}; + +&ramoops_mem { + reg = <0x0 0x110000 0x0 0xf0000>; +}; + +&ramoops { + record-size = <0x0 0x30000>; + console-size = <0x0 0xc0000>; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3308.dtsi b/arch/arm64/boot/dts/rockchip/rk3308.dtsi index a279f0aafd03a..5578630273229 100644 --- a/arch/arm64/boot/dts/rockchip/rk3308.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3308.dtsi @@ -101,6 +101,25 @@ nvmem-cells = <&cpu_leakage>; nvmem-cell-names = "leakage"; + rockchip,pvtm-voltage-sel = < + 0 54000 0 + 54001 56000 1 + 56001 58000 2 + 58001 60000 3 + 60001 62000 4 + 62001 64000 5 + 64001 99999 6 + >; + rockchip,pvtm-freq = <408000>; + rockchip,pvtm-volt = <1025000>; + rockchip,pvtm-ch = <0 0>; + rockchip,pvtm-sample-time = <1000>; + rockchip,pvtm-number = <10>; + rockchip,pvtm-error = <1000>; + rockchip,pvtm-ref-temp = <35>; + rockchip,pvtm-temp-prop = <15 37>; + rockchip,thermal-zone = "soc-thermal"; + opp-408000000 { opp-hz = /bits/ 64 <408000000>; opp-microvolt = <950000 950000 1340000>; @@ -114,18 +133,53 @@ }; opp-816000000 { opp-hz = /bits/ 64 <816000000>; - opp-microvolt = <1050000 1050000 1340000>; + opp-microvolt = <1025000 1025000 1340000>; + opp-microvolt-L0 = <1025000 1025000 1340000>; + opp-microvolt-L1 = <1000000 1000000 1340000>; + opp-microvolt-L2 = <975000 975000 1340000>; + opp-microvolt-L3 = <975000 975000 1340000>; + opp-microvolt-L4 = <950000 950000 1340000>; + opp-microvolt-L5 = <950000 950000 1340000>; + opp-microvolt-L6 = <950000 950000 1340000>; clock-latency-ns = <40000>; }; opp-1008000000 { opp-hz = /bits/ 64 <1008000000>; - opp-microvolt = <1100000 1100000 1340000>; + opp-microvolt = <1125000 1125000 1340000>; + opp-microvolt-L0 = <1125000 1125000 1340000>; + opp-microvolt-L1 = <1100000 1100000 1340000>; + opp-microvolt-L2 = <1075000 1075000 1340000>; + opp-microvolt-L3 = <1075000 1075000 1340000>; + opp-microvolt-L4 = <1050000 1050000 1340000>; + opp-microvolt-L5 = <1050000 1050000 1340000>; + opp-microvolt-L6 = <1025000 1025000 1340000>; clock-latency-ns = <40000>; }; opp-1200000000 { opp-hz = /bits/ 64 <1200000000>; - opp-microvolt = <1200000 1200000 1340000>; + opp-microvolt = <1250000 1250000 1340000>; + opp-microvolt-L0 = <1250000 1250000 1340000>; + opp-microvolt-L1 = <1225000 1225000 1340000>; + opp-microvolt-L2 = <1200000 1200000 1340000>; + opp-microvolt-L3 = <1175000 1175000 1340000>; + opp-microvolt-L4 = <1150000 1150000 1340000>; + opp-microvolt-L5 = <1125000 1125000 1340000>; + opp-microvolt-L6 = <1100000 1100000 1340000>; clock-latency-ns = <40000>; + status = "disabled"; + }; + opp-1296000000 { + opp-hz = /bits/ 64 <1296000000>; + opp-microvolt = <1300000 1300000 1340000>; + opp-microvolt-L0 = <1300000 1300000 1340000>; + opp-microvolt-L1 = <1275000 1275000 1340000>; + opp-microvolt-L2 = <1250000 1250000 1340000>; + opp-microvolt-L3 = <1225000 1225000 1340000>; + opp-microvolt-L4 = <1200000 1200000 1340000>; + opp-microvolt-L5 = <1175000 1175000 1340000>; + opp-microvolt-L6 = <1150000 1150000 1340000>; + clock-latency-ns = <40000>; + status = "disabled"; }; }; @@ -436,7 +490,6 @@ reg-io-width = <4>; dmas = <&dmac0 4>, <&dmac0 5>; dma-names = "tx", "rx"; - #dma-cells = <2>; pinctrl-names = "default"; pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>; status = "disabled"; @@ -452,7 +505,6 @@ reg-io-width = <4>; dmas = <&dmac0 6>, <&dmac0 7>; dma-names = "tx", "rx"; - #dma-cells = <2>; pinctrl-names = "default"; pinctrl-0 = <&uart1_xfer &uart1_cts &uart1_rts>; status = "disabled"; @@ -468,7 +520,6 @@ reg-io-width = <4>; dmas = <&dmac0 8>, <&dmac0 9>; dma-names = "tx", "rx"; - #dma-cells = <2>; pinctrl-names = "default"; pinctrl-0 = <&uart2m0_xfer>; status = "disabled"; @@ -484,7 +535,6 @@ reg-io-width = <4>; dmas = <&dmac0 10>, <&dmac0 11>; dma-names = "tx", "rx"; - #dma-cells = <2>; pinctrl-names = "default"; pinctrl-0 = <&uart3_xfer>; status = "disabled"; @@ -500,7 +550,6 @@ reg-io-width = <4>; dmas = <&dmac1 18>, <&dmac1 19>; dma-names = "tx", "rx"; - #dma-cells = <2>; pinctrl-names = "default"; pinctrl-0 = <&uart4_xfer &uart4_cts &uart4_rts>; status = "disabled"; @@ -515,7 +564,6 @@ clocks = <&cru SCLK_SPI0>, <&cru PCLK_SPI0>; clock-names = "spiclk", "apb_pclk"; dmas = <&dmac0 0>, <&dmac0 1>; - #dma-cells = <2>; dma-names = "tx", "rx"; pinctrl-names = "default", "high_speed"; pinctrl-0 = <&spi0_clk &spi0_csn0 &spi0_miso &spi0_mosi>; @@ -532,7 +580,6 @@ clocks = <&cru SCLK_SPI1>, <&cru PCLK_SPI1>; clock-names = "spiclk", "apb_pclk"; dmas = <&dmac0 2>, <&dmac0 3>; - #dma-cells = <2>; dma-names = "tx", "rx"; pinctrl-names = "default", "high_speed"; pinctrl-0 = <&spi1_clk &spi1_csn0 &spi1_miso &spi1_mosi>; @@ -549,7 +596,6 @@ clocks = <&cru SCLK_SPI2>, <&cru PCLK_SPI2>; clock-names = "spiclk", "apb_pclk"; dmas = <&dmac1 16>, <&dmac1 17>; - #dma-cells = <2>; dma-names = "tx", "rx"; pinctrl-names = "default", "high_speed"; pinctrl-0 = <&spi2_clk &spi2_csn0 &spi2_miso &spi2_mosi>; @@ -557,13 +603,101 @@ status = "disabled"; }; + pwm8: pwm@ff160000 { + compatible = "rockchip,rk3308-pwm", "rockchip,rk3328-pwm"; + reg = <0x0 0xff160000 0x0 0x10>; + #pwm-cells = <3>; + pinctrl-names = "active"; + pinctrl-0 = <&pwm8_pin>; + clocks = <&cru SCLK_PWM2>, <&cru PCLK_PWM2>; + clock-names = "pwm", "pclk"; + status = "disabled"; + }; + + pwm9: pwm@ff160010 { + compatible = "rockchip,rk3308-pwm", "rockchip,rk3328-pwm"; + reg = <0x0 0xff160010 0x0 0x10>; + #pwm-cells = <3>; + pinctrl-names = "active"; + pinctrl-0 = <&pwm9_pin>; + clocks = <&cru SCLK_PWM2>, <&cru PCLK_PWM2>; + clock-names = "pwm", "pclk"; + status = "disabled"; + }; + + pwm10: pwm@ff160020 { + compatible = "rockchip,rk3308-pwm", "rockchip,rk3328-pwm"; + reg = <0x0 0xff160020 0x0 0x10>; + #pwm-cells = <3>; + pinctrl-names = "active"; + pinctrl-0 = <&pwm10_pin>; + clocks = <&cru SCLK_PWM2>, <&cru PCLK_PWM2>; + clock-names = "pwm", "pclk"; + status = "disabled"; + }; + + pwm11: pwm@ff160030 { + compatible = "rockchip,rk3308-pwm", "rockchip,rk3328-pwm"; + reg = <0x0 0xff160030 0x0 0x10>; + #pwm-cells = <3>; + pinctrl-names = "active"; + pinctrl-0 = <&pwm11_pin>; + clocks = <&cru SCLK_PWM2>, <&cru PCLK_PWM2>; + clock-names = "pwm", "pclk"; + status = "disabled"; + }; + + pwm4: pwm@ff170000 { + compatible = "rockchip,rk3308-pwm", "rockchip,rk3328-pwm"; + reg = <0x0 0xff170000 0x0 0x10>; + #pwm-cells = <3>; + pinctrl-names = "active"; + pinctrl-0 = <&pwm4_pin>; + clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>; + clock-names = "pwm", "pclk"; + status = "disabled"; + }; + + pwm5: pwm@ff170010 { + compatible = "rockchip,rk3308-pwm", "rockchip,rk3328-pwm"; + reg = <0x0 0xff170010 0x0 0x10>; + #pwm-cells = <3>; + pinctrl-names = "active"; + pinctrl-0 = <&pwm5_pin>; + clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>; + clock-names = "pwm", "pclk"; + status = "disabled"; + }; + + pwm6: pwm@ff170020 { + compatible = "rockchip,rk3308-pwm", "rockchip,rk3328-pwm"; + reg = <0x0 0xff170020 0x0 0x10>; + #pwm-cells = <3>; + pinctrl-names = "active"; + pinctrl-0 = <&pwm6_pin>; + clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>; + clock-names = "pwm", "pclk"; + status = "disabled"; + }; + + pwm7: pwm@ff170030 { + compatible = "rockchip,rk3308-pwm", "rockchip,rk3328-pwm"; + reg = <0x0 0xff170030 0x0 0x10>; + #pwm-cells = <3>; + pinctrl-names = "active"; + pinctrl-0 = <&pwm7_pin>; + clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>; + clock-names = "pwm", "pclk"; + status = "disabled"; + }; + pwm0: pwm@ff180000 { compatible = "rockchip,rk3308-pwm", "rockchip,rk3328-pwm"; reg = <0x0 0xff180000 0x0 0x10>; #pwm-cells = <3>; pinctrl-names = "active"; pinctrl-0 = <&pwm0_pin>; - clocks = <&cru SCLK_PWM>, <&cru PCLK_PWM>; + clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>; clock-names = "pwm", "pclk"; status = "disabled"; }; @@ -574,7 +708,7 @@ #pwm-cells = <3>; pinctrl-names = "active"; pinctrl-0 = <&pwm1_pin>; - clocks = <&cru SCLK_PWM>, <&cru PCLK_PWM>; + clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>; clock-names = "pwm", "pclk"; status = "disabled"; }; @@ -585,7 +719,7 @@ #pwm-cells = <3>; pinctrl-names = "active"; pinctrl-0 = <&pwm2_pin>; - clocks = <&cru SCLK_PWM>, <&cru PCLK_PWM>; + clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>; clock-names = "pwm", "pclk"; status = "disabled"; }; @@ -596,19 +730,28 @@ #pwm-cells = <3>; pinctrl-names = "active"; pinctrl-0 = <&pwm3_pin>; - clocks = <&cru SCLK_PWM>, <&cru PCLK_PWM>; + clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>; clock-names = "pwm", "pclk"; status = "disabled"; }; rktimer: rktimer@ff1a0000 { compatible = "rockchip,rk3288-timer"; - reg = <0x0 0xff1a0000 0x0 0x1000>; + reg = <0x0 0xff1a0000 0x0 0x20>; interrupts = ; clocks = <&cru PCLK_TIMER>, <&cru SCLK_TIMER0>; clock-names = "pclk", "timer"; }; + rk_timer_rtc: rk-timer-rtc@ff1a0020 { + compatible = "rockchip,rk3308-timer-rtc"; + reg = <0x0 0xff1a0020 0x0 0x20>; + interrupts = ; + clocks = <&cru PCLK_TIMER>, <&cru SCLK_TIMER1>; + clock-names = "pclk", "timer"; + status = "disabled"; + }; + saradc: saradc@ff1e0000 { compatible = "rockchip,rk3308-saradc", "rockchip,rk3399-saradc"; reg = <0x0 0xff1e0000 0x0 0x100>; @@ -759,6 +902,22 @@ }; }; + rng: rng@ff2f0000 { + compatible = "rockchip,cryptov2-rng"; + reg = <0x0 0xff2f0000 0x0 0x4000>; + clocks = <&cru SCLK_CRYPTO>, <&cru SCLK_CRYPTO_APK>, + <&cru ACLK_CRYPTO>, <&cru HCLK_CRYPTO>; + clock-names = "clk_crypto", "clk_crypto_apk", + "aclk_crypto", "hclk_crypto"; + assigned-clocks = <&cru SCLK_CRYPTO>, <&cru SCLK_CRYPTO_APK>, + <&cru ACLK_CRYPTO>, <&cru HCLK_CRYPTO>; + assigned-clock-rates = <150000000>, <150000000>, + <200000000>, <100000000>; + resets = <&cru SRST_CRYPTO>; + reset-names = "reset"; + status = "disabled"; + }; + i2s_8ch_0: i2s@ff300000 { compatible = "rockchip,rk3308-i2s-tdm"; reg = <0x0 0xff300000 0x0 0x1000>; @@ -915,6 +1074,21 @@ status = "disabled"; }; + spdif_rx: spdif-rx@ff3b0000 { + compatible = "rockchip,rk3308-spdifrx"; + reg = <0x0 0xff3b0000 0x0 0x1000>; + interrupts = ; + clocks = <&cru SCLK_SPDIF_RX>, <&cru HCLK_SPDIFRX>; + clock-names = "mclk", "hclk"; + dmas = <&dmac1 14>; + dma-names = "rx"; + resets = <&cru SRST_SPDIFRX_M>; + reset-names = "spdifrx-m"; + pinctrl-names = "default"; + pinctrl-0 = <&spdif_in>; + status = "disabled"; + }; + vad: vad@ff3c0000 { compatible = "rockchip,rk3308-vad", "rockchip,vad"; reg = <0x0 0xff3c0000 0x0 0x10000>, <0x0 0xfff88000 0x0 0x38000>; @@ -1025,6 +1199,8 @@ interrupts = ; clocks = <&cru SCLK_SFC>, <&cru HCLK_SFC>; clock-names = "clk_sfc", "hclk_sfc"; + assigned-clocks = <&cru SCLK_SFC>; + assigned-clock-rates = <100000000>; status = "disabled"; }; @@ -1526,6 +1702,38 @@ /* d17 */ <1 RK_PC5 RK_FUNC_1 &pcfg_pull_none>; }; + + lcdc_rgb888_m0: lcdc-rgb888-m0 { + rockchip,pins = + /* d18 */ + <1 RK_PC6 RK_FUNC_2 &pcfg_pull_none>, + /* d19 */ + <1 RK_PC7 RK_FUNC_2 &pcfg_pull_none>, + /* d20 */ + <2 RK_PB1 RK_FUNC_4 &pcfg_pull_none>, + /* d21 */ + <2 RK_PB2 RK_FUNC_4 &pcfg_pull_none>, + /* d22 */ + <2 RK_PB7 RK_FUNC_4 &pcfg_pull_none>, + /* d23 */ + <2 RK_PC0 RK_FUNC_4 &pcfg_pull_none>; + }; + + lcdc_rgb888_m1: lcdc-rgb888-m1 { + rockchip,pins = + /* d18 */ + <3 RK_PA6 RK_FUNC_2 &pcfg_pull_none>, + /* d19 */ + <3 RK_PA7 RK_FUNC_2 &pcfg_pull_none>, + /* d20 */ + <3 RK_PB0 RK_FUNC_2 &pcfg_pull_none>, + /* d21 */ + <3 RK_PB1 RK_FUNC_2 &pcfg_pull_none>, + /* d22 */ + <3 RK_PB2 RK_FUNC_2 &pcfg_pull_none>, + /* d23 */ + <3 RK_PB3 RK_FUNC_2 &pcfg_pull_none>; + }; }; pdm_m0 { @@ -1585,7 +1793,7 @@ pdm_m2 { pdm_m2_clkm: pdm-m2-clkm { rockchip,pins = - <2 RK_PA4 RK_FUNC_2 &pcfg_pull_none>; + <2 RK_PA4 RK_FUNC_3 &pcfg_pull_none>; }; pdm_m2_clk: pdm-m2-clk { @@ -1614,6 +1822,13 @@ }; }; + spdif_in { + spdif_in: spdif-in { + rockchip,pins = + <0 RK_PC2 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + spdif_out { spdif_out: spdif-out { rockchip,pins = @@ -1693,6 +1908,14 @@ }; }; + uart3-m1 { + uart3m1_xfer: uart3m1-xfer { + rockchip,pins = + <0 RK_PC2 3 &pcfg_pull_up>, + <0 RK_PC1 3 &pcfg_pull_up>; + }; + }; + uart4 { uart4_xfer: uart4-xfer { @@ -1793,6 +2016,48 @@ }; }; + spi1-m1 { + spi1m1_miso: spi1m1-miso { + rockchip,pins = + <2 RK_PA4 2 &pcfg_pull_up_4ma>; + }; + + spi1m1_mosi: spi1m1-mosi { + rockchip,pins = + <2 RK_PA5 2 &pcfg_pull_up_4ma>; + }; + + spi1m1_clk: spi1m1-clk { + rockchip,pins = + <2 RK_PA7 2 &pcfg_pull_up_4ma>; + }; + + spi1m1_csn0: spi1m1-csn0 { + rockchip,pins = + <2 RK_PB1 2 &pcfg_pull_up_4ma>; + }; + + spi1m1_miso_hs: spi1m1-miso-hs { + rockchip,pins = + <2 RK_PA4 2 &pcfg_pull_up_8ma>; + }; + + spi1m1_mosi_hs: spi1m1-mosi-hs { + rockchip,pins = + <2 RK_PA5 2 &pcfg_pull_up_8ma>; + }; + + spi1m1_clk_hs: spi1m1-clk-hs { + rockchip,pins = + <2 RK_PA7 2 &pcfg_pull_up_8ma>; + }; + + spi1m1_csn0_hs: spi1m1-csn0-hs { + rockchip,pins = + <2 RK_PB1 2 &pcfg_pull_up_8ma>; + }; + }; + spi2 { spi2_clk: spi2-clk { rockchip,pins = @@ -2065,6 +2330,102 @@ }; }; + pwm4 { + pwm4_pin: pwm4-pin { + rockchip,pins = + <0 RK_PA1 2 &pcfg_pull_none>; + }; + + pwm4_pin_pull_down: pwm4-pin-pull-down { + rockchip,pins = + <0 RK_PA1 2 &pcfg_pull_down>; + }; + }; + + pwm5 { + pwm5_pin: pwm5-pin { + rockchip,pins = + <0 RK_PC1 2 &pcfg_pull_none>; + }; + + pwm5_pin_pull_down: pwm5-pin-pull-down { + rockchip,pins = + <0 RK_PC1 2 &pcfg_pull_down>; + }; + }; + + pwm6 { + pwm6_pin: pwm6-pin { + rockchip,pins = + <0 RK_PC2 2 &pcfg_pull_none>; + }; + + pwm6_pin_pull_down: pwm6-pin-pull-down { + rockchip,pins = + <0 RK_PC2 2 &pcfg_pull_down>; + }; + }; + + pwm7 { + pwm7_pin: pwm7-pin { + rockchip,pins = + <2 RK_PB0 2 &pcfg_pull_none>; + }; + + pwm7_pin_pull_down: pwm7-pin-pull-down { + rockchip,pins = + <2 RK_PB0 2 &pcfg_pull_down>; + }; + }; + + pwm8 { + pwm8_pin: pwm8-pin { + rockchip,pins = + <2 RK_PB2 2 &pcfg_pull_none>; + }; + + pwm8_pin_pull_down: pwm8-pin-pull-down { + rockchip,pins = + <2 RK_PB2 2 &pcfg_pull_down>; + }; + }; + + pwm9 { + pwm9_pin: pwm9-pin { + rockchip,pins = + <2 RK_PB3 2 &pcfg_pull_none>; + }; + + pwm9_pin_pull_down: pwm9-pin-pull-down { + rockchip,pins = + <2 RK_PB3 2 &pcfg_pull_down>; + }; + }; + + pwm10 { + pwm10_pin: pwm10-pin { + rockchip,pins = + <2 RK_PB4 2 &pcfg_pull_none>; + }; + + pwm10_pin_pull_down: pwm10-pin-pull-down { + rockchip,pins = + <2 RK_PB4 2 &pcfg_pull_down>; + }; + }; + + pwm11 { + pwm11_pin: pwm11-pin { + rockchip,pins = + <2 RK_PC0 4 &pcfg_pull_none>; + }; + + pwm11_pin_pull_down: pwm11-pin-pull-down { + rockchip,pins = + <2 RK_PC0 4 &pcfg_pull_down>; + }; + }; + gmac { rmii_pins: rmii-pins { rockchip,pins = @@ -2099,11 +2460,99 @@ }; }; + gmac-m1 { + rmiim1_pins: rmiim1-pins { + rockchip,pins = + /* mac_txen */ + <4 RK_PB7 2 &pcfg_pull_none_12ma>, + /* mac_txd1 */ + <4 RK_PA5 2 &pcfg_pull_none_12ma>, + /* mac_txd0 */ + <4 RK_PA4 2 &pcfg_pull_none_12ma>, + /* mac_rxd0 */ + <4 RK_PA2 2 &pcfg_pull_none>, + /* mac_rxd1 */ + <4 RK_PA3 2 &pcfg_pull_none>, + /* mac_rxer */ + <4 RK_PA0 2 &pcfg_pull_none>, + /* mac_rxdv */ + <4 RK_PA1 2 &pcfg_pull_none>, + /* mac_mdio */ + <4 RK_PB6 2 &pcfg_pull_none>, + /* mac_mdc */ + <4 RK_PB5 2 &pcfg_pull_none>; + }; + + macm1_refclk_12ma: macm1-refclk-12ma { + rockchip,pins = + <4 RK_PB4 2 &pcfg_pull_none_12ma>; + }; + + macm1_refclk: macm1-refclk { + rockchip,pins = + <4 RK_PB4 2 &pcfg_pull_none>; + }; + }; + rtc { rtc_32k: rtc-32k { rockchip,pins = <0 RK_PC3 1 &pcfg_pull_none>; }; }; + + can-m0 { + canm0_pins: canm0-pins { + rockchip,pins = + /* can_rxd_m0 */ + <0 RK_PB3 2 &pcfg_pull_none>, + /* can_txd_m0 */ + <0 RK_PB4 2 &pcfg_pull_none>; + }; + }; + + can-m1 { + canm1_pins: canm1-pins { + rockchip,pins = + /* can_rxd_m1 */ + <1 RK_PC6 5 &pcfg_pull_none>, + /* can_txd_m1 */ + <1 RK_PC7 5 &pcfg_pull_none>; + }; + }; + + can-m2 { + canm2_pins: canm2-pins { + rockchip,pins = + /* can_rxd_m2 */ + <2 RK_PA2 4 &pcfg_pull_none>, + /* can_txd_m2 */ + <2 RK_PA3 4 &pcfg_pull_none>; + }; + }; + + owire-m0 { + owirem0_pins: owirem0-pins { + rockchip,pins = + /* owire_m0 */ + <0 RK_PB3 3 &pcfg_pull_none>; + }; + }; + + owire-m1 { + owirem1_pins: owirem1-pins { + rockchip,pins = + /* owire_m1 */ + <1 RK_PC6 7 &pcfg_pull_none>; + }; + }; + + owire-m2 { + owirem2_pins: owirem2-pins { + rockchip,pins = + /* owire_m2 */ + <2 RK_PA2 5 &pcfg_pull_none>; + }; + }; }; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3326-863-lp3-v10-avb.dts b/arch/arm64/boot/dts/rockchip/rk3326-863-lp3-v10-avb.dts new file mode 100644 index 0000000000000..ce9dc36787ddb --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3326-863-lp3-v10-avb.dts @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd + */ + +/dts-v1/; +#include "rk3326-863-lp3-v10.dtsi" + +/ { + model = "Rockchip rk3326 863 avb board"; + compatible = "rockchip,rk3326-863-lp3-v10-avb", "rockchip,rk3326"; +}; + +&firmware_android { + compatible = "android,firmware"; + vbmeta { + compatible = "android,vbmeta"; + parts = "vbmeta,boot,system,vendor,dtbo"; + }; + fstab { + compatible = "android,fstab"; + vendor { + compatible = "android,vendor"; + dev = "/dev/block/platform/ff390000.dwmmc/by-name/vendor"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait,avb"; + }; + }; +}; + +&i2c2 { + status = "okay"; + + gc0312@21 { + status = "okay"; + compatible = "galaxycore,gc0312"; + reg = <0x21>; + pinctrl-names = "default"; + pinctrl-0 = <&cif_clkout_m0>; + + clocks = <&cru SCLK_CIF_OUT>; + clock-names = "xvclk"; + + avdd-supply = <&vcc2v8_dvp>; + dovdd-supply = <&vcc1v8_dvp>; + dvdd-supply = <&vcc1v8_dvp>; + + pwdn-gpios = <&gpio2 14 GPIO_ACTIVE_HIGH>; + + port { + gc0312_out: endpoint { + remote-endpoint = <&dvp_in_fcam>; + }; + }; + }; + + gc2145@3c { + status = "okay"; + compatible = "galaxycore,gc2145"; + reg = <0x3c>; + pinctrl-names = "default"; + pinctrl-0 = <&cif_clkout_m0>; + + clocks = <&cru SCLK_CIF_OUT>; + clock-names = "xvclk"; + + avdd-supply = <&vcc2v8_dvp>; + dovdd-supply = <&vcc1v8_dvp>; + dvdd-supply = <&vcc1v8_dvp>; + + pwdn-gpios = <&gpio2 13 GPIO_ACTIVE_HIGH>; + + port { + gc2145_out: endpoint { + remote-endpoint = <&dvp_in_bcam>; + }; + }; + }; +}; + +&isp_mmu { + status = "okay"; +}; + +&rkisp1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&cif_clkout_m0 &dvp_d0d1_m0 &dvp_d2d9_m0 &dvp_d10d11_m0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + dvp_in_fcam: endpoint@0 { + reg = <0>; + remote-endpoint = <&gc0312_out>; + }; + + dvp_in_bcam: endpoint@1 { + reg = <1>; + remote-endpoint = <&gc2145_out>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3326-863-lp3-v10.dts b/arch/arm64/boot/dts/rockchip/rk3326-863-lp3-v10.dts index 9d1646e84422a..7a399b3356ac4 100644 --- a/arch/arm64/boot/dts/rockchip/rk3326-863-lp3-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3326-863-lp3-v10.dts @@ -5,159 +5,11 @@ */ /dts-v1/; -#include -#include -#include -#include -#include -#include "rk3326.dtsi" -#include "rk3326-863-cif-sensor.dtsi" -#include "px30-android.dtsi" +#include "rk3326-863-lp3-v10.dtsi" / { model = "Rockchip rk3326 863 board"; compatible = "rockchip,rk3326-863-lp3-v10", "rockchip,rk3326"; - - adc-keys { - compatible = "adc-keys"; - io-channels = <&saradc 2>; - io-channel-names = "buttons"; - poll-interval = <100>; - keyup-threshold-microvolt = <1800000>; - - vol-down-key { - linux,code = ; - label = "volume down"; - press-threshold-microvolt = <300000>; - }; - - vol-up-key { - linux,code = ; - label = "volume up"; - press-threshold-microvolt = <17000>; - }; - }; - - backlight: backlight { - compatible = "pwm-backlight"; - pwms = <&pwm1 0 25000 0>; - brightness-levels = < - 0 10 10 11 11 12 12 13 - 13 14 14 15 15 16 16 17 - 17 18 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 = <200>; - }; - - charge-animation { - compatible = "rockchip,uboot-charge"; - rockchip,uboot-charge-on = <1>; - rockchip,android-charge-on = <0>; - rockchip,uboot-low-power-voltage = <3500>; - rockchip,screen-on-voltage = <3600>; - status = "okay"; - }; - - rk817-sound { - compatible = "simple-audio-card"; - simple-audio-card,format = "i2s"; - simple-audio-card,name = "rockchip,rk817-codec"; - simple-audio-card,mclk-fs = <256>; - simple-audio-card,widgets = - "Microphone", "Mic Jack", - "Headphone", "Headphone Jack"; - simple-audio-card,routing = - "Mic Jack", "MICBIAS1", - "IN1P", "Mic Jack", - "Headphone Jack", "HPOL", - "Headphone Jack", "HPOR"; - simple-audio-card,cpu { - sound-dai = <&i2s1_2ch>; - }; - simple-audio-card,codec { - sound-dai = <&rk817_codec>; - }; - }; - - rk_headset { - compatible = "rockchip_headset"; - headset_gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_LOW>; - pinctrl-names = "default"; - pinctrl-0 = <&hp_det>; - }; - - sdio_pwrseq: sdio-pwrseq { - compatible = "mmc-pwrseq-simple"; - clocks = <&cru SCLK_WIFI_PMU>; - clock-names = "clk_wifi_pmu"; - pinctrl-names = "default"; - pinctrl-0 = <&wifi_enable_h>; - - /* - * On the module itself this is one of these (depending - * on the actual card populated): - * - SDIO_RESET_L_WL_REG_ON - * - PDN (power down when low) - */ - reset-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>; /* GPIO3_A4 */ - }; - - vccsys: vccsys { - compatible = "regulator-fixed"; - regulator-name = "vcc3v8_sys"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <3800000>; - regulator-max-microvolt = <3800000>; - }; - - wireless-wlan { - compatible = "wlan-platdata"; - wifi_chip_type = "rtl8723cs"; - WIFI,host_wake_irq = <&gpio0 RK_PB2 GPIO_ACTIVE_HIGH>; - WIFI,vbat_gpio = <&gpio3 RK_PB6 GPIO_ACTIVE_LOW>; - status = "okay"; - }; - - wireless-bluetooth { - compatible = "bluetooth-platdata"; - uart_rts_gpios = <&gpio1 RK_PC3 GPIO_ACTIVE_LOW>; - pinctrl-names = "default","rts_gpio"; - pinctrl-0 = <&uart1_rts>; - pinctrl-1 = <&uart1_rts_gpio>; - BT,reset_gpio = <&gpio0 RK_PC1 GPIO_ACTIVE_HIGH>; - BT,wake_gpio = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>; - BT,wake_host_irq = <&gpio0 RK_PB3 GPIO_ACTIVE_HIGH>; - status = "okay"; - }; }; &cif { @@ -168,630 +20,23 @@ status = "okay"; }; -&display_subsystem { - status = "okay"; -}; - -&dsi { - status = "okay"; - - panel@0 { - compatible = "aoly,sl008pa21y1285-b00", "simple-panel-dsi"; - reg = <0>; - backlight = <&backlight>; - enable-gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_LOW>; - reset-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; - prepare-delay-ms = <20>; - reset-delay-ms = <20>; - init-delay-ms = <20>; - enable-delay-ms = <120>; - disable-delay-ms = <20>; - unprepare-delay-ms = <20>; - - width-mm = <108>; - height-mm = <172>; - - dsi,flags = <(MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | - MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_EOT_PACKET)>; - dsi,format = ; - dsi,lanes = <4>; - - panel-init-sequence = [ - 05 78 01 11 - 05 14 01 29 - ]; - - panel-exit-sequence = [ - 05 00 01 28 - 05 00 01 10 - ]; - - display-timings { - native-mode = <&timing0>; - - timing0: timing0 { - clock-frequency = <66000000>; - hactive = <800>; - vactive = <1280>; - hfront-porch = <2>; - hsync-len = <18>; - hback-porch = <18>; - vfront-porch = <4>; - vsync-len = <4>; - vback-porch = <16>; - hsync-active = <0>; - vsync-active = <0>; - de-active = <0>; - pixelclk-active = <0>; - }; +&firmware_android { + compatible = "android,firmware"; + fstab { + compatible = "android,fstab"; + system { + compatible = "android,system"; + dev = "/dev/block/by-name/system"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait"; }; - }; -}; - -&bus_apll { - bus-supply = <&vdd_logic>; - status = "okay"; -}; - -&cpu0 { - cpu-supply = <&vdd_arm>; -}; - -&cpu0_opp_table { - /* - * max IR-drop values on different freq condition for this board! - */ - rockchip,board-irdrop = < - /*MHz MHz uV */ - 0 815 37500 - 816 1119 50000 - 1200 1512 75000 - >; -}; - -&dmc_opp_table { - /* - * max IR-drop values on different freq condition for this board! - */ - rockchip,board-irdrop = < - /*MHz MHz uV */ - 451 800 75000 - >; -}; - -&dsi_in_vopl { - status = "disabled"; -}; - -&dfi { - status = "okay"; -}; - -&dmc { - center-supply = <&vdd_logic>; - status = "okay"; -}; - -&emmc { - bus-width = <8>; - cap-mmc-highspeed; - mmc-hs200-1_8v; - supports-emmc; - disable-wp; - non-removable; - num-slots = <1>; - status = "okay"; -}; - -&gpu { - mali-supply = <&vdd_logic>; - status = "okay"; -}; - -&i2c0 { - status = "okay"; - - rk817: pmic@20 { - compatible = "rockchip,rk817"; - reg = <0x20>; - interrupt-parent = <&gpio0>; - interrupts = <7 IRQ_TYPE_LEVEL_LOW>; - pinctrl-names = "default", "pmic-sleep", - "pmic-power-off", "pmic-reset"; - pinctrl-0 = <&pmic_int>; - pinctrl-1 = <&soc_slppin_slp>, <&rk817_slppin_slp>; - pinctrl-2 = <&soc_slppin_gpio>, <&rk817_slppin_pwrdn>; - pinctrl-3 = <&soc_slppin_rst>, <&rk817_slppin_rst>; - rockchip,system-power-controller; - wakeup-source; - #clock-cells = <1>; - clock-output-names = "rk808-clkout1", "rk808-clkout2"; - //fb-inner-reg-idxs = <2>; - /* 1: rst regs (default in codes), 0: rst the pmic */ - pmic-reset-func = <1>; - - vcc1-supply = <&vccsys>; - vcc2-supply = <&vccsys>; - vcc3-supply = <&vccsys>; - vcc4-supply = <&vccsys>; - vcc5-supply = <&vccsys>; - vcc6-supply = <&vccsys>; - vcc7-supply = <&vcc_3v0>; - vcc8-supply = <&vccsys>; - vcc9-supply = <&dcdc_boost>; - - pwrkey { - status = "okay"; + vendor { + compatible = "android,vendor"; + dev = "/dev/block/by-name/vendor"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait"; }; - - pinctrl_rk8xx: pinctrl_rk8xx { - gpio-controller; - #gpio-cells = <2>; - - rk817_ts_gpio1: rk817_ts_gpio1 { - pins = "gpio_ts"; - function = "pin_fun1"; - /* output-low; */ - /* input-enable; */ - }; - - rk817_gt_gpio2: rk817_gt_gpio2 { - pins = "gpio_gt"; - function = "pin_fun1"; - }; - - rk817_pin_ts: rk817_pin_ts { - pins = "gpio_ts"; - function = "pin_fun0"; - }; - - rk817_pin_gt: rk817_pin_gt { - pins = "gpio_gt"; - function = "pin_fun0"; - }; - - rk817_slppin_null: rk817_slppin_null { - pins = "gpio_slp"; - function = "pin_fun0"; - }; - - rk817_slppin_slp: rk817_slppin_slp { - pins = "gpio_slp"; - function = "pin_fun1"; - }; - - rk817_slppin_pwrdn: rk817_slppin_pwrdn { - pins = "gpio_slp"; - function = "pin_fun2"; - }; - - rk817_slppin_rst: rk817_slppin_rst { - pins = "gpio_slp"; - function = "pin_fun3"; - }; - }; - - regulators { - vdd_logic: DCDC_REG1 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <950000>; - regulator-max-microvolt = <1350000>; - regulator-ramp-delay = <6001>; - regulator-initial-mode = <0x2>; - regulator-name = "vdd_logic"; - regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <950000>; - }; - }; - - vdd_arm: DCDC_REG2 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <950000>; - regulator-max-microvolt = <1350000>; - regulator-ramp-delay = <6001>; - regulator-initial-mode = <0x2>; - regulator-name = "vdd_arm"; - regulator-state-mem { - regulator-off-in-suspend; - regulator-suspend-microvolt = <950000>; - }; - }; - - vcc_ddr: DCDC_REG3 { - regulator-always-on; - regulator-boot-on; - regulator-initial-mode = <0x2>; - regulator-name = "vcc_ddr"; - regulator-state-mem { - regulator-on-in-suspend; - }; - }; - - vcc_3v0: DCDC_REG4 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <3000000>; - regulator-max-microvolt = <3000000>; - regulator-initial-mode = <0x2>; - regulator-name = "vcc_3v0"; - regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <3000000>; - }; - }; - - vcc_1v0: LDO_REG1 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <1000000>; - regulator-max-microvolt = <1000000>; - regulator-name = "vcc_1v0"; - regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <1000000>; - }; - }; - - vcc1v8_soc: LDO_REG2 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - - regulator-name = "vcc1v8_soc"; - regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <1800000>; - }; - }; - - vdd1v0_soc: LDO_REG3 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <1000000>; - regulator-max-microvolt = <1000000>; - - regulator-name = "vcc1v0_soc"; - regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <1000000>; - }; - }; - - vcc3v0_pmu: LDO_REG4 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <3000000>; - regulator-max-microvolt = <3000000>; - - regulator-name = "vcc3v0_pmu"; - regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <3000000>; - - }; - }; - - vccio_sd: LDO_REG5 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <3300000>; - - regulator-name = "vccio_sd"; - regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <3300000>; - }; - }; - - vcc_sd: LDO_REG6 { - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - - regulator-name = "vcc_sd"; - regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <3300000>; - - }; - }; - - vcc2v8_dvp: LDO_REG7 { - regulator-boot-on; - regulator-min-microvolt = <2800000>; - regulator-max-microvolt = <2800000>; - - regulator-name = "vcc2v8_dvp"; - regulator-state-mem { - regulator-off-in-suspend; - regulator-suspend-microvolt = <2800000>; - }; - }; - - vcc1v8_dvp: LDO_REG8 { - regulator-boot-on; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - - regulator-name = "vcc1v8_dvp"; - regulator-state-mem { - regulator-off-in-suspend; - regulator-suspend-microvolt = <1800000>; - }; - }; - - vdd1v5_dvp: LDO_REG9 { - regulator-boot-on; - regulator-min-microvolt = <1500000>; - regulator-max-microvolt = <1500000>; - - regulator-name = "vdd1v5_dvp"; - regulator-state-mem { - regulator-off-in-suspend; - regulator-suspend-microvolt = <1500000>; - }; - }; - - dcdc_boost: BOOST { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <4700000>; - regulator-max-microvolt = <5400000>; - regulator-name = "boost"; - }; - - otg_switch: OTG_SWITCH { - regulator-boot-on; - regulator-name = "otg_switch"; - }; - }; - - battery { - compatible = "rk817,battery"; - ocv_table = <3500 3548 3592 3636 3687 3740 3780 - 3806 3827 3846 3864 3889 3929 3964 - 3993 4015 4030 4041 4056 4076 4148>; - design_capacity = <4000>; - design_qmax = <4200>; - bat_res = <100>; - sleep_enter_current = <150>; - sleep_exit_current = <180>; - sleep_filter_current = <100>; - power_off_thresd = <3500>; - zero_algorithm_vol = <3850>; - max_soc_offset = <60>; - monitor_sec = <5>; - sample_res = <10>; - virtual_power = <0>; - }; - - charger { - compatible = "rk817,charger"; - min_input_voltage = <4500>; - max_input_current = <1500>; - max_chrg_current = <2000>; - max_chrg_voltage = <4200>; - chrg_term_mode = <0>; - chrg_finish_cur = <300>; - virtual_power = <0>; - dc_det_adc = <0>; - extcon = <&u2phy>; - }; - - rk817_codec: codec { - #sound-dai-cells = <0>; - compatible = "rockchip,rk817-codec"; - clocks = <&cru SCLK_I2S1_OUT>; - clock-names = "mclk"; - pinctrl-names = "default"; - pinctrl-0 = <&i2s1_2ch_mclk>; - hp-volume = <20>; - spk-volume = <3>; - mic-in-differential; - status = "okay"; - }; - }; -}; - -&i2c1 { - status = "okay"; - - ts@40 { - status = "okay"; - compatible = "GSL,GSL3673_800X1280"; - reg = <0x40>; - irq_gpio_number = <&gpio0 RK_PA5 IRQ_TYPE_LEVEL_LOW>; - rst_gpio_number = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>; - }; - - sensor@19 { - status = "okay"; - compatible = "gs_lis3dh"; - reg = <0x19>; - type = ; - irq-gpio = <&gpio0 RK_PB5 IRQ_TYPE_LEVEL_LOW>; - irq_enable = <0>; - poll_delay_ms = <30>; - layout = <7>; - reprobe_en = <1>; - }; -}; - -&i2c2 { - status = "okay"; -}; - -&i2s1_2ch { - status = "okay"; - #sound-dai-cells = <0>; -}; - -&io_domains { - status = "okay"; - - vccio1-supply = <&vcc_3v0>; - vccio2-supply = <&vccio_sd>; - vccio3-supply = <&vcc2v8_dvp>; - vccio4-supply = <&vcc_3v0>; - vccio5-supply = <&vcc_3v0>; -}; - -&mipi_dphy { - status = "okay"; -}; - -&nandc0 { - status = "okay"; -}; - -&pinctrl { - headphone { - hp_det: hp-det { - rockchip,pins = <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_up>; - }; - }; - - pmic { - pmic_int: pmic_int { - rockchip,pins = - <0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>; - }; - - soc_slppin_gpio: soc_slppin_gpio { - rockchip,pins = - <0 RK_PA4 RK_FUNC_GPIO &pcfg_output_low>; - }; - - soc_slppin_slp: soc_slppin_slp { - rockchip,pins = - <0 RK_PA4 RK_FUNC_1 &pcfg_pull_none>; - }; - - soc_slppin_rst: soc_slppin_rst { - rockchip,pins = - <0 RK_PA4 RK_FUNC_2 &pcfg_pull_none>; - }; - }; - - sdio-pwrseq { - wifi_enable_h: wifi-enable-h { - rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; - }; - }; -}; - -&pmu_io_domains { - status = "okay"; - - pmuio1-supply = <&vcc3v0_pmu>; - pmuio2-supply = <&vcc3v0_pmu>; -}; - -&pwm1 { - status = "okay"; -}; - -&rk_rga { - status = "okay"; -}; - -&rockchip_suspend { - status = "okay"; - rockchip,sleep-debug-en = <1>; -}; - -&route_dsi { - status = "okay"; -}; - -&saradc { - status = "okay"; - vref-supply = <&vcc1v8_soc>; -}; - -&sdmmc { - bus-width = <4>; - cap-mmc-highspeed; - cap-sd-highspeed; - supports-sd; - card-detect-delay = <800>; - ignore-pm-notify; - sd-uhs-sdr12; - sd-uhs-sdr25; - sd-uhs-sdr50; - sd-uhs-sdr104; - vqmmc-supply = <&vccio_sd>; - vmmc-supply = <&vcc_sd>; - status = "disabled"; -}; - -&sdio { - bus-width = <4>; - cap-sd-highspeed; - supports-sdio; - ignore-pm-notify; - keep-power-in-suspend; - non-removable; - mmc-pwrseq = <&sdio_pwrseq>; - sd-uhs-sdr104; - status = "okay"; -}; - -&tsadc { - pinctrl-names = "init", "default"; - pinctrl-0 = <&tsadc_otp_gpio>; - pinctrl-1 = <&tsadc_otp_out>; - status = "okay"; -}; - -&u2phy { - status = "okay"; - - u2phy_host: host-port { - rockchip,low-power-mode; - status = "okay"; }; - - u2phy_otg: otg-port { - rockchip,low-power-mode; - status = "okay"; - }; -}; - -&usb20_otg { - status = "okay"; -}; - -&uart1 { - pinctrl-names = "default"; - pinctrl-0 = <&uart1_xfer &uart1_cts>; - status = "okay"; -}; - -&vip_mmu { - status = "okay"; -}; - -&vopb { - status = "okay"; -}; - -&vopb_mmu { - status = "okay"; -}; - -&vopl { - status = "okay"; -}; - -&vopl_mmu { - status = "okay"; -}; - -&vpu_combo { - status = "okay"; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3326-863-lp3-v10.dtsi b/arch/arm64/boot/dts/rockchip/rk3326-863-lp3-v10.dtsi new file mode 100644 index 0000000000000..0a2330907d8a8 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3326-863-lp3-v10.dtsi @@ -0,0 +1,786 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd + */ + +/dts-v1/; +#include +#include +#include +#include +#include +#include "rk3326.dtsi" +#include "rk3326-863-cif-sensor.dtsi" +#include "px30-android.dtsi" + +/ { + adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 2>; + io-channel-names = "buttons"; + poll-interval = <100>; + keyup-threshold-microvolt = <1800000>; + + vol-down-key { + linux,code = ; + label = "volume down"; + press-threshold-microvolt = <300000>; + }; + + vol-up-key { + linux,code = ; + label = "volume up"; + press-threshold-microvolt = <17000>; + }; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&pwm1 0 25000 0>; + brightness-levels = < + 0 10 10 11 11 12 12 13 + 13 14 14 15 15 16 16 17 + 17 18 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 = <200>; + }; + + charge-animation { + compatible = "rockchip,uboot-charge"; + rockchip,uboot-charge-on = <1>; + rockchip,android-charge-on = <0>; + rockchip,uboot-low-power-voltage = <3500>; + rockchip,screen-on-voltage = <3600>; + status = "okay"; + }; + + rk817-sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,name = "rockchip-rk817-codec"; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,widgets = + "Microphone", "Mic Jack", + "Headphone", "Headphone Jack"; + simple-audio-card,routing = + "Mic Jack", "MICBIAS1", + "IN1P", "Mic Jack", + "Headphone Jack", "HPOL", + "Headphone Jack", "HPOR"; + simple-audio-card,cpu { + sound-dai = <&i2s1_2ch>; + }; + simple-audio-card,codec { + sound-dai = <&rk817_codec>; + }; + }; + + rk_headset { + compatible = "rockchip_headset"; + headset_gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&hp_det>; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + clocks = <&cru SCLK_WIFI_PMU>; + clock-names = "clk_wifi_pmu"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_enable_h>; + + /* + * On the module itself this is one of these (depending + * on the actual card populated): + * - SDIO_RESET_L_WL_REG_ON + * - PDN (power down when low) + */ + reset-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>; /* GPIO3_A4 */ + }; + + vccsys: vccsys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v8_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3800000>; + regulator-max-microvolt = <3800000>; + }; + + wireless-wlan { + compatible = "wlan-platdata"; + wifi_chip_type = "rtl8723cs"; + WIFI,host_wake_irq = <&gpio0 RK_PB2 GPIO_ACTIVE_HIGH>; + WIFI,vbat_gpio = <&gpio3 RK_PB6 GPIO_ACTIVE_LOW>; + status = "okay"; + }; + + wireless-bluetooth { + compatible = "bluetooth-platdata"; + uart_rts_gpios = <&gpio1 RK_PC3 GPIO_ACTIVE_LOW>; + pinctrl-names = "default","rts_gpio"; + pinctrl-0 = <&uart1_rts>; + pinctrl-1 = <&uart1_rts_gpio>; + BT,reset_gpio = <&gpio0 RK_PC1 GPIO_ACTIVE_HIGH>; + BT,wake_gpio = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>; + BT,wake_host_irq = <&gpio0 RK_PB3 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; +}; + + +&display_subsystem { + status = "okay"; +}; + +&dsi { + status = "okay"; + + panel@0 { + compatible = "aoly,sl008pa21y1285-b00", "simple-panel-dsi"; + reg = <0>; + backlight = <&backlight>; + enable-gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_LOW>; + reset-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; + prepare-delay-ms = <20>; + reset-delay-ms = <20>; + init-delay-ms = <20>; + enable-delay-ms = <120>; + disable-delay-ms = <20>; + unprepare-delay-ms = <20>; + + width-mm = <108>; + height-mm = <172>; + + dsi,flags = <(MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | + MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_EOT_PACKET)>; + dsi,format = ; + dsi,lanes = <4>; + + panel-init-sequence = [ + 05 78 01 11 + 05 14 01 29 + ]; + + panel-exit-sequence = [ + 05 00 01 28 + 05 00 01 10 + ]; + + display-timings { + native-mode = <&timing0>; + + timing0: timing0 { + clock-frequency = <66000000>; + hactive = <800>; + vactive = <1280>; + hfront-porch = <2>; + hsync-len = <18>; + hback-porch = <18>; + vfront-porch = <4>; + vsync-len = <4>; + vback-porch = <16>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <0>; + pixelclk-active = <0>; + }; + }; + }; +}; + +&bus_apll { + bus-supply = <&vdd_logic>; + status = "okay"; +}; + +&cpu0 { + cpu-supply = <&vdd_arm>; +}; + +&cpu0_opp_table { + /* + * max IR-drop values on different freq condition for this board! + */ + rockchip,board-irdrop = < + /*MHz MHz uV */ + 0 815 37500 + 816 1119 50000 + 1200 1512 75000 + >; +}; + +&dmc_opp_table { + /* + * max IR-drop values on different freq condition for this board! + */ + rockchip,board-irdrop = < + /*MHz MHz uV */ + 451 800 75000 + >; +}; + +&dsi_in_vopl { + status = "disabled"; +}; + +&dfi { + status = "okay"; +}; + +&dmc { + center-supply = <&vdd_logic>; + status = "okay"; +}; + +&emmc { + bus-width = <8>; + cap-mmc-highspeed; + mmc-hs200-1_8v; + supports-emmc; + disable-wp; + non-removable; + num-slots = <1>; + status = "okay"; +}; + +&gpu { + mali-supply = <&vdd_logic>; + status = "okay"; +}; + +&i2c0 { + status = "okay"; + + rk817: pmic@20 { + compatible = "rockchip,rk817"; + reg = <0x20>; + interrupt-parent = <&gpio0>; + interrupts = <7 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default", "pmic-sleep", + "pmic-power-off", "pmic-reset"; + pinctrl-0 = <&pmic_int>; + pinctrl-1 = <&soc_slppin_slp>, <&rk817_slppin_slp>; + pinctrl-2 = <&soc_slppin_gpio>, <&rk817_slppin_pwrdn>; + pinctrl-3 = <&soc_slppin_rst>, <&rk817_slppin_rst>; + rockchip,system-power-controller; + wakeup-source; + #clock-cells = <1>; + clock-output-names = "rk808-clkout1", "rk808-clkout2"; + //fb-inner-reg-idxs = <2>; + /* 1: rst regs (default in codes), 0: rst the pmic */ + pmic-reset-func = <1>; + + vcc1-supply = <&vccsys>; + vcc2-supply = <&vccsys>; + vcc3-supply = <&vccsys>; + vcc4-supply = <&vccsys>; + vcc5-supply = <&vccsys>; + vcc6-supply = <&vccsys>; + vcc7-supply = <&vcc_3v0>; + vcc8-supply = <&vccsys>; + vcc9-supply = <&dcdc_boost>; + + pwrkey { + status = "okay"; + }; + + pinctrl_rk8xx: pinctrl_rk8xx { + gpio-controller; + #gpio-cells = <2>; + + rk817_ts_gpio1: rk817_ts_gpio1 { + pins = "gpio_ts"; + function = "pin_fun1"; + /* output-low; */ + /* input-enable; */ + }; + + rk817_gt_gpio2: rk817_gt_gpio2 { + pins = "gpio_gt"; + function = "pin_fun1"; + }; + + rk817_pin_ts: rk817_pin_ts { + pins = "gpio_ts"; + function = "pin_fun0"; + }; + + rk817_pin_gt: rk817_pin_gt { + pins = "gpio_gt"; + function = "pin_fun0"; + }; + + rk817_slppin_null: rk817_slppin_null { + pins = "gpio_slp"; + function = "pin_fun0"; + }; + + rk817_slppin_slp: rk817_slppin_slp { + pins = "gpio_slp"; + function = "pin_fun1"; + }; + + rk817_slppin_pwrdn: rk817_slppin_pwrdn { + pins = "gpio_slp"; + function = "pin_fun2"; + }; + + rk817_slppin_rst: rk817_slppin_rst { + pins = "gpio_slp"; + function = "pin_fun3"; + }; + }; + + regulators { + vdd_logic: DCDC_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-initial-mode = <0x2>; + regulator-name = "vdd_logic"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vdd_arm: DCDC_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-initial-mode = <0x2>; + regulator-name = "vdd_arm"; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x2>; + regulator-name = "vcc_ddr"; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_3v0: DCDC_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-initial-mode = <0x2>; + regulator-name = "vcc_3v0"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vcc_1v0: LDO_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-name = "vcc_1v0"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc1v8_soc: LDO_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-name = "vcc1v8_soc"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd1v0_soc: LDO_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + + regulator-name = "vcc1v0_soc"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc3v0_pmu: LDO_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + + regulator-name = "vcc3v0_pmu"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + + }; + }; + + vccio_sd: LDO_REG5 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + + regulator-name = "vccio_sd"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_sd: LDO_REG6 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-name = "vcc_sd"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + + }; + }; + + vcc2v8_dvp: LDO_REG7 { + regulator-boot-on; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + + regulator-name = "vcc2v8_dvp"; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <2800000>; + }; + }; + + vcc1v8_dvp: LDO_REG8 { + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-name = "vcc1v8_dvp"; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd1v5_dvp: LDO_REG9 { + regulator-boot-on; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + + regulator-name = "vdd1v5_dvp"; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <1500000>; + }; + }; + + dcdc_boost: BOOST { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <4700000>; + regulator-max-microvolt = <5400000>; + regulator-name = "boost"; + }; + + otg_switch: OTG_SWITCH { + regulator-boot-on; + regulator-name = "otg_switch"; + }; + }; + + battery { + compatible = "rk817,battery"; + ocv_table = <3500 3548 3592 3636 3687 3740 3780 + 3806 3827 3846 3864 3889 3929 3964 + 3993 4015 4030 4041 4056 4076 4148>; + design_capacity = <4000>; + design_qmax = <4200>; + bat_res = <100>; + sleep_enter_current = <150>; + sleep_exit_current = <180>; + sleep_filter_current = <100>; + power_off_thresd = <3500>; + zero_algorithm_vol = <3850>; + max_soc_offset = <60>; + monitor_sec = <5>; + sample_res = <10>; + virtual_power = <0>; + }; + + charger { + compatible = "rk817,charger"; + min_input_voltage = <4500>; + max_input_current = <1500>; + max_chrg_current = <2000>; + max_chrg_voltage = <4200>; + chrg_term_mode = <0>; + chrg_finish_cur = <300>; + virtual_power = <0>; + dc_det_adc = <0>; + extcon = <&u2phy>; + }; + + rk817_codec: codec { + #sound-dai-cells = <0>; + compatible = "rockchip,rk817-codec"; + clocks = <&cru SCLK_I2S1_OUT>; + clock-names = "mclk"; + pinctrl-names = "default"; + pinctrl-0 = <&i2s1_2ch_mclk>; + hp-volume = <20>; + spk-volume = <3>; + mic-in-differential; + status = "okay"; + }; + }; +}; + +&i2c1 { + status = "okay"; + + ts@40 { + status = "okay"; + compatible = "GSL,GSL3673_800X1280"; + reg = <0x40>; + irq_gpio_number = <&gpio0 RK_PA5 IRQ_TYPE_LEVEL_LOW>; + rst_gpio_number = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>; + }; + + sensor@19 { + status = "okay"; + compatible = "gs_lis3dh"; + reg = <0x19>; + type = ; + irq-gpio = <&gpio0 RK_PB5 IRQ_TYPE_LEVEL_LOW>; + irq_enable = <0>; + poll_delay_ms = <30>; + layout = <7>; + reprobe_en = <1>; + }; +}; + +&i2c2 { + status = "okay"; +}; + +&i2s1_2ch { + status = "okay"; + #sound-dai-cells = <0>; +}; + +&io_domains { + status = "okay"; + + vccio1-supply = <&vcc_3v0>; + vccio2-supply = <&vccio_sd>; + vccio3-supply = <&vcc2v8_dvp>; + vccio4-supply = <&vcc_3v0>; + vccio5-supply = <&vcc_3v0>; +}; + +&mipi_dphy { + status = "okay"; +}; + +&nandc0 { + status = "okay"; +}; + +&pinctrl { + headphone { + hp_det: hp-det { + rockchip,pins = <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + pmic { + pmic_int: pmic_int { + rockchip,pins = + <0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + soc_slppin_gpio: soc_slppin_gpio { + rockchip,pins = + <0 RK_PA4 RK_FUNC_GPIO &pcfg_output_low>; + }; + + soc_slppin_slp: soc_slppin_slp { + rockchip,pins = + <0 RK_PA4 RK_FUNC_1 &pcfg_pull_none>; + }; + + soc_slppin_rst: soc_slppin_rst { + rockchip,pins = + <0 RK_PA4 RK_FUNC_2 &pcfg_pull_none>; + }; + }; + + sdio-pwrseq { + wifi_enable_h: wifi-enable-h { + rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&pmu_io_domains { + status = "okay"; + + pmuio1-supply = <&vcc3v0_pmu>; + pmuio2-supply = <&vcc3v0_pmu>; +}; + +&pwm1 { + status = "okay"; +}; + +&rk_rga { + status = "okay"; +}; + +&rockchip_suspend { + status = "okay"; + rockchip,sleep-debug-en = <1>; +}; + +&route_dsi { + status = "okay"; +}; + +&saradc { + status = "okay"; + vref-supply = <&vcc1v8_soc>; +}; + +&sdmmc { + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + supports-sd; + card-detect-delay = <800>; + ignore-pm-notify; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vqmmc-supply = <&vccio_sd>; + vmmc-supply = <&vcc_sd>; + status = "disabled"; +}; + +&sdio { + bus-width = <4>; + cap-sd-highspeed; + supports-sdio; + ignore-pm-notify; + keep-power-in-suspend; + non-removable; + mmc-pwrseq = <&sdio_pwrseq>; + sd-uhs-sdr104; + status = "okay"; +}; + +&tsadc { + pinctrl-names = "init", "default"; + pinctrl-0 = <&tsadc_otp_gpio>; + pinctrl-1 = <&tsadc_otp_out>; + status = "okay"; +}; + +&u2phy { + status = "okay"; + + u2phy_host: host-port { + rockchip,low-power-mode; + status = "okay"; + }; + + u2phy_otg: otg-port { + rockchip,low-power-mode; + status = "okay"; + }; +}; + +&usb20_otg { + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_xfer &uart1_cts>; + status = "okay"; +}; + +&vip_mmu { + status = "okay"; +}; + +&vopb { + status = "okay"; +}; + +&vopb_mmu { + status = "okay"; +}; + +&vopl { + status = "okay"; +}; + +&vopl_mmu { + status = "okay"; +}; + +&vpu_combo { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3326-86v-v10.dts b/arch/arm64/boot/dts/rockchip/rk3326-86v-v10.dts new file mode 100644 index 0000000000000..14b99d3654ea5 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3326-86v-v10.dts @@ -0,0 +1,793 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd + */ + +/dts-v1/; +#include +#include +#include +#include +#include +#include "rk3326.dtsi" +#include "rk3326-863-cif-sensor.dtsi" +#include "px30-android.dtsi" + +/ { + model = "Rockchip rk3326 86v board"; + compatible = "rockchip,rk3326-86v-v10", "rockchip,rk3326"; + + adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 2>; + io-channel-names = "buttons"; + poll-interval = <100>; + keyup-threshold-microvolt = <617000>; + + vol-down-key { + linux,code = ; + label = "volume down"; + press-threshold-microvolt = <300000>; + }; + + vol-up-key { + linux,code = ; + label = "volume up"; + press-threshold-microvolt = <17000>; + }; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&pwm1 0 25000 0>; + brightness-levels = < + 0 10 10 11 11 12 12 13 + 13 14 14 15 15 16 16 17 + 17 18 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 = <200>; + }; + + charge-animation { + compatible = "rockchip,uboot-charge"; + rockchip,uboot-charge-on = <0>; + rockchip,android-charge-on = <0>; + rockchip,uboot-low-power-voltage = <3500>; + rockchip,screen-on-voltage = <3600>; + status = "okay"; + }; + + panel { + compatible ="simple-panel"; + enable-gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_LOW>; + reset-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; + bus-format = ; + rockchip,data-width = <18>; + rockchip,output = "rgb"; + + display-timings { + native-mode = <&timing0>; + + timing0: timing0 { + clock-frequency = <51200000>; + hactive = <1024>; + vactive = <600>; + hback-porch = <100>; + hfront-porch = <120>; + vback-porch = <10>; + vfront-porch = <15>; + hsync-len = <100>; + vsync-len = <10>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <0>; + pixelclk-active = <0>; + }; + }; + + port { + panel_in_lvds: endpoint { + remote-endpoint = <&lvds_out_panel>; + }; + }; + }; + + rk817-sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,name = "rockchip,rk817-codec"; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,widgets = + "Microphone", "Mic Jack", + "Headphone", "Headphone Jack"; + simple-audio-card,routing = + "Mic Jack", "MICBIAS1", + "IN1P", "Mic Jack", + "Headphone Jack", "HPOL", + "Headphone Jack", "HPOR"; + simple-audio-card,cpu { + sound-dai = <&i2s1_2ch>; + }; + simple-audio-card,codec { + sound-dai = <&rk817_codec>; + }; + }; + + rk_headset { + compatible = "rockchip_headset"; + headset_gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&hp_det>; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + clocks = <&cru SCLK_WIFI_PMU>; + clock-names = "clk_wifi_pmu"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_enable_h>; + + /* + * On the module itself this is one of these (depending + * on the actual card populated): + * - SDIO_RESET_L_WL_REG_ON + * - PDN (power down when low) + */ + reset-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>; /* GPIO3_A4 */ + }; + + vccsys: vccsys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v8_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3800000>; + regulator-max-microvolt = <3800000>; + }; +}; + +&cif { + status = "okay"; +}; + +&cif_sensor { + status = "okay"; +}; + +&display_subsystem { + status = "okay"; +}; + +&bus_apll { + bus-supply = <&vdd_logic>; + status = "okay"; +}; + +&cpu0 { + cpu-supply = <&vdd_arm>; +}; + +&cpu0_opp_table { + /* + * max IR-drop values on different freq condition for this board! + */ + rockchip,board-irdrop = < + /*MHz MHz uV */ + 0 815 75000 + 816 1119 75000 + 1200 1512 75000 + >; +}; + +&dmc_opp_table { + /* + * max IR-drop values on different freq condition for this board! + */ + rockchip,board-irdrop = < + /*MHz MHz uV */ + 451 800 75000 + >; +}; + +&dfi { + status = "okay"; +}; + +&dmc { + center-supply = <&vdd_logic>; + status = "disabled"; +}; + +&emmc { + bus-width = <8>; + cap-mmc-highspeed; + /*mmc-hs200-1_8v;*/ + supports-emmc; + disable-wp; + non-removable; + num-slots = <1>; + status = "okay"; +}; + +&gpu { + mali-supply = <&vdd_logic>; + status = "okay"; +}; + +&i2c0 { + status = "okay"; + + rk817: pmic@20 { + compatible = "rockchip,rk817"; + reg = <0x20>; + interrupt-parent = <&gpio0>; + interrupts = <10 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default", "pmic-sleep", + "pmic-power-off", "pmic-reset"; + pinctrl-0 = <&pmic_int>; + pinctrl-1 = <&soc_slppin_slp>, <&rk817_slppin_slp>; + pinctrl-2 = <&soc_slppin_gpio>, <&rk817_slppin_pwrdn>; + pinctrl-3 = <&soc_slppin_rst>, <&rk817_slppin_rst>; + rockchip,system-power-controller; + wakeup-source; + #clock-cells = <1>; + clock-output-names = "rk808-clkout1", "rk808-clkout2"; + //fb-inner-reg-idxs = <2>; + /* 1: rst regs (default in codes), 0: rst the pmic */ + pmic-reset-func = <1>; + + vcc1-supply = <&vccsys>; + vcc2-supply = <&vccsys>; + vcc3-supply = <&vccsys>; + vcc4-supply = <&vccsys>; + vcc5-supply = <&vccsys>; + vcc6-supply = <&vccsys>; + vcc7-supply = <&vcc_3v0>; + vcc8-supply = <&vccsys>; + vcc9-supply = <&dcdc_boost>; + + pwrkey { + status = "okay"; + }; + + pinctrl_rk8xx: pinctrl_rk8xx { + gpio-controller; + #gpio-cells = <2>; + + rk817_ts_gpio1: rk817_ts_gpio1 { + pins = "gpio_ts"; + function = "pin_fun1"; + /* output-low; */ + /* input-enable; */ + }; + + rk817_gt_gpio2: rk817_gt_gpio2 { + pins = "gpio_gt"; + function = "pin_fun1"; + }; + + rk817_pin_ts: rk817_pin_ts { + pins = "gpio_ts"; + function = "pin_fun0"; + }; + + rk817_pin_gt: rk817_pin_gt { + pins = "gpio_gt"; + function = "pin_fun0"; + }; + + rk817_slppin_null: rk817_slppin_null { + pins = "gpio_slp"; + function = "pin_fun0"; + }; + + rk817_slppin_slp: rk817_slppin_slp { + pins = "gpio_slp"; + function = "pin_fun1"; + }; + + rk817_slppin_pwrdn: rk817_slppin_pwrdn { + pins = "gpio_slp"; + function = "pin_fun2"; + }; + + rk817_slppin_rst: rk817_slppin_rst { + pins = "gpio_slp"; + function = "pin_fun3"; + }; + }; + + regulators { + vdd_logic: DCDC_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-initial-mode = <0x2>; + regulator-name = "vdd_logic"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vdd_arm: DCDC_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-initial-mode = <0x2>; + regulator-name = "vdd_arm"; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x2>; + regulator-name = "vcc_ddr"; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_3v0: DCDC_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-initial-mode = <0x2>; + regulator-name = "vcc_3v0"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vcc_1v0: LDO_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-name = "vcc_1v0"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc1v8_soc: LDO_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-name = "vcc1v8_soc"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd1v0_soc: LDO_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + + regulator-name = "vcc1v0_soc"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc3v0_pmu: LDO_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + + regulator-name = "vcc3v0_pmu"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + + }; + }; + + vccio_sd: LDO_REG5 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + + regulator-name = "vccio_sd"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_sd: LDO_REG6 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-name = "vcc_sd"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + + }; + }; + + vcc2v8_dvp: LDO_REG7 { + regulator-boot-on; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + + regulator-name = "vcc2v8_dvp"; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <2800000>; + }; + }; + + vcc1v8_dvp: LDO_REG8 { + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-name = "vcc1v8_dvp"; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd1v5_dvp: LDO_REG9 { + regulator-boot-on; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + + regulator-name = "vdd1v5_dvp"; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <1500000>; + }; + }; + + dcdc_boost: BOOST { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <4700000>; + regulator-max-microvolt = <5400000>; + regulator-name = "boost"; + }; + + otg_switch: OTG_SWITCH { + regulator-boot-on; + regulator-name = "otg_switch"; + }; + }; + + battery { + compatible = "rk817,battery"; + ocv_table = <3500 3548 3592 3636 3687 3740 3780 + 3806 3827 3846 3864 3889 3929 3964 + 3993 4015 4030 4041 4056 4076 4148>; + design_capacity = <4000>; + design_qmax = <4200>; + bat_res = <100>; + sleep_enter_current = <150>; + sleep_exit_current = <180>; + sleep_filter_current = <100>; + power_off_thresd = <3500>; + zero_algorithm_vol = <3850>; + max_soc_offset = <60>; + monitor_sec = <5>; + sample_res = <10>; + virtual_power = <0>; + }; + + charger { + compatible = "rk817,charger"; + min_input_voltage = <4500>; + max_input_current = <1500>; + max_chrg_current = <2000>; + max_chrg_voltage = <4200>; + chrg_term_mode = <0>; + chrg_finish_cur = <300>; + virtual_power = <0>; + dc_det_adc = <0>; + extcon = <&u2phy>; + }; + + rk817_codec: codec { + #sound-dai-cells = <0>; + compatible = "rockchip,rk817-codec"; + clocks = <&cru SCLK_I2S1_OUT>; + clock-names = "mclk"; + pinctrl-names = "default"; + pinctrl-0 = <&i2s1_2ch_mclk>; + hp-volume = <20>; + spk-volume = <3>; + mic-in-differential; + status = "okay"; + }; + }; +}; + +&i2c1 { + status = "okay"; + + ts@40 { + compatible = "gslX680-d708"; + reg = <0x40>; + touch-gpio = <&gpio0 RK_PB3 IRQ_TYPE_LEVEL_LOW>; + wake-gpio = <&gpio0 RK_PC1 IRQ_TYPE_LEVEL_LOW>; + screen_max_x = <1024>; + screen_max_y = <600>; + revert_x = <1>; + status = "okay"; + }; + + sensor@1d { + status = "okay"; + compatible = "gs_lsm303d"; + reg = <0x1d>; + type = ; + irq-gpio = <&gpio0 RK_PA1 IRQ_TYPE_LEVEL_LOW>; + irq_enable = <0>; + poll_delay_ms = <30>; + layout = <5>; + reprobe_en = <1>; + }; +}; + +&i2c2 { + status = "okay"; +}; + +&i2s1_2ch { + status = "okay"; + #sound-dai-cells = <0>; +}; + +&io_domains { + status = "okay"; + + vccio1-supply = <&vcc_3v0>; + vccio2-supply = <&vccio_sd>; + vccio3-supply = <&vcc2v8_dvp>; + vccio4-supply = <&vcc_3v0>; + vccio5-supply = <&vcc_3v0>; +}; + +&lvds { + pinctrl-names = "default"; + pinctrl-0 = <&lcdc_rgb_dclk_pin &lcdc_rgb666_m1_data_pins>; + status = "okay"; + + ports { + port@1 { + reg = <1>; + + lvds_out_panel: endpoint { + remote-endpoint = <&panel_in_lvds>; + }; + }; + }; +}; + +&nandc0 { + status = "okay"; +}; + +&pinctrl { + headphone { + hp_det: hp-det { + rockchip,pins = <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + lcdc { + lcdc_rgb_dclk_pin: lcdc-rgb-dclk-pin { + rockchip,pins = <3 RK_PA0 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + + pmic { + pmic_int: pmic_int { + rockchip,pins = + <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + soc_slppin_gpio: soc_slppin_gpio { + rockchip,pins = + <0 RK_PA4 RK_FUNC_GPIO &pcfg_output_low>; + }; + + soc_slppin_slp: soc_slppin_slp { + rockchip,pins = + <0 RK_PA4 RK_FUNC_1 &pcfg_pull_none>; + }; + + soc_slppin_rst: soc_slppin_rst { + rockchip,pins = + <0 RK_PA4 RK_FUNC_2 &pcfg_pull_none>; + }; + }; + + sdio-pwrseq { + wifi_enable_h: wifi-enable-h { + rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&pmu_io_domains { + status = "okay"; + + pmuio1-supply = <&vcc3v0_pmu>; + pmuio2-supply = <&vcc3v0_pmu>; +}; + +&pwm1 { + status = "okay"; +}; + +&rk_rga { + status = "okay"; +}; + +&rockchip_suspend { + status = "okay"; + rockchip,sleep-debug-en = <1>; +}; + +&route_lvds { + status = "okay"; +}; + +&saradc { + status = "okay"; + vref-supply = <&vcc1v8_soc>; +}; + +&sdmmc { + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + supports-sd; + card-detect-delay = <800>; + ignore-pm-notify; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vqmmc-supply = <&vccio_sd>; + vmmc-supply = <&vcc_sd>; + status = "disabled"; +}; + +&sdio { + bus-width = <4>; + cap-sd-highspeed; + supports-sdio; + ignore-pm-notify; + keep-power-in-suspend; + non-removable; + mmc-pwrseq = <&sdio_pwrseq>; + sd-uhs-sdr104; + status = "disabled"; +}; + +&tsadc { + pinctrl-names = "init", "default"; + pinctrl-0 = <&tsadc_otp_gpio>; + pinctrl-1 = <&tsadc_otp_out>; + status = "okay"; +}; + +&u2phy { + status = "okay"; + + u2phy_host: host-port { + rockchip,low-power-mode; + status = "okay"; + }; + + u2phy_otg: otg-port { + rockchip,low-power-mode; + status = "okay"; + }; +}; + +&usb20_otg { + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_xfer &uart1_cts>; + status = "okay"; +}; + +&vip_mmu { + status = "okay"; +}; + +&vopb { + status = "okay"; +}; + +&vopb_mmu { + status = "okay"; +}; + +&vopl { + status = "okay"; +}; + +&vopl_mmu { + status = "okay"; +}; + +&vpu_combo { + status = "okay"; +}; + +&firmware_android { + compatible = "android,firmware"; + fstab { + compatible = "android,fstab"; + system { + compatible = "android,system"; + dev = "/dev/block/by-name/system"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait"; + }; + vendor { + compatible = "android,vendor"; + dev = "/dev/block/by-name/vendor"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3326-evb-ai-va-v10.dts b/arch/arm64/boot/dts/rockchip/rk3326-evb-ai-va-v10.dts index 9afd0f5b6d0da..4078487f87f4d 100644 --- a/arch/arm64/boot/dts/rockchip/rk3326-evb-ai-va-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3326-evb-ai-va-v10.dts @@ -623,15 +623,14 @@ }; }; - vcc3v3_lcd: SWITCH_REG1 { - regulator-boot-on; - regulator-name = "vcc3v3_lcd"; + + vcc5v0_host: SWITCH_REG1 { + regulator-name = "vcc5v0_host"; }; - vcc5v0_host: SWITCH_REG2 { - regulator-always-on; + vcc3v3_lcd: SWITCH_REG2 { regulator-boot-on; - regulator-name = "vcc5v0_host"; + regulator-name = "vcc3v3_lcd"; }; }; @@ -1248,3 +1247,24 @@ &vpu_combo { status = "okay"; }; + +&firmware_android { + compatible = "android,firmware"; + fstab { + compatible = "android,fstab"; + system { + compatible = "android,system"; + dev = "/dev/block/by-name/system"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait"; + }; + vendor { + compatible = "android,vendor"; + dev = "/dev/block/by-name/vendor"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3326-evb-ai-va-v11-i2s-dmic.dts b/arch/arm64/boot/dts/rockchip/rk3326-evb-ai-va-v11-i2s-dmic.dts new file mode 100644 index 0000000000000..be7d1157cb434 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3326-evb-ai-va-v11-i2s-dmic.dts @@ -0,0 +1,1293 @@ +/* + * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd + * + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) + */ + +/dts-v1/; +#include +#include +#include +#include +#include +#include "rk3326.dtsi" +#include "rk3326-863-cif-sensor.dtsi" +#include "px30-android.dtsi" + +/ { + model = "Rockchip rk3326 ai voice assistant evb v11 i2s-dmic board"; + compatible = "rockchip,rk3326-evb-ai-va-v11-i2s-dmic", "rockchip,rk3326"; + + adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 2>; + io-channel-names = "buttons"; + poll-interval = <100>; + keyup-threshold-microvolt = <1800000>; + + mute-key { + linux,code = ; + label = "mute"; + press-threshold-microvolt = <1119000>; + }; + + mode-key { + linux,code = ; + label = "mode"; + press-threshold-microvolt = <892000>; + }; + + media-key { + linux,code = ; + label = "media"; + press-threshold-microvolt = <616000>; + }; + + vol-down-key { + linux,code = ; + label = "volume down"; + press-threshold-microvolt = <300000>; + }; + + vol-up-key { + linux,code = ; + label = "volume up"; + press-threshold-microvolt = <15000>; + }; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&pwm1 0 25000 0>; + 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 = <200>; + }; + + panel { + compatible = "samsung,lsl070nl01", "simple-panel"; + backlight = <&backlight>; + enable-gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>; + enable-delay-ms = <20>; + prepare-delay-ms = <20>; + unprepare-delay-ms = <20>; + disable-delay-ms = <20>; + width-mm = <217>; + height-mm = <136>; + rockchip,data-mapping = "vesa"; + rockchip,data-width = <24>; + rockchip,output = "lvds"; + status = "disabled"; + + display-timings { + native-mode = <&timing0>; + + timing0: timing0 { + clock-frequency = <49500000>; + hactive = <1024>; + vactive = <600>; + hback-porch = <90>; + hfront-porch = <90>; + vback-porch = <10>; + vfront-porch = <10>; + hsync-len = <90>; + vsync-len = <10>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <0>; + pixelclk-active = <0>; + }; + }; + + port { + panel_in_lvds: endpoint { + remote-endpoint = <&lvds_out_panel>; + }; + }; + }; + + multi_dais: multi-dais { + status = "okay"; + compatible = "rockchip,multi-dais"; + dais = <&pdm>, <&i2s0_8ch>; + capture,channel-mapping = <2 6>; + playback,channel-mapping = <0 0>; + #sound-dai-cells = <0>; + }; + + rk809-sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "rockchip,rk809-codec"; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,widgets = + "Microphone", "Mic Jack", + "Headphone", "Headphone Jack"; + simple-audio-card,routing = + "Mic Jack", "MICBIAS1", + "IN1P", "Mic Jack", + "Headphone Jack", "HPOL", + "Headphone Jack", "HPOR"; + simple-audio-card,dai-link@0 { + format = "i2s"; + cpu { + sound-dai = <&i2s1_2ch>; + }; + codec { + sound-dai = <&rk809_codec 0>; + }; + }; + simple-audio-card,dai-link@1 { + format = "i2s"; + cpu { + sound-dai = <&multi_dais>; + }; + codec { + sound-dai = <&rk809_codec 1>; + }; + }; + }; + + bt-sound { + compatible = "simple-audio-card"; + status = "disabled"; + simple-audio-card,format = "dsp_b"; + simple-audio-card,bitclock-inversion = <1>; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,name = "rockchip,bt"; + simple-audio-card,cpu { + sound-dai = <&i2s2_2ch>; + }; + simple-audio-card,codec { + sound-dai = <&bt_sco>; + }; + }; + + bt_sco: bt-sco { + compatible = "delta,dfbmcs320"; + #sound-dai-cells = <0>; + status = "okay"; + }; + + rk_headset { + compatible = "rockchip_headset"; + headset_gpio = <&gpio3 RK_PA4 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&hp_det>; + io-channels = <&saradc 1>; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + clocks = <&rk809 1>; + clock-names = "ext_clock"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_enable_h>; + + /* + * On the module itself this is one of these (depending + * on the actual card populated): + * - SDIO_RESET_L_WL_REG_ON + * - PDN (power down when low) + */ + reset-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>; /* GPIO3_A4 */ + }; + + vcc5v0_sys: vccsys { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + wireless-wlan { + compatible = "wlan-platdata"; + wifi_chip_type = "AP6255"; + WIFI,host_wake_irq = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; + + wireless-bluetooth { + compatible = "bluetooth-platdata"; + clocks = <&rk809 1>; + clock-names = "ext_clock"; + uart_rts_gpios = <&gpio1 RK_PC3 GPIO_ACTIVE_LOW>; + pinctrl-names = "default","rts_gpio"; + pinctrl-0 = <&uart1_rts>; + pinctrl-1 = <&uart1_rts_gpio>; + BT,reset_gpio = <&gpio0 RK_PC1 GPIO_ACTIVE_HIGH>; + BT,wake_gpio = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>; + BT,wake_host_irq = <&gpio0 RK_PA7 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; +}; + +&bus_apll { + bus-supply = <&vdd_logic>; + status = "okay"; +}; + +&cpu0 { + cpu-supply = <&vdd_arm>; +}; + +&dfi { + status = "okay"; +}; + +&display_subsystem { + status = "okay"; +}; + +&dmc { + center-supply = <&vdd_logic>; + status = "okay"; +}; + +&dsi { + status = "okay"; + + panel@0 { + compatible = "sitronix,st7703", "simple-panel-dsi"; + reg = <0>; + backlight = <&backlight>; + enable-gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>; + prepare-delay-ms = <2>; + reset-delay-ms = <1>; + init-delay-ms = <20>; + enable-delay-ms = <120>; + disable-delay-ms = <50>; + unprepare-delay-ms = <40>; + + width-mm = <68>; + height-mm = <121>; + + dsi,flags = <(MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | + MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_EOT_PACKET)>; + dsi,format = ; + dsi,lanes = <4>; + + panel-init-sequence = [ + 05 fa 01 11 + 39 00 04 b9 f1 12 83 + 39 00 1c ba 33 81 05 f9 0e 0e 00 00 00 + 00 00 00 00 00 44 25 00 91 0a + 00 00 02 4f 01 00 00 37 + 15 00 02 b8 25 + 39 00 04 bf 02 11 00 + 39 00 0b b3 0c 10 0a 50 03 ff 00 00 00 + 00 + 39 00 0a c0 73 73 50 50 00 00 08 70 00 + 15 00 02 bc 46 + 15 00 02 cc 0b + 15 00 02 b4 80 + 39 00 04 b2 c8 12 30 + 39 00 0f e3 07 07 0b 0b 03 0b 00 00 00 + 00 ff 00 c0 10 + 39 00 0d c1 53 00 1e 1e 77 e1 cc dd 67 + 77 33 33 + 39 00 07 c6 00 00 ff ff 01 ff + 39 00 03 b5 09 09 + 39 00 03 b6 87 95 + 39 00 40 e9 c2 10 05 05 10 05 a0 12 31 + 23 3f 81 0a a0 37 18 00 80 01 + 00 00 00 00 80 01 00 00 00 48 + f8 86 42 08 88 88 80 88 88 88 + 58 f8 87 53 18 88 88 81 88 88 + 88 00 00 00 01 00 00 00 00 00 + 00 00 00 00 + 39 00 3e ea 00 1a 00 00 00 00 02 00 00 + 00 00 00 1f 88 81 35 78 88 88 + 85 88 88 88 0f 88 80 24 68 88 + 88 84 88 88 88 23 10 00 00 1c + 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 30 05 a0 00 00 + 00 00 + 39 00 23 e0 00 06 08 2a 31 3f 38 36 07 + 0c 0d 11 13 12 13 11 18 00 06 + 08 2a 31 3f 38 36 07 0c 0d 11 + 13 12 13 11 18 + 05 32 01 29 + ]; + + panel-exit-sequence = [ + 05 00 01 28 + 05 00 01 10 + ]; + + display-timings { + native-mode = <&st7703_timing>; + + st7703_timing: timing0 { + clock-frequency = <66000000>; + hactive = <720>; + vactive = <1280>; + hfront-porch = <40>; + hsync-len = <10>; + hback-porch = <40>; + vfront-porch = <22>; + vsync-len = <4>; + vback-porch = <11>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <0>; + pixelclk-active = <0>; + }; + }; + }; +}; + +&dsi_in_vopl { + status = "disabled"; +}; + +&emmc { + bus-width = <8>; + cap-mmc-highspeed; + mmc-hs200-1_8v; + supports-emmc; + disable-wp; + non-removable; + num-slots = <1>; + status = "okay"; +}; + +&gpu { + mali-supply = <&vdd_logic>; + status = "okay"; +}; + +&i2c0 { + status = "okay"; + clock-frequency = <400000>; + i2c-scl-rising-time-ns = <280>; + i2c-scl-falling-time-ns = <16>; + + rk809: pmic@20 { + compatible = "rockchip,rk809"; + reg = <0x20>; + interrupt-parent = <&gpio0>; + interrupts = <10 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default", "pmic-sleep", + "pmic-power-off", "pmic-reset"; + pinctrl-0 = <&pmic_int>; + pinctrl-1 = <&soc_slppin_slp>, <&rk817_slppin_slp>; + pinctrl-2 = <&soc_slppin_gpio>, <&rk817_slppin_pwrdn>; + pinctrl-3 = <&soc_slppin_rst>, <&rk817_slppin_rst>; + rockchip,system-power-controller; + wakeup-source; + #clock-cells = <1>; + clock-output-names = "rk808-clkout1", "rk808-clkout2"; + //fb-inner-reg-idxs = <2>; + /* 1: rst regs (default in codes), 0: rst the pmic */ + pmic-reset-func = <1>; + + vcc1-supply = <&vcc5v0_sys>; + vcc2-supply = <&vcc5v0_sys>; + vcc3-supply = <&vcc5v0_sys>; + vcc4-supply = <&vcc5v0_sys>; + vcc5-supply = <&vcc3v3_sys>; + vcc6-supply = <&vcc3v3_sys>; + vcc7-supply = <&vcc3v3_sys>; + vcc8-supply = <&vcc3v3_sys>; + vcc9-supply = <&vcc5v0_sys>; + + pwrkey { + status = "okay"; + }; + + pinctrl_rk8xx: pinctrl_rk8xx { + gpio-controller; + #gpio-cells = <2>; + + rk817_slppin_null: rk817_slppin_null { + pins = "gpio_slp"; + function = "pin_fun0"; + }; + + rk817_slppin_slp: rk817_slppin_slp { + pins = "gpio_slp"; + function = "pin_fun1"; + }; + + rk817_slppin_pwrdn: rk817_slppin_pwrdn { + pins = "gpio_slp"; + function = "pin_fun2"; + }; + + rk817_slppin_rst: rk817_slppin_rst { + pins = "gpio_slp"; + function = "pin_fun3"; + }; + }; + + regulators { + vdd_logic: DCDC_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-initial-mode = <0x2>; + regulator-name = "vdd_logic"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vdd_arm: DCDC_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-initial-mode = <0x2>; + regulator-name = "vdd_arm"; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-initial-mode = <0x2>; + regulator-name = "vcc_ddr"; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_3v0: DCDC_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-initial-mode = <0x2>; + regulator-name = "vcc_3v0"; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vcc_1v0: LDO_REG1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-name = "vcc_1v0"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc1v8_soc: LDO_REG2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-name = "vcc1v8_soc"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd1v0_soc: LDO_REG3 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + + regulator-name = "vcc1v0_soc"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vcc3v0_pmu: LDO_REG4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + + regulator-name = "vcc3v0_pmu"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + + }; + }; + + vccio_sd: LDO_REG5 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + + regulator-name = "vccio_sd"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_sd: LDO_REG6 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-name = "vcc_sd"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + + }; + }; + + vcc2v8_dvp: LDO_REG7 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + + regulator-name = "vcc2v8_dvp"; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <2800000>; + }; + }; + + vcc1v8_dvp: LDO_REG8 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-name = "vcc1v8_dvp"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd1v5_dvp: LDO_REG9 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + + regulator-name = "vdd1v5_dvp"; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <1500000>; + }; + }; + + vcc3v3_sys: DCDC_REG5 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc3v3_sys"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc5v0_host: SWITCH_REG1 { + regulator-name = "vcc5v0_host"; + }; + + vcc3v3_lcd: SWITCH_REG2 { + regulator-boot-on; + regulator-name = "vcc3v3_lcd"; + }; + }; + + rk809_codec: codec { + #sound-dai-cells = <1>; + compatible = "rockchip,rk809-codec", "rockchip,rk817-codec"; + clocks = <&cru SCLK_I2S1_OUT>; + clock-names = "mclk"; + pinctrl-names = "default"; + pinctrl-0 = <&i2s1_2ch_mclk>; + pdmdata-out-enable; + use-ext-amplifier; + adc-for-loopback; + spk-ctl-gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_HIGH>; + hp-volume = <20>; + spk-volume = <20>; + }; + }; +}; + +&i2c1 { + status = "okay"; + clock-frequency = <400000>; + i2c-scl-rising-time-ns = <275>; + i2c-scl-falling-time-ns = <16>; + + gt1x: gt1x@14 { + compatible = "goodix,gt1x"; + reg = <0x14>; + goodix,rst-gpio = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>; + goodix,irq-gpio = <&gpio0 RK_PB3 IRQ_TYPE_LEVEL_LOW>; + }; + + is31fl3236: led-controller@3c { + compatible = "issi,is31fl3236"; + reg = <0x3c>; + #address-cells = <1>; + #size-cells = <0>; + reset-gpios = <&gpio3 RK_PA6 GPIO_ACTIVE_HIGH>; + status = "okay"; + + led1: led@1 { + label = "led1"; + reg = <1>; + led-max-microamp = <10000>; + linux,default-trigger = "timer"; + linux,default-trigger-delay-ms = <0>; + linux,blink-delay-on-ms = <100>; + linux,blink-delay-off-ms = <1200>; + }; + + led2: led@2 { + label = "led2"; + reg = <2>; + led-max-microamp = <10000>; + linux,default-trigger = "timer"; + linux,default-trigger-delay-ms = <0>; + linux,blink-delay-on-ms = <100>; + linux,blink-delay-off-ms = <1200>; + }; + + led3: led@3 { + label = "led3"; + reg = <3>; + led-max-microamp = <10000>; + linux,default-trigger = "default-on"; + }; + + led4: led@4 { + label = "led4"; + reg = <4>; + led-max-microamp = <10000>; + linux,default-trigger = "timer"; + linux,default-trigger-delay-ms = <100>; + linux,blink-delay-on-ms = <100>; + linux,blink-delay-off-ms = <1200>; + }; + + led5: led@5 { + label = "led5"; + reg = <5>; + led-max-microamp = <10000>; + linux,default-trigger = "timer"; + linux,default-trigger-delay-ms = <100>; + linux,blink-delay-on-ms = <100>; + linux,blink-delay-off-ms = <1200>; + }; + + led6: led@6 { + label = "led6"; + reg = <6>; + led-max-microamp = <10000>; + linux,default-trigger = "default-on"; + }; + + led7: led@7 { + label = "led7"; + reg = <7>; + led-max-microamp = <10000>; + linux,default-trigger = "timer"; + linux,default-trigger-delay-ms = <200>; + linux,blink-delay-on-ms = <100>; + linux,blink-delay-off-ms = <1200>; + }; + + led8: led@8 { + label = "led8"; + reg = <8>; + led-max-microamp = <10000>; + linux,default-trigger = "timer"; + linux,default-trigger-delay-ms = <200>; + linux,blink-delay-on-ms = <100>; + linux,blink-delay-off-ms = <1200>; + }; + + led9: led@9 { + label = "led9"; + reg = <9>; + led-max-microamp = <10000>; + linux,default-trigger = "default-on"; + }; + + led10: led@10 { + label = "led10"; + reg = <10>; + led-max-microamp = <10000>; + linux,default-trigger = "timer"; + linux,default-trigger-delay-ms = <300>; + linux,blink-delay-on-ms = <100>; + linux,blink-delay-off-ms = <1200>; + }; + + led11: led@11 { + label = "led11"; + reg = <11>; + led-max-microamp = <10000>; + linux,default-trigger = "timer"; + linux,default-trigger-delay-ms = <300>; + linux,blink-delay-on-ms = <100>; + linux,blink-delay-off-ms = <1200>; + }; + + led12: led@12 { + label = "led12"; + reg = <12>; + led-max-microamp = <10000>; + linux,default-trigger = "default-on"; + }; + + led13: led@13 { + label = "led13"; + reg = <13>; + led-max-microamp = <10000>; + linux,default-trigger = "timer"; + linux,default-trigger-delay-ms = <400>; + linux,blink-delay-on-ms = <100>; + linux,blink-delay-off-ms = <1200>; + }; + + led14: led@14 { + label = "led14"; + reg = <14>; + led-max-microamp = <10000>; + linux,default-trigger = "timer"; + linux,default-trigger-delay-ms = <400>; + linux,blink-delay-on-ms = <100>; + linux,blink-delay-off-ms = <1200>; + }; + + led15: led@15 { + label = "led15"; + reg = <15>; + led-max-microamp = <10000>; + linux,default-trigger = "default-on"; + }; + + led16: led@16 { + label = "led16"; + reg = <16>; + led-max-microamp = <10000>; + linux,default-trigger = "timer"; + linux,default-trigger-delay-ms = <500>; + linux,blink-delay-on-ms = <100>; + linux,blink-delay-off-ms = <1200>; + }; + + led17: led@17 { + label = "led17"; + reg = <17>; + led-max-microamp = <10000>; + linux,default-trigger = "timer"; + linux,default-trigger-delay-ms = <500>; + linux,blink-delay-on-ms = <100>; + linux,blink-delay-off-ms = <1200>; + }; + + led18: led@18 { + label = "led18"; + reg = <18>; + led-max-microamp = <10000>; + linux,default-trigger = "default-on"; + }; + + led19: led@19 { + label = "led19"; + reg = <19>; + led-max-microamp = <10000>; + linux,default-trigger = "timer"; + linux,default-trigger-delay-ms = <600>; + linux,blink-delay-on-ms = <100>; + linux,blink-delay-off-ms = <1200>; + }; + + led20: led@20 { + label = "led20"; + reg = <20>; + led-max-microamp = <10000>; + linux,default-trigger = "timer"; + linux,default-trigger-delay-ms = <600>; + linux,blink-delay-on-ms = <100>; + linux,blink-delay-off-ms = <1200>; + }; + + led21: led@21 { + label = "led21"; + reg = <21>; + led-max-microamp = <10000>; + linux,default-trigger = "default-on"; + }; + + led22: led@22 { + label = "led22"; + reg = <22>; + led-max-microamp = <10000>; + linux,default-trigger = "timer"; + linux,default-trigger-delay-ms = <700>; + linux,blink-delay-on-ms = <100>; + linux,blink-delay-off-ms = <1200>; + }; + + led23: led@23 { + label = "led23"; + reg = <23>; + led-max-microamp = <10000>; + linux,default-trigger = "timer"; + linux,default-trigger-delay-ms = <700>; + linux,blink-delay-on-ms = <100>; + linux,blink-delay-off-ms = <1200>; + }; + + led124: led@24 { + label = "led24"; + reg = <24>; + led-max-microamp = <10000>; + linux,default-trigger = "default-on"; + }; + + led25: led@25 { + label = "led25"; + reg = <25>; + led-max-microamp = <10000>; + linux,default-trigger = "timer"; + linux,default-trigger-delay-ms = <800>; + linux,blink-delay-on-ms = <100>; + linux,blink-delay-off-ms = <1200>; + }; + + led26: led@26 { + label = "led26"; + reg = <26>; + led-max-microamp = <10000>; + linux,default-trigger = "timer"; + linux,default-trigger-delay-ms = <800>; + linux,blink-delay-on-ms = <100>; + linux,blink-delay-off-ms = <1200>; + }; + + led27: led@27 { + label = "led27"; + reg = <27>; + led-max-microamp = <10000>; + linux,default-trigger = "default-on"; + }; + + led28: led@28 { + label = "led28"; + reg = <28>; + led-max-microamp = <10000>; + linux,default-trigger = "timer"; + linux,default-trigger-delay-ms = <900>; + linux,blink-delay-on-ms = <100>; + linux,blink-delay-off-ms = <1200>; + }; + + led29: led@29 { + label = "led29"; + reg = <29>; + led-max-microamp = <10000>; + linux,default-trigger = "timer"; + linux,default-trigger-delay-ms = <900>; + linux,blink-delay-on-ms = <100>; + linux,blink-delay-off-ms = <1200>; + }; + + led30: led@30 { + label = "led30"; + reg = <30>; + led-max-microamp = <10000>; + linux,default-trigger = "default-on"; + }; + + led31: led@31 { + label = "led31"; + reg = <31>; + led-max-microamp = <10000>; + linux,default-trigger = "timer"; + linux,default-trigger-delay-ms = <1000>; + linux,blink-delay-on-ms = <100>; + linux,blink-delay-off-ms = <1200>; + }; + + led32: led@32 { + label = "led32"; + reg = <32>; + led-max-microamp = <10000>; + linux,default-trigger = "timer"; + linux,default-trigger-delay-ms = <1000>; + linux,blink-delay-on-ms = <100>; + linux,blink-delay-off-ms = <1200>; + }; + + led33: led@33 { + label = "led33"; + reg = <33>; + led-max-microamp = <10000>; + linux,default-trigger = "default-on"; + }; + + led34: led@34 { + label = "led34"; + reg = <34>; + led-max-microamp = <10000>; + linux,default-trigger = "timer"; + linux,default-trigger-delay-ms = <1100>; + linux,blink-delay-on-ms = <100>; + linux,blink-delay-off-ms = <1200>; + }; + + led35: led@35 { + label = "led35"; + reg = <35>; + led-max-microamp = <10000>; + linux,default-trigger = "timer"; + linux,default-trigger-delay-ms = <1100>; + linux,blink-delay-on-ms = <100>; + linux,blink-delay-off-ms = <1200>; + }; + + led36: led@36 { + label = "led36"; + reg = <36>; + led-max-microamp = <10000>; + linux,default-trigger = "default-on"; + }; + }; + + ls_stk3410: light@48 { + compatible = "ls_stk3410"; + status = "okay"; + reg = <0x48>; + type = ; + irq_enable = <0>; + als_threshold_high = <100>; + als_threshold_low = <10>; + als_ctrl_gain = <2>; /* 0:x1 1:x4 2:x16 3:x64 */ + poll_delay_ms = <100>; + }; + + ps_stk3410: proximity@48 { + compatible = "ps_stk3410"; + status = "okay"; + reg = <0x48>; + type = ; + //pinctrl-names = "default"; + //pinctrl-0 = <&gpio2_c3>; + //irq-gpio = <&gpio0 RK_PB7 IRQ_TYPE_LEVEL_LOW>; + //irq_enable = <1>; + ps_threshold_high = <0x200>; + ps_threshold_low = <0x100>; + ps_ctrl_gain = <3>; /* 0:x1 1:x4 2:x16 3:x64 */ + ps_led_current = <3>; /* 0:12.5mA 1:25mA 2:50mA 3:100mA */ + poll_delay_ms = <100>; + }; + +}; + +&i2c2 { + status = "okay"; +}; + +&i2s0_8ch { + status = "okay"; + #sound-dai-cells = <0>; + rockchip,clk-trcm = <2>; + rockchip,no-dmaengine; +}; + +&i2s1_2ch { + status = "okay"; + #sound-dai-cells = <0>; + pinctrl-0 = <&i2s1_2ch_sclk + &i2s1_2ch_lrck + &i2s1_2ch_sdo>; +}; + +&i2s2_2ch { + status = "okay"; + rockchip,bclk-fs = <64>; + #sound-dai-cells = <0>; +}; + +&io_domains { + status = "okay"; + + vccio1-supply = <&vcc1v8_soc>; + vccio2-supply = <&vccio_sd>; + vccio3-supply = <&vcc1v8_dvp>; + vccio4-supply = <&vcc1v8_soc>; + vccio5-supply = <&vcc_3v0>; +}; + +&isp_mmu { + status = "okay"; +}; + +&lvds { + status = "disabled"; + + ports { + port@1 { + reg = <1>; + + lvds_out_panel: endpoint { + remote-endpoint = <&panel_in_lvds>; + }; + }; + }; +}; + +&lvds_in_vopl { + status = "disabled"; +}; + +&mipi_dphy { + status = "okay"; +}; + +&nandc0 { + status = "okay"; +}; + +&pdm { + status = "okay"; + #sound-dai-cells = <0>; + rockchip,no-dmaengine; + pinctrl-names = "default"; + pinctrl-0 = <&pdm_clk0m1 + &pdm_sdi0m1>; +}; + +&pinctrl { + pinctrl-names = "default"; + pinctrl-0 = <&tp_int>; + + headphone { + hp_det: hp-det { + rockchip,pins = <3 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + pmic { + pmic_int: pmic_int { + rockchip,pins = + <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + soc_slppin_gpio: soc_slppin_gpio { + rockchip,pins = + <0 RK_PA4 RK_FUNC_GPIO &pcfg_output_low>; + }; + + soc_slppin_slp: soc_slppin_slp { + rockchip,pins = + <0 RK_PA4 RK_FUNC_1 &pcfg_pull_none>; + }; + + soc_slppin_rst: soc_slppin_rst { + rockchip,pins = + <0 RK_PA4 RK_FUNC_2 &pcfg_pull_none>; + }; + }; + + sdio-pwrseq { + wifi_enable_h: wifi-enable-h { + rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + touchscreen-int { + tp_int: tp-int { + rockchip,pins = <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; + +&pmu_io_domains { + status = "okay"; + + pmuio1-supply = <&vcc3v0_pmu>; + pmuio2-supply = <&vcc3v0_pmu>; +}; + +&pwm1 { + status = "okay"; +}; + +&rk_isp { + status = "okay"; +}; + +&rk_rga { + status = "okay"; +}; + +&rockchip_suspend { + status = "okay"; + rockchip,sleep-debug-en = <1>; +}; + +&route_dsi { + status = "okay"; +}; + +&route_lvds { + status = "disabled"; +}; + +&saradc { + status = "okay"; + vref-supply = <&vcc1v8_soc>; +}; + +&sdmmc { + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + supports-sd; + card-detect-delay = <800>; + ignore-pm-notify; + /*cd-gpios = <&gpio2 4 GPIO_ACTIVE_HIGH>; [> CD GPIO <]*/ + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vqmmc-supply = <&vccio_sd>; + vmmc-supply = <&vcc_sd>; + status = "okay"; +}; + +&sdio { + bus-width = <4>; + cap-sd-highspeed; + supports-sdio; + ignore-pm-notify; + keep-power-in-suspend; + non-removable; + mmc-pwrseq = <&sdio_pwrseq>; + sd-uhs-sdr104; + status = "okay"; +}; + +&tsadc { + pinctrl-names = "init", "default"; + pinctrl-0 = <&tsadc_otp_gpio>; + pinctrl-1 = <&tsadc_otp_out>; + status = "okay"; +}; + +&u2phy { + status = "okay"; + + u2phy_host: host-port { + status = "okay"; + }; + + u2phy_otg: otg-port { + vbus-supply = <&vcc5v0_host>; + status = "okay"; + }; +}; + +&usb20_otg { + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_xfer &uart1_cts>; + status = "okay"; +}; + +&vopb { + status = "okay"; +}; + +&vopb_mmu { + status = "okay"; +}; + +&vopl { + status = "okay"; +}; + +&vopl_mmu { + status = "okay"; +}; + +&vpu_combo { + status = "okay"; +}; + +&firmware_android { + compatible = "android,firmware"; + fstab { + compatible = "android,fstab"; + system { + compatible = "android,system"; + dev = "/dev/block/by-name/system"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait"; + }; + vendor { + compatible = "android,vendor"; + dev = "/dev/block/by-name/vendor"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3326-evb-ai-va-v11.dts b/arch/arm64/boot/dts/rockchip/rk3326-evb-ai-va-v11.dts index d2d395aaf52db..55a229ac4d41d 100644 --- a/arch/arm64/boot/dts/rockchip/rk3326-evb-ai-va-v11.dts +++ b/arch/arm64/boot/dts/rockchip/rk3326-evb-ai-va-v11.dts @@ -261,18 +261,6 @@ status = "okay"; }; -&cpu0_opp_table { - /* - * max IR-drop values on different freq condition for this board! - */ - rockchip,board-irdrop = < - /*MHz MHz uV */ - 0 815 37500 - 816 1119 50000 - 1200 1512 75000 - >; -}; - &dmc { center-supply = <&vdd_logic>; status = "okay"; @@ -635,15 +623,13 @@ }; }; - vcc3v3_lcd: SWITCH_REG1 { - regulator-boot-on; - regulator-name = "vcc3v3_lcd"; + vcc5v0_host: SWITCH_REG1 { + regulator-name = "vcc5v0_host"; }; - vcc5v0_host: SWITCH_REG2 { - regulator-always-on; + vcc3v3_lcd: SWITCH_REG2 { regulator-boot-on; - regulator-name = "vcc5v0_host"; + regulator-name = "vcc3v3_lcd"; }; }; @@ -1236,6 +1222,7 @@ }; u2phy_otg: otg-port { + vbus-supply = <&vcc5v0_host>; status = "okay"; }; }; @@ -1269,3 +1256,24 @@ &vpu_combo { status = "okay"; }; + +&firmware_android { + compatible = "android,firmware"; + fstab { + compatible = "android,fstab"; + system { + compatible = "android,system"; + dev = "/dev/block/by-name/system"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait"; + }; + vendor { + compatible = "android,vendor"; + dev = "/dev/block/by-name/vendor"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3326-evb-linux-lp3-v10.dts b/arch/arm64/boot/dts/rockchip/rk3326-evb-lp3-v10-linux.dts similarity index 91% rename from arch/arm64/boot/dts/rockchip/rk3326-evb-linux-lp3-v10.dts rename to arch/arm64/boot/dts/rockchip/rk3326-evb-lp3-v10-linux.dts index 04d972316b380..2e7b7ec493f82 100644 --- a/arch/arm64/boot/dts/rockchip/rk3326-evb-linux-lp3-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3326-evb-lp3-v10-linux.dts @@ -1,7 +1,6 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) /* - * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd - * - * SPDX-License-Identifier: (GPL-2.0+ OR MIT) + * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd */ /dts-v1/; @@ -11,12 +10,15 @@ #include #include #include "rk3326.dtsi" -#include "rk3326-863-cif-sensor.dtsi" #include "rk3326-linux.dtsi" / { - model = "Rockchip rk3326 evb linux board"; - compatible = "rockchip,rk3326-evb-linux-lp3-v10", "rockchip,rk3326"; + model = "Rockchip rk3326 evb lpddr3 v10 board for linux"; + compatible = "rockchip,rk3326-evb-lp3-v10-linux", "rockchip,rk3326"; + + chosen { + bootargs = "earlycon=uart8250,mmio32,0xff160000 swiotlb=1 console=ttyFIQ0 root=PARTUUID=614e0000-0000 rootfstype=squashfs rootwait"; + }; adc-keys { compatible = "adc-keys"; @@ -226,6 +228,18 @@ status = "okay"; }; +&cif_new { + status = "okay"; + + port { + cif_in: endpoint { + remote-endpoint = <&gc2155_out>; + vsync-active = <0>; + hsync-active = <1>; + }; + }; +}; + &cpu0 { cpu-supply = <&vdd_arm>; }; @@ -712,15 +726,39 @@ status = "okay"; clock-frequency = <400000>; + /* 24M mclk is shared for multiple cameras */ + pinctrl-0 = <&i2c2_xfer &cif_clkout_m0>; + /* These are relatively safe rise/fall times; TODO: measure */ i2c-scl-falling-time-ns = <50>; i2c-scl-rising-time-ns = <300>; + gc2155: gc2155@3c { + compatible = "gc,gc2155"; + reg = <0x3c>; + pinctrl-names = "default"; + pinctrl-0 = <&cif_pin_m0>; + + clocks = <&cru SCLK_CIF_OUT>; + clock-names = "xvclk"; + + avdd-supply = <&vcc2v8_dvp>; + dovdd-supply = <&vcc1v8_dvp>; + dvdd-supply = <&vcc1v8_dvp>; + + /* hw changed the pwdn to gpio2_b5 */ + pwdn-gpios = <&gpio2 13 GPIO_ACTIVE_HIGH>; + + port { + gc2155_out: endpoint { + remote-endpoint = <&cif_in>; + }; + }; + }; + ov5695: ov5695@36 { compatible = "ovti,ov5695"; reg = <0x36>; - pinctrl-names = "default"; - pinctrl-0 = <&cif_clkout_m0>; clocks = <&cru SCLK_CIF_OUT>; clock-names = "xvclk"; @@ -832,42 +870,6 @@ }; }; -&pinctrl { - headphone { - hp_det: hp-det { - rockchip,pins = <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_down>; - }; - }; - - pmic { - pmic_int: pmic_int { - rockchip,pins = - <0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>; - }; - - soc_slppin_gpio: soc_slppin_gpio { - rockchip,pins = - <0 RK_PA4 RK_FUNC_GPIO &pcfg_output_low>; - }; - - soc_slppin_slp: soc_slppin_slp { - rockchip,pins = - <0 RK_PA4 RK_FUNC_1 &pcfg_pull_none>; - }; - - soc_slppin_rst: soc_slppin_rst { - rockchip,pins = - <0 RK_PA4 RK_FUNC_2 &pcfg_pull_none>; - }; - }; - - sdio-pwrseq { - wifi_enable_h: wifi-enable-h { - rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; - }; - }; -}; - &pmu_io_domains { status = "okay"; @@ -959,6 +961,10 @@ status = "okay"; }; +&vip_mmu { + status = "okay"; +}; + &vopb { status = "okay"; }; @@ -978,3 +984,60 @@ &vpu_combo { status = "okay"; }; + +&pinctrl { + cif-pin-m0 { + cif_pin_m0: cif-pin-m0 { + rockchip,pins = + <2 RK_PA0 RK_FUNC_1 &pcfg_pull_none>,/* cif_data2 */ + <2 RK_PA1 RK_FUNC_1 &pcfg_pull_none>,/* cif_data3 */ + <2 RK_PA2 RK_FUNC_1 &pcfg_pull_none>,/* cif_data4 */ + <2 RK_PA3 RK_FUNC_1 &pcfg_pull_none>,/* cif_data5 */ + <2 RK_PA4 RK_FUNC_1 &pcfg_pull_none>,/* cif_data6 */ + <2 RK_PA5 RK_FUNC_1 &pcfg_pull_none>,/* cif_data7 */ + <2 RK_PA6 RK_FUNC_1 &pcfg_pull_none>,/* cif_data8 */ + <2 RK_PA7 RK_FUNC_1 &pcfg_pull_none>,/* cif_data9 */ + <2 RK_PB0 RK_FUNC_1 &pcfg_pull_none>,/* cif_sync */ + <2 RK_PB1 RK_FUNC_1 &pcfg_pull_none>,/* cif_href */ + <2 RK_PB2 RK_FUNC_1 &pcfg_pull_none>;/* cif_clkin */ + }; + }; + + headphone { + hp_det: hp-det { + rockchip,pins = <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_down>; + }; + }; + + pmic { + pmic_int: pmic_int { + rockchip,pins = + <0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + soc_slppin_gpio: soc_slppin_gpio { + rockchip,pins = + <0 RK_PA4 RK_FUNC_GPIO &pcfg_output_low>; + }; + + soc_slppin_slp: soc_slppin_slp { + rockchip,pins = + <0 RK_PA4 RK_FUNC_1 &pcfg_pull_none>; + }; + + soc_slppin_rst: soc_slppin_rst { + rockchip,pins = + <0 RK_PA4 RK_FUNC_2 &pcfg_pull_none>; + }; + }; + + sdio-pwrseq { + wifi_enable_h: wifi-enable-h { + rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +/* DON'T PUT ANYTHING BELOW HERE. PUT IT ABOVE PINCTRL */ +/* DON'T PUT ANYTHING BELOW HERE. PUT IT ABOVE PINCTRL */ +/* DON'T PUT ANYTHING BELOW HERE. PUT IT ABOVE PINCTRL */ diff --git a/arch/arm64/boot/dts/rockchip/rk3326-evb-lp3-v10.dts b/arch/arm64/boot/dts/rockchip/rk3326-evb-lp3-v10.dts index 9164cbf9a9ba1..d86687c788177 100644 --- a/arch/arm64/boot/dts/rockchip/rk3326-evb-lp3-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3326-evb-lp3-v10.dts @@ -910,3 +910,24 @@ &vpu_combo { status = "okay"; }; + +&firmware_android { + compatible = "android,firmware"; + fstab { + compatible = "android,fstab"; + system { + compatible = "android,system"; + dev = "/dev/block/by-name/system"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait"; + }; + vendor { + compatible = "android,vendor"; + dev = "/dev/block/by-name/vendor"; + type = "ext4"; + mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; + fsmgr_flags = "wait"; + }; + }; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3326.dtsi b/arch/arm64/boot/dts/rockchip/rk3326.dtsi index 89661162d4dcc..314376b6990fd 100644 --- a/arch/arm64/boot/dts/rockchip/rk3326.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3326.dtsi @@ -17,5 +17,7 @@ opp-microvolt = <1175000>; opp-microvolt-L0 = <1175000>; opp-microvolt-L1 = <1150000>; + opp-microvolt-L2 = <1100000>; + opp-microvolt-L3 = <1050000>; }; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3328-android.dtsi b/arch/arm64/boot/dts/rockchip/rk3328-android.dtsi index 076200002d36b..1833a7c376906 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328-android.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3328-android.dtsi @@ -6,7 +6,7 @@ / { chosen { - bootargs = "earlyprintk=uart8250-32bit,0xff130000"; + bootargs = "earlyprintk=uart8250-32bit,0xff130000 swiotlb=1 kpti=0"; }; fiq-debugger { diff --git a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts index a71b6cc116bb9..3c8a5cc87322a 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328-evb.dts +++ b/arch/arm64/boot/dts/rockchip/rk3328-evb.dts @@ -49,7 +49,7 @@ compatible = "rockchip,rk3328-evb", "rockchip,rk3328"; chosen { - bootargs = "rockchip_jtag earlyprintk=uart8250-32bit,0xff130000"; + bootargs = "rockchip_jtag earlyprintk=uart8250-32bit,0xff130000 swiotlb=1 kpti=0"; }; fiq-debugger { diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts index ea8cd77333a85..4b2eef609601e 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts @@ -48,7 +48,7 @@ compatible = "pine64,rock64", "rockchip,rk3328"; chosen { - bootargs = "rockchip_jtag earlyprintk=uart8250-32bit,0xff130000"; + bootargs = "rockchip_jtag earlyprintk=uart8250-32bit,0xff130000 swiotlb=1 kpti=0"; stdout-path = "serial2:1500000n8"; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi index b319e731d97b4..138ba21f4f101 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi @@ -218,7 +218,6 @@ clocks = <&cru SCLK_I2S0>, <&cru HCLK_I2S0_8CH>; clock-names = "i2s_clk", "i2s_hclk"; dmas = <&dmac 11>, <&dmac 12>; - #dma-cells = <2>; dma-names = "tx", "rx"; status = "disabled"; }; @@ -230,7 +229,6 @@ clocks = <&cru SCLK_I2S1>, <&cru HCLK_I2S1_8CH>; clock-names = "i2s_clk", "i2s_hclk"; dmas = <&dmac 14>, <&dmac 15>; - #dma-cells = <2>; dma-names = "tx", "rx"; status = "disabled"; }; @@ -242,7 +240,6 @@ clocks = <&cru SCLK_I2S2>, <&cru HCLK_I2S2_2CH>; clock-names = "i2s_clk", "i2s_hclk"; dmas = <&dmac 0>, <&dmac 1>; - #dma-cells = <2>; dma-names = "tx", "rx"; pinctrl-names = "default", "sleep"; pinctrl-0 = <&i2s2m0_mclk @@ -262,7 +259,6 @@ clocks = <&cru SCLK_SPDIF>, <&cru HCLK_SPDIF_8CH>; clock-names = "mclk", "hclk"; dmas = <&dmac 10>; - #dma-cells = <1>; dma-names = "tx"; pinctrl-names = "default"; pinctrl-0 = <&spdifm2_tx>; @@ -275,7 +271,6 @@ clocks = <&cru SCLK_PDM>, <&cru HCLK_PDM>; clock-names = "pdm_clk", "pdm_hclk"; dmas = <&dmac 16>; - #dma-cells = <1>; dma-names = "rx"; pinctrl-names = "default", "sleep"; pinctrl-0 = <&pdmm0_clk @@ -443,7 +438,6 @@ reg-shift = <2>; reg-io-width = <4>; dmas = <&dmac 2>, <&dmac 3>; - #dma-cells = <2>; pinctrl-names = "default"; pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>; status = "disabled"; @@ -454,11 +448,10 @@ reg = <0x0 0xff120000 0x0 0x100>; interrupts = ; clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>; - clock-names = "sclk_uart", "pclk_uart"; + clock-names = "baudclk", "apb_pclk"; reg-shift = <2>; reg-io-width = <4>; dmas = <&dmac 4>, <&dmac 5>; - #dma-cells = <2>; pinctrl-names = "default"; pinctrl-0 = <&uart1_xfer &uart1_cts &uart1_rts>; status = "disabled"; @@ -473,7 +466,6 @@ reg-shift = <2>; reg-io-width = <4>; dmas = <&dmac 6>, <&dmac 7>; - #dma-cells = <2>; pinctrl-names = "default"; pinctrl-0 = <&uart2m1_xfer>; status = "disabled"; @@ -545,7 +537,6 @@ clocks = <&cru SCLK_SPI>, <&cru PCLK_SPI>; clock-names = "spiclk", "apb_pclk"; dmas = <&dmac 8>, <&dmac 9>; - #dma-cells = <2>; dma-names = "tx", "rx"; pinctrl-names = "default"; pinctrl-0 = <&spi0m2_clk &spi0m2_tx &spi0m2_rx &spi0m2_cs0>; @@ -933,6 +924,8 @@ interrupts = ; clocks = <&cru ACLK_VOP>, <&cru DCLK_LCDC>, <&cru HCLK_VOP>; clock-names = "aclk_vop", "dclk_vop", "hclk_vop"; + assigned-clocks = <&cru DCLK_LCDC>; + assigned-clock-parents = <&cru HDMIPHY>; resets = <&cru SRST_VOP_A>, <&cru SRST_VOP_H>, <&cru SRST_VOP_D>; reset-names = "axi", "ahb", "dclk"; iommus = <&vop_mmu>; @@ -1233,10 +1226,10 @@ sdmmc: dwmmc@ff500000 { compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc"; reg = <0x0 0xff500000 0x0 0x4000>; - clock-freq-min-max = <400000 150000000>; + max-frequency = <150000000>; clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>, <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>; - clock-names = "biu", "ciu", "ciu-drv", "ciu-sample"; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; interrupts = ; status = "disabled"; @@ -1245,10 +1238,10 @@ sdio: dwmmc@ff510000 { compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc"; reg = <0x0 0xff510000 0x0 0x4000>; - clock-freq-min-max = <400000 150000000>; + max-frequency = <150000000>; clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>, <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>; - clock-names = "biu", "ciu", "ciu-drv", "ciu-sample"; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; interrupts = ; status = "disabled"; @@ -1257,10 +1250,10 @@ emmc: dwmmc@ff520000 { compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc"; reg = <0x0 0xff520000 0x0 0x4000>; - clock-freq-min-max = <400000 150000000>; + max-frequency = <150000000>; clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>, <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>; - clock-names = "biu", "ciu", "ciu-drv", "ciu-sample"; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; interrupts = ; status = "disabled"; diff --git a/arch/arm64/boot/dts/rockchip/rk3368.dtsi b/arch/arm64/boot/dts/rockchip/rk3368.dtsi index 46617af933392..f263de7069511 100644 --- a/arch/arm64/boot/dts/rockchip/rk3368.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3368.dtsi @@ -509,7 +509,7 @@ sdmmc: dwmmc@ff0c0000 { compatible = "rockchip,rk3368-dw-mshc", "rockchip,rk3288-dw-mshc"; reg = <0x0 0xff0c0000 0x0 0x4000>; - clock-freq-min-max = <400000 150000000>; + max-frequency = <150000000>; clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>, <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>; clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; @@ -521,7 +521,7 @@ sdio0: dwmmc@ff0d0000 { compatible = "rockchip,rk3368-dw-mshc", "rockchip,rk3288-dw-mshc"; reg = <0x0 0xff0d0000 0x0 0x4000>; - clock-freq-min-max = <400000 150000000>; + max-frequency = <150000000>; clocks = <&cru HCLK_SDIO0>, <&cru SCLK_SDIO0>, <&cru SCLK_SDIO0_DRV>, <&cru SCLK_SDIO0_SAMPLE>; clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; @@ -533,7 +533,7 @@ emmc: dwmmc@ff0f0000 { compatible = "rockchip,rk3368-dw-mshc", "rockchip,rk3288-dw-mshc"; reg = <0x0 0xff0f0000 0x0 0x4000>; - clock-freq-min-max = <400000 150000000>; + max-frequency = <150000000>; clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>, <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>; clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; @@ -838,6 +838,8 @@ g-rx-fifo-size = <280>; g-tx-fifo-size = <256 128 128 64 32 16>; g-use-dma; + phys = <&u2phy_otg>; + phy-names = "usb2-phy"; status = "disabled"; }; @@ -1188,6 +1190,16 @@ assigned-clock-parents = <&u2phy>; status = "disabled"; + u2phy_otg: otg-port { + #phy-cells = <0>; + interrupts = , + , + ; + interrupt-names = "otg-bvalid", "otg-id", + "linestate"; + status = "disabled"; + }; + u2phy_host: host-port { #phy-cells = <0>; interrupts = ; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-android-6.0.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-android-6.0.dtsi index f43c56038a615..ede5757e0e033 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-android-6.0.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-android-6.0.dtsi @@ -57,7 +57,7 @@ cpuinfo { compatible = "rockchip,cpuinfo"; - nvmem-cells = <&efuse_id>; + nvmem-cells = <&cpu_id>; nvmem-cell-names = "id"; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-android.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-android.dtsi index 72ed5bbaa1c08..b9f5ad1857b62 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-android.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-android.dtsi @@ -53,7 +53,7 @@ cpuinfo { compatible = "rockchip,cpuinfo"; - nvmem-cells = <&efuse_id>; + nvmem-cells = <&cpu_id>; nvmem-cell-names = "id"; }; @@ -266,14 +266,14 @@ compatible = "android,fstab"; system { compatible = "android,system"; - dev = "/dev/block/platform/fe330000.sdhci/by-name/system"; + dev = "/dev/block/by-name/system"; type = "ext4"; mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; fsmgr_flags = "wait,verify"; }; vendor { compatible = "android,vendor"; - dev = "/dev/block/platform/fe330000.sdhci/by-name/vendor"; + dev = "/dev/block/by-name/vendor"; type = "ext4"; mnt_flags = "ro,barrier=1,inode_readahead_blks=8"; fsmgr_flags = "wait,verify"; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-box.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-box.dtsi index 8dc6e78eac646..9a8db8feb1c94 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-box.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-box.dtsi @@ -188,6 +188,11 @@ status = "okay"; }; +&hdmi { + pinctrl-names = "default"; + pinctrl-0 = <&hdmi_i2c_xfer>, <&hdmi_cec>; +}; + &sdmmc { clock-frequency = <100000000>; clock-freq-min-max = <100000 100000000>; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-evb-rev3-android-lp4.dts b/arch/arm64/boot/dts/rockchip/rk3399-evb-rev3-android-lp4.dts index 8dd0a0bf36ee5..3afffea7b071f 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-evb-rev3-android-lp4.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-evb-rev3-android-lp4.dts @@ -117,11 +117,11 @@ SYS_STATUS_NORMAL 800000 SYS_STATUS_REBOOT 400000 SYS_STATUS_SUSPEND 400000 - SYS_STATUS_VIDEO_1080P 400000 + SYS_STATUS_VIDEO_1080P 800000 SYS_STATUS_VIDEO_4K 800000 SYS_STATUS_VIDEO_4K_10B 800000 SYS_STATUS_PERFORMANCE 800000 - SYS_STATUS_BOOST 400000 + SYS_STATUS_BOOST 800000 SYS_STATUS_DUALVIEW 800000 SYS_STATUS_ISP 800000 >; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-excavator-sapphire.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-excavator-sapphire.dtsi index c406e54b4a870..6cb9bcd6d9844 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-excavator-sapphire.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-excavator-sapphire.dtsi @@ -150,9 +150,10 @@ >; vop-bw-dmc-freq = < /* min_bw(MB/s) max_bw(MB/s) freq(KHz) */ - 0 577 200000 - 578 1701 300000 - 1702 99999 400000 + 0 762 200000 + 763 1893 400000 + 1894 3012 528000 + 3013 99999 800000 >; auto-min-freq = <200000>; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-firefly-android.dts b/arch/arm64/boot/dts/rockchip/rk3399-firefly-android.dts index f2d5c4bfc0283..2859986d630c9 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-firefly-android.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-firefly-android.dts @@ -59,7 +59,7 @@ cpuinfo { compatible = "rockchip,cpuinfo"; - nvmem-cells = <&efuse_id>; + nvmem-cells = <&cpu_id>; nvmem-cell-names = "id"; }; @@ -344,7 +344,7 @@ /* for rockchip boot on */ rockchip,pwm_id= <2>; - rockchip,pwm_voltage = <1000000>; + rockchip,pwm_voltage = <900000>; }; vccadc_ref: vccadc-ref { diff --git a/arch/arm64/boot/dts/rockchip/rk3399-firefly-linux.dts b/arch/arm64/boot/dts/rockchip/rk3399-firefly-linux.dts index 243eef889e5f0..99d40a3f71154 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-firefly-linux.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-firefly-linux.dts @@ -293,7 +293,7 @@ /* for rockchip boot on */ rockchip,pwm_id= <2>; - rockchip,pwm_voltage = <1000000>; + rockchip,pwm_voltage = <900000>; }; vccadc_ref: vccadc-ref { @@ -670,6 +670,43 @@ io-channels = <&saradc 4>; hp-det-adc-value = <500>; }; + + camera0: ov13850@10 { + status = "okay"; + compatible = "omnivision,ov13850-v4l2-i2c-subdev"; + reg = < 0x10 >; + device_type = "v4l2-i2c-subdev"; + + clocks = <&cru SCLK_CIF_OUT>; + clock-names = "clk_cif_out"; + + pinctrl-names = "rockchip,camera_default", "rockchip,camera_sleep"; + pinctrl-0 = <&cam0_default_pins>; + pinctrl-1 = <&cam0_sleep_pins>; + + rockchip,pd-gpio = <&gpio2 12 GPIO_ACTIVE_LOW>; + rockchip,pwr-gpio = <&gpio1 23 GPIO_ACTIVE_HIGH>; + rockchip,pwr-2nd-gpio = <&gpio1 22 GPIO_ACTIVE_HIGH>; + rockchip,rst-gpio = <&gpio0 8 GPIO_ACTIVE_LOW>; + + rockchip,camera-module-mclk-name = "clk_cif_out"; + rockchip,camera-module-facing = "back"; + rockchip,camera-module-name = "cmk-cb0695-fv1"; + rockchip,camera-module-len-name = "lg9569a2"; + rockchip,camera-module-fov-h = "66.0"; + rockchip,camera-module-fov-v = "50.1"; + rockchip,camera-module-orientation = <0>; + rockchip,camera-module-iq-flip = <0>; + rockchip,camera-module-iq-mirror = <0>; + rockchip,camera-module-flip = <1>; + rockchip,camera-module-mirror = <0>; + + rockchip,camera-module-defrect0 = <2112 1568 0 0 2112 1568>; + rockchip,camera-module-defrect1 = <4224 3136 0 0 4224 3136>; + rockchip,camera-module-defrect3 = <3264 2448 0 0 3264 2448>; + rockchip,camera-module-flash-support = <0>; + rockchip,camera-module-mipi-dphy-index = <0>; + }; }; &i2c3 { @@ -1016,6 +1053,15 @@ status = "okay"; }; +&cif_isp0 { + rockchip,camera-modules-attached = <&camera0>; + status = "okay"; +}; + +&isp0_mmu { + status = "okay"; +}; + &vopb { status = "okay"; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi index 41ae17e5ea473..cc38780344756 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi @@ -515,6 +515,31 @@ cpu-supply = <&ppvar_bigcpu>; }; +&cru { + assigned-clocks = + <&cru PLL_GPLL>, <&cru PLL_CPLL>, + <&cru PLL_NPLL>, + <&cru ACLK_PERIHP>, <&cru HCLK_PERIHP>, + <&cru PCLK_PERIHP>, + <&cru ACLK_PERILP0>, <&cru HCLK_PERILP0>, + <&cru PCLK_PERILP0>, <&cru ACLK_CCI>, + <&cru HCLK_PERILP1>, <&cru PCLK_PERILP1>, + <&cru ACLK_VIO>, <&cru ACLK_HDCP>, + <&cru ACLK_GIC_PRE>, + <&cru PCLK_DDR>; + assigned-clock-rates = + <600000000>, <800000000>, + <1000000000>, + <150000000>, <75000000>, + <37500000>, + <100000000>, <100000000>, + <50000000>, <800000000>, + <100000000>, <50000000>, + <400000000>, <400000000>, + <200000000>, + <200000000>; +}; + &emmc_phy { status = "okay"; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-opp.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-opp.dtsi index f443a9a21f986..7926d95f6e6cb 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-opp.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-opp.dtsi @@ -47,6 +47,10 @@ compatible = "operating-points-v2"; opp-shared; + rockchip,temp-hysteresis = <5000>; + rockchip,low-temp = <0>; + rockchip,low-temp-min-volt = <900000>; + nvmem-cells = <&cpul_leakage>; nvmem-cell-names = "cpu_leakage"; @@ -64,7 +68,7 @@ rockchip,pvtm-error = <1000>; rockchip,pvtm-ref-temp = <41>; rockchip,pvtm-temp-prop = <115 66>; - rockchip,pvtm-thermal-zone = "soc-thermal"; + rockchip,thermal-zone = "soc-thermal"; opp-408000000 { opp-hz = /bits/ 64 <408000000>; @@ -127,6 +131,10 @@ compatible = "operating-points-v2"; opp-shared; + rockchip,temp-hysteresis = <5000>; + rockchip,low-temp = <0>; + rockchip,low-temp-min-volt = <900000>; + nvmem-cells = <&cpub_leakage>; nvmem-cell-names = "cpu_leakage"; @@ -144,7 +152,7 @@ rockchip,pvtm-error = <1000>; rockchip,pvtm-ref-temp = <41>; rockchip,pvtm-temp-prop = <71 35>; - rockchip,pvtm-thermal-zone = "soc-thermal"; + rockchip,thermal-zone = "soc-thermal"; opp-408000000 { opp-hz = /bits/ 64 <408000000>; @@ -224,6 +232,11 @@ gpu_opp_table: opp-table2 { compatible = "operating-points-v2"; + rockchip,thermal-zone = "soc-thermal"; + rockchip,temp-hysteresis = <5000>; + rockchip,low-temp = <0>; + rockchip,low-temp-min-volt = <900000>; + nvmem-cells = <&gpu_leakage>; nvmem-cell-names = "gpu_leakage"; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock960-ab.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock960-ab.dts new file mode 100644 index 0000000000000..601cd0c2351e3 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3399-rock960-ab.dts @@ -0,0 +1,1083 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd + */ + +/dts-v1/; + +#include +#include +#include "rk3399.dtsi" +#include "rk3399-linux.dtsi" +#include "rk3399-opp.dtsi" + +/ { + + model = "ROCK960 - 96boards based on Rockchip RK3399"; + compatible = "rockchip,rock960","rockchip,rk3399"; + + fiq_debugger: fiq-debugger { + compatible = "rockchip,fiq-debugger"; + rockchip,serial-id = <2>; + rockchip,signal-irq = <182>; + rockchip,wake-irq = <0>; + rockchip,irq-mode-enable = <1>; + rockchip,baudrate = <1500000>; /* Only 115200 and 1500000 */ + pinctrl-names = "default"; + pinctrl-0 = <&uart2c_xfer>; + }; + + vcc1v8_s0: vcc1v8-s0 { + compatible = "regulator-fixed"; + regulator-name = "vcc1v8_s0"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + vcc_sys: vcc-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc_sys"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + + vcc_phy: vcc-phy-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc_phy"; + regulator-always-on; + regulator-boot-on; + }; + + vcc3v3_sys: vcc3v3-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_sys"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + vin-supply = <&vcc_sys>; + }; + + vcc3v3_pcie: vcc3v3-pcie-regulator { + compatible = "regulator-fixed"; + gpio = <&gpio3 11 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&pcie_drv>; + regulator-boot-on; + regulator-always-on; + regulator-name = "vcc3v3_pcie"; + vin-supply = <&vcc3v3_sys>; + }; + + vcc5v0_host: vcc5v0-host-regulator { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio4 25 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&host_vbus_drv>; + regulator-name = "vcc5v0_host"; + regulator-always-on; + }; + + vdd_log: vdd-log { + compatible = "pwm-regulator"; + pwms = <&pwm2 0 25000 1>; + regulator-name = "vdd_log"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1400000>; + regulator-always-on; + regulator-boot-on; + + /* for rockchip boot on */ + rockchip,pwm_id= <2>; + rockchip,pwm_voltage = <900000>; + + vin-supply = <&vcc_sys>; + }; + + clkin_gmac: external-gmac-clock { + compatible = "fixed-clock"; + clock-frequency = <125000000>; + clock-output-names = "clkin_gmac"; + #clock-cells = <0>; + }; + + hdmi_codec: hdmi-codec { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,name = "HDMI-CODEC"; + + simple-audio-card,cpu { + sound-dai = <&i2s2>; + }; + + simple-audio-card,codec { + sound-dai = <&hdmi>; + }; + }; + + spdif-sound { + status = "okay"; + compatible = "simple-audio-card"; + simple-audio-card,name = "ROCKCHIP,SPDIF"; + simple-audio-card,cpu { + sound-dai = <&spdif>; + }; + simple-audio-card,codec { + sound-dai = <&spdif_out>; + }; + }; + + spdif_out: spdif-out { + status = "okay"; + compatible = "linux,spdif-dit"; + #sound-dai-cells = <0>; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + clocks = <&rk808 1>; + clock-names = "ext_clock"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_enable_h>; + + /* + * On the module itself this is one of these (depending + * on the actual card populated): + * - SDIO_RESET_L_WL_REG_ON + * - PDN (power down when low) + */ + reset-gpios = <&gpio0 10 GPIO_ACTIVE_LOW>; + }; + + wireless-wlan { + compatible = "wlan-platdata"; + rockchip,grf = <&grf>; + wifi_chip_type = "ap6354"; + sdio_vref = <1800>; + WIFI,host_wake_irq = <&gpio0 3 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; + + wireless-bluetooth { + compatible = "bluetooth-platdata"; + clocks = <&rk808 1>; + clock-names = "ext_clock"; + /* wifi-bt-power-toggle; */ + uart_rts_gpios = <&gpio2 19 GPIO_ACTIVE_LOW>; + pinctrl-names = "default", "rts_gpio"; + pinctrl-0 = <&uart0_rts>; + pinctrl-1 = <&uart0_gpios>; + /* BT,power_gpio = <&gpio3 19 GPIO_ACTIVE_HIGH>; */ + BT,reset_gpio = <&gpio0 9 GPIO_ACTIVE_HIGH>; + BT,wake_gpio = <&gpio2 27 GPIO_ACTIVE_HIGH>; + BT,wake_host_irq = <&gpio0 4 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; + + test-power { + status = "okay"; + }; +}; + +&hdmi { + #address-cells = <1>; + #size-cells = <0>; + #sound-dai-cells = <0>; + status = "okay"; +}; + +&sdmmc { + clock-frequency = <100000000>; + clock-freq-min-max = <100000 100000000>; + supports-sd; + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + disable-wp; + num-slots = <1>; + //sd-uhs-sdr104; + vqmmc-supply = <&vcc_sd>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; + card-detect-delay = <800>; + status = "okay"; +}; + +&sdio0 { + clock-frequency = <100000000>; + clock-freq-min-max = <200000 100000000>; + supports-sdio; + bus-width = <4>; + disable-wp; + cap-sd-highspeed; + cap-sdio-irq; + keep-power-in-suspend; + mmc-pwrseq = <&sdio_pwrseq>; + non-removable; + num-slots = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>; + sd-uhs-sdr104; + status = "okay"; +}; + +&emmc_phy { + status = "okay"; +}; + +&sdhci { + bus-width = <8>; + mmc-hs400-1_8v; + supports-emmc; + non-removable; + mmc-hs400-enhanced-strobe; + status = "okay"; +}; + +&i2s0 { + status = "okay"; + rockchip,i2s-broken-burst-len; + rockchip,playback-channels = <8>; + rockchip,capture-channels = <8>; + #sound-dai-cells = <0>; +}; + +&i2s2 { + status = "okay"; + #sound-dai-cells = <0>; +}; + +&spdif { + pinctrl-0 = <&spdif_bus_1>; + status = "okay"; + #sound-dai-cells = <0>; +}; + +&i2c0 { + status = "okay"; + i2c-scl-rising-time-ns = <168>; + i2c-scl-falling-time-ns = <4>; + clock-frequency = <400000>; + + vdd_cpu_b: syr827@40 { + compatible = "silergy,syr827"; + reg = <0x40>; + regulator-compatible = "fan53555-reg"; + pinctrl-0 = <&vsel1_gpio>; + vsel-gpios = <&gpio1 17 GPIO_ACTIVE_HIGH>; + regulator-name = "vdd_cpu_b"; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1500000>; + regulator-ramp-delay = <1000>; + fcs,suspend-voltage-selector = <1>; + regulator-always-on; + regulator-boot-on; + vin-supply = <&vcc_sys>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_gpu: syr828@41 { + compatible = "silergy,syr828"; + reg = <0x41>; + regulator-compatible = "fan53555-reg"; + pinctrl-0 = <&vsel2_gpio>; + vsel-gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>; + regulator-name = "vdd_gpu"; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1500000>; + regulator-ramp-delay = <1000>; + fcs,suspend-voltage-selector = <1>; + regulator-always-on; + regulator-boot-on; + vin-supply = <&vcc_sys>; + regulator-initial-mode = <1>; /* 1:force PWM 2:auto */ + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + rk808: pmic@1b { + compatible = "rockchip,rk808"; + reg = <0x1b>; + interrupt-parent = <&gpio1>; + interrupts = <21 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int_l>; + rockchip,system-power-controller; + wakeup-source; + #clock-cells = <1>; + clock-output-names = "xin32k", "rk808-clkout2"; + + vcc1-supply = <&vcc_sys>; + vcc2-supply = <&vcc_sys>; + vcc3-supply = <&vcc_sys>; + vcc4-supply = <&vcc_sys>; + vcc6-supply = <&vcc_sys>; + vcc7-supply = <&vcc_sys>; + vcc8-supply = <&vcc3v3_sys>; + vcc9-supply = <&vcc_sys>; + vcc10-supply = <&vcc_sys>; + vcc11-supply = <&vcc_sys>; + vcc12-supply = <&vcc3v3_sys>; + vddio-supply = <&vcc_1v8>; + + regulators { + vdd_center: DCDC_REG1 { + regulator-name = "vdd_center"; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_cpu_l: DCDC_REG2 { + regulator-name = "vdd_cpu_l"; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1350000>; + regulator-ramp-delay = <6001>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_1v8: DCDC_REG4 { + regulator-name = "vcc_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc1v8_dvp: LDO_REG1 { + regulator-name = "vcc1v8_dvp"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcca1v8_hdmi: LDO_REG2 { + regulator-name = "vcca1v8_hdmi"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcca_1v8: LDO_REG3 { + regulator-name = "vcca_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc_sd: LDO_REG4 { + regulator-name = "vcc_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vcc3v0_sd: LDO_REG5 { + regulator-name = "vcc3v0_sd"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vcc_1v5: LDO_REG6 { + regulator-name = "vcc_1v5"; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1500000>; + }; + }; + + vcca0v9_hdmi: LDO_REG7 { + regulator-name = "vcca0v9_hdmi"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <900000>; + }; + }; + + vcc_3v0: LDO_REG8 { + regulator-name = "vcc_3v0"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3000000>; + }; + }; + + vcc3v3_s3: SWITCH_REG1 { + regulator-name = "vcc3v3_s3"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc3v3_s0: SWITCH_REG2 { + regulator-name = "vcc3v3_s0"; + regulator-always-on; + regulator-boot-on; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + }; + }; +}; + +&i2c1 { + status = "okay"; +}; + +&i2c6 { + status = "okay"; +}; + +&i2c4 { + status = "okay"; + fusb0: fusb30x@22 { + compatible = "fairchild,fusb302"; + reg = <0x22>; + pinctrl-names = "default"; + pinctrl-0 = <&fusb0_int>; + vbus-5v-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>; + int-n-gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; +}; + +&i2c2 { + status = "okay"; + camera0: camera-module@10 { + status = "disabled"; + compatible = "omnivision,ov13850-v4l2-i2c-subdev"; + reg = < 0x10 >; + device_type = "v4l2-i2c-subdev"; + clocks = <&cru SCLK_CIF_OUT>; + clock-names = "clk_cif_out"; + pinctrl-names = "rockchip,camera_default", + "rockchip,camera_sleep"; + pinctrl-0 = <&cam0_default_pins>; + pinctrl-1 = <&cam0_sleep_pins>; + //rockchip,pd-gpio = <&gpio4 4 GPIO_ACTIVE_LOW>; + rockchip,pwr-gpio = <&gpio4 4 GPIO_ACTIVE_HIGH>; + rockchip,rst-gpio = <&gpio3 29 GPIO_ACTIVE_LOW>; + rockchip,camera-module-mclk-name = "clk_cif_out"; + rockchip,camera-module-facing = "back"; + rockchip,camera-module-name = "cmk-cb0695-fv1"; + rockchip,camera-module-len-name = "lg9569a2"; + rockchip,camera-module-fov-h = "66.0"; + rockchip,camera-module-fov-v = "50.1"; + rockchip,camera-module-orientation = <0>; + rockchip,camera-module-iq-flip = <0>; + rockchip,camera-module-iq-mirror = <0>; + rockchip,camera-module-flip = <1>; + rockchip,camera-module-mirror = <0>; + + rockchip,camera-module-defrect0 = <2112 1568 0 0 2112 1568>; + rockchip,camera-module-defrect1 = <4224 3136 0 0 4224 3136>; + rockchip,camera-module-defrect3 = <3264 2448 0 0 3264 2448>; + rockchip,camera-module-flash-support = <1>; + rockchip,camera-module-mipi-dphy-index = <0>; + }; + + camera1: camera-module@36 { + status = "disabled"; + compatible = "omnivision,ov4690-v4l2-i2c-subdev"; + reg = <0x36>; + device_type = "v4l2-i2c-subdev"; + clocks = <&cru SCLK_CIF_OUT>; + clock-names = "clk_cif_out"; + pinctrl-names = "rockchip,camera_default", + "rockchip,camera_sleep"; + pinctrl-0 = <&cam0_default_pins>; + pinctrl-1 = <&cam0_sleep_pins>; + rockchip,pd-gpio = <&gpio3 4 GPIO_ACTIVE_LOW>; + //rockchip,pwr-gpio = <&gpio3 13 0>; + rockchip,rst-gpio = <&gpio2 10 GPIO_ACTIVE_LOW>; + rockchip,camera-module-mclk-name = "clk_cif_out"; + rockchip,camera-module-facing = "back"; + rockchip,camera-module-name = "LA6111PA"; + rockchip,camera-module-len-name = "YM6011P"; + rockchip,camera-module-fov-h = "116"; + rockchip,camera-module-fov-v = "61"; + rockchip,camera-module-orientation = <0>; + rockchip,camera-module-iq-flip = <0>; + rockchip,camera-module-iq-mirror = <0>; + rockchip,camera-module-flip = <0>; + rockchip,camera-module-mirror = <1>; + + rockchip,camera-module-defrect0 = <2688 1520 0 0 2688 1520>; + rockchip,camera-module-flash-support = <0>; + rockchip,camera-module-mipi-dphy-index = <0>; + }; + +}; + +&cpu_l0 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_l1 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_l2 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_l3 { + cpu-supply = <&vdd_cpu_l>; +}; + +&cpu_b0 { + cpu-supply = <&vdd_cpu_b>; +}; + +&cpu_b1 { + cpu-supply = <&vdd_cpu_b>; +}; + +&gpu { + status = "okay"; + mali-supply = <&vdd_gpu>; +}; + +&threshold { + temperature = <85000>; +}; + +&target { + temperature = <100000>; +}; + +&soc_crit { + temperature = <105000>; +}; + +&tcphy0 { + extcon = <&fusb0>; + status = "okay"; +}; + +&tcphy1 { + status = "okay"; +}; + +&tsadc { + /* tshut mode 0:CRU 1:GPIO */ + rockchip,hw-tshut-mode = <1>; + /* tshut polarity 0:LOW 1:HIGH */ + rockchip,hw-tshut-polarity = <1>; + rockchip,hw-tshut-temp = <110000>; + status = "okay"; +}; + +&u2phy0 { + status = "okay"; + extcon = <&fusb0>; + + u2phy0_otg: otg-port { + status = "okay"; + }; + + u2phy0_host: host-port { + phy-supply = <&vcc5v0_host>; + status = "okay"; + }; +}; + +&u2phy1 { + status = "okay"; + + u2phy1_otg: otg-port { + status = "okay"; + }; + + u2phy1_host: host-port { + phy-supply = <&vcc5v0_host>; + status = "okay"; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_xfer &uart0_cts>; + dmas = <&dmac_peri 0>, <&dmac_peri 1>; + dma-names = "tx", "rx"; + status = "okay"; +}; + +&uart3 { + compatible = "rockchip,rk3399-uart", "snps,dw-apb-uart"; + reg = <0x0 0xff1b0000 0x0 0x100>; + clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>; + clock-names = "baudclk", "apb_pclk"; + interrupts = ; + dmas = <&dmac_peri 6>, <&dmac_peri 7>; + dma-names = "tx", "rx"; + reg-shift = <2>; + reg-io-width = <4>; + pinctrl-names = "default"; + pinctrl-0 = <&uart3_xfer &uart3_cts &uart3_rts>; + status = "okay"; +}; + +&uart4 { + status = "okay"; + dmas = <&dmac_peri 8>, <&dmac_peri 9>; + dma-names = "tx", "rx"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; + +&usb_host1_ehci { + status = "okay"; +}; + +&usb_host1_ohci { + status = "okay"; +}; + +&usbdrd3_0 { + extcon = <&fusb0>; + status = "okay"; +}; + +&usbdrd_dwc3_0 { + dr_mode = "otg"; + status = "okay"; +}; + +&usbdrd3_1 { + status = "okay"; +}; + +&usbdrd_dwc3_1 { + dr_mode = "host"; + status = "okay"; +}; + +&pwm2 { + status = "okay"; +}; + +&pwm3 { + status = "okay"; + + interrupts = ; + compatible = "rockchip,remotectl-pwm"; + remote_pwm_id = <3>; + handle_cpu_id = <1>; + remote_support_psci = <1>; + + ir_key1 { + rockchip,usercode = <0x4040>; + rockchip,key_table = + <0xf2 KEY_REPLY>, + <0xba KEY_BACK>, + <0xf4 KEY_UP>, + <0xf1 KEY_DOWN>, + <0xef KEY_LEFT>, + <0xee KEY_RIGHT>, + <0xbd KEY_HOME>, + <0xea KEY_VOLUMEUP>, + <0xe3 KEY_VOLUMEDOWN>, + <0xe2 KEY_SEARCH>, + <0xb2 KEY_POWER>, + <0xbc KEY_MUTE>, + <0xec KEY_MENU>, + <0xbf 0x190>, + <0xe0 0x191>, + <0xe1 0x192>, + <0xe9 183>, + <0xe6 248>, + <0xe8 185>, + <0xe7 186>, + <0xf0 388>, + <0xbe 0x175>; + }; + + ir_key2 { + rockchip,usercode = <0xff00>; + rockchip,key_table = + <0xf9 KEY_HOME>, + <0xbf KEY_BACK>, + <0xfb KEY_MENU>, + <0xaa KEY_REPLY>, + <0xb9 KEY_UP>, + <0xe9 KEY_DOWN>, + <0xb8 KEY_LEFT>, + <0xea KEY_RIGHT>, + <0xeb KEY_VOLUMEDOWN>, + <0xef KEY_VOLUMEUP>, + <0xf7 KEY_MUTE>, + <0xe7 KEY_POWER>, + <0xfc KEY_POWER>, + <0xa9 KEY_VOLUMEDOWN>, + <0xa8 KEY_VOLUMEDOWN>, + <0xe0 KEY_VOLUMEDOWN>, + <0xa5 KEY_VOLUMEDOWN>, + <0xab 183>, + <0xb7 388>, + <0xe8 388>, + <0xf8 184>, + <0xaf 185>, + <0xed KEY_VOLUMEDOWN>, + <0xee 186>, + <0xb3 KEY_VOLUMEDOWN>, + <0xf1 KEY_VOLUMEDOWN>, + <0xf2 KEY_VOLUMEDOWN>, + <0xf3 KEY_SEARCH>, + <0xb4 KEY_VOLUMEDOWN>, + <0xbe KEY_SEARCH>; + }; + + ir_key3 { + rockchip,usercode = <0x1dcc>; + rockchip,key_table = + <0xee KEY_REPLY>, + <0xf0 KEY_BACK>, + <0xf8 KEY_UP>, + <0xbb KEY_DOWN>, + <0xef KEY_LEFT>, + <0xed KEY_RIGHT>, + <0xfc KEY_HOME>, + <0xf1 KEY_VOLUMEUP>, + <0xfd KEY_VOLUMEDOWN>, + <0xb7 KEY_SEARCH>, + <0xff KEY_POWER>, + <0xf3 KEY_MUTE>, + <0xbf KEY_MENU>, + <0xf9 0x191>, + <0xf5 0x192>, + <0xb3 388>, + <0xbe KEY_1>, + <0xba KEY_2>, + <0xb2 KEY_3>, + <0xbd KEY_4>, + <0xf9 KEY_5>, + <0xb1 KEY_6>, + <0xfc KEY_7>, + <0xf8 KEY_8>, + <0xb0 KEY_9>, + <0xb6 KEY_0>, + <0xb5 KEY_BACKSPACE>; + }; +}; + +&gmac { + phy-supply = <&vcc_phy>; + phy-mode = "rgmii"; + clock_in_out = "input"; + snps,reset-gpio = <&gpio3 15 GPIO_ACTIVE_LOW>; + snps,reset-active-low; + snps,reset-delays-us = <0 10000 50000>; + assigned-clocks = <&cru SCLK_RMII_SRC>; + assigned-clock-parents = <&clkin_gmac>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&rgmii_pins>; + pinctrl-1 = <&rgmii_sleep_pins>; + tx_delay = <0x28>; + rx_delay = <0x11>; + status = "disabled"; +}; + +&saradc { + status = "okay"; +}; + +&io_domains { + status = "okay"; + + bt656-supply = <&vcc1v8_s0>; /* bt656_gpio2ab_ms */ + audio-supply = <&vcc1v8_s0>; /* audio_gpio3d4a_ms */ + sdmmc-supply = <&vcc_sd>; /* sdmmc_gpio4b_ms */ + gpio1830-supply = <&vcc_3v0>; /* gpio1833_gpio4cd_ms */ +}; + +&pcie_phy { + status = "okay"; +}; + +&pcie0 { + ep-gpios = <&gpio3 9 GPIO_ACTIVE_HIGH>; + num-lanes = <4>; + pinctrl-names = "default"; + pinctrl-0 = <&pcie_clkreqn_cpm>; + status = "okay"; +}; + +&pinctrl { + + sdio0 { + sdio0_bus1: sdio0-bus1 { + rockchip,pins = + <2 20 RK_FUNC_1 &pcfg_pull_up_20ma>; + }; + + sdio0_bus4: sdio0-bus4 { + rockchip,pins = + <2 20 RK_FUNC_1 &pcfg_pull_up_20ma>, + <2 21 RK_FUNC_1 &pcfg_pull_up_20ma>, + <2 22 RK_FUNC_1 &pcfg_pull_up_20ma>, + <2 23 RK_FUNC_1 &pcfg_pull_up_20ma>; + }; + + sdio0_cmd: sdio0-cmd { + rockchip,pins = + <2 24 RK_FUNC_1 &pcfg_pull_up_20ma>; + }; + + sdio0_clk: sdio0-clk { + rockchip,pins = + <2 25 RK_FUNC_1 &pcfg_pull_none_20ma>; + }; + }; + + sdmmc { + sdmmc_bus1: sdmmc-bus1 { + rockchip,pins = + <4 8 RK_FUNC_1 &pcfg_pull_up_8ma>; + }; + + sdmmc_bus4: sdmmc-bus4 { + rockchip,pins = + <4 8 RK_FUNC_1 &pcfg_pull_up_8ma>, + <4 9 RK_FUNC_1 &pcfg_pull_up_8ma>, + <4 10 RK_FUNC_1 &pcfg_pull_up_8ma>, + <4 11 RK_FUNC_1 &pcfg_pull_up_8ma>; + }; + + sdmmc_clk: sdmmc-clk { + rockchip,pins = + <4 12 RK_FUNC_1 &pcfg_pull_none_18ma>; + }; + + sdmmc_cmd: sdmmc-cmd { + rockchip,pins = + <4 13 RK_FUNC_1 &pcfg_pull_up_8ma>; + }; + }; + + sdio-pwrseq { + wifi_enable_h: wifi-enable-h { + rockchip,pins = + <0 10 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + wireless-bluetooth { + uart0_gpios: uart0-gpios { + rockchip,pins = + <2 19 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + usb2 { + host_vbus_drv: host-vbus-drv { + rockchip,pins = + <4 25 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pcie { + pcie_drv: pcie-drv { + rockchip,pins = + <3 11 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pmic { + pmic_int_l: pmic-int-l { + rockchip,pins = + <1 21 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + vsel1_gpio: vsel1-gpio { + rockchip,pins = + <1 17 RK_FUNC_GPIO &pcfg_pull_down>; + }; + + vsel2_gpio: vsel2-gpio { + rockchip,pins = + <1 14 RK_FUNC_GPIO &pcfg_pull_down>; + }; + }; + + gmac { + rgmii_sleep_pins: rgmii-sleep-pins { + rockchip,pins = + <3 15 RK_FUNC_GPIO &pcfg_output_low>; + }; + }; + + fusb30x { + fusb0_int: fusb0-int { + rockchip,pins = + <1 2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; + +&pvtm { + status = "okay"; +}; + +&pmu_pvtm { + status = "okay"; +}; + +&pmu_io_domains { + status = "okay"; + pmu1830-supply = <&vcc_1v8>; +}; + +&rockchip_suspend { + status = "okay"; + rockchip,sleep-debug-en = <0>; + rockchip,sleep-mode-config = < + (0 + | RKPM_SLP_ARMPD + | RKPM_SLP_PERILPPD + | RKPM_SLP_DDR_RET + | RKPM_SLP_PLLPD + | RKPM_SLP_CENTER_PD + | RKPM_SLP_AP_PWROFF + ) + >; + rockchip,wakeup-config = < + (0 + | RKPM_GPIO_WKUP_EN + | RKPM_PWM_WKUP_EN + ) + >; + rockchip,pwm-regulator-config = < + (0 + | PWM2_REGULATOR_EN + ) + >; + rockchip,power-ctrl = + <&gpio1 17 GPIO_ACTIVE_HIGH>, + <&gpio1 14 GPIO_ACTIVE_HIGH>; +}; + +&vopb { + status = "okay"; +}; + +&vopb_mmu { + status = "okay"; +}; + +&vopl { + status = "okay"; +}; + +&vopl_mmu { + status = "okay"; +}; + +&cif_isp0 { + rockchip,camera-modules-attached = <&camera0>; + status = "okay"; +}; + +&isp0_mmu { + status = "okay"; +}; + +&cif_isp1 { + rockchip,camera-modules-attached = <&camera1>; + status = "disabled"; +}; + +&isp1_mmu { + status = "okay"; +}; + +&vpu { + status = "okay"; + /* 0 means ion, 1 means drm */ + //allocator = <0>; +}; + +&rkvdec { + status = "okay"; + /* 0 means ion, 1 means drm */ + //allocator = <0>; +}; + +&display_subsystem { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-edp.dts b/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-edp.dts index 728b430079c08..98b6f352de776 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-edp.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-edp.dts @@ -193,6 +193,51 @@ pinctrl-0 = <&hdmiin_gpios>; status = "okay"; }; + + ov13850: ov13850@10 { + compatible = "ovti,ov13850"; + status = "disabled"; + reg = <0x10>; + clocks = <&cru SCLK_CIF_OUT>; + clock-names = "xvclk"; + /* avdd-supply = <>; */ + /* dvdd-supply = <>; */ + /* dovdd-supply = <>; */ + /* reset-gpios = <>; */ + reset-gpios = <&gpio2 10 GPIO_ACTIVE_HIGH>; // conflict with csi-ctl-gpios + pwdn-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>; + pinctrl-names = "rockchip,camera_default"; + pinctrl-0 = <&cif_clkout>; + port { + ucam_out0: endpoint { + remote-endpoint = <&mipi_in_ucam0>; + //remote-endpoint = <&mipi_in_ucam1>; + data-lanes = <1 2>; + }; + }; + }; + + ov4689: ov4689@36 { + compatible = "ovti,ov4689"; + status = "disabled"; + reg = <0x36>; + clocks = <&cru SCLK_CIF_OUT>; + clock-names = "xvclk"; + /* avdd-supply = <>; */ + /* dvdd-supply = <>; */ + /* dovdd-supply = <>; */ + /* reset-gpios = <>; */ + pwdn-gpios = <&gpio4 29 GPIO_ACTIVE_HIGH>; // conflict with backlight + pinctrl-names = "rockchip,camera_default"; + pinctrl-0 = <&cif_clkout>; + port { + ucam_out1: endpoint { + //remote-endpoint = <&mipi_in_ucam0>; + remote-endpoint = <&mipi_in_ucam1>; + data-lanes = <1 2>; + }; + }; + }; }; &i2c6 { @@ -229,6 +274,70 @@ status = "okay"; }; +&mipi_dphy_rx0 { + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + mipi_in_ucam0: endpoint@1 { + reg = <1>; + remote-endpoint = <&ucam_out0>; + data-lanes = <1 2>; + }; + }; + + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + dphy_rx0_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&isp0_mipi_in>; + }; + }; + }; +}; + +&mipi_dphy_tx1rx1 { + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + mipi_in_ucam1: endpoint@1 { + reg = <1>; + remote-endpoint = <&ucam_out1>; + data-lanes = <1 2>; + }; + }; + + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + dphy_tx1rx1_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&isp1_mipi_in>; + }; + }; + }; +}; + &vopb { assigned-clocks = <&cru DCLK_VOP0_DIV>; assigned-clock-parents = <&cru PLL_CPLL>; @@ -247,6 +356,34 @@ status = "okay"; }; +&rkisp1_0 { + status = "disabled"; + + port { + #address-cells = <1>; + #size-cells = <0>; + + isp0_mipi_in: endpoint@0 { + reg = <0>; + remote-endpoint = <&dphy_rx0_out>; + }; + }; +}; + +&rkisp1_1 { + status = "disabled"; + + port { + #address-cells = <1>; + #size-cells = <0>; + + isp1_mipi_in: endpoint@0 { + reg = <0>; + remote-endpoint = <&dphy_tx1rx1_out>; + }; + }; +}; + &route_edp { status = "okay"; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-linux.dts b/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-linux.dts index 10a7f4f7a96e1..6bf488add069e 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-linux.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator-linux.dts @@ -141,19 +141,101 @@ }; }; -&cif_isp0 { - rockchip,camera-modules-attached = - <&camera0 &camera1 &camera2 &camera3>; +&rkisp1_0 { status = "okay"; + + port { + #address-cells = <1>; + #size-cells = <0>; + + isp0_mipi_in: endpoint@0 { + reg = <0>; + remote-endpoint = <&dphy_rx0_out>; + }; + }; +}; + +&mipi_dphy_rx0 { + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + mipi_in_ucam0: endpoint@1 { + reg = <1>; + remote-endpoint = <&ucam_out0>; + data-lanes = <1 2>; + }; + }; + + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + dphy_rx0_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&isp0_mipi_in>; + }; + }; + }; }; &isp0_mmu { status = "okay"; }; -&cif_isp1 { - rockchip,camera-modules-attached = <&camera4>; +&rkisp1_1 { status = "okay"; + + port { + #address-cells = <1>; + #size-cells = <0>; + + isp1_mipi_in: endpoint@0 { + reg = <0>; + remote-endpoint = <&dphy_tx1rx1_out>; + }; + }; +}; + +&mipi_dphy_tx1rx1 { + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + mipi_in_ucam1: endpoint@1 { + reg = <1>; + /* Unlinked camera */ + //remote-endpoint = <&ucam_out1>; + data-lanes = <1 2>; + }; + }; + + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + dphy_tx1rx1_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&isp1_mipi_in>; + }; + }; + }; }; &isp1_mmu { @@ -227,158 +309,30 @@ rst_gpio_number = <&gpio4 22 GPIO_ACTIVE_HIGH>; }; - camera0: camera-module@60 { - status = "okay"; - compatible = "ovti,ov7750-v4l2-i2c-subdev"; - reg = < 0x60 >; - device_type = "v4l2-i2c-subdev"; - - clocks = <&cru SCLK_CIF_OUT>; - clock-names = "clk_cif_out"; - - pinctrl-names = "rockchip,camera_default", - "rockchip,camera_sleep"; - pinctrl-0 = <&cam0_default_pins>; - pinctrl-1 = <&cam0_sleep_pins>; - - rockchip,pwr-gpio = <&gpio2 10 GPIO_ACTIVE_HIGH>; - rockchip,camera-module-mclk-name = "clk_cif_out"; - rockchip,camera-module-facing = "back"; - rockchip,camera-module-name = "cmk-cb0695-fv1"; - rockchip,camera-module-len-name = "lg9569a2"; - rockchip,camera-module-fov-h = "133.0"; - rockchip,camera-module-fov-v = "100.1"; - rockchip,camera-module-orientation = <0>; - rockchip,camera-module-iq-flip = <0>; - rockchip,camera-module-iq-mirror = <0>; - rockchip,camera-module-flip = <0>; - rockchip,camera-module-mirror = <0>; - - rockchip,camera-module-defrect0 = <640 480 0 0 640 480>; - rockchip,camera-module-defrect1 = <640 480 0 0 640 480>; - rockchip,camera-module-defrect2 = <640 480 0 0 640 480>; - rockchip,camera-module-defrect3 = <640 480 0 0 640 480>; - rockchip,camera-module-flash-support = <0>; - rockchip,camera-module-mipi-dphy-index = <0>; - }; - - camera1: camera-module@1 { + ov13850: ov13850@10 { + compatible = "ovti,ov13850"; status = "okay"; - compatible = "toshiba,tc358749xbg-v4l2-i2c-subdev"; - reg = < 0x0f >; - device_type = "v4l2-i2c-subdev"; - - clocks = <&cru SCLK_CIF_OUT>; - clock-names = "clk_cif_out"; - - pinctrl-names = "default"; - pinctrl-0 = <&hdmiin_gpios>; - - //rockchip,pwr-gpio = <&gpio2 6 GPIO_ACTIVE_HIGH>; - //rckchip,pwr-snd-gpio = <&gpio2 9 GPIO_ACTIVE_HIGH>; - //rockchip,pwr-trd-gpio = <&gpio2 5 GPIO_ACTIVE_HIGH>; - //rockchip,rst-gpio = <&gpio2 7 GPIO_ACTIVE_HIGH>; - power-gpios = <&gpio2 6 GPIO_ACTIVE_HIGH>; - power18-gpios = <&gpio2 9 GPIO_ACTIVE_HIGH>; - power33-gpios = <&gpio2 5 GPIO_ACTIVE_HIGH>; - csi-ctl-gpios = <&gpio2 10 GPIO_ACTIVE_HIGH>; - stanby-gpios = <&gpio2 8 GPIO_ACTIVE_HIGH>; - reset-gpios = <&gpio2 7 GPIO_ACTIVE_HIGH>; - int-gpios = <&gpio2 12 GPIO_ACTIVE_HIGH>; - - rockchip,camera-module-mclk-name = "clk_cif_out"; - rockchip,camera-module-mipi-dphy-index = <0>; - }; - - camera2: camera-module@10 { - status = "okay"; - compatible = "omnivision,ov13850-v4l2-i2c-subdev"; - reg = < 0x10 >; - device_type = "v4l2-i2c-subdev"; - clocks = <&cru SCLK_CIF_OUT>; - clock-names = "clk_cif_out"; - pinctrl-names = "rockchip,camera_default", - "rockchip,camera_sleep"; - pinctrl-0 = <&cam0_default_pins>; - pinctrl-1 = <&cam0_sleep_pins>; - rockchip,pd-gpio = <&gpio1 4 GPIO_ACTIVE_LOW>; - //rockchip,pwr-gpio = <&gpio2 10 GPIO_ACTIVE_HIGH>; - /* mipi switch control */ - rockchip,rst-gpio = <&gpio2 10 GPIO_ACTIVE_LOW>; - rockchip,camera-module-mclk-name = "clk_cif_out"; - rockchip,camera-module-facing = "back"; - rockchip,camera-module-name = "cmk-cb0695-fv1"; - rockchip,camera-module-len-name = "lg9569a2"; - rockchip,camera-module-fov-h = "66.0"; - rockchip,camera-module-fov-v = "50.1"; - rockchip,camera-module-orientation = <0>; - rockchip,camera-module-iq-flip = <0>; - rockchip,camera-module-iq-mirror = <0>; - rockchip,camera-module-flip = <1>; - rockchip,camera-module-mirror = <0>; - - rockchip,camera-module-defrect0 = <2112 1568 0 0 2112 1568>; - rockchip,camera-module-defrect1 = <4224 3136 0 0 4224 3136>; - rockchip,camera-module-defrect3 = <3264 2448 0 0 3264 2448>; - rockchip,camera-module-flash-support = <1>; - rockchip,camera-module-mipi-dphy-index = <0>; - }; - - camera3: camera-module@36 { - status = "okay"; - compatible = "omnivision,ov4689-v4l2-i2c-subdev"; - reg = <0x36>; - device_type = "v4l2-i2c-subdev"; + reg = <0x10>; clocks = <&cru SCLK_CIF_OUT>; - clock-names = "clk_cif_out"; - pinctrl-names = "rockchip,camera_default", - "rockchip,camera_sleep"; - pinctrl-0 = <&cam0_default_pins>; - pinctrl-1 = <&cam0_sleep_pins>; - rockchip,pd-gpio = <&gpio3 4 GPIO_ACTIVE_LOW>; - //rockchip,pwr-gpio = <&gpio3 13 0>; - /* mipi switch control*/ - rockchip,rst-gpio = <&gpio2 10 GPIO_ACTIVE_LOW>; - rockchip,camera-module-mclk-name = "clk_cif_out"; - rockchip,camera-module-facing = "back"; - rockchip,camera-module-name = "LA6111PA"; - rockchip,camera-module-len-name = "YM6011P"; - rockchip,camera-module-fov-h = "116"; - rockchip,camera-module-fov-v = "61"; - rockchip,camera-module-orientation = <0>; - rockchip,camera-module-iq-flip = <0>; - rockchip,camera-module-iq-mirror = <0>; - rockchip,camera-module-flip = <0>; - rockchip,camera-module-mirror = <1>; - - rockchip,camera-module-defrect0 = <2688 1520 0 0 2688 1520>; - rockchip,camera-module-flash-support = <0>; - rockchip,camera-module-mipi-dphy-index = <0>; + clock-names = "xvclk"; + + /* conflict with csi-ctl-gpios */ + reset-gpios = <&gpio2 10 GPIO_ACTIVE_HIGH>; + pwdn-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>; + pinctrl-names = "rockchip,camera_default"; + pinctrl-0 = <&cif_clkout>; + + port { + ucam_out0: endpoint { + remote-endpoint = <&mipi_in_ucam0>; + data-lanes = <1 2>; + }; + }; }; }; &i2c4 { status = "okay"; - - camera4: camera-module@2 { - status = "okay"; - compatible = "adi,adv7181-v4l2-i2c-subdev"; - reg = < 0x21 >; - device_type = "v4l2-i2c-subdev"; - - clocks = <&cru SCLK_CIF_OUT>; - clock-names = "clk_cif_out"; - - pinctrl-names = "rockchip,camera_default", - "rockchip,camera_sleep"; - pinctrl-0 = <&isp_dvp_d0d7>; - pinctrl-1 = <&cam0_sleep_pins>; - - rockchip,camera-module-defrect0 = <720 480 0 13 720 480>; - rockchip,camera-module-defrect1 = <720 576 0 0 720 576>; - rockchip,camera-module-mclk-name = "clk_cif_out"; - rockchip,camera-module-mipi-dphy-index = <1>; - }; }; &pcie_phy { diff --git a/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi index 8276ef1a72ee0..3d76b9733665e 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-sapphire.dtsi @@ -188,7 +188,7 @@ /* for rockchip boot on */ rockchip,pwm_id= <2>; - rockchip,pwm_voltage = <1000000>; + rockchip,pwm_voltage = <900000>; }; xin32k: xin32k { diff --git a/arch/arm64/boot/dts/rockchip/rk3399-tve1030g.dts b/arch/arm64/boot/dts/rockchip/rk3399-tve1030g.dts index 610fb1973477f..ebf7a8f238778 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-tve1030g.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-tve1030g.dts @@ -140,7 +140,7 @@ compatible = "pwm-regulator"; pwms = <&pwm2 0 25000 1>; rockchip,pwm_id= <2>; - rockchip,pwm_voltage = <1000000>; + rockchip,pwm_voltage = <900000>; regulator-name = "vdd_log"; regulator-min-microvolt = <750000>; regulator-max-microvolt = <1350000>; @@ -220,11 +220,11 @@ SYS_STATUS_NORMAL 800000 SYS_STATUS_REBOOT 400000 SYS_STATUS_SUSPEND 400000 - SYS_STATUS_VIDEO_1080P 400000 + SYS_STATUS_VIDEO_1080P 800000 SYS_STATUS_VIDEO_4K 800000 SYS_STATUS_VIDEO_4K_10B 800000 SYS_STATUS_PERFORMANCE 800000 - SYS_STATUS_BOOST 400000 + SYS_STATUS_BOOST 800000 SYS_STATUS_DUALVIEW 800000 SYS_STATUS_ISP 800000 >; @@ -292,6 +292,10 @@ pinctrl-names = "default"; pinctrl-0 = <&lcd_rst_gpio>; reset-delay-ms = <60>; + enable-delay-ms = <60>; + prepare-delay-ms = <60>; + unprepare-delay-ms = <60>; + disable-delay-ms = <60>; dsi,flags = <(MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_EOT_PACKET)>; dsi,format = ; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-tve1205g.dts b/arch/arm64/boot/dts/rockchip/rk3399-tve1205g.dts index 89985cf75361f..08b6444fbbd1c 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-tve1205g.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-tve1205g.dts @@ -107,7 +107,7 @@ compatible = "pwm-regulator"; pwms = <&pwm2 0 25000 1>; rockchip,pwm_id= <2>; - rockchip,pwm_voltage = <1000000>; + rockchip,pwm_voltage = <900000>; regulator-name = "vdd_log"; regulator-min-microvolt = <750000>; regulator-max-microvolt = <1350000>; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-vop-clk-set.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-vop-clk-set.dtsi index 14ff440843cb7..f13985cf8b6dd 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-vop-clk-set.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-vop-clk-set.dtsi @@ -151,7 +151,7 @@ <600000000>, <200000000>, <800000000>, <150000000>, <75000000>, <37500000>, - <100000000>, <100000000>, + <300000000>, <100000000>, <50000000>, <100000000>, <50000000>, <100000000>, <100000000>, <100000000>, diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi index 7e2f455156224..815a8c1312393 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi @@ -116,9 +116,9 @@ reg = <0x0 0x0>; enable-method = "psci"; #cooling-cells = <2>; /* min followed by max */ - dynamic-power-coefficient = <100>; clocks = <&cru ARMCLKL>; cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>; + dynamic-power-coefficient = <100>; }; cpu_l1: cpu@1 { @@ -128,6 +128,7 @@ enable-method = "psci"; clocks = <&cru ARMCLKL>; cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>; + dynamic-power-coefficient = <100>; }; cpu_l2: cpu@2 { @@ -137,6 +138,7 @@ enable-method = "psci"; clocks = <&cru ARMCLKL>; cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>; + dynamic-power-coefficient = <100>; }; cpu_l3: cpu@3 { @@ -146,6 +148,7 @@ enable-method = "psci"; clocks = <&cru ARMCLKL>; cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>; + dynamic-power-coefficient = <100>; }; cpu_b0: cpu@100 { @@ -154,9 +157,9 @@ reg = <0x0 0x100>; enable-method = "psci"; #cooling-cells = <2>; /* min followed by max */ - dynamic-power-coefficient = <436>; clocks = <&cru ARMCLKB>; cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>; + dynamic-power-coefficient = <436>; }; cpu_b1: cpu@101 { @@ -166,6 +169,7 @@ enable-method = "psci"; clocks = <&cru ARMCLKB>; cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>; + dynamic-power-coefficient = <436>; }; idle-states { @@ -212,6 +216,7 @@ , , ; + arm,no-tick-in-suspend; }; xin24m: xin24m { @@ -236,7 +241,7 @@ }; amba { - compatible = "arm,amba-bus"; + compatible = "simple-bus"; #address-cells = <2>; #size-cells = <2>; ranges; @@ -267,7 +272,6 @@ gmac: ethernet@fe300000 { compatible = "rockchip,rk3399-gmac"; reg = <0x0 0xfe300000 0x0 0x10000>; - rockchip,grf = <&grf>; interrupts = ; interrupt-names = "macirq"; clocks = <&cru SCLK_MAC>, <&cru SCLK_MAC_RX>, @@ -278,9 +282,10 @@ "mac_clk_tx", "clk_mac_ref", "clk_mac_refout", "aclk_mac", "pclk_mac"; + power-domains = <&power RK3399_PD_GMAC>; resets = <&cru SRST_A_GMAC>; reset-names = "stmmaceth"; - power-domains = <&power RK3399_PD_GMAC>; + rockchip,grf = <&grf>; status = "disabled"; }; @@ -289,12 +294,14 @@ "rockchip,rk3288-dw-mshc"; reg = <0x0 0xfe310000 0x0 0x4000>; interrupts = ; - clock-freq-min-max = <400000 150000000>; + max-frequency = <150000000>; clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>, <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>; clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; fifo-depth = <0x100>; power-domains = <&power RK3399_PD_SDIOAUDIO>; + resets = <&cru SRST_SDIO0>; + reset-names = "reset"; status = "disabled"; }; @@ -303,12 +310,16 @@ "rockchip,rk3288-dw-mshc"; reg = <0x0 0xfe320000 0x0 0x4000>; interrupts = ; - clock-freq-min-max = <400000 150000000>; + max-frequency = <150000000>; + assigned-clocks = <&cru HCLK_SD>; + assigned-clock-rates = <200000000>; 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>; power-domains = <&power RK3399_PD_SD>; + resets = <&cru SRST_SDMMC>; + reset-names = "reset"; status = "disabled"; }; @@ -329,6 +340,17 @@ status = "disabled"; }; + usic: usb@fe340000 { + compatible = "generic-ehci"; + reg = <0x0 0xfe340000 0x0 0x30000>; + interrupts = ; + clocks = <&cru HCLK_HSIC>, <&cru SCLK_HSICPHY>, + <&cru PCLK_HSICPHY>; + clock-names = "hclk_hsic", "clk_hsicphy", "pclk_hsicphy"; + rockchip-has-usic; + status = "disabled"; + }; + usb_host0_ehci: usb@fe380000 { compatible = "generic-ehci"; reg = <0x0 0xfe380000 0x0 0x20000>; @@ -381,7 +403,7 @@ status = "disabled"; }; - usbdrd3_0: usb@fe800000 { + usbdrd3_0: usb0 { compatible = "rockchip,rk3399-dwc3"; clocks = <&cru SCLK_USB3OTG0_REF>, <&cru SCLK_USB3OTG0_SUSPEND>, <&cru ACLK_USB3OTG0>, <&cru ACLK_USB3_GRF>; @@ -394,6 +416,7 @@ #size-cells = <2>; ranges; status = "disabled"; + usbdrd_dwc3_0: dwc3@fe800000 { compatible = "snps,dwc3"; reg = <0x0 0xfe800000 0x0 0x100000>; @@ -413,7 +436,7 @@ }; }; - usbdrd3_1: usb@fe900000 { + usbdrd3_1: usb1 { compatible = "rockchip,rk3399-dwc3"; clocks = <&cru SCLK_USB3OTG1_REF>, <&cru SCLK_USB3OTG1_SUSPEND>, <&cru ACLK_USB3OTG1>, <&cru ACLK_USB3_GRF>; @@ -426,6 +449,7 @@ #size-cells = <2>; ranges; status = "disabled"; + usbdrd_dwc3_1: dwc3@fe900000 { compatible = "snps,dwc3"; reg = <0x0 0xfe900000 0x0 0x100000>; @@ -449,11 +473,11 @@ compatible = "rockchip,rk3399-cdn-dp"; reg = <0x0 0xfec00000 0x0 0x100000>; interrupts = ; + assigned-clocks = <&cru SCLK_DP_CORE>, <&cru SCLK_SPDIF_REC_DPTX>; + assigned-clock-rates = <100000000>, <200000000>; clocks = <&cru SCLK_DP_CORE>, <&cru PCLK_DP_CTRL>, <&cru SCLK_SPDIF_REC_DPTX>, <&cru PCLK_VIO_GRF>; clock-names = "core-clk", "pclk", "spdif", "grf"; - assigned-clocks = <&cru SCLK_DP_CORE>; - assigned-clock-rates = <100000000>; power-domains = <&power RK3399_PD_HDCP>; phys = <&tcphy0_dp>, <&tcphy1_dp>; resets = <&cru SRST_DPTX_SPDIF_REC>, <&cru SRST_P_UPHY0_DPTX>, @@ -796,19 +820,19 @@ compatible = "rockchip,rk3399-tsadc"; reg = <0x0 0xff260000 0x0 0x100>; interrupts = ; - rockchip,grf = <&grf>; - clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>; - clock-names = "tsadc", "apb_pclk"; assigned-clocks = <&cru SCLK_TSADC>; assigned-clock-rates = <750000>; + clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>; + clock-names = "tsadc", "apb_pclk"; resets = <&cru SRST_TSADC>; reset-names = "tsadc-apb"; + rockchip,grf = <&grf>; + rockchip,hw-tshut-temp = <120000>; pinctrl-names = "init", "default", "sleep"; pinctrl-0 = <&otp_gpio>; pinctrl-1 = <&otp_out>; pinctrl-2 = <&otp_gpio>; #thermal-sensor-cells = <1>; - rockchip,hw-tshut-temp = <120000>; status = "disabled"; }; @@ -1424,10 +1448,10 @@ clock-names = "pclk_efuse"; /* Data cells */ - efuse_id: id@7 { + cpu_id: cpu-id@7 { reg = <0x07 0x10>; }; - cpub_leakage: cpub-leakage@17 { + cpub_leakage: cpu-leakage@17 { reg = <0x17 0x1>; }; gpu_leakage: gpu-leakage@18 { @@ -1436,7 +1460,7 @@ center_leakage: center-leakage@19 { reg = <0x19 0x1>; }; - cpul_leakage: cpul-leakage@1a { + cpul_leakage: cpu-leakage@1a { reg = <0x1a 0x1>; }; logic_leakage: logic-leakage@1b { @@ -1470,8 +1494,11 @@ <&cru ACLK_PERIHP>, <&cru HCLK_PERIHP>, <&cru PCLK_PERIHP>, <&cru ACLK_PERILP0>, <&cru HCLK_PERILP0>, - <&cru PCLK_PERILP0>, - <&cru HCLK_PERILP1>, <&cru PCLK_PERILP1>; + <&cru PCLK_PERILP0>, <&cru ACLK_CCI>, + <&cru HCLK_PERILP1>, <&cru PCLK_PERILP1>, + <&cru ACLK_VIO>, <&cru ACLK_HDCP>, + <&cru ACLK_GIC_PRE>, + <&cru PCLK_DDR>; assigned-clock-rates = <400000000>, <200000000>, <400000000>, <200000000>, @@ -1481,8 +1508,11 @@ <150000000>, <75000000>, <37500000>, <100000000>, <100000000>, - <50000000>, - <100000000>, <50000000>; + <50000000>, <600000000>, + <100000000>, <50000000>, + <400000000>, <400000000>, + <200000000>, + <200000000>; }; grf: syscon@ff770000 { @@ -1496,15 +1526,6 @@ status = "disabled"; }; - emmc_phy: phy@f780 { - compatible = "rockchip,rk3399-emmc-phy"; - reg = <0xf780 0x24>; - clocks = <&sdhci>; - clock-names = "emmcclk"; - #phy-cells = <0>; - status = "disabled"; - }; - u2phy0: usb2-phy@e450 { compatible = "rockchip,rk3399-usb2phy"; reg = <0xe450 0x10>; @@ -1514,6 +1535,13 @@ clock-output-names = "clk_usbphy0_480m"; status = "disabled"; + u2phy0_host: host-port { + #phy-cells = <0>; + interrupts = ; + interrupt-names = "linestate"; + status = "disabled"; + }; + u2phy0_otg: otg-port { #phy-cells = <0>; interrupts = , @@ -1523,13 +1551,6 @@ "linestate"; status = "disabled"; }; - - u2phy0_host: host-port { - #phy-cells = <0>; - interrupts = ; - interrupt-names = "linestate"; - status = "disabled"; - }; }; u2phy1: usb2-phy@e460 { @@ -1541,6 +1562,13 @@ clock-output-names = "clk_usbphy1_480m"; status = "disabled"; + u2phy1_host: host-port { + #phy-cells = <0>; + interrupts = ; + interrupt-names = "linestate"; + status = "disabled"; + }; + u2phy1_otg: otg-port { #phy-cells = <0>; interrupts = , @@ -1550,13 +1578,15 @@ "linestate"; status = "disabled"; }; + }; - u2phy1_host: host-port { - #phy-cells = <0>; - interrupts = ; - interrupt-names = "linestate"; - status = "disabled"; - }; + emmc_phy: phy@f780 { + compatible = "rockchip,rk3399-emmc-phy"; + reg = <0xf780 0x24>; + clocks = <&sdhci>; + clock-names = "emmcclk"; + #phy-cells = <0>; + status = "disabled"; }; mipi_dphy_rx0: mipi-dphy-rx0 { @@ -1588,7 +1618,6 @@ tcphy0: phy@ff7c0000 { compatible = "rockchip,rk3399-typec-phy"; reg = <0x0 0xff7c0000 0x0 0x40000>; - rockchip,grf = <&grf>; #phy-cells = <1>; clocks = <&cru SCLK_UPHY0_TCPDCORE>, <&cru SCLK_UPHY0_TCPDPHY_REF>; @@ -1600,6 +1629,7 @@ <&cru SRST_UPHY0_PIPE_L00>, <&cru SRST_P_UPHY0_TCPHY>; reset-names = "uphy", "uphy-pipe", "uphy-tcphy"; + rockchip,grf = <&grf>; rockchip,typec-conn-dir = <0xe580 0 16>; rockchip,usb3tousb2-en = <0xe580 3 19>; rockchip,usb3-host-disable = <0x2434 0 16>; @@ -1621,7 +1651,6 @@ tcphy1: phy@ff800000 { compatible = "rockchip,rk3399-typec-phy"; reg = <0x0 0xff800000 0x0 0x40000>; - rockchip,grf = <&grf>; #phy-cells = <1>; clocks = <&cru SCLK_UPHY1_TCPDCORE>, <&cru SCLK_UPHY1_TCPDPHY_REF>; @@ -1633,6 +1662,7 @@ <&cru SRST_UPHY1_PIPE_L00>, <&cru SRST_P_UPHY1_TCPHY>; reset-names = "uphy", "uphy-pipe", "uphy-tcphy"; + rockchip,grf = <&grf>; rockchip,typec-conn-dir = <0xe58c 0 16>; rockchip,usb3tousb2-en = <0xe58c 3 19>; rockchip,usb3-host-disable = <0x2444 0 16>; @@ -1759,10 +1789,10 @@ interrupts = ; clocks = <&cru ACLK_VOP1>, <&cru DCLK_VOP1>, <&cru HCLK_VOP1>, <&cru DCLK_VOP1_DIV>; clock-names = "aclk_vop", "dclk_vop", "hclk_vop", "dclk_source"; + iommus = <&vopl_mmu>; + power-domains = <&power RK3399_PD_VOPL>; resets = <&cru SRST_A_VOP1>, <&cru SRST_H_VOP1>, <&cru SRST_D_VOP1>; reset-names = "axi", "ahb", "dclk"; - power-domains = <&power RK3399_PD_VOPL>; - iommus = <&vopl_mmu>; status = "disabled"; vopl_out: port { @@ -1910,7 +1940,7 @@ interrupts = ; interrupt-names = "isp0_mmu"; #iommu-cells = <0>; - clocks = <&cru ACLK_ISP0_NOC>, <&cru HCLK_ISP0_NOC>; + clocks = <&cru ACLK_ISP0_WRAPPER>, <&cru HCLK_ISP0_WRAPPER>; clock-names = "aclk", "hclk"; power-domains = <&power RK3399_PD_ISP0>; rk_iommu,disable_reset_quirk; @@ -1923,10 +1953,12 @@ interrupts = ; clocks = <&cru SCLK_ISP1>, <&cru ACLK_ISP1>, <&cru HCLK_ISP1>, - <&cru ACLK_ISP1_WRAPPER>, <&cru HCLK_ISP1_WRAPPER>; + <&cru ACLK_ISP1_WRAPPER>, <&cru HCLK_ISP1_WRAPPER>, + <&cru PCLK_ISP1_WRAPPER>; clock-names = "clk_isp", "aclk_isp", "hclk_isp", - "aclk_isp_wrap", "hclk_isp_wrap"; + "aclk_isp_wrap", "hclk_isp_wrap", + "pclk_isp_wrap"; devfreq = <&dmc>; power-domains = <&power RK3399_PD_ISP1>; iommus = <&isp1_mmu>; @@ -1939,7 +1971,7 @@ interrupts = ; interrupt-names = "isp1_mmu"; #iommu-cells = <0>; - clocks = <&cru ACLK_ISP1_NOC>, <&cru HCLK_ISP1_NOC>; + clocks = <&cru ACLK_ISP1_WRAPPER>, <&cru HCLK_ISP1_WRAPPER>; clock-names = "aclk", "hclk"; power-domains = <&power RK3399_PD_ISP1>; rk_iommu,disable_reset_quirk; @@ -1949,16 +1981,18 @@ hdmi: hdmi@ff940000 { compatible = "rockchip,rk3399-dw-hdmi"; reg = <0x0 0xff940000 0x0 0x20000>; - reg-io-width = <4>; - rockchip,grf = <&grf>; pinctrl-names = "default"; - pinctrl-0 = <&hdmi_i2c_xfer>, <&hdmi_cec>; - power-domains = <&power RK3399_PD_HDCP>; + pinctrl-0 = <&hdmi_i2c_xfer>; interrupts = ; - clocks = <&cru PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_SFR>, - <&cru PLL_VPLL>, <&cru PCLK_VIO_GRF>, + clocks = <&cru PCLK_HDMI_CTRL>, + <&cru SCLK_HDMI_SFR>, + <&cru PLL_VPLL>, + <&cru PCLK_VIO_GRF>, <&cru SCLK_HDMI_CEC>; clock-names = "iahb", "isfr", "vpll", "grf", "cec"; + power-domains = <&power RK3399_PD_HDCP>; + reg-io-width = <4>; + rockchip,grf = <&grf>; status = "disabled"; ports { @@ -1984,13 +2018,13 @@ clocks = <&cru SCLK_DPHY_PLL>, <&cru PCLK_MIPI_DSI0>, <&cru SCLK_DPHY_TX0_CFG>; clock-names = "ref", "pclk", "phy_cfg"; + power-domains = <&power RK3399_PD_VIO>; resets = <&cru SRST_P_MIPI_DSI0>; reset-names = "apb"; - power-domains = <&power RK3399_PD_VIO>; rockchip,grf = <&grf>; + status = "disabled"; #address-cells = <1>; #size-cells = <0>; - status = "disabled"; ports { port { @@ -2017,13 +2051,13 @@ clocks = <&cru SCLK_DPHY_PLL>, <&cru PCLK_MIPI_DSI1>, <&cru SCLK_DPHY_TX1RX1_CFG>; clock-names = "ref", "pclk", "phy_cfg"; + power-domains = <&power RK3399_PD_VIO>; resets = <&cru SRST_P_MIPI_DSI1>; reset-names = "apb"; - power-domains = <&power RK3399_PD_VIO>; rockchip,grf = <&grf>; + status = "disabled"; #address-cells = <1>; #size-cells = <0>; - status = "disabled"; ports { port { @@ -2043,6 +2077,20 @@ }; }; + mipi_dphy_tx1rx1: mipi-dphy-tx1rx1@ff968000 { + compatible = "rockchip,rk3399-mipi-dphy"; + reg = <0x0 0xff968000 0x0 0x8000>; + clocks = <&cru SCLK_MIPIDPHY_REF>, + <&cru SCLK_DPHY_TX1RX1_CFG>, + <&cru PCLK_VIO_GRF>, + <&cru PCLK_MIPI_DSI1>; + clock-names = "dphy-ref", "dphy-cfg", + "grf", "pclk_mipi_dsi"; + rockchip,grf = <&grf>; + power-domains = <&power RK3399_PD_VIO>; + status = "disabled"; + }; + edp: edp@ff970000 { compatible = "rockchip,rk3399-edp"; reg = <0x0 0xff970000 0x0 0x8000>; @@ -2172,8 +2220,8 @@ compatible = "rockchip,rk3399-pinctrl"; rockchip,grf = <&grf>; rockchip,pmu = <&pmugrf>; - #address-cells = <0x2>; - #size-cells = <0x2>; + #address-cells = <2>; + #size-cells = <2>; ranges; gpio0: gpio0@ff720000 { diff --git a/arch/arm64/configs/px30_linux_defconfig b/arch/arm64/configs/px30_linux_defconfig new file mode 100644 index 0000000000000..9b31b5d1814a2 --- /dev/null +++ b/arch/arm64/configs/px30_linux_defconfig @@ -0,0 +1,517 @@ +CONFIG_DEFAULT_HOSTNAME="localhost" +CONFIG_SYSVIPC=y +CONFIG_FHANDLE=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_LOG_BUF_SHIFT=18 +CONFIG_CGROUPS=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CPUSETS=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_CGROUP_SCHED=y +CONFIG_CFS_BANDWIDTH=y +CONFIG_NAMESPACES=y +CONFIG_USER_NS=y +CONFIG_DEFAULT_USE_ENERGY_AWARE=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_EMBEDDED=y +# CONFIG_COMPAT_BRK is not set +CONFIG_PROFILING=y +CONFIG_MODULES=y +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_ARCH_ROCKCHIP=y +CONFIG_PCI=y +CONFIG_PCI_MSI=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCIEASPM_POWERSAVE=y +# CONFIG_ARM64_ERRATUM_826319 is not set +# CONFIG_ARM64_ERRATUM_827319 is not set +# CONFIG_ARM64_ERRATUM_824069 is not set +# CONFIG_ARM64_ERRATUM_819472 is not set +# CONFIG_ARM64_ERRATUM_832075 is not set +# CONFIG_CAVIUM_ERRATUM_22375 is not set +# CONFIG_CAVIUM_ERRATUM_23154 is not set +CONFIG_SCHED_MC=y +CONFIG_NR_CPUS=8 +CONFIG_PREEMPT_VOLUNTARY=y +CONFIG_HZ_1000=y +# CONFIG_COMPACTION is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=32768 +CONFIG_ZSMALLOC=y +CONFIG_SECCOMP=y +CONFIG_ARMV8_DEPRECATED=y +CONFIG_SWP_EMULATION=y +CONFIG_CP15_BARRIER_EMULATION=y +CONFIG_SETEND_EMULATION=y +# CONFIG_EFI is not set +CONFIG_COMPAT=y +CONFIG_PM_DEBUG=y +CONFIG_PM_ADVANCED_DEBUG=y +CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y +CONFIG_CPU_IDLE=y +CONFIG_ARM_CPUIDLE=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPUFREQ_DT=y +CONFIG_ARM_ROCKCHIP_CPUFREQ=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_XFRM_USER=y +CONFIG_NET_KEY=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MROUTE=y +CONFIG_SYN_COOKIES=y +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_DIAG is not set +# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET6_XFRM_MODE_TUNNEL is not set +# CONFIG_INET6_XFRM_MODE_BEET is not set +# CONFIG_IPV6_SIT is not set +# CONFIG_ANDROID_PARANOID_NETWORK is not set +CONFIG_BT=y +CONFIG_BT_RFCOMM=y +CONFIG_BT_HIDP=y +CONFIG_BT_HCIBTUSB=y +CONFIG_BT_HCIUART=y +CONFIG_BT_HCIUART_ATH3K=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIBFUSB=y +CONFIG_BT_HCIVHCI=y +CONFIG_BT_MRVL=y +CONFIG_BT_MRVL_SDIO=y +CONFIG_NL80211_TESTMODE=y +CONFIG_CFG80211_DEBUGFS=y +CONFIG_CFG80211_WEXT=y +CONFIG_MAC80211_LEDS=y +CONFIG_MAC80211_DEBUGFS=y +CONFIG_MAC80211_DEBUG_MENU=y +CONFIG_MAC80211_VERBOSE_DEBUG=y +CONFIG_RFKILL=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_DEBUG_DEVRES=y +CONFIG_CONNECTOR=y +CONFIG_ZRAM=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=1 +CONFIG_BLK_DEV_NVME=y +CONFIG_ROCKCHIP_SCR=y +CONFIG_SRAM=y +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_BLK_DEV_SR=y +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_SPI_ATTRS=y +CONFIG_MD=y +CONFIG_NETDEVICES=y +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_VENDOR_ADAPTEC is not set +# CONFIG_NET_VENDOR_AGERE is not set +# CONFIG_NET_VENDOR_ALTEON is not set +# CONFIG_NET_VENDOR_AMD is not set +# CONFIG_NET_VENDOR_ARC is not set +# CONFIG_NET_VENDOR_ATHEROS is not set +# CONFIG_NET_CADENCE is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_BROCADE is not set +# CONFIG_NET_VENDOR_CAVIUM is not set +# CONFIG_NET_VENDOR_CHELSIO is not set +# CONFIG_NET_VENDOR_CISCO is not set +# CONFIG_NET_VENDOR_DEC is not set +# CONFIG_NET_VENDOR_DLINK is not set +# CONFIG_NET_VENDOR_EMULEX is not set +# CONFIG_NET_VENDOR_EZCHIP is not set +# CONFIG_NET_VENDOR_EXAR is not set +# CONFIG_NET_VENDOR_HISILICON is not set +# CONFIG_NET_VENDOR_HP is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MELLANOX is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MICROCHIP is not set +# CONFIG_NET_VENDOR_MYRI is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_NVIDIA is not set +# CONFIG_NET_VENDOR_OKI is not set +# CONFIG_NET_PACKET_ENGINE is not set +# CONFIG_NET_VENDOR_QLOGIC is not set +# CONFIG_NET_VENDOR_QUALCOMM is not set +# CONFIG_NET_VENDOR_REALTEK is not set +# CONFIG_NET_VENDOR_RENESAS is not set +# CONFIG_NET_VENDOR_RDC is not set +# CONFIG_NET_VENDOR_ROCKER is not set +# CONFIG_NET_VENDOR_SAMSUNG is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SILAN is not set +# CONFIG_NET_VENDOR_SIS is not set +# CONFIG_NET_VENDOR_SMSC is not set +CONFIG_STMMAC_ETH=y +# CONFIG_DWMAC_GENERIC is not set +# CONFIG_NET_VENDOR_SUN is not set +# CONFIG_NET_VENDOR_SYNOPSYS is not set +# CONFIG_NET_VENDOR_TEHUTI is not set +# CONFIG_NET_VENDOR_TI is not set +# CONFIG_NET_VENDOR_VIA is not set +# CONFIG_NET_VENDOR_WIZNET is not set +CONFIG_ROCKCHIP_PHY=y +CONFIG_USB_RTL8150=y +CONFIG_USB_RTL8152=y +CONFIG_USB_NET_CDC_MBIM=y +# CONFIG_USB_NET_NET1080 is not set +# CONFIG_USB_NET_CDC_SUBSET is not set +# CONFIG_USB_NET_ZAURUS is not set +CONFIG_LIBERTAS_THINFIRM=y +CONFIG_USB_NET_RNDIS_WLAN=y +CONFIG_WL_ROCKCHIP=y +CONFIG_WIFI_LOAD_DRIVER_WHEN_KERNEL_BOOTUP=y +CONFIG_AP6XXX=y +CONFIG_RTL8188EU=y +CONFIG_MWIFIEX=y +CONFIG_MWIFIEX_SDIO=y +CONFIG_INPUT_FF_MEMLESS=y +# CONFIG_INPUT_MOUSEDEV is not set +CONFIG_INPUT_EVDEV=y +CONFIG_KEYBOARD_ADC=y +# CONFIG_KEYBOARD_ATKBD is not set +CONFIG_KEYBOARD_GPIO=y +CONFIG_KEYBOARD_GPIO_POLLED=y +CONFIG_KEYBOARD_ROCKCHIP=y +CONFIG_KEYBOARD_CROS_EC=y +# CONFIG_MOUSE_PS2 is not set +CONFIG_MOUSE_CYAPA=y +CONFIG_MOUSE_ELAN_I2C=y +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_TOUCHSCREEN_ATMEL_MXT=y +CONFIG_TOUCHSCREEN_GSLX680_VR=y +CONFIG_TOUCHSCREEN_GSL3673=y +CONFIG_TOUCHSCREEN_GT9XX=y +CONFIG_TOUCHSCREEN_ELAN=y +CONFIG_TOUCHSCREEN_USB_COMPOSITE=y +CONFIG_TOUCHSCREEN_GT1X=y +CONFIG_ROCKCHIP_REMOTECTL=y +CONFIG_ROCKCHIP_REMOTECTL_PWM=y +CONFIG_INPUT_MISC=y +CONFIG_INPUT_RK8XX_PWRKEY=y +CONFIG_INPUT_UINPUT=y +CONFIG_INPUT_GPIO=y +# CONFIG_SERIO is not set +CONFIG_DEVPTS_MULTIPLE_INSTANCES=y +# CONFIG_LEGACY_PTYS is not set +# CONFIG_DEVKMEM is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_PCI is not set +CONFIG_SERIAL_8250_NR_UARTS=5 +CONFIG_SERIAL_8250_RUNTIME_UARTS=5 +CONFIG_SERIAL_8250_DW=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_HW_RANDOM=y +CONFIG_TCG_TPM=y +CONFIG_TCG_TIS_I2C_INFINEON=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MUX=y +CONFIG_I2C_RK3X=y +CONFIG_I2C_CROS_EC_TUNNEL=y +CONFIG_SPI=y +CONFIG_SPI_BITBANG=y +CONFIG_SPI_ROCKCHIP=y +CONFIG_SPI_SPIDEV=y +CONFIG_DEBUG_GPIO=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_GENERIC_PLATFORM=y +CONFIG_GPIO_RK8XX=y +CONFIG_BATTERY_SBS=y +CONFIG_CHARGER_GPIO=y +CONFIG_CHARGER_BQ24735=y +CONFIG_BATTERY_RK817=y +CONFIG_CHARGER_RK817=y +CONFIG_POWER_RESET_GPIO=y +CONFIG_POWER_RESET_GPIO_RESTART=y +CONFIG_SYSCON_REBOOT_MODE=y +CONFIG_POWER_AVS=y +CONFIG_ROCKCHIP_IODOMAIN=y +CONFIG_THERMAL=y +CONFIG_THERMAL_WRITABLE_TRIPS=y +CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR=y +CONFIG_THERMAL_GOV_FAIR_SHARE=y +CONFIG_THERMAL_GOV_STEP_WISE=y +CONFIG_CPU_THERMAL=y +CONFIG_DEVFREQ_THERMAL=y +CONFIG_ROCKCHIP_THERMAL=y +CONFIG_WATCHDOG=y +CONFIG_DW_WATCHDOG=y +CONFIG_MFD_CROS_EC=y +CONFIG_MFD_CROS_EC_SPI=y +CONFIG_MFD_RK808=y +CONFIG_MFD_TPS6586X=y +CONFIG_FUSB_30X=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_DEBUG=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_ACT8865=y +CONFIG_REGULATOR_FAN53555=y +CONFIG_REGULATOR_GPIO=y +CONFIG_REGULATOR_LP8752=y +CONFIG_REGULATOR_MP8865=y +CONFIG_REGULATOR_PWM=y +CONFIG_REGULATOR_RK808=y +CONFIG_REGULATOR_RK818=y +CONFIG_REGULATOR_TPS6586X=y +CONFIG_REGULATOR_XZ3216=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_RC_SUPPORT=y +CONFIG_MEDIA_CONTROLLER=y +CONFIG_VIDEO_V4L2_SUBDEV_API=y +# CONFIG_IR_RC5_DECODER is not set +# CONFIG_IR_RC6_DECODER is not set +# CONFIG_IR_JVC_DECODER is not set +# CONFIG_IR_SONY_DECODER is not set +# CONFIG_IR_SANYO_DECODER is not set +# CONFIG_IR_SHARP_DECODER is not set +# CONFIG_IR_MCE_KBD_DECODER is not set +# CONFIG_IR_XMP_DECODER is not set +CONFIG_MEDIA_USB_SUPPORT=y +CONFIG_USB_VIDEO_CLASS=y +# CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV is not set +# CONFIG_USB_GSPCA is not set +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_SOC_CAMERA=y +CONFIG_VIDEO_ROCKCHIP_ISP1=y +CONFIG_V4L_MEM2MEM_DRIVERS=y +CONFIG_VIDEO_ROCKCHIP_RGA=y +# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set +# CONFIG_VIDEO_IR_I2C is not set +CONFIG_VIDEO_OV5695=y +# CONFIG_DVB_AU8522_V4L is not set +# CONFIG_DVB_TUNER_DIB0070 is not set +# CONFIG_DVB_TUNER_DIB0090 is not set +# CONFIG_VGA_ARB is not set +CONFIG_DRM=y +CONFIG_DRM_LOAD_EDID_FIRMWARE=y +CONFIG_DRM_DMA_SYNC=y +CONFIG_DRM_ROCKCHIP=y +CONFIG_ROCKCHIP_DW_MIPI_DSI=y +CONFIG_ROCKCHIP_ANALOGIX_DP=y +CONFIG_ROCKCHIP_LVDS=y +CONFIG_ROCKCHIP_DRM_TVE=y +CONFIG_DRM_PANEL_SIMPLE=y +CONFIG_MALI_PWRSOFT_765=y +CONFIG_MALI_BIFROST_FOR_LINUX=y +CONFIG_MALI_BIFROST=y +CONFIG_MALI_BIFROST_DEVFREQ=y +CONFIG_MALI_PLATFORM_NAME="rk" +CONFIG_MALI_BIFROST_EXPERT=y +CONFIG_MALI_BIFROST_DEBUG=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +# CONFIG_LCD_CLASS_DEVICE is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_PWM=y +CONFIG_RK_VCODEC=y +CONFIG_ROCKCHIP_MPP_SERVICE=y +CONFIG_ROCKCHIP_MPP_DEVICE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_SEQUENCER=y +CONFIG_SND_SEQ_DUMMY=y +CONFIG_SND_HRTIMER=y +CONFIG_SND_DYNAMIC_MINORS=y +# CONFIG_SND_SUPPORT_OLD_API is not set +# CONFIG_SND_PROC_FS is not set +# CONFIG_SND_PCI is not set +# CONFIG_SND_SPI is not set +CONFIG_SND_USB_AUDIO=y +CONFIG_SND_SOC=y +CONFIG_SND_SOC_ROCKCHIP=y +CONFIG_SND_SOC_ROCKCHIP_SPDIF=y +CONFIG_SND_SOC_ROCKCHIP_MAX98090=y +CONFIG_SND_SOC_ROCKCHIP_RT5645=y +CONFIG_SND_SOC_ES8316=y +CONFIG_SND_SOC_RK817=y +CONFIG_SND_SOC_RT5616=y +CONFIG_SND_SOC_RT5640=y +CONFIG_SND_SOC_RT5651=y +CONFIG_SND_SOC_SPDIF=y +CONFIG_SND_SIMPLE_CARD=y +CONFIG_HID_BATTERY_STRENGTH=y +CONFIG_HIDRAW=y +CONFIG_UHID=y +CONFIG_HID_KENSINGTON=y +CONFIG_HID_MULTITOUCH=y +CONFIG_USB_HIDDEV=y +CONFIG_I2C_HID=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +# CONFIG_USB_DEFAULT_PERSIST is not set +CONFIG_USB_OTG=y +CONFIG_USB_MON=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_HCD_PCI is not set +CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_ACM=y +CONFIG_USB_STORAGE=y +CONFIG_USB_UAS=y +CONFIG_USB_DWC2=y +CONFIG_USB_SERIAL=y +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_CP210X=y +CONFIG_USB_SERIAL_FTDI_SIO=y +CONFIG_USB_SERIAL_KEYSPAN=y +CONFIG_USB_SERIAL_PL2303=y +CONFIG_USB_SERIAL_OTI6858=y +CONFIG_USB_SERIAL_QUALCOMM=y +CONFIG_USB_SERIAL_SIERRAWIRELESS=y +CONFIG_USB_SERIAL_OPTION=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_DEBUG_FILES=y +CONFIG_USB_GADGET_VBUS_DRAW=500 +CONFIG_USB_CONFIGFS=y +CONFIG_USB_CONFIGFS_ACM=y +CONFIG_USB_CONFIGFS_MASS_STORAGE=y +CONFIG_USB_CONFIGFS_F_FS=y +CONFIG_USB_CONFIGFS_UEVENT=y +CONFIG_MMC=y +CONFIG_MMC_BLOCK_MINORS=32 +CONFIG_MMC_TEST=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_OF_ARASAN=y +CONFIG_MMC_DW=y +CONFIG_MMC_DW_ROCKCHIP=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_IS31FL32XX=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_HYM8563=y +CONFIG_RTC_DRV_RK808=y +CONFIG_DMADEVICES=y +CONFIG_PL330_DMA=y +CONFIG_STAGING=y +CONFIG_SENSORS_ISL29018=y +CONFIG_TSL2583=y +# CONFIG_ANDROID_TIMED_OUTPUT is not set +CONFIG_FIQ_DEBUGGER=y +CONFIG_FIQ_DEBUGGER_NO_SLEEP=y +CONFIG_FIQ_DEBUGGER_CONSOLE=y +CONFIG_FIQ_DEBUGGER_CONSOLE_DEFAULT_ENABLE=y +CONFIG_COMMON_CLK_RK808=y +CONFIG_MAILBOX=y +CONFIG_ROCKCHIP_IOMMU=y +CONFIG_ROCKCHIP_PM_DOMAINS=y +CONFIG_ROCKCHIP_SUSPEND_MODE=y +CONFIG_PM_DEVFREQ=y +CONFIG_DEVFREQ_GOV_PERFORMANCE=y +CONFIG_DEVFREQ_GOV_POWERSAVE=y +CONFIG_DEVFREQ_GOV_USERSPACE=y +CONFIG_ARM_ROCKCHIP_DMC_DEVFREQ=y +CONFIG_PM_DEVFREQ_EVENT=y +CONFIG_MEMORY=y +CONFIG_IIO=y +CONFIG_IIO_BUFFER=y +CONFIG_IIO_KFIFO_BUF=y +CONFIG_IIO_TRIGGER=y +CONFIG_ROCKCHIP_SARADC=y +CONFIG_SENSORS_TSL2563=y +CONFIG_IIO_SYSFS_TRIGGER=y +CONFIG_PWM=y +CONFIG_PWM_ROCKCHIP=y +CONFIG_PHY_ROCKCHIP_USB=y +CONFIG_PHY_ROCKCHIP_INNO_USB2=y +CONFIG_PHY_ROCKCHIP_EMMC=y +CONFIG_PHY_ROCKCHIP_DP=y +CONFIG_PHY_ROCKCHIP_INNO_MIPI_DPHY=y +CONFIG_ANDROID=y +CONFIG_NVMEM=y +CONFIG_ROCKCHIP_EFUSE=y +CONFIG_ROCKCHIP_SIP=y +# CONFIG_ACPI is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_XFS_FS=y +# CONFIG_DNOTIFY is not set +CONFIG_FUSE_FS=y +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=936 +CONFIG_FAT_DEFAULT_IOCHARSET="utf8" +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_SQUASHFS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFS_SWAP=y +CONFIG_NLS_DEFAULT="utf8" +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_936=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_UTF8=y +CONFIG_PRINTK_TIME=y +CONFIG_DYNAMIC_DEBUG=y +CONFIG_DEBUG_INFO=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0 +CONFIG_LOCKUP_DETECTOR=y +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y +CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y +CONFIG_SCHEDSTATS=y +CONFIG_TIMER_STATS=y +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_CREDENTIALS=y +CONFIG_RCU_CPU_STALL_TIMEOUT=60 +CONFIG_FUNCTION_TRACER=y +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_LKDTM=y +CONFIG_STRICT_DEVMEM=y +CONFIG_DEBUG_SET_MODULE_RONX=y +# CONFIG_CRYPTO_ECHAINIV is not set +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA512=y +CONFIG_CRYPTO_TWOFISH=y +CONFIG_CRYPTO_ANSI_CPRNG=y +CONFIG_CRYPTO_USER_API_HASH=y +CONFIG_CRYPTO_USER_API_SKCIPHER=y +CONFIG_ASYMMETRIC_KEY_TYPE=y +CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y +CONFIG_X509_CERTIFICATE_PARSER=y +CONFIG_PKCS7_MESSAGE_PARSER=y +CONFIG_SYSTEM_TRUSTED_KEYRING=y +CONFIG_ARM64_CRYPTO=y +CONFIG_CRYPTO_SHA1_ARM64_CE=y +CONFIG_CRYPTO_SHA2_ARM64_CE=y +CONFIG_CRYPTO_GHASH_ARM64_CE=y +CONFIG_CRYPTO_AES_ARM64_CE_CCM=y +CONFIG_CRYPTO_AES_ARM64_CE_BLK=y +CONFIG_CRC_CCITT=y +CONFIG_CRC_T10DIF=y +CONFIG_CRC7=y +# CONFIG_XZ_DEC_X86 is not set +# CONFIG_XZ_DEC_POWERPC is not set +# CONFIG_XZ_DEC_IA64 is not set +# CONFIG_XZ_DEC_SPARC is not set diff --git a/arch/arm64/configs/ranchu64_defconfig b/arch/arm64/configs/ranchu64_defconfig index fc55008d8c4c9..7f847fc40d147 100644 --- a/arch/arm64/configs/ranchu64_defconfig +++ b/arch/arm64/configs/ranchu64_defconfig @@ -1,6 +1,7 @@ # CONFIG_LOCALVERSION_AUTO is not set # CONFIG_SWAP is not set CONFIG_POSIX_MQUEUE=y +# CONFIG_USELIB is not set CONFIG_AUDIT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -17,14 +18,19 @@ CONFIG_CGROUP_DEBUG=y CONFIG_CGROUP_FREEZER=y CONFIG_CGROUP_CPUACCT=y CONFIG_RT_GROUP_SCHED=y +CONFIG_NAMESPACES=y CONFIG_SCHED_AUTOGROUP=y CONFIG_BLK_DEV_INITRD=y CONFIG_KALLSYMS_ALL=y CONFIG_EMBEDDED=y # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y +CONFIG_CC_STACKPROTECTOR_STRONG=y CONFIG_ARCH_MMAP_RND_BITS=24 CONFIG_ARCH_MMAP_RND_COMPAT_BITS=16 +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y # CONFIG_BLK_DEV_BSG is not set # CONFIG_IOSCHED_DEADLINE is not set CONFIG_ARCH_VEXPRESS=y @@ -36,6 +42,8 @@ CONFIG_ARMV8_DEPRECATED=y CONFIG_SWP_EMULATION=y CONFIG_CP15_BARRIER_EMULATION=y CONFIG_SETEND_EMULATION=y +CONFIG_ARM64_SW_TTBR0_PAN=y +CONFIG_RANDOMIZE_BASE=y CONFIG_CMDLINE="console=ttyAMA0" # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_COMPAT=y @@ -50,15 +58,16 @@ CONFIG_UNIX=y CONFIG_XFRM_USER=y CONFIG_NET_KEY=y CONFIG_INET=y -CONFIG_INET_DIAG_DESTROY=y CONFIG_IP_MULTICAST=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y +CONFIG_NET_IPVTI=y CONFIG_INET_ESP=y # CONFIG_INET_LRO is not set +CONFIG_INET_DIAG_DESTROY=y CONFIG_IPV6_ROUTER_PREF=y CONFIG_IPV6_ROUTE_INFO=y CONFIG_IPV6_OPTIMISTIC_DAD=y @@ -66,6 +75,7 @@ CONFIG_INET6_AH=y CONFIG_INET6_ESP=y CONFIG_INET6_IPCOMP=y CONFIG_IPV6_MIP6=y +CONFIG_IPV6_VTI=y CONFIG_IPV6_MULTIPLE_TABLES=y CONFIG_NETFILTER=y CONFIG_NF_CONNTRACK=y @@ -124,6 +134,10 @@ CONFIG_IP_NF_MATCH_RPFILTER=y CONFIG_IP_NF_MATCH_TTL=y CONFIG_IP_NF_FILTER=y CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_IP_NF_NAT=y +CONFIG_IP_NF_TARGET_MASQUERADE=y +CONFIG_IP_NF_TARGET_NETMAP=y +CONFIG_IP_NF_TARGET_REDIRECT=y CONFIG_IP_NF_MANGLE=y CONFIG_IP_NF_TARGET_ECN=y CONFIG_IP_NF_TARGET_TTL=y @@ -141,6 +155,7 @@ CONFIG_IP6_NF_MATCH_OPTS=y CONFIG_IP6_NF_MATCH_HL=y CONFIG_IP6_NF_MATCH_IPV6HEADER=y CONFIG_IP6_NF_MATCH_MH=y +CONFIG_IP6_NF_MATCH_RPFILTER=y CONFIG_IP6_NF_MATCH_RT=y CONFIG_IP6_NF_TARGET_HL=y CONFIG_IP6_NF_FILTER=y @@ -154,12 +169,14 @@ CONFIG_NET_CLS_U32=y CONFIG_NET_EMATCH=y CONFIG_NET_EMATCH_U32=y CONFIG_NET_CLS_ACT=y -# CONFIG_WIRELESS is not set +CONFIG_MAC80211=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_VIRTIO_BLK=y +CONFIG_UID_SYS_STATS=y +CONFIG_MEMORY_STATE_TIME=y CONFIG_SCSI=y # CONFIG_SCSI_PROC_FS is not set CONFIG_BLK_DEV_SD=y @@ -180,13 +197,22 @@ CONFIG_PPP_DEFLATE=y CONFIG_PPP_MPPE=y CONFIG_PPPOLAC=y CONFIG_PPPOPNS=y -# CONFIG_WLAN is not set +CONFIG_USB_USBNET=y CONFIG_INPUT_EVDEV=y CONFIG_INPUT_KEYRESET=y CONFIG_KEYBOARD_GOLDFISH_EVENTS=y +CONFIG_KEYBOARD_GOLDFISH_ROTARY=y # CONFIG_INPUT_MOUSE is not set CONFIG_INPUT_JOYSTICK=y +CONFIG_JOYSTICK_XPAD=y +CONFIG_JOYSTICK_XPAD_FF=y +CONFIG_JOYSTICK_XPAD_LEDS=y CONFIG_INPUT_TABLET=y +CONFIG_TABLET_USB_ACECAD=y +CONFIG_TABLET_USB_AIPTEK=y +CONFIG_TABLET_USB_GTCO=y +CONFIG_TABLET_USB_HANWANG=y +CONFIG_TABLET_USB_KBTAB=y CONFIG_INPUT_MISC=y CONFIG_INPUT_KEYCHORD=y CONFIG_INPUT_UINPUT=y @@ -199,7 +225,8 @@ CONFIG_INPUT_GPIO=y CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y CONFIG_VIRTIO_CONSOLE=y -# CONFIG_HW_RANDOM is not set +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_VIRTIO=y CONFIG_BATTERY_GOLDFISH=y # CONFIG_HWMON is not set CONFIG_MEDIA_SUPPORT=y @@ -228,8 +255,10 @@ CONFIG_DRAGONRISE_FF=y CONFIG_HID_EMS_FF=y CONFIG_HID_ELECOM=y CONFIG_HID_EZKEY=y +CONFIG_HID_HOLTEK=y CONFIG_HID_KEYTOUCH=y CONFIG_HID_KYE=y +CONFIG_HID_UCLOGIC=y CONFIG_HID_WALTOP=y CONFIG_HID_GYRATION=y CONFIG_HID_TWINHAN=y @@ -244,14 +273,17 @@ CONFIG_HID_MAGICMOUSE=y CONFIG_HID_MICROSOFT=y CONFIG_HID_MONTEREY=y CONFIG_HID_MULTITOUCH=y +CONFIG_HID_NTRIG=y CONFIG_HID_ORTEK=y CONFIG_HID_PANTHERLORD=y CONFIG_PANTHERLORD_FF=y CONFIG_HID_PETALYNX=y CONFIG_HID_PICOLCD=y CONFIG_HID_PRIMAX=y +CONFIG_HID_ROCCAT=y CONFIG_HID_SAITEK=y CONFIG_HID_SAMSUNG=y +CONFIG_HID_SONY=y CONFIG_HID_SPEEDLINK=y CONFIG_HID_SUNPLUS=y CONFIG_HID_GREENASIA=y @@ -265,7 +297,18 @@ CONFIG_HID_WACOM=y CONFIG_HID_WIIMOTE=y CONFIG_HID_ZEROPLUS=y CONFIG_HID_ZYDACRON=y -# CONFIG_USB_SUPPORT is not set +CONFIG_USB_HIDDEV=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_GADGET=y +CONFIG_USB_CONFIGFS=y +CONFIG_USB_CONFIGFS_F_FS=y +CONFIG_USB_CONFIGFS_F_MTP=y +CONFIG_USB_CONFIGFS_F_PTP=y +CONFIG_USB_CONFIGFS_F_ACC=y +CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y +CONFIG_USB_CONFIGFS_UEVENT=y +CONFIG_USB_CONFIGFS_F_MIDI=y CONFIG_RTC_CLASS=y CONFIG_VIRTIO_MMIO=y CONFIG_STAGING=y @@ -286,27 +329,31 @@ CONFIG_EXT2_FS=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_SECURITY=y CONFIG_QUOTA=y +CONFIG_QUOTA_NETLINK_INTERFACE=y +CONFIG_QFMT_V2=y CONFIG_FUSE_FS=y CONFIG_CUSE=y CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y -# CONFIG_MISC_FILESYSTEMS is not set -CONFIG_NFS_FS=y -CONFIG_ROOT_NFS=y +CONFIG_SDCARD_FS=y +CONFIG_PSTORE=y +CONFIG_PSTORE_CONSOLE=y +CONFIG_PSTORE_RAM=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_FS=y CONFIG_MAGIC_SYSRQ=y CONFIG_PANIC_TIMEOUT=5 -# CONFIG_SCHED_DEBUG is not set CONFIG_SCHEDSTATS=y CONFIG_TIMER_STATS=y -# CONFIG_FTRACE is not set +CONFIG_ENABLE_DEFAULT_TRACERS=y CONFIG_ATOMIC64_SELFTEST=y -CONFIG_DEBUG_RODATA=y +CONFIG_KEYS=y +CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y +CONFIG_HARDENED_USERCOPY=y CONFIG_SECURITY_SELINUX=y +CONFIG_CRYPTO_SHA512=y diff --git a/arch/arm64/configs/rk3308_linux_defconfig b/arch/arm64/configs/rk3308_linux_defconfig index f9c5775f21542..c4c717aa4f8dc 100644 --- a/arch/arm64/configs/rk3308_linux_defconfig +++ b/arch/arm64/configs/rk3308_linux_defconfig @@ -95,7 +95,7 @@ CONFIG_NETDEVICES=y # CONFIG_ETHERNET is not set CONFIG_WL_ROCKCHIP=y CONFIG_WIFI_LOAD_DRIVER_WHEN_KERNEL_BOOTUP=y -CONFIG_CYW_BCMDHD=y +CONFIG_AP6XXX=y # CONFIG_RTL_WIRELESS_SOLUTION is not set # CONFIG_INPUT_MOUSEDEV is not set CONFIG_INPUT_EVDEV=y @@ -115,7 +115,8 @@ CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=5 CONFIG_SERIAL_8250_RUNTIME_UARTS=5 CONFIG_SERIAL_8250_DW=y -# CONFIG_HW_RANDOM is not set +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_ROCKCHIP=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_MUX=y CONFIG_I2C_RK3X=y @@ -154,7 +155,7 @@ CONFIG_SOUND=y CONFIG_SND=y CONFIG_SND_HRTIMER=y # CONFIG_SND_SUPPORT_OLD_API is not set -# CONFIG_SND_DRIVERS is not set +CONFIG_SND_ALOOP=y # CONFIG_SND_SPI is not set CONFIG_SND_SOC=y CONFIG_SND_SOC_ROCKCHIP=y @@ -163,10 +164,12 @@ CONFIG_SND_SOC_ROCKCHIP_I2S_TDM=y CONFIG_SND_SOC_ROCKCHIP_MULTI_DAIS=y CONFIG_SND_SOC_ROCKCHIP_PDM=y CONFIG_SND_SOC_ROCKCHIP_SPDIF=y +CONFIG_SND_SOC_ROCKCHIP_SPDIFRX=y CONFIG_SND_SOC_ROCKCHIP_VAD=y CONFIG_SND_SOC_ROCKCHIP_MULTICODECS=y CONFIG_SND_SOC_DUMMY_CODEC=y CONFIG_SND_SOC_RK3308=y +CONFIG_SND_SOC_TAS571X=y CONFIG_SND_SIMPLE_CARD=y # CONFIG_HID_GENERIC is not set CONFIG_USB_DWC2=y @@ -229,7 +232,10 @@ CONFIG_PHY_ROCKCHIP_INNO_USB2=y CONFIG_ANDROID=y CONFIG_NVMEM=y CONFIG_ROCKCHIP_OTP=y -CONFIG_RK_NAND=y +CONFIG_RK_FLASH=y +CONFIG_RK_NANDC_NAND=y +CONFIG_RK_SFC_NAND=y +CONFIG_RK_SFC_NOR=y CONFIG_ROCKCHIP_SIP=y CONFIG_EXT2_FS=y CONFIG_EXT4_FS=m diff --git a/arch/arm64/configs/rk3326_linux_defconfig b/arch/arm64/configs/rk3326_linux_defconfig index 533f9fb884d73..d8f55dd119f67 100644 --- a/arch/arm64/configs/rk3326_linux_defconfig +++ b/arch/arm64/configs/rk3326_linux_defconfig @@ -247,12 +247,14 @@ CONFIG_USB_VIDEO_CLASS=y # CONFIG_USB_GSPCA is not set CONFIG_V4L_PLATFORM_DRIVERS=y CONFIG_SOC_CAMERA=y +CONFIG_VIDEO_ROCKCHIP_CIF=y CONFIG_VIDEO_ROCKCHIP_ISP1=y CONFIG_V4L_MEM2MEM_DRIVERS=y CONFIG_VIDEO_ROCKCHIP_RGA=y # CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set # CONFIG_VIDEO_IR_I2C is not set CONFIG_VIDEO_OV5695=y +CONFIG_VIDEO_GC2155=y # CONFIG_DVB_AU8522_V4L is not set # CONFIG_DVB_TUNER_DIB0070 is not set # CONFIG_DVB_TUNER_DIB0090 is not set diff --git a/arch/arm64/configs/rockchip_defconfig b/arch/arm64/configs/rockchip_defconfig index c97898b72e224..8900d82c372ef 100644 --- a/arch/arm64/configs/rockchip_defconfig +++ b/arch/arm64/configs/rockchip_defconfig @@ -73,7 +73,7 @@ CONFIG_CP15_BARRIER_EMULATION=y CONFIG_SETEND_EMULATION=y CONFIG_ARM64_SW_TTBR0_PAN=y # CONFIG_EFI is not set -# CONFIG_COREDUMP is not set +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_COMPAT=y CONFIG_PM_AUTOSLEEP=y CONFIG_PM_WAKELOCKS=y @@ -106,6 +106,7 @@ CONFIG_IP_ROUTE_VERBOSE=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_SYN_COOKIES=y +CONFIG_NET_IPVTI=y CONFIG_INET_AH=y CONFIG_INET_ESP=y CONFIG_INET_IPCOMP=y @@ -118,6 +119,7 @@ CONFIG_INET6_AH=y CONFIG_INET6_ESP=y CONFIG_INET6_IPCOMP=y CONFIG_IPV6_MIP6=y +CONFIG_IPV6_VTI=y CONFIG_IPV6_MULTIPLE_TABLES=y CONFIG_IPV6_SUBTREES=y CONFIG_NETFILTER=y @@ -256,6 +258,7 @@ CONFIG_DM_CRYPT=y CONFIG_DM_UEVENT=y CONFIG_DM_VERITY=y CONFIG_DM_VERITY_FEC=y +CONFIG_DM_VERITY_AVB=y CONFIG_NETDEVICES=y CONFIG_TUN=y # CONFIG_NET_VENDOR_3COM is not set @@ -470,6 +473,10 @@ CONFIG_VIDEO_V4L2_SUBDEV_API=y CONFIG_MEDIA_USB_SUPPORT=y CONFIG_USB_VIDEO_CLASS=y CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_VIDEO_ROCKCHIP_ISP1=y +# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set +CONFIG_VIDEO_GC0312=y +CONFIG_VIDEO_GC2145=y CONFIG_CAMSYS_DRV=y CONFIG_FLASHLIGHT=y CONFIG_LEDS_RT8547=y @@ -539,6 +546,7 @@ CONFIG_SND_SOC=y CONFIG_SND_SOC_ROCKCHIP=y CONFIG_SND_SOC_ROCKCHIP_FORCE_SRAM=y CONFIG_SND_SOC_ROCKCHIP_I2S_TDM=y +CONFIG_SND_SOC_ROCKCHIP_MULTI_DAIS=y CONFIG_SND_SOC_ROCKCHIP_PDM=y CONFIG_SND_SOC_ROCKCHIP_SPDIF=y CONFIG_SND_SOC_ROCKCHIP_HDMI_ANALOG=y @@ -671,6 +679,7 @@ CONFIG_USB_CONFIGFS_F_ACC=y CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y CONFIG_USB_CONFIGFS_UEVENT=y CONFIG_USB_CONFIGFS_F_MIDI=y +CONFIG_USB_CONFIGFS_F_UVC=y CONFIG_USB20_HOST=y CONFIG_USB20_OTG=y CONFIG_MMC=y @@ -797,6 +806,7 @@ CONFIG_SCHEDSTATS=y CONFIG_TIMER_STATS=y # CONFIG_DEBUG_PREEMPT is not set CONFIG_ENABLE_DEFAULT_TRACERS=y +CONFIG_DEBUG_SET_MODULE_RONX=y CONFIG_KEYS=y CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y @@ -805,7 +815,6 @@ CONFIG_LSM_MMAP_MIN_ADDR=4096 CONFIG_HARDENED_USERCOPY=y CONFIG_SECURITY_SELINUX=y CONFIG_TEE_SUPPORT=y -CONFIG_CRYPTO_ECHAINIV=y CONFIG_CRYPTO_SHA512=y CONFIG_CRYPTO_TWOFISH=y CONFIG_CRYPTO_ANSI_CPRNG=y diff --git a/arch/arm64/configs/rockchip_linux_defconfig b/arch/arm64/configs/rockchip_linux_defconfig index ff9ab7fba87be..8095d4486aba1 100644 --- a/arch/arm64/configs/rockchip_linux_defconfig +++ b/arch/arm64/configs/rockchip_linux_defconfig @@ -294,14 +294,12 @@ CONFIG_USB_VIDEO_CLASS=y # CONFIG_USB_GSPCA is not set CONFIG_V4L_PLATFORM_DRIVERS=y CONFIG_SOC_CAMERA=y -CONFIG_VIDEO_RK_CIF_ISP10=y +CONFIG_VIDEO_ROCKCHIP_ISP1=y CONFIG_V4L_MEM2MEM_DRIVERS=y CONFIG_VIDEO_ROCKCHIP_RGA=y # CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set # CONFIG_VIDEO_IR_I2C is not set CONFIG_VIDEO_OV4689=y -CONFIG_VIDEO_OV7750=y -CONFIG_VIDEO_ADV7181=y CONFIG_VIDEO_OV13850=y # CONFIG_DVB_AU8522_V4L is not set # CONFIG_DVB_TUNER_DIB0070 is not set @@ -487,6 +485,9 @@ CONFIG_FAT_DEFAULT_IOCHARSET="utf8" CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y CONFIG_SQUASHFS=y +CONFIG_PSTORE=y +CONFIG_PSTORE_CONSOLE=y +CONFIG_PSTORE_RAM=y CONFIG_NFS_FS=y CONFIG_NFS_V3_ACL=y CONFIG_NFS_V4=y diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h index 5f6c8345c0e6e..8dade9319f3e9 100644 --- a/arch/arm64/include/asm/assembler.h +++ b/arch/arm64/include/asm/assembler.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -398,4 +399,43 @@ alternative_endif mrs \rd, sp_el0 .endm +/* + * Check the MIDR_EL1 of the current CPU for a given model and a range of + * variant/revision. See asm/cputype.h for the macros used below. + * + * model: MIDR_CPU_PART of CPU + * rv_min: Minimum of MIDR_CPU_VAR_REV() + * rv_max: Maximum of MIDR_CPU_VAR_REV() + * res: Result register. + * tmp1, tmp2, tmp3: Temporary registers + * + * Corrupts: res, tmp1, tmp2, tmp3 + * Returns: 0, if the CPU id doesn't match. Non-zero otherwise + */ + .macro cpu_midr_match model, rv_min, rv_max, res, tmp1, tmp2, tmp3 + mrs \res, midr_el1 + mov_q \tmp1, (MIDR_REVISION_MASK | MIDR_VARIANT_MASK) + mov_q \tmp2, MIDR_CPU_PART_MASK + and \tmp3, \res, \tmp2 // Extract model + and \tmp1, \res, \tmp1 // rev & variant + mov_q \tmp2, \model + cmp \tmp3, \tmp2 + cset \res, eq + cbz \res, .Ldone\@ // Model matches ? + + .if (\rv_min != 0) // Skip min check if rv_min == 0 + mov_q \tmp3, \rv_min + cmp \tmp1, \tmp3 + cset \res, ge + .endif // \rv_min != 0 + /* Skip rv_max check if rv_min == rv_max && rv_min != 0 */ + .if ((\rv_min != \rv_max) || \rv_min == 0) + mov_q \tmp2, \rv_max + cmp \tmp1, \tmp2 + cset \tmp2, le + and \res, \res, \tmp2 + .endif +.Ldone\@: + .endm + #endif /* __ASM_ASSEMBLER_H */ diff --git a/arch/arm64/include/asm/atomic_lse.h b/arch/arm64/include/asm/atomic_lse.h index 39c1d340fec59..a000e47d5016a 100644 --- a/arch/arm64/include/asm/atomic_lse.h +++ b/arch/arm64/include/asm/atomic_lse.h @@ -114,7 +114,7 @@ static inline void atomic_and(int i, atomic_t *v) /* LSE atomics */ " mvn %w[i], %w[i]\n" " stclr %w[i], %[v]") - : [i] "+r" (w0), [v] "+Q" (v->counter) + : [i] "+&r" (w0), [v] "+Q" (v->counter) : "r" (x1) : __LL_SC_CLOBBERS); } @@ -131,7 +131,7 @@ static inline void atomic_sub(int i, atomic_t *v) /* LSE atomics */ " neg %w[i], %w[i]\n" " stadd %w[i], %[v]") - : [i] "+r" (w0), [v] "+Q" (v->counter) + : [i] "+&r" (w0), [v] "+Q" (v->counter) : "r" (x1) : __LL_SC_CLOBBERS); } @@ -151,7 +151,7 @@ static inline int atomic_sub_return##name(int i, atomic_t *v) \ " neg %w[i], %w[i]\n" \ " ldadd" #mb " %w[i], w30, %[v]\n" \ " add %w[i], %w[i], w30") \ - : [i] "+r" (w0), [v] "+Q" (v->counter) \ + : [i] "+&r" (w0), [v] "+Q" (v->counter) \ : "r" (x1) \ : __LL_SC_CLOBBERS , ##cl); \ \ @@ -255,7 +255,7 @@ static inline void atomic64_and(long i, atomic64_t *v) /* LSE atomics */ " mvn %[i], %[i]\n" " stclr %[i], %[v]") - : [i] "+r" (x0), [v] "+Q" (v->counter) + : [i] "+&r" (x0), [v] "+Q" (v->counter) : "r" (x1) : __LL_SC_CLOBBERS); } @@ -272,7 +272,7 @@ static inline void atomic64_sub(long i, atomic64_t *v) /* LSE atomics */ " neg %[i], %[i]\n" " stadd %[i], %[v]") - : [i] "+r" (x0), [v] "+Q" (v->counter) + : [i] "+&r" (x0), [v] "+Q" (v->counter) : "r" (x1) : __LL_SC_CLOBBERS); } @@ -292,7 +292,7 @@ static inline long atomic64_sub_return##name(long i, atomic64_t *v) \ " neg %[i], %[i]\n" \ " ldadd" #mb " %[i], x30, %[v]\n" \ " add %[i], %[i], x30") \ - : [i] "+r" (x0), [v] "+Q" (v->counter) \ + : [i] "+&r" (x0), [v] "+Q" (v->counter) \ : "r" (x1) \ : __LL_SC_CLOBBERS, ##cl); \ \ @@ -412,7 +412,7 @@ static inline long __cmpxchg_double##name(unsigned long old1, \ " eor %[old1], %[old1], %[oldval1]\n" \ " eor %[old2], %[old2], %[oldval2]\n" \ " orr %[old1], %[old1], %[old2]") \ - : [old1] "+r" (x0), [old2] "+r" (x1), \ + : [old1] "+&r" (x0), [old2] "+&r" (x1), \ [v] "+Q" (*(unsigned long *)ptr) \ : [new1] "r" (x2), [new2] "r" (x3), [ptr] "r" (x4), \ [oldval1] "r" (oldval1), [oldval2] "r" (oldval2) \ diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h index b3a83da152a7c..8042c98ec0403 100644 --- a/arch/arm64/include/asm/cputype.h +++ b/arch/arm64/include/asm/cputype.h @@ -51,7 +51,15 @@ #define MIDR_IMPLEMENTOR(midr) \ (((midr) & MIDR_IMPLEMENTOR_MASK) >> MIDR_IMPLEMENTOR_SHIFT) -#define MIDR_CPU_MODEL(imp, partnum) \ +#define MIDR_CPU_VAR_REV(var, rev) \ + (((var) << MIDR_VARIANT_SHIFT) | (rev)) + +#define MIDR_CPU_PART_MASK \ + (MIDR_IMPLEMENTOR_MASK | \ + MIDR_ARCHITECTURE_MASK | \ + MIDR_PARTNUM_MASK) + +#define MIDR_CPU_PART(imp, partnum) \ (((imp) << MIDR_IMPLEMENTOR_SHIFT) | \ (0xf << MIDR_ARCHITECTURE_SHIFT) | \ ((partnum) << MIDR_PARTNUM_SHIFT)) @@ -75,14 +83,16 @@ #define ARM_CPU_PART_FOUNDATION 0xD00 #define ARM_CPU_PART_CORTEX_A57 0xD07 #define ARM_CPU_PART_CORTEX_A53 0xD03 +#define ARM_CPU_PART_CORTEX_A55 0xD05 #define APM_CPU_PART_POTENZA 0x000 #define CAVIUM_CPU_PART_THUNDERX 0x0A1 -#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) +#define MIDR_CORTEX_A53 MIDR_CPU_PART(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53) +#define MIDR_CORTEX_A55 MIDR_CPU_PART(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A55) +#define MIDR_CORTEX_A57 MIDR_CPU_PART(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57) +#define MIDR_THUNDERX MIDR_CPU_PART(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX) #ifndef __ASSEMBLY__ diff --git a/arch/arm64/include/asm/futex.h b/arch/arm64/include/asm/futex.h index f32b42e8725dc..5bb2fd4674e7c 100644 --- a/arch/arm64/include/asm/futex.h +++ b/arch/arm64/include/asm/futex.h @@ -48,20 +48,10 @@ do { \ } while (0) static inline int -futex_atomic_op_inuser(unsigned int encoded_op, u32 __user *uaddr) +arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (int)(encoded_op << 8) >> 20; - int cmparg = (int)(encoded_op << 20) >> 20; int oldval = 0, ret, tmp; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1U << (oparg & 0x1f); - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; - pagefault_disable(); switch (op) { @@ -91,17 +81,9 @@ futex_atomic_op_inuser(unsigned int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/arm64/include/asm/spinlock.h b/arch/arm64/include/asm/spinlock.h index 73f5d548bba1f..6d95f5d62d533 100644 --- a/arch/arm64/include/asm/spinlock.h +++ b/arch/arm64/include/asm/spinlock.h @@ -123,8 +123,8 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock) " cbnz %w1, 1f\n" " add %w1, %w0, %3\n" " casa %w0, %w1, %2\n" - " and %w1, %w1, #0xffff\n" - " eor %w1, %w1, %w0, lsr #16\n" + " sub %w1, %w1, %3\n" + " eor %w1, %w1, %w0\n" "1:") : "=&r" (lockval), "=&r" (tmp), "+Q" (*lock) : "I" (1 << TICKET_SHIFT) diff --git a/arch/arm64/include/uapi/asm/setup.h b/arch/arm64/include/uapi/asm/setup.h index 9cf2e46fbbdfe..7474c813d5ab0 100644 --- a/arch/arm64/include/uapi/asm/setup.h +++ b/arch/arm64/include/uapi/asm/setup.h @@ -21,6 +21,6 @@ #include -#define COMMAND_LINE_SIZE 2048 +#define COMMAND_LINE_SIZE 4096 #endif diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index fb3a21e17bff7..e2d4d5bc2b7e6 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -183,7 +183,7 @@ static void smp_store_cpu_info(unsigned int cpuid) * This is the secondary CPU boot entry. We're using this CPUs * idle thread stack, but a set of temporary page tables. */ -asmlinkage void secondary_start_kernel(void) +asmlinkage notrace void secondary_start_kernel(void) { struct mm_struct *mm = &init_mm; unsigned int cpu; diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index 5ab1553e434be..0dce70b869000 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -267,11 +267,13 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max) } #ifdef CONFIG_HAVE_ARCH_PFN_VALID -#define PFN_MASK ((1UL << (64 - PAGE_SHIFT)) - 1) - int pfn_valid(unsigned long pfn) { - return (pfn & PFN_MASK) == pfn && memblock_is_map_memory(pfn << PAGE_SHIFT); + phys_addr_t addr = pfn << PAGE_SHIFT; + + if ((addr >> PAGE_SHIFT) != pfn) + return 0; + return memblock_is_map_memory(addr); } EXPORT_SYMBOL(pfn_valid); #endif diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index ce6ff17998b32..41c0846f690ed 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -882,12 +882,12 @@ int pmd_clear_huge(pmd_t *pmd) } #ifdef CONFIG_HAVE_ARCH_HUGE_VMAP -int pud_free_pmd_page(pud_t *pud) +int pud_free_pmd_page(pud_t *pud, unsigned long addr) { return pud_none(*pud); } -int pmd_free_pte_page(pmd_t *pmd) +int pmd_free_pte_page(pmd_t *pmd, unsigned long addr) { return pmd_none(*pmd); } diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S index 19834ff5360cd..bfe9cb2289362 100644 --- a/arch/arm64/mm/proc.S +++ b/arch/arm64/mm/proc.S @@ -247,6 +247,11 @@ ENTRY(__cpu_setup) cbz x9, 2f cmp x9, #2 b.lt 1f +#ifdef CONFIG_ARM64_ERRATUM_1024718 + /* Disable hardware DBM on Cortex-A55 r0p0, r0p1 & r1p0 */ + cpu_midr_match MIDR_CORTEX_A55, MIDR_CPU_VAR_REV(0, 0), MIDR_CPU_VAR_REV(1, 0), x1, x2, x3, x4 + cbnz x1, 1f +#endif orr x10, x10, #TCR_HD // hardware Dirty flag update 1: orr x10, x10, #TCR_HA // hardware Access flag update 2: diff --git a/arch/frv/include/asm/futex.h b/arch/frv/include/asm/futex.h index 4bea27f50a7ab..2702bd802d447 100644 --- a/arch/frv/include/asm/futex.h +++ b/arch/frv/include/asm/futex.h @@ -7,7 +7,8 @@ #include #include -extern int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr); +extern int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, + u32 __user *uaddr); static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, diff --git a/arch/frv/kernel/futex.c b/arch/frv/kernel/futex.c index d155ca9e5098c..37f7b2bf7f730 100644 --- a/arch/frv/kernel/futex.c +++ b/arch/frv/kernel/futex.c @@ -186,20 +186,10 @@ static inline int atomic_futex_op_xchg_xor(int oparg, u32 __user *uaddr, int *_o /* * do the futex operations */ -int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) +int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; - pagefault_disable(); switch (op) { @@ -225,18 +215,9 @@ int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; break; - } - } + if (!ret) + *oval = oldval; return ret; -} /* end futex_atomic_op_inuser() */ +} /* end arch_futex_atomic_op_inuser() */ diff --git a/arch/hexagon/include/asm/futex.h b/arch/hexagon/include/asm/futex.h index 7e597f8434da0..c607b77c8215d 100644 --- a/arch/hexagon/include/asm/futex.h +++ b/arch/hexagon/include/asm/futex.h @@ -31,18 +31,9 @@ static inline int -futex_atomic_op_inuser(int encoded_op, int __user *uaddr) +arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) - return -EFAULT; pagefault_disable(); @@ -72,30 +63,9 @@ futex_atomic_op_inuser(int encoded_op, int __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: - ret = (oldval == cmparg); - break; - case FUTEX_OP_CMP_NE: - ret = (oldval != cmparg); - break; - case FUTEX_OP_CMP_LT: - ret = (oldval < cmparg); - break; - case FUTEX_OP_CMP_GE: - ret = (oldval >= cmparg); - break; - case FUTEX_OP_CMP_LE: - ret = (oldval <= cmparg); - break; - case FUTEX_OP_CMP_GT: - ret = (oldval > cmparg); - break; - default: - ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/ia64/include/asm/futex.h b/arch/ia64/include/asm/futex.h index 76acbcd5c0609..6d67dc1eaf2be 100644 --- a/arch/ia64/include/asm/futex.h +++ b/arch/ia64/include/asm/futex.h @@ -45,18 +45,9 @@ do { \ } while (0) static inline int -futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) +arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; pagefault_disable(); @@ -84,17 +75,9 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/m68k/coldfire/device.c b/arch/m68k/coldfire/device.c index 71ea4c02795d4..8a2dc0af4cadb 100644 --- a/arch/m68k/coldfire/device.c +++ b/arch/m68k/coldfire/device.c @@ -135,7 +135,11 @@ static struct platform_device mcf_fec0 = { .id = 0, .num_resources = ARRAY_SIZE(mcf_fec0_resources), .resource = mcf_fec0_resources, - .dev.platform_data = FEC_PDATA, + .dev = { + .dma_mask = &mcf_fec0.dev.coherent_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = FEC_PDATA, + } }; #ifdef MCFFEC_BASE1 @@ -167,7 +171,11 @@ static struct platform_device mcf_fec1 = { .id = 1, .num_resources = ARRAY_SIZE(mcf_fec1_resources), .resource = mcf_fec1_resources, - .dev.platform_data = FEC_PDATA, + .dev = { + .dma_mask = &mcf_fec1.dev.coherent_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = FEC_PDATA, + } }; #endif /* MCFFEC_BASE1 */ #endif /* CONFIG_FEC */ diff --git a/arch/m68k/include/asm/mcf_pgalloc.h b/arch/m68k/include/asm/mcf_pgalloc.h index f9924fbcfe42b..456e3f75ef3b7 100644 --- a/arch/m68k/include/asm/mcf_pgalloc.h +++ b/arch/m68k/include/asm/mcf_pgalloc.h @@ -43,6 +43,7 @@ extern inline pmd_t *pmd_alloc_kernel(pgd_t *pgd, unsigned long address) static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t page, unsigned long address) { + pgtable_page_dtor(page); __free_page(page); } @@ -73,8 +74,9 @@ static inline struct page *pte_alloc_one(struct mm_struct *mm, return page; } -extern inline void pte_free(struct mm_struct *mm, struct page *page) +static inline void pte_free(struct mm_struct *mm, struct page *page) { + pgtable_page_dtor(page); __free_page(page); } diff --git a/arch/m68k/mm/kmap.c b/arch/m68k/mm/kmap.c index 6e4955bc542bf..fcd52cefee296 100644 --- a/arch/m68k/mm/kmap.c +++ b/arch/m68k/mm/kmap.c @@ -88,7 +88,8 @@ static inline void free_io_area(void *addr) for (p = &iolist ; (tmp = *p) ; p = &tmp->next) { if (tmp->addr == addr) { *p = tmp->next; - __iounmap(tmp->addr, tmp->size); + /* remove gap added in get_io_area() */ + __iounmap(tmp->addr, tmp->size - IO_SIZE); kfree(tmp); return; } diff --git a/arch/microblaze/boot/Makefile b/arch/microblaze/boot/Makefile index 91d2068da1b9b..0f3fe6a151dce 100644 --- a/arch/microblaze/boot/Makefile +++ b/arch/microblaze/boot/Makefile @@ -21,17 +21,19 @@ $(obj)/linux.bin.gz: $(obj)/linux.bin FORCE quiet_cmd_cp = CP $< $@$2 cmd_cp = cat $< >$@$2 || (rm -f $@ && echo false) -quiet_cmd_strip = STRIP $@ +quiet_cmd_strip = STRIP $< $@$2 cmd_strip = $(STRIP) -K microblaze_start -K _end -K __log_buf \ - -K _fdt_start vmlinux -o $@ + -K _fdt_start $< -o $@$2 UIMAGE_LOADADDR = $(CONFIG_KERNEL_BASE_ADDR) +UIMAGE_IN = $@ +UIMAGE_OUT = $@.ub $(obj)/simpleImage.%: vmlinux FORCE $(call if_changed,cp,.unstrip) $(call if_changed,objcopy) $(call if_changed,uimage) - $(call if_changed,strip) - @echo 'Kernel: $@ is ready' ' (#'`cat .version`')' + $(call if_changed,strip,.strip) + @echo 'Kernel: $(UIMAGE_OUT) is ready' ' (#'`cat .version`')' clean-files += simpleImage.*.unstrip linux.bin.ub dts/*.dtb diff --git a/arch/microblaze/include/asm/futex.h b/arch/microblaze/include/asm/futex.h index 01848f056f439..a9dad9e5e132f 100644 --- a/arch/microblaze/include/asm/futex.h +++ b/arch/microblaze/include/asm/futex.h @@ -29,18 +29,9 @@ }) static inline int -futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) +arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; pagefault_disable(); @@ -66,30 +57,9 @@ futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: - ret = (oldval == cmparg); - break; - case FUTEX_OP_CMP_NE: - ret = (oldval != cmparg); - break; - case FUTEX_OP_CMP_LT: - ret = (oldval < cmparg); - break; - case FUTEX_OP_CMP_GE: - ret = (oldval >= cmparg); - break; - case FUTEX_OP_CMP_LE: - ret = (oldval <= cmparg); - break; - case FUTEX_OP_CMP_GT: - ret = (oldval > cmparg); - break; - default: - ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/mips/ath79/common.c b/arch/mips/ath79/common.c index 8ae4067a5eda2..40ecb6e700cd8 100644 --- a/arch/mips/ath79/common.c +++ b/arch/mips/ath79/common.c @@ -58,7 +58,7 @@ EXPORT_SYMBOL_GPL(ath79_ddr_ctrl_init); void ath79_ddr_wb_flush(u32 reg) { - void __iomem *flush_reg = ath79_ddr_wb_flush_base + reg; + void __iomem *flush_reg = ath79_ddr_wb_flush_base + (reg * 4); /* Flush the DDR write buffer. */ __raw_writel(0x1, flush_reg); diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c index 10d0b21403754..63d35076722d0 100644 --- a/arch/mips/cavium-octeon/octeon-irq.c +++ b/arch/mips/cavium-octeon/octeon-irq.c @@ -2240,7 +2240,7 @@ static int __init octeon_irq_init_cib(struct device_node *ciu_node, parent_irq = irq_of_parse_and_map(ciu_node, 0); if (!parent_irq) { - pr_err("ERROR: Couldn't acquire parent_irq for %s\n.", + pr_err("ERROR: Couldn't acquire parent_irq for %s\n", ciu_node->name); return -EINVAL; } @@ -2252,7 +2252,7 @@ static int __init octeon_irq_init_cib(struct device_node *ciu_node, addr = of_get_address(ciu_node, 0, NULL, NULL); if (!addr) { - pr_err("ERROR: Couldn't acquire reg(0) %s\n.", ciu_node->name); + pr_err("ERROR: Couldn't acquire reg(0) %s\n", ciu_node->name); return -EINVAL; } host_data->raw_reg = (u64)phys_to_virt( @@ -2260,7 +2260,7 @@ static int __init octeon_irq_init_cib(struct device_node *ciu_node, addr = of_get_address(ciu_node, 1, NULL, NULL); if (!addr) { - pr_err("ERROR: Couldn't acquire reg(1) %s\n.", ciu_node->name); + pr_err("ERROR: Couldn't acquire reg(1) %s\n", ciu_node->name); return -EINVAL; } host_data->en_reg = (u64)phys_to_virt( @@ -2268,7 +2268,7 @@ static int __init octeon_irq_init_cib(struct device_node *ciu_node, r = of_property_read_u32(ciu_node, "cavium,max-bits", &val); if (r) { - pr_err("ERROR: Couldn't read cavium,max-bits from %s\n.", + pr_err("ERROR: Couldn't read cavium,max-bits from %s\n", ciu_node->name); return r; } @@ -2278,7 +2278,7 @@ static int __init octeon_irq_init_cib(struct device_node *ciu_node, &octeon_irq_domain_cib_ops, host_data); if (!cib_domain) { - pr_err("ERROR: Couldn't irq_domain_add_linear()\n."); + pr_err("ERROR: Couldn't irq_domain_add_linear()\n"); return -ENOMEM; } diff --git a/arch/mips/include/asm/futex.h b/arch/mips/include/asm/futex.h index 1de190bdfb9c9..a9e61ea54ca96 100644 --- a/arch/mips/include/asm/futex.h +++ b/arch/mips/include/asm/futex.h @@ -83,18 +83,9 @@ } static inline int -futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) +arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; pagefault_disable(); @@ -125,17 +116,9 @@ futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index d10fd80dbb7e9..75fa296836fc4 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h @@ -411,6 +411,8 @@ static inline type pfx##in##bwlq##p(unsigned long port) \ __val = *__addr; \ slow; \ \ + /* prevent prefetching of coherent DMA data prematurely */ \ + rmb(); \ return pfx##ioswab##bwlq(__addr, __val); \ } diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h index aa3800c823321..d99ca862dae32 100644 --- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h +++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h @@ -167,7 +167,7 @@ #define AR71XX_AHB_DIV_MASK 0x7 #define AR724X_PLL_REG_CPU_CONFIG 0x00 -#define AR724X_PLL_REG_PCIE_CONFIG 0x18 +#define AR724X_PLL_REG_PCIE_CONFIG 0x10 #define AR724X_PLL_FB_SHIFT 0 #define AR724X_PLL_FB_MASK 0x3ff diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h index 98c31e5d95793..a7bc901819c82 100644 --- a/arch/mips/include/asm/pci.h +++ b/arch/mips/include/asm/pci.h @@ -89,7 +89,7 @@ static inline void pci_resource_to_user(const struct pci_dev *dev, int bar, phys_addr_t size = resource_size(rsrc); *start = fixup_bigphys_addr(rsrc->start, size); - *end = rsrc->start + size; + *end = rsrc->start + size - 1; } /* diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h index 25eef1d60f275..0f07ac3bc7447 100644 --- a/arch/mips/include/asm/processor.h +++ b/arch/mips/include/asm/processor.h @@ -137,7 +137,7 @@ struct mips_fpu_struct { #define NUM_DSP_REGS 6 -typedef __u32 dspreg_t; +typedef unsigned long dspreg_t; struct mips_dsp_state { dspreg_t dspr[NUM_DSP_REGS]; diff --git a/arch/mips/kernel/mcount.S b/arch/mips/kernel/mcount.S index 2f7c734771f4e..0df911e772ae0 100644 --- a/arch/mips/kernel/mcount.S +++ b/arch/mips/kernel/mcount.S @@ -116,10 +116,20 @@ ftrace_stub: NESTED(_mcount, PT_SIZE, ra) PTR_LA t1, ftrace_stub PTR_L t2, ftrace_trace_function /* Prepare t2 for (1) */ - bne t1, t2, static_trace + beq t1, t2, fgraph_trace nop + MCOUNT_SAVE_REGS + + move a0, ra /* arg1: self return address */ + jalr t2 /* (1) call *ftrace_trace_function */ + move a1, AT /* arg2: parent's return address */ + + MCOUNT_RESTORE_REGS + +fgraph_trace: #ifdef CONFIG_FUNCTION_GRAPH_TRACER + PTR_LA t1, ftrace_stub PTR_L t3, ftrace_graph_return bne t1, t3, ftrace_graph_caller nop @@ -128,24 +138,11 @@ NESTED(_mcount, PT_SIZE, ra) bne t1, t3, ftrace_graph_caller nop #endif - b ftrace_stub -#ifdef CONFIG_32BIT - addiu sp, sp, 8 -#else - nop -#endif -static_trace: - MCOUNT_SAVE_REGS - - move a0, ra /* arg1: self return address */ - jalr t2 /* (1) call *ftrace_trace_function */ - move a1, AT /* arg2: parent's return address */ - - MCOUNT_RESTORE_REGS #ifdef CONFIG_32BIT addiu sp, sp, 8 #endif + .globl ftrace_stub ftrace_stub: RETURN_BACK diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index fe61ce7ad9b1b..9684a0d22d975 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -633,21 +633,48 @@ unsigned long arch_align_stack(unsigned long sp) return sp & ALMASK; } +static DEFINE_PER_CPU(struct call_single_data, backtrace_csd); +static struct cpumask backtrace_csd_busy; + static void arch_dump_stack(void *info) { struct pt_regs *regs; + static arch_spinlock_t lock = __ARCH_SPIN_LOCK_UNLOCKED; + arch_spin_lock(&lock); regs = get_irq_regs(); if (regs) show_regs(regs); + else + dump_stack(); + arch_spin_unlock(&lock); - dump_stack(); + cpumask_clear_cpu(smp_processor_id(), &backtrace_csd_busy); } void arch_trigger_all_cpu_backtrace(bool include_self) { - smp_call_function(arch_dump_stack, NULL, 1); + struct call_single_data *csd; + int cpu; + + for_each_cpu(cpu, cpu_online_mask) { + /* + * If we previously sent an IPI to the target CPU & it hasn't + * cleared its bit in the busy cpumask then it didn't handle + * our previous IPI & it's not safe for us to reuse the + * call_single_data_t. + */ + if (cpumask_test_and_set_cpu(cpu, &backtrace_csd_busy)) { + pr_warn("Unable to send backtrace IPI to CPU%u - perhaps it hung?\n", + cpu); + continue; + } + + csd = &per_cpu(backtrace_csd, cpu); + csd->func = arch_dump_stack; + smp_call_function_single_async(cpu, csd); + } } int mips_get_process_fp_mode(struct task_struct *task) @@ -684,6 +711,10 @@ int mips_set_process_fp_mode(struct task_struct *task, unsigned int value) if (value & ~known_bits) return -EOPNOTSUPP; + /* Setting FRE without FR is not supported. */ + if ((value & (PR_FP_MODE_FR | PR_FP_MODE_FRE)) == PR_FP_MODE_FRE) + return -EOPNOTSUPP; + /* Avoid inadvertently triggering emulation */ if ((value & PR_FP_MODE_FR) && raw_cpu_has_fpu && !(raw_current_cpu_data.fpu_id & MIPS_FPIR_F64)) diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index 0f0030e7f6d97..9d04392f7ef09 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c @@ -482,7 +482,7 @@ static int fpr_get_msa(struct task_struct *target, /* * Copy the floating-point context to the supplied NT_PRFPREG buffer. * Choose the appropriate helper for general registers, and then copy - * the FCSR register separately. + * the FCSR and FIR registers separately. */ static int fpr_get(struct task_struct *target, const struct user_regset *regset, @@ -490,6 +490,7 @@ static int fpr_get(struct task_struct *target, void *kbuf, void __user *ubuf) { const int fcr31_pos = NUM_FPU_REGS * sizeof(elf_fpreg_t); + const int fir_pos = fcr31_pos + sizeof(u32); int err; if (sizeof(target->thread.fpu.fpr[0]) == sizeof(elf_fpreg_t)) @@ -502,6 +503,12 @@ static int fpr_get(struct task_struct *target, err = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &target->thread.fpu.fcr31, fcr31_pos, fcr31_pos + sizeof(u32)); + if (err) + return err; + + err = user_regset_copyout(&pos, &count, &kbuf, &ubuf, + &boot_cpu_data.fpu_id, + fir_pos, fir_pos + sizeof(u32)); return err; } @@ -550,7 +557,8 @@ static int fpr_set_msa(struct task_struct *target, /* * Copy the supplied NT_PRFPREG buffer to the floating-point context. * Choose the appropriate helper for general registers, and then copy - * the FCSR register separately. + * the FCSR register separately. Ignore the incoming FIR register + * contents though, as the register is read-only. * * We optimize for the case where `count % sizeof(elf_fpreg_t) == 0', * which is supposed to have been guaranteed by the kernel before @@ -564,6 +572,7 @@ static int fpr_set(struct task_struct *target, const void *kbuf, const void __user *ubuf) { const int fcr31_pos = NUM_FPU_REGS * sizeof(elf_fpreg_t); + const int fir_pos = fcr31_pos + sizeof(u32); u32 fcr31; int err; @@ -591,6 +600,11 @@ static int fpr_set(struct task_struct *target, ptrace_setfcr31(target, fcr31); } + if (count > 0) + err = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, + fir_pos, + fir_pos + sizeof(u32)); + return err; } @@ -815,7 +829,7 @@ long arch_ptrace(struct task_struct *child, long request, fregs = get_fpu_regs(child); #ifdef CONFIG_32BIT - if (test_thread_flag(TIF_32BIT_FPREGS)) { + if (test_tsk_thread_flag(child, TIF_32BIT_FPREGS)) { /* * The odd registers are actually the high * order bits of the values stored in the even @@ -826,7 +840,7 @@ long arch_ptrace(struct task_struct *child, long request, break; } #endif - tmp = get_fpr32(&fregs[addr - FPR_BASE], 0); + tmp = get_fpr64(&fregs[addr - FPR_BASE], 0); break; case PC: tmp = regs->cp0_epc; @@ -864,7 +878,7 @@ long arch_ptrace(struct task_struct *child, long request, goto out; } dregs = __get_dsp_regs(child); - tmp = (unsigned long) (dregs[addr - DSP_BASE]); + tmp = dregs[addr - DSP_BASE]; break; } case DSP_CONTROL: @@ -904,7 +918,7 @@ long arch_ptrace(struct task_struct *child, long request, init_fp_ctx(child); #ifdef CONFIG_32BIT - if (test_thread_flag(TIF_32BIT_FPREGS)) { + if (test_tsk_thread_flag(child, TIF_32BIT_FPREGS)) { /* * The odd registers are actually the high * order bits of the values stored in the even diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c index 283b5a1967d14..286ec2d24d47b 100644 --- a/arch/mips/kernel/ptrace32.c +++ b/arch/mips/kernel/ptrace32.c @@ -97,7 +97,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, break; } fregs = get_fpu_regs(child); - if (test_thread_flag(TIF_32BIT_FPREGS)) { + if (test_tsk_thread_flag(child, TIF_32BIT_FPREGS)) { /* * The odd registers are actually the high * order bits of the values stored in the even @@ -107,7 +107,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, addr & 1); break; } - tmp = get_fpr32(&fregs[addr - FPR_BASE], 0); + tmp = get_fpr64(&fregs[addr - FPR_BASE], 0); break; case PC: tmp = regs->cp0_epc; @@ -140,7 +140,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, goto out; } dregs = __get_dsp_regs(child); - tmp = (unsigned long) (dregs[addr - DSP_BASE]); + tmp = dregs[addr - DSP_BASE]; break; } case DSP_CONTROL: @@ -203,7 +203,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, sizeof(child->thread.fpu)); child->thread.fpu.fcr31 = 0; } - if (test_thread_flag(TIF_32BIT_FPREGS)) { + if (test_tsk_thread_flag(child, TIF_32BIT_FPREGS)) { /* * The odd registers are actually the high * order bits of the values stored in the even diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index e23f4775b10bb..da6997486709c 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -345,6 +345,7 @@ static void __show_regs(const struct pt_regs *regs) void show_regs(struct pt_regs *regs) { __show_regs((struct pt_regs *)regs); + dump_stack(); } void show_registers(struct pt_regs *regs) diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c index a017b23ee4aa1..8a95c3d76a9a6 100644 --- a/arch/mips/kvm/mips.c +++ b/arch/mips/kvm/mips.c @@ -40,7 +40,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { { "cache", VCPU_STAT(cache_exits), KVM_STAT_VCPU }, { "signal", VCPU_STAT(signal_exits), KVM_STAT_VCPU }, { "interrupt", VCPU_STAT(int_exits), KVM_STAT_VCPU }, - { "cop_unsuable", VCPU_STAT(cop_unusable_exits), KVM_STAT_VCPU }, + { "cop_unusable", VCPU_STAT(cop_unusable_exits), KVM_STAT_VCPU }, { "tlbmod", VCPU_STAT(tlbmod_exits), KVM_STAT_VCPU }, { "tlbmiss_ld", VCPU_STAT(tlbmiss_ld_exits), KVM_STAT_VCPU }, { "tlbmiss_st", VCPU_STAT(tlbmiss_st_exits), KVM_STAT_VCPU }, diff --git a/arch/mips/lib/multi3.c b/arch/mips/lib/multi3.c index 111ad475aa0cd..4c2483f410c26 100644 --- a/arch/mips/lib/multi3.c +++ b/arch/mips/lib/multi3.c @@ -4,12 +4,12 @@ #include "libgcc.h" /* - * GCC 7 suboptimally generates __multi3 calls for mips64r6, so for that - * specific case only we'll implement it here. + * GCC 7 & older can suboptimally generate __multi3 calls for mips64r6, so for + * that specific case only we implement that intrinsic here. * * See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82981 */ -#if defined(CONFIG_64BIT) && defined(CONFIG_CPU_MIPSR6) && (__GNUC__ == 7) +#if defined(CONFIG_64BIT) && defined(CONFIG_CPU_MIPSR6) && (__GNUC__ < 8) /* multiply 64-bit values, low 64-bits returned */ static inline long long notrace dmulu(long long a, long long b) diff --git a/arch/mips/mm/ioremap.c b/arch/mips/mm/ioremap.c index 8d5008cbdc0f0..a853a83f29449 100644 --- a/arch/mips/mm/ioremap.c +++ b/arch/mips/mm/ioremap.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -97,6 +98,20 @@ static int remap_area_pages(unsigned long address, phys_addr_t phys_addr, return error; } +static int __ioremap_check_ram(unsigned long start_pfn, unsigned long nr_pages, + void *arg) +{ + unsigned long i; + + for (i = 0; i < nr_pages; i++) { + if (pfn_valid(start_pfn + i) && + !PageReserved(pfn_to_page(start_pfn + i))) + return 1; + } + + return 0; +} + /* * Generic mapping function (not visible outside): */ @@ -115,8 +130,8 @@ static int remap_area_pages(unsigned long address, phys_addr_t phys_addr, void __iomem * __ioremap(phys_addr_t phys_addr, phys_addr_t size, unsigned long flags) { + unsigned long offset, pfn, last_pfn; struct vm_struct * area; - unsigned long offset; phys_addr_t last_addr; void * addr; @@ -136,18 +151,16 @@ void __iomem * __ioremap(phys_addr_t phys_addr, phys_addr_t size, unsigned long return (void __iomem *) CKSEG1ADDR(phys_addr); /* - * Don't allow anybody to remap normal RAM that we're using.. + * Don't allow anybody to remap RAM that may be allocated by the page + * allocator, since that could lead to races & data clobbering. */ - if (phys_addr < virt_to_phys(high_memory)) { - char *t_addr, *t_end; - struct page *page; - - t_addr = __va(phys_addr); - t_end = t_addr + (size - 1); - - for(page = virt_to_page(t_addr); page <= virt_to_page(t_end); page++) - if(!PageReserved(page)) - return NULL; + pfn = PFN_DOWN(phys_addr); + last_pfn = PFN_DOWN(last_addr); + if (walk_system_ram_range(pfn, last_pfn - pfn + 1, NULL, + __ioremap_check_ram) == 1) { + WARN_ONCE(1, "ioremap on RAM at %pa - %pa\n", + &phys_addr, &last_addr); + return NULL; } /* diff --git a/arch/mips/txx9/rbtx4939/setup.c b/arch/mips/txx9/rbtx4939/setup.c index 37030409745c3..586ca7ea3e7cc 100644 --- a/arch/mips/txx9/rbtx4939/setup.c +++ b/arch/mips/txx9/rbtx4939/setup.c @@ -186,7 +186,7 @@ static void __init rbtx4939_update_ioc_pen(void) #define RBTX4939_MAX_7SEGLEDS 8 -#if IS_ENABLED(CONFIG_LEDS_CLASS) +#if IS_BUILTIN(CONFIG_LEDS_CLASS) static u8 led_val[RBTX4939_MAX_7SEGLEDS]; struct rbtx4939_led_data { struct led_classdev cdev; @@ -261,7 +261,7 @@ static inline void rbtx4939_led_setup(void) static void __rbtx4939_7segled_putc(unsigned int pos, unsigned char val) { -#if IS_ENABLED(CONFIG_LEDS_CLASS) +#if IS_BUILTIN(CONFIG_LEDS_CLASS) unsigned long flags; local_irq_save(flags); /* bit7: reserved for LED class */ diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index d2256fa97ea0c..f7f89310a7a14 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -178,7 +178,7 @@ config PREFETCH config MLONGCALLS bool "Enable the -mlong-calls compiler option for big kernels" - def_bool y if (!MODULES) + default y depends on PA8X00 help If you configure the kernel to include many drivers built-in instead diff --git a/arch/parisc/include/asm/barrier.h b/arch/parisc/include/asm/barrier.h new file mode 100644 index 0000000000000..dbaaca84f27f3 --- /dev/null +++ b/arch/parisc/include/asm/barrier.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __ASM_BARRIER_H +#define __ASM_BARRIER_H + +#ifndef __ASSEMBLY__ + +/* The synchronize caches instruction executes as a nop on systems in + which all memory references are performed in order. */ +#define synchronize_caches() __asm__ __volatile__ ("sync" : : : "memory") + +#if defined(CONFIG_SMP) +#define mb() do { synchronize_caches(); } while (0) +#define rmb() mb() +#define wmb() mb() +#define dma_rmb() mb() +#define dma_wmb() mb() +#else +#define mb() barrier() +#define rmb() barrier() +#define wmb() barrier() +#define dma_rmb() barrier() +#define dma_wmb() barrier() +#endif + +#define __smp_mb() mb() +#define __smp_rmb() mb() +#define __smp_wmb() mb() + +#include + +#endif /* !__ASSEMBLY__ */ +#endif /* __ASM_BARRIER_H */ diff --git a/arch/parisc/include/asm/futex.h b/arch/parisc/include/asm/futex.h index 49df14805a9b4..ae5b64981d729 100644 --- a/arch/parisc/include/asm/futex.h +++ b/arch/parisc/include/asm/futex.h @@ -32,20 +32,11 @@ _futex_spin_unlock_irqrestore(u32 __user *uaddr, unsigned long int *flags) } static inline int -futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) +arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) { unsigned long int flags; u32 val; - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(*uaddr))) - return -EFAULT; pagefault_disable(); @@ -98,17 +89,9 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/parisc/include/asm/spinlock.h b/arch/parisc/include/asm/spinlock.h index 64f2992e439fc..617efa845054e 100644 --- a/arch/parisc/include/asm/spinlock.h +++ b/arch/parisc/include/asm/spinlock.h @@ -21,7 +21,6 @@ static inline void arch_spin_lock_flags(arch_spinlock_t *x, { volatile unsigned int *a; - mb(); a = __ldcw_align(x); while (__ldcw(a) == 0) while (*a == 0) @@ -31,16 +30,15 @@ static inline void arch_spin_lock_flags(arch_spinlock_t *x, local_irq_disable(); } else cpu_relax(); - mb(); } static inline void arch_spin_unlock(arch_spinlock_t *x) { volatile unsigned int *a; - mb(); + a = __ldcw_align(x); - *a = 1; mb(); + *a = 1; } static inline int arch_spin_trylock(arch_spinlock_t *x) @@ -48,10 +46,8 @@ static inline int arch_spin_trylock(arch_spinlock_t *x) volatile unsigned int *a; int ret; - mb(); a = __ldcw_align(x); ret = __ldcw(a) != 0; - mb(); return ret; } diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 5dc831955de5d..13cb2461fef5e 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -481,6 +481,8 @@ /* Release pa_tlb_lock lock without reloading lock address. */ .macro tlb_unlock0 spc,tmp #ifdef CONFIG_SMP + or,COND(=) %r0,\spc,%r0 + sync or,COND(=) %r0,\spc,%r0 stw \spc,0(\tmp) #endif diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S index 16073f4721184..b3434a7fd3c97 100644 --- a/arch/parisc/kernel/pacache.S +++ b/arch/parisc/kernel/pacache.S @@ -354,6 +354,7 @@ ENDPROC(flush_data_cache_local) .macro tlb_unlock la,flags,tmp #ifdef CONFIG_SMP ldi 1,\tmp + sync stw \tmp,0(\la) mtsm \flags #endif diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index 9f22195b90ed0..dd44022c3ae30 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S @@ -627,11 +627,12 @@ cas_action: stw %r1, 4(%sr2,%r20) #endif /* The load and store could fail */ -1: ldw,ma 0(%r26), %r28 +1: ldw 0(%r26), %r28 sub,<> %r28, %r25, %r0 -2: stw,ma %r24, 0(%r26) +2: stw %r24, 0(%r26) /* Free lock */ - stw,ma %r20, 0(%sr2,%r20) + sync + stw %r20, 0(%sr2,%r20) #if ENABLE_LWS_DEBUG /* Clear thread register indicator */ stw %r0, 4(%sr2,%r20) @@ -645,6 +646,7 @@ cas_action: 3: /* Error occurred on load or store */ /* Free lock */ + sync stw %r20, 0(%sr2,%r20) #if ENABLE_LWS_DEBUG stw %r0, 4(%sr2,%r20) @@ -794,30 +796,30 @@ cas2_action: ldo 1(%r0),%r28 /* 8bit CAS */ -13: ldb,ma 0(%r26), %r29 +13: ldb 0(%r26), %r29 sub,= %r29, %r25, %r0 b,n cas2_end -14: stb,ma %r24, 0(%r26) +14: stb %r24, 0(%r26) b cas2_end copy %r0, %r28 nop nop /* 16bit CAS */ -15: ldh,ma 0(%r26), %r29 +15: ldh 0(%r26), %r29 sub,= %r29, %r25, %r0 b,n cas2_end -16: sth,ma %r24, 0(%r26) +16: sth %r24, 0(%r26) b cas2_end copy %r0, %r28 nop nop /* 32bit CAS */ -17: ldw,ma 0(%r26), %r29 +17: ldw 0(%r26), %r29 sub,= %r29, %r25, %r0 b,n cas2_end -18: stw,ma %r24, 0(%r26) +18: stw %r24, 0(%r26) b cas2_end copy %r0, %r28 nop @@ -825,10 +827,10 @@ cas2_action: /* 64bit CAS */ #ifdef CONFIG_64BIT -19: ldd,ma 0(%r26), %r29 +19: ldd 0(%r26), %r29 sub,*= %r29, %r25, %r0 b,n cas2_end -20: std,ma %r24, 0(%r26) +20: std %r24, 0(%r26) copy %r0, %r28 #else /* Compare first word */ @@ -846,7 +848,8 @@ cas2_action: cas2_end: /* Free lock */ - stw,ma %r20, 0(%sr2,%r20) + sync + stw %r20, 0(%sr2,%r20) /* Enable interrupts */ ssm PSW_SM_I, %r0 /* Return to userspace, set no error */ @@ -856,6 +859,7 @@ cas2_end: 22: /* Error occurred on load or store */ /* Free lock */ + sync stw %r20, 0(%sr2,%r20) ssm PSW_SM_I, %r0 ldo 1(%r0),%r28 diff --git a/arch/powerpc/include/asm/firmware.h b/arch/powerpc/include/asm/firmware.h index e05808a328db2..b0629249778b3 100644 --- a/arch/powerpc/include/asm/firmware.h +++ b/arch/powerpc/include/asm/firmware.h @@ -47,12 +47,10 @@ #define FW_FEATURE_VPHN ASM_CONST(0x0000000004000000) #define FW_FEATURE_XCMO ASM_CONST(0x0000000008000000) #define FW_FEATURE_OPAL ASM_CONST(0x0000000010000000) -#define FW_FEATURE_OPALv2 ASM_CONST(0x0000000020000000) #define FW_FEATURE_SET_MODE ASM_CONST(0x0000000040000000) #define FW_FEATURE_BEST_ENERGY ASM_CONST(0x0000000080000000) #define FW_FEATURE_TYPE1_AFFINITY ASM_CONST(0x0000000100000000) #define FW_FEATURE_PRRN ASM_CONST(0x0000000200000000) -#define FW_FEATURE_OPALv3 ASM_CONST(0x0000000400000000) #ifndef __ASSEMBLY__ @@ -70,8 +68,7 @@ enum { FW_FEATURE_SET_MODE | FW_FEATURE_BEST_ENERGY | FW_FEATURE_TYPE1_AFFINITY | FW_FEATURE_PRRN, FW_FEATURE_PSERIES_ALWAYS = 0, - FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL | FW_FEATURE_OPALv2 | - FW_FEATURE_OPALv3, + FW_FEATURE_POWERNV_POSSIBLE = FW_FEATURE_OPAL, FW_FEATURE_POWERNV_ALWAYS = 0, FW_FEATURE_PS3_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1, FW_FEATURE_PS3_ALWAYS = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1, diff --git a/arch/powerpc/include/asm/futex.h b/arch/powerpc/include/asm/futex.h index 2a9cf845473bb..f4c7467f74655 100644 --- a/arch/powerpc/include/asm/futex.h +++ b/arch/powerpc/include/asm/futex.h @@ -31,18 +31,10 @@ : "b" (uaddr), "i" (-EFAULT), "r" (oparg) \ : "cr0", "memory") -static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) +static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, + u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; pagefault_disable(); @@ -68,17 +60,9 @@ static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/powerpc/include/asm/irq_work.h b/arch/powerpc/include/asm/irq_work.h index 744fd54de3741..1bcc84903930e 100644 --- a/arch/powerpc/include/asm/irq_work.h +++ b/arch/powerpc/include/asm/irq_work.h @@ -5,5 +5,6 @@ static inline bool arch_irq_work_has_interrupt(void) { return true; } +extern void arch_irq_work_raise(void); #endif /* _ASM_POWERPC_IRQ_WORK_H */ diff --git a/arch/powerpc/kernel/cpu_setup_power.S b/arch/powerpc/kernel/cpu_setup_power.S index 9c9b7411b28bb..55eb3b752ca04 100644 --- a/arch/powerpc/kernel/cpu_setup_power.S +++ b/arch/powerpc/kernel/cpu_setup_power.S @@ -27,6 +27,7 @@ _GLOBAL(__setup_cpu_power7) beqlr li r0,0 mtspr SPRN_LPID,r0 + mtspr SPRN_PCR,r0 mfspr r3,SPRN_LPCR bl __init_LPCR bl __init_tlb_power7 @@ -40,6 +41,7 @@ _GLOBAL(__restore_cpu_power7) beqlr li r0,0 mtspr SPRN_LPID,r0 + mtspr SPRN_PCR,r0 mfspr r3,SPRN_LPCR bl __init_LPCR bl __init_tlb_power7 @@ -55,6 +57,7 @@ _GLOBAL(__setup_cpu_power8) beqlr li r0,0 mtspr SPRN_LPID,r0 + mtspr SPRN_PCR,r0 mfspr r3,SPRN_LPCR ori r3, r3, LPCR_PECEDH bl __init_LPCR @@ -74,6 +77,7 @@ _GLOBAL(__restore_cpu_power8) beqlr li r0,0 mtspr SPRN_LPID,r0 + mtspr SPRN_PCR,r0 mfspr r3,SPRN_LPCR ori r3, r3, LPCR_PECEDH bl __init_LPCR diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 2837232bbffb9..59be969173696 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -574,6 +574,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) * actually hit this code path. */ + isync slbie r6 slbie r6 /* Workaround POWER5 < DD2.1 issue */ slbmte r7,r0 diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c index 26d091a1a54cf..791d4c3329c3a 100644 --- a/arch/powerpc/kernel/fadump.c +++ b/arch/powerpc/kernel/fadump.c @@ -1025,6 +1025,9 @@ void fadump_cleanup(void) init_fadump_mem_struct(&fdm, be64_to_cpu(fdm_active->cpu_state_data.destination_address)); fadump_invalidate_dump(&fdm); + } else if (fw_dump.dump_registered) { + /* Un-register Firmware-assisted dump if it was registered. */ + fadump_unregister_dump(&fdm); } } diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index 78c1eba4c04a4..01e274e6907b1 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -720,7 +720,7 @@ start_here: tovirt(r6,r6) lis r5, abatron_pteptrs@h ori r5, r5, abatron_pteptrs@l - stw r5, 0xf0(r0) /* Must match your Abatron config file */ + stw r5, 0xf0(0) /* Must match your Abatron config file */ tophys(r5,r5) stw r6, 0(r5) diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c index fdf48785d3e9f..56e4571e3a023 100644 --- a/arch/powerpc/kernel/hw_breakpoint.c +++ b/arch/powerpc/kernel/hw_breakpoint.c @@ -174,8 +174,8 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp) if (cpu_has_feature(CPU_FTR_DAWR)) { length_max = 512 ; /* 64 doublewords */ /* DAWR region can't cross 512 boundary */ - if ((bp->attr.bp_addr >> 10) != - ((bp->attr.bp_addr + bp->attr.bp_len - 1) >> 10)) + if ((bp->attr.bp_addr >> 9) != + ((bp->attr.bp_addr + bp->attr.bp_len - 1) >> 9)) return -EINVAL; } if (info->len > diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c index 1f7930037cb7d..d9e41b77dd13e 100644 --- a/arch/powerpc/kernel/pci_32.c +++ b/arch/powerpc/kernel/pci_32.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index b38fd081b2223..3b63655efa3c5 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c @@ -1004,6 +1004,7 @@ static int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, /* Create a new breakpoint request if one doesn't exist already */ hw_breakpoint_init(&attr); attr.bp_addr = hw_brk.address; + attr.bp_len = 8; arch_bp_generic_fields(hw_brk.type, &attr.bp_type); diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index 44c8d03558ac4..3182247841143 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -217,14 +217,6 @@ static int show_cpuinfo(struct seq_file *m, void *v) unsigned short maj; unsigned short min; - /* We only show online cpus: disable preempt (overzealous, I - * knew) to prevent cpu going down. */ - preempt_disable(); - if (!cpu_online(cpu_id)) { - preempt_enable(); - return 0; - } - #ifdef CONFIG_SMP pvr = per_cpu(cpu_pvr, cpu_id); #else @@ -329,9 +321,6 @@ static int show_cpuinfo(struct seq_file *m, void *v) #ifdef CONFIG_SMP seq_printf(m, "\n"); #endif - - preempt_enable(); - /* If this is the last cpu, print the summary */ if (cpumask_next(cpu_id, cpu_online_mask) >= nr_cpu_ids) show_cpuinfo_summary(m); diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 428563b195c31..767ac1572c02d 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -3002,15 +3002,17 @@ static int kvmppc_hv_setup_htab_rma(struct kvm_vcpu *vcpu) goto up_out; psize = vma_kernel_pagesize(vma); - porder = __ilog2(psize); up_read(¤t->mm->mmap_sem); /* We can handle 4k, 64k or 16M pages in the VRMA */ - err = -EINVAL; - if (!(psize == 0x1000 || psize == 0x10000 || - psize == 0x1000000)) - goto out_srcu; + if (psize >= 0x1000000) + psize = 0x1000000; + else if (psize >= 0x10000) + psize = 0x10000; + else + psize = 0x1000; + porder = __ilog2(psize); /* Update VRMASD field in the LPCR */ senc = slb_pgsize_encoding(psize); diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 669a15e7fa76a..3c4faa4c2742b 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -551,7 +551,7 @@ static int numa_setup_cpu(unsigned long lcpu) nid = of_node_to_nid_single(cpu); out_present: - if (nid < 0 || !node_online(nid)) + if (nid < 0 || !node_possible(nid)) nid = first_online_node; map_cpu_to_node(lcpu, nid); @@ -951,6 +951,32 @@ static void __init setup_node_data(int nid, u64 start_pfn, u64 end_pfn) NODE_DATA(nid)->node_spanned_pages = spanned_pages; } +static void __init find_possible_nodes(void) +{ + struct device_node *rtas; + u32 numnodes, i; + + if (min_common_depth <= 0) + return; + + rtas = of_find_node_by_path("/rtas"); + if (!rtas) + return; + + if (of_property_read_u32_index(rtas, + "ibm,max-associativity-domains", + min_common_depth, &numnodes)) + goto out; + + for (i = 0; i < numnodes; i++) { + if (!node_possible(i)) + node_set(i, node_possible_map); + } + +out: + of_node_put(rtas); +} + void __init initmem_init(void) { int nid, cpu; @@ -966,12 +992,15 @@ void __init initmem_init(void) memblock_dump_all(); /* - * Reduce the possible NUMA nodes to the online NUMA nodes, - * since we do not support node hotplug. This ensures that we - * lower the maximum NUMA node ID to what is actually present. + * Modify the set of possible NUMA nodes to reflect information + * available about the set of online nodes, and the set of nodes + * that we expect to make use of for this platform's affinity + * calculations. */ nodes_and(node_possible_map, node_possible_map, node_online_map); + find_possible_nodes(); + for_each_online_node(nid) { unsigned long start_pfn, end_pfn; @@ -1304,6 +1333,40 @@ static long vphn_get_associativity(unsigned long cpu, return rc; } +static inline int find_and_online_cpu_nid(int cpu) +{ + __be32 associativity[VPHN_ASSOC_BUFSIZE] = {0}; + int new_nid; + + /* Use associativity from first thread for all siblings */ + vphn_get_associativity(cpu, associativity); + new_nid = associativity_to_nid(associativity); + if (new_nid < 0 || !node_possible(new_nid)) + new_nid = first_online_node; + + if (NODE_DATA(new_nid) == NULL) { +#ifdef CONFIG_MEMORY_HOTPLUG + /* + * Need to ensure that NODE_DATA is initialized for a node from + * available memory (see memblock_alloc_try_nid). If unable to + * init the node, then default to nearest node that has memory + * installed. + */ + if (try_online_node(new_nid)) + new_nid = first_online_node; +#else + /* + * Default to using the nearest node that has memory installed. + * Otherwise, it would be necessary to patch the kernel MM code + * to deal with more memoryless-node error conditions. + */ + new_nid = first_online_node; +#endif + } + + return new_nid; +} + /* * Update the CPU maps and sysfs entries for a single CPU when its NUMA * characteristics change. This function doesn't perform any locking and is @@ -1369,7 +1432,6 @@ int arch_update_cpu_topology(void) { unsigned int cpu, sibling, changed = 0; struct topology_update_data *updates, *ud; - __be32 associativity[VPHN_ASSOC_BUFSIZE] = {0}; cpumask_t updated_cpus; struct device *dev; int weight, new_nid, i = 0; @@ -1404,11 +1466,7 @@ int arch_update_cpu_topology(void) continue; } - /* Use associativity from first thread for all siblings */ - vphn_get_associativity(cpu, associativity); - new_nid = associativity_to_nid(associativity); - if (new_nid < 0 || !node_online(new_nid)) - new_nid = first_online_node; + new_nid = find_and_online_cpu_nid(cpu); if (new_nid == numa_cpu_lookup_table[cpu]) { cpumask_andnot(&cpu_associativity_changes_mask, diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c index 515730e499fe6..309027208f7c0 100644 --- a/arch/powerpc/mm/slb.c +++ b/arch/powerpc/mm/slb.c @@ -69,14 +69,14 @@ static inline void slb_shadow_update(unsigned long ea, int ssize, * updating it. No write barriers are needed here, provided * we only update the current CPU's SLB shadow buffer. */ - p->save_area[index].esid = 0; - p->save_area[index].vsid = cpu_to_be64(mk_vsid_data(ea, ssize, flags)); - p->save_area[index].esid = cpu_to_be64(mk_esid_data(ea, ssize, index)); + WRITE_ONCE(p->save_area[index].esid, 0); + WRITE_ONCE(p->save_area[index].vsid, cpu_to_be64(mk_vsid_data(ea, ssize, flags))); + WRITE_ONCE(p->save_area[index].esid, cpu_to_be64(mk_esid_data(ea, ssize, index))); } static inline void slb_shadow_clear(enum slb_index index) { - get_slb_shadow()->save_area[index].esid = 0; + WRITE_ONCE(get_slb_shadow()->save_area[index].esid, 0); } static inline void create_shadowed_slbe(unsigned long ea, int ssize, diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c index 2d66a8446198d..345e255c06a25 100644 --- a/arch/powerpc/net/bpf_jit_comp.c +++ b/arch/powerpc/net/bpf_jit_comp.c @@ -329,6 +329,9 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4); PPC_LWZ_OFFS(r_A, r_skb, offsetof(struct sk_buff, len)); break; + case BPF_LDX | BPF_W | BPF_ABS: /* A = *((u32 *)(seccomp_data + K)); */ + PPC_LWZ_OFFS(r_A, r_skb, K); + break; case BPF_LDX | BPF_W | BPF_LEN: /* X = skb->len; */ PPC_LWZ_OFFS(r_X, r_skb, offsetof(struct sk_buff, len)); break; diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c index 4eba7c00ea1fb..30e2e8efbe6b7 100644 --- a/arch/powerpc/perf/core-book3s.c +++ b/arch/powerpc/perf/core-book3s.c @@ -448,6 +448,16 @@ static void power_pmu_bhrb_read(struct cpu_hw_events *cpuhw) /* invalid entry */ continue; + /* + * BHRB rolling buffer could very much contain the kernel + * addresses at this point. Check the privileges before + * exporting it to userspace (avoid exposure of regions + * where we could have speculative execution) + */ + if (perf_paranoid_kernel() && !capable(CAP_SYS_ADMIN) && + is_kernel_addr(addr)) + continue; + /* Branches are read most recent first (ie. mfbhrb 0 is * the most recent branch). * There are two types of valid entries: @@ -1188,6 +1198,7 @@ static void power_pmu_disable(struct pmu *pmu) */ write_mmcr0(cpuhw, val); mb(); + isync(); /* * Disable instruction sampling if it was enabled @@ -1196,12 +1207,26 @@ static void power_pmu_disable(struct pmu *pmu) mtspr(SPRN_MMCRA, cpuhw->mmcr[2] & ~MMCRA_SAMPLE_ENABLE); mb(); + isync(); } cpuhw->disabled = 1; cpuhw->n_added = 0; ebb_switch_out(mmcr0); + +#ifdef CONFIG_PPC64 + /* + * These are readable by userspace, may contain kernel + * addresses and are not switched by context switch, so clear + * them now to avoid leaking anything to userspace in general + * including to another process. + */ + if (ppmu->flags & PPMU_ARCH_207S) { + mtspr(SPRN_SDAR, 0); + mtspr(SPRN_SIAR, 0); + } +#endif } local_irq_restore(flags); diff --git a/arch/powerpc/platforms/chrp/time.c b/arch/powerpc/platforms/chrp/time.c index f803f4b8ab6f2..8608e358217f3 100644 --- a/arch/powerpc/platforms/chrp/time.c +++ b/arch/powerpc/platforms/chrp/time.c @@ -27,6 +27,8 @@ #include #include +#include + extern spinlock_t rtc_lock; #define NVRAM_AS0 0x74 @@ -62,7 +64,7 @@ long __init chrp_time_init(void) return 0; } -int chrp_cmos_clock_read(int addr) +static int chrp_cmos_clock_read(int addr) { if (nvram_as1 != 0) outb(addr>>8, nvram_as1); @@ -70,7 +72,7 @@ int chrp_cmos_clock_read(int addr) return (inb(nvram_data)); } -void chrp_cmos_clock_write(unsigned long val, int addr) +static void chrp_cmos_clock_write(unsigned long val, int addr) { if (nvram_as1 != 0) outb(addr>>8, nvram_as1); diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c index 9b7975706bfc7..9485f1024d46c 100644 --- a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c +++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c @@ -35,6 +35,8 @@ */ #define HW_BROADWAY_ICR 0x00 #define HW_BROADWAY_IMR 0x04 +#define HW_STARLET_ICR 0x08 +#define HW_STARLET_IMR 0x0c /* @@ -74,6 +76,9 @@ static void hlwd_pic_unmask(struct irq_data *d) void __iomem *io_base = irq_data_get_irq_chip_data(d); setbits32(io_base + HW_BROADWAY_IMR, 1 << irq); + + /* Make sure the ARM (aka. Starlet) doesn't handle this interrupt. */ + clrbits32(io_base + HW_STARLET_IMR, 1 << irq); } diff --git a/arch/powerpc/platforms/powermac/bootx_init.c b/arch/powerpc/platforms/powermac/bootx_init.c index 76f5013c35e5c..89237b84b0962 100644 --- a/arch/powerpc/platforms/powermac/bootx_init.c +++ b/arch/powerpc/platforms/powermac/bootx_init.c @@ -467,7 +467,7 @@ void __init bootx_init(unsigned long r3, unsigned long r4) boot_infos_t *bi = (boot_infos_t *) r4; unsigned long hdr; unsigned long space; - unsigned long ptr, x; + unsigned long ptr; char *model; unsigned long offset = reloc_offset(); @@ -561,6 +561,8 @@ void __init bootx_init(unsigned long r3, unsigned long r4) * MMU switched OFF, so this should not be useful anymore. */ if (bi->version < 4) { + unsigned long x __maybe_unused; + bootx_printf("Touching pages...\n"); /* diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index 8dd78f4e1af4a..32fc56cf62618 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c @@ -359,6 +359,7 @@ static int pmac_late_init(void) } machine_late_initcall(powermac, pmac_late_init); +void note_bootable_part(dev_t dev, int part, int goodness); /* * This is __init_refok because we check for "initializing" before * touching any of the __init sensitive things and "initializing" diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c index 92736851c795a..3f653f5201e7b 100644 --- a/arch/powerpc/platforms/powernv/eeh-powernv.c +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c @@ -48,8 +48,8 @@ static int pnv_eeh_init(void) struct pci_controller *hose; struct pnv_phb *phb; - if (!firmware_has_feature(FW_FEATURE_OPALv3)) { - pr_warn("%s: OPALv3 is required !\n", + if (!firmware_has_feature(FW_FEATURE_OPAL)) { + pr_warn("%s: OPAL is required !\n", __func__); return -EINVAL; } diff --git a/arch/powerpc/platforms/powernv/idle.c b/arch/powerpc/platforms/powernv/idle.c index 59d735d2e5c05..15bfbcd5debc2 100644 --- a/arch/powerpc/platforms/powernv/idle.c +++ b/arch/powerpc/platforms/powernv/idle.c @@ -242,7 +242,7 @@ static int __init pnv_init_idle_states(void) if (cpuidle_disable != IDLE_NO_OVERRIDE) goto out; - if (!firmware_has_feature(FW_FEATURE_OPALv3)) + if (!firmware_has_feature(FW_FEATURE_OPAL)) goto out; power_mgt = of_find_node_by_path("/ibm,opal/power-mgt"); diff --git a/arch/powerpc/platforms/powernv/opal-nvram.c b/arch/powerpc/platforms/powernv/opal-nvram.c index 1bceb95f422d0..5584247f50292 100644 --- a/arch/powerpc/platforms/powernv/opal-nvram.c +++ b/arch/powerpc/platforms/powernv/opal-nvram.c @@ -44,6 +44,10 @@ static ssize_t opal_nvram_read(char *buf, size_t count, loff_t *index) return count; } +/* + * This can be called in the panic path with interrupts off, so use + * mdelay in that case. + */ static ssize_t opal_nvram_write(char *buf, size_t count, loff_t *index) { s64 rc = OPAL_BUSY; @@ -58,10 +62,16 @@ static ssize_t opal_nvram_write(char *buf, size_t count, loff_t *index) while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) { rc = opal_write_nvram(__pa(buf), count, off); if (rc == OPAL_BUSY_EVENT) { - msleep(OPAL_BUSY_DELAY_MS); + if (in_interrupt() || irqs_disabled()) + mdelay(OPAL_BUSY_DELAY_MS); + else + msleep(OPAL_BUSY_DELAY_MS); opal_poll_events(NULL); } else if (rc == OPAL_BUSY) { - msleep(OPAL_BUSY_DELAY_MS); + if (in_interrupt() || irqs_disabled()) + mdelay(OPAL_BUSY_DELAY_MS); + else + msleep(OPAL_BUSY_DELAY_MS); } } diff --git a/arch/powerpc/platforms/powernv/opal-xscom.c b/arch/powerpc/platforms/powernv/opal-xscom.c index 7634d1c62299b..d0ac535cf5d7c 100644 --- a/arch/powerpc/platforms/powernv/opal-xscom.c +++ b/arch/powerpc/platforms/powernv/opal-xscom.c @@ -126,7 +126,7 @@ static const struct scom_controller opal_scom_controller = { static int opal_xscom_init(void) { - if (firmware_has_feature(FW_FEATURE_OPALv3)) + if (firmware_has_feature(FW_FEATURE_OPAL)) scom_init(&opal_scom_controller); return 0; } diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index ae29eaf85e9e2..e48826aa314c3 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c @@ -98,16 +98,11 @@ int __init early_init_dt_scan_opal(unsigned long node, pr_debug("OPAL Entry = 0x%llx (sizep=%p runtimesz=%d)\n", opal.size, sizep, runtimesz); - powerpc_firmware_features |= FW_FEATURE_OPAL; if (of_flat_dt_is_compatible(node, "ibm,opal-v3")) { - powerpc_firmware_features |= FW_FEATURE_OPALv2; - powerpc_firmware_features |= FW_FEATURE_OPALv3; - pr_info("OPAL V3 detected !\n"); - } else if (of_flat_dt_is_compatible(node, "ibm,opal-v2")) { - powerpc_firmware_features |= FW_FEATURE_OPALv2; - pr_info("OPAL V2 detected !\n"); + powerpc_firmware_features |= FW_FEATURE_OPAL; + pr_info("OPAL detected !\n"); } else { - pr_info("OPAL V1 detected !\n"); + panic("OPAL != V3 detected, no longer supported.\n"); } /* Reinit all cores with the right endian */ @@ -352,17 +347,15 @@ int opal_put_chars(uint32_t vtermno, const char *data, int total_len) * enough room and be done with it */ spin_lock_irqsave(&opal_write_lock, flags); - if (firmware_has_feature(FW_FEATURE_OPALv2)) { - rc = opal_console_write_buffer_space(vtermno, &olen); - len = be64_to_cpu(olen); - if (rc || len < total_len) { - spin_unlock_irqrestore(&opal_write_lock, flags); - /* Closed -> drop characters */ - if (rc) - return total_len; - opal_poll_events(NULL); - return -EAGAIN; - } + rc = opal_console_write_buffer_space(vtermno, &olen); + len = be64_to_cpu(olen); + if (rc || len < total_len) { + spin_unlock_irqrestore(&opal_write_lock, flags); + /* Closed -> drop characters */ + if (rc) + return total_len; + opal_poll_events(NULL); + return -EAGAIN; } /* We still try to handle partial completions, though they @@ -696,10 +689,7 @@ static int __init opal_init(void) } /* Register OPAL consoles if any ports */ - if (firmware_has_feature(FW_FEATURE_OPALv2)) - consoles = of_find_node_by_path("/ibm,opal/consoles"); - else - consoles = of_node_get(opal_node); + consoles = of_find_node_by_path("/ibm,opal/consoles"); if (consoles) { for_each_child_of_node(consoles, np) { if (strcmp(np->name, "serial")) diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index ecb7f3220355b..eac3b7cc78c6f 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -344,7 +344,7 @@ static void __init pnv_ioda_parse_m64_window(struct pnv_phb *phb) return; } - if (!firmware_has_feature(FW_FEATURE_OPALv3)) { + if (!firmware_has_feature(FW_FEATURE_OPAL)) { pr_info(" Firmware too old to support M64 window\n"); return; } diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c index 30c6b3b7be902..c57afc619b204 100644 --- a/arch/powerpc/platforms/powernv/setup.c +++ b/arch/powerpc/platforms/powernv/setup.c @@ -140,12 +140,8 @@ static void pnv_show_cpuinfo(struct seq_file *m) if (root) model = of_get_property(root, "model", NULL); seq_printf(m, "machine\t\t: PowerNV %s\n", model); - if (firmware_has_feature(FW_FEATURE_OPALv3)) - seq_printf(m, "firmware\t: OPAL v3\n"); - else if (firmware_has_feature(FW_FEATURE_OPALv2)) - seq_printf(m, "firmware\t: OPAL v2\n"); - else if (firmware_has_feature(FW_FEATURE_OPAL)) - seq_printf(m, "firmware\t: OPAL v1\n"); + if (firmware_has_feature(FW_FEATURE_OPAL)) + seq_printf(m, "firmware\t: OPAL\n"); else seq_printf(m, "firmware\t: BML\n"); of_node_put(root); @@ -274,9 +270,9 @@ static void pnv_kexec_cpu_down(int crash_shutdown, int secondary) { xics_kexec_teardown_cpu(secondary); - /* On OPAL v3, we return all CPUs to firmware */ + /* On OPAL, we return all CPUs to firmware */ - if (!firmware_has_feature(FW_FEATURE_OPALv3)) + if (!firmware_has_feature(FW_FEATURE_OPAL)) return; if (secondary) { diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c index ca264833ee64d..ad7b1a3dbed09 100644 --- a/arch/powerpc/platforms/powernv/smp.c +++ b/arch/powerpc/platforms/powernv/smp.c @@ -61,14 +61,15 @@ static int pnv_smp_kick_cpu(int nr) unsigned long start_here = __pa(ppc_function_entry(generic_secondary_smp_init)); long rc; + uint8_t status; BUG_ON(nr < 0 || nr >= NR_CPUS); /* - * If we already started or OPALv2 is not supported, we just + * If we already started or OPAL is not supported, we just * kick the CPU via the PACA */ - if (paca[nr].cpu_start || !firmware_has_feature(FW_FEATURE_OPALv2)) + if (paca[nr].cpu_start || !firmware_has_feature(FW_FEATURE_OPAL)) goto kick; /* @@ -77,55 +78,42 @@ static int pnv_smp_kick_cpu(int nr) * first time. OPAL v3 allows us to query OPAL to know if it * has the CPUs, so we do that */ - if (firmware_has_feature(FW_FEATURE_OPALv3)) { - uint8_t status; - - rc = opal_query_cpu_status(pcpu, &status); - if (rc != OPAL_SUCCESS) { - pr_warn("OPAL Error %ld querying CPU %d state\n", - rc, nr); - return -ENODEV; - } + rc = opal_query_cpu_status(pcpu, &status); + if (rc != OPAL_SUCCESS) { + pr_warn("OPAL Error %ld querying CPU %d state\n", rc, nr); + return -ENODEV; + } - /* - * Already started, just kick it, probably coming from - * kexec and spinning - */ - if (status == OPAL_THREAD_STARTED) - goto kick; + /* + * Already started, just kick it, probably coming from + * kexec and spinning + */ + if (status == OPAL_THREAD_STARTED) + goto kick; - /* - * Available/inactive, let's kick it - */ - if (status == OPAL_THREAD_INACTIVE) { - pr_devel("OPAL: Starting CPU %d (HW 0x%x)...\n", - nr, pcpu); - rc = opal_start_cpu(pcpu, start_here); - if (rc != OPAL_SUCCESS) { - pr_warn("OPAL Error %ld starting CPU %d\n", - rc, nr); - return -ENODEV; - } - } else { - /* - * An unavailable CPU (or any other unknown status) - * shouldn't be started. It should also - * not be in the possible map but currently it can - * happen - */ - pr_devel("OPAL: CPU %d (HW 0x%x) is unavailable" - " (status %d)...\n", nr, pcpu, status); + /* + * Available/inactive, let's kick it + */ + if (status == OPAL_THREAD_INACTIVE) { + pr_devel("OPAL: Starting CPU %d (HW 0x%x)...\n", nr, pcpu); + rc = opal_start_cpu(pcpu, start_here); + if (rc != OPAL_SUCCESS) { + pr_warn("OPAL Error %ld starting CPU %d\n", rc, nr); return -ENODEV; } } else { /* - * On OPAL v2, we just kick it and hope for the best, - * we must not test the error from opal_start_cpu() or - * we would fail to get CPUs from kexec. + * An unavailable CPU (or any other unknown status) + * shouldn't be started. It should also + * not be in the possible map but currently it can + * happen */ - opal_start_cpu(pcpu, start_here); + pr_devel("OPAL: CPU %d (HW 0x%x) is unavailable" + " (status %d)...\n", nr, pcpu, status); + return -ENODEV; } - kick: + +kick: return smp_generic_kick_cpu(nr); } diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 2a0452e364ba7..d11f931cac694 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -626,7 +626,7 @@ static inline u32 mpic_physmask(u32 cpumask) int i; u32 mask = 0; - for (i = 0; i < min(32, NR_CPUS); ++i, cpumask >>= 1) + for (i = 0; i < min(32, NR_CPUS) && cpu_possible(i); ++i, cpumask >>= 1) mask |= (cpumask & 1) << get_hard_smp_processor_id(i); return mask; } diff --git a/arch/s390/include/asm/alternative-asm.h b/arch/s390/include/asm/alternative-asm.h new file mode 100644 index 0000000000000..955d620db23ed --- /dev/null +++ b/arch/s390/include/asm/alternative-asm.h @@ -0,0 +1,108 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_S390_ALTERNATIVE_ASM_H +#define _ASM_S390_ALTERNATIVE_ASM_H + +#ifdef __ASSEMBLY__ + +/* + * Check the length of an instruction sequence. The length may not be larger + * than 254 bytes and it has to be divisible by 2. + */ +.macro alt_len_check start,end + .if ( \end - \start ) > 254 + .error "cpu alternatives does not support instructions blocks > 254 bytes\n" + .endif + .if ( \end - \start ) % 2 + .error "cpu alternatives instructions length is odd\n" + .endif +.endm + +/* + * Issue one struct alt_instr descriptor entry (need to put it into + * the section .altinstructions, see below). This entry contains + * enough information for the alternatives patching code to patch an + * instruction. See apply_alternatives(). + */ +.macro alt_entry orig_start, orig_end, alt_start, alt_end, feature + .long \orig_start - . + .long \alt_start - . + .word \feature + .byte \orig_end - \orig_start + .byte \alt_end - \alt_start +.endm + +/* + * Fill up @bytes with nops. The macro emits 6-byte nop instructions + * for the bulk of the area, possibly followed by a 4-byte and/or + * a 2-byte nop if the size of the area is not divisible by 6. + */ +.macro alt_pad_fill bytes + .fill ( \bytes ) / 6, 6, 0xc0040000 + .fill ( \bytes ) % 6 / 4, 4, 0x47000000 + .fill ( \bytes ) % 6 % 4 / 2, 2, 0x0700 +.endm + +/* + * Fill up @bytes with nops. If the number of bytes is larger + * than 6, emit a jg instruction to branch over all nops, then + * fill an area of size (@bytes - 6) with nop instructions. + */ +.macro alt_pad bytes + .if ( \bytes > 0 ) + .if ( \bytes > 6 ) + jg . + \bytes + alt_pad_fill \bytes - 6 + .else + alt_pad_fill \bytes + .endif + .endif +.endm + +/* + * Define an alternative between two instructions. If @feature is + * present, early code in apply_alternatives() replaces @oldinstr with + * @newinstr. ".skip" directive takes care of proper instruction padding + * in case @newinstr is longer than @oldinstr. + */ +.macro ALTERNATIVE oldinstr, newinstr, feature + .pushsection .altinstr_replacement,"ax" +770: \newinstr +771: .popsection +772: \oldinstr +773: alt_len_check 770b, 771b + alt_len_check 772b, 773b + alt_pad ( ( 771b - 770b ) - ( 773b - 772b ) ) +774: .pushsection .altinstructions,"a" + alt_entry 772b, 774b, 770b, 771b, \feature + .popsection +.endm + +/* + * Define an alternative between two instructions. If @feature is + * present, early code in apply_alternatives() replaces @oldinstr with + * @newinstr. ".skip" directive takes care of proper instruction padding + * in case @newinstr is longer than @oldinstr. + */ +.macro ALTERNATIVE_2 oldinstr, newinstr1, feature1, newinstr2, feature2 + .pushsection .altinstr_replacement,"ax" +770: \newinstr1 +771: \newinstr2 +772: .popsection +773: \oldinstr +774: alt_len_check 770b, 771b + alt_len_check 771b, 772b + alt_len_check 773b, 774b + .if ( 771b - 770b > 772b - 771b ) + alt_pad ( ( 771b - 770b ) - ( 774b - 773b ) ) + .else + alt_pad ( ( 772b - 771b ) - ( 774b - 773b ) ) + .endif +775: .pushsection .altinstructions,"a" + alt_entry 773b, 775b, 770b, 771b,\feature1 + alt_entry 773b, 775b, 771b, 772b,\feature2 + .popsection +.endm + +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_S390_ALTERNATIVE_ASM_H */ diff --git a/arch/s390/include/asm/cpu_mf.h b/arch/s390/include/asm/cpu_mf.h index 9dd04b9e97821..b2f8c52b38401 100644 --- a/arch/s390/include/asm/cpu_mf.h +++ b/arch/s390/include/asm/cpu_mf.h @@ -113,7 +113,7 @@ struct hws_basic_entry { struct hws_diag_entry { unsigned int def:16; /* 0-15 Data Entry Format */ - unsigned int R:14; /* 16-19 and 20-30 reserved */ + unsigned int R:15; /* 16-19 and 20-30 reserved */ unsigned int I:1; /* 31 entry valid or invalid */ u8 data[]; /* Machine-dependent sample data */ } __packed; @@ -129,7 +129,9 @@ struct hws_trailer_entry { unsigned int f:1; /* 0 - Block Full Indicator */ unsigned int a:1; /* 1 - Alert request control */ unsigned int t:1; /* 2 - Timestamp format */ - unsigned long long:61; /* 3 - 63: Reserved */ + unsigned int :29; /* 3 - 31: Reserved */ + unsigned int bsdes:16; /* 32-47: size of basic SDE */ + unsigned int dsdes:16; /* 48-63: size of diagnostic SDE */ }; unsigned long long flags; /* 0 - 63: All indicators */ }; diff --git a/arch/s390/include/asm/futex.h b/arch/s390/include/asm/futex.h index a4811aa0304d0..8f8eec9e1198c 100644 --- a/arch/s390/include/asm/futex.h +++ b/arch/s390/include/asm/futex.h @@ -21,17 +21,12 @@ : "0" (-EFAULT), "d" (oparg), "a" (uaddr), \ "m" (*uaddr) : "cc"); -static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) +static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, + u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, newval, ret; load_kernel_asce(); - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; pagefault_disable(); switch (op) { @@ -60,17 +55,9 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) } pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/s390/include/asm/nospec-insn.h b/arch/s390/include/asm/nospec-insn.h new file mode 100644 index 0000000000000..9a56e738d645a --- /dev/null +++ b/arch/s390/include/asm/nospec-insn.h @@ -0,0 +1,195 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_S390_NOSPEC_ASM_H +#define _ASM_S390_NOSPEC_ASM_H + +#include +#include + +#ifdef __ASSEMBLY__ + +#ifdef CONFIG_EXPOLINE + +_LC_BR_R1 = __LC_BR_R1 + +/* + * The expoline macros are used to create thunks in the same format + * as gcc generates them. The 'comdat' section flag makes sure that + * the various thunks are merged into a single copy. + */ + .macro __THUNK_PROLOG_NAME name + .pushsection .text.\name,"axG",@progbits,\name,comdat + .globl \name + .hidden \name + .type \name,@function +\name: + .cfi_startproc + .endm + + .macro __THUNK_EPILOG + .cfi_endproc + .popsection + .endm + + .macro __THUNK_PROLOG_BR r1,r2 + __THUNK_PROLOG_NAME __s390x_indirect_jump_r\r2\()use_r\r1 + .endm + + .macro __THUNK_PROLOG_BC d0,r1,r2 + __THUNK_PROLOG_NAME __s390x_indirect_branch_\d0\()_\r2\()use_\r1 + .endm + + .macro __THUNK_BR r1,r2 + jg __s390x_indirect_jump_r\r2\()use_r\r1 + .endm + + .macro __THUNK_BC d0,r1,r2 + jg __s390x_indirect_branch_\d0\()_\r2\()use_\r1 + .endm + + .macro __THUNK_BRASL r1,r2,r3 + brasl \r1,__s390x_indirect_jump_r\r3\()use_r\r2 + .endm + + .macro __DECODE_RR expand,reg,ruse + .set __decode_fail,1 + .irp r1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 + .ifc \reg,%r\r1 + .irp r2,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 + .ifc \ruse,%r\r2 + \expand \r1,\r2 + .set __decode_fail,0 + .endif + .endr + .endif + .endr + .if __decode_fail == 1 + .error "__DECODE_RR failed" + .endif + .endm + + .macro __DECODE_RRR expand,rsave,rtarget,ruse + .set __decode_fail,1 + .irp r1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 + .ifc \rsave,%r\r1 + .irp r2,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 + .ifc \rtarget,%r\r2 + .irp r3,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 + .ifc \ruse,%r\r3 + \expand \r1,\r2,\r3 + .set __decode_fail,0 + .endif + .endr + .endif + .endr + .endif + .endr + .if __decode_fail == 1 + .error "__DECODE_RRR failed" + .endif + .endm + + .macro __DECODE_DRR expand,disp,reg,ruse + .set __decode_fail,1 + .irp r1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 + .ifc \reg,%r\r1 + .irp r2,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 + .ifc \ruse,%r\r2 + \expand \disp,\r1,\r2 + .set __decode_fail,0 + .endif + .endr + .endif + .endr + .if __decode_fail == 1 + .error "__DECODE_DRR failed" + .endif + .endm + + .macro __THUNK_EX_BR reg,ruse + # Be very careful when adding instructions to this macro! + # The ALTERNATIVE replacement code has a .+10 which targets + # the "br \reg" after the code has been patched. +#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES + exrl 0,555f + j . +#else + .ifc \reg,%r1 + ALTERNATIVE "ex %r0,_LC_BR_R1", ".insn ril,0xc60000000000,0,.+10", 35 + j . + .else + larl \ruse,555f + ex 0,0(\ruse) + j . + .endif +#endif +555: br \reg + .endm + + .macro __THUNK_EX_BC disp,reg,ruse +#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES + exrl 0,556f + j . +#else + larl \ruse,556f + ex 0,0(\ruse) + j . +#endif +556: b \disp(\reg) + .endm + + .macro GEN_BR_THUNK reg,ruse=%r1 + __DECODE_RR __THUNK_PROLOG_BR,\reg,\ruse + __THUNK_EX_BR \reg,\ruse + __THUNK_EPILOG + .endm + + .macro GEN_B_THUNK disp,reg,ruse=%r1 + __DECODE_DRR __THUNK_PROLOG_BC,\disp,\reg,\ruse + __THUNK_EX_BC \disp,\reg,\ruse + __THUNK_EPILOG + .endm + + .macro BR_EX reg,ruse=%r1 +557: __DECODE_RR __THUNK_BR,\reg,\ruse + .pushsection .s390_indirect_branches,"a",@progbits + .long 557b-. + .popsection + .endm + + .macro B_EX disp,reg,ruse=%r1 +558: __DECODE_DRR __THUNK_BC,\disp,\reg,\ruse + .pushsection .s390_indirect_branches,"a",@progbits + .long 558b-. + .popsection + .endm + + .macro BASR_EX rsave,rtarget,ruse=%r1 +559: __DECODE_RRR __THUNK_BRASL,\rsave,\rtarget,\ruse + .pushsection .s390_indirect_branches,"a",@progbits + .long 559b-. + .popsection + .endm + +#else + .macro GEN_BR_THUNK reg,ruse=%r1 + .endm + + .macro GEN_B_THUNK disp,reg,ruse=%r1 + .endm + + .macro BR_EX reg,ruse=%r1 + br \reg + .endm + + .macro B_EX disp,reg,ruse=%r1 + b \disp(\reg) + .endm + + .macro BASR_EX rsave,rtarget,ruse=%r1 + basr \rsave,\rtarget + .endm +#endif + +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_S390_NOSPEC_ASM_H */ diff --git a/arch/s390/include/asm/qdio.h b/arch/s390/include/asm/qdio.h index 998b61cd0e569..4b39ba700d32f 100644 --- a/arch/s390/include/asm/qdio.h +++ b/arch/s390/include/asm/qdio.h @@ -261,7 +261,6 @@ struct qdio_outbuf_state { void *user; }; -#define QDIO_OUTBUF_STATE_FLAG_NONE 0x00 #define QDIO_OUTBUF_STATE_FLAG_PENDING 0x01 #define CHSC_AC1_INITIATE_INPUTQ 0x80 diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index 8ccfbf22ecbb0..c4d4d4ef5e581 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile @@ -49,6 +49,7 @@ obj-y += nospec-branch.o extra-y += head.o head64.o vmlinux.lds +obj-$(CONFIG_SYSFS) += nospec-sysfs.o CFLAGS_REMOVE_nospec-branch.o += $(CC_FLAGS_EXPOLINE) obj-$(CONFIG_MODULES) += s390_ksyms.o module.o diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index dc6c9c6045430..39572281e2130 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c @@ -170,6 +170,7 @@ int main(void) OFFSET(__LC_MACHINE_FLAGS, _lowcore, machine_flags); OFFSET(__LC_GMAP, _lowcore, gmap); OFFSET(__LC_PASTE, _lowcore, paste); + OFFSET(__LC_BR_R1, _lowcore, br_r1_trampoline); /* software defined ABI-relevant lowcore locations 0xe00 - 0xe20 */ OFFSET(__LC_DUMP_REIPL, _lowcore, ipib); /* hardware defined lowcore locations 0x1000 - 0x18ff */ diff --git a/arch/s390/kernel/base.S b/arch/s390/kernel/base.S index 326f717df587c..61fca549a93bd 100644 --- a/arch/s390/kernel/base.S +++ b/arch/s390/kernel/base.S @@ -8,18 +8,22 @@ #include #include +#include #include #include + GEN_BR_THUNK %r9 + GEN_BR_THUNK %r14 + ENTRY(s390_base_mcck_handler) basr %r13,0 0: lg %r15,__LC_PANIC_STACK # load panic stack aghi %r15,-STACK_FRAME_OVERHEAD larl %r1,s390_base_mcck_handler_fn - lg %r1,0(%r1) - ltgr %r1,%r1 + lg %r9,0(%r1) + ltgr %r9,%r9 jz 1f - basr %r14,%r1 + BASR_EX %r14,%r9 1: la %r1,4095 lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1) lpswe __LC_MCK_OLD_PSW @@ -36,10 +40,10 @@ ENTRY(s390_base_ext_handler) basr %r13,0 0: aghi %r15,-STACK_FRAME_OVERHEAD larl %r1,s390_base_ext_handler_fn - lg %r1,0(%r1) - ltgr %r1,%r1 + lg %r9,0(%r1) + ltgr %r9,%r9 jz 1f - basr %r14,%r1 + BASR_EX %r14,%r9 1: lmg %r0,%r15,__LC_SAVE_AREA_ASYNC ni __LC_EXT_OLD_PSW+1,0xfd # clear wait state bit lpswe __LC_EXT_OLD_PSW @@ -56,10 +60,10 @@ ENTRY(s390_base_pgm_handler) basr %r13,0 0: aghi %r15,-STACK_FRAME_OVERHEAD larl %r1,s390_base_pgm_handler_fn - lg %r1,0(%r1) - ltgr %r1,%r1 + lg %r9,0(%r1) + ltgr %r9,%r9 jz 1f - basr %r14,%r1 + BASR_EX %r14,%r9 lmg %r0,%r15,__LC_SAVE_AREA_SYNC lpswe __LC_PGM_OLD_PSW 1: lpswe disabled_wait_psw-0b(%r13) @@ -116,7 +120,7 @@ ENTRY(diag308_reset) larl %r4,.Lcontinue_psw # Restore PSW flags lpswe 0(%r4) .Lcontinue: - br %r14 + BR_EX %r14 .align 16 .Lrestart_psw: .long 0x00080000,0x80000000 + .Lrestart_part2 diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index c637303262151..4cad1adff16bf 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -23,6 +23,7 @@ #include #include #include +#include __PT_R0 = __PT_GPRS __PT_R1 = __PT_GPRS + 8 @@ -225,74 +226,16 @@ _PIF_WORK = (_PIF_PER_TRAP) .popsection .endm -#ifdef CONFIG_EXPOLINE - - .macro GEN_BR_THUNK name,reg,tmp - .section .text.\name,"axG",@progbits,\name,comdat - .globl \name - .hidden \name - .type \name,@function -\name: - .cfi_startproc -#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES - exrl 0,0f -#else - larl \tmp,0f - ex 0,0(\tmp) -#endif - j . -0: br \reg - .cfi_endproc - .endm - - GEN_BR_THUNK __s390x_indirect_jump_r1use_r9,%r9,%r1 - GEN_BR_THUNK __s390x_indirect_jump_r1use_r14,%r14,%r1 - GEN_BR_THUNK __s390x_indirect_jump_r11use_r14,%r14,%r11 - - .macro BASR_R14_R9 -0: brasl %r14,__s390x_indirect_jump_r1use_r9 - .pushsection .s390_indirect_branches,"a",@progbits - .long 0b-. - .popsection - .endm - - .macro BR_R1USE_R14 -0: jg __s390x_indirect_jump_r1use_r14 - .pushsection .s390_indirect_branches,"a",@progbits - .long 0b-. - .popsection - .endm - - .macro BR_R11USE_R14 -0: jg __s390x_indirect_jump_r11use_r14 - .pushsection .s390_indirect_branches,"a",@progbits - .long 0b-. - .popsection - .endm - -#else /* CONFIG_EXPOLINE */ - - .macro BASR_R14_R9 - basr %r14,%r9 - .endm - - .macro BR_R1USE_R14 - br %r14 - .endm - - .macro BR_R11USE_R14 - br %r14 - .endm - -#endif /* CONFIG_EXPOLINE */ - + GEN_BR_THUNK %r9 + GEN_BR_THUNK %r14 + GEN_BR_THUNK %r14,%r11 .section .kprobes.text, "ax" ENTRY(__bpon) .globl __bpon BPON - BR_R1USE_R14 + BR_EX %r14 /* * Scheduler resume function, called by switch_to @@ -322,7 +265,7 @@ ENTRY(__switch_to) TSTMSK __LC_MACHINE_FLAGS,MACHINE_FLAG_LPP jz 0f .insn s,0xb2800000,__LC_LPP # set program parameter -0: BR_R1USE_R14 +0: BR_EX %r14 .L__critical_start: @@ -388,7 +331,7 @@ sie_exit: xgr %r5,%r5 lmg %r6,%r14,__SF_GPRS(%r15) # restore kernel registers lg %r2,__SF_EMPTY+16(%r15) # return exit reason code - BR_R1USE_R14 + BR_EX %r14 .Lsie_fault: lghi %r14,-EFAULT stg %r14,__SF_EMPTY+16(%r15) # set exit reason code @@ -445,7 +388,7 @@ ENTRY(system_call) lgf %r9,0(%r8,%r10) # get system call add. TSTMSK __TI_flags(%r12),_TIF_TRACE jnz .Lsysc_tracesys - BASR_R14_R9 # call sys_xxxx + BASR_EX %r14,%r9 # call sys_xxxx stg %r2,__PT_R2(%r11) # store return value .Lsysc_return: @@ -585,7 +528,7 @@ ENTRY(system_call) lmg %r3,%r7,__PT_R3(%r11) stg %r7,STACK_FRAME_OVERHEAD(%r15) lg %r2,__PT_ORIG_GPR2(%r11) - BASR_R14_R9 # call sys_xxx + BASR_EX %r14,%r9 # call sys_xxx stg %r2,__PT_R2(%r11) # store return value .Lsysc_tracenogo: TSTMSK __TI_flags(%r12),_TIF_TRACE @@ -609,7 +552,7 @@ ENTRY(ret_from_fork) lmg %r9,%r10,__PT_R9(%r11) # load gprs ENTRY(kernel_thread_starter) la %r2,0(%r10) - BASR_R14_R9 + BASR_EX %r14,%r9 j .Lsysc_tracenogo /* @@ -685,7 +628,7 @@ ENTRY(pgm_check_handler) je .Lpgm_return lgf %r9,0(%r10,%r1) # load address of handler routine lgr %r2,%r11 # pass pointer to pt_regs - BASR_R14_R9 # branch to interrupt-handler + BASR_EX %r14,%r9 # branch to interrupt-handler .Lpgm_return: LOCKDEP_SYS_EXIT tm __PT_PSW+1(%r11),0x01 # returning to user ? @@ -962,7 +905,7 @@ ENTRY(psw_idle) stpt __TIMER_IDLE_ENTER(%r2) .Lpsw_idle_lpsw: lpswe __SF_EMPTY(%r15) - BR_R1USE_R14 + BR_EX %r14 .Lpsw_idle_end: /* @@ -1007,7 +950,7 @@ ENTRY(save_fpu_regs) .Lsave_fpu_regs_done: oi __LC_CPU_FLAGS+7,_CIF_FPU .Lsave_fpu_regs_exit: - BR_R1USE_R14 + BR_EX %r14 .Lsave_fpu_regs_end: /* @@ -1054,7 +997,7 @@ load_fpu_regs: .Lload_fpu_regs_done: ni __LC_CPU_FLAGS+7,255-_CIF_FPU .Lload_fpu_regs_exit: - BR_R1USE_R14 + BR_EX %r14 .Lload_fpu_regs_end: .L__critical_end: @@ -1227,7 +1170,7 @@ cleanup_critical: jl 0f clg %r9,BASED(.Lcleanup_table+104) # .Lload_fpu_regs_end jl .Lcleanup_load_fpu_regs -0: BR_R11USE_R14 +0: BR_EX %r14,%r11 .align 8 .Lcleanup_table: @@ -1257,7 +1200,7 @@ cleanup_critical: ni __SIE_PROG0C+3(%r9),0xfe # no longer in SIE lctlg %c1,%c1,__LC_USER_ASCE # load primary asce larl %r9,sie_exit # skip forward to sie_exit - BR_R11USE_R14 + BR_EX %r14,%r11 #endif .Lcleanup_system_call: @@ -1315,7 +1258,7 @@ cleanup_critical: stg %r15,56(%r11) # r15 stack pointer # set new psw address and exit larl %r9,.Lsysc_do_svc - BR_R11USE_R14 + BR_EX %r14,%r11 .Lcleanup_system_call_insn: .quad system_call .quad .Lsysc_stmg @@ -1325,7 +1268,7 @@ cleanup_critical: .Lcleanup_sysc_tif: larl %r9,.Lsysc_tif - BR_R11USE_R14 + BR_EX %r14,%r11 .Lcleanup_sysc_restore: # check if stpt has been executed @@ -1342,14 +1285,14 @@ cleanup_critical: mvc 0(64,%r11),__PT_R8(%r9) lmg %r0,%r7,__PT_R0(%r9) 1: lmg %r8,%r9,__LC_RETURN_PSW - BR_R11USE_R14 + BR_EX %r14,%r11 .Lcleanup_sysc_restore_insn: .quad .Lsysc_exit_timer .quad .Lsysc_done - 4 .Lcleanup_io_tif: larl %r9,.Lio_tif - BR_R11USE_R14 + BR_EX %r14,%r11 .Lcleanup_io_restore: # check if stpt has been executed @@ -1363,7 +1306,7 @@ cleanup_critical: mvc 0(64,%r11),__PT_R8(%r9) lmg %r0,%r7,__PT_R0(%r9) 1: lmg %r8,%r9,__LC_RETURN_PSW - BR_R11USE_R14 + BR_EX %r14,%r11 .Lcleanup_io_restore_insn: .quad .Lio_exit_timer .quad .Lio_done - 4 @@ -1415,17 +1358,17 @@ cleanup_critical: # prepare return psw nihh %r8,0xfcfd # clear irq & wait state bits lg %r9,48(%r11) # return from psw_idle - BR_R11USE_R14 + BR_EX %r14,%r11 .Lcleanup_idle_insn: .quad .Lpsw_idle_lpsw .Lcleanup_save_fpu_regs: larl %r9,save_fpu_regs - BR_R11USE_R14 + BR_EX %r14,%r11 .Lcleanup_load_fpu_regs: larl %r9,load_fpu_regs - BR_R11USE_R14 + BR_EX %r14,%r11 /* * Integer constants diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c index f41d5208aaf76..590e9394b4ddf 100644 --- a/arch/s390/kernel/irq.c +++ b/arch/s390/kernel/irq.c @@ -173,10 +173,9 @@ void do_softirq_own_stack(void) new -= STACK_FRAME_OVERHEAD; ((struct stack_frame *) new)->back_chain = old; asm volatile(" la 15,0(%0)\n" - " basr 14,%2\n" + " brasl 14,__do_softirq\n" " la 15,0(%1)\n" - : : "a" (new), "a" (old), - "a" (__do_softirq) + : : "a" (new), "a" (old) : "0", "1", "2", "3", "4", "5", "14", "cc", "memory" ); } else { diff --git a/arch/s390/kernel/mcount.S b/arch/s390/kernel/mcount.S index e499370fbccb3..6c1c7d399bf95 100644 --- a/arch/s390/kernel/mcount.S +++ b/arch/s390/kernel/mcount.S @@ -8,12 +8,16 @@ #include #include #include +#include #include + GEN_BR_THUNK %r1 + GEN_BR_THUNK %r14 + .section .kprobes.text, "ax" ENTRY(ftrace_stub) - br %r14 + BR_EX %r14 #define STACK_FRAME_SIZE (STACK_FRAME_OVERHEAD + __PT_SIZE) #define STACK_PTREGS (STACK_FRAME_OVERHEAD) @@ -21,7 +25,7 @@ ENTRY(ftrace_stub) #define STACK_PTREGS_PSW (STACK_PTREGS + __PT_PSW) ENTRY(_mcount) - br %r14 + BR_EX %r14 ENTRY(ftrace_caller) .globl ftrace_regs_caller @@ -49,7 +53,7 @@ ENTRY(ftrace_caller) #endif lgr %r3,%r14 la %r5,STACK_PTREGS(%r15) - basr %r14,%r1 + BASR_EX %r14,%r1 #ifdef CONFIG_FUNCTION_GRAPH_TRACER # The j instruction gets runtime patched to a nop instruction. # See ftrace_enable_ftrace_graph_caller. @@ -64,7 +68,7 @@ ftrace_graph_caller_end: #endif lg %r1,(STACK_PTREGS_PSW+8)(%r15) lmg %r2,%r15,(STACK_PTREGS_GPRS+2*8)(%r15) - br %r1 + BR_EX %r1 #ifdef CONFIG_FUNCTION_GRAPH_TRACER @@ -77,6 +81,6 @@ ENTRY(return_to_handler) aghi %r15,STACK_FRAME_OVERHEAD lgr %r14,%r2 lmg %r2,%r5,32(%r15) - br %r14 + BR_EX %r14 #endif diff --git a/arch/s390/kernel/nospec-branch.c b/arch/s390/kernel/nospec-branch.c index 9f3b5b3827435..d5eed651b5abd 100644 --- a/arch/s390/kernel/nospec-branch.c +++ b/arch/s390/kernel/nospec-branch.c @@ -44,24 +44,6 @@ static int __init nospec_report(void) } arch_initcall(nospec_report); -#ifdef CONFIG_SYSFS -ssize_t cpu_show_spectre_v1(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "Mitigation: __user pointer sanitization\n"); -} - -ssize_t cpu_show_spectre_v2(struct device *dev, - struct device_attribute *attr, char *buf) -{ - if (IS_ENABLED(CC_USING_EXPOLINE) && !nospec_disable) - return sprintf(buf, "Mitigation: execute trampolines\n"); - if (__test_facility(82, S390_lowcore.alt_stfle_fac_list)) - return sprintf(buf, "Mitigation: limited branch prediction.\n"); - return sprintf(buf, "Vulnerable\n"); -} -#endif - #ifdef CONFIG_EXPOLINE int nospec_disable = IS_ENABLED(CONFIG_EXPOLINE_OFF); @@ -112,7 +94,6 @@ static void __init_or_module __nospec_revert(s32 *start, s32 *end) s32 *epo; /* Second part of the instruction replace is always a nop */ - memcpy(insnbuf + 2, (char[]) { 0x47, 0x00, 0x00, 0x00 }, 4); for (epo = start; epo < end; epo++) { instr = (u8 *) epo + *epo; if (instr[0] == 0xc0 && (instr[1] & 0x0f) == 0x04) @@ -133,18 +114,34 @@ static void __init_or_module __nospec_revert(s32 *start, s32 *end) br = thunk + (*(int *)(thunk + 2)) * 2; else continue; - if (br[0] != 0x07 || (br[1] & 0xf0) != 0xf0) + /* Check for unconditional branch 0x07f? or 0x47f???? */ + if ((br[0] & 0xbf) != 0x07 || (br[1] & 0xf0) != 0xf0) continue; + + memcpy(insnbuf + 2, (char[]) { 0x47, 0x00, 0x07, 0x00 }, 4); switch (type) { case BRCL_EXPOLINE: - /* brcl to thunk, replace with br + nop */ insnbuf[0] = br[0]; insnbuf[1] = (instr[1] & 0xf0) | (br[1] & 0x0f); + if (br[0] == 0x47) { + /* brcl to b, replace with bc + nopr */ + insnbuf[2] = br[2]; + insnbuf[3] = br[3]; + } else { + /* brcl to br, replace with bcr + nop */ + } break; case BRASL_EXPOLINE: - /* brasl to thunk, replace with basr + nop */ - insnbuf[0] = 0x0d; insnbuf[1] = (instr[1] & 0xf0) | (br[1] & 0x0f); + if (br[0] == 0x47) { + /* brasl to b, replace with bas + nopr */ + insnbuf[0] = 0x4d; + insnbuf[2] = br[2]; + insnbuf[3] = br[3]; + } else { + /* brasl to br, replace with basr + nop */ + insnbuf[0] = 0x0d; + } break; } diff --git a/arch/s390/kernel/nospec-sysfs.c b/arch/s390/kernel/nospec-sysfs.c new file mode 100644 index 0000000000000..8affad5f18cb5 --- /dev/null +++ b/arch/s390/kernel/nospec-sysfs.c @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include + +ssize_t cpu_show_spectre_v1(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "Mitigation: __user pointer sanitization\n"); +} + +ssize_t cpu_show_spectre_v2(struct device *dev, + struct device_attribute *attr, char *buf) +{ + if (IS_ENABLED(CC_USING_EXPOLINE) && !nospec_disable) + return sprintf(buf, "Mitigation: execute trampolines\n"); + if (__test_facility(82, S390_lowcore.alt_stfle_fac_list)) + return sprintf(buf, "Mitigation: limited branch prediction\n"); + return sprintf(buf, "Vulnerable\n"); +} diff --git a/arch/s390/kernel/perf_cpum_sf.c b/arch/s390/kernel/perf_cpum_sf.c index 3d8da1e742c2b..b79d51459cf25 100644 --- a/arch/s390/kernel/perf_cpum_sf.c +++ b/arch/s390/kernel/perf_cpum_sf.c @@ -744,6 +744,10 @@ static int __hw_perf_event_init(struct perf_event *event) */ rate = 0; if (attr->freq) { + if (!attr->sample_freq) { + err = -EINVAL; + goto out; + } rate = freq_to_sample_rate(&si, attr->sample_freq); rate = hw_limit_rate(&si, rate); attr->freq = 0; diff --git a/arch/s390/kernel/reipl.S b/arch/s390/kernel/reipl.S index 52aab0bd84f89..6b1b91c17b407 100644 --- a/arch/s390/kernel/reipl.S +++ b/arch/s390/kernel/reipl.S @@ -6,8 +6,11 @@ #include #include +#include #include + GEN_BR_THUNK %r14 + # # store_status # @@ -62,7 +65,7 @@ ENTRY(store_status) st %r3,__LC_PSW_SAVE_AREA-SAVE_AREA_BASE + 4(%r1) larl %r2,store_status stg %r2,__LC_PSW_SAVE_AREA-SAVE_AREA_BASE + 8(%r1) - br %r14 + BR_EX %r14 .section .bss .align 8 diff --git a/arch/s390/kernel/swsusp.S b/arch/s390/kernel/swsusp.S index 2d6b6e81f812c..60a829c77378d 100644 --- a/arch/s390/kernel/swsusp.S +++ b/arch/s390/kernel/swsusp.S @@ -12,6 +12,7 @@ #include #include #include +#include #include /* @@ -23,6 +24,8 @@ * (see below) in the resume process. * This function runs with disabled interrupts. */ + GEN_BR_THUNK %r14 + .section .text ENTRY(swsusp_arch_suspend) stmg %r6,%r15,__SF_GPRS(%r15) @@ -102,7 +105,7 @@ ENTRY(swsusp_arch_suspend) spx 0x318(%r1) lmg %r6,%r15,STACK_FRAME_OVERHEAD + __SF_GPRS(%r15) lghi %r2,0 - br %r14 + BR_EX %r14 /* * Restore saved memory image to correct place and restore register context. @@ -196,11 +199,10 @@ pgm_check_entry: larl %r15,init_thread_union ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) larl %r2,.Lpanic_string - larl %r3,_sclp_print_early lghi %r1,0 sam31 sigp %r1,%r0,SIGP_SET_ARCHITECTURE - basr %r14,%r3 + brasl %r14,_sclp_print_early larl %r3,.Ldisabled_wait_31 lpsw 0(%r3) 4: @@ -266,7 +268,7 @@ restore_registers: /* Return 0 */ lmg %r6,%r15,STACK_FRAME_OVERHEAD + __SF_GPRS(%r15) lghi %r2,0 - br %r14 + BR_EX %r14 .section .data..nosave,"aw",@progbits .align 8 diff --git a/arch/s390/lib/mem.S b/arch/s390/lib/mem.S index c6d553e85ab11..16c5998b97922 100644 --- a/arch/s390/lib/mem.S +++ b/arch/s390/lib/mem.S @@ -5,6 +5,9 @@ */ #include +#include + + GEN_BR_THUNK %r14 /* * memset implementation @@ -38,7 +41,7 @@ ENTRY(memset) .Lmemset_clear_rest: larl %r3,.Lmemset_xc ex %r4,0(%r3) - br %r14 + BR_EX %r14 .Lmemset_fill: stc %r3,0(%r2) cghi %r4,1 @@ -55,7 +58,7 @@ ENTRY(memset) .Lmemset_fill_rest: larl %r3,.Lmemset_mvc ex %r4,0(%r3) - br %r14 + BR_EX %r14 .Lmemset_xc: xc 0(1,%r1),0(%r1) .Lmemset_mvc: @@ -77,7 +80,7 @@ ENTRY(memcpy) .Lmemcpy_rest: larl %r5,.Lmemcpy_mvc ex %r4,0(%r5) - br %r14 + BR_EX %r14 .Lmemcpy_loop: mvc 0(256,%r1),0(%r3) la %r1,256(%r1) diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index ec1a30d0d11ab..7218689bd6ee8 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -459,6 +459,8 @@ static inline int do_exception(struct pt_regs *regs, int access) /* No reason to continue if interrupted by SIGKILL. */ if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) { fault = VM_FAULT_SIGNAL; + if (flags & FAULT_FLAG_RETRY_NOWAIT) + goto out_up; goto out; } if (unlikely(fault & VM_FAULT_ERROR)) diff --git a/arch/s390/net/bpf_jit.S b/arch/s390/net/bpf_jit.S index a1c917d881ec4..fa716f2a95a7a 100644 --- a/arch/s390/net/bpf_jit.S +++ b/arch/s390/net/bpf_jit.S @@ -8,6 +8,7 @@ */ #include +#include #include "bpf_jit.h" /* @@ -53,7 +54,7 @@ ENTRY(sk_load_##NAME##_pos); \ clg %r3,STK_OFF_HLEN(%r15); /* Offset + SIZE > hlen? */ \ jh sk_load_##NAME##_slow; \ LOAD %r14,-SIZE(%r3,%r12); /* Get data from skb */ \ - b OFF_OK(%r6); /* Return */ \ + B_EX OFF_OK,%r6; /* Return */ \ \ sk_load_##NAME##_slow:; \ lgr %r2,%r7; /* Arg1 = skb pointer */ \ @@ -63,11 +64,14 @@ sk_load_##NAME##_slow:; \ brasl %r14,skb_copy_bits; /* Get data from skb */ \ LOAD %r14,STK_OFF_TMP(%r15); /* Load from temp bufffer */ \ ltgr %r2,%r2; /* Set cc to (%r2 != 0) */ \ - br %r6; /* Return */ + BR_EX %r6; /* Return */ sk_load_common(word, 4, llgf) /* r14 = *(u32 *) (skb->data+offset) */ sk_load_common(half, 2, llgh) /* r14 = *(u16 *) (skb->data+offset) */ + GEN_BR_THUNK %r6 + GEN_B_THUNK OFF_OK,%r6 + /* * Load 1 byte from SKB (optimized version) */ @@ -79,7 +83,7 @@ ENTRY(sk_load_byte_pos) clg %r3,STK_OFF_HLEN(%r15) # Offset >= hlen? jnl sk_load_byte_slow llgc %r14,0(%r3,%r12) # Get byte from skb - b OFF_OK(%r6) # Return OK + B_EX OFF_OK,%r6 # Return OK sk_load_byte_slow: lgr %r2,%r7 # Arg1 = skb pointer @@ -89,7 +93,7 @@ sk_load_byte_slow: brasl %r14,skb_copy_bits # Get data from skb llgc %r14,STK_OFF_TMP(%r15) # Load result from temp buffer ltgr %r2,%r2 # Set cc to (%r2 != 0) - br %r6 # Return cc + BR_EX %r6 # Return cc #define sk_negative_common(NAME, SIZE, LOAD) \ sk_load_##NAME##_slow_neg:; \ @@ -103,7 +107,7 @@ sk_load_##NAME##_slow_neg:; \ jz bpf_error; \ LOAD %r14,0(%r2); /* Get data from pointer */ \ xr %r3,%r3; /* Set cc to zero */ \ - br %r6; /* Return cc */ + BR_EX %r6; /* Return cc */ sk_negative_common(word, 4, llgf) sk_negative_common(half, 2, llgh) @@ -112,4 +116,4 @@ sk_negative_common(byte, 1, llgc) bpf_error: # force a return 0 from jit handler ltgr %r15,%r15 # Set condition code - br %r6 + BR_EX %r6 diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index 1395eeb6005ff..727693e283da2 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include "bpf_jit.h" int bpf_jit_enable __read_mostly; @@ -41,6 +43,8 @@ struct bpf_jit { int base_ip; /* Base address for literal pool */ int ret0_ip; /* Address of return 0 */ int exit_ip; /* Address of exit */ + int r1_thunk_ip; /* Address of expoline thunk for 'br %r1' */ + int r14_thunk_ip; /* Address of expoline thunk for 'br %r14' */ int tail_call_start; /* Tail call start offset */ int labels[1]; /* Labels for local jumps */ }; @@ -248,6 +252,19 @@ static inline void reg_set_seen(struct bpf_jit *jit, u32 b1) REG_SET_SEEN(b2); \ }) +#define EMIT6_PCREL_RILB(op, b, target) \ +({ \ + int rel = (target - jit->prg) / 2; \ + _EMIT6(op | reg_high(b) << 16 | rel >> 16, rel & 0xffff); \ + REG_SET_SEEN(b); \ +}) + +#define EMIT6_PCREL_RIL(op, target) \ +({ \ + int rel = (target - jit->prg) / 2; \ + _EMIT6(op | rel >> 16, rel & 0xffff); \ +}) + #define _EMIT6_IMM(op, imm) \ ({ \ unsigned int __imm = (imm); \ @@ -475,8 +492,43 @@ static void bpf_jit_epilogue(struct bpf_jit *jit) EMIT4(0xb9040000, REG_2, BPF_REG_0); /* Restore registers */ save_restore_regs(jit, REGS_RESTORE); + if (IS_ENABLED(CC_USING_EXPOLINE) && !nospec_disable) { + jit->r14_thunk_ip = jit->prg; + /* Generate __s390_indirect_jump_r14 thunk */ + if (test_facility(35)) { + /* exrl %r0,.+10 */ + EMIT6_PCREL_RIL(0xc6000000, jit->prg + 10); + } else { + /* larl %r1,.+14 */ + EMIT6_PCREL_RILB(0xc0000000, REG_1, jit->prg + 14); + /* ex 0,0(%r1) */ + EMIT4_DISP(0x44000000, REG_0, REG_1, 0); + } + /* j . */ + EMIT4_PCREL(0xa7f40000, 0); + } /* br %r14 */ _EMIT2(0x07fe); + + if (IS_ENABLED(CC_USING_EXPOLINE) && !nospec_disable && + (jit->seen & SEEN_FUNC)) { + jit->r1_thunk_ip = jit->prg; + /* Generate __s390_indirect_jump_r1 thunk */ + if (test_facility(35)) { + /* exrl %r0,.+10 */ + EMIT6_PCREL_RIL(0xc6000000, jit->prg + 10); + /* j . */ + EMIT4_PCREL(0xa7f40000, 0); + /* br %r1 */ + _EMIT2(0x07f1); + } else { + /* ex 0,S390_lowcore.br_r1_tampoline */ + EMIT4_DISP(0x44000000, REG_0, REG_0, + offsetof(struct _lowcore, br_r1_trampoline)); + /* j . */ + EMIT4_PCREL(0xa7f40000, 0); + } + } } /* @@ -980,8 +1032,13 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i /* lg %w1,(%l) */ EMIT6_DISP_LH(0xe3000000, 0x0004, REG_W1, REG_0, REG_L, EMIT_CONST_U64(func)); - /* basr %r14,%w1 */ - EMIT2(0x0d00, REG_14, REG_W1); + if (IS_ENABLED(CC_USING_EXPOLINE) && !nospec_disable) { + /* brasl %r14,__s390_indirect_jump_r1 */ + EMIT6_PCREL_RILB(0xc0050000, REG_14, jit->r1_thunk_ip); + } else { + /* basr %r14,%w1 */ + EMIT2(0x0d00, REG_14, REG_W1); + } /* lgr %b0,%r2: load return value into %b0 */ EMIT4(0xb9040000, BPF_REG_0, REG_2); if (bpf_helper_changes_skb_data((void *)func)) { diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index ef0499b76c505..9a5754d4ee87c 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c @@ -412,6 +412,8 @@ int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) hwirq = 0; for_each_pci_msi_entry(msi, pdev) { rc = -EIO; + if (hwirq >= msi_vecs) + break; irq = irq_alloc_desc(0); /* Alloc irq on node 0 */ if (irq < 0) goto out_msi; diff --git a/arch/sh/include/asm/futex.h b/arch/sh/include/asm/futex.h index 7be39a646fbd0..e05187d26d764 100644 --- a/arch/sh/include/asm/futex.h +++ b/arch/sh/include/asm/futex.h @@ -10,20 +10,11 @@ /* XXX: UP variants, fix for SH-4A and SMP.. */ #include -static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) +static inline int arch_futex_atomic_op_inuser(int op, u32 oparg, int *oval, + u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; - pagefault_disable(); switch (op) { @@ -49,17 +40,8 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; return ret; } diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S index 13047a4facd2e..5a9017ba26aba 100644 --- a/arch/sh/kernel/entry-common.S +++ b/arch/sh/kernel/entry-common.S @@ -255,7 +255,7 @@ debug_trap: mov.l @r8, r8 jsr @r8 nop - bra __restore_all + bra ret_from_exception nop CFI_ENDPROC 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/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/sparc/include/asm/atomic_64.h b/arch/sparc/include/asm/atomic_64.h index f2fbf9e16fafc..29070c9a70f95 100644 --- a/arch/sparc/include/asm/atomic_64.h +++ b/arch/sparc/include/asm/atomic_64.h @@ -74,7 +74,11 @@ ATOMIC_OP(xor) #define atomic64_add_negative(i, v) (atomic64_add_return(i, v) < 0) #define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n))) -#define atomic_xchg(v, new) (xchg(&((v)->counter), new)) + +static inline int atomic_xchg(atomic_t *v, int new) +{ + return xchg(&v->counter, new); +} static inline int __atomic_add_unless(atomic_t *v, int a, int u) { diff --git a/arch/sparc/include/asm/futex_64.h b/arch/sparc/include/asm/futex_64.h index 4e899b0dabf79..1cfd89d922080 100644 --- a/arch/sparc/include/asm/futex_64.h +++ b/arch/sparc/include/asm/futex_64.h @@ -29,22 +29,14 @@ : "r" (uaddr), "r" (oparg), "i" (-EFAULT) \ : "memory") -static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) +static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, + u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret, tem; - if (unlikely(!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))) - return -EFAULT; if (unlikely((((unsigned long) uaddr) & 0x3UL))) return -EINVAL; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - pagefault_disable(); switch (op) { @@ -69,17 +61,9 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; - case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; - case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; - case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; - case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; - case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; - default: ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c index f87a55d770946..9b3f2e212b377 100644 --- a/arch/sparc/kernel/ds.c +++ b/arch/sparc/kernel/ds.c @@ -908,7 +908,7 @@ static int register_services(struct ds_info *dp) pbuf.req.handle = cp->handle; pbuf.req.major = 1; pbuf.req.minor = 0; - strcpy(pbuf.req.svc_id, cp->service_id); + strcpy(pbuf.id_buf, cp->service_id); err = __ds_send(lp, &pbuf, msg_len); if (err > 0) diff --git a/arch/tile/include/asm/futex.h b/arch/tile/include/asm/futex.h index 1a6ef1b69cb13..d96d9dab5c0b5 100644 --- a/arch/tile/include/asm/futex.h +++ b/arch/tile/include/asm/futex.h @@ -106,12 +106,9 @@ lock = __atomic_hashed_lock((int __force *)uaddr) #endif -static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) +static inline int arch_futex_atomic_op_inuser(int op, u32 oparg, int *oval, + u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int uninitialized_var(val), ret; __futex_prolog(); @@ -119,12 +116,6 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) /* The 32-bit futex code makes this assumption, so validate it here. */ BUILD_BUG_ON(sizeof(atomic_t) != sizeof(int)); - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; - pagefault_disable(); switch (op) { case FUTEX_OP_SET: @@ -148,30 +139,9 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) } pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: - ret = (val == cmparg); - break; - case FUTEX_OP_CMP_NE: - ret = (val != cmparg); - break; - case FUTEX_OP_CMP_LT: - ret = (val < cmparg); - break; - case FUTEX_OP_CMP_GE: - ret = (val >= cmparg); - break; - case FUTEX_OP_CMP_LE: - ret = (val <= cmparg); - break; - case FUTEX_OP_CMP_GT: - ret = (val > cmparg); - break; - default: - ret = -ENOSYS; - } - } + if (!ret) + *oval = val; + return ret; } diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index ad1f3bfafe75f..b00e3f0ed0c01 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -369,6 +369,17 @@ config X86_FEATURE_NAMES If in doubt, say Y. +config X86_FAST_FEATURE_TESTS + bool "Fast CPU feature tests" if EMBEDDED + default y + ---help--- + Some fast-paths in the kernel depend on the capabilities of the CPU. + Say Y here for the kernel to patch in the appropriate code at runtime + based on the capabilities of the CPU. The infrastructure for patching + code at runtime takes up some additional space; space-constrained + embedded systems may wish to say N here to produce smaller, slightly + slower code. + config X86_X2APIC bool "Support x2apic" depends on X86_LOCAL_APIC && X86_64 && (IRQ_REMAP || HYPERVISOR_GUEST) diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index e5031f46c443d..3cb8e179f2f23 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug @@ -355,16 +355,6 @@ config DEBUG_IMR_SELFTEST If unsure say N here. -config X86_DEBUG_STATIC_CPU_HAS - bool "Debug alternatives" - depends on DEBUG_KERNEL - ---help--- - This option causes additional code to be generated which - fails if static_cpu_has() is used before alternatives have - run. - - If unsure, say N. - config X86_DEBUG_FPU bool "Debug the x86 FPU code" depends on DEBUG_KERNEL diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index 583d539a41977..2bc6651791cc8 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c @@ -364,7 +364,8 @@ __setup_efi_pci32(efi_pci_io_protocol_32 *pci, struct pci_setup_rom **__rom) if (status != EFI_SUCCESS) goto free_struct; - memcpy(rom->romdata, pci->romimage, pci->romsize); + memcpy(rom->romdata, (void *)(unsigned long)pci->romimage, + pci->romsize); return status; free_struct: @@ -470,7 +471,8 @@ __setup_efi_pci64(efi_pci_io_protocol_64 *pci, struct pci_setup_rom **__rom) if (status != EFI_SUCCESS) goto free_struct; - memcpy(rom->romdata, pci->romimage, pci->romsize); + memcpy(rom->romdata, (void *)(unsigned long)pci->romimage, + pci->romsize); return status; free_struct: diff --git a/arch/x86/boot/cpuflags.h b/arch/x86/boot/cpuflags.h index ea97697e51e40..4cb404fd45cea 100644 --- a/arch/x86/boot/cpuflags.h +++ b/arch/x86/boot/cpuflags.h @@ -1,7 +1,7 @@ #ifndef BOOT_CPUFLAGS_H #define BOOT_CPUFLAGS_H -#include +#include #include struct cpu_features { diff --git a/arch/x86/boot/mkcpustr.c b/arch/x86/boot/mkcpustr.c index 637097e66a62a..f72498dc90d23 100644 --- a/arch/x86/boot/mkcpustr.c +++ b/arch/x86/boot/mkcpustr.c @@ -17,7 +17,7 @@ #include "../include/asm/required-features.h" #include "../include/asm/disabled-features.h" -#include "../include/asm/cpufeature.h" +#include "../include/asm/cpufeatures.h" #include "../kernel/cpu/capflags.c" int main(void) diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig index 9f0107157b8f2..71026930c04c1 100644 --- a/arch/x86/configs/x86_64_cuttlefish_defconfig +++ b/arch/x86/configs/x86_64_cuttlefish_defconfig @@ -11,6 +11,7 @@ CONFIG_TASK_IO_ACCOUNTING=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_CGROUPS=y +CONFIG_CGROUP_DEBUG=y CONFIG_CGROUP_FREEZER=y CONFIG_CGROUP_CPUACCT=y CONFIG_CGROUP_SCHED=y @@ -56,6 +57,7 @@ CONFIG_RANDOMIZE_BASE=y CONFIG_PHYSICAL_ALIGN=0x1000000 CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="console=ttyS0 reboot=p nopti" +CONFIG_PM_AUTOSLEEP=y CONFIG_PM_WAKELOCKS=y CONFIG_PM_WAKELOCKS_LIMIT=0 # CONFIG_PM_WAKELOCKS_GC is not set @@ -88,8 +90,8 @@ CONFIG_IP_MROUTE=y CONFIG_IP_PIMSM_V1=y CONFIG_IP_PIMSM_V2=y CONFIG_SYN_COOKIES=y +CONFIG_NET_IPVTI=y CONFIG_INET_ESP=y -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set CONFIG_INET_DIAG_DESTROY=y @@ -105,6 +107,7 @@ CONFIG_INET6_AH=y CONFIG_INET6_ESP=y CONFIG_INET6_IPCOMP=y CONFIG_IPV6_MIP6=y +CONFIG_IPV6_VTI=y CONFIG_IPV6_MULTIPLE_TABLES=y CONFIG_NETLABEL=y CONFIG_NETFILTER=y @@ -298,7 +301,6 @@ CONFIG_SOUND=y CONFIG_SND=y CONFIG_HIDRAW=y CONFIG_UHID=y -# CONFIG_HID_GENERIC is not set CONFIG_HID_A4TECH=y CONFIG_HID_ACRUX=y CONFIG_HID_ACRUX_FF=y @@ -362,6 +364,8 @@ CONFIG_USB_GADGET=y CONFIG_USB_DUMMY_HCD=y CONFIG_USB_CONFIGFS=y CONFIG_USB_CONFIGFS_F_FS=y +CONFIG_USB_CONFIGFS_F_MTP=y +CONFIG_USB_CONFIGFS_F_PTP=y CONFIG_USB_CONFIGFS_F_ACC=y CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y CONFIG_USB_CONFIGFS_UEVENT=y @@ -390,6 +394,9 @@ CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y CONFIG_EXT4_ENCRYPTION=y +CONFIG_F2FS_FS=y +CONFIG_F2FS_FS_SECURITY=y +CONFIG_F2FS_FS_ENCRYPTION=y CONFIG_QUOTA=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set @@ -423,7 +430,6 @@ CONFIG_DEBUG_MEMORY_INIT=y CONFIG_DEBUG_STACKOVERFLOW=y CONFIG_LOCKUP_DETECTOR=y CONFIG_PANIC_TIMEOUT=5 -# CONFIG_SCHED_DEBUG is not set CONFIG_SCHEDSTATS=y CONFIG_TIMER_STATS=y CONFIG_RCU_CPU_STALL_TIMEOUT=60 @@ -440,3 +446,4 @@ CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 # CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set CONFIG_CRYPTO_ECHAINIV=y +CONFIG_CRYPTO_SHA512=y diff --git a/arch/x86/configs/x86_64_ranchu_defconfig b/arch/x86/configs/x86_64_ranchu_defconfig index e8ed8eef62ec8..5cf2450842ab6 100644 --- a/arch/x86/configs/x86_64_ranchu_defconfig +++ b/arch/x86/configs/x86_64_ranchu_defconfig @@ -1,5 +1,6 @@ # CONFIG_LOCALVERSION_AUTO is not set CONFIG_POSIX_MQUEUE=y +# CONFIG_USELIB is not set CONFIG_AUDIT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -8,20 +9,29 @@ 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_CGROUPS=y CONFIG_CGROUP_DEBUG=y CONFIG_CGROUP_FREEZER=y CONFIG_CGROUP_CPUACCT=y CONFIG_CGROUP_SCHED=y CONFIG_RT_GROUP_SCHED=y +CONFIG_NAMESPACES=y CONFIG_BLK_DEV_INITRD=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS_ALL=y +CONFIG_BPF_SYSCALL=y CONFIG_EMBEDDED=y # CONFIG_COMPAT_BRK is not set +CONFIG_PROFILING=y +CONFIG_CC_STACKPROTECTOR_STRONG=y CONFIG_ARCH_MMAP_RND_BITS=32 CONFIG_ARCH_MMAP_RND_COMPAT_BITS=16 +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y CONFIG_PARTITION_ADVANCED=y CONFIG_OSF_PARTITION=y CONFIG_AMIGA_PARTITION=y @@ -34,6 +44,9 @@ CONFIG_SGI_PARTITION=y CONFIG_SUN_PARTITION=y CONFIG_KARMA_PARTITION=y CONFIG_SMP=y +CONFIG_GOLDFISH=y +CONFIG_HYPERVISOR_GUEST=y +CONFIG_PARAVIRT=y CONFIG_MCORE2=y CONFIG_MAXSMP=y CONFIG_PREEMPT=y @@ -47,6 +60,9 @@ CONFIG_EFI=y CONFIG_EFI_STUB=y CONFIG_HZ_100=y CONFIG_PHYSICAL_START=0x100000 +CONFIG_RANDOMIZE_BASE=y +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="nopti" CONFIG_PM_AUTOSLEEP=y CONFIG_PM_WAKELOCKS=y CONFIG_PM_WAKELOCKS_LIMIT=0 @@ -69,6 +85,7 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM_USER=y +CONFIG_XFRM_STATISTICS=y CONFIG_NET_KEY=y CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -84,6 +101,8 @@ CONFIG_IP_MROUTE=y CONFIG_IP_PIMSM_V1=y CONFIG_IP_PIMSM_V2=y CONFIG_SYN_COOKIES=y +CONFIG_NET_IPVTI=y +CONFIG_INET_AH=y CONFIG_INET_ESP=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_LRO is not set @@ -95,6 +114,7 @@ CONFIG_INET6_AH=y CONFIG_INET6_ESP=y CONFIG_INET6_IPCOMP=y CONFIG_IPV6_MIP6=y +CONFIG_IPV6_VTI=y CONFIG_IPV6_MULTIPLE_TABLES=y CONFIG_NETLABEL=y CONFIG_NETFILTER=y @@ -153,6 +173,10 @@ CONFIG_IP_NF_MATCH_ECN=y CONFIG_IP_NF_MATCH_TTL=y CONFIG_IP_NF_FILTER=y CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_IP_NF_NAT=y +CONFIG_IP_NF_TARGET_MASQUERADE=y +CONFIG_IP_NF_TARGET_NETMAP=y +CONFIG_IP_NF_TARGET_REDIRECT=y CONFIG_IP_NF_MANGLE=y CONFIG_IP_NF_RAW=y CONFIG_IP_NF_SECURITY=y @@ -161,6 +185,7 @@ CONFIG_IP_NF_ARPFILTER=y CONFIG_IP_NF_ARP_MANGLE=y CONFIG_NF_CONNTRACK_IPV6=y CONFIG_IP6_NF_IPTABLES=y +CONFIG_IP6_NF_MATCH_RPFILTER=y CONFIG_IP6_NF_FILTER=y CONFIG_IP6_NF_TARGET_REJECT=y CONFIG_IP6_NF_MANGLE=y @@ -177,10 +202,13 @@ CONFIG_MAC80211_LEDS=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_DMA_CMA=y CONFIG_CONNECTOR=y +CONFIG_OF=y +CONFIG_OF_UNITTEST=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_RAM_SIZE=16384 CONFIG_VIRTIO_BLK=y +CONFIG_UID_SYS_STATS=y CONFIG_BLK_DEV_SD=y CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y @@ -210,6 +238,7 @@ CONFIG_DM_VERITY_FEC=y CONFIG_NETDEVICES=y CONFIG_NETCONSOLE=y CONFIG_TUN=y +CONFIG_VETH=y CONFIG_VIRTIO_NET=y CONFIG_BNX2=y CONFIG_TIGON3=y @@ -231,6 +260,7 @@ CONFIG_PPP_MPPE=y CONFIG_PPPOLAC=y CONFIG_PPPOPNS=y CONFIG_USB_USBNET=y +CONFIG_MAC80211_HWSIM=y CONFIG_INPUT_POLLDEV=y # CONFIG_INPUT_MOUSEDEV_PSAUX is not set CONFIG_INPUT_EVDEV=y @@ -263,7 +293,10 @@ CONFIG_SERIAL_NONSTANDARD=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_VIRTIO_CONSOLE=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_VIRTIO=y CONFIG_NVRAM=y +# CONFIG_DEVPORT is not set CONFIG_I2C_I801=y CONFIG_BATTERY_GOLDFISH=y CONFIG_WATCHDOG=y @@ -280,6 +313,18 @@ CONFIG_BACKLIGHT_LCD_SUPPORT=y # CONFIG_LCD_CLASS_DEVICE is not set CONFIG_SOUND=y CONFIG_SND=y +CONFIG_SND_HDA_INTEL=y +CONFIG_SND_HDA_CODEC_REALTEK=y +CONFIG_SND_HDA_CODEC_ANALOG=y +CONFIG_SND_HDA_CODEC_SIGMATEL=y +CONFIG_SND_HDA_CODEC_VIA=y +CONFIG_SND_HDA_CODEC_HDMI=y +CONFIG_SND_HDA_CODEC_CIRRUS=y +CONFIG_SND_HDA_CODEC_CONEXANT=y +CONFIG_SND_HDA_CODEC_CA0110=y +CONFIG_SND_HDA_CODEC_CA0132=y +CONFIG_SND_HDA_CODEC_CMEDIA=y +CONFIG_SND_HDA_CODEC_SI3054=y CONFIG_HIDRAW=y CONFIG_UHID=y CONFIG_HID_A4TECH=y @@ -349,6 +394,15 @@ CONFIG_USB_UHCI_HCD=y CONFIG_USB_PRINTER=y CONFIG_USB_STORAGE=y CONFIG_USB_OTG_WAKELOCK=y +CONFIG_USB_GADGET=y +CONFIG_USB_CONFIGFS=y +CONFIG_USB_CONFIGFS_F_FS=y +CONFIG_USB_CONFIGFS_F_MTP=y +CONFIG_USB_CONFIGFS_F_PTP=y +CONFIG_USB_CONFIGFS_F_ACC=y +CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y +CONFIG_USB_CONFIGFS_UEVENT=y +CONFIG_USB_CONFIGFS_F_MIDI=y CONFIG_EDAC=y CONFIG_RTC_CLASS=y # CONFIG_RTC_HCTOSYS is not set @@ -362,8 +416,6 @@ CONFIG_SW_SYNC=y CONFIG_ION=y CONFIG_GOLDFISH_AUDIO=y CONFIG_GOLDFISH_SYNC=y -CONFIG_SND_HDA_INTEL=y -CONFIG_GOLDFISH=y CONFIG_GOLDFISH_PIPE=y CONFIG_ANDROID=y CONFIG_ANDROID_BINDER_IPC=y @@ -373,6 +425,7 @@ CONFIG_EXT4_FS_SECURITY=y CONFIG_QUOTA=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set +CONFIG_QFMT_V2=y CONFIG_FUSE_FS=y CONFIG_ISO9660_FS=y CONFIG_JOLIET=y @@ -383,8 +436,10 @@ CONFIG_PROC_KCORE=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y CONFIG_HUGETLBFS=y +CONFIG_SDCARD_FS=y CONFIG_PSTORE=y CONFIG_PSTORE_CONSOLE=y +CONFIG_PSTORE_PMSG=y CONFIG_PSTORE_RAM=y # CONFIG_NETWORK_FILESYSTEMS is not set CONFIG_NLS_DEFAULT="utf8" @@ -399,16 +454,24 @@ CONFIG_DEBUG_INFO=y # CONFIG_UNUSED_SYMBOLS is not set CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_MEMORY_INIT=y +CONFIG_DETECT_HUNG_TASK=y CONFIG_PANIC_TIMEOUT=5 CONFIG_SCHEDSTATS=y CONFIG_TIMER_STATS=y CONFIG_SCHED_TRACER=y CONFIG_BLK_DEV_IO_TRACE=y CONFIG_PROVIDE_OHCI1394_DMA_INIT=y +CONFIG_DEBUG_SET_MODULE_RONX=y CONFIG_KEYS=y +CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y +CONFIG_HARDENED_USERCOPY=y CONFIG_SECURITY_SELINUX=y +CONFIG_CRYPTO_USER=y +CONFIG_CRYPTO_ECHAINIV=y +CONFIG_CRYPTO_SHA512=y +CONFIG_CRYPTO_AES_X86_64=y CONFIG_CRYPTO_TWOFISH=y CONFIG_ASYMMETRIC_KEY_TYPE=y CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y @@ -417,3 +480,4 @@ CONFIG_PKCS7_MESSAGE_PARSER=y CONFIG_PKCS7_TEST_KEY=y # CONFIG_VIRTUALIZATION is not set CONFIG_CRC_T10DIF=y +CONFIG_ANDROID_BINDER_DEVICES="binder,hwbinder,vndbinder" diff --git a/arch/x86/crypto/chacha20_glue.c b/arch/x86/crypto/chacha20_glue.c index 722bacea040e7..8baaff5af0b57 100644 --- a/arch/x86/crypto/chacha20_glue.c +++ b/arch/x86/crypto/chacha20_glue.c @@ -125,7 +125,7 @@ static struct crypto_alg alg = { static int __init chacha20_simd_mod_init(void) { - if (!cpu_has_ssse3) + if (!boot_cpu_has(X86_FEATURE_SSSE3)) return -ENODEV; #ifdef CONFIG_AS_AVX2 diff --git a/arch/x86/crypto/crc32-pclmul_glue.c b/arch/x86/crypto/crc32-pclmul_glue.c index 07d2c6c86a548..27226df3f7d8a 100644 --- a/arch/x86/crypto/crc32-pclmul_glue.c +++ b/arch/x86/crypto/crc32-pclmul_glue.c @@ -33,7 +33,7 @@ #include #include -#include +#include #include #include diff --git a/arch/x86/crypto/crc32c-intel_glue.c b/arch/x86/crypto/crc32c-intel_glue.c index 81a595d75cf59..715399b14ed76 100644 --- a/arch/x86/crypto/crc32c-intel_glue.c +++ b/arch/x86/crypto/crc32c-intel_glue.c @@ -30,7 +30,7 @@ #include #include -#include +#include #include #include @@ -58,16 +58,11 @@ asmlinkage unsigned int crc_pcl(const u8 *buffer, int len, unsigned int crc_init); static int crc32c_pcl_breakeven = CRC32C_PCL_BREAKEVEN_EAGERFPU; -#if defined(X86_FEATURE_EAGER_FPU) #define set_pcl_breakeven_point() \ do { \ if (!use_eager_fpu()) \ crc32c_pcl_breakeven = CRC32C_PCL_BREAKEVEN_NOEAGERFPU; \ } while (0) -#else -#define set_pcl_breakeven_point() \ - (crc32c_pcl_breakeven = CRC32C_PCL_BREAKEVEN_NOEAGERFPU) -#endif #endif /* CONFIG_X86_64 */ static u32 crc32c_intel_le_hw_byte(u32 crc, unsigned char const *data, size_t length) @@ -257,7 +252,7 @@ static int __init crc32c_intel_mod_init(void) if (!x86_match_cpu(crc32c_cpu_id)) return -ENODEV; #ifdef CONFIG_X86_64 - if (cpu_has_pclmulqdq) { + if (boot_cpu_has(X86_FEATURE_PCLMULQDQ)) { alg.update = crc32c_pcl_intel_update; alg.finup = crc32c_pcl_intel_finup; alg.digest = crc32c_pcl_intel_digest; diff --git a/arch/x86/crypto/crct10dif-pclmul_glue.c b/arch/x86/crypto/crct10dif-pclmul_glue.c index a3fcfc97a311d..cd4df93225014 100644 --- a/arch/x86/crypto/crct10dif-pclmul_glue.c +++ b/arch/x86/crypto/crct10dif-pclmul_glue.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include asmlinkage __u16 crc_t10dif_pcl(__u16 crc, const unsigned char *buf, diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c index b5eb1cca70a0a..071582a3b5c06 100644 --- a/arch/x86/entry/common.c +++ b/arch/x86/entry/common.c @@ -27,6 +27,7 @@ #include #include #include +#include #define CREATE_TRACE_POINTS #include diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S index d437f3871e532..49a8c9f7a3797 100644 --- a/arch/x86/entry/entry_32.S +++ b/arch/x86/entry/entry_32.S @@ -40,7 +40,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S index d03bf0e28b8b3..48c27c3fdfdbd 100644 --- a/arch/x86/entry/entry_64_compat.S +++ b/arch/x86/entry/entry_64_compat.S @@ -79,24 +79,33 @@ ENTRY(entry_SYSENTER_compat) ASM_CLAC /* Clear AC after saving FLAGS */ pushq $__USER32_CS /* pt_regs->cs */ - xorq %r8,%r8 - pushq %r8 /* pt_regs->ip = 0 (placeholder) */ + pushq $0 /* pt_regs->ip = 0 (placeholder) */ pushq %rax /* pt_regs->orig_ax */ pushq %rdi /* pt_regs->di */ pushq %rsi /* pt_regs->si */ pushq %rdx /* pt_regs->dx */ pushq %rcx /* pt_regs->cx */ pushq $-ENOSYS /* pt_regs->ax */ - pushq %r8 /* pt_regs->r8 = 0 */ - pushq %r8 /* pt_regs->r9 = 0 */ - pushq %r8 /* pt_regs->r10 = 0 */ - pushq %r8 /* pt_regs->r11 = 0 */ + pushq $0 /* pt_regs->r8 = 0 */ + xorq %r8, %r8 /* nospec r8 */ + pushq $0 /* pt_regs->r9 = 0 */ + xorq %r9, %r9 /* nospec r9 */ + pushq $0 /* pt_regs->r10 = 0 */ + xorq %r10, %r10 /* nospec r10 */ + pushq $0 /* pt_regs->r11 = 0 */ + xorq %r11, %r11 /* nospec r11 */ pushq %rbx /* pt_regs->rbx */ + xorl %ebx, %ebx /* nospec rbx */ pushq %rbp /* pt_regs->rbp (will be overwritten) */ - pushq %r8 /* pt_regs->r12 = 0 */ - pushq %r8 /* pt_regs->r13 = 0 */ - pushq %r8 /* pt_regs->r14 = 0 */ - pushq %r8 /* pt_regs->r15 = 0 */ + xorl %ebp, %ebp /* nospec rbp */ + pushq $0 /* pt_regs->r12 = 0 */ + xorq %r12, %r12 /* nospec r12 */ + pushq $0 /* pt_regs->r13 = 0 */ + xorq %r13, %r13 /* nospec r13 */ + pushq $0 /* pt_regs->r14 = 0 */ + xorq %r14, %r14 /* nospec r14 */ + pushq $0 /* pt_regs->r15 = 0 */ + xorq %r15, %r15 /* nospec r15 */ cld /* @@ -185,17 +194,26 @@ ENTRY(entry_SYSCALL_compat) pushq %rdx /* pt_regs->dx */ pushq %rbp /* pt_regs->cx (stashed in bp) */ pushq $-ENOSYS /* pt_regs->ax */ - xorq %r8,%r8 - pushq %r8 /* pt_regs->r8 = 0 */ - pushq %r8 /* pt_regs->r9 = 0 */ - pushq %r8 /* pt_regs->r10 = 0 */ - pushq %r8 /* pt_regs->r11 = 0 */ + pushq $0 /* pt_regs->r8 = 0 */ + xorq %r8, %r8 /* nospec r8 */ + pushq $0 /* pt_regs->r9 = 0 */ + xorq %r9, %r9 /* nospec r9 */ + pushq $0 /* pt_regs->r10 = 0 */ + xorq %r10, %r10 /* nospec r10 */ + pushq $0 /* pt_regs->r11 = 0 */ + xorq %r11, %r11 /* nospec r11 */ pushq %rbx /* pt_regs->rbx */ + xorl %ebx, %ebx /* nospec rbx */ pushq %rbp /* pt_regs->rbp (will be overwritten) */ - pushq %r8 /* pt_regs->r12 = 0 */ - pushq %r8 /* pt_regs->r13 = 0 */ - pushq %r8 /* pt_regs->r14 = 0 */ - pushq %r8 /* pt_regs->r15 = 0 */ + xorl %ebp, %ebp /* nospec rbp */ + pushq $0 /* pt_regs->r12 = 0 */ + xorq %r12, %r12 /* nospec r12 */ + pushq $0 /* pt_regs->r13 = 0 */ + xorq %r13, %r13 /* nospec r13 */ + pushq $0 /* pt_regs->r14 = 0 */ + xorq %r14, %r14 /* nospec r14 */ + pushq $0 /* pt_regs->r15 = 0 */ + xorq %r15, %r15 /* nospec r15 */ /* * User mode is traced as though IRQs are on, and SYSENTER @@ -292,17 +310,26 @@ ENTRY(entry_INT80_compat) pushq %rdx /* pt_regs->dx */ pushq %rcx /* pt_regs->cx */ pushq $-ENOSYS /* pt_regs->ax */ - xorq %r8,%r8 - pushq %r8 /* pt_regs->r8 = 0 */ - pushq %r8 /* pt_regs->r9 = 0 */ - pushq %r8 /* pt_regs->r10 = 0 */ - pushq %r8 /* pt_regs->r11 = 0 */ + pushq $0 /* pt_regs->r8 = 0 */ + xorq %r8, %r8 /* nospec r8 */ + pushq $0 /* pt_regs->r9 = 0 */ + xorq %r9, %r9 /* nospec r9 */ + pushq $0 /* pt_regs->r10 = 0 */ + xorq %r10, %r10 /* nospec r10 */ + pushq $0 /* pt_regs->r11 = 0 */ + xorq %r11, %r11 /* nospec r11 */ pushq %rbx /* pt_regs->rbx */ + xorl %ebx, %ebx /* nospec rbx */ pushq %rbp /* pt_regs->rbp */ + xorl %ebp, %ebp /* nospec rbp */ pushq %r12 /* pt_regs->r12 */ + xorq %r12, %r12 /* nospec r12 */ pushq %r13 /* pt_regs->r13 */ + xorq %r13, %r13 /* nospec r13 */ pushq %r14 /* pt_regs->r14 */ + xorq %r14, %r14 /* nospec r14 */ pushq %r15 /* pt_regs->r15 */ + xorq %r15, %r15 /* nospec r15 */ cld /* diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile index fddeb1f4dcd22..32acb36d0a9ab 100644 --- a/arch/x86/entry/vdso/Makefile +++ b/arch/x86/entry/vdso/Makefile @@ -166,7 +166,8 @@ quiet_cmd_vdso = VDSO $@ sh $(srctree)/$(src)/checkundef.sh '$(NM)' '$@' VDSO_LDFLAGS = -fPIC -shared $(call cc-ldoption, -Wl$(comma)--hash-style=both) \ - $(call cc-ldoption, -Wl$(comma)--build-id) -Wl,-Bsymbolic $(LTO_CFLAGS) + $(call cc-ldoption, -Wl$(comma)--build-id) -Wl,-Bsymbolic $(LTO_CFLAGS) \ + $(filter --target=% --gcc-toolchain=%,$(KBUILD_CFLAGS)) GCOV_PROFILE := n # diff --git a/arch/x86/entry/vdso/vdso32-setup.c b/arch/x86/entry/vdso/vdso32-setup.c index a7508d7e20b7c..3f9d1a83891ad 100644 --- a/arch/x86/entry/vdso/vdso32-setup.c +++ b/arch/x86/entry/vdso/vdso32-setup.c @@ -11,7 +11,6 @@ #include #include -#include #include #include diff --git a/arch/x86/entry/vdso/vdso32/system_call.S b/arch/x86/entry/vdso/vdso32/system_call.S index 3a1d9297074bc..0109ac6cb79cc 100644 --- a/arch/x86/entry/vdso/vdso32/system_call.S +++ b/arch/x86/entry/vdso/vdso32/system_call.S @@ -3,7 +3,7 @@ */ #include -#include +#include #include /* diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c index b8f69e264ac41..6b46648588d88 100644 --- a/arch/x86/entry/vdso/vma.c +++ b/arch/x86/entry/vdso/vma.c @@ -20,6 +20,7 @@ #include #include #include +#include #if defined(CONFIG_X86_64) unsigned int __read_mostly vdso64_enabled = 1; @@ -254,7 +255,7 @@ static void vgetcpu_cpu_init(void *arg) #ifdef CONFIG_NUMA node = cpu_to_node(cpu); #endif - if (cpu_has(&cpu_data(cpu), X86_FEATURE_RDTSCP)) + if (static_cpu_has(X86_FEATURE_RDTSCP)) write_rdtscp_aux((node << 12) | cpu); /* diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h index 215ea9214215c..002fcd901f073 100644 --- a/arch/x86/include/asm/alternative.h +++ b/arch/x86/include/asm/alternative.h @@ -153,12 +153,6 @@ static inline int alternatives_text_reserved(void *start, void *end) ALTINSTR_REPLACEMENT(newinstr2, feature2, 2) \ ".popsection\n" -/* - * This must be included *after* the definition of ALTERNATIVE due to - * - */ -#include - /* * Alternative instructions for different CPU types or capabilities. * diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index 163769d824754..fd810a57ab1b1 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -6,7 +6,6 @@ #include #include -#include #include #include #include diff --git a/arch/x86/include/asm/apm.h b/arch/x86/include/asm/apm.h index 20370c6db74bb..3d1ec41ae09ab 100644 --- a/arch/x86/include/asm/apm.h +++ b/arch/x86/include/asm/apm.h @@ -6,6 +6,8 @@ #ifndef _ASM_X86_MACH_DEFAULT_APM_H #define _ASM_X86_MACH_DEFAULT_APM_H +#include + #ifdef APM_ZERO_SEGS # define APM_DO_ZERO_SEGS \ "pushl %%ds\n\t" \ @@ -31,6 +33,7 @@ static inline void apm_bios_call_asm(u32 func, u32 ebx_in, u32 ecx_in, * N.B. We do NOT need a cld after the BIOS call * because we always save and restore the flags. */ + firmware_restrict_branch_speculation_start(); __asm__ __volatile__(APM_DO_ZERO_SEGS "pushl %%edi\n\t" "pushl %%ebp\n\t" @@ -43,6 +46,7 @@ static inline void apm_bios_call_asm(u32 func, u32 ebx_in, u32 ecx_in, "=S" (*esi) : "a" (func), "b" (ebx_in), "c" (ecx_in) : "memory", "cc"); + firmware_restrict_branch_speculation_end(); } static inline u8 apm_bios_call_simple_asm(u32 func, u32 ebx_in, @@ -55,6 +59,7 @@ static inline u8 apm_bios_call_simple_asm(u32 func, u32 ebx_in, * N.B. We do NOT need a cld after the BIOS call * because we always save and restore the flags. */ + firmware_restrict_branch_speculation_start(); __asm__ __volatile__(APM_DO_ZERO_SEGS "pushl %%edi\n\t" "pushl %%ebp\n\t" @@ -67,6 +72,7 @@ static inline u8 apm_bios_call_simple_asm(u32 func, u32 ebx_in, "=S" (si) : "a" (func), "b" (ebx_in), "c" (ecx_in) : "memory", "cc"); + firmware_restrict_branch_speculation_end(); return error; } diff --git a/arch/x86/include/asm/arch_hweight.h b/arch/x86/include/asm/arch_hweight.h index 44f825c80ed55..e7cd63175de44 100644 --- a/arch/x86/include/asm/arch_hweight.h +++ b/arch/x86/include/asm/arch_hweight.h @@ -1,6 +1,8 @@ #ifndef _ASM_X86_HWEIGHT_H #define _ASM_X86_HWEIGHT_H +#include + #ifdef CONFIG_64BIT /* popcnt %edi, %eax */ #define POPCNT32 ".byte 0xf3,0x0f,0xb8,0xc7" diff --git a/arch/x86/include/asm/asm.h b/arch/x86/include/asm/asm.h index 858f8c354cead..f3d4f1edc9478 100644 --- a/arch/x86/include/asm/asm.h +++ b/arch/x86/include/asm/asm.h @@ -45,6 +45,65 @@ #define _ASM_SI __ASM_REG(si) #define _ASM_DI __ASM_REG(di) +#ifndef __x86_64__ +/* 32 bit */ + +#define _ASM_ARG1 _ASM_AX +#define _ASM_ARG2 _ASM_DX +#define _ASM_ARG3 _ASM_CX + +#define _ASM_ARG1L eax +#define _ASM_ARG2L edx +#define _ASM_ARG3L ecx + +#define _ASM_ARG1W ax +#define _ASM_ARG2W dx +#define _ASM_ARG3W cx + +#define _ASM_ARG1B al +#define _ASM_ARG2B dl +#define _ASM_ARG3B cl + +#else +/* 64 bit */ + +#define _ASM_ARG1 _ASM_DI +#define _ASM_ARG2 _ASM_SI +#define _ASM_ARG3 _ASM_DX +#define _ASM_ARG4 _ASM_CX +#define _ASM_ARG5 r8 +#define _ASM_ARG6 r9 + +#define _ASM_ARG1Q rdi +#define _ASM_ARG2Q rsi +#define _ASM_ARG3Q rdx +#define _ASM_ARG4Q rcx +#define _ASM_ARG5Q r8 +#define _ASM_ARG6Q r9 + +#define _ASM_ARG1L edi +#define _ASM_ARG2L esi +#define _ASM_ARG3L edx +#define _ASM_ARG4L ecx +#define _ASM_ARG5L r8d +#define _ASM_ARG6L r9d + +#define _ASM_ARG1W di +#define _ASM_ARG2W si +#define _ASM_ARG3W dx +#define _ASM_ARG4W cx +#define _ASM_ARG5W r8w +#define _ASM_ARG6W r9w + +#define _ASM_ARG1B dil +#define _ASM_ARG2B sil +#define _ASM_ARG3B dl +#define _ASM_ARG4B cl +#define _ASM_ARG5B r8b +#define _ASM_ARG6B r9b + +#endif + /* Exception table entry */ #ifdef __ASSEMBLY__ # define _ASM_EXTABLE(from,to) \ diff --git a/arch/x86/include/asm/atomic.h b/arch/x86/include/asm/atomic.h index ae5fb83e6d91c..3e86742881984 100644 --- a/arch/x86/include/asm/atomic.h +++ b/arch/x86/include/asm/atomic.h @@ -3,7 +3,6 @@ #include #include -#include #include #include #include diff --git a/arch/x86/include/asm/atomic64_32.h b/arch/x86/include/asm/atomic64_32.h index a11c30b77fb57..a984111135b16 100644 --- a/arch/x86/include/asm/atomic64_32.h +++ b/arch/x86/include/asm/atomic64_32.h @@ -3,7 +3,6 @@ #include #include -#include //#include /* An 64bit atomic type */ diff --git a/arch/x86/include/asm/barrier.h b/arch/x86/include/asm/barrier.h index 814ef83c67203..7f5dcb64cedb2 100644 --- a/arch/x86/include/asm/barrier.h +++ b/arch/x86/include/asm/barrier.h @@ -38,9 +38,9 @@ static inline unsigned long array_index_mask_nospec(unsigned long index, { unsigned long mask; - asm ("cmp %1,%2; sbb %0,%0;" + asm volatile ("cmp %1,%2; sbb %0,%0;" :"=r" (mask) - :"r"(size),"r" (index) + :"g"(size),"r" (index) :"cc"); return mask; } diff --git a/arch/x86/include/asm/cmpxchg.h b/arch/x86/include/asm/cmpxchg.h index ad19841eddfe1..9733361fed6f4 100644 --- a/arch/x86/include/asm/cmpxchg.h +++ b/arch/x86/include/asm/cmpxchg.h @@ -2,6 +2,7 @@ #define ASM_X86_CMPXCHG_H #include +#include #include /* Provides LOCK_PREFIX */ /* diff --git a/arch/x86/include/asm/cmpxchg_32.h b/arch/x86/include/asm/cmpxchg_32.h index f7e142926481b..e4959d023af84 100644 --- a/arch/x86/include/asm/cmpxchg_32.h +++ b/arch/x86/include/asm/cmpxchg_32.h @@ -109,6 +109,6 @@ static inline u64 __cmpxchg64_local(volatile u64 *ptr, u64 old, u64 new) #endif -#define system_has_cmpxchg_double() cpu_has_cx8 +#define system_has_cmpxchg_double() boot_cpu_has(X86_FEATURE_CX8) #endif /* _ASM_X86_CMPXCHG_32_H */ diff --git a/arch/x86/include/asm/cmpxchg_64.h b/arch/x86/include/asm/cmpxchg_64.h index 1af94697aae51..caa23a34c963a 100644 --- a/arch/x86/include/asm/cmpxchg_64.h +++ b/arch/x86/include/asm/cmpxchg_64.h @@ -18,6 +18,6 @@ static inline void set_64bit(volatile u64 *ptr, u64 val) cmpxchg_local((ptr), (o), (n)); \ }) -#define system_has_cmpxchg_double() cpu_has_cx16 +#define system_has_cmpxchg_double() boot_cpu_has(X86_FEATURE_CX16) #endif /* _ASM_X86_CMPXCHG_64_H */ diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index 641f0f2c2982f..d72c1db646791 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h @@ -1,294 +1,36 @@ -/* - * Defines x86 CPU feature bits - */ #ifndef _ASM_X86_CPUFEATURE_H #define _ASM_X86_CPUFEATURE_H -#ifndef _ASM_X86_REQUIRED_FEATURES_H -#include -#endif - -#ifndef _ASM_X86_DISABLED_FEATURES_H -#include -#endif - -#define NCAPINTS 14 /* N 32-bit words worth of info */ -#define NBUGINTS 1 /* N 32-bit bug flags */ - -/* - * Note: If the comment begins with a quoted string, that string is used - * in /proc/cpuinfo instead of the macro name. If the string is "", - * this feature bit is not displayed in /proc/cpuinfo at all. - */ - -/* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */ -#define X86_FEATURE_FPU ( 0*32+ 0) /* Onboard FPU */ -#define X86_FEATURE_VME ( 0*32+ 1) /* Virtual Mode Extensions */ -#define X86_FEATURE_DE ( 0*32+ 2) /* Debugging Extensions */ -#define X86_FEATURE_PSE ( 0*32+ 3) /* Page Size Extensions */ -#define X86_FEATURE_TSC ( 0*32+ 4) /* Time Stamp Counter */ -#define X86_FEATURE_MSR ( 0*32+ 5) /* Model-Specific Registers */ -#define X86_FEATURE_PAE ( 0*32+ 6) /* Physical Address Extensions */ -#define X86_FEATURE_MCE ( 0*32+ 7) /* Machine Check Exception */ -#define X86_FEATURE_CX8 ( 0*32+ 8) /* CMPXCHG8 instruction */ -#define X86_FEATURE_APIC ( 0*32+ 9) /* Onboard APIC */ -#define X86_FEATURE_SEP ( 0*32+11) /* SYSENTER/SYSEXIT */ -#define X86_FEATURE_MTRR ( 0*32+12) /* Memory Type Range Registers */ -#define X86_FEATURE_PGE ( 0*32+13) /* Page Global Enable */ -#define X86_FEATURE_MCA ( 0*32+14) /* Machine Check Architecture */ -#define X86_FEATURE_CMOV ( 0*32+15) /* CMOV instructions */ - /* (plus FCMOVcc, FCOMI with FPU) */ -#define X86_FEATURE_PAT ( 0*32+16) /* Page Attribute Table */ -#define X86_FEATURE_PSE36 ( 0*32+17) /* 36-bit PSEs */ -#define X86_FEATURE_PN ( 0*32+18) /* Processor serial number */ -#define X86_FEATURE_CLFLUSH ( 0*32+19) /* CLFLUSH instruction */ -#define X86_FEATURE_DS ( 0*32+21) /* "dts" Debug Store */ -#define X86_FEATURE_ACPI ( 0*32+22) /* ACPI via MSR */ -#define X86_FEATURE_MMX ( 0*32+23) /* Multimedia Extensions */ -#define X86_FEATURE_FXSR ( 0*32+24) /* FXSAVE/FXRSTOR, CR4.OSFXSR */ -#define X86_FEATURE_XMM ( 0*32+25) /* "sse" */ -#define X86_FEATURE_XMM2 ( 0*32+26) /* "sse2" */ -#define X86_FEATURE_SELFSNOOP ( 0*32+27) /* "ss" CPU self snoop */ -#define X86_FEATURE_HT ( 0*32+28) /* Hyper-Threading */ -#define X86_FEATURE_ACC ( 0*32+29) /* "tm" Automatic clock control */ -#define X86_FEATURE_IA64 ( 0*32+30) /* IA-64 processor */ -#define X86_FEATURE_PBE ( 0*32+31) /* Pending Break Enable */ - -/* AMD-defined CPU features, CPUID level 0x80000001, word 1 */ -/* Don't duplicate feature flags which are redundant with Intel! */ -#define X86_FEATURE_SYSCALL ( 1*32+11) /* SYSCALL/SYSRET */ -#define X86_FEATURE_MP ( 1*32+19) /* MP Capable. */ -#define X86_FEATURE_NX ( 1*32+20) /* Execute Disable */ -#define X86_FEATURE_MMXEXT ( 1*32+22) /* AMD MMX extensions */ -#define X86_FEATURE_FXSR_OPT ( 1*32+25) /* FXSAVE/FXRSTOR optimizations */ -#define X86_FEATURE_GBPAGES ( 1*32+26) /* "pdpe1gb" GB pages */ -#define X86_FEATURE_RDTSCP ( 1*32+27) /* RDTSCP */ -#define X86_FEATURE_LM ( 1*32+29) /* Long Mode (x86-64) */ -#define X86_FEATURE_3DNOWEXT ( 1*32+30) /* AMD 3DNow! extensions */ -#define X86_FEATURE_3DNOW ( 1*32+31) /* 3DNow! */ - -/* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */ -#define X86_FEATURE_RECOVERY ( 2*32+ 0) /* CPU in recovery mode */ -#define X86_FEATURE_LONGRUN ( 2*32+ 1) /* Longrun power control */ -#define X86_FEATURE_LRTI ( 2*32+ 3) /* LongRun table interface */ - -/* Other features, Linux-defined mapping, word 3 */ -/* This range is used for feature bits which conflict or are synthesized */ -#define X86_FEATURE_CXMMX ( 3*32+ 0) /* Cyrix MMX extensions */ -#define X86_FEATURE_K6_MTRR ( 3*32+ 1) /* AMD K6 nonstandard MTRRs */ -#define X86_FEATURE_CYRIX_ARR ( 3*32+ 2) /* Cyrix ARRs (= MTRRs) */ -#define X86_FEATURE_CENTAUR_MCR ( 3*32+ 3) /* Centaur MCRs (= MTRRs) */ -/* cpu types for specific tunings: */ -#define X86_FEATURE_K8 ( 3*32+ 4) /* "" Opteron, Athlon64 */ -#define X86_FEATURE_K7 ( 3*32+ 5) /* "" Athlon */ -#define X86_FEATURE_P3 ( 3*32+ 6) /* "" P3 */ -#define X86_FEATURE_P4 ( 3*32+ 7) /* "" P4 */ -#define X86_FEATURE_CONSTANT_TSC ( 3*32+ 8) /* TSC ticks at a constant rate */ -#define X86_FEATURE_UP ( 3*32+ 9) /* smp kernel running on up */ -/* free, was #define X86_FEATURE_FXSAVE_LEAK ( 3*32+10) * "" FXSAVE leaks FOP/FIP/FOP */ -#define X86_FEATURE_ARCH_PERFMON ( 3*32+11) /* Intel Architectural PerfMon */ -#define X86_FEATURE_PEBS ( 3*32+12) /* Precise-Event Based Sampling */ -#define X86_FEATURE_BTS ( 3*32+13) /* Branch Trace Store */ -#define X86_FEATURE_SYSCALL32 ( 3*32+14) /* "" syscall in ia32 userspace */ -#define X86_FEATURE_SYSENTER32 ( 3*32+15) /* "" sysenter in ia32 userspace */ -#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_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 */ -#define X86_FEATURE_TSC_RELIABLE ( 3*32+23) /* TSC is known to be reliable */ -#define X86_FEATURE_NONSTOP_TSC ( 3*32+24) /* TSC does not stop in C states */ -/* free, was #define X86_FEATURE_CLFLUSH_MONITOR ( 3*32+25) * "" clflush reqd with monitor */ -#define X86_FEATURE_EXTD_APICID ( 3*32+26) /* has extended APICID (8 bits) */ -#define X86_FEATURE_AMD_DCM ( 3*32+27) /* multi-node processor */ -#define X86_FEATURE_APERFMPERF ( 3*32+28) /* APERFMPERF */ -#define X86_FEATURE_EAGER_FPU ( 3*32+29) /* "eagerfpu" Non lazy FPU restore */ -#define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* TSC doesn't stop in S3 state */ - -/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ -#define X86_FEATURE_XMM3 ( 4*32+ 0) /* "pni" SSE-3 */ -#define X86_FEATURE_PCLMULQDQ ( 4*32+ 1) /* PCLMULQDQ instruction */ -#define X86_FEATURE_DTES64 ( 4*32+ 2) /* 64-bit Debug Store */ -#define X86_FEATURE_MWAIT ( 4*32+ 3) /* "monitor" Monitor/Mwait support */ -#define X86_FEATURE_DSCPL ( 4*32+ 4) /* "ds_cpl" CPL Qual. Debug Store */ -#define X86_FEATURE_VMX ( 4*32+ 5) /* Hardware virtualization */ -#define X86_FEATURE_SMX ( 4*32+ 6) /* Safer mode */ -#define X86_FEATURE_EST ( 4*32+ 7) /* Enhanced SpeedStep */ -#define X86_FEATURE_TM2 ( 4*32+ 8) /* Thermal Monitor 2 */ -#define X86_FEATURE_SSSE3 ( 4*32+ 9) /* Supplemental SSE-3 */ -#define X86_FEATURE_CID ( 4*32+10) /* Context ID */ -#define X86_FEATURE_SDBG ( 4*32+11) /* Silicon Debug */ -#define X86_FEATURE_FMA ( 4*32+12) /* Fused multiply-add */ -#define X86_FEATURE_CX16 ( 4*32+13) /* CMPXCHG16B */ -#define X86_FEATURE_XTPR ( 4*32+14) /* Send Task Priority Messages */ -#define X86_FEATURE_PDCM ( 4*32+15) /* Performance Capabilities */ -#define X86_FEATURE_PCID ( 4*32+17) /* Process Context Identifiers */ -#define X86_FEATURE_DCA ( 4*32+18) /* Direct Cache Access */ -#define X86_FEATURE_XMM4_1 ( 4*32+19) /* "sse4_1" SSE-4.1 */ -#define X86_FEATURE_XMM4_2 ( 4*32+20) /* "sse4_2" SSE-4.2 */ -#define X86_FEATURE_X2APIC ( 4*32+21) /* x2APIC */ -#define X86_FEATURE_MOVBE ( 4*32+22) /* MOVBE instruction */ -#define X86_FEATURE_POPCNT ( 4*32+23) /* POPCNT instruction */ -#define X86_FEATURE_TSC_DEADLINE_TIMER ( 4*32+24) /* Tsc deadline timer */ -#define X86_FEATURE_AES ( 4*32+25) /* AES instructions */ -#define X86_FEATURE_XSAVE ( 4*32+26) /* XSAVE/XRSTOR/XSETBV/XGETBV */ -#define X86_FEATURE_OSXSAVE ( 4*32+27) /* "" XSAVE enabled in the OS */ -#define X86_FEATURE_AVX ( 4*32+28) /* Advanced Vector Extensions */ -#define X86_FEATURE_F16C ( 4*32+29) /* 16-bit fp conversions */ -#define X86_FEATURE_RDRAND ( 4*32+30) /* The RDRAND instruction */ -#define X86_FEATURE_HYPERVISOR ( 4*32+31) /* Running on a hypervisor */ - -/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */ -#define X86_FEATURE_XSTORE ( 5*32+ 2) /* "rng" RNG present (xstore) */ -#define X86_FEATURE_XSTORE_EN ( 5*32+ 3) /* "rng_en" RNG enabled */ -#define X86_FEATURE_XCRYPT ( 5*32+ 6) /* "ace" on-CPU crypto (xcrypt) */ -#define X86_FEATURE_XCRYPT_EN ( 5*32+ 7) /* "ace_en" on-CPU crypto enabled */ -#define X86_FEATURE_ACE2 ( 5*32+ 8) /* Advanced Cryptography Engine v2 */ -#define X86_FEATURE_ACE2_EN ( 5*32+ 9) /* ACE v2 enabled */ -#define X86_FEATURE_PHE ( 5*32+10) /* PadLock Hash Engine */ -#define X86_FEATURE_PHE_EN ( 5*32+11) /* PHE enabled */ -#define X86_FEATURE_PMM ( 5*32+12) /* PadLock Montgomery Multiplier */ -#define X86_FEATURE_PMM_EN ( 5*32+13) /* PMM enabled */ - -/* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */ -#define X86_FEATURE_LAHF_LM ( 6*32+ 0) /* LAHF/SAHF in long mode */ -#define X86_FEATURE_CMP_LEGACY ( 6*32+ 1) /* If yes HyperThreading not valid */ -#define X86_FEATURE_SVM ( 6*32+ 2) /* Secure virtual machine */ -#define X86_FEATURE_EXTAPIC ( 6*32+ 3) /* Extended APIC space */ -#define X86_FEATURE_CR8_LEGACY ( 6*32+ 4) /* CR8 in 32-bit mode */ -#define X86_FEATURE_ABM ( 6*32+ 5) /* Advanced bit manipulation */ -#define X86_FEATURE_SSE4A ( 6*32+ 6) /* SSE-4A */ -#define X86_FEATURE_MISALIGNSSE ( 6*32+ 7) /* Misaligned SSE mode */ -#define X86_FEATURE_3DNOWPREFETCH ( 6*32+ 8) /* 3DNow prefetch instructions */ -#define X86_FEATURE_OSVW ( 6*32+ 9) /* OS Visible Workaround */ -#define X86_FEATURE_IBS ( 6*32+10) /* Instruction Based Sampling */ -#define X86_FEATURE_XOP ( 6*32+11) /* extended AVX instructions */ -#define X86_FEATURE_SKINIT ( 6*32+12) /* SKINIT/STGI instructions */ -#define X86_FEATURE_WDT ( 6*32+13) /* Watchdog timer */ -#define X86_FEATURE_LWP ( 6*32+15) /* Light Weight Profiling */ -#define X86_FEATURE_FMA4 ( 6*32+16) /* 4 operands MAC instructions */ -#define X86_FEATURE_TCE ( 6*32+17) /* translation cache extension */ -#define X86_FEATURE_NODEID_MSR ( 6*32+19) /* NodeId MSR */ -#define X86_FEATURE_TBM ( 6*32+21) /* trailing bit manipulations */ -#define X86_FEATURE_TOPOEXT ( 6*32+22) /* topology extensions CPUID leafs */ -#define X86_FEATURE_PERFCTR_CORE ( 6*32+23) /* core performance counter extensions */ -#define X86_FEATURE_PERFCTR_NB ( 6*32+24) /* NB performance counter extensions */ -#define X86_FEATURE_BPEXT (6*32+26) /* data breakpoint extension */ -#define X86_FEATURE_PERFCTR_L2 ( 6*32+28) /* L2 performance counter extensions */ -#define X86_FEATURE_MWAITX ( 6*32+29) /* MWAIT extension (MONITORX/MWAITX) */ - -/* - * Auxiliary flags: Linux defined - For features scattered in various - * CPUID levels like 0x6, 0xA etc, word 7 - */ -#define X86_FEATURE_IDA ( 7*32+ 0) /* Intel Dynamic Acceleration */ -#define X86_FEATURE_ARAT ( 7*32+ 1) /* Always Running APIC Timer */ -#define X86_FEATURE_CPB ( 7*32+ 2) /* AMD Core Performance Boost */ -#define X86_FEATURE_EPB ( 7*32+ 3) /* IA32_ENERGY_PERF_BIAS support */ -#define X86_FEATURE_INVPCID_SINGLE ( 7*32+ 4) /* Effectively INVPCID && CR4.PCIDE=1 */ -#define X86_FEATURE_PLN ( 7*32+ 5) /* Intel Power Limit Notification */ -#define X86_FEATURE_PTS ( 7*32+ 6) /* Intel Package Thermal Status */ -#define X86_FEATURE_DTHERM ( 7*32+ 7) /* Digital Thermal Sensor */ -#define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */ -#define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */ -#define X86_FEATURE_HWP ( 7*32+ 10) /* "hwp" Intel HWP */ -#define X86_FEATURE_HWP_NOTIFY ( 7*32+ 11) /* Intel HWP_NOTIFY */ -#define X86_FEATURE_HWP_ACT_WINDOW ( 7*32+ 12) /* Intel HWP_ACT_WINDOW */ -#define X86_FEATURE_HWP_EPP ( 7*32+13) /* Intel HWP_EPP */ -#define X86_FEATURE_HWP_PKG_REQ ( 7*32+14) /* Intel HWP_PKG_REQ */ -#define X86_FEATURE_INTEL_PT ( 7*32+15) /* Intel Processor Trace */ -#define X86_FEATURE_RSB_CTXSW ( 7*32+19) /* Fill RSB on context switches */ - -#define X86_FEATURE_RETPOLINE ( 7*32+29) /* Generic Retpoline mitigation for Spectre variant 2 */ -#define X86_FEATURE_RETPOLINE_AMD ( 7*32+30) /* AMD Retpoline mitigation for Spectre variant 2 */ -/* Because the ALTERNATIVE scheme is for members of the X86_FEATURE club... */ -#define X86_FEATURE_KAISER ( 7*32+31) /* CONFIG_PAGE_TABLE_ISOLATION w/o nokaiser */ - -/* Virtualization flags: Linux defined, word 8 */ -#define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */ -#define X86_FEATURE_VNMI ( 8*32+ 1) /* Intel Virtual NMI */ -#define X86_FEATURE_FLEXPRIORITY ( 8*32+ 2) /* Intel FlexPriority */ -#define X86_FEATURE_EPT ( 8*32+ 3) /* Intel Extended Page Table */ -#define X86_FEATURE_VPID ( 8*32+ 4) /* Intel Virtual Processor ID */ -#define X86_FEATURE_NPT ( 8*32+ 5) /* AMD Nested Page Table support */ -#define X86_FEATURE_LBRV ( 8*32+ 6) /* AMD LBR Virtualization support */ -#define X86_FEATURE_SVML ( 8*32+ 7) /* "svm_lock" AMD SVM locking MSR */ -#define X86_FEATURE_NRIPS ( 8*32+ 8) /* "nrip_save" AMD SVM next_rip save */ -#define X86_FEATURE_TSCRATEMSR ( 8*32+ 9) /* "tsc_scale" AMD TSC scaling support */ -#define X86_FEATURE_VMCBCLEAN ( 8*32+10) /* "vmcb_clean" AMD VMCB clean bits support */ -#define X86_FEATURE_FLUSHBYASID ( 8*32+11) /* AMD flush-by-ASID support */ -#define X86_FEATURE_DECODEASSISTS ( 8*32+12) /* AMD Decode Assists support */ -#define X86_FEATURE_PAUSEFILTER ( 8*32+13) /* AMD filtered pause intercept */ -#define X86_FEATURE_PFTHRESHOLD ( 8*32+14) /* AMD pause filter threshold */ -#define X86_FEATURE_VMMCALL ( 8*32+15) /* Prefer vmmcall to vmcall */ -#define X86_FEATURE_XENPV ( 8*32+16) /* "" Xen paravirtual guest */ - - -/* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */ -#define X86_FEATURE_FSGSBASE ( 9*32+ 0) /* {RD/WR}{FS/GS}BASE instructions*/ -#define X86_FEATURE_TSC_ADJUST ( 9*32+ 1) /* TSC adjustment MSR 0x3b */ -#define X86_FEATURE_BMI1 ( 9*32+ 3) /* 1st group bit manipulation extensions */ -#define X86_FEATURE_HLE ( 9*32+ 4) /* Hardware Lock Elision */ -#define X86_FEATURE_AVX2 ( 9*32+ 5) /* AVX2 instructions */ -#define X86_FEATURE_SMEP ( 9*32+ 7) /* Supervisor Mode Execution Protection */ -#define X86_FEATURE_BMI2 ( 9*32+ 8) /* 2nd group bit manipulation extensions */ -#define X86_FEATURE_ERMS ( 9*32+ 9) /* Enhanced REP MOVSB/STOSB */ -#define X86_FEATURE_INVPCID ( 9*32+10) /* Invalidate Processor Context ID */ -#define X86_FEATURE_RTM ( 9*32+11) /* Restricted Transactional Memory */ -#define X86_FEATURE_CQM ( 9*32+12) /* Cache QoS Monitoring */ -#define X86_FEATURE_MPX ( 9*32+14) /* Memory Protection Extension */ -#define X86_FEATURE_AVX512F ( 9*32+16) /* AVX-512 Foundation */ -#define X86_FEATURE_RDSEED ( 9*32+18) /* The RDSEED instruction */ -#define X86_FEATURE_ADX ( 9*32+19) /* The ADCX and ADOX instructions */ -#define X86_FEATURE_SMAP ( 9*32+20) /* Supervisor Mode Access Prevention */ -#define X86_FEATURE_PCOMMIT ( 9*32+22) /* PCOMMIT instruction */ -#define X86_FEATURE_CLFLUSHOPT ( 9*32+23) /* CLFLUSHOPT instruction */ -#define X86_FEATURE_CLWB ( 9*32+24) /* CLWB instruction */ -#define X86_FEATURE_AVX512PF ( 9*32+26) /* AVX-512 Prefetch */ -#define X86_FEATURE_AVX512ER ( 9*32+27) /* AVX-512 Exponential and Reciprocal */ -#define X86_FEATURE_AVX512CD ( 9*32+28) /* AVX-512 Conflict Detection */ -#define X86_FEATURE_SHA_NI ( 9*32+29) /* SHA1/SHA256 Instruction Extensions */ - -/* Extended state features, CPUID level 0x0000000d:1 (eax), word 10 */ -#define X86_FEATURE_XSAVEOPT (10*32+ 0) /* XSAVEOPT */ -#define X86_FEATURE_XSAVEC (10*32+ 1) /* XSAVEC */ -#define X86_FEATURE_XGETBV1 (10*32+ 2) /* XGETBV with ECX = 1 */ -#define X86_FEATURE_XSAVES (10*32+ 3) /* XSAVES/XRSTORS */ - -/* Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:0 (edx), word 11 */ -#define X86_FEATURE_CQM_LLC (11*32+ 1) /* LLC QoS if 1 */ - -/* 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 */ - -/* AMD-defined CPU features, CPUID level 0x80000008 (ebx), word 13 */ -#define X86_FEATURE_CLZERO (13*32+0) /* CLZERO instruction */ - -/* - * BUG word(s) - */ -#define X86_BUG(x) (NCAPINTS*32 + (x)) - -#define X86_BUG_F00F X86_BUG(0) /* Intel F00F */ -#define X86_BUG_FDIV X86_BUG(1) /* FPU FDIV */ -#define X86_BUG_COMA X86_BUG(2) /* Cyrix 6x86 coma */ -#define X86_BUG_AMD_TLB_MMATCH X86_BUG(3) /* "tlb_mmatch" AMD Erratum 383 */ -#define X86_BUG_AMD_APIC_C1E X86_BUG(4) /* "apic_c1e" AMD Erratum 400 */ -#define X86_BUG_11AP X86_BUG(5) /* Bad local APIC aka 11AP */ -#define X86_BUG_FXSAVE_LEAK X86_BUG(6) /* FXSAVE leaks FOP/FIP/FOP */ -#define X86_BUG_CLFLUSH_MONITOR X86_BUG(7) /* AAI65, CLFLUSH required before MONITOR */ -#define X86_BUG_SYSRET_SS_ATTRS X86_BUG(8) /* SYSRET doesn't fix up SS attrs */ -#define X86_BUG_CPU_MELTDOWN X86_BUG(14) /* CPU is affected by meltdown attack and needs kernel page table isolation */ -#define X86_BUG_SPECTRE_V1 X86_BUG(15) /* CPU is affected by Spectre variant 1 attack with conditional branches */ -#define X86_BUG_SPECTRE_V2 X86_BUG(16) /* CPU is affected by Spectre variant 2 attack with indirect branches */ +#include #if defined(__KERNEL__) && !defined(__ASSEMBLY__) #include #include +enum cpuid_leafs +{ + CPUID_1_EDX = 0, + CPUID_8000_0001_EDX, + CPUID_8086_0001_EDX, + CPUID_LNX_1, + CPUID_1_ECX, + CPUID_C000_0001_EDX, + CPUID_8000_0001_ECX, + CPUID_LNX_2, + CPUID_LNX_3, + CPUID_7_0_EBX, + CPUID_D_1_EAX, + CPUID_F_0_EDX, + CPUID_F_1_EDX, + CPUID_8000_0008_EBX, + CPUID_6_EAX, + CPUID_8000_000A_EDX, + CPUID_7_ECX, + CPUID_8000_0007_EBX, + CPUID_7_EDX, +}; + #ifdef CONFIG_X86_FEATURE_NAMES extern const char * const x86_cap_flags[NCAPINTS*32]; extern const char * const x86_power_flags[32]; @@ -308,29 +50,61 @@ extern const char * const x86_bug_flags[NBUGINTS*32]; #define test_cpu_cap(c, bit) \ 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)) ) - -#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)) ) +/* + * There are 32 bits/features in each mask word. The high bits + * (selected with (bit>>5) give us the word number and the low 5 + * bits give us the bit/feature number inside the word. + * (1UL<<((bit)&31) gives us a mask for the feature_bit so we can + * see if it is set in the mask word. + */ +#define CHECK_BIT_IN_MASK_WORD(maskname, word, bit) \ + (((bit)>>5)==(word) && (1UL<<((bit)&31) & maskname##word )) + +#define REQUIRED_MASK_BIT_SET(feature_bit) \ + ( CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 0, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 1, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 2, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 3, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 4, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 5, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 6, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 7, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 8, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 9, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 10, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 11, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 12, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 13, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 14, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 15, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 16, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 17, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 18, feature_bit) || \ + REQUIRED_MASK_CHECK || \ + BUILD_BUG_ON_ZERO(NCAPINTS != 19)) + +#define DISABLED_MASK_BIT_SET(feature_bit) \ + ( CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 0, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 1, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 2, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 3, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 4, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 5, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 6, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 7, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 8, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 9, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 10, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 11, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 12, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 13, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 14, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 15, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 16, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 17, feature_bit) || \ + CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 18, feature_bit) || \ + DISABLED_MASK_CHECK || \ + BUILD_BUG_ON_ZERO(NCAPINTS != 19)) #define cpu_has(c, bit) \ (__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \ @@ -349,8 +123,7 @@ extern const char * const x86_bug_flags[NBUGINTS*32]; * is not relevant. */ #define cpu_feature_enabled(bit) \ - (__builtin_constant_p(bit) && DISABLED_MASK_BIT_SET(bit) ? 0 : \ - cpu_has(&boot_cpu_data, bit)) + (__builtin_constant_p(bit) && DISABLED_MASK_BIT_SET(bit) ? 0 : static_cpu_has(bit)) #define boot_cpu_has(bit) cpu_has(&boot_cpu_data, bit) @@ -368,155 +141,39 @@ extern const char * const x86_bug_flags[NBUGINTS*32]; #define setup_force_cpu_bug(bit) setup_force_cpu_cap(bit) #define cpu_has_fpu boot_cpu_has(X86_FEATURE_FPU) -#define cpu_has_de boot_cpu_has(X86_FEATURE_DE) #define cpu_has_pse boot_cpu_has(X86_FEATURE_PSE) #define cpu_has_tsc boot_cpu_has(X86_FEATURE_TSC) #define cpu_has_pge boot_cpu_has(X86_FEATURE_PGE) #define cpu_has_apic boot_cpu_has(X86_FEATURE_APIC) -#define cpu_has_sep boot_cpu_has(X86_FEATURE_SEP) -#define cpu_has_mtrr boot_cpu_has(X86_FEATURE_MTRR) -#define cpu_has_mmx boot_cpu_has(X86_FEATURE_MMX) #define cpu_has_fxsr boot_cpu_has(X86_FEATURE_FXSR) #define cpu_has_xmm boot_cpu_has(X86_FEATURE_XMM) #define cpu_has_xmm2 boot_cpu_has(X86_FEATURE_XMM2) -#define cpu_has_xmm3 boot_cpu_has(X86_FEATURE_XMM3) -#define cpu_has_ssse3 boot_cpu_has(X86_FEATURE_SSSE3) #define cpu_has_aes boot_cpu_has(X86_FEATURE_AES) #define cpu_has_avx boot_cpu_has(X86_FEATURE_AVX) #define cpu_has_avx2 boot_cpu_has(X86_FEATURE_AVX2) -#define cpu_has_ht boot_cpu_has(X86_FEATURE_HT) -#define cpu_has_nx boot_cpu_has(X86_FEATURE_NX) -#define cpu_has_xstore boot_cpu_has(X86_FEATURE_XSTORE) -#define cpu_has_xstore_enabled boot_cpu_has(X86_FEATURE_XSTORE_EN) -#define cpu_has_xcrypt boot_cpu_has(X86_FEATURE_XCRYPT) -#define cpu_has_xcrypt_enabled boot_cpu_has(X86_FEATURE_XCRYPT_EN) -#define cpu_has_ace2 boot_cpu_has(X86_FEATURE_ACE2) -#define cpu_has_ace2_enabled boot_cpu_has(X86_FEATURE_ACE2_EN) -#define cpu_has_phe boot_cpu_has(X86_FEATURE_PHE) -#define cpu_has_phe_enabled boot_cpu_has(X86_FEATURE_PHE_EN) -#define cpu_has_pmm boot_cpu_has(X86_FEATURE_PMM) -#define cpu_has_pmm_enabled boot_cpu_has(X86_FEATURE_PMM_EN) -#define cpu_has_ds boot_cpu_has(X86_FEATURE_DS) -#define cpu_has_pebs boot_cpu_has(X86_FEATURE_PEBS) #define cpu_has_clflush boot_cpu_has(X86_FEATURE_CLFLUSH) -#define cpu_has_bts boot_cpu_has(X86_FEATURE_BTS) #define cpu_has_gbpages boot_cpu_has(X86_FEATURE_GBPAGES) #define cpu_has_arch_perfmon boot_cpu_has(X86_FEATURE_ARCH_PERFMON) #define cpu_has_pat boot_cpu_has(X86_FEATURE_PAT) -#define cpu_has_xmm4_1 boot_cpu_has(X86_FEATURE_XMM4_1) -#define cpu_has_xmm4_2 boot_cpu_has(X86_FEATURE_XMM4_2) #define cpu_has_x2apic boot_cpu_has(X86_FEATURE_X2APIC) #define cpu_has_xsave boot_cpu_has(X86_FEATURE_XSAVE) -#define cpu_has_xsaveopt boot_cpu_has(X86_FEATURE_XSAVEOPT) #define cpu_has_xsaves boot_cpu_has(X86_FEATURE_XSAVES) #define cpu_has_osxsave boot_cpu_has(X86_FEATURE_OSXSAVE) #define cpu_has_hypervisor boot_cpu_has(X86_FEATURE_HYPERVISOR) -#define cpu_has_pclmulqdq boot_cpu_has(X86_FEATURE_PCLMULQDQ) -#define cpu_has_perfctr_core boot_cpu_has(X86_FEATURE_PERFCTR_CORE) -#define cpu_has_perfctr_nb boot_cpu_has(X86_FEATURE_PERFCTR_NB) -#define cpu_has_perfctr_l2 boot_cpu_has(X86_FEATURE_PERFCTR_L2) -#define cpu_has_cx8 boot_cpu_has(X86_FEATURE_CX8) -#define cpu_has_cx16 boot_cpu_has(X86_FEATURE_CX16) -#define cpu_has_eager_fpu boot_cpu_has(X86_FEATURE_EAGER_FPU) -#define cpu_has_topoext boot_cpu_has(X86_FEATURE_TOPOEXT) -#define cpu_has_bpext boot_cpu_has(X86_FEATURE_BPEXT) - -#if __GNUC__ >= 4 -extern void warn_pre_alternatives(void); -extern bool __static_cpu_has_safe(u16 bit); +/* + * Do not add any more of those clumsy macros - use static_cpu_has() for + * fast paths and boot_cpu_has() otherwise! + */ +#if defined(CC_HAVE_ASM_GOTO) && defined(CONFIG_X86_FAST_FEATURE_TESTS) /* * Static testing of CPU features. Used the same as boot_cpu_has(). - * These are only valid after alternatives have run, but will statically - * patch the target code for additional performance. + * These will statically patch the target code for additional + * performance. */ -static __always_inline __pure bool __static_cpu_has(u16 bit) +static __always_inline __pure bool _static_cpu_has(u16 bit) { -#ifdef CC_HAVE_ASM_GOTO - -#ifdef CONFIG_X86_DEBUG_STATIC_CPU_HAS - - /* - * Catch too early usage of this before alternatives - * have run. - */ - asm_volatile_goto("1: jmp %l[t_warn]\n" - "2:\n" - ".section .altinstructions,\"a\"\n" - " .long 1b - .\n" - " .long 0\n" /* no replacement */ - " .word %P0\n" /* 1: do replace */ - " .byte 2b - 1b\n" /* source len */ - " .byte 0\n" /* replacement len */ - " .byte 0\n" /* pad len */ - ".previous\n" - /* skipping size check since replacement size = 0 */ - : : "i" (X86_FEATURE_ALWAYS) : : t_warn); - -#endif - - asm_volatile_goto("1: jmp %l[t_no]\n" - "2:\n" - ".section .altinstructions,\"a\"\n" - " .long 1b - .\n" - " .long 0\n" /* no replacement */ - " .word %P0\n" /* feature bit */ - " .byte 2b - 1b\n" /* source len */ - " .byte 0\n" /* replacement len */ - " .byte 0\n" /* pad len */ - ".previous\n" - /* skipping size check since replacement size = 0 */ - : : "i" (bit) : : t_no); - return true; - t_no: - return false; - -#ifdef CONFIG_X86_DEBUG_STATIC_CPU_HAS - t_warn: - warn_pre_alternatives(); - return false; -#endif - -#else /* CC_HAVE_ASM_GOTO */ - - u8 flag; - /* Open-coded due to __stringify() in ALTERNATIVE() */ - asm volatile("1: movb $0,%0\n" - "2:\n" - ".section .altinstructions,\"a\"\n" - " .long 1b - .\n" - " .long 3f - .\n" - " .word %P1\n" /* feature bit */ - " .byte 2b - 1b\n" /* source len */ - " .byte 4f - 3f\n" /* replacement len */ - " .byte 0\n" /* pad len */ - ".previous\n" - ".section .discard,\"aw\",@progbits\n" - " .byte 0xff + (4f-3f) - (2b-1b)\n" /* size check */ - ".previous\n" - ".section .altinstr_replacement,\"ax\"\n" - "3: movb $1,%0\n" - "4:\n" - ".previous\n" - : "=qm" (flag) : "i" (bit)); - return flag; - -#endif /* CC_HAVE_ASM_GOTO */ -} - -#define static_cpu_has(bit) \ -( \ - __builtin_constant_p(boot_cpu_has(bit)) ? \ - boot_cpu_has(bit) : \ - __builtin_constant_p(bit) ? \ - __static_cpu_has(bit) : \ - boot_cpu_has(bit) \ -) - -static __always_inline __pure bool _static_cpu_has_safe(u16 bit) -{ -#ifdef CC_HAVE_ASM_GOTO - asm_volatile_goto("1: jmp %l[t_dynamic]\n" + asm_volatile_goto("1: jmp 6f\n" "2:\n" ".skip -(((5f-4f) - (2b-1b)) > 0) * " "((5f-4f) - (2b-1b)),0x90\n" @@ -541,66 +198,34 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit) " .byte 0\n" /* repl len */ " .byte 0\n" /* pad len */ ".previous\n" - : : "i" (bit), "i" (X86_FEATURE_ALWAYS) - : : t_dynamic, t_no); + ".section .altinstr_aux,\"ax\"\n" + "6:\n" + " testb %[bitnum],%[cap_byte]\n" + " jnz %l[t_yes]\n" + " jmp %l[t_no]\n" + ".previous\n" + : : "i" (bit), "i" (X86_FEATURE_ALWAYS), + [bitnum] "i" (1 << (bit & 7)), + [cap_byte] "m" (((const char *)boot_cpu_data.x86_capability)[bit >> 3]) + : : t_yes, t_no); + t_yes: return true; t_no: return false; - t_dynamic: - return __static_cpu_has_safe(bit); -#else - u8 flag; - /* Open-coded due to __stringify() in ALTERNATIVE() */ - asm volatile("1: movb $2,%0\n" - "2:\n" - ".section .altinstructions,\"a\"\n" - " .long 1b - .\n" /* src offset */ - " .long 3f - .\n" /* repl offset */ - " .word %P2\n" /* always replace */ - " .byte 2b - 1b\n" /* source len */ - " .byte 4f - 3f\n" /* replacement len */ - " .byte 0\n" /* pad len */ - ".previous\n" - ".section .discard,\"aw\",@progbits\n" - " .byte 0xff + (4f-3f) - (2b-1b)\n" /* size check */ - ".previous\n" - ".section .altinstr_replacement,\"ax\"\n" - "3: movb $0,%0\n" - "4:\n" - ".previous\n" - ".section .altinstructions,\"a\"\n" - " .long 1b - .\n" /* src offset */ - " .long 5f - .\n" /* repl offset */ - " .word %P1\n" /* feature bit */ - " .byte 4b - 3b\n" /* src len */ - " .byte 6f - 5f\n" /* repl len */ - " .byte 0\n" /* pad len */ - ".previous\n" - ".section .discard,\"aw\",@progbits\n" - " .byte 0xff + (6f-5f) - (4b-3b)\n" /* size check */ - ".previous\n" - ".section .altinstr_replacement,\"ax\"\n" - "5: movb $1,%0\n" - "6:\n" - ".previous\n" - : "=qm" (flag) - : "i" (bit), "i" (X86_FEATURE_ALWAYS)); - return (flag == 2 ? __static_cpu_has_safe(bit) : flag); -#endif /* CC_HAVE_ASM_GOTO */ } -#define static_cpu_has_safe(bit) \ +#define static_cpu_has(bit) \ ( \ __builtin_constant_p(boot_cpu_has(bit)) ? \ boot_cpu_has(bit) : \ - _static_cpu_has_safe(bit) \ + _static_cpu_has(bit) \ ) #else /* - * gcc 3.x is too stupid to do the static test; fall back to dynamic. + * Fall back to dynamic for gcc versions which don't support asm goto. Should be + * a minority now anyway. */ #define static_cpu_has(bit) boot_cpu_has(bit) -#define static_cpu_has_safe(bit) boot_cpu_has(bit) #endif #define cpu_has_bug(c, bit) cpu_has(c, (bit)) @@ -608,7 +233,6 @@ static __always_inline __pure bool _static_cpu_has_safe(u16 bit) #define clear_cpu_bug(c, bit) clear_cpu_cap(c, (bit)) #define static_cpu_has_bug(bit) static_cpu_has((bit)) -#define static_cpu_has_bug_safe(bit) static_cpu_has_safe((bit)) #define boot_cpu_has_bug(bit) cpu_has_bug(&boot_cpu_data, (bit)) #define MAX_CPU_FEATURES (NCAPINTS * 32) diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h new file mode 100644 index 0000000000000..dd2269dcbc470 --- /dev/null +++ b/arch/x86/include/asm/cpufeatures.h @@ -0,0 +1,337 @@ +#ifndef _ASM_X86_CPUFEATURES_H +#define _ASM_X86_CPUFEATURES_H + +#ifndef _ASM_X86_REQUIRED_FEATURES_H +#include +#endif + +#ifndef _ASM_X86_DISABLED_FEATURES_H +#include +#endif + +/* + * Defines x86 CPU feature bits + */ +#define NCAPINTS 19 /* N 32-bit words worth of info */ +#define NBUGINTS 1 /* N 32-bit bug flags */ + +/* + * Note: If the comment begins with a quoted string, that string is used + * in /proc/cpuinfo instead of the macro name. If the string is "", + * this feature bit is not displayed in /proc/cpuinfo at all. + */ + +/* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */ +#define X86_FEATURE_FPU ( 0*32+ 0) /* Onboard FPU */ +#define X86_FEATURE_VME ( 0*32+ 1) /* Virtual Mode Extensions */ +#define X86_FEATURE_DE ( 0*32+ 2) /* Debugging Extensions */ +#define X86_FEATURE_PSE ( 0*32+ 3) /* Page Size Extensions */ +#define X86_FEATURE_TSC ( 0*32+ 4) /* Time Stamp Counter */ +#define X86_FEATURE_MSR ( 0*32+ 5) /* Model-Specific Registers */ +#define X86_FEATURE_PAE ( 0*32+ 6) /* Physical Address Extensions */ +#define X86_FEATURE_MCE ( 0*32+ 7) /* Machine Check Exception */ +#define X86_FEATURE_CX8 ( 0*32+ 8) /* CMPXCHG8 instruction */ +#define X86_FEATURE_APIC ( 0*32+ 9) /* Onboard APIC */ +#define X86_FEATURE_SEP ( 0*32+11) /* SYSENTER/SYSEXIT */ +#define X86_FEATURE_MTRR ( 0*32+12) /* Memory Type Range Registers */ +#define X86_FEATURE_PGE ( 0*32+13) /* Page Global Enable */ +#define X86_FEATURE_MCA ( 0*32+14) /* Machine Check Architecture */ +#define X86_FEATURE_CMOV ( 0*32+15) /* CMOV instructions */ + /* (plus FCMOVcc, FCOMI with FPU) */ +#define X86_FEATURE_PAT ( 0*32+16) /* Page Attribute Table */ +#define X86_FEATURE_PSE36 ( 0*32+17) /* 36-bit PSEs */ +#define X86_FEATURE_PN ( 0*32+18) /* Processor serial number */ +#define X86_FEATURE_CLFLUSH ( 0*32+19) /* CLFLUSH instruction */ +#define X86_FEATURE_DS ( 0*32+21) /* "dts" Debug Store */ +#define X86_FEATURE_ACPI ( 0*32+22) /* ACPI via MSR */ +#define X86_FEATURE_MMX ( 0*32+23) /* Multimedia Extensions */ +#define X86_FEATURE_FXSR ( 0*32+24) /* FXSAVE/FXRSTOR, CR4.OSFXSR */ +#define X86_FEATURE_XMM ( 0*32+25) /* "sse" */ +#define X86_FEATURE_XMM2 ( 0*32+26) /* "sse2" */ +#define X86_FEATURE_SELFSNOOP ( 0*32+27) /* "ss" CPU self snoop */ +#define X86_FEATURE_HT ( 0*32+28) /* Hyper-Threading */ +#define X86_FEATURE_ACC ( 0*32+29) /* "tm" Automatic clock control */ +#define X86_FEATURE_IA64 ( 0*32+30) /* IA-64 processor */ +#define X86_FEATURE_PBE ( 0*32+31) /* Pending Break Enable */ + +/* AMD-defined CPU features, CPUID level 0x80000001, word 1 */ +/* Don't duplicate feature flags which are redundant with Intel! */ +#define X86_FEATURE_SYSCALL ( 1*32+11) /* SYSCALL/SYSRET */ +#define X86_FEATURE_MP ( 1*32+19) /* MP Capable. */ +#define X86_FEATURE_NX ( 1*32+20) /* Execute Disable */ +#define X86_FEATURE_MMXEXT ( 1*32+22) /* AMD MMX extensions */ +#define X86_FEATURE_FXSR_OPT ( 1*32+25) /* FXSAVE/FXRSTOR optimizations */ +#define X86_FEATURE_GBPAGES ( 1*32+26) /* "pdpe1gb" GB pages */ +#define X86_FEATURE_RDTSCP ( 1*32+27) /* RDTSCP */ +#define X86_FEATURE_LM ( 1*32+29) /* Long Mode (x86-64) */ +#define X86_FEATURE_3DNOWEXT ( 1*32+30) /* AMD 3DNow! extensions */ +#define X86_FEATURE_3DNOW ( 1*32+31) /* 3DNow! */ + +/* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */ +#define X86_FEATURE_RECOVERY ( 2*32+ 0) /* CPU in recovery mode */ +#define X86_FEATURE_LONGRUN ( 2*32+ 1) /* Longrun power control */ +#define X86_FEATURE_LRTI ( 2*32+ 3) /* LongRun table interface */ + +/* Other features, Linux-defined mapping, word 3 */ +/* This range is used for feature bits which conflict or are synthesized */ +#define X86_FEATURE_CXMMX ( 3*32+ 0) /* Cyrix MMX extensions */ +#define X86_FEATURE_K6_MTRR ( 3*32+ 1) /* AMD K6 nonstandard MTRRs */ +#define X86_FEATURE_CYRIX_ARR ( 3*32+ 2) /* Cyrix ARRs (= MTRRs) */ +#define X86_FEATURE_CENTAUR_MCR ( 3*32+ 3) /* Centaur MCRs (= MTRRs) */ +/* cpu types for specific tunings: */ +#define X86_FEATURE_K8 ( 3*32+ 4) /* "" Opteron, Athlon64 */ +#define X86_FEATURE_K7 ( 3*32+ 5) /* "" Athlon */ +#define X86_FEATURE_P3 ( 3*32+ 6) /* "" P3 */ +#define X86_FEATURE_P4 ( 3*32+ 7) /* "" P4 */ +#define X86_FEATURE_CONSTANT_TSC ( 3*32+ 8) /* TSC ticks at a constant rate */ +#define X86_FEATURE_UP ( 3*32+ 9) /* smp kernel running on up */ +/* free, was #define X86_FEATURE_FXSAVE_LEAK ( 3*32+10) * "" FXSAVE leaks FOP/FIP/FOP */ +#define X86_FEATURE_ARCH_PERFMON ( 3*32+11) /* Intel Architectural PerfMon */ +#define X86_FEATURE_PEBS ( 3*32+12) /* Precise-Event Based Sampling */ +#define X86_FEATURE_BTS ( 3*32+13) /* Branch Trace Store */ +#define X86_FEATURE_SYSCALL32 ( 3*32+14) /* "" syscall in ia32 userspace */ +#define X86_FEATURE_SYSENTER32 ( 3*32+15) /* "" sysenter in ia32 userspace */ +#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_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 */ +#define X86_FEATURE_TSC_RELIABLE ( 3*32+23) /* TSC is known to be reliable */ +#define X86_FEATURE_NONSTOP_TSC ( 3*32+24) /* TSC does not stop in C states */ +/* free, was #define X86_FEATURE_CLFLUSH_MONITOR ( 3*32+25) * "" clflush reqd with monitor */ +#define X86_FEATURE_EXTD_APICID ( 3*32+26) /* has extended APICID (8 bits) */ +#define X86_FEATURE_AMD_DCM ( 3*32+27) /* multi-node processor */ +#define X86_FEATURE_APERFMPERF ( 3*32+28) /* APERFMPERF */ +/* free, was #define X86_FEATURE_EAGER_FPU ( 3*32+29) * "eagerfpu" Non lazy FPU restore */ +#define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* TSC doesn't stop in S3 state */ + +/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ +#define X86_FEATURE_XMM3 ( 4*32+ 0) /* "pni" SSE-3 */ +#define X86_FEATURE_PCLMULQDQ ( 4*32+ 1) /* PCLMULQDQ instruction */ +#define X86_FEATURE_DTES64 ( 4*32+ 2) /* 64-bit Debug Store */ +#define X86_FEATURE_MWAIT ( 4*32+ 3) /* "monitor" Monitor/Mwait support */ +#define X86_FEATURE_DSCPL ( 4*32+ 4) /* "ds_cpl" CPL Qual. Debug Store */ +#define X86_FEATURE_VMX ( 4*32+ 5) /* Hardware virtualization */ +#define X86_FEATURE_SMX ( 4*32+ 6) /* Safer mode */ +#define X86_FEATURE_EST ( 4*32+ 7) /* Enhanced SpeedStep */ +#define X86_FEATURE_TM2 ( 4*32+ 8) /* Thermal Monitor 2 */ +#define X86_FEATURE_SSSE3 ( 4*32+ 9) /* Supplemental SSE-3 */ +#define X86_FEATURE_CID ( 4*32+10) /* Context ID */ +#define X86_FEATURE_SDBG ( 4*32+11) /* Silicon Debug */ +#define X86_FEATURE_FMA ( 4*32+12) /* Fused multiply-add */ +#define X86_FEATURE_CX16 ( 4*32+13) /* CMPXCHG16B */ +#define X86_FEATURE_XTPR ( 4*32+14) /* Send Task Priority Messages */ +#define X86_FEATURE_PDCM ( 4*32+15) /* Performance Capabilities */ +#define X86_FEATURE_PCID ( 4*32+17) /* Process Context Identifiers */ +#define X86_FEATURE_DCA ( 4*32+18) /* Direct Cache Access */ +#define X86_FEATURE_XMM4_1 ( 4*32+19) /* "sse4_1" SSE-4.1 */ +#define X86_FEATURE_XMM4_2 ( 4*32+20) /* "sse4_2" SSE-4.2 */ +#define X86_FEATURE_X2APIC ( 4*32+21) /* x2APIC */ +#define X86_FEATURE_MOVBE ( 4*32+22) /* MOVBE instruction */ +#define X86_FEATURE_POPCNT ( 4*32+23) /* POPCNT instruction */ +#define X86_FEATURE_TSC_DEADLINE_TIMER ( 4*32+24) /* Tsc deadline timer */ +#define X86_FEATURE_AES ( 4*32+25) /* AES instructions */ +#define X86_FEATURE_XSAVE ( 4*32+26) /* XSAVE/XRSTOR/XSETBV/XGETBV */ +#define X86_FEATURE_OSXSAVE ( 4*32+27) /* "" XSAVE enabled in the OS */ +#define X86_FEATURE_AVX ( 4*32+28) /* Advanced Vector Extensions */ +#define X86_FEATURE_F16C ( 4*32+29) /* 16-bit fp conversions */ +#define X86_FEATURE_RDRAND ( 4*32+30) /* The RDRAND instruction */ +#define X86_FEATURE_HYPERVISOR ( 4*32+31) /* Running on a hypervisor */ + +/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */ +#define X86_FEATURE_XSTORE ( 5*32+ 2) /* "rng" RNG present (xstore) */ +#define X86_FEATURE_XSTORE_EN ( 5*32+ 3) /* "rng_en" RNG enabled */ +#define X86_FEATURE_XCRYPT ( 5*32+ 6) /* "ace" on-CPU crypto (xcrypt) */ +#define X86_FEATURE_XCRYPT_EN ( 5*32+ 7) /* "ace_en" on-CPU crypto enabled */ +#define X86_FEATURE_ACE2 ( 5*32+ 8) /* Advanced Cryptography Engine v2 */ +#define X86_FEATURE_ACE2_EN ( 5*32+ 9) /* ACE v2 enabled */ +#define X86_FEATURE_PHE ( 5*32+10) /* PadLock Hash Engine */ +#define X86_FEATURE_PHE_EN ( 5*32+11) /* PHE enabled */ +#define X86_FEATURE_PMM ( 5*32+12) /* PadLock Montgomery Multiplier */ +#define X86_FEATURE_PMM_EN ( 5*32+13) /* PMM enabled */ + +/* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */ +#define X86_FEATURE_LAHF_LM ( 6*32+ 0) /* LAHF/SAHF in long mode */ +#define X86_FEATURE_CMP_LEGACY ( 6*32+ 1) /* If yes HyperThreading not valid */ +#define X86_FEATURE_SVM ( 6*32+ 2) /* Secure virtual machine */ +#define X86_FEATURE_EXTAPIC ( 6*32+ 3) /* Extended APIC space */ +#define X86_FEATURE_CR8_LEGACY ( 6*32+ 4) /* CR8 in 32-bit mode */ +#define X86_FEATURE_ABM ( 6*32+ 5) /* Advanced bit manipulation */ +#define X86_FEATURE_SSE4A ( 6*32+ 6) /* SSE-4A */ +#define X86_FEATURE_MISALIGNSSE ( 6*32+ 7) /* Misaligned SSE mode */ +#define X86_FEATURE_3DNOWPREFETCH ( 6*32+ 8) /* 3DNow prefetch instructions */ +#define X86_FEATURE_OSVW ( 6*32+ 9) /* OS Visible Workaround */ +#define X86_FEATURE_IBS ( 6*32+10) /* Instruction Based Sampling */ +#define X86_FEATURE_XOP ( 6*32+11) /* extended AVX instructions */ +#define X86_FEATURE_SKINIT ( 6*32+12) /* SKINIT/STGI instructions */ +#define X86_FEATURE_WDT ( 6*32+13) /* Watchdog timer */ +#define X86_FEATURE_LWP ( 6*32+15) /* Light Weight Profiling */ +#define X86_FEATURE_FMA4 ( 6*32+16) /* 4 operands MAC instructions */ +#define X86_FEATURE_TCE ( 6*32+17) /* translation cache extension */ +#define X86_FEATURE_NODEID_MSR ( 6*32+19) /* NodeId MSR */ +#define X86_FEATURE_TBM ( 6*32+21) /* trailing bit manipulations */ +#define X86_FEATURE_TOPOEXT ( 6*32+22) /* topology extensions CPUID leafs */ +#define X86_FEATURE_PERFCTR_CORE ( 6*32+23) /* core performance counter extensions */ +#define X86_FEATURE_PERFCTR_NB ( 6*32+24) /* NB performance counter extensions */ +#define X86_FEATURE_BPEXT (6*32+26) /* data breakpoint extension */ +#define X86_FEATURE_PERFCTR_L2 ( 6*32+28) /* L2 performance counter extensions */ +#define X86_FEATURE_MWAITX ( 6*32+29) /* MWAIT extension (MONITORX/MWAITX) */ + +/* + * Auxiliary flags: Linux defined - For features scattered in various + * CPUID levels like 0x6, 0xA etc, word 7. + * + * Reuse free bits when adding new feature flags! + */ + +#define X86_FEATURE_CPB ( 7*32+ 2) /* AMD Core Performance Boost */ +#define X86_FEATURE_EPB ( 7*32+ 3) /* IA32_ENERGY_PERF_BIAS support */ +#define X86_FEATURE_INVPCID_SINGLE ( 7*32+ 4) /* Effectively INVPCID && CR4.PCIDE=1 */ + +#define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */ +#define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */ + +#define X86_FEATURE_RETPOLINE ( 7*32+12) /* "" Generic Retpoline mitigation for Spectre variant 2 */ +#define X86_FEATURE_RETPOLINE_AMD ( 7*32+13) /* "" AMD Retpoline mitigation for Spectre variant 2 */ + +#define X86_FEATURE_INTEL_PT ( 7*32+15) /* Intel Processor Trace */ +#define X86_FEATURE_RSB_CTXSW ( 7*32+19) /* "" Fill RSB on context switches */ + +#define X86_FEATURE_MSR_SPEC_CTRL ( 7*32+16) /* "" MSR SPEC_CTRL is implemented */ +#define X86_FEATURE_SSBD ( 7*32+17) /* Speculative Store Bypass Disable */ + +/* Because the ALTERNATIVE scheme is for members of the X86_FEATURE club... */ +#define X86_FEATURE_KAISER ( 7*32+31) /* CONFIG_PAGE_TABLE_ISOLATION w/o nokaiser */ + +#define X86_FEATURE_USE_IBPB ( 7*32+21) /* "" Indirect Branch Prediction Barrier enabled*/ +#define X86_FEATURE_USE_IBRS_FW ( 7*32+22) /* "" Use IBRS during runtime firmware calls */ +#define X86_FEATURE_SPEC_STORE_BYPASS_DISABLE ( 7*32+23) /* "" Disable Speculative Store Bypass. */ +#define X86_FEATURE_LS_CFG_SSBD ( 7*32+24) /* "" AMD SSBD implementation */ + +#define X86_FEATURE_IBRS ( 7*32+25) /* Indirect Branch Restricted Speculation */ +#define X86_FEATURE_IBPB ( 7*32+26) /* Indirect Branch Prediction Barrier */ +#define X86_FEATURE_STIBP ( 7*32+27) /* Single Thread Indirect Branch Predictors */ +#define X86_FEATURE_ZEN ( 7*32+28) /* "" CPU is AMD family 0x17 (Zen) */ +#define X86_FEATURE_L1TF_PTEINV ( 7*32+29) /* "" L1TF workaround PTE inversion */ + +/* Virtualization flags: Linux defined, word 8 */ +#define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */ +#define X86_FEATURE_VNMI ( 8*32+ 1) /* Intel Virtual NMI */ +#define X86_FEATURE_FLEXPRIORITY ( 8*32+ 2) /* Intel FlexPriority */ +#define X86_FEATURE_EPT ( 8*32+ 3) /* Intel Extended Page Table */ +#define X86_FEATURE_VPID ( 8*32+ 4) /* Intel Virtual Processor ID */ + +#define X86_FEATURE_VMMCALL ( 8*32+15) /* Prefer vmmcall to vmcall */ +#define X86_FEATURE_XENPV ( 8*32+16) /* "" Xen paravirtual guest */ + + +/* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */ +#define X86_FEATURE_FSGSBASE ( 9*32+ 0) /* {RD/WR}{FS/GS}BASE instructions*/ +#define X86_FEATURE_TSC_ADJUST ( 9*32+ 1) /* TSC adjustment MSR 0x3b */ +#define X86_FEATURE_BMI1 ( 9*32+ 3) /* 1st group bit manipulation extensions */ +#define X86_FEATURE_HLE ( 9*32+ 4) /* Hardware Lock Elision */ +#define X86_FEATURE_AVX2 ( 9*32+ 5) /* AVX2 instructions */ +#define X86_FEATURE_SMEP ( 9*32+ 7) /* Supervisor Mode Execution Protection */ +#define X86_FEATURE_BMI2 ( 9*32+ 8) /* 2nd group bit manipulation extensions */ +#define X86_FEATURE_ERMS ( 9*32+ 9) /* Enhanced REP MOVSB/STOSB */ +#define X86_FEATURE_INVPCID ( 9*32+10) /* Invalidate Processor Context ID */ +#define X86_FEATURE_RTM ( 9*32+11) /* Restricted Transactional Memory */ +#define X86_FEATURE_CQM ( 9*32+12) /* Cache QoS Monitoring */ +#define X86_FEATURE_MPX ( 9*32+14) /* Memory Protection Extension */ +#define X86_FEATURE_AVX512F ( 9*32+16) /* AVX-512 Foundation */ +#define X86_FEATURE_RDSEED ( 9*32+18) /* The RDSEED instruction */ +#define X86_FEATURE_ADX ( 9*32+19) /* The ADCX and ADOX instructions */ +#define X86_FEATURE_SMAP ( 9*32+20) /* Supervisor Mode Access Prevention */ +#define X86_FEATURE_PCOMMIT ( 9*32+22) /* PCOMMIT instruction */ +#define X86_FEATURE_CLFLUSHOPT ( 9*32+23) /* CLFLUSHOPT instruction */ +#define X86_FEATURE_CLWB ( 9*32+24) /* CLWB instruction */ +#define X86_FEATURE_AVX512PF ( 9*32+26) /* AVX-512 Prefetch */ +#define X86_FEATURE_AVX512ER ( 9*32+27) /* AVX-512 Exponential and Reciprocal */ +#define X86_FEATURE_AVX512CD ( 9*32+28) /* AVX-512 Conflict Detection */ +#define X86_FEATURE_SHA_NI ( 9*32+29) /* SHA1/SHA256 Instruction Extensions */ + +/* Extended state features, CPUID level 0x0000000d:1 (eax), word 10 */ +#define X86_FEATURE_XSAVEOPT (10*32+ 0) /* XSAVEOPT */ +#define X86_FEATURE_XSAVEC (10*32+ 1) /* XSAVEC */ +#define X86_FEATURE_XGETBV1 (10*32+ 2) /* XGETBV with ECX = 1 */ +#define X86_FEATURE_XSAVES (10*32+ 3) /* XSAVES/XRSTORS */ + +/* Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:0 (edx), word 11 */ +#define X86_FEATURE_CQM_LLC (11*32+ 1) /* LLC QoS if 1 */ + +/* 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 */ + +/* AMD-defined CPU features, CPUID level 0x80000008 (ebx), word 13 */ +#define X86_FEATURE_CLZERO (13*32+0) /* CLZERO instruction */ +#define X86_FEATURE_AMD_IBPB (13*32+12) /* Indirect Branch Prediction Barrier */ +#define X86_FEATURE_AMD_IBRS (13*32+14) /* Indirect Branch Restricted Speculation */ +#define X86_FEATURE_AMD_STIBP (13*32+15) /* Single Thread Indirect Branch Predictors */ +#define X86_FEATURE_VIRT_SSBD (13*32+25) /* Virtualized Speculative Store Bypass Disable */ + +/* Thermal and Power Management Leaf, CPUID level 0x00000006 (eax), word 14 */ +#define X86_FEATURE_DTHERM (14*32+ 0) /* Digital Thermal Sensor */ +#define X86_FEATURE_IDA (14*32+ 1) /* Intel Dynamic Acceleration */ +#define X86_FEATURE_ARAT (14*32+ 2) /* Always Running APIC Timer */ +#define X86_FEATURE_PLN (14*32+ 4) /* Intel Power Limit Notification */ +#define X86_FEATURE_PTS (14*32+ 6) /* Intel Package Thermal Status */ +#define X86_FEATURE_HWP (14*32+ 7) /* Intel Hardware P-states */ +#define X86_FEATURE_HWP_NOTIFY (14*32+ 8) /* HWP Notification */ +#define X86_FEATURE_HWP_ACT_WINDOW (14*32+ 9) /* HWP Activity Window */ +#define X86_FEATURE_HWP_EPP (14*32+10) /* HWP Energy Perf. Preference */ +#define X86_FEATURE_HWP_PKG_REQ (14*32+11) /* HWP Package Level Request */ + +/* AMD SVM Feature Identification, CPUID level 0x8000000a (edx), word 15 */ +#define X86_FEATURE_NPT (15*32+ 0) /* Nested Page Table support */ +#define X86_FEATURE_LBRV (15*32+ 1) /* LBR Virtualization support */ +#define X86_FEATURE_SVML (15*32+ 2) /* "svm_lock" SVM locking MSR */ +#define X86_FEATURE_NRIPS (15*32+ 3) /* "nrip_save" SVM next_rip save */ +#define X86_FEATURE_TSCRATEMSR (15*32+ 4) /* "tsc_scale" TSC scaling support */ +#define X86_FEATURE_VMCBCLEAN (15*32+ 5) /* "vmcb_clean" VMCB clean bits support */ +#define X86_FEATURE_FLUSHBYASID (15*32+ 6) /* flush-by-ASID support */ +#define X86_FEATURE_DECODEASSISTS (15*32+ 7) /* Decode Assists support */ +#define X86_FEATURE_PAUSEFILTER (15*32+10) /* filtered pause intercept */ +#define X86_FEATURE_PFTHRESHOLD (15*32+12) /* pause filter threshold */ + +/* 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 */ + +/* AMD-defined CPU features, CPUID level 0x80000007 (ebx), word 17 */ +#define X86_FEATURE_OVERFLOW_RECOV (17*32+0) /* MCA overflow recovery support */ +#define X86_FEATURE_SUCCOR (17*32+1) /* Uncorrectable error containment and recovery */ +#define X86_FEATURE_SMCA (17*32+3) /* Scalable MCA */ + + +/* Intel-defined CPU features, CPUID level 0x00000007:0 (EDX), word 18 */ +#define X86_FEATURE_AVX512_4VNNIW (18*32+ 2) /* AVX-512 Neural Network Instructions */ +#define X86_FEATURE_AVX512_4FMAPS (18*32+ 3) /* AVX-512 Multiply Accumulation Single precision */ +#define X86_FEATURE_SPEC_CTRL (18*32+26) /* "" Speculation Control (IBRS + IBPB) */ +#define X86_FEATURE_INTEL_STIBP (18*32+27) /* "" Single Thread Indirect Branch Predictors */ +#define X86_FEATURE_FLUSH_L1D (18*32+28) /* Flush L1D cache */ +#define X86_FEATURE_ARCH_CAPABILITIES (18*32+29) /* IA32_ARCH_CAPABILITIES MSR (Intel) */ +#define X86_FEATURE_SPEC_CTRL_SSBD (18*32+31) /* "" Speculative Store Bypass Disable */ + +/* + * BUG word(s) + */ +#define X86_BUG(x) (NCAPINTS*32 + (x)) + +#define X86_BUG_F00F X86_BUG(0) /* Intel F00F */ +#define X86_BUG_FDIV X86_BUG(1) /* FPU FDIV */ +#define X86_BUG_COMA X86_BUG(2) /* Cyrix 6x86 coma */ +#define X86_BUG_AMD_TLB_MMATCH X86_BUG(3) /* "tlb_mmatch" AMD Erratum 383 */ +#define X86_BUG_AMD_APIC_C1E X86_BUG(4) /* "apic_c1e" AMD Erratum 400 */ +#define X86_BUG_11AP X86_BUG(5) /* Bad local APIC aka 11AP */ +#define X86_BUG_FXSAVE_LEAK X86_BUG(6) /* FXSAVE leaks FOP/FIP/FOP */ +#define X86_BUG_CLFLUSH_MONITOR X86_BUG(7) /* AAI65, CLFLUSH required before MONITOR */ +#define X86_BUG_SYSRET_SS_ATTRS X86_BUG(8) /* SYSRET doesn't fix up SS attrs */ +#define X86_BUG_CPU_MELTDOWN X86_BUG(14) /* CPU is affected by meltdown attack and needs kernel page table isolation */ +#define X86_BUG_SPECTRE_V1 X86_BUG(15) /* CPU is affected by Spectre variant 1 attack with conditional branches */ +#define X86_BUG_SPECTRE_V2 X86_BUG(16) /* CPU is affected by Spectre variant 2 attack with indirect branches */ +#define X86_BUG_SPEC_STORE_BYPASS X86_BUG(17) /* CPU is affected by speculative store bypass attack */ +#define X86_BUG_L1TF X86_BUG(18) /* CPU is affected by L1 Terminal Fault */ + +#endif /* _ASM_X86_CPUFEATURES_H */ diff --git a/arch/x86/include/asm/disabled-features.h b/arch/x86/include/asm/disabled-features.h index 8b17c2ad1048f..1f8cca459c6c8 100644 --- a/arch/x86/include/asm/disabled-features.h +++ b/arch/x86/include/asm/disabled-features.h @@ -30,6 +30,14 @@ # define DISABLE_PCID (1<<(X86_FEATURE_PCID & 31)) #endif /* CONFIG_X86_64 */ +#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS +# define DISABLE_PKU 0 +# define DISABLE_OSPKE 0 +#else +# define DISABLE_PKU (1<<(X86_FEATURE_PKU & 31)) +# define DISABLE_OSPKE (1<<(X86_FEATURE_OSPKE & 31)) +#endif /* CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS */ + /* * Make sure to add features to the correct mask */ @@ -43,5 +51,15 @@ #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) +#define DISABLED_MASK17 0 +#define DISABLED_MASK18 0 +#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 19) #endif /* _ASM_X86_DISABLED_FEATURES_H */ diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index 08b1f2f6ea50c..cfde088f8e95e 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, @@ -41,8 +42,10 @@ extern unsigned long asmlinkage efi_call_phys(void *, ...); ({ \ efi_status_t __s; \ kernel_fpu_begin(); \ + firmware_restrict_branch_speculation_start(); \ __s = ((efi_##f##_t __attribute__((regparm(0)))*) \ efi.systab->runtime->f)(args); \ + firmware_restrict_branch_speculation_end(); \ kernel_fpu_end(); \ __s; \ }) @@ -51,8 +54,10 @@ extern unsigned long asmlinkage efi_call_phys(void *, ...); #define __efi_call_virt(f, args...) \ ({ \ kernel_fpu_begin(); \ + firmware_restrict_branch_speculation_start(); \ ((efi_##f##_t __attribute__((regparm(0)))*) \ efi.systab->runtime->f)(args); \ + firmware_restrict_branch_speculation_end(); \ kernel_fpu_end(); \ }) @@ -73,7 +78,9 @@ extern u64 asmlinkage efi_call(void *fp, ...); efi_sync_low_kernel_mappings(); \ preempt_disable(); \ __kernel_fpu_begin(); \ + firmware_restrict_branch_speculation_start(); \ __s = efi_call((void *)efi.systab->runtime->f, __VA_ARGS__); \ + firmware_restrict_branch_speculation_end(); \ __kernel_fpu_end(); \ preempt_enable(); \ __s; \ diff --git a/arch/x86/include/asm/fpu/internal.h b/arch/x86/include/asm/fpu/internal.h index 3c3550c3a4a3f..ec2aedb6f92a5 100644 --- a/arch/x86/include/asm/fpu/internal.h +++ b/arch/x86/include/asm/fpu/internal.h @@ -17,6 +17,7 @@ #include #include #include +#include /* * High level FPU state handling functions: @@ -42,6 +43,7 @@ extern void fpu__init_cpu_xstate(void); extern void fpu__init_system(struct cpuinfo_x86 *c); extern void fpu__init_check_bugs(void); extern void fpu__resume_cpu(void); +extern u64 fpu__get_supported_xfeatures_mask(void); /* * Debugging facility: @@ -57,22 +59,22 @@ extern void fpu__resume_cpu(void); */ static __always_inline __pure bool use_eager_fpu(void) { - return static_cpu_has_safe(X86_FEATURE_EAGER_FPU); + return true; } static __always_inline __pure bool use_xsaveopt(void) { - return static_cpu_has_safe(X86_FEATURE_XSAVEOPT); + return static_cpu_has(X86_FEATURE_XSAVEOPT); } static __always_inline __pure bool use_xsave(void) { - return static_cpu_has_safe(X86_FEATURE_XSAVE); + return static_cpu_has(X86_FEATURE_XSAVE); } static __always_inline __pure bool use_fxsr(void) { - return static_cpu_has_safe(X86_FEATURE_FXSR); + return static_cpu_has(X86_FEATURE_FXSR); } /* @@ -224,18 +226,67 @@ static inline void copy_fxregs_to_kernel(struct fpu *fpu) #define XRSTOR ".byte " REX_PREFIX "0x0f,0xae,0x2f" #define XRSTORS ".byte " REX_PREFIX "0x0f,0xc7,0x1f" -/* xstate instruction fault handler: */ -#define xstate_fault(__err) \ - \ - ".section .fixup,\"ax\"\n" \ - \ - "3: movl $-2,%[_err]\n" \ - " jmp 2b\n" \ - \ - ".previous\n" \ - \ - _ASM_EXTABLE(1b, 3b) \ - : [_err] "=r" (__err) +#define XSTATE_OP(op, st, lmask, hmask, err) \ + asm volatile("1:" op "\n\t" \ + "xor %[err], %[err]\n" \ + "2:\n\t" \ + ".pushsection .fixup,\"ax\"\n\t" \ + "3: movl $-2,%[err]\n\t" \ + "jmp 2b\n\t" \ + ".popsection\n\t" \ + _ASM_EXTABLE(1b, 3b) \ + : [err] "=r" (err) \ + : "D" (st), "m" (*st), "a" (lmask), "d" (hmask) \ + : "memory") + +/* + * If XSAVES is enabled, it replaces XSAVEOPT because it supports a compact + * format and supervisor states in addition to modified optimization in + * XSAVEOPT. + * + * Otherwise, if XSAVEOPT is enabled, XSAVEOPT replaces XSAVE because XSAVEOPT + * supports modified optimization which is not supported by XSAVE. + * + * We use XSAVE as a fallback. + * + * The 661 label is defined in the ALTERNATIVE* macros as the address of the + * original instruction which gets replaced. We need to use it here as the + * address of the instruction where we might get an exception at. + */ +#define XSTATE_XSAVE(st, lmask, hmask, err) \ + asm volatile(ALTERNATIVE_2(XSAVE, \ + XSAVEOPT, X86_FEATURE_XSAVEOPT, \ + XSAVES, X86_FEATURE_XSAVES) \ + "\n" \ + "xor %[err], %[err]\n" \ + "3:\n" \ + ".pushsection .fixup,\"ax\"\n" \ + "4: movl $-2, %[err]\n" \ + "jmp 3b\n" \ + ".popsection\n" \ + _ASM_EXTABLE(661b, 4b) \ + : [err] "=r" (err) \ + : "D" (st), "m" (*st), "a" (lmask), "d" (hmask) \ + : "memory") + +/* + * Use XRSTORS to restore context if it is enabled. XRSTORS supports compact + * XSAVE area format. + */ +#define XSTATE_XRESTORE(st, lmask, hmask, err) \ + asm volatile(ALTERNATIVE(XRSTOR, \ + XRSTORS, X86_FEATURE_XSAVES) \ + "\n" \ + "xor %[err], %[err]\n" \ + "3:\n" \ + ".pushsection .fixup,\"ax\"\n" \ + "4: movl $-2, %[err]\n" \ + "jmp 3b\n" \ + ".popsection\n" \ + _ASM_EXTABLE(661b, 4b) \ + : [err] "=r" (err) \ + : "D" (st), "m" (*st), "a" (lmask), "d" (hmask) \ + : "memory") /* * This function is called only during boot time when x86 caps are not set @@ -246,22 +297,14 @@ static inline void copy_xregs_to_kernel_booting(struct xregs_state *xstate) u64 mask = -1; u32 lmask = mask; u32 hmask = mask >> 32; - int err = 0; + int err; WARN_ON(system_state != SYSTEM_BOOTING); - if (boot_cpu_has(X86_FEATURE_XSAVES)) - asm volatile("1:"XSAVES"\n\t" - "2:\n\t" - xstate_fault(err) - : "D" (xstate), "m" (*xstate), "a" (lmask), "d" (hmask), "0" (err) - : "memory"); + if (static_cpu_has(X86_FEATURE_XSAVES)) + XSTATE_OP(XSAVES, xstate, lmask, hmask, err); else - asm volatile("1:"XSAVE"\n\t" - "2:\n\t" - xstate_fault(err) - : "D" (xstate), "m" (*xstate), "a" (lmask), "d" (hmask), "0" (err) - : "memory"); + XSTATE_OP(XSAVE, xstate, lmask, hmask, err); /* We should never fault when copying to a kernel buffer: */ WARN_ON_FPU(err); @@ -276,22 +319,14 @@ static inline void copy_kernel_to_xregs_booting(struct xregs_state *xstate) u64 mask = -1; u32 lmask = mask; u32 hmask = mask >> 32; - int err = 0; + int err; WARN_ON(system_state != SYSTEM_BOOTING); - if (boot_cpu_has(X86_FEATURE_XSAVES)) - asm volatile("1:"XRSTORS"\n\t" - "2:\n\t" - xstate_fault(err) - : "D" (xstate), "m" (*xstate), "a" (lmask), "d" (hmask), "0" (err) - : "memory"); + if (static_cpu_has(X86_FEATURE_XSAVES)) + XSTATE_OP(XRSTORS, xstate, lmask, hmask, err); else - asm volatile("1:"XRSTOR"\n\t" - "2:\n\t" - xstate_fault(err) - : "D" (xstate), "m" (*xstate), "a" (lmask), "d" (hmask), "0" (err) - : "memory"); + XSTATE_OP(XRSTOR, xstate, lmask, hmask, err); /* We should never fault when copying from a kernel buffer: */ WARN_ON_FPU(err); @@ -305,33 +340,11 @@ static inline void copy_xregs_to_kernel(struct xregs_state *xstate) u64 mask = -1; u32 lmask = mask; u32 hmask = mask >> 32; - int err = 0; + int err; WARN_ON(!alternatives_patched); - /* - * If xsaves is enabled, xsaves replaces xsaveopt because - * it supports compact format and supervisor states in addition to - * modified optimization in xsaveopt. - * - * Otherwise, if xsaveopt is enabled, xsaveopt replaces xsave - * because xsaveopt supports modified optimization which is not - * supported by xsave. - * - * If none of xsaves and xsaveopt is enabled, use xsave. - */ - alternative_input_2( - "1:"XSAVE, - XSAVEOPT, - X86_FEATURE_XSAVEOPT, - XSAVES, - X86_FEATURE_XSAVES, - [xstate] "D" (xstate), "a" (lmask), "d" (hmask) : - "memory"); - asm volatile("2:\n\t" - xstate_fault(err) - : "0" (err) - : "memory"); + XSTATE_XSAVE(xstate, lmask, hmask, err); /* We should never fault when copying to a kernel buffer: */ WARN_ON_FPU(err); @@ -344,23 +357,9 @@ static inline void copy_kernel_to_xregs(struct xregs_state *xstate, u64 mask) { u32 lmask = mask; u32 hmask = mask >> 32; - int err = 0; + int err; - /* - * Use xrstors to restore context if it is enabled. xrstors supports - * compacted format of xsave area which is not supported by xrstor. - */ - alternative_input( - "1: " XRSTOR, - XRSTORS, - X86_FEATURE_XSAVES, - "D" (xstate), "m" (*xstate), "a" (lmask), "d" (hmask) - : "memory"); - - asm volatile("2:\n" - xstate_fault(err) - : "0" (err) - : "memory"); + XSTATE_XRESTORE(xstate, lmask, hmask, err); /* We should never fault when copying from a kernel buffer: */ WARN_ON_FPU(err); @@ -388,12 +387,10 @@ static inline int copy_xregs_to_user(struct xregs_state __user *buf) if (unlikely(err)) return -EFAULT; - __asm__ __volatile__(ASM_STAC "\n" - "1:"XSAVE"\n" - "2: " ASM_CLAC "\n" - xstate_fault(err) - : "D" (buf), "a" (-1), "d" (-1), "0" (err) - : "memory"); + stac(); + XSTATE_OP(XSAVE, buf, -1, -1, err); + clac(); + return err; } @@ -405,14 +402,12 @@ static inline int copy_user_to_xregs(struct xregs_state __user *buf, u64 mask) struct xregs_state *xstate = ((__force struct xregs_state *)buf); u32 lmask = mask; u32 hmask = mask >> 32; - int err = 0; - - __asm__ __volatile__(ASM_STAC "\n" - "1:"XRSTOR"\n" - "2: " ASM_CLAC "\n" - xstate_fault(err) - : "D" (xstate), "a" (lmask), "d" (hmask), "0" (err) - : "memory"); /* memory required? */ + int err; + + stac(); + XSTATE_OP(XRSTOR, xstate, lmask, hmask, err); + clac(); + return err; } @@ -466,7 +461,7 @@ static inline void copy_kernel_to_fpregs(union fpregs_state *fpstate) * pending. Clear the x87 state here by setting it to fixed values. * "m" is a random variable that should be in L1. */ - if (unlikely(static_cpu_has_bug_safe(X86_BUG_FXSAVE_LEAK))) { + if (unlikely(static_cpu_has_bug(X86_BUG_FXSAVE_LEAK))) { asm volatile( "fnclex\n\t" "emms\n\t" @@ -595,7 +590,8 @@ switch_fpu_prepare(struct fpu *old_fpu, struct fpu *new_fpu, int cpu) * If the task has used the math, pre-load the FPU on xsave processors * or if the past 5 consecutive context-switches used math. */ - fpu.preload = new_fpu->fpstate_active && + fpu.preload = static_cpu_has(X86_FEATURE_FPU) && + new_fpu->fpstate_active && (use_eager_fpu() || new_fpu->counter > 5); if (old_fpu->fpregs_active) { diff --git a/arch/x86/include/asm/fpu/xstate.h b/arch/x86/include/asm/fpu/xstate.h index 3a6c89b703075..f23cd8c80b1c8 100644 --- a/arch/x86/include/asm/fpu/xstate.h +++ b/arch/x86/include/asm/fpu/xstate.h @@ -22,7 +22,7 @@ #define XFEATURE_MASK_LAZY (XFEATURE_MASK_FP | \ XFEATURE_MASK_SSE | \ XFEATURE_MASK_YMM | \ - XFEATURE_MASK_OPMASK | \ + XFEATURE_MASK_OPMASK | \ XFEATURE_MASK_ZMM_Hi256 | \ XFEATURE_MASK_Hi16_ZMM) diff --git a/arch/x86/include/asm/futex.h b/arch/x86/include/asm/futex.h index b4c1f54534366..f4dc9b63bdda9 100644 --- a/arch/x86/include/asm/futex.h +++ b/arch/x86/include/asm/futex.h @@ -41,20 +41,11 @@ "+m" (*uaddr), "=&r" (tem) \ : "r" (oparg), "i" (-EFAULT), "1" (0)) -static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) +static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, + u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret, tem; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; - pagefault_disable(); switch (op) { @@ -80,30 +71,9 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: - ret = (oldval == cmparg); - break; - case FUTEX_OP_CMP_NE: - ret = (oldval != cmparg); - break; - case FUTEX_OP_CMP_LT: - ret = (oldval < cmparg); - break; - case FUTEX_OP_CMP_GE: - ret = (oldval >= cmparg); - break; - case FUTEX_OP_CMP_LE: - ret = (oldval <= cmparg); - break; - case FUTEX_OP_CMP_GT: - ret = (oldval > cmparg); - break; - default: - ret = -ENOSYS; - } - } + if (!ret) + *oval = oldval; + return ret; } diff --git a/arch/x86/include/asm/intel-family.h b/arch/x86/include/asm/intel-family.h index 6999f7d01a0d1..e13ff5a146331 100644 --- a/arch/x86/include/asm/intel-family.h +++ b/arch/x86/include/asm/intel-family.h @@ -12,6 +12,7 @@ */ #define INTEL_FAM6_CORE_YONAH 0x0E + #define INTEL_FAM6_CORE2_MEROM 0x0F #define INTEL_FAM6_CORE2_MEROM_L 0x16 #define INTEL_FAM6_CORE2_PENRYN 0x17 @@ -20,6 +21,7 @@ #define INTEL_FAM6_NEHALEM 0x1E #define INTEL_FAM6_NEHALEM_EP 0x1A #define INTEL_FAM6_NEHALEM_EX 0x2E + #define INTEL_FAM6_WESTMERE 0x25 #define INTEL_FAM6_WESTMERE2 0x1F #define INTEL_FAM6_WESTMERE_EP 0x2C @@ -36,9 +38,9 @@ #define INTEL_FAM6_HASWELL_GT3E 0x46 #define INTEL_FAM6_BROADWELL_CORE 0x3D -#define INTEL_FAM6_BROADWELL_XEON_D 0x56 #define INTEL_FAM6_BROADWELL_GT3E 0x47 #define INTEL_FAM6_BROADWELL_X 0x4F +#define INTEL_FAM6_BROADWELL_XEON_D 0x56 #define INTEL_FAM6_SKYLAKE_MOBILE 0x4E #define INTEL_FAM6_SKYLAKE_DESKTOP 0x5E @@ -56,13 +58,15 @@ #define INTEL_FAM6_ATOM_SILVERMONT1 0x37 /* BayTrail/BYT / Valleyview */ #define INTEL_FAM6_ATOM_SILVERMONT2 0x4D /* Avaton/Rangely */ #define INTEL_FAM6_ATOM_AIRMONT 0x4C /* CherryTrail / Braswell */ -#define INTEL_FAM6_ATOM_MERRIFIELD1 0x4A /* Tangier */ -#define INTEL_FAM6_ATOM_MERRIFIELD2 0x5A /* Annidale */ +#define INTEL_FAM6_ATOM_MERRIFIELD 0x4A /* Tangier */ +#define INTEL_FAM6_ATOM_MOOREFIELD 0x5A /* Annidale */ #define INTEL_FAM6_ATOM_GOLDMONT 0x5C #define INTEL_FAM6_ATOM_DENVERTON 0x5F /* Goldmont Microserver */ +#define INTEL_FAM6_ATOM_GEMINI_LAKE 0x7A /* Xeon Phi */ #define INTEL_FAM6_XEON_PHI_KNL 0x57 /* Knights Landing */ +#define INTEL_FAM6_XEON_PHI_KNM 0x85 /* Knights Mill */ #endif /* _ASM_X86_INTEL_FAMILY_H */ diff --git a/arch/x86/include/asm/irq_work.h b/arch/x86/include/asm/irq_work.h index 78162f8e248bd..d0afb05c84fc1 100644 --- a/arch/x86/include/asm/irq_work.h +++ b/arch/x86/include/asm/irq_work.h @@ -1,7 +1,7 @@ #ifndef _ASM_IRQ_WORK_H #define _ASM_IRQ_WORK_H -#include +#include static inline bool arch_irq_work_has_interrupt(void) { diff --git a/arch/x86/include/asm/irqflags.h b/arch/x86/include/asm/irqflags.h index b77f5edb03b0c..8afbdcd3032bf 100644 --- a/arch/x86/include/asm/irqflags.h +++ b/arch/x86/include/asm/irqflags.h @@ -8,7 +8,9 @@ * Interrupt control: */ -static inline unsigned long native_save_fl(void) +/* Declaration required for gcc < 4.9 to prevent -Werror=missing-prototypes */ +extern inline unsigned long native_save_fl(void); +extern inline unsigned long native_save_fl(void) { unsigned long flags; @@ -26,7 +28,8 @@ static inline unsigned long native_save_fl(void) return flags; } -static inline void native_restore_fl(unsigned long flags) +extern inline void native_restore_fl(unsigned long flags); +extern inline void native_restore_fl(unsigned long flags) { asm volatile("push %0 ; popf" : /* no output */ diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h index fc3c7e49c8e48..ae357d0afc91f 100644 --- a/arch/x86/include/asm/kvm_emulate.h +++ b/arch/x86/include/asm/kvm_emulate.h @@ -105,11 +105,12 @@ struct x86_emulate_ops { * @addr: [IN ] Linear address from which to read. * @val: [OUT] Value read from memory, zero-extended to 'u_long'. * @bytes: [IN ] Number of bytes to read from memory. + * @system:[IN ] Whether the access is forced to be at CPL0. */ int (*read_std)(struct x86_emulate_ctxt *ctxt, unsigned long addr, void *val, unsigned int bytes, - struct x86_exception *fault); + struct x86_exception *fault, bool system); /* * read_phys: Read bytes of standard (non-emulated/special) memory. @@ -127,10 +128,11 @@ struct x86_emulate_ops { * @addr: [IN ] Linear address to which to write. * @val: [OUT] Value write to memory, zero-extended to 'u_long'. * @bytes: [IN ] Number of bytes to write to memory. + * @system:[IN ] Whether the access is forced to be at CPL0. */ int (*write_std)(struct x86_emulate_ctxt *ctxt, unsigned long addr, void *val, unsigned int bytes, - struct x86_exception *fault); + struct x86_exception *fault, bool system); /* * fetch: Read bytes of standard (non-emulated/special) memory. * Used for instruction fetch. diff --git a/arch/x86/include/asm/mmu.h b/arch/x86/include/asm/mmu.h index 7680b76adafc0..3359dfedc7ee7 100644 --- a/arch/x86/include/asm/mmu.h +++ b/arch/x86/include/asm/mmu.h @@ -3,12 +3,18 @@ #include #include +#include /* - * The x86 doesn't have a mmu context, but - * we put the segment information here. + * x86 has arch-specific MMU state beyond what lives in mm_struct. */ typedef struct { + /* + * ctx_id uniquely identifies this mm_struct. A ctx_id will never + * be reused, and zero is not a valid ctx_id. + */ + u64 ctx_id; + #ifdef CONFIG_MODIFY_LDT_SYSCALL struct ldt_struct *ldt; #endif @@ -24,6 +30,11 @@ typedef struct { atomic_t perf_rdpmc_allowed; /* nonzero if rdpmc is allowed */ } mm_context_t; +#define INIT_MM_CONTEXT(mm) \ + .context = { \ + .ctx_id = 1, \ + } + void leave_mm(int cpu); #endif /* _ASM_X86_MMU_H */ diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h index 9bfc5fd770156..d8d19fe99e45f 100644 --- a/arch/x86/include/asm/mmu_context.h +++ b/arch/x86/include/asm/mmu_context.h @@ -11,6 +11,9 @@ #include #include #include + +extern atomic64_t last_mm_ctx_id; + #ifndef CONFIG_PARAVIRT static inline void paravirt_activate_mm(struct mm_struct *prev, struct mm_struct *next) @@ -52,15 +55,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) @@ -102,6 +105,17 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) this_cpu_write(cpu_tlbstate.state, TLBSTATE_LAZY); } +static inline int init_new_context(struct task_struct *tsk, + struct mm_struct *mm) +{ + mm->context.ctx_id = atomic64_inc_return(&last_mm_ctx_id); + return init_new_context_ldt(tsk, mm); +} +static inline void destroy_context(struct mm_struct *mm) +{ + destroy_context_ldt(mm); +} + extern void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk); diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index b8911aecf0352..caa00191e565f 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -32,6 +32,15 @@ #define EFER_FFXSR (1<<_EFER_FFXSR) /* Intel MSRs. Some also available on other CPUs */ +#define MSR_IA32_SPEC_CTRL 0x00000048 /* Speculation Control */ +#define SPEC_CTRL_IBRS (1 << 0) /* Indirect Branch Restricted Speculation */ +#define SPEC_CTRL_STIBP (1 << 1) /* Single Thread Indirect Branch Predictors */ +#define SPEC_CTRL_SSBD_SHIFT 2 /* Speculative Store Bypass Disable bit */ +#define SPEC_CTRL_SSBD (1 << SPEC_CTRL_SSBD_SHIFT) /* Speculative Store Bypass Disable */ + +#define MSR_IA32_PRED_CMD 0x00000049 /* Prediction Command */ +#define PRED_CMD_IBPB (1 << 0) /* Indirect Branch Prediction Barrier */ + #define MSR_IA32_PERFCTR0 0x000000c1 #define MSR_IA32_PERFCTR1 0x000000c2 #define MSR_FSB_FREQ 0x000000cd @@ -45,6 +54,16 @@ #define SNB_C3_AUTO_UNDEMOTE (1UL << 28) #define MSR_MTRRcap 0x000000fe + +#define MSR_IA32_ARCH_CAPABILITIES 0x0000010a +#define ARCH_CAP_RDCL_NO (1 << 0) /* Not susceptible to Meltdown */ +#define ARCH_CAP_IBRS_ALL (1 << 1) /* Enhanced IBRS support */ +#define ARCH_CAP_SSB_NO (1 << 4) /* + * Not susceptible to Speculative Store Bypass + * attack, so no Speculative Store Bypass + * control required. + */ + #define MSR_IA32_BBL_CR_CTL 0x00000119 #define MSR_IA32_BBL_CR_CTL3 0x0000011e @@ -132,6 +151,7 @@ /* DEBUGCTLMSR bits (others vary by model): */ #define DEBUGCTLMSR_LBR (1UL << 0) /* last branch recording */ +#define DEBUGCTLMSR_BTF_SHIFT 1 #define DEBUGCTLMSR_BTF (1UL << 1) /* single-step on branches */ #define DEBUGCTLMSR_TR (1UL << 6) #define DEBUGCTLMSR_BTS (1UL << 7) @@ -308,6 +328,8 @@ #define MSR_AMD64_IBSOPDATA4 0xc001103d #define MSR_AMD64_IBS_REG_COUNT_MAX 8 /* includes MSR_AMD64_IBSBRTARGET */ +#define MSR_AMD64_VIRT_SPEC_CTRL 0xc001011f + /* Fam 16h MSRs */ #define MSR_F16H_L2I_PERF_CTL 0xc0010230 #define MSR_F16H_L2I_PERF_CTR 0xc0010231 diff --git a/arch/x86/include/asm/mwait.h b/arch/x86/include/asm/mwait.h index c70689b5e5aa4..0deeb2d26df7c 100644 --- a/arch/x86/include/asm/mwait.h +++ b/arch/x86/include/asm/mwait.h @@ -3,6 +3,8 @@ #include +#include + #define MWAIT_SUBSTATE_MASK 0xf #define MWAIT_CSTATE_MASK 0xf #define MWAIT_SUBSTATE_SIZE 4 diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h index 249f1c769f21f..b4c74c24c8908 100644 --- a/arch/x86/include/asm/nospec-branch.h +++ b/arch/x86/include/asm/nospec-branch.h @@ -5,7 +5,8 @@ #include #include -#include +#include +#include /* * Fill the CPU return stack buffer. @@ -171,6 +172,14 @@ enum spectre_v2_mitigation { SPECTRE_V2_IBRS, }; +/* The Speculative Store Bypass disable variants */ +enum ssb_mitigation { + SPEC_STORE_BYPASS_NONE, + SPEC_STORE_BYPASS_DISABLE, + SPEC_STORE_BYPASS_PRCTL, + SPEC_STORE_BYPASS_SECCOMP, +}; + extern char __indirect_thunk_start[]; extern char __indirect_thunk_end[]; @@ -194,6 +203,51 @@ static inline void vmexit_fill_RSB(void) #endif } +static __always_inline +void alternative_msr_write(unsigned int msr, u64 val, unsigned int feature) +{ + asm volatile(ALTERNATIVE("", "wrmsr", %c[feature]) + : : "c" (msr), + "a" ((u32)val), + "d" ((u32)(val >> 32)), + [feature] "i" (feature) + : "memory"); +} + +static inline void indirect_branch_prediction_barrier(void) +{ + u64 val = PRED_CMD_IBPB; + + alternative_msr_write(MSR_IA32_PRED_CMD, val, X86_FEATURE_USE_IBPB); +} + +/* The Intel SPEC CTRL MSR base value cache */ +extern u64 x86_spec_ctrl_base; + +/* + * With retpoline, we must use IBRS to restrict branch prediction + * before calling into firmware. + * + * (Implemented as CPP macros due to header hell.) + */ +#define firmware_restrict_branch_speculation_start() \ +do { \ + u64 val = x86_spec_ctrl_base | SPEC_CTRL_IBRS; \ + \ + preempt_disable(); \ + alternative_msr_write(MSR_IA32_SPEC_CTRL, val, \ + X86_FEATURE_USE_IBRS_FW); \ +} while (0) + +#define firmware_restrict_branch_speculation_end() \ +do { \ + u64 val = x86_spec_ctrl_base; \ + \ + alternative_msr_write(MSR_IA32_SPEC_CTRL, val, \ + X86_FEATURE_USE_IBRS_FW); \ + preempt_enable(); \ +} while (0) + #endif /* __ASSEMBLY__ */ /* diff --git a/arch/x86/include/asm/page_32_types.h b/arch/x86/include/asm/page_32_types.h index 3a52ee0e726d4..bfceb5cc63478 100644 --- a/arch/x86/include/asm/page_32_types.h +++ b/arch/x86/include/asm/page_32_types.h @@ -27,8 +27,13 @@ #define N_EXCEPTION_STACKS 1 #ifdef CONFIG_X86_PAE -/* 44=32+12, the limit we can fit into an unsigned long pfn */ -#define __PHYSICAL_MASK_SHIFT 44 +/* + * This is beyond the 44 bit limit imposed by the 32bit long pfns, + * but we need the full mask to make sure inverted PROT_NONE + * entries have all the host bits set in a guest. + * The real limit is still 44 bits. + */ +#define __PHYSICAL_MASK_SHIFT 52 #define __VIRTUAL_MASK_SHIFT 32 #else /* !CONFIG_X86_PAE */ diff --git a/arch/x86/include/asm/pgtable-2level.h b/arch/x86/include/asm/pgtable-2level.h index fd74a11959de0..89c50332a71ed 100644 --- a/arch/x86/include/asm/pgtable-2level.h +++ b/arch/x86/include/asm/pgtable-2level.h @@ -77,4 +77,21 @@ static inline unsigned long pte_bitop(unsigned long value, unsigned int rightshi #define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte_low }) #define __swp_entry_to_pte(x) ((pte_t) { .pte = (x).val }) +/* No inverted PFNs on 2 level page tables */ + +static inline u64 protnone_mask(u64 val) +{ + return 0; +} + +static inline u64 flip_protnone_guard(u64 oldval, u64 val, u64 mask) +{ + return val; +} + +static inline bool __pte_needs_invert(u64 val) +{ + return false; +} + #endif /* _ASM_X86_PGTABLE_2LEVEL_H */ diff --git a/arch/x86/include/asm/pgtable-3level.h b/arch/x86/include/asm/pgtable-3level.h index cdaa58c9b39ed..5c686382d84ba 100644 --- a/arch/x86/include/asm/pgtable-3level.h +++ b/arch/x86/include/asm/pgtable-3level.h @@ -177,11 +177,44 @@ static inline pmd_t native_pmdp_get_and_clear(pmd_t *pmdp) #endif /* Encode and de-code a swap entry */ +#define SWP_TYPE_BITS 5 + +#define SWP_OFFSET_FIRST_BIT (_PAGE_BIT_PROTNONE + 1) + +/* We always extract/encode the offset by shifting it all the way up, and then down again */ +#define SWP_OFFSET_SHIFT (SWP_OFFSET_FIRST_BIT + SWP_TYPE_BITS) + #define MAX_SWAPFILES_CHECK() BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > 5) #define __swp_type(x) (((x).val) & 0x1f) #define __swp_offset(x) ((x).val >> 5) #define __swp_entry(type, offset) ((swp_entry_t){(type) | (offset) << 5}) -#define __pte_to_swp_entry(pte) ((swp_entry_t){ (pte).pte_high }) -#define __swp_entry_to_pte(x) ((pte_t){ { .pte_high = (x).val } }) + +/* + * Normally, __swp_entry() converts from arch-independent swp_entry_t to + * arch-dependent swp_entry_t, and __swp_entry_to_pte() just stores the result + * to pte. But here we have 32bit swp_entry_t and 64bit pte, and need to use the + * whole 64 bits. Thus, we shift the "real" arch-dependent conversion to + * __swp_entry_to_pte() through the following helper macro based on 64bit + * __swp_entry(). + */ +#define __swp_pteval_entry(type, offset) ((pteval_t) { \ + (~(pteval_t)(offset) << SWP_OFFSET_SHIFT >> SWP_TYPE_BITS) \ + | ((pteval_t)(type) << (64 - SWP_TYPE_BITS)) }) + +#define __swp_entry_to_pte(x) ((pte_t){ .pte = \ + __swp_pteval_entry(__swp_type(x), __swp_offset(x)) }) +/* + * Analogically, __pte_to_swp_entry() doesn't just extract the arch-dependent + * swp_entry_t, but also has to convert it from 64bit to the 32bit + * intermediate representation, using the following macros based on 64bit + * __swp_type() and __swp_offset(). + */ +#define __pteval_swp_type(x) ((unsigned long)((x).pte >> (64 - SWP_TYPE_BITS))) +#define __pteval_swp_offset(x) ((unsigned long)(~((x).pte) << SWP_TYPE_BITS >> SWP_OFFSET_SHIFT)) + +#define __pte_to_swp_entry(pte) (__swp_entry(__pteval_swp_type(pte), \ + __pteval_swp_offset(pte))) + +#include #endif /* _ASM_X86_PGTABLE_3LEVEL_H */ diff --git a/arch/x86/include/asm/pgtable-invert.h b/arch/x86/include/asm/pgtable-invert.h new file mode 100644 index 0000000000000..a0c1525f1b6f4 --- /dev/null +++ b/arch/x86/include/asm/pgtable-invert.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_PGTABLE_INVERT_H +#define _ASM_PGTABLE_INVERT_H 1 + +#ifndef __ASSEMBLY__ + +/* + * A clear pte value is special, and doesn't get inverted. + * + * Note that even users that only pass a pgprot_t (rather + * than a full pte) won't trigger the special zero case, + * because even PAGE_NONE has _PAGE_PROTNONE | _PAGE_ACCESSED + * set. So the all zero case really is limited to just the + * cleared page table entry case. + */ +static inline bool __pte_needs_invert(u64 val) +{ + return val && !(val & _PAGE_PRESENT); +} + +/* Get a mask to xor with the page table entry to get the correct pfn. */ +static inline u64 protnone_mask(u64 val) +{ + return __pte_needs_invert(val) ? ~0ull : 0; +} + +static inline u64 flip_protnone_guard(u64 oldval, u64 val, u64 mask) +{ + /* + * When a PTE transitions from NONE to !NONE or vice-versa + * invert the PFN part to stop speculation. + * pte_pfn undoes this when needed. + */ + if (__pte_needs_invert(oldval) != __pte_needs_invert(val)) + val = (val & ~mask) | (~val & mask); + return val; +} + +#endif /* __ASSEMBLY__ */ + +#endif diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 84c62d9500232..68a55273ce0f4 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -148,19 +148,34 @@ static inline int pte_special(pte_t pte) return pte_flags(pte) & _PAGE_SPECIAL; } +/* Entries that were set to PROT_NONE are inverted */ + +static inline u64 protnone_mask(u64 val); + static inline unsigned long pte_pfn(pte_t pte) { - return (pte_val(pte) & PTE_PFN_MASK) >> PAGE_SHIFT; + phys_addr_t pfn = pte_val(pte); + pfn ^= protnone_mask(pfn); + return (pfn & PTE_PFN_MASK) >> PAGE_SHIFT; } static inline unsigned long pmd_pfn(pmd_t pmd) { - return (pmd_val(pmd) & pmd_pfn_mask(pmd)) >> PAGE_SHIFT; + phys_addr_t pfn = pmd_val(pmd); + pfn ^= protnone_mask(pfn); + return (pfn & pmd_pfn_mask(pmd)) >> PAGE_SHIFT; } static inline unsigned long pud_pfn(pud_t pud) { - return (pud_val(pud) & pud_pfn_mask(pud)) >> PAGE_SHIFT; + phys_addr_t pfn = pud_val(pud); + pfn ^= protnone_mask(pfn); + return (pfn & pud_pfn_mask(pud)) >> PAGE_SHIFT; +} + +static inline unsigned long pgd_pfn(pgd_t pgd) +{ + return (pgd_val(pgd) & PTE_PFN_MASK) >> PAGE_SHIFT; } #define pte_page(pte) pfn_to_page(pte_pfn(pte)) @@ -305,11 +320,6 @@ static inline pmd_t pmd_mkwrite(pmd_t pmd) return pmd_set_flags(pmd, _PAGE_RW); } -static inline pmd_t pmd_mknotpresent(pmd_t pmd) -{ - return pmd_clear_flags(pmd, _PAGE_PRESENT | _PAGE_PROTNONE); -} - #ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY static inline int pte_soft_dirty(pte_t pte) { @@ -359,19 +369,58 @@ static inline pgprotval_t massage_pgprot(pgprot_t pgprot) static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot) { - return __pte(((phys_addr_t)page_nr << PAGE_SHIFT) | - massage_pgprot(pgprot)); + phys_addr_t pfn = (phys_addr_t)page_nr << PAGE_SHIFT; + pfn ^= protnone_mask(pgprot_val(pgprot)); + pfn &= PTE_PFN_MASK; + return __pte(pfn | massage_pgprot(pgprot)); } static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot) { - return __pmd(((phys_addr_t)page_nr << PAGE_SHIFT) | - massage_pgprot(pgprot)); + phys_addr_t pfn = (phys_addr_t)page_nr << PAGE_SHIFT; + pfn ^= protnone_mask(pgprot_val(pgprot)); + pfn &= PHYSICAL_PMD_PAGE_MASK; + return __pmd(pfn | massage_pgprot(pgprot)); +} + +static inline pud_t pfn_pud(unsigned long page_nr, pgprot_t pgprot) +{ + phys_addr_t pfn = page_nr << PAGE_SHIFT; + pfn ^= protnone_mask(pgprot_val(pgprot)); + pfn &= PHYSICAL_PUD_PAGE_MASK; + return __pud(pfn | massage_pgprot(pgprot)); +} + +static inline pmd_t pmd_mknotpresent(pmd_t pmd) +{ + return pfn_pmd(pmd_pfn(pmd), + __pgprot(pmd_flags(pmd) & ~(_PAGE_PRESENT|_PAGE_PROTNONE))); +} + +static inline pud_t pud_set_flags(pud_t pud, pudval_t set) +{ + pudval_t v = native_pud_val(pud); + + return __pud(v | set); } +static inline pud_t pud_clear_flags(pud_t pud, pudval_t clear) +{ + pudval_t v = native_pud_val(pud); + + return __pud(v & ~clear); +} + +static inline pud_t pud_mkhuge(pud_t pud) +{ + return pud_set_flags(pud, _PAGE_PSE); +} + +static inline u64 flip_protnone_guard(u64 oldval, u64 val, u64 mask); + static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) { - pteval_t val = pte_val(pte); + pteval_t val = pte_val(pte), oldval = val; /* * Chop off the NX bit (if present), and add the NX portion of @@ -379,17 +428,17 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) */ val &= _PAGE_CHG_MASK; val |= massage_pgprot(newprot) & ~_PAGE_CHG_MASK; - + val = flip_protnone_guard(oldval, val, PTE_PFN_MASK); return __pte(val); } static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) { - pmdval_t val = pmd_val(pmd); + pmdval_t val = pmd_val(pmd), oldval = val; val &= _HPAGE_CHG_MASK; val |= massage_pgprot(newprot) & ~_HPAGE_CHG_MASK; - + val = flip_protnone_guard(oldval, val, PHYSICAL_PMD_PAGE_MASK); return __pmd(val); } @@ -534,8 +583,7 @@ static inline unsigned long pmd_page_vaddr(pmd_t pmd) * Currently stuck as a macro due to indirect forward reference to * linux/mmzone.h's __section_mem_map_addr() definition: */ -#define pmd_page(pmd) \ - pfn_to_page((pmd_val(pmd) & pmd_pfn_mask(pmd)) >> PAGE_SHIFT) +#define pmd_page(pmd) pfn_to_page(pmd_pfn(pmd)) /* * the pmd page can be thought of an array like this: pmd_t[PTRS_PER_PMD] @@ -603,8 +651,7 @@ static inline unsigned long pud_page_vaddr(pud_t pud) * Currently stuck as a macro due to indirect forward reference to * linux/mmzone.h's __section_mem_map_addr() definition: */ -#define pud_page(pud) \ - pfn_to_page((pud_val(pud) & pud_pfn_mask(pud)) >> PAGE_SHIFT) +#define pud_page(pud) pfn_to_page(pud_pfn(pud)) /* Find an entry in the second-level page table.. */ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address) @@ -644,7 +691,7 @@ static inline unsigned long pgd_page_vaddr(pgd_t pgd) * Currently stuck as a macro due to indirect forward reference to * linux/mmzone.h's __section_mem_map_addr() definition: */ -#define pgd_page(pgd) pfn_to_page(pgd_val(pgd) >> PAGE_SHIFT) +#define pgd_page(pgd) pfn_to_page(pgd_pfn(pgd)) /* to find an entry in a page-table-directory. */ static inline unsigned long pud_index(unsigned long address) @@ -926,6 +973,14 @@ static inline pte_t pte_swp_clear_soft_dirty(pte_t pte) } #endif +#define __HAVE_ARCH_PFN_MODIFY_ALLOWED 1 +extern bool pfn_modify_allowed(unsigned long pfn, pgprot_t prot); + +static inline bool arch_has_pfn_modify_check(void) +{ + return boot_cpu_has_bug(X86_BUG_L1TF); +} + #include #endif /* __ASSEMBLY__ */ diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h index c810226e741a6..221a32ed13727 100644 --- a/arch/x86/include/asm/pgtable_64.h +++ b/arch/x86/include/asm/pgtable_64.h @@ -163,18 +163,52 @@ static inline int pgd_large(pgd_t pgd) { return 0; } #define pte_offset_map(dir, address) pte_offset_kernel((dir), (address)) #define pte_unmap(pte) ((void)(pte))/* NOP */ -/* Encode and de-code a swap entry */ -#define SWP_TYPE_BITS 5 -#define SWP_OFFSET_SHIFT (_PAGE_BIT_PROTNONE + 1) +/* + * Encode and de-code a swap entry + * + * | ... | 11| 10| 9|8|7|6|5| 4| 3|2| 1|0| <- bit number + * | ... |SW3|SW2|SW1|G|L|D|A|CD|WT|U| W|P| <- bit names + * | TYPE (59-63) | ~OFFSET (9-58) |0|0|X|X| X| X|X|SD|0| <- swp entry + * + * G (8) is aliased and used as a PROT_NONE indicator for + * !present ptes. We need to start storing swap entries above + * there. We also need to avoid using A and D because of an + * erratum where they can be incorrectly set by hardware on + * non-present PTEs. + * + * SD (1) in swp entry is used to store soft dirty bit, which helps us + * remember soft dirty over page migration + * + * Bit 7 in swp entry should be 0 because pmd_present checks not only P, + * but also L and G. + * + * The offset is inverted by a binary not operation to make the high + * physical bits set. + */ +#define SWP_TYPE_BITS 5 + +#define SWP_OFFSET_FIRST_BIT (_PAGE_BIT_PROTNONE + 1) + +/* We always extract/encode the offset by shifting it all the way up, and then down again */ +#define SWP_OFFSET_SHIFT (SWP_OFFSET_FIRST_BIT+SWP_TYPE_BITS) #define MAX_SWAPFILES_CHECK() BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > SWP_TYPE_BITS) -#define __swp_type(x) (((x).val >> (_PAGE_BIT_PRESENT + 1)) \ - & ((1U << SWP_TYPE_BITS) - 1)) -#define __swp_offset(x) ((x).val >> SWP_OFFSET_SHIFT) -#define __swp_entry(type, offset) ((swp_entry_t) { \ - ((type) << (_PAGE_BIT_PRESENT + 1)) \ - | ((offset) << SWP_OFFSET_SHIFT) }) +/* Extract the high bits for type */ +#define __swp_type(x) ((x).val >> (64 - SWP_TYPE_BITS)) + +/* Shift up (to get rid of type), then down to get value */ +#define __swp_offset(x) (~(x).val << SWP_TYPE_BITS >> SWP_OFFSET_SHIFT) + +/* + * Shift the offset up "too far" by TYPE bits, then down again + * The offset is inverted by a binary not operation to make the high + * physical bits set. + */ +#define __swp_entry(type, offset) ((swp_entry_t) { \ + (~(unsigned long)(offset) << SWP_OFFSET_SHIFT >> SWP_TYPE_BITS) \ + | ((unsigned long)(type) << (64-SWP_TYPE_BITS)) }) + #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val((pte)) }) #define __swp_entry_to_pte(x) ((pte_t) { .pte = (x).val }) @@ -201,6 +235,8 @@ extern void cleanup_highmap(void); extern void init_extra_mapping_uc(unsigned long phys, unsigned long size); extern void init_extra_mapping_wb(unsigned long phys, unsigned long size); +#include + #endif /* !__ASSEMBLY__ */ #endif /* _ASM_X86_PGTABLE_64_H */ diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h index 8dba273da25a6..7572ce32055eb 100644 --- a/arch/x86/include/asm/pgtable_types.h +++ b/arch/x86/include/asm/pgtable_types.h @@ -70,15 +70,15 @@ /* * Tracking soft dirty bit when a page goes to a swap is tricky. * We need a bit which can be stored in pte _and_ not conflict - * with swap entry format. On x86 bits 6 and 7 are *not* involved - * into swap entry computation, but bit 6 is used for nonlinear - * file mapping, so we borrow bit 7 for soft dirty tracking. + * with swap entry format. On x86 bits 1-4 are *not* involved + * into swap entry computation, but bit 7 is used for thp migration, + * so we borrow bit 1 for soft dirty tracking. * * Please note that this bit must be treated as swap dirty page - * mark if and only if the PTE has present bit clear! + * mark if and only if the PTE/PMD has present bit clear! */ #ifdef CONFIG_MEM_SOFT_DIRTY -#define _PAGE_SWP_SOFT_DIRTY _PAGE_PSE +#define _PAGE_SWP_SOFT_DIRTY _PAGE_RW #else #define _PAGE_SWP_SOFT_DIRTY (_AT(pteval_t, 0)) #endif diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 9e77cea2a8efb..337c521922783 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -13,7 +13,7 @@ struct vm86; #include #include #include -#include +#include #include #include #include @@ -24,7 +24,6 @@ struct vm86; #include #include -#include #include #include #include @@ -173,6 +172,11 @@ extern const struct seq_operations cpuinfo_op; extern void cpu_detect(struct cpuinfo_x86 *c); +static inline unsigned long long l1tf_pfn_limit(void) +{ + return BIT_ULL(boot_cpu_data.x86_phys_bits - 1 - PAGE_SHIFT); +} + extern void early_cpu_init(void); extern void identify_boot_cpu(void); extern void identify_secondary_cpu(struct cpuinfo_x86 *); diff --git a/arch/x86/include/asm/required-features.h b/arch/x86/include/asm/required-features.h index 5c6e4fb370f5a..6847d85400a8b 100644 --- a/arch/x86/include/asm/required-features.h +++ b/arch/x86/include/asm/required-features.h @@ -92,5 +92,15 @@ #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 +#define REQUIRED_MASK17 0 +#define REQUIRED_MASK18 0 +#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 19) #endif /* _ASM_X86_REQUIRED_FEATURES_H */ diff --git a/arch/x86/include/asm/smap.h b/arch/x86/include/asm/smap.h index ba665ebd17bb8..db333300bd4be 100644 --- a/arch/x86/include/asm/smap.h +++ b/arch/x86/include/asm/smap.h @@ -15,7 +15,7 @@ #include #include -#include +#include /* "Raw" instruction opcodes */ #define __ASM_CLAC .byte 0x0f,0x01,0xca diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h index 222a6a3ca2b5e..04d6eef5f8a5c 100644 --- a/arch/x86/include/asm/smp.h +++ b/arch/x86/include/asm/smp.h @@ -16,20 +16,10 @@ #endif #include #include -#include extern int smp_num_siblings; extern unsigned int num_processors; -static inline bool cpu_has_ht_siblings(void) -{ - bool has_siblings = false; -#ifdef CONFIG_SMP - has_siblings = cpu_has_ht && smp_num_siblings > 1; -#endif - return has_siblings; -} - DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_sibling_map); DECLARE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_core_map); /* cpus sharing the last level cache: */ diff --git a/arch/x86/include/asm/spec-ctrl.h b/arch/x86/include/asm/spec-ctrl.h new file mode 100644 index 0000000000000..ae7c2c5cd7f0e --- /dev/null +++ b/arch/x86/include/asm/spec-ctrl.h @@ -0,0 +1,80 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_X86_SPECCTRL_H_ +#define _ASM_X86_SPECCTRL_H_ + +#include +#include + +/* + * On VMENTER we must preserve whatever view of the SPEC_CTRL MSR + * the guest has, while on VMEXIT we restore the host view. This + * would be easier if SPEC_CTRL were architecturally maskable or + * shadowable for guests but this is not (currently) the case. + * Takes the guest view of SPEC_CTRL MSR as a parameter and also + * the guest's version of VIRT_SPEC_CTRL, if emulated. + */ +extern void x86_virt_spec_ctrl(u64 guest_spec_ctrl, u64 guest_virt_spec_ctrl, bool guest); + +/** + * x86_spec_ctrl_set_guest - Set speculation control registers for the guest + * @guest_spec_ctrl: The guest content of MSR_SPEC_CTRL + * @guest_virt_spec_ctrl: The guest controlled bits of MSR_VIRT_SPEC_CTRL + * (may get translated to MSR_AMD64_LS_CFG bits) + * + * Avoids writing to the MSR if the content/bits are the same + */ +static inline +void x86_spec_ctrl_set_guest(u64 guest_spec_ctrl, u64 guest_virt_spec_ctrl) +{ + x86_virt_spec_ctrl(guest_spec_ctrl, guest_virt_spec_ctrl, true); +} + +/** + * x86_spec_ctrl_restore_host - Restore host speculation control registers + * @guest_spec_ctrl: The guest content of MSR_SPEC_CTRL + * @guest_virt_spec_ctrl: The guest controlled bits of MSR_VIRT_SPEC_CTRL + * (may get translated to MSR_AMD64_LS_CFG bits) + * + * Avoids writing to the MSR if the content/bits are the same + */ +static inline +void x86_spec_ctrl_restore_host(u64 guest_spec_ctrl, u64 guest_virt_spec_ctrl) +{ + x86_virt_spec_ctrl(guest_spec_ctrl, guest_virt_spec_ctrl, false); +} + +/* AMD specific Speculative Store Bypass MSR data */ +extern u64 x86_amd_ls_cfg_base; +extern u64 x86_amd_ls_cfg_ssbd_mask; + +static inline u64 ssbd_tif_to_spec_ctrl(u64 tifn) +{ + BUILD_BUG_ON(TIF_SSBD < SPEC_CTRL_SSBD_SHIFT); + return (tifn & _TIF_SSBD) >> (TIF_SSBD - SPEC_CTRL_SSBD_SHIFT); +} + +static inline unsigned long ssbd_spec_ctrl_to_tif(u64 spec_ctrl) +{ + BUILD_BUG_ON(TIF_SSBD < SPEC_CTRL_SSBD_SHIFT); + return (spec_ctrl & SPEC_CTRL_SSBD) << (TIF_SSBD - SPEC_CTRL_SSBD_SHIFT); +} + +static inline u64 ssbd_tif_to_amd_ls_cfg(u64 tifn) +{ + return (tifn & _TIF_SSBD) ? x86_amd_ls_cfg_ssbd_mask : 0ULL; +} + +#ifdef CONFIG_SMP +extern void speculative_store_bypass_ht_init(void); +#else +static inline void speculative_store_bypass_ht_init(void) { } +#endif + +extern void speculative_store_bypass_update(unsigned long tif); + +static inline void speculative_store_bypass_update_current(void) +{ + speculative_store_bypass_update(current_thread_info()->flags); +} + +#endif diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index 0c977fc124a77..128a7105cbe2c 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h @@ -49,7 +49,7 @@ */ #ifndef __ASSEMBLY__ struct task_struct; -#include +#include #include struct thread_info { @@ -92,6 +92,7 @@ struct thread_info { #define TIF_SIGPENDING 2 /* signal pending */ #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ #define TIF_SINGLESTEP 4 /* reenable singlestep on user return*/ +#define TIF_SSBD 5 /* Reduced data speculation */ #define TIF_SYSCALL_EMU 6 /* syscall emulation active */ #define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */ #define TIF_SECCOMP 8 /* secure computing */ @@ -114,8 +115,9 @@ struct thread_info { #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) -#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) +#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) +#define _TIF_SSBD (1 << TIF_SSBD) #define _TIF_SYSCALL_EMU (1 << TIF_SYSCALL_EMU) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) #define _TIF_SECCOMP (1 << TIF_SECCOMP) @@ -147,7 +149,7 @@ struct thread_info { /* flags to check in __switch_to() */ #define _TIF_WORK_CTXSW \ - (_TIF_IO_BITMAP|_TIF_NOTSC|_TIF_BLOCKSTEP) + (_TIF_IO_BITMAP|_TIF_NOTSC|_TIF_BLOCKSTEP|_TIF_SSBD) #define _TIF_WORK_CTXSW_PREV (_TIF_WORK_CTXSW|_TIF_USER_RETURN_NOTIFY) #define _TIF_WORK_CTXSW_NEXT (_TIF_WORK_CTXSW) diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h index a691b66cc40ac..72cfe3e53af1a 100644 --- a/arch/x86/include/asm/tlbflush.h +++ b/arch/x86/include/asm/tlbflush.h @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -67,6 +68,8 @@ static inline void invpcid_flush_all_nonglobals(void) struct tlb_state { struct mm_struct *active_mm; int state; + /* last user mm's ctx id */ + u64 last_ctx_id; /* * Access to this CR4 shadow and to H/W CR4 is protected by @@ -108,6 +111,16 @@ static inline void cr4_clear_bits(unsigned long mask) } } +static inline void cr4_toggle_bits(unsigned long mask) +{ + unsigned long cr4; + + cr4 = this_cpu_read(cpu_tlbstate.cr4); + cr4 ^= mask; + this_cpu_write(cpu_tlbstate.cr4, cr4); + __write_cr4(cr4); +} + /* Read the CR4 shadow. */ static inline unsigned long cr4_read_shadow(void) { diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h index 2957c8237c28d..ec9d2bcc8c249 100644 --- a/arch/x86/include/asm/uaccess_64.h +++ b/arch/x86/include/asm/uaccess_64.h @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include /* diff --git a/arch/x86/include/asm/xor_32.h b/arch/x86/include/asm/xor_32.h index 5a08bc8bff339..c54beb44c4c1f 100644 --- a/arch/x86/include/asm/xor_32.h +++ b/arch/x86/include/asm/xor_32.h @@ -553,7 +553,7 @@ do { \ if (cpu_has_xmm) { \ xor_speed(&xor_block_pIII_sse); \ xor_speed(&xor_block_sse_pf64); \ - } else if (cpu_has_mmx) { \ + } else if (boot_cpu_has(X86_FEATURE_MMX)) { \ xor_speed(&xor_block_pII_mmx); \ xor_speed(&xor_block_p5_mmx); \ } else { \ diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 616ebd22ef9a2..5e59af41d40e9 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -53,6 +53,7 @@ obj-y += alternative.o i8253.o pci-nommu.o hw_breakpoint.o obj-y += tsc.o tsc_msr.o io_delay.o rtc.o obj-y += pci-iommu_table.o obj-y += resource.o +obj-y += irqflags.o obj-y += process.o obj-y += fpu/ diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index a3e1f8497f8c6..deddc9b932990 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -1368,7 +1368,7 @@ void setup_local_APIC(void) * TODO: set up through-local-APIC from through-I/O-APIC? --macro */ value = apic_read(APIC_LVT0) & APIC_LVT_MASKED; - if (!cpu && (pic_mode || !value)) { + if (!cpu && (pic_mode || !value || skip_ioapic_setup)) { value = APIC_DM_EXTINT; apic_printk(APIC_VERBOSE, "enabled ExtINT on CPU#%d\n", cpu); } else { diff --git a/arch/x86/kernel/apic/apic_numachip.c b/arch/x86/kernel/apic/apic_numachip.c index 2bd2292a316d4..bac0805ea1d9d 100644 --- a/arch/x86/kernel/apic/apic_numachip.c +++ b/arch/x86/kernel/apic/apic_numachip.c @@ -30,7 +30,7 @@ static unsigned int numachip1_get_apic_id(unsigned long x) unsigned long value; unsigned int id = (x >> 24) & 0xff; - if (static_cpu_has_safe(X86_FEATURE_NODEID_MSR)) { + if (static_cpu_has(X86_FEATURE_NODEID_MSR)) { rdmsrl(MSR_FAM10H_NODE_ID, value); id |= (value << 2) & 0xff00; } @@ -178,7 +178,7 @@ static void fixup_cpu_id(struct cpuinfo_x86 *c, int node) this_cpu_write(cpu_llc_id, node); /* Account for nodes per socket in multi-core-module processors */ - if (static_cpu_has_safe(X86_FEATURE_NODEID_MSR)) { + if (static_cpu_has(X86_FEATURE_NODEID_MSR)) { rdmsrl(MSR_FAM10H_NODE_ID, val); nodes = ((val >> 3) & 7) + 1; } diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index 606ebe494756c..1e5184092ee6a 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile @@ -66,7 +66,7 @@ ifdef CONFIG_X86_FEATURE_NAMES quiet_cmd_mkcapflags = MKCAP $@ cmd_mkcapflags = $(CONFIG_SHELL) $(srctree)/$(src)/mkcapflags.sh $< $@ -cpufeature = $(src)/../../include/asm/cpufeature.h +cpufeature = $(src)/../../include/asm/cpufeatures.h targets += capflags.c $(obj)/capflags.c: $(cpufeature) $(src)/mkcapflags.sh FORCE diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 4bf9e77f3e059..9f61518842492 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -304,7 +305,7 @@ static void amd_get_topology(struct cpuinfo_x86 *c) int cpu = smp_processor_id(); /* get information required for multi-node processors */ - if (cpu_has_topoext) { + if (boot_cpu_has(X86_FEATURE_TOPOEXT)) { u32 eax, ebx, ecx, edx; cpuid(0x8000001e, &eax, &ebx, &ecx, &edx); @@ -519,6 +520,26 @@ static void bsp_init_amd(struct cpuinfo_x86 *c) if (cpu_has(c, X86_FEATURE_MWAITX)) use_mwaitx_delay(); + + if (c->x86 >= 0x15 && c->x86 <= 0x17) { + unsigned int bit; + + switch (c->x86) { + case 0x15: bit = 54; break; + case 0x16: bit = 33; break; + case 0x17: bit = 10; break; + default: return; + } + /* + * Try to cache the base value so further operations can + * avoid RMW. If that faults, do not enable SSBD. + */ + if (!rdmsrl_safe(MSR_AMD64_LS_CFG, &x86_amd_ls_cfg_base)) { + setup_force_cpu_cap(X86_FEATURE_LS_CFG_SSBD); + setup_force_cpu_cap(X86_FEATURE_SSBD); + x86_amd_ls_cfg_ssbd_mask = 1ULL << bit; + } + } } static void early_init_amd(struct cpuinfo_x86 *c) @@ -692,6 +713,17 @@ static void init_amd_bd(struct cpuinfo_x86 *c) } } +static void init_amd_zn(struct cpuinfo_x86 *c) +{ + set_cpu_cap(c, X86_FEATURE_ZEN); + /* + * Fix erratum 1076: CPB feature bit not being set in CPUID. It affects + * all up to and including B1. + */ + if (c->x86_model <= 1 && c->x86_mask <= 1) + set_cpu_cap(c, X86_FEATURE_CPB); +} + static void init_amd(struct cpuinfo_x86 *c) { u32 dummy; @@ -722,6 +754,7 @@ static void init_amd(struct cpuinfo_x86 *c) case 0x10: init_amd_gh(c); break; case 0x12: init_amd_ln(c); break; case 0x15: init_amd_bd(c); break; + case 0x17: init_amd_zn(c); break; } /* Enable workaround for FXSAVE leak */ @@ -791,8 +824,9 @@ static void init_amd(struct cpuinfo_x86 *c) if (cpu_has(c, X86_FEATURE_3DNOW) || cpu_has(c, X86_FEATURE_LM)) set_cpu_cap(c, X86_FEATURE_3DNOWPREFETCH); - /* AMD CPUs don't reset SS attributes on SYSRET */ - set_cpu_bug(c, X86_BUG_SYSRET_SS_ATTRS); + /* AMD CPUs don't reset SS attributes on SYSRET, Xen does. */ + if (!cpu_has(c, X86_FEATURE_XENPV)) + set_cpu_bug(c, X86_BUG_SYSRET_SS_ATTRS); } #ifdef CONFIG_X86_32 @@ -954,7 +988,7 @@ static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum) void set_dr_addr_mask(unsigned long mask, int dr) { - if (!cpu_has_bpext) + if (!boot_cpu_has(X86_FEATURE_BPEXT)) return; switch (dr) { diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index 2bbc74f8a4a83..b9e6b60df148f 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -11,8 +11,10 @@ #include #include #include +#include +#include -#include +#include #include #include #include @@ -24,8 +26,31 @@ #include #include #include +#include static void __init spectre_v2_select_mitigation(void); +static void __init ssb_select_mitigation(void); +static void __init l1tf_select_mitigation(void); + +/* + * Our boot-time value of the SPEC_CTRL MSR. We read it once so that any + * writes to SPEC_CTRL contain whatever reserved bits have been set. + */ +u64 x86_spec_ctrl_base; +EXPORT_SYMBOL_GPL(x86_spec_ctrl_base); + +/* + * The vendor and possibly platform specific bits which can be modified in + * x86_spec_ctrl_base. + */ +static u64 x86_spec_ctrl_mask = SPEC_CTRL_IBRS; + +/* + * AMD specific MSR info for Speculative Store Bypass control. + * x86_amd_ls_cfg_ssbd_mask is initialized in identify_boot_cpu(). + */ +u64 x86_amd_ls_cfg_base; +u64 x86_amd_ls_cfg_ssbd_mask; void __init check_bugs(void) { @@ -36,9 +61,29 @@ void __init check_bugs(void) print_cpu_info(&boot_cpu_data); } + /* + * Read the SPEC_CTRL MSR to account for reserved bits which may + * have unknown values. AMD64_LS_CFG MSR is cached in the early AMD + * init code as it is not enumerated and depends on the family. + */ + if (boot_cpu_has(X86_FEATURE_MSR_SPEC_CTRL)) + rdmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base); + + /* Allow STIBP in MSR_SPEC_CTRL if supported */ + if (boot_cpu_has(X86_FEATURE_STIBP)) + x86_spec_ctrl_mask |= SPEC_CTRL_STIBP; + /* Select the proper spectre mitigation before patching alternatives */ spectre_v2_select_mitigation(); + /* + * Select proper mitigation for any exposure to the Speculative Store + * Bypass vulnerability. + */ + ssb_select_mitigation(); + + l1tf_select_mitigation(); + #ifdef CONFIG_X86_32 /* * Check whether we are able to run this kernel safely on SMP. @@ -94,6 +139,73 @@ static const char *spectre_v2_strings[] = { static enum spectre_v2_mitigation spectre_v2_enabled = SPECTRE_V2_NONE; +void +x86_virt_spec_ctrl(u64 guest_spec_ctrl, u64 guest_virt_spec_ctrl, bool setguest) +{ + u64 msrval, guestval, hostval = x86_spec_ctrl_base; + struct thread_info *ti = current_thread_info(); + + /* Is MSR_SPEC_CTRL implemented ? */ + if (static_cpu_has(X86_FEATURE_MSR_SPEC_CTRL)) { + /* + * Restrict guest_spec_ctrl to supported values. Clear the + * modifiable bits in the host base value and or the + * modifiable bits from the guest value. + */ + guestval = hostval & ~x86_spec_ctrl_mask; + guestval |= guest_spec_ctrl & x86_spec_ctrl_mask; + + /* SSBD controlled in MSR_SPEC_CTRL */ + if (static_cpu_has(X86_FEATURE_SPEC_CTRL_SSBD)) + hostval |= ssbd_tif_to_spec_ctrl(ti->flags); + + if (hostval != guestval) { + msrval = setguest ? guestval : hostval; + wrmsrl(MSR_IA32_SPEC_CTRL, msrval); + } + } + + /* + * If SSBD is not handled in MSR_SPEC_CTRL on AMD, update + * MSR_AMD64_L2_CFG or MSR_VIRT_SPEC_CTRL if supported. + */ + if (!static_cpu_has(X86_FEATURE_LS_CFG_SSBD) && + !static_cpu_has(X86_FEATURE_VIRT_SSBD)) + return; + + /* + * If the host has SSBD mitigation enabled, force it in the host's + * virtual MSR value. If its not permanently enabled, evaluate + * current's TIF_SSBD thread flag. + */ + if (static_cpu_has(X86_FEATURE_SPEC_STORE_BYPASS_DISABLE)) + hostval = SPEC_CTRL_SSBD; + else + hostval = ssbd_tif_to_spec_ctrl(ti->flags); + + /* Sanitize the guest value */ + guestval = guest_virt_spec_ctrl & SPEC_CTRL_SSBD; + + if (hostval != guestval) { + unsigned long tif; + + tif = setguest ? ssbd_spec_ctrl_to_tif(guestval) : + ssbd_spec_ctrl_to_tif(hostval); + + speculative_store_bypass_update(tif); + } +} +EXPORT_SYMBOL_GPL(x86_virt_spec_ctrl); + +static void x86_amd_ssb_disable(void) +{ + u64 msrval = x86_amd_ls_cfg_base | x86_amd_ls_cfg_ssbd_mask; + + if (boot_cpu_has(X86_FEATURE_VIRT_SSBD)) + wrmsrl(MSR_AMD64_VIRT_SPEC_CTRL, SPEC_CTRL_SSBD); + else if (boot_cpu_has(X86_FEATURE_LS_CFG_SSBD)) + wrmsrl(MSR_AMD64_LS_CFG, msrval); +} #ifdef RETPOLINE static bool spectre_v2_bad_module; @@ -162,8 +274,7 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void) if (cmdline_find_option_bool(boot_command_line, "nospectre_v2")) return SPECTRE_V2_CMD_NONE; else { - ret = cmdline_find_option(boot_command_line, "spectre_v2", arg, - sizeof(arg)); + ret = cmdline_find_option(boot_command_line, "spectre_v2", arg, sizeof(arg)); if (ret < 0) return SPECTRE_V2_CMD_AUTO; @@ -184,8 +295,7 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void) cmd == SPECTRE_V2_CMD_RETPOLINE_AMD || cmd == SPECTRE_V2_CMD_RETPOLINE_GENERIC) && !IS_ENABLED(CONFIG_RETPOLINE)) { - pr_err("%s selected but not compiled in. Switching to AUTO select\n", - mitigation_options[i].option); + pr_err("%s selected but not compiled in. Switching to AUTO select\n", mitigation_options[i].option); return SPECTRE_V2_CMD_AUTO; } @@ -203,23 +313,6 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void) return cmd; } -/* Check for Skylake-like CPUs (for RSB handling) */ -static bool __init is_skylake_era(void) -{ - if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && - boot_cpu_data.x86 == 6) { - switch (boot_cpu_data.x86_model) { - case INTEL_FAM6_SKYLAKE_MOBILE: - case INTEL_FAM6_SKYLAKE_DESKTOP: - case INTEL_FAM6_SKYLAKE_X: - case INTEL_FAM6_KABYLAKE_MOBILE: - case INTEL_FAM6_KABYLAKE_DESKTOP: - return true; - } - } - return false; -} - static void __init spectre_v2_select_mitigation(void) { enum spectre_v2_mitigation_cmd cmd = spectre_v2_parse_cmdline(); @@ -255,14 +348,14 @@ static void __init spectre_v2_select_mitigation(void) goto retpoline_auto; break; } - pr_err("kernel not compiled with retpoline; no mitigation available!"); + pr_err("Spectre mitigation: kernel not compiled with retpoline; no mitigation available!"); return; retpoline_auto: if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) { retpoline_amd: if (!boot_cpu_has(X86_FEATURE_LFENCE_RDTSC)) { - pr_err("LFENCE not serializing. Switching to generic retpoline\n"); + pr_err("Spectre mitigation: LFENCE not serializing, switching to generic retpoline\n"); goto retpoline_generic; } mode = retp_compiler() ? SPECTRE_V2_RETPOLINE_AMD : @@ -280,52 +373,359 @@ static void __init spectre_v2_select_mitigation(void) pr_info("%s\n", spectre_v2_strings[mode]); /* - * If neither SMEP or KPTI are available, there is a risk of - * hitting userspace addresses in the RSB after a context switch - * from a shallow call stack to a deeper one. To prevent this fill - * the entire RSB, even when using IBRS. + * If spectre v2 protection has been enabled, unconditionally fill + * RSB during a context switch; this protects against two independent + * issues: * - * Skylake era CPUs have a separate issue with *underflow* of the - * RSB, when they will predict 'ret' targets from the generic BTB. - * The proper mitigation for this is IBRS. If IBRS is not supported - * or deactivated in favour of retpolines the RSB fill on context - * switch is required. + * - RSB underflow (and switch to BTB) on Skylake+ + * - SpectreRSB variant of spectre v2 on X86_BUG_SPECTRE_V2 CPUs */ - if ((!boot_cpu_has(X86_FEATURE_KAISER) && - !boot_cpu_has(X86_FEATURE_SMEP)) || is_skylake_era()) { - setup_force_cpu_cap(X86_FEATURE_RSB_CTXSW); - pr_info("Filling RSB on context switch\n"); + setup_force_cpu_cap(X86_FEATURE_RSB_CTXSW); + pr_info("Spectre v2 / SpectreRSB mitigation: Filling RSB on context switch\n"); + + /* Initialize Indirect Branch Prediction Barrier if supported */ + if (boot_cpu_has(X86_FEATURE_IBPB)) { + setup_force_cpu_cap(X86_FEATURE_USE_IBPB); + pr_info("Spectre v2 mitigation: Enabling Indirect Branch Prediction Barrier\n"); + } + + /* + * Retpoline means the kernel is safe because it has no indirect + * branches. But firmware isn't, so use IBRS to protect that. + */ + if (boot_cpu_has(X86_FEATURE_IBRS)) { + setup_force_cpu_cap(X86_FEATURE_USE_IBRS_FW); + pr_info("Enabling Restricted Speculation for firmware calls\n"); } } +#undef pr_fmt +#define pr_fmt(fmt) "Speculative Store Bypass: " fmt + +static enum ssb_mitigation ssb_mode = SPEC_STORE_BYPASS_NONE; + +/* The kernel command line selection */ +enum ssb_mitigation_cmd { + SPEC_STORE_BYPASS_CMD_NONE, + SPEC_STORE_BYPASS_CMD_AUTO, + SPEC_STORE_BYPASS_CMD_ON, + SPEC_STORE_BYPASS_CMD_PRCTL, + SPEC_STORE_BYPASS_CMD_SECCOMP, +}; + +static const char *ssb_strings[] = { + [SPEC_STORE_BYPASS_NONE] = "Vulnerable", + [SPEC_STORE_BYPASS_DISABLE] = "Mitigation: Speculative Store Bypass disabled", + [SPEC_STORE_BYPASS_PRCTL] = "Mitigation: Speculative Store Bypass disabled via prctl", + [SPEC_STORE_BYPASS_SECCOMP] = "Mitigation: Speculative Store Bypass disabled via prctl and seccomp", +}; + +static const struct { + const char *option; + enum ssb_mitigation_cmd cmd; +} ssb_mitigation_options[] = { + { "auto", SPEC_STORE_BYPASS_CMD_AUTO }, /* Platform decides */ + { "on", SPEC_STORE_BYPASS_CMD_ON }, /* Disable Speculative Store Bypass */ + { "off", SPEC_STORE_BYPASS_CMD_NONE }, /* Don't touch Speculative Store Bypass */ + { "prctl", SPEC_STORE_BYPASS_CMD_PRCTL }, /* Disable Speculative Store Bypass via prctl */ + { "seccomp", SPEC_STORE_BYPASS_CMD_SECCOMP }, /* Disable Speculative Store Bypass via prctl and seccomp */ +}; + +static enum ssb_mitigation_cmd __init ssb_parse_cmdline(void) +{ + enum ssb_mitigation_cmd cmd = SPEC_STORE_BYPASS_CMD_AUTO; + char arg[20]; + int ret, i; + + if (cmdline_find_option_bool(boot_command_line, "nospec_store_bypass_disable")) { + return SPEC_STORE_BYPASS_CMD_NONE; + } else { + ret = cmdline_find_option(boot_command_line, "spec_store_bypass_disable", + arg, sizeof(arg)); + if (ret < 0) + return SPEC_STORE_BYPASS_CMD_AUTO; + + for (i = 0; i < ARRAY_SIZE(ssb_mitigation_options); i++) { + if (!match_option(arg, ret, ssb_mitigation_options[i].option)) + continue; + + cmd = ssb_mitigation_options[i].cmd; + break; + } + + if (i >= ARRAY_SIZE(ssb_mitigation_options)) { + pr_err("unknown option (%s). Switching to AUTO select\n", arg); + return SPEC_STORE_BYPASS_CMD_AUTO; + } + } + + return cmd; +} + +static enum ssb_mitigation __init __ssb_select_mitigation(void) +{ + enum ssb_mitigation mode = SPEC_STORE_BYPASS_NONE; + enum ssb_mitigation_cmd cmd; + + if (!boot_cpu_has(X86_FEATURE_SSBD)) + return mode; + + cmd = ssb_parse_cmdline(); + if (!boot_cpu_has_bug(X86_BUG_SPEC_STORE_BYPASS) && + (cmd == SPEC_STORE_BYPASS_CMD_NONE || + cmd == SPEC_STORE_BYPASS_CMD_AUTO)) + return mode; + + switch (cmd) { + case SPEC_STORE_BYPASS_CMD_AUTO: + case SPEC_STORE_BYPASS_CMD_SECCOMP: + /* + * Choose prctl+seccomp as the default mode if seccomp is + * enabled. + */ + if (IS_ENABLED(CONFIG_SECCOMP)) + mode = SPEC_STORE_BYPASS_SECCOMP; + else + mode = SPEC_STORE_BYPASS_PRCTL; + break; + case SPEC_STORE_BYPASS_CMD_ON: + mode = SPEC_STORE_BYPASS_DISABLE; + break; + case SPEC_STORE_BYPASS_CMD_PRCTL: + mode = SPEC_STORE_BYPASS_PRCTL; + break; + case SPEC_STORE_BYPASS_CMD_NONE: + break; + } + + /* + * We have three CPU feature flags that are in play here: + * - X86_BUG_SPEC_STORE_BYPASS - CPU is susceptible. + * - X86_FEATURE_SSBD - CPU is able to turn off speculative store bypass + * - X86_FEATURE_SPEC_STORE_BYPASS_DISABLE - engage the mitigation + */ + if (mode == SPEC_STORE_BYPASS_DISABLE) { + setup_force_cpu_cap(X86_FEATURE_SPEC_STORE_BYPASS_DISABLE); + /* + * Intel uses the SPEC CTRL MSR Bit(2) for this, while AMD uses + * a completely different MSR and bit dependent on family. + */ + switch (boot_cpu_data.x86_vendor) { + case X86_VENDOR_INTEL: + x86_spec_ctrl_base |= SPEC_CTRL_SSBD; + x86_spec_ctrl_mask |= SPEC_CTRL_SSBD; + wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base); + break; + case X86_VENDOR_AMD: + x86_amd_ssb_disable(); + break; + } + } + + return mode; +} + +static void ssb_select_mitigation(void) +{ + ssb_mode = __ssb_select_mitigation(); + + if (boot_cpu_has_bug(X86_BUG_SPEC_STORE_BYPASS)) + pr_info("%s\n", ssb_strings[ssb_mode]); +} + +#undef pr_fmt +#define pr_fmt(fmt) "Speculation prctl: " fmt + +static int ssb_prctl_set(struct task_struct *task, unsigned long ctrl) +{ + bool update; + + if (ssb_mode != SPEC_STORE_BYPASS_PRCTL && + ssb_mode != SPEC_STORE_BYPASS_SECCOMP) + return -ENXIO; + + switch (ctrl) { + case PR_SPEC_ENABLE: + /* If speculation is force disabled, enable is not allowed */ + if (task_spec_ssb_force_disable(task)) + return -EPERM; + task_clear_spec_ssb_disable(task); + update = test_and_clear_tsk_thread_flag(task, TIF_SSBD); + break; + case PR_SPEC_DISABLE: + task_set_spec_ssb_disable(task); + update = !test_and_set_tsk_thread_flag(task, TIF_SSBD); + break; + case PR_SPEC_FORCE_DISABLE: + task_set_spec_ssb_disable(task); + task_set_spec_ssb_force_disable(task); + update = !test_and_set_tsk_thread_flag(task, TIF_SSBD); + break; + default: + return -ERANGE; + } + + /* + * If being set on non-current task, delay setting the CPU + * mitigation until it is next scheduled. + */ + if (task == current && update) + speculative_store_bypass_update_current(); + + return 0; +} + +int arch_prctl_spec_ctrl_set(struct task_struct *task, unsigned long which, + unsigned long ctrl) +{ + switch (which) { + case PR_SPEC_STORE_BYPASS: + return ssb_prctl_set(task, ctrl); + default: + return -ENODEV; + } +} + +#ifdef CONFIG_SECCOMP +void arch_seccomp_spec_mitigate(struct task_struct *task) +{ + if (ssb_mode == SPEC_STORE_BYPASS_SECCOMP) + ssb_prctl_set(task, PR_SPEC_FORCE_DISABLE); +} +#endif + +static int ssb_prctl_get(struct task_struct *task) +{ + switch (ssb_mode) { + case SPEC_STORE_BYPASS_DISABLE: + return PR_SPEC_DISABLE; + case SPEC_STORE_BYPASS_SECCOMP: + case SPEC_STORE_BYPASS_PRCTL: + if (task_spec_ssb_force_disable(task)) + return PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE; + if (task_spec_ssb_disable(task)) + return PR_SPEC_PRCTL | PR_SPEC_DISABLE; + return PR_SPEC_PRCTL | PR_SPEC_ENABLE; + default: + if (boot_cpu_has_bug(X86_BUG_SPEC_STORE_BYPASS)) + return PR_SPEC_ENABLE; + return PR_SPEC_NOT_AFFECTED; + } +} + +int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which) +{ + switch (which) { + case PR_SPEC_STORE_BYPASS: + return ssb_prctl_get(task); + default: + return -ENODEV; + } +} + +void x86_spec_ctrl_setup_ap(void) +{ + if (boot_cpu_has(X86_FEATURE_MSR_SPEC_CTRL)) + wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base); + + if (ssb_mode == SPEC_STORE_BYPASS_DISABLE) + x86_amd_ssb_disable(); +} + +#undef pr_fmt +#define pr_fmt(fmt) "L1TF: " fmt +static void __init l1tf_select_mitigation(void) +{ + u64 half_pa; + + if (!boot_cpu_has_bug(X86_BUG_L1TF)) + return; + +#if CONFIG_PGTABLE_LEVELS == 2 + pr_warn("Kernel not compiled for PAE. No mitigation for L1TF\n"); + return; +#endif + + /* + * This is extremely unlikely to happen because almost all + * systems have far more MAX_PA/2 than RAM can be fit into + * DIMM slots. + */ + half_pa = (u64)l1tf_pfn_limit() << PAGE_SHIFT; + if (e820_any_mapped(half_pa, ULLONG_MAX - half_pa, E820_RAM)) { + pr_warn("System has more than MAX_PA/2 memory. L1TF mitigation not effective.\n"); + pr_info("You may make it effective by booting the kernel with mem=%llu parameter.\n", + half_pa); + pr_info("However, doing so will make a part of your RAM unusable.\n"); + pr_info("Reading https://www.kernel.org/doc/html/latest/admin-guide/l1tf.html might help you decide.\n"); + return; + } + + setup_force_cpu_cap(X86_FEATURE_L1TF_PTEINV); +} #undef pr_fmt #ifdef CONFIG_SYSFS -ssize_t cpu_show_meltdown(struct device *dev, - struct device_attribute *attr, char *buf) + +static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr, + char *buf, unsigned int bug) { - if (!boot_cpu_has_bug(X86_BUG_CPU_MELTDOWN)) + if (!boot_cpu_has_bug(bug)) return sprintf(buf, "Not affected\n"); - if (boot_cpu_has(X86_FEATURE_KAISER)) - return sprintf(buf, "Mitigation: PTI\n"); + + switch (bug) { + case X86_BUG_CPU_MELTDOWN: + if (boot_cpu_has(X86_FEATURE_KAISER)) + return sprintf(buf, "Mitigation: PTI\n"); + + break; + + case X86_BUG_SPECTRE_V1: + return sprintf(buf, "Mitigation: __user pointer sanitization\n"); + + case X86_BUG_SPECTRE_V2: + return sprintf(buf, "%s%s%s%s\n", spectre_v2_strings[spectre_v2_enabled], + boot_cpu_has(X86_FEATURE_USE_IBPB) ? ", IBPB" : "", + boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? ", IBRS_FW" : "", + spectre_v2_module_string()); + + case X86_BUG_SPEC_STORE_BYPASS: + return sprintf(buf, "%s\n", ssb_strings[ssb_mode]); + + case X86_BUG_L1TF: + if (boot_cpu_has(X86_FEATURE_L1TF_PTEINV)) + return sprintf(buf, "Mitigation: Page Table Inversion\n"); + break; + + default: + break; + } + return sprintf(buf, "Vulnerable\n"); } -ssize_t cpu_show_spectre_v1(struct device *dev, - struct device_attribute *attr, char *buf) +ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr, char *buf) { - if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V1)) - return sprintf(buf, "Not affected\n"); - return sprintf(buf, "Mitigation: __user pointer sanitization\n"); + return cpu_show_common(dev, attr, buf, X86_BUG_CPU_MELTDOWN); } -ssize_t cpu_show_spectre_v2(struct device *dev, - struct device_attribute *attr, char *buf) +ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr, char *buf) { - if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V2)) - return sprintf(buf, "Not affected\n"); + return cpu_show_common(dev, attr, buf, X86_BUG_SPECTRE_V1); +} + +ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr, char *buf) +{ + return cpu_show_common(dev, attr, buf, X86_BUG_SPECTRE_V2); +} - return sprintf(buf, "%s%s\n", spectre_v2_strings[spectre_v2_enabled], - spectre_v2_module_string()); +ssize_t cpu_show_spec_store_bypass(struct device *dev, struct device_attribute *attr, char *buf) +{ + return cpu_show_common(dev, attr, buf, X86_BUG_SPEC_STORE_BYPASS); +} + +ssize_t cpu_show_l1tf(struct device *dev, struct device_attribute *attr, char *buf) +{ + return cpu_show_common(dev, attr, buf, X86_BUG_L1TF); } #endif diff --git a/arch/x86/kernel/cpu/centaur.c b/arch/x86/kernel/cpu/centaur.c index d8fba5c15fbd8..6608c03c21267 100644 --- a/arch/x86/kernel/cpu/centaur.c +++ b/arch/x86/kernel/cpu/centaur.c @@ -1,7 +1,7 @@ #include #include -#include +#include #include #include #include @@ -43,7 +43,7 @@ static void init_c3(struct cpuinfo_x86 *c) /* store Centaur Extended Feature Flags as * word 5 of the CPU capability bit array */ - c->x86_capability[5] = cpuid_edx(0xC0000001); + c->x86_capability[CPUID_C000_0001_EDX] = cpuid_edx(0xC0000001); } #ifdef CONFIG_X86_32 /* Cyrix III family needs CX8 & PGE explicitly enabled. */ diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 8eabbafff2133..4d3fa79c0f09f 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -43,6 +43,8 @@ #include #include #include +#include +#include #ifdef CONFIG_X86_LOCAL_APIC #include @@ -674,52 +676,86 @@ static void apply_forced_caps(struct cpuinfo_x86 *c) } } +static void init_speculation_control(struct cpuinfo_x86 *c) +{ + /* + * The Intel SPEC_CTRL CPUID bit implies IBRS and IBPB support, + * and they also have a different bit for STIBP support. Also, + * a hypervisor might have set the individual AMD bits even on + * Intel CPUs, for finer-grained selection of what's available. + */ + if (cpu_has(c, X86_FEATURE_SPEC_CTRL)) { + set_cpu_cap(c, X86_FEATURE_IBRS); + set_cpu_cap(c, X86_FEATURE_IBPB); + set_cpu_cap(c, X86_FEATURE_MSR_SPEC_CTRL); + } + + if (cpu_has(c, X86_FEATURE_INTEL_STIBP)) + set_cpu_cap(c, X86_FEATURE_STIBP); + + if (cpu_has(c, X86_FEATURE_SPEC_CTRL_SSBD)) + set_cpu_cap(c, X86_FEATURE_SSBD); + + if (cpu_has(c, X86_FEATURE_AMD_IBRS)) { + set_cpu_cap(c, X86_FEATURE_IBRS); + set_cpu_cap(c, X86_FEATURE_MSR_SPEC_CTRL); + } + + if (cpu_has(c, X86_FEATURE_AMD_IBPB)) + set_cpu_cap(c, X86_FEATURE_IBPB); + + if (cpu_has(c, X86_FEATURE_AMD_STIBP)) { + set_cpu_cap(c, X86_FEATURE_STIBP); + set_cpu_cap(c, X86_FEATURE_MSR_SPEC_CTRL); + } +} + void get_cpu_cap(struct cpuinfo_x86 *c) { - u32 tfms, xlvl; - u32 ebx; + u32 eax, ebx, ecx, edx; /* Intel-defined flags: level 0x00000001 */ if (c->cpuid_level >= 0x00000001) { - u32 capability, excap; + cpuid(0x00000001, &eax, &ebx, &ecx, &edx); - cpuid(0x00000001, &tfms, &ebx, &excap, &capability); - c->x86_capability[0] = capability; - c->x86_capability[4] = excap; + c->x86_capability[CPUID_1_ECX] = ecx; + c->x86_capability[CPUID_1_EDX] = edx; } + /* Thermal and Power Management Leaf: level 0x00000006 (eax) */ + if (c->cpuid_level >= 0x00000006) + c->x86_capability[CPUID_6_EAX] = cpuid_eax(0x00000006); + /* Additional Intel-defined flags: level 0x00000007 */ if (c->cpuid_level >= 0x00000007) { - u32 eax, ebx, ecx, edx; - cpuid_count(0x00000007, 0, &eax, &ebx, &ecx, &edx); - - c->x86_capability[9] = ebx; + c->x86_capability[CPUID_7_0_EBX] = ebx; + c->x86_capability[CPUID_7_ECX] = ecx; + c->x86_capability[CPUID_7_EDX] = edx; } /* Extended state features: level 0x0000000d */ if (c->cpuid_level >= 0x0000000d) { - u32 eax, ebx, ecx, edx; - cpuid_count(0x0000000d, 1, &eax, &ebx, &ecx, &edx); - c->x86_capability[10] = eax; + c->x86_capability[CPUID_D_1_EAX] = eax; } /* Additional Intel-defined flags: level 0x0000000F */ if (c->cpuid_level >= 0x0000000F) { - u32 eax, ebx, ecx, edx; /* QoS sub-leaf, EAX=0Fh, ECX=0 */ cpuid_count(0x0000000F, 0, &eax, &ebx, &ecx, &edx); - c->x86_capability[11] = edx; + c->x86_capability[CPUID_F_0_EDX] = edx; + if (cpu_has(c, X86_FEATURE_CQM_LLC)) { /* will be overridden if occupancy monitoring exists */ c->x86_cache_max_rmid = ebx; /* QoS sub-leaf, EAX=0Fh, ECX=1 */ cpuid_count(0x0000000F, 1, &eax, &ebx, &ecx, &edx); - c->x86_capability[12] = edx; + c->x86_capability[CPUID_F_1_EDX] = edx; + if (cpu_has(c, X86_FEATURE_CQM_OCCUP_LLC)) { c->x86_cache_max_rmid = ecx; c->x86_cache_occ_scale = ebx; @@ -731,32 +767,49 @@ void get_cpu_cap(struct cpuinfo_x86 *c) } /* AMD-defined flags: level 0x80000001 */ - xlvl = cpuid_eax(0x80000000); - c->extended_cpuid_level = xlvl; + eax = cpuid_eax(0x80000000); + c->extended_cpuid_level = eax; - if ((xlvl & 0xffff0000) == 0x80000000) { - if (xlvl >= 0x80000001) { - c->x86_capability[1] = cpuid_edx(0x80000001); - c->x86_capability[6] = cpuid_ecx(0x80000001); + if ((eax & 0xffff0000) == 0x80000000) { + if (eax >= 0x80000001) { + cpuid(0x80000001, &eax, &ebx, &ecx, &edx); + + c->x86_capability[CPUID_8000_0001_ECX] = ecx; + c->x86_capability[CPUID_8000_0001_EDX] = edx; } } + if (c->extended_cpuid_level >= 0x80000007) { + cpuid(0x80000007, &eax, &ebx, &ecx, &edx); + + c->x86_capability[CPUID_8000_0007_EBX] = ebx; + c->x86_power = edx; + } + if (c->extended_cpuid_level >= 0x80000008) { - u32 eax = cpuid_eax(0x80000008); + cpuid(0x80000008, &eax, &ebx, &ecx, &edx); c->x86_virt_bits = (eax >> 8) & 0xff; c->x86_phys_bits = eax & 0xff; - c->x86_capability[13] = cpuid_ebx(0x80000008); + c->x86_capability[CPUID_8000_0008_EBX] = ebx; } #ifdef CONFIG_X86_32 else if (cpu_has(c, X86_FEATURE_PAE) || cpu_has(c, X86_FEATURE_PSE36)) c->x86_phys_bits = 36; #endif - if (c->extended_cpuid_level >= 0x80000007) - c->x86_power = cpuid_edx(0x80000007); + if (c->extended_cpuid_level >= 0x8000000a) + c->x86_capability[CPUID_8000_000A_EDX] = cpuid_edx(0x8000000a); init_scattered_cpuid_features(c); + init_speculation_control(c); + + /* + * Clear/Set all flags overridden by options, after probe. + * This needs to happen each time we re-probe, which may happen + * several times during CPU initialization. + */ + apply_forced_caps(c); } static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c) @@ -785,6 +838,95 @@ static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c) #endif } +static const __initconst struct x86_cpu_id cpu_no_speculation[] = { + { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_CEDARVIEW, X86_FEATURE_ANY }, + { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_CLOVERVIEW, X86_FEATURE_ANY }, + { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_LINCROFT, X86_FEATURE_ANY }, + { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_PENWELL, X86_FEATURE_ANY }, + { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_PINEVIEW, X86_FEATURE_ANY }, + { X86_VENDOR_CENTAUR, 5 }, + { X86_VENDOR_INTEL, 5 }, + { X86_VENDOR_NSC, 5 }, + { X86_VENDOR_ANY, 4 }, + {} +}; + +static const __initconst struct x86_cpu_id cpu_no_meltdown[] = { + { X86_VENDOR_AMD }, + {} +}; + +static const __initconst struct x86_cpu_id cpu_no_spec_store_bypass[] = { + { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_PINEVIEW }, + { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_LINCROFT }, + { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_PENWELL }, + { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_CLOVERVIEW }, + { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_CEDARVIEW }, + { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SILVERMONT1 }, + { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_AIRMONT }, + { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SILVERMONT2 }, + { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_MERRIFIELD }, + { X86_VENDOR_INTEL, 6, INTEL_FAM6_CORE_YONAH }, + { X86_VENDOR_INTEL, 6, INTEL_FAM6_XEON_PHI_KNL }, + { X86_VENDOR_INTEL, 6, INTEL_FAM6_XEON_PHI_KNM }, + { X86_VENDOR_CENTAUR, 5, }, + { X86_VENDOR_INTEL, 5, }, + { X86_VENDOR_NSC, 5, }, + { X86_VENDOR_AMD, 0x12, }, + { X86_VENDOR_AMD, 0x11, }, + { X86_VENDOR_AMD, 0x10, }, + { X86_VENDOR_AMD, 0xf, }, + { X86_VENDOR_ANY, 4, }, + {} +}; + +static const __initconst struct x86_cpu_id cpu_no_l1tf[] = { + /* in addition to cpu_no_speculation */ + { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SILVERMONT1 }, + { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SILVERMONT2 }, + { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_AIRMONT }, + { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_MERRIFIELD }, + { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_MOOREFIELD }, + { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_GOLDMONT }, + { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_DENVERTON }, + { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_GEMINI_LAKE }, + { X86_VENDOR_INTEL, 6, INTEL_FAM6_XEON_PHI_KNL }, + { X86_VENDOR_INTEL, 6, INTEL_FAM6_XEON_PHI_KNM }, + {} +}; + +static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) +{ + u64 ia32_cap = 0; + + if (cpu_has(c, X86_FEATURE_ARCH_CAPABILITIES)) + rdmsrl(MSR_IA32_ARCH_CAPABILITIES, ia32_cap); + + if (!x86_match_cpu(cpu_no_spec_store_bypass) && + !(ia32_cap & ARCH_CAP_SSB_NO)) + setup_force_cpu_bug(X86_BUG_SPEC_STORE_BYPASS); + + if (x86_match_cpu(cpu_no_speculation)) + return; + + setup_force_cpu_bug(X86_BUG_SPECTRE_V1); + setup_force_cpu_bug(X86_BUG_SPECTRE_V2); + + if (x86_match_cpu(cpu_no_meltdown)) + return; + + /* Rogue Data Cache Load? No! */ + if (ia32_cap & ARCH_CAP_RDCL_NO) + return; + + setup_force_cpu_bug(X86_BUG_CPU_MELTDOWN); + + if (x86_match_cpu(cpu_no_l1tf)) + return; + + setup_force_cpu_bug(X86_BUG_L1TF); +} + /* * Do minimum CPU detection early. * Fields really needed: vendor, cpuid_level, family, model, mask, @@ -831,11 +973,7 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c) setup_force_cpu_cap(X86_FEATURE_ALWAYS); - if (c->x86_vendor != X86_VENDOR_AMD) - setup_force_cpu_bug(X86_BUG_CPU_MELTDOWN); - - setup_force_cpu_bug(X86_BUG_SPECTRE_V1); - setup_force_cpu_bug(X86_BUG_SPECTRE_V2); + cpu_set_bug_bits(c); fpu__init_system(c); @@ -1124,6 +1262,7 @@ void identify_secondary_cpu(struct cpuinfo_x86 *c) enable_sep_cpu(); #endif mtrr_ap_init(); + x86_spec_ctrl_setup_ap(); } struct msr_range { @@ -1539,7 +1678,9 @@ void cpu_init(void) printk(KERN_INFO "Initializing CPU#%d\n", cpu); - if (cpu_feature_enabled(X86_FEATURE_VME) || cpu_has_tsc || cpu_has_de) + if (cpu_feature_enabled(X86_FEATURE_VME) || + cpu_has_tsc || + boot_cpu_has(X86_FEATURE_DE)) cr4_clear_bits(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE); load_current_idt(); @@ -1572,20 +1713,6 @@ void cpu_init(void) } #endif -#ifdef CONFIG_X86_DEBUG_STATIC_CPU_HAS -void warn_pre_alternatives(void) -{ - WARN(1, "You're using static_cpu_has before alternatives have run!\n"); -} -EXPORT_SYMBOL_GPL(warn_pre_alternatives); -#endif - -inline bool __static_cpu_has_safe(u16 bit) -{ - return boot_cpu_has(bit); -} -EXPORT_SYMBOL_GPL(__static_cpu_has_safe); - static void bsp_resume(void) { if (this_cpu->c_bsp_resume) diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h index 2584265d47455..3b19d82f7932c 100644 --- a/arch/x86/kernel/cpu/cpu.h +++ b/arch/x86/kernel/cpu/cpu.h @@ -46,4 +46,7 @@ extern const struct cpu_dev *const __x86_cpu_dev_start[], extern void get_cpu_cap(struct cpuinfo_x86 *c); extern void cpu_detect_cache_sizes(struct cpuinfo_x86 *c); + +extern void x86_spec_ctrl_setup_ap(void); + #endif /* ARCH_X86_CPU_H */ diff --git a/arch/x86/kernel/cpu/cyrix.c b/arch/x86/kernel/cpu/cyrix.c index aaf152e796373..15e47c1cd4126 100644 --- a/arch/x86/kernel/cpu/cyrix.c +++ b/arch/x86/kernel/cpu/cyrix.c @@ -8,6 +8,7 @@ #include #include #include +#include #include "cpu.h" diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 209ac1e7d1f03..b18fe3d245fed 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -8,11 +8,12 @@ #include #include -#include +#include #include #include #include #include +#include #ifdef CONFIG_X86_64 #include @@ -25,6 +26,65 @@ #include #endif +/* + * Early microcode releases for the Spectre v2 mitigation were broken. + * Information taken from; + * - https://newsroom.intel.com/wp-content/uploads/sites/11/2018/03/microcode-update-guidance.pdf + * - https://kb.vmware.com/s/article/52345 + * - Microcode revisions observed in the wild + * - Release note from 20180108 microcode release + */ +struct sku_microcode { + u8 model; + u8 stepping; + u32 microcode; +}; +static const struct sku_microcode spectre_bad_microcodes[] = { + { INTEL_FAM6_KABYLAKE_DESKTOP, 0x0B, 0x80 }, + { INTEL_FAM6_KABYLAKE_DESKTOP, 0x0A, 0x80 }, + { INTEL_FAM6_KABYLAKE_DESKTOP, 0x09, 0x80 }, + { INTEL_FAM6_KABYLAKE_MOBILE, 0x0A, 0x80 }, + { INTEL_FAM6_KABYLAKE_MOBILE, 0x09, 0x80 }, + { INTEL_FAM6_SKYLAKE_X, 0x03, 0x0100013e }, + { INTEL_FAM6_SKYLAKE_X, 0x04, 0x0200003c }, + { INTEL_FAM6_BROADWELL_CORE, 0x04, 0x28 }, + { INTEL_FAM6_BROADWELL_GT3E, 0x01, 0x1b }, + { INTEL_FAM6_BROADWELL_XEON_D, 0x02, 0x14 }, + { INTEL_FAM6_BROADWELL_XEON_D, 0x03, 0x07000011 }, + { INTEL_FAM6_BROADWELL_X, 0x01, 0x0b000025 }, + { INTEL_FAM6_HASWELL_ULT, 0x01, 0x21 }, + { INTEL_FAM6_HASWELL_GT3E, 0x01, 0x18 }, + { INTEL_FAM6_HASWELL_CORE, 0x03, 0x23 }, + { INTEL_FAM6_HASWELL_X, 0x02, 0x3b }, + { INTEL_FAM6_HASWELL_X, 0x04, 0x10 }, + { INTEL_FAM6_IVYBRIDGE_X, 0x04, 0x42a }, + /* Observed in the wild */ + { INTEL_FAM6_SANDYBRIDGE_X, 0x06, 0x61b }, + { INTEL_FAM6_SANDYBRIDGE_X, 0x07, 0x712 }, +}; + +static bool bad_spectre_microcode(struct cpuinfo_x86 *c) +{ + int i; + + /* + * We know that the hypervisor lie to us on the microcode version so + * we may as well hope that it is running the correct version. + */ + if (cpu_has(c, X86_FEATURE_HYPERVISOR)) + return false; + + if (c->x86 != 6) + return false; + + for (i = 0; i < ARRAY_SIZE(spectre_bad_microcodes); i++) { + if (c->x86_model == spectre_bad_microcodes[i].model && + c->x86_mask == spectre_bad_microcodes[i].stepping) + return (c->microcode <= spectre_bad_microcodes[i].microcode); + } + return false; +} + static void early_init_intel(struct cpuinfo_x86 *c) { u64 misc_enable; @@ -51,6 +111,22 @@ static void early_init_intel(struct cpuinfo_x86 *c) rdmsr(MSR_IA32_UCODE_REV, lower_word, c->microcode); } + /* Now if any of them are set, check the blacklist and clear the lot */ + if ((cpu_has(c, X86_FEATURE_SPEC_CTRL) || + cpu_has(c, X86_FEATURE_INTEL_STIBP) || + cpu_has(c, X86_FEATURE_IBRS) || cpu_has(c, X86_FEATURE_IBPB) || + cpu_has(c, X86_FEATURE_STIBP)) && bad_spectre_microcode(c)) { + pr_warn("Intel Spectre v2 broken microcode detected; disabling Speculation Control\n"); + setup_clear_cpu_cap(X86_FEATURE_IBRS); + setup_clear_cpu_cap(X86_FEATURE_IBPB); + setup_clear_cpu_cap(X86_FEATURE_STIBP); + setup_clear_cpu_cap(X86_FEATURE_SPEC_CTRL); + setup_clear_cpu_cap(X86_FEATURE_MSR_SPEC_CTRL); + setup_clear_cpu_cap(X86_FEATURE_INTEL_STIBP); + setup_clear_cpu_cap(X86_FEATURE_SSBD); + setup_clear_cpu_cap(X86_FEATURE_SPEC_CTRL_SSBD); + } + /* * Atom erratum AAE44/AAF40/AAG38/AAH41: * @@ -445,7 +521,8 @@ static void init_intel(struct cpuinfo_x86 *c) if (cpu_has_xmm2) set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC); - if (cpu_has_ds) { + + if (boot_cpu_has(X86_FEATURE_DS)) { unsigned int l1; rdmsr(MSR_IA32_MISC_ENABLE, l1, l2); if (!(l1 & (1<<11))) diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c index b4ca91cf55b0d..3557b3ceab147 100644 --- a/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include @@ -591,7 +591,7 @@ cpuid4_cache_lookup_regs(int index, struct _cpuid4_info_regs *this_leaf) unsigned edx; if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) { - if (cpu_has_topoext) + if (boot_cpu_has(X86_FEATURE_TOPOEXT)) cpuid_count(0x8000001d, index, &eax.full, &ebx.full, &ecx.full, &edx); else @@ -637,7 +637,7 @@ static int find_num_cache_leaves(struct cpuinfo_x86 *c) void init_amd_cacheinfo(struct cpuinfo_x86 *c) { - if (cpu_has_topoext) { + if (boot_cpu_has(X86_FEATURE_TOPOEXT)) { num_cache_leaves = find_num_cache_leaves(c); } else if (c->extended_cpuid_level >= 0x80000006) { if (cpuid_edx(0x80000006) & 0xf000) @@ -809,7 +809,7 @@ static int __cache_amd_cpumap_setup(unsigned int cpu, int index, struct cacheinfo *this_leaf; int i, sibling; - if (cpu_has_topoext) { + if (boot_cpu_has(X86_FEATURE_TOPOEXT)) { unsigned int apicid, nshared, first, last; this_leaf = this_cpu_ci->info_list + index; diff --git a/arch/x86/kernel/cpu/match.c b/arch/x86/kernel/cpu/match.c index afa9f0d487ea0..fbb5e90557a52 100644 --- a/arch/x86/kernel/cpu/match.c +++ b/arch/x86/kernel/cpu/match.c @@ -1,5 +1,5 @@ #include -#include +#include #include #include #include diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 6edb9530d7e99..7b8c8c8381910 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c @@ -980,11 +980,12 @@ void do_machine_check(struct pt_regs *regs, long error_code) int i; int worst = 0; int severity; + /* * Establish sequential order between the CPUs entering the machine * check handler. */ - int order; + int order = -1; /* * If no_way_out gets set, there is no safe way to recover from this * MCE. If mca_cfg.tolerant is cranked up, we'll try anyway. @@ -1000,7 +1001,12 @@ void do_machine_check(struct pt_regs *regs, long error_code) char *msg = "Unknown"; u64 recover_paddr = ~0ull; int flags = MF_ACTION_REQUIRED; - int lmce = 0; + + /* + * MCEs are always local on AMD. Same is determined by MCG_STATUS_LMCES + * on Intel. + */ + int lmce = 1; /* If this CPU is offline, just bail out. */ if (cpu_is_offline(smp_processor_id())) { @@ -1039,17 +1045,23 @@ void do_machine_check(struct pt_regs *regs, long error_code) kill_it = 1; /* - * Check if this MCE is signaled to only this logical processor + * Check if this MCE is signaled to only this logical processor, + * on Intel only. */ - if (m.mcgstatus & MCG_STATUS_LMCES) - lmce = 1; - else { - /* - * Go through all the banks in exclusion of the other CPUs. - * This way we don't report duplicated events on shared banks - * because the first one to see it will clear it. - * If this is a Local MCE, then no need to perform rendezvous. - */ + if (m.cpuvendor == X86_VENDOR_INTEL) + lmce = m.mcgstatus & MCG_STATUS_LMCES; + + /* + * Local machine check may already know that we have to panic. + * Broadcast machine check begins rendezvous in mce_start() + * Go through all banks in exclusion of the other CPUs. This way we + * don't report duplicated events on shared banks because the first one + * to see it will clear it. + */ + if (lmce) { + if (no_way_out) + mce_panic("Fatal local machine check", &m, msg); + } else { order = mce_start(&no_way_out); } @@ -1128,12 +1140,17 @@ void do_machine_check(struct pt_regs *regs, long error_code) no_way_out = worst >= MCE_PANIC_SEVERITY; } else { /* - * Local MCE skipped calling mce_reign() - * If we found a fatal error, we need to panic here. + * If there was a fatal machine check we should have + * already called mce_panic earlier in this function. + * Since we re-read the banks, we might have found + * something new. Check again to see if we found a + * fatal error. We call "mce_severity()" again to + * make sure we have the right "msg". */ - if (worst >= MCE_PANIC_SEVERITY && mca_cfg.tolerant < 3) - mce_panic("Machine check from unknown source", - NULL, NULL); + if (worst >= MCE_PANIC_SEVERITY && mca_cfg.tolerant < 3) { + mce_severity(&m, cfg->tolerant, &msg, true); + mce_panic("Local fatal machine check!", &m, msg); + } } /* @@ -2277,9 +2294,6 @@ static ssize_t store_int_with_restart(struct device *s, if (check_interval == old_check_interval) return ret; - if (check_interval < 1) - check_interval = 1; - mutex_lock(&mce_sysfs_mutex); mce_restart(); mutex_unlock(&mce_sysfs_mutex); diff --git a/arch/x86/kernel/cpu/mkcapflags.sh b/arch/x86/kernel/cpu/mkcapflags.sh index 3f20710a5b23b..6988c74409a82 100644 --- a/arch/x86/kernel/cpu/mkcapflags.sh +++ b/arch/x86/kernel/cpu/mkcapflags.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Generate the x86_cap/bug_flags[] arrays from include/asm/cpufeature.h +# Generate the x86_cap/bug_flags[] arrays from include/asm/cpufeatures.h # IN=$1 @@ -49,8 +49,8 @@ dump_array() trap 'rm "$OUT"' EXIT ( - echo "#ifndef _ASM_X86_CPUFEATURE_H" - echo "#include " + echo "#ifndef _ASM_X86_CPUFEATURES_H" + echo "#include " echo "#endif" echo "" diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c index b5624fafa44a5..136ae86f4f5fd 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c @@ -349,7 +349,7 @@ static void get_fixed_ranges(mtrr_type *frs) void mtrr_save_fixed_ranges(void *info) { - if (cpu_has_mtrr) + if (boot_cpu_has(X86_FEATURE_MTRR)) get_fixed_ranges(mtrr_state.fixed_ranges); } diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c index fa77ac8291f03..49bd700d9b7f5 100644 --- a/arch/x86/kernel/cpu/mtrr/main.c +++ b/arch/x86/kernel/cpu/mtrr/main.c @@ -47,7 +47,7 @@ #include #include -#include +#include #include #include #include @@ -682,7 +682,7 @@ void __init mtrr_bp_init(void) phys_addr = 32; - if (cpu_has_mtrr) { + if (boot_cpu_has(X86_FEATURE_MTRR)) { mtrr_if = &generic_mtrr_ops; size_or_mask = SIZE_OR_MASK_BITS(36); size_and_mask = 0x00f00000; diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c index 1cee5d2d7ecea..3ea177cb73665 100644 --- a/arch/x86/kernel/cpu/perf_event_amd.c +++ b/arch/x86/kernel/cpu/perf_event_amd.c @@ -160,7 +160,7 @@ static inline int amd_pmu_addr_offset(int index, bool eventsel) if (offset) return offset; - if (!cpu_has_perfctr_core) + if (!boot_cpu_has(X86_FEATURE_PERFCTR_CORE)) offset = index; else offset = index << 1; @@ -652,7 +652,7 @@ static __initconst const struct x86_pmu amd_pmu = { static int __init amd_core_pmu_init(void) { - if (!cpu_has_perfctr_core) + if (!boot_cpu_has(X86_FEATURE_PERFCTR_CORE)) return 0; switch (boot_cpu_data.x86) { diff --git a/arch/x86/kernel/cpu/perf_event_amd_uncore.c b/arch/x86/kernel/cpu/perf_event_amd_uncore.c index cc6cedb8f25d5..49742746a6c96 100644 --- a/arch/x86/kernel/cpu/perf_event_amd_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_amd_uncore.c @@ -523,10 +523,10 @@ static int __init amd_uncore_init(void) if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) goto fail_nodev; - if (!cpu_has_topoext) + if (!boot_cpu_has(X86_FEATURE_TOPOEXT)) goto fail_nodev; - if (cpu_has_perfctr_nb) { + if (boot_cpu_has(X86_FEATURE_PERFCTR_NB)) { amd_uncore_nb = alloc_percpu(struct amd_uncore *); if (!amd_uncore_nb) { ret = -ENOMEM; @@ -540,7 +540,7 @@ static int __init amd_uncore_init(void) ret = 0; } - if (cpu_has_perfctr_l2) { + if (boot_cpu_has(X86_FEATURE_PERFCTR_L2)) { amd_uncore_l2 = alloc_percpu(struct amd_uncore *); if (!amd_uncore_l2) { ret = -ENOMEM; @@ -583,10 +583,11 @@ static int __init amd_uncore_init(void) /* amd_uncore_nb/l2 should have been freed by cleanup_cpu_online */ amd_uncore_nb = amd_uncore_l2 = NULL; - if (cpu_has_perfctr_l2) + + if (boot_cpu_has(X86_FEATURE_PERFCTR_L2)) perf_pmu_unregister(&amd_l2_pmu); fail_l2: - if (cpu_has_perfctr_nb) + if (boot_cpu_has(X86_FEATURE_PERFCTR_NB)) perf_pmu_unregister(&amd_nb_pmu); if (amd_uncore_l2) free_percpu(amd_uncore_l2); diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index 61215a69b03d9..b22e9c4dd111f 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c @@ -229,7 +229,7 @@ void uncore_perf_event_update(struct intel_uncore_box *box, struct perf_event *e u64 prev_count, new_count, delta; int shift; - if (event->hw.idx >= UNCORE_PMC_IDX_FIXED) + if (event->hw.idx == UNCORE_PMC_IDX_FIXED) shift = 64 - uncore_fixed_ctr_bits(box); else shift = 64 - uncore_perf_ctr_bits(box); diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore_nhmex.c b/arch/x86/kernel/cpu/perf_event_intel_uncore_nhmex.c index 2749965afed0b..83cadc2605a78 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore_nhmex.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore_nhmex.c @@ -240,7 +240,7 @@ static void nhmex_uncore_msr_enable_event(struct intel_uncore_box *box, struct p { struct hw_perf_event *hwc = &event->hw; - if (hwc->idx >= UNCORE_PMC_IDX_FIXED) + if (hwc->idx == UNCORE_PMC_IDX_FIXED) wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0); else if (box->pmu->type->event_mask & NHMEX_PMON_CTL_EN_BIT0) wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT22); diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c index 608fb26c72544..8cb57df9398d9 100644 --- a/arch/x86/kernel/cpu/scattered.c +++ b/arch/x86/kernel/cpu/scattered.c @@ -31,32 +31,12 @@ void init_scattered_cpuid_features(struct cpuinfo_x86 *c) const struct cpuid_bit *cb; static const struct cpuid_bit cpuid_bits[] = { - { X86_FEATURE_DTHERM, CR_EAX, 0, 0x00000006, 0 }, - { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006, 0 }, - { X86_FEATURE_ARAT, CR_EAX, 2, 0x00000006, 0 }, - { X86_FEATURE_PLN, CR_EAX, 4, 0x00000006, 0 }, - { X86_FEATURE_PTS, CR_EAX, 6, 0x00000006, 0 }, - { X86_FEATURE_HWP, CR_EAX, 7, 0x00000006, 0 }, - { X86_FEATURE_HWP_NOTIFY, CR_EAX, 8, 0x00000006, 0 }, - { X86_FEATURE_HWP_ACT_WINDOW, CR_EAX, 9, 0x00000006, 0 }, - { X86_FEATURE_HWP_EPP, CR_EAX,10, 0x00000006, 0 }, - { X86_FEATURE_HWP_PKG_REQ, CR_EAX,11, 0x00000006, 0 }, { X86_FEATURE_INTEL_PT, CR_EBX,25, 0x00000007, 0 }, { X86_FEATURE_APERFMPERF, CR_ECX, 0, 0x00000006, 0 }, { X86_FEATURE_EPB, CR_ECX, 3, 0x00000006, 0 }, { X86_FEATURE_HW_PSTATE, CR_EDX, 7, 0x80000007, 0 }, { X86_FEATURE_CPB, CR_EDX, 9, 0x80000007, 0 }, { X86_FEATURE_PROC_FEEDBACK, CR_EDX,11, 0x80000007, 0 }, - { X86_FEATURE_NPT, CR_EDX, 0, 0x8000000a, 0 }, - { X86_FEATURE_LBRV, CR_EDX, 1, 0x8000000a, 0 }, - { X86_FEATURE_SVML, CR_EDX, 2, 0x8000000a, 0 }, - { X86_FEATURE_NRIPS, CR_EDX, 3, 0x8000000a, 0 }, - { X86_FEATURE_TSCRATEMSR, CR_EDX, 4, 0x8000000a, 0 }, - { X86_FEATURE_VMCBCLEAN, CR_EDX, 5, 0x8000000a, 0 }, - { X86_FEATURE_FLUSHBYASID, CR_EDX, 6, 0x8000000a, 0 }, - { X86_FEATURE_DECODEASSISTS, CR_EDX, 7, 0x8000000a, 0 }, - { X86_FEATURE_PAUSEFILTER, CR_EDX,10, 0x8000000a, 0 }, - { X86_FEATURE_PFTHRESHOLD, CR_EDX,12, 0x8000000a, 0 }, { 0, 0, 0, 0, 0 } }; diff --git a/arch/x86/kernel/cpu/transmeta.c b/arch/x86/kernel/cpu/transmeta.c index 3fa0e5ad86b44..a19a663282b57 100644 --- a/arch/x86/kernel/cpu/transmeta.c +++ b/arch/x86/kernel/cpu/transmeta.c @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include "cpu.h" @@ -12,7 +12,7 @@ static void early_init_transmeta(struct cpuinfo_x86 *c) xlvl = cpuid_eax(0x80860000); if ((xlvl & 0xffff0000) == 0x80860000) { if (xlvl >= 0x80860001) - c->x86_capability[2] = cpuid_edx(0x80860001); + c->x86_capability[CPUID_8086_0001_EDX] = cpuid_edx(0x80860001); } } @@ -82,7 +82,7 @@ static void init_transmeta(struct cpuinfo_x86 *c) /* Unhide possibly hidden capability flags */ rdmsr(0x80860004, cap_mask, uk); wrmsr(0x80860004, ~0, uk); - c->x86_capability[0] = cpuid_edx(0x00000001); + c->x86_capability[CPUID_1_EDX] = cpuid_edx(0x00000001); wrmsr(0x80860004, cap_mask, uk); /* All Transmeta CPUs have a constant TSC */ diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c index 1f4acd68b98bc..74b8dcd1bbdc6 100644 --- a/arch/x86/kernel/devicetree.c +++ b/arch/x86/kernel/devicetree.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -199,19 +200,22 @@ static struct of_ioapic_type of_ioapic_type[] = static int dt_irqdomain_alloc(struct irq_domain *domain, unsigned int virq, unsigned int nr_irqs, void *arg) { - struct of_phandle_args *irq_data = (void *)arg; + struct irq_fwspec *fwspec = (struct irq_fwspec *)arg; struct of_ioapic_type *it; struct irq_alloc_info tmp; + int type_index; - if (WARN_ON(irq_data->args_count < 2)) + if (WARN_ON(fwspec->param_count < 2)) return -EINVAL; - if (irq_data->args[1] >= ARRAY_SIZE(of_ioapic_type)) + + type_index = fwspec->param[1]; + if (type_index >= ARRAY_SIZE(of_ioapic_type)) return -EINVAL; - it = &of_ioapic_type[irq_data->args[1]]; + it = &of_ioapic_type[type_index]; ioapic_set_alloc_attr(&tmp, NUMA_NO_NODE, it->trigger, it->polarity); tmp.ioapic_id = mpc_ioapic_id(mp_irqdomain_ioapic_idx(domain)); - tmp.ioapic_pin = irq_data->args[0]; + tmp.ioapic_pin = fwspec->param[0]; return mp_irqdomain_alloc(domain, virq, nr_irqs, &tmp); } @@ -276,14 +280,15 @@ static void __init x86_flattree_get_config(void) map_len = max(PAGE_SIZE - (initial_dtb & ~PAGE_MASK), (u64)128); - initial_boot_params = dt = early_memremap(initial_dtb, map_len); - size = of_get_flat_dt_size(); + dt = early_memremap(initial_dtb, map_len); + size = fdt_totalsize(dt); if (map_len < size) { early_memunmap(dt, map_len); - initial_boot_params = dt = early_memremap(initial_dtb, size); + dt = early_memremap(initial_dtb, size); map_len = size; } + early_init_dt_verify(dt); unflatten_and_copy_device_tree(); early_memunmap(dt, map_len); } diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 52a2526c3fbe4..19bc19d5e1741 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -24,6 +24,7 @@ #include #include #include +#include /* * The e820 map is the map that gets modified e.g. with command line parameters diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c index d25097c3fc1d1..6aa0b519c8510 100644 --- a/arch/x86/kernel/fpu/core.c +++ b/arch/x86/kernel/fpu/core.c @@ -114,6 +114,10 @@ void __kernel_fpu_begin(void) kernel_fpu_disable(); if (fpu->fpregs_active) { + /* + * Ignore return value -- we don't care if reg state + * is clobbered. + */ copy_fpregs_to_fpstate(fpu); } else { this_cpu_write(fpu_fpregs_owner_ctx, NULL); @@ -189,8 +193,12 @@ void fpu__save(struct fpu *fpu) preempt_disable(); if (fpu->fpregs_active) { - if (!copy_fpregs_to_fpstate(fpu)) - fpregs_deactivate(fpu); + if (!copy_fpregs_to_fpstate(fpu)) { + if (use_eager_fpu()) + copy_kernel_to_fpregs(&fpu->state); + else + fpregs_deactivate(fpu); + } } preempt_enable(); } @@ -259,7 +267,11 @@ static void fpu_copy(struct fpu *dst_fpu, struct fpu *src_fpu) preempt_disable(); if (!copy_fpregs_to_fpstate(dst_fpu)) { memcpy(&src_fpu->state, &dst_fpu->state, xstate_size); - fpregs_deactivate(src_fpu); + + if (use_eager_fpu()) + copy_kernel_to_fpregs(&src_fpu->state); + else + fpregs_deactivate(src_fpu); } preempt_enable(); } @@ -409,8 +421,10 @@ static inline void copy_init_fpstate_to_fpregs(void) { if (use_xsave()) copy_kernel_to_xregs(&init_fpstate.xsave, -1); - else + else if (static_cpu_has(X86_FEATURE_FXSR)) copy_kernel_to_fxregs(&init_fpstate.fxsave); + else + copy_kernel_to_fregs(&init_fpstate.fsave); } /* @@ -423,7 +437,7 @@ void fpu__clear(struct fpu *fpu) { WARN_ON_FPU(fpu != ¤t->thread.fpu); /* Almost certainly an anomaly */ - if (!use_eager_fpu()) { + if (!use_eager_fpu() || !static_cpu_has(X86_FEATURE_FPU)) { /* FPU state will be reallocated lazily at the first use. */ fpu__drop(fpu); } else { diff --git a/arch/x86/kernel/fpu/init.c b/arch/x86/kernel/fpu/init.c index 1011c05b1bd5d..954517285fa23 100644 --- a/arch/x86/kernel/fpu/init.c +++ b/arch/x86/kernel/fpu/init.c @@ -3,8 +3,11 @@ */ #include #include +#include +#include #include +#include /* * Initialize the TS bit in CR0 according to the style of context-switches @@ -12,10 +15,7 @@ */ static void fpu__init_cpu_ctx_switch(void) { - if (!cpu_has_eager_fpu) - stts(); - else - clts(); + clts(); } /* @@ -75,13 +75,15 @@ static void fpu__init_system_early_generic(struct cpuinfo_x86 *c) cr0 &= ~(X86_CR0_TS | X86_CR0_EM); write_cr0(cr0); - asm volatile("fninit ; fnstsw %0 ; fnstcw %1" - : "+m" (fsw), "+m" (fcw)); + if (!test_bit(X86_FEATURE_FPU, (unsigned long *)cpu_caps_cleared)) { + asm volatile("fninit ; fnstsw %0 ; fnstcw %1" + : "+m" (fsw), "+m" (fcw)); - if (fsw == 0 && (fcw & 0x103f) == 0x003f) - set_cpu_cap(c, X86_FEATURE_FPU); - else - clear_cpu_cap(c, X86_FEATURE_FPU); + if (fsw == 0 && (fcw & 0x103f) == 0x003f) + set_cpu_cap(c, X86_FEATURE_FPU); + else + clear_cpu_cap(c, X86_FEATURE_FPU); + } #ifndef CONFIG_MATH_EMULATION if (!cpu_has_fpu) { @@ -130,7 +132,7 @@ static void __init fpu__init_system_generic(void) * Set up the legacy init FPU context. (xstate init might overwrite this * with a more modern format, if the CPU supports it.) */ - fpstate_init_fxstate(&init_fpstate.fxsave); + fpstate_init(&init_fpstate); fpu__init_system_mxcsr(); } @@ -230,53 +232,16 @@ static void __init fpu__init_system_xstate_size_legacy(void) } /* - * FPU context switching strategies: - * - * Against popular belief, we don't do lazy FPU saves, due to the - * task migration complications it brings on SMP - we only do - * lazy FPU restores. - * - * 'lazy' is the traditional strategy, which is based on setting - * CR0::TS to 1 during context-switch (instead of doing a full - * restore of the FPU state), which causes the first FPU instruction - * after the context switch (whenever it is executed) to fault - at - * which point we lazily restore the FPU state into FPU registers. - * - * Tasks are of course under no obligation to execute FPU instructions, - * so it can easily happen that another context-switch occurs without - * a single FPU instruction being executed. If we eventually switch - * back to the original task (that still owns the FPU) then we have - * not only saved the restores along the way, but we also have the - * FPU ready to be used for the original task. - * - * 'eager' switching is used on modern CPUs, there we switch the FPU - * state during every context switch, regardless of whether the task - * has used FPU instructions in that time slice or not. This is done - * because modern FPU context saving instructions are able to optimize - * state saving and restoration in hardware: they can detect both - * unused and untouched FPU state and optimize accordingly. - * - * [ Note that even in 'lazy' mode we might optimize context switches - * to use 'eager' restores, if we detect that a task is using the FPU - * frequently. See the fpu->counter logic in fpu/internal.h for that. ] + * Find supported xfeatures based on cpu features and command-line input. + * This must be called after fpu__init_parse_early_param() is called and + * xfeatures_mask is enumerated. */ -static enum { AUTO, ENABLE, DISABLE } eagerfpu = AUTO; - -static int __init eager_fpu_setup(char *s) +u64 __init fpu__get_supported_xfeatures_mask(void) { - if (!strcmp(s, "on")) - eagerfpu = ENABLE; - else if (!strcmp(s, "off")) - eagerfpu = DISABLE; - else if (!strcmp(s, "auto")) - eagerfpu = AUTO; - return 1; + return XCNTXT_MASK; } -__setup("eagerfpu=", eager_fpu_setup); -/* - * Pick the FPU context switching strategy: - */ +/* Legacy code to initialize eager fpu mode. */ static void __init fpu__init_system_ctx_switch(void) { static bool on_boot_cpu = 1; @@ -286,25 +251,31 @@ static void __init fpu__init_system_ctx_switch(void) WARN_ON_FPU(current->thread.fpu.fpstate_active); current_thread_info()->status = 0; +} - /* Auto enable eagerfpu for xsaveopt */ - if (cpu_has_xsaveopt && eagerfpu != DISABLE) - eagerfpu = ENABLE; - - if (xfeatures_mask & XFEATURE_MASK_EAGER) { - if (eagerfpu == DISABLE) { - pr_err("x86/fpu: eagerfpu switching disabled, disabling the following xstate features: 0x%llx.\n", - xfeatures_mask & XFEATURE_MASK_EAGER); - xfeatures_mask &= ~XFEATURE_MASK_EAGER; - } else { - eagerfpu = ENABLE; - } +/* + * We parse fpu parameters early because fpu__init_system() is executed + * before parse_early_param(). + */ +static void __init fpu__init_parse_early_param(void) +{ + if (cmdline_find_option_bool(boot_command_line, "no387")) + setup_clear_cpu_cap(X86_FEATURE_FPU); + + if (cmdline_find_option_bool(boot_command_line, "nofxsr")) { + setup_clear_cpu_cap(X86_FEATURE_FXSR); + setup_clear_cpu_cap(X86_FEATURE_FXSR_OPT); + setup_clear_cpu_cap(X86_FEATURE_XMM); } - if (eagerfpu == ENABLE) - setup_force_cpu_cap(X86_FEATURE_EAGER_FPU); + if (cmdline_find_option_bool(boot_command_line, "noxsave")) + fpu__xstate_clear_all_cpu_caps(); + + if (cmdline_find_option_bool(boot_command_line, "noxsaveopt")) + setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT); - printk(KERN_INFO "x86/fpu: Using '%s' FPU context switches.\n", eagerfpu == ENABLE ? "eager" : "lazy"); + if (cmdline_find_option_bool(boot_command_line, "noxsaves")) + setup_clear_cpu_cap(X86_FEATURE_XSAVES); } /* @@ -313,6 +284,7 @@ static void __init fpu__init_system_ctx_switch(void) */ void __init fpu__init_system(struct cpuinfo_x86 *c) { + fpu__init_parse_early_param(); fpu__init_system_early_generic(c); /* @@ -336,62 +308,3 @@ void __init fpu__init_system(struct cpuinfo_x86 *c) fpu__init_system_ctx_switch(); } - -/* - * Boot parameter to turn off FPU support and fall back to math-emu: - */ -static int __init no_387(char *s) -{ - setup_clear_cpu_cap(X86_FEATURE_FPU); - return 1; -} -__setup("no387", no_387); - -/* - * Disable all xstate CPU features: - */ -static int __init x86_noxsave_setup(char *s) -{ - if (strlen(s)) - return 0; - - fpu__xstate_clear_all_cpu_caps(); - - return 1; -} -__setup("noxsave", x86_noxsave_setup); - -/* - * Disable the XSAVEOPT instruction specifically: - */ -static int __init x86_noxsaveopt_setup(char *s) -{ - setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT); - - return 1; -} -__setup("noxsaveopt", x86_noxsaveopt_setup); - -/* - * Disable the XSAVES instruction: - */ -static int __init x86_noxsaves_setup(char *s) -{ - setup_clear_cpu_cap(X86_FEATURE_XSAVES); - - return 1; -} -__setup("noxsaves", x86_noxsaves_setup); - -/* - * Disable FX save/restore and SSE support: - */ -static int __init x86_nofxsr_setup(char *s) -{ - setup_clear_cpu_cap(X86_FEATURE_FXSR); - setup_clear_cpu_cap(X86_FEATURE_FXSR_OPT); - setup_clear_cpu_cap(X86_FEATURE_XMM); - - return 1; -} -__setup("nofxsr", x86_nofxsr_setup); diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c index 70fc312221fc6..3fa200ecca623 100644 --- a/arch/x86/kernel/fpu/xstate.c +++ b/arch/x86/kernel/fpu/xstate.c @@ -632,8 +632,7 @@ void __init fpu__init_system_xstate(void) BUG(); } - /* Support only the state known to the OS: */ - xfeatures_mask = xfeatures_mask & XCNTXT_MASK; + xfeatures_mask &= fpu__get_supported_xfeatures_mask(); /* Enable xstate instructions to be able to continue with initialization: */ fpu__init_cpu_xstate(); diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index 70284d38fdc26..1c0b49fd63654 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index 4034e905741a9..734ba1d0f6868 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -76,9 +76,7 @@ startup_64: subq $_text - __START_KERNEL_map, %rbp /* Is the address not 2M aligned? */ - movq %rbp, %rax - andl $~PMD_PAGE_MASK, %eax - testl %eax, %eax + testl $~PMD_PAGE_MASK, %ebp jnz bad_address /* diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index f48eb8eeefe2b..3fdc1e53aaac7 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c index 50a3fad5b89f1..2bcfb5f2bc449 100644 --- a/arch/x86/kernel/hw_breakpoint.c +++ b/arch/x86/kernel/hw_breakpoint.c @@ -300,6 +300,10 @@ static int arch_build_bp_info(struct perf_event *bp) return -EINVAL; if (bp->attr.bp_addr & (bp->attr.bp_len - 1)) return -EINVAL; + + if (!boot_cpu_has(X86_FEATURE_BPEXT)) + return -EOPNOTSUPP; + /* * It's impossible to use a range breakpoint to fake out * user vs kernel detection because bp_len - 1 can't @@ -307,8 +311,6 @@ static int arch_build_bp_info(struct perf_event *bp) * breakpoints, then we'll have to check for kprobe-blacklisted * addresses anywhere in the range. */ - if (!cpu_has_bpext) - return -EOPNOTSUPP; info->mask = bp->attr.bp_len - 1; info->len = X86_BREAKPOINT_LEN_1; } diff --git a/arch/x86/kernel/irqflags.S b/arch/x86/kernel/irqflags.S new file mode 100644 index 0000000000000..3817eb748eb48 --- /dev/null +++ b/arch/x86/kernel/irqflags.S @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#include +#include +#include + +/* + * unsigned long native_save_fl(void) + */ +ENTRY(native_save_fl) + pushf + pop %_ASM_AX + ret +ENDPROC(native_save_fl) +EXPORT_SYMBOL(native_save_fl) + +/* + * void native_restore_fl(unsigned long flags) + * %eax/%rdi: flags + */ +ENTRY(native_restore_fl) + push %_ASM_ARG1 + popf + ret +ENDPROC(native_restore_fl) +EXPORT_SYMBOL(native_restore_fl) diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index 30bc638760357..581671172e106 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c @@ -394,7 +394,6 @@ int __copy_instruction(u8 *dest, u8 *src) newdisp = (u8 *) src + (s64) insn.displacement.value - (u8 *) dest; if ((s64) (s32) newdisp != newdisp) { pr_err("Kprobes error: new displacement does not fit into s32 (%llx)\n", newdisp); - pr_err("\tSrc: %p, Dest: %p, old disp: %x\n", src, dest, insn.displacement.value); return 0; } disp = (u8 *) dest + insn_offset_displacement(&insn); @@ -412,25 +411,38 @@ void free_insn_page(void *page) module_memfree(page); } +/* Prepare reljump right after instruction to boost */ +static void prepare_boost(struct kprobe *p, int length) +{ + if (can_boost(p->ainsn.insn, p->addr) && + MAX_INSN_SIZE - length >= RELATIVEJUMP_SIZE) { + /* + * These instructions can be executed directly if it + * jumps back to correct address. + */ + synthesize_reljump(p->ainsn.insn + length, p->addr + length); + p->ainsn.boostable = 1; + } else { + p->ainsn.boostable = -1; + } +} + static int arch_copy_kprobe(struct kprobe *p) { - int ret; + int len; set_memory_rw((unsigned long)p->ainsn.insn & PAGE_MASK, 1); /* Copy an instruction with recovering if other optprobe modifies it.*/ - ret = __copy_instruction(p->ainsn.insn, p->addr); - if (!ret) + len = __copy_instruction(p->ainsn.insn, p->addr); + if (!len) return -EINVAL; /* * __copy_instruction can modify the displacement of the instruction, * but it doesn't affect boostable check. */ - if (can_boost(p->ainsn.insn, p->addr)) - p->ainsn.boostable = 0; - else - p->ainsn.boostable = -1; + prepare_boost(p, len); set_memory_ro((unsigned long)p->ainsn.insn & PAGE_MASK, 1); @@ -597,8 +609,7 @@ static int reenter_kprobe(struct kprobe *p, struct pt_regs *regs, * Raise a BUG or we'll continue in an endless reentering loop * and eventually a stack overflow. */ - printk(KERN_WARNING "Unrecoverable kprobe detected at %p.\n", - p->addr); + pr_err("Unrecoverable kprobe detected.\n"); dump_kprobe(p); BUG(); default: @@ -895,21 +906,6 @@ static void resume_execution(struct kprobe *p, struct pt_regs *regs, break; } - if (p->ainsn.boostable == 0) { - if ((regs->ip > copy_ip) && - (regs->ip - copy_ip) + 5 < MAX_INSN_SIZE) { - /* - * These instructions can be executed directly if it - * jumps back to correct address. - */ - synthesize_reljump((void *)regs->ip, - (void *)orig_ip + (regs->ip - copy_ip)); - p->ainsn.boostable = 1; - } else { - p->ainsn.boostable = -1; - } - } - regs->ip += orig_ip - copy_ip; no_change: diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c index bc429365b72a9..8bc68cfc0d33f 100644 --- a/arch/x86/kernel/ldt.c +++ b/arch/x86/kernel/ldt.c @@ -119,7 +119,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; @@ -160,7 +160,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/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c index 469b23d6acc27..fd7e9937ddd6d 100644 --- a/arch/x86/kernel/machine_kexec_32.c +++ b/arch/x86/kernel/machine_kexec_32.c @@ -71,12 +71,17 @@ static void load_segments(void) static void machine_kexec_free_page_tables(struct kimage *image) { free_page((unsigned long)image->arch.pgd); + image->arch.pgd = NULL; #ifdef CONFIG_X86_PAE free_page((unsigned long)image->arch.pmd0); + image->arch.pmd0 = NULL; free_page((unsigned long)image->arch.pmd1); + image->arch.pmd1 = NULL; #endif free_page((unsigned long)image->arch.pte0); + image->arch.pte0 = NULL; free_page((unsigned long)image->arch.pte1); + image->arch.pte1 = NULL; } static int machine_kexec_alloc_page_tables(struct kimage *image) @@ -93,7 +98,6 @@ static int machine_kexec_alloc_page_tables(struct kimage *image) !image->arch.pmd0 || !image->arch.pmd1 || #endif !image->arch.pte0 || !image->arch.pte1) { - machine_kexec_free_page_tables(image); return -ENOMEM; } return 0; diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c index 615cc42ad6315..2ddb850bceab2 100644 --- a/arch/x86/kernel/machine_kexec_64.c +++ b/arch/x86/kernel/machine_kexec_64.c @@ -37,8 +37,11 @@ static struct kexec_file_ops *kexec_file_loaders[] = { static void free_transition_pgtable(struct kimage *image) { free_page((unsigned long)image->arch.pud); + image->arch.pud = NULL; free_page((unsigned long)image->arch.pmd); + image->arch.pmd = NULL; free_page((unsigned long)image->arch.pte); + image->arch.pte = NULL; } static int init_transition_pgtable(struct kimage *image, pgd_t *pgd) @@ -79,7 +82,6 @@ static int init_transition_pgtable(struct kimage *image, pgd_t *pgd) set_pte(pte, pfn_pte(paddr >> PAGE_SHIFT, PAGE_KERNEL_EXEC)); return 0; err: - free_transition_pgtable(image); return result; } diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c index 113e70784854f..f95ac5d435aa0 100644 --- a/arch/x86/kernel/msr.c +++ b/arch/x86/kernel/msr.c @@ -40,7 +40,7 @@ #include #include -#include +#include #include static struct class *msr_class; diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index f534a0e3af535..632195b416886 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c @@ -97,10 +97,12 @@ unsigned paravirt_patch_call(void *insnbuf, struct branch *b = insnbuf; unsigned long delta = (unsigned long)target - (addr+5); - if (tgt_clobbers & ~site_clobbers) - return len; /* target would clobber too much for this site */ - if (len < 5) + if (len < 5) { +#ifdef CONFIG_RETPOLINE + WARN_ONCE("Failing to patch indirect CALL in %ps\n", (void *)addr); +#endif return len; /* call too long for patch site */ + } b->opcode = 0xe8; /* call */ b->delta = delta; @@ -115,8 +117,12 @@ unsigned paravirt_patch_jmp(void *insnbuf, const void *target, struct branch *b = insnbuf; unsigned long delta = (unsigned long)target - (addr+5); - if (len < 5) + if (len < 5) { +#ifdef CONFIG_RETPOLINE + WARN_ONCE("Failing to patch indirect JMP in %ps\n", (void *)addr); +#endif return len; /* call too long for patch site */ + } b->opcode = 0xe9; /* jmp */ b->delta = delta; diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 2754dad268393..911ca11eb4899 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c @@ -31,6 +31,7 @@ #include #include #include +#include /* * per-CPU TSS segments. Threads are completely 'soft' on Linux, @@ -116,11 +117,6 @@ void flush_thread(void) fpu__clear(&tsk->thread.fpu); } -static void hard_disable_TSC(void) -{ - cr4_set_bits(X86_CR4_TSD); -} - void disable_TSC(void) { preempt_disable(); @@ -129,15 +125,10 @@ void disable_TSC(void) * Must flip the CPU state synchronously with * TIF_NOTSC in the current running context. */ - hard_disable_TSC(); + cr4_set_bits(X86_CR4_TSD); preempt_enable(); } -static void hard_enable_TSC(void) -{ - cr4_clear_bits(X86_CR4_TSD); -} - static void enable_TSC(void) { preempt_disable(); @@ -146,7 +137,7 @@ static void enable_TSC(void) * Must flip the CPU state synchronously with * TIF_NOTSC in the current running context. */ - hard_enable_TSC(); + cr4_clear_bits(X86_CR4_TSD); preempt_enable(); } @@ -174,48 +165,199 @@ int set_tsc_mode(unsigned int val) return 0; } -void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, - struct tss_struct *tss) +static inline void switch_to_bitmap(struct tss_struct *tss, + struct thread_struct *prev, + struct thread_struct *next, + unsigned long tifp, unsigned long tifn) { - struct thread_struct *prev, *next; - - prev = &prev_p->thread; - next = &next_p->thread; - - if (test_tsk_thread_flag(prev_p, TIF_BLOCKSTEP) ^ - test_tsk_thread_flag(next_p, TIF_BLOCKSTEP)) { - unsigned long debugctl = get_debugctlmsr(); - - debugctl &= ~DEBUGCTLMSR_BTF; - if (test_tsk_thread_flag(next_p, TIF_BLOCKSTEP)) - debugctl |= DEBUGCTLMSR_BTF; - - update_debugctlmsr(debugctl); - } - - if (test_tsk_thread_flag(prev_p, TIF_NOTSC) ^ - test_tsk_thread_flag(next_p, TIF_NOTSC)) { - /* prev and next are different */ - if (test_tsk_thread_flag(next_p, TIF_NOTSC)) - hard_disable_TSC(); - else - hard_enable_TSC(); - } - - if (test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) { + if (tifn & _TIF_IO_BITMAP) { /* * Copy the relevant range of the IO bitmap. * Normally this is 128 bytes or less: */ memcpy(tss->io_bitmap, next->io_bitmap_ptr, max(prev->io_bitmap_max, next->io_bitmap_max)); - } else if (test_tsk_thread_flag(prev_p, TIF_IO_BITMAP)) { + } else if (tifp & _TIF_IO_BITMAP) { /* * Clear any possible leftover bits: */ memset(tss->io_bitmap, 0xff, prev->io_bitmap_max); } +} + +#ifdef CONFIG_SMP + +struct ssb_state { + struct ssb_state *shared_state; + raw_spinlock_t lock; + unsigned int disable_state; + unsigned long local_state; +}; + +#define LSTATE_SSB 0 + +static DEFINE_PER_CPU(struct ssb_state, ssb_state); + +void speculative_store_bypass_ht_init(void) +{ + struct ssb_state *st = this_cpu_ptr(&ssb_state); + unsigned int this_cpu = smp_processor_id(); + unsigned int cpu; + + st->local_state = 0; + + /* + * Shared state setup happens once on the first bringup + * of the CPU. It's not destroyed on CPU hotunplug. + */ + if (st->shared_state) + return; + + raw_spin_lock_init(&st->lock); + + /* + * Go over HT siblings and check whether one of them has set up the + * shared state pointer already. + */ + for_each_cpu(cpu, topology_sibling_cpumask(this_cpu)) { + if (cpu == this_cpu) + continue; + + if (!per_cpu(ssb_state, cpu).shared_state) + continue; + + /* Link it to the state of the sibling: */ + st->shared_state = per_cpu(ssb_state, cpu).shared_state; + return; + } + + /* + * First HT sibling to come up on the core. Link shared state of + * the first HT sibling to itself. The siblings on the same core + * which come up later will see the shared state pointer and link + * themself to the state of this CPU. + */ + st->shared_state = st; +} + +/* + * Logic is: First HT sibling enables SSBD for both siblings in the core + * and last sibling to disable it, disables it for the whole core. This how + * MSR_SPEC_CTRL works in "hardware": + * + * CORE_SPEC_CTRL = THREAD0_SPEC_CTRL | THREAD1_SPEC_CTRL + */ +static __always_inline void amd_set_core_ssb_state(unsigned long tifn) +{ + struct ssb_state *st = this_cpu_ptr(&ssb_state); + u64 msr = x86_amd_ls_cfg_base; + + if (!static_cpu_has(X86_FEATURE_ZEN)) { + msr |= ssbd_tif_to_amd_ls_cfg(tifn); + wrmsrl(MSR_AMD64_LS_CFG, msr); + return; + } + + if (tifn & _TIF_SSBD) { + /* + * Since this can race with prctl(), block reentry on the + * same CPU. + */ + if (__test_and_set_bit(LSTATE_SSB, &st->local_state)) + return; + + msr |= x86_amd_ls_cfg_ssbd_mask; + + raw_spin_lock(&st->shared_state->lock); + /* First sibling enables SSBD: */ + if (!st->shared_state->disable_state) + wrmsrl(MSR_AMD64_LS_CFG, msr); + st->shared_state->disable_state++; + raw_spin_unlock(&st->shared_state->lock); + } else { + if (!__test_and_clear_bit(LSTATE_SSB, &st->local_state)) + return; + + raw_spin_lock(&st->shared_state->lock); + st->shared_state->disable_state--; + if (!st->shared_state->disable_state) + wrmsrl(MSR_AMD64_LS_CFG, msr); + raw_spin_unlock(&st->shared_state->lock); + } +} +#else +static __always_inline void amd_set_core_ssb_state(unsigned long tifn) +{ + u64 msr = x86_amd_ls_cfg_base | ssbd_tif_to_amd_ls_cfg(tifn); + + wrmsrl(MSR_AMD64_LS_CFG, msr); +} +#endif + +static __always_inline void amd_set_ssb_virt_state(unsigned long tifn) +{ + /* + * SSBD has the same definition in SPEC_CTRL and VIRT_SPEC_CTRL, + * so ssbd_tif_to_spec_ctrl() just works. + */ + wrmsrl(MSR_AMD64_VIRT_SPEC_CTRL, ssbd_tif_to_spec_ctrl(tifn)); +} + +static __always_inline void intel_set_ssb_state(unsigned long tifn) +{ + u64 msr = x86_spec_ctrl_base | ssbd_tif_to_spec_ctrl(tifn); + + wrmsrl(MSR_IA32_SPEC_CTRL, msr); +} + +static __always_inline void __speculative_store_bypass_update(unsigned long tifn) +{ + if (static_cpu_has(X86_FEATURE_VIRT_SSBD)) + amd_set_ssb_virt_state(tifn); + else if (static_cpu_has(X86_FEATURE_LS_CFG_SSBD)) + amd_set_core_ssb_state(tifn); + else + intel_set_ssb_state(tifn); +} + +void speculative_store_bypass_update(unsigned long tif) +{ + preempt_disable(); + __speculative_store_bypass_update(tif); + preempt_enable(); +} + +void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, + struct tss_struct *tss) +{ + struct thread_struct *prev, *next; + unsigned long tifp, tifn; + + prev = &prev_p->thread; + next = &next_p->thread; + + tifn = READ_ONCE(task_thread_info(next_p)->flags); + tifp = READ_ONCE(task_thread_info(prev_p)->flags); + switch_to_bitmap(tss, prev, next, tifp, tifn); + propagate_user_return_notify(prev_p, next_p); + + if ((tifp & _TIF_BLOCKSTEP || tifn & _TIF_BLOCKSTEP) && + arch_has_block_step()) { + unsigned long debugctl, msk; + + rdmsrl(MSR_IA32_DEBUGCTLMSR, debugctl); + debugctl &= ~DEBUGCTLMSR_BTF; + msk = tifn & _TIF_BLOCKSTEP; + debugctl |= (msk >> TIF_BLOCKSTEP) << DEBUGCTLMSR_BTF_SHIFT; + wrmsrl(MSR_IA32_DEBUGCTLMSR, debugctl); + } + + if ((tifp ^ tifn) & _TIF_NOTSC) + cr4_toggle_bits(X86_CR4_TSD); + + if ((tifp ^ tifn) & _TIF_SSBD) + __speculative_store_bypass_update(tifn); } /* diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 4cbb60fbff3e3..c7cc81e9bb84a 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -250,6 +250,7 @@ start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp) start_thread_common(regs, new_ip, new_sp, __USER_CS, __USER_DS, 0); } +EXPORT_SYMBOL_GPL(start_thread); #ifdef CONFIG_COMPAT void compat_start_thread(struct pt_regs *regs, u32 new_ip, u32 new_sp) diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index bbaae4cf9e8ed..31c4bc0d3372c 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -851,6 +851,12 @@ void __init setup_arch(char **cmdline_p) memblock_reserve(__pa_symbol(_text), (unsigned long)__bss_stop - (unsigned long)_text); + /* + * Make sure page 0 is always reserved because on systems with + * L1TF its contents can be leaked to user processes. + */ + memblock_reserve(0, PAGE_SIZE); + early_reserve_initrd(); /* diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 00c7878043efc..c017f1c71560d 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -75,6 +75,7 @@ #include #include #include +#include /* Number of siblings per CPU package */ int smp_num_siblings = 1; @@ -217,6 +218,8 @@ static void notrace start_secondary(void *unused) */ check_tsc_sync_target(); + speculative_store_bypass_ht_init(); + /* * Lock vector_lock and initialize the vectors on this cpu * before setting the cpu online. We must set it online with @@ -295,7 +298,7 @@ do { \ static bool match_smt(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o) { - if (cpu_has_topoext) { + if (boot_cpu_has(X86_FEATURE_TOPOEXT)) { int cpu1 = c->cpu_index, cpu2 = o->cpu_index; if (c->phys_proc_id == o->phys_proc_id && @@ -1209,6 +1212,8 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus) set_mtrr_aps_delayed_init(); smp_quirk_init_udelay(); + + speculative_store_bypass_ht_init(); } void arch_enable_nonboot_cpus_begin(void) @@ -1344,6 +1349,7 @@ static void remove_siblinginfo(int cpu) cpumask_clear(topology_core_cpumask(cpu)); c->phys_proc_id = 0; c->cpu_core_id = 0; + c->booted_cores = 0; cpumask_clear_cpu(cpu, cpu_sibling_setup_mask); } diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 1fbd2631be606..8c73bf1492b86 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -751,7 +751,6 @@ dotraplinkage void do_device_not_available(struct pt_regs *regs, long error_code) { RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU"); - BUG_ON(use_eager_fpu()); #ifdef CONFIG_MATH_EMULATION if (read_cr0() & X86_CR0_EM) { diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c index c6aace2bbe083..b8105289c60b6 100644 --- a/arch/x86/kernel/uprobes.c +++ b/arch/x86/kernel/uprobes.c @@ -290,7 +290,7 @@ static int uprobe_init_insn(struct arch_uprobe *auprobe, struct insn *insn, bool insn_init(insn, auprobe->insn, sizeof(auprobe->insn), x86_64); /* has the side-effect of processing the entire instruction */ insn_get_length(insn); - if (WARN_ON_ONCE(!insn_complete(insn))) + if (!insn_complete(insn)) return -ENOEXEC; if (is_prefix_bad(insn)) diff --git a/arch/x86/kernel/verify_cpu.S b/arch/x86/kernel/verify_cpu.S index 4cf401f581e7e..b7c9db5deebe5 100644 --- a/arch/x86/kernel/verify_cpu.S +++ b/arch/x86/kernel/verify_cpu.S @@ -30,7 +30,7 @@ * appropriately. Either display a message or halt. */ -#include +#include #include verify_cpu: diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c index af57736a03096..7f4839ef3608b 100644 --- a/arch/x86/kernel/vm86_32.c +++ b/arch/x86/kernel/vm86_32.c @@ -357,8 +357,10 @@ static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus) tss = &per_cpu(cpu_tss, get_cpu()); /* make room for real-mode segments */ tsk->thread.sp0 += 16; - if (cpu_has_sep) + + if (static_cpu_has(X86_FEATURE_SEP)) tsk->thread.sysenter_cs = 0; + load_sp0(tss, &tsk->thread); put_cpu(); diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index 31355fb1a2ccb..3611136b1455c 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S @@ -200,6 +200,17 @@ SECTIONS :init #endif + /* + * Section for code used exclusively before alternatives are run. All + * references to such code must be patched out by alternatives, normally + * by using X86_FEATURE_ALWAYS CPU feature bit. + * + * See static_cpu_has() for an example. + */ + .altinstr_aux : AT(ADDR(.altinstr_aux) - LOAD_OFFSET) { + *(.altinstr_aux) + } + INIT_DATA_SECTION(16) .x86_cpu_dev.init : AT(ADDR(.x86_cpu_dev.init) - LOAD_OFFSET) { diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 8864fec63a206..f1507626ed364 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -790,6 +790,19 @@ static inline int jmp_rel(struct x86_emulate_ctxt *ctxt, int rel) return assign_eip_near(ctxt, ctxt->_eip + rel); } +static int linear_read_system(struct x86_emulate_ctxt *ctxt, ulong linear, + void *data, unsigned size) +{ + return ctxt->ops->read_std(ctxt, linear, data, size, &ctxt->exception, true); +} + +static int linear_write_system(struct x86_emulate_ctxt *ctxt, + ulong linear, void *data, + unsigned int size) +{ + return ctxt->ops->write_std(ctxt, linear, data, size, &ctxt->exception, true); +} + static int segmented_read_std(struct x86_emulate_ctxt *ctxt, struct segmented_address addr, void *data, @@ -801,7 +814,7 @@ static int segmented_read_std(struct x86_emulate_ctxt *ctxt, rc = linearize(ctxt, addr, size, false, &linear); if (rc != X86EMUL_CONTINUE) return rc; - return ctxt->ops->read_std(ctxt, linear, data, size, &ctxt->exception); + return ctxt->ops->read_std(ctxt, linear, data, size, &ctxt->exception, false); } static int segmented_write_std(struct x86_emulate_ctxt *ctxt, @@ -815,7 +828,7 @@ static int segmented_write_std(struct x86_emulate_ctxt *ctxt, rc = linearize(ctxt, addr, size, true, &linear); if (rc != X86EMUL_CONTINUE) return rc; - return ctxt->ops->write_std(ctxt, linear, data, size, &ctxt->exception); + return ctxt->ops->write_std(ctxt, linear, data, size, &ctxt->exception, false); } /* @@ -1488,8 +1501,7 @@ static int read_interrupt_descriptor(struct x86_emulate_ctxt *ctxt, return emulate_gp(ctxt, index << 3 | 0x2); addr = dt.address + index * 8; - return ctxt->ops->read_std(ctxt, addr, desc, sizeof *desc, - &ctxt->exception); + return linear_read_system(ctxt, addr, desc, sizeof *desc); } static void get_descriptor_table_ptr(struct x86_emulate_ctxt *ctxt, @@ -1552,8 +1564,7 @@ static int read_segment_descriptor(struct x86_emulate_ctxt *ctxt, if (rc != X86EMUL_CONTINUE) return rc; - return ctxt->ops->read_std(ctxt, *desc_addr_p, desc, sizeof(*desc), - &ctxt->exception); + return linear_read_system(ctxt, *desc_addr_p, desc, sizeof(*desc)); } /* allowed just for 8 bytes segments */ @@ -1567,8 +1578,7 @@ static int write_segment_descriptor(struct x86_emulate_ctxt *ctxt, if (rc != X86EMUL_CONTINUE) return rc; - return ctxt->ops->write_std(ctxt, addr, desc, sizeof *desc, - &ctxt->exception); + return linear_write_system(ctxt, addr, desc, sizeof *desc); } static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt, @@ -1729,8 +1739,7 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt, return ret; } } else if (ctxt->mode == X86EMUL_MODE_PROT64) { - ret = ctxt->ops->read_std(ctxt, desc_addr+8, &base3, - sizeof(base3), &ctxt->exception); + ret = linear_read_system(ctxt, desc_addr+8, &base3, sizeof(base3)); if (ret != X86EMUL_CONTINUE) return ret; if (is_noncanonical_address(get_desc_base(&seg_desc) | @@ -2043,11 +2052,11 @@ static int __emulate_int_real(struct x86_emulate_ctxt *ctxt, int irq) eip_addr = dt.address + (irq << 2); cs_addr = dt.address + (irq << 2) + 2; - rc = ops->read_std(ctxt, cs_addr, &cs, 2, &ctxt->exception); + rc = linear_read_system(ctxt, cs_addr, &cs, 2); if (rc != X86EMUL_CONTINUE) return rc; - rc = ops->read_std(ctxt, eip_addr, &eip, 2, &ctxt->exception); + rc = linear_read_system(ctxt, eip_addr, &eip, 2); if (rc != X86EMUL_CONTINUE) return rc; @@ -2891,12 +2900,12 @@ static bool emulator_io_port_access_allowed(struct x86_emulate_ctxt *ctxt, #ifdef CONFIG_X86_64 base |= ((u64)base3) << 32; #endif - r = ops->read_std(ctxt, base + 102, &io_bitmap_ptr, 2, NULL); + r = ops->read_std(ctxt, base + 102, &io_bitmap_ptr, 2, NULL, true); if (r != X86EMUL_CONTINUE) return false; if (io_bitmap_ptr + port/8 > desc_limit_scaled(&tr_seg)) return false; - r = ops->read_std(ctxt, base + io_bitmap_ptr + port/8, &perm, 2, NULL); + r = ops->read_std(ctxt, base + io_bitmap_ptr + port/8, &perm, 2, NULL, true); if (r != X86EMUL_CONTINUE) return false; if ((perm >> bit_idx) & mask) @@ -3025,35 +3034,30 @@ static int task_switch_16(struct x86_emulate_ctxt *ctxt, u16 tss_selector, u16 old_tss_sel, ulong old_tss_base, struct desc_struct *new_desc) { - const struct x86_emulate_ops *ops = ctxt->ops; struct tss_segment_16 tss_seg; int ret; u32 new_tss_base = get_desc_base(new_desc); - ret = ops->read_std(ctxt, old_tss_base, &tss_seg, sizeof tss_seg, - &ctxt->exception); + ret = linear_read_system(ctxt, old_tss_base, &tss_seg, sizeof tss_seg); if (ret != X86EMUL_CONTINUE) return ret; save_state_to_tss16(ctxt, &tss_seg); - ret = ops->write_std(ctxt, old_tss_base, &tss_seg, sizeof tss_seg, - &ctxt->exception); + ret = linear_write_system(ctxt, old_tss_base, &tss_seg, sizeof tss_seg); if (ret != X86EMUL_CONTINUE) return ret; - ret = ops->read_std(ctxt, new_tss_base, &tss_seg, sizeof tss_seg, - &ctxt->exception); + ret = linear_read_system(ctxt, new_tss_base, &tss_seg, sizeof tss_seg); if (ret != X86EMUL_CONTINUE) return ret; if (old_tss_sel != 0xffff) { tss_seg.prev_task_link = old_tss_sel; - ret = ops->write_std(ctxt, new_tss_base, - &tss_seg.prev_task_link, - sizeof tss_seg.prev_task_link, - &ctxt->exception); + ret = linear_write_system(ctxt, new_tss_base, + &tss_seg.prev_task_link, + sizeof tss_seg.prev_task_link); if (ret != X86EMUL_CONTINUE) return ret; } @@ -3169,38 +3173,34 @@ static int task_switch_32(struct x86_emulate_ctxt *ctxt, u16 tss_selector, u16 old_tss_sel, ulong old_tss_base, struct desc_struct *new_desc) { - const struct x86_emulate_ops *ops = ctxt->ops; struct tss_segment_32 tss_seg; int ret; u32 new_tss_base = get_desc_base(new_desc); u32 eip_offset = offsetof(struct tss_segment_32, eip); u32 ldt_sel_offset = offsetof(struct tss_segment_32, ldt_selector); - ret = ops->read_std(ctxt, old_tss_base, &tss_seg, sizeof tss_seg, - &ctxt->exception); + ret = linear_read_system(ctxt, old_tss_base, &tss_seg, sizeof tss_seg); if (ret != X86EMUL_CONTINUE) return ret; save_state_to_tss32(ctxt, &tss_seg); /* Only GP registers and segment selectors are saved */ - ret = ops->write_std(ctxt, old_tss_base + eip_offset, &tss_seg.eip, - ldt_sel_offset - eip_offset, &ctxt->exception); + ret = linear_write_system(ctxt, old_tss_base + eip_offset, &tss_seg.eip, + ldt_sel_offset - eip_offset); if (ret != X86EMUL_CONTINUE) return ret; - ret = ops->read_std(ctxt, new_tss_base, &tss_seg, sizeof tss_seg, - &ctxt->exception); + ret = linear_read_system(ctxt, new_tss_base, &tss_seg, sizeof tss_seg); if (ret != X86EMUL_CONTINUE) return ret; if (old_tss_sel != 0xffff) { tss_seg.prev_task_link = old_tss_sel; - ret = ops->write_std(ctxt, new_tss_base, - &tss_seg.prev_task_link, - sizeof tss_seg.prev_task_link, - &ctxt->exception); + ret = linear_write_system(ctxt, new_tss_base, + &tss_seg.prev_task_link, + sizeof tss_seg.prev_task_link); if (ret != X86EMUL_CONTINUE) return ret; } diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 1c96f09367ae2..a1afd80a68aac 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -288,8 +288,16 @@ void kvm_apic_set_version(struct kvm_vcpu *vcpu) if (!kvm_vcpu_has_lapic(vcpu)) return; + /* + * KVM emulates 82093AA datasheet (with in-kernel IOAPIC implementation) + * which doesn't have EOI register; Some buggy OSes (e.g. Windows with + * Hyper-V role) disable EOI broadcast in lapic not checking for IOAPIC + * version first and level-triggered interrupts never get EOIed in + * IOAPIC. + */ feat = kvm_find_cpuid_entry(apic->vcpu, 0x1, 0); - if (feat && (feat->ecx & (1 << (X86_FEATURE_X2APIC & 31)))) + if (feat && (feat->ecx & (1 << (X86_FEATURE_X2APIC & 31))) && + !ioapic_in_kernel(vcpu->kvm)) v |= APIC_LVR_DIRECTED_EOI; apic_set_reg(apic, APIC_LVR, v); } diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 42654375b73f0..df7827a981dd1 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include "trace.h" diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 528b4352fa99e..c5a4b1978cbf7 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -48,7 +48,7 @@ #include #include #include -#include +#include #include "trace.h" #include "pmu.h" @@ -2319,6 +2319,8 @@ static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr, return; } + WARN_ON_ONCE(vmx->emulation_required); + if (kvm_exception_is_soft(nr)) { vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, vmx->vcpu.arch.event_exit_inst_len); @@ -6037,12 +6039,12 @@ static int handle_invalid_guest_state(struct kvm_vcpu *vcpu) goto out; } - if (err != EMULATE_DONE) { - vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; - vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION; - vcpu->run->internal.ndata = 0; - return 0; - } + if (err != EMULATE_DONE) + goto emulation_error; + + if (vmx->emulation_required && !vmx->rmode.vm86_active && + vcpu->arch.exception.pending) + goto emulation_error; if (vcpu->arch.halt_request) { vcpu->arch.halt_request = 0; @@ -6058,6 +6060,12 @@ static int handle_invalid_guest_state(struct kvm_vcpu *vcpu) out: return ret; + +emulation_error: + vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; + vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION; + vcpu->run->internal.ndata = 0; + return 0; } static int __grow_ple_window(int val) @@ -6684,8 +6692,7 @@ static int nested_vmx_check_vmptr(struct kvm_vcpu *vcpu, int exit_reason, vmcs_read32(VMX_INSTRUCTION_INFO), false, &gva)) return 1; - if (kvm_read_guest_virt(&vcpu->arch.emulate_ctxt, gva, &vmptr, - sizeof(vmptr), &e)) { + if (kvm_read_guest_virt(vcpu, gva, &vmptr, sizeof(vmptr), &e)) { kvm_inject_page_fault(vcpu, &e); return 1; } @@ -6836,6 +6843,8 @@ static int handle_vmon(struct kvm_vcpu *vcpu) HRTIMER_MODE_REL); vmx->nested.preemption_timer.function = vmx_preemption_timer_fn; + vmx->nested.vpid02 = allocate_vpid(); + vmx->nested.vmxon = true; skip_emulated_instruction(vcpu); @@ -7203,8 +7212,8 @@ static int handle_vmread(struct kvm_vcpu *vcpu) vmx_instruction_info, true, &gva)) return 1; /* _system ok, as nested_vmx_check_permission verified cpl=0 */ - kvm_write_guest_virt_system(&vcpu->arch.emulate_ctxt, gva, - &field_value, (is_long_mode(vcpu) ? 8 : 4), NULL); + kvm_write_guest_virt_system(vcpu, gva, &field_value, + (is_long_mode(vcpu) ? 8 : 4), NULL); } nested_vmx_succeed(vcpu); @@ -7239,8 +7248,8 @@ static int handle_vmwrite(struct kvm_vcpu *vcpu) if (get_vmx_mem_address(vcpu, exit_qualification, vmx_instruction_info, false, &gva)) return 1; - if (kvm_read_guest_virt(&vcpu->arch.emulate_ctxt, gva, - &field_value, (is_64_bit_mode(vcpu) ? 8 : 4), &e)) { + if (kvm_read_guest_virt(vcpu, gva, &field_value, + (is_64_bit_mode(vcpu) ? 8 : 4), &e)) { kvm_inject_page_fault(vcpu, &e); return 1; } @@ -7330,9 +7339,9 @@ static int handle_vmptrst(struct kvm_vcpu *vcpu) vmx_instruction_info, true, &vmcs_gva)) return 1; /* ok to use *_system, as nested_vmx_check_permission verified cpl=0 */ - if (kvm_write_guest_virt_system(&vcpu->arch.emulate_ctxt, vmcs_gva, - (void *)&to_vmx(vcpu)->nested.current_vmptr, - sizeof(u64), &e)) { + if (kvm_write_guest_virt_system(vcpu, vmcs_gva, + (void *)&to_vmx(vcpu)->nested.current_vmptr, + sizeof(u64), &e)) { kvm_inject_page_fault(vcpu, &e); return 1; } @@ -7386,8 +7395,7 @@ static int handle_invept(struct kvm_vcpu *vcpu) if (get_vmx_mem_address(vcpu, vmcs_readl(EXIT_QUALIFICATION), vmx_instruction_info, false, &gva)) return 1; - if (kvm_read_guest_virt(&vcpu->arch.emulate_ctxt, gva, &operand, - sizeof(operand), &e)) { + if (kvm_read_guest_virt(vcpu, gva, &operand, sizeof(operand), &e)) { kvm_inject_page_fault(vcpu, &e); return 1; } @@ -7446,8 +7454,7 @@ static int handle_invvpid(struct kvm_vcpu *vcpu) if (get_vmx_mem_address(vcpu, vmcs_readl(EXIT_QUALIFICATION), vmx_instruction_info, false, &gva)) return 1; - if (kvm_read_guest_virt(&vcpu->arch.emulate_ctxt, gva, &vpid, - sizeof(u32), &e)) { + if (kvm_read_guest_virt(vcpu, gva, &vpid, sizeof(u32), &e)) { kvm_inject_page_fault(vcpu, &e); return 1; } @@ -8882,10 +8889,8 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id) goto free_vmcs; } - if (nested) { + if (nested) nested_vmx_setup_ctls_msrs(vmx); - vmx->nested.vpid02 = allocate_vpid(); - } vmx->nested.posted_intr_nv = -1; vmx->nested.current_vmptr = -1ull; @@ -8894,7 +8899,6 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id) return &vmx->vcpu; free_vmcs: - free_vpid(vmx->nested.vpid02); free_loaded_vmcs(vmx->loaded_vmcs); free_msrs: kfree(vmx->guest_msrs); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index f37f0c72b22a9..53d43d22a84b1 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3973,13 +3973,14 @@ long kvm_arch_vm_ioctl(struct file *filp, mutex_unlock(&kvm->lock); break; case KVM_XEN_HVM_CONFIG: { + struct kvm_xen_hvm_config xhc; r = -EFAULT; - if (copy_from_user(&kvm->arch.xen_hvm_config, argp, - sizeof(struct kvm_xen_hvm_config))) + if (copy_from_user(&xhc, argp, sizeof(xhc))) goto out; r = -EINVAL; - if (kvm->arch.xen_hvm_config.flags) + if (xhc.flags) goto out; + memcpy(&kvm->arch.xen_hvm_config, &xhc, sizeof(xhc)); r = 0; break; } @@ -4244,11 +4245,10 @@ static int kvm_fetch_guest_virt(struct x86_emulate_ctxt *ctxt, return X86EMUL_CONTINUE; } -int kvm_read_guest_virt(struct x86_emulate_ctxt *ctxt, +int kvm_read_guest_virt(struct kvm_vcpu *vcpu, gva_t addr, void *val, unsigned int bytes, struct x86_exception *exception) { - struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt); u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0; return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, access, @@ -4256,12 +4256,17 @@ int kvm_read_guest_virt(struct x86_emulate_ctxt *ctxt, } EXPORT_SYMBOL_GPL(kvm_read_guest_virt); -static int kvm_read_guest_virt_system(struct x86_emulate_ctxt *ctxt, - gva_t addr, void *val, unsigned int bytes, - struct x86_exception *exception) +static int emulator_read_std(struct x86_emulate_ctxt *ctxt, + gva_t addr, void *val, unsigned int bytes, + struct x86_exception *exception, bool system) { struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt); - return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, 0, exception); + u32 access = 0; + + if (!system && kvm_x86_ops->get_cpl(vcpu) == 3) + access |= PFERR_USER_MASK; + + return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, access, exception); } static int kvm_read_guest_phys_system(struct x86_emulate_ctxt *ctxt, @@ -4273,18 +4278,16 @@ static int kvm_read_guest_phys_system(struct x86_emulate_ctxt *ctxt, return r < 0 ? X86EMUL_IO_NEEDED : X86EMUL_CONTINUE; } -int kvm_write_guest_virt_system(struct x86_emulate_ctxt *ctxt, - gva_t addr, void *val, - unsigned int bytes, - struct x86_exception *exception) +static int kvm_write_guest_virt_helper(gva_t addr, void *val, unsigned int bytes, + struct kvm_vcpu *vcpu, u32 access, + struct x86_exception *exception) { - struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt); void *data = val; int r = X86EMUL_CONTINUE; while (bytes) { gpa_t gpa = vcpu->arch.walk_mmu->gva_to_gpa(vcpu, addr, - PFERR_WRITE_MASK, + access, exception); unsigned offset = addr & (PAGE_SIZE-1); unsigned towrite = min(bytes, (unsigned)PAGE_SIZE - offset); @@ -4305,6 +4308,27 @@ int kvm_write_guest_virt_system(struct x86_emulate_ctxt *ctxt, out: return r; } + +static int emulator_write_std(struct x86_emulate_ctxt *ctxt, gva_t addr, void *val, + unsigned int bytes, struct x86_exception *exception, + bool system) +{ + struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt); + u32 access = PFERR_WRITE_MASK; + + if (!system && kvm_x86_ops->get_cpl(vcpu) == 3) + access |= PFERR_USER_MASK; + + return kvm_write_guest_virt_helper(addr, val, bytes, vcpu, + access, exception); +} + +int kvm_write_guest_virt_system(struct kvm_vcpu *vcpu, gva_t addr, void *val, + unsigned int bytes, struct x86_exception *exception) +{ + return kvm_write_guest_virt_helper(addr, val, bytes, vcpu, + PFERR_WRITE_MASK, exception); +} EXPORT_SYMBOL_GPL(kvm_write_guest_virt_system); static int vcpu_mmio_gva_to_gpa(struct kvm_vcpu *vcpu, unsigned long gva, @@ -5024,8 +5048,8 @@ static void emulator_set_hflags(struct x86_emulate_ctxt *ctxt, unsigned emul_fla static const struct x86_emulate_ops emulate_ops = { .read_gpr = emulator_read_gpr, .write_gpr = emulator_write_gpr, - .read_std = kvm_read_guest_virt_system, - .write_std = kvm_write_guest_virt_system, + .read_std = emulator_read_std, + .write_std = emulator_write_std, .read_phys = kvm_read_guest_phys_system, .fetch = kvm_fetch_guest_virt, .read_emulated = emulator_read_emulated, diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index f2afa5fe48a6d..53a750a10598d 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h @@ -164,11 +164,11 @@ int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq, int inc_eip); void kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr); -int kvm_read_guest_virt(struct x86_emulate_ctxt *ctxt, +int kvm_read_guest_virt(struct kvm_vcpu *vcpu, gva_t addr, void *val, unsigned int bytes, struct x86_exception *exception); -int kvm_write_guest_virt_system(struct x86_emulate_ctxt *ctxt, +int kvm_write_guest_virt_system(struct kvm_vcpu *vcpu, gva_t addr, void *val, unsigned int bytes, struct x86_exception *exception); diff --git a/arch/x86/lib/clear_page_64.S b/arch/x86/lib/clear_page_64.S index a2fe51b00ccef..65be7cfaf9472 100644 --- a/arch/x86/lib/clear_page_64.S +++ b/arch/x86/lib/clear_page_64.S @@ -1,5 +1,5 @@ #include -#include +#include #include /* diff --git a/arch/x86/lib/cmdline.c b/arch/x86/lib/cmdline.c index a744506856b1d..88ce150186c64 100644 --- a/arch/x86/lib/cmdline.c +++ b/arch/x86/lib/cmdline.c @@ -21,12 +21,14 @@ static inline int myisspace(u8 c) * @option: option string to look for * * Returns the position of that @option (starts counting with 1) - * or 0 on not found. + * or 0 on not found. @option will only be found if it is found + * as an entire word in @cmdline. For instance, if @option="car" + * then a cmdline which contains "cart" will not match. */ int cmdline_find_option_bool(const char *cmdline, const char *option) { char c; - int len, pos = 0, wstart = 0; + int pos = 0, wstart = 0; const char *opptr = NULL; enum { st_wordstart = 0, /* Start of word/after whitespace */ @@ -37,11 +39,14 @@ int cmdline_find_option_bool(const char *cmdline, const char *option) if (!cmdline) return -1; /* No command line */ - len = min_t(int, strlen(cmdline), COMMAND_LINE_SIZE); - if (!len) + if (!strlen(cmdline)) return 0; - while (len--) { + /* + * This 'pos' check ensures we do not overrun + * a non-NULL-terminated 'cmdline' + */ + while (pos < COMMAND_LINE_SIZE) { c = *(char *)cmdline++; pos++; @@ -58,17 +63,26 @@ int cmdline_find_option_bool(const char *cmdline, const char *option) /* fall through */ case st_wordcmp: - if (!*opptr) + if (!*opptr) { + /* + * We matched all the way to the end of the + * option we were looking for. If the + * command-line has a space _or_ ends, then + * we matched! + */ if (!c || myisspace(c)) return wstart; else state = st_wordskip; - else if (!c) + } else if (!c) { + /* + * Hit the NULL terminator on the end of + * cmdline. + */ return 0; - else if (c != *opptr++) + } else if (c != *opptr++) { state = st_wordskip; - else if (!len) /* last word and is matching */ - return wstart; + } break; case st_wordskip: diff --git a/arch/x86/lib/copy_page_64.S b/arch/x86/lib/copy_page_64.S index 009f98216b7eb..24ef1c2104d42 100644 --- a/arch/x86/lib/copy_page_64.S +++ b/arch/x86/lib/copy_page_64.S @@ -1,7 +1,7 @@ /* Written 2003 by Andi Kleen, based on a kernel by Evandro Menezes */ #include -#include +#include #include /* diff --git a/arch/x86/lib/copy_user_64.S b/arch/x86/lib/copy_user_64.S index 423644c230e76..accf7f2f557f3 100644 --- a/arch/x86/lib/copy_user_64.S +++ b/arch/x86/lib/copy_user_64.S @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/x86/lib/memcpy_64.S b/arch/x86/lib/memcpy_64.S index 16698bba87deb..a0de849435ad6 100644 --- a/arch/x86/lib/memcpy_64.S +++ b/arch/x86/lib/memcpy_64.S @@ -1,7 +1,7 @@ /* Copyright 2002 Andi Kleen */ #include -#include +#include #include /* diff --git a/arch/x86/lib/memmove_64.S b/arch/x86/lib/memmove_64.S index ca2afdd6d98ed..90ce01bee00c1 100644 --- a/arch/x86/lib/memmove_64.S +++ b/arch/x86/lib/memmove_64.S @@ -6,7 +6,7 @@ * - Copyright 2011 Fenghua Yu */ #include -#include +#include #include #undef memmove diff --git a/arch/x86/lib/memset_64.S b/arch/x86/lib/memset_64.S index 2661fad058271..c9c81227ea37d 100644 --- a/arch/x86/lib/memset_64.S +++ b/arch/x86/lib/memset_64.S @@ -1,7 +1,7 @@ /* Copyright 2002 Andi Kleen, SuSE Labs */ #include -#include +#include #include .weak memset diff --git a/arch/x86/lib/retpoline.S b/arch/x86/lib/retpoline.S index 3d06b482ebc7e..7bbb853e36bd4 100644 --- a/arch/x86/lib/retpoline.S +++ b/arch/x86/lib/retpoline.S @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index 151fd33e90433..f00eb52c16a6a 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c @@ -4,6 +4,8 @@ #include #include #include /* for max_low_pfn */ +#include +#include #include #include @@ -767,3 +769,26 @@ void update_cache_mode_entry(unsigned entry, enum page_cache_mode cache) __cachemode2pte_tbl[cache] = __cm_idx2pte(entry); __pte2cachemode_tbl[entry] = cache; } + +#ifdef CONFIG_SWAP +unsigned long max_swapfile_size(void) +{ + unsigned long pages; + + pages = generic_max_swapfile_size(); + + if (boot_cpu_has_bug(X86_BUG_L1TF)) { + /* Limit the swap file size to MAX_PA/2 for L1TF workaround */ + unsigned long long l1tf_limit = l1tf_pfn_limit(); + /* + * We encode swap offsets also with 3 bits below those for pfn + * which makes the usable limit higher. + */ +#if CONFIG_PGTABLE_LEVELS > 2 + l1tf_limit <<= PAGE_SHIFT - SWP_OFFSET_FIRST_BIT; +#endif + pages = min_t(unsigned long long, l1tf_limit, pages); + } + return pages; +} +#endif diff --git a/arch/x86/mm/kmmio.c b/arch/x86/mm/kmmio.c index 76604c8a2a487..7bf14e74fc8f1 100644 --- a/arch/x86/mm/kmmio.c +++ b/arch/x86/mm/kmmio.c @@ -125,24 +125,29 @@ static struct kmmio_fault_page *get_kmmio_fault_page(unsigned long addr) static void clear_pmd_presence(pmd_t *pmd, bool clear, pmdval_t *old) { + pmd_t new_pmd; pmdval_t v = pmd_val(*pmd); if (clear) { - *old = v & _PAGE_PRESENT; - v &= ~_PAGE_PRESENT; - } else /* presume this has been called with clear==true previously */ - v |= *old; - set_pmd(pmd, __pmd(v)); + *old = v; + new_pmd = pmd_mknotpresent(*pmd); + } else { + /* Presume this has been called with clear==true previously */ + new_pmd = __pmd(*old); + } + set_pmd(pmd, new_pmd); } static void clear_pte_presence(pte_t *pte, bool clear, pteval_t *old) { pteval_t v = pte_val(*pte); if (clear) { - *old = v & _PAGE_PRESENT; - v &= ~_PAGE_PRESENT; - } else /* presume this has been called with clear==true previously */ - v |= *old; - set_pte_atomic(pte, __pte(v)); + *old = v; + /* Nothing should care about address */ + pte_clear(&init_mm, 0, pte); + } else { + /* Presume this has been called with clear==true previously */ + set_pte_atomic(pte, __pte(*old)); + } } static int clear_page_presence(struct kmmio_fault_page *f, bool clear) diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c index d2dc0438d654a..74609a957c491 100644 --- a/arch/x86/mm/mmap.c +++ b/arch/x86/mm/mmap.c @@ -121,3 +121,24 @@ const char *arch_vma_name(struct vm_area_struct *vma) return "[mpx]"; return NULL; } + +/* + * Only allow root to set high MMIO mappings to PROT_NONE. + * This prevents an unpriv. user to set them to PROT_NONE and invert + * them, then pointing to valid memory for L1TF speculation. + * + * Note: for locked down kernels may want to disable the root override. + */ +bool pfn_modify_allowed(unsigned long pfn, pgprot_t prot) +{ + if (!boot_cpu_has_bug(X86_BUG_L1TF)) + return true; + if (!__pte_needs_invert(pgprot_val(prot))) + return true; + /* If it's real memory always allow */ + if (pfn_valid(pfn)) + return true; + if (pfn >= l1tf_pfn_limit() && !capable(CAP_SYS_ADMIN)) + return false; + return true; +} diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index ac9c7797b6326..7bd28d45e3270 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -1006,8 +1006,8 @@ static int populate_pmd(struct cpa_data *cpa, pmd = pmd_offset(pud, start); - set_pmd(pmd, __pmd(cpa->pfn | _PAGE_PSE | - massage_pgprot(pmd_pgprot))); + set_pmd(pmd, pmd_mkhuge(pfn_pmd(cpa->pfn >> PAGE_SHIFT, + canon_pgprot(pmd_pgprot)))); start += PMD_SIZE; cpa->pfn += PMD_SIZE; @@ -1079,8 +1079,8 @@ 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 | - massage_pgprot(pud_pgprot))); + set_pud(pud, pud_mkhuge(pfn_pud(cpa->pfn, + canon_pgprot(pud_pgprot)))); start += PUD_SIZE; cpa->pfn += PUD_SIZE; diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c index c013326a0d7ac..55c7446311a7b 100644 --- a/arch/x86/mm/pgtable.c +++ b/arch/x86/mm/pgtable.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -600,6 +601,10 @@ int pud_set_huge(pud_t *pud, phys_addr_t addr, pgprot_t prot) (mtrr != MTRR_TYPE_WRBACK)) return 0; + /* Bail out if we are we on a populated non-leaf entry: */ + if (pud_present(*pud) && !pud_huge(*pud)) + return 0; + prot = pgprot_4k_2_large(prot); set_pte((pte_t *)pud, pfn_pte( @@ -628,6 +633,10 @@ int pmd_set_huge(pmd_t *pmd, phys_addr_t addr, pgprot_t prot) return 0; } + /* Bail out if we are we on a populated non-leaf entry: */ + if (pmd_present(*pmd) && !pmd_huge(*pmd)) + return 0; + prot = pgprot_4k_2_large(prot); set_pte((pte_t *)pmd, pfn_pte( @@ -667,28 +676,50 @@ int pmd_clear_huge(pmd_t *pmd) return 0; } +#ifdef CONFIG_X86_64 /** * pud_free_pmd_page - Clear pud entry and free pmd page. * @pud: Pointer to a PUD. + * @addr: Virtual address associated with pud. * - * Context: The pud range has been unmaped and TLB purged. + * Context: The pud range has been unmapped and TLB purged. * Return: 1 if clearing the entry succeeded. 0 otherwise. + * + * NOTE: Callers must allow a single page allocation. */ -int pud_free_pmd_page(pud_t *pud) +int pud_free_pmd_page(pud_t *pud, unsigned long addr) { - pmd_t *pmd; + pmd_t *pmd, *pmd_sv; + pte_t *pte; int i; if (pud_none(*pud)) return 1; pmd = (pmd_t *)pud_page_vaddr(*pud); + pmd_sv = (pmd_t *)__get_free_page(GFP_KERNEL); + if (!pmd_sv) + return 0; - for (i = 0; i < PTRS_PER_PMD; i++) - if (!pmd_free_pte_page(&pmd[i])) - return 0; + for (i = 0; i < PTRS_PER_PMD; i++) { + pmd_sv[i] = pmd[i]; + if (!pmd_none(pmd[i])) + pmd_clear(&pmd[i]); + } pud_clear(pud); + + /* INVLPG to clear all paging-structure caches */ + flush_tlb_kernel_range(addr, addr + PAGE_SIZE-1); + + for (i = 0; i < PTRS_PER_PMD; i++) { + if (!pmd_none(pmd_sv[i])) { + pte = (pte_t *)pmd_page_vaddr(pmd_sv[i]); + free_page((unsigned long)pte); + } + } + + free_page((unsigned long)pmd_sv); free_page((unsigned long)pmd); return 1; @@ -697,11 +728,12 @@ int pud_free_pmd_page(pud_t *pud) /** * pmd_free_pte_page - Clear pmd entry and free pte page. * @pmd: Pointer to a PMD. + * @addr: Virtual address associated with pmd. * - * Context: The pmd range has been unmaped and TLB purged. + * Context: The pmd range has been unmapped and TLB purged. * Return: 1 if clearing the entry succeeded. 0 otherwise. */ -int pmd_free_pte_page(pmd_t *pmd) +int pmd_free_pte_page(pmd_t *pmd, unsigned long addr) { pte_t *pte; @@ -710,8 +742,30 @@ int pmd_free_pte_page(pmd_t *pmd) pte = (pte_t *)pmd_page_vaddr(*pmd); pmd_clear(pmd); + + /* INVLPG to clear all paging-structure caches */ + flush_tlb_kernel_range(addr, addr + PAGE_SIZE-1); + free_page((unsigned long)pte); return 1; } + +#else /* !CONFIG_X86_64 */ + +int pud_free_pmd_page(pud_t *pud, unsigned long addr) +{ + return pud_none(*pud); +} + +/* + * Disable free page handling on x86-PAE. This assures that ioremap() + * does not update sync'd pmd entries. See vmalloc_sync_one(). + */ +int pmd_free_pte_page(pmd_t *pmd, unsigned long addr) +{ + return pmd_none(*pmd); +} + +#endif /* CONFIG_X86_64 */ #endif /* CONFIG_HAVE_ARCH_HUGE_VMAP */ diff --git a/arch/x86/mm/setup_nx.c b/arch/x86/mm/setup_nx.c index 90555bf60aa45..f65a33f505b68 100644 --- a/arch/x86/mm/setup_nx.c +++ b/arch/x86/mm/setup_nx.c @@ -4,6 +4,7 @@ #include #include +#include static int disable_nx; @@ -31,7 +32,7 @@ early_param("noexec", noexec_setup); void x86_configure_nx(void) { - if (cpu_has_nx && !disable_nx) + if (boot_cpu_has(X86_FEATURE_NX) && !disable_nx) __supported_pte_mask |= _PAGE_NX; else __supported_pte_mask &= ~_PAGE_NX; @@ -39,7 +40,7 @@ void x86_configure_nx(void) void __init x86_report_nx(void) { - if (!cpu_has_nx) { + if (!boot_cpu_has(X86_FEATURE_NX)) { printk(KERN_NOTICE "Notice: NX (Execute Disable) protection " "missing in CPU!\n"); } else { diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c index 7cad01af6dcd2..6d683bbb35021 100644 --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -29,6 +30,8 @@ * Implement flush IPI by CALL_FUNCTION_VECTOR, Alex Shi */ +atomic64_t last_mm_ctx_id = ATOMIC64_INIT(1); + struct flush_tlb_info { struct mm_struct *flush_mm; unsigned long flush_start; @@ -104,6 +107,36 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next, unsigned cpu = smp_processor_id(); if (likely(prev != next)) { + u64 last_ctx_id = this_cpu_read(cpu_tlbstate.last_ctx_id); + + /* + * Avoid user/user BTB poisoning by flushing the branch + * predictor when switching between processes. This stops + * one process from doing Spectre-v2 attacks on another. + * + * As an optimization, flush indirect branches only when + * switching into processes that disable dumping. This + * protects high value processes like gpg, without having + * too high performance overhead. IBPB is *expensive*! + * + * This will not flush branches when switching into kernel + * threads. It will also not flush if we switch to idle + * thread and back to the same process. It will flush if we + * switch to a different non-dumpable process. + */ + if (tsk && tsk->mm && + tsk->mm->context.ctx_id != last_ctx_id && + get_dumpable(tsk->mm) != SUID_DUMP_USER) + indirect_branch_prediction_barrier(); + + /* + * Record last user mm's context id, so we can avoid + * flushing branch buffer with IBPB if we switch back + * to the same user. + */ + if (next != &init_mm) + this_cpu_write(cpu_tlbstate.last_ctx_id, next->context.ctx_id); + this_cpu_write(cpu_tlbstate.state, TLBSTATE_OK); this_cpu_write(cpu_tlbstate.active_mm, next); cpumask_set_cpu(cpu, mm_cpumask(next)); diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c index 50d86c0e9ba49..660a83c8287b6 100644 --- a/arch/x86/oprofile/op_model_amd.c +++ b/arch/x86/oprofile/op_model_amd.c @@ -24,7 +24,6 @@ #include #include #include -#include #include "op_x86_model.h" #include "op_counter.h" diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index a0ac0f9c307f6..f5a8cd96bae48 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -40,6 +40,7 @@ #include #include #include +#include /* * We allocate runtime services regions bottom-up, starting from -4G, i.e. @@ -347,6 +348,7 @@ extern efi_status_t efi64_thunk(u32, ...); \ efi_sync_low_kernel_mappings(); \ local_irq_save(flags); \ + firmware_restrict_branch_speculation_start(); \ \ efi_scratch.prev_cr3 = read_cr3(); \ write_cr3((unsigned long)efi_scratch.efi_pgt); \ @@ -357,6 +359,7 @@ extern efi_status_t efi64_thunk(u32, ...); \ write_cr3(efi_scratch.prev_cr3); \ __flush_tlb_all(); \ + firmware_restrict_branch_speculation_end(); \ local_irq_restore(flags); \ \ __s; \ diff --git a/arch/x86/power/hibernate_32.c b/arch/x86/power/hibernate_32.c index 291226b952a99..77ac4e4deb168 100644 --- a/arch/x86/power/hibernate_32.c +++ b/arch/x86/power/hibernate_32.c @@ -142,7 +142,7 @@ static inline void resume_init_first_level_page_table(pgd_t *pg_dir) #endif } -int swsusp_arch_resume(void) +asmlinkage int swsusp_arch_resume(void) { int error; diff --git a/arch/x86/power/hibernate_64.c b/arch/x86/power/hibernate_64.c index 009947d419a61..0e0c773edffc2 100644 --- a/arch/x86/power/hibernate_64.c +++ b/arch/x86/power/hibernate_64.c @@ -78,7 +78,7 @@ static int set_up_temporary_mappings(void) return 0; } -int swsusp_arch_resume(void) +asmlinkage int swsusp_arch_resume(void) { int error; diff --git a/arch/x86/um/asm/barrier.h b/arch/x86/um/asm/barrier.h index 755481f14d90f..764ac2fc53fe8 100644 --- a/arch/x86/um/asm/barrier.h +++ b/arch/x86/um/asm/barrier.h @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index cbef64b508e10..82fd84d5e1aa7 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -460,6 +460,12 @@ static void __init xen_init_cpuid_mask(void) cpuid_leaf1_ecx_set_mask = (1 << (X86_FEATURE_MWAIT % 32)); } +static void __init xen_init_capabilities(void) +{ + if (xen_pv_domain()) + setup_force_cpu_cap(X86_FEATURE_XENPV); +} + static void xen_set_debugreg(int reg, unsigned long val) { HYPERVISOR_set_debugreg(reg, val); @@ -1587,6 +1593,7 @@ asmlinkage __visible void __init xen_start_kernel(void) xen_init_irq_ops(); xen_init_cpuid_mask(); + xen_init_capabilities(); #ifdef CONFIG_X86_LOCAL_APIC /* @@ -1883,14 +1890,6 @@ bool xen_hvm_need_lapic(void) } EXPORT_SYMBOL_GPL(xen_hvm_need_lapic); -static void xen_set_cpu_features(struct cpuinfo_x86 *c) -{ - if (xen_pv_domain()) { - clear_cpu_bug(c, X86_BUG_SYSRET_SS_ATTRS); - set_cpu_cap(c, X86_FEATURE_XENPV); - } -} - const struct hypervisor_x86 x86_hyper_xen = { .name = "Xen", .detect = xen_platform, @@ -1898,7 +1897,6 @@ const struct hypervisor_x86 x86_hyper_xen = { .init_platform = xen_hvm_guest_init, #endif .x2apic_available = xen_x2apic_para_available, - .set_cpu_features = xen_set_cpu_features, }; EXPORT_SYMBOL(x86_hyper_xen); diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 63146c378f1e7..2b05f681a1fdd 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c @@ -1316,8 +1316,6 @@ void xen_flush_tlb_all(void) struct mmuext_op *op; struct multicall_space mcs; - trace_xen_mmu_flush_tlb_all(0); - preempt_disable(); mcs = xen_mc_entry(sizeof(*op)); @@ -1335,8 +1333,6 @@ static void xen_flush_tlb(void) struct mmuext_op *op; struct multicall_space mcs; - trace_xen_mmu_flush_tlb(0); - preempt_disable(); mcs = xen_mc_entry(sizeof(*op)); diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index 3f4ebf0261f28..29e50d1229bc0 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -87,6 +88,8 @@ static void cpu_bringup(void) cpu_data(cpu).x86_max_cores = 1; set_cpu_sibling_map(cpu); + speculative_store_bypass_ht_init(); + xen_setup_cpu_clockevents(); notify_cpu_starting(cpu); @@ -357,6 +360,8 @@ static void __init xen_smp_prepare_cpus(unsigned int max_cpus) } set_cpu_sibling_map(0); + speculative_store_bypass_ht_init(); + xen_pmu_init(0); if (xen_smp_intr_init(0)) diff --git a/arch/x86/xen/suspend.c b/arch/x86/xen/suspend.c index 7f664c416faf5..4ecd0de08557e 100644 --- a/arch/x86/xen/suspend.c +++ b/arch/x86/xen/suspend.c @@ -1,11 +1,14 @@ #include #include +#include #include #include #include #include +#include +#include #include #include #include @@ -68,6 +71,8 @@ static void xen_pv_post_suspend(int suspend_cancelled) xen_mm_unpin_all(); } +static DEFINE_PER_CPU(u64, spec_ctrl); + void xen_arch_pre_suspend(void) { if (xen_pv_domain()) @@ -84,6 +89,9 @@ void xen_arch_post_suspend(int cancelled) static void xen_vcpu_notify_restore(void *data) { + if (xen_pv_domain() && boot_cpu_has(X86_FEATURE_SPEC_CTRL)) + wrmsrl(MSR_IA32_SPEC_CTRL, this_cpu_read(spec_ctrl)); + /* Boot processor notified via generic timekeeping_resume() */ if (smp_processor_id() == 0) return; @@ -93,7 +101,15 @@ static void xen_vcpu_notify_restore(void *data) static void xen_vcpu_notify_suspend(void *data) { + u64 tmp; + tick_suspend_local(); + + if (xen_pv_domain() && boot_cpu_has(X86_FEATURE_SPEC_CTRL)) { + rdmsrl(MSR_IA32_SPEC_CTRL, tmp); + this_cpu_write(spec_ctrl, tmp); + wrmsrl(MSR_IA32_SPEC_CTRL, 0); + } } void xen_arch_resume(void) diff --git a/arch/xtensa/include/asm/futex.h b/arch/xtensa/include/asm/futex.h index 72bfc1cbc2b54..5bfbc1c401d4c 100644 --- a/arch/xtensa/include/asm/futex.h +++ b/arch/xtensa/include/asm/futex.h @@ -44,18 +44,10 @@ : "r" (uaddr), "I" (-EFAULT), "r" (oparg) \ : "memory") -static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) +static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval, + u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) - return -EFAULT; #if !XCHAL_HAVE_S32C1I return -ENOSYS; @@ -89,19 +81,10 @@ static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) pagefault_enable(); - if (ret) - return ret; + if (!ret) + *oval = oldval; - switch (cmp) { - case FUTEX_OP_CMP_EQ: return (oldval == cmparg); - case FUTEX_OP_CMP_NE: return (oldval != cmparg); - case FUTEX_OP_CMP_LT: return (oldval < cmparg); - case FUTEX_OP_CMP_GE: return (oldval >= cmparg); - case FUTEX_OP_CMP_LE: return (oldval <= cmparg); - case FUTEX_OP_CMP_GT: return (oldval > cmparg); - } - - return -ENOSYS; + return ret; } static inline int diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c index 42d441f7898b9..1edce040f470a 100644 --- a/arch/xtensa/kernel/traps.c +++ b/arch/xtensa/kernel/traps.c @@ -309,7 +309,7 @@ do_unaligned_user (struct pt_regs *regs) info.si_errno = 0; info.si_code = BUS_ADRALN; info.si_addr = (void *) regs->excvaddr; - force_sig_info(SIGSEGV, &info, current); + force_sig_info(SIGBUS, &info, current); } #endif diff --git a/block/blk-core.c b/block/blk-core.c index a2378344b12c4..34e67d2061e13 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -653,21 +653,17 @@ EXPORT_SYMBOL(blk_alloc_queue); int blk_queue_enter(struct request_queue *q, gfp_t gfp) { while (true) { - int ret; - if (percpu_ref_tryget_live(&q->q_usage_counter)) return 0; if (!gfpflags_allow_blocking(gfp)) return -EBUSY; - ret = wait_event_interruptible(q->mq_freeze_wq, - !atomic_read(&q->mq_freeze_depth) || - blk_queue_dying(q)); + wait_event(q->mq_freeze_wq, + !atomic_read(&q->mq_freeze_depth) || + blk_queue_dying(q)); if (blk_queue_dying(q)) return -ENODEV; - if (ret) - return ret; } } diff --git a/build.config.cuttlefish.x86_64 b/build.config.cuttlefish.x86_64 index b3d89109fe751..ceef306dc4042 100644 --- a/build.config.cuttlefish.x86_64 +++ b/build.config.cuttlefish.x86_64 @@ -6,7 +6,7 @@ DEFCONFIG=x86_64_cuttlefish_defconfig EXTRA_CMDS='' KERNEL_DIR=common POST_DEFCONFIG_CMDS="check_defconfig" -CLANG_PREBUILT_BIN=prebuilts/clang/host/linux-x86/clang-4630689/bin +CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r328903/bin LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/bin FILES=" arch/x86/boot/bzImage diff --git a/crypto/ablkcipher.c b/crypto/ablkcipher.c index e5b5721809e21..149e7a7f04fe7 100644 --- a/crypto/ablkcipher.c +++ b/crypto/ablkcipher.c @@ -73,11 +73,9 @@ static inline u8 *ablkcipher_get_spot(u8 *start, unsigned int len) return max(start, end_page); } -static inline unsigned int ablkcipher_done_slow(struct ablkcipher_walk *walk, - unsigned int bsize) +static inline void ablkcipher_done_slow(struct ablkcipher_walk *walk, + unsigned int n) { - unsigned int n = bsize; - for (;;) { unsigned int len_this_page = scatterwalk_pagelen(&walk->out); @@ -89,17 +87,13 @@ static inline unsigned int ablkcipher_done_slow(struct ablkcipher_walk *walk, n -= len_this_page; scatterwalk_start(&walk->out, sg_next(walk->out.sg)); } - - return bsize; } -static inline unsigned int ablkcipher_done_fast(struct ablkcipher_walk *walk, - unsigned int n) +static inline void ablkcipher_done_fast(struct ablkcipher_walk *walk, + unsigned int n) { scatterwalk_advance(&walk->in, n); scatterwalk_advance(&walk->out, n); - - return n; } static int ablkcipher_walk_next(struct ablkcipher_request *req, @@ -109,39 +103,40 @@ int ablkcipher_walk_done(struct ablkcipher_request *req, struct ablkcipher_walk *walk, int err) { struct crypto_tfm *tfm = req->base.tfm; - unsigned int nbytes = 0; + unsigned int n; /* bytes processed */ + bool more; - if (likely(err >= 0)) { - unsigned int n = walk->nbytes - err; + if (unlikely(err < 0)) + goto finish; - if (likely(!(walk->flags & ABLKCIPHER_WALK_SLOW))) - n = ablkcipher_done_fast(walk, n); - else if (WARN_ON(err)) { - err = -EINVAL; - goto err; - } else - n = ablkcipher_done_slow(walk, n); + n = walk->nbytes - err; + walk->total -= n; + more = (walk->total != 0); - nbytes = walk->total - n; - err = 0; + if (likely(!(walk->flags & ABLKCIPHER_WALK_SLOW))) { + ablkcipher_done_fast(walk, n); + } else { + if (WARN_ON(err)) { + /* unexpected case; didn't process all bytes */ + err = -EINVAL; + goto finish; + } + ablkcipher_done_slow(walk, n); } - scatterwalk_done(&walk->in, 0, nbytes); - scatterwalk_done(&walk->out, 1, nbytes); - -err: - walk->total = nbytes; - walk->nbytes = nbytes; + scatterwalk_done(&walk->in, 0, more); + scatterwalk_done(&walk->out, 1, more); - if (nbytes) { + if (more) { crypto_yield(req->base.flags); return ablkcipher_walk_next(req, walk); } - + err = 0; +finish: + walk->nbytes = 0; if (walk->iv != req->info) memcpy(req->info, walk->iv, tfm->crt_ablkcipher.ivsize); kfree(walk->iv_buffer); - return err; } EXPORT_SYMBOL_GPL(ablkcipher_walk_done); diff --git a/crypto/authenc.c b/crypto/authenc.c index 55a354d572513..b7290c5b1eaa8 100644 --- a/crypto/authenc.c +++ b/crypto/authenc.c @@ -108,6 +108,7 @@ static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key, CRYPTO_TFM_RES_MASK); out: + memzero_explicit(&keys, sizeof(keys)); return err; badkey: diff --git a/crypto/authencesn.c b/crypto/authencesn.c index 52154ef21b5e8..fa0c4567f697d 100644 --- a/crypto/authencesn.c +++ b/crypto/authencesn.c @@ -90,6 +90,7 @@ static int crypto_authenc_esn_setkey(struct crypto_aead *authenc_esn, const u8 * CRYPTO_TFM_RES_MASK); out: + memzero_explicit(&keys, sizeof(keys)); return err; badkey: diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c index 7bbfadc195a64..97ccb3108f4ad 100644 --- a/crypto/blkcipher.c +++ b/crypto/blkcipher.c @@ -71,19 +71,18 @@ static inline u8 *blkcipher_get_spot(u8 *start, unsigned int len) return max(start, end_page); } -static inline unsigned int blkcipher_done_slow(struct blkcipher_walk *walk, - unsigned int bsize) +static inline void blkcipher_done_slow(struct blkcipher_walk *walk, + unsigned int bsize) { u8 *addr; addr = (u8 *)ALIGN((unsigned long)walk->buffer, walk->alignmask + 1); addr = blkcipher_get_spot(addr, bsize); scatterwalk_copychunks(addr, &walk->out, bsize, 1); - return bsize; } -static inline unsigned int blkcipher_done_fast(struct blkcipher_walk *walk, - unsigned int n) +static inline void blkcipher_done_fast(struct blkcipher_walk *walk, + unsigned int n) { if (walk->flags & BLKCIPHER_WALK_COPY) { blkcipher_map_dst(walk); @@ -97,49 +96,48 @@ static inline unsigned int blkcipher_done_fast(struct blkcipher_walk *walk, scatterwalk_advance(&walk->in, n); scatterwalk_advance(&walk->out, n); - - return n; } int blkcipher_walk_done(struct blkcipher_desc *desc, struct blkcipher_walk *walk, int err) { - unsigned int nbytes = 0; + unsigned int n; /* bytes processed */ + bool more; - if (likely(err >= 0)) { - unsigned int n = walk->nbytes - err; + if (unlikely(err < 0)) + goto finish; - if (likely(!(walk->flags & BLKCIPHER_WALK_SLOW))) - n = blkcipher_done_fast(walk, n); - else if (WARN_ON(err)) { - err = -EINVAL; - goto err; - } else - n = blkcipher_done_slow(walk, n); + n = walk->nbytes - err; + walk->total -= n; + more = (walk->total != 0); - nbytes = walk->total - n; - err = 0; + if (likely(!(walk->flags & BLKCIPHER_WALK_SLOW))) { + blkcipher_done_fast(walk, n); + } else { + if (WARN_ON(err)) { + /* unexpected case; didn't process all bytes */ + err = -EINVAL; + goto finish; + } + blkcipher_done_slow(walk, n); } - scatterwalk_done(&walk->in, 0, nbytes); - scatterwalk_done(&walk->out, 1, nbytes); - -err: - walk->total = nbytes; - walk->nbytes = nbytes; + scatterwalk_done(&walk->in, 0, more); + scatterwalk_done(&walk->out, 1, more); - if (nbytes) { + if (more) { crypto_yield(desc->flags); return blkcipher_walk_next(desc, walk); } - + err = 0; +finish: + walk->nbytes = 0; if (walk->iv != desc->info) memcpy(desc->info, walk->iv, walk->ivsize); if (walk->buffer != walk->page) kfree(walk->buffer); if (walk->page) free_page((unsigned long)walk->page); - return err; } EXPORT_SYMBOL_GPL(blkcipher_walk_done); diff --git a/crypto/vmac.c b/crypto/vmac.c index df76a816cfb22..bb2fc787d6156 100644 --- a/crypto/vmac.c +++ b/crypto/vmac.c @@ -1,6 +1,10 @@ /* - * Modified to interface to the Linux kernel + * VMAC: Message Authentication Code using Universal Hashing + * + * Reference: https://tools.ietf.org/html/draft-krovetz-vmac-01 + * * Copyright (c) 2009, Intel Corporation. + * Copyright (c) 2018, Google Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -16,14 +20,15 @@ * Place - Suite 330, Boston, MA 02111-1307 USA. */ -/* -------------------------------------------------------------------------- - * VMAC and VHASH Implementation by Ted Krovetz (tdk@acm.org) and Wei Dai. - * This implementation is herby placed in the public domain. - * The authors offers no warranty. Use at your own risk. - * Please send bug reports to the authors. - * Last modified: 17 APR 08, 1700 PDT - * ----------------------------------------------------------------------- */ +/* + * Derived from: + * VMAC and VHASH Implementation by Ted Krovetz (tdk@acm.org) and Wei Dai. + * This implementation is herby placed in the public domain. + * The authors offers no warranty. Use at your own risk. + * Last modified: 17 APR 08, 1700 PDT + */ +#include #include #include #include @@ -31,9 +36,35 @@ #include #include #include -#include #include +/* + * User definable settings. + */ +#define VMAC_TAG_LEN 64 +#define VMAC_KEY_SIZE 128/* Must be 128, 192 or 256 */ +#define VMAC_KEY_LEN (VMAC_KEY_SIZE/8) +#define VMAC_NHBYTES 128/* Must 2^i for any 3 < i < 13 Standard = 128*/ + +/* per-transform (per-key) context */ +struct vmac_tfm_ctx { + struct crypto_cipher *cipher; + u64 nhkey[(VMAC_NHBYTES/8)+2*(VMAC_TAG_LEN/64-1)]; + u64 polykey[2*VMAC_TAG_LEN/64]; + u64 l3key[2*VMAC_TAG_LEN/64]; +}; + +/* per-request context */ +struct vmac_desc_ctx { + union { + u8 partial[VMAC_NHBYTES]; /* partial block */ + __le64 partial_words[VMAC_NHBYTES / 8]; + }; + unsigned int partial_size; /* size of the partial block */ + bool first_block_processed; + u64 polytmp[2*VMAC_TAG_LEN/64]; /* running total of L2-hash */ +}; + /* * Constants and masks */ @@ -318,13 +349,6 @@ static void poly_step_func(u64 *ahi, u64 *alo, } while (0) #endif -static void vhash_abort(struct vmac_ctx *ctx) -{ - ctx->polytmp[0] = ctx->polykey[0] ; - ctx->polytmp[1] = ctx->polykey[1] ; - ctx->first_block_processed = 0; -} - static u64 l3hash(u64 p1, u64 p2, u64 k1, u64 k2, u64 len) { u64 rh, rl, t, z = 0; @@ -364,280 +388,209 @@ static u64 l3hash(u64 p1, u64 p2, u64 k1, u64 k2, u64 len) return rl; } -static void vhash_update(const unsigned char *m, - unsigned int mbytes, /* Pos multiple of VMAC_NHBYTES */ - struct vmac_ctx *ctx) +/* L1 and L2-hash one or more VMAC_NHBYTES-byte blocks */ +static void vhash_blocks(const struct vmac_tfm_ctx *tctx, + struct vmac_desc_ctx *dctx, + const __le64 *mptr, unsigned int blocks) { - u64 rh, rl, *mptr; - const u64 *kptr = (u64 *)ctx->nhkey; - int i; - u64 ch, cl; - u64 pkh = ctx->polykey[0]; - u64 pkl = ctx->polykey[1]; - - if (!mbytes) - return; - - BUG_ON(mbytes % VMAC_NHBYTES); - - mptr = (u64 *)m; - i = mbytes / VMAC_NHBYTES; /* Must be non-zero */ - - ch = ctx->polytmp[0]; - cl = ctx->polytmp[1]; - - if (!ctx->first_block_processed) { - ctx->first_block_processed = 1; + const u64 *kptr = tctx->nhkey; + const u64 pkh = tctx->polykey[0]; + const u64 pkl = tctx->polykey[1]; + u64 ch = dctx->polytmp[0]; + u64 cl = dctx->polytmp[1]; + u64 rh, rl; + + if (!dctx->first_block_processed) { + dctx->first_block_processed = true; nh_vmac_nhbytes(mptr, kptr, VMAC_NHBYTES/8, rh, rl); rh &= m62; ADD128(ch, cl, rh, rl); mptr += (VMAC_NHBYTES/sizeof(u64)); - i--; + blocks--; } - while (i--) { + while (blocks--) { nh_vmac_nhbytes(mptr, kptr, VMAC_NHBYTES/8, rh, rl); rh &= m62; poly_step(ch, cl, pkh, pkl, rh, rl); mptr += (VMAC_NHBYTES/sizeof(u64)); } - ctx->polytmp[0] = ch; - ctx->polytmp[1] = cl; + dctx->polytmp[0] = ch; + dctx->polytmp[1] = cl; } -static u64 vhash(unsigned char m[], unsigned int mbytes, - u64 *tagl, struct vmac_ctx *ctx) +static int vmac_setkey(struct crypto_shash *tfm, + const u8 *key, unsigned int keylen) { - u64 rh, rl, *mptr; - const u64 *kptr = (u64 *)ctx->nhkey; - int i, remaining; - u64 ch, cl; - u64 pkh = ctx->polykey[0]; - u64 pkl = ctx->polykey[1]; - - mptr = (u64 *)m; - i = mbytes / VMAC_NHBYTES; - remaining = mbytes % VMAC_NHBYTES; - - if (ctx->first_block_processed) { - ch = ctx->polytmp[0]; - cl = ctx->polytmp[1]; - } else if (i) { - nh_vmac_nhbytes(mptr, kptr, VMAC_NHBYTES/8, ch, cl); - ch &= m62; - ADD128(ch, cl, pkh, pkl); - mptr += (VMAC_NHBYTES/sizeof(u64)); - i--; - } else if (remaining) { - nh_16(mptr, kptr, 2*((remaining+15)/16), ch, cl); - ch &= m62; - ADD128(ch, cl, pkh, pkl); - mptr += (VMAC_NHBYTES/sizeof(u64)); - goto do_l3; - } else {/* Empty String */ - ch = pkh; cl = pkl; - goto do_l3; - } - - while (i--) { - nh_vmac_nhbytes(mptr, kptr, VMAC_NHBYTES/8, rh, rl); - rh &= m62; - poly_step(ch, cl, pkh, pkl, rh, rl); - mptr += (VMAC_NHBYTES/sizeof(u64)); - } - if (remaining) { - nh_16(mptr, kptr, 2*((remaining+15)/16), rh, rl); - rh &= m62; - poly_step(ch, cl, pkh, pkl, rh, rl); - } - -do_l3: - vhash_abort(ctx); - remaining *= 8; - return l3hash(ch, cl, ctx->l3key[0], ctx->l3key[1], remaining); -} + struct vmac_tfm_ctx *tctx = crypto_shash_ctx(tfm); + __be64 out[2]; + u8 in[16] = { 0 }; + unsigned int i; + int err; -static u64 vmac(unsigned char m[], unsigned int mbytes, - const unsigned char n[16], u64 *tagl, - struct vmac_ctx_t *ctx) -{ - u64 *in_n, *out_p; - u64 p, h; - int i; - - in_n = ctx->__vmac_ctx.cached_nonce; - out_p = ctx->__vmac_ctx.cached_aes; - - i = n[15] & 1; - if ((*(u64 *)(n+8) != in_n[1]) || (*(u64 *)(n) != in_n[0])) { - in_n[0] = *(u64 *)(n); - in_n[1] = *(u64 *)(n+8); - ((unsigned char *)in_n)[15] &= 0xFE; - crypto_cipher_encrypt_one(ctx->child, - (unsigned char *)out_p, (unsigned char *)in_n); - - ((unsigned char *)in_n)[15] |= (unsigned char)(1-i); + if (keylen != VMAC_KEY_LEN) { + crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -EINVAL; } - p = be64_to_cpup(out_p + i); - h = vhash(m, mbytes, (u64 *)0, &ctx->__vmac_ctx); - return le64_to_cpu(p + h); -} -static int vmac_set_key(unsigned char user_key[], struct vmac_ctx_t *ctx) -{ - u64 in[2] = {0}, out[2]; - unsigned i; - int err = 0; - - err = crypto_cipher_setkey(ctx->child, user_key, VMAC_KEY_LEN); + err = crypto_cipher_setkey(tctx->cipher, key, keylen); if (err) return err; /* Fill nh key */ - ((unsigned char *)in)[0] = 0x80; - for (i = 0; i < sizeof(ctx->__vmac_ctx.nhkey)/8; i += 2) { - crypto_cipher_encrypt_one(ctx->child, - (unsigned char *)out, (unsigned char *)in); - ctx->__vmac_ctx.nhkey[i] = be64_to_cpup(out); - ctx->__vmac_ctx.nhkey[i+1] = be64_to_cpup(out+1); - ((unsigned char *)in)[15] += 1; + in[0] = 0x80; + for (i = 0; i < ARRAY_SIZE(tctx->nhkey); i += 2) { + crypto_cipher_encrypt_one(tctx->cipher, (u8 *)out, in); + tctx->nhkey[i] = be64_to_cpu(out[0]); + tctx->nhkey[i+1] = be64_to_cpu(out[1]); + in[15]++; } /* Fill poly key */ - ((unsigned char *)in)[0] = 0xC0; - in[1] = 0; - for (i = 0; i < sizeof(ctx->__vmac_ctx.polykey)/8; i += 2) { - crypto_cipher_encrypt_one(ctx->child, - (unsigned char *)out, (unsigned char *)in); - ctx->__vmac_ctx.polytmp[i] = - ctx->__vmac_ctx.polykey[i] = - be64_to_cpup(out) & mpoly; - ctx->__vmac_ctx.polytmp[i+1] = - ctx->__vmac_ctx.polykey[i+1] = - be64_to_cpup(out+1) & mpoly; - ((unsigned char *)in)[15] += 1; + in[0] = 0xC0; + in[15] = 0; + for (i = 0; i < ARRAY_SIZE(tctx->polykey); i += 2) { + crypto_cipher_encrypt_one(tctx->cipher, (u8 *)out, in); + tctx->polykey[i] = be64_to_cpu(out[0]) & mpoly; + tctx->polykey[i+1] = be64_to_cpu(out[1]) & mpoly; + in[15]++; } /* Fill ip key */ - ((unsigned char *)in)[0] = 0xE0; - in[1] = 0; - for (i = 0; i < sizeof(ctx->__vmac_ctx.l3key)/8; i += 2) { + in[0] = 0xE0; + in[15] = 0; + for (i = 0; i < ARRAY_SIZE(tctx->l3key); i += 2) { do { - crypto_cipher_encrypt_one(ctx->child, - (unsigned char *)out, (unsigned char *)in); - ctx->__vmac_ctx.l3key[i] = be64_to_cpup(out); - ctx->__vmac_ctx.l3key[i+1] = be64_to_cpup(out+1); - ((unsigned char *)in)[15] += 1; - } while (ctx->__vmac_ctx.l3key[i] >= p64 - || ctx->__vmac_ctx.l3key[i+1] >= p64); + crypto_cipher_encrypt_one(tctx->cipher, (u8 *)out, in); + tctx->l3key[i] = be64_to_cpu(out[0]); + tctx->l3key[i+1] = be64_to_cpu(out[1]); + in[15]++; + } while (tctx->l3key[i] >= p64 || tctx->l3key[i+1] >= p64); } - /* Invalidate nonce/aes cache and reset other elements */ - ctx->__vmac_ctx.cached_nonce[0] = (u64)-1; /* Ensure illegal nonce */ - ctx->__vmac_ctx.cached_nonce[1] = (u64)0; /* Ensure illegal nonce */ - ctx->__vmac_ctx.first_block_processed = 0; - - return err; + return 0; } -static int vmac_setkey(struct crypto_shash *parent, - const u8 *key, unsigned int keylen) +static int vmac_init(struct shash_desc *desc) { - struct vmac_ctx_t *ctx = crypto_shash_ctx(parent); + const struct vmac_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm); + struct vmac_desc_ctx *dctx = shash_desc_ctx(desc); - if (keylen != VMAC_KEY_LEN) { - crypto_shash_set_flags(parent, CRYPTO_TFM_RES_BAD_KEY_LEN); - return -EINVAL; - } - - return vmac_set_key((u8 *)key, ctx); -} - -static int vmac_init(struct shash_desc *pdesc) -{ + dctx->partial_size = 0; + dctx->first_block_processed = false; + memcpy(dctx->polytmp, tctx->polykey, sizeof(dctx->polytmp)); return 0; } -static int vmac_update(struct shash_desc *pdesc, const u8 *p, - unsigned int len) +static int vmac_update(struct shash_desc *desc, const u8 *p, unsigned int len) { - struct crypto_shash *parent = pdesc->tfm; - struct vmac_ctx_t *ctx = crypto_shash_ctx(parent); - int expand; - int min; - - expand = VMAC_NHBYTES - ctx->partial_size > 0 ? - VMAC_NHBYTES - ctx->partial_size : 0; - - min = len < expand ? len : expand; - - memcpy(ctx->partial + ctx->partial_size, p, min); - ctx->partial_size += min; - - if (len < expand) - return 0; - - vhash_update(ctx->partial, VMAC_NHBYTES, &ctx->__vmac_ctx); - ctx->partial_size = 0; - - len -= expand; - p += expand; + const struct vmac_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm); + struct vmac_desc_ctx *dctx = shash_desc_ctx(desc); + unsigned int n; + + if (dctx->partial_size) { + n = min(len, VMAC_NHBYTES - dctx->partial_size); + memcpy(&dctx->partial[dctx->partial_size], p, n); + dctx->partial_size += n; + p += n; + len -= n; + if (dctx->partial_size == VMAC_NHBYTES) { + vhash_blocks(tctx, dctx, dctx->partial_words, 1); + dctx->partial_size = 0; + } + } - if (len % VMAC_NHBYTES) { - memcpy(ctx->partial, p + len - (len % VMAC_NHBYTES), - len % VMAC_NHBYTES); - ctx->partial_size = len % VMAC_NHBYTES; + if (len >= VMAC_NHBYTES) { + n = round_down(len, VMAC_NHBYTES); + /* TODO: 'p' may be misaligned here */ + vhash_blocks(tctx, dctx, (const __le64 *)p, n / VMAC_NHBYTES); + p += n; + len -= n; } - vhash_update(p, len - len % VMAC_NHBYTES, &ctx->__vmac_ctx); + if (len) { + memcpy(dctx->partial, p, len); + dctx->partial_size = len; + } return 0; } -static int vmac_final(struct shash_desc *pdesc, u8 *out) +static u64 vhash_final(const struct vmac_tfm_ctx *tctx, + struct vmac_desc_ctx *dctx) { - struct crypto_shash *parent = pdesc->tfm; - struct vmac_ctx_t *ctx = crypto_shash_ctx(parent); - vmac_t mac; - u8 nonce[16] = {}; - - /* vmac() ends up accessing outside the array bounds that - * we specify. In appears to access up to the next 2-word - * boundary. We'll just be uber cautious and zero the - * unwritten bytes in the buffer. - */ - if (ctx->partial_size) { - memset(ctx->partial + ctx->partial_size, 0, - VMAC_NHBYTES - ctx->partial_size); + unsigned int partial = dctx->partial_size; + u64 ch = dctx->polytmp[0]; + u64 cl = dctx->polytmp[1]; + + /* L1 and L2-hash the final block if needed */ + if (partial) { + /* Zero-pad to next 128-bit boundary */ + unsigned int n = round_up(partial, 16); + u64 rh, rl; + + memset(&dctx->partial[partial], 0, n - partial); + nh_16(dctx->partial_words, tctx->nhkey, n / 8, rh, rl); + rh &= m62; + if (dctx->first_block_processed) + poly_step(ch, cl, tctx->polykey[0], tctx->polykey[1], + rh, rl); + else + ADD128(ch, cl, rh, rl); } - mac = vmac(ctx->partial, ctx->partial_size, nonce, NULL, ctx); - memcpy(out, &mac, sizeof(vmac_t)); - memzero_explicit(&mac, sizeof(vmac_t)); - memset(&ctx->__vmac_ctx, 0, sizeof(struct vmac_ctx)); - ctx->partial_size = 0; + + /* L3-hash the 128-bit output of L2-hash */ + return l3hash(ch, cl, tctx->l3key[0], tctx->l3key[1], partial * 8); +} + +static int vmac_final(struct shash_desc *desc, u8 *out) +{ + const struct vmac_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm); + struct vmac_desc_ctx *dctx = shash_desc_ctx(desc); + static const u8 nonce[16] = {}; /* TODO: this is insecure */ + union { + u8 bytes[16]; + __be64 pads[2]; + } block; + int index; + u64 hash, pad; + + /* Finish calculating the VHASH of the message */ + hash = vhash_final(tctx, dctx); + + /* Generate pseudorandom pad by encrypting the nonce */ + memcpy(&block, nonce, 16); + index = block.bytes[15] & 1; + block.bytes[15] &= ~1; + crypto_cipher_encrypt_one(tctx->cipher, block.bytes, block.bytes); + pad = be64_to_cpu(block.pads[index]); + + /* The VMAC is the sum of VHASH and the pseudorandom pad */ + put_unaligned_le64(hash + pad, out); return 0; } static int vmac_init_tfm(struct crypto_tfm *tfm) { - struct crypto_cipher *cipher; - struct crypto_instance *inst = (void *)tfm->__crt_alg; + struct crypto_instance *inst = crypto_tfm_alg_instance(tfm); struct crypto_spawn *spawn = crypto_instance_ctx(inst); - struct vmac_ctx_t *ctx = crypto_tfm_ctx(tfm); + struct vmac_tfm_ctx *tctx = crypto_tfm_ctx(tfm); + struct crypto_cipher *cipher; cipher = crypto_spawn_cipher(spawn); if (IS_ERR(cipher)) return PTR_ERR(cipher); - ctx->child = cipher; + tctx->cipher = cipher; return 0; } static void vmac_exit_tfm(struct crypto_tfm *tfm) { - struct vmac_ctx_t *ctx = crypto_tfm_ctx(tfm); - crypto_free_cipher(ctx->child); + struct vmac_tfm_ctx *tctx = crypto_tfm_ctx(tfm); + + crypto_free_cipher(tctx->cipher); } static int vmac_create(struct crypto_template *tmpl, struct rtattr **tb) @@ -655,6 +608,10 @@ static int vmac_create(struct crypto_template *tmpl, struct rtattr **tb) if (IS_ERR(alg)) return PTR_ERR(alg); + err = -EINVAL; + if (alg->cra_blocksize != 16) + goto out_put_alg; + inst = shash_alloc_instance("vmac", alg); err = PTR_ERR(inst); if (IS_ERR(inst)) @@ -670,11 +627,12 @@ static int vmac_create(struct crypto_template *tmpl, struct rtattr **tb) inst->alg.base.cra_blocksize = alg->cra_blocksize; inst->alg.base.cra_alignmask = alg->cra_alignmask; - inst->alg.digestsize = sizeof(vmac_t); - inst->alg.base.cra_ctxsize = sizeof(struct vmac_ctx_t); + inst->alg.base.cra_ctxsize = sizeof(struct vmac_tfm_ctx); inst->alg.base.cra_init = vmac_init_tfm; inst->alg.base.cra_exit = vmac_exit_tfm; + inst->alg.descsize = sizeof(struct vmac_desc_ctx); + inst->alg.digestsize = VMAC_TAG_LEN / 8; inst->alg.init = vmac_init; inst->alg.update = vmac_update; inst->alg.final = vmac_final; diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index f9e0d09f7c66c..8a0f77fb51819 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c @@ -154,10 +154,12 @@ static const struct lpss_device_desc lpt_sdio_dev_desc = { static const struct lpss_device_desc byt_pwm_dev_desc = { .flags = LPSS_SAVE_CTX, + .prv_offset = 0x800, }; static const struct lpss_device_desc bsw_pwm_dev_desc = { .flags = LPSS_SAVE_CTX | LPSS_NO_D3_DELAY, + .prv_offset = 0x800, }; static const struct lpss_device_desc byt_uart_dev_desc = { diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index 8ea8211b2d589..f8bb0e4d035af 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c @@ -108,6 +108,7 @@ static void round_robin_cpu(unsigned int tsk_index) cpumask_andnot(tmp, cpu_online_mask, pad_busy_cpus); if (cpumask_empty(tmp)) { mutex_unlock(&round_robin_lock); + free_cpumask_var(tmp); return; } for_each_cpu(cpu, tmp) { @@ -125,6 +126,8 @@ static void round_robin_cpu(unsigned int tsk_index) mutex_unlock(&round_robin_lock); set_cpus_allowed_ptr(current, cpumask_of(preferred_cpu)); + + free_cpumask_var(tmp); } static void exit_round_robin(unsigned int tsk_index) diff --git a/drivers/acpi/acpica/evevent.c b/drivers/acpi/acpica/evevent.c index bf6873f95e722..0b5eedb60d04f 100644 --- a/drivers/acpi/acpica/evevent.c +++ b/drivers/acpi/acpica/evevent.c @@ -204,6 +204,7 @@ u32 acpi_ev_fixed_event_detect(void) u32 fixed_status; u32 fixed_enable; u32 i; + acpi_status status; ACPI_FUNCTION_NAME(ev_fixed_event_detect); @@ -211,8 +212,12 @@ u32 acpi_ev_fixed_event_detect(void) * Read the fixed feature status and enable registers, as all the cases * depend on their values. Ignore errors here. */ - (void)acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS, &fixed_status); - (void)acpi_hw_register_read(ACPI_REGISTER_PM1_ENABLE, &fixed_enable); + status = acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS, &fixed_status); + status |= + acpi_hw_register_read(ACPI_REGISTER_PM1_ENABLE, &fixed_enable); + if (ACPI_FAILURE(status)) { + return (int_status); + } ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS, "Fixed Event Block: Enable %08X Status %08X\n", diff --git a/drivers/acpi/acpica/nseval.c b/drivers/acpi/acpica/nseval.c index 7eba578d36f36..10262cae8a19e 100644 --- a/drivers/acpi/acpica/nseval.c +++ b/drivers/acpi/acpica/nseval.c @@ -308,6 +308,14 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info) /* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */ status = AE_OK; + } else if (ACPI_FAILURE(status)) { + + /* If return_object exists, delete it */ + + if (info->return_object) { + acpi_ut_remove_reference(info->return_object); + info->return_object = NULL; + } } ACPI_DEBUG_PRINT((ACPI_DB_NAMES, diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index ae3fe4e642035..3b0b4bd67b71b 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -472,9 +472,11 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm) } control = OSC_PCI_EXPRESS_CAPABILITY_CONTROL - | OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | OSC_PCI_EXPRESS_PME_CONTROL; + if (IS_ENABLED(CONFIG_HOTPLUG_PCI_PCIE)) + control |= OSC_PCI_EXPRESS_NATIVE_HP_CONTROL; + if (pci_aer_available()) { if (aer_acpi_firmware_first()) dev_info(&device->dev, diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index bb01dea39fdcc..9825780a1cd25 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -161,7 +161,7 @@ int acpi_processor_ppc_has_changed(struct acpi_processor *pr, int event_flag) { int ret; - if (ignore_ppc) { + if (ignore_ppc || !pr->performance) { /* * Only when it is notification event, the _OST object * will be evaluated. Otherwise it is skipped. diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index e3322adaaae00..4f07029de2096 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -124,6 +124,12 @@ void __init acpi_nvs_nosave_s3(void) nvs_nosave_s3 = true; } +static int __init init_nvs_save_s3(const struct dmi_system_id *d) +{ + nvs_nosave_s3 = false; + return 0; +} + /* * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the * user to request that behavior by using the 'acpi_old_suspend_ordering' @@ -318,6 +324,27 @@ static struct dmi_system_id acpisleep_dmi_table[] __initdata = { DMI_MATCH(DMI_PRODUCT_NAME, "K54HR"), }, }, + { + .callback = init_nvs_save_s3, + .ident = "Asus 1025C", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "1025C"), + }, + }, + /* + * https://bugzilla.kernel.org/show_bug.cgi?id=189431 + * Lenovo G50-45 is a platform later than 2012, but needs nvs memory + * saving during S3. + */ + { + .callback = init_nvs_save_s3, + .ident = "Lenovo G50-45", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "80E3"), + }, + }, {}, }; diff --git a/drivers/android/Kconfig b/drivers/android/Kconfig index 01de42c8b74bd..7502ac3086c13 100644 --- a/drivers/android/Kconfig +++ b/drivers/android/Kconfig @@ -9,7 +9,7 @@ if ANDROID config ANDROID_BINDER_IPC bool "Android Binder IPC Driver" - depends on MMU + depends on MMU && !M68K default n ---help--- Binder is used in Android for both communication between processes, @@ -34,7 +34,7 @@ config ANDROID_BINDER_DEVICES config ANDROID_BINDER_IPC_32BIT bool depends on !64BIT && ANDROID_BINDER_IPC - default y + default y if ANDROID_VERSION < 0x09000000 ---help--- The Binder API has been changed to support both 32 and 64bit applications in a mixed environment. diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 67a1c13b8dda2..d1dfbe34fa7c7 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -143,7 +143,7 @@ enum { }; static uint32_t binder_debug_mask = BINDER_DEBUG_USER_ERROR | BINDER_DEBUG_FAILED_TRANSACTION | BINDER_DEBUG_DEAD_TRANSACTION; -module_param_named(debug_mask, binder_debug_mask, uint, S_IWUSR | S_IRUGO); +module_param_named(debug_mask, binder_debug_mask, uint, 0644); static char *binder_devices_param = CONFIG_ANDROID_BINDER_DEVICES; module_param_named(devices, binder_devices_param, charp, S_IRUGO); @@ -162,7 +162,7 @@ static int binder_set_stop_on_user_error(const char *val, return ret; } module_param_call(stop_on_user_error, binder_set_stop_on_user_error, - param_get_int, &binder_stop_on_user_error, S_IWUSR | S_IRUGO); + param_get_int, &binder_stop_on_user_error, 0644); #define binder_debug(mask, x...) \ do { \ @@ -251,7 +251,7 @@ static struct binder_transaction_log_entry *binder_transaction_log_add( unsigned int cur = atomic_inc_return(&log->cur); if (cur >= ARRAY_SIZE(log->entry)) - log->full = 1; + log->full = true; e = &log->entry[cur % ARRAY_SIZE(log->entry)]; WRITE_ONCE(e->debug_id_done, 0); /* @@ -466,8 +466,9 @@ struct binder_ref { }; enum binder_deferred_state { - BINDER_DEFERRED_FLUSH = 0x01, - BINDER_DEFERRED_RELEASE = 0x02, + BINDER_DEFERRED_PUT_FILES = 0x01, + BINDER_DEFERRED_FLUSH = 0x02, + BINDER_DEFERRED_RELEASE = 0x04, }; /** @@ -504,6 +505,9 @@ struct binder_priority { * (invariant after initialized) * @tsk task_struct for group_leader of process * (invariant after initialized) + * @files files_struct for process + * (protected by @files_lock) + * @files_lock mutex to protect @files * @deferred_work_node: element for binder_deferred_list * (protected by binder_deferred_lock) * @deferred_work: bitmap of deferred work to perform @@ -548,6 +552,8 @@ struct binder_proc { struct list_head waiting_threads; int pid; struct task_struct *tsk; + struct files_struct *files; + struct mutex files_lock; struct hlist_node deferred_work_node; int deferred_work; bool is_dead; @@ -895,33 +901,27 @@ static void binder_free_thread(struct binder_thread *thread); static void binder_free_proc(struct binder_proc *proc); static void binder_inc_node_tmpref_ilocked(struct binder_node *node); -struct files_struct *binder_get_files_struct(struct binder_proc *proc) -{ - return get_files_struct(proc->tsk); -} - static int task_get_unused_fd_flags(struct binder_proc *proc, int flags) { - struct files_struct *files; unsigned long rlim_cur; unsigned long irqs; int ret; - files = binder_get_files_struct(proc); - if (files == NULL) - return -ESRCH; - + mutex_lock(&proc->files_lock); + if (proc->files == NULL) { + ret = -ESRCH; + goto err; + } if (!lock_task_sighand(proc->tsk, &irqs)) { ret = -EMFILE; goto err; } - rlim_cur = task_rlimit(proc->tsk, RLIMIT_NOFILE); unlock_task_sighand(proc->tsk, &irqs); - ret = __alloc_fd(files, 0, rlim_cur, flags); + ret = __alloc_fd(proc->files, 0, rlim_cur, flags); err: - put_files_struct(files); + mutex_unlock(&proc->files_lock); return ret; } @@ -931,12 +931,10 @@ static int task_get_unused_fd_flags(struct binder_proc *proc, int flags) static void task_fd_install( struct binder_proc *proc, unsigned int fd, struct file *file) { - struct files_struct *files = binder_get_files_struct(proc); - - if (files) { - __fd_install(files, fd, file); - put_files_struct(files); - } + mutex_lock(&proc->files_lock); + if (proc->files) + __fd_install(proc->files, fd, file); + mutex_unlock(&proc->files_lock); } /* @@ -944,21 +942,22 @@ static void task_fd_install( */ static long task_close_fd(struct binder_proc *proc, unsigned int fd) { - struct files_struct *files = binder_get_files_struct(proc); int retval; - if (files == NULL) - return -ESRCH; - - retval = __close_fd(files, fd); + mutex_lock(&proc->files_lock); + if (proc->files == NULL) { + retval = -ESRCH; + goto err; + } + retval = __close_fd(proc->files, fd); /* can't restart close syscall because file table entry was cleared */ if (unlikely(retval == -ERESTARTSYS || retval == -ERESTARTNOINTR || retval == -ERESTARTNOHAND || retval == -ERESTART_RESTARTBLOCK)) retval = -EINTR; - put_files_struct(files); - +err: + mutex_unlock(&proc->files_lock); return retval; } @@ -2154,8 +2153,8 @@ static size_t binder_validate_object(struct binder_buffer *buffer, u64 offset) struct binder_object_header *hdr; size_t object_size = 0; - if (offset > buffer->data_size - sizeof(*hdr) || - buffer->data_size < sizeof(*hdr) || + if (buffer->data_size < sizeof(*hdr) || + offset > buffer->data_size - sizeof(*hdr) || !IS_ALIGNED(offset, sizeof(u32))) return 0; @@ -2295,7 +2294,7 @@ static void binder_transaction_buffer_release(struct binder_proc *proc, int debug_id = buffer->debug_id; binder_debug(BINDER_DEBUG_TRANSACTION, - "%d buffer release %d, size %zd-%zd, failed at %p\n", + "%d buffer release %d, size %zd-%zd, failed at %pK\n", proc->pid, buffer->debug_id, buffer->data_size, buffer->offsets_size, failed_at); @@ -2746,7 +2745,7 @@ static bool binder_proc_transaction(struct binder_transaction *t, target_list = &node->async_todo; wakeup = false; } else { - node->has_async_transaction = 1; + node->has_async_transaction = true; } } @@ -3608,7 +3607,7 @@ static int binder_thread_write(struct binder_proc *proc, w = binder_dequeue_work_head_ilocked( &buf_node->async_todo); if (!w) { - buf_node->has_async_transaction = 0; + buf_node->has_async_transaction = false; } else { binder_enqueue_work_ilocked( w, &proc->todo); @@ -3831,7 +3830,7 @@ static int binder_thread_write(struct binder_proc *proc, } } binder_debug(BINDER_DEBUG_DEAD_BINDER, - "%d:%d BC_DEAD_BINDER_DONE %016llx found %p\n", + "%d:%d BC_DEAD_BINDER_DONE %016llx found %pK\n", proc->pid, thread->pid, (u64)cookie, death); if (death == NULL) { @@ -4035,6 +4034,7 @@ static int binder_thread_read(struct binder_proc *proc, binder_inner_proc_unlock(proc); if (put_user(e->cmd, (uint32_t __user *)ptr)) return -EFAULT; + cmd = e->cmd; e->cmd = BR_OK; ptr += sizeof(uint32_t); @@ -4803,6 +4803,7 @@ static void binder_vma_close(struct vm_area_struct *vma) (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, (unsigned long)pgprot_val(vma->vm_page_prot)); binder_alloc_vma_close(&proc->alloc); + binder_defer_work(proc, BINDER_DEFERRED_PUT_FILES); } static int binder_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) @@ -4839,16 +4840,22 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma) failure_string = "bad vm_flags"; goto err_bad_arg; } - vma->vm_flags = (vma->vm_flags | VM_DONTCOPY) & ~VM_MAYWRITE; + vma->vm_flags |= VM_DONTCOPY | VM_MIXEDMAP; + vma->vm_flags &= ~VM_MAYWRITE; + vma->vm_ops = &binder_vm_ops; vma->vm_private_data = proc; ret = binder_alloc_mmap_handler(&proc->alloc, vma); - - return ret; + if (ret) + return ret; + mutex_lock(&proc->files_lock); + proc->files = get_files_struct(current); + mutex_unlock(&proc->files_lock); + return 0; err_bad_arg: - pr_err("binder_mmap: %d %lx-%lx %s failed %d\n", + pr_err("%s: %d %lx-%lx %s failed %d\n", __func__, proc->pid, vma->vm_start, vma->vm_end, failure_string, ret); return ret; } @@ -4858,7 +4865,7 @@ static int binder_open(struct inode *nodp, struct file *filp) struct binder_proc *proc; struct binder_device *binder_dev; - binder_debug(BINDER_DEBUG_OPEN_CLOSE, "binder_open: %d:%d\n", + binder_debug(BINDER_DEBUG_OPEN_CLOSE, "%s: %d:%d\n", __func__, current->group_leader->pid, current->pid); proc = kzalloc(sizeof(*proc), GFP_KERNEL); @@ -4868,6 +4875,7 @@ static int binder_open(struct inode *nodp, struct file *filp) spin_lock_init(&proc->outer_lock); get_task_struct(current->group_leader); proc->tsk = current->group_leader; + mutex_init(&proc->files_lock); INIT_LIST_HEAD(&proc->todo); if (binder_supported_policy(current->policy)) { proc->default_priority.sched_policy = current->policy; @@ -4903,7 +4911,7 @@ static int binder_open(struct inode *nodp, struct file *filp) * anyway print all contexts that a given PID has, so this * is not a problem. */ - proc->debugfs_entry = debugfs_create_file(strbuf, S_IRUGO, + proc->debugfs_entry = debugfs_create_file(strbuf, 0444, binder_debugfs_dir_entry_proc, (void *)(unsigned long)proc->pid, &binder_proc_fops); @@ -5024,6 +5032,8 @@ static void binder_deferred_release(struct binder_proc *proc) struct rb_node *n; int threads, nodes, incoming_refs, outgoing_refs, active_transactions; + BUG_ON(proc->files); + mutex_lock(&binder_procs_lock); hlist_del(&proc->proc_node); mutex_unlock(&binder_procs_lock); @@ -5105,6 +5115,8 @@ static void binder_deferred_release(struct binder_proc *proc) static void binder_deferred_func(struct work_struct *work) { struct binder_proc *proc; + struct files_struct *files; + int defer; do { @@ -5121,11 +5133,23 @@ static void binder_deferred_func(struct work_struct *work) } mutex_unlock(&binder_deferred_lock); + files = NULL; + if (defer & BINDER_DEFERRED_PUT_FILES) { + mutex_lock(&proc->files_lock); + files = proc->files; + if (files) + proc->files = NULL; + mutex_unlock(&proc->files_lock); + } + if (defer & BINDER_DEFERRED_FLUSH) binder_deferred_flush(proc); if (defer & BINDER_DEFERRED_RELEASE) binder_deferred_release(proc); /* frees proc */ + + if (files) + put_files_struct(files); } while (proc); } static DECLARE_WORK(binder_deferred_work, binder_deferred_func); @@ -5154,7 +5178,7 @@ static void print_binder_transaction_ilocked(struct seq_file *m, spin_lock(&t->lock); to_proc = t->to_proc; seq_printf(m, - "%s %d: %p from %d:%d to %d:%d code %x flags %x pri %d:%d r%d", + "%s %d: %pK from %d:%d to %d:%d code %x flags %x pri %d:%d r%d", prefix, t->debug_id, t, t->from ? t->from->proc->pid : 0, t->from ? t->from->pid : 0, @@ -5179,7 +5203,7 @@ static void print_binder_transaction_ilocked(struct seq_file *m, } if (buffer->target_node) seq_printf(m, " node %d", buffer->target_node->debug_id); - seq_printf(m, " size %zd:%zd data %p\n", + seq_printf(m, " size %zd:%zd data %pK\n", buffer->data_size, buffer->offsets_size, buffer->data); } @@ -5714,11 +5738,13 @@ static int __init init_binder_device(const char *name) static int __init binder_init(void) { int ret; - char *device_name, *device_names; + char *device_name, *device_names, *device_tmp; struct binder_device *device; struct hlist_node *tmp; - binder_alloc_shrinker_init(); + ret = binder_alloc_shrinker_init(); + if (ret) + return ret; atomic_set(&binder_transaction_log.cur, ~0U); atomic_set(&binder_transaction_log_failed.cur, ~0U); @@ -5733,27 +5759,27 @@ static int __init binder_init(void) if (binder_debugfs_dir_entry_root) { debugfs_create_file("state", - S_IRUGO, + 0444, binder_debugfs_dir_entry_root, NULL, &binder_state_fops); debugfs_create_file("stats", - S_IRUGO, + 0444, binder_debugfs_dir_entry_root, NULL, &binder_stats_fops); debugfs_create_file("transactions", - S_IRUGO, + 0444, binder_debugfs_dir_entry_root, NULL, &binder_transactions_fops); debugfs_create_file("transaction_log", - S_IRUGO, + 0444, binder_debugfs_dir_entry_root, &binder_transaction_log, &binder_transaction_log_fops); debugfs_create_file("failed_transaction_log", - S_IRUGO, + 0444, binder_debugfs_dir_entry_root, &binder_transaction_log_failed, &binder_transaction_log_fops); @@ -5770,7 +5796,8 @@ static int __init binder_init(void) } strcpy(device_names, binder_devices_param); - while ((device_name = strsep(&device_names, ","))) { + device_tmp = device_names; + while ((device_name = strsep(&device_tmp, ","))) { ret = init_binder_device(device_name); if (ret) goto err_init_binder_device_failed; @@ -5784,6 +5811,9 @@ static int __init binder_init(void) hlist_del(&device->hlist); kfree(device); } + + kfree(device_names); + err_alloc_device_names_failed: debugfs_remove_recursive(binder_debugfs_dir_entry_root); diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c index 3a4279d219f7e..1d9db2ef26bdd 100644 --- a/drivers/android/binder_alloc.c +++ b/drivers/android/binder_alloc.c @@ -220,7 +220,7 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate, mm = alloc->vma_vm_mm; if (mm) { - down_write(&mm->mmap_sem); + down_read(&mm->mmap_sem); vma = alloc->vma; } @@ -289,7 +289,7 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate, /* vm_insert_page does not seem to increment the refcount */ } if (mm) { - up_write(&mm->mmap_sem); + up_read(&mm->mmap_sem); mmput(mm); } return 0; @@ -322,17 +322,18 @@ static int binder_update_page_range(struct binder_alloc *alloc, int allocate, } err_no_vma: if (mm) { - up_write(&mm->mmap_sem); + up_read(&mm->mmap_sem); mmput(mm); } return vma ? -ENOMEM : -ESRCH; } -struct binder_buffer *binder_alloc_new_buf_locked(struct binder_alloc *alloc, - size_t data_size, - size_t offsets_size, - size_t extra_buffers_size, - int is_async) +static struct binder_buffer *binder_alloc_new_buf_locked( + struct binder_alloc *alloc, + size_t data_size, + size_t offsets_size, + size_t extra_buffers_size, + int is_async) { struct rb_node *n = alloc->free_buffers.rb_node; struct binder_buffer *buffer; @@ -670,7 +671,7 @@ int binder_alloc_mmap_handler(struct binder_alloc *alloc, goto err_already_mapped; } - area = get_vm_area(vma->vm_end - vma->vm_start, VM_IOREMAP); + area = get_vm_area(vma->vm_end - vma->vm_start, VM_ALLOC); if (area == NULL) { ret = -ENOMEM; failure_string = "get_vm_area"; @@ -1010,8 +1011,14 @@ void binder_alloc_init(struct binder_alloc *alloc) INIT_LIST_HEAD(&alloc->buffers); } -void binder_alloc_shrinker_init(void) +int binder_alloc_shrinker_init(void) { - list_lru_init(&binder_alloc_lru); - register_shrinker(&binder_shrinker); + int ret = list_lru_init(&binder_alloc_lru); + + if (ret == 0) { + ret = register_shrinker(&binder_shrinker); + if (ret) + list_lru_destroy(&binder_alloc_lru); + } + return ret; } diff --git a/drivers/android/binder_alloc.h b/drivers/android/binder_alloc.h index 0b145307f1fd1..9ef64e5638566 100644 --- a/drivers/android/binder_alloc.h +++ b/drivers/android/binder_alloc.h @@ -130,7 +130,7 @@ extern struct binder_buffer *binder_alloc_new_buf(struct binder_alloc *alloc, size_t extra_buffers_size, int is_async); extern void binder_alloc_init(struct binder_alloc *alloc); -void binder_alloc_shrinker_init(void); +extern int binder_alloc_shrinker_init(void); extern void binder_alloc_vma_close(struct binder_alloc *alloc); extern struct binder_buffer * binder_alloc_prepare_to_free(struct binder_alloc *alloc, diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 5ce328f086c4e..012abdcd83751 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1231,6 +1231,59 @@ static bool ahci_broken_suspend(struct pci_dev *pdev) return strcmp(buf, dmi->driver_data) < 0; } +static bool ahci_broken_lpm(struct pci_dev *pdev) +{ + static const struct dmi_system_id sysids[] = { + /* Various Lenovo 50 series have LPM issues with older BIOSen */ + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X250"), + }, + .driver_data = "20180406", /* 1.31 */ + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L450"), + }, + .driver_data = "20180420", /* 1.28 */ + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T450s"), + }, + .driver_data = "20180315", /* 1.33 */ + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad W541"), + }, + /* + * Note date based on release notes, 2.35 has been + * reported to be good, but I've been unable to get + * a hold of the reporter to get the DMI BIOS date. + * TODO: fix this. + */ + .driver_data = "20180310", /* 2.35 */ + }, + { } /* terminate list */ + }; + const struct dmi_system_id *dmi = dmi_first_match(sysids); + int year, month, date; + char buf[9]; + + if (!dmi) + return false; + + dmi_get_date(DMI_BIOS_DATE, &year, &month, &date); + snprintf(buf, sizeof(buf), "%04d%02d%02d", year, month, date); + + return strcmp(buf, dmi->driver_data) < 0; +} + static bool ahci_broken_online(struct pci_dev *pdev) { #define ENCODE_BUSDEVFN(bus, slot, func) \ @@ -1590,6 +1643,12 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) "quirky BIOS, skipping spindown on poweroff\n"); } + if (ahci_broken_lpm(pdev)) { + pi.flags |= ATA_FLAG_NO_LPM; + dev_warn(&pdev->dev, + "BIOS update required for Link Power Management support\n"); + } + if (ahci_broken_suspend(pdev)) { hpriv->flags |= AHCI_HFLAG_NO_SUSPEND; dev_warn(&pdev->dev, diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 60d6db82ce5a6..ba514fa733def 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2209,6 +2209,9 @@ int ata_dev_configure(struct ata_device *dev) (id[ATA_ID_SATA_CAPABILITY] & 0xe) == 0x2) dev->horkage |= ATA_HORKAGE_NOLPM; + if (ap->flags & ATA_FLAG_NO_LPM) + dev->horkage |= ATA_HORKAGE_NOLPM; + if (dev->horkage & ATA_HORKAGE_NOLPM) { ata_dev_warn(dev, "LPM support broken, forcing max_power\n"); dev->link->ap->target_lpm_policy = ATA_LPM_MAX_POWER; @@ -4187,6 +4190,10 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { /* https://bugzilla.kernel.org/show_bug.cgi?id=15573 */ { "C300-CTFDDAC128MAG", "0001", ATA_HORKAGE_NONCQ, }, + /* Some Sandisk SSDs lock up hard with NCQ enabled. Reported on + SD7SN6S256G and SD8SN8U256G */ + { "SanDisk SD[78]SN*G", NULL, ATA_HORKAGE_NONCQ, }, + /* devices which puke on READ_NATIVE_MAX */ { "HDS724040KLSA80", "KFAOA20N", ATA_HORKAGE_BROKEN_HPA, }, { "WDC WD3200JD-00KLB0", "WD-WCAMR1130137", ATA_HORKAGE_BROKEN_HPA }, @@ -4243,10 +4250,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { ATA_HORKAGE_ZERO_AFTER_TRIM | ATA_HORKAGE_NOLPM, }, - /* Sandisk devices which are known to not handle LPM well */ - { "SanDisk SD7UB3Q*G1001", NULL, ATA_HORKAGE_NOLPM, }, - /* devices that don't properly handle queued TRIM commands */ + { "Micron_M500IT_*", "MU01", ATA_HORKAGE_NO_NCQ_TRIM | + ATA_HORKAGE_ZERO_AFTER_TRIM, }, { "Micron_M500_*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | ATA_HORKAGE_ZERO_AFTER_TRIM, }, { "Crucial_CT*M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 75cced210b2a0..7db76b5c7ada3 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -2198,12 +2198,16 @@ static void ata_eh_link_autopsy(struct ata_link *link) if (qc->err_mask & ~AC_ERR_OTHER) qc->err_mask &= ~AC_ERR_OTHER; - /* SENSE_VALID trumps dev/unknown error and revalidation */ + /* + * SENSE_VALID trumps dev/unknown error and revalidation. Upper + * layers will determine whether the command is worth retrying + * based on the sense data and device class/type. Otherwise, + * determine directly if the command is worth retrying using its + * error mask and flags. + */ if (qc->flags & ATA_QCFLAG_SENSE_VALID) qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER); - - /* determine whether the command is worth retrying */ - if (ata_eh_worth_retry(qc)) + else if (ata_eh_worth_retry(qc)) qc->flags |= ATA_QCFLAG_RETRY; /* accumulate error info */ diff --git a/drivers/ata/libata-zpodd.c b/drivers/ata/libata-zpodd.c index f3a65a3140d3c..0ad96c647541a 100644 --- a/drivers/ata/libata-zpodd.c +++ b/drivers/ata/libata-zpodd.c @@ -34,7 +34,7 @@ struct zpodd { static int eject_tray(struct ata_device *dev) { struct ata_taskfile tf; - const char cdb[] = { GPCMD_START_STOP_UNIT, + static const char cdb[ATAPI_CDB_LEN] = { GPCMD_START_STOP_UNIT, 0, 0, 0, 0x02, /* LoEj */ 0, 0, 0, 0, 0, 0, 0, @@ -55,7 +55,7 @@ static enum odd_mech_type zpodd_get_mech_type(struct ata_device *dev) unsigned int ret; struct rm_feature_desc *desc = (void *)(buf + 8); struct ata_taskfile tf; - char cdb[] = { GPCMD_GET_CONFIGURATION, + static const char cdb[] = { GPCMD_GET_CONFIGURATION, 2, /* only 1 feature descriptor requested */ 0, 3, /* 3, removable medium feature */ 0, 0, 0,/* reserved */ diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c index 6eab52b92e017..94712e1c5cf9a 100644 --- a/drivers/atm/zatm.c +++ b/drivers/atm/zatm.c @@ -1149,8 +1149,8 @@ static void eprom_get_byte(struct zatm_dev *zatm_dev, unsigned char *byte, } -static unsigned char eprom_try_esi(struct atm_dev *dev, unsigned short cmd, - int offset, int swap) +static int eprom_try_esi(struct atm_dev *dev, unsigned short cmd, int offset, + int swap) { unsigned char buf[ZEPROM_SIZE]; struct zatm_dev *zatm_dev; @@ -1481,6 +1481,8 @@ static int zatm_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg) return -EFAULT; if (pool < 0 || pool > ZATM_LAST_POOL) return -EINVAL; + pool = array_index_nospec(pool, + ZATM_LAST_POOL + 1); if (copy_from_user(&info, &((struct zatm_pool_req __user *) arg)->info, sizeof(info))) return -EFAULT; diff --git a/drivers/base/core.c b/drivers/base/core.c index afe0457927966..049ccc070ce56 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -759,7 +759,7 @@ class_dir_create_and_add(struct class *class, struct kobject *parent_kobj) dir = kzalloc(sizeof(*dir), GFP_KERNEL); if (!dir) - return NULL; + return ERR_PTR(-ENOMEM); dir->class = class; kobject_init(&dir->kobj, &class_dir_ktype); @@ -769,7 +769,7 @@ class_dir_create_and_add(struct class *class, struct kobject *parent_kobj) retval = kobject_add(&dir->kobj, parent_kobj, "%s", class->name); if (retval < 0) { kobject_put(&dir->kobj); - return NULL; + return ERR_PTR(retval); } return &dir->kobj; } @@ -1076,6 +1076,10 @@ int device_add(struct device *dev) parent = get_device(dev->parent); kobj = get_device_parent(dev, parent); + if (IS_ERR(kobj)) { + error = PTR_ERR(kobj); + goto parent_error; + } if (kobj) dev->kobj.parent = kobj; @@ -1174,6 +1178,7 @@ int device_add(struct device *dev) kobject_del(&dev->kobj); Error: cleanup_glue_dir(dev, glue_dir); +parent_error: put_device(parent); name_error: kfree(dev->p); @@ -1990,6 +1995,11 @@ int device_move(struct device *dev, struct device *new_parent, device_pm_lock(); new_parent = get_device(new_parent); new_parent_kobj = get_device_parent(dev, new_parent); + if (IS_ERR(new_parent_kobj)) { + error = PTR_ERR(new_parent_kobj); + put_device(new_parent); + goto out; + } pr_debug("device: '%s': %s: moving to '%s'\n", dev_name(dev), __func__, new_parent ? dev_name(new_parent) : ""); diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 3db71afbba93c..41090ef5facbe 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -518,14 +518,30 @@ ssize_t __weak cpu_show_spectre_v2(struct device *dev, return sprintf(buf, "Not affected\n"); } +ssize_t __weak cpu_show_spec_store_bypass(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "Not affected\n"); +} + +ssize_t __weak cpu_show_l1tf(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "Not affected\n"); +} + static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL); static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL); static DEVICE_ATTR(spectre_v2, 0444, cpu_show_spectre_v2, NULL); +static DEVICE_ATTR(spec_store_bypass, 0444, cpu_show_spec_store_bypass, NULL); +static DEVICE_ATTR(l1tf, 0444, cpu_show_l1tf, NULL); static struct attribute *cpu_root_vulnerabilities_attrs[] = { &dev_attr_meltdown.attr, &dev_attr_spectre_v1.attr, &dev_attr_spectre_v2.attr, + &dev_attr_spec_store_bypass.attr, + &dev_attr_l1tf.attr, NULL }; diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 9e425fbf83cbe..d8887413dcffa 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -306,14 +306,6 @@ static int really_probe(struct device *dev, struct device_driver *drv) goto probe_failed; } - /* - * Ensure devices are listed in devices_kset in correct order - * It's important to move Dev to the end of devices_kset before - * calling .probe, because it could be recursive and parent Dev - * should always go first - */ - devices_kset_move_last(dev); - if (dev->bus->probe) { ret = dev->bus->probe(dev); if (ret) diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c index 7028daa3adcbd..e185950a3eece 100644 --- a/drivers/base/power/opp/core.c +++ b/drivers/base/power/opp/core.c @@ -704,15 +704,15 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) EXPORT_SYMBOL_GPL(dev_pm_opp_set_rate); /** - * dev_pm_opp_check_initial_rate() - Configure new OPP based on initial rate + * dev_pm_opp_check_rate_volt() - Configure new OPP based on current rate * @dev: device for which we do this operation * * This configures the power-supplies and clock source to the levels specified - * by the OPP corresponding to the system initial rate. + * by the OPP corresponding to current rate. * * Locking: This function takes rcu_read_lock(). */ -int dev_pm_opp_check_initial_rate(struct device *dev, unsigned long *cur_freq) +int dev_pm_opp_check_rate_volt(struct device *dev, bool force) { struct opp_table *opp_table; struct dev_pm_opp *opp; @@ -741,7 +741,6 @@ int dev_pm_opp_check_initial_rate(struct device *dev, unsigned long *cur_freq) } old_freq = clk_get_rate(clk); - *cur_freq = old_freq; target_freq = old_freq; opp = dev_pm_opp_find_freq_ceil(dev, &target_freq); @@ -772,11 +771,14 @@ int dev_pm_opp_check_initial_rate(struct device *dev, unsigned long *cur_freq) target_freq, u_volt); if (old_freq == target_freq) { - ret = _set_opp_voltage(dev, reg, u_volt, u_volt_min, - u_volt_max); - if (ret) { - dev_err(dev, "failed to set volt %lu\n", u_volt); - return ret; + if (old_volt != u_volt || force) { + ret = _set_opp_voltage(dev, reg, u_volt, u_volt_min, + u_volt_max); + if (ret) { + dev_err(dev, "failed to set volt %lu\n", + u_volt); + return ret; + } } return 0; } @@ -798,8 +800,6 @@ int dev_pm_opp_check_initial_rate(struct device *dev, unsigned long *cur_freq) return ret; } - *cur_freq = clk_get_rate(clk); - /* Scaling down? Scale voltage after frequency */ if (target_freq < old_freq) { ret = _set_opp_voltage(dev, reg, u_volt, u_volt_min, @@ -812,7 +812,7 @@ int dev_pm_opp_check_initial_rate(struct device *dev, unsigned long *cur_freq) return 0; } -EXPORT_SYMBOL_GPL(dev_pm_opp_check_initial_rate); +EXPORT_SYMBOL_GPL(dev_pm_opp_check_rate_volt); /* OPP-dev Helpers */ static void _kfree_opp_dev_rcu(struct rcu_head *head) diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index 5578c1477ba66..8bfd4fd7e9ec0 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c @@ -256,8 +256,8 @@ void drbd_request_endio(struct bio *bio) } else what = COMPLETED_OK; - bio_put(req->private_bio); req->private_bio = ERR_PTR(bio->bi_error); + bio_put(bio); /* not req_mod(), we need irqsave here! */ spin_lock_irqsave(&device->resource->req_lock, flags); diff --git a/drivers/block/loop.c b/drivers/block/loop.c index e8165ec55e6f5..da3902ac16c86 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -651,6 +651,36 @@ static void loop_reread_partitions(struct loop_device *lo, __func__, lo->lo_number, lo->lo_file_name, rc); } +static inline int is_loop_device(struct file *file) +{ + struct inode *i = file->f_mapping->host; + + return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR; +} + +static int loop_validate_file(struct file *file, struct block_device *bdev) +{ + struct inode *inode = file->f_mapping->host; + struct file *f = file; + + /* Avoid recursion */ + while (is_loop_device(f)) { + struct loop_device *l; + + if (f->f_mapping->host->i_bdev == bdev) + return -EBADF; + + l = f->f_mapping->host->i_bdev->bd_disk->private_data; + if (l->lo_state == Lo_unbound) { + return -EINVAL; + } + f = l->lo_backing_file; + } + if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode)) + return -EINVAL; + return 0; +} + /* * loop_change_fd switched the backing store of a loopback device to * a new file. This is useful for operating system installers to free up @@ -680,14 +710,15 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, if (!file) goto out; + error = loop_validate_file(file, bdev); + if (error) + goto out_putf; + inode = file->f_mapping->host; old_file = lo->lo_backing_file; error = -EINVAL; - if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode)) - goto out_putf; - /* size of the new backing store needs to be the same */ if (get_loop_size(lo, file) != get_loop_size(lo, old_file)) goto out_putf; @@ -708,13 +739,6 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, return error; } -static inline int is_loop_device(struct file *file) -{ - struct inode *i = file->f_mapping->host; - - return i && S_ISBLK(i->i_mode) && MAJOR(i->i_rdev) == LOOP_MAJOR; -} - /* loop sysfs attributes */ static ssize_t loop_attr_show(struct device *dev, char *page, @@ -811,16 +835,17 @@ static struct attribute_group loop_attribute_group = { .attrs= loop_attrs, }; -static int loop_sysfs_init(struct loop_device *lo) +static void loop_sysfs_init(struct loop_device *lo) { - return sysfs_create_group(&disk_to_dev(lo->lo_disk)->kobj, - &loop_attribute_group); + lo->sysfs_inited = !sysfs_create_group(&disk_to_dev(lo->lo_disk)->kobj, + &loop_attribute_group); } static void loop_sysfs_exit(struct loop_device *lo) { - sysfs_remove_group(&disk_to_dev(lo->lo_disk)->kobj, - &loop_attribute_group); + if (lo->sysfs_inited) + sysfs_remove_group(&disk_to_dev(lo->lo_disk)->kobj, + &loop_attribute_group); } static void loop_config_discard(struct loop_device *lo) @@ -872,7 +897,7 @@ static int loop_prepare_queue(struct loop_device *lo) static int loop_set_fd(struct loop_device *lo, fmode_t mode, struct block_device *bdev, unsigned int arg) { - struct file *file, *f; + struct file *file; struct inode *inode; struct address_space *mapping; unsigned lo_blocksize; @@ -892,29 +917,13 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, if (lo->lo_state != Lo_unbound) goto out_putf; - /* Avoid recursion */ - f = file; - while (is_loop_device(f)) { - struct loop_device *l; - - if (f->f_mapping->host->i_bdev == bdev) - goto out_putf; - - l = f->f_mapping->host->i_bdev->bd_disk->private_data; - if (l->lo_state == Lo_unbound) { - error = -EINVAL; - goto out_putf; - } - f = l->lo_backing_file; - } + error = loop_validate_file(file, bdev); + if (error) + goto out_putf; mapping = file->f_mapping; inode = mapping->host; - error = -EINVAL; - if (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode)) - goto out_putf; - if (!(file->f_mode & FMODE_WRITE) || !(mode & FMODE_WRITE) || !file->f_op->write_iter) lo_flags |= LO_FLAGS_READ_ONLY; diff --git a/drivers/block/loop.h b/drivers/block/loop.h index fb2237c73e618..60f0fd2c0c652 100644 --- a/drivers/block/loop.h +++ b/drivers/block/loop.h @@ -59,6 +59,7 @@ struct loop_device { struct kthread_worker worker; struct task_struct *worker_task; bool use_dio; + bool sysfs_inited; struct request_queue *lo_queue; struct blk_mq_tag_set tag_set; diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c index 93362362aa551..8474a1b0740f6 100644 --- a/drivers/block/paride/pcd.c +++ b/drivers/block/paride/pcd.c @@ -230,6 +230,8 @@ static int pcd_block_open(struct block_device *bdev, fmode_t mode) struct pcd_unit *cd = bdev->bd_disk->private_data; int ret; + check_disk_change(bdev); + mutex_lock(&pcd_mutex); ret = cdrom_open(&cd->info, bdev, mode); mutex_unlock(&pcd_mutex); diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 54cef3dc0beba..4a899b41145e8 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -336,6 +336,12 @@ static const struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x13d3, 0x3459), .driver_info = BTUSB_REALTEK }, { USB_DEVICE(0x13d3, 0x3494), .driver_info = BTUSB_REALTEK }, + /* Additional Realtek 8723BU Bluetooth devices */ + { USB_DEVICE(0x7392, 0xa611), .driver_info = BTUSB_REALTEK }, + + /* Additional Realtek 8723DE Bluetooth devices */ + { USB_DEVICE(0x2ff8, 0xb011), .driver_info = BTUSB_REALTEK }, + /* Additional Realtek 8821AE Bluetooth devices */ { USB_DEVICE(0x0b05, 0x17dc), .driver_info = BTUSB_REALTEK }, { USB_DEVICE(0x13d3, 0x3414), .driver_info = BTUSB_REALTEK }, @@ -343,6 +349,9 @@ static const struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x13d3, 0x3461), .driver_info = BTUSB_REALTEK }, { USB_DEVICE(0x13d3, 0x3462), .driver_info = BTUSB_REALTEK }, + /* Additional Realtek 8822BE Bluetooth devices */ + { USB_DEVICE(0x0b05, 0x185c), .driver_info = BTUSB_REALTEK }, + /* Silicon Wave based devices */ { USB_DEVICE(0x0c10, 0x0000), .driver_info = BTUSB_SWAVE }, diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 61bb2192a80b0..9c4c9d299599f 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -142,6 +142,11 @@ static void hci_uart_write_work(struct work_struct *work) struct hci_dev *hdev = hu->hdev; struct sk_buff *skb; + if (!test_bit(HCI_UART_PROTO_READY, &hu->flags)) { + clear_bit(HCI_UART_SENDING, &hu->tx_state); + return; + } + /* REVISIT: should we cope with bad skbs or ->write() returning * and error value ? */ @@ -250,6 +255,9 @@ static int hci_uart_send_frame(struct hci_dev *hdev, struct sk_buff *skb) BT_DBG("%s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len); + if (!test_bit(HCI_UART_PROTO_READY, &hu->flags)) + return -EUNATCH; + hu->proto->enqueue(hu, skb); hci_uart_tx_wakeup(hu); @@ -495,9 +503,9 @@ static void hci_uart_tty_close(struct tty_struct *tty) if (hdev) hci_uart_close(hdev); - cancel_work_sync(&hu->write_work); - if (test_and_clear_bit(HCI_UART_PROTO_READY, &hu->flags)) { + cancel_work_sync(&hu->write_work); + if (hdev) { if (test_bit(HCI_UART_REGISTERED, &hu->flags)) hci_unregister_dev(hdev); @@ -644,15 +652,15 @@ static int hci_uart_set_proto(struct hci_uart *hu, int id) return err; hu->proto = p; - set_bit(HCI_UART_PROTO_READY, &hu->flags); err = hci_uart_register_dev(hu); if (err) { - clear_bit(HCI_UART_PROTO_READY, &hu->flags); p->close(hu); return err; } + set_bit(HCI_UART_PROTO_READY, &hu->flags); + return 0; } diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 8a3bf0a8c31d7..ecfb9ed2cff64 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -884,7 +884,7 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t baudrate) */ set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(msecs_to_jiffies(BAUDRATE_SETTLE_TIMEOUT_MS)); - set_current_state(TASK_INTERRUPTIBLE); + set_current_state(TASK_RUNNING); return 0; } @@ -939,6 +939,12 @@ static int qca_setup(struct hci_uart *hu) } else if (ret == -ENOENT) { /* No patch/nvm-config found, run with original fw/config */ ret = 0; + } else if (ret == -EAGAIN) { + /* + * Userspace firmware loader will return -EAGAIN in case no + * patch/nvm-config is found, so run with original fw/config. + */ + ret = 0; } /* Setup bdaddr */ diff --git a/drivers/bluetooth/rtk_btusb.c b/drivers/bluetooth/rtk_btusb.c old mode 100755 new mode 100644 index 239ebfdc2b593..5db188416009f --- a/drivers/bluetooth/rtk_btusb.c +++ b/drivers/bluetooth/rtk_btusb.c @@ -39,8 +39,8 @@ #include "rtk_btusb.h" -#define RTKBT_RELEASE_NAME "20170109_TV_ANDROID_6.x" -#define VERSION "4.1.2" +#define RTKBT_RELEASE_NAME "20180702_BT_ANDROID_8.1" +#define VERSION "4.1.5" #define SUSPNED_DW_FW 0 #define SET_WAKEUP_DEVICE 0 @@ -54,6 +54,8 @@ static volatile uint16_t dlfw_dis_state = 0; static firmware_info *fw_info_4_suspend = NULL; #endif +static uint32_t usb_info; + static patch_info fw_patch_table[] = { /* { vid, pid, lmp_sub_default, lmp_sub, everion, mp_fw_name, fw_name, config_name, fw_cache, fw_len, mac_offset } */ { 0x0BDA, 0x1724, 0x1200, 0, 0, "mp_rtl8723a_fw", "rtl8723a_fw", "rtl8723a_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8723A */ @@ -101,15 +103,17 @@ static patch_info fw_patch_table[] = { { 0x13D3, 0x3461, 0x8821, 0, 0, "mp_rtl8821a_fw", "rtl8821a_fw", "rtl8821a_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8821AE */ { 0x13D3, 0x3462, 0x8821, 0, 0, "mp_rtl8821a_fw", "rtl8821a_fw", "rtl8821a_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8821AE */ -{ 0x0BDA, 0xB822, 0x8822, 0, 0, "mp_rtl8822b_fw", "rtl8822b_fw", "rtl8822b_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_24K}, /* RTL8822BU */ +{ 0x0BDA, 0xB822, 0x8822, 0, 0, "mp_rtl8822b_fw", "rtl8822b_fw", "rtl8822b_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_24K}, /* RTL8822BE */ { 0x0BDA, 0xB82C, 0x8822, 0, 0, "mp_rtl8822b_fw", "rtl8822b_fw", "rtl8822b_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_24K}, /* RTL8822BU */ -{ 0x0BDA, 0xb023, 0x8822, 0, 0, "mp_rtl8822b_fw", "rtl8822b_fw", "rtl8822b_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_24K}, /* RTL8822BE */ +{ 0x0BDA, 0xB023, 0x8822, 0, 0, "mp_rtl8822b_fw", "rtl8822b_fw", "rtl8822b_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_24K}, /* RTL8822BE */ { 0x0BDA, 0xB703, 0x8703, 0, 0, "mp_rtl8723c_fw", "rtl8723c_fw", "rtl8723c_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_24K}, /* RTL8723CU */ /* todo: RTL8703BU */ { 0x0BDA, 0xD723, 0x8723, 0, 0, "mp_rtl8723d_fw", "rtl8723d_fw", "rtl8723d_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_40K}, /* RTL8723DU */ +{ 0x0BDA, 0xD720, 0x8723, 0, 0, "mp_rtl8723d_fw", "rtl8723d_fw", "rtl8723d_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_40K}, /* RTL8723DE */ { 0x0BDA, 0xB820, 0x8821, 0, 0, "mp_rtl8821c_fw", "rtl8821c_fw", "rtl8821c_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_40K}, /* RTL8821CU */ { 0x0BDA, 0xC820, 0x8821, 0, 0, "mp_rtl8821c_fw", "rtl8821c_fw", "rtl8821c_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_40K}, /* RTL8821CU */ +{ 0x0BDA, 0xC821, 0x8821, 0, 0, "mp_rtl8821c_fw", "rtl8821c_fw", "rtl8821c_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_40K}, /* RTL8821CE */ /* todo: RTL8703CU */ /* NOTE: must append patch entries above the null entry */ @@ -148,6 +152,7 @@ struct btusb_data { unsigned int sco_num; int isoc_altsetting; int suspend_count; + uint16_t sco_handle; //#ifdef CONFIG_HAS_EARLYSUSPEND #if 0 struct early_suspend early_suspend; @@ -156,21 +161,28 @@ struct btusb_data { struct notifier_block reboot_notifier; #endif firmware_info *fw_info; + +#ifdef CONFIG_SCO_OVER_HCI + RTK_sco_card_t *pSCOSnd; +#endif }; #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 1) static bool reset_on_close = 0; #endif int download_patch(firmware_info *fw_info, int cached); +int reset_controller(firmware_info* fw_info); static inline int check_set_dlfw_state_value(uint16_t change_value) { + int state; spin_lock(&dlfw_lock); if(!dlfw_dis_state) { dlfw_dis_state = change_value; } + state = dlfw_dis_state; spin_unlock(&dlfw_lock); - return dlfw_dis_state; + return state; } static inline void set_dlfw_state_value(uint16_t change_value) @@ -316,12 +328,12 @@ static void print_command(struct sk_buff *skb) #if CONFIG_BLUEDROID /* Global parameters for bt usb char driver */ -#define BT_CHAR_DEVICE_NAME "rtk_btusb" +#define BT_CHAR_DEVICE_NAME "rtkbt_dev" struct mutex btchr_mutex; static struct sk_buff_head btchr_readq; static wait_queue_head_t btchr_read_wait; static wait_queue_head_t bt_dlfw_wait; -static int bt_char_dev_registered; +static bool bt_char_dev_registered; static dev_t bt_devid; /* bt char device number */ static struct cdev bt_char_dev; /* bt character device structure */ static struct class *bt_char_class; /* device class for usb char driver */ @@ -493,7 +505,7 @@ static struct sk_buff *rtk_dequeue_try(unsigned int deq_len) skb = rtk_skb_queue[rtk_skb_queue_front]; if (deq_len >= skb->len) { - + rtk_skb_queue[rtk_skb_queue_front] = NULL; rtk_skb_queue_front++; rtk_skb_queue_front %= QUEUE_SIZE; @@ -515,6 +527,22 @@ static inline int is_queue_empty(void) return (rtk_skb_queue_front == rtk_skb_queue_rear) ? 1 : 0; } +static void rtk_clear_queue(void) +{ + struct sk_buff *skb; + spin_lock(&queue_lock); + while(!is_queue_empty()) { + skb = rtk_skb_queue[rtk_skb_queue_front]; + rtk_skb_queue[rtk_skb_queue_front] = NULL; + rtk_skb_queue_front++; + rtk_skb_queue_front %= QUEUE_SIZE; + if (skb) { + kfree_skb(skb); + } + } + spin_unlock(&queue_lock); +} + /* * Realtek - Integrate from hci_core.c */ @@ -552,6 +580,14 @@ static int hci_dev_open(__u16 dev) ret = -EALREADY; goto done; } +/* + ret = hdev->open(hdev); + if(ret < 0){ + RTKBT_ERR("%s:Failed in hdev->open(hdev):%d",__func__,ret); + goto done; + } + set_bit(HCI_UP, &hdev->flags); +*/ done: return ret; @@ -658,6 +694,69 @@ static void hci_unregister_dev(struct hci_dev *hdev) kfree_skb(hdev->reassembly[i]); } + +#ifdef CONFIG_SCO_OVER_HCI +/* copy data from the URB buffer into the ALSA ring buffer */ +static bool rtk_copy_capture_data_to_alsa(struct btusb_data *data, uint8_t* p_data, unsigned int frames) +{ + struct snd_pcm_runtime *runtime; + unsigned int frame_bytes, frames1; + u8 *dest; + RTK_sco_card_t *pSCOSnd = data->pSCOSnd; + + runtime = pSCOSnd->capture.substream->runtime; + frame_bytes = 2; + + dest = runtime->dma_area + pSCOSnd->capture.buffer_pos * frame_bytes; + if (pSCOSnd->capture.buffer_pos + frames <= runtime->buffer_size) { + memcpy(dest, p_data, frames * frame_bytes); + } else { + /* wrap around at end of ring buffer */ + frames1 = runtime->buffer_size - pSCOSnd->capture.buffer_pos; + memcpy(dest, p_data, frames1 * frame_bytes); + memcpy(runtime->dma_area, + p_data + frames1 * frame_bytes, + (frames - frames1) * frame_bytes); + } + + pSCOSnd->capture.buffer_pos += frames; + if (pSCOSnd->capture.buffer_pos >= runtime->buffer_size) { + pSCOSnd->capture.buffer_pos -= runtime->buffer_size; + } + + if((pSCOSnd->capture.buffer_pos%runtime->period_size) == 0) { + snd_pcm_period_elapsed(pSCOSnd->capture.substream); + } + + return false; +} + + +static void hci_send_to_alsa_ringbuffer(struct hci_dev *hdev, struct sk_buff *skb) +{ + struct btusb_data *data = GET_DRV_DATA(hdev); + RTK_sco_card_t *pSCOSnd = data->pSCOSnd; + uint8_t* p_data; + int sco_length = skb->len - HCI_SCO_HDR_SIZE; + + RTKBT_DBG("%s", __func__); + + if (!hdev) { + RTKBT_ERR("%s: Frame for unknown HCI device", __func__); + return; + } + + if (!test_bit(ALSA_CAPTURE_RUNNING, &pSCOSnd->states)) { + //RTKBT_WARN("%s: ALSA is not running", __func__); + return; + } + + p_data = (uint8_t *)skb->data + HCI_SCO_HDR_SIZE; + rtk_copy_capture_data_to_alsa(data, p_data, sco_length/2); +} + +#endif + static void hci_send_to_stack(struct hci_dev *hdev, struct sk_buff *skb) { struct sk_buff *rtk_skb_copy = NULL; @@ -711,9 +810,14 @@ static int hci_recv_frame(struct sk_buff *skb) __net_timestamp(skb); if (atomic_read(&hdev->promisc)) { +#ifdef CONFIG_SCO_OVER_HCI + if(bt_cb(skb)->pkt_type == HCI_SCODATA_PKT) + hci_send_to_alsa_ringbuffer(hdev, skb); +#endif /* Send copy to the sockets */ hci_send_to_stack(hdev, skb); } + kfree_skb(skb); return 0; } @@ -900,6 +1004,7 @@ static int btchr_open(struct inode *inode_p, struct file *file_p) hci_dev_open(0); mutex_unlock(&btchr_mutex); + rtk_clear_queue(); return nonseekable_open(inode_p, file_p); } @@ -1036,6 +1141,11 @@ static unsigned int btchr_poll(struct file *file_p, poll_table *wait) RTKBT_DBG("%s: BT usb char device is polling", __func__); + if(!bt_char_dev_registered) { + RTKBT_ERR("%s: char device has not registered!", __func__); + return POLLERR | POLLHUP; + } + poll_wait(file_p, &btchr_read_wait, wait); hdev = hci_dev_get(0); @@ -1062,12 +1172,16 @@ static unsigned int btchr_poll(struct file *file_p, poll_table *wait) return POLLOUT | POLLWRNORM; } -static long btchr_ioctl(struct file *file_p,unsigned int cmd, unsigned long arg){ +static long btchr_ioctl(struct file *file_p, unsigned int cmd, unsigned long arg){ int ret = 0; struct hci_dev *hdev; struct btusb_data *data; firmware_info *fw_info; + if(!bt_char_dev_registered) { + return -ENODEV; + } + if(check_set_dlfw_state_value(1) != 1) { RTKBT_ERR("%s bt controller is disconnecting!", __func__); return 0; @@ -1106,6 +1220,24 @@ static long btchr_ioctl(struct file *file_p,unsigned int cmd, unsigned long arg) set_dlfw_state_value(0); wake_up_interruptible(&bt_dlfw_wait); return 1; + case GET_USB_INFO: + ret = hdev->open(hdev); + if(ret < 0){ + RTKBT_ERR("%s:Failed in hdev->open(hdev):%d",__func__,ret); + //goto done; + } + set_bit(HCI_UP, &hdev->flags); + return usb_info; + case RESET_CONTROLLER: + reset_controller(fw_info); + return 1; + +#ifdef CONFIG_SCO_OVER_HCI + case SET_ISO_CFG: + hdev->voice_setting = *(__u16 *)arg; + RTKBT_INFO(" voice settings = 0x%04x", hdev->voice_setting); + return 1; +#endif default: RTKBT_ERR("%s:Failed with wrong Cmd:%d",__func__,cmd); goto failed; @@ -1277,6 +1409,7 @@ static patch_info *get_fw_table_entry(struct usb_device* udev) uint32_t i; RTKBT_INFO("%s: Product id = 0x%04x, fw table entry size %d", __func__, pid, entry_size); + usb_info = (uint32_t)(vid<<16) | pid; for (i = 0; i < entry_size; i++, patch_entry++) { if ((vid == patch_entry->vid)&&(pid == patch_entry->pid)) @@ -1373,7 +1506,7 @@ int reset_controller(firmware_info* fw_info) //sleep 1s for firmware reset. msleep(1000); - RTKBT_INFO("%s: Wait fw reset for 1ms",__func__); + RTKBT_INFO("%s: Wait fw reset for 1000ms",__func__); return ret_val; } @@ -1618,7 +1751,7 @@ void rtk_update_altsettings(patch_info *patch_entry, const unsigned char* org_co if (config->data_len != org_config_len - sizeof(struct rtk_bt_vendor_config)) { - RTKBT_ERR("rtk_update_altsettings: config len(%x) is not right(%x)", config->data_len, (unsigned int)(org_config_len-sizeof(struct rtk_bt_vendor_config))); + RTKBT_ERR("rtk_update_altsettings: config len(%x) is not right(%x)", config->data_len, org_config_len-(int)sizeof(struct rtk_bt_vendor_config)); return; } @@ -2526,7 +2659,6 @@ void check_sco_event(struct urb *urb) { u8* opcode = (u8*)(urb->transfer_buffer); u8 status; - static uint16_t sco_handle = 0; uint16_t handle; struct hci_dev *hdev = urb->context; struct btusb_data *data = GET_DRV_DATA(hdev); @@ -2535,19 +2667,21 @@ void check_sco_event(struct urb *urb) case HCI_EV_SYNC_CONN_COMPLETE: RTKBT_INFO("%s: HCI_EV_SYNC_CONN_COMPLETE(0x%02x)", __func__, *opcode); status = *(opcode + 2); - sco_handle = *(opcode + 3) | *(opcode + 4) << 8; + data->sco_handle = *(opcode + 3) | *(opcode + 4) << 8; + //hdev->voice_setting = *(uint16_t*)&opcode[15]; if (status == 0) { hdev->conn_hash.sco_num++; - schedule_work(&data->work); + hdev->notify(hdev, 0); } break; case HCI_EV_DISCONN_COMPLETE: - RTKBT_INFO("%s: HCI_EV_DISCONN_COMPLETE(0x%02x)", __func__, *opcode); status = *(opcode + 2); handle = *(opcode + 3) | *(opcode + 4) << 8; - if (status == 0 && sco_handle == handle) { + if (status == 0 && data->sco_handle == handle) { + RTKBT_INFO("%s: SCO HCI_EV_DISCONN_COMPLETE(0x%02x)", __func__, *opcode); hdev->conn_hash.sco_num--; - schedule_work(&data->work); + hdev->notify(hdev, 0); + data->sco_handle = 0; } break; default: @@ -2565,7 +2699,9 @@ static void btusb_intr_complete(struct urb *urb) RTKBT_DBG("%s: urb %p status %d count %d ", __func__, urb, urb->status, urb->actual_length); -// check_sco_event(urb); +#ifdef CONFIG_SCO_OVER_HCI + check_sco_event(urb); +#endif if (!test_bit(HCI_RUNNING, &hdev->flags)) return; @@ -3031,6 +3167,156 @@ static int btusb_flush(struct hci_dev *hdev) return 0; } +#ifdef CONFIG_SCO_OVER_HCI +static void btusb_isoc_snd_tx_complete(struct urb *urb); + +static int snd_send_sco_frame(struct sk_buff *skb) +{ + struct hci_dev *hdev = (struct hci_dev *) skb->dev; + + struct btusb_data *data = GET_DRV_DATA(hdev); + //struct usb_ctrlrequest *dr; + struct urb *urb; + unsigned int pipe; + int err; + + RTKBT_DBG("%s:pkt type %d, packet_len : %d", + __func__,bt_cb(skb)->pkt_type, skb->len); + + if (!hdev && !test_bit(HCI_RUNNING, &hdev->flags)) + return -EBUSY; + + if (!data->isoc_tx_ep || hdev->conn_hash.sco_num < 1) { + kfree(skb); + return -ENODEV; + } + + urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_ATOMIC); + if (!urb) { + RTKBT_ERR("%s: Failed to allocate mem for sco pkts", __func__); + kfree(skb); + return -ENOMEM; + } + + pipe = usb_sndisocpipe(data->udev, data->isoc_tx_ep->bEndpointAddress); + + usb_fill_int_urb(urb, data->udev, pipe, + skb->data, skb->len, btusb_isoc_snd_tx_complete, + skb, data->isoc_tx_ep->bInterval); + + urb->transfer_flags = URB_ISO_ASAP; + + fill_isoc_descriptor(urb, skb->len, + le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize)); + + hdev->stat.sco_tx++; + + usb_anchor_urb(urb, &data->tx_anchor); + + err = usb_submit_urb(urb, GFP_ATOMIC); + if (err < 0) { + RTKBT_ERR("%s: Failed to submit urb %p, pkt type %d, err %d", + __func__, urb, bt_cb(skb)->pkt_type, err); + kfree(urb->setup_packet); + usb_unanchor_urb(urb); + } else + usb_mark_last_busy(data->udev); + usb_free_urb(urb); + + return err; + +} + +static bool snd_copy_send_sco_data( RTK_sco_card_t *pSCOSnd) +{ + struct snd_pcm_runtime *runtime = pSCOSnd->playback.substream->runtime; + unsigned int frame_bytes = 2, frames1; + const u8 *source; + + snd_pcm_uframes_t period_size = runtime->period_size; + int i, count; + u8 buffer[period_size * 3]; + int sco_packet_bytes = pSCOSnd->playback.sco_packet_bytes; + struct sk_buff *skb; + + count = frames_to_bytes(runtime, period_size)/sco_packet_bytes; + skb = bt_skb_alloc(((sco_packet_bytes + HCI_SCO_HDR_SIZE) * count), GFP_ATOMIC); + skb->dev = (void *)hci_dev_get(0); + bt_cb(skb)->pkt_type = HCI_SCODATA_PKT; + skb_put(skb, ((sco_packet_bytes + HCI_SCO_HDR_SIZE) * count)); + if(!skb) + return false; + + RTKBT_DBG("%s, buffer_pos: %d", __FUNCTION__, pSCOSnd->playback.buffer_pos); + + source = runtime->dma_area + pSCOSnd->playback.buffer_pos * frame_bytes; + + if (pSCOSnd->playback.buffer_pos + period_size <= runtime->buffer_size) { + memcpy(buffer, source, period_size * frame_bytes); + } else { + /* wrap around at end of ring buffer */ + frames1 = runtime->buffer_size - pSCOSnd->playback.buffer_pos; + memcpy(buffer, source, frames1 * frame_bytes); + memcpy(&buffer[frames1 * frame_bytes], + runtime->dma_area, (period_size - frames1) * frame_bytes); + } + + pSCOSnd->playback.buffer_pos += period_size; + if ( pSCOSnd->playback.buffer_pos >= runtime->buffer_size) + pSCOSnd->playback.buffer_pos -= runtime->buffer_size; + + for(i = 0; i < count; i++) { + *((__u16 *)(skb->data + i * (sco_packet_bytes + HCI_SCO_HDR_SIZE))) = pSCOSnd->usb_data->sco_handle; + *((__u8 *)(skb->data + i*(sco_packet_bytes + HCI_SCO_HDR_SIZE) + 2)) = sco_packet_bytes; + memcpy((skb->data + i * (sco_packet_bytes + HCI_SCO_HDR_SIZE) + HCI_SCO_HDR_SIZE), + &buffer[sco_packet_bytes * i], sco_packet_bytes); + } + + if(test_bit(ALSA_PLAYBACK_RUNNING, &pSCOSnd->states)) { + snd_pcm_period_elapsed(pSCOSnd->playback.substream); + } + snd_send_sco_frame(skb); + return true; +} + +static void btusb_isoc_snd_tx_complete(struct urb *urb) +{ + struct sk_buff *skb = urb->context; + struct hci_dev *hdev = (struct hci_dev *) skb->dev; + struct btusb_data *data = GET_DRV_DATA(hdev); + RTK_sco_card_t *pSCOSnd = data->pSCOSnd; + + RTKBT_DBG("%s: status %d count %d", + __func__,urb->status, urb->actual_length); + + if (skb && hdev) { + if (!test_bit(HCI_RUNNING, &hdev->flags)) + goto done; + + if (!urb->status) + hdev->stat.byte_tx += urb->transfer_buffer_length; + else + hdev->stat.err_tx++; + } else + RTKBT_ERR("%s: skb 0x%p hdev 0x%p", __func__, skb, hdev); + +done: + kfree(urb->setup_packet); + kfree_skb(skb); + if(test_bit(ALSA_PLAYBACK_RUNNING, &pSCOSnd->states)){ + snd_copy_send_sco_data(pSCOSnd); + //schedule_work(&pSCOSnd->send_sco_work); + } +} + +static void playback_work(struct work_struct *work) +{ + RTK_sco_card_t *pSCOSnd = container_of(work, RTK_sco_card_t, send_sco_work); + + snd_copy_send_sco_data(pSCOSnd); +} + +#endif static int btusb_send_frame(struct sk_buff *skb) { @@ -3098,7 +3384,7 @@ static int btusb_send_frame(struct sk_buff *skb) case HCI_SCODATA_PKT: print_sco(skb, 1); - if (!data->isoc_tx_ep || SCO_NUM < 1) { + if (!data->isoc_tx_ep || hdev->conn_hash.sco_num < 1) { kfree(skb); return -ENODEV; } @@ -3178,8 +3464,10 @@ static void btusb_notify(struct hci_dev *hdev, unsigned int evt) RTKBT_DBG("%s: name %s, evt %d", __func__, hdev->name, evt); - if (SCO_NUM != data->sco_num) { - data->sco_num = SCO_NUM; + RTKBT_INFO("%s: hdev->conn_hash.sco_num= %d, data->sco_num = %d", __func__, hdev->conn_hash.sco_num, + data->sco_num); + if (hdev->conn_hash.sco_num != data->sco_num) { + data->sco_num = hdev->conn_hash.sco_num; schedule_work(&data->work); } } @@ -3228,10 +3516,23 @@ static inline int set_isoc_interface(struct hci_dev *hdev, int altsetting) return 0; } +static int check_controller_support_msbc( struct usb_device *udev) +{ + //fix this in the future,when new card support msbc decode and encode + RTKBT_INFO("%s:pid = 0x%02x, vid = 0x%02x",__func__,udev->descriptor.idProduct, udev->descriptor.idVendor); + switch (udev->descriptor.idProduct) { + + default: + return 0; + } + return 0; +} + static void btusb_work(struct work_struct *work) { struct btusb_data *data = container_of(work, struct btusb_data, work); struct hci_dev *hdev = data->hdev; + int err; int new_alts; if (data->sco_num > 0) { @@ -3246,18 +3547,28 @@ static void btusb_work(struct work_struct *work) set_bit(BTUSB_DID_ISO_RESUME, &data->flags); } -#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 7, 1) - if (hdev->voice_setting & 0x0020) { - static const int alts[3] = { 2, 4, 5 }; - new_alts = alts[data->sco_num - 1]; + + RTKBT_INFO("%s voice settings = 0x%04x", __func__, hdev->voice_setting); + if (!(hdev->voice_setting & 0x0003)) { + if(data->sco_num == 1) + new_alts = 2; + else { + RTKBT_ERR("%s: we don't support mutiple sco link for cvsd", __func__); + return; + } } else{ - new_alts = data->sco_num; + if(check_controller_support_msbc(data->udev)) { + if(data->sco_num == 1) + new_alts = 4; + else { + RTKBT_ERR("%s: we don't support mutiple sco link for msbc", __func__); + return; + } + } else { + new_alts = 2; + } } if (data->isoc_altsetting != new_alts) { -#else - if (data->isoc_altsetting != 2) { - new_alts = 2; -#endif clear_bit(BTUSB_ISOC_RUNNING, &data->flags); mdelay(URB_CANCELING_DELAY_MS); @@ -3273,8 +3584,18 @@ static void btusb_work(struct work_struct *work) else btusb_submit_isoc_urb(hdev, GFP_KERNEL); } +#ifdef CONFIG_SCO_OVER_HCI + if(test_bit(BTUSB_ISOC_RUNNING, &data->flags)) { + set_bit(USB_CAPTURE_RUNNING, &data->pSCOSnd->states); + set_bit(USB_PLAYBACK_RUNNING, &data->pSCOSnd->states); + } +#endif } else { clear_bit(BTUSB_ISOC_RUNNING, &data->flags); +#ifdef CONFIG_SCO_OVER_HCI + clear_bit(USB_CAPTURE_RUNNING, &data->pSCOSnd->states); + clear_bit(USB_PLAYBACK_RUNNING, &data->pSCOSnd->states); +#endif mdelay(URB_CANCELING_DELAY_MS); usb_kill_anchored_urbs(&data->isoc_anchor); @@ -3452,6 +3773,337 @@ int bt_reboot_notify(struct notifier_block *notifier, ulong pm_event, void *unus #endif +#ifdef CONFIG_SCO_OVER_HCI +static const struct snd_pcm_hardware snd_card_sco_capture_default = +{ + .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_NONINTERLEAVED | + SNDRV_PCM_ACCESS_RW_INTERLEAVED | SNDRV_PCM_INFO_FIFO_IN_FRAMES), + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8, + .rates = (SNDRV_PCM_RATE_8000), + .rate_min = 8000, + .rate_max = 8000, + .channels_min = 1, + .channels_max = 1, + .buffer_bytes_max = 8 * 768, + .period_bytes_min = 48, + .period_bytes_max = 768, + .periods_min = 1, + .periods_max = 8, + .fifo_size = 8, + +}; + +static int snd_sco_capture_pcm_open(struct snd_pcm_substream * substream) +{ + RTK_sco_card_t *pSCOSnd = substream->private_data; + + RTKBT_INFO("%s", __FUNCTION__); + pSCOSnd->capture.substream = substream; + + memcpy(&substream->runtime->hw, &snd_card_sco_capture_default, sizeof(struct snd_pcm_hardware)); + + if(check_controller_support_msbc(pSCOSnd->dev)) { + substream->runtime->hw.rates |= SNDRV_PCM_RATE_16000; + substream->runtime->hw.rate_max = 16000; + substream->runtime->hw.period_bytes_min = 96; + substream->runtime->hw.period_bytes_max = 16 * 96; + substream->runtime->hw.buffer_bytes_max = 8 * 16 * 96; + } + set_bit(ALSA_CAPTURE_OPEN, &pSCOSnd->states); + return 0; +} + +static int snd_sco_capture_pcm_close(struct snd_pcm_substream *substream) +{ + RTK_sco_card_t *pSCOSnd = substream->private_data; + + clear_bit(ALSA_CAPTURE_OPEN, &pSCOSnd->states); + return 0; +} + +static int snd_sco_capture_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg) +{ + RTKBT_DBG("%s, cmd = %d", __FUNCTION__, cmd); + switch (cmd) + { + default: + return snd_pcm_lib_ioctl(substream, cmd, arg); + } + return 0; +} + +static int snd_sco_capture_pcm_hw_params(struct snd_pcm_substream * substream, struct snd_pcm_hw_params * hw_params) +{ + + int err; + struct snd_pcm_runtime *runtime = substream->runtime; + err = snd_pcm_lib_alloc_vmalloc_buffer(substream, params_buffer_bytes(hw_params)); + RTKBT_INFO("%s,err : %d, runtime state : %d", __FUNCTION__, err, runtime->status->state); + return err; +} + +static int snd_sco_capture_pcm_hw_free(struct snd_pcm_substream * substream) +{ + RTKBT_DBG("%s", __FUNCTION__); + return snd_pcm_lib_free_vmalloc_buffer(substream);; +} + +static int snd_sco_capture_pcm_prepare(struct snd_pcm_substream *substream) +{ + RTK_sco_card_t *pSCOSnd = substream->private_data; + struct snd_pcm_runtime *runtime = substream->runtime; + + RTKBT_INFO("%s", __FUNCTION__); + if (test_bit(DISCONNECTED, &pSCOSnd->states)) + return -ENODEV; + if (!test_bit(USB_CAPTURE_RUNNING, &pSCOSnd->states)) + return -EIO; + + if(runtime->rate == 8000) { + if(pSCOSnd->usb_data->isoc_altsetting != 2) + return -ENOEXEC; + pSCOSnd->capture.sco_packet_bytes = 48; + } + else if(runtime->rate == 16000 && check_controller_support_msbc(pSCOSnd->dev)) { + if(pSCOSnd->usb_data->isoc_altsetting != 4) + return -ENOEXEC; + pSCOSnd->capture.sco_packet_bytes = 96; + } + else if(pSCOSnd->usb_data->isoc_altsetting == 2) { + pSCOSnd->capture.sco_packet_bytes = 48; + } + else if(pSCOSnd->usb_data->isoc_altsetting == 1) { + pSCOSnd->capture.sco_packet_bytes = 24; + } + return 0; +} + +static int snd_sco_capture_pcm_trigger(struct snd_pcm_substream *substream, int cmd) +{ + RTK_sco_card_t *pSCOSnd = substream->private_data; + RTKBT_INFO("%s, cmd : %d", __FUNCTION__, cmd); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + if (!test_bit(USB_CAPTURE_RUNNING, &pSCOSnd->states)) + return -EIO; + set_bit(ALSA_CAPTURE_RUNNING, &pSCOSnd->states); + return 0; + case SNDRV_PCM_TRIGGER_STOP: + clear_bit(ALSA_CAPTURE_RUNNING, &pSCOSnd->states); + return 0; + default: + return -EINVAL; + } +} + +static snd_pcm_uframes_t snd_sco_capture_pcm_pointer(struct snd_pcm_substream *substream) +{ + RTK_sco_card_t *pSCOSnd = substream->private_data; + + return pSCOSnd->capture.buffer_pos; +} + + +static struct snd_pcm_ops snd_sco_capture_pcm_ops = { + .open = snd_sco_capture_pcm_open, + .close = snd_sco_capture_pcm_close, + .ioctl = snd_sco_capture_ioctl, + .hw_params = snd_sco_capture_pcm_hw_params, + .hw_free = snd_sco_capture_pcm_hw_free, + .prepare = snd_sco_capture_pcm_prepare, + .trigger = snd_sco_capture_pcm_trigger, + .pointer = snd_sco_capture_pcm_pointer, +}; + + +static const struct snd_pcm_hardware snd_card_sco_playback_default = +{ + .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_NONINTERLEAVED | + SNDRV_PCM_ACCESS_RW_INTERLEAVED | SNDRV_PCM_INFO_FIFO_IN_FRAMES), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rates = (SNDRV_PCM_RATE_8000), + .rate_min = 8000, + .rate_max = 8000, + .channels_min = 1, + .channels_max = 1, + .buffer_bytes_max = 8 * 768, + .period_bytes_min = 48, + .period_bytes_max = 768, + .periods_min = 1, + .periods_max = 8, + .fifo_size = 8, +}; + +static int snd_sco_playback_pcm_open(struct snd_pcm_substream * substream) +{ + RTK_sco_card_t *pSCOSnd = substream->private_data; + int err = 0; + + RTKBT_INFO("%s, rate : %d", __FUNCTION__, substream->runtime->rate); + memcpy(&substream->runtime->hw, &snd_card_sco_playback_default, sizeof(struct snd_pcm_hardware)); + if(check_controller_support_msbc(pSCOSnd->dev)) { + substream->runtime->hw.rates |= SNDRV_PCM_RATE_16000; + substream->runtime->hw.rate_max = 16000; + substream->runtime->hw.period_bytes_min = 96; + substream->runtime->hw.period_bytes_max = 16 * 96; + substream->runtime->hw.buffer_bytes_max = 8 * 16 * 96; + } + pSCOSnd->playback.substream = substream; + set_bit(ALSA_PLAYBACK_OPEN, &pSCOSnd->states); + + return err; +} + +static int snd_sco_playback_pcm_close(struct snd_pcm_substream *substream) +{ + RTK_sco_card_t *pSCOSnd = substream->private_data; + + clear_bit(ALSA_PLAYBACK_OPEN, &pSCOSnd->states); + cancel_work_sync(&pSCOSnd->send_sco_work); + return 0; +} + +static int snd_sco_playback_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg) +{ + RTKBT_DBG("%s, cmd : %d", __FUNCTION__, cmd); + switch (cmd) + { + default: + return snd_pcm_lib_ioctl(substream, cmd, arg); + break; + } + return 0; +} + +static int snd_sco_playback_pcm_hw_params(struct snd_pcm_substream * substream, struct snd_pcm_hw_params * hw_params) +{ + int err; + err = snd_pcm_lib_alloc_vmalloc_buffer(substream, params_buffer_bytes(hw_params)); + return err; +} + +static int snd_sco_palyback_pcm_hw_free(struct snd_pcm_substream * substream) +{ + RTKBT_DBG("%s", __FUNCTION__); + return snd_pcm_lib_free_vmalloc_buffer(substream); +} + +static int snd_sco_playback_pcm_prepare(struct snd_pcm_substream *substream) +{ + RTK_sco_card_t *pSCOSnd = substream->private_data; + struct snd_pcm_runtime *runtime = substream->runtime; + + RTKBT_INFO("%s, bound_rate = %d", __FUNCTION__, runtime->rate); + + if (test_bit(DISCONNECTED, &pSCOSnd->states)) + return -ENODEV; + if (!test_bit(USB_PLAYBACK_RUNNING, &pSCOSnd->states)) + return -EIO; + + if(runtime->rate == 8000) { + if(pSCOSnd->usb_data->isoc_altsetting != 2) + return -ENOEXEC; + pSCOSnd->playback.sco_packet_bytes = 48; + } + else if(runtime->rate == 16000) { + if(pSCOSnd->usb_data->isoc_altsetting != 4) + return -ENOEXEC; + pSCOSnd->playback.sco_packet_bytes = 96; + } + + return 0; +} + +static int snd_sco_playback_pcm_trigger(struct snd_pcm_substream *substream, int cmd) +{ + RTK_sco_card_t *pSCOSnd = substream->private_data; + + RTKBT_INFO("%s, cmd = %d", __FUNCTION__, cmd); + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + if (!test_bit(USB_PLAYBACK_RUNNING, &pSCOSnd->states)) + return -EIO; + set_bit(ALSA_PLAYBACK_RUNNING, &pSCOSnd->states); + schedule_work(&pSCOSnd->send_sco_work); + return 0; + case SNDRV_PCM_TRIGGER_STOP: + clear_bit(ALSA_PLAYBACK_RUNNING, &pSCOSnd->states); + return 0; + default: + return -EINVAL; + } +} + +static snd_pcm_uframes_t snd_sco_playback_pcm_pointer(struct snd_pcm_substream *substream) +{ + RTK_sco_card_t *pSCOSnd = substream->private_data; + + return pSCOSnd->playback.buffer_pos; +} + + +static struct snd_pcm_ops snd_sco_playback_pcm_ops = { + .open = snd_sco_playback_pcm_open, + .close = snd_sco_playback_pcm_close, + .ioctl = snd_sco_playback_ioctl, + .hw_params = snd_sco_playback_pcm_hw_params, + .hw_free = snd_sco_palyback_pcm_hw_free, + .prepare = snd_sco_playback_pcm_prepare, + .trigger = snd_sco_playback_pcm_trigger, + .pointer = snd_sco_playback_pcm_pointer, +}; + + +static RTK_sco_card_t* btusb_snd_init(struct usb_interface *intf, const struct usb_device_id *id, struct btusb_data *data) +{ + struct snd_card *card; + RTK_sco_card_t *pSCOSnd; + int err=0; + RTKBT_INFO("%s", __func__); + err = snd_card_new(&intf->dev, + -1, RTK_SCO_ID, THIS_MODULE, + sizeof(RTK_sco_card_t), &card); + if (err < 0) { + RTKBT_ERR("%s: sco snd card create fail", __func__); + return NULL; + } + // private data + pSCOSnd = (RTK_sco_card_t *)card->private_data; + pSCOSnd->card = card; + pSCOSnd->dev = interface_to_usbdev(intf); + pSCOSnd->usb_data = data; + + strcpy(card->driver, RTK_SCO_ID); + strcpy(card->shortname, "Realtek sco snd"); + sprintf(card->longname, "Realtek sco over hci: VID:0x%04x, PID:0x%04x", + id->idVendor, pSCOSnd->dev->descriptor.idProduct); + + err = snd_pcm_new(card, RTK_SCO_ID, 0, 1, 1, &pSCOSnd->pcm); + if (err < 0) { + RTKBT_ERR("%s: sco snd card new pcm fail", __func__); + return NULL; + } + pSCOSnd->pcm->private_data = pSCOSnd; + sprintf(pSCOSnd->pcm->name, "sco_pcm:VID:0x%04x, PID:0x%04x", + id->idVendor, pSCOSnd->dev->descriptor.idProduct); + + snd_pcm_set_ops(pSCOSnd->pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sco_playback_pcm_ops); + snd_pcm_set_ops(pSCOSnd->pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sco_capture_pcm_ops); + + err = snd_card_register(card); + if (err < 0) { + RTKBT_ERR("%s: sco snd card register card fail", __func__); + return NULL; + } + + spin_lock_init(&pSCOSnd->capture_lock); + spin_lock_init(&pSCOSnd->playback_lock); + INIT_WORK(&pSCOSnd->send_sco_work, playback_work); + return pSCOSnd; +} +#endif + static int btusb_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(intf); @@ -3530,20 +4182,6 @@ static int btusb_probe(struct usb_interface *intf, const struct usb_device_id *i goto end; } - RTKBT_INFO("%s: download begining...", __func__); - -#if CONFIG_BLUEDROID - mutex_lock(&btchr_mutex); -#endif - - - -#if CONFIG_BLUEDROID - mutex_unlock(&btchr_mutex); -#endif - - RTKBT_INFO("%s: download ending...", __func__); - hdev = hci_alloc_dev(); if (!hdev) { rtk_free(data); @@ -3590,6 +4228,9 @@ static int btusb_probe(struct usb_interface *intf, const struct usb_device_id *i data = NULL; return err; } +#ifdef CONFIG_SCO_OVER_HCI + data->pSCOSnd = btusb_snd_init(intf, id, data); +#endif } err = hci_register_dev(hdev); @@ -3638,6 +4279,9 @@ static void btusb_disconnect(struct usb_interface *intf) struct btusb_data *data; struct hci_dev *hdev = NULL; + if (intf->cur_altsetting->desc.bInterfaceNumber != 0) + return; + wait_event_interruptible(bt_dlfw_wait, (check_set_dlfw_state_value(2) == 2)); RTKBT_INFO("%s: usb_interface %p, bInterfaceNumber %d", @@ -3645,9 +4289,6 @@ static void btusb_disconnect(struct usb_interface *intf) data = usb_get_intfdata(intf); - if (intf->cur_altsetting->desc.bInterfaceNumber != 0) - return; - if (data) hdev = data->hdev; else { @@ -3655,6 +4296,19 @@ static void btusb_disconnect(struct usb_interface *intf) return; } +#ifdef CONFIG_SCO_OVER_HCI + if (intf->cur_altsetting->desc.bInterfaceNumber == 0) { + RTK_sco_card_t *pSCOSnd = data->pSCOSnd; + if(!pSCOSnd) { + RTKBT_ERR("%s: sco private data is null", __func__); + return; + } + set_bit(DISCONNECTED, &pSCOSnd->states); + snd_card_disconnect(pSCOSnd->card); + snd_card_free_when_closed(pSCOSnd->card); + } +#endif + //#ifdef CONFIG_HAS_EARLYSUSPEND #if 0 unregister_early_suspend(&data->early_suspend); @@ -3868,7 +4522,7 @@ static int __init btusb_init(void) /* usb register will go on, even bt char register failed */ RTKBT_ERR("Failed to register usb char device interfaces"); } else - bt_char_dev_registered = 1; + bt_char_dev_registered = true; #endif err = usb_register(&btusb_driver); if (err < 0) @@ -3878,10 +4532,19 @@ static int __init btusb_init(void) static void __exit btusb_exit(void) { + struct hci_dev *hdev; RTKBT_INFO("Realtek Bluetooth USB driver module exit"); #if CONFIG_BLUEDROID - if (bt_char_dev_registered > 0) + hdev = hci_dev_get(0); + if (bt_char_dev_registered) { + bt_char_dev_registered = false; + while(hdev && atomic_read(&hdev->promisc)) { + RTKBT_ERR("%s: rtkbt driver is being removed, but application is still running!", __func__); + RTKBT_ERR("%s: wait bt application to stop, or the driver can't be removed", __func__); + mdelay(100); + } btchr_exit(); + } #endif usb_deregister(&btusb_driver); } diff --git a/drivers/bluetooth/rtk_btusb.h b/drivers/bluetooth/rtk_btusb.h old mode 100755 new mode 100644 index 47fb3d5edbd4f..7f6222ebba594 --- a/drivers/bluetooth/rtk_btusb.h +++ b/drivers/bluetooth/rtk_btusb.h @@ -36,8 +36,45 @@ #include #define CONFIG_BLUEDROID 1 /* bleuz 0, bluedroid 1 */ +//#define CONFIG_SCO_OVER_HCI +#ifdef CONFIG_SCO_OVER_HCI +#include +#include +#include +#include +#include +#define RTK_SCO_ID "snd_sco_rtk" +enum { + USB_CAPTURE_RUNNING, + USB_PLAYBACK_RUNNING, + ALSA_CAPTURE_OPEN, + ALSA_PLAYBACK_OPEN, + ALSA_CAPTURE_RUNNING, + ALSA_PLAYBACK_RUNNING, + CAPTURE_URB_COMPLETED, + PLAYBACK_URB_COMPLETED, + DISCONNECTED, +}; + +// RTK sound card +typedef struct RTK_sco_card { + struct snd_card *card; + struct snd_pcm *pcm; + struct usb_device *dev; + struct btusb_data *usb_data; + unsigned long states; + struct rtk_sco_stream { + struct snd_pcm_substream *substream; + unsigned int sco_packet_bytes; + snd_pcm_uframes_t buffer_pos; + } capture, playback; + spinlock_t capture_lock; + spinlock_t playback_lock; + struct work_struct send_sco_work; +} RTK_sco_card_t; +#endif /* Some Android system may use standard Linux kernel, while * standard Linux may also implement early suspend feature. * So exclude earysuspend.h from CONFIG_BLUEDROID. @@ -96,12 +133,9 @@ #define GET_DRV_DATA(x) x->driver_data #endif -#define SCO_NUM hdev->conn_hash.sco_num - - #define BTUSB_RPM (0 * USB_RPM) /* 1 SS enable; 0 SS disable */ #define BTUSB_WAKEUP_HOST 0 /* 1 enable; 0 disable */ -#define BTUSB_MAX_ISOC_FRAMES 10 +#define BTUSB_MAX_ISOC_FRAMES 48 #define BTUSB_INTR_RUNNING 0 #define BTUSB_BULK_RUNNING 1 #define BTUSB_ISOC_RUNNING 2 @@ -445,9 +479,7 @@ struct hci_dev { #if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 4, 0) void (*destruct)(struct hci_dev *hdev); #endif -#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 7, 1) __u16 voice_setting; -#endif void (*notify)(struct hci_dev *hdev, unsigned int evt); int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg); }; @@ -630,7 +662,11 @@ typedef struct { //Define ioctl cmd the same as HCIDEVUP in the kernel #define DOWN_FW_CFG _IOW('H', 201, int) - +#ifdef CONFIG_SCO_OVER_HCI +#define SET_ISO_CFG _IOW('H', 202, int) +#endif +#define GET_USB_INFO _IOW('H', 203, int) +#define RESET_CONTROLLER _IOW('H', 204, int) /* for altsettings*/ #include @@ -643,6 +679,7 @@ static inline int getmacaddr(uint8_t * vnd_local_bd_addr) mm_segment_t oldfs; char buf[FACTORY_BT_BDADDR_STORAGE_LEN]; int32_t i = 0; + int ret = -1; memset(buf, 0, FACTORY_BT_BDADDR_STORAGE_LEN); bdaddr_file = filp_open(BDADDR_FILE, O_RDONLY, 0); if (IS_ERR(bdaddr_file)){ @@ -651,25 +688,29 @@ static inline int getmacaddr(uint8_t * vnd_local_bd_addr) } oldfs = get_fs(); set_fs(KERNEL_DS); bdaddr_file->f_op->llseek(bdaddr_file, 0, 0); - bdaddr_file->f_op->read(bdaddr_file, buf, FACTORY_BT_BDADDR_STORAGE_LEN, &bdaddr_file->f_pos); - for (i = 0; i < 6; i++) { - if(buf[3*i]>'9') - { - if(buf[3*i]>'Z') - buf[3*i] -=('a'-'A'); //change a to A - buf[3*i] -= ('A'-'9'-1); - } - if(buf[3*i+1]>'9') - { - if(buf[3*i+1]>'Z') - buf[3*i+1] -=('a'-'A'); //change a to A - buf[3*i+1] -= ('A'-'9'-1); - } - vnd_local_bd_addr[5-i] = ((uint8_t)buf[3*i]-'0')*16 + ((uint8_t)buf[3*i+1]-'0'); - } + ret = vfs_read(bdaddr_file, buf, FACTORY_BT_BDADDR_STORAGE_LEN, &bdaddr_file->f_pos); set_fs(oldfs); filp_close(bdaddr_file, NULL); - return 0; + if(ret == FACTORY_BT_BDADDR_STORAGE_LEN) + { + for (i = 0; i < 6; i++) { + if(buf[3*i]>'9') + { + if(buf[3*i]>'Z') + buf[3*i] -=('a'-'A'); //change a to A + buf[3*i] -= ('A'-'9'-1); + } + if(buf[3*i+1]>'9') + { + if(buf[3*i+1]>'Z') + buf[3*i+1] -=('a'-'A'); //change a to A + buf[3*i+1] -= ('A'-'9'-1); + } + vnd_local_bd_addr[5-i] = ((uint8_t)buf[3*i]-'0')*16 + ((uint8_t)buf[3*i+1]-'0'); + } + return 0; + } + return -1; } static inline int getAltSettings(patch_info *patch_entry, unsigned short *offset, int max_group_cnt) diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index b5f245d2875cc..1012b2cb6a165 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c @@ -1154,9 +1154,6 @@ int cdrom_open(struct cdrom_device_info *cdi, struct block_device *bdev, cd_dbg(CD_OPEN, "entering cdrom_open\n"); - /* open is event synchronization point, check events first */ - check_disk_change(bdev); - /* if this was a O_NONBLOCK open and we should honor the flags, * do a quick open without drive/disc integrity checks. */ cdi->use_count++; @@ -2529,7 +2526,7 @@ static int cdrom_ioctl_drive_status(struct cdrom_device_info *cdi, if (!CDROM_CAN(CDC_SELECT_DISC) || (arg == CDSL_CURRENT || arg == CDSL_NONE)) return cdi->ops->drive_status(cdi, CDSL_CURRENT); - if (((int)arg >= cdi->capacity)) + if (arg >= cdi->capacity) return -EINVAL; return cdrom_slot_status(cdi, arg); } diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c index 584bc3126403d..e2808fefbb78b 100644 --- a/drivers/cdrom/gdrom.c +++ b/drivers/cdrom/gdrom.c @@ -497,6 +497,9 @@ static struct cdrom_device_ops gdrom_ops = { static int gdrom_bdops_open(struct block_device *bdev, fmode_t mode) { int ret; + + check_disk_change(bdev); + mutex_lock(&gdrom_mutex); ret = cdrom_open(gd.cd_info, bdev, mode); mutex_unlock(&gdrom_mutex); diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index dbf22719462f9..c38fa0e92d914 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig @@ -381,6 +381,18 @@ config HW_RANDOM_STM32 If unsure, say N. +config HW_RANDOM_ROCKCHIP + tristate "Rockchip Random Number Generator support" + depends on ARCH_ROCKCHIP + help + This driver provides kernel-side support for the Random Number + Generator hardware found on Rockchip cpus. + + To compile this driver as a module, choose M here: the + module will be called rockchip-rng. + + If unsure, say Y. + endif # HW_RANDOM config UML_RANDOM diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile index 5ad3976351283..653bf8dfaa1d8 100644 --- a/drivers/char/hw_random/Makefile +++ b/drivers/char/hw_random/Makefile @@ -33,3 +33,4 @@ obj-$(CONFIG_HW_RANDOM_MSM) += msm-rng.o obj-$(CONFIG_HW_RANDOM_ST) += st-rng.o obj-$(CONFIG_HW_RANDOM_XGENE) += xgene-rng.o obj-$(CONFIG_HW_RANDOM_STM32) += stm32-rng.o +obj-$(CONFIG_HW_RANDOM_ROCKCHIP) += rockchip-rng.o diff --git a/drivers/char/hw_random/rockchip-rng.c b/drivers/char/hw_random/rockchip-rng.c new file mode 100644 index 0000000000000..e9520639ce4ee --- /dev/null +++ b/drivers/char/hw_random/rockchip-rng.c @@ -0,0 +1,217 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * rockchip-rng.c Random Number Generator driver for the Rockchip + * + * Copyright (c) 2018, Fuzhou Rockchip Electronics Co., Ltd. + * Author: Lin Jinhan + * + */ +#include +#include +#include +#include +#include +#include + +#define _SBF(s, v) ((v) << (s)) +#define HIWORD_UPDATE(val, mask, shift) \ + ((val) << (shift) | (mask) << ((shift) + 16)) + +#define CRYPTO_CLK_NUM (4) +#define ROCKCHIP_AUTOSUSPEND_DELAY 100 +#define ROCKCHIP_POLL_PERIOD_US 100 +#define ROCKCHIP_POLL_TIMEOUT_US 10000 + +#define RK_MAX_RNG_BYTE (32) +#define CRYPTO_RNG_CTL 0x0400 +#define CRYPTO_RNG_64_BIT_LEN _SBF(4, 0x00) +#define CRYPTO_RNG_128_BIT_LEN _SBF(4, 0x01) +#define CRYPTO_RNG_192_BIT_LEN _SBF(4, 0x02) +#define CRYPTO_RNG_256_BIT_LEN _SBF(4, 0x03) +#define CRYPTO_RNG_FATESY_SOC_RING _SBF(2, 0x00) +#define CRYPTO_RNG_SLOWER_SOC_RING_0 _SBF(2, 0x01) +#define CRYPTO_RNG_SLOWER_SOC_RING_1 _SBF(2, 0x02) +#define CRYPTO_RNG_SLOWEST_SOC_RING _SBF(2, 0x03) +#define CRYPTO_RNG_ENABLE BIT(1) +#define CRYPTO_RNG_START BIT(0) + +#define CRYPTO_RNG_SAMPLE_CNT 0x0404 +#define CRYPTO_RNG_DOUT_0 0x0410 + +struct rk_rng { + struct device *dev; + struct hwrng rng; + void __iomem *mem; + struct clk_bulk_data clk_bulk[CRYPTO_CLK_NUM]; +}; + +static void rk_rng_writel(struct rk_rng *rng, u32 val, u32 offset) +{ + __raw_writel(val, rng->mem + offset); +} + +static int rk_rng_init(struct hwrng *rng) +{ + int ret; + struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng); + + dev_dbg(rk_rng->dev, "clk_bulk_prepare_enable.\n"); + + ret = clk_bulk_prepare_enable(CRYPTO_CLK_NUM, &rk_rng->clk_bulk[0]); + if (ret < 0) { + dev_err(rk_rng->dev, "failed to enable clks %d\n", ret); + return ret; + } + + return 0; +} + +static void rk_rng_cleanup(struct hwrng *rng) +{ + struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng); + + dev_dbg(rk_rng->dev, "clk_bulk_disable_unprepare.\n"); + clk_bulk_disable_unprepare(CRYPTO_CLK_NUM, &rk_rng->clk_bulk[0]); +} + +static int rk_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait) +{ + int ret = 0; + u32 reg_ctrl = 0; + struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng); + + pm_runtime_get_sync(rk_rng->dev); + + /* enable osc_ring to get entropy, sample period is set as 100 */ + rk_rng_writel(rk_rng, 100, CRYPTO_RNG_SAMPLE_CNT); + + reg_ctrl |= CRYPTO_RNG_256_BIT_LEN; + reg_ctrl |= CRYPTO_RNG_SLOWER_SOC_RING_0; + reg_ctrl |= CRYPTO_RNG_ENABLE; + reg_ctrl |= CRYPTO_RNG_START; + + rk_rng_writel(rk_rng, HIWORD_UPDATE(reg_ctrl, 0xffff, 0), + CRYPTO_RNG_CTL); + + ret = readl_poll_timeout(rk_rng->mem + CRYPTO_RNG_CTL, reg_ctrl, + !(reg_ctrl & CRYPTO_RNG_START), + ROCKCHIP_POLL_PERIOD_US, + ROCKCHIP_POLL_TIMEOUT_US); + if (ret < 0) + goto out; + + ret = min_t(size_t, max, RK_MAX_RNG_BYTE); + + memcpy_fromio(buf, rk_rng->mem + CRYPTO_RNG_DOUT_0, ret); + +out: + /* close TRNG */ + rk_rng_writel(rk_rng, HIWORD_UPDATE(0, 0xffff, 0), CRYPTO_RNG_CTL); + + pm_runtime_mark_last_busy(rk_rng->dev); + pm_runtime_put_sync_autosuspend(rk_rng->dev); + + return ret; +} + +static int rk_rng_probe(struct platform_device *pdev) +{ + struct rk_rng *rk_rng; + int ret; + + dev_dbg(&pdev->dev, "probing...\n"); + rk_rng = devm_kzalloc(&pdev->dev, sizeof(struct rk_rng), GFP_KERNEL); + if (!rk_rng) + return -ENOMEM; + + rk_rng->dev = &pdev->dev; + rk_rng->rng.name = "rockchip"; +#ifndef CONFIG_PM + rk_rng->rng.init = rk_rng_init; + rk_rng->rng.cleanup = rk_rng_cleanup, +#endif + rk_rng->rng.read = rk_rng_read; + rk_rng->rng.quality = 999; + + rk_rng->clk_bulk[0].id = "hclk_crypto"; + rk_rng->clk_bulk[1].id = "aclk_crypto"; + rk_rng->clk_bulk[2].id = "clk_crypto"; + rk_rng->clk_bulk[3].id = "clk_crypto_apk"; + + rk_rng->mem = devm_of_iomap(&pdev->dev, pdev->dev.of_node, 0, NULL); + if (IS_ERR(rk_rng->mem)) + return PTR_ERR(rk_rng->mem); + + ret = devm_clk_bulk_get(&pdev->dev, CRYPTO_CLK_NUM, + &rk_rng->clk_bulk[0]); + if (ret) { + dev_err(&pdev->dev, "failed to get clks property\n"); + return ret; + } + + platform_set_drvdata(pdev, rk_rng); + + pm_runtime_set_autosuspend_delay(&pdev->dev, + ROCKCHIP_AUTOSUSPEND_DELAY); + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_enable(&pdev->dev); + + ret = devm_hwrng_register(&pdev->dev, &rk_rng->rng); + if (ret) { + pm_runtime_dont_use_autosuspend(&pdev->dev); + pm_runtime_disable(&pdev->dev); + } + + return ret; +} + +#ifdef CONFIG_PM +static int rk_rng_runtime_suspend(struct device *dev) +{ + struct rk_rng *rk_rng = dev_get_drvdata(dev); + + rk_rng_cleanup(&rk_rng->rng); + + return 0; +} + +static int rk_rng_runtime_resume(struct device *dev) +{ + struct rk_rng *rk_rng = dev_get_drvdata(dev); + + return rk_rng_init(&rk_rng->rng); +} + +static const struct dev_pm_ops rk_rng_pm_ops = { + SET_RUNTIME_PM_OPS(rk_rng_runtime_suspend, + rk_rng_runtime_resume, NULL) + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, + pm_runtime_force_resume) +}; + +#endif + +static const struct of_device_id rk_rng_dt_match[] = { + { + .compatible = "rockchip,cryptov2-rng", + }, + { }, +}; +MODULE_DEVICE_TABLE(of, rk_rng_dt_match); + +static struct platform_driver rk_rng_driver = { + .driver = { + .name = "rockchip-rng", +#ifdef CONFIG_PM + .pm = &rk_rng_pm_ops, +#endif + .of_match_table = rk_rng_dt_match, + }, + .probe = rk_rng_probe, +}; + +module_platform_driver(rk_rng_driver); + +MODULE_DESCRIPTION("ROCKCHIP H/W Random Number Generator driver"); +MODULE_AUTHOR("Lin Jinhan "); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/char/hw_random/stm32-rng.c b/drivers/char/hw_random/stm32-rng.c index 92a810648bd00..530aacca3eb8e 100644 --- a/drivers/char/hw_random/stm32-rng.c +++ b/drivers/char/hw_random/stm32-rng.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #define RNG_CR 0x00 @@ -46,6 +47,7 @@ struct stm32_rng_private { struct hwrng rng; void __iomem *base; struct clk *clk; + struct reset_control *rst; }; static int stm32_rng_read(struct hwrng *rng, void *data, size_t max, bool wait) @@ -140,6 +142,13 @@ static int stm32_rng_probe(struct platform_device *ofdev) if (IS_ERR(priv->clk)) return PTR_ERR(priv->clk); + priv->rst = devm_reset_control_get(&ofdev->dev, NULL); + if (!IS_ERR(priv->rst)) { + reset_control_assert(priv->rst); + udelay(2); + reset_control_deassert(priv->rst); + } + dev_set_drvdata(dev, priv); priv->rng.name = dev_driver_string(dev), diff --git a/drivers/char/hw_random/via-rng.c b/drivers/char/hw_random/via-rng.c index 0c98a9d51a249..44ce806069444 100644 --- a/drivers/char/hw_random/via-rng.c +++ b/drivers/char/hw_random/via-rng.c @@ -140,7 +140,7 @@ static int via_rng_init(struct hwrng *rng) * RNG configuration like it used to be the case in this * register */ if ((c->x86 == 6) && (c->x86_model >= 0x0f)) { - if (!cpu_has_xstore_enabled) { + if (!boot_cpu_has(X86_FEATURE_XSTORE_EN)) { pr_err(PFX "can't enable hardware RNG " "if XSTORE is not enabled\n"); return -ENODEV; @@ -200,8 +200,9 @@ static int __init mod_init(void) { int err; - if (!cpu_has_xstore) + if (!boot_cpu_has(X86_FEATURE_XSTORE)) return -ENODEV; + pr_info("VIA RNG detected\n"); err = hwrng_register(&via_rng); if (err) { diff --git a/drivers/char/ipmi/ipmi_bt_sm.c b/drivers/char/ipmi/ipmi_bt_sm.c index feafdab734ae2..4835b588b7833 100644 --- a/drivers/char/ipmi/ipmi_bt_sm.c +++ b/drivers/char/ipmi/ipmi_bt_sm.c @@ -522,11 +522,12 @@ static enum si_sm_result bt_event(struct si_sm_data *bt, long time) if (status & BT_H_BUSY) /* clear a leftover H_BUSY */ BT_CONTROL(BT_H_BUSY); + bt->timeout = bt->BT_CAP_req2rsp; + /* Read BT capabilities if it hasn't been done yet */ if (!bt->BT_CAP_outreqs) BT_STATE_CHANGE(BT_STATE_CAPABILITIES_BEGIN, SI_SM_CALL_WITHOUT_DELAY); - bt->timeout = bt->BT_CAP_req2rsp; BT_SI_SM_RETURN(SI_SM_IDLE); case BT_STATE_XACTION_START: diff --git a/drivers/char/ipmi/ipmi_powernv.c b/drivers/char/ipmi/ipmi_powernv.c index 6e658aa114f19..a70518a4fcecb 100644 --- a/drivers/char/ipmi/ipmi_powernv.c +++ b/drivers/char/ipmi/ipmi_powernv.c @@ -251,8 +251,9 @@ static int ipmi_powernv_probe(struct platform_device *pdev) ipmi->irq = opal_event_request(prop); } - if (request_irq(ipmi->irq, ipmi_opal_event, IRQ_TYPE_LEVEL_HIGH, - "opal-ipmi", ipmi)) { + rc = request_irq(ipmi->irq, ipmi_opal_event, IRQ_TYPE_LEVEL_HIGH, + "opal-ipmi", ipmi); + if (rc) { dev_warn(dev, "Unable to request irq\n"); goto err_dispose; } diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c index 83c206f0fc985..d6d166fe49a3c 100644 --- a/drivers/char/ipmi/ipmi_ssif.c +++ b/drivers/char/ipmi/ipmi_ssif.c @@ -757,7 +757,7 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result, ssif_info->ssif_state = SSIF_NORMAL; ipmi_ssif_unlock_cond(ssif_info, flags); pr_warn(PFX "Error getting flags: %d %d, %x\n", - result, len, data[2]); + result, len, (len >= 3) ? data[2] : 0); } else if (data[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 || data[1] != IPMI_GET_MSG_FLAGS_CMD) { /* @@ -779,7 +779,7 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result, if ((result < 0) || (len < 3) || (data[2] != 0)) { /* Error clearing flags */ pr_warn(PFX "Error clearing flags: %d %d, %x\n", - result, len, data[2]); + result, len, (len >= 3) ? data[2] : 0); } else if (data[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 || data[1] != IPMI_CLEAR_MSG_FLAGS_CMD) { pr_warn(PFX "Invalid response clearing flags: %x %x\n", diff --git a/drivers/char/random.c b/drivers/char/random.c index dffd06a3bb761..2916d08ee30e2 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -1503,14 +1503,22 @@ static int write_pool(struct entropy_store *r, const char __user *buffer, size_t count) { size_t bytes; - __u32 buf[16]; + __u32 t, buf[16]; const char __user *p = buffer; while (count > 0) { + int b, i = 0; + bytes = min(count, sizeof(buf)); if (copy_from_user(&buf, p, bytes)) return -EFAULT; + for (b = bytes ; b > 0 ; b -= sizeof(__u32), i++) { + if (!arch_get_random_int(&t)) + break; + buf[i] ^= t; + } + count -= bytes; p += bytes; diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c index a0d9ac6b6cc91..e759100e41a75 100644 --- a/drivers/char/tpm/tpm-chip.c +++ b/drivers/char/tpm/tpm-chip.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "tpm.h" #include "tpm_eventlog.h" @@ -324,8 +325,20 @@ static void tpm1_chip_unregister(struct tpm_chip *chip) */ int tpm_chip_register(struct tpm_chip *chip) { +#ifdef CONFIG_OF + struct device_node *np; +#endif int rc; +#ifdef CONFIG_OF + np = of_find_node_by_name(NULL, "vtpm"); + if (np) { + if (of_property_read_bool(np, "powered-while-suspended")) + chip->flags |= TPM_CHIP_FLAG_ALWAYS_POWERED; + } + of_node_put(np); +#endif + rc = tpm1_chip_register(chip); if (rc) return rc; diff --git a/drivers/char/tpm/tpm-dev.c b/drivers/char/tpm/tpm-dev.c index 912ad30be5852..4719aa781bf2a 100644 --- a/drivers/char/tpm/tpm-dev.c +++ b/drivers/char/tpm/tpm-dev.c @@ -25,7 +25,7 @@ struct file_priv { struct tpm_chip *chip; /* Data passed to and from the tpm via the read/write calls */ - atomic_t data_pending; + size_t data_pending; struct mutex buffer_mutex; struct timer_list user_read_timer; /* user needs to claim result */ @@ -46,7 +46,7 @@ static void timeout_work(struct work_struct *work) struct file_priv *priv = container_of(work, struct file_priv, work); mutex_lock(&priv->buffer_mutex); - atomic_set(&priv->data_pending, 0); + priv->data_pending = 0; memset(priv->data_buffer, 0, sizeof(priv->data_buffer)); mutex_unlock(&priv->buffer_mutex); } @@ -72,7 +72,6 @@ static int tpm_open(struct inode *inode, struct file *file) } priv->chip = chip; - atomic_set(&priv->data_pending, 0); mutex_init(&priv->buffer_mutex); setup_timer(&priv->user_read_timer, user_reader_timeout, (unsigned long)priv); @@ -86,28 +85,24 @@ static ssize_t tpm_read(struct file *file, char __user *buf, size_t size, loff_t *off) { struct file_priv *priv = file->private_data; - ssize_t ret_size; + ssize_t ret_size = 0; int rc; del_singleshot_timer_sync(&priv->user_read_timer); flush_work(&priv->work); - ret_size = atomic_read(&priv->data_pending); - if (ret_size > 0) { /* relay data */ - ssize_t orig_ret_size = ret_size; - if (size < ret_size) - ret_size = size; + mutex_lock(&priv->buffer_mutex); - mutex_lock(&priv->buffer_mutex); + if (priv->data_pending) { + ret_size = min_t(ssize_t, size, priv->data_pending); rc = copy_to_user(buf, priv->data_buffer, ret_size); - memset(priv->data_buffer, 0, orig_ret_size); + memset(priv->data_buffer, 0, priv->data_pending); if (rc) ret_size = -EFAULT; - mutex_unlock(&priv->buffer_mutex); + priv->data_pending = 0; } - atomic_set(&priv->data_pending, 0); - + mutex_unlock(&priv->buffer_mutex); return ret_size; } @@ -118,18 +113,20 @@ static ssize_t tpm_write(struct file *file, const char __user *buf, size_t in_size = size; ssize_t out_size; - /* cannot perform a write until the read has cleared - either via tpm_read or a user_read_timer timeout. - This also prevents splitted buffered writes from blocking here. - */ - if (atomic_read(&priv->data_pending) != 0) - return -EBUSY; - if (in_size > TPM_BUFSIZE) return -E2BIG; mutex_lock(&priv->buffer_mutex); + /* Cannot perform a write until the read has cleared either via + * tpm_read or a user_read_timer timeout. This also prevents split + * buffered writes from blocking here. + */ + if (priv->data_pending != 0) { + mutex_unlock(&priv->buffer_mutex); + return -EBUSY; + } + if (copy_from_user (priv->data_buffer, (void __user *) buf, in_size)) { mutex_unlock(&priv->buffer_mutex); @@ -153,7 +150,7 @@ static ssize_t tpm_write(struct file *file, const char __user *buf, return out_size; } - atomic_set(&priv->data_pending, out_size); + priv->data_pending = out_size; mutex_unlock(&priv->buffer_mutex); /* Set a timeout by which the reader must come claim the result */ @@ -172,7 +169,7 @@ static int tpm_release(struct inode *inode, struct file *file) del_singleshot_timer_sync(&priv->user_read_timer); flush_work(&priv->work); file->private_data = NULL; - atomic_set(&priv->data_pending, 0); + priv->data_pending = 0; clear_bit(0, &priv->chip->is_open); kfree(priv); return 0; diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index 36afc1a21699c..95a40ec854ad3 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c @@ -787,6 +787,10 @@ int tpm_do_selftest(struct tpm_chip *chip) loops = jiffies_to_msecs(duration) / delay_msec; rc = tpm_continue_selftest(chip); + if (rc == TPM_ERR_INVALID_POSTINIT) { + chip->flags |= TPM_CHIP_FLAG_ALWAYS_POWERED; + dev_info(&chip->dev, "TPM not ready (%d)\n", rc); + } /* This may fail if there was no TPM driver during a suspend/resume * cycle; some may return 10 (BAD_ORDINAL), others 28 (FAILEDSELFTEST) */ @@ -931,6 +935,9 @@ int tpm_pm_suspend(struct device *dev) if (chip == NULL) return -ENODEV; + if (chip->flags & TPM_CHIP_FLAG_ALWAYS_POWERED) + return 0; + if (chip->flags & TPM_CHIP_FLAG_TPM2) { tpm2_shutdown(chip, TPM2_SU_STATE); return 0; diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 772d99b3a8e4b..36e1abda00f92 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -168,6 +168,7 @@ struct tpm_vendor_specific { enum tpm_chip_flags { TPM_CHIP_FLAG_REGISTERED = BIT(0), TPM_CHIP_FLAG_TPM2 = BIT(1), + TPM_CHIP_FLAG_ALWAYS_POWERED = BIT(5), }; struct tpm_chip { diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index af9e9aff49e55..e126e9b146b4d 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -1,5 +1,5 @@ # common clock types -obj-$(CONFIG_HAVE_CLK) += clk-devres.o +obj-$(CONFIG_HAVE_CLK) += clk-devres.o clk-bulk.o obj-$(CONFIG_CLKDEV_LOOKUP) += clkdev.o obj-$(CONFIG_COMMON_CLK) += clk.o obj-$(CONFIG_COMMON_CLK) += clk-divider.o diff --git a/drivers/clk/clk-bulk.c b/drivers/clk/clk-bulk.c new file mode 100644 index 0000000000000..6904ed6da504b --- /dev/null +++ b/drivers/clk/clk-bulk.c @@ -0,0 +1,159 @@ +/* + * Copyright 2017 NXP + * + * Dong Aisheng + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +void clk_bulk_put(int num_clks, struct clk_bulk_data *clks) +{ + while (--num_clks >= 0) { + clk_put(clks[num_clks].clk); + clks[num_clks].clk = NULL; + } +} +EXPORT_SYMBOL_GPL(clk_bulk_put); + +int __must_check clk_bulk_get(struct device *dev, int num_clks, + struct clk_bulk_data *clks) +{ + int ret; + int i; + + for (i = 0; i < num_clks; i++) + clks[i].clk = NULL; + + for (i = 0; i < num_clks; i++) { + clks[i].clk = clk_get(dev, clks[i].id); + if (IS_ERR(clks[i].clk)) { + ret = PTR_ERR(clks[i].clk); + if (ret != -EPROBE_DEFER) + dev_err(dev, "Failed to get clk '%s': %d\n", + clks[i].id, ret); + clks[i].clk = NULL; + goto err; + } + } + + return 0; + +err: + clk_bulk_put(i, clks); + + return ret; +} +EXPORT_SYMBOL(clk_bulk_get); + +#ifdef CONFIG_HAVE_CLK_PREPARE + +/** + * clk_bulk_unprepare - undo preparation of a set of clock sources + * @num_clks: the number of clk_bulk_data + * @clks: the clk_bulk_data table being unprepared + * + * clk_bulk_unprepare may sleep, which differentiates it from clk_bulk_disable. + * Returns 0 on success, -EERROR otherwise. + */ +void clk_bulk_unprepare(int num_clks, const struct clk_bulk_data *clks) +{ + while (--num_clks >= 0) + clk_unprepare(clks[num_clks].clk); +} +EXPORT_SYMBOL_GPL(clk_bulk_unprepare); + +/** + * clk_bulk_prepare - prepare a set of clocks + * @num_clks: the number of clk_bulk_data + * @clks: the clk_bulk_data table being prepared + * + * clk_bulk_prepare may sleep, which differentiates it from clk_bulk_enable. + * Returns 0 on success, -EERROR otherwise. + */ +int __must_check clk_bulk_prepare(int num_clks, + const struct clk_bulk_data *clks) +{ + int ret; + int i; + + for (i = 0; i < num_clks; i++) { + ret = clk_prepare(clks[i].clk); + if (ret) { + pr_err("Failed to prepare clk '%s': %d\n", + clks[i].id, ret); + goto err; + } + } + + return 0; + +err: + clk_bulk_unprepare(i, clks); + + return ret; +} +EXPORT_SYMBOL_GPL(clk_bulk_prepare); + +#endif /* CONFIG_HAVE_CLK_PREPARE */ + +/** + * clk_bulk_disable - gate a set of clocks + * @num_clks: the number of clk_bulk_data + * @clks: the clk_bulk_data table being gated + * + * clk_bulk_disable must not sleep, which differentiates it from + * clk_bulk_unprepare. clk_bulk_disable must be called before + * clk_bulk_unprepare. + */ +void clk_bulk_disable(int num_clks, const struct clk_bulk_data *clks) +{ + + while (--num_clks >= 0) + clk_disable(clks[num_clks].clk); +} +EXPORT_SYMBOL_GPL(clk_bulk_disable); + +/** + * clk_bulk_enable - ungate a set of clocks + * @num_clks: the number of clk_bulk_data + * @clks: the clk_bulk_data table being ungated + * + * clk_bulk_enable must not sleep + * Returns 0 on success, -EERROR otherwise. + */ +int __must_check clk_bulk_enable(int num_clks, const struct clk_bulk_data *clks) +{ + int ret; + int i; + + for (i = 0; i < num_clks; i++) { + ret = clk_enable(clks[i].clk); + if (ret) { + pr_err("Failed to enable clk '%s': %d\n", + clks[i].id, ret); + goto err; + } + } + + return 0; + +err: + clk_bulk_disable(i, clks); + + return ret; +} +EXPORT_SYMBOL_GPL(clk_bulk_enable); diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c index 8f571548870f4..d854e26a8ddbc 100644 --- a/drivers/clk/clk-devres.c +++ b/drivers/clk/clk-devres.c @@ -34,6 +34,42 @@ struct clk *devm_clk_get(struct device *dev, const char *id) } EXPORT_SYMBOL(devm_clk_get); +struct clk_bulk_devres { + struct clk_bulk_data *clks; + int num_clks; +}; + +static void devm_clk_bulk_release(struct device *dev, void *res) +{ + struct clk_bulk_devres *devres = res; + + clk_bulk_put(devres->num_clks, devres->clks); +} + +int __must_check devm_clk_bulk_get(struct device *dev, int num_clks, + struct clk_bulk_data *clks) +{ + struct clk_bulk_devres *devres; + int ret; + + devres = devres_alloc(devm_clk_bulk_release, + sizeof(*devres), GFP_KERNEL); + if (!devres) + return -ENOMEM; + + ret = clk_bulk_get(dev, num_clks, clks); + if (!ret) { + devres->clks = clks; + devres->num_clks = num_clks; + devres_add(dev, devres); + } else { + devres_free(devres); + } + + return ret; +} +EXPORT_SYMBOL_GPL(devm_clk_bulk_get); + static int devm_clk_match(struct device *dev, void *res, void *data) { struct clk **c = res; @@ -53,3 +89,24 @@ void devm_clk_put(struct device *dev, struct clk *clk) WARN_ON(ret); } EXPORT_SYMBOL(devm_clk_put); + +struct clk *devm_get_clk_from_child(struct device *dev, + struct device_node *np, const char *con_id) +{ + struct clk **ptr, *clk; + + ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return ERR_PTR(-ENOMEM); + + clk = of_clk_get_by_name(np, con_id); + if (!IS_ERR(clk)) { + *ptr = clk; + devres_add(dev, ptr); + } else { + devres_free(ptr); + } + + return clk; +} +EXPORT_SYMBOL(devm_get_clk_from_child); diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index c836505e9d8eb..221d521bb00d6 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1945,7 +1945,7 @@ static int clk_core_get_phase(struct clk_core *core) int ret; clk_prepare_lock(); - /* Always try to update cached phase if possible since */ + /* Always try to update cached phase if possible */ if (core->ops->get_phase) core->phase = core->ops->get_phase(core->hw); ret = core->phase; @@ -2170,28 +2170,26 @@ static int clock_debug_rate_get(void *data, u64 *val) DEFINE_SIMPLE_ATTRIBUTE(clock_rate_fops, clock_debug_rate_get, clock_debug_rate_set, "%llu\n"); -static int clock_available_parent_show(struct seq_file *s, void *data) +static int possible_parents_show(struct seq_file *s, void *data) { - struct clk_core *core = (struct clk_core *)s->private; + struct clk_core *core = s->private; int i; - for (i = 0; i < core->num_parents; i++) { - if (!core->parents[i]) - continue; - seq_printf(s, "%s ", core->parents[i]->name); - } - seq_puts(s, "\n"); + for (i = 0; i < core->num_parents - 1; i++) + seq_printf(s, "%s ", core->parent_names[i]); + + seq_printf(s, "%s\n", core->parent_names[i]); return 0; } -static int clock_available_parent_open(struct inode *inode, struct file *file) +static int possible_parents_open(struct inode *inode, struct file *file) { - return single_open(file, clock_available_parent_show, inode->i_private); + return single_open(file, possible_parents_show, inode->i_private); } -static const struct file_operations clock_available_parent_fops = { - .open = clock_available_parent_open, +static const struct file_operations possible_parents_fops = { + .open = possible_parents_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, @@ -2224,6 +2222,9 @@ static ssize_t clock_parent_write(struct file *filp, const char __user *buf, if (ret != 1) return -EINVAL; + if (core->num_parents <= 1) + return cnt; + for (i = 0; i < core->num_parents; i++) { if (!core->parents[i]) continue; @@ -2400,10 +2401,13 @@ static int clk_debug_create_one(struct clk_core *core, struct dentry *pdentry) if (!d) goto err_out; - d = debugfs_create_file("clk_available_parent", S_IRUGO, core->dentry, - core, &clock_available_parent_fops); - if (!d) - goto err_out; + if (core->num_parents > 1) { + d = debugfs_create_file("clk_possible_parents", S_IRUGO, + core->dentry, core, + &possible_parents_fops); + if (!d) + goto err_out; + } d = debugfs_create_file("clk_parent", S_IRUGO | S_IWUSR, core->dentry, core, &clock_parent_fops); diff --git a/drivers/clk/rockchip/clk-cpu.c b/drivers/clk/rockchip/clk-cpu.c index 7b623ddb30867..8166cfd45e099 100644 --- a/drivers/clk/rockchip/clk-cpu.c +++ b/drivers/clk/rockchip/clk-cpu.c @@ -166,6 +166,7 @@ static int rockchip_cpuclk_pre_rate_change(struct rockchip_cpuclk *cpuclk, reg_data->div_core_shift), cpuclk->reg_base + reg_data->core_reg); } + rockchip_boost_add_core_div(cpuclk->pll_hw, alt_prate); /* select alternate parent */ writel(HIWORD_UPDATE(reg_data->mux_core_alt, @@ -286,6 +287,7 @@ struct clk *rockchip_clk_register_cpuclk(const char *name, goto free_cpuclk; } cpuclk->pll_hw = __clk_get_hw(pll_clk); + rockchip_boost_init(cpuclk->pll_hw); } cpuclk->alt_parent = __clk_lookup(parent_names[reg_data->mux_core_alt]); diff --git a/drivers/clk/rockchip/clk-ddr.c b/drivers/clk/rockchip/clk-ddr.c index 90d40388bb9b5..4e0e3e505d044 100644 --- a/drivers/clk/rockchip/clk-ddr.c +++ b/drivers/clk/rockchip/clk-ddr.c @@ -366,11 +366,8 @@ rockchip_clk_register_ddrclk(const char *name, int flags, ddrclk->ddr_flag = ddr_flag; clk = clk_register(NULL, &ddrclk->hw); - if (IS_ERR(clk)) { - pr_err("%s: could not register ddrclk %s\n", __func__, name); + if (IS_ERR(clk)) kfree(ddrclk); - return NULL; - } return clk; } diff --git a/drivers/clk/rockchip/clk-mmc-phase.c b/drivers/clk/rockchip/clk-mmc-phase.c index 7336446e6d534..6d60cc497493a 100644 --- a/drivers/clk/rockchip/clk-mmc-phase.c +++ b/drivers/clk/rockchip/clk-mmc-phase.c @@ -101,10 +101,8 @@ static int rockchip_mmc_set_phase(struct clk_hw *hw, int degrees) * (2) It is assigned to the wrong parent. * * This check help debug the case (1), which seems to be the - * most likely problem we often made and explicitly makes people - * harder to debug the unstable mmc tuning stuff. So hope people - * to have a close look at this comment to help check out what was - * happening. + * most likely problem we often face and which makes it difficult + * for people to debug unstable mmc tuning results. */ if (!rate) { pr_err("%s: invalid clk rate\n", __func__); diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c index addcdb07553a3..0a9f31f2dd279 100644 --- a/drivers/clk/rockchip/clk-pll.c +++ b/drivers/clk/rockchip/clk-pll.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "clk.h" #define PLL_MODE_MASK 0x3 @@ -52,9 +53,15 @@ struct rockchip_clk_pll { int sel; unsigned long scaling; spinlock_t *lock; - bool boost_enabled; struct rockchip_clk_provider *ctx; + + bool boost_enabled; + u32 boost_backup_pll_usage; + unsigned long boost_backup_pll_rate; + unsigned long boost_low_rate; + unsigned long boost_high_rate; + struct regmap *boost; #ifdef CONFIG_DEBUG_FS struct hlist_node debug_node; #endif @@ -69,6 +76,7 @@ static void rockchip_rk3366_pll_get_params(struct rockchip_clk_pll *pll, struct rockchip_pll_rate_table *rate); static int rockchip_rk3366_pll_set_params(struct rockchip_clk_pll *pll, const struct rockchip_pll_rate_table *rate); +static void rockchip_boost_disable_low(struct rockchip_clk_pll *pll); #define MHZ (1000UL * 1000UL) #define KHZ (1000UL) @@ -387,65 +395,6 @@ static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll) return -ETIMEDOUT; } -void rockchip_boost_enable_recovery_sw_low(struct clk_hw *hw) -{ - struct rockchip_clk_pll *pll; - struct regmap *boost; - unsigned int val; - - if (!hw) - return; - pll = to_rockchip_clk_pll(hw); - if (!pll->boost_enabled || IS_ERR(pll->ctx->boost)) - return; - - boost = pll->ctx->boost; - regmap_write(boost, BOOST_BOOST_CON, - HIWORD_UPDATE(1, BOOST_RECOVERY_MASK, - BOOST_RECOVERY_SHIFT)); - do { - regmap_read(boost, BOOST_FSM_STATUS, &val); - } while (!(val & BOOST_BUSY_STATE)); - - regmap_write(boost, BOOST_BOOST_CON, - HIWORD_UPDATE(1, BOOST_SW_CTRL_MASK, - BOOST_SW_CTRL_SHIFT) | - HIWORD_UPDATE(1, BOOST_LOW_FREQ_EN_MASK, - BOOST_LOW_FREQ_EN_SHIFT)); -} - -void rockchip_boost_disable_low(struct rockchip_clk_pll *pll) -{ - struct regmap *boost = pll->ctx->boost; - - if (!pll->boost_enabled || IS_ERR(boost)) - return; - - regmap_write(boost, BOOST_BOOST_CON, - HIWORD_UPDATE(0, BOOST_LOW_FREQ_EN_MASK, - BOOST_LOW_FREQ_EN_SHIFT)); -} - -void rockchip_boost_disable_recovery_sw(struct clk_hw *hw) -{ - struct rockchip_clk_pll *pll; - struct regmap *boost; - - if (!hw) - return; - pll = to_rockchip_clk_pll(hw); - if (!pll->boost_enabled || IS_ERR(pll->ctx->boost)) - return; - - boost = pll->ctx->boost; - regmap_write(boost, BOOST_BOOST_CON, - HIWORD_UPDATE(0, BOOST_RECOVERY_MASK, - BOOST_RECOVERY_SHIFT)); - regmap_write(boost, BOOST_BOOST_CON, - HIWORD_UPDATE(0, BOOST_SW_CTRL_MASK, - BOOST_SW_CTRL_SHIFT)); -} - /** * PLL used in RK3036 */ @@ -466,6 +415,30 @@ void rockchip_boost_disable_recovery_sw(struct clk_hw *hw) #define RK3036_PLLCON1_PWRDOWN (1 << 13) +static unsigned long +rockchip_rk3036_pll_con_to_rate(struct rockchip_clk_pll *pll, + u32 con0, u32 con1) +{ + unsigned int fbdiv, postdiv1, refdiv, postdiv2; + u64 rate64 = 24000000; + + fbdiv = ((con0 >> RK3036_PLLCON0_FBDIV_SHIFT) & + RK3036_PLLCON0_FBDIV_MASK); + postdiv1 = ((con0 >> RK3036_PLLCON0_POSTDIV1_SHIFT) & + RK3036_PLLCON0_POSTDIV1_MASK); + refdiv = ((con1 >> RK3036_PLLCON1_REFDIV_SHIFT) & + RK3036_PLLCON1_REFDIV_MASK); + postdiv2 = ((con1 >> RK3036_PLLCON1_POSTDIV2_SHIFT) & + RK3036_PLLCON1_POSTDIV2_MASK); + + rate64 *= fbdiv; + do_div(rate64, refdiv); + do_div(rate64, postdiv1); + do_div(rate64, postdiv2); + + return (unsigned long)rate64; +} + static void rockchip_rk3036_pll_get_params(struct rockchip_clk_pll *pll, struct rockchip_pll_rate_table *rate) { @@ -1398,8 +1371,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, u8 num_parents, int con_offset, int grf_lock_offset, int lock_shift, int mode_offset, int mode_shift, struct rockchip_pll_rate_table *rate_table, - unsigned long flags, u8 clk_pll_flags, - bool boost_enabled) + unsigned long flags, u8 clk_pll_flags) { const char *pll_parents[3]; struct clk_init_data init; @@ -1524,7 +1496,6 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, pll->flags = clk_pll_flags; pll->lock = &ctx->lock; pll->ctx = ctx; - pll->boost_enabled = boost_enabled; pll_clk = clk_register(NULL, &pll->hw); if (IS_ERR(pll_clk)) { @@ -1533,14 +1504,6 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, goto err_pll; } -#ifdef CONFIG_DEBUG_FS - if (boost_enabled && !IS_ERR(ctx->boost)) { - mutex_lock(&clk_boost_lock); - hlist_add_head(&pll->debug_node, &clk_boost_list); - mutex_unlock(&clk_boost_lock); - } -#endif - return mux_clk; err_pll: @@ -1551,36 +1514,227 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, return mux_clk; } +static unsigned long rockchip_pll_con_to_rate(struct rockchip_clk_pll *pll, + u32 con0, u32 con1) +{ + switch (pll->type) { + case pll_rk3036: + case pll_rk3328: + return rockchip_rk3036_pll_con_to_rate(pll, con0, con1); + case pll_rk3066: + break; + case pll_rk3366: + break; + case pll_rk3399: + break; + default: + pr_warn("%s: Unknown pll type\n", __func__); + } + + return 0; +} + +void rockchip_boost_init(struct clk_hw *hw) +{ + struct rockchip_clk_pll *pll; + struct device_node *np; + u32 value, con0, con1; + + if (!hw) + return; + pll = to_rockchip_clk_pll(hw); + np = of_parse_phandle(pll->ctx->cru_node, "rockchip,boost", 0); + if (!np) { + pr_debug("%s: failed to get boost np\n", __func__); + return; + } + pll->boost = syscon_node_to_regmap(np); + if (IS_ERR(pll->boost)) { + pr_debug("%s: failed to get boost regmap\n", __func__); + return; + } + + if (!of_property_read_u32(np, "rockchip,boost-low-con0", &con0) && + !of_property_read_u32(np, "rockchip,boost-low-con1", &con1)) { + pr_debug("boost-low-con=0x%x 0x%x\n", con0, con1); + regmap_write(pll->boost, BOOST_PLL_L_CON(0), + HIWORD_UPDATE(con0, BOOST_PLL_CON_MASK, 0)); + regmap_write(pll->boost, BOOST_PLL_L_CON(1), + HIWORD_UPDATE(con1, BOOST_PLL_CON_MASK, 0)); + pll->boost_low_rate = rockchip_pll_con_to_rate(pll, con0, + con1); + pr_debug("boost-low-rate=%lu\n", pll->boost_low_rate); + } + if (!of_property_read_u32(np, "rockchip,boost-high-con0", &con0) && + !of_property_read_u32(np, "rockchip,boost-high-con1", &con1)) { + pr_debug("boost-high-con=0x%x 0x%x\n", con0, con1); + regmap_write(pll->boost, BOOST_PLL_H_CON(0), + HIWORD_UPDATE(con0, BOOST_PLL_CON_MASK, 0)); + regmap_write(pll->boost, BOOST_PLL_H_CON(1), + HIWORD_UPDATE(con1, BOOST_PLL_CON_MASK, 0)); + pll->boost_high_rate = rockchip_pll_con_to_rate(pll, con0, + con1); + pr_debug("boost-high-rate=%lu\n", pll->boost_high_rate); + } + if (!of_property_read_u32(np, "rockchip,boost-backup-pll", &value)) { + pr_debug("boost-backup-pll=0x%x\n", value); + regmap_write(pll->boost, BOOST_CLK_CON, + HIWORD_UPDATE(value, BOOST_BACKUP_PLL_MASK, + BOOST_BACKUP_PLL_SHIFT)); + } + if (!of_property_read_u32(np, "rockchip,boost-backup-pll-usage", + &pll->boost_backup_pll_usage)) { + pr_debug("boost-backup-pll-usage=0x%x\n", + pll->boost_backup_pll_usage); + regmap_write(pll->boost, BOOST_CLK_CON, + HIWORD_UPDATE(pll->boost_backup_pll_usage, + BOOST_BACKUP_PLL_USAGE_MASK, + BOOST_BACKUP_PLL_USAGE_SHIFT)); + } + if (!of_property_read_u32(np, "rockchip,boost-switch-threshold", + &value)) { + pr_debug("boost-switch-threshold=0x%x\n", value); + regmap_write(pll->boost, BOOST_SWITCH_THRESHOLD, value); + } + if (!of_property_read_u32(np, "rockchip,boost-statis-threshold", + &value)) { + pr_debug("boost-statis-threshold=0x%x\n", value); + regmap_write(pll->boost, BOOST_STATIS_THRESHOLD, value); + } + if (!of_property_read_u32(np, "rockchip,boost-statis-enable", + &value)) { + pr_debug("boost-statis-enable=0x%x\n", value); + regmap_write(pll->boost, BOOST_BOOST_CON, + HIWORD_UPDATE(value, BOOST_STATIS_ENABLE_MASK, + BOOST_STATIS_ENABLE_SHIFT)); + } + if (!of_property_read_u32(np, "rockchip,boost-enable", &value)) { + pr_debug("boost-enable=0x%x\n", value); + regmap_write(pll->boost, BOOST_BOOST_CON, + HIWORD_UPDATE(value, BOOST_ENABLE_MASK, + BOOST_ENABLE_SHIFT)); + if (value) + pll->boost_enabled = true; + } +#ifdef CONFIG_DEBUG_FS + if (pll->boost_enabled) { + mutex_lock(&clk_boost_lock); + hlist_add_head(&pll->debug_node, &clk_boost_list); + mutex_unlock(&clk_boost_lock); + } +#endif +} + +void rockchip_boost_enable_recovery_sw_low(struct clk_hw *hw) +{ + struct rockchip_clk_pll *pll; + unsigned int val; + + if (!hw) + return; + pll = to_rockchip_clk_pll(hw); + if (!pll->boost_enabled) + return; + + regmap_write(pll->boost, BOOST_BOOST_CON, + HIWORD_UPDATE(1, BOOST_RECOVERY_MASK, + BOOST_RECOVERY_SHIFT)); + do { + regmap_read(pll->boost, BOOST_FSM_STATUS, &val); + } while (!(val & BOOST_BUSY_STATE)); + + regmap_write(pll->boost, BOOST_BOOST_CON, + HIWORD_UPDATE(1, BOOST_SW_CTRL_MASK, + BOOST_SW_CTRL_SHIFT) | + HIWORD_UPDATE(1, BOOST_LOW_FREQ_EN_MASK, + BOOST_LOW_FREQ_EN_SHIFT)); +} + +static void rockchip_boost_disable_low(struct rockchip_clk_pll *pll) +{ + if (!pll->boost_enabled) + return; + + regmap_write(pll->boost, BOOST_BOOST_CON, + HIWORD_UPDATE(0, BOOST_LOW_FREQ_EN_MASK, + BOOST_LOW_FREQ_EN_SHIFT)); +} + +void rockchip_boost_disable_recovery_sw(struct clk_hw *hw) +{ + struct rockchip_clk_pll *pll; + + if (!hw) + return; + pll = to_rockchip_clk_pll(hw); + if (!pll->boost_enabled) + return; + + regmap_write(pll->boost, BOOST_BOOST_CON, + HIWORD_UPDATE(0, BOOST_RECOVERY_MASK, + BOOST_RECOVERY_SHIFT)); + regmap_write(pll->boost, BOOST_BOOST_CON, + HIWORD_UPDATE(0, BOOST_SW_CTRL_MASK, + BOOST_SW_CTRL_SHIFT)); +} + +void rockchip_boost_add_core_div(struct clk_hw *hw, unsigned long prate) +{ + struct rockchip_clk_pll *pll; + unsigned int div; + + if (!hw) + return; + pll = to_rockchip_clk_pll(hw); + if (!pll->boost_enabled || pll->boost_backup_pll_rate == prate) + return; + + /* todo */ + if (pll->boost_backup_pll_usage == BOOST_BACKUP_PLL_USAGE_TARGET) + return; + /* + * cpu clock rate should be less than or equal to + * low rate when change pll rate in boost module + */ + if (pll->boost_low_rate && prate > pll->boost_low_rate) { + div = DIV_ROUND_UP(prate, pll->boost_low_rate) - 1; + regmap_write(pll->boost, BOOST_CLK_CON, + HIWORD_UPDATE(div, BOOST_CORE_DIV_MASK, + BOOST_CORE_DIV_SHIFT)); + pll->boost_backup_pll_rate = prate; + } +} + #ifdef CONFIG_DEBUG_FS #include static int boost_summary_show(struct seq_file *s, void *data) { struct rockchip_clk_pll *pll = (struct rockchip_clk_pll *)s->private; - struct regmap *boost = pll->ctx->boost; u32 boost_count = 0; u32 freq_cnt0 = 0, freq_cnt1 = 0; - u64 high_freq_time = 0; + u64 freq_cnt = 0, high_freq_time = 0; u32 short_count = 0, short_threshold = 0; u32 interval_time = 0; - seq_puts(s, " device boost_count high_freq_time(us) short_count short_threshold interval_time\n"); - seq_puts(s, "------------------------------------------------------------------------------------------\n"); + seq_puts(s, " device boost_count high_freq_count high_freq_time short_count short_threshold interval_count\n"); + seq_puts(s, "------------------------------------------------------------------------------------------------------\n"); seq_printf(s, " %s\n", clk_hw_get_name(&pll->hw)); - regmap_read(boost, BOOST_SWITCH_CNT, &boost_count); + regmap_read(pll->boost, BOOST_SWITCH_CNT, &boost_count); - regmap_read(boost, BOOST_HIGH_PERF_CNT0, &freq_cnt0); - regmap_read(boost, BOOST_HIGH_PERF_CNT1, &freq_cnt1); - high_freq_time = ((u64)freq_cnt1 << 32) + (u64)freq_cnt0; + regmap_read(pll->boost, BOOST_HIGH_PERF_CNT0, &freq_cnt0); + regmap_read(pll->boost, BOOST_HIGH_PERF_CNT1, &freq_cnt1); + freq_cnt = ((u64)freq_cnt1 << 32) + (u64)freq_cnt0; + high_freq_time = freq_cnt; do_div(high_freq_time, 24); - regmap_read(boost, BOOST_SHORT_SWITCH_CNT, &short_count); - regmap_read(boost, BOOST_STATIS_THRESHOLD, &short_threshold); - regmap_read(boost, BOOST_SWITCH_THRESHOLD, &interval_time); + regmap_read(pll->boost, BOOST_SHORT_SWITCH_CNT, &short_count); + regmap_read(pll->boost, BOOST_STATIS_THRESHOLD, &short_threshold); + regmap_read(pll->boost, BOOST_SWITCH_THRESHOLD, &interval_time); - seq_printf(s, "%21u %20llu %13u %17u %15u\n", - boost_count, high_freq_time, short_count, + seq_printf(s, "%22u %17llu %15llu %12u %16u %15u\n", + boost_count, freq_cnt, high_freq_time, short_count, short_threshold, interval_time); return 0; @@ -1598,6 +1752,29 @@ static const struct file_operations boost_summary_fops = { .release = single_release, }; +static int boost_config_show(struct seq_file *s, void *data) +{ + struct rockchip_clk_pll *pll = (struct rockchip_clk_pll *)s->private; + + seq_printf(s, "boost_enabled: %d\n", pll->boost_enabled); + seq_printf(s, "boost_low_rate: %lu\n", pll->boost_low_rate); + seq_printf(s, "boost_high_rate: %lu\n", pll->boost_high_rate); + + return 0; +} + +static int boost_config_open(struct inode *inode, struct file *file) +{ + return single_open(file, boost_config_show, inode->i_private); +} + +static const struct file_operations boost_config_fops = { + .open = boost_config_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + static int boost_debug_create_one(struct rockchip_clk_pll *pll, struct dentry *rootdir) { @@ -1617,6 +1794,13 @@ static int boost_debug_create_one(struct rockchip_clk_pll *pll, return -ENOMEM; } + d = debugfs_create_file("boost_config", 0444, pdentry, + pll, &boost_config_fops); + if (!d) { + pr_err("%s: failed to create boost config file\n", __func__); + return -ENOMEM; + } + return 0; } diff --git a/drivers/clk/rockchip/clk-px30.c b/drivers/clk/rockchip/clk-px30.c index 30a819e7b839b..52a75e12f433d 100644 --- a/drivers/clk/rockchip/clk-px30.c +++ b/drivers/clk/rockchip/clk-px30.c @@ -21,8 +21,7 @@ #include "clk.h" #define PX30_GRF_SOC_STATUS0 0x480 -#define PX30_I2S_FRAC_MAX_PRATE 600000000 -#define PX30_PDM_FRAC_MAX_PRATE 600000000 +#define PX30_FRAC_MAX_PRATE 600000000 enum px30_plls { apll, dpll, cpll, npll, apll_b_h, apll_b_l, @@ -149,15 +148,16 @@ PNAME(mux_usb480m_p) = { "xin24m", "usb480m_phy", "clk_rtc32k_pmu" }; PNAME(mux_armclk_p) = { "apll_core", "gpll_core" }; PNAME(mux_ddrphy_p) = { "dpll_ddr", "gpll_ddr" }; PNAME(mux_ddrstdby_p) = { "clk_ddrphy1x", "clk_stdby_2wrap" }; -PNAME(mux_4plls_p) = { "gpll", "dummy_cpll", "usb480m", "npll" }; +PNAME(mux_gpll_dmycpll_usb480m_npll_p) = { "gpll", "dummy_cpll", "usb480m", "npll" }; +PNAME(mux_gpll_dmycpll_usb480m_dmynpll_p) = { "gpll", "dummy_cpll", "usb480m", "dummy_npll" }; PNAME(mux_cpll_npll_p) = { "cpll", "npll" }; PNAME(mux_npll_cpll_p) = { "npll", "cpll" }; PNAME(mux_gpll_cpll_p) = { "gpll", "dummy_cpll" }; -PNAME(mux_gpll_npll_p) = { "gpll", "npll" }; +PNAME(mux_gpll_npll_p) = { "gpll", "dummy_npll" }; PNAME(mux_gpll_xin24m_p) = { "gpll", "xin24m"}; -PNAME(mux_gpll_cpll_npll_p) = { "gpll", "dummy_cpll", "npll" }; -PNAME(mux_gpll_cpll_npll_xin24m_p) = { "gpll", "dummy_cpll", "npll", "xin24m" }; -PNAME(mux_gpll_xin24m_npll_p) = { "gpll", "xin24m", "npll"}; +PNAME(mux_gpll_cpll_npll_p) = { "gpll", "dummy_cpll", "dummy_npll" }; +PNAME(mux_gpll_cpll_npll_xin24m_p) = { "gpll", "dummy_cpll", "dummy_npll", "xin24m" }; +PNAME(mux_gpll_xin24m_npll_p) = { "gpll", "xin24m", "dummy_npll"}; PNAME(mux_pdm_p) = { "clk_pdm_src", "clk_pdm_frac" }; PNAME(mux_i2s0_tx_p) = { "clk_i2s0_tx_src", "clk_i2s0_tx_frac", "mclk_i2s0_tx_in", "xin12m"}; PNAME(mux_i2s0_rx_p) = { "clk_i2s0_rx_src", "clk_i2s0_rx_frac", "mclk_i2s0_rx_in", "xin12m"}; @@ -169,25 +169,29 @@ PNAME(mux_i2s1_out_p) = { "clk_i2s1", "xin12m"}; PNAME(mux_i2s2_out_p) = { "clk_i2s2", "xin12m"}; PNAME(mux_i2s0_tx_rx_p) = { "clk_i2s0_tx_mux", "clk_i2s0_rx_mux"}; PNAME(mux_i2s0_rx_tx_p) = { "clk_i2s0_rx_mux", "clk_i2s0_tx_mux"}; -PNAME(mux_uart_src_p) = { "gpll", "xin24m", "usb480m", "npll" }; -PNAME(mux_uart1_p) = { "clk_uart1_src", "dummy", "clk_uart1_frac" }; -PNAME(mux_uart2_p) = { "clk_uart2_src", "dummy", "clk_uart2_frac" }; -PNAME(mux_uart3_p) = { "clk_uart3_src", "dummy", "clk_uart3_frac" }; -PNAME(mux_uart4_p) = { "clk_uart4_src", "dummy", "clk_uart4_frac" }; -PNAME(mux_uart5_p) = { "clk_uart5_src", "dummy", "clk_uart5_frac" }; -PNAME(mux_cif_out_p) = { "xin24m", "dummy_cpll", "npll", "usb480m" }; +PNAME(mux_uart_src_p) = { "gpll", "xin24m", "usb480m", "dummy_npll" }; +PNAME(mux_uart1_p) = { "clk_uart1_src", "clk_uart1_np5", "clk_uart1_frac" }; +PNAME(mux_uart2_p) = { "clk_uart2_src", "clk_uart2_np5", "clk_uart2_frac" }; +PNAME(mux_uart3_p) = { "clk_uart3_src", "clk_uart3_np5", "clk_uart3_frac" }; +PNAME(mux_uart4_p) = { "clk_uart4_src", "clk_uart4_np5", "clk_uart4_frac" }; +PNAME(mux_uart5_p) = { "clk_uart5_src", "clk_uart5_np5", "clk_uart5_frac" }; +PNAME(mux_cif_out_p) = { "xin24m", "dummy_cpll", "dummy_npll", "usb480m" }; PNAME(mux_dclk_vopb_p) = { "dclk_vopb_src", "dclk_vopb_frac", "xin24m" }; PNAME(mux_dclk_vopl_p) = { "dclk_vopl_src", "dclk_vopl_frac", "xin24m" }; +PNAME(mux_nandc_p) = { "clk_nandc_div", "clk_nandc_div50" }; +PNAME(mux_sdio_p) = { "clk_sdio_div", "clk_sdio_div50" }; +PNAME(mux_emmc_p) = { "clk_emmc_div", "clk_emmc_div50" }; +PNAME(mux_sdmmc_p) = { "clk_sdmmc_div", "clk_sdmmc_div50" }; PNAME(mux_gmac_p) = { "clk_gmac_src", "gmac_clkin" }; PNAME(mux_gmac_rmii_sel_p) = { "clk_gmac_rx_tx_div20", "clk_gmac_rx_tx_div2" }; PNAME(mux_rtc32k_pmu_p) = { "xin32k", "pmu_pvtm_32k", "clk_rtc32k_frac", }; PNAME(mux_wifi_pmu_p) = { "xin24m", "clk_wifi_pmu_src" }; -PNAME(mux_uart0_pmu_p) = { "clk_uart0_pmu_src", "dummy", "clk_uart0_frac" }; +PNAME(mux_uart0_pmu_p) = { "clk_uart0_pmu_src", "clk_uart0_np5", "clk_uart0_frac" }; PNAME(mux_usbphy_ref_p) = { "xin24m", "clk_ref24m_pmu" }; PNAME(mux_mipidsiphy_ref_p) = { "xin24m", "clk_ref24m_pmu" }; static struct rockchip_pll_clock px30_pll_clks[] __initdata = { - [apll] = PLL_BOOST(pll_rk3328, PLL_APLL, "apll", mux_pll_p, + [apll] = PLL(pll_rk3328, PLL_APLL, "apll", mux_pll_p, 0, PX30_PLL_CON(0), PX30_MODE_CON, 0, 0, 0, px30_pll_rates), [dpll] = PLL(pll_rk3328, PLL_DPLL, "dpll", mux_pll_p, @@ -308,9 +312,6 @@ static struct rockchip_clk_branch px30_clk_branches[] __initdata = { PX30_CLKGATE_CON(17), 4, GFLAGS), /* PD_GPU */ - COMPOSITE(0, "clk_gpu_src", mux_4plls_p, 0, - PX30_CLKSEL_CON(1), 6, 2, MFLAGS, 0, 4, DFLAGS, - PX30_CLKGATE_CON(0), 8, GFLAGS), GATE(SCLK_GPU, "clk_gpu", "clk_gpu_src", 0, PX30_CLKGATE_CON(0), 10, GFLAGS), COMPOSITE_NOMUX(0, "aclk_gpu", "clk_gpu", CLK_IGNORE_UNUSED, @@ -428,7 +429,7 @@ static struct rockchip_clk_branch px30_clk_branches[] __initdata = { &px30_dclk_vopb_fracmux, 0), GATE(DCLK_VOPB, "dclk_vopb", "dclk_vopb_mux", CLK_SET_RATE_PARENT, PX30_CLKGATE_CON(2), 4, GFLAGS), - COMPOSITE(0, "dclk_vopl_src", mux_npll_cpll_p, 0, + COMPOSITE(0, "dclk_vopl_src", mux_npll_cpll_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, PX30_CLKSEL_CON(8), 11, 1, MFLAGS, 0, 8, DFLAGS, PX30_CLKGATE_CON(2), 6, GFLAGS), COMPOSITE_FRACMUX(0, "dclk_vopl_frac", "dclk_vopl_src", CLK_SET_RATE_PARENT, @@ -465,16 +466,40 @@ static struct rockchip_clk_branch px30_clk_branches[] __initdata = { /* PD_MMC_NAND */ GATE(HCLK_MMC_NAND, "hclk_mmc_nand", "hclk_peri_pre", 0, PX30_CLKGATE_CON(6), 0, GFLAGS), - COMPOSITE(SCLK_NANDC, "clk_nandc", mux_gpll_cpll_npll_p, 0, + COMPOSITE(SCLK_NANDC_DIV, "clk_nandc_div", mux_gpll_cpll_npll_p, 0, PX30_CLKSEL_CON(15), 6, 2, MFLAGS, 0, 5, DFLAGS, + PX30_CLKGATE_CON(5), 11, GFLAGS), + COMPOSITE(SCLK_NANDC_DIV50, "clk_nandc_div50", mux_gpll_cpll_npll_p, 0, + PX30_CLKSEL_CON(15), 6, 2, MFLAGS, 8, 5, DFLAGS, + PX30_CLKGATE_CON(5), 12, GFLAGS), + COMPOSITE_NODIV(SCLK_NANDC, "clk_nandc", mux_nandc_p, + CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, + PX30_CLKSEL_CON(15), 15, 1, MFLAGS, PX30_CLKGATE_CON(5), 13, GFLAGS), - COMPOSITE(SCLK_SDIO, "clk_sdio", mux_gpll_cpll_npll_xin24m_p, 0, + COMPOSITE(SCLK_SDIO_DIV, "clk_sdio_div", mux_gpll_cpll_npll_xin24m_p, 0, PX30_CLKSEL_CON(18), 14, 2, MFLAGS, 0, 8, DFLAGS, + PX30_CLKGATE_CON(6), 1, GFLAGS), + COMPOSITE_DIV_OFFSET(SCLK_SDIO_DIV50, "clk_sdio_div50", + mux_gpll_cpll_npll_xin24m_p, 0, + PX30_CLKSEL_CON(18), 14, 2, MFLAGS, + PX30_CLKSEL_CON(19), 0, 8, DFLAGS, + PX30_CLKGATE_CON(6), 2, GFLAGS), + COMPOSITE_NODIV(SCLK_SDIO, "clk_sdio", mux_sdio_p, + CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, + PX30_CLKSEL_CON(19), 15, 1, MFLAGS, PX30_CLKGATE_CON(6), 3, GFLAGS), - COMPOSITE(SCLK_EMMC, "clk_emmc", mux_gpll_cpll_npll_xin24m_p, 0, + COMPOSITE(SCLK_EMMC_DIV, "clk_emmc_div", mux_gpll_cpll_npll_xin24m_p, 0, PX30_CLKSEL_CON(20), 14, 2, MFLAGS, 0, 8, DFLAGS, + PX30_CLKGATE_CON(6), 4, GFLAGS), + COMPOSITE_DIV_OFFSET(SCLK_EMMC_DIV50, "clk_emmc_div50", mux_gpll_cpll_npll_xin24m_p, 0, + PX30_CLKSEL_CON(20), 14, 2, MFLAGS, + PX30_CLKSEL_CON(21), 0, 8, DFLAGS, + PX30_CLKGATE_CON(6), 5, GFLAGS), + COMPOSITE_NODIV(SCLK_EMMC, "clk_emmc", mux_emmc_p, + CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, + PX30_CLKSEL_CON(21), 15, 1, MFLAGS, PX30_CLKGATE_CON(6), 6, GFLAGS), COMPOSITE(SCLK_SFC, "clk_sfc", mux_gpll_cpll_p, 0, @@ -499,8 +524,16 @@ static struct rockchip_clk_branch px30_clk_branches[] __initdata = { /* PD_SDCARD */ GATE(0, "hclk_sdmmc_pre", "hclk_peri_pre", 0, PX30_CLKGATE_CON(6), 12, GFLAGS), - COMPOSITE(SCLK_SDMMC, "clk_sdmmc", mux_gpll_cpll_npll_xin24m_p, 0, + COMPOSITE(SCLK_SDMMC_DIV, "clk_sdmmc_div", mux_gpll_cpll_npll_xin24m_p, 0, PX30_CLKSEL_CON(16), 14, 2, MFLAGS, 0, 8, DFLAGS, + PX30_CLKGATE_CON(6), 13, GFLAGS), + COMPOSITE_DIV_OFFSET(SCLK_SDMMC_DIV50, "clk_sdmmc_div50", mux_gpll_cpll_npll_xin24m_p, 0, + PX30_CLKSEL_CON(16), 14, 2, MFLAGS, + PX30_CLKSEL_CON(17), 0, 8, DFLAGS, + PX30_CLKGATE_CON(6), 14, GFLAGS), + COMPOSITE_NODIV(SCLK_SDMMC, "clk_sdmmc", mux_sdmmc_p, + CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, + PX30_CLKSEL_CON(17), 15, 1, MFLAGS, PX30_CLKGATE_CON(6), 15, GFLAGS), /* PD_USB */ @@ -560,7 +593,7 @@ static struct rockchip_clk_branch px30_clk_branches[] __initdata = { COMPOSITE_FRACMUX(0, "clk_pdm_frac", "clk_pdm_src", CLK_SET_RATE_PARENT, PX30_CLKSEL_CON(27), 0, PX30_CLKGATE_CON(9), 10, GFLAGS, - &px30_pdm_fracmux, PX30_PDM_FRAC_MAX_PRATE), + &px30_pdm_fracmux, PX30_FRAC_MAX_PRATE), GATE(SCLK_PDM, "clk_pdm", "clk_pdm_mux", CLK_SET_RATE_PARENT, PX30_CLKGATE_CON(9), 11, GFLAGS), @@ -570,7 +603,7 @@ static struct rockchip_clk_branch px30_clk_branches[] __initdata = { COMPOSITE_FRACMUX(0, "clk_i2s0_tx_frac", "clk_i2s0_tx_src", CLK_SET_RATE_PARENT, PX30_CLKSEL_CON(29), 0, PX30_CLKGATE_CON(9), 13, GFLAGS, - &px30_i2s0_tx_fracmux, PX30_I2S_FRAC_MAX_PRATE), + &px30_i2s0_tx_fracmux, PX30_FRAC_MAX_PRATE), COMPOSITE_NODIV(SCLK_I2S0_TX, "clk_i2s0_tx", mux_i2s0_tx_rx_p, CLK_SET_RATE_PARENT, PX30_CLKSEL_CON(28), 12, 1, MFLAGS, PX30_CLKGATE_CON(9), 14, GFLAGS), @@ -586,7 +619,7 @@ static struct rockchip_clk_branch px30_clk_branches[] __initdata = { COMPOSITE_FRACMUX(0, "clk_i2s0_rx_frac", "clk_i2s0_rx_src", CLK_SET_RATE_PARENT, PX30_CLKSEL_CON(59), 0, PX30_CLKGATE_CON(17), 1, GFLAGS, - &px30_i2s0_rx_fracmux, PX30_I2S_FRAC_MAX_PRATE), + &px30_i2s0_rx_fracmux, PX30_FRAC_MAX_PRATE), COMPOSITE_NODIV(SCLK_I2S0_RX, "clk_i2s0_rx", mux_i2s0_rx_tx_p, CLK_SET_RATE_PARENT, PX30_CLKSEL_CON(58), 12, 1, MFLAGS, PX30_CLKGATE_CON(17), 2, GFLAGS), @@ -602,7 +635,7 @@ static struct rockchip_clk_branch px30_clk_branches[] __initdata = { COMPOSITE_FRACMUX(0, "clk_i2s1_frac", "clk_i2s1_src", CLK_SET_RATE_PARENT, PX30_CLKSEL_CON(31), 0, PX30_CLKGATE_CON(10), 1, GFLAGS, - &px30_i2s1_fracmux, PX30_I2S_FRAC_MAX_PRATE), + &px30_i2s1_fracmux, PX30_FRAC_MAX_PRATE), GATE(SCLK_I2S1, "clk_i2s1", "clk_i2s1_mux", CLK_SET_RATE_PARENT, PX30_CLKGATE_CON(10), 2, GFLAGS), COMPOSITE_NODIV(0, "clk_i2s1_out_pre", mux_i2s1_out_p, 0, @@ -617,7 +650,7 @@ static struct rockchip_clk_branch px30_clk_branches[] __initdata = { COMPOSITE_FRACMUX(0, "clk_i2s2_frac", "clk_i2s2_src", CLK_SET_RATE_PARENT, PX30_CLKSEL_CON(33), 0, PX30_CLKGATE_CON(10), 5, GFLAGS, - &px30_i2s2_fracmux, PX30_I2S_FRAC_MAX_PRATE), + &px30_i2s2_fracmux, PX30_FRAC_MAX_PRATE), GATE(SCLK_I2S2, "clk_i2s2", "clk_i2s2_mux", CLK_SET_RATE_PARENT, PX30_CLKGATE_CON(10), 6, GFLAGS), COMPOSITE_NODIV(0, "clk_i2s2_out_pre", mux_i2s2_out_p, 0, @@ -629,50 +662,65 @@ static struct rockchip_clk_branch px30_clk_branches[] __initdata = { COMPOSITE(SCLK_UART1_SRC, "clk_uart1_src", mux_uart_src_p, CLK_SET_RATE_NO_REPARENT, PX30_CLKSEL_CON(34), 14, 2, MFLAGS, 0, 5, DFLAGS, PX30_CLKGATE_CON(10), 12, GFLAGS), + COMPOSITE_NOMUX_HALFDIV(0, "clk_uart1_np5", "clk_uart1_src", CLK_SET_RATE_PARENT, + PX30_CLKSEL_CON(35), 0, 5, DFLAGS, + PX30_CLKGATE_CON(10), 13, GFLAGS), COMPOSITE_FRACMUX(0, "clk_uart1_frac", "clk_uart1_src", CLK_SET_RATE_PARENT, PX30_CLKSEL_CON(36), 0, PX30_CLKGATE_CON(10), 14, GFLAGS, - &px30_uart1_fracmux, 0), + &px30_uart1_fracmux, PX30_FRAC_MAX_PRATE), GATE(SCLK_UART1, "clk_uart1", "clk_uart1_mux", CLK_SET_RATE_PARENT, PX30_CLKGATE_CON(10), 15, GFLAGS), COMPOSITE(SCLK_UART2_SRC, "clk_uart2_src", mux_uart_src_p, 0, PX30_CLKSEL_CON(37), 14, 2, MFLAGS, 0, 5, DFLAGS, PX30_CLKGATE_CON(11), 0, GFLAGS), + COMPOSITE_NOMUX_HALFDIV(0, "clk_uart2_np5", "clk_uart2_src", CLK_SET_RATE_PARENT, + PX30_CLKSEL_CON(38), 0, 5, DFLAGS, + PX30_CLKGATE_CON(11), 1, GFLAGS), COMPOSITE_FRACMUX(0, "clk_uart2_frac", "clk_uart2_src", CLK_SET_RATE_PARENT, PX30_CLKSEL_CON(39), 0, PX30_CLKGATE_CON(11), 2, GFLAGS, - &px30_uart2_fracmux, 0), + &px30_uart2_fracmux, PX30_FRAC_MAX_PRATE), GATE(SCLK_UART2, "clk_uart2", "clk_uart2_mux", CLK_SET_RATE_PARENT, PX30_CLKGATE_CON(11), 3, GFLAGS), COMPOSITE(0, "clk_uart3_src", mux_uart_src_p, 0, PX30_CLKSEL_CON(40), 14, 2, MFLAGS, 0, 5, DFLAGS, PX30_CLKGATE_CON(11), 4, GFLAGS), + COMPOSITE_NOMUX_HALFDIV(0, "clk_uart3_np5", "clk_uart3_src", CLK_SET_RATE_PARENT, + PX30_CLKSEL_CON(41), 0, 5, DFLAGS, + PX30_CLKGATE_CON(11), 5, GFLAGS), COMPOSITE_FRACMUX(0, "clk_uart3_frac", "clk_uart3_src", CLK_SET_RATE_PARENT, PX30_CLKSEL_CON(42), 0, PX30_CLKGATE_CON(11), 6, GFLAGS, - &px30_uart3_fracmux, 0), + &px30_uart3_fracmux, PX30_FRAC_MAX_PRATE), GATE(SCLK_UART3, "clk_uart3", "clk_uart3_mux", CLK_SET_RATE_PARENT, PX30_CLKGATE_CON(11), 7, GFLAGS), COMPOSITE(0, "clk_uart4_src", mux_uart_src_p, 0, PX30_CLKSEL_CON(43), 14, 2, MFLAGS, 0, 5, DFLAGS, PX30_CLKGATE_CON(11), 8, GFLAGS), + COMPOSITE_NOMUX_HALFDIV(0, "clk_uart4_np5", "clk_uart4_src", CLK_SET_RATE_PARENT, + PX30_CLKSEL_CON(44), 0, 5, DFLAGS, + PX30_CLKGATE_CON(11), 9, GFLAGS), COMPOSITE_FRACMUX(0, "clk_uart4_frac", "clk_uart4_src", CLK_SET_RATE_PARENT, PX30_CLKSEL_CON(45), 0, PX30_CLKGATE_CON(11), 10, GFLAGS, - &px30_uart4_fracmux, 0), + &px30_uart4_fracmux, PX30_FRAC_MAX_PRATE), GATE(SCLK_UART4, "clk_uart4", "clk_uart4_mux", CLK_SET_RATE_PARENT, PX30_CLKGATE_CON(11), 11, GFLAGS), COMPOSITE(0, "clk_uart5_src", mux_uart_src_p, 0, PX30_CLKSEL_CON(46), 14, 2, MFLAGS, 0, 5, DFLAGS, PX30_CLKGATE_CON(11), 12, GFLAGS), + COMPOSITE_NOMUX_HALFDIV(0, "clk_uart5_np5", "clk_uart5_src", CLK_SET_RATE_PARENT, + PX30_CLKSEL_CON(47), 0, 5, DFLAGS, + PX30_CLKGATE_CON(11), 13, GFLAGS), COMPOSITE_FRACMUX(0, "clk_uart5_frac", "clk_uart5_src", CLK_SET_RATE_PARENT, PX30_CLKSEL_CON(48), 0, PX30_CLKGATE_CON(11), 14, GFLAGS, - &px30_uart5_fracmux, 0), + &px30_uart5_fracmux, PX30_FRAC_MAX_PRATE), GATE(SCLK_UART5, "clk_uart5", "clk_uart5_mux", CLK_SET_RATE_PARENT, PX30_CLKGATE_CON(11), 15, GFLAGS), @@ -861,6 +909,18 @@ static struct rockchip_clk_branch px30_clk_branches[] __initdata = { PX30_CLKGATE_CON(8), 3, GFLAGS), }; +static struct rockchip_clk_branch px30_gpu_src_clk[] __initdata = { + COMPOSITE(0, "clk_gpu_src", mux_gpll_dmycpll_usb480m_dmynpll_p, 0, + PX30_CLKSEL_CON(1), 6, 2, MFLAGS, 0, 4, DFLAGS, + PX30_CLKGATE_CON(0), 8, GFLAGS), +}; + +static struct rockchip_clk_branch rk3326_gpu_src_clk[] __initdata = { + COMPOSITE(0, "clk_gpu_src", mux_gpll_dmycpll_usb480m_npll_p, 0, + PX30_CLKSEL_CON(1), 6, 2, MFLAGS, 0, 4, DFLAGS, + PX30_CLKGATE_CON(0), 8, GFLAGS), +}; + static struct rockchip_clk_branch px30_clk_pmu_branches[] __initdata = { /* * Clock-Architecture Diagram 2 @@ -885,6 +945,9 @@ static struct rockchip_clk_branch px30_clk_pmu_branches[] __initdata = { COMPOSITE(0, "clk_uart0_pmu_src", mux_uart_src_p, 0, PX30_PMU_CLKSEL_CON(3), 14, 2, MFLAGS, 0, 5, DFLAGS, PX30_PMU_CLKGATE_CON(1), 0, GFLAGS), + COMPOSITE_NOMUX_HALFDIV(0, "clk_uart0_np5", "clk_uart0_pmu_src", CLK_SET_RATE_PARENT, + PX30_PMU_CLKSEL_CON(4), 0, 5, DFLAGS, + PX30_PMU_CLKGATE_CON(1), 1, GFLAGS), COMPOSITE_FRACMUX(0, "clk_uart0_frac", "clk_uart0_pmu_src", CLK_SET_RATE_PARENT, PX30_PMU_CLKSEL_CON(5), 0, PX30_PMU_CLKGATE_CON(1), 2, GFLAGS, @@ -1005,6 +1068,12 @@ static void __init px30_clk_init(struct device_node *np) PX30_GRF_SOC_STATUS0); rockchip_clk_register_branches(ctx, px30_clk_branches, ARRAY_SIZE(px30_clk_branches)); + if (of_machine_is_compatible("rockchip,px30")) + rockchip_clk_register_branches(ctx, px30_gpu_src_clk, + ARRAY_SIZE(px30_gpu_src_clk)); + else + rockchip_clk_register_branches(ctx, rk3326_gpu_src_clk, + ARRAY_SIZE(rk3326_gpu_src_clk)); rockchip_clk_register_armclk(ctx, ARMCLK, "armclk", mux_armclk_p, ARRAY_SIZE(mux_armclk_p), diff --git a/drivers/clk/rockchip/clk-rk3036.c b/drivers/clk/rockchip/clk-rk3036.c index 9685228b20a67..39ee1add918da 100644 --- a/drivers/clk/rockchip/clk-rk3036.c +++ b/drivers/clk/rockchip/clk-rk3036.c @@ -185,6 +185,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 */ @@ -195,6 +197,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, @@ -271,6 +274,8 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { COMPOSITE(ACLK_VCODEC, "aclk_vcodec", mux_pll_src_dmyapll_dpll_gpll_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(ACLK_HEVC, "aclk_hevc", mux_pll_src_dmyapll_dpll_gpll_p, 0, RK2928_CLKSEL_CON(20), 0, 2, MFLAGS, 2, 5, DFLAGS, @@ -359,6 +364,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), @@ -387,8 +393,6 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { 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_vcodec_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), @@ -467,34 +471,11 @@ static void __init rk3036_clk_init(struct device_node *np) return; } - /* 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(ctx, 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 271630ed7effb..56a1ba236ddf0 100644 --- a/drivers/clk/rockchip/clk-rk3188.c +++ b/drivers/clk/rockchip/clk-rk3188.c @@ -345,6 +345,8 @@ static struct rockchip_clk_branch common_clk_branches[] __initdata = { INVERTER(PCLK_CIF0, "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. @@ -763,7 +765,6 @@ static struct rockchip_clk_provider *__init rk3188_common_clk_init(struct device { struct rockchip_clk_provider *ctx; void __iomem *reg_base; - struct clk *clk; reg_base = of_iomap(np, 0); if (!reg_base) { @@ -778,12 +779,6 @@ static struct rockchip_clk_provider *__init rk3188_common_clk_init(struct device return ERR_PTR(-ENOMEM); } - /* 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)); - rockchip_clk_register_branches(ctx, 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 d2e91ea853c96..885d35a0d3910 100644 --- a/drivers/clk/rockchip/clk-rk3228.c +++ b/drivers/clk/rockchip/clk-rk3228.c @@ -228,6 +228,10 @@ static struct rockchip_clk_branch rk3228_clk_branches[] __initdata = { FACTOR(0, "clk_ddrphy", "clk_ddrc", 0, 1, 4), GATE(0, "ddrphy4x", "clk_ddrc", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(7), 1, GFLAGS), + GATE(0, "ddrc", "ddrphy_pre", CLK_IGNORE_UNUSED, + RK2928_CLKGATE_CON(8), 5, GFLAGS), + FACTOR_GATE(0, "ddrphy", "ddrphy4x", CLK_IGNORE_UNUSED, 1, 4, + RK2928_CLKGATE_CON(7), 0, GFLAGS), /* PD_CORE */ GATE(0, "apll_core", "apll", CLK_IGNORE_UNUSED, diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index d0ac6fa7738c0..ca6c2ad3de96e 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -340,6 +340,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(SCLK_I2S_SRC, "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), @@ -406,12 +408,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), @@ -917,18 +917,6 @@ static void __init rk3288_clk_init(struct device_node *np) return; } - /* 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, "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-rk3308.c b/drivers/clk/rockchip/clk-rk3308.c index b2655e530505b..4d423d3338789 100644 --- a/drivers/clk/rockchip/clk-rk3308.c +++ b/drivers/clk/rockchip/clk-rk3308.c @@ -158,7 +158,8 @@ PNAME(mux_mac_rmii_sel_p) = { "clk_mac_rx_tx_div20", "clk_mac_rx_tx_div2" }; PNAME(mux_ddrstdby_p) = { "clk_ddrphy1x_out", "clk_ddr_stdby_div4" }; PNAME(mux_rtc32k_p) = { "xin32k", "clk_pvtm_32k", "clk_rtc32k_frac", "clk_rtc32k_div" }; PNAME(mux_usbphy_ref_p) = { "xin24m", "clk_usbphy_ref_src" }; -PNAME(mux_wifi_p) = { "xin24m", "clk_wifi_src" }; +PNAME(mux_wifi_src_p) = { "clk_wifi_dpll", "clk_wifi_vpll0" }; +PNAME(mux_wifi_p) = { "clk_wifi_osc", "clk_wifi_src" }; PNAME(mux_pdm_p) = { "clk_pdm_src", "clk_pdm_frac" }; PNAME(mux_i2s0_8ch_tx_p) = { "clk_i2s0_8ch_tx_src", "clk_i2s0_8ch_tx_frac", "mclk_i2s0_8ch_in" }; PNAME(mux_i2s0_8ch_tx_rx_p) = { "clk_i2s0_8ch_tx_mux", "clk_i2s0_8ch_rx_mux"}; @@ -190,12 +191,12 @@ PNAME(mux_spdif_rx_src_p) = { "clk_spdif_rx_div", "clk_spdif_rx_div50" }; PNAME(mux_spdif_rx_p) = { "clk_spdif_rx_src", "clk_spdif_rx_frac" }; static struct rockchip_pll_clock rk3308_pll_clks[] __initdata = { - [apll] = PLL_BOOST(pll_rk3328, PLL_APLL, "apll", mux_pll_p, + [apll] = PLL(pll_rk3328, PLL_APLL, "apll", mux_pll_p, 0, RK3308_PLL_CON(0), RK3308_MODE_CON, 0, 0, 0, rk3308_pll_rates), [dpll] = PLL(pll_rk3328, PLL_DPLL, "dpll", mux_pll_p, 0, RK3308_PLL_CON(8), - RK3308_MODE_CON, 2, 1, 0, NULL), + RK3308_MODE_CON, 2, 1, 0, rk3308_pll_rates), [vpll0] = PLL(pll_rk3328, PLL_VPLL0, "vpll0", mux_pll_p, 0, RK3308_PLL_CON(16), RK3308_MODE_CON, 4, 2, 0, rk3308_pll_rates), @@ -403,17 +404,23 @@ static struct rockchip_clk_branch rk3308_clk_branches[] __initdata = { RK3308_CLKSEL_CON(28), 14, 2, MFLAGS, 0, 7, DFLAGS, RK3308_CLKGATE_CON(3), 0, GFLAGS), - COMPOSITE(SCLK_PWM, "clk_pwm", mux_dpll_vpll0_xin24m_p, 0, + COMPOSITE(SCLK_PWM0, "clk_pwm0", mux_dpll_vpll0_xin24m_p, 0, RK3308_CLKSEL_CON(29), 14, 2, MFLAGS, 0, 7, DFLAGS, RK3308_CLKGATE_CON(3), 1, GFLAGS), - - COMPOSITE(SCLK_SPI0, "clk_isp0", mux_dpll_vpll0_xin24m_p, 0, + COMPOSITE(SCLK_PWM1, "clk_pwm1", mux_dpll_vpll0_xin24m_p, 0, + RK3308_CLKSEL_CON(74), 14, 2, MFLAGS, 0, 7, DFLAGS, + RK3308_CLKGATE_CON(15), 0, GFLAGS), + COMPOSITE(SCLK_PWM2, "clk_pwm2", mux_dpll_vpll0_xin24m_p, 0, + RK3308_CLKSEL_CON(75), 14, 2, MFLAGS, 0, 7, DFLAGS, + RK3308_CLKGATE_CON(15), 1, GFLAGS), + + COMPOSITE(SCLK_SPI0, "clk_spi0", mux_dpll_vpll0_xin24m_p, 0, RK3308_CLKSEL_CON(30), 14, 2, MFLAGS, 0, 7, DFLAGS, RK3308_CLKGATE_CON(3), 2, GFLAGS), - COMPOSITE(SCLK_SPI1, "clk_isp1", mux_dpll_vpll0_xin24m_p, 0, + COMPOSITE(SCLK_SPI1, "clk_spi1", mux_dpll_vpll0_xin24m_p, 0, RK3308_CLKSEL_CON(31), 14, 2, MFLAGS, 0, 7, DFLAGS, RK3308_CLKGATE_CON(3), 3, GFLAGS), - COMPOSITE(SCLK_SPI2, "clk_isp2", mux_dpll_vpll0_xin24m_p, 0, + COMPOSITE(SCLK_SPI2, "clk_spi2", mux_dpll_vpll0_xin24m_p, 0, RK3308_CLKSEL_CON(32), 14, 2, MFLAGS, 0, 7, DFLAGS, RK3308_CLKGATE_CON(3), 4, GFLAGS), @@ -548,6 +555,10 @@ static struct rockchip_clk_branch rk3308_clk_branches[] __initdata = { MUX(SCLK_MAC_RMII, "clk_mac_rmii_sel", mux_mac_rmii_sel_p, CLK_SET_RATE_PARENT, RK3308_CLKSEL_CON(43), 15, 1, MFLAGS), + COMPOSITE(SCLK_OWIRE, "clk_owire", mux_dpll_vpll0_xin24m_p, 0, + RK3308_CLKSEL_CON(44), 14, 2, MFLAGS, 8, 6, DFLAGS, + RK3308_CLKGATE_CON(8), 15, GFLAGS), + /* * Clock-Architecture Diagram 5 */ @@ -603,7 +614,13 @@ static struct rockchip_clk_branch rk3308_clk_branches[] __initdata = { RK3308_CLKSEL_CON(72), 7, 1, MFLAGS, RK3308_CLKGATE_CON(4), 8, GFLAGS), - COMPOSITE(0, "clk_wifi_src", mux_dpll_vpll0_p, 0, + GATE(0, "clk_wifi_dpll", "dpll", 0, + RK3308_CLKGATE_CON(15), 2, GFLAGS), + GATE(0, "clk_wifi_vpll0", "vpll0", 0, + RK3308_CLKGATE_CON(15), 3, GFLAGS), + GATE(0, "clk_wifi_osc", "xin24m", 0, + RK3308_CLKGATE_CON(15), 4, GFLAGS), + COMPOSITE(0, "clk_wifi_src", mux_wifi_src_p, 0, RK3308_CLKSEL_CON(44), 6, 1, MFLAGS, 0, 6, DFLAGS, RK3308_CLKGATE_CON(4), 0, GFLAGS), COMPOSITE_NODIV(SCLK_WIFI, "clk_wifi", mux_wifi_p, CLK_SET_RATE_PARENT, @@ -864,7 +881,7 @@ static struct rockchip_clk_branch rk3308_clk_branches[] __initdata = { GATE(PCLK_I2C1, "pclk_i2c1", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 0, GFLAGS), GATE(PCLK_I2C2, "pclk_i2c2", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 1, GFLAGS), GATE(PCLK_I2C3, "pclk_i2c3", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 2, GFLAGS), - GATE(PCLK_PWM, "pclk_pwm", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 3, GFLAGS), + GATE(PCLK_PWM0, "pclk_pwm0", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 3, GFLAGS), GATE(PCLK_SPI0, "pclk_spi0", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 4, GFLAGS), GATE(PCLK_SPI1, "pclk_spi1", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 5, GFLAGS), GATE(PCLK_SPI2, "pclk_spi2", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 6, GFLAGS), @@ -888,6 +905,10 @@ static struct rockchip_clk_branch rk3308_clk_branches[] __initdata = { GATE(PCLK_CRU, "pclk_cru", "pclk_bus", CLK_IGNORE_UNUSED, RK3308_CLKGATE_CON(7), 9, GFLAGS), GATE(PCLK_OTP_PHY, "pclk_otp_phy", "pclk_bus", 0, RK3308_CLKGATE_CON(7), 10, GFLAGS), GATE(PCLK_CPU_BOOST, "pclk_cpu_boost", "pclk_bus", CLK_IGNORE_UNUSED, RK3308_CLKGATE_CON(7), 11, GFLAGS), + GATE(PCLK_PWM1, "pclk_pwm1", "pclk_bus", CLK_IGNORE_UNUSED, RK3308_CLKGATE_CON(7), 12, GFLAGS), + GATE(PCLK_PWM2, "pclk_pwm2", "pclk_bus", CLK_IGNORE_UNUSED, RK3308_CLKGATE_CON(7), 13, GFLAGS), + GATE(PCLK_CAN, "pclk_can", "pclk_bus", CLK_IGNORE_UNUSED, RK3308_CLKGATE_CON(7), 14, GFLAGS), + GATE(PCLK_OWIRE, "pclk_owire", "pclk_bus", CLK_IGNORE_UNUSED, RK3308_CLKGATE_CON(7), 15, GFLAGS), }; static const char *const rk3308_critical_clocks[] __initconst = { diff --git a/drivers/clk/rockchip/clk-rk3368.c b/drivers/clk/rockchip/clk-rk3368.c index ad96b42032099..86238e6c73718 100644 --- a/drivers/clk/rockchip/clk-rk3368.c +++ b/drivers/clk/rockchip/clk-rk3368.c @@ -308,6 +308,8 @@ 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), @@ -362,7 +364,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), @@ -454,10 +456,10 @@ static struct rockchip_clk_branch rk3368_clk_branches[] __initdata = { 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, @@ -913,24 +915,6 @@ static void __init rk3368_clk_init(struct device_node *np) return; } - /* 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-rk3399.c b/drivers/clk/rockchip/clk-rk3399.c index 3bff8b9b2bb3d..d1ddf7a97dcbe 100644 --- a/drivers/clk/rockchip/clk-rk3399.c +++ b/drivers/clk/rockchip/clk-rk3399.c @@ -57,6 +57,7 @@ static struct rockchip_pll_rate_table rk3399_pll_rates[] = { RK3036_PLL_RATE(1656000000, 1, 69, 1, 1, 1, 0), RK3036_PLL_RATE(1632000000, 1, 68, 1, 1, 1, 0), RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0), + RK3036_PLL_RATE(1600000000, 3, 200, 1, 1, 1, 0), RK3036_PLL_RATE(1584000000, 1, 66, 1, 1, 1, 0), RK3036_PLL_RATE(1560000000, 1, 65, 1, 1, 1, 0), RK3036_PLL_RATE(1536000000, 1, 64, 1, 1, 1, 0), @@ -77,7 +78,7 @@ static struct rockchip_pll_rate_table rk3399_pll_rates[] = { RK3036_PLL_RATE(1104000000, 1, 46, 1, 1, 1, 0), RK3036_PLL_RATE(1100000000, 12, 550, 1, 1, 1, 0), RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0), - RK3036_PLL_RATE(1000000000, 6, 500, 2, 1, 1, 0), + RK3036_PLL_RATE(1000000000, 1, 125, 3, 1, 1, 0), RK3036_PLL_RATE( 984000000, 1, 82, 2, 1, 1, 0), RK3036_PLL_RATE( 960000000, 1, 80, 2, 1, 1, 0), RK3036_PLL_RATE( 936000000, 1, 78, 2, 1, 1, 0), @@ -87,12 +88,13 @@ static struct rockchip_pll_rate_table rk3399_pll_rates[] = { RK3036_PLL_RATE( 864000000, 1, 72, 2, 1, 1, 0), RK3036_PLL_RATE( 840000000, 1, 70, 2, 1, 1, 0), RK3036_PLL_RATE( 816000000, 1, 68, 2, 1, 1, 0), - RK3036_PLL_RATE( 800000000, 6, 400, 2, 1, 1, 0), + RK3036_PLL_RATE( 800000000, 1, 100, 3, 1, 1, 0), RK3036_PLL_RATE( 700000000, 6, 350, 2, 1, 1, 0), RK3036_PLL_RATE( 696000000, 1, 58, 2, 1, 1, 0), RK3036_PLL_RATE( 676000000, 3, 169, 2, 1, 1, 0), RK3036_PLL_RATE( 600000000, 1, 75, 3, 1, 1, 0), RK3036_PLL_RATE( 594000000, 1, 99, 4, 1, 1, 0), + RK3036_PLL_RATE( 533250000, 8, 711, 4, 1, 1, 0), RK3036_PLL_RATE( 504000000, 1, 63, 3, 1, 1, 0), RK3036_PLL_RATE( 500000000, 6, 250, 2, 1, 1, 0), RK3036_PLL_RATE( 408000000, 1, 68, 2, 2, 1, 0), @@ -183,8 +185,8 @@ PNAME(mux_pll_src_cpll_gpll_npll_ppll_upll_24m_p) = { "dummy_cpll", "gpll", "npl */ PNAME(mux_pll_src_dmyvpll_cpll_gpll_npll_p) = { "dummy_vpll", "dummy_cpll", "gpll", "npll" }; -PNAME(mux_pll_src_dmyvpll_cpll_gpll_24m_p) = { "dummy_vpll", "dummy_cpll", "gpll", - "xin24m" }; +PNAME(mux_pll_src_dmyvpll_cpll_gpll_gpll_p) = { "dummy_vpll", "dummy_cpll", "gpll", + "gpll" }; PNAME(mux_pll_src_24m_32k_cpll_gpll_p) = { "xin24m", "xin32k", "dummy_cpll", "gpll" }; @@ -237,8 +239,8 @@ PNAME(mux_pll_src_cpll_gpll_npll_ppll_upll_24m_p) = { "cpll", "gpll", "npll", */ PNAME(mux_pll_src_dmyvpll_cpll_gpll_npll_p) = { "dummy_vpll", "cpll", "gpll", "npll" }; -PNAME(mux_pll_src_dmyvpll_cpll_gpll_24m_p) = { "dummy_vpll", "cpll", "gpll", - "xin24m" }; +PNAME(mux_pll_src_dmyvpll_cpll_gpll_gpll_p) = { "dummy_vpll", "cpll", "gpll", + "gpll" }; PNAME(mux_pll_src_24m_32k_cpll_gpll_p) = { "xin24m", "xin32k", "cpll", "gpll" }; @@ -315,7 +317,7 @@ static struct rockchip_pll_clock rk3399_pll_clks[] __initdata = { RK3399_PLL_CON(27), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rk3399_pll_rates), #endif [gpll] = PLL(pll_rk3399, PLL_GPLL, "gpll", mux_pll_p, 0, RK3399_PLL_CON(32), - RK3399_PLL_CON(35), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rk3399_pll_rates), + RK3399_PLL_CON(35), 8, 31, 0, rk3399_pll_rates), [npll] = PLL(pll_rk3399, PLL_NPLL, "npll", mux_pll_p, 0, RK3399_PLL_CON(40), RK3399_PLL_CON(43), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rk3399_pll_rates), [vpll] = PLL(pll_rk3399, PLL_VPLL, "vpll", mux_pll_p, 0, RK3399_PLL_CON(48), @@ -671,7 +673,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { COMPOSITE(SCLK_SPDIF_DIV, "clk_spdif_div", mux_pll_src_cpll_gpll_p, 0, RK3399_CLKSEL_CON(32), 7, 1, MFLAGS, 0, 7, DFLAGS, RK3399_CLKGATE_CON(8), 13, GFLAGS), - COMPOSITE_FRACMUX(0, "clk_spdif_frac", "clk_spdif_div", CLK_SET_RATE_PARENT, + COMPOSITE_FRACMUX(0, "clk_spdif_frac", "clk_spdif_div", 0, RK3399_CLKSEL_CON(99), 0, RK3399_CLKGATE_CON(8), 14, GFLAGS, &rk3399_spdif_fracmux, 0), @@ -685,7 +687,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { COMPOSITE(SCLK_I2S0_DIV, "clk_i2s0_div", mux_pll_src_cpll_gpll_p, 0, RK3399_CLKSEL_CON(28), 7, 1, MFLAGS, 0, 7, DFLAGS, RK3399_CLKGATE_CON(8), 3, GFLAGS), - COMPOSITE_FRACMUX(0, "clk_i2s0_frac", "clk_i2s0_div", CLK_SET_RATE_PARENT, + COMPOSITE_FRACMUX(0, "clk_i2s0_frac", "clk_i2s0_div", 0, RK3399_CLKSEL_CON(96), 0, RK3399_CLKGATE_CON(8), 4, GFLAGS, &rk3399_i2s0_fracmux, 0), @@ -695,7 +697,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { COMPOSITE(SCLK_I2S1_DIV, "clk_i2s1_div", mux_pll_src_cpll_gpll_p, 0, RK3399_CLKSEL_CON(29), 7, 1, MFLAGS, 0, 7, DFLAGS, RK3399_CLKGATE_CON(8), 6, GFLAGS), - COMPOSITE_FRACMUX(0, "clk_i2s1_frac", "clk_i2s1_div", CLK_SET_RATE_PARENT, + COMPOSITE_FRACMUX(0, "clk_i2s1_frac", "clk_i2s1_div", 0, RK3399_CLKSEL_CON(97), 0, RK3399_CLKGATE_CON(8), 7, GFLAGS, &rk3399_i2s1_fracmux, 0), @@ -705,7 +707,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { COMPOSITE(SCLK_I2S2_DIV, "clk_i2s2_div", mux_pll_src_cpll_gpll_p, 0, RK3399_CLKSEL_CON(30), 7, 1, MFLAGS, 0, 7, DFLAGS, RK3399_CLKGATE_CON(8), 9, GFLAGS), - COMPOSITE_FRACMUX(0, "clk_i2s2_frac", "clk_i2s2_div", CLK_SET_RATE_PARENT, + COMPOSITE_FRACMUX(0, "clk_i2s2_frac", "clk_i2s2_div", 0, RK3399_CLKSEL_CON(98), 0, RK3399_CLKGATE_CON(8), 10, GFLAGS, &rk3399_i2s2_fracmux, 0), @@ -715,7 +717,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { MUX(0, "clk_i2sout_src", mux_i2sch_p, CLK_SET_RATE_PARENT, RK3399_CLKSEL_CON(31), 0, 2, MFLAGS), COMPOSITE_NODIV(SCLK_I2S_8CH_OUT, "clk_i2sout", mux_i2sout_p, CLK_SET_RATE_PARENT, - RK3399_CLKSEL_CON(30), 8, 2, MFLAGS, + RK3399_CLKSEL_CON(31), 2, 1, MFLAGS, RK3399_CLKGATE_CON(8), 12, GFLAGS), /* uart */ @@ -724,7 +726,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { COMPOSITE_NOMUX(0, "clk_uart0_div", "clk_uart0_src", 0, RK3399_CLKSEL_CON(33), 0, 7, DFLAGS, RK3399_CLKGATE_CON(9), 0, GFLAGS), - COMPOSITE_FRACMUX(0, "clk_uart0_frac", "clk_uart0_div", CLK_SET_RATE_PARENT, + COMPOSITE_FRACMUX(0, "clk_uart0_frac", "clk_uart0_div", 0, RK3399_CLKSEL_CON(100), 0, RK3399_CLKGATE_CON(9), 1, GFLAGS, &rk3399_uart0_fracmux, 0), @@ -734,7 +736,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { COMPOSITE_NOMUX(0, "clk_uart1_div", "clk_uart_src", 0, RK3399_CLKSEL_CON(34), 0, 7, DFLAGS, RK3399_CLKGATE_CON(9), 2, GFLAGS), - COMPOSITE_FRACMUX(0, "clk_uart1_frac", "clk_uart1_div", CLK_SET_RATE_PARENT, + COMPOSITE_FRACMUX(0, "clk_uart1_frac", "clk_uart1_div", 0, RK3399_CLKSEL_CON(101), 0, RK3399_CLKGATE_CON(9), 3, GFLAGS, &rk3399_uart1_fracmux, 0), @@ -742,7 +744,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { COMPOSITE_NOMUX(0, "clk_uart2_div", "clk_uart_src", 0, RK3399_CLKSEL_CON(35), 0, 7, DFLAGS, RK3399_CLKGATE_CON(9), 4, GFLAGS), - COMPOSITE_FRACMUX(0, "clk_uart2_frac", "clk_uart2_div", CLK_SET_RATE_PARENT, + COMPOSITE_FRACMUX(0, "clk_uart2_frac", "clk_uart2_div", 0, RK3399_CLKSEL_CON(102), 0, RK3399_CLKGATE_CON(9), 5, GFLAGS, &rk3399_uart2_fracmux, 0), @@ -750,7 +752,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { COMPOSITE_NOMUX(0, "clk_uart3_div", "clk_uart_src", 0, RK3399_CLKSEL_CON(36), 0, 7, DFLAGS, RK3399_CLKGATE_CON(9), 6, GFLAGS), - COMPOSITE_FRACMUX(0, "clk_uart3_frac", "clk_uart3_div", CLK_SET_RATE_PARENT, + COMPOSITE_FRACMUX(0, "clk_uart3_frac", "clk_uart3_div", 0, RK3399_CLKSEL_CON(103), 0, RK3399_CLKGATE_CON(9), 7, GFLAGS, &rk3399_uart3_fracmux, 0), @@ -807,7 +809,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { GATE(0, "gpll_cci_trace", "gpll", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(2), 6, GFLAGS), COMPOSITE(SCLK_CCI_TRACE, "clk_cci_trace", mux_cci_trace_p, CLK_IGNORE_UNUSED, - RK3399_CLKSEL_CON(5), 15, 2, MFLAGS, 8, 5, DFLAGS, + RK3399_CLKSEL_CON(5), 15, 1, MFLAGS, 8, 5, DFLAGS, RK3399_CLKGATE_CON(2), 7, GFLAGS), GATE(0, "cpll_cs", "cpll", CLK_IGNORE_UNUSED, @@ -936,7 +938,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { RK3399_CLKSEL_CON(14), 8, 2, DFLAGS, RK3399_CLKGATE_CON(5), 3, GFLAGS), COMPOSITE_NOMUX(PCLK_PERIHP, "pclk_perihp", "aclk_perihp", CLK_IGNORE_UNUSED, - RK3399_CLKSEL_CON(14), 12, 2, DFLAGS, + RK3399_CLKSEL_CON(14), 12, 3, DFLAGS, RK3399_CLKGATE_CON(5), 4, GFLAGS), GATE(ACLK_PERF_PCIE, "aclk_perf_pcie", "aclk_perihp", 0, @@ -1151,21 +1153,21 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { /* cif_testout */ MUX(0, "clk_testout1_pll_src", mux_pll_src_cpll_gpll_npll_p, 0, RK3399_CLKSEL_CON(38), 6, 2, MFLAGS), - COMPOSITE(0, "clk_testout1", mux_clk_testout1_p, 0, + COMPOSITE(SCLK_TESTCLKOUT1, "clk_testout1", mux_clk_testout1_p, 0, RK3399_CLKSEL_CON(38), 5, 1, MFLAGS, 0, 5, DFLAGS, RK3399_CLKGATE_CON(13), 14, GFLAGS), MUX(0, "clk_testout2_pll_src", mux_pll_src_cpll_gpll_npll_p, 0, RK3399_CLKSEL_CON(38), 14, 2, MFLAGS), - COMPOSITE(SCLK_TESTOUT2, "clk_testout2", mux_clk_testout2_p, 0, + COMPOSITE(SCLK_TESTCLKOUT2, "clk_testout2", mux_clk_testout2_p, 0, RK3399_CLKSEL_CON(38), 13, 1, MFLAGS, 8, 5, DFLAGS, RK3399_CLKGATE_CON(13), 15, GFLAGS), /* vio */ COMPOSITE(ACLK_VIO, "aclk_vio", mux_pll_src_cpll_gpll_ppll_p, CLK_IGNORE_UNUSED, RK3399_CLKSEL_CON(42), 6, 2, MFLAGS, 0, 5, DFLAGS, - RK3399_CLKGATE_CON(11), 10, GFLAGS), - COMPOSITE_NOMUX(PCLK_VIO, "pclk_vio", "aclk_vio", CLK_IGNORE_UNUSED, + RK3399_CLKGATE_CON(11), 0, GFLAGS), + COMPOSITE_NOMUX(PCLK_VIO, "pclk_vio", "aclk_vio", 0, RK3399_CLKSEL_CON(43), 0, 5, DFLAGS, RK3399_CLKGATE_CON(11), 1, GFLAGS), @@ -1180,9 +1182,8 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { RK3399_CLKGATE_CON(29), 12, GFLAGS), /* hdcp */ - COMPOSITE(ACLK_HDCP, "aclk_hdcp", mux_pll_src_cpll_gpll_ppll_p, 0, - RK3399_CLKSEL_CON(42), 14, 2, MFLAGS, 8, 5, DFLAGS, - RK3399_CLKGATE_CON(11), 12, GFLAGS), + COMPOSITE_NOGATE(ACLK_HDCP, "aclk_hdcp", mux_pll_src_cpll_gpll_ppll_p, 0, + RK3399_CLKSEL_CON(42), 14, 2, MFLAGS, 8, 5, DFLAGS), COMPOSITE_NOMUX(HCLK_HDCP, "hclk_hdcp", "aclk_hdcp", 0, RK3399_CLKSEL_CON(43), 5, 5, DFLAGS, RK3399_CLKGATE_CON(11), 3, GFLAGS), @@ -1217,7 +1218,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { RK3399_CLKGATE_CON(11), 8, GFLAGS), COMPOSITE(PCLK_EDP, "pclk_edp", mux_pll_src_cpll_gpll_p, 0, - RK3399_CLKSEL_CON(44), 15, 1, MFLAGS, 8, 5, DFLAGS, + RK3399_CLKSEL_CON(44), 15, 1, MFLAGS, 8, 6, DFLAGS, RK3399_CLKGATE_CON(11), 11, GFLAGS), GATE(PCLK_EDP_NOC, "pclk_edp_noc", "pclk_edp", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(32), 12, GFLAGS), @@ -1261,11 +1262,11 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { #endif /* The VOP0 is main screen, it is able to re-set parent rate. */ - COMPOSITE_FRACMUX_NOGATE(0, "dclk_vop0_frac", "dclk_vop0_div", CLK_SET_RATE_PARENT, + COMPOSITE_FRACMUX_NOGATE(DCLK_VOP0_FRAC, "dclk_vop0_frac", "dclk_vop0_div", 0, RK3399_CLKSEL_CON(106), 0, &rk3399_dclk_vop0_fracmux, 0), - COMPOSITE(SCLK_VOP0_PWM, "clk_vop0_pwm", mux_pll_src_dmyvpll_cpll_gpll_24m_p, 0, + COMPOSITE(SCLK_VOP0_PWM, "clk_vop0_pwm", mux_pll_src_dmyvpll_cpll_gpll_gpll_p, 0, RK3399_CLKSEL_CON(51), 6, 2, MFLAGS, 0, 5, DFLAGS, RK3399_CLKGATE_CON(10), 14, GFLAGS), @@ -1298,11 +1299,11 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { RK3399_CLKGATE_CON(10), 13, GFLAGS), #endif - COMPOSITE_FRACMUX_NOGATE(0, "dclk_vop1_frac", "dclk_vop1_div", CLK_SET_RATE_PARENT, + COMPOSITE_FRACMUX_NOGATE(DCLK_VOP1_FRAC, "dclk_vop1_frac", "dclk_vop1_div", 0, RK3399_CLKSEL_CON(107), 0, &rk3399_dclk_vop1_fracmux, 0), - COMPOSITE(SCLK_VOP1_PWM, "clk_vop1_pwm", mux_pll_src_dmyvpll_cpll_gpll_24m_p, 0, + COMPOSITE(SCLK_VOP1_PWM, "clk_vop1_pwm", mux_pll_src_dmyvpll_cpll_gpll_gpll_p, 0, RK3399_CLKSEL_CON(52), 6, 2, MFLAGS, 0, 5, DFLAGS, RK3399_CLKGATE_CON(10), 15, GFLAGS), @@ -1412,7 +1413,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { /* testout */ MUX(0, "clk_test_pre", mux_pll_src_cpll_gpll_p, CLK_SET_RATE_PARENT, RK3399_CLKSEL_CON(58), 7, 1, MFLAGS), - COMPOSITE_FRAC(0, "clk_test_frac", "clk_test_pre", CLK_SET_RATE_PARENT, + COMPOSITE_FRAC(0, "clk_test_frac", "clk_test_pre", 0, RK3399_CLKSEL_CON(105), 0, RK3399_CLKGATE_CON(13), 9, GFLAGS, 0), @@ -1517,7 +1518,7 @@ static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata = { RK3399_PMU_CLKSEL_CON(1), 13, 1, MFLAGS, 8, 5, DFLAGS, RK3399_PMU_CLKGATE_CON(0), 8, GFLAGS), - COMPOSITE_FRACMUX_NOGATE(0, "clk_wifi_frac", "clk_wifi_div", CLK_SET_RATE_PARENT, + COMPOSITE_FRACMUX_NOGATE(0, "clk_wifi_frac", "clk_wifi_div", 0, RK3399_PMU_CLKSEL_CON(7), 0, &rk3399_pmuclk_wifi_fracmux, 0), @@ -1548,7 +1549,7 @@ static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata = { RK3399_PMU_CLKSEL_CON(5), 0, 7, DFLAGS, RK3399_PMU_CLKGATE_CON(0), 5, GFLAGS), - COMPOSITE_FRACMUX(0, "clk_uart4_frac", "clk_uart4_div", CLK_SET_RATE_PARENT, + COMPOSITE_FRACMUX(0, "clk_uart4_frac", "clk_uart4_div", 0, RK3399_PMU_CLKSEL_CON(6), 0, RK3399_PMU_CLKGATE_CON(0), 6, GFLAGS, &rk3399_uart4_pmu_fracmux, 0), @@ -1579,10 +1580,10 @@ static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata = { GATE(PCLK_UART4_PMU, "pclk_uart4_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 14, GFLAGS), GATE(PCLK_WDT_M0_PMU, "pclk_wdt_m0_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 15, GFLAGS), - GATE(FCLK_CM0S_PMU, "fclk_cm0s_pmu", "fclk_cm0s_src_pmu", 0, RK3399_PMU_CLKGATE_CON(2), 0, GFLAGS), - GATE(SCLK_CM0S_PMU, "sclk_cm0s_pmu", "fclk_cm0s_src_pmu", 0, RK3399_PMU_CLKGATE_CON(2), 1, GFLAGS), - GATE(HCLK_CM0S_PMU, "hclk_cm0s_pmu", "fclk_cm0s_src_pmu", 0, RK3399_PMU_CLKGATE_CON(2), 2, GFLAGS), - GATE(DCLK_CM0S_PMU, "dclk_cm0s_pmu", "fclk_cm0s_src_pmu", 0, RK3399_PMU_CLKGATE_CON(2), 3, GFLAGS), + GATE(FCLK_CM0S_PMU, "fclk_cm0s_pmu", "fclk_cm0s_src_pmu", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(2), 0, GFLAGS), + GATE(SCLK_CM0S_PMU, "sclk_cm0s_pmu", "fclk_cm0s_src_pmu", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(2), 1, GFLAGS), + GATE(HCLK_CM0S_PMU, "hclk_cm0s_pmu", "fclk_cm0s_src_pmu", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(2), 2, GFLAGS), + GATE(DCLK_CM0S_PMU, "dclk_cm0s_pmu", "fclk_cm0s_src_pmu", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(2), 3, GFLAGS), GATE(HCLK_NOC_PMU, "hclk_noc_pmu", "fclk_cm0s_src_pmu", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(2), 5, GFLAGS), }; diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c index b187fae839912..b90f21731d5ee 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c @@ -410,8 +410,6 @@ struct rockchip_clk_provider * __init rockchip_clk_init(struct device_node *np, spin_lock_init(&ctx->lock); ctx->grf = syscon_regmap_lookup_by_phandle(ctx->cru_node, "rockchip,grf"); - ctx->boost = syscon_regmap_lookup_by_phandle(ctx->cru_node, - "rockchip,boost"); return ctx; @@ -455,8 +453,7 @@ void __init rockchip_clk_register_plls(struct rockchip_clk_provider *ctx, list->con_offset, grf_lock_offset, list->lock_shift, list->mode_offset, list->mode_shift, list->rate_table, - list->flags, list->pll_flags, - list->boost_enabled); + list->flags, list->pll_flags); if (IS_ERR(clk)) { pr_err("%s: failed to register clock %s\n", __func__, list->name); diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h index 65708e43cf510..7b1a98cc7f9a4 100644 --- a/drivers/clk/rockchip/clk.h +++ b/drivers/clk/rockchip/clk.h @@ -45,12 +45,25 @@ struct clk; #define BOOST_SWITCH_THRESHOLD 0x0024 #define BOOST_FSM_STATUS 0x0028 #define BOOST_PLL_L_CON(x) ((x) * 0x4 + 0x2c) +#define BOOST_PLL_CON_MASK 0xffff +#define BOOST_CORE_DIV_MASK 0x1f +#define BOOST_CORE_DIV_SHIFT 0 +#define BOOST_BACKUP_PLL_MASK 0x3 +#define BOOST_BACKUP_PLL_SHIFT 8 +#define BOOST_BACKUP_PLL_USAGE_MASK 0x1 +#define BOOST_BACKUP_PLL_USAGE_SHIFT 12 +#define BOOST_BACKUP_PLL_USAGE_BORROW 0 +#define BOOST_BACKUP_PLL_USAGE_TARGET 1 +#define BOOST_ENABLE_MASK 0x1 +#define BOOST_ENABLE_SHIFT 0 #define BOOST_RECOVERY_MASK 0x1 #define BOOST_RECOVERY_SHIFT 1 #define BOOST_SW_CTRL_MASK 0x1 #define BOOST_SW_CTRL_SHIFT 2 #define BOOST_LOW_FREQ_EN_MASK 0x1 #define BOOST_LOW_FREQ_EN_SHIFT 3 +#define BOOST_STATIS_ENABLE_MASK 0x1 +#define BOOST_STATIS_ENABLE_SHIFT 4 #define BOOST_BUSY_STATE BIT(8) #define PX30_PLL_CON(x) ((x) * 0x4) @@ -236,7 +249,6 @@ struct rockchip_clk_provider { struct clk_onecell_data clk_data; struct device_node *cru_node; struct regmap *grf; - struct regmap *boost; spinlock_t lock; }; @@ -269,7 +281,6 @@ struct rockchip_pll_rate_table { * @type: Type of PLL to be registered. * @pll_flags: hardware-specific flags * @rate_table: Table of usable pll rates - * @boost_enabled: whether pll supports boost * * Flags: * ROCKCHIP_PLL_SYNC_RATE - check rate parameters to match against the @@ -288,7 +299,6 @@ struct rockchip_pll_clock { enum rockchip_pll_type type; u8 pll_flags; struct rockchip_pll_rate_table *rate_table; - bool boost_enabled; }; #define ROCKCHIP_PLL_SYNC_RATE BIT(0) @@ -310,37 +320,22 @@ struct rockchip_pll_clock { .rate_table = _rtable, \ } -#define PLL_BOOST(_type, _id, _name, _pnames, _flags, _con, _mode, \ - _mshift, _lshift, _pflags, _rtable) \ - { \ - .id = _id, \ - .type = _type, \ - .name = _name, \ - .parent_names = _pnames, \ - .num_parents = ARRAY_SIZE(_pnames), \ - .flags = CLK_GET_RATE_NOCACHE | _flags, \ - .con_offset = _con, \ - .mode_offset = _mode, \ - .mode_shift = _mshift, \ - .lock_shift = _lshift, \ - .pll_flags = _pflags, \ - .rate_table = _rtable, \ - .boost_enabled = true, \ - } - struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, enum rockchip_pll_type pll_type, const char *name, const char *const *parent_names, u8 num_parents, int con_offset, int grf_lock_offset, int lock_shift, int mode_offset, int mode_shift, struct rockchip_pll_rate_table *rate_table, - unsigned long flags, u8 clk_pll_flags, - bool boost_enabled); + unsigned long flags, u8 clk_pll_flags); + +void rockchip_boost_init(struct clk_hw *hw); void rockchip_boost_enable_recovery_sw_low(struct clk_hw *hw); void rockchip_boost_disable_recovery_sw(struct clk_hw *hw); +void rockchip_boost_add_core_div(struct clk_hw *hw, unsigned long prate); + struct rockchip_cpuclk_clksel { int reg; u32 val; diff --git a/drivers/clk/samsung/clk-exynos3250.c b/drivers/clk/samsung/clk-exynos3250.c index fdd41b17a24fc..294efaef5b820 100644 --- a/drivers/clk/samsung/clk-exynos3250.c +++ b/drivers/clk/samsung/clk-exynos3250.c @@ -683,7 +683,7 @@ static struct samsung_pll_rate_table exynos3250_epll_rates[] = { PLL_36XX_RATE(144000000, 96, 2, 3, 0), PLL_36XX_RATE( 96000000, 128, 2, 4, 0), PLL_36XX_RATE( 84000000, 112, 2, 4, 0), - PLL_36XX_RATE( 80000004, 106, 2, 4, 43691), + PLL_36XX_RATE( 80000003, 106, 2, 4, 43691), PLL_36XX_RATE( 73728000, 98, 2, 4, 19923), PLL_36XX_RATE( 67737598, 270, 3, 5, 62285), PLL_36XX_RATE( 65535999, 174, 2, 5, 49982), @@ -719,7 +719,7 @@ static struct samsung_pll_rate_table exynos3250_vpll_rates[] = { PLL_36XX_RATE(148352005, 98, 2, 3, 59070), PLL_36XX_RATE(108000000, 144, 2, 4, 0), PLL_36XX_RATE( 74250000, 99, 2, 4, 0), - PLL_36XX_RATE( 74176002, 98, 3, 4, 59070), + PLL_36XX_RATE( 74176002, 98, 2, 4, 59070), PLL_36XX_RATE( 54054000, 216, 3, 5, 14156), PLL_36XX_RATE( 54000000, 144, 2, 5, 0), { /* sentinel */ } diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c index 5bebf8cb0d70f..f0b564c7c9c16 100644 --- a/drivers/clk/samsung/clk-exynos5250.c +++ b/drivers/clk/samsung/clk-exynos5250.c @@ -711,13 +711,13 @@ static struct samsung_pll_rate_table epll_24mhz_tbl[] __initdata = { /* sorted in descending order */ /* PLL_36XX_RATE(rate, m, p, s, k) */ PLL_36XX_RATE(192000000, 64, 2, 2, 0), - PLL_36XX_RATE(180633600, 90, 3, 2, 20762), + PLL_36XX_RATE(180633605, 90, 3, 2, 20762), PLL_36XX_RATE(180000000, 90, 3, 2, 0), PLL_36XX_RATE(73728000, 98, 2, 4, 19923), - PLL_36XX_RATE(67737600, 90, 2, 4, 20762), + PLL_36XX_RATE(67737602, 90, 2, 4, 20762), PLL_36XX_RATE(49152000, 98, 3, 4, 19923), - PLL_36XX_RATE(45158400, 90, 3, 4, 20762), - PLL_36XX_RATE(32768000, 131, 3, 5, 4719), + PLL_36XX_RATE(45158401, 90, 3, 4, 20762), + PLL_36XX_RATE(32768001, 131, 3, 5, 4719), { }, }; diff --git a/drivers/clk/samsung/clk-exynos5260.c b/drivers/clk/samsung/clk-exynos5260.c index d1a29f6c10849..7027e77bf8590 100644 --- a/drivers/clk/samsung/clk-exynos5260.c +++ b/drivers/clk/samsung/clk-exynos5260.c @@ -65,7 +65,7 @@ static struct samsung_pll_rate_table pll2650_24mhz_tbl[] __initdata = { PLL_36XX_RATE(480000000, 160, 2, 2, 0), PLL_36XX_RATE(432000000, 144, 2, 2, 0), PLL_36XX_RATE(400000000, 200, 3, 2, 0), - PLL_36XX_RATE(394073130, 459, 7, 2, 49282), + PLL_36XX_RATE(394073128, 459, 7, 2, 49282), PLL_36XX_RATE(333000000, 111, 2, 2, 0), PLL_36XX_RATE(300000000, 100, 2, 2, 0), PLL_36XX_RATE(266000000, 266, 3, 3, 0), diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c index cee062c588dec..91c89ac193b9a 100644 --- a/drivers/clk/samsung/clk-exynos5433.c +++ b/drivers/clk/samsung/clk-exynos5433.c @@ -747,7 +747,7 @@ static struct samsung_pll_rate_table exynos5443_pll_rates[] = { PLL_35XX_RATE(800000000U, 400, 6, 1), PLL_35XX_RATE(733000000U, 733, 12, 1), PLL_35XX_RATE(700000000U, 175, 3, 1), - PLL_35XX_RATE(667000000U, 222, 4, 1), + PLL_35XX_RATE(666000000U, 222, 4, 1), PLL_35XX_RATE(633000000U, 211, 4, 1), PLL_35XX_RATE(600000000U, 500, 5, 2), PLL_35XX_RATE(552000000U, 460, 5, 2), @@ -773,12 +773,12 @@ static struct samsung_pll_rate_table exynos5443_pll_rates[] = { /* AUD_PLL */ static struct samsung_pll_rate_table exynos5443_aud_pll_rates[] = { PLL_36XX_RATE(400000000U, 200, 3, 2, 0), - PLL_36XX_RATE(393216000U, 197, 3, 2, -25690), + PLL_36XX_RATE(393216003U, 197, 3, 2, -25690), PLL_36XX_RATE(384000000U, 128, 2, 2, 0), - PLL_36XX_RATE(368640000U, 246, 4, 2, -15729), - PLL_36XX_RATE(361507200U, 181, 3, 2, -16148), - PLL_36XX_RATE(338688000U, 113, 2, 2, -6816), - PLL_36XX_RATE(294912000U, 98, 1, 3, 19923), + PLL_36XX_RATE(368639991U, 246, 4, 2, -15729), + PLL_36XX_RATE(361507202U, 181, 3, 2, -16148), + PLL_36XX_RATE(338687988U, 113, 2, 2, -6816), + PLL_36XX_RATE(294912002U, 98, 1, 3, 19923), PLL_36XX_RATE(288000000U, 96, 1, 3, 0), PLL_36XX_RATE(252000000U, 84, 1, 3, 0), { /* sentinel */ } diff --git a/drivers/clk/samsung/clk-s3c2410.c b/drivers/clk/samsung/clk-s3c2410.c index 0945a8852299d..69e3e848716a1 100644 --- a/drivers/clk/samsung/clk-s3c2410.c +++ b/drivers/clk/samsung/clk-s3c2410.c @@ -168,7 +168,7 @@ static struct samsung_pll_rate_table pll_s3c2410_12mhz_tbl[] __initdata = { PLL_35XX_RATE(226000000, 105, 1, 1), PLL_35XX_RATE(210000000, 132, 2, 1), /* 2410 common */ - PLL_35XX_RATE(203000000, 161, 3, 1), + PLL_35XX_RATE(202800000, 161, 3, 1), PLL_35XX_RATE(192000000, 88, 1, 1), PLL_35XX_RATE(186000000, 85, 1, 1), PLL_35XX_RATE(180000000, 82, 1, 1), @@ -178,18 +178,18 @@ static struct samsung_pll_rate_table pll_s3c2410_12mhz_tbl[] __initdata = { PLL_35XX_RATE(147000000, 90, 2, 1), PLL_35XX_RATE(135000000, 82, 2, 1), PLL_35XX_RATE(124000000, 116, 1, 2), - PLL_35XX_RATE(118000000, 150, 2, 2), + PLL_35XX_RATE(118500000, 150, 2, 2), PLL_35XX_RATE(113000000, 105, 1, 2), - PLL_35XX_RATE(101000000, 127, 2, 2), + PLL_35XX_RATE(101250000, 127, 2, 2), PLL_35XX_RATE(90000000, 112, 2, 2), - PLL_35XX_RATE(85000000, 105, 2, 2), + PLL_35XX_RATE(84750000, 105, 2, 2), PLL_35XX_RATE(79000000, 71, 1, 2), - PLL_35XX_RATE(68000000, 82, 2, 2), - PLL_35XX_RATE(56000000, 142, 2, 3), + PLL_35XX_RATE(67500000, 82, 2, 2), + PLL_35XX_RATE(56250000, 142, 2, 3), PLL_35XX_RATE(48000000, 120, 2, 3), - PLL_35XX_RATE(51000000, 161, 3, 3), + PLL_35XX_RATE(50700000, 161, 3, 3), PLL_35XX_RATE(45000000, 82, 1, 3), - PLL_35XX_RATE(34000000, 82, 2, 3), + PLL_35XX_RATE(33750000, 82, 2, 3), { /* sentinel */ }, }; diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index 8c41c6fcb9ee5..acf83569f86fe 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -333,11 +333,11 @@ static struct pdiv_map pllu_p[] = { }; static struct tegra_clk_pll_freq_table pll_u_freq_table[] = { - { 12000000, 480000000, 960, 12, 0, 12}, - { 13000000, 480000000, 960, 13, 0, 12}, - { 16800000, 480000000, 400, 7, 0, 5}, - { 19200000, 480000000, 200, 4, 0, 3}, - { 26000000, 480000000, 960, 26, 0, 12}, + { 12000000, 480000000, 960, 12, 2, 12 }, + { 13000000, 480000000, 960, 13, 2, 12 }, + { 16800000, 480000000, 400, 7, 2, 5 }, + { 19200000, 480000000, 200, 4, 2, 3 }, + { 26000000, 480000000, 960, 26, 2, 12 }, { 0, 0, 0, 0, 0, 0 }, }; @@ -1372,6 +1372,7 @@ static struct tegra_clk_init_table init_table[] __initdata = { {TEGRA30_CLK_GR2D, TEGRA30_CLK_PLL_C, 300000000, 0}, {TEGRA30_CLK_GR3D, TEGRA30_CLK_PLL_C, 300000000, 0}, {TEGRA30_CLK_GR3D2, TEGRA30_CLK_PLL_C, 300000000, 0}, + { TEGRA30_CLK_PLL_U, TEGRA30_CLK_CLK_MAX, 480000000, 0 }, {TEGRA30_CLK_CLK_MAX, TEGRA30_CLK_CLK_MAX, 0, 0}, /* This MUST be the last entry. */ }; diff --git a/drivers/clocksource/fsl_ftm_timer.c b/drivers/clocksource/fsl_ftm_timer.c index 517e1c7624d44..a00209702f399 100644 --- a/drivers/clocksource/fsl_ftm_timer.c +++ b/drivers/clocksource/fsl_ftm_timer.c @@ -281,7 +281,7 @@ static int __init __ftm_clk_init(struct device_node *np, char *cnt_name, static unsigned long __init ftm_clk_init(struct device_node *np) { - unsigned long freq; + long freq; freq = __ftm_clk_init(np, "ftm-evt-counter-en", "ftm-evt"); if (freq <= 0) diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index ac1bb26fb158f..75ded53a74700 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig @@ -121,14 +121,6 @@ config CPU_FREQ_DEFAULT_GOV_INTERACTIVE loading your cpufreq low-level hardware driver, using the 'interactive' governor for latency-sensitive workloads. -config CPU_FREQ_DEFAULT_GOV_SCHED - bool "sched" - select CPU_FREQ_GOV_SCHED - help - Use the CPUfreq governor 'sched' as default. This scales - cpu frequency using CPU utilization estimates from the - scheduler. - config CPU_FREQ_DEFAULT_GOV_SCHEDUTIL bool "schedutil" depends on SMP diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c index 7c0bdfb1a2ca4..0dcbf951ad1b6 100644 --- a/drivers/cpufreq/cppc_cpufreq.c +++ b/drivers/cpufreq/cppc_cpufreq.c @@ -100,9 +100,19 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy) policy->cpuinfo.max_freq = policy->max; policy->shared_type = cpu->shared_type; - if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) + if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) { + int i; + cpumask_copy(policy->cpus, cpu->shared_cpu_map); - else if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL) { + + for_each_cpu(i, policy->cpus) { + if (unlikely(i == policy->cpu)) + continue; + + memcpy(&all_cpu_data[i]->perf_caps, &cpu->perf_caps, + sizeof(cpu->perf_caps)); + } + } else if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL) { /* Support only SW_ANY for now. */ pr_debug("Unsupported CPU co-ord type\n"); return -EFAULT; @@ -166,8 +176,13 @@ static int __init cppc_cpufreq_init(void) return ret; out: - for_each_possible_cpu(i) - kfree(all_cpu_data[i]); + for_each_possible_cpu(i) { + cpu = all_cpu_data[i]; + if (!cpu) + break; + free_cpumask_var(cpu->shared_cpu_map); + kfree(cpu); + } kfree(all_cpu_data); return -ENODEV; diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c index f07774f96a14a..977e9b5ba8818 100644 --- a/drivers/cpufreq/cpufreq-dt.c +++ b/drivers/cpufreq/cpufreq-dt.c @@ -32,11 +32,20 @@ #include #endif -#define MAX_CLUSTERS 2 +#ifdef CONFIG_ARCH_ROCKCHIP +static struct thermal_opp_device_data cpu_devdata = { + .type = THERMAL_OPP_TPYE_CPU, + .low_temp_adjust = rockchip_cpu_low_temp_adjust, + .high_temp_adjust = rockchip_cpu_high_temp_adjust, +}; +#endif struct private_data { struct device *cpu_dev; struct thermal_cooling_device *cdev; +#ifdef CONFIG_ARCH_ROCKCHIP + struct thermal_opp_info *opp_info; +#endif const char *reg_name; }; @@ -158,11 +167,9 @@ static int cpufreq_init(struct cpufreq_policy *policy) struct cpumask cpus; #endif unsigned int transition_latency; - unsigned long cur_freq; bool opp_v1 = false; const char *name; int ret, scale; - static int check_init; cpu_dev = get_cpu_device(policy->cpu); if (!cpu_dev) { @@ -313,12 +320,16 @@ static int cpufreq_init(struct cpufreq_policy *policy) policy->up_transition_delay_us = transition_latency / NSEC_PER_USEC; policy->down_transition_delay_us = 50000; /* 50ms */ - if (check_init < MAX_CLUSTERS) { - ret = dev_pm_opp_check_initial_rate(cpu_dev, &cur_freq); - if (!ret) - policy->cur = cur_freq / 1000; - check_init++; +#ifdef CONFIG_ARCH_ROCKCHIP + priv->opp_info = rockchip_register_thermal_notifier(cpu_dev, + &cpu_devdata); + if (IS_ERR(priv->opp_info)) { + dev_dbg(priv->cpu_dev, + "running cpufreq without thermal notifier\n"); + priv->opp_info = NULL; } + rockchip_cpufreq_check_rate_volt(cpu_dev); +#endif return 0; @@ -341,13 +352,16 @@ static int cpufreq_exit(struct cpufreq_policy *policy) struct cpumask cpus; struct private_data *priv = policy->driver_data; + priv->cpu_dev = get_cpu_device(policy->cpu); #ifdef CONFIG_ARCH_ROCKCHIP cpumask_set_cpu(policy->cpu, policy->cpus); if (cpufreq_generic_suspend(policy)) pr_err("%s: Failed to suspend driver: %p\n", __func__, policy); cpumask_clear_cpu(policy->cpu, policy->cpus); + rockchip_cpufreq_set_scale_rate(priv->cpu_dev, 0); + rockchip_cpufreq_set_temp_limit_rate(priv->cpu_dev, 0); + rockchip_unregister_thermal_notifier(priv->opp_info); #endif - priv->cpu_dev = get_cpu_device(policy->cpu); cpufreq_cooling_unregister(priv->cdev); dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table); cpumask_copy(&cpus, policy->related_cpus); diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 2a6593dde250c..875f22f177459 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -699,6 +699,8 @@ static ssize_t store_##file_name \ struct cpufreq_policy new_policy; \ \ memcpy(&new_policy, policy, sizeof(*policy)); \ + new_policy.min = policy->user_policy.min; \ + new_policy.max = policy->user_policy.max; \ \ ret = sscanf(buf, "%u", &new_policy.object); \ if (ret != 1) \ diff --git a/drivers/cpufreq/cpufreq_times.c b/drivers/cpufreq/cpufreq_times.c index e5df7a47cc167..e7a8b636a5f45 100644 --- a/drivers/cpufreq/cpufreq_times.c +++ b/drivers/cpufreq/cpufreq_times.c @@ -234,16 +234,19 @@ static int uid_time_in_state_seq_show(struct seq_file *m, void *v) void cpufreq_task_times_init(struct task_struct *p) { - void *temp; unsigned long flags; - unsigned int max_state; spin_lock_irqsave(&task_time_in_state_lock, flags); p->time_in_state = NULL; spin_unlock_irqrestore(&task_time_in_state_lock, flags); p->max_state = 0; +} - max_state = READ_ONCE(next_offset); +void cpufreq_task_times_alloc(struct task_struct *p) +{ + void *temp; + unsigned long flags; + unsigned int max_state = READ_ONCE(next_offset); /* We use one array to avoid multiple allocs per task */ temp = kcalloc(max_state, sizeof(p->time_in_state[0]), GFP_ATOMIC); diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 7ff8b15a34225..88728d9970881 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -1361,6 +1361,11 @@ static inline bool intel_pstate_platform_pwr_mgmt_exists(void) { return false; } static inline bool intel_pstate_has_acpi_ppc(void) { return false; } #endif /* CONFIG_ACPI */ +static const struct x86_cpu_id hwp_support_ids[] __initconst = { + { X86_VENDOR_INTEL, 6, X86_MODEL_ANY, X86_FEATURE_HWP }, + {} +}; + static int __init intel_pstate_init(void) { int cpu, rc = 0; @@ -1370,17 +1375,16 @@ static int __init intel_pstate_init(void) if (no_load) return -ENODEV; + if (x86_match_cpu(hwp_support_ids) && !no_hwp) { + copy_cpu_funcs(&core_params.funcs); + hwp_active++; + goto hwp_cpu_matched; + } + id = x86_match_cpu(intel_pstate_cpu_ids); if (!id) return -ENODEV; - /* - * The Intel pstate driver will be ignored if the platform - * firmware has its own power management modes. - */ - if (intel_pstate_platform_pwr_mgmt_exists()) - return -ENODEV; - cpu_def = (struct cpu_defaults *)id->driver_data; copy_pid_params(&cpu_def->pid_policy); @@ -1389,17 +1393,20 @@ static int __init intel_pstate_init(void) if (intel_pstate_msrs_not_valid()) return -ENODEV; +hwp_cpu_matched: + /* + * The Intel pstate driver will be ignored if the platform + * firmware has its own power management modes. + */ + if (intel_pstate_platform_pwr_mgmt_exists()) + return -ENODEV; + pr_info("Intel P-state driver initializing.\n"); all_cpu_data = vzalloc(sizeof(void *) * num_possible_cpus()); if (!all_cpu_data) return -ENOMEM; - if (static_cpu_has_safe(X86_FEATURE_HWP) && !no_hwp) { - pr_info("intel_pstate: HWP enabled\n"); - hwp_active++; - } - if (!hwp_active && hwp_only) goto out; @@ -1410,6 +1417,9 @@ static int __init intel_pstate_init(void) intel_pstate_debug_expose_params(); intel_pstate_sysfs_expose_params(); + if (hwp_active) + pr_info("intel_pstate: HWP enabled\n"); + return rc; out: get_online_cpus(); diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c index c4b0ef65988c9..57e6c45724e73 100644 --- a/drivers/cpufreq/powernv-cpufreq.c +++ b/drivers/cpufreq/powernv-cpufreq.c @@ -592,7 +592,7 @@ static int __init powernv_cpufreq_init(void) int rc = 0; /* Don't probe on pseries (guest) platforms */ - if (!firmware_has_feature(FW_FEATURE_OPALv3)) + if (!firmware_has_feature(FW_FEATURE_OPAL)) return -ENODEV; /* Discover pstates from device tree and init */ diff --git a/drivers/cpufreq/rockchip-cpufreq.c b/drivers/cpufreq/rockchip-cpufreq.c index cd8bcdac0e457..f77709ab3a86c 100644 --- a/drivers/cpufreq/rockchip-cpufreq.c +++ b/drivers/cpufreq/rockchip-cpufreq.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include "../clk/rockchip/clk.h" @@ -42,19 +43,45 @@ struct cluster_info { unsigned int reboot_freq; unsigned int threshold_freq; unsigned int scale_rate; + unsigned int temp_limit_rate; int volt_sel; int scale; int process; bool offline; bool rebooting; bool freq_limit; + bool is_check_init; }; static LIST_HEAD(cluster_info_list); +static int px30_get_soc_info(struct device *dev, struct device_node *np, + int *bin, int *process) +{ + int ret = 0, value = -EINVAL; + + if (!bin) + return 0; + + if (of_property_match_string(np, "nvmem-cell-names", + "performance") >= 0) { + ret = rockchip_get_efuse_value(np, "performance", &value); + if (ret) { + dev_err(dev, "Failed to get soc performance value\n"); + return ret; + } + *bin = value; + } + if (*bin >= 0) + dev_info(dev, "bin=%d\n", *bin); + + return ret; +} + static int rk3288_get_soc_info(struct device *dev, struct device_node *np, int *bin, int *process) { int ret = 0, value = -EINVAL; + char *name; if (!bin) goto next; @@ -69,9 +96,14 @@ static int rk3288_get_soc_info(struct device *dev, struct device_node *np, else *bin = 1; } - if (of_property_match_string(np, "nvmem-cell-names", - "performance") >= 0) { - ret = rockchip_get_efuse_value(np, "performance", &value); + + if (soc_is_rk3288w()) + name = "performance-w"; + else + name = "performance"; + + if (of_property_match_string(np, "nvmem-cell-names", name) >= 0) { + ret = rockchip_get_efuse_value(np, name, &value); if (ret) { dev_err(dev, "Failed to get soc performance value\n"); goto out; @@ -94,7 +126,7 @@ static int rk3288_get_soc_info(struct device *dev, struct device_node *np, dev_err(dev, "Failed to get soc process version\n"); goto out; } - if (value == 0 || value == 1) + if (soc_is_rk3288() && (value == 0 || value == 1)) *process = 0; } if (*process >= 0) @@ -105,6 +137,10 @@ static int rk3288_get_soc_info(struct device *dev, struct device_node *np, } static const struct of_device_id rockchip_cpufreq_of_match[] = { + { + .compatible = "rockchip,px30", + .data = (void *)&px30_get_soc_info, + }, { .compatible = "rockchip,rk3288", .data = (void *)&rk3288_get_soc_info, @@ -113,6 +149,10 @@ static const struct of_device_id rockchip_cpufreq_of_match[] = { .compatible = "rockchip,rk3288w", .data = (void *)&rk3288_get_soc_info, }, + { + .compatible = "rockchip,rk3326", + .data = (void *)&px30_get_soc_info, + }, {}, }; @@ -172,10 +212,78 @@ int rockchip_cpufreq_set_scale_rate(struct device *dev, unsigned long rate) } EXPORT_SYMBOL_GPL(rockchip_cpufreq_set_scale_rate); +int rockchip_cpufreq_check_rate_volt(struct device *dev) +{ + struct cluster_info *cluster; + + cluster = rockchip_cluster_lookup_by_dev(dev); + if (!cluster) + return -EINVAL; + if (cluster->is_check_init) + return 0; + dev_pm_opp_check_rate_volt(dev, true); + cluster->is_check_init = true; + + return 0; +} +EXPORT_SYMBOL_GPL(rockchip_cpufreq_check_rate_volt); + +int rockchip_cpufreq_set_temp_limit_rate(struct device *dev, unsigned long rate) +{ + struct cluster_info *cluster; + + cluster = rockchip_cluster_lookup_by_dev(dev); + if (!cluster) + return -EINVAL; + cluster->temp_limit_rate = rate / 1000; + + return 0; +} +EXPORT_SYMBOL_GPL(rockchip_cpufreq_set_temp_limit_rate); + +int rockchip_cpufreq_update_policy(struct device *dev) +{ + struct cluster_info *cluster; + unsigned int cpu; + + cluster = rockchip_cluster_lookup_by_dev(dev); + if (!cluster) + return -EINVAL; + cpu = cpumask_any(&cluster->cpus); + cpufreq_update_policy(cpu); + + return 0; +} +EXPORT_SYMBOL_GPL(rockchip_cpufreq_update_policy); + +int rockchip_cpufreq_update_cur_volt(struct device *dev) +{ + struct cluster_info *cluster; + struct cpufreq_policy *policy; + unsigned int cpu; + + cluster = rockchip_cluster_lookup_by_dev(dev); + if (!cluster) + return -EINVAL; + cpu = cpumask_any(&cluster->cpus); + + policy = cpufreq_cpu_get(cpu); + if (!policy) + return -ENODEV; + down_write(&policy->rwsem); + dev_pm_opp_check_rate_volt(dev, false); + up_write(&policy->rwsem); + + return 0; +} +EXPORT_SYMBOL_GPL(rockchip_cpufreq_update_cur_volt); + static int rockchip_cpufreq_cluster_init(int cpu, struct cluster_info *cluster) { struct device_node *np; + struct property *pp; struct device *dev; + char *reg_name = NULL; int ret = 0, bin = -EINVAL; cluster->process = -EINVAL; @@ -186,6 +294,17 @@ static int rockchip_cpufreq_cluster_init(int cpu, struct cluster_info *cluster) if (!dev) return -ENODEV; + pp = of_find_property(dev->of_node, "cpu-supply", NULL); + if (pp) { + reg_name = "cpu"; + } else { + pp = of_find_property(dev->of_node, "cpu0-supply", NULL); + if (pp) + reg_name = "cpu0"; + else + return -ENOENT; + } + np = of_parse_phandle(dev->of_node, "operating-points-v2", 0); if (!np) { dev_warn(dev, "OPP-v2 not supported\n"); @@ -207,7 +326,7 @@ static int rockchip_cpufreq_cluster_init(int cpu, struct cluster_info *cluster) rockchip_get_soc_info(dev, rockchip_cpufreq_of_match, &bin, &cluster->process); - rockchip_get_scale_volt_sel(dev, "cpu_leakage", "cpu", + rockchip_get_scale_volt_sel(dev, "cpu_leakage", reg_name, bin, cluster->process, &cluster->scale, &cluster->volt_sel); np_err: @@ -297,6 +416,16 @@ static int rockchip_cpufreq_policy_notifier(struct notifier_block *nb, if (!cluster) return NOTIFY_DONE; + if (cluster->scale_rate) { + if (cluster->scale_rate < policy->max) + policy->max = cluster->scale_rate; + } + + if (cluster->temp_limit_rate) { + if (cluster->temp_limit_rate < policy->max) + policy->max = cluster->temp_limit_rate; + } + if (cluster->rebooting) { if (cluster->reboot_freq < policy->max) policy->max = cluster->reboot_freq; @@ -307,11 +436,6 @@ static int rockchip_cpufreq_policy_notifier(struct notifier_block *nb, return NOTIFY_OK; } - if (cluster->scale_rate) { - if (cluster->scale_rate < policy->max) - policy->max = cluster->scale_rate; - } - return NOTIFY_OK; } diff --git a/drivers/cpuidle/coupled.c b/drivers/cpuidle/coupled.c index 344058f8501a2..d5657d50ac404 100644 --- a/drivers/cpuidle/coupled.c +++ b/drivers/cpuidle/coupled.c @@ -119,7 +119,6 @@ struct cpuidle_coupled { #define CPUIDLE_COUPLED_NOT_IDLE (-1) -static DEFINE_MUTEX(cpuidle_coupled_lock); static DEFINE_PER_CPU(struct call_single_data, cpuidle_coupled_poke_cb); /* diff --git a/drivers/cpuidle/cpuidle-powernv.c b/drivers/cpuidle/cpuidle-powernv.c index d5c5a476360fc..44ebda8bbc848 100644 --- a/drivers/cpuidle/cpuidle-powernv.c +++ b/drivers/cpuidle/cpuidle-powernv.c @@ -29,9 +29,31 @@ struct cpuidle_driver powernv_idle_driver = { static int max_idle_state; static struct cpuidle_state *cpuidle_state_table; -static u64 snooze_timeout; +static u64 default_snooze_timeout; static bool snooze_timeout_en; +static u64 get_snooze_timeout(struct cpuidle_device *dev, + struct cpuidle_driver *drv, + int index) +{ + int i; + + if (unlikely(!snooze_timeout_en)) + return default_snooze_timeout; + + for (i = index + 1; i < drv->state_count; i++) { + struct cpuidle_state *s = &drv->states[i]; + struct cpuidle_state_usage *su = &dev->states_usage[i]; + + if (s->disabled || su->disable) + continue; + + return s->target_residency * tb_ticks_per_usec; + } + + return default_snooze_timeout; +} + static int snooze_loop(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) @@ -41,7 +63,7 @@ static int snooze_loop(struct cpuidle_device *dev, local_irq_enable(); set_thread_flag(TIF_POLLING_NRFLAG); - snooze_exit_time = get_tb() + snooze_timeout; + snooze_exit_time = get_tb() + get_snooze_timeout(dev, drv, index); ppc64_runlatch_off(); while (!need_resched()) { HMT_low(); @@ -282,15 +304,13 @@ static int powernv_idle_probe(void) if (cpuidle_disable != IDLE_NO_OVERRIDE) return -ENODEV; - if (firmware_has_feature(FW_FEATURE_OPALv3)) { + if (firmware_has_feature(FW_FEATURE_OPAL)) { cpuidle_state_table = powernv_states; /* Device tree can indicate more idle states */ max_idle_state = powernv_add_idle_states(); - if (max_idle_state > 1) { + default_snooze_timeout = TICK_USEC * tb_ticks_per_usec; + if (max_idle_state > 1) snooze_timeout_en = true; - snooze_timeout = powernv_states[1].target_residency * - tb_ticks_per_usec; - } } else return -ENODEV; diff --git a/drivers/crypto/amcc/crypto4xx_core.c b/drivers/crypto/amcc/crypto4xx_core.c index 58a630e55d5d6..78d0722feacb5 100644 --- a/drivers/crypto/amcc/crypto4xx_core.c +++ b/drivers/crypto/amcc/crypto4xx_core.c @@ -207,7 +207,7 @@ static u32 crypto4xx_build_pdr(struct crypto4xx_device *dev) dev->pdr_pa); return -ENOMEM; } - memset(dev->pdr, 0, sizeof(struct ce_pd) * PPC4XX_NUM_PD); + memset(dev->pdr, 0, sizeof(struct ce_pd) * PPC4XX_NUM_PD); dev->shadow_sa_pool = dma_alloc_coherent(dev->core_dev->device, 256 * PPC4XX_NUM_PD, &dev->shadow_sa_pool_pa, @@ -240,13 +240,15 @@ static u32 crypto4xx_build_pdr(struct crypto4xx_device *dev) static void crypto4xx_destroy_pdr(struct crypto4xx_device *dev) { - if (dev->pdr != NULL) + if (dev->pdr) dma_free_coherent(dev->core_dev->device, sizeof(struct ce_pd) * PPC4XX_NUM_PD, dev->pdr, dev->pdr_pa); + if (dev->shadow_sa_pool) dma_free_coherent(dev->core_dev->device, 256 * PPC4XX_NUM_PD, dev->shadow_sa_pool, dev->shadow_sa_pool_pa); + if (dev->shadow_sr_pool) dma_free_coherent(dev->core_dev->device, sizeof(struct sa_state_record) * PPC4XX_NUM_PD, @@ -416,12 +418,12 @@ static u32 crypto4xx_build_sdr(struct crypto4xx_device *dev) static void crypto4xx_destroy_sdr(struct crypto4xx_device *dev) { - if (dev->sdr != NULL) + if (dev->sdr) dma_free_coherent(dev->core_dev->device, sizeof(struct ce_sd) * PPC4XX_NUM_SD, dev->sdr, dev->sdr_pa); - if (dev->scatter_buffer_va != NULL) + if (dev->scatter_buffer_va) dma_free_coherent(dev->core_dev->device, dev->scatter_buffer_size * PPC4XX_NUM_SD, dev->scatter_buffer_va, @@ -1029,12 +1031,10 @@ int crypto4xx_register_alg(struct crypto4xx_device *sec_dev, break; } - if (rc) { - list_del(&alg->entry); + if (rc) kfree(alg); - } else { + else list_add_tail(&alg->entry, &sec_dev->alg_list); - } } return 0; @@ -1188,7 +1188,7 @@ static int crypto4xx_probe(struct platform_device *ofdev) rc = crypto4xx_build_gdr(core_dev->dev); if (rc) - goto err_build_gdr; + goto err_build_pdr; rc = crypto4xx_build_sdr(core_dev->dev); if (rc) @@ -1230,12 +1230,11 @@ static int crypto4xx_probe(struct platform_device *ofdev) err_request_irq: irq_dispose_mapping(core_dev->irq); tasklet_kill(&core_dev->tasklet); - crypto4xx_destroy_sdr(core_dev->dev); err_build_sdr: + crypto4xx_destroy_sdr(core_dev->dev); crypto4xx_destroy_gdr(core_dev->dev); -err_build_gdr: - crypto4xx_destroy_pdr(core_dev->dev); err_build_pdr: + crypto4xx_destroy_pdr(core_dev->dev); kfree(core_dev->dev); err_alloc_dev: kfree(core_dev); diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c index da2d6777bd092..047ef69b7e653 100644 --- a/drivers/crypto/padlock-aes.c +++ b/drivers/crypto/padlock-aes.c @@ -266,6 +266,8 @@ static inline void padlock_xcrypt_ecb(const u8 *input, u8 *output, void *key, return; } + count -= initial; + if (initial) asm volatile (".byte 0xf3,0x0f,0xa7,0xc8" /* rep xcryptecb */ : "+S"(input), "+D"(output) @@ -273,7 +275,7 @@ static inline void padlock_xcrypt_ecb(const u8 *input, u8 *output, void *key, asm volatile (".byte 0xf3,0x0f,0xa7,0xc8" /* rep xcryptecb */ : "+S"(input), "+D"(output) - : "d"(control_word), "b"(key), "c"(count - initial)); + : "d"(control_word), "b"(key), "c"(count)); } static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key, @@ -284,6 +286,8 @@ static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key, if (count < cbc_fetch_blocks) return cbc_crypt(input, output, key, iv, control_word, count); + count -= initial; + if (initial) asm volatile (".byte 0xf3,0x0f,0xa7,0xd0" /* rep xcryptcbc */ : "+S" (input), "+D" (output), "+a" (iv) @@ -291,7 +295,7 @@ static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key, asm volatile (".byte 0xf3,0x0f,0xa7,0xd0" /* rep xcryptcbc */ : "+S" (input), "+D" (output), "+a" (iv) - : "d" (control_word), "b" (key), "c" (count-initial)); + : "d" (control_word), "b" (key), "c" (count)); return iv; } @@ -515,7 +519,7 @@ static int __init padlock_init(void) if (!x86_match_cpu(padlock_cpu_id)) return -ENODEV; - if (!cpu_has_xcrypt_enabled) { + if (!boot_cpu_has(X86_FEATURE_XCRYPT_EN)) { printk(KERN_NOTICE PFX "VIA PadLock detected, but not enabled. Hmm, strange...\n"); return -ENODEV; } diff --git a/drivers/crypto/padlock-sha.c b/drivers/crypto/padlock-sha.c index 4e154c9b92064..8c5f90647b7a7 100644 --- a/drivers/crypto/padlock-sha.c +++ b/drivers/crypto/padlock-sha.c @@ -540,7 +540,7 @@ static int __init padlock_init(void) struct shash_alg *sha1; struct shash_alg *sha256; - if (!x86_match_cpu(padlock_sha_ids) || !cpu_has_phe_enabled) + if (!x86_match_cpu(padlock_sha_ids) || !boot_cpu_has(X86_FEATURE_PHE_EN)) return -ENODEV; /* Register the newly added algorithm module if on * diff --git a/drivers/crypto/sunxi-ss/sun4i-ss-core.c b/drivers/crypto/sunxi-ss/sun4i-ss-core.c index 107cd2a41cae2..24651d3217cd0 100644 --- a/drivers/crypto/sunxi-ss/sun4i-ss-core.c +++ b/drivers/crypto/sunxi-ss/sun4i-ss-core.c @@ -422,6 +422,7 @@ static struct platform_driver sun4i_ss_driver = { module_platform_driver(sun4i_ss_driver); +MODULE_ALIAS("platform:sun4i-ss"); MODULE_DESCRIPTION("Allwinner Security System cryptographic accelerator"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Corentin LABBE "); diff --git a/drivers/crypto/vmx/aes.c b/drivers/crypto/vmx/aes.c index 263af709e5360..b907e4b1bbe22 100644 --- a/drivers/crypto/vmx/aes.c +++ b/drivers/crypto/vmx/aes.c @@ -53,8 +53,6 @@ static int p8_aes_init(struct crypto_tfm *tfm) alg, PTR_ERR(fallback)); return PTR_ERR(fallback); } - printk(KERN_INFO "Using '%s' as fallback implementation.\n", - crypto_tfm_alg_driver_name((struct crypto_tfm *) fallback)); crypto_cipher_set_flags(fallback, crypto_cipher_get_flags((struct diff --git a/drivers/crypto/vmx/aes_cbc.c b/drivers/crypto/vmx/aes_cbc.c index 3f8bb9a40df12..9506e8693c819 100644 --- a/drivers/crypto/vmx/aes_cbc.c +++ b/drivers/crypto/vmx/aes_cbc.c @@ -55,8 +55,6 @@ static int p8_aes_cbc_init(struct crypto_tfm *tfm) alg, PTR_ERR(fallback)); return PTR_ERR(fallback); } - printk(KERN_INFO "Using '%s' as fallback implementation.\n", - crypto_tfm_alg_driver_name((struct crypto_tfm *) fallback)); crypto_blkcipher_set_flags( fallback, diff --git a/drivers/crypto/vmx/aes_ctr.c b/drivers/crypto/vmx/aes_ctr.c index d83ab4bac8b12..7d070201b3d30 100644 --- a/drivers/crypto/vmx/aes_ctr.c +++ b/drivers/crypto/vmx/aes_ctr.c @@ -53,8 +53,6 @@ static int p8_aes_ctr_init(struct crypto_tfm *tfm) alg, PTR_ERR(fallback)); return PTR_ERR(fallback); } - printk(KERN_INFO "Using '%s' as fallback implementation.\n", - crypto_tfm_alg_driver_name((struct crypto_tfm *) fallback)); crypto_blkcipher_set_flags( fallback, diff --git a/drivers/crypto/vmx/ghash.c b/drivers/crypto/vmx/ghash.c index 9cb3a0b715e23..84b9389bf1edb 100644 --- a/drivers/crypto/vmx/ghash.c +++ b/drivers/crypto/vmx/ghash.c @@ -64,8 +64,6 @@ static int p8_ghash_init_tfm(struct crypto_tfm *tfm) alg, PTR_ERR(fallback)); return PTR_ERR(fallback); } - printk(KERN_INFO "Using '%s' as fallback implementation.\n", - crypto_tfm_alg_driver_name(crypto_shash_tfm(fallback))); crypto_shash_set_flags(fallback, crypto_shash_get_flags((struct crypto_shash diff --git a/drivers/devfreq/governor_userspace.c b/drivers/devfreq/governor_userspace.c index 35de6e83c1feb..9db4d6f2006ab 100644 --- a/drivers/devfreq/governor_userspace.c +++ b/drivers/devfreq/governor_userspace.c @@ -112,7 +112,13 @@ static int userspace_init(struct devfreq *devfreq) static void userspace_exit(struct devfreq *devfreq) { - sysfs_remove_group(&devfreq->dev.kobj, &dev_attr_group); + /* + * Remove the sysfs entry, unless this is being called after + * device_del(), which should have done this already via kobject_del(). + */ + if (devfreq->dev.kobj.sd) + sysfs_remove_group(&devfreq->dev.kobj, &dev_attr_group); + kfree(devfreq->data); devfreq->data = NULL; } diff --git a/drivers/devfreq/rockchip_dmc.c b/drivers/devfreq/rockchip_dmc.c index 3f03b81400b74..ba095fdfea96c 100644 --- a/drivers/devfreq/rockchip_dmc.c +++ b/drivers/devfreq/rockchip_dmc.c @@ -56,11 +56,11 @@ #include "governor.h" #define system_status_to_dmcfreq(nb) container_of(nb, struct rockchip_dmcfreq, \ - system_status_nb) + status_nb) #define reboot_to_dmcfreq(nb) container_of(nb, struct rockchip_dmcfreq, \ reboot_nb) -#define df_update_to_dmcfreq(work) container_of(work, struct rockchip_dmcfreq, \ - devfreq_update) +#define boost_to_dmcfreq(work) container_of(work, struct rockchip_dmcfreq, \ + boost_work) #define input_hd_to_dmcfreq(hd) container_of(hd, struct rockchip_dmcfreq, \ input_handler) @@ -309,6 +309,52 @@ struct rk3128_ddr_dts_config_timing { u32 available; }; +static const char * const rk3228_dts_timing[] = { + "dram_spd_bin", + "sr_idle", + "pd_idle", + "dram_dll_disb_freq", + "phy_dll_disb_freq", + "dram_odt_disb_freq", + "phy_odt_disb_freq", + "ddr3_drv", + "ddr3_odt", + "lpddr3_drv", + "lpddr3_odt", + "lpddr2_drv", + "phy_ddr3_clk_drv", + "phy_ddr3_cmd_drv", + "phy_ddr3_dqs_drv", + "phy_ddr3_odt", + "phy_lp23_clk_drv", + "phy_lp23_cmd_drv", + "phy_lp23_dqs_drv", + "phy_lp3_odt" +}; + +struct rk3228_ddr_dts_config_timing { + u32 dram_spd_bin; + u32 sr_idle; + u32 pd_idle; + u32 dram_dll_dis_freq; + u32 phy_dll_dis_freq; + u32 dram_odt_dis_freq; + u32 phy_odt_dis_freq; + u32 ddr3_drv; + u32 ddr3_odt; + u32 lpddr3_drv; + u32 lpddr3_odt; + u32 lpddr2_drv; + u32 phy_ddr3_clk_drv; + u32 phy_ddr3_cmd_drv; + u32 phy_ddr3_dqs_drv; + u32 phy_ddr3_odt; + u32 phy_lp23_clk_drv; + u32 phy_lp23_cmd_drv; + u32 phy_lp23_dqs_drv; + u32 phy_lp3_odt; +}; + static const char * const rk3288_dts_timing[] = { "ddr3_speed_bin", "pd_idle", @@ -759,18 +805,20 @@ struct rockchip_dmcfreq { struct devfreq *devfreq; struct devfreq_simple_ondemand_data ondemand_data; struct clk *dmc_clk; - struct devfreq_event_dev *edev; + struct devfreq_event_dev **edev; struct mutex lock; /* serializes access to video_info_list */ struct dram_timing *timing; struct regulator *vdd_center; - struct notifier_block system_status_nb; + struct notifier_block status_nb; struct notifier_block reboot_nb; struct notifier_block fb_nb; struct list_head video_info_list; struct freq_map_table *vop_bw_tbl; - struct work_struct devfreq_update; + struct work_struct boost_work; struct input_handler input_handler; + struct thermal_opp_info *opp_info; + unsigned long *nocp_bw; unsigned long rate, target_rate; unsigned long volt, target_volt; @@ -795,8 +843,12 @@ struct rockchip_dmcfreq { unsigned int min_cpu_freq; unsigned int auto_freq_en; + unsigned int system_status_en; unsigned int refresh; unsigned int last_refresh; + int edev_count; + int dfi_id; + bool is_fixed; struct thermal_cooling_device *devfreq_cooling; @@ -810,6 +862,12 @@ struct rockchip_dmcfreq { int (*set_auto_self_refresh)(u32 en); }; +static struct thermal_opp_device_data dmc_devdata = { + .type = THERMAL_OPP_TPYE_DEV, + .low_temp_adjust = rockchip_dev_low_temp_adjust, + .high_temp_adjust = rockchip_dev_high_temp_adjust, +}; + static struct pm_qos_request pm_qos; static DECLARE_RWSEM(rockchip_dmcfreq_sem); @@ -1094,16 +1152,32 @@ static int rockchip_dmcfreq_get_dev_status(struct device *dev, { struct rockchip_dmcfreq *dmcfreq = dev_get_drvdata(dev); struct devfreq_event_data edata; - int ret = 0; + int i, j, ret = 0; - ret = devfreq_event_get_event(dmcfreq->edev, &edata); - if (ret < 0) - return ret; + if (dmcfreq->dfi_id >= 0) { + ret = devfreq_event_get_event(dmcfreq->edev[dmcfreq->dfi_id], + &edata); + if (ret < 0) { + dev_err(dev, "failed to get dfi event\n"); + return ret; + } + stat->busy_time = edata.load_count; + stat->total_time = edata.total_count; + } - stat->busy_time = edata.load_count; - stat->total_time = edata.total_count; + for (i = 0, j = 0; i < dmcfreq->edev_count; i++) { + if (i == dmcfreq->dfi_id) + continue; + ret = devfreq_event_get_event(dmcfreq->edev[i], &edata); + if (ret < 0) { + dev_err(dev, "failed to get event %s\n", + dmcfreq->edev[i]->desc->name); + return ret; + } + dmcfreq->nocp_bw[j++] = edata.load_count; + } - return ret; + return 0; } static int rockchip_dmcfreq_get_cur_freq(struct device *dev, @@ -1123,58 +1197,6 @@ static struct devfreq_dev_profile rockchip_devfreq_dmc_profile = { .get_cur_freq = rockchip_dmcfreq_get_cur_freq, }; -static __maybe_unused int rockchip_dmcfreq_suspend(struct device *dev) -{ - struct rockchip_dmcfreq *dmcfreq = dev_get_drvdata(dev); - int ret = 0; - - if (!dmcfreq) - return 0; - - if (dmcfreq->edev) { - ret = devfreq_event_disable_edev(dmcfreq->edev); - if (ret < 0) { - dev_err(dev, "failed to disable the devfreq-event devices\n"); - return ret; - } - } - - ret = devfreq_suspend_device(dmcfreq->devfreq); - if (ret < 0) { - dev_err(dev, "failed to suspend the devfreq devices\n"); - return ret; - } - - return 0; -} - -static __maybe_unused int rockchip_dmcfreq_resume(struct device *dev) -{ - struct rockchip_dmcfreq *dmcfreq = dev_get_drvdata(dev); - int ret = 0; - - if (!dmcfreq) - return 0; - - if (dmcfreq->edev) { - ret = devfreq_event_enable_edev(dmcfreq->edev); - if (ret < 0) { - dev_err(dev, "failed to enable the devfreq-event devices\n"); - return ret; - } - } - - ret = devfreq_resume_device(dmcfreq->devfreq); - if (ret < 0) { - dev_err(dev, "failed to resume the devfreq devices\n"); - return ret; - } - return ret; -} - -static SIMPLE_DEV_PM_OPS(rockchip_dmcfreq_pm, rockchip_dmcfreq_suspend, - rockchip_dmcfreq_resume); - static int rockchip_dmcfreq_init_freq_table(struct device *dev, struct devfreq_dev_profile *devp) { @@ -1318,6 +1340,32 @@ static void of_get_rk3128_timings(struct device *dev, of_node_put(np_tim); } +static uint32_t of_get_rk3228_timings(struct device *dev, + struct device_node *np, uint32_t *timing) +{ + struct device_node *np_tim; + u32 *p; + int ret = 0; + u32 i; + + p = timing + DTS_PAR_OFFSET / 4; + np_tim = of_parse_phandle(np, "rockchip,dram_timing", 0); + if (!np_tim) { + ret = -EINVAL; + goto end; + } + for (i = 0; i < ARRAY_SIZE(rk3228_dts_timing); i++) { + ret |= of_property_read_u32(np_tim, rk3228_dts_timing[i], + p + i); + } +end: + if (ret) + dev_err(dev, "of_get_ddr_timings: fail\n"); + + of_node_put(np_tim); + return ret; +} + static void of_get_rk3288_timings(struct device *dev, struct device_node *np, uint32_t *timing) { @@ -1774,9 +1822,31 @@ static __maybe_unused int rk3128_dmc_init(struct platform_device *pdev, static __maybe_unused int rk3228_dmc_init(struct platform_device *pdev, struct rockchip_dmcfreq *dmcfreq) { - /* - * dmc_init have been done in uboot. - */ + struct arm_smccc_res res; + + res = sip_smc_request_share_mem(DIV_ROUND_UP(sizeof( + struct rk3228_ddr_dts_config_timing), + 4096) + 1, SHARE_PAGE_TYPE_DDR); + if (res.a0) { + dev_err(&pdev->dev, "no ATF memory for init\n"); + return -ENOMEM; + } + + ddr_psci_param = (struct share_params *)res.a1; + if (of_get_rk3228_timings(&pdev->dev, pdev->dev.of_node, + (uint32_t *)ddr_psci_param)) + return -ENOMEM; + + ddr_psci_param->hz = 0; + res = sip_smc_dram(SHARE_PAGE_TYPE_DDR, 0, + ROCKCHIP_SIP_CONFIG_DRAM_INIT); + + if (res.a0) { + dev_err(&pdev->dev, "rockchip_sip_config_dram_init error:%lx\n", + res.a0); + return -ENOMEM; + } + dmcfreq->set_auto_self_refresh = rockchip_ddr_set_auto_self_refresh; return 0; @@ -2733,9 +2803,308 @@ static struct devfreq_governor devfreq_dmc_ondemand = { .event_handler = devfreq_dmc_ondemand_handler, }; -static void rockchip_dmcfreq_devfreq_update(struct work_struct *work) +static int rockchip_dmcfreq_enable_event(struct rockchip_dmcfreq *dmcfreq) +{ + int i, ret; + + if (!dmcfreq->auto_freq_en) + return 0; + + for (i = 0; i < dmcfreq->edev_count; i++) { + ret = devfreq_event_enable_edev(dmcfreq->edev[i]); + if (ret < 0) { + dev_err(dmcfreq->dev, + "failed to enable devfreq-event\n"); + return ret; + } + } + + return 0; +} + +static int rockchip_dmcfreq_disable_event(struct rockchip_dmcfreq *dmcfreq) +{ + int i, ret; + + if (!dmcfreq->auto_freq_en) + return 0; + + for (i = 0; i < dmcfreq->edev_count; i++) { + ret = devfreq_event_disable_edev(dmcfreq->edev[i]); + if (ret < 0) { + dev_err(dmcfreq->dev, + "failed to disable devfreq-event\n"); + return ret; + } + } + + return 0; +} + +static int rockchip_get_edev_id(struct rockchip_dmcfreq *dmcfreq, + const char *name) +{ + struct devfreq_event_dev *edev; + int i; + + for (i = 0; i < dmcfreq->edev_count; i++) { + edev = dmcfreq->edev[i]; + if (!strcmp(edev->desc->name, name)) + return i; + } + + return -EINVAL; +} + +static int rockchip_dmcfreq_get_event(struct rockchip_dmcfreq *dmcfreq) { - struct rockchip_dmcfreq *dmcfreq = df_update_to_dmcfreq(work); + struct device *dev = dmcfreq->dev; + struct device_node *events_np, *np = dev->of_node; + int i, j, count, available_count = 0; + + count = devfreq_event_get_edev_count(dev); + if (count < 0) { + dev_dbg(dev, "failed to get count of devfreq-event dev\n"); + return 0; + } + for (i = 0; i < count; i++) { + events_np = of_parse_phandle(np, "devfreq-events", i); + if (!events_np) + continue; + if (of_device_is_available(events_np)) + available_count++; + of_node_put(events_np); + } + if (!available_count) { + dev_dbg(dev, "failed to get available devfreq-event\n"); + return 0; + } + dmcfreq->edev_count = available_count; + dmcfreq->edev = devm_kzalloc(dev, + sizeof(*dmcfreq->edev) * available_count, + GFP_KERNEL); + if (!dmcfreq->edev) + return -ENOMEM; + + for (i = 0, j = 0; i < count; i++) { + events_np = of_parse_phandle(np, "devfreq-events", i); + if (!events_np) + continue; + if (of_device_is_available(events_np)) { + of_node_put(events_np); + if (j >= available_count) { + dev_err(dev, "invalid event conut\n"); + return -EINVAL; + } + dmcfreq->edev[j] = + devfreq_event_get_edev_by_phandle(dev, i); + if (IS_ERR(dmcfreq->edev[j])) + return -EPROBE_DEFER; + j++; + } else { + of_node_put(events_np); + } + } + dmcfreq->auto_freq_en = true; + dmcfreq->dfi_id = rockchip_get_edev_id(dmcfreq, "dfi"); + if (dmcfreq->dfi_id >= 0) + available_count--; + if (available_count <= 0) + return 0; + dmcfreq->nocp_bw = + devm_kzalloc(dev, sizeof(*dmcfreq->nocp_bw) * available_count, + GFP_KERNEL); + if (!dmcfreq->nocp_bw) + return -ENOMEM; + + return 0; +} + +static int rockchip_dmcfreq_power_control(struct rockchip_dmcfreq *dmcfreq) +{ + struct device *dev = dmcfreq->dev; + + dmcfreq->vdd_center = devm_regulator_get_optional(dev, "center"); + if (IS_ERR(dmcfreq->vdd_center)) { + dev_err(dev, "Cannot get the regulator \"center\"\n"); + return PTR_ERR(dmcfreq->vdd_center); + } + + dmcfreq->dmc_clk = devm_clk_get(dev, "dmc_clk"); + if (IS_ERR(dmcfreq->dmc_clk)) { + dev_err(dev, "Cannot get the clk dmc_clk\n"); + return PTR_ERR(dmcfreq->dmc_clk); + } + dmcfreq->rate = clk_get_rate(dmcfreq->dmc_clk); + + return 0; +} + +static int rockchip_dmcfreq_dmc_init(struct platform_device *pdev, + struct rockchip_dmcfreq *dmcfreq) +{ + const struct of_device_id *match; + int (*init)(struct platform_device *pdev, + struct rockchip_dmcfreq *data); + int ret; + + match = of_match_node(rockchip_dmcfreq_of_match, pdev->dev.of_node); + if (match) { + init = match->data; + if (init) { + ret = init(pdev, dmcfreq); + if (ret) + return ret; + } + } + + return 0; +} + +static void rockchip_dmcfreq_parse_dt(struct rockchip_dmcfreq *dmcfreq) +{ + struct device *dev = dmcfreq->dev; + struct device_node *np = dev->of_node; + + if (!rockchip_get_system_status_rate(np, "system-status-freq", + dmcfreq)) + dmcfreq->system_status_en = true; + of_property_read_u32(np, "min-cpu-freq", &dmcfreq->min_cpu_freq); + + of_property_read_u32(np, "upthreshold", + &dmcfreq->ondemand_data.upthreshold); + of_property_read_u32(np, "downdifferential", + &dmcfreq->ondemand_data.downdifferential); + if (dmcfreq->auto_freq_en) + of_property_read_u32(np, "auto-freq-en", + &dmcfreq->auto_freq_en); + of_property_read_u32(np, "auto-min-freq", + (u32 *)&dmcfreq->auto_min_rate); + dmcfreq->auto_min_rate *= 1000; + + if (rockchip_get_freq_map_talbe(np, "vop-bw-dmc-freq", + &dmcfreq->vop_bw_tbl)) + dev_err(dev, "failed to get vop bandwidth to dmc rate\n"); + + of_property_read_u32(np, "touchboost_duration", + (u32 *)&dmcfreq->touchboostpulse_duration_val); + if (dmcfreq->touchboostpulse_duration_val) + dmcfreq->touchboostpulse_duration_val *= USEC_PER_MSEC; + else + dmcfreq->touchboostpulse_duration_val = 500 * USEC_PER_MSEC; +} + +static int rockchip_dmcfreq_set_volt_only(struct rockchip_dmcfreq *dmcfreq) +{ + struct device *dev = dmcfreq->dev; + struct dev_pm_opp *opp; + unsigned long opp_volt, opp_rate = dmcfreq->rate; + int ret; + + rcu_read_lock(); + opp = devfreq_recommended_opp(dev, &opp_rate, 0); + if (IS_ERR(opp)) { + rcu_read_unlock(); + return PTR_ERR(opp); + } + opp_volt = dev_pm_opp_get_voltage(opp); + rcu_read_unlock(); + + ret = regulator_set_voltage(dmcfreq->vdd_center, opp_volt, INT_MAX); + if (ret) { + dev_err(dev, "Cannot set voltage %lu uV\n", opp_volt); + return ret; + } + + return 0; +} + +static int rockchip_dmcfreq_add_devfreq(struct rockchip_dmcfreq *dmcfreq) +{ + struct devfreq_dev_profile *devp = &rockchip_devfreq_dmc_profile; + struct device *dev = dmcfreq->dev; + struct dev_pm_opp *opp; + unsigned long opp_rate = dmcfreq->rate; + + rcu_read_lock(); + opp = devfreq_recommended_opp(dev, &opp_rate, 0); + if (IS_ERR(opp)) { + rcu_read_unlock(); + return PTR_ERR(opp); + } + rcu_read_unlock(); + + if (rockchip_dmcfreq_init_freq_table(dev, devp)) { + dev_err(dev, "failed to set init freq talbe\n"); + return -EFAULT; + } + + devp->initial_freq = dmcfreq->rate; + dmcfreq->devfreq = devm_devfreq_add_device(dev, devp, + "dmc_ondemand", + &dmcfreq->ondemand_data); + if (IS_ERR(dmcfreq->devfreq)) { + dev_err(dev, "failed to add devfreq\n"); + return PTR_ERR(dmcfreq->devfreq); + } + + devm_devfreq_register_opp_notifier(dev, dmcfreq->devfreq); + + dmcfreq->min = devp->freq_table[0]; + dmcfreq->max = + devp->freq_table[devp->max_state ? devp->max_state - 1 : 0]; + dmcfreq->devfreq->min_freq = dmcfreq->min; + dmcfreq->devfreq->max_freq = dmcfreq->max; + dmcfreq->devfreq->last_status.current_frequency = opp_rate; + + reset_last_status(dmcfreq->devfreq); + + return 0; +} + +static void rockchip_dmcfreq_register_notifier(struct rockchip_dmcfreq *dmcfreq) +{ + int ret; + + if (vop_register_dmc()) + dev_err(dmcfreq->dev, "fail to register notify to vop.\n"); + + dmcfreq->status_nb.notifier_call = + rockchip_dmcfreq_system_status_notifier; + ret = rockchip_register_system_status_notifier(&dmcfreq->status_nb); + if (ret) + dev_err(dmcfreq->dev, "failed to register system_status nb\n"); + + dmcfreq->reboot_nb.notifier_call = rockchip_dmcfreq_reboot_notifier; + ret = register_reboot_notifier(&dmcfreq->reboot_nb); + if (ret) + dev_err(dmcfreq->dev, "failed to register reboot nb\n"); + + dmcfreq->fb_nb.notifier_call = rockchip_dmcfreq_fb_notifier; + ret = fb_register_client(&dmcfreq->fb_nb); + if (ret) + dev_err(dmcfreq->dev, "failed to register fb nb\n"); + + dmc_devdata.data = dmcfreq->devfreq; + dmcfreq->opp_info = rockchip_register_thermal_notifier(dmcfreq->dev, + &dmc_devdata); + if (IS_ERR(dmcfreq->opp_info)) { + dev_dbg(dmcfreq->dev, "without thermal notifier\n"); + dmcfreq->opp_info = NULL; + } +} + +static void rockchip_dmcfreq_add_interface(struct rockchip_dmcfreq *dmcfreq) +{ + if (sysfs_create_file(&dmcfreq->devfreq->dev.kobj, + &dev_attr_system_status.attr)) + dev_err(dmcfreq->dev, + "failed to register system_status sysfs file\n"); +} + +static void rockchip_dmcfreq_boost_work(struct work_struct *work) +{ + struct rockchip_dmcfreq *dmcfreq = boost_to_dmcfreq(work); rockchip_dmcfreq_update_target(dmcfreq); } @@ -2757,7 +3126,7 @@ static void rockchip_dmcfreq_input_event(struct input_handle *handle, return; dmcfreq->touchboostpulse_endtime = endtime; - schedule_work(&dmcfreq->devfreq_update); + schedule_work(&dmcfreq->boost_work); } static int rockchip_dmcfreq_input_connect(struct input_handler *handler, @@ -2823,6 +3192,20 @@ static const struct input_device_id rockchip_dmcfreq_input_ids[] = { { }, }; +static void rockchip_dmcfreq_boost_init(struct rockchip_dmcfreq *dmcfreq) +{ + if (!dmcfreq->boost_rate) + return; + INIT_WORK(&dmcfreq->boost_work, rockchip_dmcfreq_boost_work); + dmcfreq->input_handler.event = rockchip_dmcfreq_input_event; + dmcfreq->input_handler.connect = rockchip_dmcfreq_input_connect; + dmcfreq->input_handler.disconnect = rockchip_dmcfreq_input_disconnect; + dmcfreq->input_handler.name = "dmcfreq"; + dmcfreq->input_handler.id_table = rockchip_dmcfreq_input_ids; + if (input_register_handler(&dmcfreq->input_handler)) + dev_err(dmcfreq->dev, "failed to register input handler\n"); +} + static unsigned long model_static_power(struct devfreq *devfreq, unsigned long voltage) { @@ -2922,215 +3305,131 @@ static int ddr_power_model_simple_init(struct rockchip_dmcfreq *dmcfreq) return 0; } +static void +rockchip_dmcfreq_register_cooling_device(struct rockchip_dmcfreq *dmcfreq) +{ + int ret; + + ret = ddr_power_model_simple_init(dmcfreq); + if (ret) + return; + dmcfreq->devfreq_cooling = + of_devfreq_cooling_register_power(dmcfreq->dev->of_node, + dmcfreq->devfreq, + &ddr_cooling_power_data); + if (IS_ERR_OR_NULL(dmcfreq->devfreq_cooling)) { + ret = PTR_ERR(dmcfreq->devfreq_cooling); + dev_err(dmcfreq->dev, + "Failed to register cooling device (%d)\n", + ret); + } +} + static int rockchip_dmcfreq_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct device_node *events_np, *np = pdev->dev.of_node; struct rockchip_dmcfreq *data; - struct devfreq_dev_profile *devp = &rockchip_devfreq_dmc_profile; - struct dev_pm_opp *opp; - const struct of_device_id *match; - int (*init)(struct platform_device *pdev, - struct rockchip_dmcfreq *data); - unsigned long opp_rate, opp_volt; - bool is_events_available = false; int ret; data = devm_kzalloc(dev, sizeof(struct rockchip_dmcfreq), GFP_KERNEL); if (!data) return -ENOMEM; + data->dev = dev; mutex_init(&data->lock); INIT_LIST_HEAD(&data->video_info_list); - data->vdd_center = devm_regulator_get_optional(dev, "center"); - if (IS_ERR(data->vdd_center)) { - dev_err(dev, "Cannot get the regulator \"center\"\n"); - return PTR_ERR(data->vdd_center); - } - - data->dmc_clk = devm_clk_get(dev, "dmc_clk"); - if (IS_ERR(data->dmc_clk)) { - dev_err(dev, "Cannot get the clk dmc_clk\n"); - return PTR_ERR(data->dmc_clk); - } - - events_np = of_parse_phandle(np, "devfreq-events", 0); - if (events_np && of_device_is_available(events_np)) { - of_node_put(events_np); - data->edev = devfreq_event_get_edev_by_phandle(dev, 0); - if (IS_ERR(data->edev)) - return -EPROBE_DEFER; + ret = rockchip_dmcfreq_get_event(data); + if (ret) + return ret; - ret = devfreq_event_enable_edev(data->edev); - if (ret < 0) { - dev_err(dev, "failed to enable devfreq-event devices\n"); - return ret; - } - is_events_available = true; - } + ret = rockchip_dmcfreq_power_control(data); + if (ret) + return ret; - match = of_match_node(rockchip_dmcfreq_of_match, pdev->dev.of_node); - if (match) { - init = match->data; - if (init) { - ret = init(pdev, data); - if (ret) - return ret; - } - } + ret = rockchip_dmcfreq_dmc_init(pdev, data); + if (ret) + return ret; - /* - * We add a devfreq driver to our parent since it has a device tree node - * with operating points. - */ ret = rockchip_init_opp_table(dev, NULL, "ddr_leakage", "center"); - if (ret) { - dev_err(dev, "Failed to init_opp_table (%d)\n", ret); + if (ret) return ret; - } - - if (rockchip_dmcfreq_init_freq_table(dev, devp)) - return -EFAULT; - - data->rate = clk_get_rate(data->dmc_clk); - devp->initial_freq = data->rate; - opp_rate = data->rate; - - rcu_read_lock(); - opp = devfreq_recommended_opp(dev, &opp_rate, 0); - if (IS_ERR(opp)) { - rcu_read_unlock(); - return PTR_ERR(opp); - } - opp_volt = dev_pm_opp_get_voltage(opp); - rcu_read_unlock(); - of_property_read_u32(np, "auto-freq-en", &data->auto_freq_en); - if (!is_events_available && data->auto_freq_en) { - dev_warn(dev, "events isn't available, close auto freq\n"); - data->auto_freq_en = 0; + rockchip_dmcfreq_parse_dt(data); + if (!data->system_status_en && !data->auto_freq_en) { + dev_info(dev, "don't add devfreq feature\n"); + return rockchip_dmcfreq_set_volt_only(data); } - ret = rockchip_get_system_status_rate(np, "system-status-freq", data); - if (ret) { - dev_err(dev, "failed to get system status rate\n"); - if (ret == -ENODEV && !data->auto_freq_en) { - dev_info(dev, "don't add devfreq feature\n"); - if (data->edev) - devfreq_event_disable_edev(data->edev); - ret = regulator_set_voltage(data->vdd_center, opp_volt, - INT_MAX); - if (ret) { - dev_err(dev, "Cannot set voltage %lu uV\n", - opp_volt); - return ret; - } - return 0; - } - } - - of_property_read_u32(np, "upthreshold", - &data->ondemand_data.upthreshold); - of_property_read_u32(np, "downdifferential", - &data->ondemand_data.downdifferential); - of_property_read_u32(np, "min-cpu-freq", &data->min_cpu_freq); - of_property_read_u32(np, "auto-min-freq", (u32 *)&data->auto_min_rate); - data->auto_min_rate *= 1000; - if (rockchip_get_freq_map_talbe(np, "vop-bw-dmc-freq", - &data->vop_bw_tbl)) - dev_err(dev, "failed to get vop bandwidth to dmc rate\n"); - of_property_read_u32(np, "touchboost_duration", - (u32 *)&data->touchboostpulse_duration_val); - if (data->touchboostpulse_duration_val) - data->touchboostpulse_duration_val *= USEC_PER_MSEC; - else - data->touchboostpulse_duration_val = 500 * USEC_PER_MSEC; pm_qos_add_request(&pm_qos, PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE); + platform_set_drvdata(pdev, data); ret = devfreq_add_governor(&devfreq_dmc_ondemand); + if (ret) + return ret; + ret = rockchip_dmcfreq_enable_event(data); + if (ret) + return ret; + ret = rockchip_dmcfreq_add_devfreq(data); if (ret) { - dev_err(dev, "Failed to add rockchip governor: %d\n", ret); + rockchip_dmcfreq_disable_event(data); return ret; } - data->dev = dev; - platform_set_drvdata(pdev, data); + rockchip_dmcfreq_register_notifier(data); + rockchip_dmcfreq_add_interface(data); + rockchip_dmcfreq_boost_init(data); + rockchip_dmcfreq_register_cooling_device(data); - data->devfreq = devm_devfreq_add_device(dev, devp, - "dmc_ondemand", - &data->ondemand_data); - if (IS_ERR(data->devfreq)) - return PTR_ERR(data->devfreq); + rockchip_set_system_status(SYS_STATUS_NORMAL); - devm_devfreq_register_opp_notifier(dev, data->devfreq); + return 0; +} - data->min = devp->freq_table[0]; - data->max = devp->freq_table[devp->max_state ? devp->max_state - 1 : 0]; - data->devfreq->min_freq = data->min; - data->devfreq->max_freq = data->max; - data->devfreq->last_status.current_frequency = opp_rate; - reset_last_status(data->devfreq); +static __maybe_unused int rockchip_dmcfreq_suspend(struct device *dev) +{ + struct rockchip_dmcfreq *dmcfreq = dev_get_drvdata(dev); + int ret = 0; - if (vop_register_dmc()) - dev_err(dev, "fail to register notify to vop.\n"); + if (!dmcfreq) + return 0; - data->system_status_nb.notifier_call = - rockchip_dmcfreq_system_status_notifier; - ret = rockchip_register_system_status_notifier(&data->system_status_nb); + ret = rockchip_dmcfreq_disable_event(dmcfreq); if (ret) - dev_err(dev, "failed to register system_status nb\n"); + return ret; - data->reboot_nb.notifier_call = rockchip_dmcfreq_reboot_notifier; - ret = register_reboot_notifier(&data->reboot_nb); - if (ret) - dev_err(dev, "failed to register reboot nb\n"); + ret = devfreq_suspend_device(dmcfreq->devfreq); + if (ret < 0) { + dev_err(dev, "failed to suspend the devfreq devices\n"); + return ret; + } - data->fb_nb.notifier_call = rockchip_dmcfreq_fb_notifier; - ret = fb_register_client(&data->fb_nb); - if (ret) - dev_err(dev, "failed to register fb nb\n"); + return 0; +} - ret = sysfs_create_file(&data->devfreq->dev.kobj, - &dev_attr_system_status.attr); - if (ret) - dev_err(dev, "failed to register system_status sysfs file\n"); +static __maybe_unused int rockchip_dmcfreq_resume(struct device *dev) +{ + struct rockchip_dmcfreq *dmcfreq = dev_get_drvdata(dev); + int ret = 0; - if (data->boost_rate) { - INIT_WORK(&data->devfreq_update, - rockchip_dmcfreq_devfreq_update); - data->input_handler.event = rockchip_dmcfreq_input_event; - data->input_handler.connect = rockchip_dmcfreq_input_connect; - data->input_handler.disconnect = - rockchip_dmcfreq_input_disconnect; - data->input_handler.name = "dmcfreq"; - data->input_handler.id_table = rockchip_dmcfreq_input_ids; - ret = input_register_handler(&data->input_handler); - if (ret) - dev_err(dev, "failed to register input handler\n"); - } + if (!dmcfreq) + return 0; - ret = ddr_power_model_simple_init(data); + ret = rockchip_dmcfreq_enable_event(dmcfreq); + if (ret) + return ret; - if (!ret) { - data->devfreq_cooling = - of_devfreq_cooling_register_power(data->dev->of_node, - data->devfreq, - &ddr_cooling_power_data); - if (IS_ERR_OR_NULL(data->devfreq_cooling)) { - ret = PTR_ERR(data->devfreq_cooling); - dev_err(data->dev, - "Failed to register cooling device (%d)\n", - ret); - } + ret = devfreq_resume_device(dmcfreq->devfreq); + if (ret < 0) { + dev_err(dev, "failed to resume the devfreq devices\n"); + return ret; } - - rockchip_set_system_status(SYS_STATUS_NORMAL); - - return 0; + return ret; } +static SIMPLE_DEV_PM_OPS(rockchip_dmcfreq_pm, rockchip_dmcfreq_suspend, + rockchip_dmcfreq_resume); static struct platform_driver rockchip_dmcfreq_driver = { .probe = rockchip_dmcfreq_probe, .driver = { diff --git a/drivers/dma/k3dma.c b/drivers/dma/k3dma.c index 1ba2fd73852d2..0f0c06ab414b2 100644 --- a/drivers/dma/k3dma.c +++ b/drivers/dma/k3dma.c @@ -660,7 +660,7 @@ static struct dma_chan *k3_of_dma_simple_xlate(struct of_phandle_args *dma_spec, struct k3_dma_dev *d = ofdma->of_dma_data; unsigned int request = dma_spec->args[0]; - if (request > d->dma_requests) + if (request >= d->dma_requests) return NULL; return dma_get_slave_channel(&(d->chans[request].vc.chan)); diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 6fe0b1a15671f..b14f5c2254011 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -1031,6 +1031,7 @@ static void _stop(struct pl330_thread *thrd) { void __iomem *regs = thrd->dmac->base; u8 insn[6] = {0, 0, 0, 0, 0, 0}; + u32 inten = readl(regs + INTEN); if (_state(thrd) == PL330_STATE_FAULT_COMPLETING) UNTIL(thrd, PL330_STATE_FAULTING | PL330_STATE_KILLING); @@ -1043,10 +1044,13 @@ static void _stop(struct pl330_thread *thrd) _emit_KILL(0, insn); - /* Stop generating interrupts for SEV */ - writel(readl(regs + INTEN) & ~(1 << thrd->ev), regs + INTEN); - _execute_DBGINSN(thrd, insn, is_manager(thrd)); + + /* clear the event */ + if (inten & (1 << thrd->ev)) + writel(1 << thrd->ev, regs + INTCLR); + /* Stop generating interrupts for SEV */ + writel(inten & ~(1 << thrd->ev), regs + INTEN); } /* Start doing req 'idx' of thread 'thrd' */ @@ -1337,19 +1341,14 @@ static inline int _loop(struct pl330_dmac *pl330, unsigned dry_run, u8 buf[], return off; } -/* Returns bytes consumed */ -static inline int _loop_cyclic(struct pl330_dmac *pl330, unsigned dry_run, - u8 buf[], unsigned long bursts, const struct _xfer_spec *pxs, int ev) +static int _period(struct pl330_dmac *pl330, unsigned int dry_run, u8 buf[], + unsigned long bursts, const struct _xfer_spec *pxs, int ev) { - int cyc, off; - unsigned lcnt0, lcnt1, ljmp0, ljmp1, ljmpfe; + unsigned int lcnt1, ljmp1; + int cyc, off = 0; struct _arg_LPEND lpend; struct pl330_xfer *x = &pxs->desc->px; - off = 0; - ljmpfe = off; - lcnt0 = pxs->desc->num_periods; - if (bursts > 256) { lcnt1 = 256; cyc = bursts / 256; @@ -1358,18 +1357,6 @@ static inline int _loop_cyclic(struct pl330_dmac *pl330, unsigned dry_run, cyc = 1; } - /* forever loop */ - off += _emit_MOV(dry_run, &buf[off], SAR, x->src_addr); - off += _emit_MOV(dry_run, &buf[off], DAR, x->dst_addr); -#ifdef CONFIG_ARCH_ROCKCHIP - if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP)) - off += _emit_FLUSHP(dry_run, &buf[off], - pxs->desc->peri); -#endif - /* loop0 */ - off += _emit_LP(dry_run, &buf[off], 0, lcnt0); - ljmp0 = off; - /* loop1 */ off += _emit_LP(dry_run, &buf[off], 1, lcnt1); ljmp1 = off; @@ -1420,12 +1407,54 @@ static inline int _loop_cyclic(struct pl330_dmac *pl330, unsigned dry_run, off += _emit_SEV(dry_run, &buf[off], ev); + return off; +} + +/* Returns bytes consumed */ +static inline int _loop_cyclic(struct pl330_dmac *pl330, unsigned int dry_run, + u8 buf[], unsigned long bursts, const struct _xfer_spec *pxs, int ev) +{ + int off, periods, residue, i; + unsigned int lcnt0, ljmp0, ljmpfe; + struct _arg_LPEND lpend; + struct pl330_xfer *x = &pxs->desc->px; + + off = 0; + ljmpfe = off; + lcnt0 = pxs->desc->num_periods; + periods = 1; + + while (lcnt0 > 256) { + periods++; + lcnt0 = pxs->desc->num_periods / periods; + } + + residue = pxs->desc->num_periods % periods; + + /* forever loop */ + off += _emit_MOV(dry_run, &buf[off], SAR, x->src_addr); + off += _emit_MOV(dry_run, &buf[off], DAR, x->dst_addr); +#ifdef CONFIG_ARCH_ROCKCHIP + if (!(pl330->quirks & PL330_QUIRK_BROKEN_NO_FLUSHP)) + off += _emit_FLUSHP(dry_run, &buf[off], + pxs->desc->peri); +#endif + /* loop0 */ + off += _emit_LP(dry_run, &buf[off], 0, lcnt0); + ljmp0 = off; + + for (i = 0; i < periods; i++) + off += _period(pl330, dry_run, &buf[off], bursts, pxs, ev); + lpend.cond = ALWAYS; lpend.forever = false; lpend.loop = 0; lpend.bjump = off - ljmp0; off += _emit_LPEND(dry_run, &buf[off], &lpend); + for (i = 0; i < residue; i++) + off += _period(pl330, dry_run, &buf[off], bursts, pxs, ev); + lpend.cond = ALWAYS; lpend.forever = true; lpend.loop = 1; @@ -1448,6 +1477,12 @@ static inline int _setup_loops(struct pl330_dmac *pl330, off += _emit_FLUSHP(dry_run, &buf[off], pxs->desc->peri); #endif + if (pxs->desc->rqtype == DMA_DEV_TO_MEM) + bursts = x->bytes / (BRST_SIZE(ccr) * BRST_LEN(ccr) + + pxs->desc->dst_interlace_size); + else if (pxs->desc->rqtype == DMA_MEM_TO_DEV) + bursts = x->bytes / (BRST_SIZE(ccr) * BRST_LEN(ccr) + + pxs->desc->src_interlace_size); while (bursts) { c = bursts; off += _loop(pl330, dry_run, &buf[off], &c, pxs); @@ -1472,7 +1507,9 @@ static inline int _setup_xfer(struct pl330_dmac *pl330, /* Setup Loop(s) */ off += _setup_loops(pl330, dry_run, &buf[off], pxs); - if (pl330->peripherals_req_type == BURST) { + if (pxs->desc->src_interlace_size == 0 && + pxs->desc->dst_interlace_size == 0 && + pl330->peripherals_req_type == BURST) { unsigned int ccr = pxs->ccr; unsigned long c = 0; @@ -1742,7 +1779,7 @@ static void pl330_dotask(unsigned long data) /* Returns 1 if state was updated, 0 otherwise */ static int pl330_update(struct pl330_dmac *pl330) { - struct dma_pl330_desc *descdone, *tmp; + struct dma_pl330_desc *descdone; unsigned long flags; void __iomem *regs; u32 val; @@ -1822,7 +1859,9 @@ static int pl330_update(struct pl330_dmac *pl330) } /* Now that we are in no hurry, do the callbacks */ - list_for_each_entry_safe(descdone, tmp, &pl330->req_done, rqd) { + while (!list_empty(&pl330->req_done)) { + descdone = list_first_entry(&pl330->req_done, + struct dma_pl330_desc, rqd); list_del(&descdone->rqd); spin_unlock_irqrestore(&pl330->lock, flags); dma_pl330_rqcb(descdone, PL330_ERR_NONE); diff --git a/drivers/dma/pxa_dma.c b/drivers/dma/pxa_dma.c index 55f5d33f6dc70..4251e9ac0373c 100644 --- a/drivers/dma/pxa_dma.c +++ b/drivers/dma/pxa_dma.c @@ -1321,7 +1321,7 @@ static int pxad_init_phys(struct platform_device *op, return 0; } -static const struct of_device_id const pxad_dt_ids[] = { +static const struct of_device_id pxad_dt_ids[] = { { .compatible = "marvell,pdma-1.0", }, {} }; diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c index 7820d07e7beea..2b36d1c63aa5f 100644 --- a/drivers/dma/sh/rcar-dmac.c +++ b/drivers/dma/sh/rcar-dmac.c @@ -851,7 +851,7 @@ rcar_dmac_chan_prep_sg(struct rcar_dmac_chan *chan, struct scatterlist *sgl, rcar_dmac_chan_configure_desc(chan, desc); - max_chunk_size = (RCAR_DMATCR_MASK + 1) << desc->xfer_shift; + max_chunk_size = RCAR_DMATCR_MASK << desc->xfer_shift; /* * Allocate and fill the transfer chunk descriptors. We own the only diff --git a/drivers/dma/sh/usb-dmac.c b/drivers/dma/sh/usb-dmac.c index 56410ea75ac50..6682b3eec2b66 100644 --- a/drivers/dma/sh/usb-dmac.c +++ b/drivers/dma/sh/usb-dmac.c @@ -448,7 +448,7 @@ usb_dmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, static int usb_dmac_chan_terminate_all(struct dma_chan *chan) { struct usb_dmac_chan *uchan = to_usb_dmac_chan(chan); - struct usb_dmac_desc *desc; + struct usb_dmac_desc *desc, *_desc; unsigned long flags; LIST_HEAD(head); LIST_HEAD(list); @@ -459,7 +459,7 @@ static int usb_dmac_chan_terminate_all(struct dma_chan *chan) if (uchan->desc) uchan->desc = NULL; list_splice_init(&uchan->desc_got, &list); - list_for_each_entry(desc, &list, node) + list_for_each_entry_safe(desc, _desc, &list, node) list_move_tail(&desc->node, &uchan->desc_freed); spin_unlock_irqrestore(&uchan->vc.lock, flags); vchan_dma_desc_free_list(&uchan->vc, &head); diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index c2f5117fd8cb0..5545a7f3a98f3 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -1130,7 +1130,13 @@ static int context_add_buffer(struct context *ctx) return -ENOMEM; offset = (void *)&desc->buffer - (void *)desc; - desc->buffer_size = PAGE_SIZE - offset; + /* + * Some controllers, like JMicron ones, always issue 0x20-byte DMA reads + * for descriptors, even 0x10-byte ones. This can cause page faults when + * an IOMMU is in use and the oversized read crosses a page boundary. + * Work around this by always leaving at least 0x10 bytes of padding. + */ + desc->buffer_size = PAGE_SIZE - offset - 0x10; desc->buffer_bus = bus_addr + offset; desc->used = 0; diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index 0e08e665f715f..053a23a7be940 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c @@ -18,7 +18,7 @@ EXPORT_SYMBOL_GPL(dmi_kobj); * of and an antecedent to, SMBIOS, which stands for System * Management BIOS. See further: http://www.dmtf.org/standards */ -static const char dmi_empty_string[] = " "; +static const char dmi_empty_string[] = ""; static u32 dmi_ver __initdata; static u32 dmi_len; @@ -44,25 +44,21 @@ static int dmi_memdev_nr; static const char * __init dmi_string_nosave(const struct dmi_header *dm, u8 s) { const u8 *bp = ((u8 *) dm) + dm->length; + const u8 *nsp; if (s) { - s--; - while (s > 0 && *bp) { + while (--s > 0 && *bp) bp += strlen(bp) + 1; - s--; - } - - if (*bp != 0) { - size_t len = strlen(bp)+1; - size_t cmp_len = len > 8 ? 8 : len; - if (!memcmp(bp, dmi_empty_string, cmp_len)) - return dmi_empty_string; + /* Strings containing only spaces are considered empty */ + nsp = bp; + while (*nsp == ' ') + nsp++; + if (*nsp != '\0') return bp; - } } - return ""; + return dmi_empty_string; } static const char * __init dmi_string(const struct dmi_header *dm, u8 s) diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c index 3cbb25ecfc7a1..32fceda236c9b 100644 --- a/drivers/gpio/gpio-rcar.c +++ b/drivers/gpio/gpio-rcar.c @@ -200,6 +200,48 @@ static int gpio_rcar_irq_set_wake(struct irq_data *d, unsigned int on) return 0; } +static void gpio_rcar_irq_bus_lock(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct gpio_rcar_priv *p = container_of(gc, struct gpio_rcar_priv, + gpio_chip); + + pm_runtime_get_sync(&p->pdev->dev); +} + +static void gpio_rcar_irq_bus_sync_unlock(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct gpio_rcar_priv *p = container_of(gc, struct gpio_rcar_priv, + gpio_chip); + + pm_runtime_put(&p->pdev->dev); +} + + +static int gpio_rcar_irq_request_resources(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct gpio_rcar_priv *p = container_of(gc, struct gpio_rcar_priv, + gpio_chip); + int error; + + error = pm_runtime_get_sync(&p->pdev->dev); + if (error < 0) + return error; + + return 0; +} + +static void gpio_rcar_irq_release_resources(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct gpio_rcar_priv *p = container_of(gc, struct gpio_rcar_priv, + gpio_chip); + + pm_runtime_put(&p->pdev->dev); +} + static irqreturn_t gpio_rcar_irq_handler(int irq, void *dev_id) { struct gpio_rcar_priv *p = dev_id; @@ -460,6 +502,10 @@ static int gpio_rcar_probe(struct platform_device *pdev) irq_chip->irq_unmask = gpio_rcar_irq_enable; irq_chip->irq_set_type = gpio_rcar_irq_set_type; irq_chip->irq_set_wake = gpio_rcar_irq_set_wake; + irq_chip->irq_bus_lock = gpio_rcar_irq_bus_lock; + irq_chip->irq_bus_sync_unlock = gpio_rcar_irq_bus_sync_unlock; + irq_chip->irq_request_resources = gpio_rcar_irq_request_resources; + irq_chip->irq_release_resources = gpio_rcar_irq_release_resources; irq_chip->flags = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_MASK_ON_SUSPEND; ret = gpiochip_add(gpio_chip); diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 745c51a1b6cbf..72048189b4e72 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -2200,6 +2200,8 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev, struct gpio_desc *desc = NULL; int status; enum gpio_lookup_flags lookupflags = 0; + /* Maybe we have a device name, maybe not */ + const char *devname = dev ? dev_name(dev) : "?"; dev_dbg(dev, "GPIO lookup for consumer %s\n", con_id); @@ -2228,8 +2230,11 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev, return desc; } - /* If a connection label was passed use that, else use the device name as label */ - status = gpiod_request(desc, con_id ? con_id : dev_name(dev)); + /* + * If a connection label was passed use that, else attempt to use + * the device name as label + */ + status = gpiod_request(desc, con_id ? con_id : devname); if (status < 0) return ERR_PTR(status); diff --git a/drivers/gpu/arm/bifrost/backend/gpu/mali_kbase_devfreq.c b/drivers/gpu/arm/bifrost/backend/gpu/mali_kbase_devfreq.c index 0ea045c23f3ed..ce6f8d7fb4e00 100644 --- a/drivers/gpu/arm/bifrost/backend/gpu/mali_kbase_devfreq.c +++ b/drivers/gpu/arm/bifrost/backend/gpu/mali_kbase_devfreq.c @@ -47,6 +47,13 @@ #define dev_pm_opp_find_freq_ceil opp_find_freq_ceil #define dev_pm_opp_find_freq_floor opp_find_freq_floor #endif /* Linux >= 3.13 */ +#include + +static struct thermal_opp_device_data gpu_devdata = { + .type = THERMAL_OPP_TPYE_DEV, + .low_temp_adjust = rockchip_dev_low_temp_adjust, + .high_temp_adjust = rockchip_dev_high_temp_adjust, +}; /** * opp_translate - Translate nominal OPP frequency from devicetree into real @@ -396,6 +403,13 @@ int kbase_devfreq_init(struct kbase_device *kbdev) devfreq_recommended_opp(kbdev->dev, &opp_rate, 0); rcu_read_unlock(); kbdev->devfreq->last_status.current_frequency = opp_rate; + gpu_devdata.data = kbdev->devfreq; + kbdev->opp_info = rockchip_register_thermal_notifier(kbdev->dev, + &gpu_devdata); + if (IS_ERR(kbdev->opp_info)) { + dev_dbg(kbdev->dev, "without thermal notifier\n"); + kbdev->opp_info = NULL; + } #ifdef CONFIG_DEVFREQ_THERMAL err = kbase_ipa_init(kbdev); if (err) { @@ -437,6 +451,7 @@ void kbase_devfreq_term(struct kbase_device *kbdev) dev_dbg(kbdev->dev, "Term Mali devfreq\n"); + rockchip_unregister_thermal_notifier(kbdev->opp_info); #ifdef CONFIG_DEVFREQ_THERMAL if (kbdev->devfreq_cooling) devfreq_cooling_unregister(kbdev->devfreq_cooling); diff --git a/drivers/gpu/arm/bifrost/ipa/Kbuild b/drivers/gpu/arm/bifrost/ipa/Kbuild index 32008511f3662..1df2e9de9d5a4 100644 --- a/drivers/gpu/arm/bifrost/ipa/Kbuild +++ b/drivers/gpu/arm/bifrost/ipa/Kbuild @@ -25,7 +25,7 @@ bifrost_kbase-y += \ bifrost_kbase-$(CONFIG_DEBUG_FS) += ipa/mali_kbase_ipa_debugfs.o -ifneq ($(wildcard $(src)/ipa/mali_kbase_ipa_vinstr_common.c),) +ifneq ($(wildcard $(srctree)/$(src)/ipa/mali_kbase_ipa_vinstr_common.c),) bifrost_kbase-y += \ ipa/mali_kbase_ipa_vinstr_g7x.o \ ipa/mali_kbase_ipa_vinstr_common.o diff --git a/drivers/gpu/arm/bifrost/mali_kbase_defs.h b/drivers/gpu/arm/bifrost/mali_kbase_defs.h index 908293236ec4e..a79d01dca13b7 100644 --- a/drivers/gpu/arm/bifrost/mali_kbase_defs.h +++ b/drivers/gpu/arm/bifrost/mali_kbase_defs.h @@ -1536,6 +1536,7 @@ struct kbase_device { struct kbase_devfreq_opp *opp_table; int num_opps; struct kbasep_pm_metrics last_devfreq_metrics; + struct thermal_opp_info *opp_info; #ifdef CONFIG_DEVFREQ_THERMAL #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) struct devfreq_cooling_device *devfreq_cooling; diff --git a/drivers/gpu/arm/bifrost_for_linux/backend/gpu/mali_kbase_devfreq.c b/drivers/gpu/arm/bifrost_for_linux/backend/gpu/mali_kbase_devfreq.c index 9e7f1276048a5..a69008437fa1d 100644 --- a/drivers/gpu/arm/bifrost_for_linux/backend/gpu/mali_kbase_devfreq.c +++ b/drivers/gpu/arm/bifrost_for_linux/backend/gpu/mali_kbase_devfreq.c @@ -43,6 +43,14 @@ #define dev_pm_opp_find_freq_floor opp_find_freq_floor #endif /* Linux >= 3.13 */ +#include + +static struct thermal_opp_device_data gpu_devdata = { + .type = THERMAL_OPP_TPYE_DEV, + .low_temp_adjust = rockchip_dev_low_temp_adjust, + .high_temp_adjust = rockchip_dev_high_temp_adjust, +}; + /** * opp_translate - Translate nominal OPP frequency from devicetree into real * frequency and core mask @@ -369,6 +377,13 @@ int kbase_devfreq_init(struct kbase_device *kbdev) devfreq_recommended_opp(kbdev->dev, &opp_rate, 0); rcu_read_unlock(); kbdev->devfreq->last_status.current_frequency = opp_rate; + gpu_devdata.data = kbdev->devfreq; + kbdev->opp_info = rockchip_register_thermal_notifier(kbdev->dev, + &gpu_devdata); + if (IS_ERR(kbdev->opp_info)) { + dev_dbg(kbdev->dev, "without thermal notifier\n"); + kbdev->opp_info = NULL; + } #ifdef CONFIG_DEVFREQ_THERMAL err = kbase_ipa_init(kbdev); if (err) { @@ -410,6 +425,7 @@ void kbase_devfreq_term(struct kbase_device *kbdev) dev_dbg(kbdev->dev, "Term Mali devfreq\n"); + rockchip_unregister_thermal_notifier(kbdev->opp_info); #ifdef CONFIG_DEVFREQ_THERMAL if (kbdev->devfreq_cooling) devfreq_cooling_unregister(kbdev->devfreq_cooling); diff --git a/drivers/gpu/arm/bifrost_for_linux/ipa/Kbuild b/drivers/gpu/arm/bifrost_for_linux/ipa/Kbuild index 831fa83c6a8ee..0776428fce4fa 100644 --- a/drivers/gpu/arm/bifrost_for_linux/ipa/Kbuild +++ b/drivers/gpu/arm/bifrost_for_linux/ipa/Kbuild @@ -19,7 +19,7 @@ bifrost_kbase-y += \ bifrost_kbase-$(CONFIG_DEBUG_FS) += ipa/mali_kbase_ipa_debugfs.o -ifneq ($(wildcard $(src)/ipa/mali_kbase_ipa_vinstr_g71.c),) +ifneq ($(wildcard $(srctree)/$(src)/ipa/mali_kbase_ipa_vinstr_g71.c),) bifrost_kbase-y += \ ipa/mali_kbase_ipa_vinstr_g71.o \ ipa/mali_kbase_ipa_vinstr_common.o diff --git a/drivers/gpu/arm/bifrost_for_linux/mali_kbase_defs.h b/drivers/gpu/arm/bifrost_for_linux/mali_kbase_defs.h index d957c1461440b..14b596c07fe76 100644 --- a/drivers/gpu/arm/bifrost_for_linux/mali_kbase_defs.h +++ b/drivers/gpu/arm/bifrost_for_linux/mali_kbase_defs.h @@ -1126,6 +1126,7 @@ struct kbase_device { u64 current_core_mask; struct kbase_devfreq_opp *opp_table; int num_opps; + struct thermal_opp_info *opp_info; #ifdef CONFIG_DEVFREQ_THERMAL #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) struct devfreq_cooling_device *devfreq_cooling; diff --git a/drivers/gpu/arm/bifrost_for_linux/platform/rk/mali_kbase_config_rk.c b/drivers/gpu/arm/bifrost_for_linux/platform/rk/mali_kbase_config_rk.c index 324cf75df6a26..b10b8a9ade355 100755 --- a/drivers/gpu/arm/bifrost_for_linux/platform/rk/mali_kbase_config_rk.c +++ b/drivers/gpu/arm/bifrost_for_linux/platform/rk/mali_kbase_config_rk.c @@ -451,272 +451,3 @@ static void kbase_platform_rk_remove_sysfs_files(struct device *dev) device_remove_file(dev, &dev_attr_utilisation); } -static int rockchip_get_efuse_value(struct device_node *np, char *porp_name, - int *value) -{ - struct nvmem_cell *cell; - unsigned char *buf; - size_t len; - - cell = of_nvmem_cell_get(np, porp_name); - if (IS_ERR(cell)) - return PTR_ERR(cell); - - buf = (unsigned char *)nvmem_cell_read(cell, &len); - - nvmem_cell_put(cell); - - if (IS_ERR(buf)) - return PTR_ERR(buf); - - if (buf[0] == LEAKAGE_INVALID) - return -EINVAL; - - *value = buf[0]; - - kfree(buf); - - return 0; -} - -static int rockchip_get_volt_sel_table(struct device_node *np, char *porp_name, - struct volt_sel_table **table) -{ - struct volt_sel_table *sel_table; - const struct property *prop; - int count, i; - - prop = of_find_property(np, porp_name, NULL); - if (!prop) - return -EINVAL; - - if (!prop->value) - return -ENODATA; - - count = of_property_count_u32_elems(np, porp_name); - if (count < 0) - return -EINVAL; - - if (count % 3) - return -EINVAL; - - sel_table = kzalloc(sizeof(*sel_table) * (count / 3 + 1), GFP_KERNEL); - if (!sel_table) - return -ENOMEM; - - for (i = 0; i < count / 3; i++) { - of_property_read_u32_index(np, porp_name, 3 * i, - &sel_table[i].min); - of_property_read_u32_index(np, porp_name, 3 * i + 1, - &sel_table[i].max); - of_property_read_u32_index(np, porp_name, 3 * i + 2, - &sel_table[i].sel); - } - sel_table[i].min = 0; - sel_table[i].max = 0; - sel_table[i].sel = LEAKAGE_TABLE_END; - - *table = sel_table; - - return 0; -} - -static int rockchip_get_volt_sel(struct device_node *np, char *name, - int value, int *sel) -{ - struct volt_sel_table *table; - int i, j = -1, ret; - - ret = rockchip_get_volt_sel_table(np, name, &table); - if (ret) - return -EINVAL; - - for (i = 0; table[i].sel != LEAKAGE_TABLE_END; i++) { - if (value >= table[i].min) - j = i; - } - if (j != -1) - *sel = table[j].sel; - else - ret = -EINVAL; - - kfree(table); - - return ret; -} - -static int rockchip_parse_pvtm_config(struct device_node *np, - struct pvtm_config *pvtm) -{ - if (!of_find_property(np, "rockchip,pvtm-voltage-sel", NULL)) - return -EINVAL; - if (of_property_read_u32(np, "rockchip,pvtm-freq", &pvtm->freq)) - return -EINVAL; - if (of_property_read_u32(np, "rockchip,pvtm-volt", &pvtm->volt)) - return -EINVAL; - if (of_property_read_u32_array(np, "rockchip,pvtm-ch", pvtm->ch, 2)) - return -EINVAL; - if (of_property_read_u32(np, "rockchip,pvtm-sample-time", - &pvtm->sample_time)) - return -EINVAL; - if (of_property_read_u32(np, "rockchip,pvtm-number", &pvtm->num)) - return -EINVAL; - if (of_property_read_u32(np, "rockchip,pvtm-error", &pvtm->err)) - return -EINVAL; - if (of_property_read_u32(np, "rockchip,pvtm-ref-temp", &pvtm->ref_temp)) - return -EINVAL; - if (of_property_read_u32_array(np, "rockchip,pvtm-temp-prop", - pvtm->temp_prop, 2)) - return -EINVAL; - if (of_property_read_string(np, "rockchip,pvtm-thermal-zone", - &pvtm->tz_name)) - return -EINVAL; - pvtm->tz = thermal_zone_get_zone_by_name(pvtm->tz_name); - if (IS_ERR(pvtm->tz)) - return -EINVAL; - if (!pvtm->tz->ops->get_temp) - return -EINVAL; - - return 0; -} - -static int rockchip_get_pvtm_specific_value(struct device *dev, - struct device_node *np, - struct clk *clk, - struct regulator *reg, - int *target_value) -{ - struct pvtm_config *pvtm; - unsigned long old_freq; - unsigned int old_volt; - int cur_temp, diff_temp; - int cur_value, total_value, avg_value, diff_value; - int min_value, max_value; - int ret = 0, i = 0, retry = 2; - - pvtm = kzalloc(sizeof(*pvtm), GFP_KERNEL); - if (!pvtm) - return -ENOMEM; - - ret = rockchip_parse_pvtm_config(np, pvtm); - if (ret) - goto pvtm_value_out; - - old_freq = clk_get_rate(clk); - old_volt = regulator_get_voltage(reg); - - /* - * Set pvtm_freq to the lowest frequency in dts, - * so change frequency first. - */ - ret = clk_set_rate(clk, pvtm->freq * 1000); - if (ret) { - dev_err(dev, "Failed to set pvtm freq\n"); - goto pvtm_value_out; - } - - ret = regulator_set_voltage(reg, pvtm->volt, pvtm->volt); - if (ret) { - dev_err(dev, "Failed to set pvtm_volt\n"); - goto restore_clk; - } - - /* The first few values may be fluctuant, if error is too big, retry*/ - while (retry--) { - total_value = 0; - min_value = INT_MAX; - max_value = 0; - - for (i = 0; i < pvtm->num; i++) { - cur_value = rockchip_get_pvtm_value(pvtm->ch[0], - pvtm->ch[1], - pvtm->sample_time); - if (!cur_value) - goto resetore_volt; - if (cur_value < min_value) - min_value = cur_value; - if (cur_value > max_value) - max_value = cur_value; - total_value += cur_value; - } - if (max_value - min_value < pvtm->err) - break; - } - avg_value = total_value / pvtm->num; - - /* - * As pvtm is influenced by temperature, compute difference between - * current temperature and reference temperature - */ - pvtm->tz->ops->get_temp(pvtm->tz, &cur_temp); - diff_temp = (cur_temp / 1000 - pvtm->ref_temp); - diff_value = diff_temp * - (diff_temp < 0 ? pvtm->temp_prop[0] : pvtm->temp_prop[1]); - *target_value = avg_value + diff_value; - - dev_info(dev, "temp=%d, pvtm=%d (%d + %d)\n", - cur_temp, *target_value, avg_value, diff_value); - -resetore_volt: - regulator_set_voltage(reg, old_volt, old_volt); -restore_clk: - clk_set_rate(clk, old_freq); -pvtm_value_out: - kfree(pvtm); - - return ret; -} - -void kbase_platform_rk_set_opp_info(struct kbase_device *kbdev) -{ - struct device_node *np; - char name[MAX_PROP_NAME_LEN]; - int pvmt_value, leakage; - int lkg_volt_sel, pvtm_volt_sel, volt_sel = -1; - int err = 0; - - if (!kbdev) - return; - - if (IS_ERR_OR_NULL(kbdev->regulator)) - return; - if (IS_ERR_OR_NULL(kbdev->clock)) - return; - - np = of_parse_phandle(kbdev->dev->of_node, "operating-points-v2", 0); - if (!np) { - dev_warn(kbdev->dev, "OPP-v2 not supported\n"); - return; - } - - err = rockchip_get_efuse_value(np, "gpu_leakage", &leakage); - if (!err) { - dev_info(kbdev->dev, "leakage=%d\n", leakage); - err = rockchip_get_volt_sel(np, "rockchip,leakage-voltage-sel", - leakage, &lkg_volt_sel); - if (!err) { - dev_info(kbdev->dev, "leakage-sel=%d\n", lkg_volt_sel); - volt_sel = lkg_volt_sel; - } - } - - err = rockchip_get_pvtm_specific_value(kbdev->dev, np, kbdev->clock, - kbdev->regulator, - &pvmt_value); - if (!err) { - err = rockchip_get_volt_sel(np, "rockchip,pvtm-voltage-sel", - pvmt_value, &pvtm_volt_sel); - if (!err) { - dev_info(kbdev->dev, "pvtm-sel=%d\n", pvtm_volt_sel); - if (volt_sel < 0 || volt_sel > pvtm_volt_sel) - volt_sel = pvtm_volt_sel; - } - } - - if (volt_sel >= 0) { - snprintf(name, MAX_PROP_NAME_LEN, "L%d", volt_sel); - err = dev_pm_opp_set_prop_name(kbdev->dev, name); - if (err) - dev_err(kbdev->dev, "Failed to set prop name\n"); - } -} diff --git a/drivers/gpu/arm/mali400/Kbuild b/drivers/gpu/arm/mali400/Kbuild index addbd0031ca49..dbb7ad3e5d85e 100644 --- a/drivers/gpu/arm/mali400/Kbuild +++ b/drivers/gpu/arm/mali400/Kbuild @@ -1,2 +1,2 @@ # SPDX-License-Identifier: GPL-2.0 -obj-y += mali/ ump/ +obj-y += mali/ diff --git a/drivers/gpu/arm/mali400/mali/Kbuild b/drivers/gpu/arm/mali400/mali/Kbuild index 6ac149a10136c..f5e8288df4428 100755 --- a/drivers/gpu/arm/mali400/mali/Kbuild +++ b/drivers/gpu/arm/mali400/mali/Kbuild @@ -200,7 +200,7 @@ CHANGED_REVISION := $(shell $(SVN_INFO) | grep '^Last Changed Rev: ' | cut -d: - REPO_URL := $(shell $(SVN_INFO) | grep '^URL: ' | cut -d: -f2- | cut -b2-) else # SVN -GIT_REV := $(shell cd $(src); git describe --always 2>/dev/null) +# GIT_REV := $(shell cd $(src); git describe --always 2>/dev/null) ifneq ($(GIT_REV),) # Git detected DRIVER_REV := $(MALI_RELEASE_NAME)-$(GIT_REV) diff --git a/drivers/gpu/arm/mali400/mali/common/mali_osk_mali.h b/drivers/gpu/arm/mali400/mali/common/mali_osk_mali.h index 657854d83e0f1..98842df4cc72a 100755 --- a/drivers/gpu/arm/mali400/mali/common/mali_osk_mali.h +++ b/drivers/gpu/arm/mali400/mali/common/mali_osk_mali.h @@ -37,6 +37,7 @@ struct mali_device { struct devfreq *devfreq; unsigned long current_freq; unsigned long current_voltage; + struct thermal_opp_info *opp_info; #ifdef CONFIG_DEVFREQ_THERMAL struct thermal_cooling_device *devfreq_cooling; #endif diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_devfreq.c b/drivers/gpu/arm/mali400/mali/linux/mali_devfreq.c index 06c83f017165e..c9b8652f100d0 100644 --- a/drivers/gpu/arm/mali400/mali/linux/mali_devfreq.c +++ b/drivers/gpu/arm/mali400/mali/linux/mali_devfreq.c @@ -36,6 +36,14 @@ #include "mali_pm_metrics.h" +#include + +static struct thermal_opp_device_data gpu_devdata = { + .type = THERMAL_OPP_TPYE_DEV, + .low_temp_adjust = rockchip_dev_low_temp_adjust, + .high_temp_adjust = rockchip_dev_high_temp_adjust, +}; + static int mali_devfreq_target(struct device *dev, unsigned long *target_freq, u32 flags) { @@ -268,6 +276,13 @@ int mali_devfreq_init(struct mali_device *mdev) devfreq_recommended_opp(mdev->dev, &opp_rate, 0); rcu_read_unlock(); mdev->devfreq->last_status.current_frequency = opp_rate; + gpu_devdata.data = mdev->devfreq; + mdev->opp_info = rockchip_register_thermal_notifier(mdev->dev, + &gpu_devdata); + if (IS_ERR(mdev->opp_info)) { + dev_dbg(mdev->dev, "without thermal notifier\n"); + mdev->opp_info = NULL; + } #ifdef CONFIG_DEVFREQ_THERMAL if (of_machine_is_compatible("rockchip,rk3036")) return 0; @@ -319,6 +334,7 @@ void mali_devfreq_term(struct mali_device *mdev) MALI_DEBUG_PRINT(2, ("Term Mali devfreq\n")); + rockchip_unregister_thermal_notifier(mdev->opp_info); #ifdef CONFIG_DEVFREQ_THERMAL devfreq_cooling_unregister(mdev->devfreq_cooling); #endif diff --git a/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_devfreq.c b/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_devfreq.c index 0127d2a1d66fc..1495f06cd9b9e 100644 --- a/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_devfreq.c +++ b/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_devfreq.c @@ -45,6 +45,13 @@ #define dev_pm_opp_find_freq_ceil opp_find_freq_ceil #define dev_pm_opp_find_freq_floor opp_find_freq_floor #endif /* Linux >= 3.13 */ +#include + +static struct thermal_opp_device_data gpu_devdata = { + .type = THERMAL_OPP_TPYE_DEV, + .low_temp_adjust = rockchip_dev_low_temp_adjust, + .high_temp_adjust = rockchip_dev_high_temp_adjust, +}; /** * opp_translate - Translate nominal OPP frequency from devicetree into real @@ -378,6 +385,14 @@ int kbase_devfreq_init(struct kbase_device *kbdev) devfreq_recommended_opp(kbdev->dev, &opp_rate, 0); rcu_read_unlock(); kbdev->devfreq->last_status.current_frequency = opp_rate; + + gpu_devdata.data = kbdev->devfreq; + kbdev->opp_info = rockchip_register_thermal_notifier(kbdev->dev, + &gpu_devdata); + if (IS_ERR(kbdev->opp_info)) { + dev_dbg(kbdev->dev, "without thermal notifier\n"); + kbdev->opp_info = NULL; + } #ifdef CONFIG_DEVFREQ_THERMAL err = kbase_ipa_init(kbdev); if (err) { @@ -420,6 +435,7 @@ void kbase_devfreq_term(struct kbase_device *kbdev) dev_dbg(kbdev->dev, "Term Mali devfreq\n"); + rockchip_unregister_thermal_notifier(kbdev->opp_info); #ifdef CONFIG_DEVFREQ_THERMAL if (kbdev->devfreq_cooling) devfreq_cooling_unregister(kbdev->devfreq_cooling); diff --git a/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_mmu_hw_direct.c b/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_mmu_hw_direct.c index aa1817c8bca92..ba826184dd3fe 100644 --- a/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_mmu_hw_direct.c +++ b/drivers/gpu/arm/midgard/backend/gpu/mali_kbase_mmu_hw_direct.c @@ -14,6 +14,8 @@ */ +/* #define ENABLE_DEBUG_LOG */ +#include "../../platform/rk/custom_log.h" #include @@ -164,6 +166,10 @@ void kbase_mmu_interrupt(struct kbase_device *kbdev, u32 irq_stat) * the MMU is updated */ kctx = kbasep_js_runpool_lookup_ctx(kbdev, as_no); + if (!kctx) { + E("fail to lookup ctx, to break out."); + break; + } /* find faulting address */ diff --git a/drivers/gpu/arm/midgard/mali_kbase_core_linux.c b/drivers/gpu/arm/midgard/mali_kbase_core_linux.c index 3a6e5aae0bceb..24bafe2bf32cc 100644 --- a/drivers/gpu/arm/midgard/mali_kbase_core_linux.c +++ b/drivers/gpu/arm/midgard/mali_kbase_core_linux.c @@ -1154,6 +1154,7 @@ static int kbase_open(struct inode *inode, struct file *filp) } init_waitqueue_head(&kctx->event_queue); + filp->f_mode |= FMODE_UNSIGNED_OFFSET; filp->private_data = kctx; kctx->filp = filp; diff --git a/drivers/gpu/arm/midgard/mali_kbase_ctx_sched.c b/drivers/gpu/arm/midgard/mali_kbase_ctx_sched.c index e2f7baabad43f..ce004841403f4 100644 --- a/drivers/gpu/arm/midgard/mali_kbase_ctx_sched.c +++ b/drivers/gpu/arm/midgard/mali_kbase_ctx_sched.c @@ -131,16 +131,21 @@ int kbase_ctx_sched_retain_ctx(struct kbase_context *kctx) return kctx->as_nr; } -void kbase_ctx_sched_retain_ctx_refcount(struct kbase_context *kctx) +int kbase_ctx_sched_retain_ctx_refcount(struct kbase_context *kctx) { struct kbase_device *const kbdev = kctx->kbdev; lockdep_assert_held(&kbdev->hwaccess_lock); WARN_ON(atomic_read(&kctx->refcount) == 0); + if (atomic_read(&kctx->refcount) == 0) + return -1; + WARN_ON(kctx->as_nr == KBASEP_AS_NR_INVALID); WARN_ON(kbdev->as_to_kctx[kctx->as_nr] != kctx); atomic_inc(&kctx->refcount); + + return 0; } void kbase_ctx_sched_release_ctx(struct kbase_context *kctx) diff --git a/drivers/gpu/arm/midgard/mali_kbase_ctx_sched.h b/drivers/gpu/arm/midgard/mali_kbase_ctx_sched.h index e55152547c31a..47474fecc2a9d 100644 --- a/drivers/gpu/arm/midgard/mali_kbase_ctx_sched.h +++ b/drivers/gpu/arm/midgard/mali_kbase_ctx_sched.h @@ -87,8 +87,11 @@ int kbase_ctx_sched_retain_ctx(struct kbase_context *kctx); * it doesn't get descheduled. * * The kbase_device::hwaccess_lock must be held whilst calling this function + * @return + * è‹¥æˆåŠŸ, 返回 0; + * è‹¥ *kctx 状æ€å¼‚常, 返回 -1. */ -void kbase_ctx_sched_retain_ctx_refcount(struct kbase_context *kctx); +int kbase_ctx_sched_retain_ctx_refcount(struct kbase_context *kctx); /* kbase_ctx_sched_release_ctx - Release a reference to the @ref kbase_context * diff --git a/drivers/gpu/arm/midgard/mali_kbase_defs.h b/drivers/gpu/arm/midgard/mali_kbase_defs.h index 91f159b384136..9526dd9e1a20c 100644 --- a/drivers/gpu/arm/midgard/mali_kbase_defs.h +++ b/drivers/gpu/arm/midgard/mali_kbase_defs.h @@ -1096,6 +1096,7 @@ struct kbase_device { u64 current_core_mask; struct kbase_devfreq_opp *opp_table; int num_opps; + struct thermal_opp_info *opp_info; #ifdef CONFIG_DEVFREQ_THERMAL #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0) struct devfreq_cooling_device *devfreq_cooling; diff --git a/drivers/gpu/arm/midgard/mali_kbase_js.c b/drivers/gpu/arm/midgard/mali_kbase_js.c index b053ce1f22a1d..10a1d5909bbe1 100644 --- a/drivers/gpu/arm/midgard/mali_kbase_js.c +++ b/drivers/gpu/arm/midgard/mali_kbase_js.c @@ -13,9 +13,8 @@ * */ - - - +/* #define ENABLE_DEBUG_LOG */ +#include "./platform/rk/custom_log.h" /* * Job Scheduler Implementation @@ -1245,6 +1244,7 @@ bool kbasep_js_runpool_retain_ctx(struct kbase_device *kbdev, struct kbase_context *kbasep_js_runpool_lookup_ctx(struct kbase_device *kbdev, int as_nr) { + int ret = 0; unsigned long flags; struct kbasep_js_device_data *js_devdata; struct kbase_context *found_kctx = NULL; @@ -1257,8 +1257,13 @@ struct kbase_context *kbasep_js_runpool_lookup_ctx(struct kbase_device *kbdev, found_kctx = kbdev->as_to_kctx[as_nr]; - if (found_kctx != NULL) - kbase_ctx_sched_retain_ctx_refcount(found_kctx); + if (found_kctx != NULL) { + ret = kbase_ctx_sched_retain_ctx_refcount(found_kctx); + if (ret != 0) { + E("fail to retain ctx_refcount, ret : %d.", ret); + found_kctx = NULL; + } + } spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags); diff --git a/drivers/gpu/drm/armada/armada_hw.h b/drivers/gpu/drm/armada/armada_hw.h index 27319a8335e25..345dc4d0851ef 100644 --- a/drivers/gpu/drm/armada/armada_hw.h +++ b/drivers/gpu/drm/armada/armada_hw.h @@ -160,6 +160,7 @@ enum { CFG_ALPHAM_GRA = 0x1 << 16, CFG_ALPHAM_CFG = 0x2 << 16, CFG_ALPHA_MASK = 0xff << 8, +#define CFG_ALPHA(x) ((x) << 8) CFG_PIXCMD_MASK = 0xff, }; diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c index 148e8a42b2c69..9ffd91fb623d2 100644 --- a/drivers/gpu/drm/armada/armada_overlay.c +++ b/drivers/gpu/drm/armada/armada_overlay.c @@ -27,6 +27,7 @@ struct armada_ovl_plane_properties { uint16_t contrast; uint16_t saturation; uint32_t colorkey_mode; + uint32_t colorkey_enable; }; struct armada_ovl_plane { @@ -62,11 +63,13 @@ armada_ovl_update_attr(struct armada_ovl_plane_properties *prop, writel_relaxed(0x00002000, dcrtc->base + LCD_SPU_CBSH_HUE); spin_lock_irq(&dcrtc->irq_lock); - armada_updatel(prop->colorkey_mode | CFG_ALPHAM_GRA, - CFG_CKMODE_MASK | CFG_ALPHAM_MASK | CFG_ALPHA_MASK, - dcrtc->base + LCD_SPU_DMA_CTRL1); - - armada_updatel(ADV_GRACOLORKEY, 0, dcrtc->base + LCD_SPU_ADV_REG); + armada_updatel(prop->colorkey_mode, + CFG_CKMODE_MASK | CFG_ALPHAM_MASK | CFG_ALPHA_MASK, + dcrtc->base + LCD_SPU_DMA_CTRL1); + if (dcrtc->variant->has_spu_adv_reg) + armada_updatel(prop->colorkey_enable, + ADV_GRACOLORKEY | ADV_VIDCOLORKEY, + dcrtc->base + LCD_SPU_ADV_REG); spin_unlock_irq(&dcrtc->irq_lock); } @@ -339,8 +342,17 @@ static int armada_ovl_plane_set_property(struct drm_plane *plane, dplane->prop.colorkey_vb |= K2B(val); update_attr = true; } else if (property == priv->colorkey_mode_prop) { - dplane->prop.colorkey_mode &= ~CFG_CKMODE_MASK; - dplane->prop.colorkey_mode |= CFG_CKMODE(val); + if (val == CKMODE_DISABLE) { + dplane->prop.colorkey_mode = + CFG_CKMODE(CKMODE_DISABLE) | + CFG_ALPHAM_CFG | CFG_ALPHA(255); + dplane->prop.colorkey_enable = 0; + } else { + dplane->prop.colorkey_mode = + CFG_CKMODE(val) | + CFG_ALPHAM_GRA | CFG_ALPHA(0); + dplane->prop.colorkey_enable = ADV_GRACOLORKEY; + } update_attr = true; } else if (property == priv->brightness_prop) { dplane->prop.brightness = val - 256; @@ -469,7 +481,9 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs) dplane->prop.colorkey_yr = 0xfefefe00; dplane->prop.colorkey_ug = 0x01010100; dplane->prop.colorkey_vb = 0x01010100; - dplane->prop.colorkey_mode = CFG_CKMODE(CKMODE_RGB); + dplane->prop.colorkey_mode = CFG_CKMODE(CKMODE_RGB) | + CFG_ALPHAM_GRA | CFG_ALPHA(0); + dplane->prop.colorkey_enable = ADV_GRACOLORKEY; dplane->prop.brightness = 0; dplane->prop.contrast = 0x4000; dplane->prop.saturation = 0x4000; diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index a76b13151fe25..4ff96f6a06e5f 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -908,6 +908,7 @@ static irqreturn_t analogix_dp_irq_thread(int irq, void *arg) static void analogix_dp_commit(struct analogix_dp_device *dp) { + struct video_info *video = &dp->video_info; int ret; /* Keep the panel disabled while we configure video */ @@ -928,6 +929,11 @@ static void analogix_dp_commit(struct analogix_dp_device *dp) analogix_dp_enable_enhanced_mode(dp, 1); analogix_dp_init_video(dp); + analogix_dp_set_video_format(dp); + + if (video->video_bist_enable) + analogix_dp_video_bist_enable(dp); + ret = analogix_dp_config_video(dp); if (ret) dev_err(dp->dev, "unable to config video\n"); @@ -1131,6 +1137,8 @@ static void analogix_dp_bridge_mode_set(struct drm_bridge *bridge, struct device_node *dp_node = dp->dev->of_node; int vic; + drm_mode_copy(&video->mode, mode); + /* Input video interlaces & hsync pol & vsync pol */ video->interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE); video->v_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NVSYNC); @@ -1269,6 +1277,9 @@ static int analogix_dp_dt_parse_pdata(struct analogix_dp_device *dp) break; } + video_info->video_bist_enable = + of_property_read_bool(dp_node, "analogix,video-bist-enable"); + return 0; } diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h index 82f321455c192..e0f02621ae759 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h @@ -136,6 +136,7 @@ enum dp_irq_type { struct video_info { char *name; + struct drm_display_mode mode; bool h_sync_polarity; bool v_sync_polarity; @@ -148,6 +149,8 @@ struct video_info { int max_link_rate; enum link_lane_count_type max_lane_count; + + bool video_bist_enable; }; struct link_train { @@ -279,4 +282,6 @@ int analogix_dp_is_video_stream_on(struct analogix_dp_device *dp); void analogix_dp_config_video_slave_mode(struct analogix_dp_device *dp); void analogix_dp_enable_scrambling(struct analogix_dp_device *dp); void analogix_dp_disable_scrambling(struct analogix_dp_device *dp); +void analogix_dp_set_video_format(struct analogix_dp_device *dp); +void analogix_dp_video_bist_enable(struct analogix_dp_device *dp); #endif /* _ANALOGIX_DP_CORE_H */ diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c index f2cd96ec818c8..81f5ec2bbaee3 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c @@ -1326,3 +1326,69 @@ void analogix_dp_disable_scrambling(struct analogix_dp_device *dp) reg |= SCRAMBLING_DISABLE; writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET); } + +void analogix_dp_set_video_format(struct analogix_dp_device *dp) +{ + struct video_info *video = &dp->video_info; + const struct drm_display_mode *mode = &video->mode; + unsigned int hsw, hfp, hbp, vsw, vfp, vbp; + + hsw = mode->hsync_end - mode->hsync_start; + hfp = mode->hsync_start - mode->hdisplay; + hbp = mode->htotal - mode->hsync_end; + vsw = mode->vsync_end - mode->vsync_start; + vfp = mode->vsync_start - mode->vdisplay; + vbp = mode->vtotal - mode->vsync_end; + + /* Set Video Format Parameters */ + writel(TOTAL_LINE_CFG_L(mode->vtotal), + dp->reg_base + ANALOGIX_DP_TOTAL_LINE_CFG_L); + writel(TOTAL_LINE_CFG_H(mode->vtotal >> 8), + dp->reg_base + ANALOGIX_DP_TOTAL_LINE_CFG_H); + writel(ACTIVE_LINE_CFG_L(mode->vdisplay), + dp->reg_base + ANALOGIX_DP_ACTIVE_LINE_CFG_L); + writel(ACTIVE_LINE_CFG_H(mode->vdisplay >> 8), + dp->reg_base + ANALOGIX_DP_ACTIVE_LINE_CFG_H); + writel(V_F_PORCH_CFG(vfp), + dp->reg_base + ANALOGIX_DP_V_F_PORCH_CFG); + writel(V_SYNC_WIDTH_CFG(vsw), + dp->reg_base + ANALOGIX_DP_V_SYNC_WIDTH_CFG); + writel(V_B_PORCH_CFG(vbp), + dp->reg_base + ANALOGIX_DP_V_B_PORCH_CFG); + writel(TOTAL_PIXEL_CFG_L(mode->htotal), + dp->reg_base + ANALOGIX_DP_TOTAL_PIXEL_CFG_L); + writel(TOTAL_PIXEL_CFG_H(mode->htotal >> 8), + dp->reg_base + ANALOGIX_DP_TOTAL_PIXEL_CFG_H); + writel(ACTIVE_PIXEL_CFG_L(mode->hdisplay), + dp->reg_base + ANALOGIX_DP_ACTIVE_PIXEL_CFG_L); + writel(ACTIVE_PIXEL_CFG_H(mode->hdisplay >> 8), + dp->reg_base + ANALOGIX_DP_ACTIVE_PIXEL_CFG_H); + writel(H_F_PORCH_CFG_L(hfp), + dp->reg_base + ANALOGIX_DP_H_F_PORCH_CFG_L); + writel(H_F_PORCH_CFG_H(hfp >> 8), + dp->reg_base + ANALOGIX_DP_H_F_PORCH_CFG_H); + writel(H_SYNC_CFG_L(hsw), + dp->reg_base + ANALOGIX_DP_H_SYNC_CFG_L); + writel(H_SYNC_CFG_H(hsw >> 8), + dp->reg_base + ANALOGIX_DP_H_SYNC_CFG_H); + writel(H_B_PORCH_CFG_L(hbp), + dp->reg_base + ANALOGIX_DP_H_B_PORCH_CFG_L); + writel(H_B_PORCH_CFG_H(hbp >> 8), + dp->reg_base + ANALOGIX_DP_H_B_PORCH_CFG_H); +} + +void analogix_dp_video_bist_enable(struct analogix_dp_device *dp) +{ + u32 reg; + + /* Enable Video BIST */ + writel(BIST_EN, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_4); + + /* + * Note that if BIST_EN is set to 1, F_SEL must be cleared to 0 + * although video format information comes from registers set by user. + */ + reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10); + reg &= ~FORMAT_SEL; + writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10); +} diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h index 371c4218c6c9c..bbb312fc8094c 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h @@ -18,9 +18,27 @@ #define ANALOGIX_DP_VIDEO_CTL_1 0x20 #define ANALOGIX_DP_VIDEO_CTL_2 0x24 #define ANALOGIX_DP_VIDEO_CTL_3 0x28 +#define ANALOGIX_DP_VIDEO_CTL_4 0x2C #define ANALOGIX_DP_VIDEO_CTL_8 0x3C #define ANALOGIX_DP_VIDEO_CTL_10 0x44 +#define ANALOGIX_DP_TOTAL_LINE_CFG_L 0x48 +#define ANALOGIX_DP_TOTAL_LINE_CFG_H 0x4C +#define ANALOGIX_DP_ACTIVE_LINE_CFG_L 0x50 +#define ANALOGIX_DP_ACTIVE_LINE_CFG_H 0x54 +#define ANALOGIX_DP_V_F_PORCH_CFG 0x58 +#define ANALOGIX_DP_V_SYNC_WIDTH_CFG 0x5C +#define ANALOGIX_DP_V_B_PORCH_CFG 0x60 +#define ANALOGIX_DP_TOTAL_PIXEL_CFG_L 0x64 +#define ANALOGIX_DP_TOTAL_PIXEL_CFG_H 0x68 +#define ANALOGIX_DP_ACTIVE_PIXEL_CFG_L 0x6C +#define ANALOGIX_DP_ACTIVE_PIXEL_CFG_H 0x70 +#define ANALOGIX_DP_H_F_PORCH_CFG_L 0x74 +#define ANALOGIX_DP_H_F_PORCH_CFG_H 0x78 +#define ANALOGIX_DP_H_SYNC_CFG_L 0x7C +#define ANALOGIX_DP_H_SYNC_CFG_H 0x80 +#define ANALOGIX_DP_H_B_PORCH_CFG_L 0x84 +#define ANALOGIX_DP_H_B_PORCH_CFG_H 0x88 #define ANALOGIX_DP_PLL_REG_1 0xfc #define ANALOGIX_DP_PLL_REG_2 0x9e4 @@ -152,6 +170,11 @@ #define VID_CHK_UPDATE_TYPE_1 (0x1 << 4) #define VID_CHK_UPDATE_TYPE_0 (0x0 << 4) +/* ANALOGIX_DP_VIDEO_CTL_4 */ +#define BIST_EN (0x1 << 3) +#define BIST_WIDTH(x) (((x) & 0x1) << 2) +#define BIST_TYPE(x) (((x) & 0x3) << 0) + /* ANALOGIX_DP_VIDEO_CTL_8 */ #define VID_HRES_TH(x) (((x) & 0xf) << 4) #define VID_VRES_TH(x) (((x) & 0xf) << 0) @@ -162,6 +185,57 @@ #define VSYNC_POLARITY_CFG (0x1 << 1) #define HSYNC_POLARITY_CFG (0x1 << 0) +/* ANALOGIX_DP_TOTAL_LINE_CFG_L */ +#define TOTAL_LINE_CFG_L(x) (((x) & 0xff) << 0) + +/* ANALOGIX_DP_TOTAL_LINE_CFG_H */ +#define TOTAL_LINE_CFG_H(x) (((x) & 0xf) << 0) + +/* ANALOGIX_DP_ACTIVE_LINE_CFG_L */ +#define ACTIVE_LINE_CFG_L(x) (((x) & 0xff) << 0) + +/* ANALOGIX_DP_ACTIVE_LINE_CFG_H */ +#define ACTIVE_LINE_CFG_H(x) (((x) & 0xf) << 0) + +/* ANALOGIX_DP_V_F_PORCH_CFG */ +#define V_F_PORCH_CFG(x) (((x) & 0xff) << 0) + +/* ANALOGIX_DP_V_SYNC_WIDTH_CFG */ +#define V_SYNC_WIDTH_CFG(x) (((x) & 0xff) << 0) + +/* ANALOGIX_DP_V_B_PORCH_CFG */ +#define V_B_PORCH_CFG(x) (((x) & 0xff) << 0) + +/* ANALOGIX_DP_TOTAL_PIXEL_CFG_L */ +#define TOTAL_PIXEL_CFG_L(x) (((x) & 0xff) << 0) + +/* ANALOGIX_DP_TOTAL_PIXEL_CFG_H */ +#define TOTAL_PIXEL_CFG_H(x) (((x) & 0x3f) << 0) + +/* ANALOGIX_DP_ACTIVE_PIXEL_CFG_L */ +#define ACTIVE_PIXEL_CFG_L(x) (((x) & 0xff) << 0) + +/* ANALOGIX_DP_ACTIVE_PIXEL_CFG_H */ +#define ACTIVE_PIXEL_CFG_H(x) (((x) & 0x3f) << 0) + +/* ANALOGIX_DP_H_F_PORCH_CFG_L */ +#define H_F_PORCH_CFG_L(x) (((x) & 0xff) << 0) + +/* ANALOGIX_DP_H_F_PORCH_CFG_H */ +#define H_F_PORCH_CFG_H(x) (((x) & 0xf) << 0) + +/* ANALOGIX_DP_H_SYNC_CFG_L */ +#define H_SYNC_CFG_L(x) (((x) & 0xff) << 0) + +/* ANALOGIX_DP_H_SYNC_CFG_H */ +#define H_SYNC_CFG_H(x) (((x) & 0xf) << 0) + +/* ANALOGIX_DP_H_B_PORCH_CFG_L */ +#define H_B_PORCH_CFG_L(x) (((x) & 0xff) << 0) + +/* ANALOGIX_DP_H_B_PORCH_CFG_H */ +#define H_B_PORCH_CFG_H(x) (((x) & 0xf) << 0) + /* ANALOGIX_DP_PLL_REG_1 */ #define REF_CLK_24M (0x1 << 0) #define REF_CLK_27M (0x0 << 0) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index 54de21bae71dc..8cb2cb4e61a6a 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -2498,6 +2498,7 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector) struct edid *edid; struct drm_display_mode *mode; const u8 def_modes[6] = {4, 16, 31, 19, 17, 2}; + struct drm_display_info *info = &connector->display_info; struct hdr_static_metadata *metedata = &connector->display_info.hdmi.hdr_panel_metadata; int i, ret = 0; @@ -2533,6 +2534,10 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector) ret++; } } + info->edid_hdmi_dc_modes = 0; + info->hdmi.y420_dc_modes = 0; + info->color_formats = 0; + dev_info(hdmi->dev, "failed to get edid\n"); } @@ -3839,6 +3844,8 @@ void dw_hdmi_suspend(struct device *dev) if (hdmi->irq) disable_irq(hdmi->irq); mutex_unlock(&hdmi->mutex); + cancel_delayed_work(&hdmi->work); + flush_workqueue(hdmi->workqueue); pinctrl_pm_select_sleep_state(dev); } EXPORT_SYMBOL_GPL(dw_hdmi_suspend); diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 9f80708e3a776..63ba9c1e0f23c 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -979,6 +979,12 @@ int drm_atomic_connector_set_property(struct drm_connector *connector, * now?) atomic writes to DPMS property: */ return -EINVAL; + } else if (property == connector->content_protection_property) { + if (val == DRM_MODE_CONTENT_PROTECTION_ENABLED) { + DRM_DEBUG_KMS("only drivers can set CP Enabled\n"); + return -EINVAL; + } + state->content_protection = val; } else if (property == config->tv_select_subconnector_property) { state->tv.subconnector = val; } else if (property == config->tv_left_margin_property) { @@ -1042,6 +1048,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector, *val = (state->crtc) ? state->crtc->base.id : 0; } else if (property == config->dpms_property) { *val = connector->dpms; + } else if (property == connector->content_protection_property) { + *val = state->content_protection; } else if (property == config->tv_select_subconnector_property) { *val = state->tv.subconnector; } else if (property == config->tv_left_margin_property) { @@ -1132,7 +1140,9 @@ drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state, { struct drm_plane *plane = plane_state->plane; struct drm_crtc_state *crtc_state; - + /* Nothing to do for same crtc*/ + if (plane_state->crtc == crtc) + return 0; if (plane_state->crtc) { crtc_state = drm_atomic_get_crtc_state(plane_state->state, plane_state->crtc); diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 7cd13faf83cac..173a52afd21dd 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -78,6 +78,14 @@ static const struct drm_prop_enum_list drm_plane_type_enum_list[] = { { DRM_PLANE_TYPE_CURSOR, "Cursor" }, }; +static struct drm_prop_enum_list drm_cp_enum_list[] = { + { DRM_MODE_CONTENT_PROTECTION_UNDESIRED, "Undesired" }, + { DRM_MODE_CONTENT_PROTECTION_DESIRED, "Desired" }, + { DRM_MODE_CONTENT_PROTECTION_ENABLED, "Enabled" }, +}; + +DRM_ENUM_NAME_FN(drm_get_content_protection_name, drm_cp_enum_list) + /* * Optional properties */ @@ -1804,6 +1812,11 @@ static int drm_mode_create_standard_properties(struct drm_device *dev) return -ENOMEM; dev->mode_config.gamma_lut_size_property = prop; + prop = drm_property_create_enum(dev, 0, + "Content Protection", drm_cp_enum_list, + ARRAY_SIZE(drm_cp_enum_list)); + dev->mode_config.content_protection_property = prop; + return 0; } @@ -1975,6 +1988,42 @@ int drm_mode_create_scaling_mode_property(struct drm_device *dev) } EXPORT_SYMBOL(drm_mode_create_scaling_mode_property); +/** + * drm_connector_attach_content_protection_property - attach content protection + * property + * + * @connector: connector to attach CP property on. + * + * This is used to add support for content protection on select connectors. + * Content Protection is intentionally vague to allow for different underlying + * technologies, however it is most implemented by HDCP. + * + * The content protection will be set to &drm_connector_state.content_protection + * + * Returns: + * Zero on success, negative errno on failure. + */ +int drm_connector_attach_content_protection_property( + struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + struct drm_property *prop; + + prop = drm_property_create_enum(dev, 0, "Content Protection", + drm_cp_enum_list, + ARRAY_SIZE(drm_cp_enum_list)); + if (!prop) + return -ENOMEM; + + drm_object_attach_property(&connector->base, prop, + DRM_MODE_CONTENT_PROTECTION_UNDESIRED); + + connector->content_protection_property = prop; + + return 0; +} +EXPORT_SYMBOL(drm_connector_attach_content_protection_property); + /** * drm_mode_create_aspect_ratio_property - create aspect ratio property * @dev: DRM device @@ -5192,9 +5241,9 @@ int drm_mode_connector_property_set_ioctl(struct drm_device *dev, return drm_mode_obj_set_property_ioctl(dev, &obj_set_prop, file_priv); } -static int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj, - struct drm_property *property, - uint64_t value) +int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj, + struct drm_property *property, + uint64_t value) { int ret = -EINVAL; struct drm_connector *connector = obj_to_connector(obj); @@ -5212,6 +5261,7 @@ static int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj, drm_object_property_set_value(&connector->base, property, value); return ret; } +EXPORT_SYMBOL(drm_mode_connector_set_obj_prop); static int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj, struct drm_property *property, diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h index e27fdb4711ed0..8c73baf9a3d6b 100644 --- a/drivers/gpu/drm/drm_crtc_internal.h +++ b/drivers/gpu/drm/drm_crtc_internal.h @@ -35,6 +35,9 @@ int drm_mode_object_get(struct drm_device *dev, struct drm_mode_object *obj, uint32_t obj_type); void drm_mode_object_put(struct drm_device *dev, struct drm_mode_object *object); +int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj, + struct drm_property *property, + uint64_t value); /* drm_atomic.c */ int drm_atomic_get_property(struct drm_mode_object *obj, diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 1c6223e0e8f83..937e5e8839f74 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -209,6 +209,7 @@ static int drm_open_helper(struct file *filp, struct drm_minor *minor) return -ENOMEM; filp->private_data = priv; + filp->f_mode |= FMODE_UNSIGNED_OFFSET; priv->filp = filp; priv->uid = current_euid(); priv->pid = get_pid(task_pid(current)); diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 3567aaf899951..ae20397fba09d 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c @@ -24,6 +24,7 @@ #include #include "drm_internal.h" +#include "drm_crtc_internal.h" #define to_drm_minor(d) dev_get_drvdata(d) #define to_drm_connector(d) dev_get_drvdata(d) @@ -267,6 +268,66 @@ static ssize_t enabled_show(struct device *device, "disabled"); } +static ssize_t content_protection_store(struct device *device, + struct device_attribute *attr, + const char *buf, size_t count) +{ + const int nms[] = { + DRM_MODE_CONTENT_PROTECTION_DESIRED, + DRM_MODE_CONTENT_PROTECTION_UNDESIRED + }; + struct drm_connector *connector = to_drm_connector(device); + struct drm_device *dev = connector->dev; + struct drm_property *prop; + int ret, i, val = -1; + + for (i = 0; i < ARRAY_SIZE(nms); i++) { + if (sysfs_streq(buf, drm_get_content_protection_name(nms[i]))) + val = nms[i]; + } + if (val < 0) + return -EINVAL; + + drm_modeset_lock_all(dev); + + prop = dev->mode_config.content_protection_property; + if (!prop) { + drm_modeset_unlock_all(dev); + return count; + } + + ret = drm_mode_connector_set_obj_prop(&connector->base, prop, val); + + drm_modeset_unlock_all(dev); + return ret ? ret : count; +} + +static ssize_t content_protection_show(struct device *device, + struct device_attribute *attr, char *buf) +{ + struct drm_connector *connector = to_drm_connector(device); + struct drm_device *dev = connector->dev; + struct drm_property *prop; + uint64_t cp; + int ret; + + drm_modeset_lock_all(dev); + + prop = dev->mode_config.content_protection_property; + if (!prop) { + drm_modeset_unlock_all(dev); + return 0; + } + + ret = drm_object_property_get_value(&connector->base, prop, &cp); + drm_modeset_unlock_all(dev); + if (ret) + return 0; + + return snprintf(buf, PAGE_SIZE, "%s\n", + drm_get_content_protection_name((int)cp)); +} + static int drm_get_audio_format(struct edid *edid, char *audioformat, int len) { @@ -390,107 +451,12 @@ static ssize_t mode_show(struct device *device, return written; } -static ssize_t tv_subconnector_show(struct device *device, - struct device_attribute *attr, - char *buf) -{ - struct drm_connector *connector = to_drm_connector(device); - struct drm_device *dev = connector->dev; - struct drm_property *prop; - uint64_t subconnector; - int ret; - - prop = dev->mode_config.tv_subconnector_property; - if (!prop) { - DRM_ERROR("Unable to find subconnector property\n"); - return 0; - } - - ret = drm_object_property_get_value(&connector->base, prop, &subconnector); - if (ret) - return 0; - - return snprintf(buf, PAGE_SIZE, "%s", - drm_get_tv_subconnector_name((int)subconnector)); -} - -static ssize_t tv_select_subconnector_show(struct device *device, - struct device_attribute *attr, - char *buf) -{ - struct drm_connector *connector = to_drm_connector(device); - struct drm_device *dev = connector->dev; - struct drm_property *prop; - uint64_t subconnector; - int ret; - - prop = dev->mode_config.tv_select_subconnector_property; - if (!prop) { - DRM_ERROR("Unable to find select subconnector property\n"); - return 0; - } - - ret = drm_object_property_get_value(&connector->base, prop, &subconnector); - if (ret) - return 0; - - return snprintf(buf, PAGE_SIZE, "%s", - drm_get_tv_select_name((int)subconnector)); -} - -static ssize_t dvii_subconnector_show(struct device *device, - struct device_attribute *attr, - char *buf) -{ - struct drm_connector *connector = to_drm_connector(device); - struct drm_device *dev = connector->dev; - struct drm_property *prop; - uint64_t subconnector; - int ret; - - prop = dev->mode_config.dvi_i_subconnector_property; - if (!prop) { - DRM_ERROR("Unable to find subconnector property\n"); - return 0; - } - - ret = drm_object_property_get_value(&connector->base, prop, &subconnector); - if (ret) - return 0; - - return snprintf(buf, PAGE_SIZE, "%s", - drm_get_dvi_i_subconnector_name((int)subconnector)); -} - -static ssize_t dvii_select_subconnector_show(struct device *device, - struct device_attribute *attr, - char *buf) -{ - struct drm_connector *connector = to_drm_connector(device); - struct drm_device *dev = connector->dev; - struct drm_property *prop; - uint64_t subconnector; - int ret; - - prop = dev->mode_config.dvi_i_select_subconnector_property; - if (!prop) { - DRM_ERROR("Unable to find select subconnector property\n"); - return 0; - } - - ret = drm_object_property_get_value(&connector->base, prop, &subconnector); - if (ret) - return 0; - - return snprintf(buf, PAGE_SIZE, "%s", - drm_get_dvi_i_select_name((int)subconnector)); -} - static DEVICE_ATTR_RW(status); static DEVICE_ATTR_RO(enabled); static DEVICE_ATTR_RO(dpms); static DEVICE_ATTR_RO(modes); static DEVICE_ATTR_RO(mode); +static DEVICE_ATTR_RW(content_protection); static DEVICE_ATTR_RO(audioformat); static struct attribute *connector_dev_attrs[] = { @@ -499,58 +465,11 @@ static struct attribute *connector_dev_attrs[] = { &dev_attr_dpms.attr, &dev_attr_modes.attr, &dev_attr_mode.attr, + &dev_attr_content_protection.attr, &dev_attr_audioformat.attr, NULL }; -static DEVICE_ATTR_RO(tv_subconnector); -static DEVICE_ATTR_RO(tv_select_subconnector); - -static struct attribute *connector_tv_dev_attrs[] = { - &dev_attr_tv_subconnector.attr, - &dev_attr_tv_select_subconnector.attr, - NULL -}; - -static DEVICE_ATTR_RO(dvii_subconnector); -static DEVICE_ATTR_RO(dvii_select_subconnector); - -static struct attribute *connector_dvii_dev_attrs[] = { - &dev_attr_dvii_subconnector.attr, - &dev_attr_dvii_select_subconnector.attr, - NULL -}; - -/* Connector type related helpers */ -static int kobj_connector_type(struct kobject *kobj) -{ - struct device *dev = kobj_to_dev(kobj); - struct drm_connector *connector = to_drm_connector(dev); - - return connector->connector_type; -} - -static umode_t connector_is_dvii(struct kobject *kobj, - struct attribute *attr, int idx) -{ - return kobj_connector_type(kobj) == DRM_MODE_CONNECTOR_DVII ? - attr->mode : 0; -} - -static umode_t connector_is_tv(struct kobject *kobj, - struct attribute *attr, int idx) -{ - switch (kobj_connector_type(kobj)) { - case DRM_MODE_CONNECTOR_Composite: - case DRM_MODE_CONNECTOR_SVIDEO: - case DRM_MODE_CONNECTOR_Component: - case DRM_MODE_CONNECTOR_TV: - return attr->mode; - } - - return 0; -} - static struct bin_attribute edid_attr = { .attr.name = "edid", .attr.mode = 0444, @@ -568,20 +487,8 @@ static const struct attribute_group connector_dev_group = { .bin_attrs = connector_bin_attrs, }; -static const struct attribute_group connector_tv_dev_group = { - .attrs = connector_tv_dev_attrs, - .is_visible = connector_is_tv, -}; - -static const struct attribute_group connector_dvii_dev_group = { - .attrs = connector_dvii_dev_attrs, - .is_visible = connector_is_dvii, -}; - static const struct attribute_group *connector_dev_groups[] = { &connector_dev_group, - &connector_tv_dev_group, - &connector_dvii_dev_group, NULL }; diff --git a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c index 34cebcdc2fc4d..9cae5f69b07cb 100644 --- a/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ b/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -190,7 +190,7 @@ static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win, unsigned long val; val = readl(ctx->addr + DECON_WINCONx(win)); - val &= ~WINCONx_BPPMODE_MASK; + val &= WINCONx_ENWIN_F; switch (fb->pixel_format) { case DRM_FORMAT_XRGB1555: @@ -278,8 +278,8 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, COORDINATE_Y(plane->crtc_y + plane->crtc_h - 1); writel(val, ctx->addr + DECON_VIDOSDxB(win)); - val = VIDOSD_Wx_ALPHA_R_F(0x0) | VIDOSD_Wx_ALPHA_G_F(0x0) | - VIDOSD_Wx_ALPHA_B_F(0x0); + val = VIDOSD_Wx_ALPHA_R_F(0xff) | VIDOSD_Wx_ALPHA_G_F(0xff) | + VIDOSD_Wx_ALPHA_B_F(0xff); writel(val, ctx->addr + DECON_VIDOSDxC(win)); val = VIDOSD_Wx_ALPHA_R_F(0x0) | VIDOSD_Wx_ALPHA_G_F(0x0) | diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c index 11b87d2a7913b..ba69d1c72221a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c @@ -526,21 +526,25 @@ static int gsc_src_set_fmt(struct device *dev, u32 fmt) GSC_IN_CHROMA_ORDER_CRCB); break; case DRM_FORMAT_NV21: + cfg |= (GSC_IN_CHROMA_ORDER_CRCB | GSC_IN_YUV420_2P); + break; case DRM_FORMAT_NV61: - cfg |= (GSC_IN_CHROMA_ORDER_CRCB | - GSC_IN_YUV420_2P); + cfg |= (GSC_IN_CHROMA_ORDER_CRCB | GSC_IN_YUV422_2P); break; case DRM_FORMAT_YUV422: cfg |= GSC_IN_YUV422_3P; break; case DRM_FORMAT_YUV420: + cfg |= (GSC_IN_CHROMA_ORDER_CBCR | GSC_IN_YUV420_3P); + break; case DRM_FORMAT_YVU420: - cfg |= GSC_IN_YUV420_3P; + cfg |= (GSC_IN_CHROMA_ORDER_CRCB | GSC_IN_YUV420_3P); break; case DRM_FORMAT_NV12: + cfg |= (GSC_IN_CHROMA_ORDER_CBCR | GSC_IN_YUV420_2P); + break; case DRM_FORMAT_NV16: - cfg |= (GSC_IN_CHROMA_ORDER_CBCR | - GSC_IN_YUV420_2P); + cfg |= (GSC_IN_CHROMA_ORDER_CBCR | GSC_IN_YUV422_2P); break; default: dev_err(ippdrv->dev, "invalid target yuv order 0x%x.\n", fmt); @@ -800,18 +804,25 @@ static int gsc_dst_set_fmt(struct device *dev, u32 fmt) GSC_OUT_CHROMA_ORDER_CRCB); break; case DRM_FORMAT_NV21: - case DRM_FORMAT_NV61: cfg |= (GSC_OUT_CHROMA_ORDER_CRCB | GSC_OUT_YUV420_2P); break; + case DRM_FORMAT_NV61: + cfg |= (GSC_OUT_CHROMA_ORDER_CRCB | GSC_OUT_YUV422_2P); + break; case DRM_FORMAT_YUV422: + cfg |= GSC_OUT_YUV422_3P; + break; case DRM_FORMAT_YUV420: + cfg |= (GSC_OUT_CHROMA_ORDER_CBCR | GSC_OUT_YUV420_3P); + break; case DRM_FORMAT_YVU420: - cfg |= GSC_OUT_YUV420_3P; + cfg |= (GSC_OUT_CHROMA_ORDER_CRCB | GSC_OUT_YUV420_3P); break; case DRM_FORMAT_NV12: + cfg |= (GSC_OUT_CHROMA_ORDER_CBCR | GSC_OUT_YUV420_2P); + break; case DRM_FORMAT_NV16: - cfg |= (GSC_OUT_CHROMA_ORDER_CBCR | - GSC_OUT_YUV420_2P); + cfg |= (GSC_OUT_CHROMA_ORDER_CBCR | GSC_OUT_YUV422_2P); break; default: dev_err(ippdrv->dev, "invalid target yuv order 0x%x.\n", fmt); diff --git a/drivers/gpu/drm/exynos/regs-fimc.h b/drivers/gpu/drm/exynos/regs-fimc.h index 30496134a3d07..d7cbe53c4c01f 100644 --- a/drivers/gpu/drm/exynos/regs-fimc.h +++ b/drivers/gpu/drm/exynos/regs-fimc.h @@ -569,7 +569,7 @@ #define EXYNOS_CIIMGEFF_FIN_EMBOSSING (4 << 26) #define EXYNOS_CIIMGEFF_FIN_SILHOUETTE (5 << 26) #define EXYNOS_CIIMGEFF_FIN_MASK (7 << 26) -#define EXYNOS_CIIMGEFF_PAT_CBCR_MASK ((0xff < 13) | (0xff < 0)) +#define EXYNOS_CIIMGEFF_PAT_CBCR_MASK ((0xff << 13) | (0xff << 0)) /* Real input DMA size register */ #define EXYNOS_CIREAL_ISIZE_AUTOLOAD_ENABLE (1 << 31) diff --git a/drivers/gpu/drm/exynos/regs-gsc.h b/drivers/gpu/drm/exynos/regs-gsc.h index 9ad592707aafd..ade10966d6af7 100644 --- a/drivers/gpu/drm/exynos/regs-gsc.h +++ b/drivers/gpu/drm/exynos/regs-gsc.h @@ -138,6 +138,7 @@ #define GSC_OUT_YUV420_3P (3 << 4) #define GSC_OUT_YUV422_1P (4 << 4) #define GSC_OUT_YUV422_2P (5 << 4) +#define GSC_OUT_YUV422_3P (6 << 4) #define GSC_OUT_YUV444 (7 << 4) #define GSC_OUT_TILE_TYPE_MASK (1 << 2) #define GSC_OUT_TILE_C_16x8 (0 << 2) diff --git a/drivers/gpu/drm/gma500/psb_intel_drv.h b/drivers/gpu/drm/gma500/psb_intel_drv.h index 860dd2177ca15..283570080d47c 100644 --- a/drivers/gpu/drm/gma500/psb_intel_drv.h +++ b/drivers/gpu/drm/gma500/psb_intel_drv.h @@ -252,7 +252,7 @@ extern int intelfb_remove(struct drm_device *dev, extern bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder, const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode); -extern int psb_intel_lvds_mode_valid(struct drm_connector *connector, +extern enum drm_mode_status psb_intel_lvds_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode); extern int psb_intel_lvds_set_property(struct drm_connector *connector, struct drm_property *property, diff --git a/drivers/gpu/drm/gma500/psb_intel_lvds.c b/drivers/gpu/drm/gma500/psb_intel_lvds.c index 33df3b8c2b053..a1397a1fc1e46 100644 --- a/drivers/gpu/drm/gma500/psb_intel_lvds.c +++ b/drivers/gpu/drm/gma500/psb_intel_lvds.c @@ -343,7 +343,7 @@ static void psb_intel_lvds_restore(struct drm_connector *connector) } } -int psb_intel_lvds_mode_valid(struct drm_connector *connector, +enum drm_mode_status psb_intel_lvds_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { struct drm_psb_private *dev_priv = connector->dev->dev_private; diff --git a/drivers/gpu/drm/i2c/adv7511.c b/drivers/gpu/drm/i2c/adv7511.c index dba5c0ea0827d..c7c243e9b8083 100644 --- a/drivers/gpu/drm/i2c/adv7511.c +++ b/drivers/gpu/drm/i2c/adv7511.c @@ -450,6 +450,18 @@ static void adv7511_hpd_work(struct work_struct *work) else status = connector_status_disconnected; + /* + * The bridge resets its registers on unplug. So when we get a plug + * event and we're already supposed to be powered, cycle the bridge to + * restore its state. + */ + if (status == connector_status_connected && + adv7511->connector.status == connector_status_disconnected && + adv7511->powered) { + regcache_mark_dirty(adv7511->regmap); + adv7511_power_on(adv7511); + } + if (adv7511->connector.status != status) { adv7511->connector.status = status; drm_kms_helper_hotplug_event(adv7511->connector.dev); diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 5722a393e19b8..f8c104bb23d3b 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -768,6 +768,14 @@ static const struct dmi_system_id intel_no_lvds[] = { DMI_EXACT_MATCH(DMI_BOARD_NAME, "D525MW"), }, }, + { + .callback = intel_no_lvds_dmi_callback, + .ident = "Radiant P845", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Radiant Systems Inc"), + DMI_MATCH(DMI_PRODUCT_NAME, "P845"), + }, + }, { } /* terminating entry */ }; diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c index c79a61b67ded0..7f1bb858276e1 100644 --- a/drivers/gpu/drm/imx/imx-ldb.c +++ b/drivers/gpu/drm/imx/imx-ldb.c @@ -526,6 +526,9 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) return PTR_ERR(imx_ldb->regmap); } + /* disable LDB by resetting the control register to POR default */ + regmap_write(imx_ldb->regmap, IOMUXC_GPR2, 0); + imx_ldb->dev = dev; if (of_id) @@ -566,14 +569,14 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) if (ret || i < 0 || i > 1) return -EINVAL; + if (!of_device_is_available(child)) + continue; + if (dual && i > 0) { dev_warn(dev, "dual-channel mode, ignoring second output\n"); continue; } - if (!of_device_is_available(child)) - continue; - channel = &imx_ldb->channel[i]; channel->ldb = imx_ldb; channel->chno = i; diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 495c279da2009..ae560f5977fca 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -602,7 +602,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli, struct nouveau_bo *nvbo; uint32_t data; - if (unlikely(r->bo_index > req->nr_buffers)) { + if (unlikely(r->bo_index >= req->nr_buffers)) { NV_PRINTK(err, cli, "reloc bo index invalid\n"); ret = -EINVAL; break; @@ -612,7 +612,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli, if (b->presumed.valid) continue; - if (unlikely(r->reloc_bo_index > req->nr_buffers)) { + if (unlikely(r->reloc_bo_index >= req->nr_buffers)) { NV_PRINTK(err, cli, "reloc container bo index invalid\n"); ret = -EINVAL; break; diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 9a2be6f20e46b..8287127a71210 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -37,6 +37,7 @@ #include