Linux Tegra architecture development
 help / color / mirror / Atom feed
* [PATCH AUTOSEL 5.4 003/266] ASoC: tegra: tegra_wm8903: Support nvidia, headset property
From: Sasha Levin @ 2020-06-18  1:12 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	stable-u79uwXL29TY76Z2rM5mHXA
  Cc: Dmitry Osipenko, Mark Brown, Sasha Levin,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20200618011631.604574-1-sashal-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

From: Dmitry Osipenko <digetx-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

[ Upstream commit 3ef9d5073b552d56bd6daf2af1e89b7e8d4df183 ]

The microphone-jack state needs to be masked in a case of a 4-pin jack
when microphone and ground pins are shorted. Presence of nvidia,headset
tells that WM8903 CODEC driver should mask microphone's status if short
circuit is detected, i.e headphones are inserted.

Signed-off-by: Dmitry Osipenko <digetx-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Link: https://lore.kernel.org/r/20200330204011.18465-3-digetx-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
Signed-off-by: Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Signed-off-by: Sasha Levin <sashal-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---
 sound/soc/tegra/tegra_wm8903.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c
index 6211dfda2195..0fa01cacfec9 100644
--- a/sound/soc/tegra/tegra_wm8903.c
+++ b/sound/soc/tegra/tegra_wm8903.c
@@ -159,6 +159,7 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
 	struct snd_soc_component *component = codec_dai->component;
 	struct snd_soc_card *card = rtd->card;
 	struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
+	int shrt = 0;
 
 	if (gpio_is_valid(machine->gpio_hp_det)) {
 		tegra_wm8903_hp_jack_gpio.gpio = machine->gpio_hp_det;
@@ -171,12 +172,15 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
 					&tegra_wm8903_hp_jack_gpio);
 	}
 
+	if (of_property_read_bool(card->dev->of_node, "nvidia,headset"))
+		shrt = SND_JACK_MICROPHONE;
+
 	snd_soc_card_jack_new(rtd->card, "Mic Jack", SND_JACK_MICROPHONE,
 			      &tegra_wm8903_mic_jack,
 			      tegra_wm8903_mic_jack_pins,
 			      ARRAY_SIZE(tegra_wm8903_mic_jack_pins));
 	wm8903_mic_detect(component, &tegra_wm8903_mic_jack, SND_JACK_MICROPHONE,
-				0);
+				shrt);
 
 	snd_soc_dapm_force_enable_pin(&card->dapm, "MICBIAS");
 
-- 
2.25.1

^ permalink raw reply related

* [PATCH AUTOSEL 5.7 248/388] arm64: tegra: Fix flag for 64-bit resources in 'ranges' property
From: Sasha Levin @ 2020-06-18  1:05 UTC (permalink / raw)
  To: linux-kernel, stable
  Cc: Vidya Sagar, Thierry Reding, Sasha Levin, devicetree, linux-tegra
In-Reply-To: <20200618010805.600873-1-sashal@kernel.org>

From: Vidya Sagar <vidyas@nvidia.com>

[ Upstream commit 3482a7afb261e2de9269a7f9ad0f4a3a82a83a53 ]

Fix flag in PCIe controllers device-tree nodes 'ranges' property to correctly
represent 64-bit resources.

Fixes: 2602c32f15e7 ("arm64: tegra: Add P2U and PCIe controller nodes to Tegra194 DT")
Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/arm64/boot/dts/nvidia/tegra194.dtsi | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
index f4ede86e32b4..3c928360f4ed 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
@@ -1387,7 +1387,7 @@ pcie@14100000 {
 
 		bus-range = <0x0 0xff>;
 		ranges = <0x81000000 0x0  0x30100000 0x0  0x30100000 0x0 0x00100000   /* downstream I/O (1MB) */
-			  0xc2000000 0x12 0x00000000 0x12 0x00000000 0x0 0x30000000   /* prefetchable memory (768MB) */
+			  0xc3000000 0x12 0x00000000 0x12 0x00000000 0x0 0x30000000   /* prefetchable memory (768MB) */
 			  0x82000000 0x0  0x40000000 0x12 0x30000000 0x0 0x10000000>; /* non-prefetchable memory (256MB) */
 	};
 
@@ -1432,7 +1432,7 @@ pcie@14120000 {
 
 		bus-range = <0x0 0xff>;
 		ranges = <0x81000000 0x0  0x32100000 0x0  0x32100000 0x0 0x00100000   /* downstream I/O (1MB) */
-			  0xc2000000 0x12 0x40000000 0x12 0x40000000 0x0 0x30000000   /* prefetchable memory (768MB) */
+			  0xc3000000 0x12 0x40000000 0x12 0x40000000 0x0 0x30000000   /* prefetchable memory (768MB) */
 			  0x82000000 0x0  0x40000000 0x12 0x70000000 0x0 0x10000000>; /* non-prefetchable memory (256MB) */
 	};
 
@@ -1477,7 +1477,7 @@ pcie@14140000 {
 
 		bus-range = <0x0 0xff>;
 		ranges = <0x81000000 0x0  0x34100000 0x0  0x34100000 0x0 0x00100000   /* downstream I/O (1MB) */
-			  0xc2000000 0x12 0x80000000 0x12 0x80000000 0x0 0x30000000   /* prefetchable memory (768MB) */
+			  0xc3000000 0x12 0x80000000 0x12 0x80000000 0x0 0x30000000   /* prefetchable memory (768MB) */
 			  0x82000000 0x0  0x40000000 0x12 0xb0000000 0x0 0x10000000>; /* non-prefetchable memory (256MB) */
 	};
 
@@ -1522,7 +1522,7 @@ pcie@14160000 {
 
 		bus-range = <0x0 0xff>;
 		ranges = <0x81000000 0x0  0x36100000 0x0  0x36100000 0x0 0x00100000   /* downstream I/O (1MB) */
-			  0xc2000000 0x14 0x00000000 0x14 0x00000000 0x3 0x40000000   /* prefetchable memory (13GB) */
+			  0xc3000000 0x14 0x00000000 0x14 0x00000000 0x3 0x40000000   /* prefetchable memory (13GB) */
 			  0x82000000 0x0  0x40000000 0x17 0x40000000 0x0 0xc0000000>; /* non-prefetchable memory (3GB) */
 	};
 
@@ -1567,7 +1567,7 @@ pcie@14180000 {
 
 		bus-range = <0x0 0xff>;
 		ranges = <0x81000000 0x0  0x38100000 0x0  0x38100000 0x0 0x00100000   /* downstream I/O (1MB) */
-			  0xc2000000 0x18 0x00000000 0x18 0x00000000 0x3 0x40000000   /* prefetchable memory (13GB) */
+			  0xc3000000 0x18 0x00000000 0x18 0x00000000 0x3 0x40000000   /* prefetchable memory (13GB) */
 			  0x82000000 0x0  0x40000000 0x1b 0x40000000 0x0 0xc0000000>; /* non-prefetchable memory (3GB) */
 	};
 
@@ -1616,7 +1616,7 @@ pcie@141a0000 {
 
 		bus-range = <0x0 0xff>;
 		ranges = <0x81000000 0x0  0x3a100000 0x0  0x3a100000 0x0 0x00100000   /* downstream I/O (1MB) */
-			  0xc2000000 0x1c 0x00000000 0x1c 0x00000000 0x3 0x40000000   /* prefetchable memory (13GB) */
+			  0xc3000000 0x1c 0x00000000 0x1c 0x00000000 0x3 0x40000000   /* prefetchable memory (13GB) */
 			  0x82000000 0x0  0x40000000 0x1f 0x40000000 0x0 0xc0000000>; /* non-prefetchable memory (3GB) */
 	};
 
-- 
2.25.1

^ permalink raw reply related

* [PATCH AUTOSEL 5.7 247/388] arm64: tegra: Fix ethernet phy-mode for Jetson Xavier
From: Sasha Levin @ 2020-06-18  1:05 UTC (permalink / raw)
  To: linux-kernel, stable
  Cc: Jon Hunter, Thierry Reding, Sasha Levin, devicetree, linux-tegra
In-Reply-To: <20200618010805.600873-1-sashal@kernel.org>

From: Jon Hunter <jonathanh@nvidia.com>

[ Upstream commit bba25915b172c72f6fa635f091624d799e3c9cae ]

The 'phy-mode' property is currently defined as 'rgmii' for Jetson
Xavier. This indicates that the RGMII RX and TX delays are set by the
MAC and the internal delays set by the PHY are not used.

If the Marvell PHY driver is enabled, such that it is used and not the
generic PHY, ethernet failures are seen (DHCP is failing to obtain an
IP address) and this is caused because the Marvell PHY driver is
disabling the internal RX and TX delays. For Jetson Xavier the internal
PHY RX and TX delay should be used and so fix this by setting the
'phy-mode' to 'rgmii-id' and not 'rgmii'.

Fixes: f89b58ce71a9 ("arm64: tegra: Add ethernet controller on Tegra194")
Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi b/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi
index 623f7d7d216b..8e3136dfdd62 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra194-p2888.dtsi
@@ -33,7 +33,7 @@ ethernet@2490000 {
 
 			phy-reset-gpios = <&gpio TEGRA194_MAIN_GPIO(G, 5) GPIO_ACTIVE_LOW>;
 			phy-handle = <&phy>;
-			phy-mode = "rgmii";
+			phy-mode = "rgmii-id";
 
 			mdio {
 				#address-cells = <1>;
-- 
2.25.1

^ permalink raw reply related

* [PATCH AUTOSEL 5.7 004/388] ASoC: tegra: tegra_wm8903: Support nvidia, headset property
From: Sasha Levin @ 2020-06-18  1:01 UTC (permalink / raw)
  To: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	stable-u79uwXL29TY76Z2rM5mHXA
  Cc: Dmitry Osipenko, Mark Brown, Sasha Levin,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20200618010805.600873-1-sashal-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

From: Dmitry Osipenko <digetx-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

[ Upstream commit 3ef9d5073b552d56bd6daf2af1e89b7e8d4df183 ]

The microphone-jack state needs to be masked in a case of a 4-pin jack
when microphone and ground pins are shorted. Presence of nvidia,headset
tells that WM8903 CODEC driver should mask microphone's status if short
circuit is detected, i.e headphones are inserted.

Signed-off-by: Dmitry Osipenko <digetx-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Link: https://lore.kernel.org/r/20200330204011.18465-3-digetx-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
Signed-off-by: Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Signed-off-by: Sasha Levin <sashal-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---
 sound/soc/tegra/tegra_wm8903.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c
index 9b5651502f12..3aca354f9e08 100644
--- a/sound/soc/tegra/tegra_wm8903.c
+++ b/sound/soc/tegra/tegra_wm8903.c
@@ -177,6 +177,7 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
 	struct snd_soc_component *component = codec_dai->component;
 	struct snd_soc_card *card = rtd->card;
 	struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
+	int shrt = 0;
 
 	if (gpio_is_valid(machine->gpio_hp_det)) {
 		tegra_wm8903_hp_jack_gpio.gpio = machine->gpio_hp_det;
@@ -189,12 +190,15 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
 					&tegra_wm8903_hp_jack_gpio);
 	}
 
+	if (of_property_read_bool(card->dev->of_node, "nvidia,headset"))
+		shrt = SND_JACK_MICROPHONE;
+
 	snd_soc_card_jack_new(rtd->card, "Mic Jack", SND_JACK_MICROPHONE,
 			      &tegra_wm8903_mic_jack,
 			      tegra_wm8903_mic_jack_pins,
 			      ARRAY_SIZE(tegra_wm8903_mic_jack_pins));
 	wm8903_mic_detect(component, &tegra_wm8903_mic_jack, SND_JACK_MICROPHONE,
-				0);
+				shrt);
 
 	snd_soc_dapm_force_enable_pin(&card->dapm, "MICBIAS");
 
-- 
2.25.1

^ permalink raw reply related

* Re: [RFC PATCH v2 14/18] gpu: host1x: mipi: Split tegra_mipi_calibrate and tegra_mipi_wait
From: Dmitry Osipenko @ 2020-06-18  0:35 UTC (permalink / raw)
  To: Sowjanya Komatineni, thierry.reding-Re5JQEeQqe8AvxtiuMwx3w,
	jonathanh-DDmLM1+adcrQT0dZR+AlfA, frankc-DDmLM1+adcrQT0dZR+AlfA,
	hverkuil-qWit8jRvyhVmR6Xm/wNWPw, sakari.ailus-X3B1VOXEql0,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	helen.koike-ZGY8ohtN/8qB+jHODAdFcQ
  Cc: sboyd-DgEjT+Ai2ygdnm+yROfE0A,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	linux-media-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1592358094-23459-15-git-send-email-skomatineni-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>

17.06.2020 04:41, Sowjanya Komatineni пишет:
...
> -static int tegra_mipi_wait(struct tegra_mipi *mipi)
> +int tegra_mipi_wait(struct tegra_mipi_device *device)
>  {
> +	struct tegra_mipi *mipi = device->mipi;
>  	unsigned long timeout = jiffies + msecs_to_jiffies(250);
>  	u32 value;
> +	int err;
> +
> +	err = clk_enable(device->mipi->clk);
> +	if (err < 0)
> +		return err;
> +
> +	mutex_lock(&device->mipi->lock);

The timeout variable should be assigned *after* taking the lock.

It will be better if you could use the read_poll_timeout() or
readl_relaxed_poll_timeout() here.

>  	while (time_before(jiffies, timeout)) {
>  		value = tegra_mipi_readl(mipi, MIPI_CAL_STATUS);
>  		if ((value & MIPI_CAL_STATUS_ACTIVE) == 0 &&
>  		    (value & MIPI_CAL_STATUS_DONE) != 0)
> -			return 0;
> +			goto done;
>  
>  		usleep_range(10, 50);
>  	}
>  
> -	return -ETIMEDOUT;
> +	err = -ETIMEDOUT;
> +done:
> +	mutex_unlock(&device->mipi->lock);
> +	clk_disable(device->mipi->clk);
> +	return err;
>  }
> +EXPORT_SYMBOL(tegra_mipi_wait);

^ permalink raw reply

* Re: [RFC PATCH v2 13/18] gpu: host1x: mipi: Update tegra_mipi_request() to be node based
From: Dmitry Osipenko @ 2020-06-18  0:27 UTC (permalink / raw)
  To: Sowjanya Komatineni, thierry.reding-Re5JQEeQqe8AvxtiuMwx3w,
	jonathanh-DDmLM1+adcrQT0dZR+AlfA, frankc-DDmLM1+adcrQT0dZR+AlfA,
	hverkuil-qWit8jRvyhVmR6Xm/wNWPw, sakari.ailus-X3B1VOXEql0,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	helen.koike-ZGY8ohtN/8qB+jHODAdFcQ
  Cc: sboyd-DgEjT+Ai2ygdnm+yROfE0A,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	linux-media-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1592358094-23459-14-git-send-email-skomatineni-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>

17.06.2020 04:41, Sowjanya Komatineni пишет:
> Tegra CSI driver need a separate MIPI device for each channel as
> calibration of corresponding MIPI pads for each channel should
> happen independently.
> 
> So, this patch updates tegra_mipi_request() API to add a device_node
> pointer argument to allow creating mipi device for specific device
> node rather than a device.
> 
> Signed-off-by: Sowjanya Komatineni <skomatineni-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> ---
>  drivers/gpu/drm/tegra/dsi.c | 2 +-
>  drivers/gpu/host1x/mipi.c   | 7 +++++--
>  include/linux/host1x.h      | 3 ++-
>  3 files changed, 8 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c
> index 38beab9..0443589 100644
> --- a/drivers/gpu/drm/tegra/dsi.c
> +++ b/drivers/gpu/drm/tegra/dsi.c
> @@ -1618,7 +1618,7 @@ static int tegra_dsi_probe(struct platform_device *pdev)
>  	if (IS_ERR(dsi->regs))
>  		return PTR_ERR(dsi->regs);
>  
> -	dsi->mipi = tegra_mipi_request(&pdev->dev);
> +	dsi->mipi = tegra_mipi_request(&pdev->dev, NULL);
>  	if (IS_ERR(dsi->mipi))
>  		return PTR_ERR(dsi->mipi);
>  
> diff --git a/drivers/gpu/host1x/mipi.c b/drivers/gpu/host1x/mipi.c
> index e00809d..93b354b 100644
> --- a/drivers/gpu/host1x/mipi.c
> +++ b/drivers/gpu/host1x/mipi.c
> @@ -206,13 +206,16 @@ static int tegra_mipi_power_down(struct tegra_mipi *mipi)
>  	return 0;
>  }
>  
> -struct tegra_mipi_device *tegra_mipi_request(struct device *device)
> +struct tegra_mipi_device *tegra_mipi_request(struct device *device,
> +					     struct device_node *np)
>  {
> -	struct device_node *np = device->of_node;
>  	struct tegra_mipi_device *dev;
>  	struct of_phandle_args args;
>  	int err;
>  
> +	if (!np)
> +		np = device->of_node;

Will be nicer if DSI panel could pass the device's node directly,
instead of this.

^ permalink raw reply

* [PATCH v3 3/3] drm/tegra: plane: Support 180° rotation
From: Dmitry Osipenko @ 2020-06-17 23:40 UTC (permalink / raw)
  To: Thierry Reding, Thomas Zimmermann, Derek Basehore, Sam Ravnborg,
	Laurent Pinchart, Sean Paul, Daniel Vetter,
	Ville Syrjälä, Emil Velikov, Daniel Stone
  Cc: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20200617234040.1094-1-digetx-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Combining horizontal and vertical reflections gives us 180 degrees of
rotation. Both reflection modes are already supported, and thus, we just
need to mark the 180 rotation mode as supported. The 180 rotation mode is
needed for devices like Nexus 7 tablet, which have display panel mounted
upside-down.

Signed-off-by: Dmitry Osipenko <digetx-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/gpu/drm/tegra/dc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index f8149dc3b1b4..1a9a5f8bba34 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -816,6 +816,7 @@ static struct drm_plane *tegra_primary_plane_create(struct drm_device *drm,
 	err = drm_plane_create_rotation_property(&plane->base,
 						 DRM_MODE_ROTATE_0,
 						 DRM_MODE_ROTATE_0 |
+						 DRM_MODE_ROTATE_180 |
 						 DRM_MODE_REFLECT_X |
 						 DRM_MODE_REFLECT_Y);
 	if (err < 0)
@@ -1105,6 +1106,7 @@ static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm,
 	err = drm_plane_create_rotation_property(&plane->base,
 						 DRM_MODE_ROTATE_0,
 						 DRM_MODE_ROTATE_0 |
+						 DRM_MODE_ROTATE_180 |
 						 DRM_MODE_REFLECT_X |
 						 DRM_MODE_REFLECT_Y);
 	if (err < 0)
-- 
2.26.0

^ permalink raw reply related

* [PATCH v3 2/3] drm/tegra: plane: Support horizontal reflection
From: Dmitry Osipenko @ 2020-06-17 23:40 UTC (permalink / raw)
  To: Thierry Reding, Thomas Zimmermann, Derek Basehore, Sam Ravnborg,
	Laurent Pinchart, Sean Paul, Daniel Vetter,
	Ville Syrjälä, Emil Velikov, Daniel Stone
  Cc: dri-devel, linux-tegra, linux-kernel
In-Reply-To: <20200617234040.1094-1-digetx@gmail.com>

Support horizontal reflection mode which will allow to support 180°
rotation mode when combined with the vertical reflection.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/gpu/drm/tegra/dc.c    | 38 +++++++++++++++++++++++++++++------
 drivers/gpu/drm/tegra/dc.h    |  1 +
 drivers/gpu/drm/tegra/plane.c |  1 +
 drivers/gpu/drm/tegra/plane.h |  1 +
 4 files changed, 35 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index bb92c1ed44e9..f8149dc3b1b4 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -368,6 +368,12 @@ static void tegra_dc_setup_window(struct tegra_plane *plane,
 	h_size = window->src.w * bpp;
 	v_size = window->src.h;
 
+	if (window->reflect_x)
+		h_offset += (window->src.w - 1) * bpp;
+
+	if (window->reflect_y)
+		v_offset += window->src.h - 1;
+
 	value = V_PRESCALED_SIZE(v_size) | H_PRESCALED_SIZE(h_size);
 	tegra_plane_writel(plane, value, DC_WIN_PRESCALED_SIZE);
 
@@ -404,9 +410,6 @@ static void tegra_dc_setup_window(struct tegra_plane *plane,
 		tegra_plane_writel(plane, window->stride[0], DC_WIN_LINE_STRIDE);
 	}
 
-	if (window->reflect_y)
-		v_offset += window->src.h - 1;
-
 	tegra_plane_writel(plane, h_offset, DC_WINBUF_ADDR_H_OFFSET);
 	tegra_plane_writel(plane, v_offset, DC_WINBUF_ADDR_V_OFFSET);
 
@@ -470,6 +473,9 @@ static void tegra_dc_setup_window(struct tegra_plane *plane,
 		value |= COLOR_EXPAND;
 	}
 
+	if (window->reflect_x)
+		value |= H_DIRECTION;
+
 	if (window->reflect_y)
 		value |= V_DIRECTION;
 
@@ -601,7 +607,10 @@ static int tegra_plane_atomic_check(struct drm_plane *plane,
 				    struct drm_plane_state *state)
 {
 	struct tegra_plane_state *plane_state = to_tegra_plane_state(state);
-	unsigned int rotation = DRM_MODE_ROTATE_0 | DRM_MODE_REFLECT_Y;
+	unsigned int supported_rotation = DRM_MODE_ROTATE_0 |
+					  DRM_MODE_REFLECT_X |
+					  DRM_MODE_REFLECT_Y;
+	unsigned int rotation = state->rotation;
 	struct tegra_bo_tiling *tiling = &plane_state->tiling;
 	struct tegra_plane *tegra = to_tegra_plane(plane);
 	struct tegra_dc *dc = to_tegra_dc(state->crtc);
@@ -639,7 +648,21 @@ static int tegra_plane_atomic_check(struct drm_plane *plane,
 		return -EINVAL;
 	}
 
-	rotation = drm_rotation_simplify(state->rotation, rotation);
+	/*
+	 * Older userspace used custom BO flag in order to specify the Y
+	 * reflection, while modern userspace uses the generic DRM rotation
+	 * property in order to achieve the same result.  The legacy BO flag
+	 * duplicates the DRM rotation property when both are set.
+	 */
+	if (tegra_fb_is_bottom_up(state->fb))
+		rotation |= DRM_MODE_REFLECT_Y;
+
+	rotation = drm_rotation_simplify(rotation, supported_rotation);
+
+	if (rotation & DRM_MODE_REFLECT_X)
+		plane_state->reflect_x = true;
+	else
+		plane_state->reflect_x = false;
 
 	if (rotation & DRM_MODE_REFLECT_Y)
 		plane_state->reflect_y = true;
@@ -706,7 +729,8 @@ static void tegra_plane_atomic_update(struct drm_plane *plane,
 	window.dst.w = drm_rect_width(&plane->state->dst);
 	window.dst.h = drm_rect_height(&plane->state->dst);
 	window.bits_per_pixel = fb->format->cpp[0] * 8;
-	window.reflect_y = tegra_fb_is_bottom_up(fb) || state->reflect_y;
+	window.reflect_x = state->reflect_x;
+	window.reflect_y = state->reflect_y;
 
 	/* copy from state */
 	window.zpos = plane->state->normalized_zpos;
@@ -792,6 +816,7 @@ static struct drm_plane *tegra_primary_plane_create(struct drm_device *drm,
 	err = drm_plane_create_rotation_property(&plane->base,
 						 DRM_MODE_ROTATE_0,
 						 DRM_MODE_ROTATE_0 |
+						 DRM_MODE_REFLECT_X |
 						 DRM_MODE_REFLECT_Y);
 	if (err < 0)
 		dev_err(dc->dev, "failed to create rotation property: %d\n",
@@ -1080,6 +1105,7 @@ static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm,
 	err = drm_plane_create_rotation_property(&plane->base,
 						 DRM_MODE_ROTATE_0,
 						 DRM_MODE_ROTATE_0 |
+						 DRM_MODE_REFLECT_X |
 						 DRM_MODE_REFLECT_Y);
 	if (err < 0)
 		dev_err(dc->dev, "failed to create rotation property: %d\n",
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h
index 98e1b625168e..051d03dcb9b0 100644
--- a/drivers/gpu/drm/tegra/dc.h
+++ b/drivers/gpu/drm/tegra/dc.h
@@ -136,6 +136,7 @@ struct tegra_dc_window {
 	unsigned int stride[2];
 	unsigned long base[3];
 	unsigned int zpos;
+	bool reflect_x;
 	bool reflect_y;
 
 	struct tegra_bo_tiling tiling;
diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c
index e05ef6013a97..4cd0461cc508 100644
--- a/drivers/gpu/drm/tegra/plane.c
+++ b/drivers/gpu/drm/tegra/plane.c
@@ -61,6 +61,7 @@ tegra_plane_atomic_duplicate_state(struct drm_plane *plane)
 	copy->tiling = state->tiling;
 	copy->format = state->format;
 	copy->swap = state->swap;
+	copy->reflect_x = state->reflect_x;
 	copy->reflect_y = state->reflect_y;
 	copy->opaque = state->opaque;
 
diff --git a/drivers/gpu/drm/tegra/plane.h b/drivers/gpu/drm/tegra/plane.h
index 8047fc916d8c..c691dd79b27b 100644
--- a/drivers/gpu/drm/tegra/plane.h
+++ b/drivers/gpu/drm/tegra/plane.h
@@ -46,6 +46,7 @@ struct tegra_plane_state {
 	u32 format;
 	u32 swap;
 
+	bool reflect_x;
 	bool reflect_y;
 
 	/* used for legacy blending support only */
-- 
2.26.0

^ permalink raw reply related

* [PATCH v3 1/3] drm/tegra: plane: Rename bottom_up to reflect_y
From: Dmitry Osipenko @ 2020-06-17 23:40 UTC (permalink / raw)
  To: Thierry Reding, Thomas Zimmermann, Derek Basehore, Sam Ravnborg,
	Laurent Pinchart, Sean Paul, Daniel Vetter,
	Ville Syrjälä, Emil Velikov, Daniel Stone
  Cc: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20200617234040.1094-1-digetx-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

This makes the naming consistent with the DRM core.

Signed-off-by: Dmitry Osipenko <digetx-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/gpu/drm/tegra/dc.c    | 10 +++++-----
 drivers/gpu/drm/tegra/dc.h    |  2 +-
 drivers/gpu/drm/tegra/plane.c |  2 +-
 drivers/gpu/drm/tegra/plane.h |  2 +-
 4 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 04d6848d19fc..bb92c1ed44e9 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -404,7 +404,7 @@ static void tegra_dc_setup_window(struct tegra_plane *plane,
 		tegra_plane_writel(plane, window->stride[0], DC_WIN_LINE_STRIDE);
 	}
 
-	if (window->bottom_up)
+	if (window->reflect_y)
 		v_offset += window->src.h - 1;
 
 	tegra_plane_writel(plane, h_offset, DC_WINBUF_ADDR_H_OFFSET);
@@ -470,7 +470,7 @@ static void tegra_dc_setup_window(struct tegra_plane *plane,
 		value |= COLOR_EXPAND;
 	}
 
-	if (window->bottom_up)
+	if (window->reflect_y)
 		value |= V_DIRECTION;
 
 	if (tegra_plane_use_horizontal_filtering(plane, window)) {
@@ -642,9 +642,9 @@ static int tegra_plane_atomic_check(struct drm_plane *plane,
 	rotation = drm_rotation_simplify(state->rotation, rotation);
 
 	if (rotation & DRM_MODE_REFLECT_Y)
-		plane_state->bottom_up = true;
+		plane_state->reflect_y = true;
 	else
-		plane_state->bottom_up = false;
+		plane_state->reflect_y = false;
 
 	/*
 	 * Tegra doesn't support different strides for U and V planes so we
@@ -706,7 +706,7 @@ static void tegra_plane_atomic_update(struct drm_plane *plane,
 	window.dst.w = drm_rect_width(&plane->state->dst);
 	window.dst.h = drm_rect_height(&plane->state->dst);
 	window.bits_per_pixel = fb->format->cpp[0] * 8;
-	window.bottom_up = tegra_fb_is_bottom_up(fb) || state->bottom_up;
+	window.reflect_y = tegra_fb_is_bottom_up(fb) || state->reflect_y;
 
 	/* copy from state */
 	window.zpos = plane->state->normalized_zpos;
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h
index 3d8ddccd758f..98e1b625168e 100644
--- a/drivers/gpu/drm/tegra/dc.h
+++ b/drivers/gpu/drm/tegra/dc.h
@@ -136,7 +136,7 @@ struct tegra_dc_window {
 	unsigned int stride[2];
 	unsigned long base[3];
 	unsigned int zpos;
-	bool bottom_up;
+	bool reflect_y;
 
 	struct tegra_bo_tiling tiling;
 	u32 format;
diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c
index 9ccfb56e9b01..e05ef6013a97 100644
--- a/drivers/gpu/drm/tegra/plane.c
+++ b/drivers/gpu/drm/tegra/plane.c
@@ -61,7 +61,7 @@ tegra_plane_atomic_duplicate_state(struct drm_plane *plane)
 	copy->tiling = state->tiling;
 	copy->format = state->format;
 	copy->swap = state->swap;
-	copy->bottom_up = state->bottom_up;
+	copy->reflect_y = state->reflect_y;
 	copy->opaque = state->opaque;
 
 	for (i = 0; i < 2; i++)
diff --git a/drivers/gpu/drm/tegra/plane.h b/drivers/gpu/drm/tegra/plane.h
index a158a915109a..8047fc916d8c 100644
--- a/drivers/gpu/drm/tegra/plane.h
+++ b/drivers/gpu/drm/tegra/plane.h
@@ -46,7 +46,7 @@ struct tegra_plane_state {
 	u32 format;
 	u32 swap;
 
-	bool bottom_up;
+	bool reflect_y;
 
 	/* used for legacy blending support only */
 	struct tegra_plane_legacy_blending_state blending[2];
-- 
2.26.0

^ permalink raw reply related

* [PATCH v3 0/3] 180 degrees rotation support for NVIDIA Tegra DRM
From: Dmitry Osipenko @ 2020-06-17 23:40 UTC (permalink / raw)
  To: Thierry Reding, Thomas Zimmermann, Derek Basehore, Sam Ravnborg,
	Laurent Pinchart, Sean Paul, Daniel Vetter,
	Ville Syrjälä, Emil Velikov, Daniel Stone
  Cc: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

Hello!

This series adds 180° display plane rotation support to the NVIDIA Tegra
DRM driver which is needed for devices that have display panel physically
mounted upside-down, like Nexus 7 tablet device for example [1]. Since
DRM panel rotation is a new thing for a userspace, currently only
Opentegra Xorg driver [2] and a recent Weston [3] have support for the
rotated display panels, but this is more than good enough for the starter.

[1] https://patchwork.ozlabs.org/project/linux-tegra/patch/20200607154327.18589-3-digetx-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org/
[2] https://github.com/grate-driver/xf86-video-opentegra/commit/28eb20a3959bbe5bc3a3b67e55977093fd5114ca
[3] https://gitlab.freedesktop.org/wayland/weston/-/merge_requests/315

Changelog:

v3: - Factored out the panel patches into standalone series [4] because
      this series doesn't have hard dependency on the panel patches and it
      should be nicer to review and apply the properly grouped patches.

    - The DRM_MODE_ROTATE_180 now isn't passed to drm_rotation_simplify(),
      like it was suggested by Ville Syrjälä in the comment to v2.

    - Added clarifying comment for the tegra_fb_is_bottom_up() in the code.

[4] https://lore.kernel.org/lkml/20200617231842.30671-1-digetx-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org/T/#t

Dmitry Osipenko (3):
  drm/tegra: plane: Rename bottom_up to reflect_y
  drm/tegra: plane: Support horizontal reflection
  drm/tegra: plane: Support 180° rotation

 drivers/gpu/drm/tegra/dc.c    | 46 ++++++++++++++++++++++++++++-------
 drivers/gpu/drm/tegra/dc.h    |  3 ++-
 drivers/gpu/drm/tegra/plane.c |  3 ++-
 drivers/gpu/drm/tegra/plane.h |  3 ++-
 4 files changed, 43 insertions(+), 12 deletions(-)

-- 
2.26.0

^ permalink raw reply

* [PATCH v11 4/4] drm/panel-simple: Read panel orientation
From: Dmitry Osipenko @ 2020-06-17 23:18 UTC (permalink / raw)
  To: Thierry Reding, Thomas Zimmermann, Derek Basehore, Sam Ravnborg,
	Laurent Pinchart, Sean Paul, Daniel Vetter,
	Ville Syrjälä, Emil Velikov, Daniel Stone
  Cc: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20200617231842.30671-1-digetx-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

The panel orientation needs to parsed from a device-tree and assigned to
the panel's connector in order to make orientation property available to
userspace. That's what this patch does for the panel-simple driver.

Signed-off-by: Dmitry Osipenko <digetx-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/gpu/drm/panel/panel-simple.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index 6764ac630e22..2dee1320216c 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -112,6 +112,8 @@ struct panel_simple {
 	struct gpio_desc *hpd_gpio;
 
 	struct drm_display_mode override_mode;
+
+	enum drm_panel_orientation orientation;
 };
 
 static inline struct panel_simple *to_panel_simple(struct drm_panel *panel)
@@ -371,6 +373,9 @@ static int panel_simple_get_modes(struct drm_panel *panel,
 	/* add hard-coded panel modes */
 	num += panel_simple_get_non_edid_modes(p, connector);
 
+	/* set up connector's "panel orientation" property */
+	drm_connector_set_panel_orientation(connector, p->orientation);
+
 	return num;
 }
 
@@ -530,6 +535,12 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)
 		return err;
 	}
 
+	err = of_drm_get_panel_orientation(dev->of_node, &panel->orientation);
+	if (err) {
+		dev_err(dev, "failed to parse rotation property: %d\n", err);
+		return err;
+	}
+
 	ddc = of_parse_phandle(dev->of_node, "ddc-i2c-bus", 0);
 	if (ddc) {
 		panel->ddc = of_find_i2c_adapter_by_node(ddc);
-- 
2.26.0

^ permalink raw reply related

* [PATCH v11 3/4] drm/panel: lvds: Read panel orientation
From: Dmitry Osipenko @ 2020-06-17 23:18 UTC (permalink / raw)
  To: Thierry Reding, Thomas Zimmermann, Derek Basehore, Sam Ravnborg,
	Laurent Pinchart, Sean Paul, Daniel Vetter,
	Ville Syrjälä, Emil Velikov, Daniel Stone
  Cc: dri-devel, linux-tegra, linux-kernel
In-Reply-To: <20200617231842.30671-1-digetx@gmail.com>

The panel orientation needs to parsed from a device-tree and assigned to
the panel's connector in order to make orientation property available to
userspace. That's what this patch does for the generic LVDS panel.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/gpu/drm/panel/panel-lvds.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/panel/panel-lvds.c b/drivers/gpu/drm/panel/panel-lvds.c
index 5ce3f4a2b7a1..f62227059090 100644
--- a/drivers/gpu/drm/panel/panel-lvds.c
+++ b/drivers/gpu/drm/panel/panel-lvds.c
@@ -37,6 +37,8 @@ struct panel_lvds {
 
 	struct gpio_desc *enable_gpio;
 	struct gpio_desc *reset_gpio;
+
+	enum drm_panel_orientation orientation;
 };
 
 static inline struct panel_lvds *to_panel_lvds(struct drm_panel *panel)
@@ -99,6 +101,7 @@ static int panel_lvds_get_modes(struct drm_panel *panel,
 	connector->display_info.bus_flags = lvds->data_mirror
 					  ? DRM_BUS_FLAG_DATA_LSB_TO_MSB
 					  : DRM_BUS_FLAG_DATA_MSB_TO_LSB;
+	drm_connector_set_panel_orientation(connector, lvds->orientation);
 
 	return 1;
 }
@@ -116,6 +119,13 @@ static int panel_lvds_parse_dt(struct panel_lvds *lvds)
 	const char *mapping;
 	int ret;
 
+	ret = of_drm_get_panel_orientation(np, &lvds->orientation);
+	if (ret < 0) {
+		dev_err(lvds->dev, "%pOF: problems parsing rotation (%d)\n",
+			np, ret);
+		return ret;
+	}
+
 	ret = of_get_display_timing(np, "panel-timing", &timing);
 	if (ret < 0) {
 		dev_err(lvds->dev, "%pOF: problems parsing panel-timing (%d)\n",
-- 
2.26.0

^ permalink raw reply related

* [PATCH v11 2/4] drm/panel: Read panel orientation for BOE TV101WUM-NL6
From: Dmitry Osipenko @ 2020-06-17 23:18 UTC (permalink / raw)
  To: Thierry Reding, Thomas Zimmermann, Derek Basehore, Sam Ravnborg,
	Laurent Pinchart, Sean Paul, Daniel Vetter,
	Ville Syrjälä, Emil Velikov, Daniel Stone
  Cc: dri-devel, linux-tegra, linux-kernel
In-Reply-To: <20200617231842.30671-1-digetx@gmail.com>

From: Derek Basehore <dbasehore@chromium.org>

This reads the DT setting for the panel rotation to set the panel
orientation in the get_modes callback.

Reviewed-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Derek Basehore <dbasehore@chromium.org>
---
 drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
index db5b866357f2..4bd9397972e8 100644
--- a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
+++ b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
@@ -11,6 +11,7 @@
 #include <linux/of_device.h>
 #include <linux/regulator/consumer.h>
 
+#include <drm/drm_connector.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_mipi_dsi.h>
 #include <drm/drm_panel.h>
@@ -43,6 +44,7 @@ struct boe_panel {
 
 	const struct panel_desc *desc;
 
+	enum drm_panel_orientation orientation;
 	struct regulator *pp1800;
 	struct regulator *avee;
 	struct regulator *avdd;
@@ -740,6 +742,7 @@ static int boe_panel_get_modes(struct drm_panel *panel,
 	connector->display_info.width_mm = boe->desc->size.width_mm;
 	connector->display_info.height_mm = boe->desc->size.height_mm;
 	connector->display_info.bpc = boe->desc->bpc;
+	drm_connector_set_panel_orientation(connector, boe->orientation);
 
 	return 1;
 }
@@ -779,6 +782,9 @@ static int boe_panel_add(struct boe_panel *boe)
 
 	drm_panel_init(&boe->base, dev, &boe_panel_funcs,
 		       DRM_MODE_CONNECTOR_DSI);
+	err = of_drm_get_panel_orientation(dev->of_node, &boe->orientation);
+	if (err < 0)
+		return err;
 
 	err = drm_panel_of_backlight(&boe->base);
 	if (err)
-- 
2.26.0

^ permalink raw reply related

* [PATCH v11 1/4] drm/panel: Add helper for reading DT rotation
From: Dmitry Osipenko @ 2020-06-17 23:18 UTC (permalink / raw)
  To: Thierry Reding, Thomas Zimmermann, Derek Basehore, Sam Ravnborg,
	Laurent Pinchart, Sean Paul, Daniel Vetter,
	Ville Syrjälä, Emil Velikov, Daniel Stone
  Cc: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20200617231842.30671-1-digetx-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

From: Derek Basehore <dbasehore-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>

This adds a helper function for reading the rotation (panel
orientation) from the device tree.

Signed-off-by: Derek Basehore <dbasehore-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
Reviewed-by: Sam Ravnborg <sam-uyr5N9Q2VtJg9hUCZPvPmw@public.gmane.org>
---
 drivers/gpu/drm/drm_panel.c | 43 +++++++++++++++++++++++++++++++++++++
 include/drm/drm_panel.h     |  9 ++++++++
 2 files changed, 52 insertions(+)

diff --git a/drivers/gpu/drm/drm_panel.c b/drivers/gpu/drm/drm_panel.c
index 8c7bac85a793..5557c75301f1 100644
--- a/drivers/gpu/drm/drm_panel.c
+++ b/drivers/gpu/drm/drm_panel.c
@@ -300,6 +300,49 @@ struct drm_panel *of_drm_find_panel(const struct device_node *np)
 	return ERR_PTR(-EPROBE_DEFER);
 }
 EXPORT_SYMBOL(of_drm_find_panel);
+
+/**
+ * of_drm_get_panel_orientation - look up the orientation of the panel through
+ * the "rotation" binding from a device tree node
+ * @np: device tree node of the panel
+ * @orientation: orientation enum to be filled in
+ *
+ * Looks up the rotation of a panel in the device tree. The orientation of the
+ * panel is expressed as a property name "rotation" in the device tree. The
+ * rotation in the device tree is counter clockwise.
+ *
+ * Return: 0 when a valid rotation value (0, 90, 180, or 270) is read or the
+ * rotation property doesn't exist. -EERROR otherwise.
+ */
+int of_drm_get_panel_orientation(const struct device_node *np,
+				 enum drm_panel_orientation *orientation)
+{
+	int rotation, ret;
+
+	ret = of_property_read_u32(np, "rotation", &rotation);
+	if (ret == -EINVAL) {
+		/* Don't return an error if there's no rotation property. */
+		*orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
+		return 0;
+	}
+
+	if (ret < 0)
+		return ret;
+
+	if (rotation == 0)
+		*orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL;
+	else if (rotation == 90)
+		*orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP;
+	else if (rotation == 180)
+		*orientation = DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP;
+	else if (rotation == 270)
+		*orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP;
+	else
+		return -EINVAL;
+
+	return 0;
+}
+EXPORT_SYMBOL(of_drm_get_panel_orientation);
 #endif
 
 #if IS_REACHABLE(CONFIG_BACKLIGHT_CLASS_DEVICE)
diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
index 6193cb555acc..781c735f0f9b 100644
--- a/include/drm/drm_panel.h
+++ b/include/drm/drm_panel.h
@@ -35,6 +35,8 @@ struct drm_device;
 struct drm_panel;
 struct display_timing;
 
+enum drm_panel_orientation;
+
 /**
  * struct drm_panel_funcs - perform operations on a given panel
  *
@@ -191,11 +193,18 @@ int drm_panel_get_modes(struct drm_panel *panel, struct drm_connector *connector
 
 #if defined(CONFIG_OF) && defined(CONFIG_DRM_PANEL)
 struct drm_panel *of_drm_find_panel(const struct device_node *np);
+int of_drm_get_panel_orientation(const struct device_node *np,
+				 enum drm_panel_orientation *orientation);
 #else
 static inline struct drm_panel *of_drm_find_panel(const struct device_node *np)
 {
 	return ERR_PTR(-ENODEV);
 }
+static inline int of_drm_get_panel_orientation(const struct device_node *np,
+		enum drm_panel_orientation *orientation)
+{
+	return -ENODEV;
+}
 #endif
 
 #if IS_ENABLED(CONFIG_DRM_PANEL) && (IS_BUILTIN(CONFIG_BACKLIGHT_CLASS_DEVICE) || \
-- 
2.26.0

^ permalink raw reply related

* [PATCH v11 0/4] Panel rotation patches
From: Dmitry Osipenko @ 2020-06-17 23:18 UTC (permalink / raw)
  To: Thierry Reding, Thomas Zimmermann, Derek Basehore, Sam Ravnborg,
	Laurent Pinchart, Sean Paul, Daniel Vetter,
	Ville Syrjälä, Emil Velikov, Daniel Stone
  Cc: dri-devel, linux-tegra, linux-kernel

Hello!

This series adds support for display panel's DT rotation property. It's a
continuation of the work that was initially started by Derek Basehore for
the panel driver that is used by some Mediatek device [1]. I picked up the
Derek's patches and added my t-b and r-b tags to them, I also added
rotation support to the panel-lvds and panel-simple drivers.

We need the rotation support for the Nexus 7 tablet device which is pending
to become supported by upstream kernel, the device has display panel mounted
upside-down and it uses panel-lvds [2].

[1] https://lkml.org/lkml/2020/3/5/1119
[2] https://patchwork.ozlabs.org/project/linux-tegra/patch/20200607154327.18589-3-digetx@gmail.com/

Changelog:

v11: - This series is factored out from this patchset [3] because these
       patches do not have hard dependency on the Tegra DRM patches and
       it should be nicer to review and apply the properly grouped patches.

     - Initially [3] only touched the panel-lvds driver and Emil Velikov
       suggested that it will be better to support more panels in the review
       comments to [3]. So I included the Derek's patch for the BOE panel
       and added rotation support to the panel-simple driver. I tested that
       panel-lvds and panel-simple work properly with the rotated panel using
       the Opentegra Xorg driver [4] and Wayland Weston [5].

     - The panel-lvds driver now prints a error message if rotation property
       fails to be parsed.

[3] https://lore.kernel.org/lkml/20200614200121.14147-1-digetx@gmail.com/
[4] https://github.com/grate-driver/xf86-video-opentegra/commit/28eb20a3959bbe5bc3a3b67e55977093fd5114ca
[5] https://gitlab.freedesktop.org/wayland/weston/-/merge_requests/315

Derek Basehore (2):
  drm/panel: Add helper for reading DT rotation
  drm/panel: Read panel orientation for BOE TV101WUM-NL6

Dmitry Osipenko (2):
  drm/panel: lvds: Read panel orientation
  drm/panel-simple: Read panel orientation

 drivers/gpu/drm/drm_panel.c                   | 43 +++++++++++++++++++
 .../gpu/drm/panel/panel-boe-tv101wum-nl6.c    |  6 +++
 drivers/gpu/drm/panel/panel-lvds.c            | 10 +++++
 drivers/gpu/drm/panel/panel-simple.c          | 11 +++++
 include/drm/drm_panel.h                       |  9 ++++
 5 files changed, 79 insertions(+)

-- 
2.26.0

^ permalink raw reply

* Re: [PATCH 07/38] dt-bindings: display: tegra: Convert to json-schema
From: Rob Herring @ 2020-06-17 23:13 UTC (permalink / raw)
  To: Thierry Reding
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20200612141903.2391044-8-thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

On Fri, Jun 12, 2020 at 04:18:32PM +0200, Thierry Reding wrote:
> From: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> 
> Convert the Tegra host1x controller bindings from the free-form text
> format to json-schema.
> 
> Signed-off-by: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> ---
>  .../display/tegra/nvidia,tegra20-host1x.txt   |  516 ------
>  .../display/tegra/nvidia,tegra20-host1x.yaml  | 1418 +++++++++++++++++
>  2 files changed, 1418 insertions(+), 516 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
>  create mode 100644 Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.yaml


> diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.yaml
> new file mode 100644
> index 000000000000..3347e1b3c8f0
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.yaml
> @@ -0,0 +1,1418 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/tegra/nvidia,tegra20-host1x.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: NVIDIA Tegra host1x controller
> +
> +maintainers:
> +  - Thierry Reding <thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> +  - Jon Hunter <jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> +
> +description: The host1x top-level node defines a number of children, each
> +  representing one of the host1x client modules defined in this binding.
> +
> +properties:
> +  # required
> +  compatible:
> +    oneOf:
> +      - description: NVIDIA Tegra20
> +        items:
> +          - const: nvidia,tegra20-host1x
> +
> +      - description: NVIDIA Tegra30
> +        items:
> +          - const: nvidia,tegra30-host1x
> +
> +      - description: NVIDIA Tegra114
> +        items:
> +          - const: nvidia,tegra114-host1x
> +
> +      - description: NVIDIA Tegra124
> +        items:
> +          - const: nvidia,tegra124-host1x
> +
> +      - description: NVIDIA Tegra132
> +        items:
> +          - const: nvidia,tegra132-host1x
> +          - const: nvidia,tegra124-host1x
> +
> +      - description: NVIDIA Tegra210
> +        items:
> +          - const: nvidia,tegra210-host1x
> +
> +      - description: NVIDIA Tegra186
> +        items:
> +          - const: nvidia,tegra186-host1x
> +
> +      - description: NVIDIA Tegra194
> +        items:
> +          - const: nvidia,tegra194-host1x

I don't think the descriptions really add much. I'd rather see all the 
single entry cases as 1 'enum'.

> +
> +  interrupts:
> +    items:
> +      - description: host1x syncpoint interrupt
> +      - description: host1x general interrupt
> +    minItems: 1
> +    maxItems: 2
> +
> +  interrupt-names:
> +    items:
> +      - const: syncpt
> +      - const: host1x
> +
> +  '#address-cells':
> +    description: The number of cells used to represent physical base addresses
> +      in the host1x address space.
> +    enum: [1, 2]
> +
> +  '#size-cells':
> +    description: The number of cells used to represent the size of an address
> +      range in the host1x address space.
> +    enum: [1, 2]
> +
> +  # required

Odd comment...

> +  ranges:
> +    description: The mapping of the host1x address space to the CPU address
> +      space.

That's every 'ranges'. If you know how many entries, then define 
'maxItems'. If not, 'ranges: true' is enough.

> +
> +  clocks:
> +    description: Must contain one entry, for the module clock. See
> +      ../clocks/clock-bindings.txt for details.
> +
> +  clock-names:
> +    items:
> +      - const: host1x
> +
> +  resets:
> +    description: Must contain an entry for each entry in reset-names. See
> +      ../reset/reset.txt for details.
> +
> +  reset-names:
> +    items:
> +      - const: host1x
> +
> +  # optional
> +  iommus:
> +    $ref: "/schemas/iommu/iommu.yaml#/properties/iommus"

This is already applied to every 'iommus' property, so you just need to 
define how many entries.

> +
> +  memory-controllers:
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +
> +required:
> +  - compatible
> +  - interrupts
> +  - interrupt-names
> +  - '#address-cells'
> +  - '#size-cells'
> +  - ranges
> +  - reg
> +  - clocks
> +  - clock-names
> +  - resets
> +  - reset-names
> +
> +unevaluatedProperties: false
> +
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - nvidia,tegra186-host1x
> +              - nvidia,tegra194-host1x
> +    then:
> +      properties:
> +        reg-names:
> +          items:
> +            - const: hypervisor
> +            - const: vm
> +
> +        reg:
> +          items:
> +            - description: physical base address and length of the register
> +                region assigned to the VM
> +            - description: physical base address and length of the register
> +                region used by the hypervisor
> +
> +      required:
> +        - reg-names
> +    else:
> +      properties:
> +        reg:
> +          maxItems: 1
> +
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            oneOf:
> +              - const: nvidia,tegra20-host1x
> +              - const: nvidia,tegra30-host1x
> +              - const: nvidia,tegra114-host1x
> +              - const: nvidia,tegra124-host1x

Use 'enum'.

> +
> +    then:
> +      patternProperties:
> +        "^vi@[0-9a-f]+$":
> +          description: video input
> +          type: object
> +          properties:
> +            compatible:
> +              oneOf:
> +                - const: nvidia,tegra20-vi
> +                - const: nvidia,tegra30-vi
> +                - const: nvidia,tegra114-vi
> +                - const: nvidia,tegra124-vi

Use a 'enum' for these 4.

> +                - items:
> +                    - const: nvidia,tegra132-vi
> +                    - const: nvidia,tegra124-vi
> +
> +            reg:
> +              maxItems: 1
> +
> +            interrupts:
> +              maxItems: 1
> +
> +            clocks:
> +              maxItems: 1
> +
> +            resets: true
> +
> +            reset-names:
> +              items:
> +                - const: vi
> +    else:
> +      patternProperties:
> +        "^vi@[0-9a-f]+$":
> +          description: video input
> +          type: object
> +          properties:
> +            compatible:
> +              oneOf:
> +                - const: nvidia,tegra210-vi
> +                - const: nvidia,tegra186-vi
> +                - const: nvidia,tegra194-vi
> +
> +            reg:
> +              maxItems: 1
> +
> +            interrupts:
> +              maxItems: 1
> +
> +            clocks:
> +              maxItems: 1
> +
> +            power-domains: true
> +
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            oneOf:
> +              - const: nvidia,tegra210-host1x
> +    then:
> +      patternProperties:
> +        "^vi@[0-9a-f]+$":

type: object

> +          patternProperties:
> +            "^csi@[0-9a-f]+$":
> +              description: camera sensor interface
> +              type: object
> +              properties:
> +                compatible:
> +                  enum:
> +                    - nvidia,tegra210-csi
> +
> +                reg: true
> +
> +                clocks: true
> +
> +                clock-names:
> +                  items:
> +                    - const: csi
> +                    - const: cilab
> +                    - const: cilcd
> +                    - const: cile
> +                    - const: csi_tpg
> +
> +                power-domains: true
> +
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - nvidia,tegra20-host1x
> +              - nvidia,tegra30-host1x
> +              - nvidia,tegra114-host1x
> +    then:
> +      patternProperties:
> +        "^epp@[0-9a-f]+$":
> +          description: encoder pre-processor
> +          type: object
> +          properties:
> +            compatible:
> +              enum:
> +                - nvidia,tegra20-epp
> +                - nvidia,tegra30-epp
> +                - nvidia,tegra114-epp
> +
> +            reg:
> +              maxItems: 1
> +
> +            interrupts:
> +              maxItems: 1
> +
> +            clocks:
> +              maxItems: 1
> +
> +            resets:
> +              items:
> +                - description: module reset
> +
> +            reset-names:
> +              items:
> +                - const: epp
> +
> +            iommus:
> +              $ref: "/schemas/iommu/iommu.yaml#/properties/iommus"
> +
> +          unevaluatedProperties: false

I think 'additionalProperties: false' will work here.

> +
> +        "^mpe@[0-9a-f]+$":
> +          description: video encoder
> +          type: object
> +          properties:
> +            compatible:
> +              enum:
> +                - nvidia,tegra20-mpe
> +                - nvidia,tegra30-mpe
> +                - nvidia,tegra114-mpe
> +
> +            reg:
> +              minItems: 1
> +              maxItems: 1
> +
> +            interrupts:
> +              minItems: 1
> +              maxItems: 1
> +
> +            clocks:
> +              minItems: 1
> +              maxItems: 1
> +
> +            resets:
> +              minItems: 1
> +              maxItems: 1
> +
> +            reset-names:
> +              items:
> +                - const: mpe
> +
> +            iommus:
> +              $ref: "/schemas/iommu/iommu.yaml#/properties/iommus"
> +
> +          unevaluatedProperties: false
> +
> +        "^gr2d@[0-9a-f]+$":
> +          description: 2D graphics engine
> +          type: object
> +          properties:
> +            compatible:
> +              enum:
> +                - nvidia,tegra20-gr2d
> +                - nvidia,tegra30-gr2d
> +                - nvidia,tegra114-gr2d
> +
> +            reg:
> +              maxItems: 1
> +
> +            interrupts:
> +              maxItems: 1
> +
> +            clocks:
> +              maxItems: 1
> +
> +            resets:
> +              items:
> +                - description: module reset
> +
> +            reset-names:
> +              items:
> +                - const: 2d
> +
> +            iommus:
> +              $ref: "/schemas/iommu/iommu.yaml#/properties/iommus"
> +
> +          unevaluatedProperties: false
> +
> +        "^gr3d@[0-9a-f]+$":
> +          description: 3D graphics engine
> +          type: object
> +          properties:
> +            compatible:
> +              enum:
> +                - nvidia,tegra20-gr3d
> +                - nvidia,tegra30-gr3d
> +                - nvidia,tegra114-gr3d
> +
> +            reg:
> +              maxItems: 1
> +
> +            iommus:
> +              $ref: "/schemas/iommu/iommu.yaml#/properties/iommus"
> +
> +          allOf:
> +            - if:
> +                properties:
> +                  compatible:
> +                    contains:
> +                      const: nvidia,tegra30-gr3d
> +              then:
> +                properties:
> +                  clocks:
> +                    items:
> +                      - description: primary module clock
> +                      - description: secondary module clock
> +
> +                  clock-names:
> +                    items:
> +                      - const: 3d
> +                      - const: 3d2
> +
> +                  resets:
> +                    items:
> +                      - description: primary module reset
> +                      - description: secondary module reset
> +
> +                  reset-names:
> +                    items:
> +                      - const: 3d
> +                      - const: 3d2
> +              else:
> +                properties:
> +                  clocks:
> +                    items:
> +                      - description: module clock
> +
> +                  clock-names:
> +                    items:
> +                      - const: 3d
> +
> +                  resets:
> +                    items:
> +                      - description: module reset
> +
> +                  reset-names:
> +                    items:
> +                      - const: 3d
> +
> +          unevaluatedProperties: false
> +
> +        "^tvo@[0-9a-f]+$":
> +          description: TV encoder output
> +          type: object
> +          properties:
> +            # required
> +            compatible:
> +              enum:
> +                - nvidia,tegra20-tvo
> +                - nvidia,tegra30-tvo
> +                - nvidia,tegra114-tvo
> +
> +            reg:
> +              maxItems: 1
> +
> +            interrupts:
> +              maxItems: 1
> +
> +            clocks:
> +              maxItems: 1
> +
> +            status:
> +              $ref: "/schemas/dt-core.yaml#/properties/status"
> +
> +          unevaluatedProperties: false
> +
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - nvidia,tegra20-host1x
> +              - nvidia,tegra30-host1x
> +              - nvidia,tegra114-host1x
> +              - nvidia,tegra124-host1x
> +              - nvidia,tegra132-host1x
> +              - nvidia,tegra210-host1x
> +    then:
> +      patternProperties:
> +        "^dc@[0-9a-f]+$":
> +          description: display controller
> +          type: object
> +          properties:
> +            compatible:
> +              oneOf:
> +                - const: nvidia,tegra20-dc
> +                - const: nvidia,tegra30-dc
> +                - const: nvidia,tegra114-dc
> +                - const: nvidia,tegra124-dc
> +                - items:
> +                    - const: nvidia,tegra124-dc
> +                    - const: nvidia,tegra132-dc
> +                - const: nvidia,tegra210-dc
> +
> +            reg:
> +              maxItems: 1
> +
> +            interrupts:
> +              maxItems: 1
> +
> +            clocks:
> +              items:
> +                - description: display controller pixel clock
> +
> +            clock-names:
> +              items:
> +                - const: dc
> +
> +            resets:
> +              items:
> +                - description: module reset
> +
> +            reset-names:
> +              items:
> +                - const: dc
> +
> +            iommus:
> +              $ref: "/schemas/types.yaml#/definitions/phandle-array"
> +
> +            nvidia,head:
> +              description: The number of the display controller head. This is
> +                used to setup the various types of output to receive video
> +                data from the given head.
> +              $ref: "/schemas/types.yaml#/definitions/uint32"
> +
> +          allOf:
> +            - if:
> +                properties:
> +                  compatible:
> +                    contains:
> +                      enum:
> +                        - nvidia,tegra20-dc
> +                        - nvidia,tegra30-dc
> +                        - nvidia,tegra114-dc
> +              then:
> +                properties:
> +                  rgb:
> +                    description: Each display controller node has a child node,
> +                      named "rgb", that represents the RGB output associated
> +                      with the controller.
> +                    type: object
> +                    properties:
> +                      nvidia,ddc-i2c-bus:
> +                        description: phandle of an I2C controller used for DDC
> +                          EDID probing
> +                        $ref: "/schemas/types.yaml#/definitions/phandle"
> +
> +                      nvidia,hpd-gpio:
> +                        description: specifies a GPIO used for hotplug
> +                          detection
> +                        $ref: "/schemas/types.yaml#/definitions/phandle-array"
> +
> +                      nvidia,edid:
> +                        description: supplies a binary EDID blob
> +                        $ref: "/schemas/types.yaml#/definitions/uint8-array"
> +
> +                      nvidia,panel:
> +                        description: phandle of a display panel
> +                        $ref: "/schemas/types.yaml#/definitions/phandle"
> +
> +          unevaluatedProperties: false
> +
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - nvidia,tegra186-host1x
> +              - nvidia,tegra194-host1x
> +    then:
> +      patternProperties:
> +        "^display-hub@[0-9a-f]+$":
> +          properties:
> +            compatible:
> +              oneOf:
> +                - description: NVIDIA Tegra186
> +                  const: nvidia,tegra186-display
> +
> +                - description: NVIDIA Tegra194
> +                  const: nvidia,tegra194-display
> +
> +            '#address-cells':
> +              const: 1
> +
> +            '#size-cells':
> +              const: 1
> +
> +            reg:
> +              maxItems: 1
> +
> +            interrupts:
> +              maxItems: 1
> +
> +            ranges:
> +              $ref: "/schemas/dt-core.yaml#/properties/ranges"
> +
> +            status:
> +              $ref: "/schemas/dt-core.yaml#/properties/status"
> +
> +            resets:
> +              items:
> +                - description: display hub reset
> +                - description: window group 0 reset
> +                - description: window group 1 reset
> +                - description: window group 2 reset
> +                - description: window group 3 reset
> +                - description: window group 4 reset
> +                - description: window group 5 reset
> +
> +            reset-names:
> +              items:
> +                - const: misc
> +                - const: wgrp0
> +                - const: wgrp1
> +                - const: wgrp2
> +                - const: wgrp3
> +                - const: wgrp4
> +                - const: wgrp5
> +
> +            power-domains:
> +              $ref: "/schemas/types.yaml#/definitions/phandle-array"
> +
> +          patternProperties:
> +            "^display@[0-9a-f]+$":
> +              description: display controller
> +              type: object
> +              properties:
> +                compatible:
> +                  enum:
> +                    - nvidia,tegra186-dc
> +                    - nvidia,tegra194-dc
> +
> +                reg:
> +                  maxItems: 1
> +
> +                interrupts:
> +                  maxItems: 1
> +
> +                clocks:
> +                  items:
> +                    - description: display controller pixel clock
> +
> +                clock-names:
> +                  items:
> +                    - const: dc
> +
> +                resets:
> +                  items:
> +                    - description: display controller reset
> +
> +                reset-names:
> +                  items:
> +                    - const: dc
> +
> +                power-domains:
> +                  description: A list of phandle and specifiers that identify
> +                    the power domains that this display controller is part of.
> +                  $ref: "/schemas/types.yaml#/definitions/phandle-array"
> +
> +                iommus:
> +                  description: a phandle and specifier identifying the SMMU
> +                    master interface of this display controller.
> +                  $ref: "/schemas/types.yaml#/definitions/phandle-array"
> +
> +                memory-controllers:
> +                  $ref: /schemas/types.yaml#/definitions/phandle-array
> +
> +                nvidia,outputs:
> +                  description: A list of phandles of outputs that this display
> +                    controller can drive.
> +                  $ref: "/schemas/types.yaml#/definitions/phandle-array"
> +
> +                nvidia,head:
> +                  description: The number of the display controller head. This
> +                    is used to setup the various types of output to receive
> +                    video data from the given head.
> +                  $ref: "/schemas/types.yaml#/definitions/uint32"
> +
> +              unevaluatedProperties: false
> +
> +          allOf:
> +            - if:
> +                properties:
> +                  compatible:
> +                    contains:
> +                      const: nvidia,tegra186-display
> +              then:
> +                properties:
> +                  clocks:
> +                    items:
> +                      - description: display core clock
> +                      - description: display stream compression clock
> +                      - description: display hub clock
> +
> +                  clock-names:
> +                    items:
> +                      - const: disp
> +                      - const: dsc
> +                      - const: hub
> +              else:
> +                properties:
> +                  clocks:
> +                    items:
> +                      - description: display core clock
> +                      - description: display hub clock
> +
> +                  clock-names:
> +                    items:
> +                      - const: disp
> +                      - const: hub
> +
> +          unevaluatedProperties: false
> +
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - nvidia,tegra20-host1x
> +              - nvidia,tegra30-host1x
> +              - nvidia,tegra114-host1x
> +              - nvidia,tegra124-host1x
> +    then:
> +      patternProperties:
> +        "^hdmi@[0-9a-f]+$":
> +          description: High Definition Multimedia Interface
> +          type: object
> +          properties:
> +            # required
> +            compatible:
> +              oneOf:
> +                - const: nvidia,tegra20-hdmi
> +                - const: nvidia,tegra30-hdmi
> +                - const: nvidia,tegra114-hdmi
> +                - const: nvidia,tegra124-hdmi
> +                - items:
> +                    - const: nvidia,tegra132-hdmi
> +                    - const: nvidia,tegra124-hdmi
> +            reg:
> +              maxItems: 1
> +
> +            interrupts:
> +              maxItems: 1
> +
> +            clocks:
> +              items:
> +                - description: module clock
> +                - description: parent clock
> +
> +            clock-names:
> +              items:
> +                - const: hdmi
> +                - const: parent
> +
> +            resets:
> +              items:
> +                - description: module reset
> +
> +            reset-names:
> +              items:
> +                - const: hdmi
> +
> +            hdmi-supply:
> +              description: supply for the +5V HDMI connector pin
> +
> +            vdd-supply:
> +              description: regulator for supply voltage
> +
> +            pll-supply:
> +              description: regulator for PLL
> +
> +            # optional
> +            nvidia,ddc-i2c-bus:
> +              description: phandle of an I2C controller used for DDC EDID
> +                probing
> +              $ref: "/schemas/types.yaml#/definitions/phandle"
> +
> +            nvidia,hpd-gpio:
> +              description: specifies a GPIO used for hotplug detection
> +              $ref: "/schemas/types.yaml#/definitions/phandle-array"

*-gpio has a type already. Just 'maxItems: 1' needed.

> +
> +            nvidia,edid:
> +              description: supplies a binary EDID blob
> +              $ref: "/schemas/types.yaml#/definitions/uint8-array"
> +
> +            nvidia,panel:
> +              description: phandle of a display panel
> +              $ref: "/schemas/types.yaml#/definitions/phandle"
> +
> +            status:
> +              $ref: "/schemas/dt-core.yaml#/properties/status"
> +
> +            phandle:
> +              $ref: "/schemas/types.yaml#/definitions/uint32"
> +
> +          unevaluatedProperties: false
> +
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - nvidia,tegra124-host1x
> +              - nvidia,tegra210-host1x
> +              - nvidia,tegra186-host1x
> +              - nvidia,tegra194-host1x
> +    then:
> +      patternProperties:
> +        "^sor@[0-9a-f]+$":
> +          description: |
> +            The Serial Output Resource (SOR) can be used to drive HDMI, LVDS,
> +            eDP and DP outputs.
> +
> +            See ../pinctrl/nvidia,tegra124-dpaux-padctl.txt for information
> +            regarding the DPAUX pad controller bindings.
> +          type: object
> +          properties:
> +            # required
> +            compatible:
> +              oneOf:
> +                - const: nvidia,tegra124-sor
> +                - items:
> +                    - const: nvidia,tegra132-sor
> +                    - const: nvidia,tegra124-sor
> +                - const: nvidia,tegra210-sor
> +                - const: nvidia,tegra210-sor1
> +                - const: nvidia,tegra186-sor
> +                - const: nvidia,tegra186-sor1
> +                - const: nvidia,tegra194-sor
> +
> +            reg:
> +              maxItems: 1
> +
> +            interrupts:
> +              maxItems: 1
> +
> +            resets:
> +              items:
> +                - description: module reset
> +
> +            reset-names:
> +              items:
> +                - const: sor
> +
> +            status:
> +              $ref: "/schemas/dt-core.yaml#/properties/status"

'status' should never need to be listed.

> +
> +            power-domains:
> +              $ref: "/schemas/types.yaml#/definitions/phandle-array"
> +
> +            avdd-io-hdmi-dp-supply:
> +              description: I/O supply for HDMI/DP
> +
> +            vdd-hdmi-dp-pll-supply:
> +              description: PLL supply for HDMI/DP
> +
> +            hdmi-supply:
> +              description: +5.0V HDMI connector supply
> +
> +            # Tegra186 and later
> +            nvidia,interface:
> +              description: index of the SOR interface
> +              $ref: "/schemas/types.yaml#/definitions/uint32"
> +
> +            # optional
> +            nvidia,ddc-i2c-bus:
> +              description: phandle of an I2C controller used for DDC EDID
> +                probing
> +              $ref: "/schemas/types.yaml#/definitions/phandle"
> +
> +            nvidia,hpd-gpio:
> +              description: specifies a GPIO used for hotplug detection
> +              $ref: "/schemas/types.yaml#/definitions/phandle-array"
> +
> +            nvidia,edid:
> +              description: supplies a binary EDID blob
> +              $ref: "/schemas/types.yaml#/definitions/uint8-array"
> +
> +            nvidia,panel:
> +              description: phandle of a display panel
> +              $ref: "/schemas/types.yaml#/definitions/phandle"
> +
> +            nvidia,xbar-cfg:
> +              description: 5 cells containing the crossbar configuration.
> +                Each lane of the SOR, identified by the cell's index, is
> +                mapped via the crossbar to the pad specified by the cell's
> +                value.
> +              $ref: "/schemas/types.yaml#/definitions/uint32-array"
> +
> +            # optional when driving an eDP output
> +            nvidia,dpaux:
> +              description: phandle to a DispayPort AUX interface
> +              $ref: "/schemas/types.yaml#/definitions/phandle"
> +
> +            pinctrl-names: true
> +            phandle:
> +              $ref: "/schemas/types.yaml#/definitions/uint32"

'phandle' shouldn't need to be listed.

> +
> +          patternProperties:
> +            "^pinctrl-[0-9]+$": true

pinctrl properties are automatically added, but maybe not if under an 
'if' schema. Really, I think probably either this should be split 
into multiple schema files or all of these child nodes should be 
described at the top-level. I'm not sure it's really important to define 
which set of child nodes belong or not for each chip.

I'm stopping there. I think the rest is more of the same comments.

Rob

^ permalink raw reply

* Re: [PATCH 06/38] dt-bindings: display: tegra: Document display-hub
From: Rob Herring @ 2020-06-17 22:55 UTC (permalink / raw)
  To: Thierry Reding
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20200612141903.2391044-7-thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

On Fri, Jun 12, 2020 at 04:18:31PM +0200, Thierry Reding wrote:
> From: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> 
> Tegra186 and later have an additional component in the display pipeline
> called the display hub. Document the bindings which were missing.

I'd rather this be after the conversion or I'm reviewing it twice.

> 
> Signed-off-by: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> ---
>  .../display/tegra/nvidia,tegra20-host1x.txt   | 50 +++++++++++++++++++
>  1 file changed, 50 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
> index 47319214b5f6..2cf3cc4893da 100644
> --- a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
> +++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
> @@ -297,6 +297,56 @@ of the following host1x client modules:
>    - reset-names: Must include the following entries:
>      - vic
>  
> +- display-hub: display controller hub
> +  Required properties:
> +  - compatible: "nvidia,tegra<chip>-display"
> +  - reg: Physical base address and length of the controller's registers.
> +  - interrupts: The interrupt outputs from the controller.
> +  - clocks: Must contain an entry for each entry in clock-names.
> +    See ../clocks/clock-bindings.txt for details.
> +  - clock-names: Must include the following entries:
> +    - disp
> +    - dsc
> +    - hub
> +  - resets: Must contain an entry for each entry in reset-names.
> +    See ../reset/reset.txt for details.
> +  - reset-names: Must include the following entries:
> +    - misc
> +    - wgrp0
> +    - wgrp1
> +    - wgrp2
> +    - wgrp3
> +    - wgrp4
> +    - wgrp5
> +  - power-domains: A list of phandle and specifiers identifying the power
> +    domains that the display hub is part of.
> +  - ranges: Range of registers used for the display controllers.
> +
> +  Each subnode of the display hub represents one of the display controllers
> +  available:
> +
> +  - display: display controller
> +    - compatible: "nvidia,tegra<chip>-dc"
> +    - reg: Physical base address and length of the controller's registers.
> +    - interrupts: The interrupt outputs from the controller.
> +    - clocks: Must contain an entry for each entry in clock-names.
> +      See ../clocks/clock-bindings.txt for details.
> +    - clock-names: Must include the following entries:
> +      - dc
> +    - resets: Must contain an entry for each entry in reset-names.
> +      See ../reset/reset.txt for details.
> +    - reset-names: Must include the following entries:
> +      - dc
> +    - power-domains: A list of phandle and specifiers that identify the power
> +      domains that this display controller is part of.
> +    - iommus: A phandle and specifier identifying the SMMU master interface of
> +      this display controller.
> +    - nvidia,outputs: A list of phandles of outputs that this display
> +      controller can drive.

Seems like an OF graph should describe this?

> +    - nvidia,head: The number of the display controller head. This is used to
> +      setup the various types of output to receive video data from the given
> +      head.

Not really clear what this is...

> +
>  Example:
>  
>  / {
> -- 
> 2.24.1
> 

^ permalink raw reply

* Re: [PATCH 05/38] dt-bindings: firmware: tegra186-bpmp: Document interconnect paths
From: Rob Herring @ 2020-06-17 22:50 UTC (permalink / raw)
  To: Thierry Reding
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20200612141903.2391044-6-thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

On Fri, Jun 12, 2020 at 04:18:30PM +0200, Thierry Reding wrote:
> From: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> 
> Document the interconnects property that is used to describe the paths
> from and to system memory from and to the BPMP.
> 
> Signed-off-by: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> ---
>  .../firmware/nvidia,tegra186-bpmp.yaml        | 21 +++++++++++++++++++
>  1 file changed, 21 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.yaml b/Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.yaml
> index 0e4d51ba7aa1..fd642eeb8dde 100644
> --- a/Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.yaml
> +++ b/Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.yaml
> @@ -43,6 +43,21 @@ properties:
>        - enum:
>            - nvidia,tegra186-bpmp
>  
> +  interconnects:
> +    description: A list of phandle and specifier pairs that describe the
> +      interconnect paths to and from the BPMP.
> +    $ref: "/schemas/types.yaml#/definitions/phandle-array"

Again, don't re-define standard properties.

> +
> +  interconnect-names:
> +    description: One string for each pair of phandle and specifier in the
> +      "interconnects" property.
> +    $ref: "/schemas/types.yaml#/definitions/string-array"
> +    items:
> +      - const: read
> +      - const: write
> +      - const: dma-mem # dma-read
> +      - const: dma-write
> +
>    iommus:
>      description: |
>        The phandle of the IOMMU and the IOMMU specifier. See ../iommu/iommu.txt
> @@ -158,6 +173,12 @@ examples:
>  
>      bpmp {
>          compatible = "nvidia,tegra186-bpmp";
> +        interconnects = <&mc TEGRA186_MEMORY_CLIENT_BPMPR &emc>,
> +                        <&mc TEGRA186_MEMORY_CLIENT_BPMPW &emc>,
> +                        <&mc TEGRA186_MEMORY_CLIENT_BPMPDMAR &emc>,
> +                        <&mc TEGRA186_MEMORY_CLIENT_BPMPDMAW &emc>;
> +        interconnect-names = "read", "write", "dma-mem", "dma-write";
> +
>          iommus = <&smmu TEGRA186_SID_BPMP>;
>          mboxes = <&hsp_top0 TEGRA_HSP_MBOX_TYPE_DB TEGRA_HSP_DB_MASTER_BPMP>;
>          shmem = <&cpu_bpmp_tx &cpu_bpmp_rx>;
> -- 
> 2.24.1
> 

^ permalink raw reply

* Re: [PATCH 04/38] dt-bindings: firmware: Convert Tegra186 BPMP bindings to json-schema
From: Rob Herring @ 2020-06-17 22:49 UTC (permalink / raw)
  To: Thierry Reding
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20200612141903.2391044-5-thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

On Fri, Jun 12, 2020 at 04:18:29PM +0200, Thierry Reding wrote:
> From: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> 
> Convert the Tegra186 BPMP bindings from the free-form text format to a
> json-schema and fix things up so that existing device trees properly
> validate.
> 
> Signed-off-by: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> ---
>  .../firmware/nvidia,tegra186-bpmp.txt         | 107 -----------
>  .../firmware/nvidia,tegra186-bpmp.yaml        | 180 ++++++++++++++++++
>  2 files changed, 180 insertions(+), 107 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt
>  create mode 100644 Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.yaml

[...]

> diff --git a/Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.yaml b/Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.yaml
> new file mode 100644
> index 000000000000..0e4d51ba7aa1
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.yaml
> @@ -0,0 +1,180 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/firmware/nvidia,tegra186-bpmp.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: NVIDIA Tegra186 (and later) Boot and Power Management Processor (BPMP)
> +
> +maintainers:
> +  - Thierry Reding <thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> +  - Jon Hunter <jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> +
> +description: |
> +  The BPMP is a specific processor in Tegra chip, which is designed for
> +  booting process handling and offloading the power management, clock
> +  management, and reset control tasks from the CPU. The binding document
> +  defines the resources that would be used by the BPMP firmware driver,
> +  which can create the interprocessor communication (IPC) between the
> +  CPU and BPMP.
> +
> +  The BPMP implements some services which must be represented by separate
> +  nodes. For example, it can provide access to certain I2C controllers, and
> +  the I2C bindings represent each I2C controller as a device tree node. Such
> +  nodes should be nested directly inside the main BPMP node.
> +
> +  Software can determine whether a child node of the BPMP node represents a
> +  device by checking for a compatible property. Any node with a compatible
> +  property represents a device that can be instantiated. Nodes without a
> +  compatible property may be used to provide configuration information
> +  regarding the BPMP itself, although no such configuration nodes are
> +  currently defined by this binding.
> +
> +  The BPMP firmware defines no single global name-/numbering-space for such
> +  services. Put another way, the numbering scheme for I2C buses is distinct
> +  from the numbering scheme for any other service the BPMP may provide (e.g.
> +  a future hypothetical SPI bus service). As such, child device nodes will
> +  have no "reg" property, and the BPMP node will have no "#address-cells" or
> +  "#size-cells" property.
> +
> +properties:
> +  compatible:
> +    items:
> +      - enum:
> +          - nvidia,tegra186-bpmp
> +
> +  iommus:
> +    description: |
> +      The phandle of the IOMMU and the IOMMU specifier. See ../iommu/iommu.txt
> +      for details.
> +    $ref: "/schemas/types.yaml#/definitions/phandle-array"

Standard property, don't need a type. Just 'maxItems: 1' if 1 entry or 
an 'items' list if more than 1.

> +
> +  mboxes:
> +    description: |
> +      The phandle of the mailbox controller and the mailbox specifier. See
> +      ../mailbox/mailbox.txt and ../mailbox/nvidia,tegra186-hsp.txt for
> +      details.
> +    $ref: "/schemas/types.yaml#/definitions/phandle-array"

Same here.

> +
> +  shmem:
> +    description: |
> +      List of phandles for the TX and RX shared memory areas used for
> +      interprocess communication between the CPU and the BPMP.
> +
> +      The shared memory area for the IPC TX and RX between CPU and BPMP are
> +      predefined and work on top of sysram, which is an SRAM inside the chip.
> +
> +      See ../sram/sram.yaml for the bindings.
> +    $ref: "/schemas/types.yaml#/definitions/phandle-array"
> +
> +  "#clock-cells":
> +    const: 1
> +
> +  "#power-domain-cells":
> +    const: 1
> +
> +  "#reset-cells":
> +    const: 1
> +
> +  i2c:
> +    type: object
> +    description: |
> +      The BPMP can provide serialized access to I2C controllers that have
> +      been assigned to it.

Should have a $ref to i2c-controller.yaml

> +
> +    properties:
> +      compatible:
> +        items:
> +          - enum:
> +              - nvidia,tegra186-bpmp-i2c
> +
> +      "#address-cells":
> +        const: 1
> +
> +      "#size-cells":
> +        const: 0
> +
> +      nvidia,bpmp-bus-id:
> +        description: The bus ID of the I2C controller.
> +        $ref: "/schemas/types.yaml#/definitions/uint32"
> +
> +    required:
> +      - compatible
> +      - "#address-cells"
> +      - "#size-cells"
> +      - nvidia,bpmp-bus-id
> +
> +    patternProperties:
> +      "^.*@[0-9a-f]+$":
> +        type: object
> +        description: I2C slave
> +        properties:
> +          reg:
> +            maxItems: 1
> +            description: I2C address of the slave
> +
> +        required:
> +          - reg

And child node schema can be dropped.

> +
> +    additionalProperties: false
> +
> +  thermal:
> +    type: object
> +    description:
> +      The BPMP provides functionality that exposes system temperature sensors
> +      and which can be used to trigger a system shutdown if the temperature
> +      for a given zone exceeds the specified thresholds.
> +
> +    properties:
> +      compatible:
> +        items:
> +          - enum:
> +              - nvidia,tegra186-bpmp-thermal
> +
> +      "#thermal-sensor-cells":
> +        description: The ID of the thermal zone.
> +        const: 1
> +
> +    required:
> +      - compatible
> +      - "#thermal-sensor-cells"
> +
> +    additionalProperties: false
> +
> +required:
> +  - compatible
> +  - mboxes
> +  - shmem
> +  - "#clock-cells"
> +  - "#power-domain-cells"
> +  - "#reset-cells"
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/mailbox/tegra186-hsp.h>
> +    #include <dt-bindings/memory/tegra186-mc.h>
> +
> +    bpmp {
> +        compatible = "nvidia,tegra186-bpmp";
> +        iommus = <&smmu TEGRA186_SID_BPMP>;
> +        mboxes = <&hsp_top0 TEGRA_HSP_MBOX_TYPE_DB TEGRA_HSP_DB_MASTER_BPMP>;
> +        shmem = <&cpu_bpmp_tx &cpu_bpmp_rx>;
> +        #clock-cells = <1>;
> +        #power-domain-cells = <1>;
> +        #reset-cells = <1>;
> +
> +        i2c {
> +            compatible = "nvidia,tegra186-bpmp-i2c";
> +            nvidia,bpmp-bus-id = <5>;
> +            #address-cells = <1>;
> +            #size-cells = <0>;
> +            status = "disabled";

Don't show status in examples.

> +        };
> +
> +        thermal {
> +            compatible = "nvidia,tegra186-bpmp-thermal";
> +            #thermal-sensor-cells = <1>;
> +        };
> +    };
> -- 
> 2.24.1
> 

^ permalink raw reply

* [PATCH v8 7/7] drm/panel-simple: Add missing connector type for some panels
From: Dmitry Osipenko @ 2020-06-17 22:27 UTC (permalink / raw)
  To: Thierry Reding, Sam Ravnborg, Laurent Pinchart, Rob Herring,
	Frank Rowand
  Cc: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20200617222703.17080-1-digetx-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

The DRM panel bridge core requires connector type to be set up properly,
otherwise it rejects the panel. The missing connector type problem popped
up while I was trying to wrap CLAA070WP03XG panel into a DRM bridge in
order to test whether panel's rotation property work properly using
panel-simple driver on NVIDIA Tegra30 Nexus 7 tablet device, which uses
CLAA070WP03XG display panel.

The NVIDIA Tegra DRM driver recently gained DRM bridges support for the
RGB output and now driver wraps directly-connected panels into DRM bridge.
Hence all panels should have connector type set properly now, otherwise
the panel's wrapping fails.

This patch adds missing connector types for the LVDS panels that are found
on NVIDIA Tegra devices:

  1. AUO B101AW03
  2. Chunghwa CLAA070WP03XG
  3. Chunghwa CLAA101WA01A
  4. Chunghwa CLAA101WB01
  5. EDT ET057090DHU
  6. Innolux N156BGE L21
  7. Samsung LTN101NT05

Signed-off-by: Dmitry Osipenko <digetx-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/gpu/drm/panel/panel-simple.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index 6764ac630e22..9eb2dbb7bfa6 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -687,6 +687,7 @@ static const struct panel_desc auo_b101aw03 = {
 		.width = 223,
 		.height = 125,
 	},
+	.connector_type = DRM_MODE_CONNECTOR_LVDS,
 };
 
 static const struct display_timing auo_b101ean01_timing = {
@@ -1340,6 +1341,7 @@ static const struct panel_desc chunghwa_claa070wp03xg = {
 		.width = 94,
 		.height = 150,
 	},
+	.connector_type = DRM_MODE_CONNECTOR_LVDS,
 };
 
 static const struct drm_display_mode chunghwa_claa101wa01a_mode = {
@@ -1362,6 +1364,7 @@ static const struct panel_desc chunghwa_claa101wa01a = {
 		.width = 220,
 		.height = 120,
 	},
+	.connector_type = DRM_MODE_CONNECTOR_LVDS,
 };
 
 static const struct drm_display_mode chunghwa_claa101wb01_mode = {
@@ -1384,6 +1387,7 @@ static const struct panel_desc chunghwa_claa101wb01 = {
 		.width = 223,
 		.height = 125,
 	},
+	.connector_type = DRM_MODE_CONNECTOR_LVDS,
 };
 
 static const struct drm_display_mode dataimage_scf0700c48ggu18_mode = {
@@ -1573,6 +1577,7 @@ static const struct panel_desc edt_et057090dhu = {
 	},
 	.bus_format = MEDIA_BUS_FMT_RGB666_1X18,
 	.bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE,
+	.connector_type = DRM_MODE_CONNECTOR_LVDS,
 };
 
 static const struct drm_display_mode edt_etm0700g0dh6_mode = {
@@ -2055,6 +2060,7 @@ static const struct panel_desc innolux_n156bge_l21 = {
 		.width = 344,
 		.height = 193,
 	},
+	.connector_type = DRM_MODE_CONNECTOR_LVDS,
 };
 
 static const struct drm_display_mode innolux_p120zdg_bf1_mode = {
@@ -3001,6 +3007,7 @@ static const struct panel_desc samsung_ltn101nt05 = {
 		.width = 223,
 		.height = 125,
 	},
+	.connector_type = DRM_MODE_CONNECTOR_LVDS,
 };
 
 static const struct drm_display_mode samsung_ltn140at29_301_mode = {
-- 
2.26.0

^ permalink raw reply related

* [PATCH v8 6/7] drm/tegra: output: rgb: Wrap directly-connected panel into DRM bridge
From: Dmitry Osipenko @ 2020-06-17 22:27 UTC (permalink / raw)
  To: Thierry Reding, Sam Ravnborg, Laurent Pinchart, Rob Herring,
	Frank Rowand
  Cc: dri-devel, linux-tegra, devicetree, linux-kernel
In-Reply-To: <20200617222703.17080-1-digetx@gmail.com>

Currently Tegra DRM driver manually manages display panel, but this
management could be moved out into DRM core if we'll wrap panel into
DRM bridge. This patch wraps RGB panel into a DRM bridge and removes
manual handling of the panel from the RGB output code.

Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Sam Ravnborg <sam@ravnborg.org>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/gpu/drm/tegra/rgb.c | 70 ++++++++++---------------------------
 1 file changed, 18 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/tegra/rgb.c b/drivers/gpu/drm/tegra/rgb.c
index 9a7024ec96bc..4142a56ca764 100644
--- a/drivers/gpu/drm/tegra/rgb.c
+++ b/drivers/gpu/drm/tegra/rgb.c
@@ -8,7 +8,6 @@
 
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_bridge_connector.h>
-#include <drm/drm_panel.h>
 #include <drm/drm_simple_kms_helper.h>
 
 #include "drm.h"
@@ -86,45 +85,13 @@ static void tegra_dc_write_regs(struct tegra_dc *dc,
 		tegra_dc_writel(dc, table[i].value, table[i].offset);
 }
 
-static const struct drm_connector_funcs tegra_rgb_connector_funcs = {
-	.reset = drm_atomic_helper_connector_reset,
-	.detect = tegra_output_connector_detect,
-	.fill_modes = drm_helper_probe_single_connector_modes,
-	.destroy = tegra_output_connector_destroy,
-	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
-	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
-};
-
-static enum drm_mode_status
-tegra_rgb_connector_mode_valid(struct drm_connector *connector,
-			       struct drm_display_mode *mode)
-{
-	/*
-	 * FIXME: For now, always assume that the mode is okay. There are
-	 * unresolved issues with clk_round_rate(), which doesn't always
-	 * reliably report whether a frequency can be set or not.
-	 */
-	return MODE_OK;
-}
-
-static const struct drm_connector_helper_funcs tegra_rgb_connector_helper_funcs = {
-	.get_modes = tegra_output_connector_get_modes,
-	.mode_valid = tegra_rgb_connector_mode_valid,
-};
-
 static void tegra_rgb_encoder_disable(struct drm_encoder *encoder)
 {
 	struct tegra_output *output = encoder_to_output(encoder);
 	struct tegra_rgb *rgb = to_rgb(output);
 
-	if (output->panel)
-		drm_panel_disable(output->panel);
-
 	tegra_dc_write_regs(rgb->dc, rgb_disable, ARRAY_SIZE(rgb_disable));
 	tegra_dc_commit(rgb->dc);
-
-	if (output->panel)
-		drm_panel_unprepare(output->panel);
 }
 
 static void tegra_rgb_encoder_enable(struct drm_encoder *encoder)
@@ -133,9 +100,6 @@ static void tegra_rgb_encoder_enable(struct drm_encoder *encoder)
 	struct tegra_rgb *rgb = to_rgb(output);
 	u32 value;
 
-	if (output->panel)
-		drm_panel_prepare(output->panel);
-
 	tegra_dc_write_regs(rgb->dc, rgb_enable, ARRAY_SIZE(rgb_enable));
 
 	value = DE_SELECT_ACTIVE | DE_CONTROL_NORMAL;
@@ -157,9 +121,6 @@ static void tegra_rgb_encoder_enable(struct drm_encoder *encoder)
 	tegra_dc_writel(rgb->dc, value, DC_DISP_SHIFT_CLOCK_OPTIONS);
 
 	tegra_dc_commit(rgb->dc);
-
-	if (output->panel)
-		drm_panel_enable(output->panel);
 }
 
 static int
@@ -278,6 +239,23 @@ int tegra_dc_rgb_init(struct drm_device *drm, struct tegra_dc *dc)
 	drm_encoder_helper_add(&output->encoder,
 			       &tegra_rgb_encoder_helper_funcs);
 
+	/*
+	 * Wrap directly-connected panel into DRM bridge in order to let
+	 * DRM core to handle panel for us.
+	 */
+	if (output->panel) {
+		output->bridge = devm_drm_panel_bridge_add(output->dev,
+							   output->panel);
+		if (IS_ERR(output->bridge)) {
+			dev_err(output->dev,
+				"failed to wrap panel into bridge: %pe\n",
+				output->bridge);
+			return PTR_ERR(output->bridge);
+		}
+
+		output->panel = NULL;
+	}
+
 	/*
 	 * Tegra devices that have LVDS panel utilize LVDS encoder bridge
 	 * for converting up to 28 LCD LVTTL lanes into 5/4 LVDS lanes that
@@ -292,8 +270,7 @@ int tegra_dc_rgb_init(struct drm_device *drm, struct tegra_dc *dc)
 	 * Newer device-trees utilize LVDS encoder bridge, which provides
 	 * us with a connector and handles the display panel.
 	 *
-	 * For older device-trees we fall back to our own connector and use
-	 * nvidia,panel phandle.
+	 * For older device-trees we wrapped panel into the panel-bridge.
 	 */
 	if (output->bridge) {
 		err = drm_bridge_attach(&output->encoder, output->bridge,
@@ -313,17 +290,6 @@ int tegra_dc_rgb_init(struct drm_device *drm, struct tegra_dc *dc)
 		}
 
 		drm_connector_attach_encoder(connector, &output->encoder);
-	} else {
-		drm_connector_init(drm, &output->connector,
-				   &tegra_rgb_connector_funcs,
-				   DRM_MODE_CONNECTOR_LVDS);
-		drm_connector_helper_add(&output->connector,
-					 &tegra_rgb_connector_helper_funcs);
-		output->connector.dpms = DRM_MODE_DPMS_OFF;
-
-		drm_connector_attach_encoder(&output->connector,
-					     &output->encoder);
-		drm_connector_register(&output->connector);
 	}
 
 	err = tegra_output_init(drm, output);
-- 
2.26.0

^ permalink raw reply related

* [PATCH v8 5/7] drm/tegra: output: rgb: Support LVDS encoder bridge
From: Dmitry Osipenko @ 2020-06-17 22:27 UTC (permalink / raw)
  To: Thierry Reding, Sam Ravnborg, Laurent Pinchart, Rob Herring,
	Frank Rowand
  Cc: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20200617222703.17080-1-digetx-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Newer Tegra device-trees will specify a video output graph, which involves
LVDS encoder bridge. This patch adds support for the LVDS encoder bridge
to the RGB output, allowing us to model the display hardware properly.

Reviewed-by: Laurent Pinchart <laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw@public.gmane.org>
Acked-by: Sam Ravnborg <sam-uyr5N9Q2VtJg9hUCZPvPmw@public.gmane.org>
Signed-off-by: Dmitry Osipenko <digetx-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/gpu/drm/tegra/rgb.c | 58 +++++++++++++++++++++++++++++++------
 1 file changed, 49 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/tegra/rgb.c b/drivers/gpu/drm/tegra/rgb.c
index 0562a7eb793f..9a7024ec96bc 100644
--- a/drivers/gpu/drm/tegra/rgb.c
+++ b/drivers/gpu/drm/tegra/rgb.c
@@ -7,6 +7,7 @@
 #include <linux/clk.h>
 
 #include <drm/drm_atomic_helper.h>
+#include <drm/drm_bridge_connector.h>
 #include <drm/drm_panel.h>
 #include <drm/drm_simple_kms_helper.h>
 
@@ -267,24 +268,63 @@ int tegra_dc_rgb_remove(struct tegra_dc *dc)
 int tegra_dc_rgb_init(struct drm_device *drm, struct tegra_dc *dc)
 {
 	struct tegra_output *output = dc->rgb;
+	struct drm_connector *connector;
 	int err;
 
 	if (!dc->rgb)
 		return -ENODEV;
 
-	drm_connector_init(drm, &output->connector, &tegra_rgb_connector_funcs,
-			   DRM_MODE_CONNECTOR_LVDS);
-	drm_connector_helper_add(&output->connector,
-				 &tegra_rgb_connector_helper_funcs);
-	output->connector.dpms = DRM_MODE_DPMS_OFF;
-
 	drm_simple_encoder_init(drm, &output->encoder, DRM_MODE_ENCODER_LVDS);
 	drm_encoder_helper_add(&output->encoder,
 			       &tegra_rgb_encoder_helper_funcs);
 
-	drm_connector_attach_encoder(&output->connector,
-					  &output->encoder);
-	drm_connector_register(&output->connector);
+	/*
+	 * Tegra devices that have LVDS panel utilize LVDS encoder bridge
+	 * for converting up to 28 LCD LVTTL lanes into 5/4 LVDS lanes that
+	 * go to display panel's receiver.
+	 *
+	 * Encoder usually have a power-down control which needs to be enabled
+	 * in order to transmit data to the panel.  Historically devices that
+	 * use an older device-tree version didn't model the bridge, assuming
+	 * that encoder is turned ON by default, while today's DRM allows us
+	 * to model LVDS encoder properly.
+	 *
+	 * Newer device-trees utilize LVDS encoder bridge, which provides
+	 * us with a connector and handles the display panel.
+	 *
+	 * For older device-trees we fall back to our own connector and use
+	 * nvidia,panel phandle.
+	 */
+	if (output->bridge) {
+		err = drm_bridge_attach(&output->encoder, output->bridge,
+					NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+		if (err) {
+			dev_err(output->dev, "failed to attach bridge: %d\n",
+				err);
+			return err;
+		}
+
+		connector = drm_bridge_connector_init(drm, &output->encoder);
+		if (IS_ERR(connector)) {
+			dev_err(output->dev,
+				"failed to initialize bridge connector: %pe\n",
+				connector);
+			return PTR_ERR(connector);
+		}
+
+		drm_connector_attach_encoder(connector, &output->encoder);
+	} else {
+		drm_connector_init(drm, &output->connector,
+				   &tegra_rgb_connector_funcs,
+				   DRM_MODE_CONNECTOR_LVDS);
+		drm_connector_helper_add(&output->connector,
+					 &tegra_rgb_connector_helper_funcs);
+		output->connector.dpms = DRM_MODE_DPMS_OFF;
+
+		drm_connector_attach_encoder(&output->connector,
+					     &output->encoder);
+		drm_connector_register(&output->connector);
+	}
 
 	err = tegra_output_init(drm, output);
 	if (err < 0) {
-- 
2.26.0

^ permalink raw reply related

* [PATCH v8 4/7] drm/tegra: output: Support DRM bridges
From: Dmitry Osipenko @ 2020-06-17 22:27 UTC (permalink / raw)
  To: Thierry Reding, Sam Ravnborg, Laurent Pinchart, Rob Herring,
	Frank Rowand
  Cc: dri-devel, linux-tegra, devicetree, linux-kernel
In-Reply-To: <20200617222703.17080-1-digetx@gmail.com>

Newer Tegra device-trees will specify a video output graph which involves
a bridge. This patch adds initial support for the DRM bridges to the Tegra
DRM output.

Acked-by: Sam Ravnborg <sam@ravnborg.org>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/gpu/drm/tegra/drm.h    |  2 ++
 drivers/gpu/drm/tegra/output.c | 12 ++++++++++++
 2 files changed, 14 insertions(+)

diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h
index b25443255be6..f38de08e0c95 100644
--- a/drivers/gpu/drm/tegra/drm.h
+++ b/drivers/gpu/drm/tegra/drm.h
@@ -12,6 +12,7 @@
 #include <linux/gpio/consumer.h>
 
 #include <drm/drm_atomic.h>
+#include <drm/drm_bridge.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_encoder.h>
 #include <drm/drm_fb_helper.h>
@@ -116,6 +117,7 @@ struct tegra_output {
 	struct device_node *of_node;
 	struct device *dev;
 
+	struct drm_bridge *bridge;
 	struct drm_panel *panel;
 	struct i2c_adapter *ddc;
 	const struct edid *edid;
diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c
index a6a711d54e88..ccd1421f1b24 100644
--- a/drivers/gpu/drm/tegra/output.c
+++ b/drivers/gpu/drm/tegra/output.c
@@ -5,6 +5,7 @@
  */
 
 #include <drm/drm_atomic_helper.h>
+#include <drm/drm_of.h>
 #include <drm/drm_panel.h>
 #include <drm/drm_simple_kms_helper.h>
 
@@ -99,8 +100,19 @@ int tegra_output_probe(struct tegra_output *output)
 	if (!output->of_node)
 		output->of_node = output->dev->of_node;
 
+	err = drm_of_find_panel_or_bridge(output->of_node, -1, -1,
+					  &output->panel, &output->bridge);
+	if (err && err != -ENODEV)
+		return err;
+
 	panel = of_parse_phandle(output->of_node, "nvidia,panel", 0);
 	if (panel) {
+		/*
+		 * Don't mix nvidia,panel phandle with the graph in a
+		 * device-tree.
+		 */
+		WARN_ON(output->panel || output->bridge);
+
 		output->panel = of_drm_find_panel(panel);
 		of_node_put(panel);
 
-- 
2.26.0

^ permalink raw reply related

* [PATCH v8 3/7] drm/tegra: output: Don't leak OF node on error
From: Dmitry Osipenko @ 2020-06-17 22:26 UTC (permalink / raw)
  To: Thierry Reding, Sam Ravnborg, Laurent Pinchart, Rob Herring,
	Frank Rowand
  Cc: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20200617222703.17080-1-digetx-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

The OF node should be put before returning error in tegra_output_probe(),
otherwise node's refcount will be leaked.

Reviewed-by: Laurent Pinchart <laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw@public.gmane.org>
Reviewed-by: Sam Ravnborg <sam-uyr5N9Q2VtJg9hUCZPvPmw@public.gmane.org>
Signed-off-by: Dmitry Osipenko <digetx-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/gpu/drm/tegra/output.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/tegra/output.c b/drivers/gpu/drm/tegra/output.c
index e36e5e7c2f69..a6a711d54e88 100644
--- a/drivers/gpu/drm/tegra/output.c
+++ b/drivers/gpu/drm/tegra/output.c
@@ -102,10 +102,10 @@ int tegra_output_probe(struct tegra_output *output)
 	panel = of_parse_phandle(output->of_node, "nvidia,panel", 0);
 	if (panel) {
 		output->panel = of_drm_find_panel(panel);
+		of_node_put(panel);
+
 		if (IS_ERR(output->panel))
 			return PTR_ERR(output->panel);
-
-		of_node_put(panel);
 	}
 
 	output->edid = of_get_property(output->of_node, "nvidia,edid", &size);
@@ -113,13 +113,12 @@ int tegra_output_probe(struct tegra_output *output)
 	ddc = of_parse_phandle(output->of_node, "nvidia,ddc-i2c-bus", 0);
 	if (ddc) {
 		output->ddc = of_find_i2c_adapter_by_node(ddc);
+		of_node_put(ddc);
+
 		if (!output->ddc) {
 			err = -EPROBE_DEFER;
-			of_node_put(ddc);
 			return err;
 		}
-
-		of_node_put(ddc);
 	}
 
 	output->hpd_gpio = devm_gpiod_get_from_of_node(output->dev,
-- 
2.26.0

^ permalink raw reply related

* [PATCH v8 2/7] drm/of: Make drm_of_find_panel_or_bridge() to check graph's presence
From: Dmitry Osipenko @ 2020-06-17 22:26 UTC (permalink / raw)
  To: Thierry Reding, Sam Ravnborg, Laurent Pinchart, Rob Herring,
	Frank Rowand
  Cc: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20200617222703.17080-1-digetx-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

When graph isn't defined in a device-tree, the of_graph_get_remote_node()
prints a noisy error message, telling that port node is not found. This is
undesirable behaviour in our case because absence of a panel/bridge graph
is a valid case. Let's check the graph's presence in a device-tree before
proceeding with parsing of the graph.

Reviewed-by: Sam Ravnborg <sam-uyr5N9Q2VtJg9hUCZPvPmw@public.gmane.org>
Signed-off-by: Dmitry Osipenko <digetx-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/gpu/drm/drm_of.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
index b50b44e76279..cbe65efdae39 100644
--- a/drivers/gpu/drm/drm_of.c
+++ b/drivers/gpu/drm/drm_of.c
@@ -246,6 +246,15 @@ int drm_of_find_panel_or_bridge(const struct device_node *np,
 	if (panel)
 		*panel = NULL;
 
+	/*
+	 * of_graph_get_remote_node() produces a noisy error message if port
+	 * node isn't found and the absence of the port is a legit case here,
+	 * so at first we silently check whether graph presents in the
+	 * device-tree node.
+	 */
+	if (!of_graph_presents(np))
+		return -ENODEV;
+
 	remote = of_graph_get_remote_node(np, port, endpoint);
 	if (!remote)
 		return -ENODEV;
-- 
2.26.0

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox