[PATCH 0/8] OMAPDSS: Misc improvements

STALE5161d

25 messages, 3 authors, 2012-09-07 · open the first message on its own page

[PATCH 0/8] OMAPDSS: Misc improvements

From: Tomi Valkeinen <hidden>
Date: 2012-08-23 13:45:06

Hi,

This series contains miscellaneous improvements for omapdss, which I've made
while implementing device tree support for omapdss. This includes some changes
to arch/arm/:

* remove OMAP4 HDMI gpio handling from board files
* add vdda_hdmi_dac supply for HDMI to twl-common.c
* remove DSS clock dividers from 4430sdp board file

Tony, omapdss has dependencies to those changes, and the first change also has
a dependency to omapdss header file. Is it ok to merge them with other omapdss
changes?

Chances for conflict are probably pretty small, 1st and 3rd change are
pure display stuff, and the 2nd adds the supply to a regulator not used by
anyone else than DSS.

 Tomi

Tomi Valkeinen (8):
  OMAPDSS: HDMI: Move GPIO handling to HDMI driver
  OMAPDSS: HDMI: Add delay to wait for 5V power
  OMAP4: TWL: add vdda_hdmi_dac regulator supply
  OMAPDSS: HDMI: use vdda_hdmi_dac
  OMAPDSS: Add DSI fclk maximum to dss_features
  OMAPDSS: DSI: calculate dsi clock
  OMAP: 4430SDP: remove DSI clock config from board file
  OMAPDSS: fix use of dssdev->caps

 arch/arm/mach-omap2/board-4430sdp.c       |   73 +---------------
 arch/arm/mach-omap2/board-omap4panda.c    |   27 +-----
 arch/arm/mach-omap2/twl-common.c          |    6 ++
 drivers/video/omap2/displays/panel-n8x0.c |    1 +
 drivers/video/omap2/displays/panel-taal.c |    8 ++
 drivers/video/omap2/dss/dsi.c             |  131 +++++++++++++++++++++++++++--
 drivers/video/omap2/dss/dss_features.c    |    2 +
 drivers/video/omap2/dss/dss_features.h    |    1 +
 drivers/video/omap2/dss/hdmi.c            |  101 +++++++++++++++++-----
 drivers/video/omap2/dss/rfbi.c            |    1 -

6 more lines

[PATCH 1/8] OMAPDSS: HDMI: Move GPIO handling to HDMI driver

From: Tomi Valkeinen <hidden>
Date: 2012-08-23 13:45:07

We currently manage HDMI GPIOs in the board files via
platform_enable/disable calls. This won't work with device tree, and in
any case the correct place to manage the GPIOs is in the HDMI driver.

This patch moves the handling of the GPIOs to the HDMI driver. The GPIO
handling is moved to the common hdmi.c file, and this probably needs to
be revisited when adding OMAP5 HDMI support to see if the GPIO handling
needs to be moved to IP specific files.

Signed-off-by: Tomi Valkeinen <redacted>
Cc: Tony Lindgren <tony@atomide.com>
---
 arch/arm/mach-omap2/board-4430sdp.c    |   27 +-----------
 arch/arm/mach-omap2/board-omap4panda.c |   27 +-----------
 drivers/video/omap2/dss/hdmi.c         |   75 +++++++++++++++++++++++---------
 include/video/omapdss.h                |    2 +
 4 files changed, 61 insertions(+), 70 deletions(-)
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 8e17284..852e05c 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -601,29 +601,6 @@ static void __init omap_sfh7741prox_init(void)
 			__func__, OMAP4_SFH7741_ENABLE_GPIO, error);
 }
 
-static struct gpio sdp4430_hdmi_gpios[] = {
-	{ HDMI_GPIO_CT_CP_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ct_cp_hpd" },
-	{ HDMI_GPIO_LS_OE,	GPIOF_OUT_INIT_HIGH,	"hdmi_gpio_ls_oe" },
-	{ HDMI_GPIO_HPD, GPIOF_DIR_IN, "hdmi_gpio_hpd" },
-};
-
-static int sdp4430_panel_enable_hdmi(struct omap_dss_device *dssdev)
-{
-	int status;
-
-	status = gpio_request_array(sdp4430_hdmi_gpios,
-				    ARRAY_SIZE(sdp4430_hdmi_gpios));
-	if (status)
-		pr_err("%s: Cannot request HDMI GPIOs\n", __func__);
-
-	return status;
-}
-
-static void sdp4430_panel_disable_hdmi(struct omap_dss_device *dssdev)
-{
-	gpio_free_array(sdp4430_hdmi_gpios, ARRAY_SIZE(sdp4430_hdmi_gpios));
-}
-
 static struct nokia_dsi_panel_data dsi1_panel = {
 		.name		= "taal",
 		.reset_gpio	= 102,
@@ -718,6 +695,8 @@ static struct omap_dss_device sdp4430_lcd2_device = {
 };
 
 static struct omap_dss_hdmi_data sdp4430_hdmi_data = {
+	.ct_cp_hpd_gpio = HDMI_GPIO_CT_CP_HPD,
+	.ls_oe_gpio = HDMI_GPIO_LS_OE,
 	.hpd_gpio = HDMI_GPIO_HPD,
 };
 
@@ -725,8 +704,6 @@ static struct omap_dss_device sdp4430_hdmi_device = {
 	.name = "hdmi",
 	.driver_name = "hdmi_panel",
 	.type = OMAP_DISPLAY_TYPE_HDMI,
-	.platform_enable = sdp4430_panel_enable_hdmi,
-	.platform_disable = sdp4430_panel_disable_hdmi,
 	.channel = OMAP_DSS_CHANNEL_DIGIT,
 	.data = &sdp4430_hdmi_data,
 };
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index 982fb26..5415faa 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -405,30 +405,9 @@ static struct omap_dss_device omap4_panda_dvi_device = {
 	.channel		= OMAP_DSS_CHANNEL_LCD2,
 };
 
-static struct gpio panda_hdmi_gpios[] = {
-	{ HDMI_GPIO_CT_CP_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ct_cp_hpd" },
-	{ HDMI_GPIO_LS_OE,	GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" },
-	{ HDMI_GPIO_HPD, GPIOF_DIR_IN, "hdmi_gpio_hpd" },
-};
-
-static int omap4_panda_panel_enable_hdmi(struct omap_dss_device *dssdev)
-{
-	int status;
-
-	status = gpio_request_array(panda_hdmi_gpios,
-				    ARRAY_SIZE(panda_hdmi_gpios));
-	if (status)
-		pr_err("Cannot request HDMI GPIOs\n");
-
-	return status;
-}
-
-static void omap4_panda_panel_disable_hdmi(struct omap_dss_device *dssdev)
-{
-	gpio_free_array(panda_hdmi_gpios, ARRAY_SIZE(panda_hdmi_gpios));
-}
-
 static struct omap_dss_hdmi_data omap4_panda_hdmi_data = {
+	.ct_cp_hpd_gpio = HDMI_GPIO_CT_CP_HPD,
+	.ls_oe_gpio = HDMI_GPIO_LS_OE,
 	.hpd_gpio = HDMI_GPIO_HPD,
 };
 
@@ -436,8 +415,6 @@ static struct omap_dss_device  omap4_panda_hdmi_device = {
 	.name = "hdmi",
 	.driver_name = "hdmi_panel",
 	.type = OMAP_DISPLAY_TYPE_HDMI,
-	.platform_enable = omap4_panda_panel_enable_hdmi,
-	.platform_disable = omap4_panda_panel_disable_hdmi,
 	.channel = OMAP_DSS_CHANNEL_DIGIT,
 	.data = &omap4_panda_hdmi_data,
 };
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 0cdf246..4fbe271 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -32,6 +32,7 @@
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/clk.h>
+#include <linux/gpio.h>
 #include <video/omapdss.h>
 
 #include "ti_hdmi.h"
@@ -61,6 +62,10 @@ static struct {
 	struct hdmi_ip_data ip_data;
 
 	struct clk *sys_clk;
+
+	int ct_cp_hpd_gpio;
+	int ls_oe_gpio;
+	int hpd_gpio;
 } hdmi;
 
 /*
@@ -314,12 +319,34 @@ static void hdmi_runtime_put(void)
 
 static int __init hdmi_init_display(struct omap_dss_device *dssdev)
 {
+	int r;
+
+	struct gpio gpios[] = {
+		{ hdmi.ct_cp_hpd_gpio, GPIOF_OUT_INIT_LOW, "hdmi_ct_cp_hpd" },
+		{ hdmi.ls_oe_gpio, GPIOF_OUT_INIT_LOW, "hdmi_ls_oe" },
+		{ hdmi.hpd_gpio, GPIOF_DIR_IN, "hdmi_hpd" },
+	};
+
 	DSSDBG("init_display\n");
 
 	dss_init_hdmi_ip_ops(&hdmi.ip_data);
+
+	r = gpio_request_array(gpios, ARRAY_SIZE(gpios));
+	if (r)
+		return r;
+
 	return 0;
 }
 
+static void __exit hdmi_uninit_display(struct omap_dss_device *dssdev)
+{
+	DSSDBG("uninit_display\n");
+
+	gpio_free(hdmi.ct_cp_hpd_gpio);
+	gpio_free(hdmi.ls_oe_gpio);
+	gpio_free(hdmi.hpd_gpio);
+}
+
 static const struct hdmi_config *hdmi_find_timing(
 					const struct hdmi_config *timings_arr,
 					int len)
@@ -462,9 +489,12 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
 	struct omap_video_timings *p;
 	unsigned long phy;
 
+	gpio_set_value(hdmi.ct_cp_hpd_gpio, 1);
+	gpio_set_value(hdmi.ls_oe_gpio, 1);
+
 	r = hdmi_runtime_get();
 	if (r)
-		return r;
+		goto err_runtime_get;
 
 	dss_mgr_disable(dssdev->manager);
 
@@ -482,7 +512,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
 	r = hdmi.ip_data.ops->pll_enable(&hdmi.ip_data);
 	if (r) {
 		DSSDBG("Failed to lock PLL\n");
-		goto err;
+		goto err_pll_enable;
 	}
 
 	r = hdmi.ip_data.ops->phy_enable(&hdmi.ip_data);
@@ -526,8 +556,11 @@ err_vid_enable:
 	hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
 err_phy_enable:
 	hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
-err:
+err_pll_enable:
 	hdmi_runtime_put();
+err_runtime_get:
+	gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
+	gpio_set_value(hdmi.ls_oe_gpio, 0);
 	return -EIO;
 }
 
@@ -539,6 +572,9 @@ static void hdmi_power_off(struct omap_dss_device *dssdev)
 	hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
 	hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
 	hdmi_runtime_put();
+
+	gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
+	gpio_set_value(hdmi.ls_oe_gpio, 0);
 }
 
 int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
@@ -637,7 +673,6 @@ bool omapdss_hdmi_detect(void)
 
 int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
 {
-	struct omap_dss_hdmi_data *priv = dssdev->data;
 	int r = 0;
 
 	DSSDBG("ENTER hdmi_display_enable\n");
@@ -650,7 +685,7 @@ int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
 		goto err0;
 	}
 
-	hdmi.ip_data.hpd_gpio = priv->hpd_gpio;
+	hdmi.ip_data.hpd_gpio = hdmi.hpd_gpio;
 
 	r = omap_dss_start_device(dssdev);
 	if (r) {
@@ -658,26 +693,15 @@ int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
 		goto err0;
 	}
 
-	if (dssdev->platform_enable) {
-		r = dssdev->platform_enable(dssdev);
-		if (r) {
-			DSSERR("failed to enable GPIO's\n");
-			goto err1;
-		}
-	}
-
 	r = hdmi_power_on(dssdev);
 	if (r) {
 		DSSERR("failed to power on device\n");
-		goto err2;
+		goto err1;
 	}
 
 	mutex_unlock(&hdmi.lock);
 	return 0;
 
-err2:
-	if (dssdev->platform_disable)
-		dssdev->platform_disable(dssdev);
 err1:
 	omap_dss_stop_device(dssdev);
 err0:
@@ -693,9 +717,6 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
 
 	hdmi_power_off(dssdev);
 
-	if (dssdev->platform_disable)
-		dssdev->platform_disable(dssdev);
-
 	omap_dss_stop_device(dssdev);
 
 	mutex_unlock(&hdmi.lock);
@@ -873,10 +894,15 @@ static void __init hdmi_probe_pdata(struct platform_device *pdev)
 
 	for (i = 0; i < pdata->num_devices; ++i) {
 		struct omap_dss_device *dssdev = pdata->devices[i];
+		struct omap_dss_hdmi_data *priv = dssdev->data;
 
 		if (dssdev->type != OMAP_DISPLAY_TYPE_HDMI)
 			continue;
 
+		hdmi.ct_cp_hpd_gpio = priv->ct_cp_hpd_gpio;
+		hdmi.ls_oe_gpio = priv->ls_oe_gpio;
+		hdmi.hpd_gpio = priv->hpd_gpio;
+
 		r = hdmi_init_display(dssdev);
 		if (r) {
 			DSSERR("device %s init failed: %d\n", dssdev->name, r);
@@ -938,8 +964,17 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
 	return 0;
 }
 
+static int __exit hdmi_remove_child(struct device *dev, void *data)
+{
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	hdmi_uninit_display(dssdev);
+	return 0;
+}
+
 static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
 {
+	device_for_each_child(&pdev->dev, NULL, hdmi_remove_child);
+
 	omap_dss_unregister_child_devices(&pdev->dev);
 
 	hdmi_panel_exit();
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index b868123..c6ffe88 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -605,6 +605,8 @@ struct omap_dss_device {
 
 struct omap_dss_hdmi_data
 {
+	int ct_cp_hpd_gpio;
+	int ls_oe_gpio;
 	int hpd_gpio;
 };
 
-- 
1.7.9.5

[PATCH 2/8] OMAPDSS: HDMI: Add delay to wait for 5V power

From: Tomi Valkeinen <hidden>
Date: 2012-08-23 13:45:08

TPD12S015A spec says to wait 300us after setting CT_CP_HPD gpio for the
5V power output to reach 90% of the voltage. This patch adds the delay
to the driver.

Signed-off-by: Tomi Valkeinen <redacted>
---
 drivers/video/omap2/dss/hdmi.c |    3 +++
 1 file changed, 3 insertions(+)
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 4fbe271..96a6e29 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -492,6 +492,9 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
 	gpio_set_value(hdmi.ct_cp_hpd_gpio, 1);
 	gpio_set_value(hdmi.ls_oe_gpio, 1);
 
+	/* wait 300us after CT_CP_HPD for the 5V power output to reach 90% */
+	udelay(300);
+
 	r = hdmi_runtime_get();
 	if (r)
 		goto err_runtime_get;
-- 
1.7.9.5

[PATCH 3/8] OMAP4: TWL: add vdda_hdmi_dac regulator supply

From: Tomi Valkeinen <hidden>
Date: 2012-08-23 13:45:09

HDMI requires vdda_hdmi_dac (vdac) power for operation. The regulator,
or the regulator supplying the vdac, has been enabled by default and
things have worked without the HDMI driver enabling the vdac.

I encountered the problem when implementing HDMI device tree support,
where the regulator was not enabled by default.

This patch adds the vdda_hdmi_dac to twl-common.c so that the HDMI
driver can use it.

Signed-off-by: Tomi Valkeinen <redacted>
Cc: Tony Lindgren <tony@atomide.com>
---
 arch/arm/mach-omap2/twl-common.c |    6 ++++++
 1 file changed, 6 insertions(+)
diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c
index 119d5a9..bf90356 100644
--- a/arch/arm/mach-omap2/twl-common.c
+++ b/arch/arm/mach-omap2/twl-common.c
@@ -257,6 +257,10 @@ static struct twl4030_usb_data omap4_usb_pdata = {
 	.phy_suspend	= omap4430_phy_suspend,
 };
 
+static struct regulator_consumer_supply omap4_vdda_hdmi_dac_supplies[] = {
+	REGULATOR_SUPPLY("vdda_hdmi_dac", "omapdss_hdmi"),
+};
+
 static struct regulator_init_data omap4_vdac_idata = {
 	.constraints = {
 		.min_uV			= 1800000,
@@ -266,6 +270,8 @@ static struct regulator_init_data omap4_vdac_idata = {
 		.valid_ops_mask		= REGULATOR_CHANGE_MODE
 					| REGULATOR_CHANGE_STATUS,
 	},
+	.num_consumer_supplies	= ARRAY_SIZE(omap4_vdda_hdmi_dac_supplies),
+	.consumer_supplies	= omap4_vdda_hdmi_dac_supplies,
 	.supply_regulator	= "V2V1",
 };
 
-- 
1.7.9.5

[PATCH 4/8] OMAPDSS: HDMI: use vdda_hdmi_dac

From: Tomi Valkeinen <hidden>
Date: 2012-08-23 13:45:10

The HDMI driver requires vdda_hdmi_dac power for operation, but does not
enable it. This has worked because the regulator has been always
enabled.

But this may not always be the case, as I encountered when implementing
HDMI device tree support.

This patch changes the HDMI driver to use the vdda_hdmi_dac.

Signed-off-by: Tomi Valkeinen <redacted>
---
 drivers/video/omap2/dss/hdmi.c |   23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 96a6e29..ccfc677 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -33,6 +33,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/clk.h>
 #include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
 #include <video/omapdss.h>
 
 #include "ti_hdmi.h"
@@ -62,6 +63,7 @@ static struct {
 	struct hdmi_ip_data ip_data;
 
 	struct clk *sys_clk;
+	struct regulator *vdda_hdmi_dac_reg;
 
 	int ct_cp_hpd_gpio;
 	int ls_oe_gpio;
@@ -331,6 +333,19 @@ static int __init hdmi_init_display(struct omap_dss_device *dssdev)
 
 	dss_init_hdmi_ip_ops(&hdmi.ip_data);
 
+	if (hdmi.vdda_hdmi_dac_reg = NULL) {
+		struct regulator *reg;
+
+		reg = devm_regulator_get(&hdmi.pdev->dev, "vdda_hdmi_dac");
+
+		if (IS_ERR(reg)) {
+			DSSERR("can't get VDDA_HDMI_DAC regulator\n");
+			return PTR_ERR(reg);
+		}
+
+		hdmi.vdda_hdmi_dac_reg = reg;
+	}
+
 	r = gpio_request_array(gpios, ARRAY_SIZE(gpios));
 	if (r)
 		return r;
@@ -495,6 +510,10 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
 	/* wait 300us after CT_CP_HPD for the 5V power output to reach 90% */
 	udelay(300);
 
+	r = regulator_enable(hdmi.vdda_hdmi_dac_reg);
+	if (r)
+		goto err_vdac_enable;
+
 	r = hdmi_runtime_get();
 	if (r)
 		goto err_runtime_get;
@@ -562,6 +581,8 @@ err_phy_enable:
 err_pll_enable:
 	hdmi_runtime_put();
 err_runtime_get:
+	regulator_disable(hdmi.vdda_hdmi_dac_reg);
+err_vdac_enable:
 	gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
 	gpio_set_value(hdmi.ls_oe_gpio, 0);
 	return -EIO;
@@ -576,6 +597,8 @@ static void hdmi_power_off(struct omap_dss_device *dssdev)
 	hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
 	hdmi_runtime_put();
 
+	regulator_disable(hdmi.vdda_hdmi_dac_reg);
+
 	gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
 	gpio_set_value(hdmi.ls_oe_gpio, 0);
 }
-- 
1.7.9.5

[PATCH 5/8] OMAPDSS: Add DSI fclk maximum to dss_features

From: Tomi Valkeinen <hidden>
Date: 2012-08-23 13:45:11

Add max value of DSI functional clock to dss_features, so that DSI
driver can use it.

Signed-off-by: Tomi Valkeinen <redacted>
---
 drivers/video/omap2/dss/dss_features.c |    2 ++
 drivers/video/omap2/dss/dss_features.h |    1 +
 2 files changed, 3 insertions(+)
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 2fe39d6..c26fc1f 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -326,6 +326,7 @@ static const struct dss_param_range omap3_dss_param_range[] = {
 	[FEAT_PARAM_DSIPLL_REGM_DSI]		= { 0, (1 << 4) - 1 },
 	[FEAT_PARAM_DSIPLL_FINT]		= { 750000, 2100000 },
 	[FEAT_PARAM_DSIPLL_LPDIV]		= { 1, (1 << 13) - 1},
+	[FEAT_PARAM_DSI_FCK]			= { 0, 173000000 },
 	[FEAT_PARAM_DOWNSCALE]			= { 1, 4 },
 	[FEAT_PARAM_LINEWIDTH]			= { 1, 1024 },
 	[FEAT_PARAM_MGR_WIDTH]			= { 1, 2048 },
@@ -341,6 +342,7 @@ static const struct dss_param_range omap4_dss_param_range[] = {
 	[FEAT_PARAM_DSIPLL_REGM_DSI]		= { 0, (1 << 5) - 1 },
 	[FEAT_PARAM_DSIPLL_FINT]		= { 500000, 2500000 },
 	[FEAT_PARAM_DSIPLL_LPDIV]		= { 0, (1 << 13) - 1 },
+	[FEAT_PARAM_DSI_FCK]			= { 0, 170000000 },
 	[FEAT_PARAM_DOWNSCALE]			= { 1, 4 },
 	[FEAT_PARAM_LINEWIDTH]			= { 1, 2048 },
 	[FEAT_PARAM_MGR_WIDTH]			= { 1, 2048 },
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index 26d43a4..b81d603 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -92,6 +92,7 @@ enum dss_range_param {
 	FEAT_PARAM_DSIPLL_REGM_DSI,
 	FEAT_PARAM_DSIPLL_FINT,
 	FEAT_PARAM_DSIPLL_LPDIV,
+	FEAT_PARAM_DSI_FCK,
 	FEAT_PARAM_DOWNSCALE,
 	FEAT_PARAM_LINEWIDTH,
 	FEAT_PARAM_MGR_WIDTH,
-- 
1.7.9.5

[PATCH 6/8] OMAPDSS: DSI: calculate dsi clock

From: Tomi Valkeinen <hidden>
Date: 2012-08-23 13:45:12

Currently the way to configure clocks related to DSI (both DSI and DISPC
clocks) happens via omapdss platform data. The reason for this is that
configuring the DSS clocks is a very complex problem, and it's
impossible for the SW to know requirements about things like
interference.

However, for general cases it should be fine to calculate the dividers
for clocks in the SW. The calculated clocks are probably not perfect,
but should work.

This patch adds support to calculate the dividers when using DSI command
mode panels. The panel gives the required DDR clock rate and LP clock
rate, and the DSI driver configures itself and DISPC accordingly.

This patch is somewhat ugly, though. The code does its job by modifying
the platform data where the clock dividers would be if the board file
gave them. This is not how it's going to be in the future, but allows us
to have quite simple patch and keep the backward compatibility.

It also allows the developer to still give the exact dividers from the
board file when there's need for that, as long as the panel driver does
not override them.

There are also other areas for improvement. For example, it would be
better if the panel driver could ask for a DSI clock in a certain range,
as, at least command mode panels, the panel can work fine with many
different clock speeds.

While the patch is not perfect, it allows us to remove the hardcoded
clock dividers from the board file, making it easier to bring up a new
panel and to use device tree from omapdss.

Signed-off-by: Tomi Valkeinen <redacted>
---
 drivers/video/omap2/displays/panel-taal.c |    6 ++
 drivers/video/omap2/dss/dsi.c             |  126 +++++++++++++++++++++++++++++
 include/video/omapdss.h                   |    2 +
 3 files changed, 134 insertions(+)
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index 77aed0e..ddda96a 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -1065,6 +1065,12 @@ static int taal_power_on(struct omap_dss_device *dssdev)
 	omapdss_dsi_set_pixel_format(dssdev, OMAP_DSS_DSI_FMT_RGB888);
 	omapdss_dsi_set_operation_mode(dssdev, OMAP_DSS_DSI_CMD_MODE);
 
+	r = omapdss_dsi_set_clocks(dssdev, 216000000, 10000000);
+	if (r) {
+		dev_err(&dssdev->dev, "failed to set HS and LP clocks\n");
+		goto err0;
+	}
+
 	r = omapdss_dsi_display_enable(dssdev);
 	if (r) {
 		dev_err(&dssdev->dev, "failed to enable DSI\n");
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 96d0024..340c832 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -1454,6 +1454,68 @@ found:
 	return 0;
 }
 
+static int dsi_pll_calc_ddrfreq(struct platform_device *dsidev,
+		unsigned long req_clk, struct dsi_clock_info *cinfo)
+{
+	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+	struct dsi_clock_info cur, best;
+	unsigned long dss_sys_clk, max_dss_fck, max_dsi_fck;
+	unsigned long req_clkin4ddr;
+
+	DSSDBG("dsi_pll_calc_ddrfreq\n");
+
+	dss_sys_clk = clk_get_rate(dsi->sys_clk);
+
+	max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
+	max_dsi_fck = dss_feat_get_param_max(FEAT_PARAM_DSI_FCK);
+
+	memset(&best, 0, sizeof(best));
+	memset(&cur, 0, sizeof(cur));
+
+	cur.clkin = dss_sys_clk;
+
+	req_clkin4ddr = req_clk * 4;
+
+	for (cur.regn = 1; cur.regn < dsi->regn_max; ++cur.regn) {
+		cur.fint = cur.clkin / cur.regn;
+
+		if (cur.fint > dsi->fint_max || cur.fint < dsi->fint_min)
+			continue;
+
+		/* DSIPHY(MHz) = (2 * regm / regn) * clkin */
+		for (cur.regm = 1; cur.regm < dsi->regm_max; ++cur.regm) {
+			unsigned long a, b;
+
+			a = 2 * cur.regm * (cur.clkin/1000);
+			b = cur.regn;
+			cur.clkin4ddr = a / b * 1000;
+
+			if (cur.clkin4ddr > 1800 * 1000 * 1000)
+				break;
+
+			if (abs(cur.clkin4ddr - req_clkin4ddr) <
+					abs(best.clkin4ddr - req_clkin4ddr)) {
+				best = cur;
+				DSSDBG("best %ld\n", best.clkin4ddr);
+			}
+
+			if (cur.clkin4ddr = req_clkin4ddr)
+				goto found;
+		}
+	}
+found:
+	best.regm_dispc = DIV_ROUND_UP(best.clkin4ddr, max_dss_fck);
+	best.dsi_pll_hsdiv_dispc_clk = best.clkin4ddr / best.regm_dispc;
+
+	best.regm_dsi = DIV_ROUND_UP(best.clkin4ddr, max_dsi_fck);
+	best.dsi_pll_hsdiv_dsi_clk = best.clkin4ddr / best.regm_dsi;
+
+	if (cinfo)
+		*cinfo = best;
+
+	return 0;
+}
+
 int dsi_pll_set_clock_div(struct platform_device *dsidev,
 		struct dsi_clock_info *cinfo)
 {
@@ -4110,6 +4172,70 @@ int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev,
 }
 EXPORT_SYMBOL(omapdss_dsi_configure_pins);
 
+int omapdss_dsi_set_clocks(struct omap_dss_device *dssdev,
+		unsigned long ddr_clk, unsigned long lp_clk)
+{
+	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+	struct dsi_clock_info cinfo;
+	struct dispc_clock_info dispc_cinfo;
+	unsigned lp_clk_div;
+	unsigned long dsi_fclk;
+	int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
+	unsigned long pck;
+	int r;
+
+	DSSDBGF("ddr_clk %lu, lp_clk %lu", ddr_clk, lp_clk);
+
+	mutex_lock(&dsi->lock);
+
+	r = dsi_pll_calc_ddrfreq(dsidev, ddr_clk, &cinfo);
+	if (r)
+		goto err;
+
+	dssdev->clocks.dsi.regn = cinfo.regn;
+	dssdev->clocks.dsi.regm = cinfo.regm;
+	dssdev->clocks.dsi.regm_dispc = cinfo.regm_dispc;
+	dssdev->clocks.dsi.regm_dsi = cinfo.regm_dsi;
+
+
+	dsi_fclk = cinfo.dsi_pll_hsdiv_dsi_clk;
+	lp_clk_div = DIV_ROUND_UP(dsi_fclk, lp_clk * 2);
+
+	dssdev->clocks.dsi.lp_clk_div = lp_clk_div;
+
+	/* pck = TxByteClkHS * datalanes * 8 / bitsperpixel */
+
+	pck = cinfo.clkin4ddr / 16 * (dsi->num_lanes_used - 1) * 8 / bpp;
+
+	DSSDBG("finding dispc dividers for pck %lu\n", pck);
+
+	dispc_find_clk_divs(pck, cinfo.dsi_pll_hsdiv_dispc_clk, &dispc_cinfo);
+
+	dssdev->clocks.dispc.channel.lck_div = dispc_cinfo.lck_div;
+	dssdev->clocks.dispc.channel.pck_div = dispc_cinfo.pck_div;
+
+
+	dssdev->clocks.dispc.dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK;
+
+	dssdev->clocks.dispc.channel.lcd_clk_src +		dsi->module_id = 0 ?
+		OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC :
+		OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC;
+
+	dssdev->clocks.dsi.dsi_fclk_src +		dsi->module_id = 0 ?
+		OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI :
+		OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI;
+
+	mutex_unlock(&dsi->lock);
+	return 0;
+err:
+	mutex_unlock(&dsi->lock);
+	return r;
+}
+EXPORT_SYMBOL(omapdss_dsi_set_clocks);
+
 int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
 {
 	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index c6ffe88..8a926f8 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -738,6 +738,8 @@ int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id);
 void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel);
 int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev,
 		const struct omap_dsi_pin_config *pin_cfg);
+int omapdss_dsi_set_clocks(struct omap_dss_device *dssdev,
+		unsigned long ddr_clk, unsigned long lp_clk);
 
 int omapdss_dsi_display_enable(struct omap_dss_device *dssdev);
 void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
-- 
1.7.9.5

[PATCH 7/8] OMAP: 4430SDP: remove DSI clock config from board file

From: Tomi Valkeinen <hidden>
Date: 2012-08-23 13:45:13

DSI clocks are now configured dynamically by the DSI driver, so we can
remove the hardcoded clock configuration from the board file.

Signed-off-by: Tomi Valkeinen <redacted>
Cc: Tony Lindgren <tony@atomide.com>
---
 arch/arm/mach-omap2/board-4430sdp.c |   46 -----------------------------------
 1 file changed, 46 deletions(-)
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 852e05c..4352d91 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -621,29 +621,6 @@ static struct omap_dss_device sdp4430_lcd_device = {
 	.phy.dsi		= {
 		.module		= 0,
 	},
-
-	.clocks = {
-		.dispc = {
-			.channel = {
-				/* Logic Clock = 172.8 MHz */
-				.lck_div	= 1,
-				/* Pixel Clock = 34.56 MHz */
-				.pck_div	= 5,
-				.lcd_clk_src	= OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC,
-			},
-			.dispc_fclk_src	= OMAP_DSS_CLK_SRC_FCK,
-		},
-
-		.dsi = {
-			.regn		= 16,	/* Fint = 2.4 MHz */
-			.regm		= 180,	/* DDR Clock = 216 MHz */
-			.regm_dispc	= 5,	/* PLL1_CLK1 = 172.8 MHz */
-			.regm_dsi	= 5,	/* PLL1_CLK2 = 172.8 MHz */
-
-			.lp_clk_div	= 10,	/* LP Clock = 8.64 MHz */
-			.dsi_fclk_src	= OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI,
-		},
-	},
 	.channel		= OMAP_DSS_CHANNEL_LCD,
 };
 
@@ -668,29 +645,6 @@ static struct omap_dss_device sdp4430_lcd2_device = {
 
 		.module		= 1,
 	},
-
-	.clocks = {
-		.dispc = {
-			.channel = {
-				/* Logic Clock = 172.8 MHz */
-				.lck_div	= 1,
-				/* Pixel Clock = 34.56 MHz */
-				.pck_div	= 5,
-				.lcd_clk_src	= OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC,
-			},
-			.dispc_fclk_src	= OMAP_DSS_CLK_SRC_FCK,
-		},
-
-		.dsi = {
-			.regn		= 16,	/* Fint = 2.4 MHz */
-			.regm		= 180,	/* DDR Clock = 216 MHz */
-			.regm_dispc	= 5,	/* PLL1_CLK1 = 172.8 MHz */
-			.regm_dsi	= 5,	/* PLL1_CLK2 = 172.8 MHz */
-
-			.lp_clk_div	= 10,	/* LP Clock = 8.64 MHz */
-			.dsi_fclk_src	= OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI,
-		},
-	},
 	.channel		= OMAP_DSS_CHANNEL_LCD2,
 };
 
-- 
1.7.9.5

[PATCH 8/8] OMAPDSS: fix use of dssdev->caps

From: Tomi Valkeinen <hidden>
Date: 2012-08-23 13:45:14

Recent commit dca2b1522ccab28d03fb79f6e70e70ea78033d52 (OMAPDSS: DSI:
Maintain copy of operation mode in driver data) broke DSI for video mode
displays. The commit changed the way dssdev->caps are initialized, and
the result was that every DSI display is initialized with manual-update
and tear-elim caps.

The code that sets dssdev->caps is not very good, even when fixed.
omapdss driver shouldn't be writing dssdev->caps at all.

This patch fixes the problem with video mode displays by moving the
initialization of dssdev->caps to the panel driver. The same change is
done for RFBI.

Signed-off-by: Tomi Valkeinen <redacted>
---
 drivers/video/omap2/displays/panel-n8x0.c |    1 +
 drivers/video/omap2/displays/panel-taal.c |    2 ++
 drivers/video/omap2/dss/dsi.c             |    5 -----
 drivers/video/omap2/dss/rfbi.c            |    1 -
 4 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/drivers/video/omap2/displays/panel-n8x0.c b/drivers/video/omap2/displays/panel-n8x0.c
index 17ae85e..3fc5ad0 100644
--- a/drivers/video/omap2/displays/panel-n8x0.c
+++ b/drivers/video/omap2/displays/panel-n8x0.c
@@ -489,6 +489,7 @@ static int n8x0_panel_probe(struct omap_dss_device *dssdev)
 	dssdev->panel.timings.y_res = 480;
 	dssdev->ctrl.pixel_size = 16;
 	dssdev->ctrl.rfbi_timings = n8x0_panel_timings;
+	dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
 
 	memset(&props, 0, sizeof(props));
 	props.max_brightness = 127;
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index ddda96a..7b2d7bb 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -884,6 +884,8 @@ static int taal_probe(struct omap_dss_device *dssdev)
 
 	dssdev->panel.timings = panel_config->timings;
 	dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888;
+	dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
+		OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
 
 	td = kzalloc(sizeof(*td), GFP_KERNEL);
 	if (!td) {
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 340c832..254666f 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -4866,11 +4866,6 @@ static int __init dsi_init_display(struct omap_dss_device *dssdev)
 
 	DSSDBG("DSI init\n");
 
-	if (dsi->mode = OMAP_DSS_DSI_CMD_MODE) {
-		dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
-			OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
-	}
-
 	if (dsi->vdds_dsi_reg = NULL) {
 		struct regulator *vdds_dsi;
 
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 5a9c0e9..2e520d3 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -939,7 +939,6 @@ EXPORT_SYMBOL(omapdss_rfbi_display_disable);
 static int __init rfbi_init_display(struct omap_dss_device *dssdev)
 {
 	rfbi.dssdev[dssdev->phy.rfbi.channel] = dssdev;
-	dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
 	return 0;
 }
 
-- 
1.7.9.5

Re: [PATCH 8/8] OMAPDSS: fix use of dssdev->caps

From: Archit Taneja <hidden>
Date: 2012-08-24 05:52:50

On Thursday 23 August 2012 07:15 PM, Tomi Valkeinen wrote:
Recent commit dca2b1522ccab28d03fb79f6e70e70ea78033d52 (OMAPDSS: DSI:
Maintain copy of operation mode in driver data) broke DSI for video mode
displays. The commit changed the way dssdev->caps are initialized, and
the result was that every DSI display is initialized with manual-update
and tear-elim caps.
Ah, I didn't realise that. Thanks for catching this.
The code that sets dssdev->caps is not very good, even when fixed.
omapdss driver shouldn't be writing dssdev->caps at all.

This patch fixes the problem with video mode displays by moving the
initialization of dssdev->caps to the panel driver. The same change is
done for RFBI.
Yes, it makes more sense to configure these in the panel driver.

Archit
quoted hunk
Signed-off-by: Tomi Valkeinen <redacted>
---
  drivers/video/omap2/displays/panel-n8x0.c |    1 +
  drivers/video/omap2/displays/panel-taal.c |    2 ++
  drivers/video/omap2/dss/dsi.c             |    5 -----
  drivers/video/omap2/dss/rfbi.c            |    1 -
  4 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/drivers/video/omap2/displays/panel-n8x0.c b/drivers/video/omap2/displays/panel-n8x0.c
index 17ae85e..3fc5ad0 100644
--- a/drivers/video/omap2/displays/panel-n8x0.c
+++ b/drivers/video/omap2/displays/panel-n8x0.c
@@ -489,6 +489,7 @@ static int n8x0_panel_probe(struct omap_dss_device *dssdev)
  	dssdev->panel.timings.y_res = 480;
  	dssdev->ctrl.pixel_size = 16;
  	dssdev->ctrl.rfbi_timings = n8x0_panel_timings;
+	dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;

  	memset(&props, 0, sizeof(props));
  	props.max_brightness = 127;
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index ddda96a..7b2d7bb 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -884,6 +884,8 @@ static int taal_probe(struct omap_dss_device *dssdev)

  	dssdev->panel.timings = panel_config->timings;
  	dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888;
+	dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
+		OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;

  	td = kzalloc(sizeof(*td), GFP_KERNEL);
  	if (!td) {
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 340c832..254666f 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -4866,11 +4866,6 @@ static int __init dsi_init_display(struct omap_dss_device *dssdev)

23 more quoted lines

Re: [PATCH 1/8] OMAPDSS: HDMI: Move GPIO handling to HDMI driver

From: Archit Taneja <hidden>
Date: 2012-08-24 06:12:57

On Thursday 23 August 2012 07:15 PM, Tomi Valkeinen wrote:
quoted hunk
We currently manage HDMI GPIOs in the board files via
platform_enable/disable calls. This won't work with device tree, and in
any case the correct place to manage the GPIOs is in the HDMI driver.

This patch moves the handling of the GPIOs to the HDMI driver. The GPIO
handling is moved to the common hdmi.c file, and this probably needs to
be revisited when adding OMAP5 HDMI support to see if the GPIO handling
needs to be moved to IP specific files.

Signed-off-by: Tomi Valkeinen <redacted>
Cc: Tony Lindgren <tony@atomide.com>
---
  arch/arm/mach-omap2/board-4430sdp.c    |   27 +-----------
  arch/arm/mach-omap2/board-omap4panda.c |   27 +-----------
  drivers/video/omap2/dss/hdmi.c         |   75 +++++++++++++++++++++++---------
  include/video/omapdss.h                |    2 +
  4 files changed, 61 insertions(+), 70 deletions(-)
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 8e17284..852e05c 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -601,29 +601,6 @@ static void __init omap_sfh7741prox_init(void)
  			__func__, OMAP4_SFH7741_ENABLE_GPIO, error);
  }

-static struct gpio sdp4430_hdmi_gpios[] = {
-	{ HDMI_GPIO_CT_CP_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ct_cp_hpd" },
-	{ HDMI_GPIO_LS_OE,	GPIOF_OUT_INIT_HIGH,	"hdmi_gpio_ls_oe" },
-	{ HDMI_GPIO_HPD, GPIOF_DIR_IN, "hdmi_gpio_hpd" },
-};
-
-static int sdp4430_panel_enable_hdmi(struct omap_dss_device *dssdev)
-{
-	int status;
-
-	status = gpio_request_array(sdp4430_hdmi_gpios,
-				    ARRAY_SIZE(sdp4430_hdmi_gpios));
-	if (status)
-		pr_err("%s: Cannot request HDMI GPIOs\n", __func__);

119 more quoted lines

Is there a reason to request these gpios in hdmi_init_display()? Why 
can't these be requested simply in the probe of the hdmi platform 
device. These gpios are sort of specific to the hdmi output on OMAP, 
aren't they?

<snip>

Archit

Re: [PATCH 1/8] OMAPDSS: HDMI: Move GPIO handling to HDMI driver

From: Tomi Valkeinen <hidden>
Date: 2012-08-24 06:28:36

On Fri, 2012-08-24 at 11:30 +0530, Archit Taneja wrote:
On Thursday 23 August 2012 07:15 PM, Tomi Valkeinen wrote:
quoted
We currently manage HDMI GPIOs in the board files via
platform_enable/disable calls. This won't work with device tree, and in
any case the correct place to manage the GPIOs is in the HDMI driver.

This patch moves the handling of the GPIOs to the HDMI driver. The GPIO
handling is moved to the common hdmi.c file, and this probably needs to
be revisited when adding OMAP5 HDMI support to see if the GPIO handling
needs to be moved to IP specific files.
<snip>
quoted
  static int __init hdmi_init_display(struct omap_dss_device *dssdev)
  {
+	int r;
+
+	struct gpio gpios[] = {
+		{ hdmi.ct_cp_hpd_gpio, GPIOF_OUT_INIT_LOW, "hdmi_ct_cp_hpd" },
+		{ hdmi.ls_oe_gpio, GPIOF_OUT_INIT_LOW, "hdmi_ls_oe" },
+		{ hdmi.hpd_gpio, GPIOF_DIR_IN, "hdmi_hpd" },
+	};
+
  	DSSDBG("init_display\n");

  	dss_init_hdmi_ip_ops(&hdmi.ip_data);
+
+	r = gpio_request_array(gpios, ARRAY_SIZE(gpios));
+	if (r)
+		return r;
+
Is there a reason to request these gpios in hdmi_init_display()? Why 
can't these be requested simply in the probe of the hdmi platform 
device. These gpios are sort of specific to the hdmi output on OMAP, 
aren't they?
Well, it is a bit ugly, agreed. But I'm not sure it can be helped
easily.

First, the struct omap_dss_hdmi_data where the gpios are passed from
board file, is really "panel" platform data. I.e. it's attached to the
hdmi dssdev, and thus we can't handle it in hdmi output driver's probe,
as we don't have dssdevs there.

Second, the gpios are actually not OMAP HDMI stuff. They belong to the
tpd12s015 chip, sitting between OMAP HDMI output and the HDMI connector,
which is the ESD/level shifter/whatnot (I don't remember exactly what it
does =). So making the GPIOs a property of the OMAP HDMI device wouldn't
be right either.

tpd12s015 is rather simple chip, but it still has the gpios and require
special handling. I think the only way to properly handle this would be
to have a chain of external display devices, and the tpd12s015 would be
handled by a separate driver. Until then, the gpio handling is quite
hacky.

We could move the gpios to omapdss's platform data, but it would still
be wrong, and I'm not sure if it'd be any cleaner hack.

 Tomi

Re: [PATCH 6/8] OMAPDSS: DSI: calculate dsi clock

From: Archit Taneja <hidden>
Date: 2012-08-24 06:28:39

On Thursday 23 August 2012 07:15 PM, Tomi Valkeinen wrote:
quoted hunk
Currently the way to configure clocks related to DSI (both DSI and DISPC
clocks) happens via omapdss platform data. The reason for this is that
configuring the DSS clocks is a very complex problem, and it's
impossible for the SW to know requirements about things like
interference.

However, for general cases it should be fine to calculate the dividers
for clocks in the SW. The calculated clocks are probably not perfect,
but should work.

This patch adds support to calculate the dividers when using DSI command
mode panels. The panel gives the required DDR clock rate and LP clock
rate, and the DSI driver configures itself and DISPC accordingly.

This patch is somewhat ugly, though. The code does its job by modifying
the platform data where the clock dividers would be if the board file
gave them. This is not how it's going to be in the future, but allows us
to have quite simple patch and keep the backward compatibility.

It also allows the developer to still give the exact dividers from the
board file when there's need for that, as long as the panel driver does
not override them.

There are also other areas for improvement. For example, it would be
better if the panel driver could ask for a DSI clock in a certain range,
as, at least command mode panels, the panel can work fine with many
different clock speeds.

While the patch is not perfect, it allows us to remove the hardcoded
clock dividers from the board file, making it easier to bring up a new
panel and to use device tree from omapdss.

Signed-off-by: Tomi Valkeinen <redacted>
---
  drivers/video/omap2/displays/panel-taal.c |    6 ++
  drivers/video/omap2/dss/dsi.c             |  126 +++++++++++++++++++++++++++++
  include/video/omapdss.h                   |    2 +
  3 files changed, 134 insertions(+)
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c

126 more quoted lines

This formula looks a bit simplified, we aren't considering the header 
and footers of long packets that will add to the DDR clock. But I guess 
not considering these would only give a higher pixel clock than needed, 
which isn't that bad.
quoted hunk
+
+	pck = cinfo.clkin4ddr / 16 * (dsi->num_lanes_used - 1) * 8 / bpp;
+
+	DSSDBG("finding dispc dividers for pck %lu\n", pck);
+
+	dispc_find_clk_divs(pck, cinfo.dsi_pll_hsdiv_dispc_clk, &dispc_cinfo);
+
+	dssdev->clocks.dispc.channel.lck_div = dispc_cinfo.lck_div;
+	dssdev->clocks.dispc.channel.pck_div = dispc_cinfo.pck_div;
+
+
one unnecessary new line above.

<snip>

Archit

Re: [PATCH 4/8] OMAPDSS: HDMI: use vdda_hdmi_dac

From: Archit Taneja <hidden>
Date: 2012-08-24 06:32:23

On Thursday 23 August 2012 07:15 PM, Tomi Valkeinen wrote:
quoted hunk
The HDMI driver requires vdda_hdmi_dac power for operation, but does not
enable it. This has worked because the regulator has been always
enabled.

But this may not always be the case, as I encountered when implementing
HDMI device tree support.

This patch changes the HDMI driver to use the vdda_hdmi_dac.

Signed-off-by: Tomi Valkeinen <redacted>
---
  drivers/video/omap2/dss/hdmi.c |   23 +++++++++++++++++++++++
  1 file changed, 23 insertions(+)
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 96a6e29..ccfc677 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -33,6 +33,7 @@
  #include <linux/pm_runtime.h>
  #include <linux/clk.h>
  #include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
  #include <video/omapdss.h>

  #include "ti_hdmi.h"
@@ -62,6 +63,7 @@ static struct {
  	struct hdmi_ip_data ip_data;

  	struct clk *sys_clk;
+	struct regulator *vdda_hdmi_dac_reg;

  	int ct_cp_hpd_gpio;
  	int ls_oe_gpio;
@@ -331,6 +333,19 @@ static int __init hdmi_init_display(struct omap_dss_device *dssdev)

  	dss_init_hdmi_ip_ops(&hdmi.ip_data);

+	if (hdmi.vdda_hdmi_dac_reg = NULL) {
+		struct regulator *reg;

2 more quoted lines

There is no corresponding devm_regulator_put() call here, I guess that's 
what devm_* calls are supposed to help us with. But the only place I saw 
the usage of dev_regulator_get() is here:

sound/soc/ux500/ux500_msp_dai.c

And here, they are doing devm_regulator_put() calls to, so I was 
wondering what the deal is.

Archit

Re: [PATCH 4/8] OMAPDSS: HDMI: use vdda_hdmi_dac

From: Tomi Valkeinen <hidden>
Date: 2012-08-24 06:41:20

On Fri, 2012-08-24 at 11:50 +0530, Archit Taneja wrote:
On Thursday 23 August 2012 07:15 PM, Tomi Valkeinen wrote:
quoted
The HDMI driver requires vdda_hdmi_dac power for operation, but does not
enable it. This has worked because the regulator has been always
enabled.

But this may not always be the case, as I encountered when implementing
HDMI device tree support.

This patch changes the HDMI driver to use the vdda_hdmi_dac.

Signed-off-by: Tomi Valkeinen <redacted>
---
  drivers/video/omap2/dss/hdmi.c |   23 +++++++++++++++++++++++
  1 file changed, 23 insertions(+)
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 96a6e29..ccfc677 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -33,6 +33,7 @@
  #include <linux/pm_runtime.h>
  #include <linux/clk.h>
  #include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
  #include <video/omapdss.h>

  #include "ti_hdmi.h"
@@ -62,6 +63,7 @@ static struct {
  	struct hdmi_ip_data ip_data;

  	struct clk *sys_clk;
+	struct regulator *vdda_hdmi_dac_reg;

  	int ct_cp_hpd_gpio;
  	int ls_oe_gpio;
@@ -331,6 +333,19 @@ static int __init hdmi_init_display(struct omap_dss_device *dssdev)

  	dss_init_hdmi_ip_ops(&hdmi.ip_data);

+	if (hdmi.vdda_hdmi_dac_reg == NULL) {

12 more quoted lines

No idea. But there are other places also: sound/soc/codecs/wm5100.c,
sound/soc/codecs/wm8996.c, sound/soc/soc-dapm.c, and those don't use
put().

Anyway, I think it's quite clear how devm_* functions are used, so the
put call in ux500_msp_dai.c is probably just a mistake.

I also want to mention that doing the regulator_get in
hdmi_init_display() is somewhat strange, but the point is to do the
regulator_get only if a hdmi display has been defined in the board file.
If we did it unconditionally in hdmi's probe, we'd try to get the
regulator always, and it could be that there's no regulator if the hdmi
is not used on a particular board. This is again something that feels
hackish, and I'd like to find a cleaner solution to it.

 Tomi

Re: [PATCH 6/8] OMAPDSS: DSI: calculate dsi clock

From: Tomi Valkeinen <hidden>
Date: 2012-08-24 08:55:40

On Fri, 2012-08-24 at 11:46 +0530, Archit Taneja wrote:
On Thursday 23 August 2012 07:15 PM, Tomi Valkeinen wrote:
quoted
+	/* pck = TxByteClkHS * datalanes * 8 / bitsperpixel */
This formula looks a bit simplified, we aren't considering the header 
and footers of long packets that will add to the DDR clock. But I guess 
not considering these would only give a higher pixel clock than needed, 
which isn't that bad.
Hmm. The TRM (omap4460) gives this formula in "10.3.4.5.12 How to
Configure the DSI PLL in Video Mode". The headers/footers etc. are
handled with adjusting the blanking periods so that DISPC and DSI Tline
times match.

But obviously they are not used for command mode transfers, so perhaps
you have a point there. Then again, at least in theory, in command mode
the DISPC pck should be configurable as high as possible because the
stall mechanism should stop DISPC when DSI has had enough. And so the
pck calculation is a bit unneeded for cmd mode, we could just configure
pck to max.

But if it's correct for video mode, and very close for cmd mode, I guess
it should be fine?

 Tomi

Re: [PATCH 6/8] OMAPDSS: DSI: calculate dsi clock

From: Archit Taneja <hidden>
Date: 2012-08-24 09:29:59

On Friday 24 August 2012 02:25 PM, Tomi Valkeinen wrote:
On Fri, 2012-08-24 at 11:46 +0530, Archit Taneja wrote:
quoted
On Thursday 23 August 2012 07:15 PM, Tomi Valkeinen wrote:
quoted
quoted
+	/* pck = TxByteClkHS * datalanes * 8 / bitsperpixel */
This formula looks a bit simplified, we aren't considering the header
and footers of long packets that will add to the DDR clock. But I guess
not considering these would only give a higher pixel clock than needed,
which isn't that bad.
Hmm. The TRM (omap4460) gives this formula in "10.3.4.5.12 How to
Configure the DSI PLL in Video Mode". The headers/footers etc. are
handled with adjusting the blanking periods so that DISPC and DSI Tline
times match.

But obviously they are not used for command mode transfers, so perhaps
you have a point there. Then again, at least in theory, in command mode
the DISPC pck should be configurable as high as possible because the
stall mechanism should stop DISPC when DSI has had enough. And so the
pck calculation is a bit unneeded for cmd mode, we could just configure
pck to max.

But if it's correct for video mode, and very close for cmd mode, I guess
it should be fine?
Yes, it's fine, and we shouldn't try to have an unnecessarily high pixel 
clock in command mode anyway, that would reduce the amount of 
downscaling we could do.

Archit

Re: [PATCH 0/8] OMAPDSS: Misc improvements

From: Tomi Valkeinen <hidden>
Date: 2012-09-04 07:22:48

Hi Tony,

Can you check the arch/arm patches below, and suggest how you'd like to
go forward with them?

 Tomi

On Thu, 2012-08-23 at 16:45 +0300, Tomi Valkeinen wrote:
Hi,

This series contains miscellaneous improvements for omapdss, which I've made
while implementing device tree support for omapdss. This includes some changes
to arch/arm/:

* remove OMAP4 HDMI gpio handling from board files
* add vdda_hdmi_dac supply for HDMI to twl-common.c
* remove DSS clock dividers from 4430sdp board file

Tony, omapdss has dependencies to those changes, and the first change also has
a dependency to omapdss header file. Is it ok to merge them with other omapdss
changes?

Chances for conflict are probably pretty small, 1st and 3rd change are
pure display stuff, and the 2nd adds the supply to a regulator not used by
anyone else than DSS.

 Tomi

Tomi Valkeinen (8):
  OMAPDSS: HDMI: Move GPIO handling to HDMI driver
  OMAPDSS: HDMI: Add delay to wait for 5V power
  OMAP4: TWL: add vdda_hdmi_dac regulator supply
  OMAPDSS: HDMI: use vdda_hdmi_dac
  OMAPDSS: Add DSI fclk maximum to dss_features
  OMAPDSS: DSI: calculate dsi clock
  OMAP: 4430SDP: remove DSI clock config from board file
  OMAPDSS: fix use of dssdev->caps

 arch/arm/mach-omap2/board-4430sdp.c       |   73 +---------------
 arch/arm/mach-omap2/board-omap4panda.c    |   27 +-----
 arch/arm/mach-omap2/twl-common.c          |    6 ++
 drivers/video/omap2/displays/panel-n8x0.c |    1 +
 drivers/video/omap2/displays/panel-taal.c |    8 ++
 drivers/video/omap2/dss/dsi.c             |  131 +++++++++++++++++++++++++++--
 drivers/video/omap2/dss/dss_features.c    |    2 +
 drivers/video/omap2/dss/dss_features.h    |    1 +
 drivers/video/omap2/dss/hdmi.c            |  101 +++++++++++++++++-----
 drivers/video/omap2/dss/rfbi.c            |    1 -

3 more quoted lines

Re: [PATCH 7/8] OMAP: 4430SDP: remove DSI clock config from board file

From: Tony Lindgren <tony@atomide.com>
Date: 2012-09-06 20:11:55

* Tomi Valkeinen [off-list ref] [120823 06:46]:
DSI clocks are now configured dynamically by the DSI driver, so we can
remove the hardcoded clock configuration from the board file.

Signed-off-by: Tomi Valkeinen <redacted>
Cc: Tony Lindgren <tony@atomide.com>
This should be safe to merge via fb tree:

Acked-by: Tony Lindgren <tony@atomide.com>

Re: [PATCH 3/8] OMAP4: TWL: add vdda_hdmi_dac regulator supply

From: Tony Lindgren <tony@atomide.com>
Date: 2012-09-06 20:12:28

* Tomi Valkeinen [off-list ref] [120823 06:46]:
HDMI requires vdda_hdmi_dac (vdac) power for operation. The regulator,
or the regulator supplying the vdac, has been enabled by default and
things have worked without the HDMI driver enabling the vdac.

I encountered the problem when implementing HDMI device tree support,
where the regulator was not enabled by default.

This patch adds the vdda_hdmi_dac to twl-common.c so that the HDMI
driver can use it.

Signed-off-by: Tomi Valkeinen <redacted>
Cc: Tony Lindgren <tony@atomide.com>
Looks safe to merge vi fb changes:

Acked-by: Tony Lindgren <tony@atomide.com>
quoted hunk
---
 arch/arm/mach-omap2/twl-common.c |    6 ++++++
 1 file changed, 6 insertions(+)
diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c
index 119d5a9..bf90356 100644
--- a/arch/arm/mach-omap2/twl-common.c
+++ b/arch/arm/mach-omap2/twl-common.c
@@ -257,6 +257,10 @@ static struct twl4030_usb_data omap4_usb_pdata = {
 	.phy_suspend	= omap4430_phy_suspend,
 };
 
+static struct regulator_consumer_supply omap4_vdda_hdmi_dac_supplies[] = {
+	REGULATOR_SUPPLY("vdda_hdmi_dac", "omapdss_hdmi"),
+};
+
 static struct regulator_init_data omap4_vdac_idata = {
 	.constraints = {
 		.min_uV			= 1800000,
@@ -266,6 +270,8 @@ static struct regulator_init_data omap4_vdac_idata = {
 		.valid_ops_mask		= REGULATOR_CHANGE_MODE
 					| REGULATOR_CHANGE_STATUS,
 	},
+	.num_consumer_supplies	= ARRAY_SIZE(omap4_vdda_hdmi_dac_supplies),
+	.consumer_supplies	= omap4_vdda_hdmi_dac_supplies,
 	.supply_regulator	= "V2V1",
 };
 
-- 
1.7.9.5

Re: [PATCH 0/8] OMAPDSS: Misc improvements

From: Tony Lindgren <tony@atomide.com>
Date: 2012-09-06 20:13:30

* Tomi Valkeinen [off-list ref] [120904 00:23]:
Hi Tony,

Can you check the arch/arm patches below, and suggest how you'd like to
go forward with them?
Acked them, then as soon as we have the initial immutable header
move branch available, you should merge with that to avoid
merge conflicts in upstream.

Regards,

Tony

Re: [PATCH 0/8] OMAPDSS: Misc improvements

From: Tomi Valkeinen <hidden>
Date: 2012-09-07 10:16:00

On Thu, 2012-09-06 at 13:13 -0700, Tony Lindgren wrote:
* Tomi Valkeinen [off-list ref] [120904 00:23]:
quoted
Hi Tony,

Can you check the arch/arm patches below, and suggest how you'd like to
go forward with them?
Acked them, then as soon as we have the initial immutable header
move branch available, you should merge with that to avoid
merge conflicts in upstream.
Thanks, but you missed the first patch "[PATCH 1/8] OMAPDSS: HDMI: Move
GPIO handling to HDMI driver".

 Tomi

Re: [PATCH 1/8] OMAPDSS: HDMI: Move GPIO handling to HDMI driver

From: Tony Lindgren <tony@atomide.com>
Date: 2012-09-07 16:21:37

* Tomi Valkeinen [off-list ref] [120823 06:46]:
We currently manage HDMI GPIOs in the board files via
platform_enable/disable calls. This won't work with device tree, and in
any case the correct place to manage the GPIOs is in the HDMI driver.

This patch moves the handling of the GPIOs to the HDMI driver. The GPIO
handling is moved to the common hdmi.c file, and this probably needs to
be revisited when adding OMAP5 HDMI support to see if the GPIO handling
needs to be moved to IP specific files.

Signed-off-by: Tomi Valkeinen <redacted>
Cc: Tony Lindgren <tony@atomide.com>
This too looks safe to merge via fb tree:

Acked-by: Tony Lindgren <tony@atomide.com>

Re: [PATCH 0/8] OMAPDSS: Misc improvements

From: Tony Lindgren <tony@atomide.com>
Date: 2012-09-07 16:22:58

* Tomi Valkeinen [off-list ref] [120907 03:16]:
On Thu, 2012-09-06 at 13:13 -0700, Tony Lindgren wrote:
quoted
* Tomi Valkeinen [off-list ref] [120904 00:23]:
quoted
Hi Tony,

Can you check the arch/arm patches below, and suggest how you'd like to
go forward with them?
Acked them, then as soon as we have the initial immutable header
move branch available, you should merge with that to avoid
merge conflicts in upstream.
Thanks, but you missed the first patch "[PATCH 1/8] OMAPDSS: HDMI: Move
GPIO handling to HDMI driver".
Oops sorry, that's a nice one, acked that too. BTW, do you have any
platform code callbacks remaining for DSS?

Regards,

Tony

Re: [PATCH 0/8] OMAPDSS: Misc improvements

From: Tomi Valkeinen <hidden>
Date: 2012-09-07 16:59:00

On Fri, 2012-09-07 at 09:22 -0700, Tony Lindgren wrote:
* Tomi Valkeinen [off-list ref] [120907 03:16]:
quoted
On Thu, 2012-09-06 at 13:13 -0700, Tony Lindgren wrote:
quoted
* Tomi Valkeinen [off-list ref] [120904 00:23]:
quoted
Hi Tony,

Can you check the arch/arm patches below, and suggest how you'd like to
go forward with them?
Acked them, then as soon as we have the initial immutable header
move branch available, you should merge with that to avoid
merge conflicts in upstream.
Thanks, but you missed the first patch "[PATCH 1/8] OMAPDSS: HDMI: Move
GPIO handling to HDMI driver".
Oops sorry, that's a nice one, acked that too. BTW, do you have any
platform code callbacks remaining for DSS?
Yes, for quite many boards:

$ git grep platform_enable arch/arm/mach-omap2/|wc -l
17

Some of those are trivial, I just need to move the panel's reset gpio
handling to the panel driver. But some fiddle around with board specific
gpios that do not belong to the panel driver. Also some board files
contain backlight handling.

Those are for panel drivers, then there's also callbacks for the omapdss
driver itself. get_context_loss_count, set_min_bus_tput, and dsi pin
enable/disable.

 Tomi
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help