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

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

Merge "msm: cpp: Provide cpp clock frequency table to user-space"

parents 704807bf 833192e6
Loading
Loading
Loading
Loading
+43 −13
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@
#include <media/msmb_camera.h>
#include <media/msmb_generic_buf_mgr.h>
#include <media/msmb_pproc.h>
#include <linux/clk/msm-clk-provider.h>
#include "msm_cpp.h"
#include "msm_isp_util.h"
#include "msm_camera_io_util.h"
@@ -683,10 +684,33 @@ void msm_cpp_do_tasklet(unsigned long data)
	}
}

static void cpp_get_clk_freq_tbl(struct clk *clk, struct cpp_hw_info *hw_info)
{
	uint32_t count;
	signed long freq_tbl_entry = 0;

	if ((clk == NULL) || (hw_info == NULL) || (clk->ops == NULL) ||
		(clk->ops->list_rate == NULL)) {
		pr_err("Bad parameter\n");
		return;
	}

	for (count = 0; count < MAX_FREQ_TBL; count++) {
		freq_tbl_entry = clk->ops->list_rate(clk, count);
		if (freq_tbl_entry >= 0)
			hw_info->freq_tbl[count] = freq_tbl_entry;
		else
			break;
	}

	hw_info->freq_tbl_count = count;
}

static int cpp_init_hardware(struct cpp_device *cpp_dev)
{
	int rc = 0;
	uint32_t msm_micro_iface_idx;
	uint32_t msm_cpp_core_clk_idx;
	rc = msm_isp_init_bandwidth_mgr(ISP_CPP);
	if (rc < 0) {
		pr_err("%s: Bandwidth registration Failed!\n", __func__);
@@ -809,6 +833,9 @@ static int cpp_init_hardware(struct cpp_device *cpp_dev)
	pr_info("CPP HW Version: 0x%x\n", cpp_dev->hw_info.cpp_hw_version);
	cpp_dev->hw_info.cpp_hw_caps =
		msm_camera_io_r(cpp_dev->cpp_hw_base + 0x4);
	msm_cpp_core_clk_idx = get_clock_index("cpp_core_clk");
	cpp_get_clk_freq_tbl(cpp_dev->cpp_clk[msm_cpp_core_clk_idx],
		&cpp_dev->hw_info);
	pr_debug("CPP HW Caps: 0x%x\n", cpp_dev->hw_info.cpp_hw_caps);
	msm_camera_io_w(0x1, cpp_dev->vbif_base + 0x4);
	cpp_dev->taskletq_idx = 0;
@@ -1899,8 +1926,9 @@ long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd,
		break;
	}
	case VIDIOC_MSM_CPP_SET_CLOCK: {
		long clock_rate = 0;
		uint32_t msm_cpp_core_clk_idx;
		struct msm_cpp_clock_settings_t clock_settings;
		unsigned long clock_rate = 0;
		CPP_DBG("VIDIOC_MSM_CPP_SET_CLOCK\n");
		if (ioctl_ptr->len == 0) {
			pr_err("ioctl_ptr->len is 0\n");
@@ -1914,13 +1942,13 @@ long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd,
			return -EINVAL;
		}

		if (ioctl_ptr->len > sizeof(clock_rate)) {
		if (ioctl_ptr->len != sizeof(struct msm_cpp_clock_settings_t)) {
			pr_err("Not valid ioctl_ptr->len\n");
			mutex_unlock(&cpp_dev->mutex);
			return -EINVAL;
		}

		rc = (copy_from_user(&clock_rate,
		rc = (copy_from_user(&clock_settings,
			(void __user *)ioctl_ptr->ioctl_ptr,
			ioctl_ptr->len) ? -EFAULT : 0);
		if (rc) {
@@ -1929,27 +1957,29 @@ long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd,
			return -EINVAL;
		}

		if (clock_rate > 0) {
		if (clock_settings.clock_rate > 0) {
			msm_cpp_core_clk_idx = get_clock_index("cpp_core_clk");
			if (msm_cpp_core_clk_idx < 0) {
				pr_err(" Fail to get clock index\n");
				return -EINVAL;
			}
			clock_rate =
				clk_round_rate(cpp_dev->
					cpp_clk[msm_cpp_core_clk_idx],
					clock_rate);
			CPP_DBG("clk:%ld\n", clock_rate);
			clk_set_rate(cpp_dev->cpp_clk[msm_cpp_core_clk_idx],
				clock_rate);
			rc = msm_isp_update_bandwidth(ISP_CPP, clock_rate * 4,
				clock_rate * 6);
			rc = msm_isp_update_bandwidth(ISP_CPP,
				clock_settings.avg,
				clock_settings.inst);

			if (rc < 0) {
				pr_err("Bandwidth Set Failed!\n");
				msm_isp_update_bandwidth(ISP_CPP, 0, 0);
				mutex_unlock(&cpp_dev->mutex);
				return -EINVAL;
			}
			clock_rate = clk_round_rate(
				cpp_dev->cpp_clk[msm_cpp_core_clk_idx],
				clock_settings.clock_rate);
			if (clock_rate != clock_settings.clock_rate)
				pr_err("clock rate differ from settings\n");
			clk_set_rate(cpp_dev->cpp_clk[msm_cpp_core_clk_idx],
				clock_rate);
		}
		break;
	}
+6 −0
Original line number Diff line number Diff line
@@ -170,6 +170,12 @@ struct msm_cpp_work_t {
	struct cpp_device *cpp_dev;
};

struct msm_cpp_clock_settings_t {
	unsigned long clock_rate;
	uint64_t avg;
	uint64_t inst;
};

struct cpp_device {
	struct platform_device *pdev;
	struct msm_sd_subdev msm_sd;
+3 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#define MSM_CPP_MAX_NUM_PLANES 3
#define MSM_CPP_MAX_FRAME_LENGTH 1024
#define MSM_CPP_MAX_FW_NAME_LEN 32
#define MAX_FREQ_TBL 10

enum msm_cpp_frame_type {
	MSM_CPP_OFFLINE_FRAME,
@@ -171,6 +172,8 @@ struct msm_cpp_pop_stream_info_t {
struct cpp_hw_info {
	uint32_t cpp_hw_version;
	uint32_t cpp_hw_caps;
	unsigned long freq_tbl[MAX_FREQ_TBL];
	uint32_t freq_tbl_count;
};

struct msm_vpe_frame_strip_info {