File Index
Files and directories
Sign in
FILE

clk-rpmh.c

File preview with syntax highlighting.

linux-6.19.14/drivers/clk/qcom/clk-rpmh.c C
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
   4 */
   5
   6#include <linux/clk-provider.h>
   7#include <linux/err.h>
   8#include <linux/kernel.h>
   9#include <linux/module.h>
  10#include <linux/of.h>
  11#include <linux/platform_device.h>
  12#include <linux/string_choices.h>
  13#include <soc/qcom/cmd-db.h>
  14#include <soc/qcom/rpmh.h>
  15#include <soc/qcom/tcs.h>
  16
  17#include <dt-bindings/clock/qcom,rpmh.h>
  18
  19#define CLK_RPMH_ARC_EN_OFFSET		0
  20#define CLK_RPMH_VRM_EN_OFFSET		4
  21
  22/**
  23 * struct bcm_db - Auxiliary data pertaining to each Bus Clock Manager(BCM)
  24 * @unit: divisor used to convert Hz value to an RPMh msg
  25 * @width: multiplier used to convert Hz value to an RPMh msg
  26 * @vcd: virtual clock domain that this bcm belongs to
  27 * @reserved: reserved to pad the struct
  28 */
  29struct bcm_db {
  30	__le32 unit;
  31	__le16 width;
  32	u8 vcd;
  33	u8 reserved;
  34};
  35
  36/**
  37 * struct clk_rpmh - individual rpmh clock data structure
  38 * @hw:			handle between common and hardware-specific interfaces
  39 * @res_name:		resource name for the rpmh clock
  40 * @div:		clock divider to compute the clock rate
  41 * @res_addr:		base address of the rpmh resource within the RPMh
  42 * @res_on_val:		rpmh clock enable value
  43 * @state:		rpmh clock requested state
  44 * @aggr_state:		rpmh clock aggregated state
  45 * @last_sent_aggr_state: rpmh clock last aggr state sent to RPMh
  46 * @valid_state_mask:	mask to determine the state of the rpmh clock
  47 * @unit:		divisor to convert rate to rpmh msg in magnitudes of Khz
  48 * @dev:		device to which it is attached
  49 * @peer:		pointer to the clock rpmh sibling
  50 */
  51struct clk_rpmh {
  52	struct clk_hw hw;
  53	const char *res_name;
  54	u8 div;
  55	u32 res_addr;
  56	u32 res_on_val;
  57	u32 state;
  58	u32 aggr_state;
  59	u32 last_sent_aggr_state;
  60	u32 valid_state_mask;
  61	u32 unit;
  62	struct device *dev;
  63	struct clk_rpmh *peer;
  64};
  65
  66struct clk_rpmh_desc {
  67	struct clk_hw **clks;
  68	size_t num_clks;
  69	/* RPMh clock clkaN are optional for this platform */
  70	bool clka_optional;
  71};
  72
  73static DEFINE_MUTEX(rpmh_clk_lock);
  74
  75#define __DEFINE_CLK_RPMH(_name, _clk_name, _res_name,			\
  76			  _res_en_offset, _res_on, _div)		\
  77	static struct clk_rpmh clk_rpmh_##_clk_name##_ao;		\
  78	static struct clk_rpmh clk_rpmh_##_clk_name = {			\
  79		.res_name = _res_name,					\
  80		.res_addr = _res_en_offset,				\
  81		.res_on_val = _res_on,					\
  82		.div = _div,						\
  83		.peer = &clk_rpmh_##_clk_name##_ao,			\
  84		.valid_state_mask = (BIT(RPMH_WAKE_ONLY_STATE) |	\
  85				      BIT(RPMH_ACTIVE_ONLY_STATE) |	\
  86				      BIT(RPMH_SLEEP_STATE)),		\
  87		.hw.init = &(struct clk_init_data){			\
  88			.ops = &clk_rpmh_ops,				\
  89			.name = #_name,					\
  90			.parent_data = &(const struct clk_parent_data){ \
  91					.fw_name = "xo",		\
  92					.name = "xo_board",		\
  93			},						\
  94			.num_parents = 1,				\
  95		},							\
  96	};								\
  97	static struct clk_rpmh clk_rpmh_##_clk_name##_ao= {		\
  98		.res_name = _res_name,					\
  99		.res_addr = _res_en_offset,				\
 100		.res_on_val = _res_on,					\
 101		.div = _div,						\
 102		.peer = &clk_rpmh_##_clk_name,				\
 103		.valid_state_mask = (BIT(RPMH_WAKE_ONLY_STATE) |	\
 104					BIT(RPMH_ACTIVE_ONLY_STATE)),	\
 105		.hw.init = &(struct clk_init_data){			\
 106			.ops = &clk_rpmh_ops,				\
 107			.name = #_name "_ao",				\
 108			.parent_data = &(const struct clk_parent_data){ \
 109					.fw_name = "xo",		\
 110					.name = "xo_board",		\
 111			},						\
 112			.num_parents = 1,				\
 113		},							\
 114	}
 115
 116#define DEFINE_CLK_RPMH_ARC(_name, _res_name, _res_on, _div)		\
 117	__DEFINE_CLK_RPMH(_name, _name##_##div##_div, _res_name,	\
 118			  CLK_RPMH_ARC_EN_OFFSET, _res_on, _div)
 119
 120#define DEFINE_CLK_RPMH_VRM(_name, _suffix, _res_name, _div)		\
 121	__DEFINE_CLK_RPMH(_name, _name##_suffix, _res_name,		\
 122			  CLK_RPMH_VRM_EN_OFFSET, 1, _div)
 123
 124#define DEFINE_CLK_RPMH_BCM(_name, _res_name)				\
 125	static struct clk_rpmh clk_rpmh_##_name = {			\
 126		.res_name = _res_name,					\
 127		.valid_state_mask = BIT(RPMH_ACTIVE_ONLY_STATE),	\
 128		.div = 1,						\
 129		.hw.init = &(struct clk_init_data){			\
 130			.ops = &clk_rpmh_bcm_ops,			\
 131			.name = #_name,					\
 132		},							\
 133	}
 134
 135static inline struct clk_rpmh *to_clk_rpmh(struct clk_hw *_hw)
 136{
 137	return container_of(_hw, struct clk_rpmh, hw);
 138}
 139
 140static inline bool has_state_changed(struct clk_rpmh *c, u32 state)
 141{
 142	return (c->last_sent_aggr_state & BIT(state))
 143		!= (c->aggr_state & BIT(state));
 144}
 145
 146static int clk_rpmh_send(struct clk_rpmh *c, enum rpmh_state state,
 147			 struct tcs_cmd *cmd, bool wait)
 148{
 149	if (wait)
 150		return rpmh_write(c->dev, state, cmd, 1);
 151
 152	return rpmh_write_async(c->dev, state, cmd, 1);
 153}
 154
 155static int clk_rpmh_send_aggregate_command(struct clk_rpmh *c)
 156{
 157	struct tcs_cmd cmd = { 0 };
 158	u32 cmd_state, on_val;
 159	enum rpmh_state state = RPMH_SLEEP_STATE;
 160	int ret;
 161	bool wait;
 162
 163	cmd.addr = c->res_addr;
 164	cmd_state = c->aggr_state;
 165	on_val = c->res_on_val;
 166
 167	for (; state <= RPMH_ACTIVE_ONLY_STATE; state++) {
 168		if (has_state_changed(c, state)) {
 169			if (cmd_state & BIT(state))
 170				cmd.data = on_val;
 171
 172			wait = cmd_state && state == RPMH_ACTIVE_ONLY_STATE;
 173			ret = clk_rpmh_send(c, state, &cmd, wait);
 174			if (ret) {
 175				dev_err(c->dev, "set %s state of %s failed: (%d)\n",
 176					!state ? "sleep" :
 177					state == RPMH_WAKE_ONLY_STATE	?
 178					"wake" : "active", c->res_name, ret);
 179				return ret;
 180			}
 181		}
 182	}
 183
 184	c->last_sent_aggr_state = c->aggr_state;
 185	c->peer->last_sent_aggr_state = c->last_sent_aggr_state;
 186
 187	return 0;
 188}
 189
 190/*
 191 * Update state and aggregate state values based on enable value.
 192 */
 193static int clk_rpmh_aggregate_state_send_command(struct clk_rpmh *c,
 194						bool enable)
 195{
 196	int ret;
 197
 198	c->state = enable ? c->valid_state_mask : 0;
 199	c->aggr_state = c->state | c->peer->state;
 200	c->peer->aggr_state = c->aggr_state;
 201
 202	ret = clk_rpmh_send_aggregate_command(c);
 203	if (!ret)
 204		return 0;
 205
 206	if (ret && enable)
 207		c->state = 0;
 208	else if (ret)
 209		c->state = c->valid_state_mask;
 210
 211	WARN(1, "clk: %s failed to %s\n", c->res_name,
 212	     str_enable_disable(enable));
 213	return ret;
 214}
 215
 216static int clk_rpmh_prepare(struct clk_hw *hw)
 217{
 218	struct clk_rpmh *c = to_clk_rpmh(hw);
 219	int ret = 0;
 220
 221	mutex_lock(&rpmh_clk_lock);
 222	ret = clk_rpmh_aggregate_state_send_command(c, true);
 223	mutex_unlock(&rpmh_clk_lock);
 224
 225	return ret;
 226}
 227
 228static void clk_rpmh_unprepare(struct clk_hw *hw)
 229{
 230	struct clk_rpmh *c = to_clk_rpmh(hw);
 231
 232	mutex_lock(&rpmh_clk_lock);
 233	clk_rpmh_aggregate_state_send_command(c, false);
 234	mutex_unlock(&rpmh_clk_lock);
 235};
 236
 237static unsigned long clk_rpmh_recalc_rate(struct clk_hw *hw,
 238					unsigned long prate)
 239{
 240	struct clk_rpmh *r = to_clk_rpmh(hw);
 241
 242	/*
 243	 * RPMh clocks have a fixed rate. Return static rate.
 244	 */
 245	return prate / r->div;
 246}
 247
 248static const struct clk_ops clk_rpmh_ops = {
 249	.prepare	= clk_rpmh_prepare,
 250	.unprepare	= clk_rpmh_unprepare,
 251	.recalc_rate	= clk_rpmh_recalc_rate,
 252};
 253
 254static int clk_rpmh_bcm_send_cmd(struct clk_rpmh *c, bool enable)
 255{
 256	struct tcs_cmd cmd = { 0 };
 257	u32 cmd_state;
 258	int ret = 0;
 259
 260	mutex_lock(&rpmh_clk_lock);
 261	if (enable) {
 262		cmd_state = 1;
 263		if (c->aggr_state)
 264			cmd_state = c->aggr_state;
 265	} else {
 266		cmd_state = 0;
 267	}
 268
 269	cmd_state = min(cmd_state, BCM_TCS_CMD_VOTE_MASK);
 270
 271	if (c->last_sent_aggr_state != cmd_state) {
 272		cmd.addr = c->res_addr;
 273		cmd.data = BCM_TCS_CMD(1, enable, 0, cmd_state);
 274
 275		/*
 276		 * Send only an active only state request. RPMh continues to
 277		 * use the active state when we're in sleep/wake state as long
 278		 * as the sleep/wake state has never been set.
 279		 */
 280		ret = clk_rpmh_send(c, RPMH_ACTIVE_ONLY_STATE, &cmd, enable);
 281		if (ret) {
 282			dev_err(c->dev, "set active state of %s failed: (%d)\n",
 283				c->res_name, ret);
 284		} else {
 285			c->last_sent_aggr_state = cmd_state;
 286		}
 287	}
 288
 289	mutex_unlock(&rpmh_clk_lock);
 290
 291	return ret;
 292}
 293
 294static int clk_rpmh_bcm_prepare(struct clk_hw *hw)
 295{
 296	struct clk_rpmh *c = to_clk_rpmh(hw);
 297
 298	return clk_rpmh_bcm_send_cmd(c, true);
 299}
 300
 301static void clk_rpmh_bcm_unprepare(struct clk_hw *hw)
 302{
 303	struct clk_rpmh *c = to_clk_rpmh(hw);
 304
 305	clk_rpmh_bcm_send_cmd(c, false);
 306}
 307
 308static int clk_rpmh_bcm_set_rate(struct clk_hw *hw, unsigned long rate,
 309				 unsigned long parent_rate)
 310{
 311	struct clk_rpmh *c = to_clk_rpmh(hw);
 312
 313	c->aggr_state = rate / c->unit;
 314	/*
 315	 * Since any non-zero value sent to hw would result in enabling the
 316	 * clock, only send the value if the clock has already been prepared.
 317	 */
 318	if (clk_hw_is_prepared(hw))
 319		clk_rpmh_bcm_send_cmd(c, true);
 320
 321	return 0;
 322}
 323
 324static int clk_rpmh_determine_rate(struct clk_hw *hw,
 325				   struct clk_rate_request *req)
 326{
 327	return 0;
 328}
 329
 330static unsigned long clk_rpmh_bcm_recalc_rate(struct clk_hw *hw,
 331					unsigned long prate)
 332{
 333	struct clk_rpmh *c = to_clk_rpmh(hw);
 334
 335	return (unsigned long)c->aggr_state * c->unit;
 336}
 337
 338static const struct clk_ops clk_rpmh_bcm_ops = {
 339	.prepare	= clk_rpmh_bcm_prepare,
 340	.unprepare	= clk_rpmh_bcm_unprepare,
 341	.set_rate	= clk_rpmh_bcm_set_rate,
 342	.determine_rate = clk_rpmh_determine_rate,
 343	.recalc_rate	= clk_rpmh_bcm_recalc_rate,
 344};
 345
 346/* Resource name must match resource id present in cmd-db */
 347DEFINE_CLK_RPMH_ARC(bi_tcxo, "xo.lvl", 0x3, 1);
 348DEFINE_CLK_RPMH_ARC(bi_tcxo, "xo.lvl", 0x3, 2);
 349DEFINE_CLK_RPMH_ARC(bi_tcxo, "xo.lvl", 0x3, 4);
 350DEFINE_CLK_RPMH_ARC(qlink, "qphy.lvl", 0x1, 4);
 351
 352DEFINE_CLK_RPMH_VRM(ln_bb_clk1, _a2, "lnbclka1", 2);
 353DEFINE_CLK_RPMH_VRM(ln_bb_clk2, _a2, "lnbclka2", 2);
 354DEFINE_CLK_RPMH_VRM(ln_bb_clk3, _a2, "lnbclka3", 2);
 355
 356DEFINE_CLK_RPMH_VRM(ln_bb_clk1, _a4, "lnbclka1", 4);
 357DEFINE_CLK_RPMH_VRM(ln_bb_clk2, _a4, "lnbclka2", 4);
 358DEFINE_CLK_RPMH_VRM(ln_bb_clk3, _a4, "lnbclka3", 4);
 359
 360DEFINE_CLK_RPMH_VRM(ln_bb_clk2, _g4, "lnbclkg2", 4);
 361DEFINE_CLK_RPMH_VRM(ln_bb_clk3, _g4, "lnbclkg3", 4);
 362
 363DEFINE_CLK_RPMH_VRM(rf_clk1, _a, "rfclka1", 1);
 364DEFINE_CLK_RPMH_VRM(rf_clk2, _a, "rfclka2", 1);
 365DEFINE_CLK_RPMH_VRM(rf_clk3, _a, "rfclka3", 1);
 366DEFINE_CLK_RPMH_VRM(rf_clk4, _a, "rfclka4", 1);
 367DEFINE_CLK_RPMH_VRM(rf_clk5, _a, "rfclka5", 1);
 368
 369DEFINE_CLK_RPMH_VRM(rf_clk1, _d, "rfclkd1", 1);
 370DEFINE_CLK_RPMH_VRM(rf_clk2, _d, "rfclkd2", 1);
 371DEFINE_CLK_RPMH_VRM(rf_clk3, _d, "rfclkd3", 1);
 372DEFINE_CLK_RPMH_VRM(rf_clk4, _d, "rfclkd4", 1);
 373
 374DEFINE_CLK_RPMH_VRM(rf_clk3, _a2, "rfclka3", 2);
 375
 376DEFINE_CLK_RPMH_VRM(clk1, _a1, "clka1", 1);
 377DEFINE_CLK_RPMH_VRM(clk2, _a1, "clka2", 1);
 378DEFINE_CLK_RPMH_VRM(clk3, _a1, "clka3", 1);
 379DEFINE_CLK_RPMH_VRM(clk4, _a1, "clka4", 1);
 380DEFINE_CLK_RPMH_VRM(clk5, _a1, "clka5", 1);
 381
 382DEFINE_CLK_RPMH_VRM(clk3, _a2, "clka3", 2);
 383DEFINE_CLK_RPMH_VRM(clk4, _a2, "clka4", 2);
 384DEFINE_CLK_RPMH_VRM(clk5, _a2, "clka5", 2);
 385DEFINE_CLK_RPMH_VRM(clk6, _a2, "clka6", 2);
 386DEFINE_CLK_RPMH_VRM(clk7, _a2, "clka7", 2);
 387DEFINE_CLK_RPMH_VRM(clk8, _a2, "clka8", 2);
 388
 389DEFINE_CLK_RPMH_VRM(clk7, _a4, "clka7", 4);
 390
 391DEFINE_CLK_RPMH_VRM(div_clk1, _div2, "divclka1", 2);
 392
 393DEFINE_CLK_RPMH_VRM(clk3, _a, "C3A_E0", 1);
 394DEFINE_CLK_RPMH_VRM(clk4, _a, "C4A_E0", 1);
 395DEFINE_CLK_RPMH_VRM(clk5, _a, "C5A_E0", 1);
 396DEFINE_CLK_RPMH_VRM(clk8, _a, "C8A_E0", 1);
 397
 398DEFINE_CLK_RPMH_BCM(ce, "CE0");
 399DEFINE_CLK_RPMH_BCM(hwkm, "HK0");
 400DEFINE_CLK_RPMH_BCM(ipa, "IP0");
 401DEFINE_CLK_RPMH_BCM(pka, "PKA0");
 402DEFINE_CLK_RPMH_BCM(qpic_clk, "QP0");
 403
 404static struct clk_hw *sar2130p_rpmh_clocks[] = {
 405	[RPMH_CXO_CLK]		= &clk_rpmh_bi_tcxo_div1.hw,
 406	[RPMH_CXO_CLK_A]	= &clk_rpmh_bi_tcxo_div1_ao.hw,
 407	[RPMH_RF_CLK1]		= &clk_rpmh_rf_clk1_a.hw,
 408	[RPMH_RF_CLK1_A]	= &clk_rpmh_rf_clk1_a_ao.hw,
 409};
 410
 411static const struct clk_rpmh_desc clk_rpmh_sar2130p = {
 412	.clks = sar2130p_rpmh_clocks,
 413	.num_clks = ARRAY_SIZE(sar2130p_rpmh_clocks),
 414};
 415
 416static struct clk_hw *sdm845_rpmh_clocks[] = {
 417	[RPMH_CXO_CLK]		= &clk_rpmh_bi_tcxo_div2.hw,
 418	[RPMH_CXO_CLK_A]	= &clk_rpmh_bi_tcxo_div2_ao.hw,
 419	[RPMH_LN_BB_CLK2]	= &clk_rpmh_ln_bb_clk2_a2.hw,
 420	[RPMH_LN_BB_CLK2_A]	= &clk_rpmh_ln_bb_clk2_a2_ao.hw,
 421	[RPMH_LN_BB_CLK3]	= &clk_rpmh_ln_bb_clk3_a2.hw,
 422	[RPMH_LN_BB_CLK3_A]	= &clk_rpmh_ln_bb_clk3_a2_ao.hw,
 423	[RPMH_RF_CLK1]		= &clk_rpmh_rf_clk1_a.hw,
 424	[RPMH_RF_CLK1_A]	= &clk_rpmh_rf_clk1_a_ao.hw,
 425	[RPMH_RF_CLK2]		= &clk_rpmh_rf_clk2_a.hw,
 426	[RPMH_RF_CLK2_A]	= &clk_rpmh_rf_clk2_a_ao.hw,
 427	[RPMH_RF_CLK3]		= &clk_rpmh_rf_clk3_a.hw,
 428	[RPMH_RF_CLK3_A]	= &clk_rpmh_rf_clk3_a_ao.hw,
 429	[RPMH_IPA_CLK]		= &clk_rpmh_ipa.hw,
 430	[RPMH_CE_CLK]		= &clk_rpmh_ce.hw,
 431};
 432
 433static const struct clk_rpmh_desc clk_rpmh_sdm845 = {
 434	.clks = sdm845_rpmh_clocks,
 435	.num_clks = ARRAY_SIZE(sdm845_rpmh_clocks),
 436};
 437
 438static struct clk_hw *sa8775p_rpmh_clocks[] = {
 439	[RPMH_CXO_CLK]		= &clk_rpmh_bi_tcxo_div2.hw,
 440	[RPMH_CXO_CLK_A]	= &clk_rpmh_bi_tcxo_div2_ao.hw,
 441	[RPMH_LN_BB_CLK1]	= &clk_rpmh_ln_bb_clk1_a2.hw,
 442	[RPMH_LN_BB_CLK2]	= &clk_rpmh_ln_bb_clk2_a2.hw,
 443	[RPMH_LN_BB_CLK2_A]	= &clk_rpmh_ln_bb_clk2_a4_ao.hw,
 444	[RPMH_IPA_CLK]		= &clk_rpmh_ipa.hw,
 445	[RPMH_PKA_CLK]		= &clk_rpmh_pka.hw,
 446	[RPMH_HWKM_CLK]		= &clk_rpmh_hwkm.hw,
 447};
 448
 449static const struct clk_rpmh_desc clk_rpmh_sa8775p = {
 450	.clks = sa8775p_rpmh_clocks,
 451	.num_clks = ARRAY_SIZE(sa8775p_rpmh_clocks),
 452};
 453
 454static struct clk_hw *sdm670_rpmh_clocks[] = {
 455	[RPMH_CXO_CLK]		= &clk_rpmh_bi_tcxo_div2.hw,
 456	[RPMH_CXO_CLK_A]	= &clk_rpmh_bi_tcxo_div2_ao.hw,
 457	[RPMH_LN_BB_CLK2]	= &clk_rpmh_ln_bb_clk2_a2.hw,
 458	[RPMH_LN_BB_CLK2_A]	= &clk_rpmh_ln_bb_clk2_a2_ao.hw,
 459	[RPMH_LN_BB_CLK3]	= &clk_rpmh_ln_bb_clk3_a2.hw,
 460	[RPMH_LN_BB_CLK3_A]	= &clk_rpmh_ln_bb_clk3_a2_ao.hw,
 461	[RPMH_RF_CLK1]		= &clk_rpmh_rf_clk1_a.hw,
 462	[RPMH_RF_CLK1_A]	= &clk_rpmh_rf_clk1_a_ao.hw,
 463	[RPMH_RF_CLK2]		= &clk_rpmh_rf_clk2_a.hw,
 464	[RPMH_RF_CLK2_A]	= &clk_rpmh_rf_clk2_a_ao.hw,
 465	[RPMH_IPA_CLK]		= &clk_rpmh_ipa.hw,
 466	[RPMH_CE_CLK]		= &clk_rpmh_ce.hw,
 467};
 468
 469static const struct clk_rpmh_desc clk_rpmh_sdm670 = {
 470	.clks = sdm670_rpmh_clocks,
 471	.num_clks = ARRAY_SIZE(sdm670_rpmh_clocks),
 472};
 473
 474static struct clk_hw *sdx55_rpmh_clocks[] = {
 475	[RPMH_CXO_CLK]		= &clk_rpmh_bi_tcxo_div2.hw,
 476	[RPMH_CXO_CLK_A]	= &clk_rpmh_bi_tcxo_div2_ao.hw,
 477	[RPMH_RF_CLK1]		= &clk_rpmh_rf_clk1_d.hw,
 478	[RPMH_RF_CLK1_A]	= &clk_rpmh_rf_clk1_d_ao.hw,
 479	[RPMH_RF_CLK2]		= &clk_rpmh_rf_clk2_d.hw,
 480	[RPMH_RF_CLK2_A]	= &clk_rpmh_rf_clk2_d_ao.hw,
 481	[RPMH_QPIC_CLK]		= &clk_rpmh_qpic_clk.hw,
 482	[RPMH_IPA_CLK]		= &clk_rpmh_ipa.hw,
 483};
 484
 485static const struct clk_rpmh_desc clk_rpmh_sdx55 = {
 486	.clks = sdx55_rpmh_clocks,
 487	.num_clks = ARRAY_SIZE(sdx55_rpmh_clocks),
 488};
 489
 490static struct clk_hw *sm8150_rpmh_clocks[] = {
 491	[RPMH_CXO_CLK]		= &clk_rpmh_bi_tcxo_div2.hw,
 492	[RPMH_CXO_CLK_A]	= &clk_rpmh_bi_tcxo_div2_ao.hw,
 493	[RPMH_LN_BB_CLK2]	= &clk_rpmh_ln_bb_clk2_a2.hw,
 494	[RPMH_LN_BB_CLK2_A]	= &clk_rpmh_ln_bb_clk2_a2_ao.hw,
 495	[RPMH_LN_BB_CLK3]	= &clk_rpmh_ln_bb_clk3_a2.hw,
 496	[RPMH_LN_BB_CLK3_A]	= &clk_rpmh_ln_bb_clk3_a2_ao.hw,
 497	[RPMH_RF_CLK1]		= &clk_rpmh_rf_clk1_a.hw,
 498	[RPMH_RF_CLK1_A]	= &clk_rpmh_rf_clk1_a_ao.hw,
 499	[RPMH_RF_CLK2]		= &clk_rpmh_rf_clk2_a.hw,
 500	[RPMH_RF_CLK2_A]	= &clk_rpmh_rf_clk2_a_ao.hw,
 501	[RPMH_RF_CLK3]		= &clk_rpmh_rf_clk3_a.hw,
 502	[RPMH_RF_CLK3_A]	= &clk_rpmh_rf_clk3_a_ao.hw,
 503	[RPMH_IPA_CLK]		= &clk_rpmh_ipa.hw,
 504};
 505
 506static const struct clk_rpmh_desc clk_rpmh_sm8150 = {
 507	.clks = sm8150_rpmh_clocks,
 508	.num_clks = ARRAY_SIZE(sm8150_rpmh_clocks),
 509};
 510
 511static struct clk_hw *sc7180_rpmh_clocks[] = {
 512	[RPMH_CXO_CLK]		= &clk_rpmh_bi_tcxo_div2.hw,
 513	[RPMH_CXO_CLK_A]	= &clk_rpmh_bi_tcxo_div2_ao.hw,
 514	[RPMH_LN_BB_CLK2]	= &clk_rpmh_ln_bb_clk2_a2.hw,
 515	[RPMH_LN_BB_CLK2_A]	= &clk_rpmh_ln_bb_clk2_a2_ao.hw,
 516	[RPMH_LN_BB_CLK3]	= &clk_rpmh_ln_bb_clk3_a2.hw,
 517	[RPMH_LN_BB_CLK3_A]	= &clk_rpmh_ln_bb_clk3_a2_ao.hw,
 518	[RPMH_RF_CLK1]		= &clk_rpmh_rf_clk1_a.hw,
 519	[RPMH_RF_CLK1_A]	= &clk_rpmh_rf_clk1_a_ao.hw,
 520	[RPMH_RF_CLK2]		= &clk_rpmh_rf_clk2_a.hw,
 521	[RPMH_RF_CLK2_A]	= &clk_rpmh_rf_clk2_a_ao.hw,
 522	[RPMH_IPA_CLK]		= &clk_rpmh_ipa.hw,
 523};
 524
 525static const struct clk_rpmh_desc clk_rpmh_sc7180 = {
 526	.clks = sc7180_rpmh_clocks,
 527	.num_clks = ARRAY_SIZE(sc7180_rpmh_clocks),
 528};
 529
 530static struct clk_hw *sc8180x_rpmh_clocks[] = {
 531	[RPMH_CXO_CLK]		= &clk_rpmh_bi_tcxo_div2.hw,
 532	[RPMH_CXO_CLK_A]	= &clk_rpmh_bi_tcxo_div2_ao.hw,
 533	[RPMH_LN_BB_CLK2]	= &clk_rpmh_ln_bb_clk2_a2.hw,
 534	[RPMH_LN_BB_CLK2_A]	= &clk_rpmh_ln_bb_clk2_a2_ao.hw,
 535	[RPMH_LN_BB_CLK3]	= &clk_rpmh_ln_bb_clk3_a2.hw,
 536	[RPMH_LN_BB_CLK3_A]	= &clk_rpmh_ln_bb_clk3_a2_ao.hw,
 537	[RPMH_RF_CLK1]		= &clk_rpmh_rf_clk1_d.hw,
 538	[RPMH_RF_CLK1_A]	= &clk_rpmh_rf_clk1_d_ao.hw,
 539	[RPMH_RF_CLK2]		= &clk_rpmh_rf_clk2_d.hw,
 540	[RPMH_RF_CLK2_A]	= &clk_rpmh_rf_clk2_d_ao.hw,
 541	[RPMH_RF_CLK3]		= &clk_rpmh_rf_clk3_d.hw,
 542	[RPMH_RF_CLK3_A]	= &clk_rpmh_rf_clk3_d_ao.hw,
 543	[RPMH_IPA_CLK]		= &clk_rpmh_ipa.hw,
 544};
 545
 546static const struct clk_rpmh_desc clk_rpmh_sc8180x = {
 547	.clks = sc8180x_rpmh_clocks,
 548	.num_clks = ARRAY_SIZE(sc8180x_rpmh_clocks),
 549};
 550
 551static struct clk_hw *milos_rpmh_clocks[] = {
 552	[RPMH_CXO_CLK]		= &clk_rpmh_bi_tcxo_div4.hw,
 553	[RPMH_CXO_CLK_A]	= &clk_rpmh_bi_tcxo_div4_ao.hw,
 554	[RPMH_LN_BB_CLK2]	= &clk_rpmh_clk7_a4.hw,
 555	[RPMH_LN_BB_CLK2_A]	= &clk_rpmh_clk7_a4_ao.hw,
 556	/*
 557	 * RPMH_LN_BB_CLK3(_A) and RPMH_LN_BB_CLK4(_A) are marked as optional
 558	 * downstream, but do not exist in cmd-db on SM7635, so skip them.
 559	 */
 560	[RPMH_RF_CLK1]		= &clk_rpmh_clk1_a1.hw,
 561	[RPMH_RF_CLK1_A]	= &clk_rpmh_clk1_a1_ao.hw,
 562	[RPMH_RF_CLK2]		= &clk_rpmh_clk2_a1.hw,
 563	[RPMH_RF_CLK2_A]	= &clk_rpmh_clk2_a1_ao.hw,
 564	[RPMH_RF_CLK3]		= &clk_rpmh_clk3_a1.hw,
 565	[RPMH_RF_CLK3_A]	= &clk_rpmh_clk3_a1_ao.hw,
 566	[RPMH_IPA_CLK]		= &clk_rpmh_ipa.hw,
 567};
 568
 569static const struct clk_rpmh_desc clk_rpmh_milos = {
 570	.clks = milos_rpmh_clocks,
 571	.num_clks = ARRAY_SIZE(milos_rpmh_clocks),
 572};
 573
 574static struct clk_hw *sm8250_rpmh_clocks[] = {
 575	[RPMH_CXO_CLK]		= &clk_rpmh_bi_tcxo_div2.hw,
 576	[RPMH_CXO_CLK_A]	= &clk_rpmh_bi_tcxo_div2_ao.hw,
 577	[RPMH_LN_BB_CLK1]	= &clk_rpmh_ln_bb_clk1_a2.hw,
 578	[RPMH_LN_BB_CLK1_A]	= &clk_rpmh_ln_bb_clk1_a2_ao.hw,
 579	[RPMH_LN_BB_CLK2]	= &clk_rpmh_ln_bb_clk2_a2.hw,
 580	[RPMH_LN_BB_CLK2_A]	= &clk_rpmh_ln_bb_clk2_a2_ao.hw,
 581	[RPMH_LN_BB_CLK3]	= &clk_rpmh_ln_bb_clk3_a2.hw,
 582	[RPMH_LN_BB_CLK3_A]	= &clk_rpmh_ln_bb_clk3_a2_ao.hw,
 583	[RPMH_RF_CLK1]		= &clk_rpmh_rf_clk1_a.hw,
 584	[RPMH_RF_CLK1_A]	= &clk_rpmh_rf_clk1_a_ao.hw,
 585	[RPMH_RF_CLK3]		= &clk_rpmh_rf_clk3_a.hw,
 586	[RPMH_RF_CLK3_A]	= &clk_rpmh_rf_clk3_a_ao.hw,
 587	[RPMH_IPA_CLK]		= &clk_rpmh_ipa.hw,
 588};
 589
 590static const struct clk_rpmh_desc clk_rpmh_sm8250 = {
 591	.clks = sm8250_rpmh_clocks,
 592	.num_clks = ARRAY_SIZE(sm8250_rpmh_clocks),
 593};
 594
 595static struct clk_hw *sm8350_rpmh_clocks[] = {
 596	[RPMH_CXO_CLK]		= &clk_rpmh_bi_tcxo_div2.hw,
 597	[RPMH_CXO_CLK_A]	= &clk_rpmh_bi_tcxo_div2_ao.hw,
 598	[RPMH_DIV_CLK1]		= &clk_rpmh_div_clk1_div2.hw,
 599	[RPMH_DIV_CLK1_A]	= &clk_rpmh_div_clk1_div2_ao.hw,
 600	[RPMH_LN_BB_CLK1]	= &clk_rpmh_ln_bb_clk1_a2.hw,
 601	[RPMH_LN_BB_CLK1_A]	= &clk_rpmh_ln_bb_clk1_a2_ao.hw,
 602	[RPMH_LN_BB_CLK2]	= &clk_rpmh_ln_bb_clk2_a2.hw,
 603	[RPMH_LN_BB_CLK2_A]	= &clk_rpmh_ln_bb_clk2_a2_ao.hw,
 604	[RPMH_RF_CLK1]		= &clk_rpmh_rf_clk1_a.hw,
 605	[RPMH_RF_CLK1_A]	= &clk_rpmh_rf_clk1_a_ao.hw,
 606	[RPMH_RF_CLK3]		= &clk_rpmh_rf_clk3_a.hw,
 607	[RPMH_RF_CLK3_A]	= &clk_rpmh_rf_clk3_a_ao.hw,
 608	[RPMH_RF_CLK4]		= &clk_rpmh_rf_clk4_a.hw,
 609	[RPMH_RF_CLK4_A]	= &clk_rpmh_rf_clk4_a_ao.hw,
 610	[RPMH_RF_CLK5]		= &clk_rpmh_rf_clk5_a.hw,
 611	[RPMH_RF_CLK5_A]	= &clk_rpmh_rf_clk5_a_ao.hw,
 612	[RPMH_IPA_CLK]		= &clk_rpmh_ipa.hw,
 613	[RPMH_PKA_CLK]		= &clk_rpmh_pka.hw,
 614	[RPMH_HWKM_CLK]		= &clk_rpmh_hwkm.hw,
 615};
 616
 617static const struct clk_rpmh_desc clk_rpmh_sm8350 = {
 618	.clks = sm8350_rpmh_clocks,
 619	.num_clks = ARRAY_SIZE(sm8350_rpmh_clocks),
 620};
 621
 622static struct clk_hw *sc8280xp_rpmh_clocks[] = {
 623	[RPMH_CXO_CLK]		= &clk_rpmh_bi_tcxo_div2.hw,
 624	[RPMH_CXO_CLK_A]	= &clk_rpmh_bi_tcxo_div2_ao.hw,
 625	[RPMH_LN_BB_CLK3]       = &clk_rpmh_ln_bb_clk3_a2.hw,
 626	[RPMH_LN_BB_CLK3_A]     = &clk_rpmh_ln_bb_clk3_a2_ao.hw,
 627	[RPMH_IPA_CLK]          = &clk_rpmh_ipa.hw,
 628	[RPMH_PKA_CLK]          = &clk_rpmh_pka.hw,
 629	[RPMH_HWKM_CLK]         = &clk_rpmh_hwkm.hw,
 630};
 631
 632static const struct clk_rpmh_desc clk_rpmh_sc8280xp = {
 633	.clks = sc8280xp_rpmh_clocks,
 634	.num_clks = ARRAY_SIZE(sc8280xp_rpmh_clocks),
 635};
 636
 637static struct clk_hw *sm8450_rpmh_clocks[] = {
 638	[RPMH_CXO_CLK]		= &clk_rpmh_bi_tcxo_div4.hw,
 639	[RPMH_CXO_CLK_A]	= &clk_rpmh_bi_tcxo_div4_ao.hw,
 640	[RPMH_LN_BB_CLK1]	= &clk_rpmh_ln_bb_clk1_a4.hw,
 641	[RPMH_LN_BB_CLK1_A]	= &clk_rpmh_ln_bb_clk1_a4_ao.hw,
 642	[RPMH_LN_BB_CLK2]	= &clk_rpmh_ln_bb_clk2_a4.hw,
 643	[RPMH_LN_BB_CLK2_A]	= &clk_rpmh_ln_bb_clk2_a4_ao.hw,
 644	[RPMH_RF_CLK1]		= &clk_rpmh_rf_clk1_a.hw,
 645	[RPMH_RF_CLK1_A]	= &clk_rpmh_rf_clk1_a_ao.hw,
 646	[RPMH_RF_CLK2]		= &clk_rpmh_rf_clk2_a.hw,
 647	[RPMH_RF_CLK2_A]	= &clk_rpmh_rf_clk2_a_ao.hw,
 648	[RPMH_RF_CLK3]		= &clk_rpmh_rf_clk3_a.hw,
 649	[RPMH_RF_CLK3_A]	= &clk_rpmh_rf_clk3_a_ao.hw,
 650	[RPMH_RF_CLK4]		= &clk_rpmh_rf_clk4_a.hw,
 651	[RPMH_RF_CLK4_A]	= &clk_rpmh_rf_clk4_a_ao.hw,
 652	[RPMH_IPA_CLK]		= &clk_rpmh_ipa.hw,
 653};
 654
 655static const struct clk_rpmh_desc clk_rpmh_sm8450 = {
 656	.clks = sm8450_rpmh_clocks,
 657	.num_clks = ARRAY_SIZE(sm8450_rpmh_clocks),
 658};
 659
 660static struct clk_hw *sm8550_rpmh_clocks[] = {
 661	[RPMH_CXO_CLK]		= &clk_rpmh_bi_tcxo_div2.hw,
 662	[RPMH_CXO_CLK_A]	= &clk_rpmh_bi_tcxo_div2_ao.hw,
 663	[RPMH_LN_BB_CLK1]	= &clk_rpmh_clk6_a2.hw,
 664	[RPMH_LN_BB_CLK1_A]	= &clk_rpmh_clk6_a2_ao.hw,
 665	[RPMH_LN_BB_CLK2]	= &clk_rpmh_clk7_a2.hw,
 666	[RPMH_LN_BB_CLK2_A]	= &clk_rpmh_clk7_a2_ao.hw,
 667	[RPMH_LN_BB_CLK3]	= &clk_rpmh_clk8_a2.hw,
 668	[RPMH_LN_BB_CLK3_A]	= &clk_rpmh_clk8_a2_ao.hw,
 669	[RPMH_RF_CLK1]		= &clk_rpmh_clk1_a1.hw,
 670	[RPMH_RF_CLK1_A]	= &clk_rpmh_clk1_a1_ao.hw,
 671	[RPMH_RF_CLK2]		= &clk_rpmh_clk2_a1.hw,
 672	[RPMH_RF_CLK2_A]	= &clk_rpmh_clk2_a1_ao.hw,
 673	[RPMH_RF_CLK3]		= &clk_rpmh_clk3_a1.hw,
 674	[RPMH_RF_CLK3_A]	= &clk_rpmh_clk3_a1_ao.hw,
 675	[RPMH_RF_CLK4]		= &clk_rpmh_clk4_a1.hw,
 676	[RPMH_RF_CLK4_A]	= &clk_rpmh_clk4_a1_ao.hw,
 677	[RPMH_IPA_CLK]		= &clk_rpmh_ipa.hw,
 678};
 679
 680static const struct clk_rpmh_desc clk_rpmh_sm8550 = {
 681	.clks = sm8550_rpmh_clocks,
 682	.num_clks = ARRAY_SIZE(sm8550_rpmh_clocks),
 683	.clka_optional = true,
 684};
 685
 686static struct clk_hw *sm8650_rpmh_clocks[] = {
 687	[RPMH_CXO_CLK]		= &clk_rpmh_bi_tcxo_div2.hw,
 688	[RPMH_CXO_CLK_A]	= &clk_rpmh_bi_tcxo_div2_ao.hw,
 689	[RPMH_LN_BB_CLK1]	= &clk_rpmh_clk6_a2.hw,
 690	[RPMH_LN_BB_CLK1_A]	= &clk_rpmh_clk6_a2_ao.hw,
 691	[RPMH_LN_BB_CLK2]	= &clk_rpmh_clk7_a2.hw,
 692	[RPMH_LN_BB_CLK2_A]	= &clk_rpmh_clk7_a2_ao.hw,
 693	[RPMH_LN_BB_CLK3]	= &clk_rpmh_clk8_a2.hw,
 694	[RPMH_LN_BB_CLK3_A]	= &clk_rpmh_clk8_a2_ao.hw,
 695	[RPMH_RF_CLK1]		= &clk_rpmh_clk1_a1.hw,
 696	[RPMH_RF_CLK1_A]	= &clk_rpmh_clk1_a1_ao.hw,
 697	[RPMH_RF_CLK2]		= &clk_rpmh_clk2_a1.hw,
 698	[RPMH_RF_CLK2_A]	= &clk_rpmh_clk2_a1_ao.hw,
 699	/*
 700	 * The clka3 RPMh resource is missing in cmd-db
 701	 * for current platforms, while the clka3 exists
 702	 * on the PMK8550, the clock is unconnected and
 703	 * unused.
 704	 */
 705	[RPMH_RF_CLK4]		= &clk_rpmh_clk4_a2.hw,
 706	[RPMH_RF_CLK4_A]	= &clk_rpmh_clk4_a2_ao.hw,
 707	[RPMH_RF_CLK5]		= &clk_rpmh_clk5_a2.hw,
 708	[RPMH_RF_CLK5_A]	= &clk_rpmh_clk5_a2_ao.hw,
 709	[RPMH_IPA_CLK]		= &clk_rpmh_ipa.hw,
 710};
 711
 712static const struct clk_rpmh_desc clk_rpmh_sm8650 = {
 713	.clks = sm8650_rpmh_clocks,
 714	.num_clks = ARRAY_SIZE(sm8650_rpmh_clocks),
 715	.clka_optional = true,
 716};
 717
 718static struct clk_hw *sc7280_rpmh_clocks[] = {
 719	[RPMH_CXO_CLK]      = &clk_rpmh_bi_tcxo_div4.hw,
 720	[RPMH_CXO_CLK_A]    = &clk_rpmh_bi_tcxo_div4_ao.hw,
 721	[RPMH_LN_BB_CLK2]   = &clk_rpmh_ln_bb_clk2_a2.hw,
 722	[RPMH_LN_BB_CLK2_A] = &clk_rpmh_ln_bb_clk2_a2_ao.hw,
 723	[RPMH_RF_CLK1]      = &clk_rpmh_rf_clk1_a.hw,
 724	[RPMH_RF_CLK1_A]    = &clk_rpmh_rf_clk1_a_ao.hw,
 725	[RPMH_RF_CLK3]      = &clk_rpmh_rf_clk3_a.hw,
 726	[RPMH_RF_CLK3_A]    = &clk_rpmh_rf_clk3_a_ao.hw,
 727	[RPMH_RF_CLK4]      = &clk_rpmh_rf_clk4_a.hw,
 728	[RPMH_RF_CLK4_A]    = &clk_rpmh_rf_clk4_a_ao.hw,
 729	[RPMH_IPA_CLK]      = &clk_rpmh_ipa.hw,
 730	[RPMH_PKA_CLK]      = &clk_rpmh_pka.hw,
 731	[RPMH_HWKM_CLK]     = &clk_rpmh_hwkm.hw,
 732};
 733
 734static const struct clk_rpmh_desc clk_rpmh_sc7280 = {
 735	.clks = sc7280_rpmh_clocks,
 736	.num_clks = ARRAY_SIZE(sc7280_rpmh_clocks),
 737};
 738
 739static struct clk_hw *sm6350_rpmh_clocks[] = {
 740	[RPMH_CXO_CLK]		= &clk_rpmh_bi_tcxo_div4.hw,
 741	[RPMH_CXO_CLK_A]	= &clk_rpmh_bi_tcxo_div4_ao.hw,
 742	[RPMH_LN_BB_CLK2]	= &clk_rpmh_ln_bb_clk2_g4.hw,
 743	[RPMH_LN_BB_CLK2_A]	= &clk_rpmh_ln_bb_clk2_g4_ao.hw,
 744	[RPMH_LN_BB_CLK3]	= &clk_rpmh_ln_bb_clk3_g4.hw,
 745	[RPMH_LN_BB_CLK3_A]	= &clk_rpmh_ln_bb_clk3_g4_ao.hw,
 746	[RPMH_QLINK_CLK]	= &clk_rpmh_qlink_div4.hw,
 747	[RPMH_QLINK_CLK_A]	= &clk_rpmh_qlink_div4_ao.hw,
 748	[RPMH_IPA_CLK]		= &clk_rpmh_ipa.hw,
 749};
 750
 751static const struct clk_rpmh_desc clk_rpmh_sm6350 = {
 752	.clks = sm6350_rpmh_clocks,
 753	.num_clks = ARRAY_SIZE(sm6350_rpmh_clocks),
 754};
 755
 756static struct clk_hw *sdx65_rpmh_clocks[] = {
 757	[RPMH_CXO_CLK]          = &clk_rpmh_bi_tcxo_div4.hw,
 758	[RPMH_CXO_CLK_A]        = &clk_rpmh_bi_tcxo_div4_ao.hw,
 759	[RPMH_LN_BB_CLK1]       = &clk_rpmh_ln_bb_clk1_a4.hw,
 760	[RPMH_LN_BB_CLK1_A]     = &clk_rpmh_ln_bb_clk1_a4_ao.hw,
 761	[RPMH_RF_CLK1]          = &clk_rpmh_rf_clk1_a.hw,
 762	[RPMH_RF_CLK1_A]        = &clk_rpmh_rf_clk1_a_ao.hw,
 763	[RPMH_RF_CLK2]          = &clk_rpmh_rf_clk2_a.hw,
 764	[RPMH_RF_CLK2_A]        = &clk_rpmh_rf_clk2_a_ao.hw,
 765	[RPMH_RF_CLK3]          = &clk_rpmh_rf_clk3_a.hw,
 766	[RPMH_RF_CLK3_A]        = &clk_rpmh_rf_clk3_a_ao.hw,
 767	[RPMH_RF_CLK4]          = &clk_rpmh_rf_clk4_a.hw,
 768	[RPMH_RF_CLK4_A]        = &clk_rpmh_rf_clk4_a_ao.hw,
 769	[RPMH_IPA_CLK]          = &clk_rpmh_ipa.hw,
 770	[RPMH_QPIC_CLK]         = &clk_rpmh_qpic_clk.hw,
 771};
 772
 773static const struct clk_rpmh_desc clk_rpmh_sdx65 = {
 774	.clks = sdx65_rpmh_clocks,
 775	.num_clks = ARRAY_SIZE(sdx65_rpmh_clocks),
 776};
 777
 778static struct clk_hw *qdu1000_rpmh_clocks[] = {
 779	[RPMH_CXO_CLK]      = &clk_rpmh_bi_tcxo_div1.hw,
 780	[RPMH_CXO_CLK_A]    = &clk_rpmh_bi_tcxo_div1_ao.hw,
 781};
 782
 783static const struct clk_rpmh_desc clk_rpmh_qdu1000 = {
 784	.clks = qdu1000_rpmh_clocks,
 785	.num_clks = ARRAY_SIZE(qdu1000_rpmh_clocks),
 786};
 787
 788static struct clk_hw *sdx75_rpmh_clocks[] = {
 789	[RPMH_CXO_CLK]		= &clk_rpmh_bi_tcxo_div4.hw,
 790	[RPMH_CXO_CLK_A]	= &clk_rpmh_bi_tcxo_div4_ao.hw,
 791	[RPMH_RF_CLK1]		= &clk_rpmh_rf_clk1_a.hw,
 792	[RPMH_RF_CLK1_A]	= &clk_rpmh_rf_clk1_a_ao.hw,
 793	[RPMH_RF_CLK2]		= &clk_rpmh_rf_clk2_a.hw,
 794	[RPMH_RF_CLK2_A]	= &clk_rpmh_rf_clk2_a_ao.hw,
 795	[RPMH_RF_CLK3]		= &clk_rpmh_rf_clk3_a.hw,
 796	[RPMH_RF_CLK3_A]	= &clk_rpmh_rf_clk3_a_ao.hw,
 797	[RPMH_QPIC_CLK]		= &clk_rpmh_qpic_clk.hw,
 798	[RPMH_IPA_CLK]		= &clk_rpmh_ipa.hw,
 799};
 800
 801static const struct clk_rpmh_desc clk_rpmh_sdx75 = {
 802	.clks = sdx75_rpmh_clocks,
 803	.num_clks = ARRAY_SIZE(sdx75_rpmh_clocks),
 804};
 805
 806static struct clk_hw *sm4450_rpmh_clocks[] = {
 807	[RPMH_CXO_CLK]		= &clk_rpmh_bi_tcxo_div4.hw,
 808	[RPMH_CXO_CLK_A]	= &clk_rpmh_bi_tcxo_div4_ao.hw,
 809	[RPMH_LN_BB_CLK2]	= &clk_rpmh_ln_bb_clk2_a4.hw,
 810	[RPMH_LN_BB_CLK2_A]	= &clk_rpmh_ln_bb_clk2_a4_ao.hw,
 811	[RPMH_LN_BB_CLK3]       = &clk_rpmh_ln_bb_clk3_a4.hw,
 812	[RPMH_LN_BB_CLK3_A]     = &clk_rpmh_ln_bb_clk3_a4_ao.hw,
 813	[RPMH_RF_CLK1]		= &clk_rpmh_rf_clk1_a.hw,
 814	[RPMH_RF_CLK1_A]	= &clk_rpmh_rf_clk1_a_ao.hw,
 815	[RPMH_RF_CLK5]		= &clk_rpmh_rf_clk5_a.hw,
 816	[RPMH_RF_CLK5_A]	= &clk_rpmh_rf_clk5_a_ao.hw,
 817	[RPMH_IPA_CLK]		= &clk_rpmh_ipa.hw,
 818};
 819
 820static const struct clk_rpmh_desc clk_rpmh_sm4450 = {
 821	.clks = sm4450_rpmh_clocks,
 822	.num_clks = ARRAY_SIZE(sm4450_rpmh_clocks),
 823};
 824
 825static struct clk_hw *x1e80100_rpmh_clocks[] = {
 826	[RPMH_CXO_CLK]		= &clk_rpmh_bi_tcxo_div2.hw,
 827	[RPMH_CXO_CLK_A]	= &clk_rpmh_bi_tcxo_div2_ao.hw,
 828	[RPMH_LN_BB_CLK1]	= &clk_rpmh_clk6_a2.hw,
 829	[RPMH_LN_BB_CLK1_A]	= &clk_rpmh_clk6_a2_ao.hw,
 830	[RPMH_LN_BB_CLK2]	= &clk_rpmh_clk7_a2.hw,
 831	[RPMH_LN_BB_CLK2_A]	= &clk_rpmh_clk7_a2_ao.hw,
 832	[RPMH_LN_BB_CLK3]	= &clk_rpmh_clk8_a2.hw,
 833	[RPMH_LN_BB_CLK3_A]	= &clk_rpmh_clk8_a2_ao.hw,
 834	[RPMH_RF_CLK3]		= &clk_rpmh_clk3_a2.hw,
 835	[RPMH_RF_CLK3_A]	= &clk_rpmh_clk3_a2_ao.hw,
 836	[RPMH_RF_CLK4]		= &clk_rpmh_clk4_a2.hw,
 837	[RPMH_RF_CLK4_A]	= &clk_rpmh_clk4_a2_ao.hw,
 838	[RPMH_RF_CLK5]		= &clk_rpmh_clk5_a2.hw,
 839	[RPMH_RF_CLK5_A]	= &clk_rpmh_clk5_a2_ao.hw,
 840};
 841
 842static const struct clk_rpmh_desc clk_rpmh_x1e80100 = {
 843	.clks = x1e80100_rpmh_clocks,
 844	.num_clks = ARRAY_SIZE(x1e80100_rpmh_clocks),
 845};
 846
 847static struct clk_hw *qcs615_rpmh_clocks[] = {
 848	[RPMH_CXO_CLK]		= &clk_rpmh_bi_tcxo_div2.hw,
 849	[RPMH_CXO_CLK_A]	= &clk_rpmh_bi_tcxo_div2_ao.hw,
 850	[RPMH_LN_BB_CLK2]	= &clk_rpmh_ln_bb_clk2_a2.hw,
 851	[RPMH_LN_BB_CLK2_A]	= &clk_rpmh_ln_bb_clk2_a2_ao.hw,
 852	[RPMH_LN_BB_CLK3]	= &clk_rpmh_ln_bb_clk3_a2.hw,
 853	[RPMH_LN_BB_CLK3_A]	= &clk_rpmh_ln_bb_clk3_a2_ao.hw,
 854	[RPMH_RF_CLK1]		= &clk_rpmh_rf_clk1_a.hw,
 855	[RPMH_RF_CLK1_A]	= &clk_rpmh_rf_clk1_a_ao.hw,
 856	[RPMH_RF_CLK2]		= &clk_rpmh_rf_clk2_a.hw,
 857	[RPMH_RF_CLK2_A]	= &clk_rpmh_rf_clk2_a_ao.hw,
 858	[RPMH_IPA_CLK]		= &clk_rpmh_ipa.hw,
 859};
 860
 861static const struct clk_rpmh_desc clk_rpmh_qcs615 = {
 862	.clks = qcs615_rpmh_clocks,
 863	.num_clks = ARRAY_SIZE(qcs615_rpmh_clocks),
 864};
 865
 866static struct clk_hw *sm8750_rpmh_clocks[] = {
 867	[RPMH_CXO_CLK]		= &clk_rpmh_bi_tcxo_div2.hw,
 868	[RPMH_CXO_CLK_A]	= &clk_rpmh_bi_tcxo_div2_ao.hw,
 869	[RPMH_LN_BB_CLK1]	= &clk_rpmh_clk6_a2.hw,
 870	[RPMH_LN_BB_CLK1_A]	= &clk_rpmh_clk6_a2_ao.hw,
 871	[RPMH_LN_BB_CLK3]	= &clk_rpmh_clk8_a2.hw,
 872	[RPMH_LN_BB_CLK3_A]	= &clk_rpmh_clk8_a2_ao.hw,
 873	[RPMH_RF_CLK1]		= &clk_rpmh_rf_clk1_a.hw,
 874	[RPMH_RF_CLK1_A]	= &clk_rpmh_rf_clk1_a_ao.hw,
 875	[RPMH_RF_CLK2]		= &clk_rpmh_rf_clk2_a.hw,
 876	[RPMH_RF_CLK2_A]	= &clk_rpmh_rf_clk2_a_ao.hw,
 877	[RPMH_RF_CLK3]		= &clk_rpmh_rf_clk3_a2.hw,
 878	[RPMH_RF_CLK3_A]	= &clk_rpmh_rf_clk3_a2_ao.hw,
 879	[RPMH_IPA_CLK]		= &clk_rpmh_ipa.hw,
 880};
 881
 882static const struct clk_rpmh_desc clk_rpmh_sm8750 = {
 883	.clks = sm8750_rpmh_clocks,
 884	.num_clks = ARRAY_SIZE(sm8750_rpmh_clocks),
 885	.clka_optional = true,
 886};
 887
 888static struct clk_hw *glymur_rpmh_clocks[] = {
 889	[RPMH_CXO_CLK]		= &clk_rpmh_bi_tcxo_div2.hw,
 890	[RPMH_CXO_CLK_A]	= &clk_rpmh_bi_tcxo_div2_ao.hw,
 891	[RPMH_RF_CLK3]		= &clk_rpmh_clk3_a.hw,
 892	[RPMH_RF_CLK3_A]	= &clk_rpmh_clk3_a_ao.hw,
 893	[RPMH_RF_CLK4]		= &clk_rpmh_clk4_a.hw,
 894	[RPMH_RF_CLK4_A]	= &clk_rpmh_clk4_a_ao.hw,
 895	[RPMH_RF_CLK5]		= &clk_rpmh_clk5_a.hw,
 896	[RPMH_RF_CLK5_A]	= &clk_rpmh_clk5_a_ao.hw,
 897};
 898
 899static const struct clk_rpmh_desc clk_rpmh_glymur = {
 900	.clks = glymur_rpmh_clocks,
 901	.num_clks = ARRAY_SIZE(glymur_rpmh_clocks),
 902};
 903
 904static struct clk_hw *of_clk_rpmh_hw_get(struct of_phandle_args *clkspec,
 905					 void *data)
 906{
 907	struct clk_rpmh_desc *rpmh = data;
 908	unsigned int idx = clkspec->args[0];
 909
 910	if (idx >= rpmh->num_clks) {
 911		pr_err("%s: invalid index %u\n", __func__, idx);
 912		return ERR_PTR(-EINVAL);
 913	}
 914
 915	return rpmh->clks[idx];
 916}
 917
 918static int clk_rpmh_probe(struct platform_device *pdev)
 919{
 920	struct clk_hw **hw_clks;
 921	struct clk_rpmh *rpmh_clk;
 922	const struct clk_rpmh_desc *desc;
 923	int ret, i;
 924
 925	desc = of_device_get_match_data(&pdev->dev);
 926	if (!desc)
 927		return -ENODEV;
 928
 929	hw_clks = desc->clks;
 930
 931	for (i = 0; i < desc->num_clks; i++) {
 932		const char *name;
 933		u32 res_addr;
 934		size_t aux_data_len;
 935		const struct bcm_db *data;
 936
 937		if (!hw_clks[i])
 938			continue;
 939
 940		name = hw_clks[i]->init->name;
 941
 942		rpmh_clk = to_clk_rpmh(hw_clks[i]);
 943		res_addr = cmd_db_read_addr(rpmh_clk->res_name);
 944		if (!res_addr) {
 945			hw_clks[i] = NULL;
 946
 947			if (desc->clka_optional &&
 948			    !strncmp(rpmh_clk->res_name, "clka", sizeof("clka") - 1))
 949				continue;
 950
 951			dev_err(&pdev->dev, "missing RPMh resource address for %s\n",
 952				rpmh_clk->res_name);
 953			return -ENODEV;
 954		}
 955
 956		data = cmd_db_read_aux_data(rpmh_clk->res_name, &aux_data_len);
 957		if (IS_ERR(data)) {
 958			ret = PTR_ERR(data);
 959			dev_err(&pdev->dev,
 960				"error reading RPMh aux data for %s (%d)\n",
 961				rpmh_clk->res_name, ret);
 962			return ret;
 963		}
 964
 965		/* Convert unit from Khz to Hz */
 966		if (aux_data_len == sizeof(*data))
 967			rpmh_clk->unit = le32_to_cpu(data->unit) * 1000ULL;
 968
 969		rpmh_clk->res_addr += res_addr;
 970		rpmh_clk->dev = &pdev->dev;
 971
 972		ret = devm_clk_hw_register(&pdev->dev, hw_clks[i]);
 973		if (ret) {
 974			dev_err(&pdev->dev, "failed to register %s\n", name);
 975			return ret;
 976		}
 977	}
 978
 979	/* typecast to silence compiler warning */
 980	ret = devm_of_clk_add_hw_provider(&pdev->dev, of_clk_rpmh_hw_get,
 981					  (void *)desc);
 982	if (ret) {
 983		dev_err(&pdev->dev, "Failed to add clock provider\n");
 984		return ret;
 985	}
 986
 987	dev_dbg(&pdev->dev, "Registered RPMh clocks\n");
 988
 989	return 0;
 990}
 991
 992static const struct of_device_id clk_rpmh_match_table[] = {
 993	{ .compatible = "qcom,glymur-rpmh-clk", .data = &clk_rpmh_glymur},
 994	{ .compatible = "qcom,milos-rpmh-clk", .data = &clk_rpmh_milos},
 995	{ .compatible = "qcom,qcs615-rpmh-clk", .data = &clk_rpmh_qcs615},
 996	{ .compatible = "qcom,qdu1000-rpmh-clk", .data = &clk_rpmh_qdu1000},
 997	{ .compatible = "qcom,sa8775p-rpmh-clk", .data = &clk_rpmh_sa8775p},
 998	{ .compatible = "qcom,sar2130p-rpmh-clk", .data = &clk_rpmh_sar2130p},
 999	{ .compatible = "qcom,sc7180-rpmh-clk", .data = &clk_rpmh_sc7180},
1000	{ .compatible = "qcom,sc7280-rpmh-clk", .data = &clk_rpmh_sc7280},
1001	{ .compatible = "qcom,sc8180x-rpmh-clk", .data = &clk_rpmh_sc8180x},
1002	{ .compatible = "qcom,sc8280xp-rpmh-clk", .data = &clk_rpmh_sc8280xp},
1003	{ .compatible = "qcom,sdm845-rpmh-clk", .data = &clk_rpmh_sdm845},
1004	{ .compatible = "qcom,sdm670-rpmh-clk", .data = &clk_rpmh_sdm670},
1005	{ .compatible = "qcom,sdx55-rpmh-clk",  .data = &clk_rpmh_sdx55},
1006	{ .compatible = "qcom,sdx65-rpmh-clk",  .data = &clk_rpmh_sdx65},
1007	{ .compatible = "qcom,sdx75-rpmh-clk",  .data = &clk_rpmh_sdx75},
1008	{ .compatible = "qcom,sm4450-rpmh-clk", .data = &clk_rpmh_sm4450},
1009	{ .compatible = "qcom,sm6350-rpmh-clk", .data = &clk_rpmh_sm6350},
1010	{ .compatible = "qcom,sm8150-rpmh-clk", .data = &clk_rpmh_sm8150},
1011	{ .compatible = "qcom,sm8250-rpmh-clk", .data = &clk_rpmh_sm8250},
1012	{ .compatible = "qcom,sm8350-rpmh-clk", .data = &clk_rpmh_sm8350},
1013	{ .compatible = "qcom,sm8450-rpmh-clk", .data = &clk_rpmh_sm8450},
1014	{ .compatible = "qcom,sm8550-rpmh-clk", .data = &clk_rpmh_sm8550},
1015	{ .compatible = "qcom,sm8650-rpmh-clk", .data = &clk_rpmh_sm8650},
1016	{ .compatible = "qcom,sm8750-rpmh-clk", .data = &clk_rpmh_sm8750},
1017	{ .compatible = "qcom,x1e80100-rpmh-clk", .data = &clk_rpmh_x1e80100},
1018	{ }
1019};
1020MODULE_DEVICE_TABLE(of, clk_rpmh_match_table);
1021
1022static struct platform_driver clk_rpmh_driver = {
1023	.probe		= clk_rpmh_probe,
1024	.driver		= {
1025		.name	= "clk-rpmh",
1026		.of_match_table = clk_rpmh_match_table,
1027	},
1028};
1029
1030static int __init clk_rpmh_init(void)
1031{
1032	return platform_driver_register(&clk_rpmh_driver);
1033}
1034core_initcall(clk_rpmh_init);
1035
1036static void __exit clk_rpmh_exit(void)
1037{
1038	platform_driver_unregister(&clk_rpmh_driver);
1039}
1040module_exit(clk_rpmh_exit);
1041
1042MODULE_DESCRIPTION("QCOM RPMh Clock Driver");
1043MODULE_LICENSE("GPL v2");
~/ Read-only file preview.