From 898db47a7810c2ffce83c89d6944933bce84fd46 Mon Sep 17 00:00:00 2001 From: Skylar Chang Date: Thu, 9 Feb 2017 06:08:08 -0800 Subject: [PATCH] msm: ipa3: disable clock gating for MISC As per design recommendation on clock gating of MISC block for IPA 3.1, as a workaround, clock gating for MISC needs to be disabled using IPA_CLKON_CFG register. Change-Id: If38741933f2700231977b87f1eaa7b4d95efd478 Signed-off-by: Skylar Chang --- drivers/platform/msm/ipa/ipa_v3/ipa.c | 23 ++++++++++++++++++- drivers/platform/msm/ipa/ipa_v3/ipa_i.h | 1 + drivers/platform/msm/ipa/ipa_v3/ipa_utils.c | 22 ++++++++++++++++++ .../msm/ipa/ipa_v3/ipahal/ipahal_reg.c | 16 +++++++++++++ .../msm/ipa/ipa_v3/ipahal/ipahal_reg.h | 9 ++++++++ .../msm/ipa/ipa_v3/ipahal/ipahal_reg_i.h | 3 +++ 6 files changed, 73 insertions(+), 1 deletion(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index a50cd0b807a2..934fbe189b1b 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -1654,6 +1654,21 @@ int ipa3_setup_dflt_rt_tables(void) return 0; } +static int ipa3_clkon_cfg_wa(void) +{ + struct ipahal_reg_clkon_cfg clkon_cfg = { 0 }; + int ret = 0; + + clkon_cfg.cgc_open_misc = 1; + + if (ipa3_cfg_clkon_cfg(&clkon_cfg)) { + IPAERR("fail to set cgc_open_misc = 1\n"); + ret = -EPERM; + } + + return ret; +} + static int ipa3_setup_exception_path(void) { struct ipa_ioc_add_hdr *hdr; @@ -4063,8 +4078,14 @@ static int ipa3_post_init(const struct ipa3_plat_drv_res *resource_p, ipa3_trigger_ipa_ready_cbs(); complete_all(&ipa3_ctx->init_completion_obj); - pr_info("IPA driver initialization was successful.\n"); + /* WA to disable MISC clock gating for IPA_HW_v3_1 */ + if (ipa3_ctx->ipa_hw_type == IPA_HW_v3_1) { + pr_info(" WA to set cgc_open_misc = 1\n"); + ipa3_clkon_cfg_wa(); + } + + pr_info("IPA driver initialization was successful\n"); return 0; fail_teth_bridge_driver_init: diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index ac7ef6a21952..5e1c55988ef2 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -1859,6 +1859,7 @@ void ipa3_dump_buff_internal(void *base, dma_addr_t phy_base, u32 size); #else #define IPA_DUMP_BUFF(base, phy_base, size) #endif +int ipa3_cfg_clkon_cfg(struct ipahal_reg_clkon_cfg *clkon_cfg); int ipa3_init_mem_partition(struct device_node *dev_node); int ipa3_controller_static_bind(struct ipa3_controller *controller, enum ipa_hw_type ipa_hw_type); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c index 6647f919a577..81ceda48b348 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c @@ -794,6 +794,28 @@ void _ipa_sram_settings_read_v3_0(void) ipa3_ctx->ip6_flt_tbl_nhash_lcl = 0; } +/** + * ipa3_cfg_clkon_cfg() - configure IPA clkon_cfg + * @clkon_cfg: IPA clkon_cfg + * + * Return codes: + * 0: success + */ +int ipa3_cfg_clkon_cfg(struct ipahal_reg_clkon_cfg *clkon_cfg) +{ + + IPA_ACTIVE_CLIENTS_INC_SIMPLE(); + + IPADBG("cgc_open_misc = %d\n", + clkon_cfg->cgc_open_misc); + + ipahal_write_reg_fields(IPA_CLKON_CFG, clkon_cfg); + + IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); + + return 0; +} + /** * ipa3_cfg_route() - configure IPA route * @route: IPA route diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c index 585f9e6bd492..0db9f30181a7 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c @@ -19,6 +19,7 @@ #include "ipahal_reg_i.h" static const char *ipareg_name_to_str[IPA_REG_MAX] = { + __stringify(IPA_CLKON_CFG), __stringify(IPA_ROUTE), __stringify(IPA_IRQ_STTS_EE_n), __stringify(IPA_IRQ_EN_EE_n), @@ -858,6 +859,18 @@ static void ipareg_construct_endp_init_hdr_n(enum ipahal_reg_name reg, IPA_ENDP_INIT_HDR_n_HDR_LEN_BMSK); } +static void ipareg_construct_clkon_cfg(enum ipahal_reg_name reg, + const void *fields, u32 *val) +{ + struct ipahal_reg_clkon_cfg *clkon_cfg; + + clkon_cfg = (struct ipahal_reg_clkon_cfg *)fields; + + IPA_SETFIELD_IN_REG(*val, clkon_cfg->cgc_open_misc, + IPA_CLKON_CFG_CGC_OPEN_MISC_SHFT, + IPA_CLKON_CFG_CGC_OPEN_MISC_BMSK); +} + static void ipareg_construct_route(enum ipahal_reg_name reg, const void *fields, u32 *val) { @@ -1159,6 +1172,9 @@ static struct ipahal_reg_obj ipahal_reg_objs[IPA_HW_MAX][IPA_REG_MAX] = { /* IPAv3.1 */ + [IPA_HW_v3_1][IPA_CLKON_CFG] = { + ipareg_construct_clkon_cfg, ipareg_parse_dummy, + 0x00000044, 0}, [IPA_HW_v3_1][IPA_IRQ_SUSPEND_INFO_EE_n] = { ipareg_construct_dummy, ipareg_parse_dummy, 0x00003030, 0x1000}, diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.h b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.h index c37415f13380..4db09475d5e2 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.h @@ -22,6 +22,7 @@ * array as well. */ enum ipahal_reg_name { + IPA_CLKON_CFG, IPA_ROUTE, IPA_IRQ_STTS_EE_n, IPA_IRQ_EN_EE_n, @@ -89,6 +90,14 @@ enum ipahal_reg_name { IPA_REG_MAX, }; +/* + * struct ipahal_reg_clkon_cfg - IPA clock on configuration register + * @cgc_open_misc: clock gating needs for MISC + */ +struct ipahal_reg_clkon_cfg { + u32 cgc_open_misc; +}; + /* * struct ipahal_reg_route - IPA route register * @route_dis: route disable diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg_i.h b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg_i.h index ac97e5ac0494..37458c4d0697 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg_i.h @@ -21,6 +21,9 @@ int ipahal_reg_init(enum ipa_hw_type ipa_hw_type); #define IPA_GETFIELD_FROM_REG(reg, shift, mask) \ (((reg) & (mask)) >> (shift)) +/* IPA_CLKON_CFG register */ +#define IPA_CLKON_CFG_CGC_OPEN_MISC_SHFT 0x3 +#define IPA_CLKON_CFG_CGC_OPEN_MISC_BMSK 0x8 /* IPA_ROUTE register */ #define IPA_ROUTE_ROUTE_DIS_SHFT 0x0