drivers/soc/qcom/ramp_controller.c

Source file repositories/reference/linux-study-clean/drivers/soc/qcom/ramp_controller.c

File Facts

System
Linux kernel
Corpus path
drivers/soc/qcom/ramp_controller.c
Extension
.c
Size
9292 bytes
Lines
346
Domain
Driver Families
Bucket
drivers/soc
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct qcom_ramp_controller_desc {
	const struct reg_sequence *cfg_dfs_sid;
	const struct reg_sequence *cfg_link_sid;
	const struct reg_sequence *cfg_lmh_sid;
	const struct reg_sequence *cfg_ramp_en;
	const struct reg_sequence *cfg_ramp_dis;
	u8 cmd_reg;
	u8 num_dfs_sids;
	u8 num_link_sids;
	u8 num_lmh_sids;
	u8 num_ramp_en;
	u8 num_ramp_dis;
};

/**
 * struct qcom_ramp_controller - Main driver structure
 * @regmap: Regmap handle
 * @desc:   SoC specific parameters
 */
struct qcom_ramp_controller {
	struct regmap *regmap;
	const struct qcom_ramp_controller_desc *desc;
};

/**
 * rc_wait_for_update() - Wait for Ramp Controller root update
 * @qrc: Main driver structure
 *
 * Return: Zero for success or negative number for failure
 */
static int rc_wait_for_update(struct qcom_ramp_controller *qrc)
{
	const struct qcom_ramp_controller_desc *d = qrc->desc;
	struct regmap *r = qrc->regmap;
	u32 val;
	int ret;

	ret = regmap_set_bits(r, d->cmd_reg, RC_ROOT_EN);
	if (ret)
		return ret;

	return regmap_read_poll_timeout(r, d->cmd_reg, val, !(val & RC_UPDATE_EN),
					1, RC_UPDATE_TIMEOUT_US);
}

/**
 * rc_set_cfg_update() - Ramp Controller configuration update
 * @qrc: Main driver structure
 * @ce: Configuration entry to update
 *
 * Return: Zero for success or negative number for failure
 */
static int rc_set_cfg_update(struct qcom_ramp_controller *qrc, u8 ce)
{
	const struct qcom_ramp_controller_desc *d = qrc->desc;
	struct regmap *r = qrc->regmap;
	u32 ack, val;
	int ret;

	/* The ack bit is between bits 16-31 of RC_REG_CFG_UPDATE */
	ack = FIELD_PREP(RC_CFG_ACK, BIT(ce));

	/* Write the configuration type first... */
	ret = regmap_set_bits(r, d->cmd_reg + RC_REG_CFG_UPDATE, ce);
	if (ret)
		return ret;

	/* ...and after that, enable the update bit to sync the changes */
	ret = regmap_set_bits(r, d->cmd_reg + RC_REG_CFG_UPDATE, RC_CFG_UPDATE_EN);
	if (ret)
		return ret;

	/* Wait for the changes to go through */
	ret = regmap_read_poll_timeout(r, d->cmd_reg + RC_REG_CFG_UPDATE, val,
				       val & ack, 1, RC_UPDATE_TIMEOUT_US);
	if (ret)
		return ret;

	/*
	 * Configuration update success! The CFG_UPDATE register will not be
	 * cleared automatically upon applying the configuration, so we have
	 * to do that manually in order to leave the ramp controller in a
	 * predictable and clean state.
	 */
	ret = regmap_write(r, d->cmd_reg + RC_REG_CFG_UPDATE, 0);
	if (ret)
		return ret;

	/* Wait for the update bit cleared ack */
	return regmap_read_poll_timeout(r, d->cmd_reg + RC_REG_CFG_UPDATE,

Annotation

Implementation Notes