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

Commit 678382be authored by Odelu Kukatla's avatar Odelu Kukatla Committed by Gerrit - the friendly Code Review server
Browse files

clk: msm: gcc: Add support for clocks for SDM439



Add a new compatible flag for sdm439 and update
the required clock lookup table accordingly.
Also add support for cpu quad core configuration.

Change-Id: Ie12c98e0a939992b975de0db79b20798ce12371b
Signed-off-by: default avatarOdelu Kukatla <okukatla@codeaurora.org>
parent af3795d2
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@ Required properties:
			"qcom,gcc-8992"
			"qcom,gcc-8952"
			"qcom,gcc-8937"
			"qcom,gcc-sdm439"
			"qcom,gcc-sdm429"
			"qcom,gcc-8917"
			"qcom,gcc-8940"
			"qcom,gcc-8920"
+2 −1
Original line number Diff line number Diff line
@@ -7,7 +7,8 @@ fmax tables, avs settings table, etc.

Required properties:
- compatible:		Must be one of "qcom,clock-cpu-8939" or
			"qcom,cpu-clock-8952", "qcom,cpu-clock-8917".
			"qcom,cpu-clock-8952", "qcom,cpu-clock-8917",
			"qcom,cpu-clock-sdm439", "qcom,cpu-clock-sdm429".
- reg:			Pairs of physical base addresses and region sizes of
			memory mapped registers.
- reg-names:		Names of the bases for the above registers. Expected
+95 −12
Original line number Diff line number Diff line
@@ -222,6 +222,12 @@ static struct clk_lookup cpu_clocks_8939_single_cluster[] = {
	CLK_LIST(a53_bc_clk),
};

static struct clk_lookup cpu_clocks_sdm429[] = {
	CLK_LIST(a53ssmux_bc),
	CLK_LIST(a53ssmux_cci),
	CLK_LIST(a53_bc_clk),
	CLK_LIST(cci_clk),
};

static struct mux_div_clk *a53ssmux[] = {&a53ssmux_bc,
						&a53ssmux_lc, &a53ssmux_cci};
@@ -691,6 +697,26 @@ static int clock_8939_pm_event(struct notifier_block *this,
	return NOTIFY_DONE;
}

static int clock_sdm429_pm_event(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);
		clk_unprepare(&cci_clk.c);
		break;
	case PM_HIBERNATION_PREPARE:
	case PM_SUSPEND_PREPARE:
		clk_prepare(&a53_bc_clk.c);
		clk_prepare(&cci_clk.c);
		break;
	default:
		break;
	}
	return NOTIFY_DONE;
}

static int clock_8939_pm_event_single_cluster(struct notifier_block *this,
						unsigned long event, void *ptr)
{
@@ -713,6 +739,10 @@ static struct notifier_block clock_8939_pm_notifier = {
	.notifier_call = clock_8939_pm_event,
};

static struct notifier_block clock_sdm429_pm_notifier = {
	.notifier_call = clock_sdm429_pm_event,
};

static struct notifier_block clock_8939_pm_notifier_single_cluster = {
	.notifier_call = clock_8939_pm_event_single_cluster,
};
@@ -762,10 +792,14 @@ static int clock_a53_probe(struct platform_device *pdev)
	char prop_name[] = "qcom,speedX-bin-vX-XXX";
	int mux_num;
	bool single_cluster;
	bool is_sdm429 = false;

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

	is_sdm429 = of_device_is_compatible(pdev->dev.of_node,
						"qcom,cpu-clock-sdm429");

	get_speed_bin(pdev, &speed_bin, &version);

	mux_num = single_cluster ? A53SS_MUX_LC:A53SS_MUX_NUM;
@@ -798,11 +832,35 @@ static int clock_a53_probe(struct platform_device *pdev)
			dev_info(&pdev->dev, "Safe voltage plan loaded.\n");
		}
	}
	if (single_cluster)

	if (is_sdm429) {
		rc = cpu_parse_devicetree(pdev, A53SS_MUX_CCI);
		if (rc)
			return rc;

		snprintf(prop_name, ARRAY_SIZE(prop_name),
				"qcom,speed%d-bin-v%d-%s",
				speed_bin, version, mux_names[A53SS_MUX_CCI]);

		rc = of_get_fmax_vdd_class(pdev, &cpuclk[A53SS_MUX_CCI]->c,
								prop_name);
		if (rc) {
			dev_err(&pdev->dev, "Unable to load voltage plan %s!\n",
								prop_name);
			return rc;
		}
	}

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

@@ -811,7 +869,7 @@ static int clock_a53_probe(struct platform_device *pdev)
		return rc;
	}

	if (!single_cluster) {
	if (!single_cluster || is_sdm429) {
		rate = clk_get_rate(&cci_clk.c);
		clk_set_rate(&cci_clk.c, rate);
	}
@@ -832,7 +890,7 @@ static int clock_a53_probe(struct platform_device *pdev)
	for_each_online_cpu(cpu) {
		WARN(clk_prepare_enable(&cpuclk[cpu/4]->c),
				"Unable to turn on CPU clock");
		if (!single_cluster)
		if (!single_cluster || is_sdm429)
			clk_prepare_enable(&cci_clk.c);
	}
	put_online_cpus();
@@ -847,9 +905,13 @@ static int clock_a53_probe(struct platform_device *pdev)
	a53_lc_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);
	if (single_cluster) {
		if (is_sdm429)
			register_pm_notifier(&clock_sdm429_pm_notifier);
		else
			register_pm_notifier(
				&clock_8939_pm_notifier_single_cluster);
	} else
		register_pm_notifier(&clock_8939_pm_notifier);

	populate_opp_table(pdev, single_cluster);
@@ -863,6 +925,8 @@ static int clock_a53_probe(struct platform_device *pdev)
static const struct of_device_id clock_a53_match_table[] = {
	{.compatible = "qcom,cpu-clock-8939"},
	{.compatible = "qcom,cpu-clock-8917"},
	{.compatible = "qcom,cpu-clock-sdm429"},
	{.compatible = "qcom,cpu-clock-sdm439"},
	{}
};

@@ -890,8 +954,15 @@ static int __init clock_cpu_lpm_get_latency(void)

	if (!ofnode)
		ofnode = of_find_compatible_node(NULL, NULL,
					"qcom,cpu-clock-gold");
					"qcom,cpu-clock-8917");

	if (!ofnode)
		ofnode = of_find_compatible_node(NULL, NULL,
					"qcom,cpu-clock-sdm439");

	if (!ofnode)
		ofnode = of_find_compatible_node(NULL, NULL,
					"qcom,cpu-clock-sdm429");
	if (!ofnode)
		return 0;

@@ -935,7 +1006,7 @@ late_initcall(clock_cpu_lpm_get_latency);
#define SRC_SEL				0x4
#define SRC_DIV				0x3

static void __init configure_enable_sr2_pll(void __iomem *base)
static void __init configure_enable_sr2_pll(void __iomem *base, bool is_sdm439)
{
	/* Disable Mode */
	writel_relaxed(0x0, base + C0_PLL_MODE);
@@ -947,6 +1018,10 @@ static void __init configure_enable_sr2_pll(void __iomem *base)

	/* Configure USER_CTL and CONFIG_CTL value */
	writel_relaxed(0x0100000f, base + C0_PLL_USER_CTL);

	if (is_sdm439)
		writel_relaxed(0x44024665, base + C0_PLL_CONFIG_CTL);
	else
		writel_relaxed(0x4c015765, base + C0_PLL_CONFIG_CTL);

	/* Enable PLL now */
@@ -965,13 +1040,21 @@ static int __init cpu_clock_a53_init_little(void)
{
	void __iomem  *base;
	int regval = 0, count;
	bool is_sdm439 = false;
	struct device_node *ofnode = of_find_compatible_node(NULL, NULL,
							"qcom,cpu-clock-8939");

	if (!ofnode)
		ofnode = of_find_compatible_node(NULL, NULL,
						"qcom,cpu-clock-sdm439");

	if (!ofnode)
		return 0;

	is_sdm439 = of_device_is_compatible(ofnode, "qcom,cpu-clock-sdm439");

	base = ioremap_nocache(APCS_C0_PLL, SZ_32);
	configure_enable_sr2_pll(base);
	configure_enable_sr2_pll(base, is_sdm439);
	iounmap(base);

	base = ioremap_nocache(APCS_ALIAS0_CMD_RCGR, SZ_8);
+97 −6
Original line number Diff line number Diff line
@@ -202,7 +202,10 @@ static struct pll_freq_tbl apcs_c0_pll_freq[] = {
	F_APCS_PLL( 921600000,  48, 0x0, 0x1, 0x0, 0x0, 0x0),
	F_APCS_PLL( 998400000,  52, 0x0, 0x1, 0x0, 0x0, 0x0),
	F_APCS_PLL(1094400000,  57, 0x0, 0x1, 0x0, 0x0, 0x0),
	F_APCS_PLL(1171200000,  61, 0x0, 0x1, 0x0, 0x0, 0x0),
	F_APCS_PLL(1209600000,  63, 0x0, 0x1, 0x0, 0x0, 0x0),
	F_APCS_PLL(1305600000,  68, 0x0, 0x1, 0x0, 0x0, 0x0),
	F_APCS_PLL(1459200000,  76, 0x0, 0x1, 0x0, 0x0, 0x0),
};

static struct pll_clk a53ss_c0_pll = {
@@ -257,6 +260,7 @@ static struct pll_freq_tbl apcs_c1_pll_freq[] = {
	F_APCS_PLL(1209600000, 63, 0x0, 0x1, 0x0, 0x0, 0x0),
	F_APCS_PLL(1248000000, 65, 0x0, 0x1, 0x0, 0x0, 0x0),
	F_APCS_PLL(1267200000, 66, 0x0, 0x1, 0x0, 0x0, 0x0),
	F_APCS_PLL(1305600000, 68, 0x0, 0x1, 0x0, 0x0, 0x0),
	F_APCS_PLL(1344000000, 70, 0x0, 0x1, 0x0, 0x0, 0x0),
	F_APCS_PLL(1401000000, 73, 0x0, 0x1, 0x0, 0x0, 0x0),
	F_APCS_PLL(1420800000, 74, 0x0, 0x1, 0x0, 0x0, 0x0),
@@ -266,6 +270,9 @@ static struct pll_freq_tbl apcs_c1_pll_freq[] = {
	F_APCS_PLL(1516800000, 79, 0x0, 0x1, 0x0, 0x0, 0x0),
	F_APCS_PLL(1536000000, 80, 0x0, 0x1, 0x0, 0x0, 0x0),
	F_APCS_PLL(1651200000, 86, 0x0, 0x1, 0x0, 0x0, 0x0),
	F_APCS_PLL(1708800000, 89, 0x0, 0x1, 0x0, 0x0, 0x0),
	F_APCS_PLL(1804800000, 94, 0x0, 0x1, 0x0, 0x0, 0x0),
	F_APCS_PLL(1958400000, 102, 0x0, 0x1, 0x0, 0x0, 0x0),
};

static struct pll_clk a53ss_c1_pll = {
@@ -754,6 +761,29 @@ static struct clk_freq_tbl ftbl_gcc_oxili_gfx3d_clk_8937[] = {
	F_END
};

static struct clk_freq_tbl ftbl_gcc_oxili_gfx3d_clk_sdm439[] = {
	F_SLEW( 19200000,  FIXED_CLK_SRC, xo,		1,	0,	0),
	F_SLEW( 50000000,  FIXED_CLK_SRC, gpll0,	16,	0,	0),
	F_SLEW( 80000000,  FIXED_CLK_SRC, gpll0,	10,	0,	0),
	F_SLEW( 100000000, FIXED_CLK_SRC, gpll0,	8,	0,	0),
	F_SLEW( 160000000, FIXED_CLK_SRC, gpll0,	5,	0,	0),
	F_SLEW( 200000000, FIXED_CLK_SRC, gpll0,	4,	0,	0),
	F_SLEW( 216000000, FIXED_CLK_SRC, gpll6_aux,	5,	0,	0),
	F_SLEW( 228570000, FIXED_CLK_SRC, gpll0,	3.5,	0,	0),
	F_SLEW( 240000000, FIXED_CLK_SRC, gpll6_aux,	4.5,	0,	0),
	F_SLEW( 259200000, 1296000000,	  gpll3,	2.5,	0,	0),
	F_SLEW( 266670000, FIXED_CLK_SRC, gpll0,	3,	0,	0),
	F_SLEW( 320000000, FIXED_CLK_SRC, gpll0,	2.5,	0,	0),
	F_SLEW( 355200000, 710400000,	  gpll3,	1,	0,	0),
	F_SLEW( 375000000, 750000000,	  gpll3,	1,	0,	0),
	F_SLEW( 400000000, FIXED_CLK_SRC, gpll0,	2,	0,	0),
	F_SLEW( 450000000, 900000000,	  gpll3,	1,	0,	0),
	F_SLEW( 510000000, 1020000000,	  gpll3,	1,	0,	0),
	F_SLEW( 560000000, 1120000000,	  gpll3,	1,	0,	0),
	F_SLEW( 650000000, 1300000000,	  gpll3,	1,	0,	0),
	F_END
};

static struct clk_freq_tbl ftbl_gcc_oxili_gfx3d_clk_8937_475MHz[] = {
	F_SLEW( 19200000,  FIXED_CLK_SRC, xo,		1,	0,	0),
	F_SLEW( 50000000,  FIXED_CLK_SRC, gpll0,	16,	0,	0),
@@ -4046,6 +4076,26 @@ static struct clk_lookup msm_clocks_lookup_8937[] = {
	CLK_LIST(gcc_oxili_timer_clk),
};

static struct clk_lookup msm_clocks_lookup_sdm429[] = {
	CLK_LIST(gpll0_clk_src_8937),
	CLK_LIST(gpll0_ao_clk_src_8937),
	CLK_LIST(gpll0_sleep_clk_src),
	CLK_LIST(esc1_clk_src),
	CLK_LIST(gcc_mdss_esc1_clk),
	CLK_LIST(gcc_dcc_clk),
	CLK_LIST(gcc_oxili_aon_clk),
	CLK_LIST(gcc_qdss_dap_clk),
	CLK_LIST(blsp1_qup1_i2c_apps_clk_src),
	CLK_LIST(blsp1_qup1_spi_apps_clk_src),
	CLK_LIST(gcc_blsp1_qup1_i2c_apps_clk),
	CLK_LIST(gcc_blsp1_qup1_spi_apps_clk),
	CLK_LIST(blsp2_qup4_i2c_apps_clk_src),
	CLK_LIST(blsp2_qup4_spi_apps_clk_src),
	CLK_LIST(gcc_blsp2_qup4_i2c_apps_clk),
	CLK_LIST(gcc_blsp2_qup4_spi_apps_clk),
	CLK_LIST(gcc_oxili_timer_clk),
};

static struct clk_lookup msm_clocks_lookup_8917[] = {
	CLK_LIST(gpll0_clk_src_8937),
	CLK_LIST(gpll0_ao_clk_src_8937),
@@ -4329,6 +4379,8 @@ static int msm_gcc_probe(struct platform_device *pdev)
	bool compat_bin2 = false;
	bool compat_bin3 = false;
	bool compat_bin4 = false;
	bool compat_bin5 = false;
	bool compat_bin6 = false;

	compat_bin = of_device_is_compatible(pdev->dev.of_node,
						"qcom,gcc-8937");
@@ -4342,11 +4394,17 @@ static int msm_gcc_probe(struct platform_device *pdev)
	compat_bin4 = of_device_is_compatible(pdev->dev.of_node,
						"qcom,gcc-8920");

	compat_bin5 = of_device_is_compatible(pdev->dev.of_node,
						"qcom,gcc-sdm429");

	compat_bin6 = of_device_is_compatible(pdev->dev.of_node,
						"qcom,gcc-sdm439");

	ret = vote_bimc(&bimc_clk, INT_MAX);
	if (ret < 0)
		return ret;

	if (compat_bin2 || compat_bin4)
	if (compat_bin2 || compat_bin4 || compat_bin5)
		nbases = APCS_C0_PLL_BASE;

	ret = get_mmio_addr(pdev, nbases);
@@ -4374,7 +4432,7 @@ static int msm_gcc_probe(struct platform_device *pdev)
		return PTR_ERR(vdd_dig.regulator[0]);
	}

	if (!compat_bin2 && !compat_bin4) {
	if (!compat_bin2 && !compat_bin4 && !compat_bin5) {
		vdd_sr2_pll.regulator[0] = devm_regulator_get(&pdev->dev,
							"vdd_sr2_pll");
		if (IS_ERR(vdd_sr2_pll.regulator[0])) {
@@ -4417,16 +4475,43 @@ static int msm_gcc_probe(struct platform_device *pdev)
	regval |= BIT(0);
	writel_relaxed(regval, GCC_REG_BASE(APCS_GPLL_ENA_VOTE));

	if (compat_bin || compat_bin3) {
	if (compat_bin || compat_bin3 || compat_bin5 || compat_bin6) {
		gpll0_clk_src.c.parent = &gpll0_clk_src_8937.c;
		gpll0_ao_clk_src.c.parent = &gpll0_ao_clk_src_8937.c;
		/* Oxili Ocmem in GX rail: OXILI_GMEM_CLAMP_IO */
		regval = readl_relaxed(GCC_REG_BASE(GX_DOMAIN_MISC));
		regval &= ~BIT(0);
		writel_relaxed(regval, GCC_REG_BASE(GX_DOMAIN_MISC));

		if (compat_bin5 || compat_bin6)
			speed_bin = 0;
		else
			get_speed_bin(pdev, &speed_bin);

		override_for_8937(speed_bin);

		if (compat_bin5 || compat_bin6) {
			vdd_dig.num_levels = VDD_DIG_NUM_439;
			vdd_dig.cur_level = VDD_DIG_NUM_439;
			vdd_sr2_pll.num_levels = VDD_SR2_PLL_NUM_439;
			vdd_sr2_pll.cur_level = VDD_SR2_PLL_NUM_439;
			vdd_hf_pll.num_levels = VDD_HF_PLL_NUM_439;
			vdd_hf_pll.cur_level = VDD_HF_PLL_NUM_439;

			gpll3_clk_src.vco_tbl = p_vco;
			gpll3_clk_src.num_vco = ARRAY_SIZE(p_vco);
			gpll3_clk_src.c.fmax[VDD_DIG_LOW] = 800000000;
			gpll3_clk_src.c.fmax[VDD_DIG_NOMINAL] = 1400000000;
			gfx3d_clk_src.freq_tbl =
					ftbl_gcc_oxili_gfx3d_clk_sdm439;

			gfx3d_clk_src.c.fmax[VDD_DIG_LOWER] = 320000000;
			gfx3d_clk_src.c.fmax[VDD_DIG_LOW] = 400000000;
			gfx3d_clk_src.c.fmax[VDD_DIG_NOMINAL] = 510000000;
			gfx3d_clk_src.c.fmax[VDD_DIG_NOM_PLUS] = 560000000;
			gfx3d_clk_src.c.fmax[VDD_DIG_HIGH] = 650000000;
		}

		if (compat_bin3) {
			if (speed_bin) {
				gfx3d_clk_src.freq_tbl =
@@ -4475,7 +4560,7 @@ static int msm_gcc_probe(struct platform_device *pdev)
	if (ret)
		return ret;

	if (compat_bin)
	if (compat_bin || compat_bin6)
		ret = of_msm_clock_register(pdev->dev.of_node,
					msm_clocks_lookup_8937,
					ARRAY_SIZE(msm_clocks_lookup_8937));
@@ -4491,6 +4576,10 @@ static int msm_gcc_probe(struct platform_device *pdev)
		ret = of_msm_clock_register(pdev->dev.of_node,
					msm_clocks_lookup_8920,
					ARRAY_SIZE(msm_clocks_lookup_8920));
	else if (compat_bin5)
		ret = of_msm_clock_register(pdev->dev.of_node,
					msm_clocks_lookup_sdm429,
					ARRAY_SIZE(msm_clocks_lookup_sdm429));
	else
		ret = of_msm_clock_register(pdev->dev.of_node,
					msm_clocks_lookup_8952,
@@ -4513,7 +4602,7 @@ static int msm_gcc_probe(struct platform_device *pdev)

	clk_prepare_enable(&xo_a_clk_src.c);

	if (!compat_bin && !compat_bin3) {
	if (!compat_bin && !compat_bin3 && !compat_bin5 && !compat_bin6) {
		/* Configure Sleep and Wakeup cycles for GMEM clock */
		regval = readl_relaxed(GCC_REG_BASE(OXILI_GMEM_CBCR));
		regval ^= 0xFF0;
@@ -4546,6 +4635,8 @@ static const struct of_device_id msm_clock_gcc_match_table[] = {
	{ .compatible = "qcom,gcc-8917" },
	{ .compatible = "qcom,gcc-8940" },
	{ .compatible = "qcom,gcc-8920" },
	{ .compatible = "qcom,gcc-sdm439" },
	{ .compatible = "qcom,gcc-sdm429" },
	{}
};

+26 −0
Original line number Diff line number Diff line
@@ -432,6 +432,32 @@ enum vdd_hf_pll_levels_8917 {
	VDD_HF_PLL_NUM_8917,
};

enum vdd_sr2_pll_levels_439 {
	VDD_SR2_PLL_OFF_439,
	VDD_SR2_PLL_SVS_439,
	VDD_SR2_PLL_NOM_439,
	VDD_SR2_PLL_TUR_439,
	VDD_SR2_PLL_NUM_439,
};

enum vdd_dig_levels_439 {
	VDD_DIG_NONE_439,
	VDD_DIG_LOWER_439,
	VDD_DIG_LOW_439,
	VDD_DIG_NOMINAL_439,
	VDD_DIG_NOM_PLUS_439,
	VDD_DIG_HIGH_439,
	VDD_DIG_NUM_439
};

enum vdd_hf_pll_levels_439 {
	VDD_HF_PLL_OFF_439,
	VDD_HF_PLL_SVS_439,
	VDD_HF_PLL_NOM_439,
	VDD_HF_PLL_TUR_439,
	VDD_HF_PLL_NUM_439,
};

static int vdd_corner[] = {
	RPM_REGULATOR_LEVEL_NONE,		/* VDD_DIG_NONE */
	RPM_REGULATOR_LEVEL_SVS,		/* VDD_DIG_SVS */