
On chipsets having cesta hw block support, for cesta supported clks clk frequency can be changed during veritcal blanking based on CSID DRV events. For this to happen, camera clients need to setup high and low clock votes through hw clients. Use corresponding clk, crm APIs to setup high, low clk frquencies and do channel switch to apply newly set rates. Clients can also set clk frequency through sw client which will set the floor. This feature helps in saving power for usecases where vertical blanking is high such as Fast Shutter usecase. CRs-Fixed: 3294948 Change-Id: I1bcf650b439991a23b2a0f0f9a5162bdcd60dc64 Signed-off-by: Mukund Madhusudan Atre <quic_matre@quicinc.com> Signed-off-by: Pavan Kumar Chilamkurthi <quic_pchilamk@quicinc.com>
885 行
31 KiB
C
885 行
31 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/*
|
|
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
|
|
* Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
|
|
*/
|
|
|
|
#ifndef _CAM_SOC_UTIL_H_
|
|
#define _CAM_SOC_UTIL_H_
|
|
|
|
#include <linux/version.h>
|
|
#include <linux/types.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/clk.h>
|
|
#include <linux/interrupt.h>
|
|
#include <linux/io.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/i2c.h>
|
|
#include <linux/regulator/consumer.h>
|
|
#include <linux/debugfs.h>
|
|
#include <linux/of_fdt.h>
|
|
|
|
#include "cam_io_util.h"
|
|
#include <media/cam_defs.h>
|
|
|
|
#if IS_REACHABLE(CONFIG_MSM_MMRM)
|
|
#include <linux/soc/qcom/msm_mmrm.h>
|
|
#endif
|
|
|
|
#define NO_SET_RATE -1
|
|
#define INIT_RATE -2
|
|
|
|
/* maximum number of device block */
|
|
#define CAM_SOC_MAX_BLOCK 8
|
|
|
|
/* maximum number of device base */
|
|
#define CAM_SOC_MAX_BASE CAM_SOC_MAX_BLOCK
|
|
|
|
/* maximum number of device regulator */
|
|
#define CAM_SOC_MAX_REGULATOR 10
|
|
|
|
/* maximum number of device clock */
|
|
#define CAM_SOC_MAX_CLK 32
|
|
|
|
/* maximum number of optional device clock */
|
|
#define CAM_SOC_MAX_OPT_CLK 7
|
|
|
|
/* maximum number of pinctrl mapping */
|
|
#define CAM_SOC_MAX_PINCTRL_MAP 2
|
|
|
|
/* DDR device types */
|
|
#define DDR_TYPE_LPDDR4 6
|
|
#define DDR_TYPE_LPDDR4X 7
|
|
#define DDR_TYPE_LPDDR5 8
|
|
#define DDR_TYPE_LPDDR5X 9
|
|
|
|
/* Maximum length of tag while dumping */
|
|
#define CAM_SOC_HW_DUMP_TAG_MAX_LEN 32
|
|
|
|
/* Client index to be used to vote clk frequency through sw client */
|
|
#define CAM_CLK_SW_CLIENT_IDX -1
|
|
|
|
/**
|
|
* enum cam_vote_level - Enum for voting level
|
|
*
|
|
* @CAM_SUSPEND_VOTE : Suspend vote
|
|
* @CAM_MINSVS_VOTE : Min SVS vote
|
|
* @CAM_LOWSVS_VOTE : Low SVS vote
|
|
* @CAM_SVS_VOTE : SVS vote
|
|
* @CAM_SVSL1_VOTE : SVS Plus vote
|
|
* @CAM_NOMINAL_VOTE : Nominal vote
|
|
* @CAM_NOMINALL1_VOTE: Nominal plus vote
|
|
* @CAM_TURBO_VOTE : Turbo vote
|
|
* @CAM_MAX_VOTE : Max voting level, This is invalid level.
|
|
*/
|
|
enum cam_vote_level {
|
|
CAM_SUSPEND_VOTE,
|
|
CAM_MINSVS_VOTE,
|
|
CAM_LOWSVS_VOTE,
|
|
CAM_SVS_VOTE,
|
|
CAM_SVSL1_VOTE,
|
|
CAM_NOMINAL_VOTE,
|
|
CAM_NOMINALL1_VOTE,
|
|
CAM_TURBO_VOTE,
|
|
CAM_MAX_VOTE,
|
|
};
|
|
|
|
/* pinctrl states */
|
|
#define CAM_SOC_PINCTRL_STATE_SLEEP "cam_suspend"
|
|
#define CAM_SOC_PINCTRL_STATE_DEFAULT "cam_default"
|
|
|
|
#define CAM_CESTA_MAX_CLIENTS 3
|
|
|
|
/**
|
|
* struct cam_soc_util_hw_client_clk_rates: Information about HW client clock vote
|
|
*
|
|
* @high: HW client clock vote high value
|
|
* @low: HW client clock vote low value
|
|
**/
|
|
struct cam_soc_util_hw_client_clk_rates {
|
|
unsigned long high;
|
|
unsigned long low;
|
|
};
|
|
|
|
/**
|
|
* struct cam_soc_util_clk_rates: Information about clock vote for SW and HW clients
|
|
*
|
|
* @sw_client: SW client clock vote
|
|
* @hw_client: HW client clock vote
|
|
**/
|
|
struct cam_soc_util_clk_rates {
|
|
unsigned long sw_client;
|
|
struct cam_soc_util_hw_client_clk_rates hw_client[CAM_CESTA_MAX_CLIENTS];
|
|
};
|
|
|
|
/**
|
|
* struct cam_soc_reg_map: Information about the mapped register space
|
|
*
|
|
* @mem_base: Starting location of MAPPED register space
|
|
* @mem_cam_base: Starting offset of this register space compared
|
|
* to ENTIRE Camera register space
|
|
* @size: Size of register space
|
|
**/
|
|
struct cam_soc_reg_map {
|
|
void __iomem *mem_base;
|
|
uint32_t mem_cam_base;
|
|
resource_size_t size;
|
|
};
|
|
|
|
/**
|
|
* struct cam_soc_pinctrl_state: Information about pinctrl state
|
|
*
|
|
* @gpio_state_active: default pinctrl state
|
|
* @gpio_state_suspend: suspend state of pinctrl
|
|
* @is_active: to identify if pinctrl is in use.
|
|
**/
|
|
struct cam_soc_pinctrl_state {
|
|
struct pinctrl_state *gpio_state_active;
|
|
struct pinctrl_state *gpio_state_suspend;
|
|
bool is_active;
|
|
};
|
|
|
|
/**
|
|
* struct cam_soc_pinctrl_info: Information about pinctrl data
|
|
*
|
|
* @pinctrl: pintrl object
|
|
* @pctrl_state: pinctrl state montior map
|
|
**/
|
|
struct cam_soc_pinctrl_info {
|
|
struct pinctrl *pinctrl;
|
|
struct cam_soc_pinctrl_state pctrl_state[
|
|
CAM_SOC_MAX_PINCTRL_MAP];
|
|
};
|
|
|
|
/**
|
|
* struct cam_soc_gpio_data: Information about the gpio pins
|
|
*
|
|
* @cam_gpio_common_tbl: It is list of al the gpios present in gpios node
|
|
* @cam_gpio_common_tbl_size: It is equal to number of gpios prsent in
|
|
* gpios node in DTSI
|
|
* @cam_gpio_req_tbl It is list of al the requesetd gpios
|
|
* @cam_gpio_req_tbl_size: It is size of requested gpios
|
|
**/
|
|
struct cam_soc_gpio_data {
|
|
struct gpio *cam_gpio_common_tbl;
|
|
uint8_t cam_gpio_common_tbl_size;
|
|
struct gpio *cam_gpio_req_tbl;
|
|
uint8_t cam_gpio_req_tbl_size;
|
|
};
|
|
|
|
/**
|
|
* struct cam_hw_soc_info: Soc information pertaining to specific instance of
|
|
* Camera hardware driver module
|
|
*
|
|
* @pdev: Platform device pointer
|
|
* @device: Device pointer
|
|
* @hw_version: Camera device version
|
|
* @index: Instance id for the camera device
|
|
* @dev_name: Device Name
|
|
* @is_nrt_dev: Whether this is a non-real time device
|
|
* @irq_name: Name of the irq associated with the device
|
|
* @label_name: label name
|
|
* @irq_line: Irq resource
|
|
* @irq_num: Irq number
|
|
* @irq_data: Private data that is passed when IRQ is requested
|
|
* @compatible: Compatible string associated with the device
|
|
* @num_mem_block: Number of entry in the "reg-names"
|
|
* @mem_block_name: Array of the reg block name
|
|
* @mem_block_cam_base: Array of offset of this register space compared
|
|
* to ENTIRE Camera register space
|
|
* @mem_block: Associated resource structs
|
|
* @reg_map: Array of Mapped register info for the "reg-names"
|
|
* @num_reg_map: Number of mapped register space associated
|
|
* with mem_block. num_reg_map = num_mem_block in
|
|
* most cases
|
|
* @reserve_mem: Whether to reserve memory for Mem blocks
|
|
* @num_rgltr: Number of regulators
|
|
* @rgltr_name: Array of regulator names
|
|
* @rgltr_ctrl_support: Whether regulator control is supported
|
|
* @rgltr_min_volt: Array of minimum regulator voltage
|
|
* @rgltr_max_volt: Array of maximum regulator voltage
|
|
* @rgltr_op_mode: Array of regulator operation mode
|
|
* @rgltr_type: Array of regulator names
|
|
* @rgltr: Array of associated regulator resources
|
|
* @rgltr_delay: Array of regulator delay values
|
|
* @num_clk: Number of clocks
|
|
* @clk_name: Array of clock names
|
|
* @clk: Array of associated clock resources
|
|
* @clk_rate: 2D array of clock rates representing clock rate
|
|
* values at different vote levels
|
|
* @clk_id Clock IDs
|
|
* @shared_clk_mask Mask indicating which of the clocks are shared with
|
|
* other devices. Set rate on these clocks needs to go
|
|
* through camera clk wrapper for aggregation.
|
|
* @prev_clk_level Last vote level
|
|
* @src_clk_idx: Source clock index that is rate-controllable
|
|
* @applied_src_clk_rates: Applied src clock rates for SW and HW client
|
|
* @clk_level_valid: Indicates whether corresponding level is valid
|
|
* @lowest_clk_level: Lowest clock level that has valid freq info
|
|
* @scl_clk_count: Number of scalable clocks present
|
|
* @scl_clk_idx: Index of scalable clocks
|
|
* @optional_clk_name: Array of clock names
|
|
* @optional_clk: Array of associated clock resources
|
|
* @optional_clk_rate: Optional clock's clk rate
|
|
* @optional_clk_id Clock IDs
|
|
* @optional_shared_clk_mask Mask indicating which of the clocks are shared with
|
|
* other devices. Set rate on these clocks needs to go
|
|
* through camera clk wrapper for aggregation.
|
|
* @gpio_data: Pointer to gpio info
|
|
* @mmrm_handle: MMRM Client handle for src clock
|
|
* @is_clk_drv_en: If clock drv is enabled in hw
|
|
* @pinctrl_info: Pointer to pinctrl info
|
|
* @dentry: Debugfs entry
|
|
* @clk_level_override_high:Clk level set from debugfs. When cesta is enabled, used to override
|
|
* high clk value
|
|
* @clk_level_override_high:Low clk level set from debugfs when cesta is enabled, used to override
|
|
* low clk value
|
|
* @clk_control: Enable/disable clk rate control through debugfs
|
|
* @cam_cx_ipeak_enable cx-ipeak enable/disable flag
|
|
* @cam_cx_ipeak_bit cx-ipeak mask for driver
|
|
* @soc_private: Soc private data
|
|
*/
|
|
struct cam_hw_soc_info {
|
|
struct platform_device *pdev;
|
|
struct device *dev;
|
|
uint32_t hw_version;
|
|
uint32_t index;
|
|
const char *dev_name;
|
|
bool is_nrt_dev;
|
|
const char *irq_name;
|
|
const char *label_name;
|
|
struct resource *irq_line;
|
|
int irq_num;
|
|
void *irq_data;
|
|
const char *compatible;
|
|
|
|
uint32_t num_mem_block;
|
|
const char *mem_block_name[CAM_SOC_MAX_BLOCK];
|
|
uint32_t mem_block_cam_base[CAM_SOC_MAX_BLOCK];
|
|
struct resource *mem_block[CAM_SOC_MAX_BLOCK];
|
|
struct cam_soc_reg_map reg_map[CAM_SOC_MAX_BASE];
|
|
uint32_t num_reg_map;
|
|
uint32_t reserve_mem;
|
|
|
|
uint32_t num_rgltr;
|
|
const char *rgltr_name[CAM_SOC_MAX_REGULATOR];
|
|
uint32_t rgltr_ctrl_support;
|
|
uint32_t rgltr_min_volt[CAM_SOC_MAX_REGULATOR];
|
|
uint32_t rgltr_max_volt[CAM_SOC_MAX_REGULATOR];
|
|
uint32_t rgltr_op_mode[CAM_SOC_MAX_REGULATOR];
|
|
uint32_t rgltr_type[CAM_SOC_MAX_REGULATOR];
|
|
struct regulator *rgltr[CAM_SOC_MAX_REGULATOR];
|
|
uint32_t rgltr_delay[CAM_SOC_MAX_REGULATOR];
|
|
|
|
uint32_t use_shared_clk;
|
|
uint32_t num_clk;
|
|
const char *clk_name[CAM_SOC_MAX_CLK];
|
|
struct clk *clk[CAM_SOC_MAX_CLK];
|
|
int32_t clk_rate[CAM_MAX_VOTE][CAM_SOC_MAX_CLK];
|
|
uint32_t clk_id[CAM_SOC_MAX_CLK];
|
|
uint32_t shared_clk_mask;
|
|
int32_t prev_clk_level;
|
|
int32_t src_clk_idx;
|
|
struct cam_soc_util_clk_rates applied_src_clk_rates;
|
|
bool clk_level_valid[CAM_MAX_VOTE];
|
|
uint32_t lowest_clk_level;
|
|
int32_t scl_clk_count;
|
|
int32_t scl_clk_idx[CAM_SOC_MAX_CLK];
|
|
const char *optional_clk_name[CAM_SOC_MAX_OPT_CLK];
|
|
struct clk *optional_clk[CAM_SOC_MAX_OPT_CLK];
|
|
int32_t optional_clk_rate[CAM_SOC_MAX_OPT_CLK];
|
|
uint32_t optional_clk_id[CAM_SOC_MAX_OPT_CLK];
|
|
uint32_t optional_shared_clk_mask;
|
|
|
|
void *mmrm_handle;
|
|
|
|
bool is_clk_drv_en;
|
|
|
|
struct cam_soc_gpio_data *gpio_data;
|
|
struct cam_soc_pinctrl_info pinctrl_info;
|
|
|
|
struct dentry *dentry;
|
|
uint32_t clk_level_override_high;
|
|
uint32_t clk_level_override_low;
|
|
bool clk_control_enable;
|
|
bool cam_cx_ipeak_enable;
|
|
int32_t cam_cx_ipeak_bit;
|
|
|
|
void *soc_private;
|
|
};
|
|
|
|
/**
|
|
* struct cam_hw_soc_dump_header - SOC dump header
|
|
*
|
|
* @Brief: soc hw dump header
|
|
*
|
|
* @tag: Tag name for the header
|
|
* @word_size: Size of each word
|
|
* @size: Total size of dumped data
|
|
*/
|
|
struct cam_hw_soc_dump_header {
|
|
uint8_t tag[CAM_SOC_HW_DUMP_TAG_MAX_LEN];
|
|
uint64_t size;
|
|
uint32_t word_size;
|
|
};
|
|
|
|
/**
|
|
* struct cam_hw_soc_dump_args: SOC Dump args
|
|
*
|
|
* @request_id: Issue request id
|
|
* @offset: Buffer offset, updated as the informaton is dumped
|
|
* @buf_handle: Buffer handle of the out buffer
|
|
*/
|
|
struct cam_hw_soc_dump_args {
|
|
uint64_t request_id;
|
|
size_t offset;
|
|
uint32_t buf_handle;
|
|
};
|
|
|
|
/*
|
|
* CAM_SOC_GET_REG_MAP_START
|
|
*
|
|
* @brief: This MACRO will get the mapped starting address
|
|
* where the register space can be accessed
|
|
*
|
|
* @__soc_info: Device soc information
|
|
* @__base_index: Index of register space in the HW block
|
|
*
|
|
* @return: Returns a pointer to the mapped register memory
|
|
*/
|
|
#define CAM_SOC_GET_REG_MAP_START(__soc_info, __base_index) \
|
|
((!__soc_info || __base_index >= __soc_info->num_reg_map) ? \
|
|
NULL : __soc_info->reg_map[__base_index].mem_base)
|
|
|
|
/*
|
|
* CAM_SOC_GET_REG_MAP_CAM_BASE
|
|
*
|
|
* @brief: This MACRO will get the cam_base of the
|
|
* register space
|
|
*
|
|
* @__soc_info: Device soc information
|
|
* @__base_index: Index of register space in the HW block
|
|
*
|
|
* @return: Returns an int32_t value.
|
|
* Failure: -1
|
|
* Success: Starting offset of register space compared
|
|
* to entire Camera Register Map
|
|
*/
|
|
#define CAM_SOC_GET_REG_MAP_CAM_BASE(__soc_info, __base_index) \
|
|
((!__soc_info || __base_index >= __soc_info->num_reg_map) ? \
|
|
-1 : __soc_info->reg_map[__base_index].mem_cam_base)
|
|
|
|
/*
|
|
* CAM_SOC_GET_REG_MAP_SIZE
|
|
*
|
|
* @brief: This MACRO will get the size of the mapped
|
|
* register space
|
|
*
|
|
* @__soc_info: Device soc information
|
|
* @__base_index: Index of register space in the HW block
|
|
*
|
|
* @return: Returns a uint32_t value.
|
|
* Failure: 0
|
|
* Success: Non-zero size of mapped register space
|
|
*/
|
|
#define CAM_SOC_GET_REG_MAP_SIZE(__soc_info, __base_index) \
|
|
((!__soc_info || __base_index >= __soc_info->num_reg_map) ? \
|
|
0 : __soc_info->reg_map[__base_index].size)
|
|
|
|
/**
|
|
* cam_soc_util_get_level_from_string()
|
|
*
|
|
* @brief: Get the associated vote level for the input string
|
|
*
|
|
* @string: Input string to compare with.
|
|
* @level: Vote level corresponds to input string.
|
|
*
|
|
* @return: Success or failure
|
|
*/
|
|
int cam_soc_util_get_level_from_string(const char *string,
|
|
enum cam_vote_level *level);
|
|
|
|
/**
|
|
* cam_soc_util_get_dt_properties()
|
|
*
|
|
* @brief: Parse the DT and populate the common properties that
|
|
* are part of the soc_info structure - register map,
|
|
* clocks, regulators, irq, etc.
|
|
*
|
|
* @soc_info: Device soc struct to be populated
|
|
*
|
|
* @return: Success or failure
|
|
*/
|
|
int cam_soc_util_get_dt_properties(struct cam_hw_soc_info *soc_info);
|
|
|
|
/**
|
|
* cam_soc_util_request_platform_resource()
|
|
*
|
|
* @brief: Request regulator, irq, and clock resources
|
|
*
|
|
* @soc_info: Device soc information
|
|
* @handler: Irq handler function pointer
|
|
* @irq_data: Irq handler function CB data
|
|
*
|
|
* @return: Success or failure
|
|
*/
|
|
int cam_soc_util_request_platform_resource(struct cam_hw_soc_info *soc_info,
|
|
irq_handler_t handler, void *irq_data);
|
|
|
|
/**
|
|
* cam_soc_util_release_platform_resource()
|
|
*
|
|
* @brief: Release regulator, irq, and clock resources
|
|
*
|
|
* @soc_info: Device soc information
|
|
*
|
|
* @return: Success or failure
|
|
*/
|
|
int cam_soc_util_release_platform_resource(struct cam_hw_soc_info *soc_info);
|
|
|
|
/**
|
|
* cam_soc_util_enable_platform_resource()
|
|
*
|
|
* @brief: Enable regulator, irq resources
|
|
*
|
|
* @soc_info: Device soc information
|
|
* @cesta_client_idx: CESTA Client idx for hw client based src clocks
|
|
* @enable_clocks: Boolean flag:
|
|
* TRUE: Enable all clocks in soc_info Now.
|
|
* False: Don't enable clocks Now. Driver will
|
|
* enable independently.
|
|
* @clk_level: Clock level to be applied.
|
|
* Applicable only if enable_clocks is true
|
|
* Valid range : 0 to (CAM_MAX_VOTE - 1)
|
|
* @enable_irq: Boolean flag:
|
|
* TRUE: Enable IRQ in soc_info Now.
|
|
* False: Don't enable IRQ Now. Driver will
|
|
* enable independently.
|
|
*
|
|
* @return: Success or failure
|
|
*/
|
|
int cam_soc_util_enable_platform_resource(struct cam_hw_soc_info *soc_info,
|
|
int cesta_client_idx, bool enable_clocks, enum cam_vote_level clk_level,
|
|
bool enable_irq);
|
|
|
|
/**
|
|
* cam_soc_util_disable_platform_resource()
|
|
*
|
|
* @brief: Disable regulator, irq resources
|
|
*
|
|
* @soc_info: Device soc information
|
|
* @cesta_client_idx: CESTA Client idx for hw client based src clocks
|
|
* @disable_irq: Boolean flag:
|
|
* TRUE: Disable IRQ in soc_info Now.
|
|
* False: Don't disable IRQ Now. Driver will
|
|
* disable independently.
|
|
*
|
|
* @return: Success or failure
|
|
*/
|
|
int cam_soc_util_disable_platform_resource(struct cam_hw_soc_info *soc_info,
|
|
int cesta_client_idx, bool disable_clocks, bool disable_irq);
|
|
|
|
/**
|
|
* cam_soc_util_get_clk_round_rate()
|
|
*
|
|
* @brief: Get the rounded clock rate for the given clock's
|
|
* clock rate value
|
|
*
|
|
* @soc_info: Device soc information
|
|
* @clk_index: Clock index in soc_info for which round rate is needed
|
|
* @clk_rate: Input clock rate for which rounded rate is needed
|
|
*
|
|
* @return: Rounded clock rate
|
|
*/
|
|
long cam_soc_util_get_clk_round_rate(struct cam_hw_soc_info *soc_info,
|
|
uint32_t clk_index, unsigned long clk_rate);
|
|
|
|
/**
|
|
* cam_soc_util_set_src_clk_rate()
|
|
*
|
|
* @brief: Set the rate on the source clock for sw or hw clients. Requires a valid
|
|
* CESTA client idx for hw client voting.
|
|
*
|
|
* @soc_info: Device soc information
|
|
* @cesta_client_idx: CESTA client idx if src clock belongs to cesta client, otherwise -1
|
|
* @clk_rate_high: High clock rate associated with the src clk, applies to sw client vote
|
|
* if not cesta client
|
|
* @clk_rate_low: Low clock rate associated with the src clk, only applies to cesta based
|
|
* hw client vote
|
|
*
|
|
* @return: success or failure
|
|
*/
|
|
int cam_soc_util_set_src_clk_rate(struct cam_hw_soc_info *soc_info, int cesta_client_idx,
|
|
unsigned long clk_rate_high, unsigned long clk_rate_low);
|
|
|
|
|
|
/**
|
|
* cam_soc_util_get_option_clk_by_name()
|
|
*
|
|
* @brief: Get reference to optional clk using name
|
|
*
|
|
* @soc_info: Device soc information
|
|
* @clk_name: Name of clock to find reference for
|
|
* @clk_index: Clk index in the option clk array to be returned
|
|
*
|
|
* @return: 0: Success
|
|
* Negative: Failure
|
|
*/
|
|
int cam_soc_util_get_option_clk_by_name(struct cam_hw_soc_info *soc_info,
|
|
const char *clk_name, int32_t *clk_index);
|
|
|
|
/**
|
|
* cam_soc_util_put_optional_clk()
|
|
*
|
|
* @brief: Put clock corresponding to index specified in params
|
|
*
|
|
* @soc_info: Device soc information
|
|
* @clk_idx: Clock index in optional clocks to put
|
|
*
|
|
* @return: Success or failure
|
|
*/
|
|
int cam_soc_util_put_optional_clk(struct cam_hw_soc_info *soc_info,
|
|
int32_t clk_idx);
|
|
|
|
/**
|
|
* cam_soc_util_clk_enable()
|
|
*
|
|
* @brief: Enable clock specified in params
|
|
*
|
|
* @soc_info: Device soc information
|
|
* @cesta_client_idx: CESTA Client idx for hw client based src clocks
|
|
* @optional_clk: Whether to set optional clk or normal clk with
|
|
* the idx given
|
|
* @clk_idx: Clock index to set
|
|
* @apply_level: Apply level.
|
|
* -1 for 0 rate
|
|
* any other value indicate level for normal clocks
|
|
* For optional clocks any other value means the rate saved
|
|
* in soc_info
|
|
*
|
|
* @return: Success or failure
|
|
*/
|
|
int cam_soc_util_clk_enable(struct cam_hw_soc_info *soc_info, int cesta_client_idx,
|
|
bool optional_clk, int32_t clk_idx, int32_t apply_level);
|
|
|
|
/**
|
|
* cam_soc_util_set_clk_rate_level()
|
|
*
|
|
* @brief: Apply clock rates for the requested level.
|
|
* This applies the new requested level for all
|
|
* the clocks listed in DT based on their values.
|
|
*
|
|
* @soc_info: Device soc information
|
|
* @cesta_client_idx: CESTA client idx for HW client based src clocks
|
|
* @clk_level_high: Clock level number to set, high value if crm based src clock
|
|
* @clk_level_low: Low clock level value if crm based src clock
|
|
* @do_not_set_src_clk: If true, set clock rates except the src clk
|
|
*
|
|
* @return: Success or failure
|
|
*/
|
|
int cam_soc_util_set_clk_rate_level(struct cam_hw_soc_info *soc_info,
|
|
int cesta_client_idx, enum cam_vote_level clk_level_high,
|
|
enum cam_vote_level clk_level_low, bool do_not_set_src_clk);
|
|
|
|
/**
|
|
* cam_soc_util_clk_disable()
|
|
*
|
|
* @brief: Disable clock specified in params
|
|
*
|
|
* @soc_info: Device soc information
|
|
* @cesta_client_idx: CESTA Client idx for hw client based src clocks
|
|
* @optional_clk: Whether to set optional clk or normal clk with
|
|
* the idx given
|
|
* @clk_idx: Clock index to disable
|
|
*
|
|
* @return: Success or failure
|
|
*/
|
|
int cam_soc_util_clk_disable(struct cam_hw_soc_info *soc_info, int cesta_client_idx,
|
|
bool optional_clk, int32_t clk_idx);
|
|
|
|
/**
|
|
* cam_soc_util_irq_enable()
|
|
*
|
|
* @brief: Enable IRQ in SOC
|
|
*
|
|
* @soc_info: Device soc information
|
|
*
|
|
* @return: Success or failure
|
|
*/
|
|
int cam_soc_util_irq_enable(struct cam_hw_soc_info *soc_info);
|
|
|
|
/**
|
|
* cam_soc_util_irq_disable()
|
|
*
|
|
* @brief: Disable IRQ in SOC
|
|
*
|
|
* @soc_info: Device soc information
|
|
*
|
|
* @return: Success or failure
|
|
*/
|
|
int cam_soc_util_irq_disable(struct cam_hw_soc_info *soc_info);
|
|
|
|
/**
|
|
* cam_soc_util_regulator_enable()
|
|
*
|
|
* @brief: Enable single regulator
|
|
*
|
|
* @rgltr Regulator that needs to be turned ON
|
|
* @rgltr_name Associated Regulator name
|
|
* @rgltr_min_volt: Requested minimum volatage
|
|
* @rgltr_max_volt: Requested maximum volatage
|
|
* @rgltr_op_mode: Requested Load
|
|
* @rgltr_delay: Requested delay needed aaftre enabling regulator
|
|
*
|
|
* @return: Success or failure
|
|
*/
|
|
int cam_soc_util_regulator_enable(struct regulator *rgltr,
|
|
const char *rgltr_name,
|
|
uint32_t rgltr_min_volt, uint32_t rgltr_max_volt,
|
|
uint32_t rgltr_op_mode, uint32_t rgltr_delay);
|
|
|
|
/**
|
|
* cam_soc_util_regulator_enable()
|
|
*
|
|
* @brief: Disable single regulator
|
|
*
|
|
* @rgltr Regulator that needs to be turned ON
|
|
* @rgltr_name Associated Regulator name
|
|
* @rgltr_min_volt: Requested minimum volatage
|
|
* @rgltr_max_volt: Requested maximum volatage
|
|
* @rgltr_op_mode: Requested Load
|
|
* @rgltr_delay: Requested delay needed aaftre enabling regulator
|
|
*
|
|
* @return: Success or failure
|
|
*/
|
|
int cam_soc_util_regulator_disable(struct regulator *rgltr,
|
|
const char *rgltr_name,
|
|
uint32_t rgltr_min_volt, uint32_t rgltr_max_volt,
|
|
uint32_t rgltr_op_mode, uint32_t rgltr_delay);
|
|
|
|
|
|
/**
|
|
* cam_soc_util_w()
|
|
*
|
|
* @brief: Camera SOC util for register write
|
|
*
|
|
* @soc_info: Device soc information
|
|
* @base_index: Index of register space in the HW block
|
|
* @offset: Offset of register to be read
|
|
* @data: Value to be written
|
|
*
|
|
* @return: Success or Failure
|
|
*/
|
|
static inline int cam_soc_util_w(struct cam_hw_soc_info *soc_info,
|
|
uint32_t base_index, uint32_t offset, uint32_t data)
|
|
{
|
|
if (!CAM_SOC_GET_REG_MAP_START(soc_info, base_index))
|
|
return -EINVAL;
|
|
return cam_io_w(data,
|
|
CAM_SOC_GET_REG_MAP_START(soc_info, base_index) + offset);
|
|
}
|
|
|
|
/**
|
|
* cam_soc_util_w_mb()
|
|
*
|
|
* @brief: Camera SOC util for register write with memory barrier.
|
|
* Memory Barrier is only before the write to ensure the
|
|
* order. If need to ensure this write is also flushed
|
|
* call wmb() independently in the caller.
|
|
*
|
|
* @soc_info: Device soc information
|
|
* @base_index: Index of register space in the HW block
|
|
* @offset: Offset of register to be read
|
|
* @data: Value to be written
|
|
*
|
|
* @return: Success or Failure
|
|
*/
|
|
static inline int cam_soc_util_w_mb(struct cam_hw_soc_info *soc_info,
|
|
uint32_t base_index, uint32_t offset, uint32_t data)
|
|
{
|
|
if (!CAM_SOC_GET_REG_MAP_START(soc_info, base_index))
|
|
return -EINVAL;
|
|
return cam_io_w_mb(data,
|
|
CAM_SOC_GET_REG_MAP_START(soc_info, base_index) + offset);
|
|
}
|
|
|
|
/**
|
|
* cam_soc_util_r()
|
|
*
|
|
* @brief: Camera SOC util for register read
|
|
*
|
|
* @soc_info: Device soc information
|
|
* @base_index: Index of register space in the HW block
|
|
* @offset: Offset of register to be read
|
|
*
|
|
* @return: Value read from the register address
|
|
*/
|
|
static inline uint32_t cam_soc_util_r(struct cam_hw_soc_info *soc_info,
|
|
uint32_t base_index, uint32_t offset)
|
|
{
|
|
if (!CAM_SOC_GET_REG_MAP_START(soc_info, base_index))
|
|
return 0;
|
|
return cam_io_r(
|
|
CAM_SOC_GET_REG_MAP_START(soc_info, base_index) + offset);
|
|
}
|
|
|
|
/**
|
|
* cam_soc_util_r_mb()
|
|
*
|
|
* @brief: Camera SOC util for register read with memory barrier.
|
|
* Memory Barrier is only before the write to ensure the
|
|
* order. If need to ensure this write is also flushed
|
|
* call rmb() independently in the caller.
|
|
*
|
|
* @soc_info: Device soc information
|
|
* @base_index: Index of register space in the HW block
|
|
* @offset: Offset of register to be read
|
|
*
|
|
* @return: Value read from the register address
|
|
*/
|
|
static inline uint32_t cam_soc_util_r_mb(struct cam_hw_soc_info *soc_info,
|
|
uint32_t base_index, uint32_t offset)
|
|
{
|
|
if (!CAM_SOC_GET_REG_MAP_START(soc_info, base_index))
|
|
return 0;
|
|
return cam_io_r_mb(
|
|
CAM_SOC_GET_REG_MAP_START(soc_info, base_index) + offset);
|
|
}
|
|
|
|
/**
|
|
* cam_soc_util_reg_dump()
|
|
*
|
|
* @brief: Camera SOC util for dumping a range of register
|
|
*
|
|
* @soc_info: Device soc information
|
|
* @base_index: Index of register space in the HW block
|
|
* @offset: Start register offset for the dump
|
|
* @size: Size specifying the range for dump
|
|
*
|
|
* @return: Success or Failure
|
|
*/
|
|
int cam_soc_util_reg_dump(struct cam_hw_soc_info *soc_info,
|
|
uint32_t base_index, uint32_t offset, int size);
|
|
|
|
void cam_soc_util_clk_disable_default(struct cam_hw_soc_info *soc_info,
|
|
int cesta_client_idx);
|
|
|
|
int cam_soc_util_clk_enable_default(struct cam_hw_soc_info *soc_info, int cesta_client_idx,
|
|
enum cam_vote_level clk_level);
|
|
|
|
int cam_soc_util_get_clk_level(struct cam_hw_soc_info *soc_info,
|
|
int64_t clk_rate, int clk_idx, int32_t *clk_lvl);
|
|
|
|
/* Callback to get reg space data for specific HW */
|
|
typedef int (*cam_soc_util_regspace_data_cb)(uint32_t reg_base_type,
|
|
void *ctx, struct cam_hw_soc_info **soc_info_ptr,
|
|
uint32_t *reg_base_idx);
|
|
|
|
/**
|
|
* cam_soc_util_reg_dump_to_cmd_buf()
|
|
*
|
|
* @brief: Camera SOC util for dumping sets of register ranges
|
|
* command buffer
|
|
*
|
|
* @ctx: Context info from specific hardware manager
|
|
* @cmd_desc: Command buffer descriptor
|
|
* @req_id: Last applied req id for which reg dump is required
|
|
* @reg_data_cb: Callback function to get reg space info based on type
|
|
* in command buffer
|
|
* @soc_dump_args: Dump buffer args to dump the soc information.
|
|
* @user_triggered_dump: Flag to indicate if the dump request is issued by
|
|
* user.
|
|
* @return: Success or Failure
|
|
*/
|
|
int cam_soc_util_reg_dump_to_cmd_buf(void *ctx,
|
|
struct cam_cmd_buf_desc *cmd_desc, uint64_t req_id,
|
|
cam_soc_util_regspace_data_cb reg_data_cb,
|
|
struct cam_hw_soc_dump_args *soc_dump_args,
|
|
bool user_triggered_dump);
|
|
|
|
/**
|
|
* cam_soc_util_print_clk_freq()
|
|
*
|
|
* @brief: This function gets the clk rates for each clk from clk
|
|
* driver and prints in log
|
|
*
|
|
* @soc_info: Device soc struct to be populated
|
|
*
|
|
* @return: success or failure
|
|
*/
|
|
int cam_soc_util_print_clk_freq(struct cam_hw_soc_info *soc_info);
|
|
|
|
/**
|
|
* cam_soc_util_select_pinctrl_state()
|
|
*
|
|
* @brief: This function gets the pinctrl handle
|
|
*
|
|
* @soc_info: Device soc struct to be populated
|
|
* @active: True for active and false for suspend state
|
|
*
|
|
* @return: success or failure
|
|
*/
|
|
int cam_soc_util_select_pinctrl_state(
|
|
struct cam_hw_soc_info *soc_info, int idx, bool active);
|
|
|
|
/**
|
|
* cam_soc_util_print_clk_freq()
|
|
*
|
|
* @brief: This function checks whether regulators of this device are enabled at this
|
|
* time.
|
|
*
|
|
* @soc_info: Device soc struct to be populated
|
|
*
|
|
* @return: Number of regulators enabled
|
|
*/
|
|
int cam_soc_util_regulators_enabled(struct cam_hw_soc_info *soc_info);
|
|
|
|
/**
|
|
* cam_soc_util_cesta_populate_crm_device()
|
|
*
|
|
* @brief: This function populates the camera cesta crm device in soc util
|
|
*
|
|
* @return: success or failure
|
|
*/
|
|
inline int cam_soc_util_cesta_populate_crm_device(void);
|
|
|
|
/**
|
|
* cam_soc_util_cesta_channel_switch()
|
|
*
|
|
* @brief: This function triggers the application of power states to crm
|
|
* and channel switch operation in hw. Also, for camera it applies
|
|
* the high vote of the active channel
|
|
* @cesta_client_idx: CESTA client index through which power states need to be applied
|
|
* @identifier: Identifying the caller triggerring channel switch
|
|
*
|
|
* @return: success or failure
|
|
*/
|
|
int cam_soc_util_cesta_channel_switch(uint32_t cesta_client_idx, const char *identifier);
|
|
|
|
/**
|
|
* cam_soc_util_get_applied_src_clk()
|
|
*
|
|
* @brief: Inline function to get applied src clk rate.
|
|
|
|
* @soc_info: Device soc struct to be populated
|
|
* @is_max: Is max of all hw clients if cesta is enabled
|
|
*
|
|
* @return: success or failure
|
|
*/
|
|
inline unsigned long cam_soc_util_get_applied_src_clk(
|
|
struct cam_hw_soc_info *soc_info, bool is_max);
|
|
|
|
/**
|
|
* cam_soc_util_get_string_from_level()
|
|
*
|
|
* @brief: Returns the string for a given clk level
|
|
*
|
|
* @level: Clock level
|
|
*
|
|
* @return: String corresponding to the clk level
|
|
*/
|
|
const char *cam_soc_util_get_string_from_level(enum cam_vote_level level);
|
|
|
|
#endif /* _CAM_SOC_UTIL_H_ */
|