Loading msm/sde/sde_hw_vbif.c +29 −4 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ /* * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ #include <linux/iopoll.h> #include "sde_hwio.h" #include "sde_hw_catalog.h" Loading @@ -9,6 +10,7 @@ #include "sde_dbg.h" #define VBIF_VERSION 0x0000 #define VBIF_CLKON 0x0004 #define VBIF_CLK_FORCE_CTRL0 0x0008 #define VBIF_CLK_FORCE_CTRL1 0x000C #define VBIF_QOS_REMAP_00 0x0020 Loading @@ -33,6 +35,8 @@ #define VBIF_XIN_CLR_ERR 0x019C #define VBIF_XIN_HALT_CTRL0 0x0200 #define VBIF_XIN_HALT_CTRL1 0x0204 #define VBIF_AXI_HALT_CTRL0 0x0208 #define VBIF_AXI_HALT_CTRL1 0x020c #define VBIF_XINL_QOS_RP_REMAP_000 0x0550 #define VBIF_XINL_QOS_LVL_REMAP_000 0x0590 Loading Loading @@ -154,7 +158,7 @@ static u32 sde_hw_get_limit_conf(struct sde_hw_vbif *vbif, return limit; } static void sde_hw_set_halt_ctrl(struct sde_hw_vbif *vbif, static void sde_hw_set_xin_halt(struct sde_hw_vbif *vbif, u32 xin_id, bool enable) { struct sde_hw_blk_reg_map *c = &vbif->hw; Loading @@ -168,9 +172,10 @@ static void sde_hw_set_halt_ctrl(struct sde_hw_vbif *vbif, reg_val &= ~BIT(xin_id); SDE_REG_WRITE(c, VBIF_XIN_HALT_CTRL0, reg_val); wmb(); /* make sure that xin client halted */ } static bool sde_hw_get_halt_ctrl(struct sde_hw_vbif *vbif, static bool sde_hw_get_xin_halt_status(struct sde_hw_vbif *vbif, u32 xin_id) { struct sde_hw_blk_reg_map *c = &vbif->hw; Loading @@ -181,6 +186,24 @@ static bool sde_hw_get_halt_ctrl(struct sde_hw_vbif *vbif, return ((reg_val >> 16) & BIT(xin_id)) ? true : false; } static void sde_hw_set_axi_halt(struct sde_hw_vbif *vbif) { struct sde_hw_blk_reg_map *c = &vbif->hw; SDE_REG_WRITE(c, VBIF_CLKON, BIT(0)); SDE_REG_WRITE(c, VBIF_AXI_HALT_CTRL0, BIT(0)); wmb(); /* make sure that axi transactions are halted */ } static int sde_hw_get_axi_halt_status(struct sde_hw_vbif *vbif) { struct sde_hw_blk_reg_map *c = &vbif->hw; int ctrl = 0; return readl_poll_timeout(c->base_off + c->blk_off + VBIF_AXI_HALT_CTRL1, ctrl, ctrl & BIT(0), 100, 4000); } static void sde_hw_set_qos_remap(struct sde_hw_vbif *vbif, u32 xin_id, u32 level, u32 remap_level) { Loading Loading @@ -230,8 +253,10 @@ static void _setup_vbif_ops(const struct sde_mdss_cfg *m, { ops->set_limit_conf = sde_hw_set_limit_conf; ops->get_limit_conf = sde_hw_get_limit_conf; ops->set_halt_ctrl = sde_hw_set_halt_ctrl; ops->get_halt_ctrl = sde_hw_get_halt_ctrl; ops->set_axi_halt = sde_hw_set_axi_halt; ops->get_axi_halt_status = sde_hw_get_axi_halt_status; ops->set_xin_halt = sde_hw_set_xin_halt; ops->get_xin_halt_status = sde_hw_get_xin_halt_status; if (test_bit(SDE_VBIF_QOS_REMAP, &cap)) ops->set_qos_remap = sde_hw_set_qos_remap; if (test_bit(SDE_VBIF_DISABLE_SHAREABLE, &cap)) Loading msm/sde/sde_hw_vbif.h +17 −5 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ #ifndef _SDE_HW_VBIF_H Loading Loading @@ -38,23 +38,35 @@ struct sde_hw_vbif_ops { u32 xin_id, bool rd); /** * set_halt_ctrl - set halt control * set_xin_halt - set xin client halt control * @vbif: vbif context driver * @xin_id: client interface identifier * @enable: halt control enable */ void (*set_halt_ctrl)(struct sde_hw_vbif *vbif, void (*set_xin_halt)(struct sde_hw_vbif *vbif, u32 xin_id, bool enable); /** * get_halt_ctrl - get halt control * get_xin_halt_status - get xin client halt control * @vbif: vbif context driver * @xin_id: client interface identifier * @return: halt control enable */ bool (*get_halt_ctrl)(struct sde_hw_vbif *vbif, bool (*get_xin_halt_status)(struct sde_hw_vbif *vbif, u32 xin_id); /** * set_axi_halt - set axi port halt control * @vbif: vbif context driver */ void (*set_axi_halt)(struct sde_hw_vbif *vbif); /** * get_axi_halt_status - get axi port halt control status * @vbif: vbif context driver */ int (*get_axi_halt_status)(struct sde_hw_vbif *vbif); /** * set_qos_remap - set QoS priority remap * @vbif: vbif context driver Loading msm/sde/sde_kms.c +2 −0 Original line number Diff line number Diff line Loading @@ -2948,6 +2948,8 @@ static void sde_kms_handle_power_event(u32 event_type, void *usr) sde_irq_update(msm_kms, false); sde_kms->first_kickoff = false; _sde_kms_active_override(sde_kms, true); if (!is_sde_rsc_available(SDE_RSC_INDEX)) sde_vbif_axi_halt_request(sde_kms); } } Loading msm/sde/sde_vbif.c +65 −19 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__ Loading @@ -26,18 +26,18 @@ static int _sde_vbif_wait_for_xin_halt(struct sde_hw_vbif *vbif, u32 xin_id) bool status; int rc; if (!vbif || !vbif->cap || !vbif->ops.get_halt_ctrl) { if (!vbif || !vbif->cap || !vbif->ops.get_xin_halt_status) { SDE_ERROR("invalid arguments vbif %d\n", !vbif); return -EINVAL; } timeout = ktime_add_us(ktime_get(), vbif->cap->xin_halt_timeout); for (;;) { status = vbif->ops.get_halt_ctrl(vbif, xin_id); status = vbif->ops.get_xin_halt_status(vbif, xin_id); if (status) break; if (ktime_compare_safe(ktime_get(), timeout) > 0) { status = vbif->ops.get_halt_ctrl(vbif, xin_id); status = vbif->ops.get_xin_halt_status(vbif, xin_id); break; } usleep_range(501, 1000); Loading @@ -56,6 +56,26 @@ static int _sde_vbif_wait_for_xin_halt(struct sde_hw_vbif *vbif, u32 xin_id) return rc; } static int _sde_vbif_wait_for_axi_halt(struct sde_hw_vbif *vbif) { int rc; if (!vbif || !vbif->cap || !vbif->ops.get_axi_halt_status) { SDE_ERROR("invalid arguments vbif %d\n", !vbif); return -EINVAL; } rc = vbif->ops.get_axi_halt_status(vbif); if (rc) SDE_ERROR("VBIF %d AXI port(s) not halting. TIMEDOUT.\n", vbif->idx - VBIF_0); else SDE_DEBUG("VBIF %d AXI port(s) halted\n", vbif->idx - VBIF_0); return rc; } int sde_vbif_halt_plane_xin(struct sde_kms *sde_kms, u32 xin_id, u32 clk_ctrl) { struct sde_hw_vbif *vbif = NULL; Loading @@ -76,8 +96,8 @@ int sde_vbif_halt_plane_xin(struct sde_kms *sde_kms, u32 xin_id, u32 clk_ctrl) vbif = sde_kms->hw_vbif[VBIF_RT]; mdp = sde_kms->hw_mdp; if (!vbif || !mdp || !vbif->ops.get_halt_ctrl || !vbif->ops.set_halt_ctrl || if (!vbif || !mdp || !vbif->ops.get_xin_halt_status || !vbif->ops.set_xin_halt || !mdp->ops.setup_clk_force_ctrl) { SDE_ERROR("invalid vbif or mdp arguments\n"); return -EINVAL; Loading @@ -92,7 +112,7 @@ int sde_vbif_halt_plane_xin(struct sde_kms *sde_kms, u32 xin_id, u32 clk_ctrl) * while halting by forcing it ON only if it was not previously * forced on. If status is 1 then its already halted. */ status = vbif->ops.get_halt_ctrl(vbif, xin_id); status = vbif->ops.get_xin_halt_status(vbif, xin_id); if (status) { mutex_unlock(&vbif->mutex); return 0; Loading @@ -101,7 +121,7 @@ int sde_vbif_halt_plane_xin(struct sde_kms *sde_kms, u32 xin_id, u32 clk_ctrl) forced_on = mdp->ops.setup_clk_force_ctrl(mdp, clk_ctrl, true); /* send halt request for unused plane's xin client */ vbif->ops.set_halt_ctrl(vbif, xin_id, true); vbif->ops.set_xin_halt(vbif, xin_id, true); rc = _sde_vbif_wait_for_xin_halt(vbif, xin_id); if (rc) { Loading @@ -112,7 +132,7 @@ int sde_vbif_halt_plane_xin(struct sde_kms *sde_kms, u32 xin_id, u32 clk_ctrl) } /* open xin client to enable transactions */ vbif->ops.set_halt_ctrl(vbif, xin_id, false); vbif->ops.set_xin_halt(vbif, xin_id, false); if (forced_on) mdp->ops.setup_clk_force_ctrl(mdp, clk_ctrl, false); Loading Loading @@ -250,7 +270,7 @@ void sde_vbif_set_ot_limit(struct sde_kms *sde_kms, if (!mdp->ops.setup_clk_force_ctrl || !vbif->ops.set_limit_conf || !vbif->ops.set_halt_ctrl) !vbif->ops.set_xin_halt) return; mutex_lock(&vbif->mutex); Loading @@ -273,13 +293,13 @@ void sde_vbif_set_ot_limit(struct sde_kms *sde_kms, vbif->ops.set_limit_conf(vbif, params->xin_id, params->rd, ot_lim); vbif->ops.set_halt_ctrl(vbif, params->xin_id, true); vbif->ops.set_xin_halt(vbif, params->xin_id, true); ret = _sde_vbif_wait_for_xin_halt(vbif, params->xin_id); if (ret) SDE_EVT32(vbif->idx, params->xin_id); vbif->ops.set_halt_ctrl(vbif, params->xin_id, false); vbif->ops.set_xin_halt(vbif, params->xin_id, false); if (forced_on) mdp->ops.setup_clk_force_ctrl(mdp, params->clk_ctrl, false); Loading Loading @@ -357,7 +377,7 @@ bool sde_vbif_set_xin_halt(struct sde_kms *sde_kms, } if (!mdp->ops.setup_clk_force_ctrl || !vbif->ops.set_halt_ctrl) !vbif->ops.set_xin_halt) return false; mutex_lock(&vbif->mutex); Loading @@ -368,13 +388,13 @@ bool sde_vbif_set_xin_halt(struct sde_kms *sde_kms, forced_on = mdp->ops.setup_clk_force_ctrl(mdp, params->clk_ctrl, true); vbif->ops.set_halt_ctrl(vbif, params->xin_id, true); vbif->ops.set_xin_halt(vbif, params->xin_id, true); ret = _sde_vbif_wait_for_xin_halt(vbif, params->xin_id); if (ret) SDE_EVT32(vbif->idx, params->xin_id, SDE_EVTLOG_ERROR); } else { vbif->ops.set_halt_ctrl(vbif, params->xin_id, false); vbif->ops.set_xin_halt(vbif, params->xin_id, false); if (params->forced_on) mdp->ops.setup_clk_force_ctrl(mdp, Loading Loading @@ -511,6 +531,32 @@ void sde_vbif_init_memtypes(struct sde_kms *sde_kms) } } void sde_vbif_axi_halt_request(struct sde_kms *sde_kms) { struct sde_hw_vbif *vbif; int i; if (!sde_kms) { SDE_ERROR("invalid argument\n"); return; } if (!sde_kms_is_vbif_operation_allowed(sde_kms)) { SDE_DEBUG("vbif operations not permitted\n"); return; } for (i = 0; i < ARRAY_SIZE(sde_kms->hw_vbif); i++) { vbif = sde_kms->hw_vbif[i]; if (vbif && vbif->cap && vbif->ops.set_axi_halt) { mutex_lock(&vbif->mutex); vbif->ops.set_axi_halt(vbif); _sde_vbif_wait_for_axi_halt(vbif); mutex_unlock(&vbif->mutex); } } } int sde_vbif_halt_xin_mask(struct sde_kms *sde_kms, u32 xin_id_mask, bool halt) { Loading @@ -524,7 +570,7 @@ int sde_vbif_halt_xin_mask(struct sde_kms *sde_kms, u32 xin_id_mask, vbif = sde_kms->hw_vbif[VBIF_RT]; if (!vbif->ops.get_halt_ctrl || !vbif->ops.set_halt_ctrl) if (!vbif->ops.get_xin_halt_status || !vbif->ops.set_xin_halt) return 0; SDE_EVT32(xin_id_mask, halt); Loading @@ -533,16 +579,16 @@ int sde_vbif_halt_xin_mask(struct sde_kms *sde_kms, u32 xin_id_mask, if (xin_id_mask & BIT(i)) { /* unhalt the xin-clients */ if (!halt) { vbif->ops.set_halt_ctrl(vbif, i, false); vbif->ops.set_xin_halt(vbif, i, false); continue; } status = vbif->ops.get_halt_ctrl(vbif, i); status = vbif->ops.get_xin_halt_status(vbif, i); if (status) continue; /* halt xin-clients and wait for ack */ vbif->ops.set_halt_ctrl(vbif, i, true); vbif->ops.set_xin_halt(vbif, i, true); rc = _sde_vbif_wait_for_xin_halt(vbif, i); if (rc) { Loading msm/sde/sde_vbif.h +7 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ #ifndef __SDE_VBIF_H__ Loading Loading @@ -98,6 +98,12 @@ void sde_vbif_clear_errors(struct sde_kms *sde_kms); */ void sde_vbif_init_memtypes(struct sde_kms *sde_kms); /** * sde_vbif_axi_halt_request - halt all axi transcations on vbif * @sde_kms: SDE handler */ void sde_vbif_axi_halt_request(struct sde_kms *sde_kms); /** * sde_vbif_halt_plane_xin - halts the xin client for the unused plane * On unused plane, check if the vbif for this plane is idle or not. Loading Loading
msm/sde/sde_hw_vbif.c +29 −4 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ /* * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ #include <linux/iopoll.h> #include "sde_hwio.h" #include "sde_hw_catalog.h" Loading @@ -9,6 +10,7 @@ #include "sde_dbg.h" #define VBIF_VERSION 0x0000 #define VBIF_CLKON 0x0004 #define VBIF_CLK_FORCE_CTRL0 0x0008 #define VBIF_CLK_FORCE_CTRL1 0x000C #define VBIF_QOS_REMAP_00 0x0020 Loading @@ -33,6 +35,8 @@ #define VBIF_XIN_CLR_ERR 0x019C #define VBIF_XIN_HALT_CTRL0 0x0200 #define VBIF_XIN_HALT_CTRL1 0x0204 #define VBIF_AXI_HALT_CTRL0 0x0208 #define VBIF_AXI_HALT_CTRL1 0x020c #define VBIF_XINL_QOS_RP_REMAP_000 0x0550 #define VBIF_XINL_QOS_LVL_REMAP_000 0x0590 Loading Loading @@ -154,7 +158,7 @@ static u32 sde_hw_get_limit_conf(struct sde_hw_vbif *vbif, return limit; } static void sde_hw_set_halt_ctrl(struct sde_hw_vbif *vbif, static void sde_hw_set_xin_halt(struct sde_hw_vbif *vbif, u32 xin_id, bool enable) { struct sde_hw_blk_reg_map *c = &vbif->hw; Loading @@ -168,9 +172,10 @@ static void sde_hw_set_halt_ctrl(struct sde_hw_vbif *vbif, reg_val &= ~BIT(xin_id); SDE_REG_WRITE(c, VBIF_XIN_HALT_CTRL0, reg_val); wmb(); /* make sure that xin client halted */ } static bool sde_hw_get_halt_ctrl(struct sde_hw_vbif *vbif, static bool sde_hw_get_xin_halt_status(struct sde_hw_vbif *vbif, u32 xin_id) { struct sde_hw_blk_reg_map *c = &vbif->hw; Loading @@ -181,6 +186,24 @@ static bool sde_hw_get_halt_ctrl(struct sde_hw_vbif *vbif, return ((reg_val >> 16) & BIT(xin_id)) ? true : false; } static void sde_hw_set_axi_halt(struct sde_hw_vbif *vbif) { struct sde_hw_blk_reg_map *c = &vbif->hw; SDE_REG_WRITE(c, VBIF_CLKON, BIT(0)); SDE_REG_WRITE(c, VBIF_AXI_HALT_CTRL0, BIT(0)); wmb(); /* make sure that axi transactions are halted */ } static int sde_hw_get_axi_halt_status(struct sde_hw_vbif *vbif) { struct sde_hw_blk_reg_map *c = &vbif->hw; int ctrl = 0; return readl_poll_timeout(c->base_off + c->blk_off + VBIF_AXI_HALT_CTRL1, ctrl, ctrl & BIT(0), 100, 4000); } static void sde_hw_set_qos_remap(struct sde_hw_vbif *vbif, u32 xin_id, u32 level, u32 remap_level) { Loading Loading @@ -230,8 +253,10 @@ static void _setup_vbif_ops(const struct sde_mdss_cfg *m, { ops->set_limit_conf = sde_hw_set_limit_conf; ops->get_limit_conf = sde_hw_get_limit_conf; ops->set_halt_ctrl = sde_hw_set_halt_ctrl; ops->get_halt_ctrl = sde_hw_get_halt_ctrl; ops->set_axi_halt = sde_hw_set_axi_halt; ops->get_axi_halt_status = sde_hw_get_axi_halt_status; ops->set_xin_halt = sde_hw_set_xin_halt; ops->get_xin_halt_status = sde_hw_get_xin_halt_status; if (test_bit(SDE_VBIF_QOS_REMAP, &cap)) ops->set_qos_remap = sde_hw_set_qos_remap; if (test_bit(SDE_VBIF_DISABLE_SHAREABLE, &cap)) Loading
msm/sde/sde_hw_vbif.h +17 −5 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ #ifndef _SDE_HW_VBIF_H Loading Loading @@ -38,23 +38,35 @@ struct sde_hw_vbif_ops { u32 xin_id, bool rd); /** * set_halt_ctrl - set halt control * set_xin_halt - set xin client halt control * @vbif: vbif context driver * @xin_id: client interface identifier * @enable: halt control enable */ void (*set_halt_ctrl)(struct sde_hw_vbif *vbif, void (*set_xin_halt)(struct sde_hw_vbif *vbif, u32 xin_id, bool enable); /** * get_halt_ctrl - get halt control * get_xin_halt_status - get xin client halt control * @vbif: vbif context driver * @xin_id: client interface identifier * @return: halt control enable */ bool (*get_halt_ctrl)(struct sde_hw_vbif *vbif, bool (*get_xin_halt_status)(struct sde_hw_vbif *vbif, u32 xin_id); /** * set_axi_halt - set axi port halt control * @vbif: vbif context driver */ void (*set_axi_halt)(struct sde_hw_vbif *vbif); /** * get_axi_halt_status - get axi port halt control status * @vbif: vbif context driver */ int (*get_axi_halt_status)(struct sde_hw_vbif *vbif); /** * set_qos_remap - set QoS priority remap * @vbif: vbif context driver Loading
msm/sde/sde_kms.c +2 −0 Original line number Diff line number Diff line Loading @@ -2948,6 +2948,8 @@ static void sde_kms_handle_power_event(u32 event_type, void *usr) sde_irq_update(msm_kms, false); sde_kms->first_kickoff = false; _sde_kms_active_override(sde_kms, true); if (!is_sde_rsc_available(SDE_RSC_INDEX)) sde_vbif_axi_halt_request(sde_kms); } } Loading
msm/sde/sde_vbif.c +65 −19 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__ Loading @@ -26,18 +26,18 @@ static int _sde_vbif_wait_for_xin_halt(struct sde_hw_vbif *vbif, u32 xin_id) bool status; int rc; if (!vbif || !vbif->cap || !vbif->ops.get_halt_ctrl) { if (!vbif || !vbif->cap || !vbif->ops.get_xin_halt_status) { SDE_ERROR("invalid arguments vbif %d\n", !vbif); return -EINVAL; } timeout = ktime_add_us(ktime_get(), vbif->cap->xin_halt_timeout); for (;;) { status = vbif->ops.get_halt_ctrl(vbif, xin_id); status = vbif->ops.get_xin_halt_status(vbif, xin_id); if (status) break; if (ktime_compare_safe(ktime_get(), timeout) > 0) { status = vbif->ops.get_halt_ctrl(vbif, xin_id); status = vbif->ops.get_xin_halt_status(vbif, xin_id); break; } usleep_range(501, 1000); Loading @@ -56,6 +56,26 @@ static int _sde_vbif_wait_for_xin_halt(struct sde_hw_vbif *vbif, u32 xin_id) return rc; } static int _sde_vbif_wait_for_axi_halt(struct sde_hw_vbif *vbif) { int rc; if (!vbif || !vbif->cap || !vbif->ops.get_axi_halt_status) { SDE_ERROR("invalid arguments vbif %d\n", !vbif); return -EINVAL; } rc = vbif->ops.get_axi_halt_status(vbif); if (rc) SDE_ERROR("VBIF %d AXI port(s) not halting. TIMEDOUT.\n", vbif->idx - VBIF_0); else SDE_DEBUG("VBIF %d AXI port(s) halted\n", vbif->idx - VBIF_0); return rc; } int sde_vbif_halt_plane_xin(struct sde_kms *sde_kms, u32 xin_id, u32 clk_ctrl) { struct sde_hw_vbif *vbif = NULL; Loading @@ -76,8 +96,8 @@ int sde_vbif_halt_plane_xin(struct sde_kms *sde_kms, u32 xin_id, u32 clk_ctrl) vbif = sde_kms->hw_vbif[VBIF_RT]; mdp = sde_kms->hw_mdp; if (!vbif || !mdp || !vbif->ops.get_halt_ctrl || !vbif->ops.set_halt_ctrl || if (!vbif || !mdp || !vbif->ops.get_xin_halt_status || !vbif->ops.set_xin_halt || !mdp->ops.setup_clk_force_ctrl) { SDE_ERROR("invalid vbif or mdp arguments\n"); return -EINVAL; Loading @@ -92,7 +112,7 @@ int sde_vbif_halt_plane_xin(struct sde_kms *sde_kms, u32 xin_id, u32 clk_ctrl) * while halting by forcing it ON only if it was not previously * forced on. If status is 1 then its already halted. */ status = vbif->ops.get_halt_ctrl(vbif, xin_id); status = vbif->ops.get_xin_halt_status(vbif, xin_id); if (status) { mutex_unlock(&vbif->mutex); return 0; Loading @@ -101,7 +121,7 @@ int sde_vbif_halt_plane_xin(struct sde_kms *sde_kms, u32 xin_id, u32 clk_ctrl) forced_on = mdp->ops.setup_clk_force_ctrl(mdp, clk_ctrl, true); /* send halt request for unused plane's xin client */ vbif->ops.set_halt_ctrl(vbif, xin_id, true); vbif->ops.set_xin_halt(vbif, xin_id, true); rc = _sde_vbif_wait_for_xin_halt(vbif, xin_id); if (rc) { Loading @@ -112,7 +132,7 @@ int sde_vbif_halt_plane_xin(struct sde_kms *sde_kms, u32 xin_id, u32 clk_ctrl) } /* open xin client to enable transactions */ vbif->ops.set_halt_ctrl(vbif, xin_id, false); vbif->ops.set_xin_halt(vbif, xin_id, false); if (forced_on) mdp->ops.setup_clk_force_ctrl(mdp, clk_ctrl, false); Loading Loading @@ -250,7 +270,7 @@ void sde_vbif_set_ot_limit(struct sde_kms *sde_kms, if (!mdp->ops.setup_clk_force_ctrl || !vbif->ops.set_limit_conf || !vbif->ops.set_halt_ctrl) !vbif->ops.set_xin_halt) return; mutex_lock(&vbif->mutex); Loading @@ -273,13 +293,13 @@ void sde_vbif_set_ot_limit(struct sde_kms *sde_kms, vbif->ops.set_limit_conf(vbif, params->xin_id, params->rd, ot_lim); vbif->ops.set_halt_ctrl(vbif, params->xin_id, true); vbif->ops.set_xin_halt(vbif, params->xin_id, true); ret = _sde_vbif_wait_for_xin_halt(vbif, params->xin_id); if (ret) SDE_EVT32(vbif->idx, params->xin_id); vbif->ops.set_halt_ctrl(vbif, params->xin_id, false); vbif->ops.set_xin_halt(vbif, params->xin_id, false); if (forced_on) mdp->ops.setup_clk_force_ctrl(mdp, params->clk_ctrl, false); Loading Loading @@ -357,7 +377,7 @@ bool sde_vbif_set_xin_halt(struct sde_kms *sde_kms, } if (!mdp->ops.setup_clk_force_ctrl || !vbif->ops.set_halt_ctrl) !vbif->ops.set_xin_halt) return false; mutex_lock(&vbif->mutex); Loading @@ -368,13 +388,13 @@ bool sde_vbif_set_xin_halt(struct sde_kms *sde_kms, forced_on = mdp->ops.setup_clk_force_ctrl(mdp, params->clk_ctrl, true); vbif->ops.set_halt_ctrl(vbif, params->xin_id, true); vbif->ops.set_xin_halt(vbif, params->xin_id, true); ret = _sde_vbif_wait_for_xin_halt(vbif, params->xin_id); if (ret) SDE_EVT32(vbif->idx, params->xin_id, SDE_EVTLOG_ERROR); } else { vbif->ops.set_halt_ctrl(vbif, params->xin_id, false); vbif->ops.set_xin_halt(vbif, params->xin_id, false); if (params->forced_on) mdp->ops.setup_clk_force_ctrl(mdp, Loading Loading @@ -511,6 +531,32 @@ void sde_vbif_init_memtypes(struct sde_kms *sde_kms) } } void sde_vbif_axi_halt_request(struct sde_kms *sde_kms) { struct sde_hw_vbif *vbif; int i; if (!sde_kms) { SDE_ERROR("invalid argument\n"); return; } if (!sde_kms_is_vbif_operation_allowed(sde_kms)) { SDE_DEBUG("vbif operations not permitted\n"); return; } for (i = 0; i < ARRAY_SIZE(sde_kms->hw_vbif); i++) { vbif = sde_kms->hw_vbif[i]; if (vbif && vbif->cap && vbif->ops.set_axi_halt) { mutex_lock(&vbif->mutex); vbif->ops.set_axi_halt(vbif); _sde_vbif_wait_for_axi_halt(vbif); mutex_unlock(&vbif->mutex); } } } int sde_vbif_halt_xin_mask(struct sde_kms *sde_kms, u32 xin_id_mask, bool halt) { Loading @@ -524,7 +570,7 @@ int sde_vbif_halt_xin_mask(struct sde_kms *sde_kms, u32 xin_id_mask, vbif = sde_kms->hw_vbif[VBIF_RT]; if (!vbif->ops.get_halt_ctrl || !vbif->ops.set_halt_ctrl) if (!vbif->ops.get_xin_halt_status || !vbif->ops.set_xin_halt) return 0; SDE_EVT32(xin_id_mask, halt); Loading @@ -533,16 +579,16 @@ int sde_vbif_halt_xin_mask(struct sde_kms *sde_kms, u32 xin_id_mask, if (xin_id_mask & BIT(i)) { /* unhalt the xin-clients */ if (!halt) { vbif->ops.set_halt_ctrl(vbif, i, false); vbif->ops.set_xin_halt(vbif, i, false); continue; } status = vbif->ops.get_halt_ctrl(vbif, i); status = vbif->ops.get_xin_halt_status(vbif, i); if (status) continue; /* halt xin-clients and wait for ack */ vbif->ops.set_halt_ctrl(vbif, i, true); vbif->ops.set_xin_halt(vbif, i, true); rc = _sde_vbif_wait_for_xin_halt(vbif, i); if (rc) { Loading
msm/sde/sde_vbif.h +7 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ #ifndef __SDE_VBIF_H__ Loading Loading @@ -98,6 +98,12 @@ void sde_vbif_clear_errors(struct sde_kms *sde_kms); */ void sde_vbif_init_memtypes(struct sde_kms *sde_kms); /** * sde_vbif_axi_halt_request - halt all axi transcations on vbif * @sde_kms: SDE handler */ void sde_vbif_axi_halt_request(struct sde_kms *sde_kms); /** * sde_vbif_halt_plane_xin - halts the xin client for the unused plane * On unused plane, check if the vbif for this plane is idle or not. Loading