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

Commit 985d533d authored by Stephane Viau's avatar Stephane Viau
Browse files

msm: VPU: Support new clocks for HQV, FRC and QDSS



New clocks such as FRC and QDSS need to be handled in the VPU driver.
Updated implementation allows the vpu driver to check which clocks are
required in the system, based on device tree entries.

Change-Id: I87e6ae8de933e70b2f20636de95565ba511c5b4a
Signed-off-by: default avatarStephane Viau <sviau@codeaurora.org>
parent 02983880
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@ Required properties:
- interrupt-names : Names corresponding to the defined interrupts list.
    - "vpu_wdog" : Watchdog interrupt
    - "vpu_hfi" : Firmware to Host interrupt
- clock-names: Array of clocks that the driver requires for the device.
 The names here correspond to the clock names used in clk_get(<name>).

- qcom,maple-clk-load-freq-tbl: Table of <load, freq> entries. An entry
  specifies a given VPU processing load (in bits per second), and a
@@ -41,6 +43,7 @@ Example:
		reg-names = "vpu_csr", "vpu_smem";
		interrupts = <0 44 0>, <0 45 0>;
		interrupt-names = "vpu_wdog", "vpu_hfi";
		clock-names = "core_clk", "bus_clock", "iface_clk";
		qcom,maple-clk-load-freq-tbl = <100000 50000000>,
			<500000 400000000>;
		qcom,vdp-clk-load-freq-tbl = <200000 100000000>,
+91 −81
Original line number Diff line number Diff line
/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -156,33 +156,15 @@ int vpu_bus_scale(u32 load)
 * vpu_vdp_clk between 200MHz and 400MHz during runtime to optimize for
 * power consumption
 */
#define	VPU_CLK_GATE_LEVEL VPU_VDP_CLK

static const char *clock_names[VPU_MAX_CLKS] = {
	[VPU_BUS_CLK] = "vdp_bus_clk",
	[VPU_MAPLE_CLK] = "core_clk",
	[VPU_VDP_CLK] = "vdp_clk",
	[VPU_AHB_CLK] = "iface_clk",
	[VPU_AXI_CLK] = "bus_clk",
	[VPU_SLEEP_CLK] = "sleep_clk",
	[VPU_CXO_CLK] = "cxo_clk",
	[VPU_MAPLE_AXI_CLK] = "maple_bus_clk",
	[VPU_PRNG_CLK] = "prng_clk",
};

struct vpu_core_clock {
	struct clk *clk;
	u32 status;
	u32 current_freq;
	struct load_freq_table *load_freq_tbl;
	const char *name;
};
#define NOT_USED(clk_ctrl, i) (!( \
			((clk_ctrl)->clock[i]->flag & CLOCK_PRESENT) && \
			((clk_ctrl)->clock[i]->flag & (clk_ctrl)->mask)))
#define NOT_IN_GROUP(clk_ctrl, i, clk_group) (!( \
			((clk_ctrl)->clock[i]->flag & (clk_group))))

static const u32 clock_freqs[VPU_MAX_CLKS][VPU_POWER_MAX] = {
	[VPU_BUS_CLK]	= { 40000000,  80000000,  80000000},
	[VPU_MAPLE_CLK]	= {200000000, 400000000, 400000000},
	[VPU_VDP_CLK]	= {200000000, 200000000, 400000000},
};
#define CLOCK_IS_SCALABLE(clk_ctrl, i) \
			((clk_ctrl)->clock[i]->flag & CLOCK_SCALABLE)

/*
 * Note: there is no lock in this block
@@ -194,14 +176,15 @@ struct vpu_clk_control {
	/* svs, nominal, turbo, dynamic(default) */
	u32 mode;

	struct vpu_core_clock clock[VPU_MAX_CLKS];
	struct vpu_clock *clock[VPU_MAX_CLKS];

	u32 mask;
};

void *vpu_clock_init(struct vpu_platform_resources *res)
{
	int i;
	int rc = -1;
	struct vpu_core_clock *cl;
	struct vpu_clock *cl;
	struct vpu_clk_control *clk_ctrl;

	if (!res)
@@ -214,14 +197,21 @@ void *vpu_clock_init(struct vpu_platform_resources *res)
		return NULL;
	}

	for (i = 0; i < VPU_MAX_CLKS; i++)
		clk_ctrl->clock[i] = &res->clock[i];

	/* mask allowing to only enable clocks from certain groups of clocks */
	clk_ctrl->mask = CLOCK_CORE;

	/* setup the clock handles */
	for (i = 0; i < VPU_MAX_CLKS; i++) {
		cl = &clk_ctrl->clock[i];
		if (NOT_USED(clk_ctrl, i))
			continue;

		cl->load_freq_tbl = &res->clock_tables[i];
		cl->name = clock_names[i];
		cl = clk_ctrl->clock[i];

		if (i <= VPU_CLK_GATE_LEVEL && cl->load_freq_tbl->count == 0) {
		if (CLOCK_IS_SCALABLE(clk_ctrl, i) &&
				!cl->load_freq_tbl.count) {
			pr_err("%s freq table size is 0\n", cl->name);
			goto fail_init_clocks;
		}
@@ -229,27 +219,16 @@ void *vpu_clock_init(struct vpu_platform_resources *res)
		cl->clk = devm_clk_get(&res->pdev->dev, cl->name);
		if (IS_ERR_OR_NULL(cl->clk)) {
			pr_err("Failed to get clock: %s\n", cl->name);
			rc = PTR_ERR(cl->clk);
			break;
		}
		cl->status = 0;
	}

	/* free the clock if not all successful */
	if (i < VPU_MAX_CLKS) {
		for (i = 0; i < VPU_MAX_CLKS; i++) {
			cl = &clk_ctrl->clock[i];
			if (cl->clk) {
				clk_put(cl->clk);
			cl->clk = NULL;
			}
		}
			goto fail_init_clocks;
		}
		cl->status = 0;
	}

	return clk_ctrl;

fail_init_clocks:
	vpu_clock_deinit((void *)clk_ctrl);
	kfree(clk_ctrl);
	return NULL;
}
@@ -257,7 +236,7 @@ fail_init_clocks:
void vpu_clock_deinit(void *clkh)
{
	int i;
	struct vpu_core_clock *cl;
	struct vpu_clock *cl;
	struct vpu_clk_control *clk_ctr = (struct vpu_clk_control *)clkh;

	if (!clk_ctr) {
@@ -266,21 +245,32 @@ void vpu_clock_deinit(void *clkh)
	}

	for (i = 0; i < VPU_MAX_CLKS; i++) {
		cl = &clk_ctr->clock[i];
		if (NOT_USED(clk_ctr, i))
			continue;
		cl = clk_ctr->clock[i];
		if (cl->status) {
			clk_disable_unprepare(cl->clk);
			cl->status = 0;
		}
		if (cl->clk) {
			clk_put(cl->clk);
			cl->clk = NULL;
		}
	}

	kfree(clk_ctr);
}

int vpu_clock_enable(void *clkh)
/*
 * vpu_clock_enable() - enable a group of clocks
 *
 * @clkh:		clock handler
 * @clk_group:	see vpu_clock_flag (group section)
 *
 */
int vpu_clock_enable(void *clkh, u32 clk_group)
{
	struct vpu_core_clock *cl;
	struct vpu_clock *cl;
	struct vpu_clk_control *clk_ctr = (struct vpu_clk_control *)clkh;
	int i = 0;
	int rc = 0;
@@ -293,14 +283,18 @@ int vpu_clock_enable(void *clkh)
	clk_ctr->mode = VPU_POWER_DYNAMIC;

	for (i = 0; i < VPU_MAX_CLKS; i++) {
		cl = &clk_ctr->clock[i];
		if (NOT_USED(clk_ctr, i) ||
				NOT_IN_GROUP(clk_ctr, i, clk_group))
			continue;

		cl = clk_ctr->clock[i];

		if (cl->status == 0) {
			/* set rate if it's a gated clock */
			if (i <= VPU_CLK_GATE_LEVEL &&
				cl->load_freq_tbl->entry) {
			if (CLOCK_IS_SCALABLE(clk_ctr, i) &&
				cl->load_freq_tbl.entry) {
				cl->current_freq =
					cl->load_freq_tbl->entry[0].freq;
					cl->load_freq_tbl.entry[0].freq;

				rc = clk_set_rate(cl->clk, cl->current_freq);
				if (rc) {
@@ -325,21 +319,21 @@ int vpu_clock_enable(void *clkh)
	return rc;

fail_clk_enable:
	for (i = 0; i < VPU_MAX_CLKS; i++) {
		cl = &clk_ctr->clock[i];
		if (cl->status) {
			clk_disable_unprepare(cl->clk);
			cl->status = 0;
		}
	}

	vpu_clock_disable(clkh, clk_group);
	return rc;
}

void vpu_clock_disable(void *clkh)
/*
 * vpu_clock_disable() - disable a group of clocks
 *
 * @clkh:		clock handler
 * @clk_group:	see vpu_clock_flag (group section)
 *
 */
void vpu_clock_disable(void *clkh, u32 clk_group)
{
	int i;
	struct vpu_core_clock *cl;
	struct vpu_clock *cl;
	struct vpu_clk_control *clk_ctr = (struct vpu_clk_control *)clkh;

	if (!clk_ctr) {
@@ -348,7 +342,10 @@ void vpu_clock_disable(void *clkh)
	}

	for (i = 0; i < VPU_MAX_CLKS; i++) {
		cl = &clk_ctr->clock[i];
		if (NOT_USED(clk_ctr, i) ||
				NOT_IN_GROUP(clk_ctr, i, clk_group))
			continue;
		cl = clk_ctr->clock[i];
		if (cl->status) {
			clk_disable_unprepare(cl->clk);
			cl->status = 0;
@@ -356,10 +353,10 @@ void vpu_clock_disable(void *clkh)
	}
}

static unsigned long __clock_get_rate(struct vpu_core_clock *clock,
static unsigned long __clock_get_rate(struct vpu_clock *clock,
	u32 num_bits_per_sec)
{
	struct load_freq_table *table = clock->load_freq_tbl;
	struct load_freq_table *table = &clock->load_freq_tbl;
	unsigned long ret = 0;
	int i;

@@ -385,10 +382,13 @@ int vpu_clock_scale(void *clkh, u32 load)

	clk_ctr->load = load;

	for (i = 0; i <= VPU_CLK_GATE_LEVEL; i++) {
		struct vpu_core_clock *cl = &clk_ctr->clock[i];
	for (i = 0; i < VPU_MAX_CLKS; i++) {
		struct vpu_clock *cl = clk_ctr->clock[i];
		unsigned long freq;

		if (NOT_USED(clk_ctr, i) || !CLOCK_IS_SCALABLE(clk_ctr, i))
			continue;

		freq = __clock_get_rate(cl, load);
		if (clk_ctr->mode == VPU_POWER_DYNAMIC) {
			rc = clk_set_rate(cl->clk, freq);
@@ -407,7 +407,7 @@ int vpu_clock_scale(void *clkh, u32 load)
int vpu_clock_gating_off(void *clkh)
{
	int i;
	struct vpu_core_clock *cl;
	struct vpu_clock *cl;
	struct vpu_clk_control *clk_ctr = (struct vpu_clk_control *)clkh;
	int rc = 0;

@@ -420,8 +420,11 @@ int vpu_clock_gating_off(void *clkh)
	if (clk_ctr->mode != VPU_POWER_DYNAMIC)
		return 0;

	for (i = 0; i <= VPU_CLK_GATE_LEVEL; i++) {
		cl = &clk_ctr->clock[i];
	for (i = 0; i < VPU_MAX_CLKS; i++) {
		if (NOT_USED(clk_ctr, i) || !CLOCK_IS_SCALABLE(clk_ctr, i))
			continue;

		cl = clk_ctr->clock[i];
		if (cl->status == 0) {
			rc = clk_enable(cl->clk);
			if (rc) {
@@ -440,7 +443,7 @@ int vpu_clock_gating_off(void *clkh)
void vpu_clock_gating_on(void *clkh)
{
	int i;
	struct vpu_core_clock *cl;
	struct vpu_clock *cl;
	struct vpu_clk_control *clk_ctr = (struct vpu_clk_control *)clkh;

	if (!clk_ctr) {
@@ -452,8 +455,11 @@ void vpu_clock_gating_on(void *clkh)
	if (clk_ctr->mode != VPU_POWER_DYNAMIC)
		return;

	for (i = 0; i <= VPU_CLK_GATE_LEVEL; i++) {
		cl = &clk_ctr->clock[i];
	for (i = 0; i < VPU_MAX_CLKS; i++) {
		if (NOT_USED(clk_ctr, i) || !CLOCK_IS_SCALABLE(clk_ctr, i))
			continue;

		cl = clk_ctr->clock[i];
		if (cl->status) {
			clk_disable(cl->clk);
			cl->status = 0;
@@ -477,12 +483,16 @@ void vpu_clock_mode_set(void *clkh, enum vpu_power_mode mode)

	if (mode <= VPU_POWER_DYNAMIC) {
		clk_ctr->mode = mode;
		for (i = 0; i <= VPU_CLK_GATE_LEVEL; i++) {
			struct vpu_core_clock *cl = &clk_ctr->clock[i];
		for (i = 0; i < VPU_MAX_CLKS; i++) {
			struct vpu_clock *cl = clk_ctr->clock[i];
			unsigned long freq;

			if (NOT_USED(clk_ctr, i) ||
					!CLOCK_IS_SCALABLE(clk_ctr, i))
				continue;

			if (mode < VPU_POWER_DYNAMIC)
				freq = clock_freqs[i][mode];
				freq = cl->pwr_frequencies[mode];
			else
				freq = cl->current_freq;

+3 −11
Original line number Diff line number Diff line
/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -26,21 +26,13 @@ int vpu_bus_scale(u32 load);
void *vpu_clock_init(struct vpu_platform_resources *res);
void vpu_clock_deinit(void *clk_handle);

int  vpu_clock_enable(void *clk_handle);
void vpu_clock_disable(void *clk_handle);
int  vpu_clock_enable(void *clk_handle, u32 clk_group);
void vpu_clock_disable(void *clk_handle, u32 clk_group);
int vpu_clock_scale(void *clk_handle, u32 load);

int vpu_clock_gating_off(void *clkh);
void vpu_clock_gating_on(void *clkh);

enum vpu_power_mode {
	VPU_POWER_SVS,
	VPU_POWER_NOMINAL,
	VPU_POWER_TURBO,
	VPU_POWER_DYNAMIC,
	VPU_POWER_MAX = VPU_POWER_DYNAMIC
};

void vpu_clock_mode_set(void *clkh, enum vpu_power_mode mode);
enum vpu_power_mode vpu_clock_mode_get(void *clkh);
#endif /* __H_VPU_BUS_CLOCK_H__ */
+4 −4
Original line number Diff line number Diff line
/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -1947,7 +1947,7 @@ static int vpu_hw_power_on(struct vpu_channel_hal *hal)
	}

	/* enable the VPU clocks */
	rc = vpu_clock_enable(hal->clk_handle);
	rc = vpu_clock_enable(hal->clk_handle, CLOCK_BOOT);
	if (unlikely(rc)) {
		pr_err("failed to enable clock\n");
		goto err_clock;
@@ -1970,7 +1970,7 @@ err_power:
 */
static void vpu_hw_power_off(struct vpu_channel_hal *hal)
{
	vpu_clock_disable(hal->clk_handle);
	vpu_clock_disable(hal->clk_handle, CLOCK_ALL_GROUPS);
	vpu_bus_unvote();
	if (hal->vdd_enabled) {
		regulator_disable(hal->vdd);
@@ -1993,7 +1993,7 @@ int vpu_hw_sys_suspend(void)
	/* TODO: Send suspend IPC command once it is defined	*/

	/* make sure clock are on */
	rc = vpu_clock_enable(ch_hal->clk_handle);
	rc = vpu_clock_enable(ch_hal->clk_handle, CLOCK_BOOT);
	if (rc) {
		pr_err("clock off when trying to suspend\n");
		goto suspend_exit;
+165 −11
Original line number Diff line number Diff line
/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -78,10 +78,110 @@ static struct vpu_iommu_map iommus_array[VPU_MAX_IOMMU_DOMAIN] = {
	},
};

static const char * const clk_table_dt_entries[] = {
	[VPU_BUS_CLK] = "qcom,bus-clk-load-freq-tbl",
	[VPU_MAPLE_CLK] = "qcom,maple-clk-load-freq-tbl",
	[VPU_VDP_CLK] = "qcom,vdp-clk-load-freq-tbl",
struct vpu_clock_descr {
	char *name;
	u32 flag;	/* enum vpu_clock_flag */
	u32 pwr_frequencies[VPU_POWER_MAX];
	char *load_freq_dt_entry;
};

const struct vpu_clock_descr vpu_clock_set[VPU_MAX_CLKS] = {
		[VPU_BUS_CLK] = {
			.name = "vdp_bus_clk",
			.flag = CLOCK_CORE | CLOCK_BOOT | CLOCK_SCALABLE,
			.pwr_frequencies = { 40000000,  80000000,  80000000},
			.load_freq_dt_entry = "qcom,bus-clk-load-freq-tbl",
		},
		[VPU_MAPLE_CLK] = {
			.name = "core_clk",
			.flag = CLOCK_CORE | CLOCK_BOOT | CLOCK_SCALABLE,
			.pwr_frequencies = {200000000, 400000000, 400000000},
			.load_freq_dt_entry = "qcom,maple-clk-load-freq-tbl",
		},
		[VPU_VDP_CLK] = {
			.name = "vdp_clk",
			.flag = CLOCK_CORE | CLOCK_BOOT | CLOCK_SCALABLE,
			.pwr_frequencies = {200000000, 200000000, 400000000},
			.load_freq_dt_entry = "qcom,vdp-clk-load-freq-tbl",
		},
		[VPU_VDP_XIN] = {
			.name = "vdp_xin_clk",
			.flag = CLOCK_CORE | CLOCK_BOOT | CLOCK_SCALABLE,
			.pwr_frequencies = {200000000, 467000000, 467000000},
			.load_freq_dt_entry = "qcom,vdp-xin-clk-load-freq-tbl",
		},
		[VPU_AHB_CLK] = {
			.name = "iface_clk",
			.flag = CLOCK_CORE | CLOCK_BOOT,
		},
		[VPU_AXI_CLK] = {
			.name = "bus_clk",
			.flag = CLOCK_CORE | CLOCK_BOOT,
		},
		[VPU_SLEEP_CLK] = {
			.name = "sleep_clk",
			.flag = CLOCK_CORE | CLOCK_BOOT,
		},
		[VPU_CXO_CLK] = {
			.name = "cxo_clk",
			.flag = CLOCK_CORE | CLOCK_BOOT,
		},
		[VPU_MAPLE_AXI_CLK] = {
			.name = "maple_bus_clk",
			.flag = CLOCK_CORE | CLOCK_BOOT,
		},
		[VPU_PRNG_CLK] = {
			.name = "prng_clk",
			.flag = CLOCK_CORE | CLOCK_BOOT,
		},
		[VPU_FRC_GPROC] {
			.name = "gproc_clk",
			.flag = CLOCK_FRC | CLOCK_BOOT,
		},
		[VPU_FRC_KPROC] {
			.name = "kproc_clk",
			.flag = CLOCK_FRC | CLOCK_BOOT,
		},
		[VPU_FRC_SDMC_FRCS] {
			.name = "sdmc_frcs_clk",
			.flag = CLOCK_FRC,
		},
		[VPU_FRC_SDME_FRCF] {
			.name = "sdme_frcf_clk",
			.flag = CLOCK_FRC,
		},
		[VPU_FRC_SDME_FRCS] {
			.name = "sdme_frcs_clk",
			.flag = CLOCK_FRC,
		},
		[VPU_FRC_SDME_VPRO] {
			.name = "sdme_vproc_clk",
			.flag = CLOCK_FRC,
		},
		[VPU_FRC_HDMC_FRCF] {
			.name = "hdmc_frcf_clk",
			.flag = CLOCK_FRC,
		},
		[VPU_FRC_PREPROC] {
			.name = "preproc_clk",
			.flag = CLOCK_FRC,
		},
		[VPU_FRC_FRC_XIN] {
			.name = "frc_xin_clk",
			.flag = CLOCK_FRC,
		},
		[VPU_FRC_MAPLE_AXI] {
			.name = "maple_axi_clk",
			.flag = CLOCK_FRC,
		},
		[VPU_QDSS_AT] {
			.name = "qdss_at_clk",
			.flag = CLOCK_QDSS,
		},
		[VPU_QDSS_TSCTR_DIV8] {
			.name = "qdss_tsctr_div8_clk",
			.flag = CLOCK_QDSS,
		},
};

struct bus_pdata_config {
@@ -125,7 +225,7 @@ static int __vpu_load_freq_table(struct vpu_platform_resources *res,
	clk_table->entry = devm_kzalloc(&pdev->dev,
		num_elements * sizeof(*clk_table->entry), GFP_KERNEL);
	if (!clk_table->entry) {
		pr_err("Failed alloc load_freq_tabll\n");
		pr_err("Failed alloc load_freq_table\n");
		return -ENOMEM;
	}

@@ -148,12 +248,17 @@ static int __vpu_load_freq_tables(struct vpu_platform_resources *res)
{
	int ret = 0, i;

	for (i = 0; i < ARRAY_SIZE(clk_table_dt_entries); i++) {
		ret = __vpu_load_freq_table(res, clk_table_dt_entries[i],
				&res->clock_tables[i]);
	for (i = 0; i < VPU_MAX_CLKS; i++) {
		struct vpu_clock *cl = &res->clock[i];

		if ((cl->flag & CLOCK_PRESENT) && (cl->flag & CLOCK_SCALABLE)) {
			ret = __vpu_load_freq_table(res,
					vpu_clock_set[i].load_freq_dt_entry,
					&cl->load_freq_tbl);
			if (ret)
				return ret;
		}
	}

	return ret;
}
@@ -259,6 +364,49 @@ static int __vpu_load_bus_vectors(struct vpu_platform_resources *res)
	return 0;
}

static int __vpu_load_clk_names(struct vpu_platform_resources *res)
{
	int ret = 0, i, j, num_elements;
	struct platform_device *pdev = res->pdev;
	const char *name;

	num_elements = of_property_count_strings(pdev->dev.of_node,
				"qcom,clock-names");
	if (num_elements <= 0) {
		pr_err("No valid clock list in device tree.\n");
		return -EINVAL;
	} else if (num_elements > VPU_MAX_CLKS) {
		pr_err("List of clocks to enable is too large\n");
		return -EINVAL;
	}

	for (i = 0; i < num_elements; i++) {
		bool found = false;
		ret = of_property_read_string_index(pdev->dev.of_node,
				"qcom,clock-names", i, &name);
		if (ret)
			return ret;

		for (j = 0; j < VPU_MAX_CLKS; j++) {
			if (strcmp(name, vpu_clock_set[j].name) == 0) {
				res->clock[j].name = vpu_clock_set[j].name;
				res->clock[j].flag = vpu_clock_set[j].flag |
								CLOCK_PRESENT;
				res->clock[j].pwr_frequencies =
					vpu_clock_set[j].pwr_frequencies;
				found = true;
				break;
			}
		}
		if (!found) {
			pr_err("clock %s not found\n", name);
			return -EINVAL;
		}
	}

	return 0;
}

static int __vpu_load_iommu_maps(struct vpu_platform_resources *res)
{
	int ret = 0, i, j, num_elements;
@@ -351,6 +499,12 @@ int read_vpu_platform_resources(struct vpu_platform_resources *res,
			GFP_KERNEL))
		return -ENOMEM;

	ret = __vpu_load_clk_names(res);
	if (ret) {
		pr_err("Failed to load clock names: %d\n", ret);
		goto err_read_dt_resources;
	}

	ret = __vpu_load_freq_tables(res);
	if (ret) {
		pr_err("Failed to load freq tables: %d\n", ret);
Loading