clk: qcom: Add additional clock debugfs support

Update QCOM clock debugfs to support the below functionalities.
 - Display the register contents of all the clocks which support
   this operation.
 - Display the frequency to voltage mapping of a clock.
 - Display the list of clock frequencies supported by the root
   clocks.
 - Display the clk_rate_max associated with enabled clocks list.

Also add the clock list_rate_vdd_level operation, which is required
for the "clk_enabled_list" and "trace_clocks" debugfs nodes to print
the current voltage.

Change-Id: I3b4cf83e776750d993d53331142223109bf0862e
Signed-off-by: Taniya Das <tdas@codeaurora.org>
Signed-off-by: Deepak Katragadda <dkatraga@codeaurora.org>
Signed-off-by: David Dai <daidavid1@codeaurora.org>
Signed-off-by: Mike Tipton <mdtipton@codeaurora.org>
This commit is contained in:
Taniya Das 2016-11-07 10:01:38 +05:30 committed by Mike Tipton
parent 0028e0c356
commit 39024b050c
7 changed files with 607 additions and 5 deletions

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2015, 2018-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2015, 2018-2021, The Linux Foundation. All rights reserved.
*/
#include <linux/kernel.h>
@ -10,6 +10,7 @@
#include <linux/delay.h>
#include "clk-alpha-pll.h"
#include "clk-debug.h"
#include "common.h"
#define PLL_MODE(p) ((p)->offset + 0x0)
@ -115,6 +116,9 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = {
[PLL_OFF_STATUS] = 0x30,
[PLL_OFF_OPMODE] = 0x38,
[PLL_OFF_ALPHA_VAL] = 0x40,
[PLL_OFF_SSC_DELTA_ALPHA] = 0x48,
[PLL_OFF_SSC_NUM_STEPS] = 0x4C,
[PLL_OFF_SSC_UPDATE_RATE] = 0x50,
},
[CLK_ALPHA_PLL_TYPE_AGERA] = {
[PLL_OFF_L_VAL] = 0x04,
@ -904,6 +908,55 @@ clk_trion_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
return alpha_pll_calc_rate(parent_rate, l, frac, alpha_width);
}
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);
int size, i, val;
static struct clk_register_data data[] = {
{"PLL_MODE", 0x0},
{"PLL_L_VAL", 0x4},
{"PLL_ALPHA_VAL", 0x8},
{"PLL_ALPHA_VAL_U", 0xC},
{"PLL_USER_CTL", 0x10},
{"PLL_CONFIG_CTL", 0x18},
};
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 + data[i].offset,
&val);
clock_debug_output(f, "%20s: 0x%.8x\n", data[i].name, val);
}
regmap_read(pll->clkr.regmap, pll->offset + 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, "%20s: 0x%.8x\n", data1[0].name, val);
}
}
static struct clk_regmap_ops clk_alpha_pll_regmap_ops = {
.list_registers = clk_alpha_pll_list_registers,
};
static int clk_alpha_pll_init(struct clk_hw *hw)
{
struct clk_regmap *rclk = to_clk_regmap(hw);
if (!rclk->ops)
rclk->ops = &clk_alpha_pll_regmap_ops;
return 0;
}
const struct clk_ops clk_alpha_pll_fixed_ops = {
.prepare = clk_prepare_regmap,
.unprepare = clk_unprepare_regmap,
@ -913,6 +966,8 @@ const struct clk_ops clk_alpha_pll_fixed_ops = {
.disable = clk_alpha_pll_disable,
.is_enabled = clk_alpha_pll_is_enabled,
.recalc_rate = clk_alpha_pll_recalc_rate,
.init = clk_alpha_pll_init,
.debug_init = clk_common_debug_init,
};
EXPORT_SYMBOL_GPL(clk_alpha_pll_fixed_ops);
@ -927,9 +982,68 @@ const struct clk_ops clk_alpha_pll_ops = {
.recalc_rate = clk_alpha_pll_recalc_rate,
.round_rate = clk_alpha_pll_round_rate,
.set_rate = clk_alpha_pll_set_rate,
.init = clk_alpha_pll_init,
.debug_init = clk_common_debug_init,
};
EXPORT_SYMBOL_GPL(clk_alpha_pll_ops);
static void clk_alpha_pll_huayra_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, "%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, "%20s: 0x%.8x\n", data1[0].name, val);
}
}
static struct clk_regmap_ops clk_alpha_pll_huayra_regmap_ops = {
.list_registers = clk_alpha_pll_huayra_list_registers,
};
static int clk_alpha_pll_huayra_init(struct clk_hw *hw)
{
struct clk_regmap *rclk = to_clk_regmap(hw);
if (!rclk->ops)
rclk->ops = &clk_alpha_pll_huayra_regmap_ops;
return 0;
}
const struct clk_ops clk_alpha_pll_huayra_ops = {
.prepare = clk_prepare_regmap,
.unprepare = clk_unprepare_regmap,
@ -941,6 +1055,8 @@ 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,
.init = clk_alpha_pll_huayra_init,
.debug_init = clk_common_debug_init,
};
EXPORT_SYMBOL_GPL(clk_alpha_pll_huayra_ops);
@ -955,9 +1071,70 @@ const struct clk_ops clk_alpha_pll_hwfsm_ops = {
.recalc_rate = clk_alpha_pll_recalc_rate,
.round_rate = clk_alpha_pll_round_rate,
.set_rate = clk_alpha_pll_hwfsm_set_rate,
.init = clk_alpha_pll_init,
.debug_init = clk_common_debug_init,
};
EXPORT_SYMBOL_GPL(clk_alpha_pll_hwfsm_ops);
static void clk_trion_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_CAL_L_VAL", PLL_OFF_CAL_L_VAL},
{"PLL_USER_CTL", PLL_OFF_USER_CTL},
{"PLL_USER_CTL_U", PLL_OFF_USER_CTL_U},
{"PLL_USER_CTL_U1", PLL_OFF_USER_CTL_U1},
{"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_STATUS", PLL_OFF_STATUS},
{"PLL_OPMODE", PLL_OFF_OPMODE},
{"PLL_ALPHA_VAL", PLL_OFF_ALPHA_VAL},
};
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, "%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, "%20s: 0x%.8x\n", data1[0].name, val);
}
}
static struct clk_regmap_ops clk_trion_pll_regmap_ops = {
.list_registers = &clk_trion_pll_list_registers,
};
static int clk_trion_pll_init(struct clk_hw *hw)
{
struct clk_regmap *rclk = to_clk_regmap(hw);
if (!rclk->ops)
rclk->ops = &clk_trion_pll_regmap_ops;
return 0;
}
const struct clk_ops clk_alpha_pll_fixed_trion_ops = {
.prepare = clk_prepare_regmap,
.unprepare = clk_unprepare_regmap,
@ -968,6 +1145,8 @@ const struct clk_ops clk_alpha_pll_fixed_trion_ops = {
.is_enabled = clk_trion_pll_is_enabled,
.recalc_rate = clk_trion_pll_recalc_rate,
.round_rate = clk_alpha_pll_round_rate,
.debug_init = clk_common_debug_init,
.init = clk_trion_pll_init,
};
EXPORT_SYMBOL_GPL(clk_alpha_pll_fixed_trion_ops);
@ -1299,6 +1478,62 @@ static int alpha_pll_fabia_prepare(struct clk_hw *hw)
return 0;
}
static void clk_fabia_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_CAL_L_VAL", PLL_OFF_CAL_L_VAL},
{"PLL_USER_CTL", PLL_OFF_USER_CTL},
{"PLL_USER_CTL_U", PLL_OFF_USER_CTL_U},
{"PLL_CONFIG_CTL", PLL_OFF_CONFIG_CTL},
{"PLL_CONFIG_CTL_U", PLL_OFF_CONFIG_CTL_U},
{"PLL_TEST_CTL", PLL_OFF_TEST_CTL},
{"PLL_TEST_CTL_U", PLL_OFF_TEST_CTL_U},
{"PLL_STATUS", PLL_OFF_STATUS},
{"PLL_OPMODE", PLL_OFF_OPMODE},
{"PLL_FRAC", PLL_OFF_FRAC},
};
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, "%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, "%20s: 0x%.8x\n", data1[0].name, val);
}
}
static struct clk_regmap_ops clk_fabia_pll_regmap_ops = {
.list_registers = &clk_fabia_pll_list_registers,
};
static int clk_fabia_pll_init(struct clk_hw *hw)
{
struct clk_regmap *rclk = to_clk_regmap(hw);
if (!rclk->ops)
rclk->ops = &clk_fabia_pll_regmap_ops;
return 0;
}
const struct clk_ops clk_alpha_pll_fabia_ops = {
.prepare = alpha_pll_fabia_prepare,
.unprepare = clk_unprepare_regmap,
@ -1310,6 +1545,8 @@ const struct clk_ops clk_alpha_pll_fabia_ops = {
.set_rate = alpha_pll_fabia_set_rate,
.recalc_rate = alpha_pll_fabia_recalc_rate,
.round_rate = clk_alpha_pll_round_rate,
.debug_init = clk_common_debug_init,
.init = clk_fabia_pll_init,
};
EXPORT_SYMBOL_GPL(clk_alpha_pll_fabia_ops);
@ -1323,6 +1560,8 @@ const struct clk_ops clk_alpha_pll_fixed_fabia_ops = {
.is_enabled = clk_alpha_pll_is_enabled,
.recalc_rate = alpha_pll_fabia_recalc_rate,
.round_rate = clk_alpha_pll_round_rate,
.debug_init = clk_common_debug_init,
.init = clk_fabia_pll_init,
};
EXPORT_SYMBOL_GPL(clk_alpha_pll_fixed_fabia_ops);
@ -1617,9 +1856,74 @@ const struct clk_ops clk_alpha_pll_trion_ops = {
.recalc_rate = clk_trion_pll_recalc_rate,
.round_rate = clk_alpha_pll_round_rate,
.set_rate = alpha_pll_trion_set_rate,
.debug_init = clk_common_debug_init,
.init = clk_trion_pll_init,
};
EXPORT_SYMBOL_GPL(clk_alpha_pll_trion_ops);
static void lucid_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_CAL_L_VAL", PLL_OFF_CAL_L_VAL},
{"PLL_USER_CTL", PLL_OFF_USER_CTL},
{"PLL_USER_CTL_U", PLL_OFF_USER_CTL_U},
{"PLL_USER_CTL_U1", PLL_OFF_USER_CTL_U1},
{"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_STATUS", PLL_OFF_STATUS},
{"PLL_OPMODE", PLL_OFF_OPMODE},
{"PLL_ALPHA_VAL", PLL_OFF_ALPHA_VAL},
{"PLL_SSC_DELTA_ALPHA", PLL_OFF_SSC_DELTA_ALPHA},
{"PLL_SSC_NUM_STEPS", PLL_OFF_SSC_NUM_STEPS},
{"PLL_SSC_UPDATE_RATE", PLL_OFF_SSC_UPDATE_RATE},
};
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, "%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, "%20s: 0x%.8x\n", data[0].name, val);
}
}
static struct clk_regmap_ops clk_lucid_pll_regmap_ops = {
.list_registers = &lucid_pll_list_registers,
};
static int clk_lucid_pll_init(struct clk_hw *hw)
{
struct clk_regmap *rclk = to_clk_regmap(hw);
if (!rclk->ops)
rclk->ops = &clk_lucid_pll_regmap_ops;
return 0;
}
const struct clk_ops clk_alpha_pll_lucid_ops = {
.prepare = alpha_pll_lucid_prepare,
.unprepare = clk_unprepare_regmap,
@ -1631,6 +1935,8 @@ const struct clk_ops clk_alpha_pll_lucid_ops = {
.recalc_rate = clk_trion_pll_recalc_rate,
.round_rate = clk_alpha_pll_round_rate,
.set_rate = alpha_pll_trion_set_rate,
.debug_init = clk_common_debug_init,
.init = clk_lucid_pll_init,
};
EXPORT_SYMBOL_GPL(clk_alpha_pll_lucid_ops);
@ -1683,6 +1989,59 @@ static int clk_alpha_pll_agera_set_rate(struct clk_hw *hw, unsigned long rate,
return 0;
}
static void clk_agera_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_TEST_CTL", PLL_OFF_TEST_CTL},
{"PLL_TEST_CTL_U", PLL_OFF_TEST_CTL_U},
{"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, "%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, "%20s: 0x%.8x\n", data[0].name, val);
}
}
static struct clk_regmap_ops clk_agera_pll_regmap_ops = {
.list_registers = clk_agera_pll_list_registers,
};
static int clk_agera_pll_init(struct clk_hw *hw)
{
struct clk_regmap *rclk = to_clk_regmap(hw);
if (!rclk->ops)
rclk->ops = &clk_agera_pll_regmap_ops;
return 0;
}
const struct clk_ops clk_alpha_pll_agera_ops = {
.prepare = clk_prepare_regmap,
.unprepare = clk_unprepare_regmap,
@ -1694,6 +2053,8 @@ const struct clk_ops clk_alpha_pll_agera_ops = {
.recalc_rate = alpha_pll_fabia_recalc_rate,
.round_rate = clk_alpha_pll_round_rate,
.set_rate = clk_alpha_pll_agera_set_rate,
.debug_init = clk_common_debug_init,
.init = clk_agera_pll_init,
};
EXPORT_SYMBOL_GPL(clk_alpha_pll_agera_ops);
@ -1852,6 +2213,8 @@ const struct clk_ops clk_alpha_pll_lucid_5lpe_ops = {
.recalc_rate = clk_trion_pll_recalc_rate,
.round_rate = clk_alpha_pll_round_rate,
.set_rate = alpha_pll_lucid_5lpe_set_rate,
.debug_init = clk_common_debug_init,
.init = clk_lucid_pll_init,
};
EXPORT_SYMBOL(clk_alpha_pll_lucid_5lpe_ops);
@ -1865,6 +2228,8 @@ const struct clk_ops clk_alpha_pll_fixed_lucid_5lpe_ops = {
.is_enabled = clk_trion_pll_is_enabled,
.recalc_rate = clk_trion_pll_recalc_rate,
.round_rate = clk_alpha_pll_round_rate,
.debug_init = clk_common_debug_init,
.init = clk_lucid_pll_init,
};
EXPORT_SYMBOL(clk_alpha_pll_fixed_lucid_5lpe_ops);
@ -2018,6 +2383,65 @@ static int clk_zonda_pll_set_rate(struct clk_hw *hw, unsigned long rate,
return 0;
}
static void clk_alpha_pll_zonda_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},
{"PLL_SSC_DELTA_ALPHA", PLL_OFF_SSC_DELTA_ALPHA},
{"PLL_SSC_UPDATE_RATE", PLL_OFF_SSC_UPDATE_RATE},
};
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, "%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, "%20s: 0x%.8x\n", data1[0].name, val);
}
}
static struct clk_regmap_ops clk_alpha_pll_zonda_regmap_ops = {
.list_registers = clk_alpha_pll_zonda_list_registers,
};
static int clk_alpha_pll_zonda_init(struct clk_hw *hw)
{
struct clk_regmap *rclk = to_clk_regmap(hw);
if (!rclk->ops)
rclk->ops = &clk_alpha_pll_zonda_regmap_ops;
return 0;
}
const struct clk_ops clk_alpha_pll_zonda_ops = {
.prepare = clk_prepare_regmap,
.unprepare = clk_unprepare_regmap,
@ -2029,5 +2453,7 @@ const struct clk_ops clk_alpha_pll_zonda_ops = {
.recalc_rate = clk_trion_pll_recalc_rate,
.round_rate = clk_alpha_pll_round_rate,
.set_rate = clk_zonda_pll_set_rate,
.debug_init = clk_common_debug_init,
.init = clk_alpha_pll_zonda_init,
};
EXPORT_SYMBOL(clk_alpha_pll_zonda_ops);

View File

@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (c) 2015, 2018, The Linux Foundation. All rights reserved. */
/* Copyright (c) 2015, 2018, 2021, The Linux Foundation. All rights reserved. */
#ifndef __QCOM_CLK_ALPHA_PLL_H__
#define __QCOM_CLK_ALPHA_PLL_H__
@ -21,6 +21,7 @@ enum {
};
enum {
PLL_OFF_MODE,
PLL_OFF_L_VAL,
PLL_OFF_CAL_L_VAL,
PLL_OFF_ALPHA_VAL,
@ -38,6 +39,9 @@ enum {
PLL_OFF_OPMODE,
PLL_OFF_FRAC,
PLL_OFF_CAL_VAL,
PLL_OFF_SSC_DELTA_ALPHA,
PLL_OFF_SSC_NUM_STEPS,
PLL_OFF_SSC_UPDATE_RATE,
PLL_OFF_MAX_REGS
};

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2013, 2016, 2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2013, 2016, 2020-2021, The Linux Foundation. All rights reserved.
*/
#include <linux/kernel.h>
@ -14,6 +14,8 @@
#include <linux/clk/qcom.h>
#include "clk-branch.h"
#include "clk-debug.h"
#include "clk-regmap.h"
static bool clk_branch_in_hwcg_mode(const struct clk_branch *br)
{
@ -125,10 +127,17 @@ static void clk_branch_disable(struct clk_hw *hw)
clk_branch_toggle(hw, false, clk_branch_check_halt);
}
static void clk_branch_debug_init(struct clk_hw *hw, struct dentry *dentry)
{
clk_common_debug_init(hw, dentry);
clk_debug_measure_add(hw, dentry);
}
const struct clk_ops clk_branch_ops = {
.enable = clk_branch_enable,
.disable = clk_branch_disable,
.is_enabled = clk_is_enabled_regmap,
.debug_init = clk_branch_debug_init,
};
EXPORT_SYMBOL_GPL(clk_branch_ops);
@ -162,6 +171,57 @@ static void clk_branch2_force_off_disable(struct clk_hw *hw)
clk_branch2_disable(hw);
}
static void clk_branch2_list_registers(struct seq_file *f, struct clk_hw *hw)
{
struct clk_branch *br = to_clk_branch(hw);
struct clk_regmap *rclk = to_clk_regmap(hw);
int size, i, val;
static struct clk_register_data data[] = {
{"CBCR", 0x0},
};
static struct clk_register_data data1[] = {
{"APSS_VOTE", 0x0},
{"APSS_SLEEP_VOTE", 0x4},
};
size = ARRAY_SIZE(data);
for (i = 0; i < size; i++) {
regmap_read(br->clkr.regmap, br->halt_reg + data[i].offset,
&val);
seq_printf(f, "%20s: 0x%.8x\n", data[i].name, val);
}
if ((br->halt_check & BRANCH_HALT_VOTED) &&
!(br->halt_check & BRANCH_VOTED)) {
if (rclk->enable_reg) {
size = ARRAY_SIZE(data1);
for (i = 0; i < size; i++) {
regmap_read(br->clkr.regmap, rclk->enable_reg +
data1[i].offset, &val);
seq_printf(f, "%20s: 0x%.8x\n",
data1[i].name, val);
}
}
}
}
static struct clk_regmap_ops clk_branch2_regmap_ops = {
.list_registers = clk_branch2_list_registers,
};
static int clk_branch2_init(struct clk_hw *hw)
{
struct clk_regmap *rclk = to_clk_regmap(hw);
if (!rclk->ops)
rclk->ops = &clk_branch2_regmap_ops;
return 0;
}
const struct clk_ops clk_branch2_ops = {
.prepare = clk_prepare_regmap,
.unprepare = clk_unprepare_regmap,
@ -170,12 +230,16 @@ const struct clk_ops clk_branch2_ops = {
.enable = clk_branch2_enable,
.disable = clk_branch2_disable,
.is_enabled = clk_is_enabled_regmap,
.init = clk_branch2_init,
.debug_init = clk_branch_debug_init,
};
EXPORT_SYMBOL_GPL(clk_branch2_ops);
const struct clk_ops clk_branch2_aon_ops = {
.enable = clk_branch2_enable,
.is_enabled = clk_is_enabled_regmap,
.init = clk_branch2_init,
.debug_init = clk_branch_debug_init,
};
EXPORT_SYMBOL_GPL(clk_branch2_aon_ops);
@ -183,6 +247,8 @@ const struct clk_ops clk_branch2_force_off_ops = {
.enable = clk_branch2_force_off_enable,
.disable = clk_branch2_force_off_disable,
.is_enabled = clk_is_enabled_regmap,
.init = clk_branch2_init,
.debug_init = clk_branch_debug_init,
};
EXPORT_SYMBOL(clk_branch2_force_off_ops);
@ -234,6 +300,8 @@ const struct clk_ops clk_branch2_hw_ctl_ops = {
.is_enabled = clk_is_enabled_regmap,
.recalc_rate = clk_branch2_hw_ctl_recalc_rate,
.determine_rate = clk_branch2_hw_ctl_determine_rate,
.init = clk_branch2_init,
.debug_init = clk_branch_debug_init,
};
EXPORT_SYMBOL(clk_branch2_hw_ctl_ops);
@ -241,6 +309,8 @@ const struct clk_ops clk_branch_simple_ops = {
.enable = clk_enable_regmap,
.disable = clk_disable_regmap,
.is_enabled = clk_is_enabled_regmap,
.init = clk_branch2_init,
.debug_init = clk_branch_debug_init,
};
EXPORT_SYMBOL_GPL(clk_branch_simple_ops);

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2018-2019, 2021, The Linux Foundation. All rights reserved.
*/
#include <linux/clk-provider.h>
@ -11,6 +11,7 @@
#include <linux/slab.h>
#include "common.h"
#include "clk-debug.h"
#define to_clk_dummy(_hw) container_of(_hw, struct clk_dummy, hw)
@ -49,6 +50,7 @@ const struct clk_ops clk_dummy_ops = {
.set_rate = dummy_clk_set_rate,
.round_rate = dummy_clk_round_rate,
.recalc_rate = dummy_clk_recalc_rate,
.debug_init = clk_debug_measure_add,
};
EXPORT_SYMBOL(clk_dummy_ops);

View File

@ -20,6 +20,7 @@
#include "clk-rcg.h"
#include "common.h"
#include "clk-debug.h"
#define CMD_REG 0x0
#define CMD_UPDATE BIT(0)
@ -447,6 +448,61 @@ static int clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f)
return update_config(rcg);
}
static void clk_rcg2_list_registers(struct seq_file *f, struct clk_hw *hw)
{
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
int i = 0, size = 0, val;
static struct clk_register_data data[] = {
{"CMD_RCGR", 0x0},
{"CFG_RCGR", 0x4},
};
static struct clk_register_data data1[] = {
{"CMD_RCGR", 0x0},
{"CFG_RCGR", 0x4},
{"M_VAL", 0x8},
{"N_VAL", 0xC},
{"D_VAL", 0x10},
};
if (rcg->mnd_width) {
size = ARRAY_SIZE(data1);
for (i = 0; i < size; i++) {
regmap_read(rcg->clkr.regmap, (rcg->cmd_rcgr +
data1[i].offset), &val);
seq_printf(f, "%20s: 0x%.8x\n", data1[i].name, val);
}
} else {
size = ARRAY_SIZE(data);
for (i = 0; i < size; i++) {
regmap_read(rcg->clkr.regmap, (rcg->cmd_rcgr +
data[i].offset), &val);
seq_printf(f, "%20s: 0x%.8x\n", data[i].name, val);
}
}
}
/* Return the nth supported frequency for a given clock. */
static long clk_rcg2_list_rate(struct clk_hw *hw, unsigned int n,
unsigned long fmax)
{
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
const struct freq_tbl *f = rcg->freq_tbl;
size_t freq_tbl_size = 0;
if (!f)
return -ENXIO;
for (; f->freq; f++)
freq_tbl_size++;
if (n > freq_tbl_size - 1)
return -EINVAL;
return (rcg->freq_tbl + n)->freq;
}
static int __clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate,
enum freq_policy policy)
{
@ -708,6 +764,21 @@ static void clk_rcg2_disable(struct clk_hw *hw)
clk_rcg2_clear_force_enable(hw);
}
static struct clk_regmap_ops clk_rcg2_regmap_ops = {
.list_rate = clk_rcg2_list_rate,
.list_registers = clk_rcg2_list_registers,
};
static int clk_rcg2_init(struct clk_hw *hw)
{
struct clk_regmap *rclk = to_clk_regmap(hw);
if (!rclk->ops)
rclk->ops = &clk_rcg2_regmap_ops;
return 0;
}
const struct clk_ops clk_rcg2_ops = {
.prepare = clk_prepare_regmap,
.unprepare = clk_unprepare_regmap,
@ -724,6 +795,8 @@ const struct clk_ops clk_rcg2_ops = {
.set_rate_and_parent = clk_rcg2_set_rate_and_parent,
.get_duty_cycle = clk_rcg2_get_duty_cycle,
.set_duty_cycle = clk_rcg2_set_duty_cycle,
.init = clk_rcg2_init,
.debug_init = clk_common_debug_init,
};
EXPORT_SYMBOL_GPL(clk_rcg2_ops);
@ -741,6 +814,8 @@ const struct clk_ops clk_rcg2_floor_ops = {
.set_rate_and_parent = clk_rcg2_set_floor_rate_and_parent,
.get_duty_cycle = clk_rcg2_get_duty_cycle,
.set_duty_cycle = clk_rcg2_set_duty_cycle,
.init = clk_rcg2_init,
.debug_init = clk_common_debug_init,
};
EXPORT_SYMBOL_GPL(clk_rcg2_floor_ops);
@ -874,6 +949,8 @@ const struct clk_ops clk_edp_pixel_ops = {
.set_rate = clk_edp_pixel_set_rate,
.set_rate_and_parent = clk_edp_pixel_set_rate_and_parent,
.determine_rate = clk_edp_pixel_determine_rate,
.init = clk_rcg2_init,
.debug_init = clk_common_debug_init,
};
EXPORT_SYMBOL_GPL(clk_edp_pixel_ops);
@ -938,6 +1015,8 @@ const struct clk_ops clk_byte_ops = {
.set_rate = clk_byte_set_rate,
.set_rate_and_parent = clk_byte_set_rate_and_parent,
.determine_rate = clk_byte_determine_rate,
.init = clk_rcg2_init,
.debug_init = clk_common_debug_init,
};
EXPORT_SYMBOL_GPL(clk_byte_ops);
@ -1013,6 +1092,8 @@ const struct clk_ops clk_byte2_ops = {
.set_rate = clk_byte2_set_rate,
.set_rate_and_parent = clk_byte2_set_rate_and_parent,
.determine_rate = clk_byte2_determine_rate,
.init = clk_rcg2_init,
.debug_init = clk_common_debug_init,
};
EXPORT_SYMBOL_GPL(clk_byte2_ops);
@ -1110,6 +1191,8 @@ const struct clk_ops clk_pixel_ops = {
.set_rate = clk_pixel_set_rate,
.set_rate_and_parent = clk_pixel_set_rate_and_parent,
.determine_rate = clk_pixel_determine_rate,
.init = clk_rcg2_init,
.debug_init = clk_common_debug_init,
};
EXPORT_SYMBOL_GPL(clk_pixel_ops);
@ -1221,6 +1304,8 @@ const struct clk_ops clk_gfx3d_ops = {
.set_rate = clk_gfx3d_set_rate,
.set_rate_and_parent = clk_gfx3d_set_rate_and_parent,
.determine_rate = clk_gfx3d_determine_rate,
.init = clk_rcg2_init,
.debug_init = clk_common_debug_init,
};
EXPORT_SYMBOL_GPL(clk_gfx3d_ops);
@ -1332,6 +1417,8 @@ const struct clk_ops clk_rcg2_shared_ops = {
.determine_rate = clk_rcg2_determine_rate,
.set_rate = clk_rcg2_shared_set_rate,
.set_rate_and_parent = clk_rcg2_shared_set_rate_and_parent,
.init = clk_rcg2_init,
.debug_init = clk_common_debug_init,
};
EXPORT_SYMBOL_GPL(clk_rcg2_shared_ops);
@ -1481,6 +1568,8 @@ static const struct clk_ops clk_rcg2_dfs_ops = {
.get_parent = clk_rcg2_get_parent,
.determine_rate = clk_rcg2_dfs_determine_rate,
.recalc_rate = clk_rcg2_dfs_recalc_rate,
.init = clk_rcg2_init,
.debug_init = clk_common_debug_init,
};
static int clk_rcg2_enable_dfs(const struct clk_rcg_dfs_data *data,
@ -1609,5 +1698,7 @@ const struct clk_ops clk_dp_ops = {
.set_rate = clk_rcg2_dp_set_rate,
.set_rate_and_parent = clk_rcg2_dp_set_rate_and_parent,
.determine_rate = clk_rcg2_dp_determine_rate,
.init = clk_rcg2_init,
.debug_init = clk_common_debug_init,
};
EXPORT_SYMBOL_GPL(clk_dp_ops);

View File

@ -10,6 +10,7 @@
#include <linux/pm_runtime.h>
#include "clk-regmap.h"
#include "clk-debug.h"
static LIST_HEAD(clk_regmap_list);
static DEFINE_MUTEX(clk_regmap_lock);
@ -300,6 +301,8 @@ int devm_clk_register_regmap(struct device *dev, struct clk_regmap *rclk)
mutex_lock(&clk_regmap_lock);
list_add(&rclk->list_node, &clk_regmap_list);
mutex_unlock(&clk_regmap_lock);
ret = clk_hw_debug_register(dev, &rclk->hw);
}
return ret;

View File

@ -1,10 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2014, 2019-2020, The Linux Foundation. All rights reserved. */
/* Copyright (c) 2014, 2019-2021, The Linux Foundation. All rights reserved. */
#ifndef __QCOM_CLK_REGMAP_H__
#define __QCOM_CLK_REGMAP_H__
#include <linux/clk-provider.h>
#include <linux/debugfs.h>
#include "vdd-class.h"
struct regmap;
@ -72,4 +73,9 @@ bool clk_is_regmap_clk(struct clk_hw *hw);
int clk_runtime_get_regmap(struct clk_regmap *rclk);
void clk_runtime_put_regmap(struct clk_regmap *rclk);
struct clk_register_data {
char *name;
u32 offset;
};
#endif