Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 35e3dabd authored by Linux Build Service Account's avatar Linux Build Service Account
Browse files

Promotion of kernel.lnx.4.4-160726.

CRs      Change ID                                   Subject
--------------------------------------------------------------------------------------------------------------
1021659   I322b9b57ec89f5cdc75336d83010ff89a6bb5726   ARM: dts: msm: update frequency to ACC level mappings fo
1043040   I9499497cb558efcf3c73e7145ce65d3f129be696   clk: osm: msm: add support for DxFSM workaround
1021656   Icf4b640ec2c330b0d9721d3494297e2d8445c9b6   regulator: cprh-kbss-regulator: add support for APM cros
1045435   I5e41ce376c694736128ceb051db86f93467fdaea   clk: msm: osm: add workaround for C2D/C3 + D2D collapse
1021656 1030444   Iebeb45eaa2503bd5be19f00938d0dbec1163c5a5   ARM: dts: msm: specify APM threshold voltage in OSM for
1039560   Id2811c67a423c82201993b3119647a3d4caf4517   ARM: dts: msm: put ipa3 in smmu s1-bypass on msmcobalt
1021659   I178fb226f4eec4c188f11e9e868a575c70ad58ae   clk: msm: osm: support PLL droop detector workaround
1021656 1030444   Iac04f6db8e85b3651a33b6c9bff667365cae891d   clk: msm: osm: add support for APM crossover corner

Change-Id: Idedae9661ff2343e37e898c5ae0ef53420055c78
CRs-Fixed: 1039560, 1030444, 1021656, 1043040, 1021659, 1045435
parents 6385cefa bb02457c
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -182,6 +182,14 @@ Properties:
		    command register for each of the two clusters managed
		    by the OSM controller.

- qcom,apm-threshold-voltage
	Usage:      required
	Value type: <u32>
	Definition: Specifies the APM threshold voltage in microvolts.  If the
		    VDD_APCC supply voltage is above or at this level, then the
		    APM is switched to use VDD_APCC.  If VDD_APCC is below
		    this level, then the APM is switched to use VDD_MX.

- qcom,apm-mode-ctl
	Usage:      required
	Value type: <prop-encoded-array>
@@ -392,6 +400,8 @@ Example:
		qcom,apm-ctrl-status =
			<0x179d000c 0x179d0018>;

		qcom,apm-threshold-voltage = <832000>;

		qcom,pwrcl-apcs-mem-acc-cfg =
			<0x179d1360 0x179d1364 0x179d1364>;
		qcom,perfcl-apcs-mem-acc-cfg =
+15 −4
Original line number Diff line number Diff line
@@ -42,10 +42,21 @@ KBSS specific properties:
- qcom,apm-threshold-voltage
	Usage:      optional
	Value type: <u32>
	Definition: Specifies the APM threshold voltage in microvolts.  If the
		    VDD_APCC supply voltage is above this level, then the APM is
		    switched to use VDD_APCC.  If VDD_APCC is below this level,
		    then the APM is switched to use VDD_MX.
	Definition: Specifies the APM threshold voltage in microvolts.  The
		    floor to ceiling range for every corner is adjusted to ensure
		    it does not intersect this voltage. The value of this property
		    must match with the APM threshold voltage defined in the OSM
		    device to ensure that if the VDD_APCC supply voltage is above
		    this level, then the APM is switched to use VDD_APCC and if
		    VDD_APCC is below this level, then the APM is switched to use
		    VDD_MX.

- qcom,apm-crossover-voltage
	Usage:      required if qcom,apm-threshold-voltage is specified
	Value type: <u32>
	Definition: Specifies the APM crossover voltage in microvolts which
		    corresponds to the voltage the VDD supply must be set at
		    during an APM switch transition.

- qcom,apm-hysteresis-voltage
	Usage:      optional
+2 −0
Original line number Diff line number Diff line
@@ -576,6 +576,7 @@
		qcom,cpr-voltage-settling-time = <1760>;

		qcom,apm-threshold-voltage = <832000>;
		qcom,apm-crossover-voltage = <880000>;
		qcom,apm-hysteresis-voltage = <32000>;
		qcom,voltage-step = <4000>;
		qcom,voltage-base = <352000>;
@@ -737,6 +738,7 @@
		qcom,cpr-voltage-settling-time = <1760>;

		qcom,apm-threshold-voltage = <832000>;
		qcom,apm-crossover-voltage = <880000>;
		qcom,apm-hysteresis-voltage = <32000>;
		qcom,voltage-step = <4000>;
		qcom,voltage-base = <352000>;
+41 −21
Original line number Diff line number Diff line
@@ -804,21 +804,21 @@
			<   576000000 0x0504001e 0x03200020 0x1 >,
			<   633600000 0x05040021 0x03200020 0x1 >,
			<   710400000 0x05040025 0x03200020 0x1 >,
			<   806400000 0x0504002a 0x04200020 0x2 >,
			<   883200000 0x0404002e 0x04250025 0x2 >,
			<   960000000 0x04040032 0x05280028 0x2 >,
			<  1036800000 0x04040036 0x052b002b 0x3 >,
			<  1113600000 0x0404003a 0x052e002e 0x3 >,
			<  1190400000 0x0404003e 0x06320032 0x3 >,
			<  1248000000 0x04040041 0x06340034 0x3 >,
			<  1324800000 0x04040045 0x06370037 0x3 >,
			<  1401600000 0x04040049 0x073a003a 0x3 >,
			<  1478400000 0x0404004d 0x073e003e 0x3 >,
			<  1574400000 0x04040052 0x08420042 0x4 >,
			<  1651200000 0x04040056 0x08450045 0x4 >,
			<  1728000000 0x0404005a 0x08480048 0x4 >,
			<  1804800000 0x0404005e 0x094b004b 0x4 >,
			<  1881600000 0x04040062 0x094e004e 0x4 >;
			<   806400000 0x0504002a 0x04200020 0x1 >,
			<   883200000 0x0404002e 0x04250025 0x1 >,
			<   960000000 0x04040032 0x05280028 0x1 >,
			<  1036800000 0x04040036 0x052b002b 0x2 >,
			<  1113600000 0x0404003a 0x052e002e 0x2 >,
			<  1190400000 0x0404003e 0x06320032 0x2 >,
			<  1248000000 0x04040041 0x06340034 0x2 >,
			<  1324800000 0x04040045 0x06370037 0x2 >,
			<  1401600000 0x04040049 0x073a003a 0x2 >,
			<  1478400000 0x0404004d 0x073e003e 0x2 >,
			<  1574400000 0x04040052 0x08420042 0x3 >,
			<  1651200000 0x04040056 0x08450045 0x3 >,
			<  1728000000 0x0404005a 0x08480048 0x3 >,
			<  1804800000 0x0404005e 0x094b004b 0x3 >,
			<  1881600000 0x04040062 0x094e004e 0x3 >;

		qcom,perfcl-speedbin0-v0 =
			<   300000000 0x0004000f 0x01200020 0x1 >,
@@ -888,6 +888,7 @@
			<0x8fff0036 0x8fff003a 0x0fff0036>,
			<0x8fff003d 0x8fff0041 0x0fff003d>;

		qcom,apm-threshold-voltage = <832000>;
		qcom,boost-fsm-en;
		qcom,safe-fsm-en;
		qcom,ps-fsm-en;
@@ -900,13 +901,11 @@
		qcom,perfcl-apcs-mem-acc-cfg =
			<0x179d1368 0x179d136C 0x179d1370>;
		qcom,pwrcl-apcs-mem-acc-val =
			<0x00000000 0x10000000 0x10000000>,
			<0x00000000 0x10000000 0x10000000>,
			<0x00000000 0x80000000 0x80000000>,
			<0x00000000 0x00000000 0x00000000>,
			<0x00000000 0x00000001 0x00000001>;
		qcom,perfcl-apcs-mem-acc-val =
			<0x00000000 0x00000000 0x10000000>,
			<0x00000000 0x00000000 0x10000000>,
			<0x00000000 0x00000000 0x80000000>,
			<0x00000000 0x00000000 0x00000000>,
			<0x00000000 0x00000000 0x00000001>;

@@ -966,8 +965,12 @@
		qcom,do-not-use-ch-gsi-20;
		qcom,ipa-wdi2;
		qcom,use-64-bit-dma-mask;
		clock-names = "core_clk";
		clocks = <&clock_gcc clk_ipa_clk>;
		clocks = <&clock_gcc clk_ipa_clk>,
			<&clock_gcc clk_aggre2_noc_clk>;
		clock-names = "core_clk", "smmu_clk";
		qcom,arm-smmu;
		qcom,smmu-disable-htw;
		qcom,smmu-s1-bypass;
		qcom,msm-bus,name = "ipa";
		qcom,msm-bus,num-cases = <4>;
		qcom,msm-bus,num-paths = <3>;
@@ -1074,6 +1077,23 @@
			compatible = "qcom,smp2pgpio-map-ipa-1-in";
			gpios = <&smp2pgpio_ipa_1_in 0 0>;
		};

		ipa_smmu_ap: ipa_smmu_ap {
			compatible = "qcom,ipa-smmu-ap-cb";
			iommus = <&anoc2_smmu 0x18e0>;
			qcom,iova-mapping = <0x10000000 0x40000000>;
		};

		ipa_smmu_wlan: ipa_smmu_wlan {
			compatible = "qcom,ipa-smmu-wlan-cb";
			iommus = <&anoc2_smmu 0x18e1>;
		};

		ipa_smmu_uc: ipa_smmu_uc {
			compatible = "qcom,ipa-smmu-uc-cb";
			iommus = <&anoc2_smmu 0x18e2>;
			qcom,iova-mapping = <0x40000000 0x20000000>;
		};
	};

	qcom,ipa_fws@1e08000 {
+241 −92
Original line number Diff line number Diff line
@@ -75,8 +75,7 @@ enum clk_osm_trace_packet_id {
#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) \
	((n) < 8 ? SEQ_REG(4 + (n)) : SEQ_REG(60 + (n) - 8))
#define MEM_ACC_SEQ_REG_VAL_START(n) (SEQ_REG(60 + (n)))

#define OSM_TABLE_SIZE 40
#define MAX_CLUSTER_CNT 2
@@ -125,6 +124,7 @@ enum clk_osm_trace_packet_id {
#define SPM_CC_CTRL 0x1028
#define SPM_CC_HYSTERESIS 0x101C
#define SPM_CORE_RET_MAPPING 0x1024
#define CFG_DELAY_VAL_3 0x12C

#define LLM_FREQ_VOTE_HYSTERESIS 0x102C
#define LLM_VOLT_VOTE_HYSTERESIS 0x1030
@@ -184,11 +184,11 @@ enum clk_osm_trace_packet_id {
#define MAX_INSTRUCTIONS 256
#define MAX_BR_INSTRUCTIONS 49

#define MAX_MEM_ACC_LEVELS 4
#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_READ_MASK 0x7
#define MEM_ACC_APM_READ_MASK 0xff

#define TRACE_CTRL 0x1F38
#define TRACE_CTRL_EN_MASK BIT(0)
@@ -203,6 +203,11 @@ enum clk_osm_trace_packet_id {
#define PERIODIC_TRACE_MAX_NS 21474836475
#define PERIODIC_TRACE_DEFAULT_NS 1000000

#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

static void __iomem *virt_base;

#define lmh_lite_clk_src_source_val 1
@@ -222,50 +227,48 @@ static void __iomem *virt_base;

static u32 seq_instr[] = {
	0xc2005000, 0x2c9e3b21, 0xc0ab2cdc, 0xc2882525, 0x359dc491,
	0x700a500b, 0x70005001, 0x390938c8, 0xcb44c833, 0xce56cd54,
	0x341336e0, 0xadba0000, 0x10004000, 0x70005001, 0x1000500c,
	0xc792c5a1, 0x501625e1, 0x3da335a2, 0x50170006, 0x50150006,
	0xafb9c633, 0xacb31000, 0xacb41000, 0x1000c422, 0x500baefc,
	0x5001700a, 0xaefd7000, 0x700b5010, 0x700c5012, 0xadb9ad41,
	0x181b0000, 0x500f500c, 0x34135011, 0x84b9181b, 0xbd808539,
	0x2ba40003, 0x0006a001, 0x10007105, 0x1000500e, 0x1c0a500c,
	0x3b181c01, 0x3b431c06, 0x10001c07, 0x39831c06, 0x500c1c07,
	0x1c0a1c02, 0x10000000, 0x70015002, 0x10000000, 0x50038103,
	0x50047002, 0x10007003, 0x39853b44, 0x50038104, 0x40037002,
	0x70095005, 0xb1c0a146, 0x238b0003, 0x10004005, 0x848b8308,
	0x1000850c, 0x848e830d, 0x1000850c, 0x3a4c5006, 0x3a8f39cd,
	0x40063ad0, 0x50071000, 0x2c127006, 0x4007a00f, 0x71050006,
	0x1000700d, 0x1c1aa964, 0x700d4007, 0x50071000, 0x1c167006,
	0x50125010, 0x40072411, 0x4007700d, 0xa00f1000, 0x0006a821,
	0x40077105, 0x500c700d, 0x1c1591ad, 0x5011500f, 0x10000000,
	0x500c2bd4, 0x0006a00f, 0x10007105, 0xa821a00f, 0x70050006,
	0x91ad500c, 0x500f1c15, 0x10005011, 0x1c162bce, 0x50125010,
	0xa82aa022, 0x71050006, 0x1c1591a6, 0x5011500f, 0x5014500c,
	0x0006a00f, 0x00007105, 0x91a41000, 0x22175013, 0x1c1aa963,
	0x22171000, 0x1c1aa963, 0x50081000, 0x40087007, 0x1c1aa963,
	0x70085009, 0x10004009, 0x850c848e, 0x0003b1c0, 0x400d2b99,
	0x500d1000, 0xabaf1000, 0x853184b0, 0x0003bb80, 0xa0371000,
	0x71050006, 0x85481000, 0xbf8084c3, 0x2ba80003, 0xbf8084c2,
	0x2ba70003, 0xbf8084c1, 0x2ba60003, 0x8ec71000, 0xc6dd8dc3,
	0x8c1625ec, 0x8d498c97, 0x8ec61c00, 0xc6dd8dc2, 0x8c1325ec,
	0x8d158c94, 0x8ec51c00, 0xc6dd8dc1, 0x8c1025ec, 0x8d128c91,
	0x8dc01c00, 0x182cc633, 0x84c08548, 0x0003bf80, 0x84c12ba9,
	0x0003bf80, 0x84c22baa, 0x0003bf80, 0x10002bab, 0x8dc08ec4,
	0x25ecc6dd, 0x8c948c13, 0x1c008d15, 0x8dc18ec5, 0x25ecc6dd,
	0x8c978c16, 0x1c008d49, 0x8dc28ec6, 0x25ecc6dd, 0x8ccb8c4a,
	0x1c008d4c, 0xc6338dc3, 0x1000af9b, 0xa759a79a, 0x1000a718,
	0x700a500b, 0x5001aefc, 0xaefd7000, 0x390938c8, 0xcb44c833,
	0xce56cd54, 0x341336e0, 0xa4baadba, 0xb480a493, 0x10004000,
	0x70005001, 0x1000500c, 0xc792c5a1, 0x501625e1, 0x3da335a2,
	0x50170006, 0x50150006, 0x1000c633, 0x1000acb3, 0xc422acb4,
	0xaefc1000, 0x700a500b, 0x70005001, 0x5010aefd, 0x5012700b,
	0xad41700c, 0x84e5adb9, 0xb3808566, 0x239b0003, 0x856484e3,
	0xb9800007, 0x2bad0003, 0xac3aa20b, 0x0003181b, 0x0003bb40,
	0xa30d239b, 0x500c181b, 0x5011500f, 0x181b3413, 0x853984b9,
	0x0003bd80, 0xa0012ba4, 0x72050803, 0x500e1000, 0x500c1000,
	0x1c011c0a, 0x3b181c06, 0x1c073b43, 0x1c061000, 0x1c073983,
	0x1c02500c, 0x10001c0a, 0x70015002, 0x81031000, 0x70025003,
	0x70035004, 0x3b441000, 0x81553985, 0x70025003, 0x50054003,
	0xa1467009, 0x0003b1c0, 0x4005238b, 0x835a1000, 0x855c84db,
	0x1000a51f, 0x84de835d, 0xa52c855c, 0x50061000, 0x39cd3a4c,
	0x3ad03a8f, 0x10004006, 0x70065007, 0xa00f2c12, 0x08034007,
	0xaefc7205, 0xaefd700d, 0xa9641000, 0x40071c1a, 0x700daefc,
	0x1000aefd, 0x70065007, 0x50101c16, 0x40075012, 0x700daefc,
	0x2411aefd, 0xa8211000, 0x0803a00f, 0x500c7005, 0x1c1591e0,
	0x500f5014, 0x10005011, 0x500c2bd4, 0x0803a00f, 0x10007205,
	0xa00fa9d1, 0x0803a821, 0xa9d07005, 0x91e0500c, 0x500f1c15,
	0x10005011, 0x1c162bce, 0x50125010, 0xa022a82a, 0x70050803,
	0x1c1591df, 0x5011500f, 0x5014500c, 0x0803a00f, 0x10007205,
	0x501391a4, 0x22172217, 0x70075008, 0xa9634008, 0x1c1a0006,
	0x70085009, 0x10004009, 0x00008ed9, 0x3e05c8dd, 0x1c033604,
	0xabaf1000, 0x856284e1, 0x0003bb80, 0x1000239f, 0x0803a037,
	0x10007205, 0x8dc61000, 0x38a71c2a, 0x1c2a8dc4, 0x100038a6,
	0x1c2a8dc5, 0x8dc73867, 0x38681c2a, 0x8c491000, 0x8d4b8cca,
	0x10001c00, 0x8ccd8c4c, 0x1c008d4e, 0x8c4f1000, 0x8d518cd0,
	0x10001c00, 0xa759a79a, 0x1000a718, 0xbf80af9b, 0x00001000,
};

static u32 seq_br_instr[] = {
	0x28c, 0x1e6, 0x238, 0xd0, 0xec,
	0xf4, 0xbc, 0xc4, 0x9c, 0xac,
	0xfc, 0xe2, 0x154, 0x174, 0x17c,
	0x10a, 0x126, 0x13a, 0x11c, 0x98,
	0x160, 0x1a6, 0x19a, 0x1ae, 0x1c0,
	0x1ce, 0x1d2, 0x30, 0x60, 0x86,
	0x7c, 0x1d8, 0x34, 0x3c, 0x56,
	0x5a, 0x1de, 0x2e, 0x222, 0x212,
	0x202, 0x254, 0x264, 0x274, 0x288,
	0x248, 0x20e, 0x21c, 0xf6, 0x112,
	0x11c, 0xe4, 0xea, 0xc6, 0xd6,
	0x126, 0x108, 0x184, 0x1a8, 0x1b0,
	0x134, 0x158, 0x16e, 0x14a, 0xc2,
	0x190, 0x1d2, 0x1cc, 0x1d4, 0x1e8,
	0x0, 0x1f6, 0x32, 0x66, 0xb0,
	0xa6, 0x1fc, 0x3c, 0x44, 0x5c,
	0x60, 0x204, 0x30, 0x22a, 0x234,
	0x23e, 0x0, 0x250, 0x0, 0x0, 0x9a,
	0x20c,
};

DEFINE_EXT_CLK(xo_ao, NULL);
@@ -298,6 +301,7 @@ struct clk_osm {
	u32 cluster_num;
	u32 irq;
	u32 apm_crossover_vc;
	u32 apm_threshold_vc;
	u32 cycle_counter_reads;
	u32 cycle_counter_delay;
	u32 cycle_counter_factor;
@@ -551,8 +555,8 @@ static void clk_osm_print_osm_table(struct clk_osm *c)
			lval,
			table[i].spare_data);
	}
	pr_debug("APM crossover corner: %d\n",
		 c->apm_crossover_vc);
	pr_debug("APM threshold corner=%d, crossover corner=%d\n",
		 c->apm_threshold_vc, c->apm_crossover_vc);
}

static int clk_osm_get_lut(struct platform_device *pdev,
@@ -1116,10 +1120,21 @@ exit:
static int clk_osm_resolve_crossover_corners(struct clk_osm *c,
				     struct platform_device *pdev)
{
	struct regulator *regulator = c->vdd_reg;
	struct dev_pm_opp *opp;
	unsigned long freq = 0;
	int vc, rc = 0;
	int vc, i, threshold, rc = 0;
	u32 corner_volt, data;

	rc = of_property_read_u32(pdev->dev.of_node,
				  "qcom,apm-threshold-voltage",
				  &threshold);
	if (rc) {
		pr_info("qcom,apm-threshold-voltage property not specified\n");
		return rc;
	}

	/* Determine crossover virtual corner */
	rcu_read_lock();
	opp = dev_pm_opp_find_freq_exact(&c->vdd_dev->dev, freq, true);
	if (IS_ERR(opp)) {
@@ -1138,6 +1153,48 @@ static int clk_osm_resolve_crossover_corners(struct clk_osm *c,
	vc--;
	c->apm_crossover_vc = vc;

	/* Determine threshold virtual corner */
	for (i = 0; i < OSM_TABLE_SIZE; i++) {
		freq = c->osm_table[i].frequency;
		/*
		 * Only frequencies that are supported across all configurations
		 * are present in the OPP table associated with the regulator
		 * device.
		 */
		data = (c->osm_table[i].freq_data & GENMASK(18, 16)) >> 16;
		if (data != MAX_CONFIG)
			continue;

		rcu_read_lock();
		opp = dev_pm_opp_find_freq_exact(&c->vdd_dev->dev, freq, true);
		if (IS_ERR(opp)) {
			rc = PTR_ERR(opp);
			if (rc == -ERANGE)
				pr_err("Frequency %lu not found\n", freq);
			goto exit;
		}

		vc = dev_pm_opp_get_voltage(opp);
		if (!vc) {
			pr_err("No virtual corner found for frequency %lu\n",
			       freq);
			rc = -ERANGE;
			goto exit;
		}

		rcu_read_unlock();

		corner_volt = regulator_list_corner_voltage(regulator, vc);

		/* CPR virtual corners are zero-based numbered */
		vc--;

		if (corner_volt >= threshold) {
			c->apm_threshold_vc = vc;
			break;
		}
	}

	return 0;
exit:
	rcu_read_unlock();
@@ -1413,47 +1470,56 @@ static void clk_osm_program_apm_regs(struct clk_osm *c)
	 */
	clk_osm_write_reg(c, c->apm_mode_ctl, SEQ_REG(2));

	/* Program mode value to switch APM from VDD_APCC to VDD_MX */
	clk_osm_write_reg(c, APM_MX_MODE, SEQ_REG(22));

	/* Program mode value to switch APM from VDD_MX to VDD_APCC */
	clk_osm_write_reg(c, APM_APC_MODE, SEQ_REG(25));

	/* Program address of controller status register */
	clk_osm_write_reg(c, c->apm_ctrl_status, SEQ_REG(3));

	/* Program mask used to determine status of APM power supply switch */
	clk_osm_write_reg(c, APM_MODE_SWITCH_MASK, SEQ_REG(24));
	/* Program mode value to switch APM from VDD_APCC to VDD_MX */
	clk_osm_write_reg(c, APM_MX_MODE, SEQ_REG(77));

	/* Program value used to determine current APM power supply is VDD_MX */
	clk_osm_write_reg(c, APM_MX_MODE_VAL, SEQ_REG(23));
	clk_osm_write_reg(c, APM_MX_MODE_VAL, SEQ_REG(78));

	/* Program mask used to determine status of APM power supply switch */
	clk_osm_write_reg(c, APM_MODE_SWITCH_MASK, SEQ_REG(79));

	/* Program mode value to switch APM from VDD_MX to VDD_APCC */
	clk_osm_write_reg(c, APM_APC_MODE, SEQ_REG(80));

	/*
	 * Program value used to determine current APM power supply
	 * is VDD_APCC
	 */
	clk_osm_write_reg(c, APM_APC_MODE_VAL, SEQ_REG(26));
	clk_osm_write_reg(c, APM_APC_MODE_VAL, SEQ_REG(81));
}

static void clk_osm_program_mem_acc_regs(struct clk_osm *c)
{
	int i;
	int i, curr_level, j = 0;
	int mem_acc_level_map[MAX_MEM_ACC_LEVELS] = {0, 0, 0};

	if (!c->secure_init)
		return;
	curr_level = c->osm_table[0].spare_data;
	for (i = 0; i < c->num_entries; i++) {
		if (curr_level == MAX_MEM_ACC_LEVELS)
			break;

	clk_osm_write_reg(c, c->pbases[OSM_BASE] + SEQ_REG(50),
			  SEQ_REG(49));
	clk_osm_write_reg(c, MEM_ACC_SEQ_CONST(1), SEQ_REG(50));
		if (c->osm_table[i].spare_data != curr_level) {
			mem_acc_level_map[j++] = i - 1;
			curr_level = c->osm_table[i].spare_data;
		}
	}

	if (c->secure_init) {
		clk_osm_write_reg(c, MEM_ACC_SEQ_CONST(1), SEQ_REG(51));
		clk_osm_write_reg(c, MEM_ACC_SEQ_CONST(2), SEQ_REG(52));
		clk_osm_write_reg(c, MEM_ACC_SEQ_CONST(3), SEQ_REG(53));
		clk_osm_write_reg(c, MEM_ACC_SEQ_CONST(4), SEQ_REG(54));
	clk_osm_write_reg(c, MEM_ACC_INSTR_COMP(0), SEQ_REG(55));
	clk_osm_write_reg(c, MEM_ACC_INSTR_COMP(1), SEQ_REG(56));
	clk_osm_write_reg(c, MEM_ACC_INSTR_COMP(2), SEQ_REG(57));
	clk_osm_write_reg(c, MEM_ACC_INSTR_COMP(3), SEQ_REG(58));
	clk_osm_write_reg(c, MEM_ACC_READ_MASK, SEQ_REG(59));
		clk_osm_write_reg(c, MEM_ACC_APM_READ_MASK, SEQ_REG(59));
		clk_osm_write_reg(c, mem_acc_level_map[0], SEQ_REG(55));
		clk_osm_write_reg(c, mem_acc_level_map[0] + 1, SEQ_REG(56));
		clk_osm_write_reg(c, mem_acc_level_map[1], SEQ_REG(57));
		clk_osm_write_reg(c, mem_acc_level_map[1] + 1, SEQ_REG(58));
		clk_osm_write_reg(c, c->pbases[OSM_BASE] + SEQ_REG(28),
				  SEQ_REG(49));

		for (i = 0; i < MAX_MEM_ACC_VALUES; i++)
			clk_osm_write_reg(c, c->apcs_mem_acc_val[i],
@@ -1462,6 +1528,19 @@ static void clk_osm_program_mem_acc_regs(struct clk_osm *c)
		for (i = 0; i < MAX_MEM_ACC_VAL_PER_LEVEL; i++)
			clk_osm_write_reg(c, c->apcs_mem_acc_cfg[i],
					  MEM_ACC_SEQ_REG_CFG_START(i));
	} else {
		scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(55),
			     mem_acc_level_map[0]);
		scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(56),
			     mem_acc_level_map[0] + 1);
		scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(57),
			     mem_acc_level_map[1]);
		scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(58),
			     mem_acc_level_map[1] + 1);
		/* SEQ_REG(49) = SEQ_REG(28) init by TZ */
	}

	return;
}

void clk_osm_setup_sequencer(struct clk_osm *c)
@@ -1500,10 +1579,12 @@ static void clk_osm_setup_cycle_counters(struct clk_osm *c)

static void clk_osm_setup_osm_was(struct clk_osm *c)
{
	u32 cc_hyst;
	u32 val;

	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));
@@ -1518,10 +1599,51 @@ static void clk_osm_setup_osm_was(struct clk_osm *c)
		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) {
@@ -1671,18 +1793,15 @@ static void clk_osm_do_additional_setup(struct clk_osm *c,
	/* APM Programming */
	clk_osm_program_apm_regs(c);

	/* MEM-ACC Programming */
	clk_osm_program_mem_acc_regs(c);

	/* GFMUX Programming */
	clk_osm_write_reg(c, c->apcs_cfg_rcgr, SEQ_REG(16));
	clk_osm_write_reg(c, GPLL_SEL, SEQ_REG(17));
	clk_osm_write_reg(c, PLL_EARLY_SEL, SEQ_REG(20));
	clk_osm_write_reg(c, PLL_MAIN_SEL, SEQ_REG(32));
	clk_osm_write_reg(c, c->apcs_cmd_rcgr, SEQ_REG(33));
	clk_osm_write_reg(c, RCG_UPDATE, SEQ_REG(34));
	clk_osm_write_reg(c, RCG_UPDATE_SUCCESS, SEQ_REG(35));
	clk_osm_write_reg(c, RCG_UPDATE, SEQ_REG(36));
	clk_osm_write_reg(c, GPLL_SEL, SEQ_REG(17));
	clk_osm_write_reg(c, PLL_EARLY_SEL, SEQ_REG(82));
	clk_osm_write_reg(c, PLL_MAIN_SEL, SEQ_REG(83));
	clk_osm_write_reg(c, RCG_UPDATE_SUCCESS, SEQ_REG(84));
	clk_osm_write_reg(c, RCG_UPDATE, SEQ_REG(85));

	pr_debug("seq_size: %lu, seqbr_size: %lu\n", ARRAY_SIZE(seq_instr),
						ARRAY_SIZE(seq_br_instr));
@@ -1693,17 +1812,43 @@ static void clk_osm_do_additional_setup(struct clk_osm *c,
static void clk_osm_apm_vc_setup(struct clk_osm *c)
{
	/*
	 * APM crossover virtual corner at which the switch
	 * from APC to MX and vice-versa should take place.
	 * APM crossover virtual corner corresponds to switching
	 * voltage during APM transition. APM threshold virtual
	 * corner is the first corner which requires switch
	 * sequence of APM from MX to APC.
	 */
	if (c->secure_init) {
		clk_osm_write_reg(c, c->apm_crossover_vc, SEQ_REG(1));
		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));
		clk_osm_write_reg(c, c->apm_threshold_vc != 0 ?
				  c->apm_threshold_vc - 1 : 0xff,
				  SEQ_REG(31));
		clk_osm_write_reg(c, 0x3b | c->apm_threshold_vc << 6,
				  SEQ_REG(73));
		clk_osm_write_reg(c, 0x39 | c->apm_threshold_vc << 6,
				  SEQ_REG(76));

		/* Ensure writes complete before returning */
		mb();
	} else {
		scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(1),
			     c->apm_threshold_vc);
		scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(72),
			     c->apm_crossover_vc);
		/* SEQ_REG(8) = address of SEQ_REG(1) init by TZ */
		clk_osm_write_reg(c, c->apm_threshold_vc,
				  SEQ_REG(15));
		scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(31),
			     c->apm_threshold_vc != 0 ?
			     c->apm_threshold_vc - 1 : 0xff);
		scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(73),
			     0x3b | c->apm_threshold_vc << 6);
		scm_io_write(c->pbases[OSM_BASE] + SEQ_REG(76),
			     0x39 | c->apm_threshold_vc << 6);
	}
}

@@ -2412,6 +2557,10 @@ static int cpu_clock_osm_driver_probe(struct platform_device *pdev)
	clk_osm_do_additional_setup(&pwrcl_clk, pdev);
	clk_osm_do_additional_setup(&perfcl_clk, pdev);

	/* MEM-ACC Programming */
	clk_osm_program_mem_acc_regs(&pwrcl_clk);
	clk_osm_program_mem_acc_regs(&perfcl_clk);

	/* Program APM crossover corners */
	clk_osm_apm_vc_setup(&pwrcl_clk);
	clk_osm_apm_vc_setup(&perfcl_clk);
Loading