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

Commit 0bab6ead authored by Naveen Yadav's avatar Naveen Yadav
Browse files

clk: qcom: clk-alpha-pll: Add support for controlling huayra PLLs



Add support for initial configuration and programming sequence
for controlling huayra PLLs. Also add list register op to dump
the register contents from debugfs and also in cases of failure
of PLL.

Change-Id: I05bc3f5d6a7f87ab169775f68260b86f283d958b
Signed-off-by: default avatarNaveen Yadav <naveenky@codeaurora.org>
parent 38ae0c3a
Loading
Loading
Loading
Loading
+106 −0
Original line number Diff line number Diff line
@@ -699,6 +699,67 @@ static long clk_alpha_pll_round_rate(struct clk_hw *hw, unsigned long rate,
	return clamp(rate, min_freq, max_freq);
}

void clk_huayra_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
				const struct alpha_pll_config *config)
{
	if (config->config_ctl_val)
		regmap_write(regmap, PLL_CONFIG_CTL(pll),
				config->config_ctl_val);

	if (config->config_ctl_hi_val)
		regmap_write(regmap, PLL_CONFIG_CTL_U(pll),
				config->config_ctl_hi_val);

	if (config->config_ctl_hi1_val)
		regmap_write(regmap, PLL_CONFIG_CTL_U1(pll),
				config->config_ctl_hi1_val);

	if (config->test_ctl_val)
		regmap_write(regmap, PLL_TEST_CTL(pll),
				config->test_ctl_val);

	if (config->test_ctl_hi_val)
		regmap_write(regmap, PLL_TEST_CTL_U(pll),
				config->test_ctl_hi_val);

	if (config->test_ctl_hi1_val)
		regmap_write(regmap, PLL_TEST_CTL_U1(pll),
				config->test_ctl_hi1_val);

	if (config->l)
		regmap_write(regmap, PLL_L_VAL(pll), config->l);

	if (config->alpha)
		regmap_write(regmap, PLL_ALPHA_VAL(pll), config->alpha);

	if (config->user_ctl_val)
		regmap_write(regmap, PLL_USER_CTL(pll),
				config->user_ctl_val);

	/* Set PLL_BYPASSNL */
	regmap_update_bits(regmap, PLL_MODE(pll),
			 PLL_BYPASSNL, PLL_BYPASSNL);

	/*
	 * H/W requires a 1us delay between disabling the bypass and
	 * de-asserting the reset.
	 */
	mb();
	udelay(5);

	/* Take PLL out from reset state */
	regmap_update_bits(regmap, PLL_MODE(pll),
				 PLL_RESET_N, PLL_RESET_N);

	/* Wait 50us for pll_lock_det bit to go high */
	mb();
	udelay(50);

	/* Enables PLL output */
	regmap_update_bits(regmap, PLL_MODE(pll),
			 PLL_OUTCTRL, PLL_OUTCTRL);
}

static unsigned long
alpha_huayra_pll_calc_rate(u64 prate, u32 l, u32 a)
{
@@ -851,6 +912,50 @@ static long alpha_pll_huayra_round_rate(struct clk_hw *hw, unsigned long rate,
	return alpha_huayra_pll_round_rate(rate, *prate, &l, &a);
}

static void clk_huayra_pll_list_registers(struct seq_file *f, struct clk_hw *hw)
{
	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
	int size, i, val;

	static struct clk_register_data data[] = {
		{"PLL_MODE", PLL_OFF_MODE},
		{"PLL_L_VAL", PLL_OFF_L_VAL},
		{"PLL_ALPHA_VAL", PLL_OFF_ALPHA_VAL},
		{"PLL_USER_CTL", PLL_OFF_USER_CTL},
		{"PLL_CONFIG_CTL", PLL_OFF_CONFIG_CTL},
		{"PLL_CONFIG_CTL_U", PLL_OFF_CONFIG_CTL_U},
		{"PLL_CONFIG_CTL_U1", PLL_OFF_CONFIG_CTL_U1},
		{"PLL_TEST_CTL", PLL_OFF_TEST_CTL},
		{"PLL_TEST_CTL_U", PLL_OFF_TEST_CTL_U},
		{"PLL_TEST_CTL_U1", PLL_OFF_TEST_CTL_U1},
		{"PLL_OPMODE", PLL_OFF_OPMODE},
		{"PLL_STATUS", PLL_OFF_STATUS},
	};

	static struct clk_register_data data1[] = {
		{"APSS_PLL_VOTE", 0x0},
	};

	size = ARRAY_SIZE(data);

	for (i = 0; i < size; i++) {
		regmap_read(pll->clkr.regmap,
				pll->offset + pll->regs[data[i].offset], &val);
		clock_debug_output(f, false,
				"%20s: 0x%.8x\n", data[i].name, val);
	}

	regmap_read(pll->clkr.regmap, pll->offset +
					pll->regs[data[0].offset], &val);

	if (val & PLL_FSM_ENA) {
		regmap_read(pll->clkr.regmap, pll->clkr.enable_reg +
					data1[0].offset, &val);
		clock_debug_output(f, false,
				"%20s: 0x%.8x\n", data1[0].name, val);
	}
}

static void clk_alpha_pll_list_registers(struct seq_file *f, struct clk_hw *hw)
{
	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
@@ -1200,6 +1305,7 @@ const struct clk_ops clk_alpha_pll_huayra_ops = {
	.recalc_rate = alpha_pll_huayra_recalc_rate,
	.round_rate = alpha_pll_huayra_round_rate,
	.set_rate = alpha_pll_huayra_set_rate,
	.list_registers = clk_huayra_pll_list_registers,
	.bus_vote = clk_debug_bus_vote,
};
EXPORT_SYMBOL_GPL(clk_alpha_pll_huayra_ops);
+3 −1
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (c) 2015, 2018-2019, The Linux Foundation. All rights reserved. */
/* Copyright (c) 2015, 2018-2020, The Linux Foundation. All rights reserved. */

#ifndef __QCOM_CLK_ALPHA_PLL_H__
#define __QCOM_CLK_ALPHA_PLL_H__
@@ -152,4 +152,6 @@ void clk_zonda_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
				const struct alpha_pll_config *config);
int clk_agera_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
				const struct alpha_pll_config *config);
void clk_huayra_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
				const struct alpha_pll_config *config);
#endif