mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-14 08:36:12 -04:00
dsp: afe: Enhance and expose API for configuring ext clk
To configure the external clock, the client (machine driver) is expected to configure the clock attributes (M, N, D, div2x, clk root, etc.) and if required, to toggle the external clock source in the registered callback function, before sending the param to the DSP. Expose the API to the clock driver for the same. During clock disable, the sequence of operations is reversed. Change-Id: I289625e40c3a9c102270eae3c10ad7bf1a112f4f Signed-off-by: Abhilash Sathyanarayana <quic_abhisath@quicinc.com>
This commit is contained in:
parent
cc879c910d
commit
bfe2d34ede
2 changed files with 60 additions and 30 deletions
80
dsp/q6afe.c
80
dsp/q6afe.c
|
|
@ -9858,8 +9858,8 @@ int afe_set_pll_clk_drift(u16 port_id, int32_t set_clk_drift,
|
|||
}
|
||||
EXPORT_SYMBOL(afe_set_pll_clk_drift);
|
||||
|
||||
static int afe_set_lpass_clk_cfg_ext_mclk(int index, struct afe_clk_set *cfg,
|
||||
uint32_t mclk_freq)
|
||||
int afe_set_lpass_clk_cfg_ext_mclk(int index, struct afe_clk_set *cfg,
|
||||
uint32_t mclk_freq)
|
||||
{
|
||||
struct param_hdr_v3 param_hdr;
|
||||
struct afe_param_id_clock_set_v2_t dyn_mclk_cfg;
|
||||
|
|
@ -9871,6 +9871,12 @@ static int afe_set_lpass_clk_cfg_ext_mclk(int index, struct afe_clk_set *cfg,
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (!afe_ext_mclk.ext_mclk_cb) {
|
||||
pr_debug("%s: ext_mclk_cb not registered; platform doesn't support ext clk\n",
|
||||
__func__);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (index < 0 || index >= AFE_MAX_PORTS) {
|
||||
pr_err("%s: index[%d] invalid!\n", __func__, index);
|
||||
return -EINVAL;
|
||||
|
|
@ -9883,34 +9889,33 @@ static int afe_set_lpass_clk_cfg_ext_mclk(int index, struct afe_clk_set *cfg,
|
|||
param_hdr.param_size = sizeof(struct afe_param_id_clock_set_v2_t);
|
||||
|
||||
memset(&dyn_mclk_cfg, 0, sizeof(dyn_mclk_cfg));
|
||||
dyn_mclk_cfg.clk_freq_in_hz = cfg->clk_freq_in_hz;
|
||||
if (afe_ext_mclk.ext_mclk_cb) {
|
||||
ret = afe_ext_mclk.ext_mclk_cb(afe_ext_mclk.private_data,
|
||||
cfg->enable, mclk_freq, &dyn_mclk_cfg);
|
||||
if (ret) {
|
||||
pr_err_ratelimited("%s: get mclk cfg failed %d\n",
|
||||
__func__, ret);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
pr_err_ratelimited("%s: mclk callback not registered\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dyn_mclk_cfg.clk_freq_in_hz = cfg->clk_freq_in_hz;
|
||||
dyn_mclk_cfg.clk_set_minor_version = 1;
|
||||
dyn_mclk_cfg.clk_id = cfg->clk_id;
|
||||
dyn_mclk_cfg.clk_attri = cfg->clk_attri;
|
||||
dyn_mclk_cfg.enable = cfg->enable;
|
||||
pr_debug("%s: Minor version =0x%x clk id = %d\n", __func__,
|
||||
dyn_mclk_cfg.clk_set_minor_version, dyn_mclk_cfg.clk_id);
|
||||
dyn_mclk_cfg.clk_set_minor_version, dyn_mclk_cfg.clk_id);
|
||||
pr_debug("%s: clk freq (Hz) = %d, clk attri = 0x%x\n", __func__,
|
||||
dyn_mclk_cfg.clk_freq_in_hz, dyn_mclk_cfg.clk_attri);
|
||||
pr_debug("%s: clk root = 0x%x clk enable = 0x%x\n", __func__,
|
||||
dyn_mclk_cfg.clk_root, dyn_mclk_cfg.enable);
|
||||
pr_debug("%s: divider_2x =%d m = %d n = %d, d =%d\n", __func__,
|
||||
dyn_mclk_cfg.divider_2x, dyn_mclk_cfg.m, dyn_mclk_cfg.n,
|
||||
dyn_mclk_cfg.d);
|
||||
dyn_mclk_cfg.clk_freq_in_hz, dyn_mclk_cfg.clk_attri);
|
||||
pr_debug("%s: clk input freq (Hz) = %d clk enable = 0x%x\n", __func__,
|
||||
mclk_freq, dyn_mclk_cfg.enable);
|
||||
|
||||
if (dyn_mclk_cfg.enable) {
|
||||
/* callback to populate Div2x, M, N, D, clock root and enable GPIOs */
|
||||
ret = afe_ext_mclk.ext_mclk_cb(afe_ext_mclk.private_data,
|
||||
dyn_mclk_cfg.enable, mclk_freq, &dyn_mclk_cfg);
|
||||
if (ret) {
|
||||
pr_err_ratelimited("%s: mclk cb during enable failed %d\n",
|
||||
__func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
pr_debug("%s: clk root = 0x%x divider_2x = %d m = %d n = %d d = %d\n",
|
||||
__func__, dyn_mclk_cfg.clk_root, dyn_mclk_cfg.divider_2x,
|
||||
dyn_mclk_cfg.m, dyn_mclk_cfg.n, dyn_mclk_cfg.d);
|
||||
}
|
||||
|
||||
ret = afe_q6_interface_prepare();
|
||||
if (ret != 0) {
|
||||
|
|
@ -9922,23 +9927,37 @@ static int afe_set_lpass_clk_cfg_ext_mclk(int index, struct afe_clk_set *cfg,
|
|||
mutex_lock(&this_afe.afe_cmd_lock);
|
||||
ret = q6afe_svc_pack_and_set_param_in_band(index, param_hdr,
|
||||
(u8 *) &dyn_mclk_cfg);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
pr_err_ratelimited("%s: ext MCLK clk cfg failed with ret %d\n",
|
||||
__func__, ret);
|
||||
__func__, ret);
|
||||
mutex_unlock(&this_afe.afe_cmd_lock);
|
||||
goto stop_mclk;
|
||||
}
|
||||
|
||||
mutex_unlock(&this_afe.afe_cmd_lock);
|
||||
|
||||
if (!dyn_mclk_cfg.enable) {
|
||||
/* callback to disable GPIOs */
|
||||
ret = afe_ext_mclk.ext_mclk_cb(afe_ext_mclk.private_data,
|
||||
dyn_mclk_cfg.enable, mclk_freq, &dyn_mclk_cfg);
|
||||
if (ret) {
|
||||
pr_err_ratelimited("%s: mclk cb during disable failed %d\n",
|
||||
__func__, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret >= 0)
|
||||
return ret;
|
||||
|
||||
stop_mclk:
|
||||
if (afe_ext_mclk.ext_mclk_cb && cfg->enable) {
|
||||
afe_ext_mclk.ext_mclk_cb(afe_ext_mclk.private_data,
|
||||
cfg->enable, mclk_freq, &dyn_mclk_cfg);
|
||||
}
|
||||
dyn_mclk_cfg.enable = 0;
|
||||
afe_ext_mclk.ext_mclk_cb(afe_ext_mclk.private_data,
|
||||
dyn_mclk_cfg.enable, mclk_freq, &dyn_mclk_cfg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(afe_set_lpass_clk_cfg_ext_mclk);
|
||||
|
||||
static int ext_dyn_mclk_port_id;
|
||||
static int ext_dyn_clk_root = Q6AFE_LPASS_CLK_ROOT_DEFAULT;
|
||||
|
|
@ -10162,7 +10181,8 @@ int afe_set_lpass_clock_v2(u16 port_id, struct afe_clk_set *cfg)
|
|||
build_branch_version, afe_api_version);
|
||||
if ((build_major_version != AVS_BUILD_MAJOR_VERSION_V2) ||
|
||||
(build_minor_version != AVS_BUILD_MINOR_VERSION_V9) ||
|
||||
(build_branch_version != AVS_BUILD_BRANCH_VERSION_V3) ||
|
||||
((build_branch_version != AVS_BUILD_BRANCH_VERSION_V0) &&
|
||||
(build_branch_version != AVS_BUILD_BRANCH_VERSION_V3)) ||
|
||||
(afe_api_version < AFE_API_VERSION_V8)) {
|
||||
pr_err("%s: ext mclk not supported by AVS\n", __func__);
|
||||
return -EINVAL;
|
||||
|
|
|
|||
|
|
@ -603,6 +603,8 @@ int afe_port_send_afe_limiter_param(u16 port_id,
|
|||
struct afe_param_id_port_afe_limiter_disable_t *disable_limiter);
|
||||
int afe_get_av_dev_drift(struct afe_param_id_dev_timing_stats *timing_stats,
|
||||
u16 port);
|
||||
int afe_set_lpass_clk_cfg_ext_mclk(int index, struct afe_clk_set *cfg,
|
||||
uint32_t mclk_freq);
|
||||
int afe_set_lpass_clk_cfg_ext_mclk_v2(int index,
|
||||
struct afe_param_id_clock_set_v2_t *dyn_mclk_cfg, uint32_t mclk_freq);
|
||||
int afe_get_sp_rx_tmax_xmax_logging_data(
|
||||
|
|
@ -634,6 +636,14 @@ int afe_set_source_clk(u16 port_id, const char *clk_src);
|
|||
void afe_set_clk_src_array(const char *clk_src[CLK_SRC_MAX]);
|
||||
int afe_set_mclk_src_cfg(u16 port_id, uint32_t mclk_src_id, uint32_t mclk_freq);
|
||||
|
||||
/* Client of AFE registers afe_enable_mclk_and_get_info_cb_func callback function via
|
||||
* afe_register_ext_mclk_cb() when external clock is supported by the platform. During
|
||||
* clock enable sequence, AFE triggers this callback before requesting DSP for clock
|
||||
* enable. Client can provide Div2X, M, N, D and clock root as part of this callback.
|
||||
* Client can also enable required GPIO that are essential to route external clock in
|
||||
* this callback. During clock disable sequence, AFE triggers this callback after
|
||||
* requesting DSP for clock disable. Client can disable required GPIOs in this callback.
|
||||
*/
|
||||
typedef int (*afe_enable_mclk_and_get_info_cb_func) (void *private_data,
|
||||
uint32_t enable, uint32_t mclk_freq,
|
||||
struct afe_param_id_clock_set_v2_t *dyn_mclk_cfg);
|
||||
|
|
|
|||
Loading…
Reference in a new issue