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

Commit f127889e authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "defconfig: Enable CPU clock drivers for sdxnightjar"

parents 4abd93bb b0012338
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ CONFIG_IIO=y
CONFIG_QCOM_CLK_SMD_RPM=y
CONFIG_SDX_DEBUGCC_NIGHTJAR=y
CONFIG_COMMON_CLK_QCOM_DEBUG=y
CONFIG_CLOCK_CPU_SDXLEMUR=y
CONFIG_MSM_RPM_SMD=y
# CONFIG_GENERIC_ADC_BATTERY is not set
# CONFIG_BATTERY_LEGO_EV3 is not set
+1 −0
Original line number Diff line number Diff line
@@ -72,6 +72,7 @@ CONFIG_IIO=y
CONFIG_QCOM_CLK_SMD_RPM=y
CONFIG_SDX_DEBUGCC_NIGHTJAR=y
CONFIG_COMMON_CLK_QCOM_DEBUG=y
CONFIG_CLOCK_CPU_SDXLEMUR=y
CONFIG_MSM_RPM_SMD=y
# CONFIG_GENERIC_ADC_BATTERY is not set
# CONFIG_BATTERY_LEGO_EV3 is not set
+129 −17
Original line number Diff line number Diff line
@@ -88,26 +88,50 @@ cpucc_calc_rate(unsigned long rate, u32 m, u32 n, u32 mode, u32 hid_div)
	return tmp;
}

static int cpucc_clk_determine_rate(struct clk_hw *hw,
					struct clk_rate_request *req)
static int cpucc_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
{
	struct clk_hw *apcs_cpu_pll_hw;
	struct clk_hw  *xo_hw, *gpll0_hw;
	struct clk_rate_request parent_req = { };
	struct clk_regmap_mux_div *cpuclk = to_clk_regmap_mux_div(hw);
	unsigned long rate = req->rate, rrate;
	u32 div;
	int ret;

	apcs_cpu_pll_hw = clk_hw_get_parent_by_index(hw,
						       P_APCS_CPU_PLL);
	xo_hw = clk_hw_get_parent_by_index(hw, P_BI_TCXO);
	if (rate == clk_hw_get_rate(xo_hw)) {
		req->best_parent_hw = xo_hw;
		req->best_parent_rate = rate;
		cpuclk->div = 1;
		cpuclk->src = cpuclk->parent_map[P_BI_TCXO].cfg;
		return 0;
	}

	gpll0_hw = clk_hw_get_parent_by_index(hw, P_GPLL0);
	div = DIV_ROUND_UP((2 * (clk_hw_get_rate(gpll0_hw))), rate) - 1;

	rrate = cpucc_calc_rate(clk_hw_get_rate(gpll0_hw), 0, 0, 0, div);
	/* Use the GPLL0 source */
	if (rate <= rrate) {
		parent_req.best_parent_hw = gpll0_hw;
		req->best_parent_hw = gpll0_hw;
		req->best_parent_rate = clk_hw_get_rate(gpll0_hw);
		req->rate = rrate;
		cpuclk->src = cpuclk->parent_map[P_GPLL0].cfg;
	} else { /* Use the APCS PLL source */
		parent_req.rate = req->rate;
	parent_req.best_parent_hw = apcs_cpu_pll_hw;
	req->best_parent_hw = apcs_cpu_pll_hw;
		parent_req.best_parent_hw = clk_hw_get_parent_by_index(hw,
								       P_APCS_CPU_PLL);
		req->best_parent_hw = parent_req.best_parent_hw;
		ret = __clk_determine_rate(req->best_parent_hw, &parent_req);
		if (ret)
			return ret;

		req->best_parent_rate = parent_req.rate;
		cpuclk->src = cpuclk->parent_map[P_APCS_CPU_PLL].cfg;
	cpuclk->div = 1;
		div = 1;
	}

	cpuclk->div = div;

	return 0;
}
@@ -187,6 +211,28 @@ static u8 cpucc_clk_get_parent(struct clk_hw *hw)
	return clk_regmap_mux_div_ops.get_parent(hw);
}

/*
 * We use the notifier function for switching to a temporary safe configuration
 * (mux and divider), while the APSS pll is reconfigured.
 */

static int cpucc_notifier_cb(struct notifier_block *nb, unsigned long event,
								void *data)
{
	struct clk_regmap_mux_div *cpuclk = container_of(nb,
					struct clk_regmap_mux_div, clk_nb);
	int ret = 0;

	if (event == PRE_RATE_CHANGE)
		/* set the mux to safe source(gpll0) & div */
		ret = mux_div_set_src_div(cpuclk,  cpuclk->safe_src, 1);

	if (event == ABORT_RATE_CHANGE)
		pr_err("Error in configuring PLL - stay at safe src only\n");

	return notifier_from_errno(ret);
}

static const struct clk_ops cpucc_clk_ops = {
	.enable = cpucc_clk_enable,
	.disable = cpucc_clk_disable,
@@ -204,6 +250,11 @@ static struct pll_vco lucid_5lpe_vco[] = {
	{ 249600000, 2000000000, 0 },
};

static struct pll_vco alpha_pll_vco[] = {
	{ 250000000,  500000000, 3 },
	{ 750000000, 1500000000, 1 },
};

/* Initial configuration for 1094.4 */
static const struct alpha_pll_config apcs_cpu_pll_config = {
	.l = 0x4E,
@@ -220,6 +271,25 @@ static const struct alpha_pll_config apcs_cpu_pll_config = {
	.user_ctl_hi1_val = 0x00000000,
};

/* Initial configuration for 1190.4 MHz */
static struct alpha_pll_config apcs_cpu_alpha_pll_config = {
	.l = 0x3E,
	.config_ctl_val = 0x4001055b,
	.test_ctl_hi_val = 0x0,
	.vco_val = BIT(20),
	.vco_mask = 0x3 << 20,
	.main_output_mask = BIT(0),
};

static struct clk_init_data apcs_cpu_pll_sdxnightjar = {
	.name = "apcs_cpu_pll",
	.parent_data = &(const struct clk_parent_data){
		.fw_name = "bi_tcxo_ao",
	},
	.num_parents = 1,
	.ops = &clk_alpha_pll_ops,
};

static struct clk_alpha_pll apcs_cpu_pll = {
	.offset = 0x0,
	.vco_table = lucid_5lpe_vco,
@@ -279,6 +349,7 @@ static struct clk_regmap_mux_div apcs_mux_clk = {

static const struct of_device_id match_table[] = {
	{ .compatible = "qcom,sdxlemur-apsscc" },
	{ .compatible = "qcom,sdxnightjar-apsscc" },
	{}
};

@@ -487,6 +558,28 @@ static void cpucc_clk_populate_opp_table(struct platform_device *pdev)
	cpucc_clk_print_opp_table(final_cpu);
}

static void cpucc_sdxnightjar_fixup(void)
{
	apcs_cpu_pll.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT];
	apcs_cpu_pll.vco_table = alpha_pll_vco;
	apcs_cpu_pll.num_vco = sizeof(alpha_pll_vco);

	apcs_cpu_pll.clkr.hw.init = &apcs_cpu_pll_sdxnightjar;
	apcs_cpu_pll.clkr.vdd_data.rate_max[VDD_MIN] = 0;
	apcs_cpu_pll.clkr.vdd_data.rate_max[VDD_LOW] = 1000000000;
	apcs_cpu_pll.clkr.vdd_data.rate_max[VDD_LOW_L1] = 0;
	apcs_cpu_pll.clkr.vdd_data.rate_max[VDD_NOMINAL] = 2000000000;

	/* GPLL0 as safe source Index */
	apcs_mux_clk.safe_src = 1;
	apcs_mux_clk.safe_div = 1;

	apcs_mux_clk.clk_nb.notifier_call = cpucc_notifier_cb;

	clk_alpha_pll_configure(&apcs_cpu_pll, apcs_cpu_pll.clkr.regmap,
				&apcs_cpu_alpha_pll_config);
}

static int cpucc_get_and_parse_dt_resource(struct platform_device *pdev,
						unsigned long *xo_rate)
{
@@ -597,6 +690,7 @@ static int cpucc_driver_probe(struct platform_device *pdev)
	struct clk_hw_onecell_data *data;
	struct device *dev = &pdev->dev;
	int i, ret, cpu;
	bool is_sdxnightjar;
	unsigned long xo_rate;
	u32 l_val;

@@ -604,9 +698,17 @@ static int cpucc_driver_probe(struct platform_device *pdev)
	if (ret < 0)
		return ret;

	is_sdxnightjar = of_device_is_compatible(pdev->dev.of_node,
						 "qcom,sdxnightjar-apsscc");

	if (is_sdxnightjar) {
		l_val = apcs_cpu_alpha_pll_config.l;
		cpucc_sdxnightjar_fixup();
	} else {
		l_val = apcs_cpu_pll_config.l;
		clk_lucid_5lpe_pll_configure(&apcs_cpu_pll, apcs_cpu_pll.clkr.regmap,
								&apcs_cpu_pll_config);
	}

	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
	if (!data)
@@ -631,6 +733,16 @@ static int cpucc_driver_probe(struct platform_device *pdev)
		return ret;
	}

	if (is_sdxnightjar) {
		ret = clk_notifier_register(apcs_mux_clk.clkr.hw.clk,
							&apcs_mux_clk.clk_nb);
		if (ret) {
			dev_err(&pdev->dev,
				"failed to register clock notifier: %d\n", ret);
			return ret;
		}
	}

	/* Set to boot frequency */
	ret = clk_set_rate(apcs_mux_clk.clkr.hw.clk, l_val * xo_rate);
	if (ret) {