summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2016-08-10 18:29:18 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2016-08-10 18:29:17 -0700
commitca29376ef10aec37cad04db5df88b34103426739 (patch)
tree057c436fc692c734d8319a6c2747a72954ae7528
parente2dc38ec3f90f645844bfcc0b8f973d261a4d015 (diff)
parentcfabc2bcfe357aa6e523274e2036752e91816f92 (diff)
Merge "mdss: display-port: add support to send HPD event to framework"
-rw-r--r--drivers/video/fbdev/msm/mdss_dp.c106
-rw-r--r--drivers/video/fbdev/msm/mdss_dp.h4
-rw-r--r--drivers/video/fbdev/msm/mdss_fb.c4
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_panel.c2
-rw-r--r--drivers/video/fbdev/msm/mdss_hdmi_panel.h3
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_ctl.c4
-rw-r--r--drivers/video/fbdev/msm/mdss_panel.h6
7 files changed, 112 insertions, 17 deletions
diff --git a/drivers/video/fbdev/msm/mdss_dp.c b/drivers/video/fbdev/msm/mdss_dp.c
index eefea9f117c0..0ac5ef4f750c 100644
--- a/drivers/video/fbdev/msm/mdss_dp.c
+++ b/drivers/video/fbdev/msm/mdss_dp.c
@@ -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,
diff --git a/drivers/video/fbdev/msm/mdss_dp.h b/drivers/video/fbdev/msm/mdss_dp.h
index 10fcdec49515..03646cd7cc65 100644
--- a/drivers/video/fbdev/msm/mdss_dp.h
+++ b/drivers/video/fbdev/msm/mdss_dp.h
@@ -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;
};
diff --git a/drivers/video/fbdev/msm/mdss_fb.c b/drivers/video/fbdev/msm/mdss_fb.c
index 99a924c38d65..b2c0c78d3f2b 100644
--- a/drivers/video/fbdev/msm/mdss_fb.c
+++ b/drivers/video/fbdev/msm/mdss_fb.c
@@ -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");
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_panel.c b/drivers/video/fbdev/msm/mdss_hdmi_panel.c
index b4d3dad50d45..0335bf900866 100644
--- a/drivers/video/fbdev/msm/mdss_hdmi_panel.c
+++ b/drivers/video/fbdev/msm/mdss_hdmi_panel.c
@@ -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;
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_panel.h b/drivers/video/fbdev/msm/mdss_hdmi_panel.h
index 24d3b9b52798..e5cc1486f222 100644
--- a/drivers/video/fbdev/msm/mdss_hdmi_panel.h
+++ b/drivers/video/fbdev/msm/mdss_hdmi_panel.h
@@ -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__ */
diff --git a/drivers/video/fbdev/msm/mdss_mdp_ctl.c b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
index 1a0ba8f0e2a7..2218e9c4ac81 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_ctl.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_ctl.c
@@ -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;
diff --git a/drivers/video/fbdev/msm/mdss_panel.h b/drivers/video/fbdev/msm/mdss_panel.h
index 7a49f37660dd..bde137269422 100644
--- a/drivers/video/fbdev/msm/mdss_panel.h
+++ b/drivers/video/fbdev/msm/mdss_panel.h
@@ -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: