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

Commit 9b2afaad authored by Gidon Studinski's avatar Gidon Studinski
Browse files

msm: ipa: add clock scaling support to IPA driver



Add implementation of internal API for scaling IPA clocks
depends on floor voltage and bandwidth required.
This API is called from IPA RM.

Change-Id: I181c0c5294a03008ff586fe37ed2b1889fbbfe09
Acked-by: default avatarAdy Abraham <adya@qti.qualcomm.com>
Signed-off-by: default avatarGidon Studinski <gidons@codeaurora.org>
parent 360013b1
Loading
Loading
Loading
Loading
+57 −3
Original line number Diff line number Diff line
@@ -1413,7 +1413,8 @@ void _ipa_enable_clks_v2_0(void)
	if (ipa_clk) {
		clk_prepare(ipa_clk);
		clk_enable(ipa_clk);
		clk_set_rate(ipa_clk, ipa_ctx->ctrl->ipa_clk_rate);
		IPADBG("curr_ipa_clk_rate=%d", ipa_ctx->curr_ipa_clk_rate);
		clk_set_rate(ipa_clk, ipa_ctx->curr_ipa_clk_rate);
	} else {
		WARN_ON(1);
	}
@@ -1432,7 +1433,7 @@ void _ipa_enable_clks_v1(void)

	if (ipa_clk_src)
		clk_set_rate(ipa_clk_src,
				ipa_ctx->ctrl->ipa_clk_rate);
				ipa_ctx->curr_ipa_clk_rate);
	else
		WARN_ON(1);

@@ -1607,7 +1608,57 @@ fail:
int ipa_set_required_perf_profile(enum ipa_voltage_level floor_voltage,
				  u32 bandwidth_mbps)
{
	IPADBG("Not Implemented yet");
	enum ipa_voltage_level needed_voltage;
	u32 clk_rate;

	IPADBG("floor_voltage=%d, bandwidth_mbps=%u",
					floor_voltage, bandwidth_mbps);

	if (floor_voltage < IPA_VOLTAGE_UNSPECIFIED ||
		floor_voltage >= IPA_VOLTAGE_MAX) {
		IPAERR("bad voltage\n");
		return -EINVAL;
	}

	if (ipa_ctx->enable_clock_scaling) {
		IPADBG("Clock scaling is enabled\n");
		if (bandwidth_mbps > ipa_ctx->ctrl->clock_scaling_bw_threshold)
			needed_voltage = IPA_VOLTAGE_NOMINAL;
		else
			needed_voltage = IPA_VOLTAGE_SVS;
	} else {
		IPADBG("Clock scaling is disabled\n");
		needed_voltage = IPA_VOLTAGE_NOMINAL;
	}

	needed_voltage = max(needed_voltage, floor_voltage);
	switch (needed_voltage) {
	case IPA_VOLTAGE_SVS:
		clk_rate = ipa_ctx->ctrl->ipa_clk_rate_lo;
		break;
	case IPA_VOLTAGE_NOMINAL:
		clk_rate = ipa_ctx->ctrl->ipa_clk_rate_hi;
		break;
	default:
		IPAERR("bad voltage\n");
		WARN_ON(1);
		return -EFAULT;
	}

	if (clk_rate == ipa_ctx->curr_ipa_clk_rate) {
		IPADBG("Same voltage\n");
		return 0;
	}

	mutex_lock(&ipa_ctx->ipa_active_clients_lock);
	ipa_ctx->curr_ipa_clk_rate = clk_rate;
	IPADBG("setting clock rate to %u\n", ipa_ctx->curr_ipa_clk_rate);
	if (ipa_ctx->ipa_active_clients > 0)
		clk_set_rate(ipa_clk, ipa_ctx->curr_ipa_clk_rate);
	else
		IPADBG("clocks are gated, not setting rate\n");
	mutex_unlock(&ipa_ctx->ipa_active_clients_lock);
	IPADBG("Done\n");
	return 0;
}

@@ -1781,6 +1832,9 @@ static int ipa_init(const struct ipa_plat_drv_res *resource_p,
		goto fail_bind;
	}

	ipa_ctx->enable_clock_scaling = 0;
	ipa_ctx->curr_ipa_clk_rate = ipa_ctx->ctrl->ipa_clk_rate_hi;

	/* enable IPA clocks explicitly to allow the initialization */
	ipa_enable_clks();

+15 −0
Original line number Diff line number Diff line
@@ -1285,6 +1285,21 @@ void ipa_debugfs_init(void)
		goto fail;
	}

	file = debugfs_create_u32("enable_clock_scaling", read_write_mode,
		dent, &ipa_ctx->enable_clock_scaling);
	if (!file) {
		IPAERR("could not create enable_clock_scaling file\n");
		goto fail;
	}

	file = debugfs_create_u32("clock_scaling_bw_threshold_mbps",
		read_write_mode, dent,
		&ipa_ctx->ctrl->clock_scaling_bw_threshold);
	if (!file) {
		IPAERR("could not create clock_scaling_bw_threshold_mbps\n");
		goto fail;
	}

	return;

fail:
+9 −1
Original line number Diff line number Diff line
@@ -325,6 +325,7 @@ struct ipa_ep_cfg_status {
 * @suspended: valid for B2B pipes, whether IPA EP is suspended
 * @skip_ep_cfg: boolean field that determines if EP should be configured
 *  by IPA driver
 * @keep_ipa_awake: when true, IPA will not be clock gated
 */
struct ipa_ep_context {
	int valid;
@@ -351,6 +352,7 @@ struct ipa_ep_context {
	u32 dflt_flt4_rule_hdl;
	u32 dflt_flt6_rule_hdl;
	bool skip_ep_cfg;
	bool keep_ipa_awake;
};

enum ipa_sys_pipe_policy {
@@ -634,6 +636,8 @@ struct ipa_controller;
 * @ipa_bus_hdl: msm driver handle for the data path bus
 * @ctrl: holds the core specific operations based on
 *  core version (vtable like)
 * @enable_clock_scaling: clock scaling is enabled ?
 * @curr_ipa_clk_rate: ipa_clk current rate

 * IPA context - holds all relevant info about IPA driver and its state
 */
@@ -702,6 +706,8 @@ struct ipa_context {
	struct idr ipa_idr;
	struct device *pdev;
	spinlock_t idr_lock;
	u32 enable_clock_scaling;
	u32 curr_ipa_clk_rate;

	/* wlan related member */
	spinlock_t wlan_spinlock;
@@ -757,7 +763,9 @@ struct ipa_plat_drv_res {
};

struct ipa_controller {
	u32 ipa_clk_rate;
	u32 ipa_clk_rate_hi;
	u32 ipa_clk_rate_lo;
	u32 clock_scaling_bw_threshold;
	void (*ipa_sram_read_settings)(void);
	void (*ipa_cfg_ep_hdr)(u32 pipe_number,
			const struct ipa_ep_cfg_hdr *ipa_ep_hdr_cfg);
+11 −4
Original line number Diff line number Diff line
@@ -20,7 +20,10 @@

#define IPA_V1_CLK_RATE (92.31 * 1000 * 1000UL)
#define IPA_V1_1_CLK_RATE (100 * 1000 * 1000UL)
#define IPA_V2_0_CLK_RATE (150 * 1000 * 1000UL)
#define IPA_V2_0_CLK_RATE_LOW (75 * 1000 * 1000UL)
#define IPA_V2_0_CLK_RATE_HIGH (150 * 1000 * 1000UL)

#define IPA_V2_0_BW_THRESHOLD_MBPS (800)

static const int ipa_ofst_meq32[] = { IPA_OFFSET_MEQ32_0,
					IPA_OFFSET_MEQ32_1, -1 };
@@ -2958,7 +2961,8 @@ int ipa_controller_static_bind(struct ipa_controller *ctrl,
		ctrl->ipa_cfg_ep_status = _ipa_cfg_ep_status_v1_1;
		ctrl->ipa_cfg_ep_cfg = _ipa_cfg_ep_cfg_v1_1;
		ctrl->ipa_cfg_ep_metadata_mask = _ipa_cfg_ep_metadata_mask_v1_1;
		ctrl->ipa_clk_rate = IPA_V1_CLK_RATE;
		ctrl->ipa_clk_rate_hi = IPA_V1_CLK_RATE;
		ctrl->ipa_clk_rate_lo = IPA_V1_CLK_RATE;
		ctrl->ipa_read_gen_reg = _ipa_read_gen_reg_v1_0;
		ctrl->ipa_read_ep_reg = _ipa_read_ep_reg_v1_0;
		ctrl->ipa_write_dbg_cnt = _ipa_write_dbg_cnt_v1;
@@ -2985,7 +2989,8 @@ int ipa_controller_static_bind(struct ipa_controller *ctrl,
		ctrl->ipa_cfg_ep_status = _ipa_cfg_ep_status_v1_1;
		ctrl->ipa_cfg_ep_cfg = _ipa_cfg_ep_cfg_v1_1;
		ctrl->ipa_cfg_ep_metadata_mask = _ipa_cfg_ep_metadata_mask_v1_1;
		ctrl->ipa_clk_rate = IPA_V1_1_CLK_RATE;
		ctrl->ipa_clk_rate_hi = IPA_V1_1_CLK_RATE;
		ctrl->ipa_clk_rate_lo = IPA_V1_1_CLK_RATE;
		ctrl->ipa_read_gen_reg = _ipa_read_gen_reg_v1_1;
		ctrl->ipa_read_ep_reg = _ipa_read_ep_reg_v1_1;
		ctrl->ipa_write_dbg_cnt = _ipa_write_dbg_cnt_v1;
@@ -3012,7 +3017,8 @@ int ipa_controller_static_bind(struct ipa_controller *ctrl,
		ctrl->ipa_cfg_ep_status = _ipa_cfg_ep_status_v2_0;
		ctrl->ipa_cfg_ep_cfg = _ipa_cfg_ep_cfg_v2_0;
		ctrl->ipa_cfg_ep_metadata_mask = _ipa_cfg_ep_metadata_mask_v2_0;
		ctrl->ipa_clk_rate = IPA_V2_0_CLK_RATE;
		ctrl->ipa_clk_rate_hi = IPA_V2_0_CLK_RATE_HIGH;
		ctrl->ipa_clk_rate_lo = IPA_V2_0_CLK_RATE_LOW;
		ctrl->ipa_read_gen_reg = _ipa_read_gen_reg_v2_0;
		ctrl->ipa_read_ep_reg = _ipa_read_ep_reg_v2_0;
		ctrl->ipa_write_dbg_cnt = _ipa_write_dbg_cnt_v2_0;
@@ -3024,6 +3030,7 @@ int ipa_controller_static_bind(struct ipa_controller *ctrl,
		ctrl->ipa_disable_clks = _ipa_disable_clks_v2_0;
		ctrl->msm_bus_data_ptr = &ipa_bus_client_pdata_v2_0;
		ctrl->ipa_cfg_ep_metadata = _ipa_cfg_ep_metadata_v2_0;
		ctrl->clock_scaling_bw_threshold = IPA_V2_0_BW_THRESHOLD_MBPS;
		break;
	default:
		return -EPERM;