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

Commit 7e76cddb authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge changes Id4943bb5,I8eb893ac,I9ad0b90b into msm-4.14

* changes:
  ARM: dts: msm: Add BCL sensors for pm855b
  ARM: dts: msm: Add LMH-DCVSh configuration for sdm855
  drivers: lmh-dcvs: Update cooling device registration and register space
parents 8d6a6a76 cf40046b
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -46,14 +46,24 @@ Properties:
			property is valid only if there is valid entry for
			isens_vref-supply.

- reg:
	Usage: Required
	Value type: <a b>
	Definition: where 'a' is the starting register address of the OSM/LLM
			and 'b' is the size of OSM/LLM address space. The
			register space in index 0 should be LLM and index 1
			should be OSM.

Example:

	lmh_dcvs0: qcom,limits-dcvs@0 {
	lmh_dcvs0: qcom,limits-dcvs@18350800 {
		compatible = "qcom,msm-hw-limits";
		interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
		qcom,affinity = <0>;
		isens_vref-supply = <&pm8998_l1_ao>;
		isens-vref-settings = <880000 880000 36000>;
		reg =  <0x18350800 0x1000>, //LLM
			<0x18323000 0x1000>; //OSM
	};

	CPU0: cpu@0 {
+111 −0
Original line number Diff line number Diff line
@@ -259,6 +259,27 @@
						 <9000 3000>, /* 9V @ 3A */
						 <12000 2250>; /* 12V @ 2.25A */
		};

		pm855b_bcl: bcl@1d00 {
			compatible = "qcom,bcl-v5";
			reg = <0x1d00 0x100>;
			interrupts = <0x2 0x1d 0x0 IRQ_TYPE_NONE>,
					<0x2 0x1d 0x1 IRQ_TYPE_NONE>,
					<0x2 0x1d 0x0 IRQ_TYPE_NONE>,
					<0x2 0x1d 0x1 IRQ_TYPE_NONE>,
					<0x2 0x1d 0x2 IRQ_TYPE_NONE>;
			interrupt-names = "bcl-ibat-lvl0",
						"bcl-ibat-lvl1",
						"bcl-vbat-lvl0",
						"bcl-vbat-lvl1",
						"bcl-vbat-lvl2";
			#thermal-sensor-cells = <1>;
		};

		bcl_soc:bcl-soc {
			compatible = "qcom,msm-bcl-soc";
			#thermal-sensor-cells = <0>;
		};
	};

	qcom,pm855b@3 {
@@ -318,4 +339,94 @@
			};
		};
	};

	pm855b-ibat-lvl0 {
		polling-delay-passive = <0>;
		polling-delay = <0>;
		thermal-governor = "step_wise";
		thermal-sensors = <&pm855b_bcl 0>;

		trips {
			ibat_lvl0:ibat-lvl0 {
				temperature = <4500>;
				hysteresis = <200>;
				type = "passive";
			};
		};
	};

	pm855b-ibat-lvl1 {
		polling-delay-passive = <0>;
		polling-delay = <0>;
		thermal-governor = "step_wise";
		thermal-sensors = <&pm855b_bcl 1>;

		trips {
			ibat_lvl1:ibat-lvl1 {
				temperature = <5000>;
				hysteresis = <200>;
				type = "passive";
			};
		};
	};

	pm855b-vbat-lvl0 {
		polling-delay-passive = <0>;
		polling-delay = <0>;
		thermal-governor = "step_wise";
		thermal-sensors = <&pm855b_bcl 2>;

		trips {
			vbat_lvl0: vbat-lvl0 {
				temperature = <3500>;
				hysteresis = <200>;
				type = "passive";
			};
		};
	};

	pm855b-vbat-lvl1 {
		polling-delay-passive = <0>;
		polling-delay = <0>;
		thermal-governor = "step_wise";
		thermal-sensors = <&pm855b_bcl 3>;

		trips {
			vbat_lvl1:vbat-lvl1 {
				temperature = <3000>;
				hysteresis = <200>;
				type = "passive";
			};
		};
	};

	pm855b-vbat-lvl2 {
		polling-delay-passive = <0>;
		polling-delay = <0>;
		thermal-governor = "step_wise";
		thermal-sensors = <&pm855b_bcl 4>;

		trips {
			vbat_lvl2:vbat-lvl2 {
				temperature = <2800>;
				hysteresis = <200>;
				type = "passive";
			};
		};
	};

	soc {
		polling-delay-passive = <0>;
		polling-delay = <0>;
		thermal-governor = "step_wise";
		thermal-sensors = <&bcl_soc>;

		trips {
			soc_trip:soc-trip {
				temperature = <10>;
				hysteresis = <0>;
				type = "passive";
			};
		};
	};
};
+52 −0
Original line number Diff line number Diff line
@@ -12,6 +12,28 @@

#include <dt-bindings/thermal/thermal.h>

&clock_cpucc {
	#address-cells = <1>;
	#size-cells = <1>;
	lmh_dcvs0: qcom,limits-dcvs@18358800 {
		compatible = "qcom,msm-hw-limits";
		interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
		qcom,affinity = <0>;
		reg = <0x18358800 0x1000>,
			<0x18323000 0x1000>;
		#thermal-sensor-cells = <0>;
	};

	lmh_dcvs1: qcom,limits-dcvs@18350800 {
		compatible = "qcom,msm-hw-limits";
		interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
		qcom,affinity = <1>;
		reg = <0x18350800 0x1000>,
			<0x18325800 0x1000>;
		#thermal-sensor-cells = <0>;
	};
};

&thermal_zones {
	aoss0-usr {
		polling-delay-passive = <0>;
@@ -444,4 +466,34 @@
			};
		};
	};

	lmh-dcvs-01 {
		polling-delay-passive = <0>;
		polling-delay = <0>;
		thermal-governor = "user_space";
		thermal-sensors = <&lmh_dcvs1>;

		trips {
			active-config {
				temperature = <95000>;
				hysteresis = <30000>;
				type = "passive";
			};
		};
	};

	lmh-dcvs-00 {
		polling-delay-passive = <0>;
		polling-delay = <0>;
		thermal-governor = "user_space";
		thermal-sensors = <&lmh_dcvs0>;

		trips {
			active-config {
				temperature = <95000>;
				hysteresis = <30000>;
				type = "passive";
			};
		};
	};
};
+8 −0
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@
			cache-size = <0x8000>;
			next-level-cache = <&L2_0>;
			sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
			qcom,lmh-dcvs = <&lmh_dcvs0>;
			#cooling-cells = <2>;
			L2_0: l2-cache {
			      compatible = "arm,arch-cache";
@@ -96,6 +97,7 @@
			cache-size = <0x8000>;
			next-level-cache = <&L2_1>;
			sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
			qcom,lmh-dcvs = <&lmh_dcvs0>;
			#cooling-cells = <2>;
			L2_1: l2-cache {
			      compatible = "arm,arch-cache";
@@ -128,6 +130,7 @@
			cache-size = <0x8000>;
			next-level-cache = <&L2_2>;
			sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
			qcom,lmh-dcvs = <&lmh_dcvs0>;
			#cooling-cells = <2>;
			L2_2: l2-cache {
			      compatible = "arm,arch-cache";
@@ -160,6 +163,7 @@
			cache-size = <0x8000>;
			next-level-cache = <&L2_3>;
			sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
			qcom,lmh-dcvs = <&lmh_dcvs0>;
			#cooling-cells = <2>;
			L2_3: l2-cache {
			      compatible = "arm,arch-cache";
@@ -192,6 +196,7 @@
			cache-size = <0x20000>;
			next-level-cache = <&L2_4>;
			sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_1>;
			qcom,lmh-dcvs = <&lmh_dcvs1>;
			#cooling-cells = <2>;
			L2_4: l2-cache {
			      compatible = "arm,arch-cache";
@@ -224,6 +229,7 @@
			cache-size = <0x20000>;
			next-level-cache = <&L2_5>;
			sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_1>;
			qcom,lmh-dcvs = <&lmh_dcvs1>;
			#cooling-cells = <2>;
			L2_5: l2-cache {
			      compatible = "arm,arch-cache";
@@ -256,6 +262,7 @@
			cache-size = <0x20000>;
			next-level-cache = <&L2_6>;
			sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_1>;
			qcom,lmh-dcvs = <&lmh_dcvs1>;
			#cooling-cells = <2>;
			L2_6: l2-cache {
			      compatible = "arm,arch-cache";
@@ -288,6 +295,7 @@
			cache-size = <0x20000>;
			next-level-cache = <&L2_7>;
			sched-energy-costs = <&CPU_COST_2 &CLUSTER_COST_2>;
			qcom,lmh-dcvs = <&lmh_dcvs1>;
			#cooling-cells = <2>;
			L2_7: l2-cache {
			      compatible = "arm,arch-cache";
+74 −62
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/sched.h>
#include <linux/io.h>
@@ -56,12 +57,9 @@
#define LIMITS_TEMP_HIGH_THRESH_MAX	120000
#define LIMITS_LOW_THRESHOLD_OFFSET	500
#define LIMITS_POLLING_DELAY_MS		10
#define LIMITS_CLUSTER_0_REQ        0x17D43704
#define LIMITS_CLUSTER_1_REQ        0x17D45F04
#define LIMITS_CLUSTER_0_INT_CLR    0x17D78808
#define LIMITS_CLUSTER_1_INT_CLR    0x17D70808
#define LIMITS_CLUSTER_0_MIN_FREQ   0x17D78BC0
#define LIMITS_CLUSTER_1_MIN_FREQ   0x17D70BC0
#define LIMITS_CLUSTER_REQ_OFFSET	0x704
#define LIMITS_CLUSTER_INT_CLR_OFFSET	0x8
#define LIMITS_CLUSTER_MIN_FREQ_OFFSET	0x3C0
#define dcvsh_get_frequency(_val, _max) do { \
	_max = (_val) & 0x3FF; \
	_max *= 19200; \
@@ -98,8 +96,11 @@ struct limits_dcvs_hw {
	struct list_head list;
	bool is_irq_enabled;
	struct mutex access_lock;
	struct mutex cdev_reg_lock;
	struct __limits_cdev_data *cdev_data;
	uint32_t cdev_registered;
	struct regulator *isens_reg;
	struct work_struct cdev_register_work;
};

LIST_HEAD(lmh_dcvs_hw_list);
@@ -118,10 +119,8 @@ static int limits_dcvs_get_freq_limits(uint32_t cpu, unsigned long *max_freq,
		return -ENODEV;
	}

	rcu_read_lock();
	dev_pm_opp_find_freq_floor(cpu_dev, &freq_ceil);
	dev_pm_opp_find_freq_ceil(cpu_dev, &freq_floor);
	rcu_read_unlock();

	*max_freq = freq_ceil / 1000;
	*min_freq = freq_floor / 1000;
@@ -149,7 +148,6 @@ static unsigned long limits_mitigation_notify(struct limits_dcvs_hw *hw)
			cpumask_first(&hw->core_map),
			max_limit);
	freq_val = FREQ_KHZ_TO_HZ(max_limit);
	rcu_read_lock();
	opp_entry = dev_pm_opp_find_freq_floor(cpu_dev, &freq_val);
	/*
	 * Hardware mitigation frequency can be lower than the lowest
@@ -163,7 +161,6 @@ static unsigned long limits_mitigation_notify(struct limits_dcvs_hw *hw)
			dev_err(cpu_dev, "frequency:%lu. opp error:%ld\n",
					freq_val, PTR_ERR(opp_entry));
	}
	rcu_read_unlock();
	max_limit = FREQ_HZ_TO_KHZ(freq_val);

	sched_update_cpu_freq_min_max(&hw->core_map, 0, max_limit);
@@ -184,7 +181,7 @@ static void limits_dcvs_poll(struct work_struct *work)
					freq_poll_work.work);

	mutex_lock(&hw->access_lock);
	if (hw->max_freq == UINT_MAX)
	if (hw->max_freq == U32_MAX)
		limits_dcvs_get_freq_limits(cpumask_first(&hw->core_map),
			&hw->max_freq, &hw->min_freq);
	max_limit = limits_mitigation_notify(hw);
@@ -390,22 +387,23 @@ static struct cpu_cooling_ops cd_ops = {
	.floor_limit = lmh_set_min_limit,
};

static int limits_cpu_online(unsigned int online_cpu)
static void register_cooling_device(struct work_struct *work)
{
	struct limits_dcvs_hw *hw = get_dcvsh_hw_from_cpu(online_cpu);
	unsigned int idx = 0, cpu = 0;
	struct limits_dcvs_hw *hw = container_of(work, struct limits_dcvs_hw,
						cdev_register_work);
	unsigned int cpu = 0, idx = 0;

	if (!hw)
		return 0;
	mutex_lock(&hw->cdev_reg_lock);
	if (hw->max_freq == U32_MAX)
		limits_dcvs_get_freq_limits(cpumask_first(&hw->core_map),
			&hw->max_freq, &hw->min_freq);

	for_each_cpu(cpu, &hw->core_map) {
		cpumask_t cpu_mask  = { CPU_BITS_NONE };

		if (cpu != online_cpu) {
		if (hw->cdev_data[idx].cdev) {
			idx++;
			continue;
		} else if (hw->cdev_data[idx].cdev) {
			return 0;
		}
		cpumask_set_cpu(cpu, &cpu_mask);
		hw->cdev_data[idx].max_freq = U32_MAX;
@@ -418,10 +416,21 @@ static int limits_cpu_online(unsigned int online_cpu)
			hw->cdev_data[idx].cdev = NULL;
		} else {
			pr_debug("CPU:%u cooling device registered\n", cpu);
			hw->cdev_registered++;
		}
		break;

		idx++;
	}
	mutex_unlock(&hw->cdev_reg_lock);
}

static int limits_cpu_online(unsigned int online_cpu)
{
	struct limits_dcvs_hw *hw = get_dcvsh_hw_from_cpu(online_cpu);

	if (!hw)
		return 0;
	if (hw->cdev_registered != cpumask_weight(&hw->core_map))
		queue_work(system_highpri_wq, &hw->cdev_register_work);

	return 0;
}
@@ -489,9 +498,9 @@ static int limits_dcvs_probe(struct platform_device *pdev)
	struct device_node *dn = pdev->dev.of_node;
	struct device_node *cpu_node, *lmh_node;
	uint32_t request_reg, clear_reg, min_reg;
	unsigned long max_freq, min_freq;
	int cpu;
	int cpu, idx = 0;
	cpumask_t mask = { CPU_BITS_NONE };
	const __be32 *addr;

	for_each_possible_cpu(cpu) {
		cpu_node = of_cpu_device_node_get(cpu);
@@ -513,10 +522,6 @@ static int limits_dcvs_probe(struct platform_device *pdev)
	if (cpumask_empty(&mask))
		return -EINVAL;

	ret = limits_dcvs_get_freq_limits(cpumask_first(&mask), &max_freq,
				     &min_freq);
	if (ret)
		return ret;
	hw = devm_kzalloc(&pdev->dev, sizeof(*hw), GFP_KERNEL);
	if (!hw)
		return -ENOMEM;
@@ -527,6 +532,13 @@ static int limits_dcvs_probe(struct platform_device *pdev)
		return -ENOMEM;

	cpumask_copy(&hw->core_map, &mask);
	hw->cdev_registered = 0;
	for_each_cpu(cpu, &hw->core_map) {
		hw->cdev_data[idx].cdev = NULL;
		hw->cdev_data[idx].max_freq = U32_MAX;
		hw->cdev_data[idx].min_freq = 0;
		idx++;
	}
	ret = of_property_read_u32(dn, "qcom,affinity", &affinity);
	if (ret)
		return -ENODEV;
@@ -541,6 +553,20 @@ static int limits_dcvs_probe(struct platform_device *pdev)
		return -EINVAL;
	};

	addr = of_get_address(dn, 0, NULL, NULL);
	if (!addr) {
		pr_err("Property llm-base-addr not found\n");
		return -EINVAL;
	}
	clear_reg = be32_to_cpu(addr[0]) + LIMITS_CLUSTER_INT_CLR_OFFSET;
	min_reg = be32_to_cpu(addr[0]) + LIMITS_CLUSTER_MIN_FREQ_OFFSET;
	addr = of_get_address(dn, 1, NULL, NULL);
	if (!addr) {
		pr_err("Property osm-base-addr not found\n");
		return -EINVAL;
	}
	request_reg = be32_to_cpu(addr[0]) + LIMITS_CLUSTER_REQ_OFFSET;

	/*
	 * Setup virtual thermal zones for each LMH-DCVS hardware
	 * The sensor does not do actual thermal temperature readings
@@ -550,8 +576,8 @@ static int limits_dcvs_probe(struct platform_device *pdev)
	 */
	hw->temp_limits[LIMITS_TRIP_HI] = INT_MAX;
	hw->temp_limits[LIMITS_TRIP_ARM] = 0;
	hw->hw_freq_limit = hw->max_freq = max_freq;
	hw->min_freq = min_freq;
	hw->hw_freq_limit = hw->max_freq = U32_MAX;
	hw->min_freq = 0;
	snprintf(hw->sensor_name, sizeof(hw->sensor_name), "limits_sensor-%02d",
			affinity);
	tzdev = thermal_zone_of_sensor_register(&pdev->dev, 0, hw,
@@ -559,22 +585,6 @@ static int limits_dcvs_probe(struct platform_device *pdev)
	if (IS_ERR_OR_NULL(tzdev))
		return PTR_ERR(tzdev);

	switch (affinity) {
	case 0:
		request_reg = LIMITS_CLUSTER_0_REQ;
		clear_reg = LIMITS_CLUSTER_0_INT_CLR;
		min_reg = LIMITS_CLUSTER_0_MIN_FREQ;
		break;
	case 1:
		request_reg = LIMITS_CLUSTER_1_REQ;
		clear_reg = LIMITS_CLUSTER_1_INT_CLR;
		min_reg = LIMITS_CLUSTER_1_MIN_FREQ;
		break;
	default:
		ret = -EINVAL;
		goto unregister_sensor;
	};

	hw->min_freq_reg = devm_ioremap(&pdev->dev, min_reg, 0x4);
	if (!hw->min_freq_reg) {
		pr_err("min frequency enable register remap failed\n");
@@ -583,6 +593,8 @@ static int limits_dcvs_probe(struct platform_device *pdev)
	}

	mutex_init(&hw->access_lock);
	mutex_init(&hw->cdev_reg_lock);
	INIT_WORK(&hw->cdev_register_work, register_cooling_device);
	INIT_DEFERRABLE_WORK(&hw->freq_poll_work, limits_dcvs_poll);
	hw->osm_hw_reg = devm_ioremap(&pdev->dev, request_reg, 0x4);
	if (!hw->osm_hw_reg) {