mdss: display-port: add support to send HPD event to framework
Add support to send switch event to framework when the HDP status changes. This switch event is shared between HDMI and DP. Change-Id: I13161bd8b2a7777abbe2521178c5b1b1b6416eea Signed-off-by: Chandan Uddaraju <chandanu@codeaurora.org>
This commit is contained in:
parent
362a4d381d
commit
cfabc2bcfe
7 changed files with 112 additions and 17 deletions
|
@ -33,6 +33,7 @@
|
|||
#include "mdss.h"
|
||||
#include "mdss_dp.h"
|
||||
#include "mdss_dp_util.h"
|
||||
#include "mdss_hdmi_panel.h"
|
||||
#include "mdss_debug.h"
|
||||
|
||||
#define RGB_COMPONENTS 3
|
||||
|
@ -863,7 +864,7 @@ int mdss_dp_wait4train(struct mdss_dp_drv_pdata *dp_drv)
|
|||
|
||||
#define DEFAULT_VIDEO_RESOLUTION HDMI_VFRMT_640x480p60_4_3
|
||||
|
||||
static int dp_init_panel_info(struct mdss_dp_drv_pdata *dp_drv)
|
||||
static int dp_init_panel_info(struct mdss_dp_drv_pdata *dp_drv, u32 vic)
|
||||
{
|
||||
struct mdss_panel_info *pinfo;
|
||||
struct msm_hdmi_mode_timing_info timing = {0};
|
||||
|
@ -875,8 +876,7 @@ static int dp_init_panel_info(struct mdss_dp_drv_pdata *dp_drv)
|
|||
}
|
||||
|
||||
dp_drv->ds_data.ds_registered = false;
|
||||
ret = hdmi_get_supported_mode(&timing, &dp_drv->ds_data,
|
||||
DEFAULT_VIDEO_RESOLUTION);
|
||||
ret = hdmi_get_supported_mode(&timing, &dp_drv->ds_data, vic);
|
||||
pinfo = &dp_drv->panel_data.panel_info;
|
||||
|
||||
if (ret || !timing.supported || !pinfo) {
|
||||
|
@ -884,6 +884,7 @@ static int dp_init_panel_info(struct mdss_dp_drv_pdata *dp_drv)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
dp_drv->vic = vic;
|
||||
pinfo->xres = timing.active_h;
|
||||
pinfo->yres = timing.active_v;
|
||||
pinfo->clk_rate = timing.pixel_freq * 1000;
|
||||
|
@ -895,7 +896,7 @@ static int dp_init_panel_info(struct mdss_dp_drv_pdata *dp_drv)
|
|||
pinfo->lcdc.v_front_porch = timing.front_porch_v;
|
||||
pinfo->lcdc.v_pulse_width = timing.pulse_width_v;
|
||||
|
||||
pinfo->type = EDP_PANEL;
|
||||
pinfo->type = DP_PANEL;
|
||||
pinfo->pdest = DISPLAY_4;
|
||||
pinfo->wait_cycle = 0;
|
||||
pinfo->bpp = 24;
|
||||
|
@ -904,6 +905,10 @@ static int dp_init_panel_info(struct mdss_dp_drv_pdata *dp_drv)
|
|||
pinfo->lcdc.border_clr = 0; /* blk */
|
||||
pinfo->lcdc.underflow_clr = 0xff; /* blue */
|
||||
pinfo->lcdc.hsync_skew = 0;
|
||||
pinfo->is_pluggable = true;
|
||||
|
||||
pr_debug("update res. vic= %d, pclk_rate = %llu\n",
|
||||
dp_drv->vic, pinfo->clk_rate);
|
||||
|
||||
return 0;
|
||||
} /* dp_init_panel_info */
|
||||
|
@ -963,6 +968,9 @@ int mdss_dp_on(struct mdss_panel_data *pdata)
|
|||
|
||||
}
|
||||
|
||||
if (dp_drv->new_vic && (dp_drv->new_vic != dp_drv->vic))
|
||||
dp_init_panel_info(dp_drv, dp_drv->new_vic);
|
||||
|
||||
mdss_dp_phy_aux_setup(&dp_drv->phy_io);
|
||||
|
||||
mdss_dp_irq_enable(dp_drv);
|
||||
|
@ -1072,6 +1080,44 @@ int mdss_dp_off(struct mdss_panel_data *pdata)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void mdss_dp_send_cable_notification(
|
||||
struct mdss_dp_drv_pdata *dp, int val)
|
||||
{
|
||||
int state = 0;
|
||||
|
||||
if (!dp) {
|
||||
DEV_ERR("%s: invalid input\n", __func__);
|
||||
return;
|
||||
}
|
||||
state = dp->sdev.state;
|
||||
|
||||
switch_set_state(&dp->sdev, val);
|
||||
|
||||
DEV_INFO("%s: cable state %s %d\n", __func__,
|
||||
dp->sdev.state == state ?
|
||||
"is same" : "switched to",
|
||||
dp->sdev.state);
|
||||
}
|
||||
|
||||
static int mdss_dp_register_switch_event(struct mdss_dp_drv_pdata *dp)
|
||||
{
|
||||
int rc = -EINVAL;
|
||||
|
||||
if (!dp) {
|
||||
DEV_ERR("%s: invalid input\n", __func__);
|
||||
goto end;
|
||||
}
|
||||
|
||||
dp->sdev.name = "hdmi";
|
||||
rc = switch_dev_register(&dp->sdev);
|
||||
if (rc) {
|
||||
DEV_ERR("%s: display switch registration failed\n", __func__);
|
||||
goto end;
|
||||
}
|
||||
end:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int mdss_dp_edid_init(struct mdss_panel_data *pdata)
|
||||
{
|
||||
struct mdss_dp_drv_pdata *dp_drv = NULL;
|
||||
|
@ -1097,9 +1143,6 @@ static int mdss_dp_edid_init(struct mdss_panel_data *pdata)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
edid_init_data.buf = edid_init_data.buf;
|
||||
edid_init_data.buf_size = edid_init_data.buf_size;
|
||||
|
||||
/* Use the existing EDID buffer for 1080p */
|
||||
memcpy(edid_init_data.buf, edid_buf1, sizeof(edid_buf1));
|
||||
dp_drv->panel_data.panel_info.edid_data = edid_data;
|
||||
|
@ -1152,6 +1195,8 @@ static int mdss_dp_host_init(struct mdss_panel_data *pdata)
|
|||
goto edid_parser_error;
|
||||
}
|
||||
|
||||
mdss_dp_send_cable_notification(dp_drv, true);
|
||||
|
||||
return ret;
|
||||
|
||||
edid_parser_error:
|
||||
|
@ -1162,6 +1207,44 @@ vreg_error:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int mdss_dp_check_params(struct mdss_dp_drv_pdata *dp, void *arg)
|
||||
{
|
||||
struct mdss_panel_info *var_pinfo, *pinfo;
|
||||
int rc = 0;
|
||||
int new_vic = -1;
|
||||
|
||||
if (!dp || !arg)
|
||||
return 0;
|
||||
|
||||
pinfo = &dp->panel_data.panel_info;
|
||||
var_pinfo = (struct mdss_panel_info *)arg;
|
||||
|
||||
pr_debug("reconfig xres: %d yres: %d, current xres: %d yres: %d\n",
|
||||
var_pinfo->xres, var_pinfo->yres,
|
||||
pinfo->xres, pinfo->yres);
|
||||
|
||||
new_vic = hdmi_panel_get_vic(var_pinfo, &dp->ds_data);
|
||||
|
||||
if ((new_vic < 0) || (new_vic > HDMI_VFRMT_MAX)) {
|
||||
DEV_ERR("%s: invalid or not supported vic\n", __func__);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/*
|
||||
* return value of 1 lets mdss know that panel
|
||||
* needs a reconfig due to new resolution and
|
||||
* it will issue close and open subsequently.
|
||||
*/
|
||||
if (new_vic != dp->vic) {
|
||||
rc = 1;
|
||||
DEV_ERR("%s: res change %d ==> %d\n", __func__,
|
||||
dp->vic, new_vic);
|
||||
}
|
||||
dp->new_vic = new_vic;
|
||||
end:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int mdss_dp_event_handler(struct mdss_panel_data *pdata,
|
||||
int event, void *arg)
|
||||
{
|
||||
|
@ -1194,9 +1277,13 @@ static int mdss_dp_event_handler(struct mdss_panel_data *pdata,
|
|||
dp->kobj = &fbi->dev->kobj;
|
||||
dp->fb_node = fbi->node;
|
||||
mdss_dp_edid_init(pdata);
|
||||
mdss_dp_register_switch_event(dp);
|
||||
break;
|
||||
case MDSS_EVENT_CHECK_PARAMS:
|
||||
rc = mdss_dp_check_params(dp, arg);
|
||||
break;
|
||||
default:
|
||||
pr_debug("%s: unhandled event=%d\n", __func__, event);
|
||||
pr_debug("unhandled event=%d\n", event);
|
||||
break;
|
||||
}
|
||||
return rc;
|
||||
|
@ -1220,7 +1307,7 @@ static int mdss_dp_device_register(struct mdss_dp_drv_pdata *dp_drv)
|
|||
{
|
||||
int ret;
|
||||
|
||||
ret = dp_init_panel_info(dp_drv);
|
||||
ret = dp_init_panel_info(dp_drv, DEFAULT_VIDEO_RESOLUTION);
|
||||
if (ret) {
|
||||
DEV_ERR("%s: dp_init_panel_info failed\n", __func__);
|
||||
return ret;
|
||||
|
@ -1493,6 +1580,7 @@ static void usbpd_disconnect_callback(struct usbpd_svid_handler *hdlr)
|
|||
mutex_lock(&dp_drv->pd_msg_mutex);
|
||||
dp_drv->cable_connected = false;
|
||||
mutex_unlock(&dp_drv->pd_msg_mutex);
|
||||
mdss_dp_send_cable_notification(dp_drv, false);
|
||||
}
|
||||
|
||||
static void usbpd_response_callback(struct usbpd_svid_handler *hdlr, u8 cmd,
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <linux/gpio.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/usb/usbpd.h>
|
||||
#include <linux/switch.h>
|
||||
|
||||
#include "mdss_hdmi_util.h"
|
||||
#include "mdss_hdmi_edid.h"
|
||||
|
@ -430,8 +431,11 @@ struct mdss_dp_drv_pdata {
|
|||
spinlock_t event_lock;
|
||||
spinlock_t lock;
|
||||
struct hdmi_util_ds_data ds_data;
|
||||
struct switch_dev sdev;
|
||||
struct kobject *kobj;
|
||||
u32 max_pclk_khz;
|
||||
u32 vic;
|
||||
u32 new_vic;
|
||||
int fb_node;
|
||||
};
|
||||
|
||||
|
|
|
@ -331,8 +331,8 @@ static ssize_t mdss_fb_get_type(struct device *dev,
|
|||
case WRITEBACK_PANEL:
|
||||
ret = snprintf(buf, PAGE_SIZE, "writeback panel\n");
|
||||
break;
|
||||
case EDP_PANEL:
|
||||
ret = snprintf(buf, PAGE_SIZE, "edp panel\n");
|
||||
case DP_PANEL:
|
||||
ret = snprintf(buf, PAGE_SIZE, "dp panel\n");
|
||||
break;
|
||||
default:
|
||||
ret = snprintf(buf, PAGE_SIZE, "unknown panel\n");
|
||||
|
|
|
@ -150,7 +150,7 @@ enum hdmi_scaling_info {
|
|||
HDMI_SCALING_HORZ_VERT,
|
||||
};
|
||||
|
||||
static int hdmi_panel_get_vic(struct mdss_panel_info *pinfo,
|
||||
int hdmi_panel_get_vic(struct mdss_panel_info *pinfo,
|
||||
struct hdmi_util_ds_data *ds_data)
|
||||
{
|
||||
int new_vic = -1;
|
||||
|
|
|
@ -104,4 +104,7 @@ void *hdmi_panel_init(struct hdmi_panel_init_data *data);
|
|||
*/
|
||||
void hdmi_panel_deinit(void *input);
|
||||
|
||||
int hdmi_panel_get_vic(struct mdss_panel_info *pinfo,
|
||||
struct hdmi_util_ds_data *ds_data);
|
||||
|
||||
#endif /* __MDSS_HDMI_PANEL_H__ */
|
||||
|
|
|
@ -2668,7 +2668,7 @@ int mdss_mdp_ctl_splash_finish(struct mdss_mdp_ctl *ctl, bool handoff)
|
|||
{
|
||||
switch (ctl->panel_data->panel_info.type) {
|
||||
case MIPI_VIDEO_PANEL:
|
||||
case EDP_PANEL:
|
||||
case DP_PANEL:
|
||||
case DTV_PANEL:
|
||||
return mdss_mdp_video_reconfigure_splash_done(ctl, handoff);
|
||||
case MIPI_CMD_PANEL:
|
||||
|
@ -3686,7 +3686,7 @@ struct mdss_mdp_ctl *mdss_mdp_ctl_init(struct mdss_panel_data *pdata,
|
|||
ctl->disable_prefill = false;
|
||||
|
||||
switch (pdata->panel_info.type) {
|
||||
case EDP_PANEL:
|
||||
case DP_PANEL:
|
||||
ctl->is_video_mode = true;
|
||||
ctl->intf_num = MDSS_MDP_INTF0;
|
||||
ctl->intf_type = MDSS_INTF_EDP;
|
||||
|
|
|
@ -51,7 +51,7 @@ struct panel_id {
|
|||
#define MIPI_CMD_PANEL 9 /* MIPI */
|
||||
#define WRITEBACK_PANEL 10 /* Wifi display */
|
||||
#define LVDS_PANEL 11 /* LVDS */
|
||||
#define EDP_PANEL 12 /* LVDS */
|
||||
#define DP_PANEL 12 /* LVDS */
|
||||
|
||||
#define DSC_PPS_LEN 128
|
||||
|
||||
|
@ -61,7 +61,7 @@ static inline const char *mdss_panel2str(u32 panel)
|
|||
#define PANEL_NAME(n) [n ## _PANEL] = __stringify(n)
|
||||
PANEL_NAME(MIPI_VIDEO),
|
||||
PANEL_NAME(MIPI_CMD),
|
||||
PANEL_NAME(EDP),
|
||||
PANEL_NAME(DP),
|
||||
PANEL_NAME(HDMI),
|
||||
PANEL_NAME(DTV),
|
||||
PANEL_NAME(WRITEBACK),
|
||||
|
@ -811,7 +811,7 @@ static inline u32 mdss_panel_get_framerate(struct mdss_panel_info *panel_info)
|
|||
case MIPI_CMD_PANEL:
|
||||
frame_rate = panel_info->mipi.frame_rate;
|
||||
break;
|
||||
case EDP_PANEL:
|
||||
case DP_PANEL:
|
||||
frame_rate = panel_info->edp.frame_rate;
|
||||
break;
|
||||
case WRITEBACK_PANEL:
|
||||
|
|
Loading…
Add table
Reference in a new issue