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

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

Merge "msm: vidc: Enable clocks during smmu configuration"

parents 9c2ff6c2 003cbed2
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -628,6 +628,12 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev)
		msm_vidc_read_efuse_version(
			pdev, core->resources.pf_cap_tbl, "efuse2");

	rc = call_hfi_op(core->device, core_early_init,
		core->device->hfi_device_data);
	if (rc) {
		dprintk(VIDC_ERR, "Failed to early init core\n");
		goto err_fail_sub_device_probe;
	}
	dprintk(VIDC_DBG, "populating sub devices\n");
	/*
	 * Trigger probe for each sub-device i.e. qcom,msm-vidc,context-bank.
@@ -639,8 +645,12 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev)
			&pdev->dev);
	if (rc) {
		dprintk(VIDC_ERR, "Failed to trigger probe for sub-devices\n");
		call_hfi_op(core->device, core_early_release,
			core->device->hfi_device_data);
		goto err_fail_sub_device_probe;
	}
	call_hfi_op(core->device, core_early_release,
		core->device->hfi_device_data);

	return rc;

+0 −123
Original line number Diff line number Diff line
@@ -22,16 +22,11 @@
#include "venus_boot.h"
#include "soc/qcom/secure_buffer.h"
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/regulator/consumer.h>

enum clock_properties {
	CLOCK_PROP_HAS_SCALING = 1 << 0,
};

struct regulator *gdsc_venus;
struct regulator *gdsc_venus_core0;

static inline struct device *msm_iommu_get_ctx(const char *ctx_name)
{
	return NULL;
@@ -64,118 +59,6 @@ static size_t get_u32_array_num_elements(struct device_node *np,
	return 0;
}

static int venus_regulator_setup(struct msm_vidc_platform_resources *res)
{
	const char *reg_name = "venus";
	const char *reg_name_core0 = "venus-core0";
	int rc = 0;

	gdsc_venus = devm_regulator_get(&res->pdev->dev, reg_name);
	if (IS_ERR(gdsc_venus))
		dprintk(VIDC_ERR, "Failed to get Venus GDSC\n");

	rc = regulator_enable(gdsc_venus);
	if (rc)
		dprintk(VIDC_ERR, "Venus GDSC enable failed\n");

	gdsc_venus_core0 = devm_regulator_get(&res->pdev->dev, reg_name_core0);
	if (IS_ERR(gdsc_venus_core0))
		dprintk(VIDC_ERR, "Failed to get Venus-Core0 GDSC\n");

	rc = regulator_enable(gdsc_venus_core0);
	if (rc)
		dprintk(VIDC_ERR, "Venus-Core0 GDSC enable failed\n");

	dprintk(VIDC_DBG, "Vensu, Venus-Core0 GDSC's are enabled\n");
	return rc;
}


static int venus_clock_setup(struct msm_vidc_platform_resources *res,
		unsigned long rate)
{
	int i, rc = 0;
	struct clock_info *cl;
	struct clk *clk = NULL;

	dprintk(VIDC_DBG, " %s In\n", __func__);
	for (i = 0; i < res->clock_set.count; i++) {
	cl = &res->clock_set.clock_tbl[i];
		if (!cl->has_scaling)
			continue;

		clk = clk_get(&res->pdev->dev, cl->name);
		rc = clk_set_rate(clk, clk_round_rate(clk, rate));

		if (rc)
			dprintk(VIDC_ERR,
				"%s: Failed to set clock rate %s: %d\n",
				__func__, cl->name, rc);

		dprintk(VIDC_DBG, "%s clock set clock rate to %lu\n",
				cl->name, rate);
	}

	dprintk(VIDC_DBG, " %s exit\n", __func__);
	return rc;
}

static int venus_clock_prepare_enable(struct msm_vidc_platform_resources *res)
{
	int i, rc = 0;
	struct clock_info *cl;
	struct clk *clk = NULL;

	dprintk(VIDC_DBG, " %s In\n", __func__);
	for (i = 0; i < res->clock_set.count; i++) {
		cl = &res->clock_set.clock_tbl[i];
		clk = clk_get(&res->pdev->dev, cl->name);
		rc = clk_prepare_enable(clk);

		if (rc) {
			dprintk(VIDC_ERR, "failed to enable %s clock\n",
					cl->name);
			for (i--; i >= 0; i--) {
				cl = &res->clock_set.clock_tbl[i];
				clk = clk_get(&res->pdev->dev, cl->name);
				clk_disable_unprepare(clk);
				dprintk(VIDC_ERR, "clock %s unprepared\n",
						cl->name);
			}
			return rc;
		}
		dprintk(VIDC_DBG, " Clock : %s enabled\n", cl->name);
	}

	dprintk(VIDC_DBG, " %s exit\n", __func__);
	return rc;
}

static void venus_clk_disable_unprepare(struct msm_vidc_platform_resources *res)
{
	int i;
	struct clock_info *cl;
	struct clk *clk = NULL;

	for (i = 0; i < res->clock_set.count; i++) {
		cl = &res->clock_set.clock_tbl[i];
		clk = clk_get(&res->pdev->dev, cl->name);
		dprintk(VIDC_DBG, "clock %s unprepared\n", cl->name);
		clk_disable_unprepare(clk);
	}

	if (gdsc_venus) {
		regulator_disable(gdsc_venus);
		dprintk(VIDC_DBG, "Venus Regulator disabled\n");
		gdsc_venus = NULL;
	}
	if (gdsc_venus_core0) {
		regulator_disable(gdsc_venus_core0);
		dprintk(VIDC_DBG, "Venus-Core0 Regulator disabled\n");
		gdsc_venus_core0 = NULL;
	}
}

static inline enum imem_type read_imem_type(struct platform_device *pdev)
{
	bool is_compatible(char *compat)
@@ -961,7 +844,6 @@ static int msm_vidc_populate_bus(struct device *dev,
	dprintk(VIDC_DBG, "Found bus %s [%d->%d] with governor %s\n",
			bus->name, bus->master, bus->slave, bus->governor);

	venus_clk_disable_unprepare(res);
err_bus:
	return rc;
}
@@ -1352,11 +1234,6 @@ int read_platform_resources_from_dt(
			"qcom,max-secure-instances",
			&res->max_secure_inst_count);

	venus_regulator_setup(res);
	venus_clock_setup(res, 0);
	venus_clock_prepare_enable(res);
	venus_clock_setup(res, 1);

	return rc;

err_setup_legacy_cb:
+100 −0
Original line number Diff line number Diff line
@@ -4001,6 +4001,32 @@ static int __init_resources(struct venus_hfi_device *device,
	return rc;
}

static int __early_init_resources(struct venus_hfi_device *device,
				struct msm_vidc_platform_resources *res)
{
	int rc = 0;

	rc = __init_regulators(device);
	if (rc) {
		dprintk(VIDC_ERR, "Failed to get all regulators\n");
		return -ENODEV;
	}

	rc = __init_clocks(device);
	if (rc) {
		dprintk(VIDC_ERR, "Failed to init clocks\n");
		rc = -ENODEV;
		goto err_init_clocks;
	}

	return rc;

err_init_clocks:
	__deinit_regulators(device);
	return rc;
}


static void __deinit_resources(struct venus_hfi_device *device)
{
	__deinit_bus(device);
@@ -4010,6 +4036,12 @@ static void __deinit_resources(struct venus_hfi_device *device)
	device->sys_init_capabilities = NULL;
}

static void __early_deinit_resources(struct venus_hfi_device *device)
{
	__deinit_clocks(device);
	__deinit_regulators(device);
}

static int __protect_cp_mem(struct venus_hfi_device *device)
{
	struct tzbsp_memprot memprot;
@@ -4235,6 +4267,41 @@ static int __venus_power_on(struct venus_hfi_device *device)
	return rc;
}

static int __venus_early_power_on(struct venus_hfi_device *device)
{
	int rc = 0;

	if (device->power_enabled)
		return 0;

	device->power_enabled = true;

	rc = __enable_regulators(device);
	if (rc) {
		dprintk(VIDC_ERR, "Failed to enable GDSC, err = %d\n", rc);
		goto fail_enable_gdsc;
	}

	rc = __prepare_enable_clks(device);
	if (rc) {
		dprintk(VIDC_ERR, "Failed to enable clocks: %d\n", rc);
		goto fail_enable_clks;
	}

	rc = __scale_clocks(device, 0, NULL, 0);
	if (rc) {
		dprintk(VIDC_WARN,
				"Failed to scale clocks, performance might be affected\n");
		rc = 0;
	}
	return rc;

fail_enable_clks:
	__disable_regulators(device);
fail_enable_gdsc:
	return rc;
}

static void __venus_power_off(struct venus_hfi_device *device, bool halt_axi)
{
	if (!device->power_enabled)
@@ -4261,6 +4328,14 @@ static void __venus_power_off(struct venus_hfi_device *device, bool halt_axi)
	device->power_enabled = false;
}

static void __venus_early_power_off(struct venus_hfi_device *device)
{
	__disable_unprepare_clks(device);
	if (__disable_regulators(device))
		dprintk(VIDC_WARN, "Failed to disable regulators\n");
	device->power_enabled = false;
}

static inline int __suspend(struct venus_hfi_device *device)
{
	int rc = 0;
@@ -4652,10 +4727,35 @@ void venus_hfi_delete_device(void *device)
	}
}

static int venus_hfi_core_early_init(void *device)
{
	int rc = 0;
	struct venus_hfi_device *dev = device;

	mutex_lock(&dev->lock);
	rc = __early_init_resources(dev, dev->res);
	rc = __venus_early_power_on(device);
	mutex_unlock(&dev->lock);
	return rc;
}

static int venus_hfi_core_early_release(void *device)
{
	struct venus_hfi_device *dev = device;

	mutex_lock(&dev->lock);
	__venus_early_power_off(dev);
	__early_deinit_resources(dev);
	mutex_unlock(&dev->lock);
	return 0;
}

static void venus_init_hfi_callbacks(struct hfi_device *hdev)
{
	hdev->core_init = venus_hfi_core_init;
	hdev->core_release = venus_hfi_core_release;
	hdev->core_early_init = venus_hfi_core_early_init;
	hdev->core_early_release = venus_hfi_core_early_release;
	hdev->core_ping = venus_hfi_core_ping;
	hdev->core_trigger_ssr = venus_hfi_core_trigger_ssr;
	hdev->session_init = venus_hfi_session_init;
+2 −0
Original line number Diff line number Diff line
@@ -1483,7 +1483,9 @@ struct hfi_device {

	/*Add function pointers for all the hfi functions below*/
	int (*core_init)(void *device);
	int (*core_early_init)(void *device);
	int (*core_release)(void *device);
	int (*core_early_release)(void *device);
	int (*core_ping)(void *device);
	int (*core_trigger_ssr)(void *device, enum hal_ssr_trigger_type);
	int (*session_init)(void *device, void *session_id,