Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ca29376e authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "mdss: display-port: add support to send HPD event to framework"

parents e2dc38ec cfabc2bc
Loading
Loading
Loading
Loading
+97 −9
Original line number Diff line number Diff line
@@ -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,
+4 −0
Original line number Diff line number Diff line
@@ -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;
};

+2 −2
Original line number Diff line number Diff line
@@ -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");
+1 −1
Original line number Diff line number Diff line
@@ -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;
+3 −0
Original line number Diff line number Diff line
@@ -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__ */
Loading