drm/msm/sde: add secure fb translation mode for writeback
Add secure fb translation mode property to writeback connector
to support secure writeback. Writeback buffer can be non-secure
and secure.
Change-Id: Icdf915a139eb508db76a58cd2f1f58b2943bc541
Signed-off-by: Alan Kwong <akwong@codeaurora.org>
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index c6943de..9cde834 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -175,6 +175,7 @@
CONNECTOR_PROP_TOPOLOGY_CONTROL,
CONNECTOR_PROP_AUTOREFRESH,
CONNECTOR_PROP_LP,
+ CONNECTOR_PROP_FB_TRANSLATION_MODE,
/* total # of properties */
CONNECTOR_PROP_COUNT
diff --git a/drivers/gpu/drm/msm/sde/sde_connector.c b/drivers/gpu/drm/msm/sde/sde_connector.c
index 447a6c3..ae6602f 100644
--- a/drivers/gpu/drm/msm/sde/sde_connector.c
+++ b/drivers/gpu/drm/msm/sde/sde_connector.c
@@ -522,7 +522,6 @@
return;
}
- msm_framebuffer_cleanup(c_state->out_fb, c_state->aspace);
drm_framebuffer_unreference(c_state->out_fb);
c_state->out_fb = NULL;
@@ -603,7 +602,6 @@
{
struct sde_connector *c_conn;
struct sde_connector_state *c_state, *c_oldstate;
- int rc;
if (!connector || !connector->state) {
SDE_ERROR("invalid connector %pK\n", connector);
@@ -624,13 +622,8 @@
&c_state->property_state, c_state->property_values);
/* additional handling for drm framebuffer objects */
- if (c_state->out_fb) {
+ if (c_state->out_fb)
drm_framebuffer_reference(c_state->out_fb);
- rc = msm_framebuffer_prepare(c_state->out_fb,
- c_state->aspace);
- if (rc)
- SDE_ERROR("failed to prepare fb, %d\n", rc);
- }
return &c_state->base;
}
@@ -795,18 +788,6 @@
} else {
msm_framebuffer_set_kmap(c_state->out_fb,
c_conn->fb_kmap);
-
- if (c_state->out_fb->flags & DRM_MODE_FB_SECURE)
- c_state->aspace =
- c_conn->aspace[SDE_IOMMU_DOMAIN_SECURE];
- else
- c_state->aspace =
- c_conn->aspace[SDE_IOMMU_DOMAIN_UNSECURE];
-
- rc = msm_framebuffer_prepare(c_state->out_fb,
- c_state->aspace);
- if (rc)
- SDE_ERROR("prep fb failed, %d\n", rc);
}
break;
default:
diff --git a/drivers/gpu/drm/msm/sde/sde_connector.h b/drivers/gpu/drm/msm/sde/sde_connector.h
index 4747d3a..8ac621a 100644
--- a/drivers/gpu/drm/msm/sde/sde_connector.h
+++ b/drivers/gpu/drm/msm/sde/sde_connector.h
@@ -322,7 +322,6 @@
* struct sde_connector_state - private connector status structure
* @base: Base drm connector structure
* @out_fb: Pointer to output frame buffer, if applicable
- * @aspace: Address space for accessing frame buffer objects, if applicable
* @property_state: Local storage for msm_prop properties
* @property_values: Local cache of current connector property values
* @rois: Regions of interest structure for mapping CRTC to Connector output
@@ -331,7 +330,6 @@
struct sde_connector_state {
struct drm_connector_state base;
struct drm_framebuffer *out_fb;
- struct msm_gem_address_space *aspace;
struct msm_property_state property_state;
struct msm_property_value property_values[CONNECTOR_PROP_COUNT];
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys.h b/drivers/gpu/drm/msm/sde/sde_encoder_phys.h
index 2098b9f..236ca369 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder_phys.h
+++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys.h
@@ -348,6 +348,8 @@
* @intf_cfg: Interface hardware configuration
* @wb_roi: Writeback region-of-interest
* @wb_fmt: Writeback pixel format
+ * @wb_fb: Pointer to current writeback framebuffer
+ * @wb_aspace: Pointer to current writeback address space
* @frame_count: Counter of completed writeback operations
* @kickoff_count: Counter of issued writeback operations
* @aspace: address space identifier for non-secure/secure domain
@@ -370,6 +372,8 @@
struct sde_hw_intf_cfg intf_cfg;
struct sde_rect wb_roi;
const struct sde_format *wb_fmt;
+ struct drm_framebuffer *wb_fb;
+ struct msm_gem_address_space *wb_aspace;
u32 frame_count;
u32 kickoff_count;
struct msm_gem_address_space *aspace[SDE_IOMMU_DOMAIN_MAX];
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c b/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c
index 2b736e5..6e024ff 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys_wb.c
@@ -13,6 +13,7 @@
#define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__
#include <linux/debugfs.h>
+#include <uapi/drm/sde_drm.h>
#include "sde_encoder_phys.h"
#include "sde_formats.h"
@@ -252,8 +253,10 @@
const struct msm_format *format;
int ret;
struct msm_gem_address_space *aspace;
+ u32 fb_mode;
- if (!phys_enc || !phys_enc->sde_kms || !phys_enc->sde_kms->catalog) {
+ if (!phys_enc || !phys_enc->sde_kms || !phys_enc->sde_kms->catalog ||
+ !phys_enc->connector) {
SDE_ERROR("invalid encoder\n");
return;
}
@@ -264,13 +267,32 @@
memset(wb_cfg, 0, sizeof(struct sde_hw_wb_cfg));
wb_cfg->intf_mode = phys_enc->intf_mode;
- wb_cfg->is_secure = (fb->flags & DRM_MODE_FB_SECURE) ? true : false;
+
+ fb_mode = sde_connector_get_property(phys_enc->connector->state,
+ CONNECTOR_PROP_FB_TRANSLATION_MODE);
+ if (phys_enc->enable_state == SDE_ENC_DISABLING)
+ wb_cfg->is_secure = false;
+ else if (fb_mode == SDE_DRM_FB_SEC)
+ wb_cfg->is_secure = true;
+ else
+ wb_cfg->is_secure = false;
+
aspace = (wb_cfg->is_secure) ?
wb_enc->aspace[SDE_IOMMU_DOMAIN_SECURE] :
wb_enc->aspace[SDE_IOMMU_DOMAIN_UNSECURE];
SDE_DEBUG("[fb_secure:%d]\n", wb_cfg->is_secure);
+ ret = msm_framebuffer_prepare(fb, aspace);
+ if (ret) {
+ SDE_ERROR("prep fb failed, %d\n", ret);
+ return;
+ }
+
+ /* cache framebuffer for cleanup in writeback done */
+ wb_enc->wb_fb = fb;
+ wb_enc->wb_aspace = aspace;
+
format = msm_framebuffer_format(fb);
if (!format) {
SDE_DEBUG("invalid format for fb\n");
@@ -559,6 +581,10 @@
memset(wb_roi, 0, sizeof(struct sde_rect));
+ /* clear writeback framebuffer - will be updated in setup_fb */
+ wb_enc->wb_fb = NULL;
+ wb_enc->wb_aspace = NULL;
+
if (phys_enc->enable_state == SDE_ENC_DISABLING) {
fb = wb_enc->fb_disable;
wb_roi->w = 0;
@@ -856,6 +882,13 @@
wb_enc->wb_dev->wb_idx - WB_0, wb_time);
}
+ /* cleanup writeback framebuffer */
+ if (wb_enc->wb_fb && wb_enc->wb_aspace) {
+ msm_framebuffer_cleanup(wb_enc->wb_fb, wb_enc->wb_aspace);
+ wb_enc->wb_fb = NULL;
+ wb_enc->wb_aspace = NULL;
+ }
+
SDE_EVT32(DRMID(phys_enc->parent), WBID(wb_enc), wb_enc->frame_count,
wb_time, event, rc);
diff --git a/drivers/gpu/drm/msm/sde/sde_wb.c b/drivers/gpu/drm/msm/sde/sde_wb.c
index 145acea..576a8f3 100644
--- a/drivers/gpu/drm/msm/sde/sde_wb.c
+++ b/drivers/gpu/drm/msm/sde/sde_wb.c
@@ -13,6 +13,8 @@
#define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__
+#include <uapi/drm/sde_drm.h>
+
#include "msm_kms.h"
#include "sde_kms.h"
#include "sde_wb.h"
@@ -318,6 +320,10 @@
struct sde_connector *c_conn;
struct sde_wb_device *wb_dev = display;
const struct sde_format_extended *format_list;
+ static const struct drm_prop_enum_list e_fb_translation_mode[] = {
+ {SDE_DRM_FB_NON_SEC, "non_sec"},
+ {SDE_DRM_FB_SEC, "sec"},
+ };
if (!connector || !info || !display || !wb_dev->wb_cfg) {
SDE_ERROR("invalid params\n");
@@ -342,6 +348,12 @@
0x0, 0, UINT_MAX, 0, CONNECTOR_PROP_DST_W);
msm_property_install_range(&c_conn->property_info, "DST_H",
0x0, 0, UINT_MAX, 0, CONNECTOR_PROP_DST_H);
+ msm_property_install_enum(&c_conn->property_info,
+ "fb_translation_mode",
+ 0x0,
+ 0, e_fb_translation_mode,
+ ARRAY_SIZE(e_fb_translation_mode),
+ CONNECTOR_PROP_FB_TRANSLATION_MODE);
/*
* Populate info buffer