msm: camera: utils: Add camera clk wrapper infrastructure

Source clocks that are shared with multiple devices need
to be consolidated before setting clock rate on them.
If not, a set call with lower freq from one device
overwrites the frequency that previously set by another
device, causing issues. Clk wrapper helps to consolidate
the frequency among multiple devices and set the max
frequency required by all of them. A shared clock notation
is defined in DT and go through clk wrapper based on that.

CRs-Fixed: 2901925
Change-Id: Ia5b2b5fd3c0619c994e27d96fad6e11d126de182
Signed-off-by: Pavan Kumar Chilamkurthi <pchilamk@codeaurora.org>
This commit is contained in:
Pavan Kumar Chilamkurthi
2021-03-02 10:43:27 -08:00
parent 8b6740991b
commit cd745eb39a
8 changed files with 607 additions and 108 deletions

View File

@@ -36,6 +36,9 @@
/* maximum number of device clock */
#define CAM_SOC_MAX_CLK 32
/* maximum number of optional device clock */
#define CAM_SOC_MAX_OPT_CLK 2
/* DDR device types */
#define DDR_TYPE_LPDDR4 6
#define DDR_TYPE_LPDDR4X 7
@@ -155,12 +158,23 @@ struct cam_soc_gpio_data {
* @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_rate Current clock rate of the core source clk
* @clk_level_valid: Indicates whether corresponding level is valid
* @scl_clk_count: Number of scalable clocks present
* @scl_clk_idx: Index of scalable clocks
* @applied_src_clk_rate Current clock rate of the core source clk
* @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
* @pinctrl_info: Pointer to pinctrl info
* @dentry: Debugfs entry
@@ -205,12 +219,19 @@ struct cam_hw_soc_info {
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;
unsigned long applied_src_clk_rate;
bool clk_level_valid[CAM_MAX_VOTE];
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;
struct cam_soc_gpio_data *gpio_data;
struct cam_soc_pinctrl_info pinctrl_info;
@@ -427,42 +448,48 @@ int cam_soc_util_set_src_clk_rate(struct cam_hw_soc_info *soc_info,
*
* @soc_info: Device soc information
* @clk_name: Name of clock to find reference for
* @clk: Clock reference pointer to be filled if Success
* @clk_index: Clk index in the option clk array to be returned
* @clk_rate: Clk rate in the option clk array
*
* @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, struct clk **clk, int32_t *clk_index,
int32_t *clk_rate);
const char *clk_name, int32_t *clk_index);
/**
* cam_soc_util_clk_put()
* cam_soc_util_put_optional_clk()
*
* @brief: Put clock specified in params
* @brief: Put clock corresponding to index specified in params
*
* @clk: Reference to the Clock that needs to be put
* @soc_info: Device soc information
* @clk_idx: Clock index in optional clocks to put
*
* @return: Success or failure
*/
int cam_soc_util_clk_put(struct clk **clk);
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
*
* @clk: Clock that needs to be turned ON
* @clk_name: Clocks name associated with clk
* @clk_rate: Clocks rate associated with clk
* @soc_info: Device soc information
* @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
* @applied_clock_rate Final Clock rate applied to the clk
*
* @return: Success or failure
*/
int cam_soc_util_clk_enable(struct clk *clk, const char *clk_name,
int32_t clk_rate, unsigned long *applied_clock_rate);
int cam_soc_util_clk_enable(struct cam_hw_soc_info *soc_info,
bool optional_clk, int32_t clk_idx, int32_t apply_level,
unsigned long *applied_clock_rate);
/**
* cam_soc_util_set_clk_rate_level()
@@ -485,12 +512,15 @@ int cam_soc_util_set_clk_rate_level(struct cam_hw_soc_info *soc_info,
*
* @brief: Disable clock specified in params
*
* @clk: Clock that needs to be turned OFF
* @clk_name: Clocks name associated with clk
* @soc_info: Device soc information
* @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 clk *clk, const char *clk_name);
int cam_soc_util_clk_disable(struct cam_hw_soc_info *soc_info,
bool optional_clk, int32_t clk_idx);
/**
* cam_soc_util_irq_enable()