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

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

Merge "clk: msm: clock-cpu-8939: Add support for single cluster target"

parents f73c886e 5836a8fa
Loading
Loading
Loading
Loading
+3 −1
Original line number Original line Diff line number Diff line
@@ -7,7 +7,7 @@ fmax tables, avs settings table, etc.


Required properties:
Required properties:
- compatible:		Must be one of "qcom,clock-cpu-8939" or
- compatible:		Must be one of "qcom,clock-cpu-8939" or
			"qcom,cpu-clock-8952"
			"qcom,cpu-clock-8952", "qcom,cpu-clock-gold".
- reg:			Pairs of physical base addresses and region sizes of
- reg:			Pairs of physical base addresses and region sizes of
			memory mapped registers.
			memory mapped registers.
- reg-names:		Names of the bases for the above registers. Expected
- reg-names:		Names of the bases for the above registers. Expected
@@ -33,6 +33,8 @@ Required properties:
Optional properties:
Optional properties:
- qcom,cpu-pcnoc-vote:  Boolean to indicate cpu clocks would need to keep
- qcom,cpu-pcnoc-vote:  Boolean to indicate cpu clocks would need to keep
			active pcnoc vote.
			active pcnoc vote.
- qcom,num-cluster:     Boolean to indicate cpu clock code is used for single
			cluster.
Example:
Example:
	clock_cpu: qcom,cpu-clock-8939@f9015000 {
	clock_cpu: qcom,cpu-clock-8939@f9015000 {
		compatible = "qcom,cpu-clock-8939";
		compatible = "qcom,cpu-clock-8939";
+6 −6
Original line number Original line Diff line number Diff line
@@ -566,11 +566,11 @@
	clock_gcc: qcom,gcc@1800000 {
	clock_gcc: qcom,gcc@1800000 {
		compatible = "qcom,gcc-8937";
		compatible = "qcom,gcc-8937";
		reg = <0x1800000 0x80000>,
		reg = <0x1800000 0x80000>,
			<0xb116000 0x00040>,
			<0xb016000 0x00040>,
			<0xb016000 0x00040>,
			<0xb116000 0x00040>,
			<0xb1d0000 0x00040>;
			<0xb1d0000 0x00040>;
		reg-names = "cc_base", "apcs_c0_base",
		reg-names = "cc_base", "apcs_c1_base",
			"apcs_c1_base", "apcs_cci_base";
			"apcs_c0_base", "apcs_cci_base";
		vdd_dig-supply = <&pm8937_s2_level>;
		vdd_dig-supply = <&pm8937_s2_level>;
		vdd_sr2_dig-supply = <&pm8937_s2_level_ao>;
		vdd_sr2_dig-supply = <&pm8937_s2_level_ao>;
		vdd_sr2_pll-supply = <&pm8937_l7_ao>;
		vdd_sr2_pll-supply = <&pm8937_l7_ao>;
@@ -607,11 +607,11 @@


	clock_cpu: qcom,cpu-clock-8939@b111050 {
	clock_cpu: qcom,cpu-clock-8939@b111050 {
		compatible = "qcom,cpu-clock-8939";
		compatible = "qcom,cpu-clock-8939";
		reg =   <0xb111050 0x8>,
		reg =   <0xb011050 0x8>,
			<0xb011050 0x8>,
			<0xb111050 0x8>,
			<0xb1d1050 0x8>,
			<0xb1d1050 0x8>,
			<0x00a412c 0x8>;
			<0x00a412c 0x8>;
		reg-names = "apcs-c0-rcg-base", "apcs-c1-rcg-base",
		reg-names = "apcs-c1-rcg-base", "apcs-c0-rcg-base",
			    "apcs-cci-rcg-base", "efuse";
			    "apcs-cci-rcg-base", "efuse";
		vdd-c0-supply = <&apc_vreg_corner>;
		vdd-c0-supply = <&apc_vreg_corner>;
		vdd-c1-supply = <&apc_vreg_corner>;
		vdd-c1-supply = <&apc_vreg_corner>;
+6 −6
Original line number Original line Diff line number Diff line
@@ -145,11 +145,11 @@
		#size-cells = <1>;
		#size-cells = <1>;
		compatible = "qcom,gcc-8952";
		compatible = "qcom,gcc-8952";
		reg = <0x1800000 0x80000>,
		reg = <0x1800000 0x80000>,
			<0xb116000 0x00040>,
			<0xb016000 0x00040>,
			<0xb016000 0x00040>,
			<0xb116000 0x00040>,
			<0xb1d0000 0x00040>;
			<0xb1d0000 0x00040>;
		reg-names = "cc_base", "apcs_c0_base",
		reg-names = "cc_base", "apcs_c1_base",
			"apcs_c1_base", "apcs_cci_base";
			"apcs_c0_base", "apcs_cci_base";
		vdd_dig-supply = <&pm8950_s2_level>;
		vdd_dig-supply = <&pm8950_s2_level>;
		vdd_sr2_dig-supply = <&pm8950_s2_level_ao>;
		vdd_sr2_dig-supply = <&pm8950_s2_level_ao>;
		vdd_sr2_pll-supply = <&pm8950_l7_ao>;
		vdd_sr2_pll-supply = <&pm8950_l7_ao>;
@@ -185,11 +185,11 @@


	clock_cpu: qcom,cpu-clock-8939@b111050 {
	clock_cpu: qcom,cpu-clock-8939@b111050 {
		compatible = "qcom,cpu-clock-8939";
		compatible = "qcom,cpu-clock-8939";
		reg =   <0xb111050 0x8>,
		reg =   <0xb011050 0x8>,
			<0xb011050 0x8>,
			<0xb111050 0x8>,
			<0xb1d1050 0x8>,
			<0xb1d1050 0x8>,
			<0x005c00c 0x8>;
			<0x005c00c 0x8>;
		reg-names = "apcs-c0-rcg-base", "apcs-c1-rcg-base",
		reg-names = "apcs-c1-rcg-base", "apcs-c0-rcg-base",
			    "apcs-cci-rcg-base", "efuse";
			    "apcs-cci-rcg-base", "efuse";
		vdd-c0-supply = <&apc_vreg_corner>;
		vdd-c0-supply = <&apc_vreg_corner>;
		vdd-c1-supply = <&apc_vreg_corner>;
		vdd-c1-supply = <&apc_vreg_corner>;
+86 −30
Original line number Original line Diff line number Diff line
@@ -203,6 +203,12 @@ static struct clk_lookup cpu_clocks_8939[] = {
	CLK_LIST(cci_clk),
	CLK_LIST(cci_clk),
};
};


static struct clk_lookup cpu_clocks_8939_single_cluster[] = {
	CLK_LIST(a53ssmux_bc),
	CLK_LIST(a53_bc_clk),
};


static struct mux_div_clk *a53ssmux[] = {&a53ssmux_bc,
static struct mux_div_clk *a53ssmux[] = {&a53ssmux_bc,
						&a53ssmux_lc, &a53ssmux_cci};
						&a53ssmux_lc, &a53ssmux_cci};


@@ -516,30 +522,33 @@ static int add_opp(struct clk *c, struct device *cpudev, struct device *vregdev,
	return 0;
	return 0;
}
}


static void print_opp_table(int a53_c0_cpu, int a53_c1_cpu)
static void print_opp_table(int a53_c0_cpu, int a53_c1_cpu, bool single_cluster)
{
{
	struct dev_pm_opp *oppfmax, *oppfmin;
	struct dev_pm_opp *oppfmax, *oppfmin;
	unsigned long apc0_fmax, apc1_fmax, apc0_fmin, apc1_fmin;
	unsigned long apc0_fmax, apc1_fmax, apc0_fmin, apc1_fmin;

	if (!single_cluster) {
		apc0_fmax = a53_lc_clk.c.fmax[a53_lc_clk.c.num_fmax - 1];
		apc0_fmax = a53_lc_clk.c.fmax[a53_lc_clk.c.num_fmax - 1];
	apc1_fmax = a53_bc_clk.c.fmax[a53_bc_clk.c.num_fmax - 1];
		apc0_fmin = a53_lc_clk.c.fmax[1];
		apc0_fmin = a53_lc_clk.c.fmax[1];
	}
	apc1_fmax = a53_bc_clk.c.fmax[a53_bc_clk.c.num_fmax - 1];
	apc1_fmin = a53_bc_clk.c.fmax[1];
	apc1_fmin = a53_bc_clk.c.fmax[1];


	rcu_read_lock();
	rcu_read_lock();
	if (!single_cluster) {
		oppfmax = dev_pm_opp_find_freq_exact(get_cpu_device(a53_c0_cpu),
		oppfmax = dev_pm_opp_find_freq_exact(get_cpu_device(a53_c0_cpu),
						apc0_fmax, true);
						apc0_fmax, true);
		oppfmin = dev_pm_opp_find_freq_exact(get_cpu_device(a53_c0_cpu),
		oppfmin = dev_pm_opp_find_freq_exact(get_cpu_device(a53_c0_cpu),
						apc0_fmin, true);
						apc0_fmin, true);
		/*
		/*
	 * One time information during boot. Important to know that this looks
		* One time information during boot. Important to know that this
	 * sane since it can eventually make its way to the scheduler.
		* looks sane since it can eventually make its way to the
		* scheduler.
		*/
		*/
	pr_info("clock_cpu: a53_c0: OPP voltage for %lu: %ld\n", apc0_fmin,
		pr_info("clock_cpu: a53_c0: OPP voltage for %lu: %ld\n",
		dev_pm_opp_get_voltage(oppfmin));
			apc0_fmin, dev_pm_opp_get_voltage(oppfmin));
	pr_info("clock_cpu: a53_c0: OPP voltage for %lu: %ld\n", apc0_fmax,
		pr_info("clock_cpu: a53_c0: OPP voltage for %lu: %ld\n",
		dev_pm_opp_get_voltage(oppfmax));
			apc0_fmax, dev_pm_opp_get_voltage(oppfmax));

	}
	oppfmax = dev_pm_opp_find_freq_exact(get_cpu_device(a53_c1_cpu),
	oppfmax = dev_pm_opp_find_freq_exact(get_cpu_device(a53_c1_cpu),
						apc1_fmax, true);
						apc1_fmax, true);
	oppfmin = dev_pm_opp_find_freq_exact(get_cpu_device(a53_c1_cpu),
	oppfmin = dev_pm_opp_find_freq_exact(get_cpu_device(a53_c1_cpu),
@@ -551,16 +560,19 @@ static void print_opp_table(int a53_c0_cpu, int a53_c1_cpu)
	rcu_read_unlock();
	rcu_read_unlock();
}
}


static void populate_opp_table(struct platform_device *pdev)
static void populate_opp_table(struct platform_device *pdev,
					bool single_cluster)
{
{
	struct platform_device *apc0_dev, *apc1_dev;
	struct platform_device *apc0_dev, *apc1_dev;
	struct device_node *apc0_node, *apc1_node;
	struct device_node *apc0_node, *apc1_node;
	unsigned long apc0_fmax, apc1_fmax;
	unsigned long apc0_fmax, apc1_fmax;
	int cpu, a53_c0_cpu, a53_c1_cpu;
	int cpu, a53_c0_cpu, a53_c1_cpu;


	apc0_node = of_parse_phandle(pdev->dev.of_node, "vdd-c0-supply", 0);
	if (!single_cluster)
		apc0_node = of_parse_phandle(pdev->dev.of_node,
						"vdd-c0-supply", 0);
	apc1_node = of_parse_phandle(pdev->dev.of_node, "vdd-c1-supply", 0);
	apc1_node = of_parse_phandle(pdev->dev.of_node, "vdd-c1-supply", 0);
	if (!apc0_node) {
	if (!apc0_node && !single_cluster) {
		pr_err("can't find the apc0 dt node.\n");
		pr_err("can't find the apc0 dt node.\n");
		return;
		return;
	}
	}
@@ -568,10 +580,11 @@ static void populate_opp_table(struct platform_device *pdev)
		pr_err("can't find the apc1 dt node.\n");
		pr_err("can't find the apc1 dt node.\n");
		return;
		return;
	}
	}

	if (!single_cluster)
		apc0_dev = of_find_device_by_node(apc0_node);
		apc0_dev = of_find_device_by_node(apc0_node);

	apc1_dev = of_find_device_by_node(apc1_node);
	apc1_dev = of_find_device_by_node(apc1_node);
	if (!apc0_dev) {
	if (!apc1_dev && !single_cluster) {
		pr_err("can't find the apc0 device node.\n");
		pr_err("can't find the apc0 device node.\n");
		return;
		return;
	}
	}
@@ -580,7 +593,9 @@ static void populate_opp_table(struct platform_device *pdev)
		return;
		return;
	}
	}


	if (!single_cluster)
		apc0_fmax = a53_lc_clk.c.fmax[a53_lc_clk.c.num_fmax - 1];
		apc0_fmax = a53_lc_clk.c.fmax[a53_lc_clk.c.num_fmax - 1];

	apc1_fmax = a53_bc_clk.c.fmax[a53_bc_clk.c.num_fmax - 1];
	apc1_fmax = a53_bc_clk.c.fmax[a53_bc_clk.c.num_fmax - 1];


	for_each_possible_cpu(cpu) {
	for_each_possible_cpu(cpu) {
@@ -590,7 +605,7 @@ static void populate_opp_table(struct platform_device *pdev)
			WARN(add_opp(&a53_bc_clk.c, get_cpu_device(cpu),
			WARN(add_opp(&a53_bc_clk.c, get_cpu_device(cpu),
				     &apc1_dev->dev, apc1_fmax),
				     &apc1_dev->dev, apc1_fmax),
				     "Failed to add OPP levels for A53 big cluster\n");
				     "Failed to add OPP levels for A53 big cluster\n");
		} else if (cpu/4 == 1) {
		} else if (cpu/4 == 1 && !single_cluster) {
			a53_c0_cpu = cpu;
			a53_c0_cpu = cpu;
			WARN(add_opp(&a53_lc_clk.c, get_cpu_device(cpu),
			WARN(add_opp(&a53_lc_clk.c, get_cpu_device(cpu),
				     &apc0_dev->dev, apc0_fmax),
				     &apc0_dev->dev, apc0_fmax),
@@ -602,7 +617,8 @@ static void populate_opp_table(struct platform_device *pdev)
	pr_info("clock-cpu-8939: OPP tables populated (cpu %d and %d)",
	pr_info("clock-cpu-8939: OPP tables populated (cpu %d and %d)",
		a53_c0_cpu, a53_c1_cpu);
		a53_c0_cpu, a53_c1_cpu);


	print_opp_table(a53_c0_cpu, a53_c1_cpu);
	print_opp_table(a53_c0_cpu, a53_c1_cpu, single_cluster);

}
}


static void config_pll(int mux_id)
static void config_pll(int mux_id)
@@ -644,18 +660,47 @@ static int clock_8939_pm_event(struct notifier_block *this,
	return NOTIFY_DONE;
	return NOTIFY_DONE;
}
}


static int clock_8939_pm_event_single_cluster(struct notifier_block *this,
						unsigned long event, void *ptr)
{
	switch (event) {
	case PM_POST_HIBERNATION:
	case PM_POST_SUSPEND:
		clk_unprepare(&a53_bc_clk.c);
		break;
	case PM_HIBERNATION_PREPARE:
	case PM_SUSPEND_PREPARE:
		clk_prepare(&a53_bc_clk.c);
		break;
	default:
		break;
	}
	return NOTIFY_DONE;
}

static struct notifier_block clock_8939_pm_notifier = {
static struct notifier_block clock_8939_pm_notifier = {
	.notifier_call = clock_8939_pm_event,
	.notifier_call = clock_8939_pm_event,
};
};


static struct notifier_block clock_8939_pm_notifier_single_cluster = {
	.notifier_call = clock_8939_pm_event_single_cluster,
};

static int clock_a53_probe(struct platform_device *pdev)
static int clock_a53_probe(struct platform_device *pdev)
{
{
	int speed_bin, version, rc, cpu, mux_id, rate;
	int speed_bin, version, rc, cpu, mux_id, rate;
	char prop_name[] = "qcom,speedX-bin-vX-XXX";
	char prop_name[] = "qcom,speedX-bin-vX-XXX";
	int mux_num;
	bool single_cluster;

	single_cluster = of_property_read_bool(pdev->dev.of_node,
						"qcom,num-cluster");


	get_speed_bin(pdev, &speed_bin, &version);
	get_speed_bin(pdev, &speed_bin, &version);


	for (mux_id = 0; mux_id < A53SS_MUX_NUM; mux_id++) {
	mux_num = single_cluster ? A53SS_MUX_LC:A53SS_MUX_NUM;

	for (mux_id = 0; mux_id < mux_num; mux_id++) {
		rc = cpu_parse_devicetree(pdev, mux_id);
		rc = cpu_parse_devicetree(pdev, mux_id);
		if (rc)
		if (rc)
			return rc;
			return rc;
@@ -683,16 +728,23 @@ static int clock_a53_probe(struct platform_device *pdev)
			dev_info(&pdev->dev, "Safe voltage plan loaded.\n");
			dev_info(&pdev->dev, "Safe voltage plan loaded.\n");
		}
		}
	}
	}

	if (single_cluster)
		rc = of_msm_clock_register(pdev->dev.of_node,
				cpu_clocks_8939_single_cluster,
				ARRAY_SIZE(cpu_clocks_8939_single_cluster));
	else
		rc = of_msm_clock_register(pdev->dev.of_node,
		rc = of_msm_clock_register(pdev->dev.of_node,
				cpu_clocks_8939, ARRAY_SIZE(cpu_clocks_8939));
				cpu_clocks_8939, ARRAY_SIZE(cpu_clocks_8939));

	if (rc) {
	if (rc) {
		dev_err(&pdev->dev, "msm_clock_register failed\n");
		dev_err(&pdev->dev, "msm_clock_register failed\n");
		return rc;
		return rc;
	}
	}


	if (!single_cluster) {
		rate = clk_get_rate(&cci_clk.c);
		rate = clk_get_rate(&cci_clk.c);
		clk_set_rate(&cci_clk.c, rate);
		clk_set_rate(&cci_clk.c, rate);
	}


	for (mux_id = 0; mux_id < A53SS_MUX_CCI; mux_id++) {
	for (mux_id = 0; mux_id < A53SS_MUX_CCI; mux_id++) {
		/* Force a PLL reconfiguration */
		/* Force a PLL reconfiguration */
@@ -724,15 +776,19 @@ static int clock_a53_probe(struct platform_device *pdev)
	a53_lc_clk.hw_low_power_ctrl = true;
	a53_lc_clk.hw_low_power_ctrl = true;
	a53_bc_clk.hw_low_power_ctrl = true;
	a53_bc_clk.hw_low_power_ctrl = true;


	if (single_cluster)
		register_pm_notifier(&clock_8939_pm_notifier_single_cluster);
	else
		register_pm_notifier(&clock_8939_pm_notifier);
		register_pm_notifier(&clock_8939_pm_notifier);


	populate_opp_table(pdev);
	populate_opp_table(pdev, single_cluster);


	return 0;
	return 0;
}
}


static struct of_device_id clock_a53_match_table[] = {
static struct of_device_id clock_a53_match_table[] = {
	{.compatible = "qcom,cpu-clock-8939"},
	{.compatible = "qcom,cpu-clock-8939"},
	{.compatible = "qcom,cpu-clock-gold"},
	{}
	{}
};
};