drm: msm: Add support AD4 custom event notifications
SDM845 target supports AD4 feature. User-space client of AD4 driver
needs to be notified of system back-light notifications, suspend/resume
events. Change adds support in sde display driver for notify the events.
Change-Id: Ia2fbae75cc66389145292082c46d3bd16653e941
Signed-off-by: Gopikrishnaiah Anandan <agopik@codeaurora.org>
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 4e0b678..a3a9142 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -1271,22 +1271,20 @@
return ret;
}
-void msm_send_crtc_notification(struct drm_crtc *crtc,
- struct drm_event *event, u8 *payload)
+void msm_mode_object_event_nofity(struct drm_mode_object *obj,
+ struct drm_device *dev, struct drm_event *event, u8 *payload)
{
- struct drm_device *dev = NULL;
struct msm_drm_private *priv = NULL;
unsigned long flags;
struct msm_drm_event *notify, *node;
int len = 0, ret;
- if (!crtc || !event || !event->length || !payload) {
- DRM_ERROR("err param crtc %pK event %pK len %d payload %pK\n",
- crtc, event, ((event) ? (event->length) : -1),
+ if (!obj || !event || !event->length || !payload) {
+ DRM_ERROR("err param obj %pK event %pK len %d payload %pK\n",
+ obj, event, ((event) ? (event->length) : -1),
payload);
return;
}
- dev = crtc->dev;
priv = (dev) ? dev->dev_private : NULL;
if (!dev || !priv) {
DRM_ERROR("invalid dev %pK priv %pK\n", dev, priv);
@@ -1296,7 +1294,7 @@
spin_lock_irqsave(&dev->event_lock, flags);
list_for_each_entry(node, &priv->client_event_list, base.link) {
if (node->event.type != event->type ||
- crtc->base.id != node->info.object_id)
+ obj->id != node->info.object_id)
continue;
len = event->length + sizeof(struct drm_msm_event_resp);
if (node->base.file_priv->event_space < len) {
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 322b7f2..7061575 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -707,13 +707,14 @@
};
/* *
- * msm_send_crtc_notification - notify user-space clients of crtc events.
- * @crtc: crtc that is generating the event.
+ * msm_mode_object_event_notify - notify user-space clients of drm object
+ * events.
+ * @obj: mode object (crtc/connector) that is generating the event.
* @event: event that needs to be notified.
* @payload: payload for the event.
*/
-void msm_send_crtc_notification(struct drm_crtc *crtc,
- struct drm_event *event, u8 *payload);
+void msm_mode_object_event_nofity(struct drm_mode_object *obj,
+ struct drm_device *dev, struct drm_event *event, u8 *payload);
#ifdef CONFIG_DRM_MSM_DSI
void __init msm_dsi_register(void);
void __exit msm_dsi_unregister(void);
diff --git a/drivers/gpu/drm/msm/sde/sde_color_processing.c b/drivers/gpu/drm/msm/sde/sde_color_processing.c
index d5207b9..3114960 100644
--- a/drivers/gpu/drm/msm/sde/sde_color_processing.c
+++ b/drivers/gpu/drm/msm/sde/sde_color_processing.c
@@ -1357,7 +1357,8 @@
hw_dspp->ops.ad_read_intr_resp(hw_dspp, AD4_BACKLIGHT, &bl);
event.length = sizeof(u32);
event.type = DRM_EVENT_AD_BACKLIGHT;
- msm_send_crtc_notification(&crtc->base, &event, (u8 *)&bl);
+ msm_mode_object_event_nofity(&crtc_drm->base, crtc_drm->dev,
+ &event, (u8 *)&bl);
}
int sde_cp_ad_interrupt(struct drm_crtc *crtc_drm, bool en,
diff --git a/drivers/gpu/drm/msm/sde/sde_connector.c b/drivers/gpu/drm/msm/sde/sde_connector.c
index 58222f3..905ad93 100644
--- a/drivers/gpu/drm/msm/sde/sde_connector.c
+++ b/drivers/gpu/drm/msm/sde/sde_connector.c
@@ -57,6 +57,7 @@
struct dsi_display *display;
struct sde_connector *c_conn;
int bl_lvl;
+ struct drm_event event;
brightness = bd->props.brightness;
@@ -77,8 +78,13 @@
if (!bl_lvl && brightness)
bl_lvl = 1;
- if (c_conn->ops.set_backlight)
+ if (c_conn->ops.set_backlight) {
+ event.type = DRM_EVENT_SYS_BACKLIGHT;
+ event.length = sizeof(u32);
+ msm_mode_object_event_nofity(&c_conn->base.base,
+ c_conn->base.dev, &event, (u8 *)&brightness);
c_conn->ops.set_backlight(c_conn->display, bl_lvl);
+ }
return 0;
}
@@ -1168,5 +1174,14 @@
int sde_connector_register_custom_event(struct sde_kms *kms,
struct drm_connector *conn_drm, u32 event, bool val)
{
- return -EINVAL;
+ int ret = -EINVAL;
+
+ switch (event) {
+ case DRM_EVENT_SYS_BACKLIGHT:
+ ret = 0;
+ break;
+ default:
+ break;
+ }
+ return ret;
}
diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c
index 1ff2cb5..7bfaa1c 100644
--- a/drivers/gpu/drm/msm/sde/sde_crtc.c
+++ b/drivers/gpu/drm/msm/sde/sde_crtc.c
@@ -51,8 +51,12 @@
struct sde_irq_callback *irq);
};
+static int sde_crtc_power_interrupt_handler(struct drm_crtc *crtc_drm,
+ bool en, struct sde_irq_callback *ad_irq);
+
static struct sde_crtc_custom_events custom_events[] = {
- {DRM_EVENT_AD_BACKLIGHT, sde_cp_ad_interrupt}
+ {DRM_EVENT_AD_BACKLIGHT, sde_cp_ad_interrupt},
+ {DRM_EVENT_CRTC_POWER, sde_crtc_power_interrupt_handler}
};
/* default input fence timeout, in ms */
@@ -2053,6 +2057,8 @@
struct sde_crtc *sde_crtc;
struct msm_drm_private *priv;
struct sde_kms *sde_kms;
+ struct drm_event event;
+ u32 power_on;
if (!crtc || !crtc->dev || !crtc->dev->dev_private) {
SDE_ERROR("invalid crtc\n");
@@ -2071,13 +2077,18 @@
mutex_lock(&sde_crtc->crtc_lock);
+ event.type = DRM_EVENT_CRTC_POWER;
+ event.length = sizeof(u32);
/*
* Update CP on suspend/resume transitions
*/
- if (enable && !sde_crtc->suspend)
+ if (enable && !sde_crtc->suspend) {
sde_cp_crtc_suspend(crtc);
- else if (!enable && sde_crtc->suspend)
+ power_on = 0;
+ } else if (!enable && sde_crtc->suspend) {
sde_cp_crtc_resume(crtc);
+ power_on = 1;
+ }
/*
* If the vblank refcount != 0, release a power reference on suspend
@@ -2090,7 +2101,8 @@
_sde_crtc_vblank_enable_nolock(sde_crtc, !enable);
sde_crtc->suspend = enable;
-
+ msm_mode_object_event_nofity(&crtc->base, crtc->dev, &event,
+ (u8 *)&power_on);
mutex_unlock(&sde_crtc->crtc_lock);
}
@@ -3556,3 +3568,9 @@
return ret;
}
+
+static int sde_crtc_power_interrupt_handler(struct drm_crtc *crtc_drm,
+ bool en, struct sde_irq_callback *irq)
+{
+ return 0;
+}