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

Commit 6d5b2a79 authored by Camera Software Integration's avatar Camera Software Integration Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: camera: common: Add sysfs support for bw override" into camera-kernel.lnx.4.0

parents 85ac759b 2e6a2419
Loading
Loading
Loading
Loading
+84 −0
Original line number Diff line number Diff line
@@ -13,10 +13,63 @@
#include "cam_cpas_hw.h"
#include "cam_cpas_hw_intf.h"
#include "cam_cpas_soc.h"
#include "cam_req_mgr_dev.h"

static uint cam_min_camnoc_ib_bw;
module_param(cam_min_camnoc_ib_bw, uint, 0644);

static void cam_cpas_process_bw_overrides(
	struct cam_cpas_bus_client *bus_client, uint64_t *ab, uint64_t *ib,
	const struct cam_cpas_debug_settings *cpas_settings)
{
	uint64_t curr_ab = *ab;
	uint64_t curr_ib = *ib;
	size_t name_len = strlen(bus_client->common_data.name);

	if (!cpas_settings) {
		CAM_ERR(CAM_CPAS, "Invalid cpas debug settings");
		return;
	}

	if (strnstr(bus_client->common_data.name, "cam_hf_0", name_len)) {
		if (cpas_settings->mnoc_hf_0_ab_bw)
			*ab = cpas_settings->mnoc_hf_0_ab_bw;
		if (cpas_settings->mnoc_hf_0_ib_bw)
			*ib = cpas_settings->mnoc_hf_0_ib_bw;
	} else if (strnstr(bus_client->common_data.name, "cam_hf_1",
		name_len)) {
		if (cpas_settings->mnoc_hf_1_ab_bw)
			*ab = cpas_settings->mnoc_hf_1_ab_bw;
		if (cpas_settings->mnoc_hf_0_ib_bw)
			*ib = cpas_settings->mnoc_hf_1_ib_bw;
	} else if (strnstr(bus_client->common_data.name, "cam_sf_0",
		name_len)) {
		if (cpas_settings->mnoc_sf_0_ab_bw)
			*ab = cpas_settings->mnoc_sf_0_ab_bw;
		if (cpas_settings->mnoc_sf_0_ib_bw)
			*ib = cpas_settings->mnoc_sf_0_ib_bw;
	} else if (strnstr(bus_client->common_data.name, "cam_sf_1",
		name_len)) {
		if (cpas_settings->mnoc_sf_1_ab_bw)
			*ab = cpas_settings->mnoc_sf_1_ab_bw;
		if (cpas_settings->mnoc_sf_1_ib_bw)
			*ib = cpas_settings->mnoc_sf_1_ib_bw;
	} else if (strnstr(bus_client->common_data.name, "cam_sf_icp",
		name_len)) {
		if (cpas_settings->mnoc_sf_icp_ab_bw)
			*ab = cpas_settings->mnoc_sf_icp_ab_bw;
		if (cpas_settings->mnoc_sf_icp_ib_bw)
			*ib = cpas_settings->mnoc_sf_icp_ib_bw;
	} else {
		CAM_ERR(CAM_CPAS, "unknown mnoc port: %s, bw override failed",
			bus_client->common_data.name);
		return;
	}

	CAM_INFO(CAM_CPAS,
		"Overriding mnoc bw for: %s with ab: %llu, ib: %llu, curr_ab: %llu, curr_ib: %llu",
		bus_client->common_data.name, *ab, *ib, curr_ab, curr_ib);
}

int cam_cpas_util_reg_update(struct cam_hw_info *cpas_hw,
	enum cam_cpas_reg_base reg_base, struct cam_cpas_reg *reg_info)
@@ -85,6 +138,7 @@ static int cam_cpas_util_vote_bus_client_bw(
{
	int rc = 0;
	uint64_t min_camnoc_ib_bw = CAM_CPAS_AXI_MIN_CAMNOC_IB_BW;
	const struct camera_debug_settings *cam_debug = NULL;

	if (!bus_client->valid) {
		CAM_ERR(CAM_CPAS, "bus client: %s not valid",
@@ -116,6 +170,21 @@ static int cam_cpas_util_vote_bus_client_bw(
			ib = CAM_CPAS_AXI_MIN_MNOC_IB_BW;
	}

	cam_debug = cam_debug_get_settings();

	if (cam_debug && (cam_debug->cpas_settings.mnoc_hf_0_ab_bw ||
		cam_debug->cpas_settings.mnoc_hf_0_ib_bw ||
		cam_debug->cpas_settings.mnoc_hf_1_ab_bw ||
		cam_debug->cpas_settings.mnoc_hf_1_ib_bw ||
		cam_debug->cpas_settings.mnoc_sf_0_ab_bw ||
		cam_debug->cpas_settings.mnoc_sf_0_ib_bw ||
		cam_debug->cpas_settings.mnoc_sf_1_ab_bw ||
		cam_debug->cpas_settings.mnoc_sf_1_ib_bw ||
		cam_debug->cpas_settings.mnoc_sf_icp_ab_bw ||
		cam_debug->cpas_settings.mnoc_sf_icp_ib_bw))
		cam_cpas_process_bw_overrides(bus_client, &ab, &ib,
			&cam_debug->cpas_settings);

	rc = cam_soc_bus_client_update_bw(bus_client->soc_bus_client, ab, ib);
	if (rc) {
		CAM_ERR(CAM_CPAS,
@@ -376,6 +445,8 @@ static int cam_cpas_util_set_camnoc_axi_clk_rate(
	struct cam_cpas *cpas_core = (struct cam_cpas *) cpas_hw->core_info;
	struct cam_cpas_tree_node *tree_node = NULL;
	int rc = 0, i = 0;
	const struct camera_debug_settings *cam_debug = NULL;


	CAM_DBG(CAM_CPAS, "control_camnoc_axi_clk=%d",
		soc_private->control_camnoc_axi_clk);
@@ -415,6 +486,19 @@ static int cam_cpas_util_set_camnoc_axi_clk_rate(
			soc_private->camnoc_axi_min_ib_bw))
			required_camnoc_bw = soc_private->camnoc_axi_min_ib_bw;

		cam_debug = cam_debug_get_settings();
		if (cam_debug && cam_debug->cpas_settings.camnoc_bw) {
			if (cam_debug->cpas_settings.camnoc_bw <
				soc_private->camnoc_bus_width)
				required_camnoc_bw =
					soc_private->camnoc_bus_width;
			else
				required_camnoc_bw =
					cam_debug->cpas_settings.camnoc_bw;
			CAM_INFO(CAM_CPAS, "Overriding camnoc bw: %llu",
				required_camnoc_bw);
		}

		intermediate_result = required_camnoc_bw;
		do_div(intermediate_result, soc_private->camnoc_bus_width);
		clk_rate = intermediate_result;
+13 −0
Original line number Diff line number Diff line
@@ -25,12 +25,16 @@
#include "cam_debug_util.h"
#include "cam_common_util.h"
#include "cam_compat.h"
#include "cam_cpas_hw.h"

#define CAM_REQ_MGR_EVENT_MAX 30

static struct cam_req_mgr_device g_dev;
struct kmem_cache *g_cam_req_mgr_timer_cachep;

static struct device_attribute camera_debug_sysfs_attr =
	__ATTR(debug_node, 0600, NULL, cam_debug_sysfs_node_store);

static int cam_media_device_setup(struct device *dev)
{
	int rc;
@@ -810,9 +814,17 @@ static int cam_req_mgr_component_master_bind(struct device *dev)
	}

	CAM_INFO(CAM_CRM, "All camera components bound successfully");
	rc = sysfs_create_file(&dev->kobj, &camera_debug_sysfs_attr.attr);
	if (rc < 0) {
		CAM_ERR(CAM_CPAS,
			"Failed to create debug attribute, rc=%d\n", rc);
		goto sysfs_fail;
	}

	return rc;

sysfs_fail:
	sysfs_remove_file(&dev->kobj, &camera_debug_sysfs_attr.attr);
req_mgr_device_deinit:
	cam_req_mgr_core_device_deinit();
req_mgr_core_fail:
@@ -835,6 +847,7 @@ static void cam_req_mgr_component_master_unbind(struct device *dev)
	component_unbind_all(dev, NULL);

	/* Now proceed with unbinding master */
	sysfs_remove_file(&dev->kobj, &camera_debug_sysfs_attr.attr);
	cam_req_mgr_core_device_deinit();
	cam_req_mgr_util_deinit();
	cam_media_device_cleanup();
+103 −0
Original line number Diff line number Diff line
@@ -4,12 +4,115 @@
 */

#include <linux/io.h>
#include <linux/slab.h>
#include <linux/module.h>

#include "cam_debug_util.h"

static uint debug_mdl;
module_param(debug_mdl, uint, 0644);
struct camera_debug_settings cam_debug;

const struct camera_debug_settings *cam_debug_get_settings()
{
	return &cam_debug;
}

static int cam_debug_parse_cpas_settings(const char *setting, u64 value)
{
	if (!strcmp(setting, "camnoc_bw")) {
		cam_debug.cpas_settings.camnoc_bw = value;
	} else if (!strcmp(setting, "mnoc_hf_0_ab_bw")) {
		cam_debug.cpas_settings.mnoc_hf_0_ab_bw = value;
	} else if (!strcmp(setting, "mnoc_hf_0_ib_bw")) {
		cam_debug.cpas_settings.mnoc_hf_0_ib_bw = value;
	} else if (!strcmp(setting, "mnoc_hf_1_ab_bw")) {
		cam_debug.cpas_settings.mnoc_hf_1_ab_bw = value;
	} else if (!strcmp(setting, "mnoc_hf_1_ib_bw")) {
		cam_debug.cpas_settings.mnoc_hf_1_ib_bw = value;
	} else if (!strcmp(setting, "mnoc_sf_0_ab_bw")) {
		cam_debug.cpas_settings.mnoc_sf_0_ab_bw = value;
	} else if (!strcmp(setting, "mnoc_sf_0_ib_bw")) {
		cam_debug.cpas_settings.mnoc_sf_0_ib_bw = value;
	} else if (!strcmp(setting, "mnoc_sf_1_ab_bw")) {
		cam_debug.cpas_settings.mnoc_sf_1_ab_bw = value;
	} else if (!strcmp(setting, "mnoc_sf_1_ib_bw")) {
		cam_debug.cpas_settings.mnoc_sf_1_ib_bw = value;
	} else if (!strcmp(setting, "mnoc_sf_icp_ab_bw")) {
		cam_debug.cpas_settings.mnoc_sf_icp_ab_bw = value;
	} else if (!strcmp(setting, "mnoc_sf_icp_ib_bw")) {
		cam_debug.cpas_settings.mnoc_sf_icp_ib_bw = value;
	} else {
		CAM_ERR(CAM_UTIL, "Unsupported cpas sysfs entry");
		return -EINVAL;
	}

	return 0;
}

ssize_t cam_debug_sysfs_node_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
	int rc = 0;
	char *local_buf = NULL, *local_buf_temp = NULL;
	char *driver;
	char *setting = NULL;
	char *value_str = NULL;
	u64 value;

	CAM_INFO(CAM_UTIL, "Sysfs debug attr name:[%s] buf:[%s] bytes:[%d]",
		attr->attr.name, buf, count);
	local_buf = kmemdup(buf, (count + sizeof(char)), GFP_KERNEL);
	local_buf_temp = local_buf;
	driver = strsep(&local_buf, "#");
	if (!driver) {
		CAM_ERR(CAM_UTIL,
			"Invalid input driver name buf:[%s], count:%d",
			buf, count);
		goto error;
	}

	setting = strsep(&local_buf, "=");
	if (!setting) {
		CAM_ERR(CAM_UTIL, "Invalid input setting buf:[%s], count:%d",
			buf, count);
		goto error;
	}

	value_str = strsep(&local_buf, "=");
	if (!value_str) {
		CAM_ERR(CAM_UTIL, "Invalid input value buf:[%s], count:%d",
			buf, count);
		goto error;
	}

	rc = kstrtou64(value_str, 0, &value);
	if (rc < 0) {
		CAM_ERR(CAM_UTIL, "Error converting value:[%s], buf:[%s]",
			value_str, buf);
		goto error;
	}

	CAM_INFO(CAM_UTIL,
		"Processing sysfs store for driver:[%s], setting:[%s], value:[%llu]",
		driver, setting, value);

	if (!strcmp(driver, "cpas")) {
		rc = cam_debug_parse_cpas_settings(setting, value);
		if (rc)
			goto error;
	} else {
		CAM_ERR(CAM_UTIL, "Unsupported driver in camera debug node");
		goto error;
	}

	kfree(local_buf_temp);
	return count;

error:
	kfree(local_buf_temp);
	return -EPERM;
}

const char *cam_get_module_name(unsigned int module_id)
{
+41 −0
Original line number Diff line number Diff line
@@ -6,6 +6,8 @@
#ifndef _CAM_DEBUG_UTIL_H_
#define _CAM_DEBUG_UTIL_H_

#include <linux/platform_device.h>

#define CAM_CDM        (1 << 0)
#define CAM_CORE       (1 << 1)
#define CAM_CPAS       (1 << 2)
@@ -44,6 +46,32 @@

#define STR_BUFFER_MAX_LENGTH  1024

/**
 * struct cam_cpas_debug_settings - Sysfs debug settings for cpas driver
 */
struct cam_cpas_debug_settings {
	uint64_t mnoc_hf_0_ab_bw;
	uint64_t mnoc_hf_0_ib_bw;
	uint64_t mnoc_hf_1_ab_bw;
	uint64_t mnoc_hf_1_ib_bw;
	uint64_t mnoc_sf_0_ab_bw;
	uint64_t mnoc_sf_0_ib_bw;
	uint64_t mnoc_sf_1_ab_bw;
	uint64_t mnoc_sf_1_ib_bw;
	uint64_t mnoc_sf_icp_ab_bw;
	uint64_t mnoc_sf_icp_ib_bw;
	uint64_t camnoc_bw;
};

/**
 * struct camera_debug_settings - Sysfs debug settings for camera
 *
 * @cpas_settings: Debug settings for cpas driver.
 */
struct camera_debug_settings {
	struct cam_cpas_debug_settings cpas_settings;
};

/*
 *  cam_debug_log()
 *
@@ -211,4 +239,17 @@ const char *cam_get_module_name(unsigned int module_id);
				__LINE__, ##args);                         \
	})

/**
 * @brief : API to get camera debug settings
 * @return const struct camera_debug_settings pointer.
 */
const struct camera_debug_settings *cam_debug_get_settings(void);

/**
 * @brief : API to parse and store input from sysfs debug node
 * @return Number of bytes read from buffer on success, or -EPERM on error.
 */
ssize_t cam_debug_sysfs_node_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count);

#endif /* _CAM_DEBUG_UTIL_H_ */