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

Commit 6a831340 authored by Ghanim Fodi's avatar Ghanim Fodi Committed by Gerrit - the friendly Code Review server
Browse files

msm: ipa3: Bandwidth voting for IPA core clocks



As RPMH HW is being used at sdm845 chip, IPA clock
voting cannot be done through LINUX clock driver.
Instead, vote for IPA clocks by bandwidth voting
using msm-bus-scale driver.

Change-Id: Ic978a6fc09cf3e88f2a0d001b18cde573e7fe209
Signed-off-by: default avatarGhanim Fodi <gfodi@codeaurora.org>
parent 448abcab
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -56,6 +56,9 @@ memory allocation over a PCIe bridge
                                a pipe reset via the IPA uC is required
                                a pipe reset via the IPA uC is required
- qcom,ipa-wdi2:		Boolean context flag to indicate whether
- qcom,ipa-wdi2:		Boolean context flag to indicate whether
				using wdi-2.0 or not
				using wdi-2.0 or not
- qcom,bandwidth-vote-for-ipa:	Boolean context flag to indicate whether
				ipa clock voting is done by bandwidth
				voting via msm-bus-scale driver or not
- qcom,use-dma-zone:            Boolean context flag to indicate whether memory
- qcom,use-dma-zone:            Boolean context flag to indicate whether memory
                                allocations controlled by IPA driver that do not
                                allocations controlled by IPA driver that do not
				specify a struct device * should use GFP_DMA to
				specify a struct device * should use GFP_DMA to
+51 −36
Original line number Original line Diff line number Diff line
@@ -3122,6 +3122,12 @@ static const struct file_operations ipa3_drv_fops = {


static int ipa3_get_clks(struct device *dev)
static int ipa3_get_clks(struct device *dev)
{
{
	if (ipa3_res.use_bw_vote) {
		IPADBG("Vote IPA clock by bw voting via bus scaling driver\n");
		ipa3_clk = NULL;
		return 0;
	}

	ipa3_clk = clk_get(dev, "core_clk");
	ipa3_clk = clk_get(dev, "core_clk");
	if (IS_ERR(ipa3_clk)) {
	if (IS_ERR(ipa3_clk)) {
		if (ipa3_clk != ERR_PTR(-EPROBE_DEFER))
		if (ipa3_clk != ERR_PTR(-EPROBE_DEFER))
@@ -3136,17 +3142,15 @@ static int ipa3_get_clks(struct device *dev)
 */
 */
void _ipa_enable_clks_v3_0(void)
void _ipa_enable_clks_v3_0(void)
{
{
	IPADBG_LOW("enabling gcc_ipa_clk\n");
	IPADBG_LOW("curr_ipa_clk_rate=%d", ipa3_ctx->curr_ipa_clk_rate);
	if (ipa3_clk) {
	if (ipa3_clk) {
		IPADBG_LOW("enabling gcc_ipa_clk\n");
		clk_prepare(ipa3_clk);
		clk_prepare(ipa3_clk);
		clk_enable(ipa3_clk);
		clk_enable(ipa3_clk);
		IPADBG_LOW("curr_ipa_clk_rate=%d", ipa3_ctx->curr_ipa_clk_rate);
		clk_set_rate(ipa3_clk, ipa3_ctx->curr_ipa_clk_rate);
		clk_set_rate(ipa3_clk, ipa3_ctx->curr_ipa_clk_rate);
		ipa3_uc_notify_clk_state(true);
	} else {
		WARN_ON(1);
	}
	}


	ipa3_uc_notify_clk_state(true);
	ipa3_suspend_apps_pipes(false);
	ipa3_suspend_apps_pipes(false);
}
}


@@ -3184,12 +3188,11 @@ void ipa3_enable_clks(void)
{
{
	IPADBG("enabling IPA clocks and bus voting\n");
	IPADBG("enabling IPA clocks and bus voting\n");


	ipa3_ctx->ctrl->ipa3_enable_clks();

	if (ipa3_ctx->ipa3_hw_mode != IPA_HW_MODE_VIRTUAL)
	if (msm_bus_scale_client_update_request(ipa3_ctx->ipa_bus_hdl,
	if (msm_bus_scale_client_update_request(ipa3_ctx->ipa_bus_hdl,
	    ipa3_get_bus_vote()))
	    ipa3_get_bus_vote()))
		WARN_ON(1);
		WARN_ON(1);

	ipa3_ctx->ctrl->ipa3_enable_clks();
}
}




@@ -3198,13 +3201,12 @@ void ipa3_enable_clks(void)
 */
 */
void _ipa_disable_clks_v3_0(void)
void _ipa_disable_clks_v3_0(void)
{
{
	IPADBG_LOW("disabling gcc_ipa_clk\n");
	ipa3_suspend_apps_pipes(true);
	ipa3_suspend_apps_pipes(true);
	ipa3_uc_notify_clk_state(false);
	ipa3_uc_notify_clk_state(false);
	if (ipa3_clk)
	if (ipa3_clk) {
		IPADBG_LOW("disabling gcc_ipa_clk\n");
		clk_disable_unprepare(ipa3_clk);
		clk_disable_unprepare(ipa3_clk);
	else
	}
		WARN_ON(1);
}
}


/**
/**
@@ -3219,9 +3221,7 @@ void ipa3_disable_clks(void)


	ipa3_ctx->ctrl->ipa3_disable_clks();
	ipa3_ctx->ctrl->ipa3_disable_clks();


	if (ipa3_ctx->ipa3_hw_mode != IPA_HW_MODE_VIRTUAL)
	if (msm_bus_scale_client_update_request(ipa3_ctx->ipa_bus_hdl, 0))
		if (msm_bus_scale_client_update_request(ipa3_ctx->ipa_bus_hdl,
		    0))
		WARN_ON(1);
		WARN_ON(1);
}
}


@@ -3524,10 +3524,10 @@ int ipa3_set_required_perf_profile(enum ipa_voltage_level floor_voltage,
	ipa3_ctx->curr_ipa_clk_rate = clk_rate;
	ipa3_ctx->curr_ipa_clk_rate = clk_rate;
	IPADBG_LOW("setting clock rate to %u\n", ipa3_ctx->curr_ipa_clk_rate);
	IPADBG_LOW("setting clock rate to %u\n", ipa3_ctx->curr_ipa_clk_rate);
	if (ipa3_ctx->ipa3_active_clients.cnt > 0) {
	if (ipa3_ctx->ipa3_active_clients.cnt > 0) {
		if (ipa3_clk)
			clk_set_rate(ipa3_clk, ipa3_ctx->curr_ipa_clk_rate);
			clk_set_rate(ipa3_clk, ipa3_ctx->curr_ipa_clk_rate);
		if (ipa3_ctx->ipa3_hw_mode != IPA_HW_MODE_VIRTUAL)
		if (msm_bus_scale_client_update_request(ipa3_ctx->ipa_bus_hdl,
			if (msm_bus_scale_client_update_request(
			ipa3_get_bus_vote()))
			    ipa3_ctx->ipa_bus_hdl, ipa3_get_bus_vote()))
			WARN_ON(1);
			WARN_ON(1);
	} else {
	} else {
		IPADBG_LOW("clocks are gated, not setting rate\n");
		IPADBG_LOW("clocks are gated, not setting rate\n");
@@ -4008,6 +4008,9 @@ static int ipa3_post_init(const struct ipa3_plat_drv_res *resource_p,
	destroy_workqueue(ipa3_ctx->power_mgmt_wq);
	destroy_workqueue(ipa3_ctx->power_mgmt_wq);
	iounmap(ipa3_ctx->mmio);
	iounmap(ipa3_ctx->mmio);
	ipa3_disable_clks();
	ipa3_disable_clks();
	if (ipa3_clk)
		clk_put(ipa3_clk);
	ipa3_clk = NULL;
	msm_bus_scale_unregister_client(ipa3_ctx->ipa_bus_hdl);
	msm_bus_scale_unregister_client(ipa3_ctx->ipa_bus_hdl);
	if (ipa3_bus_scale_table) {
	if (ipa3_bus_scale_table) {
		msm_bus_cl_clear_pdata(ipa3_bus_scale_table);
		msm_bus_cl_clear_pdata(ipa3_bus_scale_table);
@@ -4293,11 +4296,11 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p,
	}
	}


	if (ipa3_bus_scale_table) {
	if (ipa3_bus_scale_table) {
		IPADBG("Use bus scaling info from device tree\n");
		IPADBG("Use bus scaling info from device tree #usecases=%d\n",
			ipa3_bus_scale_table->num_usecases);
		ipa3_ctx->ctrl->msm_bus_data_ptr = ipa3_bus_scale_table;
		ipa3_ctx->ctrl->msm_bus_data_ptr = ipa3_bus_scale_table;
	}
	}


	if (ipa3_ctx->ipa3_hw_mode != IPA_HW_MODE_VIRTUAL) {
	/* get BUS handle */
	/* get BUS handle */
	ipa3_ctx->ipa_bus_hdl =
	ipa3_ctx->ipa_bus_hdl =
		msm_bus_scale_register_client(
		msm_bus_scale_register_client(
@@ -4307,9 +4310,6 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p,
		result = -ENODEV;
		result = -ENODEV;
		goto fail_bus_reg;
		goto fail_bus_reg;
	}
	}
	} else {
		IPADBG("Skipping bus scaling registration on Virtual plat\n");
	}


	/* get IPA clocks */
	/* get IPA clocks */
	result = ipa3_get_clks(master_dev);
	result = ipa3_get_clks(master_dev);
@@ -4684,9 +4684,16 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p,
	ipa3_disable_clks();
	ipa3_disable_clks();
	ipa3_active_clients_log_destroy();
	ipa3_active_clients_log_destroy();
fail_init_active_client:
fail_init_active_client:
	if (ipa3_clk)
		clk_put(ipa3_clk);
	ipa3_clk = NULL;
fail_clk:
fail_clk:
	msm_bus_scale_unregister_client(ipa3_ctx->ipa_bus_hdl);
	msm_bus_scale_unregister_client(ipa3_ctx->ipa_bus_hdl);
fail_bus_reg:
fail_bus_reg:
	if (ipa3_bus_scale_table) {
		msm_bus_cl_clear_pdata(ipa3_bus_scale_table);
		ipa3_bus_scale_table = NULL;
	}
fail_init_mem_partition:
fail_init_mem_partition:
fail_bind:
fail_bind:
	kfree(ipa3_ctx->ctrl);
	kfree(ipa3_ctx->ctrl);
@@ -4717,6 +4724,7 @@ static int get_ipa_dts_configuration(struct platform_device *pdev,
	ipa_drv_res->modem_cfg_emb_pipe_flt = false;
	ipa_drv_res->modem_cfg_emb_pipe_flt = false;
	ipa_drv_res->ipa_wdi2 = false;
	ipa_drv_res->ipa_wdi2 = false;
	ipa_drv_res->use_64_bit_dma_mask = false;
	ipa_drv_res->use_64_bit_dma_mask = false;
	ipa_drv_res->use_bw_vote = false;
	ipa_drv_res->wan_rx_ring_size = IPA_GENERIC_RX_POOL_SZ;
	ipa_drv_res->wan_rx_ring_size = IPA_GENERIC_RX_POOL_SZ;
	ipa_drv_res->lan_rx_ring_size = IPA_GENERIC_RX_POOL_SZ;
	ipa_drv_res->lan_rx_ring_size = IPA_GENERIC_RX_POOL_SZ;
	ipa_drv_res->apply_rg10_wa = false;
	ipa_drv_res->apply_rg10_wa = false;
@@ -4796,6 +4804,13 @@ static int get_ipa_dts_configuration(struct platform_device *pdev,
			ipa_drv_res->use_64_bit_dma_mask
			ipa_drv_res->use_64_bit_dma_mask
			? "True" : "False");
			? "True" : "False");


	ipa_drv_res->use_bw_vote =
			of_property_read_bool(pdev->dev.of_node,
			"qcom,bandwidth-vote-for-ipa");
	IPADBG(": use_bw_vote = %s\n",
			ipa_drv_res->use_bw_vote
			? "True" : "False");

	ipa_drv_res->skip_uc_pipe_reset =
	ipa_drv_res->skip_uc_pipe_reset =
		of_property_read_bool(pdev->dev.of_node,
		of_property_read_bool(pdev->dev.of_node,
		"qcom,skip-uc-pipe-reset");
		"qcom,skip-uc-pipe-reset");
+2 −1
Original line number Original line Diff line number Diff line
@@ -1054,7 +1054,7 @@ struct ipa_tz_unlock_reg_info {
 * @ctrl: holds the core specific operations based on
 * @ctrl: holds the core specific operations based on
 *  core version (vtable like)
 *  core version (vtable like)
 * @enable_clock_scaling: clock scaling is enabled ?
 * @enable_clock_scaling: clock scaling is enabled ?
 * @curr_ipa_clk_rate: ipa3_clk current rate
 * @curr_ipa_clk_rate: IPA current clock rate
 * @wcstats: wlan common buffer stats
 * @wcstats: wlan common buffer stats
 * @uc_ctx: uC interface context
 * @uc_ctx: uC interface context
 * @uc_wdi_ctx: WDI specific fields for uC interface
 * @uc_wdi_ctx: WDI specific fields for uC interface
@@ -1209,6 +1209,7 @@ struct ipa3_plat_drv_res {
	bool modem_cfg_emb_pipe_flt;
	bool modem_cfg_emb_pipe_flt;
	bool ipa_wdi2;
	bool ipa_wdi2;
	bool use_64_bit_dma_mask;
	bool use_64_bit_dma_mask;
	bool use_bw_vote;
	u32 wan_rx_ring_size;
	u32 wan_rx_ring_size;
	u32 lan_rx_ring_size;
	u32 lan_rx_ring_size;
	bool skip_uc_pipe_reset;
	bool skip_uc_pipe_reset;