summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorGuchun Chen <guchunc@codeaurora.org>2018-12-04 10:29:39 +0800
committerGuchun Chen <guchunc@codeaurora.org>2018-12-04 16:15:05 +0800
commitbfe77429f9bbc2930c259603b16aa77309d3470c (patch)
treebe24c79d8e3c32b3ddd6d99e08108f5fdda69c44 /drivers
parent58a9174f204e980b45317eec4e240f4afc3c24c0 (diff)
drm: msm: sde: update blob property after splash is done
After early splash handoff is finished, kernel needs to update each crtc's and plane's impacted blob property by splash. This ensures framework can get correct resource in the second init process. Change-Id: Iddfa823d7ba786f3d81b96e86ad3b6e4b10a3375 Signed-off-by: Guchun Chen <guchunc@codeaurora.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/msm/sde/sde_crtc.c20
-rw-r--r--drivers/gpu/drm/msm/sde/sde_crtc.h9
-rw-r--r--drivers/gpu/drm/msm/sde/sde_kms.h12
-rw-r--r--drivers/gpu/drm/msm/sde/sde_kms_utils.c60
-rw-r--r--drivers/gpu/drm/msm/sde/sde_plane.c18
-rw-r--r--drivers/gpu/drm/msm/sde/sde_plane.h9
-rw-r--r--drivers/gpu/drm/msm/sde/sde_splash.c26
7 files changed, 152 insertions, 2 deletions
diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c
index 01da32ae5958..4dac785ad59f 100644
--- a/drivers/gpu/drm/msm/sde/sde_crtc.c
+++ b/drivers/gpu/drm/msm/sde/sde_crtc.c
@@ -1995,6 +1995,26 @@ static void _sde_crtc_init_debugfs(struct sde_crtc *sde_crtc,
}
#endif
+void sde_crtc_update_blob_property(struct drm_crtc *crtc,
+ const char *key,
+ int32_t value)
+{
+ struct sde_crtc *sde_crtc;
+ char *kms_info_str = NULL;
+ size_t len;
+
+ sde_crtc = to_sde_crtc(crtc);
+
+ kms_info_str = (char *)msm_property_get_blob(&sde_crtc->property_info,
+ &sde_crtc->blob_info, &len, CRTC_PROP_INFO);
+ if (!kms_info_str) {
+ SDE_ERROR("get crtc property_info failed");
+ return;
+ }
+
+ sde_kms_info_update_keystr(kms_info_str, key, value);
+}
+
/* initialize crtc */
struct drm_crtc *sde_crtc_init(struct drm_device *dev,
struct drm_plane *plane)
diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.h b/drivers/gpu/drm/msm/sde/sde_crtc.h
index 200073995d43..a1042390b1a9 100644
--- a/drivers/gpu/drm/msm/sde/sde_crtc.h
+++ b/drivers/gpu/drm/msm/sde/sde_crtc.h
@@ -292,4 +292,13 @@ static inline bool sde_crtc_is_enabled(struct drm_crtc *crtc)
return crtc ? crtc->enabled : false;
}
+/**
+ * sde_crtc_update_blob_property - update blob property of a given crtc
+ * @crtc: Pointer to crtc
+ * @key: Pointer to key string
+ * @value: Signed 32 bit integer value
+ */
+void sde_crtc_update_blob_property(struct drm_crtc *crtc,
+ const char *key,
+ int32_t value);
#endif /* _SDE_CRTC_H_ */
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.h b/drivers/gpu/drm/msm/sde/sde_kms.h
index dee16d119d47..c7355f5bd891 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.h
+++ b/drivers/gpu/drm/msm/sde/sde_kms.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
* Copyright (C) 2013 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
*
@@ -306,6 +306,16 @@ void sde_kms_info_add_keyint(struct sde_kms_info *info,
int32_t value);
/**
+ * sde_kms_info_update_keystr - update the special string's value.
+ * @info_str: Pointer to source blob str
+ * @key: Pointer to key string
+ * @value: Signed 32-bit integer value
+ */
+void sde_kms_info_update_keystr(char *info_str,
+ const char *key,
+ int32_t value);
+
+/**
* sde_kms_info_add_keystr - add string value to 'sde_kms_info'
* @info: Pointer to sde_kms_info structure
* @key: Pointer to key string
diff --git a/drivers/gpu/drm/msm/sde/sde_kms_utils.c b/drivers/gpu/drm/msm/sde/sde_kms_utils.c
index 30e12c969538..90fd3912eb59 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms_utils.c
+++ b/drivers/gpu/drm/msm/sde/sde_kms_utils.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -41,6 +41,64 @@ void sde_kms_info_add_keyint(struct sde_kms_info *info,
}
}
+void sde_kms_info_update_keystr(char *info_str,
+ const char *key,
+ int32_t value)
+{
+ char *str, *temp, *append_str;
+ uint32_t dst_len = 0, prefix_len = 0;
+ char c;
+ int32_t size = 0;
+
+ if (info_str && key) {
+ str = strnstr(info_str, key, strlen(info_str));
+ if (str) {
+ temp = str + strlen(key);
+ c = *temp;
+ while (c != '\n') {
+ dst_len++;
+ c = *(++temp);
+ }
+ /*
+ * If input key string to update is exactly the last
+ * string in source string, no need to allocate one
+ * memory to store the string after string key. Just
+ * replace the value of the last string.
+ *
+ * If it is not, allocate one new memory to save
+ * the string after string key+"\n". This new allocated
+ * string will be appended to the whole source string
+ * after key value is updated.
+ */
+ size = strlen(str) - strlen(key) - dst_len - 1;
+ if (size > 0) {
+ append_str = kzalloc(size + 1, GFP_KERNEL);
+ if (!append_str) {
+ SDE_ERROR("failed to alloc memory\n");
+ return;
+ }
+ memcpy(append_str,
+ str + strlen(key) + dst_len + 1, size);
+ }
+
+ prefix_len = strlen(info_str) - strlen(str);
+ /* Update string with new value for the string key. */
+ snprintf(info_str + prefix_len,
+ SDE_KMS_INFO_MAX_SIZE - prefix_len,
+ "%s%d\n", key, value);
+
+ /* Append the string save aboved. */
+ if (size > 0 && append_str) {
+ size = prefix_len + strlen(key) + dst_len + 1;
+ snprintf(info_str + size,
+ SDE_KMS_INFO_MAX_SIZE - size,
+ "%s", append_str);
+ kfree(append_str);
+ }
+ }
+ }
+}
+
void sde_kms_info_add_keystr(struct sde_kms_info *info,
const char *key,
const char *value)
diff --git a/drivers/gpu/drm/msm/sde/sde_plane.c b/drivers/gpu/drm/msm/sde/sde_plane.c
index e50577e3eb4b..a35428c93867 100644
--- a/drivers/gpu/drm/msm/sde/sde_plane.c
+++ b/drivers/gpu/drm/msm/sde/sde_plane.c
@@ -2732,6 +2732,24 @@ end:
return rc;
}
+void sde_plane_update_blob_property(struct drm_plane *plane,
+ const char *key,
+ int32_t value)
+{
+ char *kms_info_str = NULL;
+ struct sde_plane *sde_plane = to_sde_plane(plane);
+ size_t len;
+
+ kms_info_str = (char *)msm_property_get_blob(&sde_plane->property_info,
+ &sde_plane->blob_info, &len, 0);
+ if (!kms_info_str) {
+ SDE_ERROR("get plane property_info failed\n");
+ return;
+ }
+
+ sde_kms_info_update_keystr(kms_info_str, key, value);
+}
+
/* initialize plane */
struct drm_plane *sde_plane_init(struct drm_device *dev,
uint32_t pipe, bool primary_plane,
diff --git a/drivers/gpu/drm/msm/sde/sde_plane.h b/drivers/gpu/drm/msm/sde/sde_plane.h
index 8ac582643926..c1414e7db74e 100644
--- a/drivers/gpu/drm/msm/sde/sde_plane.h
+++ b/drivers/gpu/drm/msm/sde/sde_plane.h
@@ -102,4 +102,13 @@ int sde_plane_wait_input_fence(struct drm_plane *plane, uint32_t wait_ms);
int sde_plane_color_fill(struct drm_plane *plane,
uint32_t color, uint32_t alpha);
+/**
+ * sde_plane_update_blob_property - update plane blob property
+ * @plane: Pointer to DRM plane object
+ * @key: Pointer to key string
+ * @value: Signed 32 bit integer value
+ */
+void sde_plane_update_blob_property(struct drm_plane *plane,
+ const char *key,
+ int32_t value);
#endif /* _SDE_PLANE_H_ */
diff --git a/drivers/gpu/drm/msm/sde/sde_splash.c b/drivers/gpu/drm/msm/sde/sde_splash.c
index 16f9248b7abe..3ea93b654ce8 100644
--- a/drivers/gpu/drm/msm/sde/sde_splash.c
+++ b/drivers/gpu/drm/msm/sde/sde_splash.c
@@ -26,6 +26,7 @@
#include "dsi_display.h"
#include "sde_hdmi.h"
#include "sde_crtc.h"
+#include "sde_plane.h"
#define MDP_SSPP_TOP0_OFF 0x1000
#define DISP_INTF_SEL 0x004
@@ -391,6 +392,28 @@ static bool _sde_splash_validate_commit(struct sde_kms *sde_kms,
return false;
}
+static void _sde_splash_update_property(struct sde_kms *sde_kms)
+{
+ struct drm_device *dev = sde_kms->dev;
+ struct drm_crtc *crtc;
+ struct drm_plane *plane;
+ struct sde_mdss_cfg *catalog = sde_kms->catalog;
+
+ /*
+ * Update plane availability property
+ * after splash handoff is done.
+ */
+ drm_for_each_plane(plane, dev) {
+ sde_plane_update_blob_property(plane,
+ "plane_unavailability=", 0);
+ }
+
+ /* update crtc blend stage property */
+ drm_for_each_crtc(crtc, dev)
+ sde_crtc_update_blob_property(crtc, "max_blendstages=",
+ catalog->max_mixer_blendstages);
+}
+
__ref int sde_splash_init(struct sde_power_handle *phandle, struct msm_kms *kms)
{
struct sde_kms *sde_kms;
@@ -837,6 +860,9 @@ int sde_splash_free_resource(struct msm_kms *kms,
/* send uevent to notify user to recycle resource */
_sde_splash_sent_pipe_update_uevent(sde_kms);
+ /* update impacted crtc and plane property by splash */
+ _sde_splash_update_property(sde_kms);
+
/* set display's splash status to false after handoff is done */
_sde_splash_update_display_splash_status(sde_kms);