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

Commit 7ab01151 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: ipa: add clock scaling support to IPA driver"

parents 14340c71 9b2afaad
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
@@ -1289,6 +1289,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 {
@@ -635,6 +637,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
 */
@@ -703,6 +707,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;
@@ -758,7 +764,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;