msm: camera: utils: Add support bypass clock/regulator/icc wrapper

Sometimes need to avoid access clock/regulator/icc api, this change
add support bypass clock/regulator/icc wrapper through enable
some debugfs parameters and devicetree.

CRs-Fixed: 3445248
Change-Id: I0546975bf063625b39b771c776813e7dbff84e06
Signed-off-by: zhuo <quic_zhuo@quicinc.com>
This commit is contained in:
zhuo
2023-03-09 16:05:19 +08:00
committed by Camera Software Integration
parent 27216cc09b
commit a6ef23e7e5
13 changed files with 446 additions and 71 deletions

View File

@@ -96,7 +96,7 @@ int cam_bps_transfer_gdsc_control(struct cam_hw_soc_info *soc_info)
int rc;
for (i = 0; i < soc_info->num_rgltr; i++) {
rc = regulator_set_mode(soc_info->rgltr[i],
rc = cam_wrapper_regulator_set_mode(soc_info->rgltr[i],
REGULATOR_MODE_FAST);
if (rc) {
CAM_ERR(CAM_ICP, "Regulator set mode %s failed",
@@ -109,7 +109,7 @@ int cam_bps_transfer_gdsc_control(struct cam_hw_soc_info *soc_info)
rgltr_set_mode_failed:
for (i = i - 1; i >= 0; i--)
if (soc_info->rgltr[i])
regulator_set_mode(soc_info->rgltr[i],
cam_wrapper_regulator_set_mode(soc_info->rgltr[i],
REGULATOR_MODE_NORMAL);
return rc;
@@ -121,7 +121,7 @@ int cam_bps_get_gdsc_control(struct cam_hw_soc_info *soc_info)
int rc;
for (i = 0; i < soc_info->num_rgltr; i++) {
rc = regulator_set_mode(soc_info->rgltr[i],
rc = cam_wrapper_regulator_set_mode(soc_info->rgltr[i],
REGULATOR_MODE_NORMAL);
if (rc) {
CAM_ERR(CAM_ICP, "Regulator set mode %s failed",
@@ -134,7 +134,7 @@ int cam_bps_get_gdsc_control(struct cam_hw_soc_info *soc_info)
rgltr_set_mode_failed:
for (i = i - 1; i >= 0; i--)
if (soc_info->rgltr[i])
regulator_set_mode(soc_info->rgltr[i],
cam_wrapper_regulator_set_mode(soc_info->rgltr[i],
REGULATOR_MODE_FAST);
return rc;

View File

@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/slab.h>
@@ -257,7 +257,7 @@ int cam_icp_v1_init_hw(void *device_priv, void *args,
if (send_freq_info) {
int32_t clk_rate = 0;
clk_rate = clk_get_rate(soc_info->clk[soc_info->src_clk_idx]);
clk_rate = cam_wrapper_clk_get_rate(soc_info->clk[soc_info->src_clk_idx]);
hfi_send_freq_info(core_info->hfi_handle, clk_rate);
}
}

View File

@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/of_address.h>
@@ -244,7 +244,8 @@ int cam_icp_v2_hw_init(void *priv, void *args, uint32_t arg_size)
if (send_freq_info) {
int32_t clk_rate = 0;
clk_rate = clk_get_rate(icp_v2->soc_info.clk[icp_v2->soc_info.src_clk_idx]);
clk_rate = cam_wrapper_clk_get_rate(
icp_v2->soc_info.clk[icp_v2->soc_info.src_clk_idx]);
hfi_send_freq_info(core_info->hfi_handle, clk_rate);
}
}

View File

@@ -20,7 +20,7 @@ int cam_ipe_transfer_gdsc_control(struct cam_hw_soc_info *soc_info)
int rc;
for (i = 0; i < soc_info->num_rgltr; i++) {
rc = regulator_set_mode(soc_info->rgltr[i],
rc = cam_wrapper_regulator_set_mode(soc_info->rgltr[i],
REGULATOR_MODE_FAST);
if (rc) {
CAM_ERR(CAM_ICP, "Regulator set mode %s failed",
@@ -33,7 +33,7 @@ int cam_ipe_transfer_gdsc_control(struct cam_hw_soc_info *soc_info)
rgltr_set_mode_failed:
for (i = i - 1; i >= 0; i--)
if (soc_info->rgltr[i])
regulator_set_mode(soc_info->rgltr[i],
cam_wrapper_regulator_set_mode(soc_info->rgltr[i],
REGULATOR_MODE_NORMAL);
return rc;
@@ -45,7 +45,7 @@ int cam_ipe_get_gdsc_control(struct cam_hw_soc_info *soc_info)
int rc;
for (i = 0; i < soc_info->num_rgltr; i++) {
rc = regulator_set_mode(soc_info->rgltr[i],
rc = cam_wrapper_regulator_set_mode(soc_info->rgltr[i],
REGULATOR_MODE_NORMAL);
if (rc) {
CAM_ERR(CAM_ICP, "Regulator set mode %s failed",
@@ -58,7 +58,7 @@ int cam_ipe_get_gdsc_control(struct cam_hw_soc_info *soc_info)
rgltr_set_mode_failed:
for (i = i - 1; i >= 0; i--)
if (soc_info->rgltr[i])
regulator_set_mode(soc_info->rgltr[i],
cam_wrapper_regulator_set_mode(soc_info->rgltr[i],
REGULATOR_MODE_FAST);
return rc;

View File

@@ -96,7 +96,7 @@ static inline int cam_ofe_set_regulators_mode(struct cam_hw_soc_info *soc_info,
int i, rc;
for (i = 0; i < soc_info->num_rgltr; i++) {
rc = regulator_set_mode(soc_info->rgltr[i], mode);
rc = cam_wrapper_regulator_set_mode(soc_info->rgltr[i], mode);
if (rc) {
CAM_ERR(CAM_ICP, "Regulator set mode %s failed",
soc_info->rgltr_name[i]);
@@ -108,7 +108,7 @@ static inline int cam_ofe_set_regulators_mode(struct cam_hw_soc_info *soc_info,
rgltr_set_mode_failed:
for (i = i - 1; i >= 0; i--) {
if (soc_info->rgltr[i])
regulator_set_mode(soc_info->rgltr[i],
cam_wrapper_regulator_set_mode(soc_info->rgltr[i],
(mode == REGULATOR_MODE_NORMAL ?
REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL));
}

View File

@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/module.h>
@@ -1088,6 +1088,8 @@ static int cam_req_mgr_probe(struct platform_device *pdev)
struct component_match *match_list = NULL;
struct device *dev = &pdev->dev;
struct device_node *np = NULL;
uint32_t cam_bypass_driver = 0;
struct device_node *of_node = NULL;
for (i = 0; i < ARRAY_SIZE(cam_component_i2c_drivers); i++) {
while ((np = of_find_compatible_node(np, NULL,
@@ -1131,6 +1133,16 @@ static int cam_req_mgr_probe(struct platform_device *pdev)
goto end;
}
of_node = dev->of_node;
rc = of_property_read_u32(of_node, "cam-bypass-driver",
&cam_bypass_driver);
if (!rc) {
cam_soc_util_set_bypass_drivers(cam_bypass_driver);
} else {
CAM_INFO(CAM_CRM, "bypass driver parameter not found");
rc = 0;
}
end:
of_node_put(np);
return rc;

View File

@@ -1983,7 +1983,7 @@ int cam_sensor_bob_pwm_mode_switch(struct cam_hw_soc_info *soc_info,
(flag == true) ? soc_info->rgltr_op_mode[bob_reg_idx] : 0;
if (soc_info->rgltr[bob_reg_idx] != NULL) {
rc = regulator_set_load(soc_info->rgltr[bob_reg_idx],
rc = cam_wrapper_regulator_set_load(soc_info->rgltr[bob_reg_idx],
op_current);
if (rc)
CAM_WARN(CAM_SENSOR_UTIL,

View File

@@ -25,6 +25,9 @@ module_param(debug_priority, uint, 0644);
uint debug_drv;
module_param(debug_drv, uint, 0644);
uint debug_bypass_drivers;
module_param(debug_bypass_drivers, uint, 0644);
struct camera_debug_settings cam_debug;
struct dentry *cam_debugfs_root;

View File

@@ -7,6 +7,7 @@
#ifndef _CAM_DEBUG_UTIL_H_
#define _CAM_DEBUG_UTIL_H_
#include <dt-bindings/msm-camera.h>
#include <linux/platform_device.h>
#include "cam_presil_hw_access.h"
#include "cam_trace.h"
@@ -15,10 +16,13 @@ extern unsigned long long debug_mdl;
extern unsigned int debug_type;
extern unsigned int debug_priority;
extern unsigned int debug_drv;
extern unsigned int debug_bypass_drivers;
#define CAM_IS_NULL_TO_STR(ptr) ((ptr) ? "Non-NULL" : "NULL")
#define CAM_LOG_BUF_LEN 512
#define BYPASS_VALUE 0xDEADBEEF
#define DEFAULT_CLK_VALUE 19200000
/* Module IDs used for debug logging */
enum cam_debug_module_id {

View File

@@ -1,13 +1,56 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/interconnect.h>
#include <dt-bindings/interconnect/qcom,icc.h>
#include "cam_soc_bus.h"
static inline struct icc_path *cam_wrapper_icc_get(struct device *dev,
const int src_id, const int dst_id)
{
if (debug_bypass_drivers & CAM_BYPASS_ICC) {
CAM_WARN(CAM_UTIL, "Bypass icc get for %d %d", src_id, dst_id);
return (struct icc_path *)BYPASS_VALUE;
}
return icc_get(dev, src_id, dst_id);
}
static inline void cam_wrapper_icc_put(struct icc_path *path)
{
if (debug_bypass_drivers & CAM_BYPASS_ICC) {
CAM_WARN(CAM_UTIL, "Bypass icc put");
return;
}
return icc_put(path);
}
static inline int cam_wrapper_icc_set_bw(struct icc_path *path,
u32 avg_bw, u32 peak_bw)
{
if (debug_bypass_drivers & CAM_BYPASS_ICC) {
CAM_WARN(CAM_UTIL, "Bypass icc set bw");
return 0;
}
return icc_set_bw(path, avg_bw, peak_bw);
}
static inline void cam_wrapper_icc_set_tag(struct icc_path *path,
u32 tag)
{
if (debug_bypass_drivers & CAM_BYPASS_ICC) {
CAM_WARN(CAM_UTIL, "Bypass icc set tag");
return;
}
icc_set_tag(path, tag);
}
/**
* struct cam_soc_bus_client_data : Bus client data
*
@@ -52,7 +95,9 @@ int cam_soc_bus_client_update_request(void *client, unsigned int idx)
CAM_DBG(CAM_PERF, "Bus client=[%s] index[%d] ab[%llu] ib[%llu]",
bus_client->common_data->name, idx, ab, ib);
rc = icc_set_bw(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_HLOS], Bps_to_icc(ab),
rc = cam_wrapper_icc_set_bw(
bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_HLOS],
Bps_to_icc(ab),
Bps_to_icc(ib));
if (rc) {
CAM_ERR(CAM_UTIL,
@@ -77,7 +122,8 @@ int cam_soc_bus_client_update_bw(void *client, uint64_t ab, uint64_t ib,
CAM_DBG(CAM_PERF, "Bus client=[%s] [%s] :ab[%llu] ib[%llu]",
bus_client->common_data->name, cam_soc_bus_path_data_to_str(bus_path_data),
ab, ib);
rc = icc_set_bw(bus_client_data->icc_data[bus_path_data], Bps_to_icc(ab),
rc = cam_wrapper_icc_set_bw(
bus_client_data->icc_data[bus_path_data], Bps_to_icc(ab),
Bps_to_icc(ib));
if (rc) {
CAM_ERR(CAM_UTIL, "Update request failed, client[%s]",
@@ -118,7 +164,8 @@ int cam_soc_bus_client_register(struct platform_device *pdev,
bus_client->client_data = bus_client_data;
bus_client->common_data = common_data;
if (bus_client->common_data->is_drv_port) {
bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_HIGH] = icc_get(&pdev->dev,
bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_HIGH] =
cam_wrapper_icc_get(&pdev->dev,
bus_client->common_data->src_id, bus_client->common_data->dst_id);
if (IS_ERR_OR_NULL(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_HIGH])) {
CAM_ERR(CAM_UTIL,
@@ -129,7 +176,8 @@ int cam_soc_bus_client_register(struct platform_device *pdev,
goto error;
}
bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_LOW] = icc_get(&pdev->dev,
bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_LOW] =
cam_wrapper_icc_get(&pdev->dev,
bus_client->common_data->src_id, bus_client->common_data->dst_id);
if (IS_ERR_OR_NULL(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_LOW])) {
CAM_ERR(CAM_UTIL,
@@ -141,26 +189,31 @@ int cam_soc_bus_client_register(struct platform_device *pdev,
}
/* Set appropriate tags for HIGH and LOW vote paths */
icc_set_tag(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_HIGH],
cam_wrapper_icc_set_tag(
bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_HIGH],
QCOM_ICC_TAG_ACTIVE_ONLY);
icc_set_tag(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_LOW],
cam_wrapper_icc_set_tag(
bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_LOW],
QCOM_ICC_TAG_SLEEP);
rc = icc_set_bw(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_HIGH], 0, 0);
rc = cam_wrapper_icc_set_bw(
bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_HIGH], 0, 0);
if (rc) {
CAM_ERR(CAM_UTIL, "Bus client[%s] update request failed, rc = %d",
bus_client->common_data->name, rc);
goto fail_unregister_client;
}
rc = icc_set_bw(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_LOW], 0, 0);
rc = cam_wrapper_icc_set_bw(
bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_LOW], 0, 0);
if (rc) {
CAM_ERR(CAM_UTIL, "Bus client[%s] update request failed, rc = %d",
bus_client->common_data->name, rc);
goto fail_unregister_client;
}
} else {
bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_HLOS] = icc_get(&pdev->dev,
bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_HLOS] =
cam_wrapper_icc_get(&pdev->dev,
bus_client->common_data->src_id, bus_client->common_data->dst_id);
if (IS_ERR_OR_NULL(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_HLOS])) {
CAM_ERR(CAM_UTIL, "failed to register HLOS bus client");
@@ -168,7 +221,8 @@ int cam_soc_bus_client_register(struct platform_device *pdev,
goto error;
}
rc = icc_set_bw(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_HLOS], 0, 0);
rc = cam_wrapper_icc_set_bw(
bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_HLOS], 0, 0);
if (rc) {
CAM_ERR(CAM_UTIL, "Bus client[%s] update request failed, rc = %d",
bus_client->common_data->name, rc);
@@ -185,10 +239,13 @@ int cam_soc_bus_client_register(struct platform_device *pdev,
fail_unregister_client:
if (bus_client->common_data->is_drv_port) {
icc_put(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_HIGH]);
icc_put(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_LOW]);
cam_wrapper_icc_put(
bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_HIGH]);
cam_wrapper_icc_put(
bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_LOW]);
} else {
icc_put(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_HLOS]);
cam_wrapper_icc_put(
bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_HLOS]);
}
error:
@@ -209,10 +266,13 @@ void cam_soc_bus_client_unregister(void **client)
(struct cam_soc_bus_client_data *) bus_client->client_data;
if (bus_client->common_data->is_drv_port) {
icc_put(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_HIGH]);
icc_put(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_LOW]);
cam_wrapper_icc_put(
bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_HIGH]);
cam_wrapper_icc_put(
bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_LOW]);
} else {
icc_put(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_HLOS]);
cam_wrapper_icc_put(
bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_HLOS]);
}
kfree(bus_client_data);

View File

@@ -97,10 +97,233 @@ static LIST_HEAD(wrapper_clk_list);
const struct device *cam_cesta_crm_dev;
#if IS_ENABLED(CONFIG_QCOM_CRM)
static inline const struct device *cam_wrapper_crm_get_device(
const char *name)
{
if (debug_bypass_drivers & CAM_BYPASS_CESTA) {
CAM_WARN(CAM_UTIL, "Bypass crm get device");
return (const struct device *)BYPASS_VALUE;
}
return crm_get_device(name);
}
static inline int cam_wrapper_crm_write_pwr_states(const struct device *dev,
u32 drv_id)
{
if (debug_bypass_drivers & CAM_BYPASS_CESTA) {
CAM_WARN(CAM_UTIL, "Bypass crm write pwr states");
return 0;
}
return crm_write_pwr_states(cam_cesta_crm_dev, drv_id);
}
#endif
#if IS_ENABLED(CONFIG_QCOM_CRM) && IS_ENABLED(CONFIG_SPECTRA_USE_CLK_CRM_API)
static inline int cam_wrapper_qcom_clk_crm_set_rate(struct clk *clk,
enum crm_drv_type client_type, u32 client_idx,
u32 pwr_st, unsigned long rate)
{
if (debug_bypass_drivers & CAM_BYPASS_CESTA) {
CAM_WARN(CAM_UTIL, "Bypass qcom clk crm set rate");
return 0;
}
return qcom_clk_crm_set_rate(clk, client_type, client_idx, pwr_st, rate);
}
#endif
static inline int cam_wrapper_clk_set_rate(struct clk *clk, unsigned long rate)
{
if (debug_bypass_drivers & CAM_BYPASS_CLKS) {
CAM_WARN(CAM_UTIL, "Bypass clk set rate");
return 0;
}
return clk_set_rate(clk, rate);
}
static inline long cam_wrapper_clk_round_rate(struct clk *clk, unsigned long rate)
{
if (debug_bypass_drivers & CAM_BYPASS_CLKS) {
CAM_WARN(CAM_UTIL, "Bypass clk round rate");
return rate;
}
return clk_round_rate(clk, rate);
}
inline unsigned long cam_wrapper_clk_get_rate(struct clk *clk)
{
if (debug_bypass_drivers & CAM_BYPASS_CLKS) {
CAM_WARN(CAM_UTIL, "Bypass clk get rate");
return DEFAULT_CLK_VALUE;
}
return clk_get_rate(clk);
}
static inline struct clk *cam_wrapper_clk_get(struct device *dev, const char *id)
{
if (debug_bypass_drivers & CAM_BYPASS_CLKS) {
CAM_WARN(CAM_UTIL, "Bypass clk get");
return (struct clk *)BYPASS_VALUE;
}
return clk_get(dev, id);
}
static inline void cam_wrapper_clk_put(struct clk *clk)
{
if (debug_bypass_drivers & CAM_BYPASS_CLKS) {
CAM_WARN(CAM_UTIL, "Bypass clk put");
return;
}
clk_put(clk);
}
static inline struct clk *cam_wrapper_of_clk_get_from_provider(
struct of_phandle_args *clkspec)
{
if (debug_bypass_drivers & CAM_BYPASS_CLKS) {
CAM_WARN(CAM_UTIL, "Bypass of clk get from provider");
return (struct clk *)BYPASS_VALUE;
}
return of_clk_get_from_provider(clkspec);
}
static inline int cam_wrapper_clk_prepare_enable(struct clk *clk)
{
if (debug_bypass_drivers & CAM_BYPASS_CLKS) {
CAM_WARN(CAM_UTIL, "Bypass clk prepare enable");
return 0;
}
return clk_prepare_enable(clk);
}
static inline void cam_wrapper_clk_disable_unprepare(struct clk *clk)
{
if (debug_bypass_drivers & CAM_BYPASS_CLKS) {
CAM_WARN(CAM_UTIL, "Bypass clk disable unprepare");
return;
}
clk_disable_unprepare(clk);
}
static inline struct regulator *cam_wrapper_regulator_get(struct device *dev,
const char *id)
{
if (debug_bypass_drivers & CAM_BYPASS_RGLTR) {
CAM_WARN(CAM_UTIL, "Bypass regulator get");
return (struct regulator *)BYPASS_VALUE;
}
return regulator_get(dev, id);
}
static inline void cam_wrapper_regulator_put(struct regulator *regulator)
{
if (debug_bypass_drivers & CAM_BYPASS_RGLTR) {
CAM_WARN(CAM_UTIL, "Bypass regulator put");
return;
}
regulator_put(regulator);
}
static inline int cam_wrapper_regulator_disable(struct regulator *regulator)
{
if (debug_bypass_drivers & CAM_BYPASS_RGLTR) {
CAM_WARN(CAM_UTIL, "Bypass regulator disable");
return 0;
}
return regulator_disable(regulator);
}
static inline int cam_wrapper_regulator_enable(struct regulator *regulator)
{
if (debug_bypass_drivers & CAM_BYPASS_RGLTR) {
CAM_WARN(CAM_UTIL, "Bypass regulator enable");
return 0;
}
return regulator_enable(regulator);
}
static inline int cam_wrapper_regulator_set_voltage(
struct regulator *regulator, int min_uV, int max_uV)
{
if (debug_bypass_drivers & CAM_BYPASS_RGLTR) {
CAM_WARN(CAM_UTIL, "Bypass regulator set voltage");
return 0;
}
return regulator_set_voltage(regulator, min_uV, max_uV);
}
static inline int cam_wrapper_regulator_count_voltages(
struct regulator *regulator)
{
if (debug_bypass_drivers & CAM_BYPASS_RGLTR) {
CAM_WARN(CAM_UTIL, "Bypass regulator count voltages");
return 0;
}
return regulator_count_voltages(regulator);
}
inline int cam_wrapper_regulator_set_load(
struct regulator *regulator, int uA_load)
{
if (debug_bypass_drivers & CAM_BYPASS_RGLTR) {
CAM_WARN(CAM_UTIL, "Bypass regulator set load");
return 0;
}
return regulator_set_load(regulator, uA_load);
}
inline int cam_wrapper_regulator_set_mode(
struct regulator *regulator, unsigned int mode)
{
if (debug_bypass_drivers & CAM_BYPASS_RGLTR_MODE) {
CAM_WARN(CAM_UTIL, "Bypass regulator set mode");
return 0;
}
return regulator_set_mode(regulator, mode);
}
static inline int cam_wrapper_regulator_is_enabled(
struct regulator *regulator)
{
if (debug_bypass_drivers & CAM_BYPASS_RGLTR) {
CAM_WARN(CAM_UTIL, "Bypass regulator is enabled");
return 0;
}
return regulator_is_enabled(regulator);
}
inline void cam_soc_util_set_bypass_drivers(
uint32_t bypass_drivers)
{
debug_bypass_drivers = bypass_drivers;
CAM_INFO(CAM_UTIL, "bypass drivers %d", debug_bypass_drivers);
}
#if IS_ENABLED(CONFIG_QCOM_CRM)
inline int cam_soc_util_cesta_populate_crm_device(void)
{
cam_cesta_crm_dev = crm_get_device(CAM_CRM_DEV_IDENTIFIER);
cam_cesta_crm_dev = cam_wrapper_crm_get_device(CAM_CRM_DEV_IDENTIFIER);
if (!cam_cesta_crm_dev) {
CAM_ERR(CAM_UTIL, "Failed to get cesta crm dev for %s", CAM_CRM_DEV_IDENTIFIER);
return -ENODEV;
@@ -127,7 +350,7 @@ int cam_soc_util_cesta_channel_switch(uint32_t cesta_client_idx, const char *ide
CAM_DBG(CAM_PERF, "CESTA Channel switch : hw client idx %d identifier=%s",
cesta_client_idx, identifier);
rc = crm_write_pwr_states(cam_cesta_crm_dev, cesta_client_idx);
rc = cam_wrapper_crm_write_pwr_states(cam_cesta_crm_dev, cesta_client_idx);
if (rc) {
CAM_ERR(CAM_UTIL,
"Failed to trigger cesta channel switch cesta_client_idx: %u rc: %d",
@@ -183,7 +406,8 @@ static int cam_soc_util_set_cesta_clk_rate(struct cam_hw_soc_info *soc_info,
CAM_DBG(CAM_UTIL, "%s Requested clk rate [high low]: [%llu %llu] cesta_client_idx: %d",
soc_info->clk_name[src_clk_idx], high_val, low_val, cesta_client_idx);
rc = qcom_clk_crm_set_rate(clk, CRM_HW_DRV, cesta_client_idx, CRM_PWR_STATE1, high_val);
rc = cam_wrapper_qcom_clk_crm_set_rate(
clk, CRM_HW_DRV, cesta_client_idx, CRM_PWR_STATE1, high_val);
if (rc) {
CAM_ERR(CAM_UTIL,
"Failed in setting cesta high clk rate, client idx: %u pwr state: %u clk_val: %llu rc: %d",
@@ -191,7 +415,8 @@ static int cam_soc_util_set_cesta_clk_rate(struct cam_hw_soc_info *soc_info,
return rc;
}
rc = qcom_clk_crm_set_rate(clk, CRM_HW_DRV, cesta_client_idx, CRM_PWR_STATE0, low_val);
rc = cam_wrapper_qcom_clk_crm_set_rate(
clk, CRM_HW_DRV, cesta_client_idx, CRM_PWR_STATE0, low_val);
if (rc) {
CAM_ERR(CAM_UTIL,
"Failed in setting cesta low clk rate, client idx: %u pwr state: %u clk_val: %llu rc: %d",
@@ -270,6 +495,11 @@ int cam_soc_util_register_mmrm_client(
*mmrm_handle = (void *)NULL;
if (debug_bypass_drivers & CAM_BYPASS_CLKS) {
CAM_WARN(CAM_UTIL, "Bypass register mmrm client");
return 0;
}
if (!cam_is_mmrm_supported_on_current_chip())
return 0;
@@ -638,7 +868,7 @@ static int cam_soc_util_clk_wrapper_set_clk_rate(
if (!set_rate_finish && final_clk_rate &&
(final_clk_rate != wrapper_clk->curr_clk_rate)) {
rc = clk_set_rate(clk, final_clk_rate);
rc = cam_wrapper_clk_set_rate(clk, final_clk_rate);
if (rc) {
CAM_ERR(CAM_UTIL, "set_rate failed on clk %d",
wrapper_clk->clk_id);
@@ -667,7 +897,8 @@ int cam_soc_util_get_clk_level(struct cam_hw_soc_info *soc_info,
return -EINVAL;
}
clk_rate_round = clk_round_rate(soc_info->clk[clk_idx], clk_rate);
clk_rate_round = cam_wrapper_clk_round_rate(
soc_info->clk[clk_idx], clk_rate);
if (clk_rate_round < 0) {
CAM_ERR(CAM_UTIL, "round failed rc = %ld",
clk_rate_round);
@@ -675,6 +906,12 @@ int cam_soc_util_get_clk_level(struct cam_hw_soc_info *soc_info,
return -EINVAL;
}
if (debug_bypass_drivers & CAM_BYPASS_CLKS) {
CAM_WARN(CAM_UTIL, "Bypass get clk level");
*clk_lvl = CAM_NOMINAL_VOTE;
return 0;
}
for (i = 0; i < CAM_MAX_VOTE; i++) {
if ((soc_info->clk_level_valid[i]) &&
(soc_info->clk_rate[i][clk_idx] >=
@@ -1022,7 +1259,7 @@ long cam_soc_util_get_clk_round_rate(struct cam_hw_soc_info *soc_info,
return clk_rate;
}
return clk_round_rate(soc_info->clk[clk_index], clk_rate);
return cam_wrapper_clk_round_rate(soc_info->clk[clk_index], clk_rate);
}
/**
@@ -1059,7 +1296,7 @@ static int cam_soc_util_set_clk_rate(struct cam_hw_soc_info *soc_info,
if (!clk)
return 0;
if (clk_rate > 0) {
clk_rate_round = clk_round_rate(clk, clk_rate);
clk_rate_round = cam_wrapper_clk_round_rate(clk, clk_rate);
CAM_DBG(CAM_UTIL, "new_rate %ld", clk_rate_round);
if (clk_rate_round < 0) {
CAM_ERR(CAM_UTIL, "round failed for clock %s rc = %ld",
@@ -1068,10 +1305,10 @@ static int cam_soc_util_set_clk_rate(struct cam_hw_soc_info *soc_info,
}
set_rate = true;
} else if (clk_rate == INIT_RATE) {
clk_rate_round = clk_get_rate(clk);
clk_rate_round = cam_wrapper_clk_get_rate(clk);
CAM_DBG(CAM_UTIL, "init new_rate %ld", clk_rate_round);
if (clk_rate_round == 0) {
clk_rate_round = clk_round_rate(clk, 0);
clk_rate_round = cam_wrapper_clk_round_rate(clk, 0);
if (clk_rate_round <= 0) {
CAM_ERR(CAM_UTIL, "round rate failed on %s",
clk_name);
@@ -1120,7 +1357,7 @@ static int cam_soc_util_set_clk_rate(struct cam_hw_soc_info *soc_info,
}
if (!set_rate_finish) {
rc = clk_set_rate(clk, clk_rate_round);
rc = cam_wrapper_clk_set_rate(clk, clk_rate_round);
if (rc) {
CAM_ERR(CAM_UTIL, "set_rate failed on %s", clk_name);
return rc;
@@ -1251,7 +1488,7 @@ int cam_soc_util_put_optional_clk(struct cam_hw_soc_info *soc_info,
cam_soc_util_clk_wrapper_unregister_entry(
soc_info->optional_clk_id[clk_indx], soc_info);
clk_put(soc_info->optional_clk[clk_indx]);
cam_wrapper_clk_put(soc_info->optional_clk[clk_indx]);
soc_info->optional_clk[clk_indx] = NULL;
return 0;
@@ -1272,7 +1509,7 @@ static struct clk *cam_soc_util_option_clk_get(struct device_node *np,
if (rc)
return ERR_PTR(rc);
clk = of_clk_get_from_provider(&clkspec);
clk = cam_wrapper_of_clk_get_from_provider(&clkspec);
*clk_id = clkspec.args[0];
of_node_put(clkspec.np);
@@ -1385,7 +1622,7 @@ int cam_soc_util_get_option_clk_by_name(struct cam_hw_soc_info *soc_info,
return 0;
error:
clk_put(soc_info->optional_clk[index]);
cam_wrapper_clk_put(soc_info->optional_clk[index]);
soc_info->optional_clk_rate[index] = 0;
soc_info->optional_clk[index] = NULL;
*clk_index = -1;
@@ -1459,7 +1696,7 @@ int cam_soc_util_clk_enable(struct cam_hw_soc_info *soc_info, int cesta_client_i
}
CAM_DBG(CAM_UTIL, "[%s] : clk enable %s", soc_info->dev_name, clk_name);
rc = clk_prepare_enable(clk);
rc = cam_wrapper_clk_prepare_enable(clk);
if (rc) {
CAM_ERR(CAM_UTIL, "enable failed for %s: rc(%d)", clk_name, rc);
return rc;
@@ -1498,7 +1735,7 @@ int cam_soc_util_clk_disable(struct cam_hw_soc_info *soc_info, int cesta_client_
if (!clk)
return 0;
clk_disable_unprepare(clk);
cam_wrapper_clk_disable_unprepare(clk);
if ((clk_idx == soc_info->src_clk_idx) && soc_info->is_clk_drv_en &&
CAM_IS_VALID_CESTA_IDX(cesta_client_idx)) {
@@ -2425,7 +2662,7 @@ static int cam_soc_util_get_regulator(struct device *dev,
struct regulator **reg, const char *rgltr_name)
{
int rc = 0;
*reg = regulator_get(dev, rgltr_name);
*reg = cam_wrapper_regulator_get(dev, rgltr_name);
if (IS_ERR_OR_NULL(*reg)) {
rc = PTR_ERR(*reg);
rc = rc ? rc : -EINVAL;
@@ -2447,7 +2684,7 @@ int cam_soc_util_regulator_disable(struct regulator *rgltr,
return -EINVAL;
}
rc = regulator_disable(rgltr);
rc = cam_wrapper_regulator_disable(rgltr);
if (rc) {
CAM_ERR(CAM_UTIL, "%s regulator disable failed", rgltr_name);
return rc;
@@ -2459,9 +2696,9 @@ int cam_soc_util_regulator_disable(struct regulator *rgltr,
usleep_range(rgltr_delay_ms * 1000,
(rgltr_delay_ms * 1000) + 1000);
if (regulator_count_voltages(rgltr) > 0) {
regulator_set_load(rgltr, 0);
regulator_set_voltage(rgltr, 0, rgltr_max_volt);
if (cam_wrapper_regulator_count_voltages(rgltr) > 0) {
cam_wrapper_regulator_set_load(rgltr, 0);
cam_wrapper_regulator_set_voltage(rgltr, 0, rgltr_max_volt);
}
return rc;
@@ -2480,18 +2717,18 @@ int cam_soc_util_regulator_enable(struct regulator *rgltr,
return -EINVAL;
}
if (regulator_count_voltages(rgltr) > 0) {
if (cam_wrapper_regulator_count_voltages(rgltr) > 0) {
CAM_DBG(CAM_UTIL, "[%s] voltage min=%d, max=%d",
rgltr_name, rgltr_min_volt, rgltr_max_volt);
rc = regulator_set_voltage(
rc = cam_wrapper_regulator_set_voltage(
rgltr, rgltr_min_volt, rgltr_max_volt);
if (rc) {
CAM_ERR(CAM_UTIL, "%s set voltage failed", rgltr_name);
return rc;
}
rc = regulator_set_load(rgltr, rgltr_op_mode);
rc = cam_wrapper_regulator_set_load(rgltr, rgltr_op_mode);
if (rc) {
CAM_ERR(CAM_UTIL, "%s set optimum mode failed",
rgltr_name);
@@ -2499,7 +2736,7 @@ int cam_soc_util_regulator_enable(struct regulator *rgltr,
}
}
rc = regulator_enable(rgltr);
rc = cam_wrapper_regulator_enable(rgltr);
if (rc) {
CAM_ERR(CAM_UTIL, "%s regulator_enable failed", rgltr_name);
return rc;
@@ -2690,7 +2927,7 @@ static void cam_soc_util_regulator_disable_default(
soc_info->rgltr_delay[j]);
} else {
if (soc_info->rgltr[j])
regulator_disable(soc_info->rgltr[j]);
cam_wrapper_regulator_disable(soc_info->rgltr[j]);
}
}
}
@@ -2720,7 +2957,7 @@ static int cam_soc_util_regulator_enable_default(
soc_info->rgltr_delay[j]);
} else {
if (soc_info->rgltr[j])
rc = regulator_enable(soc_info->rgltr[j]);
rc = cam_wrapper_regulator_enable(soc_info->rgltr[j]);
}
if (rc) {
@@ -2743,7 +2980,7 @@ disable_rgltr:
soc_info->rgltr_delay[j]);
} else {
if (soc_info->rgltr[j])
regulator_disable(soc_info->rgltr[j]);
cam_wrapper_regulator_disable(soc_info->rgltr[j]);
}
}
@@ -2968,7 +3205,7 @@ int cam_soc_util_request_platform_resource(
/* Get Clock */
for (i = 0; i < soc_info->num_clk; i++) {
soc_info->clk[i] = clk_get(soc_info->dev,
soc_info->clk[i] = cam_wrapper_clk_get(soc_info->dev,
soc_info->clk_name[i]);
if (IS_ERR(soc_info->clk[i])) {
CAM_ERR(CAM_UTIL, "get failed for %s",
@@ -3000,7 +3237,7 @@ int cam_soc_util_request_platform_resource(
"Failed in registering shared clk Dev %s id %d",
soc_info->dev_name,
soc_info->clk_id[i]);
clk_put(soc_info->clk[i]);
cam_wrapper_clk_put(soc_info->clk[i]);
soc_info->clk[i] = NULL;
goto put_clk;
}
@@ -3015,7 +3252,7 @@ int cam_soc_util_request_platform_resource(
"Failed in register mmrm client Dev %s clk id %d",
soc_info->dev_name,
soc_info->clk_id[i]);
clk_put(soc_info->clk[i]);
cam_wrapper_clk_put(soc_info->clk[i]);
soc_info->clk[i] = NULL;
goto put_clk;
}
@@ -3052,7 +3289,7 @@ put_clk:
cam_soc_util_clk_wrapper_unregister_entry(
soc_info->clk_id[i], soc_info);
clk_put(soc_info->clk[i]);
cam_wrapper_clk_put(soc_info->clk[i]);
soc_info->clk[i] = NULL;
}
}
@@ -3070,8 +3307,8 @@ put_regulator:
i = soc_info->num_rgltr;
for (i = i - 1; i >= 0; i--) {
if (soc_info->rgltr[i]) {
regulator_disable(soc_info->rgltr[i]);
regulator_put(soc_info->rgltr[i]);
cam_wrapper_regulator_disable(soc_info->rgltr[i]);
cam_wrapper_regulator_put(soc_info->rgltr[i]);
soc_info->rgltr[i] = NULL;
}
}
@@ -3115,13 +3352,13 @@ int cam_soc_util_release_platform_resource(struct cam_hw_soc_info *soc_info)
soc_info->clk_name[i]);
continue;
}
clk_put(soc_info->clk[i]);
cam_wrapper_clk_put(soc_info->clk[i]);
soc_info->clk[i] = NULL;
}
for (i = soc_info->num_rgltr - 1; i >= 0; i--) {
if (soc_info->rgltr[i]) {
regulator_put(soc_info->rgltr[i]);
cam_wrapper_regulator_put(soc_info->rgltr[i]);
soc_info->rgltr[i] = NULL;
}
}
@@ -3961,7 +4198,7 @@ int cam_soc_util_print_clk_freq(struct cam_hw_soc_info *soc_info)
}
for (i = 0; i < soc_info->num_clk; i++) {
clk_rate = clk_get_rate(soc_info->clk[i]);
clk_rate = cam_wrapper_clk_get_rate(soc_info->clk[i]);
CAM_INFO(CAM_UTIL,
"[%s] idx = %d clk name = %s clk_rate=%lld",
@@ -4006,7 +4243,7 @@ int cam_soc_util_regulators_enabled(struct cam_hw_soc_info *soc_info)
for (j = 0; j < soc_info->num_rgltr; j++) {
if (soc_info->rgltr[j]) {
rc = regulator_is_enabled(soc_info->rgltr[j]);
rc = cam_wrapper_regulator_is_enabled(soc_info->rgltr[j]);
if (rc < 0) {
CAM_ERR(CAM_UTIL, "%s regulator_is_enabled failed",
soc_info->rgltr_name[j]);

View File

@@ -886,4 +886,55 @@ inline unsigned long cam_soc_util_get_applied_src_clk(
*/
const char *cam_soc_util_get_string_from_level(enum cam_vote_level level);
/**
* cam_wrapper_clk_get_rate()
*
* @brief: Wrapper for clk get rate
*
* @clk: Clock
*
* @return: Clock rate
*/
inline unsigned long cam_wrapper_clk_get_rate(struct clk *clk);
/**
* cam_wrapper_regulator_set_load()
*
* @brief: Wrapper for regulator set load
*
* @regulator: Regulator
*
* @uA_load: Load current
*
* @return: Success or failure
*/
inline int cam_wrapper_regulator_set_load(
struct regulator *regulator, int uA_load);
/**
* cam_wrapper_regulator_set_mode()
*
* @brief: Wrapper for regulator set mode
*
* @regulator: Regulator
*
* @mode: Mode
*
* @return: Success or failure
*/
inline int cam_wrapper_regulator_set_mode(
struct regulator *regulator, unsigned int mode);
/**
* cam_soc_util_set_bypass_drivers()
*
* @brief: Set bypass drivers
*
* @bypass_drivers: Bypass drivers
*
* @return: Void
*/
inline void cam_soc_util_set_bypass_drivers(
uint32_t bypass_drivers);
#endif /* _CAM_SOC_UTIL_H_ */

View File

@@ -142,4 +142,11 @@
#define CAM_CPAS_NON_SECURE_DOMAIN 0
#define CAM_CPAS_SECURE_DOMAIN 1
/* Debug bypass driver */
#define CAM_BYPASS_RGLTR 0x1
#define CAM_BYPASS_RGLTR_MODE 0x2
#define CAM_BYPASS_CLKS 0x4
#define CAM_BYPASS_CESTA 0x8
#define CAM_BYPASS_ICC 0x10
#endif