diff --git a/msm/sde/sde_hw_catalog.c b/msm/sde/sde_hw_catalog.c index 28de29d1..3ab9a242 100644 --- a/msm/sde/sde_hw_catalog.c +++ b/msm/sde/sde_hw_catalog.c @@ -1740,7 +1740,7 @@ static int sde_ctl_parse_dt(struct device_node *np, set_bit(SDE_CTL_PINGPONG_SPLIT, &ctl->features); if (IS_SDE_CTL_REV_100(sde_cfg->ctl_rev)) set_bit(SDE_CTL_ACTIVE_CFG, &ctl->features); - if (IS_SDE_UIDLE_REV_100(sde_cfg->uidle_cfg.uidle_rev)) + if (SDE_UIDLE_MAJOR(sde_cfg->uidle_cfg.uidle_rev)) set_bit(SDE_CTL_UIDLE, &ctl->features); if (SDE_HW_MAJOR(sde_cfg->hwversion) >= SDE_HW_MAJOR(SDE_HW_VER_700)) @@ -4222,7 +4222,8 @@ static void _sde_hw_setup_uidle(struct sde_uidle_cfg *uidle_cfg) if (!uidle_cfg->uidle_rev) return; - if (IS_SDE_UIDLE_REV_100(uidle_cfg->uidle_rev)) { + if ((IS_SDE_UIDLE_REV_101(uidle_cfg->uidle_rev)) || + (IS_SDE_UIDLE_REV_100(uidle_cfg->uidle_rev))) { uidle_cfg->fal10_exit_cnt = SDE_UIDLE_FAL10_EXIT_CNT; uidle_cfg->fal10_exit_danger = SDE_UIDLE_FAL10_EXIT_DANGER; uidle_cfg->fal10_danger = SDE_UIDLE_FAL10_DANGER; @@ -4232,6 +4233,9 @@ static void _sde_hw_setup_uidle(struct sde_uidle_cfg *uidle_cfg) uidle_cfg->max_dwnscale = SDE_UIDLE_MAX_DWNSCALE; uidle_cfg->max_fps = SDE_UIDLE_MAX_FPS; uidle_cfg->debugfs_ctrl = true; + if (IS_SDE_UIDLE_REV_101(uidle_cfg->uidle_rev)) + set_bit(SDE_UIDLE_QACTIVE_OVERRIDE, + &uidle_cfg->features); } else { pr_err("invalid uidle rev:0x%x, disabling uidle\n", uidle_cfg->uidle_rev); @@ -4436,7 +4440,7 @@ static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev) set_bit(SDE_MDP_DHDR_MEMPOOL_4K, &sde_cfg->mdp[0].features); sde_cfg->has_vig_p010 = true; sde_cfg->true_inline_rot_rev = SDE_INLINE_ROT_VERSION_2_0_0; - sde_cfg->uidle_cfg.uidle_rev = SDE_UIDLE_VERSION_1_0_0; + sde_cfg->uidle_cfg.uidle_rev = SDE_UIDLE_VERSION_1_0_1; sde_cfg->vbif_disable_inner_outer_shareable = true; } else { SDE_ERROR("unsupported chipset id:%X\n", hw_rev); diff --git a/msm/sde/sde_hw_catalog.h b/msm/sde/sde_hw_catalog.h index 6d26a726..d147bb23 100644 --- a/msm/sde/sde_hw_catalog.h +++ b/msm/sde/sde_hw_catalog.h @@ -105,9 +105,15 @@ /* * UIDLE supported versions */ -#define SDE_UIDLE_VERSION_1_0_0 0x100 +#define SDE_UIDLE_VERSION_1_0_0 0x100 +#define SDE_UIDLE_VERSION_1_0_1 0x101 + #define IS_SDE_UIDLE_REV_100(rev) \ ((rev) == SDE_UIDLE_VERSION_1_0_0) +#define IS_SDE_UIDLE_REV_101(rev) \ + ((rev) == SDE_UIDLE_VERSION_1_0_1) + +#define SDE_UIDLE_MAJOR(rev) ((rev) >> 8) #define SDE_HW_UBWC_VER(rev) \ SDE_HW_VER((((rev) >> 8) & 0xF), (((rev) >> 4) & 0xF), ((rev) & 0xF)) @@ -503,6 +509,16 @@ enum { SDE_VBIF_MAX }; +/** + * uidle features + * @SDE_UIDLE_QACTIVE_OVERRIDE uidle sends qactive signal + * @SDE_UIDLE_MAX maximum value + */ +enum { + SDE_UIDLE_QACTIVE_OVERRIDE = 0x1, + SDE_UIDLE_MAX +}; + /** * MACRO SDE_HW_BLK_INFO - information of HW blocks inside SDE * @name: string name for debug purposes diff --git a/msm/sde/sde_hw_uidle.c b/msm/sde/sde_hw_uidle.c index f1a8a8b1..bb691520 100644 --- a/msm/sde/sde_hw_uidle.c +++ b/msm/sde/sde_hw_uidle.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. * */ @@ -13,6 +13,7 @@ #define UIDLE_CTL 0x0 #define UIDLE_STATUS 0x4 #define UIDLE_FAL10_VETO_OVERRIDE 0x8 +#define UIDLE_QACTIVE_HF_OVERRIDE 0xc #define UIDLE_WD_TIMER_CTL 0x10 #define UIDLE_WD_TIMER_CTL2 0x14 @@ -177,6 +178,18 @@ void sde_hw_uidle_setup_ctl(struct sde_hw_uidle *uidle, SDE_REG_WRITE(c, UIDLE_CTL, reg_val); } +static void sde_hw_uilde_active_override(struct sde_hw_uidle *uidle, + bool enable) +{ + struct sde_hw_blk_reg_map *c = &uidle->hw; + u32 reg_val = 0; + + if (enable) + reg_val = BIT(0) | BIT(31); + + SDE_REG_WRITE(c, UIDLE_QACTIVE_HF_OVERRIDE, reg_val); +} + static inline void _setup_uidle_ops(struct sde_hw_uidle_ops *ops, unsigned long cap) { @@ -185,6 +198,8 @@ static inline void _setup_uidle_ops(struct sde_hw_uidle_ops *ops, ops->uidle_setup_cntr = sde_hw_uidle_setup_cntr; ops->uidle_get_cntr = sde_hw_uidle_get_cntr; ops->uidle_get_status = sde_hw_uidle_get_status; + if (cap & BIT(SDE_UIDLE_QACTIVE_OVERRIDE)) + ops->active_override_enable = sde_hw_uilde_active_override; } struct sde_hw_uidle *sde_hw_uidle_init(enum sde_uidle idx, diff --git a/msm/sde/sde_hw_uidle.h b/msm/sde/sde_hw_uidle.h index de3d7165..847bcfac 100644 --- a/msm/sde/sde_hw_uidle.h +++ b/msm/sde/sde_hw_uidle.h @@ -104,6 +104,13 @@ struct sde_hw_uidle_ops { void (*uidle_get_status)(struct sde_hw_uidle *uidle, struct sde_uidle_status *status); + /** + * active_override_enable - enable/disable qactive signal override + * @uidle: uidle context driver + * @enable: enable/disable + */ + void (*active_override_enable)(struct sde_hw_uidle *uidle, + bool enable); }; struct sde_hw_uidle { diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index c1c6486e..a56087da 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -2901,6 +2901,23 @@ static void _sde_kms_set_lutdma_vbif_remap(struct sde_kms *sde_kms) sde_vbif_set_qos_remap(sde_kms, &qos_params); } +static int _sde_kms_active_override(struct sde_kms *sde_kms, bool enable) +{ + struct sde_hw_uidle *uidle; + + if (!sde_kms) { + SDE_ERROR("invalid kms\n"); + return -EINVAL; + } + + uidle = sde_kms->hw_uidle; + + if (uidle && uidle->ops.active_override_enable) + uidle->ops.active_override_enable(uidle, enable); + + return 0; +} + static void sde_kms_handle_power_event(u32 event_type, void *usr) { struct sde_kms *sde_kms = usr; @@ -2922,6 +2939,7 @@ static void sde_kms_handle_power_event(u32 event_type, void *usr) } else if (event_type == SDE_POWER_EVENT_PRE_DISABLE) { sde_irq_update(msm_kms, false); sde_kms->first_kickoff = false; + _sde_kms_active_override(sde_kms, true); } }