Merge "msm: camera: common: Add sysfs support for bw override" into camera-kernel.lnx.4.0
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

commit
6d5b2a796c
@@ -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;
|
||||
|
@@ -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();
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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_ */
|
||||
|
Reference in New Issue
Block a user