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

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

Merge "msm: mdss: add support for edp panel"

parents 81fcfaff 63017087
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@ Required properties
- vdda-supply :				Phandle for vdd regulator device node.
- gpio-panel-en	:			GPIO for supplying power to panel and backlight
							driver.
- gpio-lvl-en	:			GPIO to enable HPD be received by host.
- status :				A string that has to be set to "okay/ok" to enable
						the driver. By default this property will be set to
						"disable". Will be set to "ok/okay" status for
@@ -41,6 +42,7 @@ Example:
		reg-names = "edp_base", "mmss_cc_base";
		vdda-supply = <&pm8941_l12>;
		gpio-panel-en = <&msmgpio 58 0>;
		gpio-lvl-en = <&msmgpio 91 0>;
		qcom,panel-lpg-channel = <7>; /* LPG Channel 8 */
		qcom,panel-pwm-period = <53>;
		status = "disable";
+62 −5
Original line number Diff line number Diff line
/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
 *
 * 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
@@ -153,6 +153,41 @@ gpio_err:
	return -ENODEV;
}

static int mdss_edp_gpio_lvl_en(struct mdss_edp_drv_pdata *edp_drv)
{
	int ret = 0;

	edp_drv->gpio_lvl_en = of_get_named_gpio(edp_drv->pdev->dev.of_node,
			"gpio-lvl-en", 0);
	if (!gpio_is_valid(edp_drv->gpio_lvl_en)) {
		pr_err("%s: gpio_lvl_en=%d not specified\n", __func__,
				edp_drv->gpio_lvl_en);
		ret = -ENODEV;
		goto gpio_err;
	}

	ret = gpio_request(edp_drv->gpio_lvl_en, "lvl_enable");
	if (ret) {
		pr_err("%s: Request reset gpio_lvl_en failed, ret=%d\n",
				__func__, ret);
		return ret;
	}

	ret = gpio_direction_output(edp_drv->gpio_lvl_en, 1);
	if (ret) {
		pr_err("%s: Set direction for gpio_lvl_en failed, ret=%d\n",
				__func__, ret);
		goto gpio_free;
	}

	return ret;

gpio_free:
	gpio_free(edp_drv->gpio_lvl_en);
gpio_err:
	return ret;
}

static int mdss_edp_pwm_config(struct mdss_edp_drv_pdata *edp_drv)
{
	int ret = 0;
@@ -578,6 +613,8 @@ int mdss_edp_on(struct mdss_panel_data *pdata)
		mdss_edp_timing_cfg(edp_drv);

		gpio_set_value(edp_drv->gpio_panel_en, 1);
		if (gpio_is_valid(edp_drv->gpio_lvl_en))
			gpio_set_value(edp_drv->gpio_lvl_en, 1);

		INIT_COMPLETION(edp_drv->idle_comp);
		mdss_edp_mainlink_ctrl(edp_drv, 1);
@@ -587,6 +624,11 @@ int mdss_edp_on(struct mdss_panel_data *pdata)

	mdss_edp_irq_enable(edp_drv);

	if (edp_drv->delay_link_train) {
		mdss_edp_link_train(edp_drv);
		edp_drv->delay_link_train = 0;
	}

	mdss_edp_wait4train(edp_drv);

	edp_drv->cont_splash = 0;
@@ -626,6 +668,8 @@ int mdss_edp_off(struct mdss_panel_data *pdata)
	mdss_edp_irq_disable(edp_drv);

	gpio_set_value(edp_drv->gpio_panel_en, 0);
	if (gpio_is_valid(edp_drv->gpio_lvl_en))
		gpio_set_value(edp_drv->gpio_lvl_en, 0);
	if (edp_drv->bl_pwm != NULL)
		pwm_disable(edp_drv->bl_pwm);
	edp_drv->is_pwm_enabled = 0;
@@ -720,6 +764,8 @@ static int mdss_edp_remove(struct platform_device *pdev)
	edp_drv = platform_get_drvdata(pdev);

	gpio_free(edp_drv->gpio_panel_en);
	if (gpio_is_valid(edp_drv->gpio_lvl_en))
		gpio_free(edp_drv->gpio_lvl_en);
	mdss_edp_regulator_off(edp_drv);
	iounmap(edp_drv->base);
	iounmap(edp_drv->mmss_cc_base);
@@ -756,7 +802,7 @@ static int mdss_edp_device_register(struct mdss_edp_drv_pdata *edp_drv)
		return ret;
	}

	pr_debug("%s: eDP initialized\n", __func__);
	pr_info("%s: eDP initialized\n", __func__);

	return 0;
}
@@ -829,6 +875,11 @@ static void mdss_edp_do_link_train(struct mdss_edp_drv_pdata *ep)
	if (ep->cont_splash)
		return;

	if (!ep->inited) {
		ep->delay_link_train++;
		return;
	}

	mdss_edp_link_train(ep);
}

@@ -1094,6 +1145,10 @@ static int mdss_edp_probe(struct platform_device *pdev)
	if (ret)
		goto edp_clk_deinit;

	ret = mdss_edp_gpio_lvl_en(edp_drv);
	if (ret)
		pr_err("%s: No gpio_lvl_en detected\n", __func__);

	ret = mdss_edp_pwm_config(edp_drv);
	if (ret)
		goto edp_free_gpio_panel_en;
@@ -1107,8 +1162,6 @@ static int mdss_edp_probe(struct platform_device *pdev)
	edp_drv->cont_splash = of_property_read_bool(pdev->dev.of_node,
			"qcom,cont-splash-enabled");

	pr_debug("%s:cont_splash=%d\n", __func__, edp_drv->cont_splash);

	/* only need aux and ahb clock for aux channel */
	mdss_edp_prepare_aux_clocks(edp_drv);
	mdss_edp_aux_clk_enable(edp_drv);
@@ -1144,13 +1197,17 @@ static int mdss_edp_probe(struct platform_device *pdev)

	mdss_edp_device_register(edp_drv);

	pr_info("%s: done\n", __func__);
	edp_drv->inited = true;

	pr_debug("%s: done\n", __func__);

	return 0;


edp_free_gpio_panel_en:
	gpio_free(edp_drv->gpio_panel_en);
	if (gpio_is_valid(edp_drv->gpio_lvl_en))
		gpio_free(edp_drv->gpio_lvl_en);
edp_clk_deinit:
	mdss_edp_clk_deinit(edp_drv);
	mdss_edp_regulator_off(edp_drv);
+4 −1
Original line number Diff line number Diff line
/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
 *
 * 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
@@ -262,6 +262,8 @@ struct mdss_edp_drv_pdata {
	struct mutex emutex;
	int clk_cnt;
	int cont_splash;
	bool inited;
	int delay_link_train;

	/* edp specific */
	unsigned char *base;
@@ -298,6 +300,7 @@ struct mdss_edp_drv_pdata {

	/* gpios */
	int gpio_panel_en;
	int gpio_lvl_en;

	/* backlight */
	struct pwm_device *bl_pwm;
+5 −6
Original line number Diff line number Diff line
/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
 *
 * 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
@@ -1201,7 +1201,6 @@ static int edp_aux_link_train(struct mdss_edp_drv_pdata *ep)
{
	int ret = 0;

	pr_debug("%s", __func__);
	ret = edp_aux_chan_ready(ep);
	if (ret == 0) {
		pr_err("%s: LINK Train failed: aux chan NOT ready\n", __func__);
@@ -1229,13 +1228,13 @@ train_start:
		if (edp_link_rate_down_shift(ep) == 0) {
			goto train_start;
		} else {
			pr_err("%s: Training 1 failed", __func__);
			pr_err("%s: Training 1 failed\n", __func__);
			ret = -1;
			goto clear;
		}
	}

	pr_debug("%s: Training 1 completed successfully", __func__);
	pr_debug("%s: Training 1 completed successfully\n", __func__);

	mdss_edp_state_ctrl(ep, 0);
	edp_clear_training_pattern(ep);
@@ -1244,13 +1243,13 @@ train_start:
		if (edp_link_rate_down_shift(ep) == 0) {
			goto train_start;
		} else {
			pr_err("%s: Training 2 failed", __func__);
			pr_err("%s: Training 2 failed\n", __func__);
			ret = -1;
			goto clear;
		}
	}

	pr_debug("%s: Training 2 completed successfully", __func__);
	pr_debug("%s: Training 2 completed successfully\n", __func__);

	mdss_edp_state_ctrl(ep, ST_SEND_VIDEO);
clear:
+13 −0
Original line number Diff line number Diff line
@@ -1492,6 +1492,17 @@ void mdss_edp_aux_clk_disable(struct mdss_edp_drv_pdata *edp_drv)
	clk_disable(edp_drv->mdp_core_clk);
}

static void mdss_edp_clk_set_rate(struct mdss_edp_drv_pdata *edp_drv)
{
	if (clk_set_rate(edp_drv->link_clk, edp_drv->link_rate * 27000000) < 0)
		pr_err("%s: link_clk - clk_set_rate failed\n",
					__func__);

	if (clk_set_rate(edp_drv->pixel_clk, edp_drv->pixel_rate) < 0)
		pr_err("%s: pixel_clk - clk_set_rate failed\n",
					__func__);
}

int mdss_edp_clk_enable(struct mdss_edp_drv_pdata *edp_drv)
{
	int ret;
@@ -1615,6 +1626,8 @@ int mdss_edp_prepare_clocks(struct mdss_edp_drv_pdata *edp_drv)
{
	int ret;

	mdss_edp_clk_set_rate(edp_drv);

	/* ahb clock should be prepared first */
	ret = clk_prepare(edp_drv->ahb_clk);
	if (ret) {