diff --git a/Documentation/devicetree/bindings/arm/msm/imem.txt b/Documentation/devicetree/bindings/arm/msm/imem.txt index a9d2a2456cfd..2989fbfe7972 100644 --- a/Documentation/devicetree/bindings/arm/msm/imem.txt +++ b/Documentation/devicetree/bindings/arm/msm/imem.txt @@ -63,6 +63,11 @@ Emergency Download Mode: -compatible: "qcom,msm-imem-emergency_download_mode" -reg: start address and size of emergency_download_mode region in imem +Kaslr Offset: +------------------------ +-compatible: "qcom,msm-imem-kaslr_offset" +-reg: start address and size of kaslr_offset region in imem + USB Diag Cookies: ----------------- Memory region used to store USB PID and serial numbers to be used by @@ -101,6 +106,12 @@ Example: reg = <0x6b0 32>; }; + kaslr_offset@6d0 { + compatible = "qcom,msm-imem-kaslr_offset"; + reg = <0x6d0 12>; + }; + + pil@94c { compatible = "qcom,msm-imem-pil"; reg = <0x94c 200>; diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt b/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt index a8334e1cfde7..be8f27d87738 100644 --- a/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt +++ b/Documentation/devicetree/bindings/arm/msm/qcom,osm.txt @@ -9,8 +9,9 @@ Properties: - compatible Usage: required Value type: - Definition: must be "qcom,cpu-clock-osm-msm8998-v1" or - "qcom,cpu-clock-osm-msm8998-v2". + Definition: must be "qcom,cpu-clock-osm-msm8998-v1", + "qcom,cpu-clock-osm-msm8998-v2" or + "qcom,clk-cpu-osm". - reg Usage: required diff --git a/Documentation/devicetree/bindings/fb/mdss-pll.txt b/Documentation/devicetree/bindings/fb/mdss-pll.txt index 945d79825695..e9e4a9af381b 100644 --- a/Documentation/devicetree/bindings/fb/mdss-pll.txt +++ b/Documentation/devicetree/bindings/fb/mdss-pll.txt @@ -15,7 +15,7 @@ Required properties: "qcom,mdss_hdmi_pll_8996_v2", "qcom,mdss_dsi_pll_8996_v2", "qcom,mdss_hdmi_pll_8996_v3", "qcom,mdss_hdmi_pll_8996_v3_1p8", "qcom,mdss_dsi_pll_8998", "qcom,mdss_dp_pll_8998", - "qcom,mdss_hdmi_pll_8998" + "qcom,mdss_hdmi_pll_8998", "qcom,mdss_dsi_pll_msmfalcon" - cell-index: Specifies the controller used - reg: offset and length of the register set for the device. - reg-names : names to refer to register sets related to this device diff --git a/Documentation/devicetree/bindings/gpu/adreno.txt b/Documentation/devicetree/bindings/gpu/adreno.txt index f5ae85d27692..453223dc195a 100644 --- a/Documentation/devicetree/bindings/gpu/adreno.txt +++ b/Documentation/devicetree/bindings/gpu/adreno.txt @@ -143,6 +143,12 @@ Optional Properties: Specify the name of GPU temperature sensor. This name will be used to get the temperature from the thermal driver API. +- qcom,enable-midframe-timer: + Boolean. Enables the use of midframe sampling timer. This timer + samples the GPU powerstats if the cmdbatch expiry takes longer than + the threshold set by KGSL_GOVERNOR_CALL_INTERVAL. Enable only if + target has NAP state enabled. + GPU Quirks: - qcom,gpu-quirk-two-pass-use-wfi: Signal the GPU to set Set TWOPASSUSEWFI bit in diff --git a/Documentation/devicetree/bindings/regulator/cpr4-mmss-ldo-regulator.txt b/Documentation/devicetree/bindings/regulator/cpr4-mmss-ldo-regulator.txt new file mode 100644 index 000000000000..41cec67b7627 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/cpr4-mmss-ldo-regulator.txt @@ -0,0 +1,321 @@ +Qualcomm Technologies, Inc. CPR4 Regulator - MMSS LDO Specific Bindings + +MMSS LDO CPR4 controllers each support one CPR thread that monitors the voltage +of the graphics processor (MMSS) supply regulator. The CPR open-loop voltages +are stored in hardware fuses for MMSS CPR4 controllers. However, the CPR target +quotients must be defined in device tree. + +This document describes the MMSS LDO specific CPR4 bindings. + +======================= +Required Node Structure +======================= + +CPR3 regulators must be described in three levels of devices nodes. The first +level describes the CPR3 controller. The second level describes exacly one +hardware thread managed by the controller. The third level describes one or +more logical regulators handled by the CPR thread. + +All platform independent cpr3-regulator binding guidelines defined in +cpr3-regulator.txt also apply to cpr4-mmss-ldo-regulator devices. + +==================================== +First Level Nodes - CPR3 Controllers +==================================== + +MMSS LDO specific properties: +- compatible + Usage: required + Value type: + Definition: should be the following: + "qcom,cpr4-msmfalcon-mmss-ldo-regulator". + +- clocks + Usage: required + Value type: + Definition: Array of clock tuples in which each tuple consists of a + phandle to a clock device and a clock ID number. The + following clocks must be specified: MMSS RBCPR and MMSS + RBCPR AHB. + +- clock-names + Usage: required + Value type: + Definition: Clock names. This list must match up 1-to-1 with the clocks + specified in the 'clocks' property. "core_clk", and "bus_clk" + must be specified. + +- qcom,cpr-step-quot-fixed + Usage: Optional + Value type: + Definition: Fixed step quotient value used by controller for applying + the SDELTA margin adjustments on the programmed target + quotient values. The step quotient is the number of + additional ring oscillator ticks observed for each + qcom,voltage-step increase in vdd-supply output voltage. + Supported values: 0 - 63. + +================================================= +Second Level Nodes - CPR Threads for a Controller +================================================= + +MMSS specific properties: +N/A + +=============================================== +Third Level Nodes - CPR Regulators for a Thread +=============================================== + +MMSS specific properties: +- qcom,cpr-fuse-corners + Usage: required + Value type: + Definition: Specifies the number of fuse corners. This value must be 6 + for msmfalcon GFX LDO. These fuse corners are: MinSVS, + LowSVS, SVS, SVSP, NOM and NOMP. The open-loop voltage fuses + are allocated for LowSVS, SVS, NOM and NOMP corners. The + open-loop voltages for MinSVS and SVSP are derived by + applying fixed offset from LowSVS and NOM open-loop voltages + respectively. The closed-loop offset voltage fuses are + allocated for LowSVS, SVS, NOM and NOMP corners. The MinSVS + and SVSP corners use the closed-loop offset voltage fuses of + LowSVS and NOM corners respectively. + +- qcom,cpr-fuse-combos + Usage: required + Value type: + Definition: Specifies the number of fuse combinations being supported by + the device. This value is utilized by several other + properties. Supported values are 1 up to the maximum + possible for a given regulator type. For MMSS the maximum + supported value is 8. These combos correspond to CPR + revision fuse values from 0 to 7 in order. + +- qcom,mem-acc-voltage + Usage: required if mem-acc-supply is specified for the CPR3 controller + containing this CPR3 regulator + Value type: + Definition: A list of integer tuples which each define the mem-acc-supply + corner for each voltage corner in order from lowest to highest. + + The list must contain qcom,cpr-fuse-combos number of tuples + in which case the tuples are matched to fuse combinations + 1-to-1 or qcom,cpr-speed-bins number of tuples in which case + the tuples are matched to speed bins 1-to-1 or exactly 1 + tuple which is used regardless of the fuse combination and + speed bin found on a given chip. + + Each tuple must be of the length defined in the + corresponding element of the qcom,cpr-corners property or + the qcom,cpr-speed-bins property. A single tuple may only + be specified if all of the corner counts in qcom,cpr-corners + are the same. + +- qcom,cpr-target-quotients + Usage: required + Value type: + Definition: A grouping of integer tuple lists. Each tuple defines the + CPR target quotient for each ring oscillator (RO) for a + given corner. Since CPR3 supports exactly 16 ROs, each + tuple must contain 16 elements corresponding to RO0 through + RO15 in order. If a given RO is unused for a corner, then + its target quotient should be specified as 0. + + Each tuple list in the grouping must meet the same size + requirements as those specified for qcom,mem-acc-voltage + above. The tuples in a given list are ordered from the + lowest corner to the highest corner. + +- qcom,cpr-ro-scaling-factor + Usage: required if qcom,cpr-closed-loop-voltage-adjustment is + specified + Value type: + Definition: The common definition of this property in cpr3-regulator.txt + is accurate for MMSS CPR3 controllers except for this + modification: + + Each tuple list must contain the number of tuples defined in + the corresponding element of the qcom,cpr-corners property + or the qcom,cpr-speed-bins property as opposed to the value + of the qcom,cpr-fuse-corners property. + +- qcom,cpr-fused-closed-loop-voltage-adjustment-map + Usage: optional + Value type: + Definition: A list of integer tuples which each define the CPR fused + corner closed-loop offset adjustment fuse to utilize for + each voltage corner in order from lowest to highest. + + The list must contain qcom,cpr-fuse-combos number of tuples + in which case the tuples are matched to fuse combinations + 1-to-1 or qcom,cpr-speed-bins number of tuples in which case + the tuples are matched to speed bins 1-to-1 or exactly 1 + tuple which is used regardless of the fuse combination and + speed bin found on a given chip. + + Each tuple must be of the length defined in the + corresponding element of the qcom,cpr-corners property or + the qcom,cpr-speed-bins property. A single tuple may only + be specified if all of the corner counts in qcom,cpr-corners + are the same. + + Each tuple element must be either 0 or in the range 1 to + qcom,cpr-fuse-corners. A value of 0 signifies that no fuse + based adjustment should be applied to the fuse corner. + Values 1 to qcom,cpr-fuse-corners denote the specific fuse + corner that should be used by a given voltage corner. + +- qcom,cpr-corner-allow-ldo-mode + Usage: optional + Value type: + Definition: A list of integer tuples which each define the LDO mode + allowed state for each voltage corner in order from lowest + to highest. Each element in the tuple should be either + 0 (LDO mode not allowed) or 1 (LDO mode allowed). + + The list must contain qcom,cpr-fuse-combos number of tuples + in which case the tuples are matched to fuse combinations + 1-to-1 or qcom,cpr-speed-bins number of tuples in which case + the tuples are matched to speed bins 1-to-1 or exactly 1 + tuple which is used regardless of the fuse combination and + speed bin found on a given chip. + + Each tuple must be of the length defined in the + corresponding element of the qcom,cpr-corners property or + the qcom,cpr-speed-bin-corners property. A single tuple may + only be specified if all of the corner counts in + qcom,cpr-corners are the same. + +- qcom,cpr-corner-allow-closed-loop + Usage: optional + Value type: + Definition: A list of integer tuples which each define the CPR + closed-loop operation allowed state for each voltage corner + in order from lowest to highest. Each element in the tuple + should be either 0 (CPR closed-loop operation not allowed) + or 1 (CPR closed-loop operation allowed). + + The list must contain qcom,cpr-fuse-combos number of tuples + in which case the tuples are matched to fuse combinations + 1-to-1 or qcom,cpr-speed-bins number of tuples in which case + the tuples are matched to speed bins 1-to-1 or exactly 1 + tuple which is used regardless of the fuse combination and + speed bin found on a given chip. + + Each tuple must be of the length defined in the + corresponding element of the qcom,cpr-corners property or + the qcom,cpr-speed-bin-corners property. A single tuple may + only be specified if all of the corner counts in + qcom,cpr-corners are the same. + +Note that the qcom,cpr-closed-loop-voltage-fuse-adjustment property is not +meaningful for MMSS LDO CPR3 regulator nodes since target quotients are not +defined in fuses. + +======= +Example +======= + +gfx_cpr: cpr4-ctrl@05061000 { + compatible = "qcom,cpr4-msmfalcon-mmss-ldo-regulator"; + reg = <0x05061000 0x4000>, <0x00784000 0x1000>; + reg-names = "cpr_ctrl", "fuse_base"; + interrupts = ; + interrupt-names = "cpr"; + qcom,cpr-ctrl-name = "gfx"; + + qcom,cpr-sensor-time = <1000>; + qcom,cpr-loop-time = <5000000>; + qcom,cpr-idle-cycles = <15>; + qcom,cpr-step-quot-init-min = <8>; + qcom,cpr-step-quot-init-max = <12>; + qcom,cpr-count-mode = <0>; /* All at once */ + + vdd-supply = <&gfx_stub_vreg>; + mem-acc-supply = <&gfx_mem_acc_vreg>; + system-supply = <&pm2falcon_s3_level>; /* vdd_cx */ + qcom,voltage-step = <5000>; + vdd-thread0-ldo-supply = <&gfx_ldo_vreg>; + + qcom,cpr-enable; + + thread@0 { + qcom,cpr-thread-id = <0>; + qcom,cpr-consecutive-up = <0>; + qcom,cpr-consecutive-down = <2>; + qcom,cpr-up-threshold = <0>; + qcom,cpr-down-threshold = <2>; + + gfx_vreg_corner: regulator { + regulator-name = "gfx_corner"; + regulator-min-microvolt = <1>; + regulator-max-microvolt = <7>; + + qcom,cpr-fuse-corners = <6>; + qcom,cpr-fuse-combos = <8>; + qcom,cpr-corners = <7>; + + qcom,cpr-corner-fmax-map = <1 2 3 4 5 6>; + + qcom,cpr-voltage-ceiling = + <584000 644000 724000 788000 + 868000 924000 1068000>; + qcom,cpr-voltage-floor = + <504000 504000 596000 652000 + 712000 744000 1068000>; + + qcom,mem-acc-voltage = <1 1 1 2 2 2 2>; + qcom,system-voltage = + , + , + , + , + , + , + ; + + qcom,corner-frequencies = + <160000000 266000000 370000000 + 465000000 588000000 647000000 + 800000000>; + + qcom,cpr-target-quotients = + <0 0 0 0 0 0 185 179 + 291 299 304 319 0 0 0 0>, + <0 0 0 0 0 0 287 273 + 425 426 443 453 0 0 0 0>, + <0 0 0 0 0 0 414 392 + 584 576 608 612 0 0 0 0>, + <0 0 0 0 0 0 459 431 + 684 644 692 679 0 0 0 0>, + <0 0 0 0 0 0 577 543 + 798 768 823 810 0 0 0 0>, + <0 0 0 0 0 0 669 629 + 886 864 924 911 0 0 0 0>, + <0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0>; + + qcom,cpr-ro-scaling-factor = + < 0 0 0 0 0 0 2035 1917 + 1959 2131 2246 2253 0 0 0 0>, + < 0 0 0 0 0 0 2035 1917 + 1959 2131 2246 2253 0 0 0 0>, + < 0 0 0 0 0 0 2035 1917 + 1959 2131 2246 2253 0 0 0 0>, + < 0 0 0 0 0 0 2035 1917 + 1959 2131 2246 2253 0 0 0 0>, + < 0 0 0 0 0 0 2035 1917 + 1959 2131 2246 2253 0 0 0 0>, + < 0 0 0 0 0 0 2035 1917 + 1959 2131 2246 2253 0 0 0 0>, + < 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0>; + + qcom,cpr-scaled-open-loop-voltage-as-ceiling; + qcom,cpr-corner-ldo-mode-allowed = + <1 1 1 1 1 1 0>; + qcom,cpr-corner-use-closed-loop = + <1 1 1 1 1 1 0>; + }; + }; +}; diff --git a/arch/arm/boot/dts/qcom/Makefile b/arch/arm/boot/dts/qcom/Makefile index 4293b1929794..9b702a7bf08e 100644 --- a/arch/arm/boot/dts/qcom/Makefile +++ b/arch/arm/boot/dts/qcom/Makefile @@ -116,6 +116,8 @@ dtb-$(CONFIG_ARCH_MSM8998) += msm8998-sim.dtb \ msm8998-v2-qrd-skuk.dtb \ msm8998-qrd-vr1.dtb \ msm8998-v2-qrd-vr1.dtb \ + msm8998-v2-qrd-skuk-evt3.dtb \ + msm8998-v2-qrd-skuk-hdk.dtb \ apq8998-mtp.dtb \ apq8998-cdp.dtb \ apq8998-v2-mtp.dtb \ @@ -135,17 +137,29 @@ dtb-$(CONFIG_ARCH_MSM8998) += msm8998-sim.dtb \ dtb-$(CONFIG_ARCH_MSMHAMSTER) += msmhamster-rumi.dtb dtb-$(CONFIG_ARCH_MSMFALCON) += msmfalcon-sim.dtb \ - msmfalcon-rumi.dtb \ - msmfalcon-cdp.dtb \ msmfalcon-internal-codec-cdp.dtb \ - msmfalcon-mtp.dtb \ msmfalcon-internal-codec-mtp.dtb \ - msmfalcon-rcm.dtb \ msmfalcon-internal-codec-rcm.dtb \ + msmfalcon-cdp.dtb \ + msmfalcon-mtp.dtb \ msmfalcon-qrd.dtb \ + msmfalcon-rcm.dtb \ + msmfalcon-rumi.dtb \ + msmfalcon-pm3falcon-cdp.dtb \ + msmfalcon-pm3falcon-mtp.dtb \ + msmfalcon-pm3falcon-qrd.dtb \ + msmfalcon-pm3falcon-rcm.dtb \ + msmfalcon-pm3falcon-rumi.dtb \ + msmfalcon-internal-codec-pm3falcon-cdp.dtb \ + msmfalcon-internal-codec-pm3falcon-mtp.dtb \ + msmfalcon-internal-codec-pm3falcon-rcm.dtb \ + msmfalcon-pm3falcon-sim.dtb \ apqfalcon-cdp.dtb \ apqfalcon-mtp.dtb \ - apqfalcon-rcm.dtb + apqfalcon-rcm.dtb \ + apqfalcon-pm3falcon-cdp.dtb \ + apqfalcon-pm3falcon-mtp.dtb \ + apqfalcon-pm3falcon-rcm.dtb dtb-$(CONFIG_ARCH_MSMTRITON) += msmtriton-rumi.dtb diff --git a/arch/arm/boot/dts/qcom/apqfalcon-cdp.dts b/arch/arm/boot/dts/qcom/apqfalcon-cdp.dts index 9ed26e5ff0aa..fc449860da0d 100644 --- a/arch/arm/boot/dts/qcom/apqfalcon-cdp.dts +++ b/arch/arm/boot/dts/qcom/apqfalcon-cdp.dts @@ -17,7 +17,9 @@ #include "msmfalcon-cdp.dtsi" / { - model = "Qualcomm Technologies, Inc. APQ FALCON CDP"; + model = "Qualcomm Technologies, Inc. APQ FALCON PMFALCON + PM2FALCON CDP"; compatible = "qcom,apqfalcon-cdp", "qcom,apqfalcon", "qcom,cdp"; qcom,board-id = <1 0>; + qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>, + <0x0001001b 0x0201011a 0x0 0x0>; }; diff --git a/arch/arm/boot/dts/qcom/apqfalcon-mtp.dts b/arch/arm/boot/dts/qcom/apqfalcon-mtp.dts index 74e4fc8154a9..c4f6e9fb30b9 100644 --- a/arch/arm/boot/dts/qcom/apqfalcon-mtp.dts +++ b/arch/arm/boot/dts/qcom/apqfalcon-mtp.dts @@ -17,7 +17,9 @@ #include "msmfalcon-mtp.dtsi" / { - model = "Qualcomm Technologies, Inc. APQ FALCON MTP"; + model = "Qualcomm Technologies, Inc. APQ FALCON PMFALCON + PM2FALCON MTP"; compatible = "qcom,apqfalcon-mtp", "qcom,apqfalcon", "qcom,mtp"; qcom,board-id = <8 0>; + qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>, + <0x0001001b 0x0201011a 0x0 0x0>; }; diff --git a/arch/arm/boot/dts/qcom/apqfalcon-pm3falcon-cdp.dts b/arch/arm/boot/dts/qcom/apqfalcon-pm3falcon-cdp.dts new file mode 100644 index 000000000000..851533931a61 --- /dev/null +++ b/arch/arm/boot/dts/qcom/apqfalcon-pm3falcon-cdp.dts @@ -0,0 +1,25 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +/dts-v1/; + +#include "apqfalcon.dtsi" +#include "msmfalcon-cdp.dtsi" +#include "msm-pm3falcon.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. APQ FALCON PMFALCON + PM3FALCON CDP"; + compatible = "qcom,apqfalcon-cdp", "qcom,apqfalcon", "qcom,cdp"; + qcom,board-id = <1 0>; + qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; +}; diff --git a/arch/arm/boot/dts/qcom/apqfalcon-pm3falcon-mtp.dts b/arch/arm/boot/dts/qcom/apqfalcon-pm3falcon-mtp.dts new file mode 100644 index 000000000000..e7e8aeb9c2aa --- /dev/null +++ b/arch/arm/boot/dts/qcom/apqfalcon-pm3falcon-mtp.dts @@ -0,0 +1,25 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +/dts-v1/; + +#include "apqfalcon.dtsi" +#include "msmfalcon-mtp.dtsi" +#include "msm-pm3falcon.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. APQ FALCON PMFALCON + PM3FALCON MTP"; + compatible = "qcom,apqfalcon-mtp", "qcom,apqfalcon", "qcom,mtp"; + qcom,board-id = <8 0>; + qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; +}; diff --git a/arch/arm/boot/dts/qcom/apqfalcon-pm3falcon-rcm.dts b/arch/arm/boot/dts/qcom/apqfalcon-pm3falcon-rcm.dts new file mode 100644 index 000000000000..68c4bd724ccd --- /dev/null +++ b/arch/arm/boot/dts/qcom/apqfalcon-pm3falcon-rcm.dts @@ -0,0 +1,25 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +/dts-v1/; + +#include "apqfalcon.dtsi" +#include "msmfalcon-cdp.dtsi" +#include "msm-pm3falcon.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. APQ FALCON PMFALCON + PM3FALCON RCM"; + compatible = "qcom,apqfalcon-cdp", "qcom,apqfalcon", "qcom,cdp"; + qcom,board-id = <21 0>; + qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; +}; diff --git a/arch/arm/boot/dts/qcom/apqfalcon-rcm.dts b/arch/arm/boot/dts/qcom/apqfalcon-rcm.dts index 52ff518f4ce4..8f4b164c55ca 100644 --- a/arch/arm/boot/dts/qcom/apqfalcon-rcm.dts +++ b/arch/arm/boot/dts/qcom/apqfalcon-rcm.dts @@ -17,7 +17,9 @@ #include "msmfalcon-cdp.dtsi" / { - model = "Qualcomm Technologies, Inc. APQ FALCON RCM"; + model = "Qualcomm Technologies, Inc. APQ FALCON PMFALCON + PM2FALCON RCM"; compatible = "qcom,apqfalcon-cdp", "qcom,apqfalcon", "qcom,cdp"; qcom,board-id = <21 0>; + qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>, + <0x0001001b 0x0201011a 0x0 0x0>; }; diff --git a/arch/arm/boot/dts/qcom/msm8998-camera-sensor-skuk.dtsi b/arch/arm/boot/dts/qcom/msm8998-camera-sensor-skuk.dtsi index 69b0286dba09..3e7b5614bc55 100644 --- a/arch/arm/boot/dts/qcom/msm8998-camera-sensor-skuk.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-camera-sensor-skuk.dtsi @@ -16,6 +16,7 @@ cell-index = <0>; compatible = "qcom,camera-flash"; qcom,flash-source = <&pmi8998_flash0 &pmi8998_flash1>; + qcom,torch-source = <&pmi8998_torch0 &pmi8998_torch1>; qcom,switch-source = <&pmi8998_switch0>; status = "ok"; }; @@ -24,6 +25,7 @@ cell-index = <1>; compatible = "qcom,camera-flash"; qcom,flash-source = <&pmi8998_flash2>; + qcom,torch-source = <&pmi8998_torch2>; qcom,switch-source = <&pmi8998_switch1>; status = "ok"; }; diff --git a/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon.dtsi b/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon.dtsi index 5b4dda445ff3..347b924749fd 100644 --- a/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-interposer-msmfalcon.dtsi @@ -2886,7 +2886,6 @@ }; qcom,icnss@18800000 { - status = "disabled"; compatible = "qcom,icnss"; reg = <0x18800000 0x800000>, <0x10AC000 0x20>, @@ -2894,6 +2893,8 @@ <0xb0000000 0x10000>; reg-names = "membase", "mpm_config", "smmu_iova_base", "smmu_iova_ipa"; + iommus = <&anoc2_smmu 0x1900>, + <&anoc2_smmu 0x1901>; interrupts = <0 413 0 /* CE0 */ >, <0 414 0 /* CE1 */ >, <0 415 0 /* CE2 */ >, @@ -2907,6 +2908,8 @@ <0 424 0 /* CE10 */ >, <0 425 0 /* CE11 */ >; qcom,wlan-msa-memory = <0x100000>; + qcom,icnss-vadc = <&pmfalcon_vadc>; + qcom,icnss-adc_tm = <&pmfalcon_adc_tm>; }; tspp: msm_tspp@0c1e7000 { diff --git a/arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi b/arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi index bd20ae0a9b85..7c3bb4101de7 100644 --- a/arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-pinctrl.dtsi @@ -1637,6 +1637,82 @@ }; }; + /* add pingrp for touchscreen */ + pmx_ts_int_active { + ts_int_active: ts_int_active { + mux { + pins = "gpio125"; + function = "gpio"; + }; + + config { + pins = "gpio125"; + drive-strength = <8>; + bias-pull-up; + }; + }; + }; + + pmx_ts_int_suspend { + ts_int_suspend1: ts_int_suspend1 { + mux { + pins = "gpio125"; + function = "gpio"; + }; + + config { + pins = "gpio125"; + drive-strength = <2>; + bias-pull-down; + }; + }; + }; + + pmx_ts_reset_active { + ts_reset_active: ts_reset_active { + mux { + pins = "gpio89"; + function = "gpio"; + }; + + config { + pins = "gpio89"; + drive-strength = <8>; + bias-pull-up; + }; + }; + }; + + pmx_ts_reset_suspend { + ts_reset_suspend1: ts_reset_suspend1 { + mux { + pins = "gpio89"; + function = "gpio"; + }; + + config { + pins = "gpio89"; + drive-strength = <2>; + bias-pull-down; + }; + }; + }; + + pmx_ts_release { + ts_release: ts_release { + mux { + pins = "gpio125", "gpio89"; + function = "gpio"; + }; + + config { + pins = "gpio125", "gpio89"; + drive-strength = <2>; + bias-pull-down; + }; + }; + }; + ts_mux { ts_active: ts_active { mux { diff --git a/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi b/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi index 0352874c64c7..07a0e6e6d5ad 100644 --- a/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-qrd-skuk.dtsi @@ -160,6 +160,15 @@ input-name = "gpio-keys"; status = "okay"; + home { + label = "home"; + gpios = <&pm8998_gpios 5 0x1>; + linux,input-type = <1>; + linux,code = <102>; + gpio-key,wakeup; + debounce-interval = <15>; + }; + vol_up { label = "volume_up"; gpios = <&pm8998_gpios 6 0x1>; @@ -290,12 +299,18 @@ &pmi8998_fg { qcom,battery-data = <&qrd_batterydata>; + qcom,fg-jeita-thresholds = <0 5 55 55>; }; &pmi8998_haptics { status = "okay"; }; +&pmi8998_wled { + qcom,led-strings-list = [00 01]; + qcom,fs-curr-ua = <20000>; +}; + &tlmm { /* add pingrp for touchscreen */ pmx_ts_rst_active { diff --git a/arch/arm/boot/dts/qcom/msm8998-qrd-vr1.dtsi b/arch/arm/boot/dts/qcom/msm8998-qrd-vr1.dtsi index 7b67bdb7243b..c67bbcefad80 100644 --- a/arch/arm/boot/dts/qcom/msm8998-qrd-vr1.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-qrd-vr1.dtsi @@ -196,6 +196,7 @@ &pmi8998_fg { qcom,battery-data = <&qrd_batterydata>; + qcom,fg-jeita-thresholds = <0 5 55 55>; }; &pmi8998_haptics { diff --git a/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-evt3.dts b/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-evt3.dts new file mode 100644 index 000000000000..51ff3888bc3d --- /dev/null +++ b/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-evt3.dts @@ -0,0 +1,23 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +/dts-v1/; + +#include "msm8998-v2.dtsi" +#include "msm8998-qrd-skuk.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM 8998 V2 SKUK EVT3"; + compatible = "qcom,msm8998-qrd", "qcom,msm8998", "qcom,qrd"; + qcom,board-id = <0x02000b 0x10>; +}; diff --git a/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-hdk.dts b/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-hdk.dts new file mode 100644 index 000000000000..c2b70224ed2c --- /dev/null +++ b/arch/arm/boot/dts/qcom/msm8998-v2-qrd-skuk-hdk.dts @@ -0,0 +1,23 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +/dts-v1/; + +#include "msm8998-v2.dtsi" +#include "msm8998-qrd-skuk.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM 8998 SKUK HDK"; + compatible = "qcom,msm8998-qrd", "qcom,msm8998", "qcom,qrd"; + qcom,board-id = <0x06000b 0x10>; +}; diff --git a/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dts b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dts index 44c4b74dd696..3de548ed1446 100644 --- a/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dts +++ b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dts @@ -118,6 +118,11 @@ core-supply = <&pmfalcon_l1>; }; +&sdhc_2 { + vdd-supply = <&pm2falcon_l5>; + vdd-io-supply = <&pm2falcon_l2>; +}; + &pm2falcon_gpios { /* GPIO 7 for VOL_UP */ gpio@c600 { diff --git a/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dtsi b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dtsi index dcfb851cd116..9740e9c1b168 100644 --- a/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-v2.1-interposer-msmfalcon-qrd.dtsi @@ -72,30 +72,6 @@ status = "ok"; }; -&sdc2_cd_on { - mux { - pins = "gpio54"; - }; - - config { - pins = "gpio54"; - /delete-property/ bias-pull-up; - bias-disable; - }; -}; - -&sdc2_cd_off { - mux { - pins = "gpio54"; - }; - - config { - pins = "gpio54"; - /delete-property/ bias-pull-up; - bias-disable; - }; -}; - &sdhc_2 { vdd-supply = <&pm2falcon_l5>; qcom,vdd-voltage-level = <2950000 2950000>; @@ -113,7 +89,37 @@ 50000000 100000000 200000000>; qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50", "SDR104"; - cd-gpios = <&tlmm 54 0x0>; + cd-gpios = <&tlmm 95 0x0>; status = "ok"; }; + + +&i2c_5 { + status = "okay"; + synaptics@20 { + compatible = "synaptics,dsx"; + reg = <0x20>; + interrupt-parent = <&tlmm>; + interrupts = <125 0x2008>; + avdd-supply = <&pm2falcon_l3>; + vdd-supply = <&pmfalcon_l11>; + synaptics,vdd-voltage = <1880000 1880000>; + synaptics,avdd-voltage = <3000000 3008000>; + synaptics,vdd-current = <40000>; + synaptics,avdd-current = <20000>; + /* pins used by touchscreen */ + pinctrl-names = "pmx_ts_active", "pmx_ts_suspend", + "pmx_ts_release"; + pinctrl-0 = <&ts_int_active &ts_reset_active>; + pinctrl-1 = <&ts_int_suspend1 &ts_reset_suspend1>; + pinctrl-2 = <&ts_release>; + synaptics,display-coords = <0 0 1439 2559>; + synaptics,panel-coords = <0 0 1439 2779>; + synaptics,irq-gpio = <&tlmm 125 0x2008>; + synaptics,reset-gpio = <&tlmm 89 0x0>; + synaptics,i2c-pull-up; + synaptics,disable-gpios; + synaptics,button-map = <139 172 158>; + }; +}; diff --git a/arch/arm/boot/dts/qcom/msm8998.dtsi b/arch/arm/boot/dts/qcom/msm8998.dtsi index 8ce9e7c22761..ab835bf3aba1 100644 --- a/arch/arm/boot/dts/qcom/msm8998.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998.dtsi @@ -2825,6 +2825,11 @@ reg = <0x6b0 32>; }; + kaslr_offset@6d0 { + compatible = "qcom,msm-imem-kaslr_offset"; + reg = <0x6d0 12>; + }; + pil@94c { compatible = "qcom,msm-imem-pil"; reg = <0x94c 200>; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-audio.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-audio.dtsi index bf367944f50c..df42ba124641 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-audio.dtsi +++ b/arch/arm/boot/dts/qcom/msmfalcon-audio.dtsi @@ -15,12 +15,13 @@ #include "msmfalcon-lpi.dtsi" &slim_aud { - msm_dai_slim { + status = "okay"; + dai_slim: msm_dai_slim { compatible = "qcom,msm-dai-slim"; elemental-addr = [ff ff ff fe 17 02]; }; - tasha_codec { + wcd9335: tasha_codec { compatible = "qcom,tasha-slim-pgd"; elemental-addr = [00 01 a0 01 17 02]; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-cdp.dts b/arch/arm/boot/dts/qcom/msmfalcon-cdp.dts index 76fa0bbc0fe8..ddcea8653983 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-cdp.dts +++ b/arch/arm/boot/dts/qcom/msmfalcon-cdp.dts @@ -17,7 +17,9 @@ #include "msmfalcon-cdp.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM FALCON CDP"; + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM2FALCON CDP"; compatible = "qcom,msmfalcon-cdp", "qcom,msmfalcon", "qcom,cdp"; qcom,board-id = <1 0>; + qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>, + <0x0001001b 0x0201011a 0x0 0x0>; }; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-cdp.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-cdp.dtsi index 9f057b9444c1..e1306bd78837 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-cdp.dtsi +++ b/arch/arm/boot/dts/qcom/msmfalcon-cdp.dtsi @@ -42,6 +42,52 @@ status = "ok"; }; +&mdss_mdp { + qcom,mdss-pref-prim-intf = "dsi"; +}; + +&mdss_dsi { + hw-config = "split_dsi"; +}; + +&mdss_dsi0 { + qcom,dsi-pref-prim-pan = <&dsi_dual_nt35597_truly_video>; + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; + pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; + qcom,platform-reset-gpio = <&tlmm 53 0>; + qcom,platform-te-gpio = <&tlmm 59 0>; +}; + +&mdss_dsi1 { + qcom,dsi-pref-prim-pan = <&dsi_dual_nt35597_truly_video>; + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; + pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; + qcom,platform-reset-gpio = <&tlmm 53 0>; + qcom,platform-te-gpio = <&tlmm 59 0>; +}; + +&pm2falcon_wled { + qcom,led-strings-list = [01 02]; +}; + +&dsi_dual_nt35597_truly_video { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-mode-sel-gpio-state = "dual_port"; + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; +}; + +&dsi_dual_nt35597_truly_cmd { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-mode-sel-gpio-state = "dual_port"; + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; +}; + &soc { qcom,msm-ssc-sensors { compatible = "qcom,msm-ssc-sensors"; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-cdp.dts b/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-cdp.dts index 108328bd91f0..ee3255ebe9f8 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-cdp.dts +++ b/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-cdp.dts @@ -17,7 +17,57 @@ #include "msmfalcon-cdp.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM FALCON Int. Audio Codec CDP"; + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM2FALCON Int. Audio Codec CDP"; compatible = "qcom,msmfalcon-cdp", "qcom,msmfalcon", "qcom,cdp"; qcom,board-id = <1 1>; + qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>, + <0x0001001b 0x0201011a 0x0 0x0>; +}; + +&slim_aud { + status = "disabled"; +}; + +&dai_slim { + status = "disabled"; +}; + +&wcd9335 { + status = "disabled"; +}; + +&wcd934x_cdc { + status = "disabled"; +}; + +&clock_audio { + status = "disabled"; +}; + +&wcd_rst_gpio { + status = "disabled"; +}; + +&wcd9xxx_intc { + status = "disabled"; +}; + +&tasha_snd { + status = "disabled"; +}; + +&tavil_snd { + status = "disabled"; +}; + +&int_codec { + status = "okay"; +}; + +&pmic_analog_codec { + status = "okay"; +}; + +&msm_sdw_codec { + status = "okay"; }; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-mtp.dts b/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-mtp.dts index 3697ee8f97a0..59611ab3e5ff 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-mtp.dts +++ b/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-mtp.dts @@ -17,7 +17,58 @@ #include "msmfalcon-mtp.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM FALCON Int. Audio Codec MTP"; + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM2FALCON Int. Audio Codec MTP"; compatible = "qcom,msmfalcon-mtp", "qcom,msmfalcon", "qcom,mtp"; qcom,board-id = <8 1>; + qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>, + <0x0001001b 0x0201011a 0x0 0x0>; +}; + +&slim_aud { + status = "disabled"; +}; + +&dai_slim { + status = "disabled"; +}; + +&wcd9335 { + status = "disabled"; +}; + +&wcd934x_cdc { + status = "disabled"; +}; + +&clock_audio { + status = "disabled"; +}; + +&wcd_rst_gpio { + status = "disabled"; +}; + +&wcd9xxx_intc { + status = "disabled"; +}; + +&tasha_snd { + status = "disabled"; +}; + +&tavil_snd { + status = "disabled"; +}; + +&int_codec { + qcom,model = "msmfalcon-snd-card-mtp"; + status = "okay"; +}; + +&pmic_analog_codec { + status = "okay"; +}; + +&msm_sdw_codec { + status = "okay"; }; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-pm3falcon-cdp.dts b/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-pm3falcon-cdp.dts new file mode 100644 index 000000000000..fe91109a4a07 --- /dev/null +++ b/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-pm3falcon-cdp.dts @@ -0,0 +1,25 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +/dts-v1/; + +#include "msmfalcon.dtsi" +#include "msmfalcon-cdp.dtsi" +#include "msm-pm3falcon.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM3FALCON Int. Audio Codec CDP"; + compatible = "qcom,msmfalcon-cdp", "qcom,msmfalcon", "qcom,cdp"; + qcom,board-id = <1 1>; + qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-pm3falcon-mtp.dts b/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-pm3falcon-mtp.dts new file mode 100644 index 000000000000..0653e898ec7d --- /dev/null +++ b/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-pm3falcon-mtp.dts @@ -0,0 +1,25 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +/dts-v1/; + +#include "msmfalcon.dtsi" +#include "msmfalcon-mtp.dtsi" +#include "msm-pm3falcon.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM3FALCON Int. Audio Codec MTP"; + compatible = "qcom,msmfalcon-mtp", "qcom,msmfalcon", "qcom,mtp"; + qcom,board-id = <8 1>; + qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-pm3falcon-rcm.dts b/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-pm3falcon-rcm.dts new file mode 100644 index 000000000000..cb2b2239588d --- /dev/null +++ b/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-pm3falcon-rcm.dts @@ -0,0 +1,25 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +/dts-v1/; + +#include "msmfalcon.dtsi" +#include "msmfalcon-cdp.dtsi" +#include "msm-pm3falcon.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM3FALCON Int. Audio Codec RCM"; + compatible = "qcom,msmfalcon-cdp", "qcom,msmfalcon", "qcom,cdp"; + qcom,board-id = <21 1>; + qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-rcm.dts b/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-rcm.dts index bbdc41b97574..1d67fe1129c7 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-rcm.dts +++ b/arch/arm/boot/dts/qcom/msmfalcon-internal-codec-rcm.dts @@ -17,7 +17,57 @@ #include "msmfalcon-cdp.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM FALCON Int. Audio Codec RCM"; + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM2FALCON Int. Audio Codec RCM"; compatible = "qcom,msmfalcon-cdp", "qcom,msmfalcon", "qcom,cdp"; qcom,board-id = <21 1>; + qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>, + <0x0001001b 0x0201011a 0x0 0x0>; +}; + +&slim_aud { + status = "disabled"; +}; + +&dai_slim { + status = "disabled"; +}; + +&wcd9335 { + status = "disabled"; +}; + +&wcd934x_cdc { + status = "disabled"; +}; + +&clock_audio { + status = "disabled"; +}; + +&wcd_rst_gpio { + status = "disabled"; +}; + +&wcd9xxx_intc { + status = "disabled"; +}; + +&tasha_snd { + status = "disabled"; +}; + +&tavil_snd { + status = "disabled"; +}; + +&int_codec { + status = "okay"; +}; + +&pmic_analog_codec { + status = "okay"; +}; + +&msm_sdw_codec { + status = "okay"; }; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-mdss-panels.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-mdss-panels.dtsi new file mode 100644 index 000000000000..28e5f6ba8b45 --- /dev/null +++ b/arch/arm/boot/dts/qcom/msmfalcon-mdss-panels.dtsi @@ -0,0 +1,83 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "dsi-panel-sim-video.dtsi" +#include "dsi-panel-sim-dualmipi-video.dtsi" +#include "dsi-panel-nt35597-truly-dualmipi-wqxga-video.dtsi" +#include "dsi-panel-nt35597-truly-dualmipi-wqxga-cmd.dtsi" + +&soc { + dsi_panel_pwr_supply: dsi_panel_pwr_supply { + #address-cells = <1>; + #size-cells = <0>; + + qcom,panel-supply-entry@0 { + reg = <0>; + qcom,supply-name = "wqhd-vddio"; + qcom,supply-min-voltage = <1880000>; + qcom,supply-max-voltage = <1950000>; + qcom,supply-enable-load = <32000>; + qcom,supply-disable-load = <80>; + }; + + qcom,panel-supply-entry@1 { + reg = <1>; + qcom,supply-name = "lab"; + qcom,supply-min-voltage = <4600000>; + qcom,supply-max-voltage = <6000000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + }; + + qcom,panel-supply-entry@2 { + reg = <2>; + qcom,supply-name = "ibb"; + qcom,supply-min-voltage = <4600000>; + qcom,supply-max-voltage = <6000000>; + qcom,supply-enable-load = <100000>; + qcom,supply-disable-load = <100>; + qcom,supply-post-on-sleep = <10>; + }; + }; +}; + +&soc { + dsi_panel_pwr_supply_no_labibb: dsi_panel_pwr_supply_no_labibb { + #address-cells = <1>; + #size-cells = <0>; + + qcom,panel-supply-entry@0 { + reg = <0>; + qcom,supply-name = "wqhd-vddio"; + qcom,supply-min-voltage = <1880000>; + qcom,supply-max-voltage = <1950000>; + qcom,supply-enable-load = <32000>; + qcom,supply-disable-load = <80>; + }; + }; +}; + +&dsi_dual_nt35597_truly_video { + qcom,mdss-dsi-panel-timings-8996 = [23 1e 07 08 05 03 04 a0 + 23 1e 07 08 05 03 04 a0 + 23 1e 07 08 05 03 04 a0 + 23 1e 07 08 05 03 04 a0 + 23 18 07 08 04 03 04 a0]; +}; + +&dsi_dual_nt35597_truly_cmd { + qcom,mdss-dsi-panel-timings-8996 = [23 1e 07 08 05 03 04 a0 + 23 1e 07 08 05 03 04 a0 + 23 1e 07 08 05 03 04 a0 + 23 1e 07 08 05 03 04 a0 + 23 18 07 08 04 03 04 a0]; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-mdss-pll.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-mdss-pll.dtsi new file mode 100644 index 000000000000..61baf6aff4b1 --- /dev/null +++ b/arch/arm/boot/dts/qcom/msmfalcon-mdss-pll.dtsi @@ -0,0 +1,82 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +&soc { + mdss_dsi0_pll: qcom,mdss_dsi_pll@c994400 { + compatible = "qcom,mdss_dsi_pll_msmfalcon"; + status = "ok"; + label = "MDSS DSI 0 PLL"; + cell-index = <0>; + #clock-cells = <1>; + + reg = <0xc994400 0x588>, + <0xc8c2300 0x8>; + reg-names = "pll_base", "gdsc_base"; + + gdsc-supply = <&gdsc_mdss>; + + clocks = <&clock_mmss MMSS_MDSS_AHB_CLK>; + clock-names = "iface_clk"; + clock-rate = <0>; + qcom,dsi-pll-ssc-en; + qcom,dsi-pll-ssc-mode = "down-spread"; + + qcom,platform-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,platform-supply-entry@0 { + reg = <0>; + qcom,supply-name = "gdsc"; + qcom,supply-min-voltage = <0>; + qcom,supply-max-voltage = <0>; + qcom,supply-enable-load = <0>; + qcom,supply-disable-load = <0>; + }; + + }; + }; + + mdss_dsi1_pll: qcom,mdss_dsi_pll@c996400 { + compatible = "qcom,mdss_dsi_pll_msmfalcon"; + status = "ok"; + label = "MDSS DSI 1 PLL"; + cell-index = <1>; + #clock-cells = <1>; + + reg = <0xc996400 0x588>, + <0xc8c2300 0x8>; + reg-names = "pll_base", "gdsc_base"; + + gdsc-supply = <&gdsc_mdss>; + + clocks = <&clock_mmss MMSS_MDSS_AHB_CLK>; + clock-names = "iface_clk"; + clock-rate = <0>; + qcom,dsi-pll-ssc-en; + qcom,dsi-pll-ssc-mode = "down-spread"; + + qcom,platform-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,platform-supply-entry@0 { + reg = <0>; + qcom,supply-name = "gdsc"; + qcom,supply-min-voltage = <0>; + qcom,supply-max-voltage = <0>; + qcom,supply-enable-load = <0>; + qcom,supply-disable-load = <0>; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-mdss.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-mdss.dtsi new file mode 100644 index 000000000000..f7e1b053dbb2 --- /dev/null +++ b/arch/arm/boot/dts/qcom/msmfalcon-mdss.dtsi @@ -0,0 +1,579 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +&soc { + mdss_mdp: qcom,mdss_mdp@c900000 { + compatible = "qcom,mdss_mdp"; + status = "ok"; + reg = <0x0c900000 0x90000>, + <0x0c9b0000 0x1040>; + reg-names = "mdp_phys", "vbif_phys"; + interrupts = <0 83 0>; + interrupt-controller; + #interrupt-cells = <1>; + vdd-supply = <&gdsc_mdss>; + + /* Bus Scale Settings */ + qcom,msm-bus,name = "mdss_mdp"; + qcom,msm-bus,num-cases = <3>; + qcom,msm-bus,num-paths = <2>; + qcom,msm-bus,vectors-KBps = + <22 512 0 0>, <23 512 0 0>, + <22 512 0 6400000>, <23 512 0 6400000>, + <22 512 0 6400000>, <23 512 0 6400000>; + + /* Fudge factors */ + qcom,mdss-ab-factor = <1 1>; /* 1 time */ + qcom,mdss-ib-factor = <1 1>; /* 1 time */ + qcom,mdss-clk-factor = <105 100>; /* 1.05 times */ + + qcom,max-mixer-width = <2560>; + qcom,max-pipe-width = <2560>; + + qcom,max-dest-scaler-input-width = <2048>; + qcom,max-dest-scaler-output-width = <2560>; + + /* VBIF QoS remapper settings*/ + qcom,mdss-vbif-qos-rt-setting = <1 2 2 2>; + qcom,vbif-settings = <0x00ac 0x00000040>, + <0x00d0 0x00001010>; /* v1 only */ + + qcom,mdss-has-panic-ctrl; + qcom,mdss-per-pipe-panic-luts = <0x000f>, + <0xffff>, + <0xfffc>, + <0xff00>; + + qcom,mdss-mdp-reg-offset = <0x00001000>; + qcom,max-bandwidth-low-kbps = <6600000>; + qcom,max-bandwidth-high-kbps = <6600000>; + qcom,max-bandwidth-per-pipe-kbps = <3100000>; + qcom,max-clk-rate = <412500000>; + qcom,mdss-default-ot-rd-limit = <32>; + qcom,mdss-default-ot-wr-limit = <40>; + qcom,mdss-dram-channels = <2>; + + /* Bandwidth limit settings */ + qcom,max-bw-settings = <1 6600000>, /* Default */ + <2 4500000>; /* Camera */ + + qcom,mdss-pipe-vig-off = <0x00005000 0x00007000>; + qcom,mdss-pipe-dma-off = <0x00025000 0x00027000 + 0x00029000>; + qcom,mdss-pipe-cursor-off = <0x00035000>; + + qcom,mdss-pipe-vig-xin-id = <0 4>; + qcom,mdss-pipe-dma-xin-id = <1 5 9>; + qcom,mdss-pipe-cursor-xin-id = <2>; + + /* These Offsets are relative to + * "mdp_phys + mdp-reg-offset" address + */ + qcom,mdss-pipe-vig-clk-ctrl-offsets = <0x2ac 0 0>, + <0x2b4 0 0>; + qcom,mdss-pipe-dma-clk-ctrl-offsets = <0x2ac 8 12>, + <0x2b4 8 12>, + <0x2c4 8 12>; + qcom,mdss-pipe-cursor-clk-ctrl-offsets = <0x3a8 16 15>; + + qcom,mdss-ctl-off = <0x00002000 0x00002200 0x00002400 + 0x00002600 0x00002800>; + qcom,mdss-mixer-intf-off = <0x00045000 0x00046000 + 0x00047000 0x0004a000>; + qcom,mdss-dspp-off = <0x00055000 0x00057000>; + qcom,mdss-wb-off = <0x00066000>; + qcom,mdss-intf-off = <0x0006b000 0x0006b800 + 0x0006c000 0x0006c800>; + qcom,mdss-pingpong-off = <0x00071000 0x00071800 + 0x00072000 0x00072800>; + qcom,mdss-slave-pingpong-off = <0x00073000>; + qcom,mdss-ppb-ctl-off = <0x00000330 0x00000338 0x00000370 + 0x00000374> ; + qcom,mdss-ppb-cfg-off = <0x00000334 0x0000033C>; + qcom,mdss-has-pingpong-split; + qcom,mdss-has-separate-rotator; + + qcom,mdss-ad-off = <0x0079000 0x00079800>; + qcom,mdss-cdm-off = <0x0007a200>; + qcom,mdss-dsc-off = <0x00081000 0x00081400>; + qcom,mdss-wfd-mode = "intf"; + qcom,mdss-has-source-split; + qcom,mdss-highest-bank-bit = <0x1>; + qcom,mdss-has-decimation; + qcom,mdss-idle-power-collapse-enabled; + clocks = <&clock_mmss MMSS_MNOC_AHB_CLK>, + <&clock_mmss MMSS_MDSS_AHB_CLK>, + <&clock_mmss MMSS_MDSS_AXI_CLK>, + <&clock_mmss MDP_CLK_SRC>, + <&clock_mmss MMSS_MDSS_MDP_CLK>, + <&clock_mmss MMSS_MDSS_VSYNC_CLK>, + <&clock_mmss MDP_CLK_SRC>; + clock-names = "mnoc_clk", "iface_clk", "bus_clk", + "core_clk_src", "core_clk", "vsync_clk", + "lut_clk"; + + qcom,mdp-settings = <0x01190 0x00000000>, + <0x012ac 0xc0000ccc>, + <0x012b4 0xc0000ccc>, + <0x012bc 0x00cccccc>, + <0x012c4 0x000000cc>, + <0x013a8 0x0cccc0c0>, + <0x013b0 0xccccc0c0>, + <0x013b8 0xcccc0000>, + <0x013d0 0x00cc0000>, + <0x0506c 0x00000000>, + <0x0706c 0x00000000>, + <0x0906c 0x00000000>, + <0x0b06c 0x00000000>, + <0x1506c 0x00000000>, + <0x1706c 0x00000000>, + <0x1906c 0x00000000>, + <0x1b06c 0x00000000>, + <0x2506c 0x00000000>, + <0x2706c 0x00000000>; + + qcom,regs-dump-mdp = <0x01000 0x01458>, + <0x02000 0x02094>, + <0x02200 0x02294>, + <0x02400 0x02494>, + <0x02600 0x02694>, + <0x02800 0x02894>, + <0x05000 0x05154>, + <0x05a00 0x05b00>, + <0x07000 0x07154>, + <0x07a00 0x07b00>, + <0x25000 0x25184>, + <0x27000 0x27184>, + <0x29000 0x29184>, + <0x35000 0x35150>, + <0x45000 0x452bc>, + <0x46000 0x462bc>, + <0x47000 0x472bc>, + <0x4a000 0x4a2bc>, + <0x55000 0x5522c>, + <0x57000 0x5722c>, + <0x66000 0x662c0>, + <0x6b000 0x6b268>, + <0x6b800 0x6ba68>, + <0x6c000 0x6c268>, + <0x71000 0x710d4>, + <0x71800 0x718d4>, + <0x73000 0x730d4>, + <0x81000 0x81140>, + <0x81400 0x81540>; + + qcom,regs-dump-names-mdp = "MDP", + "CTL_0", "CTL_1", "CTL_2", "CTL_3", "CTL_4", + "VIG0_SSPP", "VIG0", "VIG1_SSPP", "VIG1", + "DMA0_SSPP", "DMA1_SSPP","DMA2_SSPP", + "CURSOR0_SSPP", + "LAYER_0", "LAYER_1", "LAYER_2", + "LAYER_5", + "DSPP_0", "DSPP_1", + "WB_2", + "INTF_0", "INTF_1", "INTF_2", + "PP_0", "PP_1", "PP_4", + "DSC_0", "DSC_1"; + + /* buffer parameters to calculate prefill bandwidth */ + qcom,mdss-prefill-outstanding-buffer-bytes = <0>; + qcom,mdss-prefill-y-buffer-bytes = <0>; + qcom,mdss-prefill-scaler-buffer-lines-bilinear = <2>; + qcom,mdss-prefill-scaler-buffer-lines-caf = <4>; + qcom,mdss-prefill-post-scaler-buffer-pixels = <2560>; + qcom,mdss-prefill-pingpong-buffer-pixels = <5120>; + + qcom,mdss-pp-offsets { + qcom,mdss-sspp-mdss-igc-lut-off = <0x2000>; + qcom,mdss-sspp-vig-pcc-off = <0x1b00>; + qcom,mdss-sspp-rgb-pcc-off = <0x380>; + qcom,mdss-sspp-dma-pcc-off = <0x380>; + qcom,mdss-lm-pgc-off = <0x3c0>; + qcom,mdss-dspp-gamut-off = <0x1600>; + qcom,mdss-dspp-pcc-off = <0x1700>; + qcom,mdss-dspp-pgc-off = <0x17c0>; + }; + + qcom,mdss-scaler-offsets { + qcom,mdss-vig-scaler-off = <0xa00>; + qcom,mdss-vig-scaler-lut-off = <0xb00>; + qcom,mdss-has-dest-scaler; + qcom,mdss-dest-block-off = <0x00061000>; + qcom,mdss-dest-scaler-off = <0x800 0x1000>; + qcom,mdss-dest-scaler-lut-off = <0x900 0x1100>; + }; + + smmu_mdp_unsec: qcom,smmu_mdp_unsec_cb { + compatible = "qcom,smmu_mdp_unsec"; + iommus = <&mmss_bimc_smmu 0>; + gdsc-mmagic-mdss-supply = <&gdsc_bimc_smmu>; + clocks = <&clock_rpmcc MMSSNOC_AXI_CLK>, + <&clock_mmss MMSS_MNOC_AHB_CLK>, + <&clock_mmss MMSS_BIMC_SMMU_AHB_CLK>, + <&clock_mmss MMSS_BIMC_SMMU_AXI_CLK>; + clock-names = "mmss_noc_axi_clk", + "mmss_noc_ahb_clk", + "mmss_smmu_ahb_clk", + "mmss_smmu_axi_clk"; + }; + + smmu_mdp_sec: qcom,smmu_mdp_sec_cb { + compatible = "qcom,smmu_mdp_sec"; + iommus = <&mmss_bimc_smmu 1>; + gdsc-mmagic-mdss-supply = <&gdsc_bimc_smmu>; + clocks = <&clock_rpmcc MMSSNOC_AXI_CLK>, + <&clock_mmss MMSS_MNOC_AHB_CLK>, + <&clock_mmss MMSS_BIMC_SMMU_AHB_CLK>, + <&clock_mmss MMSS_BIMC_SMMU_AXI_CLK>; + clock-names = "mmss_noc_axi_clk", + "mmss_noc_ahb_clk", + "mmss_smmu_ahb_clk", + "mmss_smmu_axi_clk"; + }; + + mdss_fb0: qcom,mdss_fb_primary { + cell-index = <0>; + compatible = "qcom,mdss-fb"; + }; + + mdss_fb1: qcom,mdss_fb_wfd { + cell-index = <1>; + compatible = "qcom,mdss-fb"; + }; + + mdss_fb2: qcom,mdss_fb_dp { + cell-index = <2>; + compatible = "qcom,mdss-fb"; + qcom,mdss-intf = <&mdss_dp_ctrl>; + }; + + }; + + mdss_dsi: qcom,mdss_dsi@0 { + compatible = "qcom,mdss-dsi"; + #address-cells = <1>; + #size-cells = <1>; + gdsc-supply = <&gdsc_mdss>; + vdda-1p2-supply = <&pmfalcon_l1>; + vdda-0p9-supply = <&pm2falcon_l1>; + ranges = <0xc994000 0xc994000 0x400 + 0xc994400 0xc994400 0x588 + 0xc828000 0xc828000 0xac + 0xc996000 0xc996000 0x400 + 0xc996400 0xc996400 0x588 + 0xc828000 0xc828000 0xac>; + + /* Bus Scale Settings */ + qcom,msm-bus,name = "mdss_dsi"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <22 512 0 0>, + <22 512 0 1000>; + + qcom,mmss-ulp-clamp-ctrl-offset = <0x14>; + + clocks = <&clock_mmss MMSS_MDSS_MDP_CLK>, + <&clock_mmss MMSS_MNOC_AHB_CLK>, + <&clock_mmss MMSS_MDSS_AHB_CLK>, + <&clock_mmss MMSS_MDSS_AXI_CLK>, + <&clock_mmss MMSS_MISC_AHB_CLK>, + <&mdss_dsi0_pll BYTE0_MUX_CLK>, + <&mdss_dsi1_pll BYTE1_MUX_CLK>, + <&mdss_dsi0_pll PIX0_MUX_CLK>, + <&mdss_dsi1_pll PIX1_MUX_CLK>; + clock-names = "mdp_core_clk", + "mnoc_clk", "iface_clk", + "bus_clk", "core_mmss_clk", + "ext_byte0_clk", "ext_byte1_clk", + "ext_pixel0_clk", "ext_pixel1_clk"; + + qcom,core-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,core-supply-entry@0 { + reg = <0>; + qcom,supply-name = "gdsc"; + qcom,supply-min-voltage = <0>; + qcom,supply-max-voltage = <0>; + qcom,supply-enable-load = <0>; + qcom,supply-disable-load = <0>; + }; + }; + + qcom,ctrl-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,ctrl-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdda-1p2"; + qcom,supply-min-voltage = <1200000>; + qcom,supply-max-voltage = <1250000>; + qcom,supply-enable-load = <12560>; + qcom,supply-disable-load = <4>; + }; + }; + + qcom,phy-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,phy-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdda-0p9"; + qcom,supply-min-voltage = <880000>; + qcom,supply-max-voltage = <925000>; + qcom,supply-enable-load = <73400>; + qcom,supply-disable-load = <32>; + }; + }; + + mdss_dsi0: qcom,mdss_dsi_ctrl0@c994000 { + compatible = "qcom,mdss-dsi-ctrl"; + label = "MDSS DSI CTRL->0"; + cell-index = <0>; + reg = <0xc994000 0x400>, + <0xc994400 0x588>, + <0xc828000 0xac>; + reg-names = "dsi_ctrl", "dsi_phy", "mmss_misc_phys"; + + qcom,timing-db-mode; + wqhd-vddio-supply = <&pmfalcon_l11>; + lab-supply = <&lcdb_ldo_vreg>; + ibb-supply = <&lcdb_ncp_vreg>; + qcom,mdss-mdp = <&mdss_mdp>; + qcom,mdss-fb-map = <&mdss_fb0>; + + clocks = <&clock_mmss MMSS_MDSS_BYTE0_CLK>, + <&clock_mmss MMSS_MDSS_PCLK0_CLK>, + <&clock_mmss MMSS_MDSS_ESC0_CLK>, + <&clock_mmss BYTE0_CLK_SRC>, + <&clock_mmss PCLK0_CLK_SRC>, + <&clock_mmss MMSS_MDSS_BYTE0_INTF_CLK>; + clock-names = "byte_clk", "pixel_clk", "core_clk", + "byte_clk_rcg", "pixel_clk_rcg", + "byte_intf_clk"; + + qcom,platform-strength-ctrl = [ff 06 + ff 06 + ff 06 + ff 06 + ff 00]; + qcom,platform-regulator-settings = [1d + 1d 1d 1d 1d]; + qcom,platform-lane-config = [00 00 10 0f + 00 00 10 0f + 00 00 10 0f + 00 00 10 0f + 00 00 10 8f]; + }; + + mdss_dsi1: qcom,mdss_dsi_ctrl1@c996000 { + compatible = "qcom,mdss-dsi-ctrl"; + label = "MDSS DSI CTRL->1"; + cell-index = <1>; + reg = <0xc996000 0x400>, + <0xc996400 0x588>, + <0xc828000 0xac>; + reg-names = "dsi_ctrl", "dsi_phy", "mmss_misc_phys"; + + qcom,timing-db-mode; + wqhd-vddio-supply = <&pmfalcon_l11>; + lab-supply = <&lcdb_ldo_vreg>; + ibb-supply = <&lcdb_ncp_vreg>; + qcom,mdss-mdp = <&mdss_mdp>; + qcom,mdss-fb-map = <&mdss_fb0>; + + clocks = <&clock_mmss MMSS_MDSS_BYTE1_CLK>, + <&clock_mmss MMSS_MDSS_PCLK1_CLK>, + <&clock_mmss MMSS_MDSS_ESC1_CLK>, + <&clock_mmss BYTE1_CLK_SRC>, + <&clock_mmss PCLK1_CLK_SRC>, + <&clock_mmss MMSS_MDSS_BYTE1_INTF_CLK>; + clock-names = "byte_clk", "pixel_clk", "core_clk", + "byte_clk_rcg", "pixel_clk_rcg", + "byte_intf_clk"; + + qcom,platform-strength-ctrl = [ff 06 + ff 06 + ff 06 + ff 06 + ff 00]; + qcom,platform-regulator-settings = [1d + 1d 1d 1d 1d]; + qcom,platform-lane-config = [00 00 10 0f + 00 00 10 0f + 00 00 10 0f + 00 00 10 0f + 00 00 10 8f]; + }; + }; + + qcom,mdss_wb_panel { + compatible = "qcom,mdss_wb"; + qcom,mdss_pan_res = <640 480>; + qcom,mdss_pan_bpp = <24>; + qcom,mdss-fb-map = <&mdss_fb1>; + }; + + msm_ext_disp: qcom,msm_ext_disp { + status = "disabled"; + compatible = "qcom,msm-ext-disp"; + + ext_disp_audio_codec: qcom,msm-ext-disp-audio-codec-rx { + compatible = "qcom,msm-ext-disp-audio-codec-rx"; + qcom,msm_ext_disp = <&msm_ext_disp>; + }; + }; + + mdss_dp_ctrl: qcom,dp_ctrl@c990000 { + status = "disabled"; + cell-index = <0>; + compatible = "qcom,mdss-dp"; + qcom,mdss-fb-map = <&mdss_fb2>; + + gdsc-supply = <&gdsc_mdss>; + vdda-1p2-supply = <&pmfalcon_l1>; + vdda-0p9-supply = <&pm2falcon_l1>; + + reg = <0xc990000 0xa84>, + <0xc011000 0x910>, + <0x1fcb200 0x050>, + <0xc8c2200 0x1a0>, + <0x780000 0x621c>, + <0xc9e1000 0x02c>; + reg-names = "dp_ctrl", "dp_phy", "tcsr_regs", "dp_mmss_cc", + "qfprom_physical","hdcp_physical"; + + qcom,msm_ext_disp = <&msm_ext_disp>; + + qcom,core-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,core-supply-entry@0 { + reg = <0>; + qcom,supply-name = "gdsc"; + qcom,supply-min-voltage = <0>; + qcom,supply-max-voltage = <0>; + qcom,supply-enable-load = <0>; + qcom,supply-disable-load = <0>; + }; + }; + + qcom,ctrl-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,ctrl-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdda-1p2"; + qcom,supply-min-voltage = <1200000>; + qcom,supply-max-voltage = <1250000>; + qcom,supply-enable-load = <12560>; + qcom,supply-disable-load = <4>; + }; + }; + + qcom,phy-supply-entries { + #address-cells = <1>; + #size-cells = <0>; + + qcom,phy-supply-entry@0 { + reg = <0>; + qcom,supply-name = "vdda-0p9"; + qcom,supply-min-voltage = <880000>; + qcom,supply-max-voltage = <925000>; + qcom,supply-enable-load = <73400>; + qcom,supply-disable-load = <32>; + }; + }; + }; + + mdss_rotator: qcom,mdss_rotator { + compatible = "qcom,sde_rotator"; + reg = <0x0c900000 0xab100>, + <0x0c9b0000 0x1040>; + reg-names = "mdp_phys", + "rot_vbif_phys"; + + qcom,mdss-rot-mode = <1>; + qcom,mdss-highest-bank-bit = <0x2>; + + /* Bus Scale Settings */ + qcom,msm-bus,name = "mdss_rotator"; + qcom,msm-bus,num-cases = <3>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = + <22 512 0 0>, + <22 512 0 6400000>, + <22 512 0 6400000>; + + rot-vdd-supply = <&gdsc_mdss>; + qcom,supply-names = "rot-vdd"; + + clocks = <&clock_mmss MMSS_MNOC_AHB_CLK>, + <&clock_mmss MMSS_MDSS_AHB_CLK>, + <&clock_mmss ROT_CLK_SRC>, + <&clock_mmss MMSS_MDSS_ROT_CLK>, + <&clock_mmss MMSS_MDSS_AXI_CLK>; + clock-names = "mnoc_clk", + "iface_clk", "rot_core_clk", + "rot_clk", "axi_clk"; + + interrupt-parent = <&mdss_mdp>; + interrupts = <2 0>; + + /* VBIF QoS remapper settings*/ + qcom,mdss-rot-vbif-qos-setting = <1 1 1 1>; + + qcom,mdss-default-ot-rd-limit = <32>; + qcom,mdss-default-ot-wr-limit = <40>; + + smmu_rot_unsec: qcom,smmu_rot_unsec_cb { + compatible = "qcom,smmu_sde_rot_unsec"; + iommus = <&mmss_bimc_smmu 0xe00>; + gdsc-mdss-supply = <&gdsc_bimc_smmu>; + + clocks = <&clock_rpmcc MMSSNOC_AXI_CLK>, + <&clock_mmss MMSS_MNOC_AHB_CLK>, + <&clock_mmss MMSS_BIMC_SMMU_AHB_CLK>, + <&clock_mmss MMSS_BIMC_SMMU_AXI_CLK>; + clock-names = "mmss_noc_axi_clk", + "mmss_noc_ahb_clk", + "mmss_smmu_ahb_clk", + "mmss_smmu_axi_clk"; + }; + + smmu_rot_sec: qcom,smmu_rot_sec_cb { + compatible = "qcom,smmu_sde_rot_sec"; + iommus = <&mmss_bimc_smmu 0xe01>; + gdsc-mdss-supply = <&gdsc_bimc_smmu>; + + clocks = <&clock_rpmcc MMSSNOC_AXI_CLK>, + <&clock_mmss MMSS_MNOC_AHB_CLK>, + <&clock_mmss MMSS_BIMC_SMMU_AHB_CLK>, + <&clock_mmss MMSS_BIMC_SMMU_AXI_CLK>; + clock-names = "mmss_noc_axi_clk", + "mmss_noc_ahb_clk", + "mmss_smmu_ahb_clk", + "mmss_smmu_axi_clk"; + }; + }; + +}; + +#include "msmfalcon-mdss-panels.dtsi" diff --git a/arch/arm/boot/dts/qcom/msmfalcon-mtp.dts b/arch/arm/boot/dts/qcom/msmfalcon-mtp.dts index 1d4aaa2333cb..cefe0d7c275b 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-mtp.dts +++ b/arch/arm/boot/dts/qcom/msmfalcon-mtp.dts @@ -17,7 +17,9 @@ #include "msmfalcon-mtp.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM FALCON MTP"; + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM2FALCON MTP"; compatible = "qcom,msmfalcon-mtp", "qcom,msmfalcon", "qcom,mtp"; qcom,board-id = <8 0>; + qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>, + <0x0001001b 0x0201011a 0x0 0x0>; }; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-mtp.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-mtp.dtsi index bde93bf4c314..a9d77583b590 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-mtp.dtsi +++ b/arch/arm/boot/dts/qcom/msmfalcon-mtp.dtsi @@ -42,8 +42,58 @@ status = "ok"; }; +&mdss_mdp { + qcom,mdss-pref-prim-intf = "dsi"; +}; + +&mdss_dsi { + hw-config = "split_dsi"; +}; + +&mdss_dsi0 { + qcom,dsi-pref-prim-pan = <&dsi_dual_nt35597_truly_video>; + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; + pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; + qcom,platform-reset-gpio = <&tlmm 53 0>; + qcom,platform-te-gpio = <&tlmm 59 0>; +}; + +&mdss_dsi1 { + qcom,dsi-pref-prim-pan = <&dsi_dual_nt35597_truly_video>; + pinctrl-names = "mdss_default", "mdss_sleep"; + pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; + pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; + qcom,platform-reset-gpio = <&tlmm 53 0>; + qcom,platform-te-gpio = <&tlmm 59 0>; +}; + +&pm2falcon_wled { + qcom,led-strings-list = [01 02]; +}; + +&dsi_dual_nt35597_truly_video { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-mode-sel-gpio-state = "dual_port"; + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; +}; + +&dsi_dual_nt35597_truly_cmd { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-mode-sel-gpio-state = "dual_port"; + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; +}; + &soc { qcom,msm-ssc-sensors { compatible = "qcom,msm-ssc-sensors"; }; }; + +&mem_client_3_size { + qcom,peripheral-size = <0x500000>; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-pinctrl.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-pinctrl.dtsi index d89293c63840..a54079413e7c 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-pinctrl.dtsi +++ b/arch/arm/boot/dts/qcom/msmfalcon-pinctrl.dtsi @@ -1196,6 +1196,59 @@ }; }; + pmx_mdss: pmx_mdss { + mdss_dsi_active: mdss_dsi_active { + mux { + pins = "gpio53"; + function = "gpio"; + }; + + config { + pins = "gpio53"; + drive-strength = <8>; /* 8 mA */ + bias-disable = <0>; /* no pull */ + }; + }; + mdss_dsi_suspend: mdss_dsi_suspend { + mux { + pins = "gpio53"; + function = "gpio"; + }; + + config { + pins = "gpio53"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* pull down */ + }; + }; + }; + + pmx_mdss_te { + mdss_te_active: mdss_te_active { + mux { + pins = "gpio59"; + function = "mdp_vsync_p"; + }; + config { + pins = "gpio59"; + drive-strength = <2>; /* 8 mA */ + bias-pull-down; /* pull down*/ + }; + }; + + mdss_te_suspend: mdss_te_suspend { + mux { + pins = "gpio59"; + function = "mdp_vsync_p"; + }; + config { + pins = "gpio59"; + drive-strength = <2>; /* 2 mA */ + bias-pull-down; /* pull down */ + }; + }; + }; + ts_mux { ts_active: ts_active { mux { diff --git a/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-cdp.dts b/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-cdp.dts new file mode 100644 index 000000000000..3d3f8682941f --- /dev/null +++ b/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-cdp.dts @@ -0,0 +1,25 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +/dts-v1/; + +#include "msmfalcon.dtsi" +#include "msmfalcon-cdp.dtsi" +#include "msm-pm3falcon.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM3FALCON CDP"; + compatible = "qcom,msmfalcon-cdp", "qcom,msmfalcon", "qcom,cdp"; + qcom,board-id = <1 0>; + qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-mtp.dts b/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-mtp.dts new file mode 100644 index 000000000000..4e6bb7336f2b --- /dev/null +++ b/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-mtp.dts @@ -0,0 +1,25 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +/dts-v1/; + +#include "msmfalcon.dtsi" +#include "msmfalcon-mtp.dtsi" +#include "msm-pm3falcon.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM3FALCON MTP"; + compatible = "qcom,msmfalcon-mtp", "qcom,msmfalcon", "qcom,mtp"; + qcom,board-id = <8 0>; + qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-qrd.dts b/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-qrd.dts new file mode 100644 index 000000000000..e2d45f0d151e --- /dev/null +++ b/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-qrd.dts @@ -0,0 +1,25 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +/dts-v1/; + +#include "msmfalcon.dtsi" +#include "msmfalcon-qrd.dtsi" +#include "msm-pm3falcon.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM3FALCON QRD"; + compatible = "qcom,msmfalcon-qrd", "qcom,msmfalcon", "qcom,qrd"; + qcom,board-id = <0x1000b 0>; + qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-rcm.dts b/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-rcm.dts new file mode 100644 index 000000000000..c48124120d61 --- /dev/null +++ b/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-rcm.dts @@ -0,0 +1,25 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +/dts-v1/; + +#include "msmfalcon.dtsi" +#include "msmfalcon-cdp.dtsi" +#include "msm-pm3falcon.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM3FALCON RCM"; + compatible = "qcom,msmfalcon-cdp", "qcom,msmfalcon", "qcom,cdp"; + qcom,board-id = <21 0>; + qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-rumi.dts b/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-rumi.dts new file mode 100644 index 000000000000..b81a92a4aa7c --- /dev/null +++ b/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-rumi.dts @@ -0,0 +1,146 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +/dts-v1/; + +#include "msmfalcon.dtsi" +#include "msmfalcon-pinctrl.dtsi" +#include "msm-pm3falcon.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM3FALCON RUMI"; + compatible = "qcom,msmfalcon-rumi", "qcom,msmfalcon", "qcom,rumi"; + qcom,board-id = <15 0>; + qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; + + chosen { + bootargs = "lpm_levels.sleep_disabled=1"; + }; +}; + +&usb3 { + /delete-property/ USB3_GDSC-supply; + /delete-property/ extcon; + dwc3@a800000 { + maximum-speed = "high-speed"; + }; +}; + +&ssphy { + compatible = "usb-nop-xceiv"; +}; + +&qusb_phy0 { + reg = <0x0a928000 0x8000>, + <0x0a8f8800 0x400>, + <0x0a920000 0x100>; + reg-names = "qusb_phy_base", + "qscratch_base", + "emu_phy_base"; + qcom,emulation; + qcom,qusb-phy-init-seq = <0x19 0x1404 + 0x20 0x1414 + 0x79 0x1410 + 0x00 0x1418 + 0x99 0x1404 + 0x04 0x1408 + 0xd9 0x1404>; + qcom,emu-dcm-reset-seq = <0x100000 0x20 + 0x0 0x20 + 0x1a0 0x20 + 0x5 0x14>; +}; + +&uartblsp1dm1 { + status = "ok"; + pinctrl-names = "default"; + pinctrl-0 = <&uart_console_active>; +}; + +&sdhc_1 { + /* device core power supply */ + vdd-supply = <&pm2falcon_l4>; + qcom,vdd-voltage-level = <2950000 2950000>; + qcom,vdd-current-level = <200 570000>; + + /* device communication power supply */ + vdd-io-supply = <&pmfalcon_l8>; + qcom,vdd-io-always-on; + qcom,vdd-io-lpm-sup; + qcom,vdd-io-voltage-level = <1800000 1800000>; + qcom,vdd-io-current-level = <200 325000>; + + pinctrl-names = "active", "sleep"; + pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on &sdc1_rclk_on>; + pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off &sdc1_rclk_off>; + + qcom,clk-rates = <400000 20000000 25000000 50000000 192000000 + 384000000>; + + qcom,nonremovable; + qcom,bus-speed-mode = "HS400_1p8v", "HS200_1p8v", "DDR_1p8v"; + + status = "ok"; +}; + +&clock_gcc { + compatible = "qcom,dummycc"; + clock-output-names = "gcc_clocks"; +}; + +&pmfalcon_charger { + status = "disabled"; +}; + +&pmfalcon_fg { + status = "disabled"; +}; + +&clock_gfx { + compatible = "qcom,dummycc"; + clock-output-names = "gfx_clocks"; +}; + +&pmfalcon_pdphy { + status = "disabled"; +}; + +&clock_mmss { + compatible = "qcom,dummycc"; + clock-output-names = "mmss_clocks"; +}; + +&ufsphy1 { + vdda-phy-supply = <&pm2falcon_l1>; + vdda-pll-supply = <&pmfalcon_l10>; + vddp-ref-clk-supply = <&pmfalcon_l1>; + vdda-phy-max-microamp = <51400>; + vdda-pll-max-microamp = <14200>; + vddp-ref-clk-max-microamp = <100>; + vddp-ref-clk-always-on; +}; + +&ufs1 { + vdd-hba-supply = <&gdsc_ufs>; + vdd-hba-fixed-regulator; + vcc-supply = <&pm2falcon_l4>; + vccq2-supply = <&pmfalcon_l8>; + vcc-max-microamp = <500000>; + vccq2-max-microamp = <600000>; + qcom,disable-lpm; +}; + +&clock_debug { + compatible = "qcom,dummycc"; + clock-output-names = "debug_clocks"; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-sim.dts b/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-sim.dts new file mode 100644 index 000000000000..b47c1d328201 --- /dev/null +++ b/arch/arm/boot/dts/qcom/msmfalcon-pm3falcon-sim.dts @@ -0,0 +1,111 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +/dts-v1/; + +#include "msmfalcon.dtsi" +#include "msmfalcon-pinctrl.dtsi" +#include "msm-pm3falcon.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM3FALCON SIM"; + compatible = "qcom,msmfalcon-sim", "qcom,msmfalcon", "qcom,sim"; + qcom,board-id = <16 0>; + qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>; + + chosen { + bootargs = "lpm_levels.sleep_disabled=1"; + }; +}; + +&usb3 { + reg = <0xa800000 0xfc000>; + reg-names = "core_base"; + /delete-property/ extcon; + dwc3@a800000 { + maximum-speed = "high-speed"; + }; +}; + +&ssphy { + compatible = "usb-nop-xceiv"; +}; + +&qusb_phy0 { + compatible = "usb-nop-xceiv"; +}; + +&uartblsp1dm1 { + status = "ok"; + pinctrl-names = "default"; + pinctrl-0 = <&uart_console_active>; +}; + +&sdhc_1 { + /* device core power supply */ + vdd-supply = <&pm2falcon_l4>; + qcom,vdd-voltage-level = <2950000 2950000>; + qcom,vdd-current-level = <200 570000>; + + /* device communication power supply */ + vdd-io-supply = <&pmfalcon_l8>; + qcom,vdd-io-always-on; + qcom,vdd-io-lpm-sup; + qcom,vdd-io-voltage-level = <1800000 1800000>; + qcom,vdd-io-current-level = <200 325000>; + + pinctrl-names = "active", "sleep"; + pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on &sdc1_rclk_on>; + pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off &sdc1_rclk_off>; + + qcom,clk-rates = <400000 20000000 25000000 50000000 192000000 + 384000000>; + + qcom,nonremovable; + qcom,bus-speed-mode = "HS400_1p8v", "HS200_1p8v", "DDR_1p8v"; + + status = "ok"; +}; + +&pmfalcon_charger { + status = "disabled"; +}; + +&pmfalcon_fg { + status = "disabled"; +}; + +&pmfalcon_pdphy { + status = "disabled"; +}; + +&ufsphy1 { + vdda-phy-supply = <&pm2falcon_l1>; + vdda-pll-supply = <&pmfalcon_l10>; + vddp-ref-clk-supply = <&pmfalcon_l1>; + vdda-phy-max-microamp = <51400>; + vdda-pll-max-microamp = <14200>; + vddp-ref-clk-max-microamp = <100>; + vddp-ref-clk-always-on; + status = "ok"; +}; + +&ufs1 { + vdd-hba-supply = <&gdsc_ufs>; + vdd-hba-fixed-regulator; + vcc-supply = <&pm2falcon_l4>; + vccq2-supply = <&pmfalcon_l8>; + vcc-max-microamp = <500000>; + vccq2-max-microamp = <600000>; + status = "ok"; +}; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-qrd.dts b/arch/arm/boot/dts/qcom/msmfalcon-qrd.dts index 229676f17456..b97fdd18e229 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-qrd.dts +++ b/arch/arm/boot/dts/qcom/msmfalcon-qrd.dts @@ -17,7 +17,9 @@ #include "msmfalcon-qrd.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM FALCON QRD"; + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM2FALCON QRD"; compatible = "qcom,msmfalcon-qrd", "qcom,msmfalcon", "qcom,qrd"; qcom,board-id = <0x1000b 0>; + qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>, + <0x0001001b 0x0201011a 0x0 0x0>; }; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-rcm.dts b/arch/arm/boot/dts/qcom/msmfalcon-rcm.dts index 140be9311e8a..e4f59c735e70 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-rcm.dts +++ b/arch/arm/boot/dts/qcom/msmfalcon-rcm.dts @@ -17,7 +17,9 @@ #include "msmfalcon-cdp.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM FALCON RCM"; + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM2FALCON RCM"; compatible = "qcom,msmfalcon-cdp", "qcom,msmfalcon", "qcom,cdp"; qcom,board-id = <21 0>; + qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>, + <0x0001001b 0x0201011a 0x0 0x0>; }; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-rumi.dts b/arch/arm/boot/dts/qcom/msmfalcon-rumi.dts index eed69d178fa3..c371ddeda563 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-rumi.dts +++ b/arch/arm/boot/dts/qcom/msmfalcon-rumi.dts @@ -17,9 +17,11 @@ #include "msmfalcon-pinctrl.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM FALCON RUMI"; + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM2FALCON RUMI"; compatible = "qcom,msmfalcon-rumi", "qcom,msmfalcon", "qcom,rumi"; qcom,board-id = <15 0>; + qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>, + <0x0001001b 0x0201011a 0x0 0x0>; chosen { bootargs = "lpm_levels.sleep_disabled=1"; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-sim.dts b/arch/arm/boot/dts/qcom/msmfalcon-sim.dts index 80772bab86e4..596aae818fab 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-sim.dts +++ b/arch/arm/boot/dts/qcom/msmfalcon-sim.dts @@ -17,9 +17,11 @@ #include "msmfalcon-pinctrl.dtsi" / { - model = "Qualcomm Technologies, Inc. MSM FALCON SIM"; + model = "Qualcomm Technologies, Inc. MSM FALCON PMFALCON + PM2FALCON SIM"; compatible = "qcom,msmfalcon-sim", "qcom,msmfalcon", "qcom,sim"; qcom,board-id = <16 0>; + qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>, + <0x0001001b 0x0201011a 0x0 0x0>; chosen { bootargs = "lpm_levels.sleep_disabled=1"; diff --git a/arch/arm/boot/dts/qcom/msmfalcon-vidc.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-vidc.dtsi index 73d1cac48f9e..9a9c96f5181d 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon-vidc.dtsi +++ b/arch/arm/boot/dts/qcom/msmfalcon-vidc.dtsi @@ -14,6 +14,8 @@ #include #include #include +#include + &soc { msm_vidc: qcom,vidc@cc00000 { @@ -25,16 +27,10 @@ qcom,hfi-version = "3xx"; qcom,firmware-name = "venus"; qcom,sw-power-collapse; - qcom,debug-timeout; qcom,reg-presets = - <0x80124 0x00000003>, - <0x80550 0x01111111>, - <0x80560 0x01111111>, - <0x80568 0x01111111>, - <0x80570 0x01111111>, - <0x80580 0x01111111>, - <0x80588 0x01111111>, - <0xe2010 0x00000000>; + <0x80010 0x00000003>, + <0x80018 0x05555556>, + <0x8001c 0x05555556>; qcom,max-hw-load = <1036800>; /* Full 4k @ 30 */ qcom,allowed-clock-rates = @@ -70,7 +66,7 @@ "mmss_video_axi_clk", "mmss_video_core0_clk"; clocks = <&clock_gcc GCC_MMSS_SYS_NOC_AXI_CLK>, - <&clock_gcc MMSSNOC_AXI_CLK>, + <&clock_rpmcc MMSSNOC_AXI_CLK>, <&clock_mmss MMSS_MNOC_AHB_CLK>, <&clock_mmss MMSS_BIMC_SMMU_AHB_CLK>, <&clock_mmss MMSS_BIMC_SMMU_AXI_CLK>, @@ -210,7 +206,7 @@ <&mmss_bimc_smmu 0x411>, <&mmss_bimc_smmu 0x431>; buffer-types = <0xfff>; - virtual-addr-pool = <0x70800000 0x8f800000>; + virtual-addr-pool = <0x70800000 0x6f800000>; }; firmware_cb { diff --git a/arch/arm/boot/dts/qcom/msmfalcon.dtsi b/arch/arm/boot/dts/qcom/msmfalcon.dtsi index edea1eea6752..b57e7d033c70 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon.dtsi +++ b/arch/arm/boot/dts/qcom/msmfalcon.dtsi @@ -32,6 +32,7 @@ chosen { stdout-path = "serial0"; + bootargs = "rcupdate.rcu_expedited=1"; }; psci { @@ -952,6 +953,231 @@ #clock-cells = <1>; }; + cpubw: qcom,cpubw { + compatible = "qcom,devbw"; + governor = "performance"; + qcom,src-dst-ports = <1 512>; + qcom,active-only; + qcom,bw-tbl = + < 762 /* 100 MHz */ >, + < 1144 /* 150 MHz */ >, + < 1525 /* 200 MHz */ >, + < 2288 /* 300 MHz */ >, + < 3143 /* 412 MHz */ >, + < 4173 /* 547 MHz */ >, + < 5195 /* 681 MHz */ >, + < 5859 /* 768 MHz */ >, + < 7759 /* 1017 MHz */ >, + < 9887 /* 1296 MHz */ >, + < 10327 /* 1353 MHz */ >, + < 11863 /* 1555 MHz */ >, + < 13763 /* 1804 MHz */ >; + }; + + bwmon: qcom,cpu-bwmon { + compatible = "qcom,bimc-bwmon3"; + reg = <0x01008000 0x300>, <0x01001000 0x200>; + reg-names = "base", "global_base"; + interrupts = <0 183 4>; + qcom,mport = <0>; + qcom,target-dev = <&cpubw>; + }; + + mincpubw: qcom,mincpubw { + compatible = "qcom,devbw"; + governor = "powersave"; + qcom,src-dst-ports = <1 512>; + qcom,active-only; + qcom,bw-tbl = + < 762 /* 100 MHz */ >, + < 1144 /* 150 MHz */ >, + < 1525 /* 200 MHz */ >, + < 2288 /* 300 MHz */ >, + < 3143 /* 412 MHz */ >, + < 4173 /* 547 MHz */ >, + < 5195 /* 681 MHz */ >, + < 5859 /* 768 MHz */ >, + < 7759 /* 1017 MHz */ >, + < 9887 /* 1296 MHz */ >, + < 10327 /* 1353 MHz */ >, + < 11863 /* 1555 MHz */ >, + < 13763 /* 1804 MHz */ >; + }; + + memlat_cpu0: qcom,memlat-cpu0 { + compatible = "qcom,devbw"; + governor = "powersave"; + qcom,src-dst-ports = <1 512>; + qcom,active-only; + qcom,bw-tbl = + < 762 /* 100 MHz */ >, + < 1144 /* 150 MHz */ >, + < 1525 /* 200 MHz */ >, + < 2288 /* 300 MHz */ >, + < 3143 /* 412 MHz */ >, + < 4173 /* 547 MHz */ >, + < 5195 /* 681 MHz */ >, + < 5859 /* 768 MHz */ >, + < 7759 /* 1017 MHz */ >, + < 9887 /* 1296 MHz */ >, + < 10327 /* 1353 MHz */ >, + < 11863 /* 1555 MHz */ >, + < 13763 /* 1804 MHz */ >; + }; + + memlat_cpu4: qcom,memlat-cpu4 { + compatible = "qcom,devbw"; + governor = "powersave"; + qcom,src-dst-ports = <1 512>; + qcom,active-only; + qcom,bw-tbl = + < 762 /* 100 MHz */ >, + < 1144 /* 150 MHz */ >, + < 1525 /* 200 MHz */ >, + < 2288 /* 300 MHz */ >, + < 3143 /* 412 MHz */ >, + < 4173 /* 547 MHz */ >, + < 5195 /* 681 MHz */ >, + < 5859 /* 768 MHz */ >, + < 7759 /* 1017 MHz */ >, + < 9887 /* 1296 MHz */ >, + < 10327 /* 1353 MHz */ >, + < 11863 /* 1555 MHz */ >, + < 13763 /* 1804 MHz */ >; + }; + + devfreq_memlat_0: qcom,arm-memlat-mon-0 { + compatible = "qcom,arm-memlat-mon"; + qcom,cpulist = <&CPU0 &CPU1 &CPU2 &CPU3>; + qcom,target-dev = <&memlat_cpu0>; + qcom,core-dev-table = + < 633600 1525 >, + < 1401600 4173 >, + < 1881600 7759 >; + }; + + devfreq_memlat_4: qcom,arm-memlat-mon-4 { + compatible = "qcom,arm-memlat-mon"; + qcom,cpulist = <&CPU4 &CPU5 &CPU6 &CPU7>; + qcom,target-dev = <&memlat_cpu4>; + qcom,core-dev-table = + < 1113600 1525 >, + < 1401600 7759 >, + < 2150400 11863 >, + < 2457600 13763 >; + }; + + devfreq_cpufreq: devfreq-cpufreq { + mincpubw-cpufreq { + target-dev = <&mincpubw>; + cpu-to-dev-map-0 = + < 633600 1525 >, + < 1401600 3143 >, + < 1881600 5859 >; + cpu-to-dev-map-4 = + < 1113600 1525 >, + < 1401600 4173 >, + < 1747200 5859 >, + < 2150400 7759 >, + < 2457600 13763 >; + }; + }; + + clock_cpu: qcom,clk-cpu-falcon@179c0000 { + compatible = "qcom,clk-cpu-osm"; + status = "disabled"; + reg = <0x179c0000 0x4000>, <0x17916000 0x1000>, + <0x17816000 0x1000>, <0x179d1000 0x1000>, + <0x00784130 0x8>; + reg-names = "osm", "pwrcl_pll", "perfcl_pll", + "apcs_common", "perfcl_efuse"; + + /* ToDo: Add power and perf supply rails */ + + interrupts = , + ; + interrupt-names = "pwrcl-irq", "perfcl-irq"; + + qcom,pwrcl-speedbin0-v0 = + < 300000000 0x0004000f 0x01200020 0x1 1 >, + < 633600000 0x05040021 0x03200020 0x1 1 >, + < 902400000 0x0404002f 0x04260026 0x1 2 >, + < 1113600000 0x0404003a 0x052e002e 0x2 3 >, + < 1401600000 0x04040049 0x073a003a 0x2 4 >, + < 1536000000 0x04040050 0x08400040 0x3 5 >, + < 1747200000 0x0404005b 0x09480048 0x3 6 >, + < 1843200000 0x04040060 0x094c004c 0x3 7 >; + + qcom,perfcl-speedbin0-v0 = + < 300000000 0x0004000f 0x01200020 0x1 1 >, + < 1113600000 0x0404003a 0x052e002e 0x1 1 >, + < 1401600000 0x04040049 0x073a003a 0x2 2 >, + < 1747200000 0x0404005b 0x09480048 0x2 3 >, + < 1958400000 0x04040066 0x0a510051 0x3 4 >, + < 2150400000 0x04040070 0x0b590059 0x3 5 >, + < 2457600000 0x04040080 0x0c660066 0x3 6 >; + + qcom,perfcl-speedbin1-v0 = + < 300000000 0x0004000f 0x01200020 0x1 1 >, + < 1113600000 0x0404003a 0x052e002e 0x1 1 >, + < 1401600000 0x04040049 0x073a003a 0x2 2 >, + < 1747200000 0x0404005b 0x09480048 0x2 3 >, + < 1958400000 0x04040066 0x0a510051 0x3 4 >, + < 2150400000 0x04040070 0x0b590059 0x3 5 >, + < 2208000000 0x04040073 0x0b5c005c 0x3 6 >; + + qcom,up-timer = <1000 1000>; + qcom,down-timer = <1000 1000>; + qcom,pc-override-index = <0 0>; + qcom,set-ret-inactive; + qcom,enable-llm-freq-vote; + qcom,llm-freq-up-timer = <327675 327675>; + qcom,llm-freq-down-timer = <327675 327675>; + qcom,enable-llm-volt-vote; + qcom,llm-volt-up-timer = <327675 327675>; + qcom,llm-volt-down-timer = <327675 327675>; + qcom,cc-reads = <10>; + qcom,cc-delay = <5>; + qcom,cc-factor = <100>; + qcom,osm-clk-rate = <200000000>; + qcom,xo-clk-rate = <19200000>; + + qcom,l-val-base = <0x17916004 0x17816004>; + qcom,apcs-itm-present = <0x179d143c 0x179d143c>; + qcom,apcs-pll-user-ctl = <0x1791600c 0x1781600c>; + qcom,apcs-cfg-rcgr = <0x17911054 0x17811054>; + qcom,apcs-cmd-rcgr = <0x17911050 0x17811050>; + qcom,apm-mode-ctl = <0x179d0004 0x179d0010>; + qcom,apm-ctrl-status = <0x179d000c 0x179d0018>; + + qcom,apm-threshold-voltage = <832000>; + qcom,boost-fsm-en; + qcom,safe-fsm-en; + qcom,ps-fsm-en; + qcom,droop-fsm-en; + qcom,wfx-fsm-en; + qcom,pc-fsm-en; + + qcom,pwrcl-apcs-mem-acc-cfg = + <0x179d1360 0x179d1364 0x179d1364>; + qcom,perfcl-apcs-mem-acc-cfg = + <0x179d1368 0x179d136C 0x179d1370>; + qcom,pwrcl-apcs-mem-acc-val = + <0x00000000 0x80000000 0x80000000>, + <0x00000000 0x00000000 0x00000000>, + <0x00000000 0x00000001 0x00000001>; + qcom,perfcl-apcs-mem-acc-val = + <0x00000000 0x00000000 0x80000000>, + <0x00000000 0x00000000 0x00000000>, + <0x00000000 0x00000000 0x00000001>; + + clock-names = "aux_clk", "xo_a"; + clocks = <&clock_gcc HMSS_GPLL0_CLK_SRC>, + <&clock_rpmcc RPM_XO_A_CLK_SRC>; + + #clock-cells = <1>; + }; + sdhc_1: sdhci@c0c4000 { compatible = "qcom,sdhci-msm-v5"; reg = <0xc0c4000 0x1000>, <0xc0c5000 0x1000>; @@ -2047,3 +2273,6 @@ }; }; }; + +#include "msmfalcon-mdss.dtsi" +#include "msmfalcon-mdss-pll.dtsi" diff --git a/arch/arm/boot/dts/qcom/msmtriton.dtsi b/arch/arm/boot/dts/qcom/msmtriton.dtsi index ed58d5d3c683..4ef236d52911 100644 --- a/arch/arm/boot/dts/qcom/msmtriton.dtsi +++ b/arch/arm/boot/dts/qcom/msmtriton.dtsi @@ -30,6 +30,7 @@ chosen { stdout-path = "serial0"; + bootargs = "rcupdate.rcu_expedited=1"; }; psci { @@ -46,6 +47,7 @@ compatible = "arm,armv8"; reg = <0x0 0x100>; enable-method = "psci"; + qcom,limits-info = <&mitigation_profile0>; efficiency = <1024>; next-level-cache = <&L2_1>; L2_1: l2-cache { @@ -69,6 +71,7 @@ compatible = "arm,armv8"; reg = <0x0 0x101>; enable-method = "psci"; + qcom,limits-info = <&mitigation_profile1>; efficiency = <1024>; next-level-cache = <&L2_1>; L1_I_101: l1-icache { @@ -86,6 +89,7 @@ compatible = "arm,armv8"; reg = <0x0 0x102>; enable-method = "psci"; + qcom,limits-info = <&mitigation_profile2>; efficiency = <1024>; next-level-cache = <&L2_1>; L1_I_102: l1-icache { @@ -103,6 +107,7 @@ compatible = "arm,armv8"; reg = <0x0 0x103>; enable-method = "psci"; + qcom,limits-info = <&mitigation_profile3>; efficiency = <1024>; next-level-cache = <&L2_1>; L1_I_103: l1-icache { @@ -120,6 +125,7 @@ compatible = "arm,armv8"; reg = <0x0 0x0>; enable-method = "psci"; + qcom,limits-info = <&mitigation_profile4>; efficiency = <1024>; next-level-cache = <&L2_0>; L2_0: l2-cache { @@ -143,6 +149,7 @@ compatible = "arm,armv8"; reg = <0x0 0x1>; enable-method = "psci"; + qcom,limits-info = <&mitigation_profile4>; efficiency = <1024>; next-level-cache = <&L2_0>; L1_I_1: l1-icache { @@ -160,6 +167,7 @@ compatible = "arm,armv8"; reg = <0x0 0x2>; enable-method = "psci"; + qcom,limits-info = <&mitigation_profile4>; efficiency = <1024>; next-level-cache = <&L2_0>; L1_I_2: l1-icache { @@ -177,6 +185,7 @@ compatible = "arm,armv8"; reg = <0x0 0x3>; enable-method = "psci"; + qcom,limits-info = <&mitigation_profile4>; efficiency = <1024>; next-level-cache = <&L2_0>; L1_I_3: l1-icache { @@ -449,6 +458,175 @@ qcom,sensors = <12>; }; + qcom,sensor-information { + compatible = "qcom,sensor-information"; + sensor_information0: qcom,sensor-information-0 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor0"; + qcom,scaling-factor = <10>; + }; + sensor_information1: qcom,sensor-information-1 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor1"; + qcom,scaling-factor = <10>; + }; + sensor_information2: qcom,sensor-information-2 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor2"; + qcom,scaling-factor = <10>; + }; + sensor_information3: qcom,sensor-information-3 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor3"; + qcom,scaling-factor = <10>; + }; + sensor_information4: qcom,sensor-information-4 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor4"; + qcom,scaling-factor = <10>; + }; + sensor_information5: qcom,sensor-information-5 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor5"; + qcom,scaling-factor = <10>; + }; + sensor_information6: qcom,sensor-information-6 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor6"; + qcom,scaling-factor = <10>; + }; + sensor_information7: qcom,sensor-information-7 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor7"; + qcom,scaling-factor = <10>; + }; + sensor_information8: qcom,sensor-information-8 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor8"; + qcom,scaling-factor = <10>; + qcom,alias-name = "gpu"; + }; + sensor_information9: qcom,sensor-information-9 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor9"; + qcom,scaling-factor = <10>; + }; + sensor_information10: qcom,sensor-information-10 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor10"; + qcom,scaling-factor = <10>; + }; + sensor_information11: qcom,sensor-information-11 { + qcom,sensor-type = "tsens"; + qcom,sensor-name = "tsens_tz_sensor11"; + qcom,scaling-factor = <10>; + }; + sensor_information12: qcom,sensor-information-12 { + qcom,sensor-type = "alarm"; + qcom,sensor-name = "pmfalcon_tz"; + qcom,scaling-factor = <1000>; + }; + sensor_information13: qcom,sensor-information-13 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "msm_therm"; + }; + sensor_information14: qcom,sensor-information-14 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "xo_therm"; + }; + sensor_information15: qcom,sensor-information-15 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "pa_therm0"; + }; + sensor_information16: qcom,sensor-information-16 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "pa_therm1"; + }; + sensor_information17: qcom,sensor-information-17 { + qcom,sensor-type = "adc"; + qcom,sensor-name = "quiet_therm"; + }; + sensor_information18: qcom,sensor-information-18 { + qcom,sensor-type = "llm"; + qcom,sensor-name = "limits_sensor-00"; + }; + sensor_information19: qcom,sensor-information-19 { + qcom,sensor-type = "llm"; + qcom,sensor-name = "limits_sensor-01"; + }; + }; + + mitigation_profile0: qcom,limit_info-0 { + qcom,temperature-sensor = <&sensor_information3>; + qcom,hotplug-mitigation-enable; + }; + + mitigation_profile1: qcom,limit_info-1 { + qcom,temperature-sensor = <&sensor_information4>; + qcom,hotplug-mitigation-enable; + }; + + mitigation_profile2: qcom,limit_info-2 { + qcom,temperature-sensor = <&sensor_information5>; + qcom,hotplug-mitigation-enable; + }; + + mitigation_profile3: qcom,limit_info-3 { + qcom,temperature-sensor = <&sensor_information6>; + qcom,hotplug-mitigation-enable; + }; + + mitigation_profile4: qcom,limit_info-4 { + qcom,temperature-sensor = <&sensor_information1>; + qcom,hotplug-mitigation-enable; + }; + + qcom,msm-thermal { + compatible = "qcom,msm-thermal"; + qcom,sensor-id = <3>; + qcom,poll-ms = <100>; + qcom,therm-reset-temp = <115>; + qcom,core-limit-temp = <70>; + qcom,core-temp-hysteresis = <10>; + qcom,hotplug-temp = <105>; + qcom,hotplug-temp-hysteresis = <20>; + qcom,online-hotplug-core; + qcom,synchronous-cluster-id = <0 1>; + qcom,synchronous-cluster-map = <0 4 &CPU4 &CPU5 &CPU6 &CPU7>, + <1 4 &CPU0 &CPU1 &CPU2 &CPU3>; + + qcom,vdd-restriction-temp = <5>; + qcom,vdd-restriction-temp-hysteresis = <10>; + + vdd-dig-supply = <&pm2falcon_s3_floor_level>; + vdd-gfx-supply = <&gfx_vreg_corner>; + + qcom,vdd-dig-rstr{ + qcom,vdd-rstr-reg = "vdd-dig"; + qcom,levels = ; + qcom,min-level = ; + }; + + qcom,vdd-gfx-rstr{ + qcom,vdd-rstr-reg = "vdd-gfx"; + qcom,levels = <5 6 6>; /* Nominal, Turbo, Turbo */ + qcom,min-level = <1>; /* No Request */ + }; + + msm_thermal_freq: qcom,vdd-apps-rstr{ + qcom,vdd-rstr-reg = "vdd-apps"; + qcom,levels = <1248000>; + qcom,freq-req; + }; + }; + + qcom,lmh { + compatible = "qcom,lmh_v1"; + interrupts = ; + }; + wdog: qcom,wdt@17817000 { status = "disabled"; compatible = "qcom,msm-watchdog"; diff --git a/arch/arm/configs/msmcortex_defconfig b/arch/arm/configs/msmcortex_defconfig index 9eaa449d4df6..5e9afadeb7ae 100644 --- a/arch/arm/configs/msmcortex_defconfig +++ b/arch/arm/configs/msmcortex_defconfig @@ -353,6 +353,7 @@ CONFIG_USB_STORAGE=y CONFIG_USB_DWC3=y CONFIG_USB_ISP1760=y CONFIG_USB_ISP1760_HOST_ROLE=y +CONFIG_USB_EHSET_TEST_FIXTURE=y CONFIG_USB_OTG_WAKELOCK=y CONFIG_NOP_USB_XCEIV=y CONFIG_USB_MSM_SSPHY_QMP=y diff --git a/arch/arm/configs/msmfalcon-perf_defconfig b/arch/arm/configs/msmfalcon-perf_defconfig index 37b44ff5358f..211ec1c6cabc 100644 --- a/arch/arm/configs/msmfalcon-perf_defconfig +++ b/arch/arm/configs/msmfalcon-perf_defconfig @@ -348,6 +348,7 @@ CONFIG_WCD9335_CODEC=y CONFIG_WCD934X_CODEC=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_MSM_GFX_LDO=y CONFIG_REGULATOR_RPM_SMD=y CONFIG_REGULATOR_QPNP=y CONFIG_REGULATOR_QPNP_LABIBB=y @@ -355,6 +356,7 @@ CONFIG_REGULATOR_SPM=y CONFIG_REGULATOR_CPR3_HMSS=y CONFIG_REGULATOR_CPR3_MMSS=y CONFIG_REGULATOR_CPRH_KBSS=y +CONFIG_REGULATOR_CPR4_MMSS_LDO=y CONFIG_REGULATOR_MEM_ACC=y CONFIG_REGULATOR_PROXY_CONSUMER=y CONFIG_REGULATOR_STUB=y diff --git a/arch/arm/configs/msmfalcon_defconfig b/arch/arm/configs/msmfalcon_defconfig index 058a1b3ddd24..10981157afc3 100644 --- a/arch/arm/configs/msmfalcon_defconfig +++ b/arch/arm/configs/msmfalcon_defconfig @@ -346,6 +346,7 @@ CONFIG_WCD9335_CODEC=y CONFIG_WCD934X_CODEC=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_MSM_GFX_LDO=y CONFIG_REGULATOR_RPM_SMD=y CONFIG_REGULATOR_QPNP=y CONFIG_REGULATOR_QPNP_LABIBB=y @@ -354,6 +355,7 @@ CONFIG_REGULATOR_SPM=y CONFIG_REGULATOR_CPR3_HMSS=y CONFIG_REGULATOR_CPR3_MMSS=y CONFIG_REGULATOR_CPRH_KBSS=y +CONFIG_REGULATOR_CPR4_MMSS_LDO=y CONFIG_REGULATOR_MEM_ACC=y CONFIG_REGULATOR_PROXY_CONSUMER=y CONFIG_REGULATOR_STUB=y @@ -482,6 +484,7 @@ CONFIG_USB_BAM=y CONFIG_QCOM_CLK_SMD_RPM=y CONFIG_MSM_GPUCC_FALCON=y CONFIG_MSM_MMCC_FALCON=y +CONFIG_CLOCK_CPU_OSM=y CONFIG_QCOM_MDSS_PLL=y CONFIG_REMOTE_SPINLOCK_MSM=y CONFIG_ARM_SMMU=y diff --git a/arch/arm64/configs/msmcortex-perf_defconfig b/arch/arm64/configs/msmcortex-perf_defconfig index 31d4aac67ee2..97a082dd4fcd 100644 --- a/arch/arm64/configs/msmcortex-perf_defconfig +++ b/arch/arm64/configs/msmcortex-perf_defconfig @@ -430,6 +430,7 @@ CONFIG_USB_ISP1760=y CONFIG_USB_ISP1760_HOST_ROLE=y CONFIG_USB_PD_POLICY=y CONFIG_QPNP_USB_PDPHY=y +CONFIG_USB_EHSET_TEST_FIXTURE=y CONFIG_USB_OTG_WAKELOCK=y CONFIG_NOP_USB_XCEIV=y CONFIG_USB_MSM_SSPHY_QMP=y @@ -614,7 +615,6 @@ CONFIG_CRYPTO_DEV_QCRYPTO=y CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y CONFIG_CRYPTO_DEV_QCEDEV=y CONFIG_CRYPTO_DEV_OTA_CRYPTO=y -CONFIG_CRYPTO_DEV_QCE=y CONFIG_CRYPTO_DEV_QCOM_ICE=y CONFIG_ARM64_CRYPTO=y CONFIG_CRYPTO_SHA1_ARM64_CE=y diff --git a/arch/arm64/configs/msmcortex_defconfig b/arch/arm64/configs/msmcortex_defconfig index 0680cb0408db..965a13caaeb5 100644 --- a/arch/arm64/configs/msmcortex_defconfig +++ b/arch/arm64/configs/msmcortex_defconfig @@ -432,6 +432,7 @@ CONFIG_USB_ISP1760=y CONFIG_USB_ISP1760_HOST_ROLE=y CONFIG_USB_PD_POLICY=y CONFIG_QPNP_USB_PDPHY=y +CONFIG_USB_EHSET_TEST_FIXTURE=y CONFIG_USB_OTG_WAKELOCK=y CONFIG_NOP_USB_XCEIV=y CONFIG_USB_MSM_SSPHY_QMP=y @@ -681,7 +682,6 @@ CONFIG_CRYPTO_DEV_QCRYPTO=y CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y CONFIG_CRYPTO_DEV_QCEDEV=y CONFIG_CRYPTO_DEV_OTA_CRYPTO=y -CONFIG_CRYPTO_DEV_QCE=y CONFIG_CRYPTO_DEV_QCOM_ICE=y CONFIG_ARM64_CRYPTO=y CONFIG_CRYPTO_SHA1_ARM64_CE=y diff --git a/arch/arm64/configs/msmfalcon-perf_defconfig b/arch/arm64/configs/msmfalcon-perf_defconfig index 6f1e987e6d0c..b84168e18478 100644 --- a/arch/arm64/configs/msmfalcon-perf_defconfig +++ b/arch/arm64/configs/msmfalcon-perf_defconfig @@ -346,6 +346,7 @@ CONFIG_WCD9335_CODEC=y CONFIG_WCD934X_CODEC=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_MSM_GFX_LDO=y CONFIG_REGULATOR_RPM_SMD=y CONFIG_REGULATOR_QPNP=y CONFIG_REGULATOR_QPNP_LABIBB=y @@ -354,6 +355,7 @@ CONFIG_REGULATOR_SPM=y CONFIG_REGULATOR_CPR3_HMSS=y CONFIG_REGULATOR_CPR3_MMSS=y CONFIG_REGULATOR_CPRH_KBSS=y +CONFIG_REGULATOR_CPR4_MMSS_LDO=y CONFIG_REGULATOR_MEM_ACC=y CONFIG_REGULATOR_PROXY_CONSUMER=y CONFIG_REGULATOR_STUB=y @@ -504,6 +506,7 @@ CONFIG_USB_BAM=y CONFIG_QCOM_CLK_SMD_RPM=y CONFIG_MSM_GPUCC_FALCON=y CONFIG_MSM_MMCC_FALCON=y +CONFIG_CLOCK_CPU_OSM=y CONFIG_QCOM_MDSS_PLL=y CONFIG_REMOTE_SPINLOCK_MSM=y CONFIG_IOMMU_IO_PGTABLE_FAST=y diff --git a/arch/arm64/configs/msmfalcon_defconfig b/arch/arm64/configs/msmfalcon_defconfig index c83e8427389e..ce91e8992b46 100644 --- a/arch/arm64/configs/msmfalcon_defconfig +++ b/arch/arm64/configs/msmfalcon_defconfig @@ -348,6 +348,7 @@ CONFIG_WCD9335_CODEC=y CONFIG_WCD934X_CODEC=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_MSM_GFX_LDO=y CONFIG_REGULATOR_RPM_SMD=y CONFIG_REGULATOR_QPNP=y CONFIG_REGULATOR_QPNP_LABIBB=y @@ -356,6 +357,7 @@ CONFIG_REGULATOR_SPM=y CONFIG_REGULATOR_CPR3_HMSS=y CONFIG_REGULATOR_CPR3_MMSS=y CONFIG_REGULATOR_CPRH_KBSS=y +CONFIG_REGULATOR_CPR4_MMSS_LDO=y CONFIG_REGULATOR_MEM_ACC=y CONFIG_REGULATOR_PROXY_CONSUMER=y CONFIG_REGULATOR_STUB=y @@ -513,6 +515,7 @@ CONFIG_USB_BAM=y CONFIG_QCOM_CLK_SMD_RPM=y CONFIG_MSM_GPUCC_FALCON=y CONFIG_MSM_MMCC_FALCON=y +CONFIG_CLOCK_CPU_OSM=y CONFIG_QCOM_MDSS_PLL=y CONFIG_REMOTE_SPINLOCK_MSM=y CONFIG_IOMMU_IO_PGTABLE_FAST=y diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c index 7af9d8184f97..f47b390375c4 100644 --- a/drivers/char/diag/diag_dci.c +++ b/drivers/char/diag/diag_dci.c @@ -771,6 +771,7 @@ static int diag_dci_remove_req_entry(unsigned char *buf, int len, if (*buf != 0x80) { list_del(&entry->track); kfree(entry); + entry = NULL; return 1; } @@ -788,6 +789,7 @@ static int diag_dci_remove_req_entry(unsigned char *buf, int len, if (delayed_rsp_id == 0) { list_del(&entry->track); kfree(entry); + entry = NULL; return 1; } @@ -801,6 +803,7 @@ static int diag_dci_remove_req_entry(unsigned char *buf, int len, if (rsp_count > 0 && rsp_count < 0x1000) { list_del(&entry->track); kfree(entry); + entry = NULL; return 1; } @@ -2682,10 +2685,12 @@ int diag_dci_init(void) err: pr_err("diag: Could not initialize diag DCI buffers"); kfree(driver->apps_dci_buf); + driver->apps_dci_buf = NULL; if (driver->diag_dci_wq) destroy_workqueue(driver->diag_dci_wq); kfree(partial_pkt.data); + partial_pkt.data = NULL; mutex_destroy(&driver->dci_mutex); mutex_destroy(&dci_log_mask_mutex); mutex_destroy(&dci_event_mask_mutex); @@ -2705,7 +2710,9 @@ void diag_dci_channel_init(void) void diag_dci_exit(void) { kfree(partial_pkt.data); + partial_pkt.data = NULL; kfree(driver->apps_dci_buf); + driver->apps_dci_buf = NULL; mutex_destroy(&driver->dci_mutex); mutex_destroy(&dci_log_mask_mutex); mutex_destroy(&dci_event_mask_mutex); @@ -2917,22 +2924,30 @@ fail_alloc: mutex_destroy(&proc_buf->health_mutex); if (proc_buf->buf_primary) { kfree(proc_buf->buf_primary->data); + proc_buf->buf_primary->data = NULL; mutex_destroy( &proc_buf->buf_primary->data_mutex); } kfree(proc_buf->buf_primary); + proc_buf->buf_primary = NULL; if (proc_buf->buf_cmd) { kfree(proc_buf->buf_cmd->data); + proc_buf->buf_cmd->data = NULL; mutex_destroy( &proc_buf->buf_cmd->data_mutex); } kfree(proc_buf->buf_cmd); + proc_buf->buf_cmd = NULL; } } kfree(new_entry->dci_event_mask); + new_entry->dci_event_mask = NULL; kfree(new_entry->dci_log_mask); + new_entry->dci_log_mask = NULL; kfree(new_entry->buffers); + new_entry->buffers = NULL; kfree(new_entry); + new_entry = NULL; } mutex_unlock(&driver->dci_mutex); return DIAG_DCI_NO_REG; @@ -2963,6 +2978,7 @@ int diag_dci_deinit_client(struct diag_dci_client_tbl *entry) * masks and send the masks to peripherals */ kfree(entry->dci_log_mask); + entry->dci_log_mask = NULL; diag_dci_invalidate_cumulative_log_mask(token); if (token == DCI_LOCAL_PROC) diag_update_userspace_clients(DCI_LOG_MASKS_TYPE); @@ -2971,6 +2987,7 @@ int diag_dci_deinit_client(struct diag_dci_client_tbl *entry) return ret; } kfree(entry->dci_event_mask); + entry->dci_event_mask = NULL; diag_dci_invalidate_cumulative_event_mask(token); if (token == DCI_LOCAL_PROC) diag_update_userspace_clients(DCI_EVENT_MASKS_TYPE); @@ -2986,6 +3003,7 @@ int diag_dci_deinit_client(struct diag_dci_client_tbl *entry) if (!list_empty(&req_entry->track)) list_del(&req_entry->track); kfree(req_entry); + req_entry = NULL; } } @@ -3001,6 +3019,7 @@ int diag_dci_deinit_client(struct diag_dci_client_tbl *entry) buf_entry->data = NULL; mutex_unlock(&buf_entry->data_mutex); kfree(buf_entry); + buf_entry = NULL; } else if (buf_entry->buf_type == DCI_BUF_CMD) { peripheral = buf_entry->data_source; if (peripheral == APPS_DATA) @@ -3027,14 +3046,17 @@ int diag_dci_deinit_client(struct diag_dci_client_tbl *entry) mutex_unlock(&buf_entry->data_mutex); mutex_destroy(&buf_entry->data_mutex); kfree(buf_entry); + buf_entry = NULL; } mutex_lock(&proc_buf->buf_primary->data_mutex); kfree(proc_buf->buf_primary->data); + proc_buf->buf_primary->data = NULL; mutex_unlock(&proc_buf->buf_primary->data_mutex); mutex_lock(&proc_buf->buf_cmd->data_mutex); kfree(proc_buf->buf_cmd->data); + proc_buf->buf_cmd->data = NULL; mutex_unlock(&proc_buf->buf_cmd->data_mutex); mutex_destroy(&proc_buf->health_mutex); @@ -3042,13 +3064,17 @@ int diag_dci_deinit_client(struct diag_dci_client_tbl *entry) mutex_destroy(&proc_buf->buf_cmd->data_mutex); kfree(proc_buf->buf_primary); + proc_buf->buf_primary = NULL; kfree(proc_buf->buf_cmd); + proc_buf->buf_cmd = NULL; mutex_unlock(&proc_buf->buf_mutex); } mutex_destroy(&entry->write_buf_mutex); kfree(entry->buffers); + entry->buffers = NULL; kfree(entry); + entry = NULL; if (driver->num_dci_client == 0) { diag_update_proc_vote(DIAG_PROC_DCI, VOTE_DOWN, token); diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index c4aec62d1014..ac815c6dbac0 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -71,6 +71,8 @@ struct clk_core { bool orphan; unsigned int enable_count; unsigned int prepare_count; + bool need_handoff_enable; + bool need_handoff_prepare; unsigned long min_rate; unsigned long max_rate; unsigned long accuracy; @@ -195,6 +197,19 @@ static void clk_unprepare_unused_subtree(struct clk_core *core) hlist_for_each_entry(child, &core->children, child_node) clk_unprepare_unused_subtree(child); + /* + * setting CLK_ENABLE_HAND_OFF flag triggers this conditional + * + * need_handoff_prepare implies this clk was already prepared by + * __clk_init. now we have a proper user, so unset the flag in our + * internal bookkeeping. See CLK_ENABLE_HAND_OFF flag in clk-provider.h + * for details. + */ + if (core->need_handoff_prepare) { + core->need_handoff_prepare = false; + core->prepare_count--; + } + if (core->prepare_count) return; @@ -221,6 +236,19 @@ static void clk_disable_unused_subtree(struct clk_core *core) hlist_for_each_entry(child, &core->children, child_node) clk_disable_unused_subtree(child); + /* + * setting CLK_ENABLE_HAND_OFF flag triggers this conditional + * + * need_handoff_enable implies this clk was already enabled by + * __clk_init. now we have a proper user, so unset the flag in our + * internal bookkeeping. See CLK_ENABLE_HAND_OFF flag in clk-provider.h + * for details. + */ + if (core->need_handoff_enable) { + core->need_handoff_enable = false; + core->enable_count--; + } + flags = clk_enable_lock(); if (core->enable_count) @@ -925,7 +953,7 @@ static int clk_core_prepare(struct clk_core *core) */ int clk_prepare(struct clk *clk) { - int ret; + int ret = 0; if (!clk) return 0; @@ -1040,7 +1068,7 @@ static int clk_core_enable(struct clk_core *core) int clk_enable(struct clk *clk) { unsigned long flags; - int ret; + int ret = 0; if (!clk) return 0; @@ -3146,6 +3174,37 @@ static int __clk_init(struct device *dev, struct clk *clk_user) clk_enable_unlock(flags); } + /* + * enable clocks with the CLK_ENABLE_HAND_OFF flag set + * + * This flag causes the framework to enable the clock at registration + * time, which is sometimes necessary for clocks that would cause a + * system crash when gated (e.g. cpu, memory, etc). The prepare_count + * is migrated over to the first clk consumer to call clk_prepare(). + * Similarly the clk's enable_count is migrated to the first consumer + * to call clk_enable(). + */ + if (core->flags & CLK_ENABLE_HAND_OFF) { + unsigned long flags; + + /* + * Few clocks might have hardware gating which would be required + * to be ON before prepare/enabling the clocks. So check if the + * clock has been turned ON earlier and we should + * prepare/enable those clocks. + */ + if (clk_core_is_enabled(core)) { + core->need_handoff_prepare = true; + core->need_handoff_enable = true; + ret = clk_core_prepare(core); + if (ret) + goto out; + flags = clk_enable_lock(); + clk_core_enable(core); + clk_enable_unlock(flags); + } + } + kref_init(&core->ref); out: clk_prepare_unlock(); diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 2148dad33e87..b5dd556b3f96 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -219,4 +219,16 @@ config QCOM_A53 Say Y if you want to support CPU frequency scaling on devices such as MSM8916. +config CLOCK_CPU_OSM + tristate "OSM CPU Clock Controller" + depends on COMMON_CLK_QCOM + help + Support for the osm clock controller. + Operating State Manager (OSM) is a hardware engine used by some + Qualcomm Technologies, Inc. (QTI) SoCs to manage frequency and + voltage scaling in hardware. OSM is capable of controlling + frequency and voltage requests for multiple clusters via the + existence of multiple OSM domains. + Say Y if you want to support osm clocks. + source "drivers/clk/qcom/mdss/Kconfig" diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 176dc3103cdb..a63065c97319 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -37,5 +37,6 @@ obj-$(CONFIG_KRAITCC) += krait-cc.o obj-$(CONFIG_QCOM_A53) += clk-a53.o obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o +obj-$(CONFIG_CLOCK_CPU_OSM) += clk-cpu-osm.o obj-y += mdss/ diff --git a/drivers/clk/qcom/clk-cpu-osm.c b/drivers/clk/qcom/clk-cpu-osm.c index f97cd1b03c81..ab6a1384ffbd 100644 --- a/drivers/clk/qcom/clk-cpu-osm.c +++ b/drivers/clk/qcom/clk-cpu-osm.c @@ -22,9 +22,7 @@ #include #include #include -#include -#include -#include +#include #include #include #include @@ -32,18 +30,20 @@ #include #include #include +#include #include #include - #include -#include -#include -#include +#include -#include -#include +#include "common.h" +#include "clk-regmap.h" +#include "clk-rcg.h" -#include "clock.h" +enum { + LMH_LITE_CLK_SRC, + P_XO, +}; enum clk_osm_bases { OSM_BASE, @@ -74,210 +74,192 @@ enum clk_osm_trace_packet_id { TRACE_PACKET3, }; -#define SEQ_REG(n) (0x300 + (n) * 4) -#define MEM_ACC_SEQ_REG_CFG_START(n) (SEQ_REG(12 + (n))) -#define MEM_ACC_SEQ_CONST(n) (n) -#define MEM_ACC_INSTR_COMP(n) (0x67 + ((n) * 0x40)) -#define MEM_ACC_SEQ_REG_VAL_START(n) (SEQ_REG(60 + (n))) -#define SEQ_REG1_MSMCOBALT_V2 0x1048 -#define VERSION_REG 0x0 -#define VERSION_1P1 0x00010100 +#define SEQ_REG(n) (0x300 + (n) * 4) +#define MEM_ACC_SEQ_REG_CFG_START(n) (SEQ_REG(12 + (n))) +#define MEM_ACC_SEQ_CONST(n) (n) +#define MEM_ACC_INSTR_COMP(n) (0x67 + ((n) * 0x40)) +#define MEM_ACC_SEQ_REG_VAL_START(n) (SEQ_REG(60 + (n))) +#define SEQ_REG1_OFFSET 0x1048 +#define VERSION_REG 0x0 -#define OSM_TABLE_SIZE 40 -#define MAX_CLUSTER_CNT 2 -#define MAX_CONFIG 4 -#define LLM_SW_OVERRIDE_CNT 3 +#define OSM_TABLE_SIZE 40 +#define MAX_CLUSTER_CNT 2 +#define LLM_SW_OVERRIDE_CNT 3 +#define CORE_COUNT_VAL(val) ((val & GENMASK(18, 16)) >> 16) +#define SINGLE_CORE 1 +#define MAX_CORE_COUNT 4 -#define ENABLE_REG 0x1004 -#define INDEX_REG 0x1150 -#define FREQ_REG 0x1154 -#define VOLT_REG 0x1158 -#define OVERRIDE_REG 0x115C -#define SPARE_REG 0x1164 +#define ENABLE_REG 0x1004 +#define INDEX_REG 0x1150 +#define FREQ_REG 0x1154 +#define VOLT_REG 0x1158 +#define OVERRIDE_REG 0x115C +#define SPARE_REG 0x1164 -#define OSM_CYCLE_COUNTER_CTRL_REG 0x1F00 -#define OSM_CYCLE_COUNTER_STATUS_REG 0x1F04 -#define DCVS_PERF_STATE_DESIRED_REG 0x1F10 -#define DCVS_PERF_STATE_DEVIATION_INTR_STAT 0x1F14 -#define DCVS_PERF_STATE_DEVIATION_INTR_EN 0x1F18 -#define DCVS_PERF_STATE_DEVIATION_INTR_CLEAR 0x1F1C -#define DCVS_PERF_STATE_DEVIATION_CORRECTED_INTR_STAT 0x1F20 -#define DCVS_PERF_STATE_DEVIATION_CORRECTED_INTR_EN 0x1F24 -#define DCVS_PERF_STATE_DEVIATION_CORRECTED_INTR_CLEAR 0x1F28 -#define DCVS_PERF_STATE_MET_INTR_STAT 0x1F2C -#define DCVS_PERF_STATE_MET_INTR_EN 0x1F30 -#define DCVS_PERF_STATE_MET_INTR_CLR 0x1F34 -#define OSM_CORE_TABLE_SIZE 8192 -#define OSM_REG_SIZE 32 +#define OSM_CYCLE_COUNTER_CTRL_REG 0x1F00 +#define OSM_CYCLE_COUNTER_STATUS_REG 0x1F04 +#define DCVS_PERF_STATE_DESIRED_REG 0x1F10 +#define DCVS_PERF_STATE_DEVIATION_INTR_STAT 0x1F14 +#define DCVS_PERF_STATE_DEVIATION_INTR_EN 0x1F18 +#define DCVS_PERF_STATE_DEVIATION_INTR_CLEAR 0x1F1C +#define DCVS_PERF_STATE_DEVIATION_CORRECTED_INTR_STAT 0x1F20 +#define DCVS_PERF_STATE_DEVIATION_CORRECTED_INTR_EN 0x1F24 +#define DCVS_PERF_STATE_DEVIATION_CORRECTED_INTR_CLEAR 0x1F28 +#define DCVS_PERF_STATE_MET_INTR_STAT 0x1F2C +#define DCVS_PERF_STATE_MET_INTR_EN 0x1F30 +#define DCVS_PERF_STATE_MET_INTR_CLR 0x1F34 +#define OSM_CORE_TABLE_SIZE 8192 +#define OSM_REG_SIZE 32 -#define WDOG_DOMAIN_PSTATE_STATUS 0x1c00 -#define WDOG_PROGRAM_COUNTER 0x1c74 +#define WDOG_DOMAIN_PSTATE_STATUS 0x1c00 +#define WDOG_PROGRAM_COUNTER 0x1c74 -#define OSM_CYCLE_COUNTER_USE_XO_EDGE_EN BIT(8) -#define PLL_MODE 0x0 -#define PLL_L_VAL 0x4 -#define PLL_USER_CTRL 0xC -#define PLL_CONFIG_CTL_LO 0x10 -#define PLL_TEST_CTL_HI 0x1C -#define PLL_STATUS 0x2C -#define PLL_LOCK_DET_MASK BIT(16) -#define PLL_WAIT_LOCK_TIME_US 10 -#define PLL_WAIT_LOCK_TIME_NS (PLL_WAIT_LOCK_TIME_US * 1000) -#define PLL_MIN_LVAL 43 +#define OSM_CYCLE_COUNTER_USE_XO_EDGE_EN BIT(8) -#define CC_ZERO_BEHAV_CTRL 0x100C -#define SPM_CC_DCVS_DISABLE 0x1020 -#define SPM_CC_CTRL 0x1028 -#define SPM_CC_HYSTERESIS 0x101C -#define SPM_CORE_RET_MAPPING 0x1024 -#define CFG_DELAY_VAL_3 0x12C +#define PLL_MODE 0x0 +#define PLL_L_VAL 0x4 +#define PLL_USER_CTRL 0xC +#define PLL_CONFIG_CTL_LO 0x10 +#define PLL_TEST_CTL_HI 0x1C +#define PLL_STATUS 0x2C +#define PLL_LOCK_DET_MASK BIT(16) +#define PLL_WAIT_LOCK_TIME_US 10 +#define PLL_WAIT_LOCK_TIME_NS (PLL_WAIT_LOCK_TIME_US * 1000) +#define PLL_MIN_LVAL 43 +#define L_VAL(freq_data) ((freq_data) & GENMASK(7, 0)) -#define LLM_FREQ_VOTE_HYSTERESIS 0x102C -#define LLM_VOLT_VOTE_HYSTERESIS 0x1030 -#define LLM_INTF_DCVS_DISABLE 0x1034 +#define CC_ZERO_BEHAV_CTRL 0x100C +#define SPM_CC_DCVS_DISABLE 0x1020 +#define SPM_CC_CTRL 0x1028 +#define SPM_CC_HYSTERESIS 0x101C +#define SPM_CORE_RET_MAPPING 0x1024 +#define CFG_DELAY_VAL_3 0x12C -#define ENABLE_OVERRIDE BIT(0) +#define LLM_FREQ_VOTE_HYSTERESIS 0x102C +#define LLM_VOLT_VOTE_HYSTERESIS 0x1030 +#define LLM_INTF_DCVS_DISABLE 0x1034 -#define ITM_CL0_DISABLE_CL1_ENABLED 0x2 -#define ITM_CL0_ENABLED_CL1_DISABLE 0x1 +#define ENABLE_OVERRIDE BIT(0) -#define APM_MX_MODE 0 -#define APM_APC_MODE BIT(1) -#define APM_MODE_SWITCH_MASK (BVAL(4, 2, 7) | BVAL(1, 0, 3)) -#define APM_MX_MODE_VAL 0 -#define APM_APC_MODE_VAL 0x3 +#define ITM_CL0_DISABLE_CL1_ENABLED 0x2 +#define ITM_CL0_ENABLED_CL1_DISABLE 0x1 -#define GPLL_SEL 0x400 -#define PLL_EARLY_SEL 0x500 -#define PLL_MAIN_SEL 0x300 -#define RCG_UPDATE 0x3 -#define RCG_UPDATE_SUCCESS 0x2 -#define PLL_POST_DIV1 0x1F -#define PLL_POST_DIV2 0x11F +#define APM_MX_MODE 0 +#define APM_APC_MODE BIT(1) +#define APM_MODE_SWITCH_MASK (BVAL(4, 2, 7) | BVAL(1, 0, 3)) +#define APM_MX_MODE_VAL 0 +#define APM_APC_MODE_VAL 0x3 -#define LLM_SW_OVERRIDE_REG 0x1038 -#define VMIN_REDUC_ENABLE_REG 0x103C -#define VMIN_REDUC_TIMER_REG 0x1040 -#define PDN_FSM_CTRL_REG 0x1070 -#define CC_BOOST_TIMER_REG0 0x1074 -#define CC_BOOST_TIMER_REG1 0x1078 -#define CC_BOOST_TIMER_REG2 0x107C -#define CC_BOOST_EN_MASK BIT(0) -#define PS_BOOST_EN_MASK BIT(1) -#define DCVS_BOOST_EN_MASK BIT(2) -#define PC_RET_EXIT_DROOP_EN_MASK BIT(3) -#define WFX_DROOP_EN_MASK BIT(4) -#define DCVS_DROOP_EN_MASK BIT(5) -#define LMH_PS_EN_MASK BIT(6) -#define IGNORE_PLL_LOCK_MASK BIT(15) -#define SAFE_FREQ_WAIT_NS 5000 -#define DEXT_DECREMENT_WAIT_NS 1000 -#define DCVS_BOOST_TIMER_REG0 0x1084 -#define DCVS_BOOST_TIMER_REG1 0x1088 -#define DCVS_BOOST_TIMER_REG2 0x108C -#define PS_BOOST_TIMER_REG0 0x1094 -#define PS_BOOST_TIMER_REG1 0x1098 -#define PS_BOOST_TIMER_REG2 0x109C -#define BOOST_PROG_SYNC_DELAY_REG 0x10A0 -#define DROOP_CTRL_REG 0x10A4 -#define DROOP_RELEASE_TIMER_CTRL 0x10A8 -#define DROOP_PROG_SYNC_DELAY_REG 0x10BC -#define DROOP_UNSTALL_TIMER_CTRL_REG 0x10AC -#define DROOP_WAIT_TO_RELEASE_TIMER_CTRL0_REG 0x10B0 -#define DROOP_WAIT_TO_RELEASE_TIMER_CTRL1_REG 0x10B4 -#define OSM_PLL_SW_OVERRIDE_EN 0x10C0 +#define GPLL_SEL 0x400 +#define PLL_EARLY_SEL 0x500 +#define PLL_MAIN_SEL 0x300 +#define RCG_UPDATE 0x3 +#define RCG_UPDATE_SUCCESS 0x2 +#define PLL_POST_DIV1 0x1F +#define PLL_POST_DIV2 0x11F -#define PLL_SW_OVERRIDE_DROOP_EN BIT(0) -#define DCVS_DROOP_TIMER_CTRL 0x10B8 -#define SEQ_MEM_ADDR 0x500 -#define SEQ_CFG_BR_ADDR 0x170 -#define MAX_INSTRUCTIONS 256 -#define MAX_BR_INSTRUCTIONS 49 +#define LLM_SW_OVERRIDE_REG 0x1038 +#define VMIN_REDUC_ENABLE_REG 0x103C +#define VMIN_REDUC_TIMER_REG 0x1040 +#define PDN_FSM_CTRL_REG 0x1070 +#define CC_BOOST_TIMER_REG0 0x1074 +#define CC_BOOST_TIMER_REG1 0x1078 +#define CC_BOOST_TIMER_REG2 0x107C +#define CC_BOOST_EN_MASK BIT(0) +#define PS_BOOST_EN_MASK BIT(1) +#define DCVS_BOOST_EN_MASK BIT(2) +#define PC_RET_EXIT_DROOP_EN_MASK BIT(3) +#define WFX_DROOP_EN_MASK BIT(4) +#define DCVS_DROOP_EN_MASK BIT(5) +#define LMH_PS_EN_MASK BIT(6) +#define IGNORE_PLL_LOCK_MASK BIT(15) +#define SAFE_FREQ_WAIT_NS 5000 +#define DEXT_DECREMENT_WAIT_NS 1000 +#define DCVS_BOOST_TIMER_REG0 0x1084 +#define DCVS_BOOST_TIMER_REG1 0x1088 +#define DCVS_BOOST_TIMER_REG2 0x108C +#define PS_BOOST_TIMER_REG0 0x1094 +#define PS_BOOST_TIMER_REG1 0x1098 +#define PS_BOOST_TIMER_REG2 0x109C +#define BOOST_PROG_SYNC_DELAY_REG 0x10A0 +#define DROOP_CTRL_REG 0x10A4 +#define DROOP_RELEASE_TIMER_CTRL 0x10A8 +#define DROOP_PROG_SYNC_DELAY_REG 0x10BC +#define DROOP_UNSTALL_TIMER_CTRL_REG 0x10AC +#define DROOP_WAIT_TO_RELEASE_TIMER_CTRL0_REG 0x10B0 +#define DROOP_WAIT_TO_RELEASE_TIMER_CTRL1_REG 0x10B4 +#define OSM_PLL_SW_OVERRIDE_EN 0x10C0 -#define MAX_MEM_ACC_LEVELS 3 -#define MAX_MEM_ACC_VAL_PER_LEVEL 3 -#define MAX_MEM_ACC_VALUES (MAX_MEM_ACC_LEVELS * \ - MAX_MEM_ACC_VAL_PER_LEVEL) -#define MEM_ACC_APM_READ_MASK 0xff +#define PLL_SW_OVERRIDE_DROOP_EN BIT(0) +#define DCVS_DROOP_TIMER_CTRL 0x10B8 +#define SEQ_MEM_ADDR 0x500 +#define SEQ_CFG_BR_ADDR 0x170 +#define MAX_INSTRUCTIONS 256 +#define MAX_BR_INSTRUCTIONS 49 -#define TRACE_CTRL 0x1F38 -#define TRACE_CTRL_EN_MASK BIT(0) -#define TRACE_CTRL_ENABLE 1 -#define TRACE_CTRL_DISABLE 0 -#define TRACE_CTRL_ENABLE_WDOG_STATUS BIT(30) -#define TRACE_CTRL_PACKET_TYPE_MASK BVAL(2, 1, 3) -#define TRACE_CTRL_PACKET_TYPE_SHIFT 1 -#define TRACE_CTRL_PERIODIC_TRACE_EN_MASK BIT(3) -#define TRACE_CTRL_PERIODIC_TRACE_ENABLE BIT(3) -#define PERIODIC_TRACE_TIMER_CTRL 0x1F3C -#define PERIODIC_TRACE_MIN_NS 1000 -#define PERIODIC_TRACE_MAX_NS 21474836475 -#define PERIODIC_TRACE_DEFAULT_NS 1000000 +#define MAX_MEM_ACC_LEVELS 3 +#define MAX_MEM_ACC_VAL_PER_LEVEL 3 +#define MAX_MEM_ACC_VALUES (MAX_MEM_ACC_LEVELS * \ + MAX_MEM_ACC_VAL_PER_LEVEL) +#define MEM_ACC_APM_READ_MASK 0xff -#define PLL_DD_USER_CTL_LO_ENABLE 0x0f04c408 -#define PLL_DD_USER_CTL_LO_DISABLE 0x1f04c41f -#define PLL_DD_D0_USER_CTL_LO 0x17916208 -#define PLL_DD_D1_USER_CTL_LO 0x17816208 +#define TRACE_CTRL 0x1F38 +#define TRACE_CTRL_EN_MASK BIT(0) +#define TRACE_CTRL_ENABLE 1 +#define TRACE_CTRL_DISABLE 0 +#define TRACE_CTRL_ENABLE_WDOG_STATUS BIT(30) +#define TRACE_CTRL_PACKET_TYPE_MASK BVAL(2, 1, 3) +#define TRACE_CTRL_PACKET_TYPE_SHIFT 1 +#define TRACE_CTRL_PERIODIC_TRACE_EN_MASK BIT(3) +#define TRACE_CTRL_PERIODIC_TRACE_ENABLE BIT(3) +#define PERIODIC_TRACE_TIMER_CTRL 0x1F3C +#define PERIODIC_TRACE_MIN_NS 1000 +#define PERIODIC_TRACE_MAX_NS 21474836475ULL +#define PERIODIC_TRACE_DEFAULT_NS 1000000 -#define PWRCL_EFUSE_SHIFT 0 -#define PWRCL_EFUSE_MASK 0 -#define PERFCL_EFUSE_SHIFT 29 -#define PERFCL_EFUSE_MASK 0x7 +#define PLL_DD_USER_CTL_LO_ENABLE 0x0f04c408 +#define PLL_DD_USER_CTL_LO_DISABLE 0x1f04c41f +#define PLL_DD_D0_USER_CTL_LO 0x17916208 +#define PLL_DD_D1_USER_CTL_LO 0x17816208 -#define MSMCOBALTV1_PWRCL_BOOT_RATE 1478400000 -#define MSMCOBALTV1_PERFCL_BOOT_RATE 1536000000 -#define MSMCOBALTV2_PWRCL_BOOT_RATE 1555200000 -#define MSMCOBALTV2_PERFCL_BOOT_RATE 1728000000 +#define PWRCL_EFUSE_SHIFT 0 +#define PWRCL_EFUSE_MASK 0 +#define PERFCL_EFUSE_SHIFT 29 +#define PERFCL_EFUSE_MASK 0x7 /* ACD registers */ -#define ACD_HW_VERSION 0x0 -#define ACDCR 0x4 -#define ACDTD 0x8 -#define ACDSSCR 0x28 -#define ACD_EXTINT_CFG 0x30 -#define ACD_DCVS_SW 0x34 -#define ACD_GFMUX_CFG 0x3c -#define ACD_READOUT_CFG 0x48 -#define ACD_AUTOXFER_CFG 0x80 -#define ACD_AUTOXFER 0x84 -#define ACD_AUTOXFER_CTL 0x88 -#define ACD_AUTOXFER_STATUS 0x8c -#define ACD_WRITE_CTL 0x90 -#define ACD_WRITE_STATUS 0x94 -#define ACD_READOUT 0x98 +#define ACD_HW_VERSION 0x0 +#define ACDCR 0x4 +#define ACDTD 0x8 +#define ACDSSCR 0x28 +#define ACD_EXTINT_CFG 0x30 +#define ACD_DCVS_SW 0x34 +#define ACD_GFMUX_CFG 0x3c +#define ACD_READOUT_CFG 0x48 +#define ACD_AUTOXFER_CFG 0x80 +#define ACD_AUTOXFER 0x84 +#define ACD_AUTOXFER_CTL 0x88 +#define ACD_AUTOXFER_STATUS 0x8c +#define ACD_WRITE_CTL 0x90 +#define ACD_WRITE_STATUS 0x94 +#define ACD_READOUT 0x98 -#define ACD_MASTER_ONLY_REG_ADDR 0x80 -#define ACD_WRITE_CTL_UPDATE_EN BIT(0) -#define ACD_WRITE_CTL_SELECT_SHIFT 1 -#define ACD_GFMUX_CFG_SELECT BIT(0) -#define ACD_AUTOXFER_START_CLEAR 0 -#define ACD_AUTOXFER_START_SET BIT(0) -#define AUTO_XFER_DONE_MASK BIT(0) -#define ACD_DCVS_SW_DCVS_IN_PRGR_SET BIT(0) -#define ACD_DCVS_SW_DCVS_IN_PRGR_CLEAR 0 -#define ACD_LOCAL_TRANSFER_TIMEOUT_NS 500 +#define ACD_MASTER_ONLY_REG_ADDR 0x80 +#define ACD_WRITE_CTL_UPDATE_EN BIT(0) +#define ACD_WRITE_CTL_SELECT_SHIFT 1 +#define ACD_GFMUX_CFG_SELECT BIT(0) +#define ACD_AUTOXFER_START_CLEAR 0 +#define ACD_AUTOXFER_START_SET BIT(0) +#define AUTO_XFER_DONE_MASK BIT(0) +#define ACD_DCVS_SW_DCVS_IN_PRGR_SET BIT(0) +#define ACD_DCVS_SW_DCVS_IN_PRGR_CLEAR 0 +#define ACD_LOCAL_TRANSFER_TIMEOUT_NS 500 -static void __iomem *virt_base; -static void __iomem *debug_base; - -#define lmh_lite_clk_src_source_val 1 - -#define ACD_REG_RELATIVE_ADDR(addr) (addr / 4) +#define ACD_REG_RELATIVE_ADDR(addr) (addr / 4) #define ACD_REG_RELATIVE_ADDR_BITMASK(addr) \ - (1 << (ACD_REG_RELATIVE_ADDR(addr))) + (1 << (ACD_REG_RELATIVE_ADDR(addr))) -#define FIXDIV(div) (div ? (2 * (div) - 1) : (0)) - -#define F(f, s, div, m, n) \ - { \ - .freq_hz = (f), \ - .src_clk = &s.c, \ - .m_val = (m), \ - .n_val = ~((n)-(m)) * !!(n), \ - .d_val = ~(n),\ - .div_src_val = BVAL(4, 0, (int)FIXDIV(div)) \ - | BVAL(10, 8, s##_source_val), \ - } +#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } static u32 seq_instr[] = { 0xc2005000, 0x2c9e3b21, 0xc0ab2cdc, 0xc2882525, 0x359dc491, @@ -325,10 +307,6 @@ static u32 seq_br_instr[] = { 0x20c, }; -DEFINE_EXT_CLK(xo_ao, NULL); -DEFINE_EXT_CLK(sys_apcsaux_clk_gcc, NULL); -DEFINE_EXT_CLK(lmh_lite_clk_src, NULL); - struct osm_entry { u16 virtual_corner; u16 open_loop_volt; @@ -338,10 +316,20 @@ struct osm_entry { long frequency; }; +static void __iomem *virt_base; static struct dentry *osm_debugfs_base; +static struct regulator *vdd_pwrcl; +static struct regulator *vdd_perfcl; + +static const struct regmap_config osm_qcom_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .fast_io = true, +}; struct clk_osm { - struct clk c; + struct clk_hw hw; struct osm_entry osm_table[OSM_TABLE_SIZE]; struct dentry *debugfs; struct regulator *vdd_reg; @@ -350,13 +338,14 @@ struct clk_osm { unsigned long pbases[NUM_BASES]; spinlock_t lock; - u32 version; u32 cpu_reg_mask; u32 num_entries; u32 cluster_num; u32 irq; u32 apm_crossover_vc; u32 apm_threshold_vc; + u32 mem_acc_crossover_vc; + u32 mem_acc_threshold_vc; u32 cycle_counter_reads; u32 cycle_counter_delay; u32 cycle_counter_factor; @@ -399,9 +388,6 @@ struct clk_osm { bool wdog_trace_en; }; -static bool msmcobalt_v1; -static bool msmcobalt_v2; - static inline void clk_osm_masked_write_reg(struct clk_osm *c, u32 val, u32 offset, u32 mask) { @@ -600,63 +586,86 @@ static inline int clk_osm_count_ns(struct clk_osm *c, u64 nsec) return temp; } -static inline struct clk_osm *to_clk_osm(struct clk *c) +static inline struct clk_osm *to_clk_osm(struct clk_hw *_hw) { - return container_of(c, struct clk_osm, c); + return container_of(_hw, struct clk_osm, hw); } -static enum handoff clk_osm_handoff(struct clk *c) +static long clk_osm_list_rate(struct clk_hw *hw, unsigned n, + unsigned long rate_max) { - return HANDOFF_DISABLED_CLK; -} - -static long clk_osm_list_rate(struct clk *c, unsigned n) -{ - if (n >= c->num_fmax) + if (n >= hw->init->num_rate_max) return -ENXIO; - return c->fmax[n]; + return hw->init->rate_max[n]; } -static long clk_osm_round_rate(struct clk *c, unsigned long rate) +static inline bool is_better_rate(unsigned long req, unsigned long best, + unsigned long new) +{ + if (IS_ERR_VALUE(new)) + return false; + + return (req <= new && new < best) || (best < req && best < new); +} + +static long clk_osm_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) { int i; unsigned long rrate = 0; /* - * If the rate passed in is 0, return the first frequency in - * the FMAX table. + * If the rate passed in is 0, return the first frequency in the + * FMAX table. */ if (!rate) - return c->fmax[0]; + return hw->init->rate_max[0]; - for (i = 0; i < c->num_fmax; i++) { - if (is_better_rate(rate, rrate, c->fmax[i])) { - rrate = c->fmax[i]; - if (rrate == rate) + for (i = 0; i < hw->init->num_rate_max; i++) { + if (is_better_rate(rate, rrate, hw->init->rate_max[i])) { + rrate = hw->init->rate_max[i]; + if (rate == rrate) break; } } + pr_debug("%s: rate %lu, rrate %ld, Rate max %ld\n", __func__, rate, + rrate, hw->init->rate_max[i]); + return rrate; } static int clk_osm_search_table(struct osm_entry *table, int entries, long rate) { - int i; + int quad_core_index, single_core_index = 0; + int core_count; + + for (quad_core_index = 0; quad_core_index < entries; + quad_core_index++) { + core_count = CORE_COUNT_VAL(table[quad_core_index].freq_data); + if (rate == table[quad_core_index].frequency && + core_count == SINGLE_CORE) { + single_core_index = quad_core_index; + continue; + } + if (rate == table[quad_core_index].frequency && + core_count == MAX_CORE_COUNT) + return quad_core_index; + } + if (single_core_index) + return single_core_index; - for (i = 0; i < entries; i++) - if (rate == table[i].frequency) - return i; return -EINVAL; } -static int clk_osm_set_rate(struct clk *c, unsigned long rate) +static int clk_osm_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) { - struct clk_osm *cpuclk = to_clk_osm(c); + struct clk_osm *cpuclk = to_clk_osm(hw); int index = 0; unsigned long r_rate; - r_rate = clk_osm_round_rate(c, rate); + r_rate = clk_osm_round_rate(hw, rate, NULL); if (rate != r_rate) { pr_err("invalid rate requested rate=%ld\n", rate); @@ -675,9 +684,9 @@ static int clk_osm_set_rate(struct clk *c, unsigned long rate) if (cpuclk->llm_sw_overr[0]) { clk_osm_write_reg(cpuclk, cpuclk->llm_sw_overr[0], - LLM_SW_OVERRIDE_REG); + LLM_SW_OVERRIDE_REG); clk_osm_write_reg(cpuclk, cpuclk->llm_sw_overr[1], - LLM_SW_OVERRIDE_REG); + LLM_SW_OVERRIDE_REG); udelay(1); } @@ -687,7 +696,7 @@ static int clk_osm_set_rate(struct clk *c, unsigned long rate) if (cpuclk->llm_sw_overr[0]) { udelay(1); clk_osm_write_reg(cpuclk, cpuclk->llm_sw_overr[2], - LLM_SW_OVERRIDE_REG); + LLM_SW_OVERRIDE_REG); } /* Make sure the write goes through before proceeding */ @@ -696,9 +705,9 @@ static int clk_osm_set_rate(struct clk *c, unsigned long rate) return 0; } -static int clk_osm_enable(struct clk *c) +static int clk_osm_enable(struct clk_hw *hw) { - struct clk_osm *cpuclk = to_clk_osm(c); + struct clk_osm *cpuclk = to_clk_osm(hw); clk_osm_write_reg(cpuclk, 1, ENABLE_REG); @@ -713,96 +722,109 @@ static int clk_osm_enable(struct clk *c) return 0; } +static unsigned long clk_osm_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_osm *cpuclk = to_clk_osm(hw); + int index = 0; + + index = clk_osm_read_reg(cpuclk, DCVS_PERF_STATE_DESIRED_REG); + + pr_debug("%s: Index %d, freq %ld\n", __func__, index, + cpuclk->osm_table[index].frequency); + + /* Convert index to frequency. + * The frequency corresponding to the index requested might not + * be what the clock is actually running at. + * There are other inputs into OSM(acd, LMH, sequencer) + * which might decide the final rate. + */ + return cpuclk->osm_table[index].frequency; +} + static struct clk_ops clk_ops_cpu_osm = { .enable = clk_osm_enable, .set_rate = clk_osm_set_rate, .round_rate = clk_osm_round_rate, .list_rate = clk_osm_list_rate, - .handoff = clk_osm_handoff, + .recalc_rate = clk_osm_recalc_rate, }; -static struct regulator *vdd_pwrcl; -static struct regulator *vdd_perfcl; - -static struct clk_freq_tbl ftbl_osm_clk_src[] = { - F( 200000000, lmh_lite_clk_src, 1.5, 0, 0), - F_END +static const struct parent_map gcc_parent_map_1[] = { + { P_XO, 0 }, + { LMH_LITE_CLK_SRC, 1 }, }; -static struct rcg_clk osm_clk_src = { - .cmd_rcgr_reg = APCS_COMMON_LMH_CMD_RCGR, - .set_rate = set_rate_hid, +static const char * const gcc_parent_names_1[] = { + "xo", + "hmss_gpll0_clk_src", +}; + +static struct freq_tbl ftbl_osm_clk_src[] = { + F(200000000, LMH_LITE_CLK_SRC, 3, 0, 0), + { } +}; + +/* APCS_COMMON_LMH_CMD_RCGR */ +static struct clk_rcg2 osm_clk_src = { + .cmd_rcgr = 0x0012c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_1, .freq_tbl = ftbl_osm_clk_src, - .current_freq = &rcg_dummy_freq, - .base = &virt_base, - .c = { - .dbg_name = "osm_clk_src", - .ops = &clk_ops_rcg, - CLK_INIT(osm_clk_src.c), + .clkr.hw.init = &(struct clk_init_data){ + .name = "osm_clk_src", + .parent_names = gcc_parent_names_1, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_fixed_factor sys_apcsaux_clk_gcc = { + .div = 1, + .mult = 1, + .hw.init = &(struct clk_init_data){ + .name = "sys_apcsaux_clk_gcc", + .parent_names = (const char *[]){ "hmss_gpll0_clk_src" }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + }, +}; + +static struct clk_init_data osm_clks_init[] = { + [0] = { + .name = "pwrcl_clk", + .parent_names = (const char *[]){ "cxo_a" }, + .num_parents = 1, + .ops = &clk_ops_cpu_osm, + }, + [1] = { + .name = "perfcl_clk", + .parent_names = (const char *[]){ "cxo_a" }, + .num_parents = 1, + .ops = &clk_ops_cpu_osm, }, }; static struct clk_osm pwrcl_clk = { .cluster_num = 0, .cpu_reg_mask = 0x3, - .c = { - .dbg_name = "pwrcl_clk", - .ops = &clk_ops_cpu_osm, - .parent = &xo_ao.c, - CLK_INIT(pwrcl_clk.c), - }, + .hw.init = &osm_clks_init[0], }; static struct clk_osm perfcl_clk = { .cluster_num = 1, .cpu_reg_mask = 0x103, - .c = { - .dbg_name = "perfcl_clk", - .ops = &clk_ops_cpu_osm, - .parent = &xo_ao.c, - CLK_INIT(perfcl_clk.c), - }, + .hw.init = &osm_clks_init[1], }; -static struct clk_ops clk_ops_cpu_dbg_mux; - -static struct mux_clk cpu_debug_mux = { - .offset = 0x0, - .mask = 0x3, - .shift = 8, - .ops = &mux_reg_ops, - MUX_SRC_LIST( - { &pwrcl_clk.c, 0x00 }, - { &perfcl_clk.c, 0x01 }, - ), - .base = &debug_base, - .c = { - .dbg_name = "cpu_debug_mux", - .ops = &clk_ops_cpu_dbg_mux, - .flags = CLKFLAG_NO_RATE_CACHE, - CLK_INIT(cpu_debug_mux.c), - }, +static struct clk_hw *osm_qcom_clk_hws[] = { + [SYS_APCSAUX_CLK_GCC] = &sys_apcsaux_clk_gcc.hw, + [PWRCL_CLK] = &pwrcl_clk.hw, + [PERFCL_CLK] = &perfcl_clk.hw, + [OSM_CLK_SRC] = &osm_clk_src.clkr.hw, }; -static struct clk_lookup cpu_clocks_osm[] = { - CLK_LIST(pwrcl_clk), - CLK_LIST(perfcl_clk), - CLK_LIST(sys_apcsaux_clk_gcc), - CLK_LIST(xo_ao), - CLK_LIST(osm_clk_src), - CLK_LIST(cpu_debug_mux), -}; - -static unsigned long cpu_dbg_mux_get_rate(struct clk *clk) -{ - /* Account for the divider between the clock and the debug mux */ - if (!strcmp(clk->parent->dbg_name, "pwrcl_clk")) - return clk->rate/4; - else if (!strcmp(clk->parent->dbg_name, "perfcl_clk")) - return clk->rate/8; - return clk->rate; -} - static void clk_osm_print_osm_table(struct clk_osm *c) { int i; @@ -813,7 +835,7 @@ static void clk_osm_print_osm_table(struct clk_osm *c) for (i = 0; i < c->num_entries; i++) { pll_src = (table[i].freq_data & GENMASK(27, 26)) >> 26; pll_div = (table[i].freq_data & GENMASK(25, 24)) >> 24; - lval = table[i].freq_data & GENMASK(7, 0); + lval = L_VAL(table[i].freq_data); core_count = (table[i].freq_data & GENMASK(18, 16)) >> 16; pr_debug("%3d, %11lu, %2u, %5u, %2u, %6u, %8u, %7u, %5u\n", @@ -828,18 +850,21 @@ static void clk_osm_print_osm_table(struct clk_osm *c) table[i].spare_data); } pr_debug("APM threshold corner=%d, crossover corner=%d\n", - c->apm_threshold_vc, c->apm_crossover_vc); + c->apm_threshold_vc, c->apm_crossover_vc); + pr_debug("MEM-ACC threshold corner=%d, crossover corner=%d\n", + c->mem_acc_threshold_vc, c->mem_acc_crossover_vc); } static int clk_osm_get_lut(struct platform_device *pdev, struct clk_osm *c, char *prop_name) { - struct clk *clk = &c->c; struct device_node *of = pdev->dev.of_node; int prop_len, total_elems, num_rows, i, j, k; int rc = 0; u32 *array; + u32 *fmax_temp; u32 data; + unsigned long abs_fmax = 0; bool last_entry = false; if (!of_find_property(of, prop_name, &prop_len)) { @@ -855,9 +880,9 @@ static int clk_osm_get_lut(struct platform_device *pdev, num_rows = total_elems / NUM_FIELDS; - clk->fmax = devm_kzalloc(&pdev->dev, num_rows * sizeof(unsigned long), - GFP_KERNEL); - if (!clk->fmax) + fmax_temp = devm_kzalloc(&pdev->dev, num_rows * sizeof(unsigned long), + GFP_KERNEL); + if (!fmax_temp) return -ENOMEM; array = devm_kzalloc(&pdev->dev, prop_len, GFP_KERNEL); @@ -893,18 +918,34 @@ static int clk_osm_get_lut(struct platform_device *pdev, c->osm_table[j].spare_data); data = (array[i + FREQ_DATA] & GENMASK(18, 16)) >> 16; - if (!last_entry) { - clk->fmax[k] = array[i]; + if (!last_entry && data == MAX_CORE_COUNT) { + fmax_temp[k] = array[i]; k++; } if (i < total_elems - NUM_FIELDS) i += NUM_FIELDS; - else + else { + abs_fmax = array[i]; last_entry = true; + } } - clk->num_fmax = k; + fmax_temp[k] = abs_fmax; + + osm_clks_init[c->cluster_num].rate_max = devm_kzalloc(&pdev->dev, + k * sizeof(unsigned long), + GFP_KERNEL); + if (!osm_clks_init[c->cluster_num].rate_max) { + rc = -ENOMEM; + goto exit; + } + + for (i = 0; i < k; i++) + osm_clks_init[c->cluster_num].rate_max[i] = fmax_temp[i]; + + osm_clks_init[c->cluster_num].num_rate_max = k; exit: + devm_kfree(&pdev->dev, fmax_temp); devm_kfree(&pdev->dev, array); return rc; } @@ -1192,7 +1233,6 @@ static int clk_osm_resources_init(struct platform_device *pdev) { struct device_node *node; struct resource *res; - struct clk *c; unsigned long pbase; int i, rc = 0; void *vbase; @@ -1213,9 +1253,9 @@ static int clk_osm_resources_init(struct platform_device *pdev) } perfcl_clk.pbases[OSM_BASE] = pwrcl_clk.pbases[OSM_BASE] + - perfcl_clk.cluster_num * OSM_CORE_TABLE_SIZE; + perfcl_clk.cluster_num * OSM_CORE_TABLE_SIZE; perfcl_clk.vbases[OSM_BASE] = pwrcl_clk.vbases[OSM_BASE] + - perfcl_clk.cluster_num * OSM_CORE_TABLE_SIZE; + perfcl_clk.cluster_num * OSM_CORE_TABLE_SIZE; for (i = 0; i < MAX_CLUSTER_CNT; i++) { res = platform_get_resource_byname(pdev, IORESOURCE_MEM, @@ -1244,22 +1284,6 @@ static int clk_osm_resources_init(struct platform_device *pdev) } } - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "debug"); - if (!res) { - dev_err(&pdev->dev, "Failed to get debug mux base\n"); - return -EINVAL; - } - - debug_base = devm_ioremap(&pdev->dev, res->start, - resource_size(res)); - if (!debug_base) { - dev_err(&pdev->dev, "Unable to map in debug mux base\n"); - return -ENOMEM; - } - - clk_ops_cpu_dbg_mux = clk_ops_gen_mux; - clk_ops_cpu_dbg_mux.get_rate = cpu_dbg_mux_get_rate; - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "apcs_common"); if (!res) { dev_err(&pdev->dev, "Failed to get apcs common base\n"); @@ -1272,6 +1296,13 @@ static int clk_osm_resources_init(struct platform_device *pdev) return -ENOMEM; } + osm_clk_src.clkr.regmap = devm_regmap_init_mmio(&pdev->dev, virt_base, + &osm_qcom_regmap_config); + if (IS_ERR(osm_clk_src.clkr.regmap)) { + dev_err(&pdev->dev, "Couldn't get regmap OSM clock\n"); + return PTR_ERR(osm_clk_src.clkr.regmap); + } + /* efuse speed bin fuses are optional */ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pwrcl_efuse"); @@ -1381,26 +1412,6 @@ static int clk_osm_resources_init(struct platform_device *pdev) return -EINVAL; } - c = devm_clk_get(&pdev->dev, "aux_clk"); - if (IS_ERR(c)) { - rc = PTR_ERR(c); - if (rc != -EPROBE_DEFER) - dev_err(&pdev->dev, "Unable to get aux_clk, rc=%d\n", - rc); - return rc; - } - sys_apcsaux_clk_gcc.c.parent = c; - - c = devm_clk_get(&pdev->dev, "xo_ao"); - if (IS_ERR(c)) { - rc = PTR_ERR(c); - if (rc != -EPROBE_DEFER) - dev_err(&pdev->dev, "Unable to get xo_ao clk, rc=%d\n", - rc); - return rc; - } - xo_ao.c.parent = c; - return 0; } @@ -1490,20 +1501,27 @@ static int clk_osm_resolve_open_loop_voltages(struct clk_osm *c) } static int clk_osm_resolve_crossover_corners(struct clk_osm *c, - struct platform_device *pdev) + struct platform_device *pdev, + const char *mem_acc_prop) { struct regulator *regulator = c->vdd_reg; - int count, vc, i, threshold, rc = 0; + int count, vc, i, apm_threshold; + int mem_acc_threshold = 0; + int rc = 0; u32 corner_volt; rc = of_property_read_u32(pdev->dev.of_node, "qcom,apm-threshold-voltage", - &threshold); + &apm_threshold); if (rc) { pr_info("qcom,apm-threshold-voltage property not specified\n"); return rc; } + if (mem_acc_prop) + of_property_read_u32(pdev->dev.of_node, mem_acc_prop, + &mem_acc_threshold); + /* Determine crossover virtual corner */ count = regulator_count_voltages(regulator); if (count < 0) { @@ -1511,19 +1529,49 @@ static int clk_osm_resolve_crossover_corners(struct clk_osm *c, return count; } - c->apm_crossover_vc = count - 1; + /* + * CPRh corners (in hardware) are ordered: + * 0 - n-1 - for n functional corners + * APM crossover - required for OSM + * [MEM ACC Crossover] - optional + * + * 'count' corresponds to the total number of corners including n + * functional corners, the APM crossover corner, and potentially the + * MEM ACC cross over corner. + */ + if (mem_acc_threshold) { + c->apm_crossover_vc = count - 2; + c->mem_acc_crossover_vc = count - 1; + } else { + c->apm_crossover_vc = count - 1; + } - /* Determine threshold virtual corner */ + /* Determine APM threshold virtual corner */ for (i = 0; i < OSM_TABLE_SIZE; i++) { vc = c->osm_table[i].virtual_corner + 1; corner_volt = regulator_list_corner_voltage(regulator, vc); - if (corner_volt >= threshold) { + if (corner_volt >= apm_threshold) { c->apm_threshold_vc = c->osm_table[i].virtual_corner; break; } } + /* Determine MEM ACC threshold virtual corner */ + if (mem_acc_threshold) { + for (i = 0; i < OSM_TABLE_SIZE; i++) { + vc = c->osm_table[i].virtual_corner + 1; + corner_volt = + regulator_list_corner_voltage(regulator, vc); + + if (corner_volt >= mem_acc_threshold) { + c->mem_acc_threshold_vc + = c->osm_table[i].virtual_corner; + break; + } + } + } + return 0; } @@ -1777,9 +1825,9 @@ static int clk_osm_set_llm_volt_policy(struct platform_device *pdev) /* Enable or disable LLM VOLT DVCS */ regval = val | clk_osm_read_reg(&pwrcl_clk, LLM_INTF_DCVS_DISABLE); - clk_osm_write_reg(&pwrcl_clk, val, LLM_INTF_DCVS_DISABLE); + clk_osm_write_reg(&pwrcl_clk, regval, LLM_INTF_DCVS_DISABLE); regval = val | clk_osm_read_reg(&perfcl_clk, LLM_INTF_DCVS_DISABLE); - clk_osm_write_reg(&perfcl_clk, val, LLM_INTF_DCVS_DISABLE); + clk_osm_write_reg(&perfcl_clk, regval, LLM_INTF_DCVS_DISABLE); /* Wait for the writes to complete */ clk_osm_mb(&perfcl_clk, OSM_BASE); @@ -1820,8 +1868,10 @@ static void clk_osm_program_apm_regs(struct clk_osm *c) static void clk_osm_program_mem_acc_regs(struct clk_osm *c) { + struct osm_entry *table = c->osm_table; int i, curr_level, j = 0; int mem_acc_level_map[MAX_MEM_ACC_LEVELS] = {0, 0, 0}; + int threshold_vc[4]; curr_level = c->osm_table[0].spare_data; for (i = 0; i < c->num_entries; i++) { @@ -1829,7 +1879,8 @@ static void clk_osm_program_mem_acc_regs(struct clk_osm *c) break; if (c->osm_table[i].spare_data != curr_level) { - mem_acc_level_map[j++] = i - 1; + mem_acc_level_map[j++] = + c->osm_table[i].virtual_corner - 1; curr_level = c->osm_table[i].spare_data; } } @@ -1855,16 +1906,49 @@ static void clk_osm_program_mem_acc_regs(struct clk_osm *c) clk_osm_write_reg(c, c->apcs_mem_acc_cfg[i], MEM_ACC_SEQ_REG_CFG_START(i)); } else { + if (c->mem_acc_crossover_vc) + scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(88), + c->mem_acc_crossover_vc); + + threshold_vc[0] = mem_acc_level_map[0]; + threshold_vc[1] = mem_acc_level_map[0] + 1; + threshold_vc[2] = mem_acc_level_map[1]; + threshold_vc[3] = mem_acc_level_map[1] + 1; + + /* + * Use dynamic MEM ACC threshold voltage based value for the + * highest MEM ACC threshold if it is specified instead of the + * fixed mapping in the LUT. + */ + if (c->mem_acc_threshold_vc) { + threshold_vc[2] = c->mem_acc_threshold_vc - 1; + threshold_vc[3] = c->mem_acc_threshold_vc; + if (threshold_vc[1] >= threshold_vc[2]) + threshold_vc[1] = threshold_vc[2] - 1; + if (threshold_vc[0] >= threshold_vc[1]) + threshold_vc[0] = threshold_vc[1] - 1; + } + scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(55), - mem_acc_level_map[0]); + threshold_vc[0]); scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(56), - mem_acc_level_map[0] + 1); + threshold_vc[1]); scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(57), - mem_acc_level_map[1]); + threshold_vc[2]); scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(58), - mem_acc_level_map[1] + 1); + threshold_vc[3]); /* SEQ_REG(49) = SEQ_REG(28) init by TZ */ } + + /* + * Program L_VAL corresponding to the first virtual + * corner with MEM ACC level 3. + */ + if (c->mem_acc_threshold_vc) + for (i = 0; i < c->num_entries; i++) + if (c->mem_acc_threshold_vc == table[i].virtual_corner) + scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(32), + L_VAL(table[i].freq_data)); } void clk_osm_setup_sequencer(struct clk_osm *c) @@ -1895,95 +1979,15 @@ static void clk_osm_setup_cycle_counters(struct clk_osm *c) /* Setup OSM clock to XO ratio */ do_div(ratio, c->xo_clk_rate); val |= BVAL(5, 1, ratio - 1) | OSM_CYCLE_COUNTER_USE_XO_EDGE_EN; + clk_osm_write_reg(c, val, OSM_CYCLE_COUNTER_CTRL_REG); + c->total_cycle_counter = 0; c->prev_cycle_counter = 0; + pr_debug("OSM to XO clock ratio: %d\n", ratio); } -static void clk_osm_setup_osm_was(struct clk_osm *c) -{ - u32 cc_hyst; - u32 val; - - if (msmcobalt_v2) - return; - - val = clk_osm_read_reg(c, PDN_FSM_CTRL_REG); - val |= IGNORE_PLL_LOCK_MASK; - cc_hyst = clk_osm_read_reg(c, SPM_CC_HYSTERESIS); - - if (c->secure_init) { - clk_osm_write_reg(c, val, SEQ_REG(47)); - val &= ~IGNORE_PLL_LOCK_MASK; - clk_osm_write_reg(c, val, SEQ_REG(48)); - - clk_osm_write_reg(c, c->pbases[OSM_BASE] + SEQ_REG(42), - SEQ_REG(40)); - clk_osm_write_reg(c, c->pbases[OSM_BASE] + SEQ_REG(43), - SEQ_REG(41)); - clk_osm_write_reg(c, 0x1, SEQ_REG(44)); - clk_osm_write_reg(c, 0x0, SEQ_REG(45)); - clk_osm_write_reg(c, c->pbases[OSM_BASE] + PDN_FSM_CTRL_REG, - SEQ_REG(46)); - - /* C2D/C3 + D2D workaround */ - clk_osm_write_reg(c, c->pbases[OSM_BASE] + SPM_CC_HYSTERESIS, - SEQ_REG(6)); - clk_osm_write_reg(c, cc_hyst, SEQ_REG(7)); - - /* Droop detector PLL lock detect workaround */ - clk_osm_write_reg(c, PLL_DD_USER_CTL_LO_ENABLE, SEQ_REG(4)); - clk_osm_write_reg(c, PLL_DD_USER_CTL_LO_DISABLE, SEQ_REG(5)); - clk_osm_write_reg(c, c->cluster_num == 0 ? PLL_DD_D0_USER_CTL_LO - : PLL_DD_D1_USER_CTL_LO, SEQ_REG(21)); - - /* PLL lock detect and HMSS AHB clock workaround */ - clk_osm_write_reg(c, 0x640, CFG_DELAY_VAL_3); - - /* DxFSM workaround */ - clk_osm_write_reg(c, c->cluster_num == 0 ? 0x17911200 : - 0x17811200, SEQ_REG(22)); - clk_osm_write_reg(c, 0x80800, SEQ_REG(23)); - clk_osm_write_reg(c, 0x179D1100, SEQ_REG(24)); - clk_osm_write_reg(c, 0x11f, SEQ_REG(25)); - clk_osm_write_reg(c, c->cluster_num == 0 ? 0x17912000 : - 0x17811290, SEQ_REG(26)); - clk_osm_write_reg(c, c->cluster_num == 0 ? 0x17911290 : - 0x17811290, SEQ_REG(20)); - clk_osm_write_reg(c, c->cluster_num == 0 ? 0x17811290 : - 0x17911290, SEQ_REG(32)); - clk_osm_write_reg(c, 0x179D4020, SEQ_REG(35)); - clk_osm_write_reg(c, 0x11f, SEQ_REG(25)); - clk_osm_write_reg(c, 0xa, SEQ_REG(86)); - clk_osm_write_reg(c, 0xe, SEQ_REG(87)); - clk_osm_write_reg(c, 0x00400000, SEQ_REG(88)); - clk_osm_write_reg(c, 0x00700000, SEQ_REG(89)); - } else { - scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(47), val); - val &= ~IGNORE_PLL_LOCK_MASK; - scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(48), val); - - /* C2D/C3 + D2D workaround */ - scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(7), - cc_hyst); - - /* Droop detector PLL lock detect workaround */ - scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(4), - PLL_DD_USER_CTL_LO_ENABLE); - } - - if (c->cluster_num == 0) { - val = readl_relaxed(c->vbases[PLL_BASE] + PLL_TEST_CTL_HI) - | BIT(13); - writel_relaxed(val, c->vbases[PLL_BASE] + - PLL_TEST_CTL_HI); - } - - /* Ensure writes complete before returning */ - clk_osm_mb(c, OSM_BASE); -} - static void clk_osm_setup_fsms(struct clk_osm *c) { u32 val; @@ -2128,7 +2132,7 @@ static void clk_osm_do_additional_setup(struct clk_osm *c, return; dev_info(&pdev->dev, "Performing additional OSM setup due to lack of TZ for cluster=%d\n", - c->cluster_num); + c->cluster_num); clk_osm_write_reg(c, BVAL(23, 16, 0xF), SPM_CC_CTRL); @@ -2157,7 +2161,7 @@ static void clk_osm_do_additional_setup(struct clk_osm *c, /* ITM to OSM handoff */ clk_osm_setup_itm_to_osm_handoff(); - pr_debug("seq_size: %lu, seqbr_size: %lu\n", ARRAY_SIZE(seq_instr), + pr_debug("seq_size: %zu, seqbr_size: %zu\n", ARRAY_SIZE(seq_instr), ARRAY_SIZE(seq_br_instr)); clk_osm_setup_sequencer(&pwrcl_clk); clk_osm_setup_sequencer(&perfcl_clk); @@ -2175,38 +2179,31 @@ static void clk_osm_apm_vc_setup(struct clk_osm *c) clk_osm_write_reg(c, c->apm_threshold_vc, SEQ_REG(1)); clk_osm_write_reg(c, c->apm_crossover_vc, SEQ_REG(72)); clk_osm_write_reg(c, c->pbases[OSM_BASE] + SEQ_REG(1), - SEQ_REG(8)); - clk_osm_write_reg(c, c->apm_threshold_vc, - SEQ_REG(15)); + SEQ_REG(8)); + clk_osm_write_reg(c, c->apm_threshold_vc, SEQ_REG(15)); clk_osm_write_reg(c, c->apm_threshold_vc != 0 ? - c->apm_threshold_vc - 1 : 0xff, - SEQ_REG(31)); + c->apm_threshold_vc - 1 : 0xff, + SEQ_REG(31)); clk_osm_write_reg(c, 0x3b | c->apm_threshold_vc << 6, - SEQ_REG(73)); + SEQ_REG(73)); clk_osm_write_reg(c, 0x39 | c->apm_threshold_vc << 6, - SEQ_REG(76)); + SEQ_REG(76)); /* Ensure writes complete before returning */ clk_osm_mb(c, OSM_BASE); } else { - if (msmcobalt_v1) { - scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(1), - c->apm_threshold_vc); - scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(73), - 0x3b | c->apm_threshold_vc << 6); - } else if (msmcobalt_v2) { + if (c->apm_threshold_vc) clk_osm_write_reg(c, c->apm_threshold_vc, - SEQ_REG1_MSMCOBALT_V2); - } + SEQ_REG1_OFFSET); scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(72), - c->apm_crossover_vc); + c->apm_crossover_vc); scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(15), - c->apm_threshold_vc); + c->apm_threshold_vc); scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(31), - c->apm_threshold_vc != 0 ? - c->apm_threshold_vc - 1 : 0xff); + c->apm_threshold_vc != 0 ? + c->apm_threshold_vc - 1 : 0xff); scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(76), - 0x39 | c->apm_threshold_vc << 6); + 0x39 | c->apm_threshold_vc << 6); } } @@ -2298,11 +2295,12 @@ static int add_opp(struct clk_osm *c, struct device *dev) u32 uv; long rc; int j = 0; - unsigned long min_rate = c->c.fmax[0]; - unsigned long max_rate = c->c.fmax[c->c.num_fmax - 1]; + unsigned long min_rate = c->hw.init->rate_max[0]; + unsigned long max_rate = + c->hw.init->rate_max[c->hw.init->num_rate_max - 1]; while (1) { - rate = c->c.fmax[j++]; + rate = c->hw.init->rate_max[j++]; uv = find_voltage(c, rate); if (uv <= 0) { pr_warn("No voltage for %lu.\n", rate); @@ -2360,12 +2358,12 @@ static struct clk *logical_cpu_to_clk(int cpu) hwid = of_read_number(cell, of_n_addr_cells(cpu_node)); if ((hwid | pwrcl_clk.cpu_reg_mask) == pwrcl_clk.cpu_reg_mask) { - cpu_clk_map[cpu] = &pwrcl_clk.c; - return &pwrcl_clk.c; + cpu_clk_map[cpu] = pwrcl_clk.hw.clk; + return pwrcl_clk.hw.clk; } if ((hwid | perfcl_clk.cpu_reg_mask) == perfcl_clk.cpu_reg_mask) { - cpu_clk_map[cpu] = &perfcl_clk.c; - return &perfcl_clk.c; + cpu_clk_map[cpu] = perfcl_clk.hw.clk; + return perfcl_clk.hw.clk; } fail: @@ -2378,9 +2376,9 @@ static u64 clk_osm_get_cpu_cycle_counter(int cpu) u32 val; unsigned long flags; - if (logical_cpu_to_clk(cpu) == &pwrcl_clk.c) + if (logical_cpu_to_clk(cpu) == pwrcl_clk.hw.clk) c = &pwrcl_clk; - else if (logical_cpu_to_clk(cpu) == &perfcl_clk.c) + else if (logical_cpu_to_clk(cpu) == perfcl_clk.hw.clk) c = &perfcl_clk; else { pr_err("no clock device for CPU=%d\n", cpu); @@ -2409,11 +2407,11 @@ static void populate_opp_table(struct platform_device *pdev) int cpu; for_each_possible_cpu(cpu) { - if (logical_cpu_to_clk(cpu) == &pwrcl_clk.c) { + if (logical_cpu_to_clk(cpu) == pwrcl_clk.hw.clk) { WARN(add_opp(&pwrcl_clk, get_cpu_device(cpu)), "Failed to add OPP levels for power cluster\n"); } - if (logical_cpu_to_clk(cpu) == &perfcl_clk.c) { + if (logical_cpu_to_clk(cpu) == perfcl_clk.hw.clk) { WARN(add_opp(&perfcl_clk, get_cpu_device(cpu)), "Failed to add OPP levels for perf cluster\n"); } @@ -2456,15 +2454,11 @@ static int debugfs_set_wdog_trace(void *data, u64 val) struct clk_osm *c = data; int regval; - if (c->version >= VERSION_1P1) { - regval = clk_osm_read_reg(c, TRACE_CTRL); - regval = val ? regval | TRACE_CTRL_ENABLE_WDOG_STATUS : + regval = clk_osm_read_reg(c, TRACE_CTRL); + regval = val ? regval | TRACE_CTRL_ENABLE_WDOG_STATUS : regval & ~TRACE_CTRL_ENABLE_WDOG_STATUS; - clk_osm_write_reg(c, regval, TRACE_CTRL); - c->wdog_trace_en = val ? true : false; - } else { - pr_info("wdog status registers enabled by default\n"); - } + clk_osm_write_reg(c, regval, TRACE_CTRL); + c->wdog_trace_en = val ? true : false; return 0; } @@ -2618,7 +2612,7 @@ static int debugfs_set_trace_periodic_timer(void *data, u64 val) struct clk_osm *c = data; if (val < PERIODIC_TRACE_MIN_NS || val > PERIODIC_TRACE_MAX_NS) { - pr_err("supported periodic trace periods=%d-%ld ns\n", + pr_err("supported periodic trace periods=%d-%lld ns\n", PERIODIC_TRACE_MIN_NS, PERIODIC_TRACE_MAX_NS); return 0; } @@ -2760,7 +2754,7 @@ static void populate_debugfs_dir(struct clk_osm *c) } } - c->debugfs = debugfs_create_dir(c->c.dbg_name, osm_debugfs_base); + c->debugfs = debugfs_create_dir(c->hw.init->name, osm_debugfs_base); if (IS_ERR_OR_NULL(c->debugfs)) { pr_err("osm debugfs directory creation failed\n"); return; @@ -2977,31 +2971,60 @@ static int clk_osm_acd_init(struct clk_osm *c) static unsigned long init_rate = 300000000; static unsigned long osm_clk_init_rate = 200000000; +static unsigned long pwrcl_boot_rate = 1401600000; +static unsigned long perfcl_boot_rate = 1747200000; -static int cpu_clock_osm_driver_probe(struct platform_device *pdev) +static int clk_cpu_osm_driver_probe(struct platform_device *pdev) { - int rc, cpu; + int rc, cpu, i; int speedbin = 0, pvs_ver = 0; u32 pte_efuse; - char pwrclspeedbinstr[] = "qcom,pwrcl-speedbin0-v0"; + int num_clks = ARRAY_SIZE(osm_qcom_clk_hws); + struct clk *clk; + struct clk *ext_xo_clk, *ext_hmss_gpll0_clk_src; + struct device *dev = &pdev->dev; + struct clk_onecell_data *clk_data; char perfclspeedbinstr[] = "qcom,perfcl-speedbin0-v0"; + char pwrclspeedbinstr[] = "qcom,pwrcl-speedbin0-v0"; struct cpu_cycle_counter_cb cb = { .get_cpu_cycle_counter = clk_osm_get_cpu_cycle_counter, }; - if (of_find_compatible_node(NULL, NULL, - "qcom,cpu-clock-osm-msmcobalt-v1")) { - msmcobalt_v1 = true; - } else if (of_find_compatible_node(NULL, NULL, - "qcom,cpu-clock-osm-msmcobalt-v2")) { - msmcobalt_v2 = true; + /* + * Require the RPM-XO clock and GCC-HMSS-GPLL0 clocks to be registererd + * before OSM. + */ + ext_xo_clk = devm_clk_get(dev, "xo_a"); + if (IS_ERR(ext_xo_clk)) { + if (PTR_ERR(ext_xo_clk) != -EPROBE_DEFER) + dev_err(dev, "Unable to get xo clock\n"); + return PTR_ERR(ext_xo_clk); } + ext_hmss_gpll0_clk_src = devm_clk_get(dev, "aux_clk"); + if (IS_ERR(ext_hmss_gpll0_clk_src)) { + if (PTR_ERR(ext_hmss_gpll0_clk_src) != -EPROBE_DEFER) + dev_err(dev, "Unable to get aux_clk clock\n"); + return PTR_ERR(ext_hmss_gpll0_clk_src); + } + + clk_data = devm_kzalloc(&pdev->dev, sizeof(struct clk_onecell_data), + GFP_KERNEL); + if (!clk_data) + goto exit; + + clk_data->clks = devm_kzalloc(&pdev->dev, (num_clks * + sizeof(struct clk *)), GFP_KERNEL); + if (!clk_data->clks) + goto clk_err; + + clk_data->clk_num = num_clks; + rc = clk_osm_resources_init(pdev); if (rc) { if (rc != -EPROBE_DEFER) dev_err(&pdev->dev, "resources init failed, rc=%d\n", - rc); + rc); return rc; } @@ -3011,17 +3034,11 @@ static int cpu_clock_osm_driver_probe(struct platform_device *pdev) return rc; } - if ((pwrcl_clk.secure_init || perfcl_clk.secure_init) && - msmcobalt_v2) { - pr_err("unsupported configuration for msmcobalt v2\n"); - return -EINVAL; - } - if (pwrcl_clk.vbases[EFUSE_BASE]) { /* Multiple speed-bins are supported */ pte_efuse = readl_relaxed(pwrcl_clk.vbases[EFUSE_BASE]); speedbin = ((pte_efuse >> PWRCL_EFUSE_SHIFT) & - PWRCL_EFUSE_MASK); + PWRCL_EFUSE_MASK); snprintf(pwrclspeedbinstr, ARRAY_SIZE(pwrclspeedbinstr), "qcom,pwrcl-speedbin%d-v%d", speedbin, pvs_ver); } @@ -3029,8 +3046,7 @@ static int cpu_clock_osm_driver_probe(struct platform_device *pdev) dev_info(&pdev->dev, "using pwrcl speed bin %u and pvs_ver %d\n", speedbin, pvs_ver); - rc = clk_osm_get_lut(pdev, &pwrcl_clk, - pwrclspeedbinstr); + rc = clk_osm_get_lut(pdev, &pwrcl_clk, pwrclspeedbinstr); if (rc) { dev_err(&pdev->dev, "Unable to get OSM LUT for power cluster, rc=%d\n", rc); @@ -3041,7 +3057,7 @@ static int cpu_clock_osm_driver_probe(struct platform_device *pdev) /* Multiple speed-bins are supported */ pte_efuse = readl_relaxed(perfcl_clk.vbases[EFUSE_BASE]); speedbin = ((pte_efuse >> PERFCL_EFUSE_SHIFT) & - PERFCL_EFUSE_MASK); + PERFCL_EFUSE_MASK); snprintf(perfclspeedbinstr, ARRAY_SIZE(perfclspeedbinstr), "qcom,perfcl-speedbin%d-v%d", speedbin, pvs_ver); } @@ -3074,13 +3090,14 @@ static int cpu_clock_osm_driver_probe(struct platform_device *pdev) return rc; } - rc = clk_osm_resolve_crossover_corners(&pwrcl_clk, pdev); + rc = clk_osm_resolve_crossover_corners(&pwrcl_clk, pdev, NULL); if (rc) dev_info(&pdev->dev, "No APM crossover corner programmed\n"); - rc = clk_osm_resolve_crossover_corners(&perfcl_clk, pdev); + rc = clk_osm_resolve_crossover_corners(&perfcl_clk, pdev, + "qcom,perfcl-apcs-mem-acc-threshold-voltage"); if (rc) - dev_info(&pdev->dev, "No APM crossover corner programmed\n"); + dev_info(&pdev->dev, "No MEM-ACC crossover corner programmed\n"); clk_osm_setup_cycle_counters(&pwrcl_clk); clk_osm_setup_cycle_counters(&perfcl_clk); @@ -3146,11 +3163,7 @@ static int cpu_clock_osm_driver_probe(struct platform_device *pdev) if (rc) pr_err("Debug IRQ not set for perfcl\n"); - clk_osm_setup_osm_was(&pwrcl_clk); - clk_osm_setup_osm_was(&perfcl_clk); - - if (of_property_read_bool(pdev->dev.of_node, - "qcom,osm-pll-setup")) { + if (of_property_read_bool(pdev->dev.of_node, "qcom,osm-pll-setup")) { clk_osm_setup_cluster_pll(&pwrcl_clk); clk_osm_setup_cluster_pll(&perfcl_clk); } @@ -3176,12 +3189,22 @@ static int cpu_clock_osm_driver_probe(struct platform_device *pdev) atomic_notifier_chain_register(&panic_notifier_list, &perfcl_clk.panic_notifier); - rc = of_msm_clock_register(pdev->dev.of_node, cpu_clocks_osm, - ARRAY_SIZE(cpu_clocks_osm)); + /* Register OSM pwr and perf clocks with Clock Framework */ + for (i = 0; i < num_clks; i++) { + clk = devm_clk_register(&pdev->dev, osm_qcom_clk_hws[i]); + if (IS_ERR(clk)) { + dev_err(&pdev->dev, "Unable to register CPU clock at index %d\n", + i); + return PTR_ERR(clk); + } + clk_data->clks[i] = clk; + } + + rc = of_clk_add_provider(pdev->dev.of_node, of_clk_src_onecell_get, + clk_data); if (rc) { - dev_err(&pdev->dev, "Unable to register CPU clocks, rc=%d\n", - rc); - return rc; + dev_err(&pdev->dev, "Unable to register CPU clocks\n"); + goto provider_err; } /* @@ -3189,15 +3212,15 @@ static int cpu_clock_osm_driver_probe(struct platform_device *pdev) * frequency before enabling OSM. LUT index 0 is always sourced from * this clock. */ - rc = clk_set_rate(&sys_apcsaux_clk_gcc.c, init_rate); + rc = clk_set_rate(sys_apcsaux_clk_gcc.hw.clk, init_rate); if (rc) { dev_err(&pdev->dev, "Unable to set init rate on hmss_gpll0, rc=%d\n", rc); return rc; } - clk_prepare_enable(&sys_apcsaux_clk_gcc.c); + clk_prepare_enable(sys_apcsaux_clk_gcc.hw.clk); - rc = clk_set_rate(&osm_clk_src.c, osm_clk_init_rate); + rc = clk_set_rate(osm_clk_src.clkr.hw.clk, osm_clk_init_rate); if (rc) { dev_err(&pdev->dev, "Unable to set init rate on osm_clk, rc=%d\n", rc); @@ -3205,14 +3228,14 @@ static int cpu_clock_osm_driver_probe(struct platform_device *pdev) } /* Make sure index zero is selected */ - rc = clk_set_rate(&pwrcl_clk.c, init_rate); + rc = clk_set_rate(pwrcl_clk.hw.clk, init_rate); if (rc) { dev_err(&pdev->dev, "Unable to set init rate on pwr cluster, rc=%d\n", rc); goto exit2; } - rc = clk_set_rate(&perfcl_clk.c, init_rate); + rc = clk_set_rate(perfcl_clk.hw.clk, init_rate); if (rc) { dev_err(&pdev->dev, "Unable to set init rate on perf cluster, rc=%d\n", rc); @@ -3228,27 +3251,20 @@ static int cpu_clock_osm_driver_probe(struct platform_device *pdev) } /* Set final boot rate */ - rc = clk_set_rate(&pwrcl_clk.c, msmcobalt_v1 ? - MSMCOBALTV1_PWRCL_BOOT_RATE : - MSMCOBALTV2_PWRCL_BOOT_RATE); + rc = clk_set_rate(pwrcl_clk.hw.clk, pwrcl_boot_rate); if (rc) { dev_err(&pdev->dev, "Unable to set boot rate on pwr cluster, rc=%d\n", rc); goto exit2; } - rc = clk_set_rate(&perfcl_clk.c, msmcobalt_v1 ? - MSMCOBALTV1_PERFCL_BOOT_RATE : - MSMCOBALTV2_PERFCL_BOOT_RATE); + rc = clk_set_rate(perfcl_clk.hw.clk, perfcl_boot_rate); if (rc) { dev_err(&pdev->dev, "Unable to set boot rate on perf cluster, rc=%d\n", rc); goto exit2; } - pwrcl_clk.version = clk_osm_read_reg(&pwrcl_clk, VERSION_REG); - perfcl_clk.version = clk_osm_read_reg(&perfcl_clk, VERSION_REG); - populate_opp_table(pdev); populate_debugfs_dir(&pwrcl_clk); populate_debugfs_dir(&perfcl_clk); @@ -3263,39 +3279,42 @@ static int cpu_clock_osm_driver_probe(struct platform_device *pdev) return 0; exit2: - clk_disable_unprepare(&sys_apcsaux_clk_gcc.c); + clk_disable_unprepare(sys_apcsaux_clk_gcc.hw.clk); +provider_err: + if (clk_data) + devm_kfree(&pdev->dev, clk_data->clks); +clk_err: + devm_kfree(&pdev->dev, clk_data); exit: - dev_err(&pdev->dev, "OSM driver failed to initialize, rc=%d\n", - rc); + dev_err(&pdev->dev, "OSM driver failed to initialize, rc=%d\n", rc); panic("Unable to Setup OSM"); } static const struct of_device_id match_table[] = { - { .compatible = "qcom,cpu-clock-osm-msmcobalt-v1" }, - { .compatible = "qcom,cpu-clock-osm-msmcobalt-v2" }, + { .compatible = "qcom,clk-cpu-osm" }, {} }; -static struct platform_driver cpu_clock_osm_driver = { - .probe = cpu_clock_osm_driver_probe, +static struct platform_driver clk_cpu_osm_driver = { + .probe = clk_cpu_osm_driver_probe, .driver = { - .name = "cpu-clock-osm", + .name = "clk-cpu-osm", .of_match_table = match_table, .owner = THIS_MODULE, }, }; -static int __init cpu_clock_osm_init(void) +static int __init clk_cpu_osm_init(void) { - return platform_driver_register(&cpu_clock_osm_driver); + return platform_driver_register(&clk_cpu_osm_driver); } -arch_initcall(cpu_clock_osm_init); +arch_initcall(clk_cpu_osm_init); -static void __exit cpu_clock_osm_exit(void) +static void __exit clk_cpu_osm_exit(void) { - platform_driver_unregister(&cpu_clock_osm_driver); + platform_driver_unregister(&clk_cpu_osm_driver); } -module_exit(cpu_clock_osm_exit); +module_exit(clk_cpu_osm_exit); MODULE_DESCRIPTION("CPU clock driver for OSM"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/qcom/clk-smd-rpm.c b/drivers/clk/qcom/clk-smd-rpm.c index c6ea293a8df3..d14c32bffe14 100644 --- a/drivers/clk/qcom/clk-smd-rpm.c +++ b/drivers/clk/qcom/clk-smd-rpm.c @@ -551,6 +551,39 @@ DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8996, bb_clk2_pin, bb_clk2_a_pin, 2); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8996, rf_clk1_pin, rf_clk1_a_pin, 4); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8996, rf_clk2_pin, rf_clk2_a_pin, 5); +/* Voter clocks */ +static DEFINE_CLK_VOTER(mmssnoc_axi_clk, mmssnoc_axi_rpm_clk, 0); +static DEFINE_CLK_VOTER(mmssnoc_axi_a_clk, mmssnoc_axi_rpm_a_clk, 0); +static DEFINE_CLK_VOTER(mmssnoc_gds_clk, mmssnoc_axi_rpm_clk, 40000000); +static DEFINE_CLK_VOTER(bimc_msmbus_clk, bimc_clk, LONG_MAX); +static DEFINE_CLK_VOTER(bimc_msmbus_a_clk, bimc_a_clk, LONG_MAX); +static DEFINE_CLK_VOTER(cnoc_msmbus_clk, cnoc_clk, LONG_MAX); +static DEFINE_CLK_VOTER(cnoc_msmbus_a_clk, cnoc_a_clk, LONG_MAX); +static DEFINE_CLK_VOTER(snoc_msmbus_clk, snoc_clk, LONG_MAX); +static DEFINE_CLK_VOTER(snoc_msmbus_a_clk, snoc_a_clk, LONG_MAX); +static DEFINE_CLK_VOTER(cnoc_periph_keepalive_a_clk, cnoc_periph_a_clk, + LONG_MAX); +static DEFINE_CLK_VOTER(mcd_ce1_clk, ce1_clk, 85710000); +static DEFINE_CLK_VOTER(qcedev_ce1_clk, ce1_clk, 85710000); +static DEFINE_CLK_VOTER(qcrypto_ce1_clk, ce1_clk, 85710000); +static DEFINE_CLK_VOTER(qseecom_ce1_clk, ce1_clk, 85710000); +static DEFINE_CLK_VOTER(scm_ce1_clk, ce1_clk, 85710000); +static DEFINE_CLK_VOTER(pnoc_keepalive_a_clk, pnoc_a_clk, LONG_MAX); +static DEFINE_CLK_VOTER(pnoc_msmbus_clk, pnoc_clk, LONG_MAX); +static DEFINE_CLK_VOTER(pnoc_msmbus_a_clk, pnoc_a_clk, LONG_MAX); +static DEFINE_CLK_VOTER(pnoc_pm_clk, pnoc_clk, LONG_MAX); +static DEFINE_CLK_VOTER(pnoc_sps_clk, pnoc_clk, 0); +static DEFINE_CLK_VOTER(mmssnoc_a_clk_cpu_vote, mmssnoc_axi_rpm_a_clk, + 19200000); + +/* Voter Branch clocks */ +static DEFINE_CLK_BRANCH_VOTER(cxo_dwc3_clk, cxo); +static DEFINE_CLK_BRANCH_VOTER(cxo_lpm_clk, cxo); +static DEFINE_CLK_BRANCH_VOTER(cxo_otg_clk, cxo); +static DEFINE_CLK_BRANCH_VOTER(cxo_pil_lpass_clk, cxo); +static DEFINE_CLK_BRANCH_VOTER(cxo_pil_ssc_clk, cxo); +static DEFINE_CLK_BRANCH_VOTER(cxo_pil_cdsp_clk, cxo); + static struct clk_hw *msm8996_clks[] = { [RPM_XO_CLK_SRC] = &msm8996_cxo.hw, [RPM_XO_A_CLK_SRC] = &msm8996_cxo_a.hw, @@ -590,6 +623,31 @@ static struct clk_hw *msm8996_clks[] = { [RPM_DIV_CLK3_AO] = &msm8996_div_clk3_ao.hw, [RPM_LN_BB_CLK] = &msm8996_ln_bb_clk.hw, [RPM_LN_BB_A_CLK] = &msm8996_ln_bb_a_clk.hw, + [MMSSNOC_AXI_CLK] = &mmssnoc_axi_clk.hw, + [MMSSNOC_AXI_A_CLK] = &mmssnoc_axi_a_clk.hw, + [MMSSNOC_GDS_CLK] = &mmssnoc_gds_clk.hw, + [BIMC_MSMBUS_CLK] = &bimc_msmbus_clk.hw, + [BIMC_MSMBUS_A_CLK] = &bimc_msmbus_a_clk.hw, + [CNOC_MSMBUS_CLK] = &cnoc_msmbus_clk.hw, + [CNOC_MSMBUS_A_CLK] = &cnoc_msmbus_a_clk.hw, + [PNOC_KEEPALIVE_A_CLK] = &pnoc_keepalive_a_clk.hw, + [PNOC_MSMBUS_CLK] = &pnoc_msmbus_clk.hw, + [PNOC_MSMBUS_A_CLK] = &pnoc_msmbus_a_clk.hw, + [PNOC_PM_CLK] = &pnoc_pm_clk.hw, + [PNOC_SPS_CLK] = &pnoc_sps_clk.hw, + [MCD_CE1_CLK] = &mcd_ce1_clk.hw, + [QCEDEV_CE1_CLK] = &qcedev_ce1_clk.hw, + [QCRYPTO_CE1_CLK] = &qcrypto_ce1_clk.hw, + [QSEECOM_CE1_CLK] = &qseecom_ce1_clk.hw, + [SCM_CE1_CLK] = &scm_ce1_clk.hw, + [SNOC_MSMBUS_CLK] = &snoc_msmbus_clk.hw, + [SNOC_MSMBUS_A_CLK] = &snoc_msmbus_a_clk.hw, + [CXO_DWC3_CLK] = &cxo_dwc3_clk.hw, + [CXO_LPM_CLK] = &cxo_lpm_clk.hw, + [CXO_OTG_CLK] = &cxo_otg_clk.hw, + [CXO_PIL_LPASS_CLK] = &cxo_pil_lpass_clk.hw, + [CXO_PIL_SSC_CLK] = &cxo_pil_ssc_clk.hw, + [MMSSNOC_A_CLK_CPU_VOTE] = &mmssnoc_a_clk_cpu_vote.hw }; static const struct rpm_smd_clk_desc rpm_clk_msm8996 = { @@ -627,26 +685,6 @@ DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msmfalcon, ln_bb_clk2_pin, ln_bb_clk2_pin_ao, 0x2); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msmfalcon, ln_bb_clk3_pin, ln_bb_clk3_pin_ao, 0x3); -/* Voter clocks */ -static DEFINE_CLK_VOTER(bimc_msmbus_clk, bimc_clk, LONG_MAX); -static DEFINE_CLK_VOTER(bimc_msmbus_a_clk, bimc_a_clk, LONG_MAX); -static DEFINE_CLK_VOTER(cnoc_msmbus_clk, cnoc_clk, LONG_MAX); -static DEFINE_CLK_VOTER(cnoc_msmbus_a_clk, cnoc_a_clk, LONG_MAX); -static DEFINE_CLK_VOTER(snoc_msmbus_clk, snoc_clk, LONG_MAX); -static DEFINE_CLK_VOTER(snoc_msmbus_a_clk, snoc_a_clk, LONG_MAX); -static DEFINE_CLK_VOTER(cnoc_periph_keepalive_a_clk, cnoc_periph_a_clk, - LONG_MAX); -static DEFINE_CLK_VOTER(mcd_ce1_clk, ce1_clk, 85710000); -static DEFINE_CLK_VOTER(qcedev_ce1_clk, ce1_clk, 85710000); -static DEFINE_CLK_VOTER(qcrypto_ce1_clk, ce1_clk, 85710000); -static DEFINE_CLK_VOTER(qseecom_ce1_clk, ce1_clk, 85710000); -static DEFINE_CLK_VOTER(scm_ce1_clk, ce1_clk, 85710000); - -static DEFINE_CLK_BRANCH_VOTER(cxo_dwc3_clk, cxo); -static DEFINE_CLK_BRANCH_VOTER(cxo_lpm_clk, cxo); -static DEFINE_CLK_BRANCH_VOTER(cxo_otg_clk, cxo); -static DEFINE_CLK_BRANCH_VOTER(cxo_pil_lpass_clk, cxo); -static DEFINE_CLK_BRANCH_VOTER(cxo_pil_cdsp_clk, cxo); static struct clk_hw *msmfalcon_clks[] = { [RPM_XO_CLK_SRC] = &msmfalcon_cxo.hw, @@ -799,10 +837,19 @@ static int rpm_smd_clk_probe(struct platform_device *pdev) if (ret) goto err; - /* Keep an active vote on CXO in case no other driver votes for it */ - if (is_8996) + if (is_8996) { + /* + * Keep an active vote on CXO in case no other driver + * votes for it. + */ clk_prepare_enable(msm8996_cxo_a.hw.clk); - else if (is_falcon) { + + /* Hold an active set vote for the pnoc_keepalive_a_clk */ + clk_set_rate(pnoc_keepalive_a_clk.hw.clk, 19200000); + clk_prepare_enable(pnoc_keepalive_a_clk.hw.clk); + + clk_prepare_enable(mmssnoc_a_clk_cpu_vote.hw.clk); + } else if (is_falcon) { clk_prepare_enable(msmfalcon_cxo_a.hw.clk); /* Hold an active set vote for the cnoc_periph resource */ diff --git a/drivers/clk/qcom/common.h b/drivers/clk/qcom/common.h index 841367eb21ff..76c010970b51 100644 --- a/drivers/clk/qcom/common.h +++ b/drivers/clk/qcom/common.h @@ -137,6 +137,7 @@ struct clk_debug_mux { }; #define BM(msb, lsb) (((((uint32_t)-1) << (31-msb)) >> (31-msb+lsb)) << lsb) +#define BVAL(msb, lsb, val) (((val) << lsb) & BM(msb, lsb)) #define to_clk_measure(_hw) container_of((_hw), struct clk_debug_mux, hw) diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c index 0f39bf278cd4..51c85e08372c 100644 --- a/drivers/clk/qcom/gcc-msm8996.c +++ b/drivers/clk/qcom/gcc-msm8996.c @@ -31,9 +31,12 @@ #include "clk-rcg.h" #include "clk-branch.h" #include "reset.h" +#include "vdd-level-8996.h" #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } +static DEFINE_VDD_REGULATORS(vdd_dig, VDD_DIG_NUM, 1, vdd_corner); + enum { P_XO, P_GPLL0, @@ -89,7 +92,7 @@ static const struct parent_map gcc_xo_gpll0_gpll4_map[] = { static const char * const gcc_xo_gpll0_gpll4[] = { "xo", "gpll0", - "gpll4" + "gpll4_early" }; static const struct parent_map gcc_xo_gpll0_aud_ref_clk_map[] = { @@ -128,7 +131,7 @@ static const struct parent_map gcc_xo_gpll0_gpll4_gpll0_early_div_map[] = { static const char * const gcc_xo_gpll0_gpll4_gpll0_early_div[] = { "xo", "gpll0", - "gpll4", + "gpll4_early", "gpll0_early_div" }; @@ -162,7 +165,7 @@ static const char * const gcc_xo_gpll0_gpll1_early_div_gpll1_gpll4_gpll0_early_d "gpll0", "gpll1_early_div", "gpll1", - "gpll4", + "gpll4_early", "gpll0_early_div" }; @@ -202,10 +205,24 @@ static const char * const gcc_xo_gpll0_gpll2_gpll3_gpll1_gpll4_gpll0_early_div[] "gpll2", "gpll3", "gpll1", - "gpll4", + "gpll4_early", "gpll0_early_div" }; +static struct clk_fixed_factor gcc_ce1_ahb_m_clk = { + .hw.init = &(struct clk_init_data){ + .name = "gcc_ce1_ahb_m_clk", + .ops = &clk_dummy_ops, + }, +}; + +static struct clk_fixed_factor gcc_ce1_axi_m_clk = { + .hw.init = &(struct clk_init_data){ + .name = "gcc_ce1_axi_m_clk", + .ops = &clk_dummy_ops, + }, +}; + static struct clk_fixed_factor xo = { .mult = 1, .div = 1, @@ -294,6 +311,8 @@ static struct clk_rcg2 usb30_master_clk_src = { .parent_names = gcc_xo_gpll0_gpll0_early_div, .num_parents = 3, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 60000000, LOW, 120000000, + NOMINAL, 150000000), }, }; @@ -312,6 +331,7 @@ static struct clk_rcg2 usb30_mock_utmi_clk_src = { .parent_names = gcc_xo_gpll0_gpll0_early_div, .num_parents = 3, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2(LOWER, 40000000, LOW, 60000000), }, }; @@ -330,6 +350,7 @@ static struct clk_rcg2 usb3_phy_aux_clk_src = { .parent_names = gcc_xo_sleep_clk, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP1(LOWER, 1200000), }, }; @@ -349,6 +370,8 @@ static struct clk_rcg2 usb20_master_clk_src = { .parent_names = gcc_xo_gpll0_gpll0_early_div, .num_parents = 3, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 60000000, + NOMINAL, 120000000), }, }; @@ -362,6 +385,7 @@ static struct clk_rcg2 usb20_mock_utmi_clk_src = { .parent_names = gcc_xo_gpll0_gpll0_early_div, .num_parents = 3, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2(LOWER, 19200000, LOW, 60000000), }, }; @@ -388,6 +412,8 @@ static struct clk_rcg2 sdcc1_apps_clk_src = { .parent_names = gcc_xo_gpll0_gpll4_gpll0_early_div, .num_parents = 4, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 200000000, + NOMINAL, 400000000), }, }; @@ -408,6 +434,8 @@ static struct clk_rcg2 sdcc1_ice_core_clk_src = { .parent_names = gcc_xo_gpll0_gpll4_gpll0_early_div, .num_parents = 4, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 150000000, + NOMINAL, 300000000), }, }; @@ -433,6 +461,8 @@ static struct clk_rcg2 sdcc2_apps_clk_src = { .parent_names = gcc_xo_gpll0_gpll4, .num_parents = 3, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 100000000, + NOMINAL, 200000000), }, }; @@ -447,6 +477,8 @@ static struct clk_rcg2 sdcc3_apps_clk_src = { .parent_names = gcc_xo_gpll0_gpll4, .num_parents = 3, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 100000000, + NOMINAL, 200000000), }, }; @@ -471,6 +503,8 @@ static struct clk_rcg2 sdcc4_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 50000000, + NOMINAL, 100000000), }, }; @@ -496,6 +530,8 @@ static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 25000000, + NOMINAL, 50000000), }, }; @@ -515,6 +551,7 @@ static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2(LOWER, 19200000, LOW, 50000000), }, }; @@ -548,6 +585,8 @@ static struct clk_rcg2 blsp1_uart1_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 31580000, + NOMINAL, 63160000), }, }; @@ -562,6 +601,8 @@ static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 25000000, + NOMINAL, 50000000), }, }; @@ -575,6 +616,7 @@ static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2(LOWER, 19200000, LOW, 50000000), }, }; @@ -589,6 +631,8 @@ static struct clk_rcg2 blsp1_uart2_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 31580000, + NOMINAL, 63160000), }, }; @@ -603,6 +647,8 @@ static struct clk_rcg2 blsp1_qup3_spi_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 25000000, + NOMINAL, 50000000), }, }; @@ -616,6 +662,7 @@ static struct clk_rcg2 blsp1_qup3_i2c_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2(LOWER, 19200000, LOW, 50000000), }, }; @@ -630,6 +677,8 @@ static struct clk_rcg2 blsp1_uart3_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 31580000, + NOMINAL, 63160000), }, }; @@ -644,6 +693,8 @@ static struct clk_rcg2 blsp1_qup4_spi_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 25000000, + NOMINAL, 50000000), }, }; @@ -657,6 +708,7 @@ static struct clk_rcg2 blsp1_qup4_i2c_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2(LOWER, 19200000, LOW, 50000000), }, }; @@ -671,6 +723,8 @@ static struct clk_rcg2 blsp1_uart4_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 31580000, + NOMINAL, 63160000), }, }; @@ -685,6 +739,8 @@ static struct clk_rcg2 blsp1_qup5_spi_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 25000000, + NOMINAL, 50000000), }, }; @@ -698,6 +754,7 @@ static struct clk_rcg2 blsp1_qup5_i2c_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2(LOWER, 19200000, LOW, 50000000), }, }; @@ -712,6 +769,8 @@ static struct clk_rcg2 blsp1_uart5_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 31580000, + NOMINAL, 63160000), }, }; @@ -726,6 +785,8 @@ static struct clk_rcg2 blsp1_qup6_spi_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 25000000, + NOMINAL, 50000000), }, }; @@ -739,6 +800,7 @@ static struct clk_rcg2 blsp1_qup6_i2c_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2(LOWER, 19200000, LOW, 50000000), }, }; @@ -753,6 +815,8 @@ static struct clk_rcg2 blsp1_uart6_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 31580000, + NOMINAL, 63160000), }, }; @@ -767,6 +831,8 @@ static struct clk_rcg2 blsp2_qup1_spi_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 25000000, + NOMINAL, 50000000), }, }; @@ -780,6 +846,7 @@ static struct clk_rcg2 blsp2_qup1_i2c_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2(LOWER, 19200000, LOW, 50000000), }, }; @@ -794,6 +861,8 @@ static struct clk_rcg2 blsp2_uart1_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 31580000, + NOMINAL, 63160000), }, }; @@ -808,6 +877,8 @@ static struct clk_rcg2 blsp2_qup2_spi_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 25000000, + NOMINAL, 50000000), }, }; @@ -821,6 +892,7 @@ static struct clk_rcg2 blsp2_qup2_i2c_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2(LOWER, 19200000, LOW, 50000000), }, }; @@ -835,6 +907,8 @@ static struct clk_rcg2 blsp2_uart2_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 31580000, + NOMINAL, 63160000), }, }; @@ -849,6 +923,8 @@ static struct clk_rcg2 blsp2_qup3_spi_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 25000000, + NOMINAL, 50000000), }, }; @@ -862,6 +938,7 @@ static struct clk_rcg2 blsp2_qup3_i2c_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2(LOWER, 19200000, LOW, 50000000), }, }; @@ -876,6 +953,8 @@ static struct clk_rcg2 blsp2_uart3_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 31580000, + NOMINAL, 63160000), }, }; @@ -890,6 +969,8 @@ static struct clk_rcg2 blsp2_qup4_spi_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 25000000, + NOMINAL, 50000000), }, }; @@ -903,6 +984,7 @@ static struct clk_rcg2 blsp2_qup4_i2c_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2(LOWER, 19200000, LOW, 50000000), }, }; @@ -917,6 +999,8 @@ static struct clk_rcg2 blsp2_uart4_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 31580000, + NOMINAL, 63160000), }, }; @@ -931,6 +1015,8 @@ static struct clk_rcg2 blsp2_qup5_spi_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 25000000, + NOMINAL, 50000000), }, }; @@ -944,6 +1030,7 @@ static struct clk_rcg2 blsp2_qup5_i2c_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2(LOWER, 19200000, LOW, 50000000), }, }; @@ -958,6 +1045,8 @@ static struct clk_rcg2 blsp2_uart5_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 31580000, + NOMINAL, 63160000), }, }; @@ -972,6 +1061,8 @@ static struct clk_rcg2 blsp2_qup6_spi_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 25000000, + NOMINAL, 50000000), }, }; @@ -985,6 +1076,7 @@ static struct clk_rcg2 blsp2_qup6_i2c_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2(LOWER, 19200000, LOW, 50000000), }, }; @@ -999,6 +1091,8 @@ static struct clk_rcg2 blsp2_uart6_apps_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 31580000, + NOMINAL, 63160000), }, }; @@ -1017,6 +1111,7 @@ static struct clk_rcg2 pdm2_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP2(LOWER, 19200000, LOW, 60000000), }, }; @@ -1036,6 +1131,7 @@ static struct clk_rcg2 tsif_ref_clk_src = { .parent_names = gcc_xo_gpll0_aud_ref_clk, .num_parents = 3, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP1(LOWER, 19200000), }, }; @@ -1082,6 +1178,8 @@ static struct clk_rcg2 gp1_clk_src = { .parent_names = gcc_xo_gpll0_sleep_clk_gpll0_early_div, .num_parents = 4, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 50000000, LOW, 100000000, + NOMINAL, 200000000), }, }; @@ -1096,6 +1194,8 @@ static struct clk_rcg2 gp2_clk_src = { .parent_names = gcc_xo_gpll0_sleep_clk_gpll0_early_div, .num_parents = 4, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 50000000, LOW, 100000000, + NOMINAL, 200000000), }, }; @@ -1110,6 +1210,8 @@ static struct clk_rcg2 gp3_clk_src = { .parent_names = gcc_xo_gpll0_sleep_clk_gpll0_early_div, .num_parents = 4, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 50000000, LOW, 100000000, + NOMINAL, 200000000), }, }; @@ -1129,6 +1231,7 @@ static struct clk_rcg2 pcie_aux_clk_src = { .parent_names = gcc_xo_sleep_clk, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP1(LOWER, 1011000), }, }; @@ -1150,6 +1253,8 @@ static struct clk_rcg2 ufs_axi_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP4(LOWER, 19200000, LOW, 100000000, + NOMINAL, 200000000, HIGH, 240000000), }, }; @@ -1170,6 +1275,8 @@ static struct clk_rcg2 ufs_ice_core_clk_src = { .parent_names = gcc_xo_gpll0, .num_parents = 2, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 19200000, LOW, 150000000, + NOMINAL, 300000000), }, }; @@ -1191,6 +1298,8 @@ static struct clk_rcg2 qspi_ser_clk_src = { .parent_names = gcc_xo_gpll0_gpll1_early_div_gpll1_gpll4_gpll0_early_div, .num_parents = 6, .ops = &clk_rcg2_ops, + VDD_DIG_FMAX_MAP3(LOWER, 80200000, LOW, 160400000, + NOMINAL, 320000000), }, }; @@ -1321,6 +1430,18 @@ static struct clk_branch gcc_usb3_phy_aux_clk = { }, }; +static struct clk_gate2 gpll0_out_msscc_clk = { + .udelay = 1, + .clkr = { + .enable_reg = 0x5200c, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "gpll0_out_msscc_clk", + .ops = &clk_gate2_ops, + }, + }, +}; + static struct clk_gate2 gcc_usb3_phy_pipe_clk = { .udelay = 50, .clkr = { @@ -1333,18 +1454,6 @@ static struct clk_gate2 gcc_usb3_phy_pipe_clk = { }, }; -static struct clk_gate2 gpll0_out_msscc = { - .udelay = 1, - .clkr = { - .enable_reg = 0x5200c, - .enable_mask = BIT(2), - .hw.init = &(struct clk_init_data){ - .name = "gpll0_out_msscc", - .ops = &clk_gate2_ops, - }, - }, -}; - static struct clk_branch gcc_usb20_master_clk = { .halt_reg = 0x12004, .clkr = { @@ -1826,6 +1935,7 @@ static struct clk_branch gcc_blsp2_ahb_clk = { .enable_mask = BIT(15), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp2_ahb_clk", + .flags = CLK_ENABLE_HAND_OFF, .ops = &clk_branch2_ops, }, }, @@ -2728,18 +2838,6 @@ static struct clk_branch gcc_smmu_aggre0_ahb_clk = { }, }; -static struct clk_branch gcc_aggre1_pnoc_ahb_clk = { - .halt_reg = 0x82014, - .clkr = { - .enable_reg = 0x82014, - .enable_mask = BIT(0), - .hw.init = &(struct clk_init_data){ - .name = "gcc_aggre1_pnoc_ahb_clk", - .ops = &clk_branch2_ops, - }, - }, -}; - static struct clk_branch gcc_aggre2_ufs_axi_clk = { .halt_reg = 0x83014, .clkr = { @@ -2995,11 +3093,13 @@ static struct clk_branch gcc_mmss_gpll0_div_clk = { }; static struct clk_hw *gcc_msm8996_hws[] = { - &xo.hw, - &gpll0_early_div.hw, - &ufs_tx_cfg_clk_src.hw, - &ufs_rx_cfg_clk_src.hw, - &ufs_ice_core_postdiv_clk_src.hw, + [GCC_XO] = &xo.hw, + [GCC_CE1_AHB_M_CLK] = &gcc_ce1_ahb_m_clk.hw, + [GCC_CE1_AXI_M_CLK] = &gcc_ce1_axi_m_clk.hw, + [GCC_GPLL0_EARLY_DIV] = &gpll0_early_div.hw, + [GCC_UFS_TX_CFG_CLK_SRC] = &ufs_tx_cfg_clk_src.hw, + [GCC_UFS_RX_CFG_CLK_SRC] = &ufs_rx_cfg_clk_src.hw, + [GCC_UFS_ICE_CORE_PDIV_CLK_SRC] = &ufs_ice_core_postdiv_clk_src.hw, }; static struct clk_regmap *gcc_msm8996_clocks[] = { @@ -3170,7 +3270,6 @@ static struct clk_regmap *gcc_msm8996_clocks[] = { [GCC_AGGRE0_CNOC_AHB_CLK] = &gcc_aggre0_cnoc_ahb_clk.clkr, [GCC_SMMU_AGGRE0_AXI_CLK] = &gcc_smmu_aggre0_axi_clk.clkr, [GCC_SMMU_AGGRE0_AHB_CLK] = &gcc_smmu_aggre0_ahb_clk.clkr, - [GCC_AGGRE1_PNOC_AHB_CLK] = &gcc_aggre1_pnoc_ahb_clk.clkr, [GCC_AGGRE2_UFS_AXI_CLK] = &gcc_aggre2_ufs_axi_clk.clkr, [GCC_AGGRE2_USB3_AXI_CLK] = &gcc_aggre2_usb3_axi_clk.clkr, [GCC_QSPI_AHB_CLK] = &gcc_qspi_ahb_clk.clkr, @@ -3192,10 +3291,10 @@ static struct clk_regmap *gcc_msm8996_clocks[] = { [GCC_MSS_Q6_BIMC_AXI_CLK] = &gcc_mss_q6_bimc_axi_clk.clkr, [GCC_MSS_SNOC_AXI_CLK] = &gcc_mss_snoc_axi_clk.clkr, [GCC_MSS_MNOC_BIMC_AXI_CLK] = &gcc_mss_mnoc_bimc_axi_clk.clkr, - [GCC_DCC_AHB_ALK] = &gcc_dcc_ahb_clk.clkr, + [GCC_DCC_AHB_CLK] = &gcc_dcc_ahb_clk.clkr, [GCC_AGGRE0_NOC_MPU_CFG_AHB_CLK] = &gcc_aggre0_noc_mpu_cfg_ahb_clk.clkr, [GCC_MMSS_GPLL0_DIV_CLK] = &gcc_mmss_gpll0_div_clk.clkr, - [GPLL0_OUT_MSSCC] = &gpll0_out_msscc.clkr, + [GPLL0_OUT_MSSCC_CLK] = &gpll0_out_msscc_clk.clkr, }; static const struct qcom_reset_map gcc_msm8996_resets[] = { @@ -3317,6 +3416,8 @@ static const struct regmap_config gcc_msm8996_regmap_config = { static const struct qcom_cc_desc gcc_msm8996_desc = { .config = &gcc_msm8996_regmap_config, .clks = gcc_msm8996_clocks, + .hwclks = gcc_msm8996_hws, + .num_hwclks = ARRAY_SIZE(gcc_msm8996_hws), .num_clks = ARRAY_SIZE(gcc_msm8996_clocks), .resets = gcc_msm8996_resets, .num_resets = ARRAY_SIZE(gcc_msm8996_resets), @@ -3330,9 +3431,7 @@ MODULE_DEVICE_TABLE(of, gcc_msm8996_match_table); static int gcc_msm8996_probe(struct platform_device *pdev) { - struct clk *clk; - struct device *dev = &pdev->dev; - int i, ret = 0; + int ret = 0; struct regmap *regmap; regmap = qcom_cc_map(pdev, &gcc_msm8996_desc); @@ -3342,10 +3441,14 @@ static int gcc_msm8996_probe(struct platform_device *pdev) /* Set the HMSS_AHB_CLK_ENA bit to enable the hmss_ahb_clk */ regmap_update_bits(regmap, 0x52004, BIT(21), BIT(21)); - for (i = 0; i < ARRAY_SIZE(gcc_msm8996_hws); i++) { - clk = devm_clk_register(dev, gcc_msm8996_hws[i]); - if (IS_ERR(clk)) - return PTR_ERR(clk); + vdd_dig.vdd_uv[1] = RPM_REGULATOR_CORNER_SVS_KRAIT; + + vdd_dig.regulator[0] = devm_regulator_get(&pdev->dev, "vdd_dig"); + if (IS_ERR(vdd_dig.regulator[0])) { + if (!(PTR_ERR(vdd_dig.regulator[0]) == -EPROBE_DEFER)) + dev_err(&pdev->dev, + "Unable to get vdd_dig regulator!"); + return PTR_ERR(vdd_dig.regulator[0]); } ret = qcom_cc_really_probe(pdev, &gcc_msm8996_desc, regmap); @@ -3358,6 +3461,12 @@ static int gcc_msm8996_probe(struct platform_device *pdev) /* This clock is used for all MMSS register access */ clk_prepare_enable(gcc_mmss_noc_cfg_ahb_clk.clkr.hw.clk); + /* + * Keep the core memory settings enabled at all times for + * gcc_mmss_bimc_gfx_clk. + */ + clk_set_flags(gcc_mmss_bimc_gfx_clk.clkr.hw.clk, CLKFLAG_RETAIN_MEM); + dev_info(&pdev->dev, "Registered GCC clocks\n"); return ret; diff --git a/drivers/clk/qcom/gcc-msmfalcon.c b/drivers/clk/qcom/gcc-msmfalcon.c index dfcd55ab2c26..1e1c871ef22c 100644 --- a/drivers/clk/qcom/gcc-msmfalcon.c +++ b/drivers/clk/qcom/gcc-msmfalcon.c @@ -1229,6 +1229,7 @@ static struct clk_branch gcc_blsp1_ahb_clk = { .enable_mask = BIT(17), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp1_ahb_clk", + .flags = CLK_ENABLE_HAND_OFF, .ops = &clk_branch2_ops, }, }, @@ -1422,6 +1423,7 @@ static struct clk_branch gcc_blsp2_ahb_clk = { .enable_mask = BIT(15), .hw.init = &(struct clk_init_data){ .name = "gcc_blsp2_ahb_clk", + .flags = CLK_ENABLE_HAND_OFF, .ops = &clk_branch2_ops, }, }, @@ -2844,7 +2846,7 @@ static struct measure_clk_data debug_mux_priv = { static const char *const debug_mux_parent_names[] = { "snoc_clk", "cnoc_clk", - "cnoc_periph", + "cnoc_periph_clk", "bimc_clk", "ce1_clk", "ipa_clk", @@ -2924,6 +2926,7 @@ static const char *const debug_mux_parent_names[] = { "gcc_ufs_rx_symbol_1_clk", "gcc_ufs_tx_symbol_0_clk", "gcc_usb3_phy_pipe_clk", + "mmssnoc_axi_clk", "mmss_bimc_smmu_ahb_clk", "mmss_bimc_smmu_axi_clk", "mmss_camss_ahb_clk", @@ -3104,6 +3107,7 @@ static struct clk_debug_mux gcc_debug_mux = { { "gcc_ufs_rx_symbol_1_clk", 0x162 }, { "gcc_ufs_tx_symbol_0_clk", 0x0EC }, { "gcc_usb3_phy_pipe_clk", 0x040 }, + { "mmssnoc_axi_clk", 0x22, MMCC, 0x004 }, { "mmss_bimc_smmu_ahb_clk", 0x22, MMCC, 0x00C }, { "mmss_bimc_smmu_axi_clk", 0x22, MMCC, 0x00D }, { "mmss_camss_ahb_clk", 0x22, MMCC, 0x037 }, diff --git a/drivers/clk/qcom/mdss/mdss-pll.c b/drivers/clk/qcom/mdss/mdss-pll.c index b4b73ea4211a..b51ab4f21561 100644 --- a/drivers/clk/qcom/mdss/mdss-pll.c +++ b/drivers/clk/qcom/mdss/mdss-pll.c @@ -133,6 +133,10 @@ static int mdss_pll_resource_parse(struct platform_device *pdev, pll_res->pll_interface_type = MDSS_DSI_PLL_8996; pll_res->target_id = MDSS_PLL_TARGET_8996; pll_res->revision = 2; + } else if (!strcmp(compatible_stream, "qcom,mdss_dsi_pll_msmfalcon")) { + pll_res->pll_interface_type = MDSS_DSI_PLL_8996; + pll_res->target_id = MDSS_PLL_TARGET_MSMFALCON; + pll_res->revision = 2; } else if (!strcmp(compatible_stream, "qcom,mdss_dsi_pll_8998")) { pll_res->pll_interface_type = MDSS_DSI_PLL_8998; } else if (!strcmp(compatible_stream, "qcom,mdss_dp_pll_8998")) { @@ -378,6 +382,7 @@ static const struct of_device_id mdss_pll_dt_match[] = { {.compatible = "qcom,mdss_hdmi_pll_8996_v3_1p8"}, {.compatible = "qcom,mdss_dp_pll_8998"}, {.compatible = "qcom,mdss_hdmi_pll_8998"}, + {.compatible = "qcom,mdss_dsi_pll_msmfalcon"}, {} }; diff --git a/drivers/clk/qcom/mdss/mdss-pll.h b/drivers/clk/qcom/mdss/mdss-pll.h index 3528dcfd0cb5..01664eaa815c 100644 --- a/drivers/clk/qcom/mdss/mdss-pll.h +++ b/drivers/clk/qcom/mdss/mdss-pll.h @@ -51,6 +51,7 @@ enum { enum { MDSS_PLL_TARGET_8996, + MDSS_PLL_TARGET_MSMFALCON, }; #define DFPS_MAX_NUM_OF_FRAME_RATES 20 diff --git a/drivers/clk/qcom/mmcc-msmfalcon.c b/drivers/clk/qcom/mmcc-msmfalcon.c index 44611bfce0d1..59dbebd825fd 100644 --- a/drivers/clk/qcom/mmcc-msmfalcon.c +++ b/drivers/clk/qcom/mmcc-msmfalcon.c @@ -529,6 +529,7 @@ static struct clk_rcg2 ahb_clk_src = { .hid_width = 5, .parent_map = mmcc_parent_map_10, .freq_tbl = ftbl_ahb_clk_src, + .flags = FORCE_ENABLE_RCGR, .clkr.hw.init = &(struct clk_init_data){ .name = "ahb_clk_src", .parent_names = mmcc_parent_names_10, @@ -1281,6 +1282,7 @@ static struct clk_rcg2 video_core_clk_src = { .hid_width = 5, .parent_map = mmcc_parent_map_12, .freq_tbl = ftbl_video_core_clk_src, + .flags = FORCE_ENABLE_RCGR, .clkr.hw.init = &(struct clk_init_data){ .name = "video_core_clk_src", .parent_names = mmcc_parent_names_12, @@ -1323,6 +1325,7 @@ static struct clk_branch mmss_bimc_smmu_ahb_clk = { .parent_names = (const char *[]){ "ahb_clk_src", }, + .flags = CLK_ENABLE_HAND_OFF, .num_parents = 1, .ops = &clk_branch2_ops, }, @@ -1337,6 +1340,7 @@ static struct clk_branch mmss_bimc_smmu_axi_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "mmss_bimc_smmu_axi_clk", + .flags = CLK_ENABLE_HAND_OFF, .ops = &clk_branch2_ops, }, }, @@ -2016,9 +2020,9 @@ static struct clk_branch mmss_camss_jpeg0_clk = { }, }; -static DEFINE_CLK_VOTER(mmss_camss_jpeg0_vote_clk, &mmss_camss_jpeg0_clk.c, 0); +static DEFINE_CLK_VOTER(mmss_camss_jpeg0_vote_clk, mmss_camss_jpeg0_clk, 0); static DEFINE_CLK_VOTER(mmss_camss_jpeg0_dma_vote_clk, - &mmss_camss_jpeg0_clk.c, 0); + mmss_camss_jpeg0_clk, 0); static struct clk_branch mmss_camss_jpeg_ahb_clk = { .halt_reg = 0x35b4, @@ -2318,6 +2322,7 @@ static struct clk_branch mmss_mdss_ahb_clk = { .parent_names = (const char *[]){ "ahb_clk_src", }, + .flags = CLK_ENABLE_HAND_OFF, .num_parents = 1, .ops = &clk_branch2_ops, }, @@ -2602,7 +2607,7 @@ static struct clk_branch mmss_mdss_mdp_clk = { "mdp_clk_src", }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, + .flags = CLK_SET_RATE_PARENT | CLK_ENABLE_HAND_OFF, .ops = &clk_branch2_ops, }, }, diff --git a/drivers/clk/qcom/vdd-level-8996.h b/drivers/clk/qcom/vdd-level-8996.h new file mode 100644 index 000000000000..f93dd1638b1b --- /dev/null +++ b/drivers/clk/qcom/vdd-level-8996.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __QCOM_VDD_LEVEL_8996_H__ +#define __QCOM_VDD_LEVEL_8996_H__ + +#include +#include + +#define VDD_DIG_FMAX_MAP1(l1, f1) \ + .vdd_class = &vdd_dig, \ + .rate_max = (unsigned long[VDD_DIG_NUM]) { \ + [VDD_DIG_##l1] = (f1), \ + }, \ + .num_rate_max = VDD_DIG_NUM + +#define VDD_DIG_FMAX_MAP2(l1, f1, l2, f2) \ + .vdd_class = &vdd_dig, \ + .rate_max = (unsigned long[VDD_DIG_NUM]) { \ + [VDD_DIG_##l1] = (f1), \ + [VDD_DIG_##l2] = (f2), \ + }, \ + .num_rate_max = VDD_DIG_NUM + +#define VDD_DIG_FMAX_MAP3(l1, f1, l2, f2, l3, f3) \ + .vdd_class = &vdd_dig, \ + .rate_max = (unsigned long[VDD_DIG_NUM]) { \ + [VDD_DIG_##l1] = (f1), \ + [VDD_DIG_##l2] = (f2), \ + [VDD_DIG_##l3] = (f3), \ + }, \ + .num_rate_max = VDD_DIG_NUM + +#define VDD_DIG_FMAX_MAP4(l1, f1, l2, f2, l3, f3, l4, f4) \ + .vdd_class = &vdd_dig, \ + .rate_max = (unsigned long[VDD_DIG_NUM]) { \ + [VDD_DIG_##l1] = (f1), \ + [VDD_DIG_##l2] = (f2), \ + [VDD_DIG_##l3] = (f3), \ + [VDD_DIG_##l4] = (f4), \ + }, \ + .num_rate_max = VDD_DIG_NUM + +#define VDD_MMPLL4_FMAX_MAP1(l1, f1) \ + .vdd_class = &vdd_mmpll4, \ + .rate_max = (unsigned long[VDD_DIG_NUM]) { \ + [VDD_DIG_##l1] = (f1), \ + }, \ + .num_rate_max = VDD_DIG_NUM + +#define VDD_MMPLL4_FMAX_MAP2(l1, f1, l2, f2) \ + .vdd_class = &vdd_mmpll4, \ + .rate_max = (unsigned long[VDD_DIG_NUM]) { \ + [VDD_DIG_##l1] = (f1), \ + [VDD_DIG_##l2] = (f2), \ + }, \ + .num_rate_max = VDD_DIG_NUM + +#define VDD_MMPLL4_FMAX_MAP3(l1, f1, l2, f2, l3, f3) \ + .vdd_class = &vdd_mmpll4, \ + .rate_max = (unsigned long[VDD_DIG_NUM]) { \ + [VDD_DIG_##l1] = (f1), \ + [VDD_DIG_##l2] = (f2), \ + [VDD_DIG_##l3] = (f3), \ + }, \ + .num_rate_max = VDD_DIG_NUM + +enum vdd_dig_levels { + VDD_DIG_NONE, + VDD_DIG_LOWER, /* SVS2 */ + VDD_DIG_LOW, /* SVS */ + VDD_DIG_NOMINAL, /* NOMINAL */ + VDD_DIG_HIGH, /* Turbo */ + VDD_DIG_NUM +}; + +static int vdd_corner[] = { + RPM_REGULATOR_CORNER_NONE, /* VDD_DIG_NONE */ + RPM_REGULATOR_CORNER_SVS_SOC, /* SVS2 is remapped to SVS */ + RPM_REGULATOR_CORNER_SVS_SOC, /* VDD_DIG_SVS */ + RPM_REGULATOR_CORNER_NORMAL, /* VDD_DIG_NOMINAL */ + RPM_REGULATOR_CORNER_SUPER_TURBO, /* VDD_DIG_TURBO */ +}; + +#endif diff --git a/drivers/crypto/msm/qce50.c b/drivers/crypto/msm/qce50.c index 0bef7effe601..8d17ea89e266 100644 --- a/drivers/crypto/msm/qce50.c +++ b/drivers/crypto/msm/qce50.c @@ -2485,8 +2485,11 @@ static int _qce_sps_add_sg_data_off(struct qce_device *pce_dev, res_within_sg = sg_dma_len(sg_src); while (off > 0) { - if (!sg_src) + if (!sg_src) { + pr_err("broken sg list off %d nbytes %d\n", + off, nbytes); return -ENOENT; + } len = sg_dma_len(sg_src); if (off < len) { res_within_sg = len - off; @@ -2494,7 +2497,8 @@ static int _qce_sps_add_sg_data_off(struct qce_device *pce_dev, } off -= len; sg_src = sg_next(sg_src); - res_within_sg = sg_dma_len(sg_src); + if (sg_src) + res_within_sg = sg_dma_len(sg_src); } while (nbytes > 0 && sg_src) { len = min(nbytes, res_within_sg); @@ -2525,9 +2529,15 @@ static int _qce_sps_add_sg_data_off(struct qce_device *pce_dev, addr += data_cnt; len -= data_cnt; } - sg_src = sg_next(sg_src); - off = 0; - res_within_sg = sg_dma_len(sg_src); + if (nbytes) { + sg_src = sg_next(sg_src); + if (!sg_src) { + pr_err("more data bytes %d\n", nbytes); + return -ENOMEM; + } + res_within_sg = sg_dma_len(sg_src); + off = 0; + } } return 0; } diff --git a/drivers/crypto/msm/qcrypto.c b/drivers/crypto/msm/qcrypto.c index faeff0b55202..a898dbcbd0ca 100644 --- a/drivers/crypto/msm/qcrypto.c +++ b/drivers/crypto/msm/qcrypto.c @@ -821,19 +821,16 @@ static struct qcrypto_alg *_qcrypto_aead_alg_alloc(struct crypto_priv *cp, return q_alg; }; -static int _qcrypto_cipher_cra_init(struct crypto_tfm *tfm) +static int _qcrypto_cipher_ctx_init(struct qcrypto_cipher_ctx *ctx, + struct qcrypto_alg *q_alg) { - struct crypto_alg *alg = tfm->__crt_alg; - struct qcrypto_alg *q_alg; - struct qcrypto_cipher_ctx *ctx = crypto_tfm_ctx(tfm); - - - q_alg = container_of(alg, struct qcrypto_alg, cipher_alg); + if (!ctx || !q_alg) { + pr_err("ctx or q_alg is NULL\n"); + return -EINVAL; + } ctx->flags = 0; - /* update context with ptr to cp */ ctx->cp = q_alg->cp; - /* random first IV */ get_random_bytes(ctx->iv, QCRYPTO_MAX_IV_LENGTH); if (_qcrypto_init_assign) { @@ -845,6 +842,16 @@ static int _qcrypto_cipher_cra_init(struct crypto_tfm *tfm) INIT_LIST_HEAD(&ctx->rsp_queue); ctx->auth_alg = QCE_HASH_LAST; return 0; +} + +static int _qcrypto_cipher_cra_init(struct crypto_tfm *tfm) +{ + struct crypto_alg *alg = tfm->__crt_alg; + struct qcrypto_alg *q_alg; + struct qcrypto_cipher_ctx *ctx = crypto_tfm_ctx(tfm); + + q_alg = container_of(alg, struct qcrypto_alg, cipher_alg); + return _qcrypto_cipher_ctx_init(ctx, q_alg); }; static int _qcrypto_ahash_cra_init(struct crypto_tfm *tfm) @@ -941,13 +948,22 @@ static int _qcrypto_cra_aes_ablkcipher_init(struct crypto_tfm *tfm) return _qcrypto_cra_ablkcipher_init(tfm); }; +static int _qcrypto_aead_cra_init(struct crypto_aead *tfm) +{ + struct qcrypto_cipher_ctx *ctx = crypto_aead_ctx(tfm); + struct aead_alg *aeadalg = crypto_aead_alg(tfm); + struct qcrypto_alg *q_alg = container_of(aeadalg, struct qcrypto_alg, + aead_alg); + return _qcrypto_cipher_ctx_init(ctx, q_alg); +}; + static int _qcrypto_cra_aead_sha1_init(struct crypto_aead *tfm) { int rc; struct qcrypto_cipher_ctx *ctx = crypto_aead_ctx(tfm); crypto_aead_set_reqsize(tfm, sizeof(struct qcrypto_cipher_req_ctx)); - rc = _qcrypto_cipher_cra_init(&tfm->base); + rc = _qcrypto_aead_cra_init(tfm); ctx->auth_alg = QCE_HASH_SHA1_HMAC; return rc; } @@ -958,7 +974,7 @@ static int _qcrypto_cra_aead_sha256_init(struct crypto_aead *tfm) struct qcrypto_cipher_ctx *ctx = crypto_aead_ctx(tfm); crypto_aead_set_reqsize(tfm, sizeof(struct qcrypto_cipher_req_ctx)); - rc = _qcrypto_cipher_cra_init(&tfm->base); + rc = _qcrypto_aead_cra_init(tfm); ctx->auth_alg = QCE_HASH_SHA256_HMAC; return rc; } @@ -969,7 +985,7 @@ static int _qcrypto_cra_aead_ccm_init(struct crypto_aead *tfm) struct qcrypto_cipher_ctx *ctx = crypto_aead_ctx(tfm); crypto_aead_set_reqsize(tfm, sizeof(struct qcrypto_cipher_req_ctx)); - rc = _qcrypto_cipher_cra_init(&tfm->base); + rc = _qcrypto_aead_cra_init(tfm); ctx->auth_alg = QCE_HASH_AES_CMAC; return rc; } @@ -980,7 +996,7 @@ static int _qcrypto_cra_aead_rfc4309_ccm_init(struct crypto_aead *tfm) struct qcrypto_cipher_ctx *ctx = crypto_aead_ctx(tfm); crypto_aead_set_reqsize(tfm, sizeof(struct qcrypto_cipher_req_ctx)); - rc = _qcrypto_cipher_cra_init(&tfm->base); + rc = _qcrypto_aead_cra_init(tfm); ctx->auth_alg = QCE_HASH_AES_CMAC; return rc; } @@ -992,7 +1008,7 @@ static int _qcrypto_cra_aead_aes_sha1_init(struct crypto_aead *tfm) struct crypto_priv *cp = &qcrypto_dev; crypto_aead_set_reqsize(tfm, sizeof(struct qcrypto_cipher_req_ctx)); - rc = _qcrypto_cipher_cra_init(&tfm->base); + rc = _qcrypto_aead_cra_init(tfm); if (rc) return rc; ctx->cipher_aes192_fb = NULL; @@ -1023,7 +1039,7 @@ static int _qcrypto_cra_aead_aes_sha256_init(struct crypto_aead *tfm) struct crypto_priv *cp = &qcrypto_dev; crypto_aead_set_reqsize(tfm, sizeof(struct qcrypto_cipher_req_ctx)); - rc = _qcrypto_cipher_cra_init(&tfm->base); + rc = _qcrypto_aead_cra_init(tfm); if (rc) return rc; ctx->cipher_aes192_fb = NULL; @@ -1828,7 +1844,7 @@ static void _qce_aead_complete(void *cookie, unsigned char *icv, if (rctx->dir == QCE_ENCRYPT) { /* copy the icv to dst */ scatterwalk_map_and_copy(icv, areq->dst, - areq->cryptlen, + areq->cryptlen + areq->assoclen, ctx->authsize, 1); } else { @@ -1836,8 +1852,9 @@ static void _qce_aead_complete(void *cookie, unsigned char *icv, /* compare icv from src */ scatterwalk_map_and_copy(tmp, - areq->src, areq->cryptlen - - ctx->authsize, ctx->authsize, 0); + areq->src, areq->assoclen + + areq->cryptlen - ctx->authsize, + ctx->authsize, 0); ret = memcmp(icv, tmp, ctx->authsize); if (ret != 0) ret = -EBADMSG; diff --git a/drivers/gpu/msm/adreno_dispatch.c b/drivers/gpu/msm/adreno_dispatch.c index 18c05e930216..0d068e9c5805 100644 --- a/drivers/gpu/msm/adreno_dispatch.c +++ b/drivers/gpu/msm/adreno_dispatch.c @@ -604,6 +604,16 @@ static int sendcmd(struct adreno_device *adreno_dev, if (!test_and_set_bit(ADRENO_DISPATCHER_ACTIVE, &dispatcher->priv)) reinit_completion(&dispatcher->idle_gate); + + /* + * We update power stats generally at the expire of + * cmdbatch. In cases where the cmdbatch takes a long + * time to finish, it will delay power stats update, + * in effect it will delay DCVS decision. Start a + * timer to update power state on expire of this timer. + */ + kgsl_pwrscale_midframe_timer_restart(device); + } else { kgsl_active_count_put(device); clear_bit(ADRENO_DISPATCHER_POWER, &dispatcher->priv); diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c index 172de7406c26..cd9a82a9bf4a 100644 --- a/drivers/gpu/msm/kgsl_pwrctrl.c +++ b/drivers/gpu/msm/kgsl_pwrctrl.c @@ -2355,6 +2355,7 @@ static int _init(struct kgsl_device *device) case KGSL_STATE_ACTIVE: kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF); del_timer_sync(&device->idle_timer); + kgsl_pwrscale_midframe_timer_cancel(device); device->ftbl->stop(device); /* fall through */ case KGSL_STATE_AWARE: @@ -2462,6 +2463,7 @@ _aware(struct kgsl_device *device) case KGSL_STATE_ACTIVE: kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF); del_timer_sync(&device->idle_timer); + kgsl_pwrscale_midframe_timer_cancel(device); break; case KGSL_STATE_SLUMBER: status = kgsl_pwrctrl_enable(device); @@ -2486,6 +2488,8 @@ _nap(struct kgsl_device *device) return -EBUSY; } + kgsl_pwrscale_midframe_timer_cancel(device); + /* * Read HW busy counters before going to NAP state. * The data might be used by power scale governors @@ -2522,6 +2526,7 @@ _slumber(struct kgsl_device *device) /* fall through */ case KGSL_STATE_NAP: del_timer_sync(&device->idle_timer); + kgsl_pwrscale_midframe_timer_cancel(device); if (device->pwrctrl.thermal_cycle == CYCLE_ACTIVE) { device->pwrctrl.thermal_cycle = CYCLE_ENABLE; del_timer_sync(&device->pwrctrl.thermal_timer); diff --git a/drivers/gpu/msm/kgsl_pwrscale.c b/drivers/gpu/msm/kgsl_pwrscale.c index 85cd29b5364e..413a3098b0ef 100644 --- a/drivers/gpu/msm/kgsl_pwrscale.c +++ b/drivers/gpu/msm/kgsl_pwrscale.c @@ -13,6 +13,7 @@ #include #include +#include #include "kgsl.h" #include "kgsl_pwrscale.h" @@ -37,6 +38,18 @@ static struct kgsl_popp popp_param[POPP_MAX] = { {0, 0}, }; +/** +* struct kgsl_midframe_info - midframe power stats sampling info +* @timer - midframe sampling timer +* @timer_check_ws - Updates powerstats on midframe expiry +* @device - pointer to kgsl_device +*/ +static struct kgsl_midframe_info { + struct hrtimer timer; + struct work_struct timer_check_ws; + struct kgsl_device *device; +} *kgsl_midframe = NULL; + static void do_devfreq_suspend(struct work_struct *work); static void do_devfreq_resume(struct work_struct *work); static void do_devfreq_notify(struct work_struct *work); @@ -183,9 +196,57 @@ void kgsl_pwrscale_update(struct kgsl_device *device) if (device->state != KGSL_STATE_SLUMBER) queue_work(device->pwrscale.devfreq_wq, &device->pwrscale.devfreq_notify_ws); + + kgsl_pwrscale_midframe_timer_restart(device); } EXPORT_SYMBOL(kgsl_pwrscale_update); +void kgsl_pwrscale_midframe_timer_restart(struct kgsl_device *device) +{ + if (kgsl_midframe) { + WARN_ON(!mutex_is_locked(&device->mutex)); + + /* If the timer is already running, stop it */ + if (hrtimer_active(&kgsl_midframe->timer)) + hrtimer_cancel( + &kgsl_midframe->timer); + + hrtimer_start(&kgsl_midframe->timer, + ns_to_ktime(KGSL_GOVERNOR_CALL_INTERVAL + * NSEC_PER_USEC), HRTIMER_MODE_REL); + } +} +EXPORT_SYMBOL(kgsl_pwrscale_midframe_timer_restart); + +void kgsl_pwrscale_midframe_timer_cancel(struct kgsl_device *device) +{ + if (kgsl_midframe) { + WARN_ON(!mutex_is_locked(&device->mutex)); + hrtimer_cancel(&kgsl_midframe->timer); + } +} +EXPORT_SYMBOL(kgsl_pwrscale_midframe_timer_cancel); + +static void kgsl_pwrscale_midframe_timer_check(struct work_struct *work) +{ + struct kgsl_device *device = kgsl_midframe->device; + + mutex_lock(&device->mutex); + if (device->state == KGSL_STATE_ACTIVE) + kgsl_pwrscale_update(device); + mutex_unlock(&device->mutex); +} + +static enum hrtimer_restart kgsl_pwrscale_midframe_timer(struct hrtimer *timer) +{ + struct kgsl_device *device = kgsl_midframe->device; + + queue_work(device->pwrscale.devfreq_wq, + &kgsl_midframe->timer_check_ws); + + return HRTIMER_NORESTART; +} + /* * kgsl_pwrscale_disable - temporarily disable the governor * @device: The device @@ -852,6 +913,17 @@ int kgsl_pwrscale_init(struct device *dev, const char *governor) data->bin.ctxt_aware_busy_penalty = 12000; } + if (of_property_read_bool(device->pdev->dev.of_node, + "qcom,enable-midframe-timer")) { + kgsl_midframe = kzalloc( + sizeof(struct kgsl_midframe_info), GFP_KERNEL); + hrtimer_init(&kgsl_midframe->timer, + CLOCK_MONOTONIC, HRTIMER_MODE_REL); + kgsl_midframe->timer.function = + kgsl_pwrscale_midframe_timer; + kgsl_midframe->device = device; + } + /* * If there is a separate GX power rail, allow * independent modification to its voltage through @@ -900,6 +972,9 @@ int kgsl_pwrscale_init(struct device *dev, const char *governor) INIT_WORK(&pwrscale->devfreq_suspend_ws, do_devfreq_suspend); INIT_WORK(&pwrscale->devfreq_resume_ws, do_devfreq_resume); INIT_WORK(&pwrscale->devfreq_notify_ws, do_devfreq_notify); + if (kgsl_midframe) + INIT_WORK(&kgsl_midframe->timer_check_ws, + kgsl_pwrscale_midframe_timer_check); pwrscale->next_governor_call = ktime_add_us(ktime_get(), KGSL_GOVERNOR_CALL_INTERVAL); @@ -940,9 +1015,13 @@ void kgsl_pwrscale_close(struct kgsl_device *device) pwrscale = &device->pwrscale; if (!pwrscale->devfreqptr) return; + + kgsl_pwrscale_midframe_timer_cancel(device); flush_workqueue(pwrscale->devfreq_wq); destroy_workqueue(pwrscale->devfreq_wq); devfreq_remove_device(device->pwrscale.devfreqptr); + kfree(kgsl_midframe); + kgsl_midframe = NULL; device->pwrscale.devfreqptr = NULL; srcu_cleanup_notifier_head(&device->pwrscale.nh); for (i = 0; i < KGSL_PWREVENT_MAX; i++) diff --git a/drivers/gpu/msm/kgsl_pwrscale.h b/drivers/gpu/msm/kgsl_pwrscale.h index 0756a4490f22..184bfd1a2692 100644 --- a/drivers/gpu/msm/kgsl_pwrscale.h +++ b/drivers/gpu/msm/kgsl_pwrscale.h @@ -122,6 +122,9 @@ void kgsl_pwrscale_busy(struct kgsl_device *device); void kgsl_pwrscale_sleep(struct kgsl_device *device); void kgsl_pwrscale_wake(struct kgsl_device *device); +void kgsl_pwrscale_midframe_timer_restart(struct kgsl_device *device); +void kgsl_pwrscale_midframe_timer_cancel(struct kgsl_device *device); + void kgsl_pwrscale_enable(struct kgsl_device *device); void kgsl_pwrscale_disable(struct kgsl_device *device, bool turbo); diff --git a/drivers/i2c/busses/i2c-msm-v2.c b/drivers/i2c/busses/i2c-msm-v2.c index a510490d28d6..04b1b62f85c3 100644 --- a/drivers/i2c/busses/i2c-msm-v2.c +++ b/drivers/i2c/busses/i2c-msm-v2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -2236,12 +2236,12 @@ static void i2c_msm_pm_xfer_end(struct i2c_msm_ctrl *ctrl) i2c_msm_dma_free_channels(ctrl); i2c_msm_pm_clk_disable_unprepare(ctrl); - if (pm_runtime_enabled(ctrl->dev)) { - pm_runtime_mark_last_busy(ctrl->dev); - pm_runtime_put_autosuspend(ctrl->dev); - } else { + + if (!pm_runtime_enabled(ctrl->dev)) i2c_msm_pm_suspend(ctrl->dev); - } + + pm_runtime_mark_last_busy(ctrl->dev); + pm_runtime_put_autosuspend(ctrl->dev); mutex_unlock(&ctrl->xfer.mtx); } diff --git a/drivers/input/misc/hbtp_input.c b/drivers/input/misc/hbtp_input.c index 05cd1edefb7f..1df5d8812991 100644 --- a/drivers/input/misc/hbtp_input.c +++ b/drivers/input/misc/hbtp_input.c @@ -208,9 +208,13 @@ static int hbtp_input_create_input_dev(struct hbtp_input_absinfo *absinfo) input_mt_init_slots(input_dev, HBTP_MAX_FINGER, 0); for (i = 0; i <= ABS_MT_LAST - ABS_MT_FIRST; i++) { abs = absinfo + i; - if (abs->active) - input_set_abs_params(input_dev, abs->code, + if (abs->active) { + if (abs->code >= 0 && abs->code < ABS_CNT) + input_set_abs_params(input_dev, abs->code, abs->minimum, abs->maximum, 0, 0); + else + pr_err("%s: ABS code out of bound\n", __func__); + } } if (hbtp->override_disp_coords) { diff --git a/drivers/input/qpnp-power-on.c b/drivers/input/qpnp-power-on.c index 760c92a47a36..967b23cae05c 100644 --- a/drivers/input/qpnp-power-on.c +++ b/drivers/input/qpnp-power-on.c @@ -31,6 +31,7 @@ #include #include #include +#include #define PMIC_VER_8941 0x01 #define PMIC_VERSION_REG 0x0105 @@ -220,6 +221,11 @@ struct qpnp_pon { bool store_hard_reset_reason; }; +static int pon_ship_mode_en; +module_param_named( + ship_mode_en, pon_ship_mode_en, int, S_IRUSR | S_IWUSR +); + static struct qpnp_pon *sys_reset_dev; static DEFINE_SPINLOCK(spon_list_slock); static LIST_HEAD(spon_dev_list); @@ -523,6 +529,8 @@ int qpnp_pon_system_pwr_off(enum pon_power_off_type type) int rc = 0; struct qpnp_pon *pon = sys_reset_dev; struct qpnp_pon *tmp; + struct power_supply *batt_psy; + union power_supply_propval val; unsigned long flags; if (!pon) @@ -557,6 +565,19 @@ int qpnp_pon_system_pwr_off(enum pon_power_off_type type) goto out; } } + /* Set ship mode here if it has been requested */ + if (!!pon_ship_mode_en) { + batt_psy = power_supply_get_by_name("battery"); + if (batt_psy) { + pr_debug("Set ship mode!\n"); + val.intval = 1; + rc = power_supply_set_property(batt_psy, + POWER_SUPPLY_PROP_SET_SHIP_MODE, &val); + if (rc) + dev_err(&pon->pdev->dev, + "Set ship-mode failed\n"); + } + } out: spin_unlock_irqrestore(&spon_list_slock, flags); return rc; diff --git a/drivers/leds/leds-qpnp-wled.c b/drivers/leds/leds-qpnp-wled.c index 77014f93927c..56750ac8e9e2 100644 --- a/drivers/leds/leds-qpnp-wled.c +++ b/drivers/leds/leds-qpnp-wled.c @@ -108,7 +108,14 @@ #define QPNP_WLED_SWITCH_FREQ_1600_KHZ 1600 #define QPNP_WLED_SWITCH_FREQ_OVERWRITE 0x80 #define QPNP_WLED_OVP_MASK GENMASK(1, 0) -#define QPNP_WLED_TEST4_EN_VREF_UP 0x32 +#define QPNP_WLED_TEST4_EN_DEB_BYPASS_ILIM_BIT BIT(6) +#define QPNP_WLED_TEST4_EN_SH_FOR_SS_BIT BIT(5) +#define QPNP_WLED_TEST4_EN_CLAMP_BIT BIT(4) +#define QPNP_WLED_TEST4_EN_SOFT_START_BIT BIT(1) +#define QPNP_WLED_TEST4_EN_VREF_UP \ + (QPNP_WLED_TEST4_EN_SH_FOR_SS_BIT | \ + QPNP_WLED_TEST4_EN_CLAMP_BIT | \ + QPNP_WLED_TEST4_EN_SOFT_START_BIT) #define QPNP_WLED_TEST4_EN_IIND_UP 0x1 /* sink registers */ @@ -167,6 +174,7 @@ #define QPNP_WLED_SINK_TEST5_HYB 0x14 #define QPNP_WLED_SINK_TEST5_DIG 0x1E +#define QPNP_WLED_SINK_TEST5_HVG_PULL_STR_BIT BIT(3) #define QPNP_WLED_SWITCH_FREQ_800_KHZ_CODE 0x0B #define QPNP_WLED_SWITCH_FREQ_1600_KHZ_CODE 0x05 @@ -1035,7 +1043,8 @@ static int qpnp_wled_set_disp(struct qpnp_wled *wled, u16 base_addr) /* * enable VREF_UP to avoid false ovp on low brightness for LCD */ - reg = QPNP_WLED_TEST4_EN_VREF_UP; + reg = QPNP_WLED_TEST4_EN_VREF_UP + | QPNP_WLED_TEST4_EN_DEB_BYPASS_ILIM_BIT; rc = qpnp_wled_sec_write_reg(wled, QPNP_WLED_TEST4_REG(base_addr), reg); if (rc) @@ -1550,10 +1559,13 @@ static int qpnp_wled_config(struct qpnp_wled *wled) return rc; /* Configure TEST5 register */ - if (wled->dim_mode == QPNP_WLED_DIM_DIGITAL) + if (wled->dim_mode == QPNP_WLED_DIM_DIGITAL) { reg = QPNP_WLED_SINK_TEST5_DIG; - else + } else { reg = QPNP_WLED_SINK_TEST5_HYB; + if (wled->pmic_rev_id->pmic_subtype == PM2FALCON_SUBTYPE) + reg |= QPNP_WLED_SINK_TEST5_HVG_PULL_STR_BIT; + } rc = qpnp_wled_sec_write_reg(wled, QPNP_WLED_SINK_TEST5_REG(wled->sink_base), reg); diff --git a/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c b/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c index b045d6c6e8da..54c0aa39cdd3 100644 --- a/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c +++ b/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c @@ -1102,11 +1102,11 @@ static int cam_smmu_map_secure_buffer_and_add_to_list(int idx, } if (table->sgl) { - CDBG("DMA buf: %p, device: %p, attach: %p, table: %p\n", + CDBG("DMA buf: %pK, device: %pK, attach: %pK, table: %pK\n", (void *)buf, (void *)iommu_cb_set.cb_info[idx].dev, (void *)attach, (void *)table); - CDBG("table sgl: %p, rc: %d, dma_address: 0x%x\n", + CDBG("table sgl: %pK, rc: %d, dma_address: 0x%x\n", (void *)table->sgl, rc, (unsigned int)table->sgl->dma_address); } else { @@ -1139,7 +1139,7 @@ static int cam_smmu_map_secure_buffer_and_add_to_list(int idx, rc = -ENOSPC; goto err_mapping_info; } - CDBG("dev = %p, paddr= %p, len = %u\n", + CDBG("dev = %pK, paddr= %pK, len = %u\n", (void *)iommu_cb_set.cb_info[idx].dev, (void *)*paddr_ptr, (unsigned int)*len_ptr); diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c index a1fb307b09c1..ab01d37790d6 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c @@ -1099,7 +1099,7 @@ static int msm_vfe40_start_fetch_engine_multi_pass(struct vfe_device *vfe_dev, rc = vfe_dev->buf_mgr->ops->get_buf_by_index( vfe_dev->buf_mgr, bufq_handle, fe_cfg->buf_idx, &buf); if (rc < 0 || !buf) { - pr_err("%s: No fetch buffer rc= %d buf= %p\n", + pr_err("%s: No fetch buffer rc= %d buf= %pK\n", __func__, rc, buf); return -EINVAL; } diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c index f6e0d9083b22..941119fad78e 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c @@ -1768,7 +1768,7 @@ int msm_isp_cfg_offline_ping_pong_address(struct vfe_device *vfe_dev, rc = vfe_dev->buf_mgr->ops->get_buf_by_index( vfe_dev->buf_mgr, bufq_handle, buf_idx, &buf); if (rc < 0 || !buf) { - pr_err("%s: No fetch buffer rc= %d buf= %p\n", + pr_err("%s: No fetch buffer rc= %d buf= %pK\n", __func__, rc, buf); return -EINVAL; } diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c index 6911e8fc5f2f..ddd32fc5c339 100644 --- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c +++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c @@ -91,7 +91,7 @@ static int cpp_get_clk_freq_tbl_dt(struct cpp_device *cpp_dev) hw_info = &cpp_dev->hw_info; if ((hw_info == NULL) || (of_node == NULL)) { - pr_err("Invalid hw_info %p or ofnode %p\n", hw_info, of_node); + pr_err("Invalid hw_info %pK or ofnode %pK\n", hw_info, of_node); rc = -EINVAL; goto err; diff --git a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c index b413bf3855b8..4b6005b9af46 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c +++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c @@ -1418,6 +1418,7 @@ static int32_t msm_actuator_config(struct msm_actuator_ctrl_t *a_ctrl, case CFG_GET_ACTUATOR_INFO: cdata->is_af_supported = 1; cdata->cfg.cam_name = a_ctrl->cam_name; + rc = 0; break; case CFG_SET_ACTUATOR_INFO: diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c index a7b3663ad7fe..6b3d84a2c145 100644 --- a/drivers/misc/qseecom.c +++ b/drivers/misc/qseecom.c @@ -4621,6 +4621,40 @@ int qseecom_set_bandwidth(struct qseecom_handle *handle, bool high) } EXPORT_SYMBOL(qseecom_set_bandwidth); +int qseecom_process_listener_from_smcinvoke(struct scm_desc *desc) +{ + struct qseecom_registered_app_list dummy_app_entry = { {0} }; + struct qseecom_dev_handle dummy_private_data = {0}; + struct qseecom_command_scm_resp resp; + int ret = 0; + + if (!desc) { + pr_err("desc is NULL\n"); + return -EINVAL; + } + + resp.result = desc->ret[0]; /*req_cmd*/ + resp.resp_type = desc->ret[1]; /*app_id*/ + resp.data = desc->ret[2]; /*listener_id*/ + + dummy_private_data.client.app_id = desc->ret[1]; + dummy_app_entry.app_id = desc->ret[1]; + + mutex_lock(&app_access_lock); + ret = __qseecom_process_reentrancy(&resp, &dummy_app_entry, + &dummy_private_data); + mutex_unlock(&app_access_lock); + if (ret) + pr_err("Failed to req cmd %d lsnr %d on app %d, ret = %d\n", + (int)desc->ret[0], (int)desc->ret[2], + (int)desc->ret[1], ret); + desc->ret[0] = resp.result; + desc->ret[1] = resp.resp_type; + desc->ret[2] = resp.data; + return ret; +} +EXPORT_SYMBOL(qseecom_process_listener_from_smcinvoke); + static int qseecom_send_resp(void) { qseecom.send_resp_flag = 1; diff --git a/drivers/misc/qseecom_kernel.h b/drivers/misc/qseecom_kernel.h index ca0205560875..8f981903c3a1 100644 --- a/drivers/misc/qseecom_kernel.h +++ b/drivers/misc/qseecom_kernel.h @@ -14,6 +14,7 @@ #define __QSEECOM_KERNEL_H_ #include +#include #define QSEECOM_ALIGN_SIZE 0x40 #define QSEECOM_ALIGN_MASK (QSEECOM_ALIGN_SIZE - 1) @@ -38,5 +39,6 @@ int qseecom_shutdown_app(struct qseecom_handle **handle); int qseecom_send_command(struct qseecom_handle *handle, void *send_buf, uint32_t sbuf_len, void *resp_buf, uint32_t rbuf_len); int qseecom_set_bandwidth(struct qseecom_handle *handle, bool high); +int qseecom_process_listener_from_smcinvoke(struct scm_desc *desc); #endif /* __QSEECOM_KERNEL_H_ */ diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index daa7a33d12d8..f5575747d11e 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c @@ -964,6 +964,7 @@ int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len, wil->reply_id = reply_id; wil->reply_buf = reply; wil->reply_size = reply_size; + reinit_completion(&wil->wmi_call); spin_unlock(&wil->wmi_ev_lock); rc = __wmi_send(wil, cmdid, buf, len); diff --git a/drivers/platform/msm/msm_11ad/msm_11ad.c b/drivers/platform/msm/msm_11ad/msm_11ad.c index 5810f7bf7f2f..b7fc68a6efdd 100644 --- a/drivers/platform/msm/msm_11ad/msm_11ad.c +++ b/drivers/platform/msm/msm_11ad/msm_11ad.c @@ -33,7 +33,7 @@ #define WIGIG_DEVICE (0x0310) #define SMMU_BASE 0x10000000 /* Device address range base */ -#define SMMU_SIZE 0x40000000 /* Device address range size */ +#define SMMU_SIZE ((SZ_1G * 4ULL) - SMMU_BASE) #define WIGIG_ENABLE_DELAY 50 #define PM_OPT_SUSPEND (MSM_PCIE_CONFIG_NO_CFG_RESTORE | \ @@ -87,6 +87,8 @@ struct msm11ad_ctx { /* SMMU */ bool use_smmu; /* have SMMU enabled? */ + int smmu_bypass; + int smmu_fast_map; struct dma_iommu_mapping *mapping; /* bus frequency scaling */ @@ -596,11 +598,13 @@ static int msm_11ad_smmu_init(struct msm11ad_ctx *ctx) { int atomic_ctx = 1; int rc; - int bypass_enable = 1; if (!ctx->use_smmu) return 0; + dev_info(ctx->dev, "Initialize SMMU, bypass = %d, fastmap = %d\n", + ctx->smmu_bypass, ctx->smmu_fast_map); + ctx->mapping = arm_iommu_create_mapping(&platform_bus_type, SMMU_BASE, SMMU_SIZE); if (IS_ERR_OR_NULL(ctx->mapping)) { @@ -608,7 +612,6 @@ static int msm_11ad_smmu_init(struct msm11ad_ctx *ctx) dev_err(ctx->dev, "Failed to create IOMMU mapping (%d)\n", rc); return rc; } - dev_info(ctx->dev, "IOMMU mapping created: %p\n", ctx->mapping); rc = iommu_domain_set_attr(ctx->mapping->domain, DOMAIN_ATTR_ATOMIC, @@ -619,13 +622,24 @@ static int msm_11ad_smmu_init(struct msm11ad_ctx *ctx) goto release_mapping; } - rc = iommu_domain_set_attr(ctx->mapping->domain, - DOMAIN_ATTR_S1_BYPASS, - &bypass_enable); - if (rc) { - dev_err(ctx->dev, "Set bypass attribute to SMMU failed (%d)\n", - rc); - goto release_mapping; + if (ctx->smmu_bypass) { + rc = iommu_domain_set_attr(ctx->mapping->domain, + DOMAIN_ATTR_S1_BYPASS, + &ctx->smmu_bypass); + if (rc) { + dev_err(ctx->dev, "Set bypass attribute to SMMU failed (%d)\n", + rc); + goto release_mapping; + } + } else if (ctx->smmu_fast_map) { + rc = iommu_domain_set_attr(ctx->mapping->domain, + DOMAIN_ATTR_FAST, + &ctx->smmu_fast_map); + if (rc) { + dev_err(ctx->dev, "Set fast attribute to SMMU failed (%d)\n", + rc); + goto release_mapping; + } } rc = arm_iommu_attach_device(&ctx->pcidev->dev, ctx->mapping); @@ -870,6 +884,9 @@ static int msm_11ad_probe(struct platform_device *pdev) ctx->use_smmu = of_property_read_bool(of_node, "qcom,smmu-support"); ctx->bus_scale = msm_bus_cl_get_pdata(pdev); + ctx->smmu_bypass = 1; + ctx->smmu_fast_map = 0; + /*== execute ==*/ /* turn device on */ rc = msm_11ad_init_vregs(ctx); diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c index a4aee80798e4..83b75fcd257e 100644 --- a/drivers/power/power_supply_sysfs.c +++ b/drivers/power/power_supply_sysfs.c @@ -278,6 +278,7 @@ static struct device_attribute power_supply_attrs[] = { POWER_SUPPLY_ATTR(parallel_percent), POWER_SUPPLY_ATTR(pe_start), POWER_SUPPLY_ATTR(set_ship_mode), + POWER_SUPPLY_ATTR(soc_reporting_ready), /* Local extensions of type int64_t */ POWER_SUPPLY_ATTR(charge_counter_ext), /* Properties of type `const char *' */ diff --git a/drivers/power/qcom-charger/fg-core.h b/drivers/power/qcom-charger/fg-core.h index d8b6754a465f..6f8266a3161c 100644 --- a/drivers/power/qcom-charger/fg-core.h +++ b/drivers/power/qcom-charger/fg-core.h @@ -335,6 +335,7 @@ struct fg_chip { bool recharge_soc_adjusted; bool ki_coeff_dischg_en; bool esr_fcc_ctrl_en; + bool soc_reporting_ready; struct completion soc_update; struct completion soc_ready; struct delayed_work profile_load_work; diff --git a/drivers/power/qcom-charger/qpnp-fg-gen3.c b/drivers/power/qcom-charger/qpnp-fg-gen3.c index 22025ac27ffa..7c1ece431beb 100644 --- a/drivers/power/qcom-charger/qpnp-fg-gen3.c +++ b/drivers/power/qcom-charger/qpnp-fg-gen3.c @@ -2050,6 +2050,7 @@ done: fg_notify_charger(chip); chip->profile_loaded = true; + chip->soc_reporting_ready = true; fg_dbg(chip, FG_STATUS, "profile loaded successfully"); out: vote(chip->awake_votable, PROFILE_LOAD, false, 0); @@ -2386,6 +2387,9 @@ static int fg_psy_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG: rc = fg_get_time_to_empty(chip, &pval->intval); break; + case POWER_SUPPLY_PROP_SOC_REPORTING_READY: + pval->intval = chip->soc_reporting_ready; + break; default: pr_err("unsupported property %d\n", psp); rc = -EINVAL; @@ -2483,6 +2487,7 @@ static enum power_supply_property fg_psy_props[] = { POWER_SUPPLY_PROP_CHARGE_COUNTER, POWER_SUPPLY_PROP_TIME_TO_FULL_AVG, POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, + POWER_SUPPLY_PROP_SOC_REPORTING_READY, }; static const struct power_supply_desc fg_psy_desc = { @@ -2773,9 +2778,11 @@ static irqreturn_t fg_batt_missing_irq_handler(int irq, void *data) chip->profile_available = false; chip->profile_loaded = false; clear_cycle_counter(chip); + chip->soc_reporting_ready = false; } else { rc = fg_get_batt_profile(chip); if (rc < 0) { + chip->soc_reporting_ready = true; pr_err("Error in getting battery profile, rc:%d\n", rc); return IRQ_HANDLED; } @@ -3213,9 +3220,11 @@ static int fg_parse_dt(struct fg_chip *chip) chip->rradc_base = base; rc = fg_get_batt_profile(chip); - if (rc < 0) + if (rc < 0) { + chip->soc_reporting_ready = true; pr_warn("profile for batt_id=%dKOhms not found..using OTP, rc:%d\n", chip->batt_id_ohms / 1000, rc); + } /* Read all the optional properties below */ rc = of_property_read_u32(node, "qcom,fg-cutoff-voltage", &temp); diff --git a/drivers/power/reset/msm-poweroff.c b/drivers/power/reset/msm-poweroff.c index d32f293695bb..267df592ba8a 100644 --- a/drivers/power/reset/msm-poweroff.c +++ b/drivers/power/reset/msm-poweroff.c @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -65,11 +66,17 @@ static struct kobject dload_kobj; #ifdef CONFIG_QCOM_DLOAD_MODE #define EDL_MODE_PROP "qcom,msm-imem-emergency_download_mode" #define DL_MODE_PROP "qcom,msm-imem-download_mode" +#ifdef CONFIG_RANDOMIZE_BASE +#define KASLR_OFFSET_PROP "qcom,msm-imem-kaslr_offset" +#endif static int in_panic; static void *dload_mode_addr; static bool dload_mode_enabled; static void *emergency_dload_mode_addr; +#ifdef CONFIG_RANDOMIZE_BASE +static void *kaslr_imem_addr; +#endif static bool scm_dload_supported; static int dload_set(const char *val, struct kernel_param *kp); @@ -510,6 +517,28 @@ static int msm_restart_probe(struct platform_device *pdev) pr_err("unable to map imem EDLOAD mode offset\n"); } +#ifdef CONFIG_RANDOMIZE_BASE +#define KASLR_OFFSET_BIT_MASK 0x00000000FFFFFFFF + np = of_find_compatible_node(NULL, NULL, KASLR_OFFSET_PROP); + if (!np) { + pr_err("unable to find DT imem KASLR_OFFSET node\n"); + } else { + kaslr_imem_addr = of_iomap(np, 0); + if (!kaslr_imem_addr) + pr_err("unable to map imem KASLR offset\n"); + } + + if (kaslr_imem_addr && scm_is_secure_device()) { + __raw_writel(0xdead4ead, kaslr_imem_addr); + __raw_writel(KASLR_OFFSET_BIT_MASK & + (kimage_vaddr - KIMAGE_VADDR), kaslr_imem_addr + 4); + __raw_writel(KASLR_OFFSET_BIT_MASK & + ((kimage_vaddr - KIMAGE_VADDR) >> 32), + kaslr_imem_addr + 8); + iounmap(kaslr_imem_addr); + } +#endif + np = of_find_compatible_node(NULL, NULL, "qcom,msm-imem-dload-type"); if (!np) { @@ -603,4 +632,4 @@ static int __init msm_restart_init(void) { return platform_driver_register(&msm_restart_driver); } -device_initcall(msm_restart_init); +pure_initcall(msm_restart_init); diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index ba1bf3b5f492..bd2c1a8e7540 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -925,6 +925,17 @@ config REGULATOR_CPRH_KBSS independent voltage supplies. This driver reads both initial voltage and CPR target quotient values out of hardware fuses. +config REGULATOR_CPR4_MMSS_LDO + bool "RBCPR3 regulator for MMSS LDO" + depends on OF + select REGULATOR_CPR3 + help + This driver supports Qualcomm Technologies, Inc. MMSS graphics + processor specific features. The MMSS CPR3 controller only uses one + thread to monitor the MMSS LDO voltage requirements. This driver reads + initial voltage values out of hardware fuses and CPR target quotient + values out of device tree. + config REGULATOR_KRYO bool "Kryo regulator driver" depends on OF diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 79a203418a0b..abd116d3d8af 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -114,6 +114,7 @@ obj-$(CONFIG_REGULATOR_CPR3_HMSS) += cpr3-hmss-regulator.o obj-$(CONFIG_REGULATOR_CPR3_MMSS) += cpr3-mmss-regulator.o obj-$(CONFIG_REGULATOR_CPR4_APSS) += cpr4-apss-regulator.o obj-$(CONFIG_REGULATOR_CPRH_KBSS) += cprh-kbss-regulator.o +obj-$(CONFIG_REGULATOR_CPR4_MMSS_LDO) += cpr4-mmss-ldo-regulator.o obj-$(CONFIG_REGULATOR_QPNP_LABIBB) += qpnp-labibb-regulator.o obj-$(CONFIG_REGULATOR_QPNP_LCDB) += qpnp-lcdb-regulator.o obj-$(CONFIG_REGULATOR_STUB) += stub-regulator.o diff --git a/drivers/regulator/cpr4-mmss-ldo-regulator.c b/drivers/regulator/cpr4-mmss-ldo-regulator.c new file mode 100644 index 000000000000..9fa5c309b02a --- /dev/null +++ b/drivers/regulator/cpr4-mmss-ldo-regulator.c @@ -0,0 +1,722 @@ +/* + * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define pr_fmt(fmt) "%s: " fmt, __func__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cpr3-regulator.h" + +#define MSMFALCON_MMSS_FUSE_CORNERS 6 + +/** + * struct cpr4_msmfalcon_mmss_fuses - MMSS specific fuse data for MSMFALCON + * @init_voltage: Initial (i.e. open-loop) voltage fuse parameter value + * for each fuse corner (raw, not converted to a voltage) + * @offset_voltage: The closed-loop voltage margin adjustment fuse parameter + * value for each fuse corner (raw, not converted to a + * voltage) + * @cpr_fusing_rev: CPR fusing revision fuse parameter value + * @ldo_enable: The ldo enable fuse parameter for each fuse corner + * indicates that VDD_GFX can be configured to LDO mode in + * the corresponding fuse corner. + * @ldo_cpr_cl_enable: A fuse parameter indicates that GFX CPR can be + * configured to operate in closed-loop mode when VDD_GFX + * is configured for LDO sub-regulated mode. + * + * This struct holds the values for all of the fuses read from memory. + */ +struct cpr4_msmfalcon_mmss_fuses { + u64 init_voltage[MSMFALCON_MMSS_FUSE_CORNERS]; + u64 offset_voltage[MSMFALCON_MMSS_FUSE_CORNERS]; + u64 cpr_fusing_rev; + u64 ldo_enable[MSMFALCON_MMSS_FUSE_CORNERS]; + u64 ldo_cpr_cl_enable; +}; + +/* Fuse combos 0 - 7 map to CPR fusing revision 0 - 7 */ +#define CPR4_MSMFALCON_MMSS_FUSE_COMBO_COUNT 8 + +/* + * MSMFALCON MMSS fuse parameter locations: + * + * Structs are organized with the following dimensions: + * Outer: 0 to 3 for fuse corners from lowest to highest corner + * Inner: large enough to hold the longest set of parameter segments which + * fully defines a fuse parameter, +1 (for NULL termination). + * Each segment corresponds to a contiguous group of bits from a + * single fuse row. These segments are concatentated together in + * order to form the full fuse parameter value. The segments for + * a given parameter may correspond to different fuse rows. + */ +static const struct cpr3_fuse_param +msmfalcon_mmss_init_voltage_param[MSMFALCON_MMSS_FUSE_CORNERS][2] = { + {{65, 39, 43}, {} }, + {{65, 39, 43}, {} }, + {{65, 34, 38}, {} }, + {{65, 34, 38}, {} }, + {{65, 29, 33}, {} }, + {{65, 24, 28}, {} }, +}; + +static const struct cpr3_fuse_param msmfalcon_cpr_fusing_rev_param[] = { + {71, 34, 36}, + {}, +}; + +static const struct cpr3_fuse_param +msmfalcon_mmss_offset_voltage_param[MSMFALCON_MMSS_FUSE_CORNERS][2] = { + {{} }, + {{} }, + {{} }, + {{65, 52, 55}, {} }, + {{65, 48, 51}, {} }, + {{65, 44, 47}, {} }, +}; + +static const struct cpr3_fuse_param +msmfalcon_mmss_ldo_enable_param[MSMFALCON_MMSS_FUSE_CORNERS][2] = { + {{73, 62, 62}, {} }, + {{73, 61, 61}, {} }, + {{73, 60, 60}, {} }, + {{73, 59, 59}, {} }, + {{73, 58, 58}, {} }, + {{73, 57, 57}, {} }, +}; + +static const struct cpr3_fuse_param msmfalcon_ldo_cpr_cl_enable_param[] = { + {71, 38, 38}, + {}, +}; + +/* Additional MSMFALCON specific data: */ + +/* Open loop voltage fuse reference voltages in microvolts */ +static const int msmfalcon_mmss_fuse_ref_volt[MSMFALCON_MMSS_FUSE_CORNERS] = { + 584000, + 644000, + 724000, + 788000, + 868000, + 924000, +}; + +#define MSMFALCON_MMSS_FUSE_STEP_VOLT 10000 +#define MSMFALCON_MMSS_OFFSET_FUSE_STEP_VOLT 10000 +#define MSMFALCON_MMSS_VOLTAGE_FUSE_SIZE 5 + +#define MSMFALCON_MMSS_CPR_SENSOR_COUNT 11 + +#define MSMFALCON_MMSS_CPR_CLOCK_RATE 19200000 + +/** + * cpr4_msmfalcon_mmss_read_fuse_data() - load MMSS specific fuse parameter + * values + * @vreg: Pointer to the CPR3 regulator + * + * This function allocates a cpr4_msmfalcon_mmss_fuses struct, fills it with + * values read out of hardware fuses, and finally copies common fuse values + * into the regulator struct. + * + * Return: 0 on success, errno on failure + */ +static int cpr4_msmfalcon_mmss_read_fuse_data(struct cpr3_regulator *vreg) +{ + void __iomem *base = vreg->thread->ctrl->fuse_base; + struct cpr4_msmfalcon_mmss_fuses *fuse; + int i, rc; + + fuse = devm_kzalloc(vreg->thread->ctrl->dev, sizeof(*fuse), GFP_KERNEL); + if (!fuse) + return -ENOMEM; + + rc = cpr3_read_fuse_param(base, msmfalcon_cpr_fusing_rev_param, + &fuse->cpr_fusing_rev); + if (rc) { + cpr3_err(vreg, "Unable to read CPR fusing revision fuse, rc=%d\n", + rc); + return rc; + } + cpr3_info(vreg, "CPR fusing revision = %llu\n", fuse->cpr_fusing_rev); + + rc = cpr3_read_fuse_param(base, msmfalcon_ldo_cpr_cl_enable_param, + &fuse->ldo_cpr_cl_enable); + if (rc) { + cpr3_err(vreg, "Unable to read ldo cpr closed-loop enable fuse, rc=%d\n", + rc); + return rc; + } + + for (i = 0; i < MSMFALCON_MMSS_FUSE_CORNERS; i++) { + rc = cpr3_read_fuse_param(base, + msmfalcon_mmss_init_voltage_param[i], + &fuse->init_voltage[i]); + if (rc) { + cpr3_err(vreg, "Unable to read fuse-corner %d initial voltage fuse, rc=%d\n", + i, rc); + return rc; + } + + rc = cpr3_read_fuse_param(base, + msmfalcon_mmss_offset_voltage_param[i], + &fuse->offset_voltage[i]); + if (rc) { + cpr3_err(vreg, "Unable to read fuse-corner %d offset voltage fuse, rc=%d\n", + i, rc); + return rc; + } + + rc = cpr3_read_fuse_param(base, + msmfalcon_mmss_ldo_enable_param[i], + &fuse->ldo_enable[i]); + if (rc) { + cpr3_err(vreg, "Unable to read fuse-corner %d ldo enable fuse, rc=%d\n", + i, rc); + return rc; + } + } + + vreg->fuse_combo = fuse->cpr_fusing_rev; + if (vreg->fuse_combo >= CPR4_MSMFALCON_MMSS_FUSE_COMBO_COUNT) { + cpr3_err(vreg, "invalid CPR fuse combo = %d found, not in range 0 - %d\n", + vreg->fuse_combo, + CPR4_MSMFALCON_MMSS_FUSE_COMBO_COUNT - 1); + return -EINVAL; + } + + vreg->cpr_rev_fuse = fuse->cpr_fusing_rev; + vreg->fuse_corner_count = MSMFALCON_MMSS_FUSE_CORNERS; + vreg->platform_fuses = fuse; + + return 0; +} + +/** + * cpr3_msmfalcon_mmss_calculate_open_loop_voltages() - calculate the open-loop + * voltage for each corner of a CPR3 regulator + * @vreg: Pointer to the CPR3 regulator + * + * Return: 0 on success, errno on failure + */ +static int cpr4_msmfalcon_mmss_calculate_open_loop_voltages( + struct cpr3_regulator *vreg) +{ + struct cpr4_msmfalcon_mmss_fuses *fuse = vreg->platform_fuses; + int i, rc = 0; + const int *ref_volt; + int *fuse_volt; + + fuse_volt = kcalloc(vreg->fuse_corner_count, sizeof(*fuse_volt), + GFP_KERNEL); + if (!fuse_volt) + return -ENOMEM; + + ref_volt = msmfalcon_mmss_fuse_ref_volt; + for (i = 0; i < vreg->fuse_corner_count; i++) { + fuse_volt[i] = cpr3_convert_open_loop_voltage_fuse(ref_volt[i], + MSMFALCON_MMSS_FUSE_STEP_VOLT, fuse->init_voltage[i], + MSMFALCON_MMSS_VOLTAGE_FUSE_SIZE); + cpr3_info(vreg, "fuse_corner[%d] open-loop=%7d uV\n", + i, fuse_volt[i]); + } + + rc = cpr3_adjust_fused_open_loop_voltages(vreg, fuse_volt); + if (rc) { + cpr3_err(vreg, "fused open-loop voltage adjustment failed, rc=%d\n", + rc); + goto done; + } + + for (i = 1; i < vreg->fuse_corner_count; i++) { + if (fuse_volt[i] < fuse_volt[i - 1]) { + cpr3_debug(vreg, "fuse corner %d voltage=%d uV < fuse corner %d voltage=%d uV; overriding: fuse corner %d voltage=%d\n", + i, fuse_volt[i], i - 1, fuse_volt[i - 1], + i, fuse_volt[i - 1]); + fuse_volt[i] = fuse_volt[i - 1]; + } + } + + for (i = 0; i < vreg->corner_count; i++) + vreg->corner[i].open_loop_volt + = fuse_volt[vreg->corner[i].cpr_fuse_corner]; + + cpr3_debug(vreg, "unadjusted per-corner open-loop voltages:\n"); + for (i = 0; i < vreg->corner_count; i++) + cpr3_debug(vreg, "open-loop[%2d] = %d uV\n", i, + vreg->corner[i].open_loop_volt); + + rc = cpr3_adjust_open_loop_voltages(vreg); + if (rc) + cpr3_err(vreg, "open-loop voltage adjustment failed, rc=%d\n", + rc); + +done: + kfree(fuse_volt); + return rc; +} + +/** + * cpr4_mmss_parse_ldo_mode_data() - Parse the LDO mode enable state for each + * corner of a CPR3 regulator + * @vreg: Pointer to the CPR3 regulator + * + * This function considers 2 sets of data: one set from device node and other + * set from fuses and applies set intersection to decide the final LDO mode + * enable state of each corner. If the device node configuration is not + * specified, then the function applies LDO mode disable for all corners. + * + * Return: 0 on success, errno on failure + */ +static int cpr4_mmss_parse_ldo_mode_data(struct cpr3_regulator *vreg) +{ + struct cpr4_msmfalcon_mmss_fuses *fuse = vreg->platform_fuses; + int i, rc = 0; + u32 *ldo_allowed; + char *prop_str = "qcom,cpr-corner-allow-ldo-mode"; + + if (!of_find_property(vreg->of_node, prop_str, NULL)) { + cpr3_debug(vreg, "%s property is missing. LDO mode is disabled for all corners\n", + prop_str); + return 0; + } + + ldo_allowed = kcalloc(vreg->corner_count, sizeof(*ldo_allowed), + GFP_KERNEL); + if (!ldo_allowed) + return -ENOMEM; + + rc = cpr3_parse_corner_array_property(vreg, prop_str, 1, ldo_allowed); + if (rc) { + cpr3_err(vreg, "%s read failed, rc=%d\n", prop_str, rc); + goto done; + } + + for (i = 0; i < vreg->corner_count; i++) + vreg->corner[i].ldo_mode_allowed + = (ldo_allowed[i] && fuse->ldo_enable[i]); + +done: + kfree(ldo_allowed); + return rc; +} + +/** + * cpr4_mmss_parse_corner_operating_mode() - Parse the CPR closed-loop operation + * enable state for each corner of a CPR3 regulator + * @vreg: Pointer to the CPR3 regulator + * + * This function ensures that closed-loop operation is enabled only for LDO + * mode allowed corners. + * + * Return: 0 on success, errno on failure + */ +static int cpr4_mmss_parse_corner_operating_mode(struct cpr3_regulator *vreg) +{ + struct cpr4_msmfalcon_mmss_fuses *fuse = vreg->platform_fuses; + int i, rc = 0; + u32 *use_closed_loop; + char *prop_str = "qcom,cpr-corner-allow-closed-loop"; + + if (!of_find_property(vreg->of_node, prop_str, NULL)) { + cpr3_debug(vreg, "%s property is missing. Use open-loop for all corners\n", + prop_str); + for (i = 0; i < vreg->corner_count; i++) + vreg->corner[i].use_open_loop = true; + + return 0; + } + + use_closed_loop = kcalloc(vreg->corner_count, sizeof(*use_closed_loop), + GFP_KERNEL); + if (!use_closed_loop) + return -ENOMEM; + + rc = cpr3_parse_corner_array_property(vreg, prop_str, 1, + use_closed_loop); + if (rc) { + cpr3_err(vreg, "%s read failed, rc=%d\n", prop_str, rc); + goto done; + } + + for (i = 0; i < vreg->corner_count; i++) + vreg->corner[i].use_open_loop + = !(fuse->ldo_cpr_cl_enable && use_closed_loop[i] + && vreg->corner[i].ldo_mode_allowed); + +done: + kfree(use_closed_loop); + return rc; +} + +/** + * cpr4_mmss_parse_corner_data() - parse MMSS corner data from device tree + * properties of the regulator's device node + * @vreg: Pointer to the CPR3 regulator + * + * Return: 0 on success, errno on failure + */ +static int cpr4_mmss_parse_corner_data(struct cpr3_regulator *vreg) +{ + int i, rc; + u32 *temp; + + rc = cpr3_parse_common_corner_data(vreg); + if (rc) { + cpr3_err(vreg, "error reading corner data, rc=%d\n", rc); + return rc; + } + + temp = kcalloc(vreg->corner_count * CPR3_RO_COUNT, sizeof(*temp), + GFP_KERNEL); + if (!temp) + return -ENOMEM; + + rc = cpr3_parse_corner_array_property(vreg, "qcom,cpr-target-quotients", + CPR3_RO_COUNT, temp); + if (rc) { + cpr3_err(vreg, "could not load target quotients, rc=%d\n", rc); + goto done; + } + + for (i = 0; i < vreg->corner_count; i++) + memcpy(vreg->corner[i].target_quot, &temp[i * CPR3_RO_COUNT], + sizeof(*temp) * CPR3_RO_COUNT); + +done: + kfree(temp); + return rc; +} + +/** + * cpr4_mmss_print_settings() - print out MMSS CPR configuration settings into + * the kernel log for debugging purposes + * @vreg: Pointer to the CPR3 regulator + */ +static void cpr4_mmss_print_settings(struct cpr3_regulator *vreg) +{ + struct cpr3_corner *corner; + int i; + + cpr3_debug(vreg, "Corner: Frequency (Hz), Fuse Corner, Floor (uV), Open-Loop (uV), Ceiling (uV)\n"); + for (i = 0; i < vreg->corner_count; i++) { + corner = &vreg->corner[i]; + cpr3_debug(vreg, "%3d: %10u, %2d, %7d, %7d, %7d\n", + i, corner->proc_freq, corner->cpr_fuse_corner, + corner->floor_volt, corner->open_loop_volt, + corner->ceiling_volt); + } +} + +/** + * cpr4_mmss_init_thread() - perform all steps necessary to initialize the + * configuration data for a CPR3 thread + * @thread: Pointer to the CPR3 thread + * + * Return: 0 on success, errno on failure + */ +static int cpr4_mmss_init_thread(struct cpr3_thread *thread) +{ + struct cpr3_controller *ctrl = thread->ctrl; + struct cpr3_regulator *vreg = &thread->vreg[0]; + int rc; + + rc = cpr3_parse_common_thread_data(thread); + if (rc) { + cpr3_err(vreg, "unable to read CPR thread data from device tree, rc=%d\n", + rc); + return rc; + } + + if (!of_find_property(ctrl->dev->of_node, "vdd-thread0-ldo-supply", + NULL)) { + cpr3_err(vreg, "ldo supply regulator is not specified\n"); + return -EINVAL; + } + + vreg->ldo_regulator = devm_regulator_get(ctrl->dev, "vdd-thread0-ldo"); + if (IS_ERR(vreg->ldo_regulator)) { + rc = PTR_ERR(vreg->ldo_regulator); + if (rc != -EPROBE_DEFER) + cpr3_err(vreg, "unable to request vdd-thread0-ldo regulator, rc=%d\n", + rc); + return rc; + } + + vreg->ldo_mode_allowed = !of_property_read_bool(vreg->of_node, + "qcom,ldo-disable"); + vreg->ldo_regulator_bypass = BHS_MODE; + vreg->ldo_type = CPR3_LDO300; + + rc = cpr4_msmfalcon_mmss_read_fuse_data(vreg); + if (rc) { + cpr3_err(vreg, "unable to read CPR fuse data, rc=%d\n", rc); + return rc; + } + + rc = cpr4_mmss_parse_corner_data(vreg); + if (rc) { + cpr3_err(vreg, "unable to read CPR corner data from device tree, rc=%d\n", + rc); + return rc; + } + + rc = cpr4_msmfalcon_mmss_calculate_open_loop_voltages(vreg); + if (rc) { + cpr3_err(vreg, "unable to calculate open-loop voltages, rc=%d\n", + rc); + return rc; + } + + rc = cpr3_limit_open_loop_voltages(vreg); + if (rc) { + cpr3_err(vreg, "unable to limit open-loop voltages, rc=%d\n", + rc); + return rc; + } + + cpr3_open_loop_voltage_as_ceiling(vreg); + + rc = cpr3_limit_floor_voltages(vreg); + if (rc) { + cpr3_err(vreg, "unable to limit floor voltages, rc=%d\n", rc); + return rc; + } + + rc = cpr4_mmss_parse_ldo_mode_data(vreg); + if (rc) { + cpr3_err(vreg, "unable to parse ldo mode data, rc=%d\n", rc); + return rc; + } + + rc = cpr4_mmss_parse_corner_operating_mode(vreg); + if (rc) { + cpr3_err(vreg, "unable to parse closed-loop operating mode data, rc=%d\n", + rc); + return rc; + } + + cpr4_mmss_print_settings(vreg); + + return 0; +} + +/** + * cpr4_mmss_init_controller() - perform MMSS CPR4 controller specific + * initializations + * @ctrl: Pointer to the CPR3 controller + * + * Return: 0 on success, errno on failure + */ +static int cpr4_mmss_init_controller(struct cpr3_controller *ctrl) +{ + int rc; + + rc = cpr3_parse_common_ctrl_data(ctrl); + if (rc) { + if (rc != -EPROBE_DEFER) + cpr3_err(ctrl, "unable to parse common controller data, rc=%d\n", + rc); + return rc; + } + + ctrl->sensor_count = MSMFALCON_MMSS_CPR_SENSOR_COUNT; + + /* + * MMSS only has one thread (0) so the zeroed array does not need + * further modification. + */ + ctrl->sensor_owner = devm_kcalloc(ctrl->dev, ctrl->sensor_count, + sizeof(*ctrl->sensor_owner), GFP_KERNEL); + if (!ctrl->sensor_owner) + return -ENOMEM; + + ctrl->cpr_clock_rate = MSMFALCON_MMSS_CPR_CLOCK_RATE; + ctrl->ctrl_type = CPR_CTRL_TYPE_CPR4; + ctrl->support_ldo300_vreg = true; + + /* + * Use fixed step quotient if specified otherwise use dynamic + * calculated per RO step quotient + */ + of_property_read_u32(ctrl->dev->of_node, + "qcom,cpr-step-quot-fixed", + &ctrl->step_quot_fixed); + ctrl->use_dynamic_step_quot = !ctrl->step_quot_fixed; + + /* iface_clk is optional for msmfalcon */ + ctrl->iface_clk = NULL; + ctrl->bus_clk = devm_clk_get(ctrl->dev, "bus_clk"); + if (IS_ERR(ctrl->bus_clk)) { + rc = PTR_ERR(ctrl->bus_clk); + if (rc != -EPROBE_DEFER) + cpr3_err(ctrl, "unable request bus clock, rc=%d\n", + rc); + return rc; + } + + return 0; +} + +static int cpr4_mmss_regulator_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct cpr3_controller *ctrl; + int rc; + + if (!dev->of_node) { + dev_err(dev, "Device tree node is missing\n"); + return -EINVAL; + } + + ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL); + if (!ctrl) + return -ENOMEM; + + ctrl->dev = dev; + /* Set to false later if anything precludes CPR operation. */ + ctrl->cpr_allowed_hw = true; + + rc = of_property_read_string(dev->of_node, "qcom,cpr-ctrl-name", + &ctrl->name); + if (rc) { + cpr3_err(ctrl, "unable to read qcom,cpr-ctrl-name, rc=%d\n", + rc); + return rc; + } + + rc = cpr3_map_fuse_base(ctrl, pdev); + if (rc) { + cpr3_err(ctrl, "could not map fuse base address\n"); + return rc; + } + + rc = cpr3_allocate_threads(ctrl, 0, 0); + if (rc) { + cpr3_err(ctrl, "failed to allocate CPR thread array, rc=%d\n", + rc); + return rc; + } + + if (ctrl->thread_count != 1) { + cpr3_err(ctrl, "expected 1 thread but found %d\n", + ctrl->thread_count); + return -EINVAL; + } else if (ctrl->thread[0].vreg_count != 1) { + cpr3_err(ctrl, "expected 1 regulator but found %d\n", + ctrl->thread[0].vreg_count); + return -EINVAL; + } + + rc = cpr4_mmss_init_controller(ctrl); + if (rc) { + if (rc != -EPROBE_DEFER) + cpr3_err(ctrl, "failed to initialize CPR controller parameters, rc=%d\n", + rc); + return rc; + } + + rc = cpr4_mmss_init_thread(&ctrl->thread[0]); + if (rc) { + cpr3_err(&ctrl->thread[0].vreg[0], "thread initialization failed, rc=%d\n", + rc); + return rc; + } + + rc = cpr3_mem_acc_init(&ctrl->thread[0].vreg[0]); + if (rc) { + cpr3_err(ctrl, "failed to initialize mem-acc configuration, rc=%d\n", + rc); + return rc; + } + + platform_set_drvdata(pdev, ctrl); + + return cpr3_regulator_register(pdev, ctrl); +} + +static int cpr4_mmss_regulator_remove(struct platform_device *pdev) +{ + struct cpr3_controller *ctrl = platform_get_drvdata(pdev); + + return cpr3_regulator_unregister(ctrl); +} + +static int cpr4_mmss_regulator_suspend(struct platform_device *pdev, + pm_message_t state) +{ + struct cpr3_controller *ctrl = platform_get_drvdata(pdev); + + return cpr3_regulator_suspend(ctrl); +} + +static int cpr4_mmss_regulator_resume(struct platform_device *pdev) +{ + struct cpr3_controller *ctrl = platform_get_drvdata(pdev); + + return cpr3_regulator_resume(ctrl); +} + +/* Data corresponds to the SoC revision */ +static const struct of_device_id cpr4_mmss_regulator_match_table[] = { + { + .compatible = "qcom,cpr4-msmfalcon-mmss-ldo-regulator", + .data = (void *)NULL, + }, +}; + +static struct platform_driver cpr4_mmss_regulator_driver = { + .driver = { + .name = "qcom,cpr4-mmss-ldo-regulator", + .of_match_table = cpr4_mmss_regulator_match_table, + .owner = THIS_MODULE, + }, + .probe = cpr4_mmss_regulator_probe, + .remove = cpr4_mmss_regulator_remove, + .suspend = cpr4_mmss_regulator_suspend, + .resume = cpr4_mmss_regulator_resume, +}; + +static int cpr_regulator_init(void) +{ + return platform_driver_register(&cpr4_mmss_regulator_driver); +} + +static void cpr_regulator_exit(void) +{ + platform_driver_unregister(&cpr4_mmss_regulator_driver); +} + +MODULE_DESCRIPTION("CPR4 MMSS LDO regulator driver"); +MODULE_LICENSE("GPL v2"); + +arch_initcall(cpr_regulator_init); +module_exit(cpr_regulator_exit); diff --git a/drivers/soc/qcom/avtimer.c b/drivers/soc/qcom/avtimer.c index 2bded5e83cce..4331af8890c0 100644 --- a/drivers/soc/qcom/avtimer.c +++ b/drivers/soc/qcom/avtimer.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -331,9 +331,17 @@ static long avtimer_ioctl(struct file *file, unsigned int ioctl_num, switch (ioctl_num) { case IOCTL_GET_AVTIMER_TICK: { - uint64_t avtimer_tick; + uint64_t avtimer_tick = 0; + int rc; + + rc = avcs_core_query_timer(&avtimer_tick); + + if (rc) { + pr_err("%s: Error: Invalid AV Timer tick, rc = %d\n", + __func__, rc); + return rc; + } - avcs_core_query_timer(&avtimer_tick); pr_debug_ratelimited("%s: AV Timer tick: time %llx\n", __func__, avtimer_tick); if (copy_to_user((void *) ioctl_param, &avtimer_tick, diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c index 49510bfd6b24..c3792d5a72ac 100644 --- a/drivers/soc/qcom/icnss.c +++ b/drivers/soc/qcom/icnss.c @@ -781,7 +781,7 @@ static int icnss_unmap_msa_permissions(struct icnss_priv *priv, u32 index) u32 size; u32 dest_vmids[1] = {VMID_HLOS}; int source_vmlist[3] = {VMID_MSS_MSA, VMID_WLAN, 0}; - int dest_perms[1] = {PERM_READ|PERM_WRITE}; + int dest_perms[1] = {PERM_READ|PERM_WRITE|PERM_EXEC}; int source_nelems = 0; int dest_nelems = sizeof(dest_vmids)/sizeof(u32); diff --git a/drivers/soc/qcom/smcinvoke.c b/drivers/soc/qcom/smcinvoke.c index d4be8c641ad8..e920dfee8530 100644 --- a/drivers/soc/qcom/smcinvoke.c +++ b/drivers/soc/qcom/smcinvoke.c @@ -22,6 +22,8 @@ #include #include #include "smcinvoke_object.h" +#include +#include "../../misc/qseecom_kernel.h" #define SMCINVOKE_TZ_PARAM_ID 0x224 #define SMCINVOKE_TZ_CMD 0x32000600 @@ -198,6 +200,12 @@ static int prepare_send_scm_msg(const uint8_t *in_buf, size_t in_buf_len, dmac_flush_range(out_buf, out_buf + outbuf_flush_size); ret = scm_call2(SMCINVOKE_TZ_CMD, &desc); + + /* process listener request */ + if (!ret && (desc.ret[0] == QSEOS_RESULT_INCOMPLETE || + desc.ret[0] == QSEOS_RESULT_BLOCKED_ON_LISTENER)) + ret = qseecom_process_listener_from_smcinvoke(&desc); + *smcinvoke_result = (int32_t)desc.ret[1]; if (ret || desc.ret[1] || desc.ret[2] || desc.ret[0]) { pr_err("SCM call failed with ret val = %d %d %d %d\n", diff --git a/drivers/soc/qcom/spcom.c b/drivers/soc/qcom/spcom.c index 5b3e6c36810e..e8ea99827403 100644 --- a/drivers/soc/qcom/spcom.c +++ b/drivers/soc/qcom/spcom.c @@ -272,6 +272,8 @@ static struct spcom_device *spcom_dev; static int spcom_create_channel_chardev(const char *name); static int spcom_open(struct spcom_channel *ch, unsigned int timeout_msec); static int spcom_close(struct spcom_channel *ch); +static void spcom_notify_rx_abort(void *handle, const void *priv, + const void *pkt_priv); /** * spcom_is_ready() - driver is initialized and ready. @@ -467,6 +469,13 @@ static void spcom_notify_state(void *handle, const void *priv, unsigned event) * This may happen upon remote SSR. */ pr_err("GLINK_REMOTE_DISCONNECTED, ch [%s].\n", ch->name); + + /* + * Abort any blocking read() operation. + * The glink notification might be after REMOTE_DISCONNECT. + */ + spcom_notify_rx_abort(NULL, ch, NULL); + /* * after glink_close(), * expecting notify GLINK_LOCAL_DISCONNECTED @@ -515,7 +524,7 @@ static void spcom_notify_rx_abort(void *handle, const void *priv, pr_debug("ch [%s] pending rx aborted.\n", ch->name); - if (spcom_is_channel_connected(ch)) { + if (spcom_is_channel_connected(ch) && (!ch->rx_abort)) { ch->rx_abort = true; complete_all(&ch->rx_done); } @@ -535,9 +544,9 @@ static void spcom_notify_tx_abort(void *handle, const void *priv, pr_debug("ch [%s] pending tx aborted.\n", ch->name); - if (spcom_is_channel_connected(ch)) { - complete_all(&ch->tx_done); + if (spcom_is_channel_connected(ch) && (!ch->tx_abort)) { ch->tx_abort = true; + complete_all(&ch->tx_done); } } diff --git a/drivers/spi/spi_qsd.c b/drivers/spi/spi_qsd.c index a5d59e7f2d90..7aa04a4fa156 100644 --- a/drivers/spi/spi_qsd.c +++ b/drivers/spi/spi_qsd.c @@ -1830,15 +1830,15 @@ err_setup_exit: static int debugfs_iomem_x32_set(void *data, u64 val) { - struct msm_spi_regs *debugfs_spi_regs = (struct msm_spi_regs *)data; - struct msm_spi *dd = debugfs_spi_regs->dd; + struct msm_spi_debugfs_data *reg = (struct msm_spi_debugfs_data *)data; + struct msm_spi *dd = reg->dd; int ret; ret = pm_runtime_get_sync(dd->dev); if (ret < 0) return ret; - writel_relaxed(val, (dd->base + debugfs_spi_regs->offset)); + writel_relaxed(val, (dd->base + reg->offset)); /* Ensure the previous write completed. */ mb(); @@ -1849,14 +1849,14 @@ static int debugfs_iomem_x32_set(void *data, u64 val) static int debugfs_iomem_x32_get(void *data, u64 *val) { - struct msm_spi_regs *debugfs_spi_regs = (struct msm_spi_regs *)data; - struct msm_spi *dd = debugfs_spi_regs->dd; + struct msm_spi_debugfs_data *reg = (struct msm_spi_debugfs_data *)data; + struct msm_spi *dd = reg->dd; int ret; ret = pm_runtime_get_sync(dd->dev); if (ret < 0) return ret; - *val = readl_relaxed(dd->base + debugfs_spi_regs->offset); + *val = readl_relaxed(dd->base + reg->offset); /* Ensure the previous read completed. */ mb(); @@ -1870,18 +1870,21 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_iomem_x32, debugfs_iomem_x32_get, static void spi_debugfs_init(struct msm_spi *dd) { - dd->dent_spi = debugfs_create_dir(dev_name(dd->dev), NULL); + char dir_name[20]; + + scnprintf(dir_name, sizeof(dir_name), "%s_dbg", dev_name(dd->dev)); + dd->dent_spi = debugfs_create_dir(dir_name, NULL); if (dd->dent_spi) { int i; for (i = 0; i < ARRAY_SIZE(debugfs_spi_regs); i++) { - debugfs_spi_regs[i].dd = dd; + dd->reg_data[i].offset = debugfs_spi_regs[i].offset; + dd->reg_data[i].dd = dd; dd->debugfs_spi_regs[i] = debugfs_create_file( debugfs_spi_regs[i].name, debugfs_spi_regs[i].mode, - dd->dent_spi, - debugfs_spi_regs+i, + dd->dent_spi, &dd->reg_data[i], &fops_iomem_x32); } } diff --git a/drivers/spi/spi_qsd.h b/drivers/spi/spi_qsd.h index fb906939c03a..e8e6cdce1a02 100644 --- a/drivers/spi/spi_qsd.h +++ b/drivers/spi/spi_qsd.h @@ -214,52 +214,48 @@ struct spi_cs_gpio { }; #ifdef CONFIG_DEBUG_FS +struct msm_spi_debugfs_data { + int offset; + struct msm_spi *dd; +}; /* Used to create debugfs entries */ static struct msm_spi_regs{ const char *name; mode_t mode; int offset; - struct msm_spi *dd; } debugfs_spi_regs[] = { - {"config", S_IRUGO | S_IWUSR, SPI_CONFIG, NULL}, - {"io_control", S_IRUGO | S_IWUSR, SPI_IO_CONTROL, NULL}, - {"io_modes", S_IRUGO | S_IWUSR, SPI_IO_MODES, NULL}, - {"sw_reset", S_IWUSR, SPI_SW_RESET, NULL}, - {"time_out_current", S_IRUGO, SPI_TIME_OUT_CURRENT, - NULL}, - {"mx_output_count", S_IRUGO | S_IWUSR, SPI_MX_OUTPUT_COUNT, - NULL}, - {"mx_output_cnt_current", S_IRUGO, SPI_MX_OUTPUT_CNT_CURRENT, - NULL}, - {"mx_input_count", S_IRUGO | S_IWUSR, SPI_MX_INPUT_COUNT, NULL}, - {"mx_input_cnt_current", S_IRUGO, SPI_MX_INPUT_CNT_CURRENT, - NULL}, - {"mx_read_count", S_IRUGO | S_IWUSR, SPI_MX_READ_COUNT, NULL}, - {"mx_read_cnt_current", S_IRUGO, SPI_MX_READ_CNT_CURRENT, - NULL}, - {"operational", S_IRUGO | S_IWUSR, SPI_OPERATIONAL, NULL}, - {"error_flags", S_IRUGO | S_IWUSR, SPI_ERROR_FLAGS, NULL}, - {"error_flags_en", S_IRUGO | S_IWUSR, SPI_ERROR_FLAGS_EN, NULL}, - {"deassert_wait", S_IRUGO | S_IWUSR, SPI_DEASSERT_WAIT, NULL}, - {"output_debug", S_IRUGO, SPI_OUTPUT_DEBUG, NULL}, - {"input_debug", S_IRUGO, SPI_INPUT_DEBUG, NULL}, - {"test_ctrl", S_IRUGO | S_IWUSR, SPI_TEST_CTRL, NULL}, - {"output_fifo", S_IWUSR, SPI_OUTPUT_FIFO, NULL}, - {"input_fifo" , S_IRUSR, SPI_INPUT_FIFO, NULL}, - {"spi_state", S_IRUGO | S_IWUSR, SPI_STATE, NULL}, + {"config", S_IRUGO | S_IWUSR, SPI_CONFIG }, + {"io_control", S_IRUGO | S_IWUSR, SPI_IO_CONTROL }, + {"io_modes", S_IRUGO | S_IWUSR, SPI_IO_MODES }, + {"sw_reset", S_IWUSR, SPI_SW_RESET }, + {"time_out_current", S_IRUGO, SPI_TIME_OUT_CURRENT }, + {"mx_output_count", S_IRUGO | S_IWUSR, SPI_MX_OUTPUT_COUNT }, + {"mx_output_cnt_current", S_IRUGO, + SPI_MX_OUTPUT_CNT_CURRENT }, + {"mx_input_count", S_IRUGO | S_IWUSR, SPI_MX_INPUT_COUNT }, + {"mx_input_cnt_current", S_IRUGO, SPI_MX_INPUT_CNT_CURRENT }, + {"mx_read_count", S_IRUGO | S_IWUSR, SPI_MX_READ_COUNT, }, + {"mx_read_cnt_current", S_IRUGO, SPI_MX_READ_CNT_CURRENT }, + {"operational", S_IRUGO | S_IWUSR, SPI_OPERATIONAL }, + {"error_flags", S_IRUGO | S_IWUSR, SPI_ERROR_FLAGS }, + {"error_flags_en", S_IRUGO | S_IWUSR, SPI_ERROR_FLAGS_EN }, + {"deassert_wait", S_IRUGO | S_IWUSR, SPI_DEASSERT_WAIT }, + {"output_debug", S_IRUGO, SPI_OUTPUT_DEBUG }, + {"input_debug", S_IRUGO, SPI_INPUT_DEBUG }, + {"test_ctrl", S_IRUGO | S_IWUSR, SPI_TEST_CTRL }, + {"output_fifo", S_IWUSR, SPI_OUTPUT_FIFO }, + {"input_fifo", S_IRUSR, SPI_INPUT_FIFO }, + {"spi_state", S_IRUGO | S_IWUSR, SPI_STATE }, #if defined(CONFIG_SPI_QSD) || defined(CONFIG_SPI_QSD_MODULE) - {"fifo_word_cnt", S_IRUGO, SPI_FIFO_WORD_CNT, NULL}, + {"fifo_word_cnt", S_IRUGO, SPI_FIFO_WORD_CNT }, #else - {"qup_config", S_IRUGO | S_IWUSR, QUP_CONFIG, NULL}, - {"qup_error_flags", S_IRUGO | S_IWUSR, QUP_ERROR_FLAGS, NULL}, - {"qup_error_flags_en", S_IRUGO | S_IWUSR, QUP_ERROR_FLAGS_EN, NULL}, - {"mx_write_cnt", S_IRUGO | S_IWUSR, QUP_MX_WRITE_COUNT, NULL}, - {"mx_write_cnt_current", S_IRUGO, QUP_MX_WRITE_CNT_CURRENT, - NULL}, - {"output_fifo_word_cnt", S_IRUGO, SPI_OUTPUT_FIFO_WORD_CNT, - NULL}, - {"input_fifo_word_cnt", S_IRUGO, SPI_INPUT_FIFO_WORD_CNT, - NULL}, + {"qup_config", S_IRUGO | S_IWUSR, QUP_CONFIG }, + {"qup_error_flags", S_IRUGO | S_IWUSR, QUP_ERROR_FLAGS }, + {"qup_error_flags_en", S_IRUGO | S_IWUSR, QUP_ERROR_FLAGS_EN }, + {"mx_write_cnt", S_IRUGO | S_IWUSR, QUP_MX_WRITE_COUNT }, + {"mx_write_cnt_current", S_IRUGO, QUP_MX_WRITE_CNT_CURRENT }, + {"output_fifo_word_cnt", S_IRUGO, SPI_OUTPUT_FIFO_WORD_CNT }, + {"input_fifo_word_cnt", S_IRUGO, SPI_INPUT_FIFO_WORD_CNT }, #endif }; #endif @@ -349,6 +345,7 @@ struct msm_spi { #ifdef CONFIG_DEBUG_FS struct dentry *dent_spi; struct dentry *debugfs_spi_regs[ARRAY_SIZE(debugfs_spi_regs)]; + struct msm_spi_debugfs_data reg_data[ARRAY_SIZE(debugfs_spi_regs)]; #endif struct msm_spi_platform_data *pdata; /* Platform data */ /* When set indicates multiple transfers in a single message */ @@ -515,10 +512,7 @@ static inline int msm_spi_prepare_for_write(struct msm_spi *dd) static inline void msm_spi_start_write(struct msm_spi *dd, u32 read_count) { - if (read_count <= dd->input_fifo_size) - msm_spi_write_rmn_to_fifo(dd); - else - msm_spi_write_word_to_fifo(dd); + msm_spi_write_rmn_to_fifo(dd); } static inline void msm_spi_set_write_count(struct msm_spi *dd, int val) diff --git a/drivers/thermal/msm_thermal.c b/drivers/thermal/msm_thermal.c index 7158fb1239df..f685892edd39 100644 --- a/drivers/thermal/msm_thermal.c +++ b/drivers/thermal/msm_thermal.c @@ -2931,7 +2931,7 @@ static void __ref do_core_control(int temp) cpu_dev = get_cpu_device(i); trace_thermal_pre_core_offline(i); ret = device_offline(cpu_dev); - if (ret) + if (ret < 0) pr_err("Error %d offline core %d\n", ret, i); trace_thermal_post_core_offline(i, @@ -3004,7 +3004,8 @@ static int __ref update_offline_cores(int val) cpu_dev = get_cpu_device(cpu); trace_thermal_pre_core_offline(cpu); ret = device_offline(cpu_dev); - if (ret) { + if (ret < 0) { + cpus_offlined &= ~BIT(cpu); pr_err_ratelimited( "Unable to offline CPU%d. err:%d\n", cpu, ret); @@ -3074,6 +3075,14 @@ static __ref int do_hotplug(void *data) &hotplug_notify_complete) != 0) ; reinit_completion(&hotplug_notify_complete); + + /* + * Suspend framework will have disabled the + * hotplug functionality. So wait till the suspend exits + * and then re-evaluate. + */ + if (in_suspend) + continue; mask = 0; mutex_lock(&core_control_mutex); diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 9d9eed2d5d68..b826f926b205 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -325,7 +325,7 @@ config USB_CONFIGFS_ECM_SUBSET a simple CDC subset is used, placing fewer demands on USB. config USB_CONFIGFS_QCRNDIS - bool "RNDIS" + bool "QCRNDIS" depends on USB_CONFIGFS depends on RNDIS_IPA depends on NET diff --git a/drivers/usb/gadget/function/f_qc_rndis.c b/drivers/usb/gadget/function/f_qc_rndis.c index ede1c8dd51a6..5ebac7ece209 100644 --- a/drivers/usb/gadget/function/f_qc_rndis.c +++ b/drivers/usb/gadget/function/f_qc_rndis.c @@ -1347,19 +1347,16 @@ static struct miscdevice rndis_qc_device = { static void qcrndis_free_inst(struct usb_function_instance *f) { - struct f_rndis_qc *rndis; struct f_rndis_qc_opts *opts = container_of(f, struct f_rndis_qc_opts, func_inst); unsigned long flags; - rndis = opts->rndis; misc_deregister(&rndis_qc_device); ipa_data_free(USB_IPA_FUNC_RNDIS); spin_lock_irqsave(&rndis_lock, flags); - kfree(rndis); - _rndis_qc = NULL; kfree(opts->rndis); + _rndis_qc = NULL; kfree(opts); spin_unlock_irqrestore(&rndis_lock, flags); } @@ -1441,13 +1438,6 @@ static struct usb_function_instance *qcrndis_alloc_inst(void) return &opts->func_inst; } -static void rndis_qc_cleanup(void) -{ - pr_info("rndis QC cleanup\n"); - - misc_deregister(&rndis_qc_device); -} - void *rndis_qc_get_ipa_rx_cb(void) { return rndis_ipa_params.ipa_rx_notify; @@ -1485,7 +1475,6 @@ static int __init usb_qcrndis_init(void) static void __exit usb_qcrndis_exit(void) { usb_function_unregister(&rndis_bamusb_func); - rndis_qc_cleanup(); } module_init(usb_qcrndis_init); diff --git a/drivers/usb/gadget/function/u_data_ipa.c b/drivers/usb/gadget/function/u_data_ipa.c index 1683a9fea09a..2d0cd30c0641 100644 --- a/drivers/usb/gadget/function/u_data_ipa.c +++ b/drivers/usb/gadget/function/u_data_ipa.c @@ -396,7 +396,7 @@ static void ipa_data_connect_work(struct work_struct *w) unsigned long flags; bool is_ipa_disconnected = true; - pr_debug("%s: Connect workqueue started", __func__); + pr_debug("%s: Connect workqueue started\n", __func__); spin_lock_irqsave(&port->port_lock, flags); @@ -446,8 +446,14 @@ static void ipa_data_connect_work(struct work_struct *w) spin_unlock_irqrestore(&port->port_lock, flags); usb_bam_alloc_fifos(port->usb_bam_type, port->src_connection_idx); - spin_lock_irqsave(&port->port_lock, flags); + if (!port->port_usb || port->rx_req == NULL) { + spin_unlock_irqrestore(&port->port_lock, flags); + pr_err("%s: port_usb is NULL, or rx_req cleaned\n", + __func__); + goto out; + } + sps_params = MSM_SPS_MODE | MSM_DISABLE_WB | MSM_PRODUCER | port->src_pipe_idx; port->rx_req->length = 32*1024; @@ -459,8 +465,6 @@ static void ipa_data_connect_work(struct work_struct *w) if (ret) { pr_err("msm_ep_config() failed for OUT EP\n"); spin_unlock_irqrestore(&port->port_lock, flags); - usb_bam_free_fifos(port->usb_bam_type, - port->src_connection_idx); goto out; } } @@ -470,6 +474,12 @@ static void ipa_data_connect_work(struct work_struct *w) usb_bam_alloc_fifos(port->usb_bam_type, port->dst_connection_idx); spin_lock_irqsave(&port->port_lock, flags); + if (!port->port_usb || port->tx_req == NULL) { + spin_unlock_irqrestore(&port->port_lock, flags); + pr_err("%s: port_usb is NULL, or tx_req cleaned\n", + __func__); + goto unconfig_msm_ep_out; + } sps_params = MSM_SPS_MODE | MSM_DISABLE_WB | port->dst_pipe_idx; port->tx_req->length = 32*1024; @@ -538,6 +548,7 @@ static void ipa_data_connect_work(struct work_struct *w) spin_unlock_irqrestore(&port->port_lock, flags); goto disconnect_usb_bam_ipa_out; } + gport->ipa_consumer_ep = port->ipa_params.ipa_cons_ep_idx; } @@ -572,6 +583,7 @@ static void ipa_data_connect_work(struct work_struct *w) goto disconnect_usb_bam_ipa_out; } spin_lock_irqsave(&port->port_lock, flags); + is_ipa_disconnected = false; /* check if USB cable is disconnected or not */ if (!port->port_usb) { pr_debug("%s:%d: cable is disconnected.\n", @@ -581,7 +593,6 @@ static void ipa_data_connect_work(struct work_struct *w) } gport->ipa_producer_ep = port->ipa_params.ipa_prod_ep_idx; - is_ipa_disconnected = false; } spin_unlock_irqrestore(&port->port_lock, flags); @@ -612,7 +623,8 @@ static void ipa_data_connect_work(struct work_struct *w) return; } atomic_set(&port->pipe_connect_notified, 1); - } else { + } else if (port->func_type == USB_IPA_FUNC_RMNET || + port->func_type == USB_IPA_FUNC_DPL) { /* For RmNet and DPL need to update_ipa_pipes to qti */ enum qti_port_type qti_port_type = port->func_type == USB_IPA_FUNC_RMNET ? QTI_PORT_RMNET : QTI_PORT_DPL; @@ -675,13 +687,13 @@ unconfig_msm_ep_out: port->dst_connection_idx); spin_lock_irqsave(&port->port_lock, flags); /* check if USB cable is disconnected or not */ - if (port->port_usb && gport->out) { + if (port->port_usb && gport->out) msm_ep_unconfig(port->port_usb->out); - usb_bam_free_fifos(port->usb_bam_type, - port->src_connection_idx); - } spin_unlock_irqrestore(&port->port_lock, flags); out: + if (gport->out) + usb_bam_free_fifos(port->usb_bam_type, + port->src_connection_idx); spin_lock_irqsave(&port->port_lock, flags); port->is_connected = false; spin_unlock_irqrestore(&port->port_lock, flags); diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 5ff3f39af38d..163de4bde2d8 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -20,7 +20,7 @@ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - +#include #include #include @@ -874,6 +874,151 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd, return status; } +static void xhci_single_step_completion(struct urb *urb) +{ + struct completion *done = urb->context; + + complete(done); +} + +/* + * Allocate a URB and initialize the various fields of it. + * This API is used by the single_step_set_feature test of + * EHSET where IN packet of the GetDescriptor request is + * sent 15secs after the SETUP packet. + * Return NULL if failed. + */ +static struct urb *xhci_request_single_step_set_feature_urb( + struct usb_device *udev, + void *dr, + void *buf, + struct completion *done) +{ + struct urb *urb; + struct usb_hcd *hcd = bus_to_hcd(udev->bus); + struct usb_host_endpoint *ep; + + urb = usb_alloc_urb(0, GFP_KERNEL); + if (!urb) + return NULL; + + urb->pipe = usb_rcvctrlpipe(udev, 0); + ep = udev->ep_in[usb_pipeendpoint(urb->pipe)]; + if (!ep) { + usb_free_urb(urb); + return NULL; + } + + /* + * Initialize the various URB fields as these are used by the HCD + * driver to queue it and as well as when completion happens. + */ + urb->ep = ep; + urb->dev = udev; + urb->setup_packet = dr; + urb->transfer_buffer = buf; + urb->transfer_buffer_length = USB_DT_DEVICE_SIZE; + urb->complete = xhci_single_step_completion; + urb->status = -EINPROGRESS; + urb->actual_length = 0; + urb->transfer_flags = URB_DIR_IN; + usb_get_urb(urb); + atomic_inc(&urb->use_count); + atomic_inc(&urb->dev->urbnum); + usb_hcd_map_urb_for_dma(hcd, urb, GFP_KERNEL); + urb->context = done; + return urb; +} + +/* + * This function implements the USB_PORT_FEAT_TEST handling of the + * SINGLE_STEP_SET_FEATURE test mode as defined in the Embedded + * High-Speed Electrical Test (EHSET) specification. This simply + * issues a GetDescriptor control transfer, with an inserted 15-second + * delay after the end of the SETUP stage and before the IN token of + * the DATA stage is set. The idea is that this gives the test operator + * enough time to configure the oscilloscope to perform a measurement + * of the response time between the DATA and ACK packets that follow. + */ +static int xhci_ehset_single_step_set_feature(struct usb_hcd *hcd, int port) +{ + int retval; + struct usb_ctrlrequest *dr; + struct urb *urb; + struct usb_device *udev; + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct usb_device_descriptor *buf; + unsigned long flags; + DECLARE_COMPLETION_ONSTACK(done); + + /* Obtain udev of the rhub's child port */ + udev = usb_hub_find_child(hcd->self.root_hub, port); + if (!udev) { + xhci_err(xhci, "No device attached to the RootHub\n"); + return -ENODEV; + } + buf = kmalloc(USB_DT_DEVICE_SIZE, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); + if (!dr) { + kfree(buf); + return -ENOMEM; + } + + /* Fill Setup packet for GetDescriptor */ + dr->bRequestType = USB_DIR_IN; + dr->bRequest = USB_REQ_GET_DESCRIPTOR; + dr->wValue = cpu_to_le16(USB_DT_DEVICE << 8); + dr->wIndex = 0; + dr->wLength = cpu_to_le16(USB_DT_DEVICE_SIZE); + urb = xhci_request_single_step_set_feature_urb(udev, dr, buf, &done); + if (!urb) { + retval = -ENOMEM; + goto cleanup; + } + + /* Now complete just the SETUP stage */ + spin_lock_irqsave(&xhci->lock, flags); + retval = xhci_submit_single_step_set_feature(hcd, urb, 1); + spin_unlock_irqrestore(&xhci->lock, flags); + if (retval) + goto out1; + + if (!wait_for_completion_timeout(&done, msecs_to_jiffies(2000))) { + usb_kill_urb(urb); + retval = -ETIMEDOUT; + xhci_err(xhci, "%s SETUP stage timed out on ep0\n", __func__); + goto out1; + } + + /* Sleep for 15 seconds; HC will send SOFs during this period */ + msleep(15 * 1000); + + /* Complete remaining DATA and status stages. Re-use same URB */ + urb->status = -EINPROGRESS; + usb_get_urb(urb); + atomic_inc(&urb->use_count); + atomic_inc(&urb->dev->urbnum); + + spin_lock_irqsave(&xhci->lock, flags); + retval = xhci_submit_single_step_set_feature(hcd, urb, 0); + spin_unlock_irqrestore(&xhci->lock, flags); + if (!retval && !wait_for_completion_timeout(&done, + msecs_to_jiffies(2000))) { + usb_kill_urb(urb); + retval = -ETIMEDOUT; + xhci_err(xhci, "%s IN stage timed out on ep0\n", __func__); + } +out1: + usb_free_urb(urb); +cleanup: + kfree(dr); + kfree(buf); + return retval; +} + int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength) { @@ -888,6 +1033,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 link_state = 0; u16 wake_mask = 0; u16 timeout = 0; + u16 test_mode = 0; max_ports = xhci_get_ports(hcd, &port_array); bus_state = &xhci->bus_state[hcd_index(hcd)]; @@ -961,8 +1107,8 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, link_state = (wIndex & 0xff00) >> 3; if (wValue == USB_PORT_FEAT_REMOTE_WAKE_MASK) wake_mask = wIndex & 0xff00; - /* The MSB of wIndex is the U1/U2 timeout */ - timeout = (wIndex & 0xff00) >> 8; + /* The MSB of wIndex is the U1/U2 timeout OR TEST mode*/ + test_mode = timeout = (wIndex & 0xff00) >> 8; wIndex &= 0xff; if (!wIndex || wIndex > max_ports) goto error; @@ -1136,6 +1282,32 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, temp |= PORT_U2_TIMEOUT(timeout); writel(temp, port_array[wIndex] + PORTPMSC); break; + case USB_PORT_FEAT_TEST: + slot_id = xhci_find_slot_id_by_port(hcd, xhci, + wIndex + 1); + if (test_mode && test_mode <= 5) { + /* unlock to execute stop endpoint commands */ + spin_unlock_irqrestore(&xhci->lock, flags); + xhci_stop_device(xhci, slot_id, 1); + spin_lock_irqsave(&xhci->lock, flags); + xhci_halt(xhci); + + temp = readl_relaxed(port_array[wIndex] + + PORTPMSC); + temp |= test_mode << 28; + writel_relaxed(temp, port_array[wIndex] + + PORTPMSC); + /* to make sure above write goes through */ + mb(); + } else if (test_mode == 6) { + spin_unlock_irqrestore(&xhci->lock, flags); + retval = xhci_ehset_single_step_set_feature(hcd, + wIndex); + spin_lock_irqsave(&xhci->lock, flags); + } else { + goto error; + } + break; default: goto error; } diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 1f37b89e7267..a5e600910057 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -3545,6 +3545,156 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, return 0; } +/* + * Variant of xhci_queue_ctrl_tx() used to implement EHSET + * SINGLE_STEP_SET_FEATURE test mode. It differs in that the control + * transfer is broken up so that the SETUP stage can happen and call + * the URB's completion handler before the DATA/STATUS stages are + * executed by the xHC hardware. This assumes the control transfer is a + * GetDescriptor, with a DATA stage in the IN direction, and an OUT + * STATUS stage. + * + * This function is called twice, usually with a 15-second delay in between. + * - with is_setup==true, the SETUP stage for the control request + * (GetDescriptor) is queued in the TRB ring and sent to HW immediately + * - with is_setup==false, the DATA and STATUS TRBs are queued and exceuted + * + * Caller must have locked xhci->lock + */ +int xhci_submit_single_step_set_feature(struct usb_hcd *hcd, struct urb *urb, + int is_setup) +{ + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct xhci_ring *ep_ring; + int num_trbs; + int ret; + unsigned int slot_id, ep_index; + struct usb_ctrlrequest *setup; + struct xhci_generic_trb *start_trb; + int start_cycle; + u32 field, length_field, remainder; + struct urb_priv *urb_priv; + struct xhci_td *td; + + ep_ring = xhci_urb_to_transfer_ring(xhci, urb); + if (!ep_ring) + return -EINVAL; + + /* Need buffer for data stage */ + if (urb->transfer_buffer_length <= 0) + return -EINVAL; + + /* + * Need to copy setup packet into setup TRB, so we can't use the setup + * DMA address. + */ + if (!urb->setup_packet) + return -EINVAL; + setup = (struct usb_ctrlrequest *) urb->setup_packet; + + slot_id = urb->dev->slot_id; + ep_index = xhci_get_endpoint_index(&urb->ep->desc); + + urb_priv = kzalloc(sizeof(struct urb_priv) + + sizeof(struct xhci_td *), GFP_ATOMIC); + if (!urb_priv) + return -ENOMEM; + + td = urb_priv->td[0] = kzalloc(sizeof(struct xhci_td), GFP_ATOMIC); + if (!td) { + kfree(urb_priv); + return -ENOMEM; + } + + urb_priv->length = 1; + urb_priv->td_cnt = 0; + urb->hcpriv = urb_priv; + + num_trbs = is_setup ? 1 : 2; + + ret = prepare_transfer(xhci, xhci->devs[slot_id], + ep_index, urb->stream_id, + num_trbs, urb, 0, GFP_ATOMIC); + if (ret < 0) { + kfree(td); + kfree(urb_priv); + return ret; + } + + /* + * Don't give the first TRB to the hardware (by toggling the cycle bit) + * until we've finished creating all the other TRBs. The ring's cycle + * state may change as we enqueue the other TRBs, so save it too. + */ + start_trb = &ep_ring->enqueue->generic; + start_cycle = ep_ring->cycle_state; + + if (is_setup) { + /* Queue only the setup TRB */ + field = TRB_IDT | TRB_IOC | TRB_TYPE(TRB_SETUP); + if (start_cycle == 0) + field |= 0x1; + + /* xHCI 1.0 6.4.1.2.1: Transfer Type field */ + if (xhci->hci_version == 0x100) { + if (setup->bRequestType & USB_DIR_IN) + field |= TRB_TX_TYPE(TRB_DATA_IN); + else + field |= TRB_TX_TYPE(TRB_DATA_OUT); + } + + /* Save the DMA address of the last TRB in the TD */ + td->last_trb = ep_ring->enqueue; + + queue_trb(xhci, ep_ring, false, + setup->bRequestType | setup->bRequest << 8 | + le16_to_cpu(setup->wValue) << 16, + le16_to_cpu(setup->wIndex) | + le16_to_cpu(setup->wLength) << 16, + TRB_LEN(8) | TRB_INTR_TARGET(0), + field); + } else { + /* Queue data TRB */ + field = TRB_ISP | TRB_TYPE(TRB_DATA); + if (start_cycle == 0) + field |= 0x1; + if (setup->bRequestType & USB_DIR_IN) + field |= TRB_DIR_IN; + + remainder = xhci_td_remainder(xhci, 0, + urb->transfer_buffer_length, + urb->transfer_buffer_length, + urb, 1); + + length_field = TRB_LEN(urb->transfer_buffer_length) | + TRB_TD_SIZE(remainder) | + TRB_INTR_TARGET(0); + + queue_trb(xhci, ep_ring, true, + lower_32_bits(urb->transfer_dma), + upper_32_bits(urb->transfer_dma), + length_field, + field); + + /* Save the DMA address of the last TRB in the TD */ + td->last_trb = ep_ring->enqueue; + + /* Queue status TRB */ + field = TRB_IOC | TRB_TYPE(TRB_STATUS); + if (!(setup->bRequestType & USB_DIR_IN)) + field |= TRB_DIR_IN; + + queue_trb(xhci, ep_ring, false, + 0, + 0, + TRB_INTR_TARGET(0), + field | ep_ring->cycle_state); + } + + giveback_first_trb(xhci, slot_id, ep_index, 0, start_cycle, start_trb); + return 0; +} + static int count_isoc_trbs_needed(struct xhci_hcd *xhci, struct urb *urb, int i) { diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index dc03aac4f88a..097cfa9e4692 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1960,4 +1960,8 @@ struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_container_ struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx); struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int ep_index); +/* EHSET */ +int xhci_submit_single_step_set_feature(struct usb_hcd *hcd, struct urb *urb, + int is_setup); + #endif /* __LINUX_XHCI_HCD_H */ diff --git a/drivers/usb/phy/phy-msm-qusb-v2.c b/drivers/usb/phy/phy-msm-qusb-v2.c index 8b35ac933028..6fb91134b0c5 100644 --- a/drivers/usb/phy/phy-msm-qusb-v2.c +++ b/drivers/usb/phy/phy-msm-qusb-v2.c @@ -601,7 +601,8 @@ static int qusb_phy_set_suspend(struct usb_phy *phy, int suspend) readl_relaxed(qphy->base + QUSB2PHY_PLL_ANALOG_CONTROLS_TWO); - writel_relaxed(0x1b, + /* use CSR & switch to SE clk */ + writel_relaxed(0xb, qphy->base + QUSB2PHY_PLL_ANALOG_CONTROLS_TWO); /* enable clock bypass */ diff --git a/drivers/video/fbdev/msm/mdss_debug.c b/drivers/video/fbdev/msm/mdss_debug.c index 6b455e0f1e6f..9ab88d4a7a52 100644 --- a/drivers/video/fbdev/msm/mdss_debug.c +++ b/drivers/video/fbdev/msm/mdss_debug.c @@ -1359,7 +1359,9 @@ static inline struct mdss_mdp_misr_map *mdss_misr_get_map(u32 block_id, (mdata->mdp_rev == MDSS_MDP_HW_REV_300) || (mdata->mdp_rev == - MDSS_MDP_HW_REV_301)) { + MDSS_MDP_HW_REV_301) || + (mdata->mdp_rev == + MDSS_MDP_HW_REV_320)) { ctrl_reg += 0x8; value_reg += 0x8; } diff --git a/drivers/video/fbdev/msm/mdss_dp.c b/drivers/video/fbdev/msm/mdss_dp.c index da3c8ca23fb6..7076b36bb6b6 100644 --- a/drivers/video/fbdev/msm/mdss_dp.c +++ b/drivers/video/fbdev/msm/mdss_dp.c @@ -1211,16 +1211,20 @@ static int mdss_dp_on_irq(struct mdss_dp_drv_pdata *dp_drv) ret = mdss_dp_get_lane_mapping(dp_drv, dp_drv->orientation, &ln_map); - if (ret) + if (ret) { + mutex_unlock(&dp_drv->train_mutex); goto exit; + } mdss_dp_phy_share_lane_config(&dp_drv->phy_io, dp_drv->orientation, dp_drv->dpcd.max_lane_count); ret = mdss_dp_enable_mainlink_clocks(dp_drv); - if (ret) + if (ret) { + mutex_unlock(&dp_drv->train_mutex); goto exit; + } mdss_dp_mainlink_reset(&dp_drv->ctrl_io); @@ -1238,7 +1242,6 @@ static int mdss_dp_on_irq(struct mdss_dp_drv_pdata *dp_drv) pr_debug("end\n"); exit: - mutex_unlock(&dp_drv->train_mutex); return ret; } @@ -1351,9 +1354,16 @@ static inline bool mdss_dp_is_link_training_requested( return (dp->test_data.test_requested == TEST_LINK_TRAINING); } +static inline bool mdss_dp_is_phy_test_pattern_requested( + struct mdss_dp_drv_pdata *dp) +{ + return (dp->test_data.test_requested == PHY_TEST_PATTERN); +} + static inline bool mdss_dp_soft_hpd_reset(struct mdss_dp_drv_pdata *dp) { - return mdss_dp_is_link_training_requested(dp) && + return (mdss_dp_is_link_training_requested(dp) || + mdss_dp_is_phy_test_pattern_requested(dp)) && dp->alt_mode.dp_status.hpd_irq; } @@ -2500,6 +2510,57 @@ static int mdss_dp_process_link_training_request(struct mdss_dp_drv_pdata *dp) return 0; } +/** + * mdss_dp_process_phy_test_pattern_request() - process new phy test requests + * @dp: Display Port Driver data + * + * This function will handle new phy test pattern requests that are initiated + * by the sink. The function will return 0 if a phy test pattern has been + * processed, otherwise it will return -EINVAL. + */ +static int mdss_dp_process_phy_test_pattern_request( + struct mdss_dp_drv_pdata *dp) +{ + u32 test_link_rate = 0, test_lane_count = 0; + + if (!mdss_dp_is_phy_test_pattern_requested(dp)) + return -EINVAL; + + mdss_dp_send_test_response(dp); + + test_link_rate = dp->test_data.test_link_rate; + test_lane_count = dp->test_data.test_lane_count; + + pr_info("%s link rate = 0x%x, lane count = 0x%x\n", + mdss_dp_get_test_name(TEST_LINK_TRAINING), + test_link_rate, test_lane_count); + + /** + * Retrain the mainlink if there is a change in link rate or lane + * count. + */ + if (mdss_dp_aux_is_link_rate_valid(test_link_rate) && + mdss_dp_aux_is_lane_count_valid(test_lane_count) && + ((dp->dpcd.max_lane_count != test_lane_count) || + (dp->link_rate != test_link_rate))) { + + pr_info("updated link rate or lane count, retraining.\n"); + + dp->dpcd.max_lane_count = dp->test_data.test_lane_count; + dp->link_rate = dp->test_data.test_link_rate; + + mdss_dp_link_retraining(dp); + } + + mdss_dp_config_ctrl(dp); + + mdss_dp_aux_update_voltage_and_pre_emphasis_lvl(dp); + + mdss_dp_phy_send_test_pattern(dp); + + return 0; +} + /** * mdss_dp_process_downstream_port_status_change() - process port status changes * @dp: Display Port Driver data @@ -2548,6 +2609,9 @@ static int mdss_dp_process_hpd_irq_high(struct mdss_dp_drv_pdata *dp) if (!ret) goto exit; + ret = mdss_dp_process_phy_test_pattern_request(dp); + if (!ret) + goto exit; pr_debug("done\n"); exit: mdss_dp_reset_test_data(dp); diff --git a/drivers/video/fbdev/msm/mdss_dp.h b/drivers/video/fbdev/msm/mdss_dp.h index c4494aa9c629..399ca61e0f46 100644 --- a/drivers/video/fbdev/msm/mdss_dp.h +++ b/drivers/video/fbdev/msm/mdss_dp.h @@ -268,6 +268,7 @@ struct dpcd_test_request { u32 test_requested; u32 test_link_rate; u32 test_lane_count; + u32 phy_test_pattern_sel; u32 response; }; @@ -509,6 +510,51 @@ enum dp_lane_count { DP_LANE_COUNT_4 = 4, }; +enum phy_test_pattern { + PHY_TEST_PATTERN_NONE, + PHY_TEST_PATTERN_D10_2_NO_SCRAMBLING, + PHY_TEST_PATTERN_SYMBOL_ERR_MEASUREMENT_CNT, + PHY_TEST_PATTERN_PRBS7, + PHY_TEST_PATTERN_80_BIT_CUSTOM_PATTERN, + PHY_TEST_PATTERN_HBR2_CTS_EYE_PATTERN, +}; + +static inline char *mdss_dp_get_phy_test_pattern(u32 phy_test_pattern_sel) +{ + switch (phy_test_pattern_sel) { + case PHY_TEST_PATTERN_NONE: + return DP_ENUM_STR(PHY_TEST_PATTERN_NONE); + case PHY_TEST_PATTERN_D10_2_NO_SCRAMBLING: + return DP_ENUM_STR(PHY_TEST_PATTERN_D10_2_NO_SCRAMBLING); + case PHY_TEST_PATTERN_SYMBOL_ERR_MEASUREMENT_CNT: + return DP_ENUM_STR(PHY_TEST_PATTERN_SYMBOL_ERR_MEASUREMENT_CNT); + case PHY_TEST_PATTERN_PRBS7: + return DP_ENUM_STR(PHY_TEST_PATTERN_PRBS7); + case PHY_TEST_PATTERN_80_BIT_CUSTOM_PATTERN: + return DP_ENUM_STR(PHY_TEST_PATTERN_80_BIT_CUSTOM_PATTERN); + case PHY_TEST_PATTERN_HBR2_CTS_EYE_PATTERN: + return DP_ENUM_STR(PHY_TEST_PATTERN_HBR2_CTS_EYE_PATTERN); + default: + return "unknown"; + } +} + +static inline bool mdss_dp_is_phy_test_pattern_supported( + u32 phy_test_pattern_sel) +{ + switch (phy_test_pattern_sel) { + case PHY_TEST_PATTERN_NONE: + case PHY_TEST_PATTERN_D10_2_NO_SCRAMBLING: + case PHY_TEST_PATTERN_SYMBOL_ERR_MEASUREMENT_CNT: + case PHY_TEST_PATTERN_PRBS7: + case PHY_TEST_PATTERN_80_BIT_CUSTOM_PATTERN: + case PHY_TEST_PATTERN_HBR2_CTS_EYE_PATTERN: + return true; + default: + return false; + } +} + enum dp_aux_error { EDP_AUX_ERR_NONE = 0, EDP_AUX_ERR_ADDR = -1, @@ -561,7 +607,7 @@ static inline char *mdss_dp_get_test_response(u32 test_response) enum test_type { UNKNOWN_TEST = 0, TEST_LINK_TRAINING = BIT(0), - TEST_PATTERN = BIT(1), + PHY_TEST_PATTERN = BIT(3), TEST_EDID_READ = BIT(2), }; @@ -569,7 +615,7 @@ static inline char *mdss_dp_get_test_name(u32 test_requested) { switch (test_requested) { case TEST_LINK_TRAINING: return DP_ENUM_STR(TEST_LINK_TRAINING); - case TEST_PATTERN: return DP_ENUM_STR(TEST_PATTERN); + case PHY_TEST_PATTERN: return DP_ENUM_STR(PHY_TEST_PATTERN); case TEST_EDID_READ: return DP_ENUM_STR(TEST_EDID_READ); default: return "unknown"; } @@ -640,5 +686,10 @@ void *mdss_dp_get_hdcp_data(struct device *dev); int mdss_dp_hdcp2p2_init(struct mdss_dp_drv_pdata *dp_drv); bool mdss_dp_aux_clock_recovery_done(struct mdss_dp_drv_pdata *ep); bool mdss_dp_aux_channel_eq_done(struct mdss_dp_drv_pdata *ep); +bool mdss_dp_aux_is_link_rate_valid(u32 link_rate); +bool mdss_dp_aux_is_lane_count_valid(u32 lane_count); +int mdss_dp_aux_link_status_read(struct mdss_dp_drv_pdata *ep, int len); +void mdss_dp_aux_update_voltage_and_pre_emphasis_lvl( + struct mdss_dp_drv_pdata *dp); #endif /* MDSS_DP_H */ diff --git a/drivers/video/fbdev/msm/mdss_dp_aux.c b/drivers/video/fbdev/msm/mdss_dp_aux.c index b216506fe2a9..b8be110f04f0 100644 --- a/drivers/video/fbdev/msm/mdss_dp_aux.c +++ b/drivers/video/fbdev/msm/mdss_dp_aux.c @@ -537,8 +537,9 @@ char mdss_dp_gen_link_clk(struct mdss_panel_info *pinfo, char lane_cnt) else if (min_link_rate <= DP_LINK_RATE_540) calc_link_rate = DP_LINK_RATE_540; else { - pr_err("link_rate = %d is unsupported\n", min_link_rate); - calc_link_rate = 0; + /* Cap the link rate to the max supported rate */ + pr_debug("link_rate = %d is unsupported\n", min_link_rate); + calc_link_rate = DP_LINK_RATE_540; } return calc_link_rate; @@ -960,7 +961,7 @@ static void dp_sink_capability_read(struct mdss_dp_drv_pdata *ep, dp_sink_parse_sink_count(ep); } -static int dp_link_status_read(struct mdss_dp_drv_pdata *ep, int len) +int mdss_dp_aux_link_status_read(struct mdss_dp_drv_pdata *ep, int len) { char *bp; char data; @@ -1031,12 +1032,12 @@ void mdss_dp_aux_send_test_response(struct mdss_dp_drv_pdata *dp) } /** - * dp_is_link_rate_valid() - validates the link rate + * mdss_dp_aux_is_link_rate_valid() - validates the link rate * @lane_rate: link rate requested by the sink * * Returns true if the requested link rate is supported. */ -static bool dp_is_link_rate_valid(u32 link_rate) +bool mdss_dp_aux_is_link_rate_valid(u32 link_rate) { return (link_rate == DP_LINK_RATE_162) || (link_rate == DP_LINK_RATE_270) || @@ -1044,12 +1045,12 @@ static bool dp_is_link_rate_valid(u32 link_rate) } /** - * dp_is_lane_count_valid() - validates the lane count + * mdss_dp_aux_is_lane_count_valid() - validates the lane count * @lane_count: lane count requested by the sink * * Returns true if the requested lane count is supported. */ -static bool dp_is_lane_count_valid(u32 lane_count) +bool mdss_dp_aux_is_lane_count_valid(u32 lane_count) { return (lane_count == DP_LANE_COUNT_1) || (lane_count == DP_LANE_COUNT_2) || @@ -1086,7 +1087,7 @@ static int dp_parse_link_training_params(struct mdss_dp_drv_pdata *ep) bp = rp->data; data = *bp++; - if (!dp_is_link_rate_valid(data)) { + if (!mdss_dp_aux_is_link_rate_valid(data)) { pr_err("invalid link rate = 0x%x\n", data); ret = -EINVAL; goto exit; @@ -1108,7 +1109,7 @@ static int dp_parse_link_training_params(struct mdss_dp_drv_pdata *ep) data = *bp++; data &= 0x1F; - if (!dp_is_lane_count_valid(data)) { + if (!mdss_dp_aux_is_lane_count_valid(data)) { pr_err("invalid lane count = 0x%x\n", data); ret = -EINVAL; goto exit; @@ -1156,6 +1157,53 @@ static void dp_sink_parse_sink_count(struct mdss_dp_drv_pdata *ep) ep->sink_count.count, ep->sink_count.cp_ready); } +/** + * dp_parse_phy_test_params() - parses the phy test parameters + * @ep: Display Port Driver data + * + * Parses the DPCD (Byte 0x248) for the DP PHY test pattern that is being + * requested. + */ +static int dp_parse_phy_test_params(struct mdss_dp_drv_pdata *ep) +{ + char *bp; + char data; + struct edp_buf *rp; + int rlen; + int const param_len = 0x1; + int const phy_test_pattern_addr = 0x248; + int const dpcd_version_1_2 = 0x12; + int ret = 0; + + rlen = dp_aux_read_buf(ep, phy_test_pattern_addr, param_len, 0); + if (rlen < param_len) { + pr_err("failed to read phy test pattern\n"); + ret = -EINVAL; + goto end; + } + + rp = &ep->rxp; + bp = rp->data; + data = *bp++; + + if (ep->dpcd.major == dpcd_version_1_2) + data = data & 0x7; + else + data = data & 0x3; + + ep->test_data.phy_test_pattern_sel = data; + + pr_debug("phy_test_pattern_sel = %s\n", + mdss_dp_get_phy_test_pattern(data)); + + if (!mdss_dp_is_phy_test_pattern_supported(data)) + ret = -EINVAL; + +end: + return ret; +} + + /** * dp_is_test_supported() - checks if test requested by sink is supported * @test_requested: test requested by the sink @@ -1165,7 +1213,8 @@ static void dp_sink_parse_sink_count(struct mdss_dp_drv_pdata *ep) static bool dp_is_test_supported(u32 test_requested) { return (test_requested == TEST_LINK_TRAINING) || - (test_requested == TEST_EDID_READ); + (test_requested == TEST_EDID_READ) || + (test_requested == PHY_TEST_PATTERN); } /** @@ -1229,8 +1278,19 @@ static void dp_sink_parse_test_request(struct mdss_dp_drv_pdata *ep) pr_debug("%s requested\n", mdss_dp_get_test_name(data)); ep->test_data.test_requested = data; - if (ep->test_data.test_requested == TEST_LINK_TRAINING) + switch (ep->test_data.test_requested) { + case PHY_TEST_PATTERN: + ret = dp_parse_phy_test_params(ep); + if (ret) + break; + case TEST_LINK_TRAINING: ret = dp_parse_link_training_params(ep); + break; + default: + pr_debug("test 0x%x not supported\n", + ep->test_data.test_requested); + return; + } /** * Send a TEST_ACK if all test parameters are valid, otherwise send @@ -1453,7 +1513,8 @@ char vm_voltage_swing[4][4] = { {0x1E, 0xFF, 0xFF, 0xFF} /* sw1, 1.2 v, optional */ }; -static void dp_voltage_pre_emphasise_set(struct mdss_dp_drv_pdata *dp) +static void dp_aux_set_voltage_and_pre_emphasis_lvl( + struct mdss_dp_drv_pdata *dp) { u32 value0 = 0; u32 value1 = 0; @@ -1488,6 +1549,38 @@ static void dp_voltage_pre_emphasise_set(struct mdss_dp_drv_pdata *dp) } +/** + * mdss_dp_aux_update_voltage_and_pre_emphasis_lvl() - updates DP PHY settings + * @ep: Display Port Driver data + * + * Updates the DP PHY with the requested voltage swing and pre-emphasis + * levels if they are different from the current settings. + */ +void mdss_dp_aux_update_voltage_and_pre_emphasis_lvl( + struct mdss_dp_drv_pdata *dp) +{ + int const num_bytes = 6; + struct dpcd_link_status *status = &dp->link_status; + + /* Read link status for updated voltage and pre-emphasis levels. */ + mdss_dp_aux_link_status_read(dp, num_bytes); + + pr_info("Current: v_level = %d, p_level = %d\n", + dp->v_level, dp->p_level); + pr_info("Requested: v_level = %d, p_level = %d\n", + status->req_voltage_swing[0], + status->req_pre_emphasis[0]); + + if ((status->req_voltage_swing[0] != dp->v_level) || + (status->req_pre_emphasis[0] != dp->p_level)) { + dp->v_level = status->req_voltage_swing[0]; + dp->p_level = status->req_pre_emphasis[0]; + + dp_aux_set_voltage_and_pre_emphasis_lvl(dp); + } + + pr_debug("end\n"); +} static int dp_start_link_train_1(struct mdss_dp_drv_pdata *ep) { int tries, old_v_level; @@ -1500,7 +1593,7 @@ static int dp_start_link_train_1(struct mdss_dp_drv_pdata *ep) dp_host_train_set(ep, 0x01); /* train_1 */ dp_cap_lane_rate_set(ep); dp_train_pattern_set_write(ep, 0x21); /* train_1 */ - dp_voltage_pre_emphasise_set(ep); + dp_aux_set_voltage_and_pre_emphasis_lvl(ep); tries = 0; old_v_level = ep->v_level; @@ -1508,7 +1601,7 @@ static int dp_start_link_train_1(struct mdss_dp_drv_pdata *ep) usleep_time = ep->dpcd.training_read_interval; usleep_range(usleep_time, usleep_time); - dp_link_status_read(ep, 6); + mdss_dp_aux_link_status_read(ep, 6); if (mdss_dp_aux_clock_recovery_done(ep)) { ret = 0; break; @@ -1531,7 +1624,7 @@ static int dp_start_link_train_1(struct mdss_dp_drv_pdata *ep) } dp_sink_train_set_adjust(ep); - dp_voltage_pre_emphasise_set(ep); + dp_aux_set_voltage_and_pre_emphasis_lvl(ep); } return ret; @@ -1555,13 +1648,13 @@ static int dp_start_link_train_2(struct mdss_dp_drv_pdata *ep) dp_train_pattern_set_write(ep, pattern | 0x20);/* train_2 */ do { - dp_voltage_pre_emphasise_set(ep); + dp_aux_set_voltage_and_pre_emphasis_lvl(ep); dp_host_train_set(ep, pattern); usleep_time = ep->dpcd.training_read_interval; usleep_range(usleep_time, usleep_time); - dp_link_status_read(ep, 6); + mdss_dp_aux_link_status_read(ep, 6); if (mdss_dp_aux_channel_eq_done(ep)) { ret = 0; @@ -1698,7 +1791,7 @@ void mdss_dp_aux_parse_sink_status_field(struct mdss_dp_drv_pdata *ep) { dp_sink_parse_sink_count(ep); dp_sink_parse_test_request(ep); - dp_link_status_read(ep, 6); + mdss_dp_aux_link_status_read(ep, 6); } int mdss_dp_dpcd_status_read(struct mdss_dp_drv_pdata *ep) @@ -1706,7 +1799,7 @@ int mdss_dp_dpcd_status_read(struct mdss_dp_drv_pdata *ep) struct dpcd_link_status *sp; int ret = 0; /* not sync */ - ret = dp_link_status_read(ep, 6); + ret = mdss_dp_aux_link_status_read(ep, 6); if (ret) { sp = &ep->link_status; diff --git a/drivers/video/fbdev/msm/mdss_dp_util.c b/drivers/video/fbdev/msm/mdss_dp_util.c index b1bfe2c548ba..3b294a11f555 100644 --- a/drivers/video/fbdev/msm/mdss_dp_util.c +++ b/drivers/video/fbdev/msm/mdss_dp_util.c @@ -892,3 +892,87 @@ void mdss_dp_audio_enable(struct dss_io_data *ctrl_io, bool enable) writel_relaxed(audio_ctrl, ctrl_io->base + MMSS_DP_AUDIO_CFG); } + +/** + * mdss_dp_phy_send_test_pattern() - sends the requested PHY test pattern + * @ep: Display Port Driver data + * + * Updates the DP controller state and sends the requested PHY test pattern + * to the sink. + */ +void mdss_dp_phy_send_test_pattern(struct mdss_dp_drv_pdata *dp) +{ + struct dss_io_data *io = &dp->ctrl_io; + u32 phy_test_pattern_sel = dp->test_data.phy_test_pattern_sel; + u32 value = 0x0; + + if (!mdss_dp_is_phy_test_pattern_supported(phy_test_pattern_sel)) { + pr_err("test pattern 0x%x not supported\n", + phy_test_pattern_sel); + return; + } + + /* Disable mainlink */ + writel_relaxed(0x0, io->base + DP_MAINLINK_CTRL); + + /* Reset mainlink */ + mdss_dp_mainlink_reset(io); + + /* Enable mainlink */ + writel_relaxed(0x0, io->base + DP_MAINLINK_CTRL); + + /* Initialize DP state control */ + mdss_dp_state_ctrl(io, 0x00); + + pr_debug("phy_test_pattern_sel = %s\n", + mdss_dp_get_phy_test_pattern(phy_test_pattern_sel)); + + switch (phy_test_pattern_sel) { + case PHY_TEST_PATTERN_D10_2_NO_SCRAMBLING: + mdss_dp_state_ctrl(io, BIT(0)); + break; + case PHY_TEST_PATTERN_SYMBOL_ERR_MEASUREMENT_CNT: + value = readl_relaxed(io->base + + DP_HBR2_COMPLIANCE_SCRAMBLER_RESET); + value &= ~(1 << 16); + writel_relaxed(value, io->base + + DP_HBR2_COMPLIANCE_SCRAMBLER_RESET); + value |= 0xFC; + writel_relaxed(value, io->base + + DP_HBR2_COMPLIANCE_SCRAMBLER_RESET); + writel_relaxed(0x2, io->base + DP_MAINLINK_LEVELS); + mdss_dp_state_ctrl(io, BIT(4)); + break; + case PHY_TEST_PATTERN_PRBS7: + mdss_dp_state_ctrl(io, BIT(5)); + break; + case PHY_TEST_PATTERN_80_BIT_CUSTOM_PATTERN: + mdss_dp_state_ctrl(io, BIT(6)); + /* 00111110000011111000001111100000 */ + writel_relaxed(0x3E0F83E0, io->base + + DP_TEST_80BIT_CUSTOM_PATTERN_REG0); + /* 00001111100000111110000011111000 */ + writel_relaxed(0x0F83E0F8, io->base + + DP_TEST_80BIT_CUSTOM_PATTERN_REG1); + /* 1111100000111110 */ + writel_relaxed(0x0000F83E, io->base + + DP_TEST_80BIT_CUSTOM_PATTERN_REG2); + break; + case PHY_TEST_PATTERN_HBR2_CTS_EYE_PATTERN: + value = readl_relaxed(io->base + + DP_HBR2_COMPLIANCE_SCRAMBLER_RESET); + value |= BIT(16); + writel_relaxed(value, io->base + + DP_HBR2_COMPLIANCE_SCRAMBLER_RESET); + value |= 0xFC; + writel_relaxed(value, io->base + + DP_HBR2_COMPLIANCE_SCRAMBLER_RESET); + writel_relaxed(0x2, io->base + DP_MAINLINK_LEVELS); + mdss_dp_state_ctrl(io, BIT(4)); + break; + default: + pr_debug("No valid test pattern requested: 0x%x\n", + phy_test_pattern_sel); + return; + } +} diff --git a/drivers/video/fbdev/msm/mdss_dp_util.h b/drivers/video/fbdev/msm/mdss_dp_util.h index 5e238d5be2b4..c046deef48a3 100644 --- a/drivers/video/fbdev/msm/mdss_dp_util.h +++ b/drivers/video/fbdev/msm/mdss_dp_util.h @@ -60,6 +60,11 @@ #define DP_MAINLINK_LEVELS (0x00000444) #define DP_TU (0x0000044C) +#define DP_HBR2_COMPLIANCE_SCRAMBLER_RESET (0x00000454) +#define DP_TEST_80BIT_CUSTOM_PATTERN_REG0 (0x000004C0) +#define DP_TEST_80BIT_CUSTOM_PATTERN_REG1 (0x000004C4) +#define DP_TEST_80BIT_CUSTOM_PATTERN_REG2 (0x000004C8) + #define MMSS_DP_AUDIO_TIMING_GEN (0x00000480) #define MMSS_DP_AUDIO_TIMING_RBR_32 (0x00000484) #define MMSS_DP_AUDIO_TIMING_HBR_32 (0x00000488) @@ -315,5 +320,6 @@ void mdss_dp_audio_set_sample_rate(struct dss_io_data *ctrl_io, void mdss_dp_set_safe_to_exit_level(struct dss_io_data *ctrl_io, uint32_t lane_cnt); int mdss_dp_aux_read_rx_status(struct mdss_dp_drv_pdata *dp, u8 *rx_status); +void mdss_dp_phy_send_test_pattern(struct mdss_dp_drv_pdata *dp); #endif /* __DP_UTIL_H__ */ diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c index c63685bcf306..d9cfd2360ab3 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.c +++ b/drivers/video/fbdev/msm/mdss_mdp.c @@ -2105,6 +2105,48 @@ static void mdss_mdp_hw_rev_caps_init(struct mdss_data_type *mdata) set_bit(MDSS_CAPS_AVR_SUPPORTED, mdata->mdss_caps_map); set_bit(MDSS_CAPS_SEC_DETACH_SMMU, mdata->mdss_caps_map); break; + case MDSS_MDP_HW_REV_320: + mdata->max_target_zorder = 7; /* excluding base layer */ + mdata->max_cursor_size = 512; + mdata->per_pipe_ib_factor.numer = 8; + mdata->per_pipe_ib_factor.denom = 5; + mdata->apply_post_scale_bytes = false; + mdata->hflip_buffer_reused = false; + mdata->min_prefill_lines = 25; + mdata->has_ubwc = true; + mdata->pixel_ram_size = 50 * 1024; + mdata->rects_per_sspp[MDSS_MDP_PIPE_TYPE_DMA] = 2; + + mem_protect_sd_ctrl_id = MEM_PROTECT_SD_CTRL_SWITCH; + set_bit(MDSS_QOS_PER_PIPE_IB, mdata->mdss_qos_map); + set_bit(MDSS_QOS_REMAPPER, mdata->mdss_qos_map); + set_bit(MDSS_QOS_TS_PREFILL, mdata->mdss_qos_map); + set_bit(MDSS_QOS_OVERHEAD_FACTOR, mdata->mdss_qos_map); + set_bit(MDSS_QOS_CDP, mdata->mdss_qos_map); /* cdp supported */ + mdata->enable_cdp = false; /* disable cdp */ + set_bit(MDSS_QOS_OTLIM, mdata->mdss_qos_map); + set_bit(MDSS_QOS_PER_PIPE_LUT, mdata->mdss_qos_map); + set_bit(MDSS_QOS_SIMPLIFIED_PREFILL, mdata->mdss_qos_map); + set_bit(MDSS_QOS_TS_PREFILL, mdata->mdss_qos_map); + set_bit(MDSS_QOS_IB_NOCR, mdata->mdss_qos_map); + set_bit(MDSS_QOS_WB2_WRITE_GATHER_EN, mdata->mdss_qos_map); + set_bit(MDSS_CAPS_YUV_CONFIG, mdata->mdss_caps_map); + set_bit(MDSS_CAPS_SCM_RESTORE_NOT_REQUIRED, + mdata->mdss_caps_map); + set_bit(MDSS_CAPS_3D_MUX_UNDERRUN_RECOVERY_SUPPORTED, + mdata->mdss_caps_map); + set_bit(MDSS_CAPS_QSEED3, mdata->mdss_caps_map); + set_bit(MDSS_CAPS_MDP_VOTE_CLK_NOT_SUPPORTED, + mdata->mdss_caps_map); + mdss_mdp_init_default_prefill_factors(mdata); + mdss_set_quirk(mdata, MDSS_QUIRK_DSC_RIGHT_ONLY_PU); + mdss_set_quirk(mdata, MDSS_QUIRK_DSC_2SLICE_PU_THRPUT); + mdss_set_quirk(mdata, MDSS_QUIRK_MMSS_GDSC_COLLAPSE); + mdss_set_quirk(mdata, MDSS_QUIRK_MDP_CLK_SET_RATE); + mdata->has_wb_ubwc = true; + set_bit(MDSS_CAPS_10_BIT_SUPPORTED, mdata->mdss_caps_map); + set_bit(MDSS_CAPS_SEC_DETACH_SMMU, mdata->mdss_caps_map); + break; default: mdata->max_target_zorder = 4; /* excluding base layer */ mdata->max_cursor_size = 64; diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h index 20aeabfdf9a4..ab2a7184aa45 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.h +++ b/drivers/video/fbdev/msm/mdss_mdp.h @@ -1285,7 +1285,9 @@ static inline int mdss_mdp_panic_signal_support_mode( IS_MDSS_MAJOR_MINOR_SAME(mdata->mdp_rev, MDSS_MDP_HW_REV_116) || IS_MDSS_MAJOR_MINOR_SAME(mdata->mdp_rev, - MDSS_MDP_HW_REV_300)) + MDSS_MDP_HW_REV_300) || + IS_MDSS_MAJOR_MINOR_SAME(mdata->mdp_rev, + MDSS_MDP_HW_REV_320)) signal_mode = MDSS_MDP_PANIC_PER_PIPE_CFG; return signal_mode; diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c index c80d8f47bbb7..bb8227a74a04 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c +++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c @@ -5776,7 +5776,7 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg, mdss_mdp_ctl_split_display_enable(split_lm_valid, ctl, sctl); ATRACE_BEGIN("postproc_programming"); - if (ctl->mfd && ctl->mfd->dcm_state != DTM_ENTER) + if (ctl->is_video_mode && ctl->mfd && ctl->mfd->dcm_state != DTM_ENTER) /* postprocessing setup, including dspp */ mdss_mdp_pp_setup_locked(ctl); @@ -5824,6 +5824,24 @@ int mdss_mdp_display_commit(struct mdss_mdp_ctl *ctl, void *arg, if (ctl->ops.wait_pingpong && !mdata->serialize_wait4pp) mdss_mdp_display_wait4pingpong(ctl, false); + /* Moved pp programming to post ping pong */ + if (!ctl->is_video_mode && ctl->mfd && + ctl->mfd->dcm_state != DTM_ENTER) { + /* postprocessing setup, including dspp */ + mutex_lock(&ctl->flush_lock); + mdss_mdp_pp_setup_locked(ctl); + if (sctl) { + if (ctl->split_flush_en) { + ctl->flush_bits |= sctl->flush_bits; + sctl->flush_bits = 0; + sctl_flush_bits = 0; + } else { + sctl_flush_bits = sctl->flush_bits; + } + } + ctl_flush_bits = ctl->flush_bits; + mutex_unlock(&ctl->flush_lock); + } /* * if serialize_wait4pp is false then roi_bkup used in wait4pingpong * will be of previous frame as expected. diff --git a/drivers/video/fbdev/msm/mdss_mdp_pp.c b/drivers/video/fbdev/msm/mdss_mdp_pp.c index 264024289691..917e6889124d 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_pp.c +++ b/drivers/video/fbdev/msm/mdss_mdp_pp.c @@ -1123,7 +1123,8 @@ static int pp_vig_pipe_setup(struct mdss_mdp_pipe *pipe, u32 *op) mdss_mdp_pp_get_dcm_state(pipe, &dcm_state); mdata = mdss_mdp_get_mdata(); - if (IS_MDSS_MAJOR_MINOR_SAME(mdata->mdp_rev, MDSS_MDP_HW_REV_301) || + if (IS_MDSS_MAJOR_MINOR_SAME(mdata->mdp_rev, MDSS_MDP_HW_REV_320) || + IS_MDSS_MAJOR_MINOR_SAME(mdata->mdp_rev, MDSS_MDP_HW_REV_301) || IS_MDSS_MAJOR_MINOR_SAME(mdata->mdp_rev, MDSS_MDP_HW_REV_300)) { if (pipe->src_fmt->is_yuv) { /* TODO: check csc cfg from PP block */ @@ -7664,6 +7665,7 @@ static int pp_get_driver_ops(struct mdp_pp_driver_ops *ops) break; case MDSS_MDP_HW_REV_300: case MDSS_MDP_HW_REV_301: + case MDSS_MDP_HW_REV_320: /* * Some of the REV_300 PP features are same as REV_107. * Get the driver ops for both the versions and update the diff --git a/include/dt-bindings/clock/qcom,cpu-osm.h b/include/dt-bindings/clock/qcom,cpu-osm.h new file mode 100644 index 000000000000..71745fab287a --- /dev/null +++ b/include/dt-bindings/clock/qcom,cpu-osm.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _DT_BINDINGS_CLK_MSM_CPU_OSM_H +#define _DT_BINDINGS_CLK_MSM_CPU_OSM_H + +/* CPU clock IDs */ +#define SYS_APCSAUX_CLK_GCC 0 +#define PWRCL_CLK 1 +#define PERFCL_CLK 2 +#define OSM_CLK_SRC 3 + +#endif diff --git a/include/dt-bindings/clock/qcom,gcc-msm8996.h b/include/dt-bindings/clock/qcom,gcc-msm8996.h index f66264a2beb4..efed312fe914 100644 --- a/include/dt-bindings/clock/qcom,gcc-msm8996.h +++ b/include/dt-bindings/clock/qcom,gcc-msm8996.h @@ -14,238 +14,239 @@ #ifndef _DT_BINDINGS_CLK_MSM_GCC_8996_H #define _DT_BINDINGS_CLK_MSM_GCC_8996_H -#define GPLL0_EARLY 0 -#define GPLL0 1 -#define GPLL1_EARLY 2 -#define GPLL1 3 -#define GPLL2_EARLY 4 -#define GPLL2 5 -#define GPLL3_EARLY 6 -#define GPLL3 7 -#define GPLL4_EARLY 8 -#define GPLL4 9 -#define SYSTEM_NOC_CLK_SRC 10 -#define CONFIG_NOC_CLK_SRC 11 -#define PERIPH_NOC_CLK_SRC 12 -#define MMSS_BIMC_GFX_CLK_SRC 13 -#define USB30_MASTER_CLK_SRC 14 -#define USB30_MOCK_UTMI_CLK_SRC 15 -#define USB3_PHY_AUX_CLK_SRC 16 -#define USB20_MASTER_CLK_SRC 17 -#define USB20_MOCK_UTMI_CLK_SRC 18 -#define SDCC1_APPS_CLK_SRC 19 -#define SDCC1_ICE_CORE_CLK_SRC 20 -#define SDCC2_APPS_CLK_SRC 21 -#define SDCC3_APPS_CLK_SRC 22 -#define SDCC4_APPS_CLK_SRC 23 -#define BLSP1_QUP1_SPI_APPS_CLK_SRC 24 -#define BLSP1_QUP1_I2C_APPS_CLK_SRC 25 -#define BLSP1_UART1_APPS_CLK_SRC 26 -#define BLSP1_QUP2_SPI_APPS_CLK_SRC 27 -#define BLSP1_QUP2_I2C_APPS_CLK_SRC 28 -#define BLSP1_UART2_APPS_CLK_SRC 29 -#define BLSP1_QUP3_SPI_APPS_CLK_SRC 30 -#define BLSP1_QUP3_I2C_APPS_CLK_SRC 31 -#define BLSP1_UART3_APPS_CLK_SRC 32 -#define BLSP1_QUP4_SPI_APPS_CLK_SRC 33 -#define BLSP1_QUP4_I2C_APPS_CLK_SRC 34 -#define BLSP1_UART4_APPS_CLK_SRC 35 -#define BLSP1_QUP5_SPI_APPS_CLK_SRC 36 -#define BLSP1_QUP5_I2C_APPS_CLK_SRC 37 -#define BLSP1_UART5_APPS_CLK_SRC 38 -#define BLSP1_QUP6_SPI_APPS_CLK_SRC 39 -#define BLSP1_QUP6_I2C_APPS_CLK_SRC 40 -#define BLSP1_UART6_APPS_CLK_SRC 41 -#define BLSP2_QUP1_SPI_APPS_CLK_SRC 42 -#define BLSP2_QUP1_I2C_APPS_CLK_SRC 43 -#define BLSP2_UART1_APPS_CLK_SRC 44 -#define BLSP2_QUP2_SPI_APPS_CLK_SRC 45 -#define BLSP2_QUP2_I2C_APPS_CLK_SRC 46 -#define BLSP2_UART2_APPS_CLK_SRC 47 -#define BLSP2_QUP3_SPI_APPS_CLK_SRC 48 -#define BLSP2_QUP3_I2C_APPS_CLK_SRC 49 -#define BLSP2_UART3_APPS_CLK_SRC 50 -#define BLSP2_QUP4_SPI_APPS_CLK_SRC 51 -#define BLSP2_QUP4_I2C_APPS_CLK_SRC 52 -#define BLSP2_UART4_APPS_CLK_SRC 53 -#define BLSP2_QUP5_SPI_APPS_CLK_SRC 54 -#define BLSP2_QUP5_I2C_APPS_CLK_SRC 55 -#define BLSP2_UART5_APPS_CLK_SRC 56 -#define BLSP2_QUP6_SPI_APPS_CLK_SRC 57 -#define BLSP2_QUP6_I2C_APPS_CLK_SRC 58 -#define BLSP2_UART6_APPS_CLK_SRC 59 -#define PDM2_CLK_SRC 60 -#define TSIF_REF_CLK_SRC 61 -#define CE1_CLK_SRC 62 -#define GCC_SLEEP_CLK_SRC 63 -#define BIMC_CLK_SRC 64 -#define HMSS_AHB_CLK_SRC 65 -#define BIMC_HMSS_AXI_CLK_SRC 66 -#define HMSS_RBCPR_CLK_SRC 67 -#define HMSS_GPLL0_CLK_SRC 68 -#define GP1_CLK_SRC 69 -#define GP2_CLK_SRC 70 -#define GP3_CLK_SRC 71 -#define PCIE_AUX_CLK_SRC 72 -#define UFS_AXI_CLK_SRC 73 -#define UFS_ICE_CORE_CLK_SRC 74 -#define QSPI_SER_CLK_SRC 75 -#define GCC_SYS_NOC_AXI_CLK 76 -#define GCC_SYS_NOC_HMSS_AHB_CLK 77 -#define GCC_SNOC_CNOC_AHB_CLK 78 -#define GCC_SNOC_PNOC_AHB_CLK 79 -#define GCC_SYS_NOC_AT_CLK 80 -#define GCC_SYS_NOC_USB3_AXI_CLK 81 -#define GCC_SYS_NOC_UFS_AXI_CLK 82 -#define GCC_CFG_NOC_AHB_CLK 83 -#define GCC_PERIPH_NOC_AHB_CLK 84 -#define GCC_PERIPH_NOC_USB20_AHB_CLK 85 -#define GCC_TIC_CLK 86 -#define GCC_IMEM_AXI_CLK 87 -#define GCC_MMSS_SYS_NOC_AXI_CLK 88 -#define GCC_MMSS_NOC_CFG_AHB_CLK 89 -#define GCC_MMSS_BIMC_GFX_CLK 90 -#define GCC_USB30_MASTER_CLK 91 -#define GCC_USB30_SLEEP_CLK 92 -#define GCC_USB30_MOCK_UTMI_CLK 93 -#define GCC_USB3_PHY_AUX_CLK 94 -#define GCC_USB3_PHY_PIPE_CLK 95 -#define GCC_USB20_MASTER_CLK 96 -#define GCC_USB20_SLEEP_CLK 97 -#define GCC_USB20_MOCK_UTMI_CLK 98 -#define GCC_USB_PHY_CFG_AHB2PHY_CLK 99 -#define GCC_SDCC1_APPS_CLK 100 -#define GCC_SDCC1_AHB_CLK 101 -#define GCC_SDCC1_ICE_CORE_CLK 102 -#define GCC_SDCC2_APPS_CLK 103 -#define GCC_SDCC2_AHB_CLK 104 -#define GCC_SDCC3_APPS_CLK 105 -#define GCC_SDCC3_AHB_CLK 106 -#define GCC_SDCC4_APPS_CLK 107 -#define GCC_SDCC4_AHB_CLK 108 -#define GCC_BLSP1_AHB_CLK 109 -#define GCC_BLSP1_SLEEP_CLK 110 -#define GCC_BLSP1_QUP1_SPI_APPS_CLK 111 -#define GCC_BLSP1_QUP1_I2C_APPS_CLK 112 -#define GCC_BLSP1_UART1_APPS_CLK 113 -#define GCC_BLSP1_QUP2_SPI_APPS_CLK 114 -#define GCC_BLSP1_QUP2_I2C_APPS_CLK 115 -#define GCC_BLSP1_UART2_APPS_CLK 116 -#define GCC_BLSP1_QUP3_SPI_APPS_CLK 117 -#define GCC_BLSP1_QUP3_I2C_APPS_CLK 118 -#define GCC_BLSP1_UART3_APPS_CLK 119 -#define GCC_BLSP1_QUP4_SPI_APPS_CLK 120 -#define GCC_BLSP1_QUP4_I2C_APPS_CLK 121 -#define GCC_BLSP1_UART4_APPS_CLK 122 -#define GCC_BLSP1_QUP5_SPI_APPS_CLK 123 -#define GCC_BLSP1_QUP5_I2C_APPS_CLK 124 -#define GCC_BLSP1_UART5_APPS_CLK 125 -#define GCC_BLSP1_QUP6_SPI_APPS_CLK 126 -#define GCC_BLSP1_QUP6_I2C_APPS_CLK 127 -#define GCC_BLSP1_UART6_APPS_CLK 128 -#define GCC_BLSP2_AHB_CLK 129 -#define GCC_BLSP2_SLEEP_CLK 130 -#define GCC_BLSP2_QUP1_SPI_APPS_CLK 131 -#define GCC_BLSP2_QUP1_I2C_APPS_CLK 132 -#define GCC_BLSP2_UART1_APPS_CLK 133 -#define GCC_BLSP2_QUP2_SPI_APPS_CLK 134 -#define GCC_BLSP2_QUP2_I2C_APPS_CLK 135 -#define GCC_BLSP2_UART2_APPS_CLK 136 -#define GCC_BLSP2_QUP3_SPI_APPS_CLK 137 -#define GCC_BLSP2_QUP3_I2C_APPS_CLK 138 -#define GCC_BLSP2_UART3_APPS_CLK 139 -#define GCC_BLSP2_QUP4_SPI_APPS_CLK 140 -#define GCC_BLSP2_QUP4_I2C_APPS_CLK 141 -#define GCC_BLSP2_UART4_APPS_CLK 142 -#define GCC_BLSP2_QUP5_SPI_APPS_CLK 143 -#define GCC_BLSP2_QUP5_I2C_APPS_CLK 144 -#define GCC_BLSP2_UART5_APPS_CLK 145 -#define GCC_BLSP2_QUP6_SPI_APPS_CLK 146 -#define GCC_BLSP2_QUP6_I2C_APPS_CLK 147 -#define GCC_BLSP2_UART6_APPS_CLK 148 -#define GCC_PDM_AHB_CLK 149 -#define GCC_PDM_XO4_CLK 150 -#define GCC_PDM2_CLK 151 -#define GCC_PRNG_AHB_CLK 152 -#define GCC_TSIF_AHB_CLK 153 -#define GCC_TSIF_REF_CLK 154 -#define GCC_TSIF_INACTIVITY_TIMERS_CLK 155 -#define GCC_TCSR_AHB_CLK 156 -#define GCC_BOOT_ROM_AHB_CLK 157 -#define GCC_MSG_RAM_AHB_CLK 158 -#define GCC_TLMM_AHB_CLK 159 -#define GCC_TLMM_CLK 160 -#define GCC_MPM_AHB_CLK 161 -#define GCC_SPMI_SER_CLK 162 -#define GCC_SPMI_CNOC_AHB_CLK 163 -#define GCC_CE1_CLK 164 -#define GCC_CE1_AXI_CLK 165 -#define GCC_CE1_AHB_CLK 166 -#define GCC_BIMC_HMSS_AXI_CLK 167 -#define GCC_BIMC_GFX_CLK 168 -#define GCC_HMSS_AHB_CLK 169 -#define GCC_HMSS_SLV_AXI_CLK 170 -#define GCC_HMSS_MSTR_AXI_CLK 171 -#define GCC_HMSS_RBCPR_CLK 172 -#define GCC_GP1_CLK 173 -#define GCC_GP2_CLK 174 -#define GCC_GP3_CLK 175 -#define GCC_PCIE_0_SLV_AXI_CLK 176 -#define GCC_PCIE_0_MSTR_AXI_CLK 177 -#define GCC_PCIE_0_CFG_AHB_CLK 178 -#define GCC_PCIE_0_AUX_CLK 179 -#define GCC_PCIE_0_PIPE_CLK 180 -#define GCC_PCIE_1_SLV_AXI_CLK 181 -#define GCC_PCIE_1_MSTR_AXI_CLK 182 -#define GCC_PCIE_1_CFG_AHB_CLK 183 -#define GCC_PCIE_1_AUX_CLK 184 -#define GCC_PCIE_1_PIPE_CLK 185 -#define GCC_PCIE_2_SLV_AXI_CLK 186 -#define GCC_PCIE_2_MSTR_AXI_CLK 187 -#define GCC_PCIE_2_CFG_AHB_CLK 188 -#define GCC_PCIE_2_AUX_CLK 189 -#define GCC_PCIE_2_PIPE_CLK 190 -#define GCC_PCIE_PHY_CFG_AHB_CLK 191 -#define GCC_PCIE_PHY_AUX_CLK 192 -#define GCC_UFS_AXI_CLK 193 -#define GCC_UFS_AHB_CLK 194 -#define GCC_UFS_TX_CFG_CLK 195 -#define GCC_UFS_RX_CFG_CLK 196 -#define GCC_UFS_TX_SYMBOL_0_CLK 197 -#define GCC_UFS_RX_SYMBOL_0_CLK 198 -#define GCC_UFS_RX_SYMBOL_1_CLK 199 -#define GCC_UFS_UNIPRO_CORE_CLK 200 -#define GCC_UFS_ICE_CORE_CLK 201 -#define GCC_UFS_SYS_CLK_CORE_CLK 202 -#define GCC_UFS_TX_SYMBOL_CLK_CORE_CLK 203 -#define GCC_AGGRE0_SNOC_AXI_CLK 204 -#define GCC_AGGRE0_CNOC_AHB_CLK 205 -#define GCC_SMMU_AGGRE0_AXI_CLK 206 -#define GCC_SMMU_AGGRE0_AHB_CLK 207 -#define GCC_AGGRE1_PNOC_AHB_CLK 208 -#define GCC_AGGRE2_UFS_AXI_CLK 209 -#define GCC_AGGRE2_USB3_AXI_CLK 210 -#define GCC_QSPI_AHB_CLK 211 -#define GCC_QSPI_SER_CLK 212 -#define GCC_USB3_CLKREF_CLK 213 -#define GCC_HDMI_CLKREF_CLK 214 -#define GCC_UFS_CLKREF_CLK 215 -#define GCC_PCIE_CLKREF_CLK 216 -#define GCC_RX2_USB2_CLKREF_CLK 217 -#define GCC_RX1_USB2_CLKREF_CLK 218 -#define GCC_AGGRE0_NOC_QOSGEN_EXTREF_CLK 219 -#define GCC_HLOS1_VOTE_LPASS_CORE_SMMU_CLK 220 -#define GCC_HLOS1_VOTE_LPASS_ADSP_SMMU_CLK 221 -#define GCC_EDP_CLKREF_CLK 222 -#define GCC_MSS_CFG_AHB_CLK 223 -#define GCC_MSS_Q6_BIMC_AXI_CLK 224 -#define GCC_MSS_SNOC_AXI_CLK 225 -#define GCC_MSS_MNOC_BIMC_AXI_CLK 226 -#define GCC_DCC_AHB_ALK 227 -#define GCC_AGGRE0_NOC_MPU_CFG_AHB_CLK 228 -#define GCC_MMSS_GPLL0_DIV_CLK 229 -#define GPLL0_OUT_MSSCC 230 +/* Hardware/Dummy/Voter clocks */ +#define GCC_XO 0 +#define GCC_CE1_AHB_M_CLK 1 +#define GCC_CE1_AXI_M_CLK 2 +#define GCC_GPLL0_EARLY_DIV 3 +#define GCC_UFS_TX_CFG_CLK_SRC 4 +#define GCC_UFS_RX_CFG_CLK_SRC 5 +#define GCC_UFS_ICE_CORE_PDIV_CLK_SRC 6 +/* RCGs and Branches */ +#define GPLL0_EARLY 7 +#define GPLL0 8 +#define GPLL4_EARLY 9 +#define GPLL4 10 +#define SYSTEM_NOC_CLK_SRC 11 +#define CONFIG_NOC_CLK_SRC 12 +#define PERIPH_NOC_CLK_SRC 13 +#define MMSS_BIMC_GFX_CLK_SRC 14 +#define USB30_MASTER_CLK_SRC 15 +#define USB30_MOCK_UTMI_CLK_SRC 16 +#define USB3_PHY_AUX_CLK_SRC 17 +#define USB20_MASTER_CLK_SRC 18 +#define USB20_MOCK_UTMI_CLK_SRC 19 +#define SDCC1_APPS_CLK_SRC 20 +#define SDCC1_ICE_CORE_CLK_SRC 21 +#define SDCC2_APPS_CLK_SRC 22 +#define SDCC3_APPS_CLK_SRC 23 +#define SDCC4_APPS_CLK_SRC 24 +#define BLSP1_QUP1_SPI_APPS_CLK_SRC 25 +#define BLSP1_QUP1_I2C_APPS_CLK_SRC 26 +#define BLSP1_UART1_APPS_CLK_SRC 27 +#define BLSP1_QUP2_SPI_APPS_CLK_SRC 28 +#define BLSP1_QUP2_I2C_APPS_CLK_SRC 29 +#define BLSP1_UART2_APPS_CLK_SRC 30 +#define BLSP1_QUP3_SPI_APPS_CLK_SRC 31 +#define BLSP1_QUP3_I2C_APPS_CLK_SRC 32 +#define BLSP1_UART3_APPS_CLK_SRC 33 +#define BLSP1_QUP4_SPI_APPS_CLK_SRC 34 +#define BLSP1_QUP4_I2C_APPS_CLK_SRC 35 +#define BLSP1_UART4_APPS_CLK_SRC 36 +#define BLSP1_QUP5_SPI_APPS_CLK_SRC 37 +#define BLSP1_QUP5_I2C_APPS_CLK_SRC 38 +#define BLSP1_UART5_APPS_CLK_SRC 39 +#define BLSP1_QUP6_SPI_APPS_CLK_SRC 40 +#define BLSP1_QUP6_I2C_APPS_CLK_SRC 41 +#define BLSP1_UART6_APPS_CLK_SRC 42 +#define BLSP2_QUP1_SPI_APPS_CLK_SRC 43 +#define BLSP2_QUP1_I2C_APPS_CLK_SRC 44 +#define BLSP2_UART1_APPS_CLK_SRC 45 +#define BLSP2_QUP2_SPI_APPS_CLK_SRC 46 +#define BLSP2_QUP2_I2C_APPS_CLK_SRC 47 +#define BLSP2_UART2_APPS_CLK_SRC 48 +#define BLSP2_QUP3_SPI_APPS_CLK_SRC 49 +#define BLSP2_QUP3_I2C_APPS_CLK_SRC 50 +#define BLSP2_UART3_APPS_CLK_SRC 51 +#define BLSP2_QUP4_SPI_APPS_CLK_SRC 52 +#define BLSP2_QUP4_I2C_APPS_CLK_SRC 53 +#define BLSP2_UART4_APPS_CLK_SRC 54 +#define BLSP2_QUP5_SPI_APPS_CLK_SRC 55 +#define BLSP2_QUP5_I2C_APPS_CLK_SRC 56 +#define BLSP2_UART5_APPS_CLK_SRC 57 +#define BLSP2_QUP6_SPI_APPS_CLK_SRC 58 +#define BLSP2_QUP6_I2C_APPS_CLK_SRC 59 +#define BLSP2_UART6_APPS_CLK_SRC 60 +#define PDM2_CLK_SRC 61 +#define TSIF_REF_CLK_SRC 62 +#define CE1_CLK_SRC 63 +#define GCC_SLEEP_CLK_SRC 64 +#define BIMC_CLK_SRC 65 +#define HMSS_AHB_CLK_SRC 66 +#define BIMC_HMSS_AXI_CLK_SRC 67 +#define HMSS_RBCPR_CLK_SRC 68 +#define HMSS_GPLL0_CLK_SRC 69 +#define GP1_CLK_SRC 70 +#define GP2_CLK_SRC 71 +#define GP3_CLK_SRC 72 +#define PCIE_AUX_CLK_SRC 73 +#define UFS_AXI_CLK_SRC 74 +#define UFS_ICE_CORE_CLK_SRC 75 +#define QSPI_SER_CLK_SRC 76 +#define GCC_SYS_NOC_AXI_CLK 77 +#define GCC_SYS_NOC_HMSS_AHB_CLK 78 +#define GCC_SNOC_CNOC_AHB_CLK 79 +#define GCC_SNOC_PNOC_AHB_CLK 80 +#define GCC_SYS_NOC_AT_CLK 81 +#define GCC_SYS_NOC_USB3_AXI_CLK 82 +#define GCC_SYS_NOC_UFS_AXI_CLK 83 +#define GCC_CFG_NOC_AHB_CLK 84 +#define GCC_PERIPH_NOC_AHB_CLK 85 +#define GCC_PERIPH_NOC_USB20_AHB_CLK 86 +#define GCC_TIC_CLK 87 +#define GCC_IMEM_AXI_CLK 88 +#define GCC_MMSS_SYS_NOC_AXI_CLK 89 +#define GCC_MMSS_NOC_CFG_AHB_CLK 90 +#define GCC_MMSS_BIMC_GFX_CLK 91 +#define GCC_USB30_MASTER_CLK 92 +#define GCC_USB30_SLEEP_CLK 93 +#define GCC_USB30_MOCK_UTMI_CLK 94 +#define GCC_USB3_PHY_AUX_CLK 95 +#define GCC_USB3_PHY_PIPE_CLK 96 +#define GCC_USB20_MASTER_CLK 97 +#define GCC_USB20_SLEEP_CLK 98 +#define GCC_USB20_MOCK_UTMI_CLK 99 +#define GCC_USB_PHY_CFG_AHB2PHY_CLK 100 +#define GCC_SDCC1_APPS_CLK 101 +#define GCC_SDCC1_AHB_CLK 102 +#define GCC_SDCC1_ICE_CORE_CLK 103 +#define GCC_SDCC2_APPS_CLK 104 +#define GCC_SDCC2_AHB_CLK 105 +#define GCC_SDCC3_APPS_CLK 106 +#define GCC_SDCC3_AHB_CLK 107 +#define GCC_SDCC4_APPS_CLK 108 +#define GCC_SDCC4_AHB_CLK 109 +#define GCC_BLSP1_AHB_CLK 110 +#define GCC_BLSP1_SLEEP_CLK 111 +#define GCC_BLSP1_QUP1_SPI_APPS_CLK 112 +#define GCC_BLSP1_QUP1_I2C_APPS_CLK 113 +#define GCC_BLSP1_UART1_APPS_CLK 114 +#define GCC_BLSP1_QUP2_SPI_APPS_CLK 115 +#define GCC_BLSP1_QUP2_I2C_APPS_CLK 116 +#define GCC_BLSP1_UART2_APPS_CLK 117 +#define GCC_BLSP1_QUP3_SPI_APPS_CLK 118 +#define GCC_BLSP1_QUP3_I2C_APPS_CLK 119 +#define GCC_BLSP1_UART3_APPS_CLK 120 +#define GCC_BLSP1_QUP4_SPI_APPS_CLK 121 +#define GCC_BLSP1_QUP4_I2C_APPS_CLK 122 +#define GCC_BLSP1_UART4_APPS_CLK 123 +#define GCC_BLSP1_QUP5_SPI_APPS_CLK 124 +#define GCC_BLSP1_QUP5_I2C_APPS_CLK 125 +#define GCC_BLSP1_UART5_APPS_CLK 126 +#define GCC_BLSP1_QUP6_SPI_APPS_CLK 127 +#define GCC_BLSP1_QUP6_I2C_APPS_CLK 128 +#define GCC_BLSP1_UART6_APPS_CLK 129 +#define GCC_BLSP2_AHB_CLK 130 +#define GCC_BLSP2_SLEEP_CLK 131 +#define GCC_BLSP2_QUP1_SPI_APPS_CLK 132 +#define GCC_BLSP2_QUP1_I2C_APPS_CLK 133 +#define GCC_BLSP2_UART1_APPS_CLK 134 +#define GCC_BLSP2_QUP2_SPI_APPS_CLK 135 +#define GCC_BLSP2_QUP2_I2C_APPS_CLK 136 +#define GCC_BLSP2_UART2_APPS_CLK 137 +#define GCC_BLSP2_QUP3_SPI_APPS_CLK 138 +#define GCC_BLSP2_QUP3_I2C_APPS_CLK 139 +#define GCC_BLSP2_UART3_APPS_CLK 140 +#define GCC_BLSP2_QUP4_SPI_APPS_CLK 141 +#define GCC_BLSP2_QUP4_I2C_APPS_CLK 142 +#define GCC_BLSP2_UART4_APPS_CLK 143 +#define GCC_BLSP2_QUP5_SPI_APPS_CLK 144 +#define GCC_BLSP2_QUP5_I2C_APPS_CLK 145 +#define GCC_BLSP2_UART5_APPS_CLK 146 +#define GCC_BLSP2_QUP6_SPI_APPS_CLK 147 +#define GCC_BLSP2_QUP6_I2C_APPS_CLK 148 +#define GCC_BLSP2_UART6_APPS_CLK 149 +#define GCC_PDM_AHB_CLK 150 +#define GCC_PDM_XO4_CLK 151 +#define GCC_PDM2_CLK 152 +#define GCC_PRNG_AHB_CLK 153 +#define GCC_TSIF_AHB_CLK 154 +#define GCC_TSIF_REF_CLK 155 +#define GCC_TSIF_INACTIVITY_TIMERS_CLK 156 +#define GCC_TCSR_AHB_CLK 157 +#define GCC_BOOT_ROM_AHB_CLK 158 +#define GCC_MSG_RAM_AHB_CLK 159 +#define GCC_TLMM_AHB_CLK 160 +#define GCC_TLMM_CLK 161 +#define GCC_MPM_AHB_CLK 162 +#define GCC_SPMI_SER_CLK 163 +#define GCC_SPMI_CNOC_AHB_CLK 164 +#define GCC_BIMC_HMSS_AXI_CLK 165 +#define GCC_BIMC_GFX_CLK 166 +#define GCC_HMSS_AHB_CLK 167 +#define GCC_HMSS_SLV_AXI_CLK 168 +#define GCC_HMSS_MSTR_AXI_CLK 169 +#define GCC_HMSS_RBCPR_CLK 170 +#define GCC_GP1_CLK 171 +#define GCC_GP2_CLK 172 +#define GCC_GP3_CLK 173 +#define GCC_PCIE_0_SLV_AXI_CLK 174 +#define GCC_PCIE_0_MSTR_AXI_CLK 175 +#define GCC_PCIE_0_CFG_AHB_CLK 176 +#define GCC_PCIE_0_AUX_CLK 177 +#define GCC_PCIE_0_PIPE_CLK 178 +#define GCC_PCIE_1_SLV_AXI_CLK 179 +#define GCC_PCIE_1_MSTR_AXI_CLK 180 +#define GCC_PCIE_1_CFG_AHB_CLK 181 +#define GCC_PCIE_1_AUX_CLK 182 +#define GCC_PCIE_1_PIPE_CLK 183 +#define GCC_PCIE_2_SLV_AXI_CLK 184 +#define GCC_PCIE_2_MSTR_AXI_CLK 185 +#define GCC_PCIE_2_CFG_AHB_CLK 186 +#define GCC_PCIE_2_AUX_CLK 187 +#define GCC_PCIE_2_PIPE_CLK 188 +#define GCC_PCIE_PHY_CFG_AHB_CLK 189 +#define GCC_PCIE_PHY_AUX_CLK 190 +#define GCC_UFS_AXI_CLK 191 +#define GCC_UFS_AHB_CLK 192 +#define GCC_UFS_TX_CFG_CLK 193 +#define GCC_UFS_RX_CFG_CLK 194 +#define GCC_UFS_TX_SYMBOL_0_CLK 195 +#define GCC_UFS_RX_SYMBOL_0_CLK 196 +#define GCC_UFS_RX_SYMBOL_1_CLK 197 +#define GCC_UFS_UNIPRO_CORE_CLK 198 +#define GCC_UFS_ICE_CORE_CLK 199 +#define GCC_UFS_SYS_CLK_CORE_CLK 200 +#define GCC_UFS_TX_SYMBOL_CLK_CORE_CLK 201 +#define GCC_AGGRE0_SNOC_AXI_CLK 202 +#define GCC_AGGRE0_CNOC_AHB_CLK 203 +#define GCC_SMMU_AGGRE0_AXI_CLK 204 +#define GCC_SMMU_AGGRE0_AHB_CLK 205 +#define GCC_AGGRE2_UFS_AXI_CLK 206 +#define GCC_AGGRE2_USB3_AXI_CLK 207 +#define GCC_QSPI_AHB_CLK 208 +#define GCC_QSPI_SER_CLK 209 +#define GCC_USB3_CLKREF_CLK 210 +#define GCC_HDMI_CLKREF_CLK 211 +#define GCC_UFS_CLKREF_CLK 212 +#define GCC_PCIE_CLKREF_CLK 213 +#define GCC_RX2_USB2_CLKREF_CLK 214 +#define GCC_RX1_USB2_CLKREF_CLK 215 +#define GCC_AGGRE0_NOC_QOSGEN_EXTREF_CLK 216 +#define GCC_HLOS1_VOTE_LPASS_CORE_SMMU_CLK 217 +#define GCC_HLOS1_VOTE_LPASS_ADSP_SMMU_CLK 218 +#define GCC_EDP_CLKREF_CLK 219 +#define GCC_MSS_CFG_AHB_CLK 220 +#define GCC_MSS_Q6_BIMC_AXI_CLK 221 +#define GCC_MSS_SNOC_AXI_CLK 222 +#define GCC_MSS_MNOC_BIMC_AXI_CLK 223 +#define GCC_DCC_AHB_CLK 224 +#define GCC_AGGRE0_NOC_MPU_CFG_AHB_CLK 225 +#define GCC_MMSS_GPLL0_DIV_CLK 226 +#define GPLL0_OUT_MSSCC_CLK 227 + +/* Block resets */ #define GCC_SYSTEM_NOC_BCR 0 #define GCC_CONFIG_NOC_BCR 1 #define GCC_PERIPH_NOC_BCR 2 diff --git a/include/dt-bindings/clock/qcom,rpmcc.h b/include/dt-bindings/clock/qcom,rpmcc.h index bcaa1a552e8e..0f0c6300642c 100644 --- a/include/dt-bindings/clock/qcom,rpmcc.h +++ b/include/dt-bindings/clock/qcom,rpmcc.h @@ -128,5 +128,6 @@ #define CXO_PIL_SSC_CLK 83 #define CXO_PIL_CDSP_CLK 84 #define CNOC_PERIPH_KEEPALIVE_A_CLK 85 +#define MMSSNOC_A_CLK_CPU_VOTE 86 #endif diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 744167a9ca8b..f91991b97888 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -33,6 +33,9 @@ #define CLK_GET_ACCURACY_NOCACHE BIT(8) /* do not use the cached clk accuracy */ #define CLK_RECALC_NEW_RATES BIT(9) /* recalc rates after notifications */ #define CLK_IS_CRITICAL BIT(11) /* do not gate, ever */ +#define CLK_ENABLE_HAND_OFF BIT(12) /* enable clock when registered. + hand-off enable_count & prepare_count + to first consumer that enables clk */ #define CLK_IS_MEASURE BIT(14) /* measure clock */ struct clk; diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index 9b6359241018..20280ff20e52 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h @@ -227,6 +227,7 @@ enum power_supply_property { POWER_SUPPLY_PROP_PARALLEL_PERCENT, POWER_SUPPLY_PROP_PE_START, POWER_SUPPLY_PROP_SET_SHIP_MODE, + POWER_SUPPLY_PROP_SOC_REPORTING_READY, /* Local extensions of type int64_t */ POWER_SUPPLY_PROP_CHARGE_COUNTER_EXT, /* Properties of type `const char *' */ diff --git a/include/uapi/linux/msm_mdp.h b/include/uapi/linux/msm_mdp.h index 20b879c2e5fc..4df3845c159c 100644 --- a/include/uapi/linux/msm_mdp.h +++ b/include/uapi/linux/msm_mdp.h @@ -118,6 +118,7 @@ #define MDSS_MDP_HW_REV_116 MDSS_MDP_REV(1, 16, 0) /* msmtitanium */ #define MDSS_MDP_HW_REV_300 MDSS_MDP_REV(3, 0, 0) /* msm8998 */ #define MDSS_MDP_HW_REV_301 MDSS_MDP_REV(3, 0, 1) /* msm8998 v1.0 */ +#define MDSS_MDP_HW_REV_320 MDSS_MDP_REV(3, 2, 0) /* msmfalcon */ enum { NOTIFY_UPDATE_INIT, diff --git a/kernel/trace/msm_rtb.c b/kernel/trace/msm_rtb.c index ba609d5eb07f..80058b544cb5 100644 --- a/kernel/trace/msm_rtb.c +++ b/kernel/trace/msm_rtb.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -27,6 +27,7 @@ #include #include #include +#include #define SENTINEL_BYTE_1 0xFF #define SENTINEL_BYTE_2 0xAA @@ -41,8 +42,9 @@ * 4) 4 bytes index * 4) 8 bytes extra data from the caller * 5) 8 bytes of timestamp + * 6) 8 bytes of cyclecount * - * Total = 32 bytes. + * Total = 40 bytes. */ struct msm_rtb_layout { unsigned char sentinel[3]; @@ -51,6 +53,7 @@ struct msm_rtb_layout { uint64_t caller; uint64_t data; uint64_t timestamp; + uint64_t cycle_count; } __attribute__ ((__packed__)); @@ -132,6 +135,11 @@ static void msm_rtb_write_timestamp(struct msm_rtb_layout *start) start->timestamp = sched_clock(); } +static void msm_rtb_write_cyclecount(struct msm_rtb_layout *start) +{ + start->cycle_count = get_cycles(); +} + static void uncached_logk_pc_idx(enum logk_event_type log_type, uint64_t caller, uint64_t data, int idx) { @@ -145,6 +153,7 @@ static void uncached_logk_pc_idx(enum logk_event_type log_type, uint64_t caller, msm_rtb_write_idx(idx, start); msm_rtb_write_data(data, start); msm_rtb_write_timestamp(start); + msm_rtb_write_cyclecount(start); mb(); return; diff --git a/sound/soc/codecs/wcd934x/wcd934x-mbhc.c b/sound/soc/codecs/wcd934x/wcd934x-mbhc.c index 5dbdb9a2df00..0e0c26dc72cd 100644 --- a/sound/soc/codecs/wcd934x/wcd934x-mbhc.c +++ b/sound/soc/codecs/wcd934x/wcd934x-mbhc.c @@ -905,6 +905,29 @@ static const struct snd_kcontrol_new impedance_detect_controls[] = { tavil_hph_impedance_get, NULL), }; +/* + * tavil_mbhc_get_impedance: get impedance of headphone left and right channels + * @wcd934x_mbhc: handle to struct wcd934x_mbhc * + * @zl: handle to left-ch impedance + * @zr: handle to right-ch impedance + * return 0 for success or error code in case of failure + */ +int tavil_mbhc_get_impedance(struct wcd934x_mbhc *wcd934x_mbhc, + uint32_t *zl, uint32_t *zr) +{ + if (!wcd934x_mbhc) { + pr_err("%s: mbhc not initialized!\n", __func__); + return -EINVAL; + } + if (!zl || !zr) { + pr_err("%s: zl or zr null!\n", __func__); + return -EINVAL; + } + + return wcd_mbhc_get_impedance(&wcd934x_mbhc->wcd_mbhc, zl, zr); +} +EXPORT_SYMBOL(tavil_mbhc_get_impedance); + /* * tavil_mbhc_hs_detect: starts mbhc insertion/removal functionality * @codec: handle to snd_soc_codec * diff --git a/sound/soc/codecs/wcd934x/wcd934x-mbhc.h b/sound/soc/codecs/wcd934x/wcd934x-mbhc.h index 3c88a12194af..0b27f3f62b02 100644 --- a/sound/soc/codecs/wcd934x/wcd934x-mbhc.h +++ b/sound/soc/codecs/wcd934x/wcd934x-mbhc.h @@ -44,6 +44,8 @@ extern int tavil_mbhc_hs_detect(struct snd_soc_codec *codec, extern void tavil_mbhc_deinit(struct snd_soc_codec *codec); extern int tavil_mbhc_post_ssr_init(struct wcd934x_mbhc *mbhc, struct snd_soc_codec *codec); +extern int tavil_mbhc_get_impedance(struct wcd934x_mbhc *wcd934x_mbhc, + uint32_t *zl, uint32_t *zr); #endif /* __WCD934X_MBHC_H__ */ diff --git a/sound/soc/codecs/wcd934x/wcd934x.c b/sound/soc/codecs/wcd934x/wcd934x.c index 8be608c8511c..9b45db43ffb2 100644 --- a/sound/soc/codecs/wcd934x/wcd934x.c +++ b/sound/soc/codecs/wcd934x/wcd934x.c @@ -175,6 +175,7 @@ enum { VI_SENSE_2, AUDIO_NOMINAL, HPH_PA_DELAY, + CLSH_Z_CONFIG, }; enum { @@ -2241,6 +2242,7 @@ static int tavil_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, u8 dem_inp; int ret = 0; struct tavil_dsd_config *dsd_conf = tavil->dsd_config; + uint32_t impedl = 0, impedr = 0; dev_dbg(codec->dev, "%s wname: %s event: %d hph_mode: %d\n", __func__, w->name, event, hph_mode); @@ -2277,6 +2279,18 @@ static int tavil_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, WCD_CLSH_EVENT_PRE_DAC, WCD_CLSH_STATE_HPHL, hph_mode); + + ret = tavil_mbhc_get_impedance(tavil->mbhc, + &impedl, &impedr); + if (!ret) { + wcd_clsh_imped_config(codec, impedl, false); + set_bit(CLSH_Z_CONFIG, &tavil->status_mask); + } else { + dev_dbg(codec->dev, "%s: Failed to get mbhc impedance %d\n", + __func__, ret); + ret = 0; + } + break; case SND_SOC_DAPM_POST_PMD: /* 1000us required as per HW requirement */ @@ -2295,6 +2309,11 @@ static int tavil_codec_hphl_dac_event(struct snd_soc_dapm_widget *w, snd_soc_update_bits(codec, WCD934X_HPH_NEW_INT_RDAC_GAIN_CTL, 0xF0, 0x0); + + if (test_bit(CLSH_Z_CONFIG, &tavil->status_mask)) { + wcd_clsh_imped_config(codec, impedl, true); + clear_bit(CLSH_Z_CONFIG, &tavil->status_mask); + } break; default: break; @@ -5107,19 +5126,18 @@ static int tavil_amic_pwr_lvl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); - u16 amic_reg; + u16 amic_reg = 0; if (!strcmp(kcontrol->id.name, "AMIC_1_2 PWR MODE")) amic_reg = WCD934X_ANA_AMIC1; if (!strcmp(kcontrol->id.name, "AMIC_3_4 PWR MODE")) amic_reg = WCD934X_ANA_AMIC3; - else - goto ret; - ucontrol->value.integer.value[0] = - (snd_soc_read(codec, amic_reg) & WCD934X_AMIC_PWR_LVL_MASK) >> - WCD934X_AMIC_PWR_LVL_SHIFT; -ret: + if (amic_reg) + ucontrol->value.integer.value[0] = + (snd_soc_read(codec, amic_reg) & + WCD934X_AMIC_PWR_LVL_MASK) >> + WCD934X_AMIC_PWR_LVL_SHIFT; return 0; } @@ -5128,7 +5146,7 @@ static int tavil_amic_pwr_lvl_put(struct snd_kcontrol *kcontrol, { struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); u32 mode_val; - u16 amic_reg; + u16 amic_reg = 0; mode_val = ucontrol->value.enumerated.item[0]; @@ -5138,12 +5156,10 @@ static int tavil_amic_pwr_lvl_put(struct snd_kcontrol *kcontrol, amic_reg = WCD934X_ANA_AMIC1; if (!strcmp(kcontrol->id.name, "AMIC_3_4 PWR MODE")) amic_reg = WCD934X_ANA_AMIC3; - else - goto ret; - snd_soc_update_bits(codec, amic_reg, WCD934X_AMIC_PWR_LVL_MASK, - mode_val << WCD934X_AMIC_PWR_LVL_SHIFT); -ret: + if (amic_reg) + snd_soc_update_bits(codec, amic_reg, WCD934X_AMIC_PWR_LVL_MASK, + mode_val << WCD934X_AMIC_PWR_LVL_SHIFT); return 0; } diff --git a/sound/soc/msm/msmfalcon-common.c b/sound/soc/msm/msmfalcon-common.c index e705fa8faf73..013127c48984 100644 --- a/sound/soc/msm/msmfalcon-common.c +++ b/sound/soc/msm/msmfalcon-common.c @@ -2797,6 +2797,8 @@ err: pdata->hph_en0_gpio = 0; } devm_kfree(&pdev->dev, pdata); + if (pdata->snd_card_val != INT_SND_CARD) + msm_ext_cdc_deinit(); return ret; } @@ -2807,6 +2809,8 @@ static int msm_asoc_machine_remove(struct platform_device *pdev) if (pdata->snd_card_val == INT_SND_CARD) mutex_destroy(&pdata->cdc_int_mclk0_mutex); + else + msm_ext_cdc_deinit(); msm_free_auxdev_mem(pdev); gpio_free(pdata->us_euro_gpio); diff --git a/sound/soc/msm/msmfalcon-external.c b/sound/soc/msm/msmfalcon-external.c index 3934c50c48a9..ef0b23e2e51e 100644 --- a/sound/soc/msm/msmfalcon-external.c +++ b/sound/soc/msm/msmfalcon-external.c @@ -35,6 +35,22 @@ #define CODEC_EXT_CLK_RATE 9600000 #define ADSP_STATE_READY_TIMEOUT_MS 3000 +#define TLMM_CENTER_MPM_WAKEUP_INT_EN_0 0x03596000 +#define LPI_GPIO_22_WAKEUP_VAL 0x00000002 + +#define TLMM_LPI_DIR_CONN_INTR1_CFG_APPS 0x0359D004 +#define LPI_GPIO_22_INTR1_CFG_VAL 0x01 +#define LPI_GPIO_22_INTR1_CFG_MASK 0x03 + +#define TLMM_LPI_GPIO_INTR_CFG1 0x0359B004 +#define LPI_GPIO_INTR_CFG1_VAL 0x00000113 + +#define TLMM_LPI_GPIO22_CFG 0x15078040 +#define LPI_GPIO22_CFG_VAL 0x0000009 + +#define TLMM_LPI_GPIO22_INOUT 0x15078044 +#define LPI_GPIO22_INOUT_VAL 0x00000000 + #define WSA8810_NAME_1 "wsa881x.20170211" #define WSA8810_NAME_2 "wsa881x.20170212" @@ -50,6 +66,16 @@ struct msm_asoc_wcd93xx_codec { static struct msm_asoc_wcd93xx_codec msm_codec_fn; static struct platform_device *spdev; +struct msm_snd_interrupt { + void __iomem *mpm_wakeup; + void __iomem *intr1_cfg_apps; + void __iomem *lpi_gpio_intr_cfg; + void __iomem *lpi_gpio_cfg; + void __iomem *lpi_gpio_inout; +}; + +static struct msm_snd_interrupt msm_snd_intr_lpi; + static bool is_initial_boot; static void *def_ext_mbhc_cal(void); @@ -1193,6 +1219,27 @@ static void msm_afe_clear_config(void) afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG); } +static void msm_snd_interrupt_config(void) +{ + int val; + + val = ioread32(msm_snd_intr_lpi.mpm_wakeup); + val |= LPI_GPIO_22_WAKEUP_VAL; + iowrite32(val, msm_snd_intr_lpi.mpm_wakeup); + + val = ioread32(msm_snd_intr_lpi.intr1_cfg_apps); + val &= ~(LPI_GPIO_22_INTR1_CFG_MASK); + val |= LPI_GPIO_22_INTR1_CFG_VAL; + iowrite32(val, msm_snd_intr_lpi.intr1_cfg_apps); + + iowrite32(LPI_GPIO_INTR_CFG1_VAL, + msm_snd_intr_lpi.lpi_gpio_intr_cfg); + iowrite32(LPI_GPIO22_CFG_VAL, + msm_snd_intr_lpi.lpi_gpio_cfg); + iowrite32(LPI_GPIO22_INOUT_VAL, + msm_snd_intr_lpi.lpi_gpio_inout); +} + static int msm_adsp_power_up_config(struct snd_soc_codec *codec) { int ret = 0; @@ -1221,6 +1268,7 @@ static int msm_adsp_power_up_config(struct snd_soc_codec *codec) ret = -ETIMEDOUT; goto err_fail; } + msm_snd_interrupt_config(); ret = msm_afe_set_config(codec); if (ret) @@ -1759,7 +1807,35 @@ int msm_ext_cdc_init(struct platform_device *pdev, ret); ret = 0; } + msm_snd_intr_lpi.mpm_wakeup = + ioremap(TLMM_CENTER_MPM_WAKEUP_INT_EN_0, 4); + msm_snd_intr_lpi.intr1_cfg_apps = + ioremap(TLMM_LPI_DIR_CONN_INTR1_CFG_APPS, 4); + msm_snd_intr_lpi.lpi_gpio_intr_cfg = + ioremap(TLMM_LPI_GPIO_INTR_CFG1, 4); + msm_snd_intr_lpi.lpi_gpio_cfg = + ioremap(TLMM_LPI_GPIO22_CFG, 4); + msm_snd_intr_lpi.lpi_gpio_inout = + ioremap(TLMM_LPI_GPIO22_INOUT, 4); err: return ret; } EXPORT_SYMBOL(msm_ext_cdc_init); + +/** + * msm_ext_cdc_deinit - external codec machine specific deinit. + */ +void msm_ext_cdc_deinit(void) +{ + if (msm_snd_intr_lpi.mpm_wakeup) + iounmap(msm_snd_intr_lpi.mpm_wakeup); + if (msm_snd_intr_lpi.intr1_cfg_apps) + iounmap(msm_snd_intr_lpi.intr1_cfg_apps); + if (msm_snd_intr_lpi.lpi_gpio_intr_cfg) + iounmap(msm_snd_intr_lpi.lpi_gpio_intr_cfg); + if (msm_snd_intr_lpi.lpi_gpio_cfg) + iounmap(msm_snd_intr_lpi.lpi_gpio_cfg); + if (msm_snd_intr_lpi.lpi_gpio_inout) + iounmap(msm_snd_intr_lpi.lpi_gpio_inout); +} +EXPORT_SYMBOL(msm_ext_cdc_deinit); diff --git a/sound/soc/msm/msmfalcon-external.h b/sound/soc/msm/msmfalcon-external.h index 654cb70b9c84..fc82b628dfac 100644 --- a/sound/soc/msm/msmfalcon-external.h +++ b/sound/soc/msm/msmfalcon-external.h @@ -34,6 +34,7 @@ int msm_ext_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, int msm_ext_cdc_init(struct platform_device *, struct msm_asoc_mach_data *, struct snd_soc_card **, struct wcd_mbhc_config *); void msm_ext_register_audio_notifier(void); +void msm_ext_cdc_deinit(void); #else inline int msm_ext_cdc_init(struct platform_device *pdev, struct msm_asoc_mach_data *pdata, @@ -46,5 +47,8 @@ inline int msm_ext_cdc_init(struct platform_device *pdev, inline void msm_ext_register_audio_notifier(void) { } +inline void msm_ext_cdc_deinit(void) +{ +} #endif #endif diff --git a/sound/soc/msm/qdsp6v2/msm-dai-slim.c b/sound/soc/msm/qdsp6v2/msm-dai-slim.c index 7c56f4ad8884..43a27eb35a44 100644 --- a/sound/soc/msm/qdsp6v2/msm-dai-slim.c +++ b/sound/soc/msm/qdsp6v2/msm-dai-slim.c @@ -314,7 +314,7 @@ static int msm_dai_slim_prepare(struct snd_pcm_substream *substream, struct msm_slim_dai_data *dai_data = NULL; struct slim_ch prop; int rc; - u8 i, j; + u8 i; dai_data = msm_slim_get_dai_data(drv_data, dai); if (!dai_data) { @@ -331,6 +331,13 @@ static int msm_dai_slim_prepare(struct snd_pcm_substream *substream, return -EINVAL; } + if (dai_data->status & DAI_STATE_PREPARED) { + dev_dbg(dai->dev, + "%s: dai id (%d) has already prepared.\n", + __func__, dai->id); + return 0; + } + dma_data = &dai_data->dma_data; snd_soc_dai_set_dma_data(dai, substream, dma_data); @@ -344,6 +351,10 @@ static int msm_dai_slim_prepare(struct snd_pcm_substream *substream, } } + /* To decrement the channel ref count*/ + for (i = 0; i < dai_data->ch_cnt; i++) + slim_dealloc_ch(drv_data->sdev, dai_data->chan_h[i]); + prop.prot = SLIM_AUTO_ISO; prop.baser = SLIM_RATE_4000HZ; prop.dataf = SLIM_CH_DATAF_NOT_DEFINED; @@ -367,8 +378,6 @@ static int msm_dai_slim_prepare(struct snd_pcm_substream *substream, error_define_chan: error_chan_query: - for (j = 0; j < i; j++) - slim_dealloc_ch(drv_data->sdev, dai_data->chan_h[j]); return rc; } @@ -378,7 +387,6 @@ static void msm_dai_slim_shutdown(struct snd_pcm_substream *stream, struct msm_dai_slim_drv_data *drv_data = dev_get_drvdata(dai->dev); struct msm_slim_dma_data *dma_data = NULL; struct msm_slim_dai_data *dai_data; - int i, rc = 0; dai_data = msm_slim_get_dai_data(drv_data, dai); dma_data = snd_soc_dai_get_dma_data(dai, stream); @@ -397,15 +405,6 @@ static void msm_dai_slim_shutdown(struct snd_pcm_substream *stream, return; } - for (i = 0; i < dai_data->ch_cnt; i++) { - rc = slim_dealloc_ch(drv_data->sdev, dai_data->chan_h[i]); - if (rc) { - dev_err(dai->dev, - "%s: dealloc_ch failed, err = %d\n", - __func__, rc); - } - } - snd_soc_dai_set_dma_data(dai, stream, NULL); /* clear prepared state for the dai */ CLR_DAI_STATE(dai_data->status, DAI_STATE_PREPARED);