techpack: display: add mi display notifier
Change-Id: I50670448c6a865744b2c003188500560666bb4e1
This commit is contained in:
parent
8bc0ed6f0e
commit
f218b912e6
52
include/drm/mi_disp_notifier.h
Normal file
52
include/drm/mi_disp_notifier.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (C) 2020 XiaoMi, Inc.
|
||||
*
|
||||
* 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
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _MI_DRM_NOTIFIER_H_
|
||||
#define _MI_DRM_NOTIFIER_H_
|
||||
|
||||
#include <linux/notifier.h>
|
||||
|
||||
/* A hardware display power mode state change occurred */
|
||||
#define MI_DISP_DPMS_EVENT 0x01
|
||||
/* A hardware display power mode state early change occurred */
|
||||
#define MI_DISP_DPMS_EARLY_EVENT 0x02
|
||||
|
||||
enum {
|
||||
/* panel: power on */
|
||||
MI_DISP_DPMS_ON = 0,
|
||||
MI_DISP_DPMS_LP1 = 1,
|
||||
MI_DISP_DPMS_LP2 = 2,
|
||||
MI_DISP_DPMS_STANDBY = 3,
|
||||
MI_DISP_DPMS_SUSPEND = 4,
|
||||
/* panel: power off */
|
||||
MI_DISP_DPMS_POWERDOWN = 5,
|
||||
};
|
||||
|
||||
enum mi_disp_id {
|
||||
MI_DISPLAY_PRIMARY = 0,
|
||||
MI_DISPLAY_SECONDARY,
|
||||
MI_DISPLAY_MAX,
|
||||
};
|
||||
|
||||
struct mi_disp_notifier {
|
||||
int disp_id;
|
||||
void *data;
|
||||
};
|
||||
|
||||
int mi_disp_register_client(struct notifier_block *nb);
|
||||
int mi_disp_unregister_client(struct notifier_block *nb);
|
||||
int mi_disp_notifier_call_chain(unsigned long val, void *v);
|
||||
|
||||
#endif /* _MI_DRM_NOTIFIER_H_ */
|
@ -4,6 +4,7 @@ ccflags-y += -I$(srctree)/techpack/display/msm/sde
|
||||
ccflags-y += -I$(srctree)/techpack/display/rotator
|
||||
ccflags-y += -I$(srctree)/techpack/display/hdcp
|
||||
ccflags-y += -I$(srctree)/drivers/clk/qcom/
|
||||
ccflags-y += -I$(srctree)/techpack/display/msm/mi_disp
|
||||
|
||||
msm_drm-$(CONFIG_DRM_MSM_DP) += dp/dp_altmode.o \
|
||||
dp/dp_parser.o \
|
||||
@ -140,6 +141,10 @@ msm_drm-$(CONFIG_DRM_MSM) += \
|
||||
|
||||
msm_drm-$(CONFIG_HDCP_QSEECOM) += ../hdcp/msm_hdcp.o \
|
||||
|
||||
msm_drm-$(CONFIG_DRM_MSM) += \
|
||||
mi_disp/mi_disp_notifier.o \
|
||||
mi_disp/mi_dsi_display.o
|
||||
|
||||
msm_drm-$(CONFIG_MSM_SDE_ROTATOR) += ../rotator/sde_rotator_dev.o \
|
||||
../rotator/sde_rotator_core.o \
|
||||
../rotator/sde_rotator_base.o \
|
||||
|
@ -9,6 +9,8 @@
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
#include <drm/mi_disp_notifier.h>
|
||||
|
||||
#include "msm_drv.h"
|
||||
#include "sde_connector.h"
|
||||
#include "msm_mmu.h"
|
||||
@ -21,6 +23,7 @@
|
||||
#include "dsi_pwr.h"
|
||||
#include "sde_dbg.h"
|
||||
#include "dsi_parser.h"
|
||||
#include "mi_dsi_display.h"
|
||||
|
||||
#define to_dsi_display(x) container_of(x, struct dsi_display, host)
|
||||
#define INT_BASE_10 10
|
||||
@ -1240,6 +1243,8 @@ int dsi_display_set_power(struct drm_connector *connector,
|
||||
int power_mode, void *disp)
|
||||
{
|
||||
struct dsi_display *display = disp;
|
||||
struct mi_disp_notifier notify_data;
|
||||
int disp_id = 0;
|
||||
int rc = 0;
|
||||
|
||||
if (!display || !display->panel) {
|
||||
@ -1247,18 +1252,27 @@ int dsi_display_set_power(struct drm_connector *connector,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
disp_id = mi_get_disp_id(display);
|
||||
|
||||
notify_data.data = &power_mode;
|
||||
notify_data.disp_id = disp_id;
|
||||
|
||||
switch (power_mode) {
|
||||
case SDE_MODE_DPMS_LP1:
|
||||
mi_disp_notifier_call_chain(MI_DISP_DPMS_EARLY_EVENT, ¬ify_data);
|
||||
if (display->panel->power_mode == SDE_MODE_DPMS_LP2) {
|
||||
if (dsi_display_set_ulp_load(display, false) < 0)
|
||||
DSI_WARN("failed to set load for lp1 state\n");
|
||||
}
|
||||
rc = dsi_panel_set_lp1(display->panel);
|
||||
mi_disp_notifier_call_chain(MI_DISP_DPMS_EVENT, ¬ify_data);
|
||||
break;
|
||||
case SDE_MODE_DPMS_LP2:
|
||||
mi_disp_notifier_call_chain(MI_DISP_DPMS_EARLY_EVENT, ¬ify_data);
|
||||
rc = dsi_panel_set_lp2(display->panel);
|
||||
if (dsi_display_set_ulp_load(display, true) < 0)
|
||||
DSI_WARN("failed to set load for lp2 state\n");
|
||||
mi_disp_notifier_call_chain(MI_DISP_DPMS_EVENT, ¬ify_data);
|
||||
break;
|
||||
case SDE_MODE_DPMS_ON:
|
||||
if (display->panel->power_mode == SDE_MODE_DPMS_LP2) {
|
||||
@ -1266,8 +1280,11 @@ int dsi_display_set_power(struct drm_connector *connector,
|
||||
DSI_WARN("failed to set load for on state\n");
|
||||
}
|
||||
if ((display->panel->power_mode == SDE_MODE_DPMS_LP1) ||
|
||||
(display->panel->power_mode == SDE_MODE_DPMS_LP2))
|
||||
(display->panel->power_mode == SDE_MODE_DPMS_LP2)) {
|
||||
mi_disp_notifier_call_chain(MI_DISP_DPMS_EARLY_EVENT, ¬ify_data);
|
||||
rc = dsi_panel_set_nolp(display->panel);
|
||||
mi_disp_notifier_call_chain(MI_DISP_DPMS_EVENT, ¬ify_data);
|
||||
}
|
||||
break;
|
||||
case SDE_MODE_DPMS_OFF:
|
||||
default:
|
||||
|
@ -7,12 +7,14 @@
|
||||
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_atomic.h>
|
||||
#include <drm/mi_disp_notifier.h>
|
||||
|
||||
#include "msm_kms.h"
|
||||
#include "sde_connector.h"
|
||||
#include "dsi_drm.h"
|
||||
#include "sde_trace.h"
|
||||
#include "sde_dbg.h"
|
||||
#include "mi_dsi_display.h"
|
||||
|
||||
#define to_dsi_bridge(x) container_of((x), struct dsi_bridge, base)
|
||||
#define to_dsi_state(x) container_of((x), struct dsi_connector_state, base)
|
||||
@ -169,6 +171,8 @@ static void dsi_bridge_pre_enable(struct drm_bridge *bridge)
|
||||
{
|
||||
int rc = 0;
|
||||
struct dsi_bridge *c_bridge = to_dsi_bridge(bridge);
|
||||
struct mi_disp_notifier notify_data;
|
||||
int power_mode = 0;
|
||||
|
||||
if (!bridge) {
|
||||
DSI_ERR("Invalid params\n");
|
||||
@ -183,6 +187,11 @@ static void dsi_bridge_pre_enable(struct drm_bridge *bridge)
|
||||
if (bridge->encoder->crtc->state->active_changed)
|
||||
atomic_set(&c_bridge->display->panel->esd_recovery_pending, 0);
|
||||
|
||||
power_mode = sde_connector_get_lp(c_bridge->display->drm_conn);
|
||||
notify_data.data = &power_mode;
|
||||
notify_data.disp_id = mi_get_disp_id(c_bridge->display);
|
||||
mi_disp_notifier_call_chain(MI_DISP_DPMS_EARLY_EVENT, ¬ify_data);
|
||||
|
||||
/* By this point mode should have been validated through mode_fixup */
|
||||
rc = dsi_display_set_mode(c_bridge->display,
|
||||
&(c_bridge->dsi_mode), 0x0);
|
||||
@ -216,6 +225,8 @@ static void dsi_bridge_pre_enable(struct drm_bridge *bridge)
|
||||
c_bridge->id, rc);
|
||||
(void)dsi_display_unprepare(c_bridge->display);
|
||||
}
|
||||
|
||||
mi_disp_notifier_call_chain(MI_DISP_DPMS_EVENT, ¬ify_data);
|
||||
SDE_ATRACE_END("dsi_display_enable");
|
||||
|
||||
rc = dsi_display_splash_res_cleanup(c_bridge->display);
|
||||
@ -295,12 +306,24 @@ static void dsi_bridge_post_disable(struct drm_bridge *bridge)
|
||||
{
|
||||
int rc = 0;
|
||||
struct dsi_bridge *c_bridge = to_dsi_bridge(bridge);
|
||||
struct mi_disp_notifier notify_data;
|
||||
int power_mode = 0;
|
||||
|
||||
if (!bridge) {
|
||||
DSI_ERR("Invalid params\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!c_bridge || !c_bridge->display || !c_bridge->display->panel) {
|
||||
DSI_ERR("Incorrect bridge details\n");
|
||||
return;
|
||||
}
|
||||
|
||||
power_mode = sde_connector_get_lp(c_bridge->display->drm_conn);
|
||||
notify_data.data = &power_mode;
|
||||
notify_data.disp_id = mi_get_disp_id(c_bridge->display);
|
||||
mi_disp_notifier_call_chain(MI_DISP_DPMS_EARLY_EVENT, ¬ify_data);
|
||||
|
||||
SDE_ATRACE_BEGIN("dsi_bridge_post_disable");
|
||||
SDE_ATRACE_BEGIN("dsi_display_disable");
|
||||
rc = dsi_display_disable(c_bridge->display);
|
||||
@ -319,6 +342,8 @@ static void dsi_bridge_post_disable(struct drm_bridge *bridge)
|
||||
SDE_ATRACE_END("dsi_bridge_post_disable");
|
||||
return;
|
||||
}
|
||||
|
||||
mi_disp_notifier_call_chain(MI_DISP_DPMS_EVENT, ¬ify_data);
|
||||
SDE_ATRACE_END("dsi_bridge_post_disable");
|
||||
}
|
||||
|
||||
|
48
techpack/display/msm/mi_disp/mi_disp_notifier.c
Normal file
48
techpack/display/msm/mi_disp/mi_disp_notifier.c
Normal file
@ -0,0 +1,48 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (C) 2020 XiaoMi, Inc.
|
||||
*/
|
||||
|
||||
#include <linux/notifier.h>
|
||||
|
||||
static BLOCKING_NOTIFIER_HEAD(mi_disp_notifier_list);
|
||||
|
||||
/**
|
||||
* mi_drm_register_client - register a client notifier
|
||||
* @nb: notifier block to callback on events
|
||||
*
|
||||
* This function registers a notifier callback function
|
||||
* to msm_drm_notifier_list, which would be called when
|
||||
* received unblank/power down event.
|
||||
*/
|
||||
int mi_disp_register_client(struct notifier_block *nb)
|
||||
{
|
||||
return blocking_notifier_chain_register(&mi_disp_notifier_list, nb);
|
||||
}
|
||||
EXPORT_SYMBOL(mi_disp_register_client);
|
||||
|
||||
/**
|
||||
* mi_drm_unregister_client - unregister a client notifier
|
||||
* @nb: notifier block to callback on events
|
||||
*
|
||||
* This function unregisters the callback function from
|
||||
* msm_drm_notifier_list.
|
||||
*/
|
||||
int mi_disp_unregister_client(struct notifier_block *nb)
|
||||
{
|
||||
return blocking_notifier_chain_unregister(&mi_disp_notifier_list, nb);
|
||||
}
|
||||
EXPORT_SYMBOL(mi_disp_unregister_client);
|
||||
|
||||
/**
|
||||
* mi_drm_notifier_call_chain - notify clients of drm_events
|
||||
* @val: event MSM_DRM_EARLY_EVENT_BLANK or MSM_DRM_EVENT_BLANK
|
||||
* @v: notifier data, inculde display id and display blank
|
||||
* event(unblank or power down).
|
||||
*/
|
||||
int mi_disp_notifier_call_chain(unsigned long val, void *v)
|
||||
{
|
||||
return blocking_notifier_call_chain(&mi_disp_notifier_list, val, v);
|
||||
}
|
||||
EXPORT_SYMBOL(mi_disp_notifier_call_chain);
|
Loading…
Reference in New Issue
Block a user