All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tomi Valkeinen <tomi.valkeinen@ti.com>
To: Andrzej Hajda <a.hajda@samsung.com>,
	Laurent Pinchart <Laurent.pinchart@ideasonboard.com>,
	dri-devel@lists.freedesktop.org,
	Lucas Stach <l.stach@pengutronix.de>,
	Andrey Gusakov <andrey.gusakov@cogentembedded.com>,
	Philipp Zabel <p.zabel@pengutronix.de>,
	Andrey Smirnov <andrew.smirnov@gmail.com>,
	Jyri Sarha <jsarha@ti.com>,
	Peter Ujfalusi <peter.ujfalusi@ti.com>,
	Benoit Parrot <bparrot@ti.com>
Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
Subject: [PATCHv2 21/22] drm/bridge: tc358767: add IRQ and HPD support
Date: Tue, 26 Mar 2019 12:31:45 +0200	[thread overview]
Message-ID: <20190326103146.24795-22-tomi.valkeinen@ti.com> (raw)
In-Reply-To: <20190326103146.24795-1-tomi.valkeinen@ti.com>

Add support for interrupt and hotplug handling. Both are optional.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/gpu/drm/bridge/tc358767.c | 157 ++++++++++++++++++++++++++----
 1 file changed, 139 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c
index 8606de29c9b2..6978129428a8 100644
--- a/drivers/gpu/drm/bridge/tc358767.c
+++ b/drivers/gpu/drm/bridge/tc358767.c
@@ -71,6 +71,7 @@
 
 /* System */
 #define TC_IDREG		0x0500
+#define SYSSTAT			0x0508
 #define SYSCTRL			0x0510
 #define DP0_AUDSRC_NO_INPUT		(0 << 3)
 #define DP0_AUDSRC_I2S_RX		(1 << 3)
@@ -79,9 +80,16 @@
 #define DP0_VIDSRC_DPI_RX		(2 << 0)
 #define DP0_VIDSRC_COLOR_BAR		(3 << 0)
 #define GPIOM			0x0540
+#define GPIOC			0x0544
+#define GPIOO			0x0548
 #define GPIOI			0x054c
 #define INTCTL_G		0x0560
 #define INTSTS_G		0x0564
+
+#define INT_SYSERR		BIT(16)
+#define INT_GPIO_H(x)		(1 << (x == 0 ? 2 : 10))
+#define INT_GPIO_LC(x)		(1 << (x == 0 ? 3 : 11))
+
 #define INT_GP0_LCNT		0x0584
 #define INT_GP1_LCNT		0x0588
 
@@ -219,6 +227,12 @@ struct tc_data {
 	struct gpio_desc	*sd_gpio;
 	struct gpio_desc	*reset_gpio;
 	struct clk		*refclk;
+
+	/* do we have IRQ */
+	bool			have_irq;
+
+	/* HPD pin number (0 or 1) or -ENODEV */
+	int			hpd_num;
 };
 
 static inline struct tc_data *aux_to_tc(struct drm_dp_aux *a)
@@ -1095,6 +1109,12 @@ static void tc_bridge_enable(struct drm_bridge *bridge)
 	struct tc_data *tc = bridge_to_tc(bridge);
 	int ret;
 
+	ret = tc_get_display_props(tc);
+	if (ret < 0) {
+		dev_err(tc->dev, "failed to read display props: %d\n", ret);
+		return;
+	}
+
 	ret = tc_main_link_enable(tc);
 	if (ret < 0) {
 		dev_err(tc->dev, "main link enable error: %d\n", ret);
@@ -1200,19 +1220,42 @@ static int tc_connector_get_modes(struct drm_connector *connector)
 	return count;
 }
 
-static void tc_connector_set_polling(struct tc_data *tc,
-				     struct drm_connector *connector)
-{
-	/* TODO: add support for HPD */
-	connector->polled = DRM_CONNECTOR_POLL_CONNECT |
-			    DRM_CONNECTOR_POLL_DISCONNECT;
-}
-
 static const struct drm_connector_helper_funcs tc_connector_helper_funcs = {
 	.get_modes = tc_connector_get_modes,
 };
 
+static enum drm_connector_status tc_connector_detect(struct drm_connector *connector, bool force)
+{
+	struct tc_data *tc = connector_to_tc(connector);
+	bool conn;
+	u32 val;
+	int ret;
+
+	if (tc->hpd_num < 0) {
+		if (tc->panel)
+			return connector_status_connected;
+		else
+			return connector_status_unknown;
+	}
+
+	tc_read(GPIOI, &val);
+
+	conn = val & BIT(tc->hpd_num);
+
+	if (force && conn)
+		tc_get_display_props(tc);
+
+	if (conn)
+		return connector_status_connected;
+	else
+		return connector_status_disconnected;
+
+err:
+	return connector_status_unknown;
+}
+
 static const struct drm_connector_funcs tc_connector_funcs = {
+	.detect = tc_connector_detect,
 	.fill_modes = drm_helper_probe_single_connector_modes,
 	.destroy = drm_connector_cleanup,
 	.reset = drm_atomic_helper_connector_reset,
@@ -1227,7 +1270,7 @@ static int tc_bridge_attach(struct drm_bridge *bridge)
 	struct drm_device *drm = bridge->dev;
 	int ret;
 
-	/* Create eDP connector */
+	/* Create DP/eDP connector */
 	drm_connector_helper_add(&tc->connector, &tc_connector_helper_funcs);
 	ret = drm_connector_init(drm, &tc->connector, &tc_connector_funcs,
 				 tc->panel ? DRM_MODE_CONNECTOR_eDP :
@@ -1235,6 +1278,15 @@ static int tc_bridge_attach(struct drm_bridge *bridge)
 	if (ret)
 		return ret;
 
+	/* Don't poll if don't have HPD connected */
+	if (tc->hpd_num >= 0) {
+		if (tc->have_irq)
+			tc->connector.polled = DRM_CONNECTOR_POLL_HPD;
+		else
+			tc->connector.polled = DRM_CONNECTOR_POLL_CONNECT |
+					       DRM_CONNECTOR_POLL_DISCONNECT;
+	}
+
 	if (tc->panel)
 		drm_panel_attach(tc->panel, &tc->connector);
 
@@ -1301,6 +1353,43 @@ static const struct regmap_config tc_regmap_config = {
 	.val_format_endian = REGMAP_ENDIAN_LITTLE,
 };
 
+static irqreturn_t tc_irq_handler(int irq, void *arg)
+{
+	struct tc_data *tc = arg;
+	u32 val;
+	int r;
+
+	r = regmap_read(tc->regmap, INTSTS_G, &val);
+	if (r)
+		return IRQ_NONE;
+
+	if (!val)
+		return IRQ_NONE;
+
+	if (val & INT_SYSERR) {
+		u32 stat = 0;
+
+		regmap_read(tc->regmap, SYSSTAT, &stat);
+
+		dev_err(tc->dev, "syserr %x\n", stat);
+	}
+
+	if (tc->hpd_num >= 0 && tc->bridge.dev) {
+		bool h = val & INT_GPIO_H(tc->hpd_num);
+		bool lc = val & INT_GPIO_LC(tc->hpd_num);
+
+		dev_dbg(tc->dev, "GPIO%d: %s %s\n", tc->hpd_num,
+			h ? "H" : "", lc ? "LC" : "");
+
+		if (h || lc)
+			drm_kms_helper_hotplug_event(tc->bridge.dev);
+	}
+
+	regmap_write(tc->regmap, INTSTS_G, val);
+
+	return IRQ_HANDLED;
+}
+
 static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
 	struct device *dev = &client->dev;
@@ -1352,6 +1441,31 @@ static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id)
 		return ret;
 	}
 
+	ret = of_property_read_u32(dev->of_node, "hpd-num", &tc->hpd_num);
+	if (ret) {
+		tc->hpd_num = -ENODEV;
+	} else {
+		if (tc->hpd_num < 0 || tc->hpd_num > 1) {
+			dev_err(dev, "failed to parse HPD number\n");
+			return ret;
+		}
+	}
+
+	if (client->irq > 0) {
+		/* enable SysErr */
+		regmap_write(tc->regmap, INTCTL_G, INT_SYSERR);
+
+		ret = devm_request_threaded_irq(dev, client->irq,
+						NULL, tc_irq_handler, IRQF_ONESHOT,
+						"tc358767-irq", tc);
+		if (ret) {
+			dev_err(dev, "failed to register dp interrupt\n");
+			return ret;
+		}
+
+		tc->have_irq = true;
+	}
+
 	ret = regmap_read(tc->regmap, TC_IDREG, &tc->rev);
 	if (ret) {
 		dev_err(tc->dev, "can not read device ID: %d\n", ret);
@@ -1365,6 +1479,22 @@ static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id)
 
 	tc->assr = (tc->rev == 0x6601); /* Enable ASSR for eDP panels */
 
+	if (tc->hpd_num >= 0) {
+		u32 lcnt_reg = tc->hpd_num == 0 ? INT_GP0_LCNT : INT_GP1_LCNT;
+		u32 h_lc = INT_GPIO_H(tc->hpd_num) | INT_GPIO_LC(tc->hpd_num);
+
+		/* Set LCNT to 2ms */
+		regmap_write(tc->regmap, lcnt_reg,
+			     clk_get_rate(tc->refclk) * 2 / 1000);
+		/* We need the "alternate" mode for HPD */
+		regmap_write(tc->regmap, GPIOM, BIT(tc->hpd_num));
+
+		if (tc->have_irq) {
+			/* enable H & LC */
+			regmap_update_bits(tc->regmap, INTCTL_G, h_lc, h_lc);
+		}
+	}
+
 	ret = tc_aux_link_setup(tc);
 	if (ret)
 		return ret;
@@ -1377,12 +1507,6 @@ static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id)
 	if (ret)
 		return ret;
 
-	ret = tc_get_display_props(tc);
-	if (ret)
-		goto err_unregister_aux;
-
-	tc_connector_set_polling(tc, &tc->connector);
-
 	tc->bridge.funcs = &tc_bridge_funcs;
 	tc->bridge.of_node = dev->of_node;
 	drm_bridge_add(&tc->bridge);
@@ -1390,9 +1514,6 @@ static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id)
 	i2c_set_clientdata(client, tc);
 
 	return 0;
-err_unregister_aux:
-	drm_dp_aux_unregister(&tc->aux);
-	return ret;
 }
 
 static int tc_remove(struct i2c_client *client)
-- 
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  parent reply	other threads:[~2019-03-26 10:33 UTC|newest]

Thread overview: 103+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-03-26 10:31 [PATCHv2 00/22] drm/bridge: tc358767: DP support Tomi Valkeinen
2019-03-26 10:31 ` [PATCHv2 01/22] drm/bridge: tc358767: fix tc_aux_get_status error handling Tomi Valkeinen
2019-04-15  7:20   ` Andrzej Hajda
2019-04-20 20:14   ` Laurent Pinchart
2019-04-26 14:08     ` Tomi Valkeinen
2019-03-26 10:31 ` [PATCHv2 02/22] drm/bridge: tc358767: reset voltage-swing & pre-emphasis Tomi Valkeinen
2019-04-15  7:20   ` Andrzej Hajda
2019-04-20 20:30   ` Laurent Pinchart
2019-04-26 14:14     ` Tomi Valkeinen
2019-04-26 23:46       ` Laurent Pinchart
2019-04-26 23:54       ` Andrey Smirnov
2019-03-26 10:31 ` [PATCHv2 03/22] drm/bridge: tc358767: fix ansi 8b10b use Tomi Valkeinen
2019-04-15  7:29   ` Andrzej Hajda
2019-04-20 21:13   ` Laurent Pinchart
2019-04-23  8:19     ` Andrey Gusakov
2019-04-23 14:56       ` Laurent Pinchart
2019-04-24 13:52         ` Andrey Gusakov
2019-05-03 11:43         ` Tomi Valkeinen
2019-05-03 12:48           ` Laurent Pinchart
2019-05-03 13:17             ` Tomi Valkeinen
2019-05-03 17:11               ` Laurent Pinchart
2019-05-06  9:58                 ` Tomi Valkeinen
2019-05-21  7:21                   ` Andrey Smirnov
2019-03-26 10:31 ` [PATCHv2 04/22] drm/bridge: tc358767: cleanup spread & scrambler_dis Tomi Valkeinen
2019-04-15  7:31   ` Andrzej Hajda
2019-04-20 21:16   ` Laurent Pinchart
2019-03-26 10:31 ` [PATCHv2 05/22] drm/bridge: tc358767: remove unused swing & preemp Tomi Valkeinen
2019-04-15  7:31   ` Andrzej Hajda
2019-04-20 21:16   ` Laurent Pinchart
2019-03-26 10:31 ` [PATCHv2 06/22] drm/bridge: tc358767: cleanup aux_link_setup Tomi Valkeinen
2019-04-15  7:38   ` Andrzej Hajda
2019-04-15  7:52     ` Tomi Valkeinen
2019-04-20 21:20       ` Laurent Pinchart
2019-03-26 10:31 ` [PATCHv2 07/22] drm/bridge: tc358767: move video stream setup to tc_main_link_stream Tomi Valkeinen
2019-04-15  7:48   ` Andrzej Hajda
2019-04-20 21:25   ` Laurent Pinchart
2019-05-03  9:12     ` Tomi Valkeinen
2019-03-26 10:31 ` [PATCHv2 08/22] drm/bridge: tc358767: split stream enable/disable Tomi Valkeinen
2019-04-15  8:26   ` Andrzej Hajda
2019-04-20 21:29   ` Laurent Pinchart
2019-05-03  9:20     ` Tomi Valkeinen
2019-05-03 12:55       ` Laurent Pinchart
2019-05-03 13:08         ` Tomi Valkeinen
2019-03-26 10:31 ` [PATCHv2 09/22] drm/bridge: tc358767: move PXL PLL enable/disable to " Tomi Valkeinen
2019-04-15  8:28   ` Andrzej Hajda
2019-04-20 21:33   ` Laurent Pinchart
2019-03-26 10:31 ` [PATCHv2 10/22] drm/bridge: tc358767: add link disable function Tomi Valkeinen
2019-04-15  8:36   ` Andrzej Hajda
2019-04-15 11:39     ` Tomi Valkeinen
2019-04-20 21:39       ` Laurent Pinchart
2019-05-03  9:36         ` Tomi Valkeinen
2019-03-26 10:31 ` [PATCHv2 11/22] drm/bridge: tc358767: ensure DP is disabled before LT Tomi Valkeinen
2019-04-15  8:49   ` Andrzej Hajda
2019-04-15 11:26     ` Tomi Valkeinen
2019-04-20 21:41       ` Laurent Pinchart
2019-03-26 10:31 ` [PATCHv2 12/22] drm/bridge: tc358767: remove unnecessary msleep Tomi Valkeinen
2019-04-15  8:50   ` Andrzej Hajda
2019-04-20 21:43   ` Laurent Pinchart
2019-04-23  7:52     ` Andrey Gusakov
2019-03-26 10:31 ` [PATCHv2 13/22] drm/bridge: tc358767: use more reliable seq when finishing LT Tomi Valkeinen
2019-04-15  8:51   ` Andrzej Hajda
2019-04-20 21:44   ` Laurent Pinchart
2019-05-03 11:04     ` Tomi Valkeinen
2019-03-26 10:31 ` [PATCHv2 14/22] drm/bridge: tc358767: cleanup LT result check Tomi Valkeinen
2019-04-15  8:53   ` Andrzej Hajda
2019-04-20 22:06   ` Laurent Pinchart
2019-05-03 11:00     ` Tomi Valkeinen
2019-03-26 10:31 ` [PATCHv2 15/22] drm/bridge: tc358767: clean-up link training Tomi Valkeinen
2019-04-15  9:54   ` Andrzej Hajda
2019-04-15 11:03     ` Tomi Valkeinen
2019-04-20 22:13   ` Laurent Pinchart
2019-05-03  8:37     ` Tomi Valkeinen
2019-03-26 10:31 ` [PATCHv2 16/22] drm/bridge: tc358767: remove check for video mode in link enable Tomi Valkeinen
2019-04-15  9:55   ` Andrzej Hajda
2019-04-20 22:14   ` Laurent Pinchart
2019-05-03  8:10     ` Tomi Valkeinen
2019-05-03 13:00       ` Laurent Pinchart
2019-03-26 10:31 ` [PATCHv2 17/22] drm/bridge: tc358767: use bridge mode_valid Tomi Valkeinen
2019-04-15  9:56   ` Andrzej Hajda
2019-04-20 22:15   ` Laurent Pinchart
2019-03-26 10:31 ` [PATCHv2 18/22] drm/bridge: tc358767: remove tc_connector_best_encoder Tomi Valkeinen
2019-04-15  9:57   ` Andrzej Hajda
2019-04-20 22:18   ` Laurent Pinchart
2019-03-26 10:31 ` [PATCHv2 19/22] drm/bridge: tc358767: copy the mode data, instead of storing the pointer Tomi Valkeinen
2019-04-15 10:09   ` Andrzej Hajda
2019-04-15 11:19     ` Tomi Valkeinen
2019-04-15 12:12       ` Andrzej Hajda
2019-04-20 22:20         ` Laurent Pinchart
2019-03-26 10:31 ` [PATCHv2 20/22] drm/bridge: tc358767: add GPIO & interrupt registers Tomi Valkeinen
2019-04-15 10:09   ` Andrzej Hajda
2019-03-26 10:31 ` Tomi Valkeinen [this message]
2019-04-02  2:16   ` [PATCHv2 21/22] drm/bridge: tc358767: add IRQ and HPD support Andrey Smirnov
2019-04-03 11:34     ` Tomi Valkeinen
2019-04-12  8:02       ` Tomi Valkeinen
2019-04-12 18:17         ` Andrey Smirnov
2019-04-15 10:42   ` Andrzej Hajda
2019-04-15 10:59     ` Tomi Valkeinen
2019-04-17  7:32       ` Andrzej Hajda
2019-04-29  9:27         ` Tomi Valkeinen
2019-03-26 10:31 ` [PATCHv2 22/22] dt-bindings: tc358767: add IRQ & " Tomi Valkeinen
2019-03-31  6:42   ` Rob Herring
2019-04-01 10:13   ` [PATCHv2.1 22/22] dt-bindings: tc358767: add " Tomi Valkeinen
2019-04-06  6:06     ` Rob Herring

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190326103146.24795-22-tomi.valkeinen@ti.com \
    --to=tomi.valkeinen@ti.com \
    --cc=Laurent.pinchart@ideasonboard.com \
    --cc=a.hajda@samsung.com \
    --cc=andrew.smirnov@gmail.com \
    --cc=andrey.gusakov@cogentembedded.com \
    --cc=bparrot@ti.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=jsarha@ti.com \
    --cc=l.stach@pengutronix.de \
    --cc=p.zabel@pengutronix.de \
    --cc=peter.ujfalusi@ti.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.