当前位置: 首页 > 工具软件 > Venus > 使用案例 >

Android-venus时钟频率

万博涛
2023-12-01

前言:

  当硬件性能足够的情况下,有时候还是会遇到平台编解码耗时较长的问题。此时,就需要检查venus的时钟频率了。时钟频率低必将导致codec速度下降。

 

时钟频率的查看:

step1: 打开log

   adb shell setprop vendor.vidc.debug.level 7

   adb shell "echo 0x103F > /d/msm_vidc/debug_level"

   adb shell "echo 0x3F > /d/msm_vidc/fw_level"

step2: 复现问题抓取log

   adb logcat -b kernel >kernel.log

step3: 查看时钟频率

   09-10 17:19:13.552 0 0 I msm_vidc: prof: Scaling clock core1_clk to 100000000

   09-10 17:19:13.588 0 0 I msm_vidc: prof: Scaling clock core_clk to 100000000

   09-10 17:19:13.588 0 0 I msm_vidc: prof: Scaling clock core0_clk to 100000000

   综上我们就可以看到复现问题时venus的时钟频率为100Mhz.

 

时钟频率的设置:

// kernel/msm-4.14/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
msm_clock_data_reset
msm_comm_scale_clocks_and_bus
msm-4.14/drivers/media/platform/msm/vidc/msm_vidc.c start_streaming
msm_vidc_start_streaming   start_streaming = msm_vidc_start_streaming


int msm_comm_scale_clocks(struct msm_vidc_inst *inst)
{
	struct msm_vidc_buffer *temp, *next;
	unsigned long freq = 0;
	u32 filled_len = 0;
	u32 device_addr = 0;
	bool is_turbo = false;
	if (!inst || !inst->core) {
		dprintk(VIDC_ERR, "%s Invalid args: Inst = %pK\n",
			__func__, inst);
		return -EINVAL;
	}
	mutex_lock(&inst->registeredbufs.lock);
	list_for_each_entry_safe(temp, next, &inst->registeredbufs.list, list) {
		if (temp->vvb.vb2_buf.type ==
				V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
			filled_len = max(filled_len,
				temp->vvb.vb2_buf.planes[0].bytesused);
			if (inst->session_type == MSM_VIDC_ENCODER &&
				(temp->vvb.flags &
				 V4L2_QCOM_BUF_FLAG_PERF_MODE)) {
				is_turbo = true;
			}
			device_addr = temp->smem[0].device_addr;
		}
	}
	mutex_unlock(&inst->registeredbufs.lock);
	if (!filled_len || !device_addr) {
		dprintk(VIDC_DBG, "%s no input for session %x\n",
			__func__, hash32_ptr(inst->session));
		goto no_clock_change;
	}
	freq = call_core_op(inst->core, calc_freq, inst, filled_len);
	inst->clk_data.min_freq = freq;
	/* update dcvs flags */
	msm_dcvs_scale_clocks(inst, freq);
	if (inst->clk_data.buffer_counter < DCVS_FTB_WINDOW || is_turbo ||
		msm_vidc_clock_voting) {
		inst->clk_data.min_freq = msm_vidc_max_freq(inst->core);
		inst->clk_data.dcvs_flags = 0;
	}
	msm_vidc_update_freq_entry(inst, freq, device_addr, is_turbo);
	msm_vidc_set_clocks(inst->core);
no_clock_change:
	return 0;
}

int msm_vidc_set_clocks(struct msm_vidc_core *core)
{
	struct hfi_device *hdev;
	unsigned long freq_core_1 = 0, freq_core_2 = 0, rate = 0;
	unsigned long freq_core_max = 0;
	struct msm_vidc_inst *temp = NULL;
	int rc = 0, i = 0;
	struct allowed_clock_rates_table *allowed_clks_tbl = NULL;
	bool increment, decrement;
	hdev = core->device;
	allowed_clks_tbl = core->resources.allowed_clks_tbl;
	if (!allowed_clks_tbl) {
		dprintk(VIDC_ERR,
			"%s Invalid parameters\n", __func__);
		return -EINVAL;
	}
	mutex_lock(&core->lock);
	increment = false;
	decrement = true;
	list_for_each_entry(temp, &core->instances, list) {
		if (temp->clk_data.core_id == VIDC_CORE_ID_1)
			freq_core_1 += temp->clk_data.min_freq;
		else if (temp->clk_data.core_id == VIDC_CORE_ID_2)
			freq_core_2 += temp->clk_data.min_freq;
		else if (temp->clk_data.core_id == VIDC_CORE_ID_3) {
			freq_core_1 += temp->clk_data.min_freq;
			freq_core_2 += temp->clk_data.min_freq;
		}
		freq_core_max = max_t(unsigned long, freq_core_1, freq_core_2);
		if (msm_vidc_clock_voting) {
			dprintk(VIDC_PROF,
				"msm_vidc_clock_voting %d\n",
				 msm_vidc_clock_voting);
			freq_core_max = msm_vidc_clock_voting;
			decrement = false;
			break;
		}
		if (temp->clk_data.turbo_mode) {
			dprintk(VIDC_PROF,
				"Found an instance with Turbo request\n");
			freq_core_max = msm_vidc_max_freq(core);
			decrement = false;
			break;
		}
		/* increment even if one session requested for it */
		if (temp->clk_data.dcvs_flags & MSM_VIDC_DCVS_INCR)
			increment = true;
		/* decrement only if all sessions requested for it */
		if (!(temp->clk_data.dcvs_flags & MSM_VIDC_DCVS_DECR))
			decrement = false;
	}
	for (i = core->resources.allowed_clks_tbl_size - 1; i >= 0; i--) {
		rate = allowed_clks_tbl[i].clock_rate;
		if (rate >= freq_core_max)
			break;
	}
	if (increment) {
		if (i > 0)
			rate = allowed_clks_tbl[i-1].clock_rate;
	} else if (decrement) {
		if (i < (core->resources.allowed_clks_tbl_size - 1))
			rate = allowed_clks_tbl[i+1].clock_rate;
	}
	core->min_freq = freq_core_max;
	core->curr_freq = rate;
	mutex_unlock(&core->lock);
	dprintk(VIDC_PROF,
		"%s: clock rate %lu requested %lu increment %d decrement %d\n",
		__func__, core->curr_freq, core->min_freq,
		increment, decrement);
	rc = call_hfi_op(hdev, scale_clocks,
			hdev->hfi_device_data, core->curr_freq);
	return rc;
}

// kernel/msm-4.14/drivers/media/platform/msm/vidc/venus_hfi.c
static void venus_init_hfi_callbacks(struct hfi_device *hdev)
{   ......
    hdev->scale_clocks = venus_hfi_scale_clocks;
    ......
}

static int venus_hfi_scale_clocks(void *dev, u32 freq)
{
	int rc = 0;
	struct venus_hfi_device *device = dev;
	if (!device) {
		dprintk(VIDC_ERR, "Invalid args: %pK\n", device);
		return -EINVAL;
	}
	mutex_lock(&device->lock);
	if (__resume(device)) {
		dprintk(VIDC_ERR, "Resume from power collapse failed\n");
		rc = -ENODEV;
		goto exit;
	}
	rc = __set_clocks(device, freq);
exit:
	mutex_unlock(&device->lock);
	return rc;
}

static int __set_clocks(struct venus_hfi_device *device, u32 freq)
{
	struct clock_info *cl;
	int rc = 0;
	venus_hfi_for_each_clock(device, cl) {
		if (cl->has_scaling) {/* has_scaling */
			rc = __set_clk_rate(device, cl, freq);
			if (rc)
				return rc;
			trace_msm_vidc_perf_clock_scale(cl->name, freq);
			dprintk(VIDC_PROF, "Scaling clock %s to %u\n",
					cl->name, freq);
		}
	}
	return 0;
}

 

 类似资料: