summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm64/configs/msm-auto-gvm-perf_defconfig14
-rw-r--r--arch/arm64/configs/msm-auto-gvm_defconfig1
-rw-r--r--drivers/gpu/drm/msm/sde/sde_connector.c15
-rw-r--r--drivers/gpu/drm/msm/sde/sde_kms.c8
-rw-r--r--drivers/gpu/drm/msm/sde/sde_splash.c134
-rw-r--r--drivers/gpu/drm/msm/sde/sde_splash.h24
-rw-r--r--drivers/mmc/card/block.c17
-rw-r--r--kernel/auditsc.c5
8 files changed, 172 insertions, 46 deletions
diff --git a/arch/arm64/configs/msm-auto-gvm-perf_defconfig b/arch/arm64/configs/msm-auto-gvm-perf_defconfig
index 55655ac06803..63f492ee9786 100644
--- a/arch/arm64/configs/msm-auto-gvm-perf_defconfig
+++ b/arch/arm64/configs/msm-auto-gvm-perf_defconfig
@@ -5,6 +5,10 @@ CONFIG_AUDIT=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_IRQ_TIME_ACCOUNTING=y
+CONFIG_RCU_EXPERT=y
+CONFIG_RCU_FAST_NO_HZ=y
+CONFIG_RCU_NOCB_CPU=y
+CONFIG_RCU_NOCB_CPU_ALL=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_CPU_MAX_BUF_SHIFT=15
@@ -15,10 +19,15 @@ CONFIG_CGROUP_SCHED=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_SCHED_HMP=y
CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_PID_NS is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_KALLSYMS_ALL=y
+# CONFIG_MEMBARRIER is not set
CONFIG_EMBEDDED=y
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_COMPAT_BRK is not set
CONFIG_PROFILING=y
CONFIG_CC_STACKPROTECTOR_REGULAR=y
CONFIG_MODULES=y
@@ -35,6 +44,7 @@ CONFIG_PCI_HOST_GENERIC=y
CONFIG_SCHED_MC=y
CONFIG_NR_CPUS=8
CONFIG_PREEMPT=y
+CONFIG_HZ_100=y
CONFIG_ARM64_REG_REBALANCE_ON_CTX_SW=y
CONFIG_ZSMALLOC=y
CONFIG_BALANCE_ANON_FILE_RECLAIM=y
@@ -42,11 +52,13 @@ CONFIG_FORCE_ALLOC_FROM_DMA_ZONE=y
CONFIG_SECCOMP=y
CONFIG_ARMV8_DEPRECATED=y
CONFIG_SWP_EMULATION=y
+# CONFIG_EFI is not set
CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y
CONFIG_COMPAT=y
CONFIG_PM_AUTOSLEEP=y
CONFIG_PM_WAKELOCKS=y
CONFIG_PM_WAKELOCKS_LIMIT=0
+# CONFIG_PM_WAKELOCKS_GC is not set
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
@@ -369,6 +381,8 @@ CONFIG_DEBUG_INFO=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_PANIC_TIMEOUT=5
CONFIG_SCHEDSTATS=y
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
CONFIG_IPC_LOGGING=y
CONFIG_SECURITY=y
CONFIG_SECURITY_NETWORK=y
diff --git a/arch/arm64/configs/msm-auto-gvm_defconfig b/arch/arm64/configs/msm-auto-gvm_defconfig
index 177ccef17f77..7e6d0f152306 100644
--- a/arch/arm64/configs/msm-auto-gvm_defconfig
+++ b/arch/arm64/configs/msm-auto-gvm_defconfig
@@ -33,6 +33,7 @@ CONFIG_PCI_HOST_GENERIC=y
CONFIG_SCHED_MC=y
CONFIG_NR_CPUS=8
CONFIG_PREEMPT=y
+CONFIG_HZ_100=y
CONFIG_ARM64_REG_REBALANCE_ON_CTX_SW=y
CONFIG_ZSMALLOC=y
CONFIG_BALANCE_ANON_FILE_RECLAIM=y
diff --git a/drivers/gpu/drm/msm/sde/sde_connector.c b/drivers/gpu/drm/msm/sde/sde_connector.c
index f74a682c5f04..1bc3d0a926eb 100644
--- a/drivers/gpu/drm/msm/sde/sde_connector.c
+++ b/drivers/gpu/drm/msm/sde/sde_connector.c
@@ -572,6 +572,7 @@ void sde_connector_complete_commit(struct drm_connector *connector)
{
struct drm_device *dev;
struct msm_drm_private *priv;
+ struct sde_connector *c_conn;
if (!connector) {
SDE_ERROR("invalid connector\n");
@@ -584,11 +585,17 @@ void sde_connector_complete_commit(struct drm_connector *connector)
/* signal connector's retire fence */
sde_fence_signal(&to_sde_connector(connector)->retire_fence, 0);
- /* after first vsync comes,
- * early splash resource should start to be released.
+ /*
+ * After LK totally exits, LK's early splash resource
+ * should be released.
*/
- if (sde_splash_get_lk_complete_status(priv->kms))
- sde_splash_free_resource(priv->kms, &priv->phandle);
+ if (sde_splash_get_lk_complete_status(priv->kms)) {
+ c_conn = to_sde_connector(connector);
+
+ sde_splash_free_resource(priv->kms, &priv->phandle,
+ c_conn->connector_type,
+ c_conn->display);
+ }
}
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c
index 1da8b5b4ff10..86a5c23b5258 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.c
+++ b/drivers/gpu/drm/msm/sde/sde_kms.c
@@ -345,10 +345,10 @@ static void sde_kms_prepare_commit(struct msm_kms *kms,
if (sde_kms->splash_info.handoff &&
sde_kms->splash_info.display_splash_enabled)
- sde_splash_lk_stop_splash(kms);
- else
- sde_power_resource_enable(&priv->phandle,
- sde_kms->core_client, true);
+ sde_splash_lk_stop_splash(kms, state);
+
+ sde_power_resource_enable(&priv->phandle,
+ sde_kms->core_client, true);
}
static void sde_kms_commit(struct msm_kms *kms,
diff --git a/drivers/gpu/drm/msm/sde/sde_splash.c b/drivers/gpu/drm/msm/sde/sde_splash.c
index f124bd7d5904..9c3964e99c1f 100644
--- a/drivers/gpu/drm/msm/sde/sde_splash.c
+++ b/drivers/gpu/drm/msm/sde/sde_splash.c
@@ -313,6 +313,15 @@ static void _sde_splash_sent_pipe_update_uevent(struct sde_kms *sde_kms)
kfree(event_string);
}
+static void _sde_splash_get_connector_ref_cnt(struct sde_splash_info *sinfo,
+ u32 *hdmi_cnt, u32 *dsi_cnt)
+{
+ mutex_lock(&sde_splash_lock);
+ *hdmi_cnt = sinfo->hdmi_connector_cnt;
+ *dsi_cnt = sinfo->dsi_connector_cnt;
+ mutex_unlock(&sde_splash_lock);
+}
+
static int _sde_splash_free_module_resource(struct msm_mmu *mmu,
struct sde_splash_info *sinfo)
{
@@ -339,6 +348,29 @@ static int _sde_splash_free_module_resource(struct msm_mmu *mmu,
return 0;
}
+static bool _sde_splash_validate_commit(struct sde_kms *sde_kms,
+ struct drm_atomic_state *state)
+{
+ int i, nplanes;
+ struct drm_plane *plane;
+ struct drm_device *dev = sde_kms->dev;
+
+ nplanes = dev->mode_config.num_total_plane;
+
+ for (i = 0; i < nplanes; i++) {
+ plane = state->planes[i];
+
+ /*
+ * As plane state has been swapped, we need to check
+ * fb in state->planes, not fb in state->plane_state.
+ */
+ if (plane && plane->fb)
+ return true;
+ }
+
+ return false;
+}
+
__ref int sde_splash_init(struct sde_power_handle *phandle, struct msm_kms *kms)
{
struct sde_kms *sde_kms;
@@ -369,8 +401,7 @@ __ref int sde_splash_init(struct sde_power_handle *phandle, struct msm_kms *kms)
sde_power_data_bus_bandwidth_ctrl(phandle,
sde_kms->core_client, false);
- ret = -EINVAL;
- break;
+ return -EINVAL;
}
}
@@ -716,11 +747,17 @@ bool sde_splash_get_lk_complete_status(struct msm_kms *kms)
}
int sde_splash_free_resource(struct msm_kms *kms,
- struct sde_power_handle *phandle)
+ struct sde_power_handle *phandle,
+ int connector_type, void *display)
{
struct sde_kms *sde_kms;
struct sde_splash_info *sinfo;
struct msm_mmu *mmu;
+ struct dsi_display *dsi_display = display;
+ int ret = 0;
+ int hdmi_conn_count = 0;
+ int dsi_conn_count = 0;
+ static const char *last_commit_display_type = "unknown";
if (!phandle || !kms) {
SDE_ERROR("invalid phandle/kms.\n");
@@ -734,41 +771,88 @@ int sde_splash_free_resource(struct msm_kms *kms,
return -EINVAL;
}
+ /* Get connector number where the early splash in on. */
+ _sde_splash_get_connector_ref_cnt(sinfo, &hdmi_conn_count,
+ &dsi_conn_count);
+
mutex_lock(&sde_splash_lock);
if (!sinfo->handoff) {
mutex_unlock(&sde_splash_lock);
return 0;
}
- mmu = sde_kms->aspace[0]->mmu;
- if (!mmu) {
- mutex_unlock(&sde_splash_lock);
- return -EINVAL;
- }
+ /*
+ * Start to free all LK's resource till user commit happens
+ * on each display which early splash is enabled on.
+ */
+ if (hdmi_conn_count == 0 && dsi_conn_count == 0) {
+ mmu = sde_kms->aspace[0]->mmu;
+ if (!mmu) {
+ mutex_unlock(&sde_splash_lock);
+ return -EINVAL;
+ }
- /* free HDMI's, DSI's and early camera's reserved memory */
- _sde_splash_free_module_resource(mmu, sinfo);
+ /* free HDMI's, DSI's and early camera's reserved memory */
+ _sde_splash_free_module_resource(mmu, sinfo);
- _sde_splash_destroy_splash_node(sinfo);
+ _sde_splash_destroy_splash_node(sinfo);
- /* free lk_pool heap memory */
- _sde_splash_free_bootup_memory_to_system(sinfo->lk_pool_paddr,
+ /* free lk_pool heap memory */
+ _sde_splash_free_bootup_memory_to_system(sinfo->lk_pool_paddr,
sinfo->lk_pool_size);
- /* withdraw data bus vote */
- sde_power_data_bus_bandwidth_ctrl(phandle,
- sde_kms->core_client, false);
+ /* withdraw data bus vote */
+ sde_power_data_bus_bandwidth_ctrl(phandle,
+ sde_kms->core_client, false);
- /* send uevent to notify user to recycle resource */
- _sde_splash_sent_pipe_update_uevent(sde_kms);
+ /*
+ * Turn off MDP core power to keep power on/off operations
+ * be matched, as MDP core power is enabled already when
+ * early splash is enabled.
+ */
+ sde_power_resource_enable(phandle,
+ sde_kms->core_client, false);
+
+ /* send uevent to notify user to recycle resource */
+ _sde_splash_sent_pipe_update_uevent(sde_kms);
+
+ /* Finally mark handoff flag to false to say
+ * handoff is complete.
+ */
+ sinfo->handoff = false;
+
+ DRM_INFO("HDMI and DSI resource handoff is completed\n");
+ mutex_unlock(&sde_splash_lock);
+ return 0;
+ }
- /* Finally mark handoff flag to false to say handoff is complete */
- sinfo->handoff = false;
+ /*
+ * Ensure user commit happens on different connectors
+ * who has splash.
+ */
+ switch (connector_type) {
+ case DRM_MODE_CONNECTOR_HDMIA:
+ if (sinfo->hdmi_connector_cnt == 1)
+ sinfo->hdmi_connector_cnt--;
+ break;
+ case DRM_MODE_CONNECTOR_DSI:
+ if (strcmp(dsi_display->display_type, "unknown") &&
+ strcmp(last_commit_display_type,
+ dsi_display->display_type)) {
+ if (sinfo->dsi_connector_cnt >= 1)
+ sinfo->dsi_connector_cnt--;
- DRM_INFO("HDMI and DSI resource handoff is completed\n");
+ last_commit_display_type = dsi_display->display_type;
+ }
+ break;
+ default:
+ ret = -EINVAL;
+ SDE_ERROR("%s: invalid connector_type %d\n",
+ __func__, connector_type);
+ }
mutex_unlock(&sde_splash_lock);
- return 0;
+ return ret;
}
/*
@@ -776,7 +860,8 @@ int sde_splash_free_resource(struct msm_kms *kms,
* 1. Notify LK to stop display splash.
* 2. Set DOMAIN_ATTR_EARLY_MAP to 1 to enable stage 1 translation in iommu.
*/
-int sde_splash_lk_stop_splash(struct msm_kms *kms)
+int sde_splash_lk_stop_splash(struct msm_kms *kms,
+ struct drm_atomic_state *state)
{
struct sde_splash_info *sinfo;
struct msm_mmu *mmu;
@@ -792,7 +877,8 @@ int sde_splash_lk_stop_splash(struct msm_kms *kms)
/* Monitor LK's status and tell it to exit. */
mutex_lock(&sde_splash_lock);
- if (sinfo->display_splash_enabled) {
+ if (_sde_splash_validate_commit(sde_kms, state) &&
+ sinfo->display_splash_enabled) {
if (_sde_splash_lk_check(sde_kms->hw_intr))
_sde_splash_notify_lk_stop_splash(sde_kms->hw_intr);
diff --git a/drivers/gpu/drm/msm/sde/sde_splash.h b/drivers/gpu/drm/msm/sde/sde_splash.h
index 2fd8ba03112f..c4bb7b08f817 100644
--- a/drivers/gpu/drm/msm/sde/sde_splash.h
+++ b/drivers/gpu/drm/msm/sde/sde_splash.h
@@ -17,9 +17,6 @@
#include "msm_mmu.h"
#include "sde_hw_mdss.h"
-#define SPLASH_CTL_MAX 5
-#define SPLASH_LM_MAX 7
-
enum splash_connector_type {
SPLASH_DSI = 0,
SPLASH_HDMI,
@@ -35,13 +32,13 @@ struct splash_ctl_top {
u32 value;
u8 intf_sel;
u8 ctl_lm_cnt;
- struct splash_lm_hw lm[SPLASH_LM_MAX];
+ struct splash_lm_hw lm[LM_MAX - LM_0];
};
struct sde_res_data {
- struct splash_ctl_top top[SPLASH_CTL_MAX];
- u8 ctl_ids[SPLASH_CTL_MAX];
- u8 lm_ids[SPLASH_LM_MAX];
+ struct splash_ctl_top top[CTL_MAX - CTL_0];
+ u8 ctl_ids[CTL_MAX - CTL_0];
+ u8 lm_ids[LM_MAX - LM_0];
u8 ctl_top_cnt;
u8 lm_cnt;
};
@@ -121,18 +118,21 @@ void sde_splash_setup_connector_count(struct sde_splash_info *sinfo,
/**
* sde_splash_lk_stop_splash.
*
- * Tell LK to stop display splash.
+ * Tell LK to stop display splash once one valid user commit arrives.
*/
-int sde_splash_lk_stop_splash(struct msm_kms *kms);
+int sde_splash_lk_stop_splash(struct msm_kms *kms,
+ struct drm_atomic_state *state);
/**
* sde_splash_free_resource.
*
- * According to input connector_type, free
- * HDMI's and DSI's resource respectively.
+ * To free all LK's resource, including free reserved memory to system,
+ * withdraw data bus vote, disable MDP core power, send uevent to user
+ * to recycle pipe etc.
*/
int sde_splash_free_resource(struct msm_kms *kms,
- struct sde_power_handle *phandle);
+ struct sde_power_handle *phandle,
+ int connector_type, void *display);
/**
* sde_splash_parse_memory_dt.
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 35be47dafda2..13e0df67d3b7 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -1301,9 +1301,26 @@ static int mmc_blk_ioctl_multi_cmd(struct block_device *bdev,
mmc_get_card(card);
+ if (mmc_card_cmdq(card)) {
+ err = mmc_cmdq_halt(card->host, true);
+ if (err) {
+ pr_err("%s: halt failed while doing %s err (%d)\n",
+ mmc_hostname(card->host),
+ __func__, err);
+ mmc_put_card(card);
+ goto cmd_done;
+ }
+ }
+
for (i = 0; i < num_of_cmds && !ioc_err; i++)
ioc_err = __mmc_blk_ioctl_cmd(card, md, idata[i]);
+ if (mmc_card_cmdq(card)) {
+ if (mmc_cmdq_halt(card->host, false))
+ pr_err("%s: %s: cmdq unhalt failed\n",
+ mmc_hostname(card->host), __func__);
+ }
+
mmc_put_card(card);
/* copy to user if data and response */
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 6375465af0a7..b72f4f5616ac 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -2248,10 +2248,11 @@ int __audit_signal_info(int sig, struct task_struct *t)
audit_sig_uid = uid;
security_task_getsecid(tsk, &audit_sig_sid);
}
- if (!audit_signals || audit_dummy_context())
- return 0;
}
+ if (!audit_signals || audit_dummy_context())
+ return 0;
+
/* optimize the common case by putting first signal recipient directly
* in audit_context */
if (!ctx->target_pid) {