All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC 0/4] Add NVIDIA Tegra DRM support
@ 2012-04-11 12:10 Thierry Reding
       [not found] ` <1334146230-1795-1-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
  0 siblings, 1 reply; 65+ messages in thread
From: Thierry Reding @ 2012-04-11 12:10 UTC (permalink / raw)
  To: linux-tegra-u79uwXL29TY76Z2rM5mHXA
  Cc: Stephen Warren, Olof Johansson, Colin Cross, Jon Mayo,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, David Airlie,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Joerg Roedel,
	Hiroshi Doyu, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

This series adds a basic DRM driver for NVIDIA Tegra 2 processors. It
currently only supports the RGB output and I've successfully tested it
against the fbcon kernel module and the xf86-video-modesetting driver.
The code uses the Tegra's IOMMU/GART to remap non-contiguous memory.
This means that currently video memory is limited to 32 MB, the size of
the GART aperture.

Note that this is very early work-in-progress and there is a lot of room
for improvement and cleanup. You'll also note that there is still a
whole lot of debugging output, most of which is disabled by default.

However I explicitly wanted to post this early to get feedback and to
discuss options on how to get this included in the mainline kernel. I
have been in contact with some people at NVIDIA and they seem to be
willing to work together on a solution that satisfies both their
requirements and those of the community.

Thierry

Thierry Reding (3):
  iommu: tegra/gart: Add device tree support
  drm: fixed: Add dfixed_frac() macro
  drm: Add NVIDIA Tegra support

Vandana Salve (1):
  iommu: tegra/gart: use correct gart_device

 .../devicetree/bindings/gpu/drm/tegra.txt          |   24 +
 arch/arm/boot/dts/tegra20.dtsi                     |    6 +
 arch/arm/mach-tegra/board-dt-tegra20.c             |    4 +
 arch/arm/mach-tegra/tegra2_clocks.c                |    8 +-
 drivers/gpu/drm/Kconfig                            |    2 +
 drivers/gpu/drm/Makefile                           |    1 +
 drivers/gpu/drm/tegra/Kconfig                      |   10 +
 drivers/gpu/drm/tegra/Makefile                     |    5 +
 drivers/gpu/drm/tegra/tegra_drv.c                  | 2241 ++++++++++++++++++++
 drivers/gpu/drm/tegra/tegra_drv.h                  |  184 ++
 drivers/iommu/tegra-gart.c                         |   12 +-
 include/drm/drm_fixed.h                            |    1 +
 include/drm/tegra_drm.h                            |   44 +
 13 files changed, 2537 insertions(+), 5 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/gpu/drm/tegra.txt
 create mode 100644 drivers/gpu/drm/tegra/Kconfig
 create mode 100644 drivers/gpu/drm/tegra/Makefile
 create mode 100644 drivers/gpu/drm/tegra/tegra_drv.c
 create mode 100644 drivers/gpu/drm/tegra/tegra_drv.h
 create mode 100644 include/drm/tegra_drm.h

-- 
1.7.10

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [RFC 1/4] iommu: tegra/gart: use correct gart_device
       [not found] ` <1334146230-1795-1-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
@ 2012-04-11 12:10   ` Thierry Reding
  2012-04-11 12:10   ` [RFC 2/4] iommu: tegra/gart: Add device tree support Thierry Reding
                     ` (5 subsequent siblings)
  6 siblings, 0 replies; 65+ messages in thread
From: Thierry Reding @ 2012-04-11 12:10 UTC (permalink / raw)
  To: linux-tegra-u79uwXL29TY76Z2rM5mHXA
  Cc: Vandana Salve, Hiroshi DOYU, Stephen Warren, Olof Johansson,
	Colin Cross, Jon Mayo,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, David Airlie,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Joerg Roedel,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

From: Vandana Salve <vsalve-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>

Pass the correct gart device pointer.

Reviewed-by: Vandana Salve <vsalve-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Tested-by: Vandana Salve <vsalve-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Reviewed-by: Hiroshi Doyu <hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Reviewed-by: Bharat Nihalani <bnihalani-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Hiroshi DOYU <hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
---
 drivers/iommu/tegra-gart.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c
index 779306e..f6bc1e6 100644
--- a/drivers/iommu/tegra-gart.c
+++ b/drivers/iommu/tegra-gart.c
@@ -158,7 +158,7 @@ static int gart_iommu_attach_dev(struct iommu_domain *domain,
 	struct gart_client *client, *c;
 	int err = 0;
 
-	gart = dev_get_drvdata(dev->parent);
+	gart = gart_handle;
 	if (!gart)
 		return -EINVAL;
 	domain->priv = gart;
-- 
1.7.10

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [RFC 2/4] iommu: tegra/gart: Add device tree support
       [not found] ` <1334146230-1795-1-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
  2012-04-11 12:10   ` [RFC 1/4] iommu: tegra/gart: use correct gart_device Thierry Reding
@ 2012-04-11 12:10   ` Thierry Reding
       [not found]     ` <1334146230-1795-3-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
  2012-04-11 12:10   ` [RFC 3/4] drm: fixed: Add dfixed_frac() macro Thierry Reding
                     ` (4 subsequent siblings)
  6 siblings, 1 reply; 65+ messages in thread
From: Thierry Reding @ 2012-04-11 12:10 UTC (permalink / raw)
  To: linux-tegra-u79uwXL29TY76Z2rM5mHXA
  Cc: Stephen Warren, Olof Johansson, Colin Cross, Jon Mayo,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, David Airlie,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Joerg Roedel,
	Hiroshi Doyu, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

This commit adds device tree support for the GART hardware available on
NVIDIA Tegra 20 SoCs.

Signed-off-by: Thierry Reding <thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
---
 arch/arm/boot/dts/tegra20.dtsi         |    6 ++++++
 arch/arm/mach-tegra/board-dt-tegra20.c |    1 +
 drivers/iommu/tegra-gart.c             |   10 ++++++++++
 3 files changed, 17 insertions(+)

diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index 55b28fd..cf3ff41 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -212,5 +212,11 @@
 		interrupts = < 0 97 0x04 >;
 		phy_type = "utmi";
 	};
+
+	gart: gart@7000f000 {
+		compatible = "nvidia,tegra20-gart";
+		reg = < 0x7000f000 0x00000100    /* controller registers */
+		        0x58000000 0x02000000 >; /* GART aperture */
+	};
 };
 
diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/board-dt-tegra20.c
index 57745e6..bffba1b 100644
--- a/arch/arm/mach-tegra/board-dt-tegra20.c
+++ b/arch/arm/mach-tegra/board-dt-tegra20.c
@@ -66,6 +66,7 @@ struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = {
 	OF_DEV_AUXDATA("nvidia,tegra20-ehci", TEGRA_USB3_BASE, "tegra-ehci.2",
 		       &tegra_ehci3_pdata),
 	OF_DEV_AUXDATA("nvidia,tegra20-pwm", TEGRA_PWFM_BASE, "tegra-pwm", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra20-gart", TEGRA_MC_BASE, "tegra-gart", NULL),
 	{}
 };
 
diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c
index f6bc1e6..4a571b7 100644
--- a/drivers/iommu/tegra-gart.c
+++ b/drivers/iommu/tegra-gart.c
@@ -29,6 +29,7 @@
 #include <linux/device.h>
 #include <linux/io.h>
 #include <linux/iommu.h>
+#include <linux/of.h>
 
 #include <asm/cacheflush.h>
 
@@ -422,6 +423,13 @@ const struct dev_pm_ops tegra_gart_pm_ops = {
 	.resume		= tegra_gart_resume,
 };
 
+#ifdef CONFIG_OF
+static struct of_device_id tegra_gart_of_match[] __devinitdata = {
+	{ .compatible = "nvidia,tegra20-gart", },
+	{ },
+};
+#endif
+
 static struct platform_driver tegra_gart_driver = {
 	.probe		= tegra_gart_probe,
 	.remove		= tegra_gart_remove,
@@ -429,6 +437,7 @@ static struct platform_driver tegra_gart_driver = {
 		.owner	= THIS_MODULE,
 		.name	= "tegra-gart",
 		.pm	= &tegra_gart_pm_ops,
+		.of_match_table = of_match_ptr(tegra_gart_of_match),
 	},
 };
 
@@ -448,4 +457,5 @@ module_exit(tegra_gart_exit);
 
 MODULE_DESCRIPTION("IOMMU API for GART in Tegra20");
 MODULE_AUTHOR("Hiroshi DOYU <hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>");
+MODULE_ALIAS("platform:tegra-gart");
 MODULE_LICENSE("GPL v2");
-- 
1.7.10

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [RFC 3/4] drm: fixed: Add dfixed_frac() macro
       [not found] ` <1334146230-1795-1-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
  2012-04-11 12:10   ` [RFC 1/4] iommu: tegra/gart: use correct gart_device Thierry Reding
  2012-04-11 12:10   ` [RFC 2/4] iommu: tegra/gart: Add device tree support Thierry Reding
@ 2012-04-11 12:10   ` Thierry Reding
       [not found]     ` <1334146230-1795-4-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
  2012-04-11 12:10   ` [RFC 4/4] drm: Add NVIDIA Tegra support Thierry Reding
                     ` (3 subsequent siblings)
  6 siblings, 1 reply; 65+ messages in thread
From: Thierry Reding @ 2012-04-11 12:10 UTC (permalink / raw)
  To: linux-tegra-u79uwXL29TY76Z2rM5mHXA
  Cc: Stephen Warren, David Airlie,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Jon Mayo,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	Olof Johansson

This commit is taken from the Chromium tree and was originally written
by Robert Morell.

Signed-off-by: Thierry Reding <thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
---
 include/drm/drm_fixed.h |    1 +
 1 file changed, 1 insertion(+)

diff --git a/include/drm/drm_fixed.h b/include/drm/drm_fixed.h
index 4a08a66..0ead502 100644
--- a/include/drm/drm_fixed.h
+++ b/include/drm/drm_fixed.h
@@ -37,6 +37,7 @@ typedef union dfixed {
 #define dfixed_init(A) { .full = dfixed_const((A)) }
 #define dfixed_init_half(A) { .full = dfixed_const_half((A)) }
 #define dfixed_trunc(A) ((A).full >> 12)
+#define dfixed_frac(A) ((A).full & ((1 << 12) - 1))
 
 static inline u32 dfixed_floor(fixed20_12 A)
 {
-- 
1.7.10

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found] ` <1334146230-1795-1-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
                     ` (2 preceding siblings ...)
  2012-04-11 12:10   ` [RFC 3/4] drm: fixed: Add dfixed_frac() macro Thierry Reding
@ 2012-04-11 12:10   ` Thierry Reding
       [not found]     ` <1334146230-1795-5-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
  2012-04-11 12:25   ` [RFC 0/4] Add NVIDIA Tegra DRM support Alan Cox
                     ` (2 subsequent siblings)
  6 siblings, 1 reply; 65+ messages in thread
From: Thierry Reding @ 2012-04-11 12:10 UTC (permalink / raw)
  To: linux-tegra-u79uwXL29TY76Z2rM5mHXA
  Cc: Stephen Warren, Olof Johansson, Colin Cross, Jon Mayo,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, David Airlie,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Joerg Roedel,
	Hiroshi Doyu, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

This commit adds a very basic DRM driver for NVIDIA Tegra SoCs. It
currently has rudimentary GEM support and can run a console on the
framebuffer as well as X using the xf86-video-modesetting driver.
Only the RGB output is supported. Quite a lot of things still need
to be worked out and there is a lot of room for cleanup.

Signed-off-by: Thierry Reding <thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
---
 .../devicetree/bindings/gpu/drm/tegra.txt          |   24 +
 arch/arm/mach-tegra/board-dt-tegra20.c             |    3 +
 arch/arm/mach-tegra/tegra2_clocks.c                |    8 +-
 drivers/gpu/drm/Kconfig                            |    2 +
 drivers/gpu/drm/Makefile                           |    1 +
 drivers/gpu/drm/tegra/Kconfig                      |   10 +
 drivers/gpu/drm/tegra/Makefile                     |    5 +
 drivers/gpu/drm/tegra/tegra_drv.c                  | 2241 ++++++++++++++++++++
 drivers/gpu/drm/tegra/tegra_drv.h                  |  184 ++
 include/drm/tegra_drm.h                            |   44 +
 10 files changed, 2518 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/gpu/drm/tegra.txt
 create mode 100644 drivers/gpu/drm/tegra/Kconfig
 create mode 100644 drivers/gpu/drm/tegra/Makefile
 create mode 100644 drivers/gpu/drm/tegra/tegra_drv.c
 create mode 100644 drivers/gpu/drm/tegra/tegra_drv.h
 create mode 100644 include/drm/tegra_drm.h

diff --git a/Documentation/devicetree/bindings/gpu/drm/tegra.txt b/Documentation/devicetree/bindings/gpu/drm/tegra.txt
new file mode 100644
index 0000000..d39fe64
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpu/drm/tegra.txt
@@ -0,0 +1,24 @@
+Example:
+
+	drm@54200000 {
+		compatible = "nvidia,tegra20-drm";
+		reg = < 0x54200000 0x00040000    /* display A */
+		        0x54240000 0x00040000    /* display B */
+		        0x58000000 0x02000000 >; /* GART aperture */
+		interrupts = < 0 73 0x04    /* display A */
+		               0 74 0x04 >; /* display B */
+
+		lvds {
+			type = "rgb";
+			size = <345 194>;
+
+			default-mode {
+				pixel-clock = <61715000>;
+				vertical-refresh = <50>;
+				resolution = <1366 768>;
+				bits-per-pixel = <16>;
+				horizontal-timings = <4 136 2 36>;
+				vertical-timings = <2 4 21 10>;
+			};
+		};
+	};
diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/board-dt-tegra20.c
index bffba1b..6ce6162 100644
--- a/arch/arm/mach-tegra/board-dt-tegra20.c
+++ b/arch/arm/mach-tegra/board-dt-tegra20.c
@@ -67,6 +67,7 @@ struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = {
 		       &tegra_ehci3_pdata),
 	OF_DEV_AUXDATA("nvidia,tegra20-pwm", TEGRA_PWFM_BASE, "tegra-pwm", NULL),
 	OF_DEV_AUXDATA("nvidia,tegra20-gart", TEGRA_MC_BASE, "tegra-gart", NULL),
+	OF_DEV_AUXDATA("nvidia,tegra20-drm", TEGRA_DISPLAY_BASE, "tegra-drm", NULL),
 	{}
 };
 
@@ -81,6 +82,8 @@ static __initdata struct tegra_clk_init_table tegra_dt_clk_init_table[] = {
 	{ "cdev1",      NULL,           0,              true },
 	{ "i2s1",       "pll_a_out0",   11289600,       false},
 	{ "i2s2",       "pll_a_out0",   11289600,       false},
+	{ "host1x",     "pll_c",        144000000,      true },
+	{ "disp1",      "pll_p",        600000000,      true },
 	{ NULL,		NULL,		0,		0},
 };
 
diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c
index f29084d..c86eae6 100644
--- a/arch/arm/mach-tegra/tegra2_clocks.c
+++ b/arch/arm/mach-tegra/tegra2_clocks.c
@@ -2219,8 +2219,8 @@ static struct clk tegra_list_clks[] = {
 	PERIPH_CLK("tvo",	"tvo",			NULL,	49,	0x188,	250000000, mux_pllp_plld_pllc_clkm,	MUX | DIV_U71), /* requires min voltage */
 	PERIPH_CLK("hdmi",	"hdmi",			NULL,	51,	0x18c,	600000000, mux_pllp_plld_pllc_clkm,	MUX | DIV_U71), /* requires min voltage */
 	PERIPH_CLK("tvdac",	"tvdac",		NULL,	53,	0x194,	250000000, mux_pllp_plld_pllc_clkm,	MUX | DIV_U71), /* requires min voltage */
-	PERIPH_CLK("disp1",	"tegradc.0",		NULL,	27,	0x138,	600000000, mux_pllp_plld_pllc_clkm,	MUX), /* scales with voltage and process_id */
-	PERIPH_CLK("disp2",	"tegradc.1",		NULL,	26,	0x13c,	600000000, mux_pllp_plld_pllc_clkm,	MUX), /* scales with voltage and process_id */
+	PERIPH_CLK("disp1",	"tegra-drm",		NULL,	27,	0x138,	600000000, mux_pllp_plld_pllc_clkm,	MUX), /* scales with voltage and process_id */
+	PERIPH_CLK("disp2",	"tegra-drm",		NULL,	26,	0x13c,	600000000, mux_pllp_plld_pllc_clkm,	MUX), /* scales with voltage and process_id */
 	PERIPH_CLK("usbd",	"fsl-tegra-udc",	NULL,	22,	0,	480000000, mux_clk_m,			0), /* requires min voltage */
 	PERIPH_CLK("usb2",	"tegra-ehci.1",		NULL,	58,	0,	480000000, mux_clk_m,			0), /* requires min voltage */
 	PERIPH_CLK("usb3",	"tegra-ehci.2",		NULL,	59,	0,	480000000, mux_clk_m,			0), /* requires min voltage */
@@ -2235,8 +2235,8 @@ static struct clk tegra_list_clks[] = {
 	SHARED_CLK("avp.sclk",	"tegra-avp",		"sclk",	&tegra_clk_sclk),
 	SHARED_CLK("avp.emc",	"tegra-avp",		"emc",	&tegra_clk_emc),
 	SHARED_CLK("cpu.emc",	"cpu",			"emc",	&tegra_clk_emc),
-	SHARED_CLK("disp1.emc",	"tegradc.0",		"emc",	&tegra_clk_emc),
-	SHARED_CLK("disp2.emc",	"tegradc.1",		"emc",	&tegra_clk_emc),
+	SHARED_CLK("disp1.emc",	"tegra-drm",		"emc",	&tegra_clk_emc),
+	SHARED_CLK("disp2.emc",	"tegra-drm",		"emc",	&tegra_clk_emc),
 	SHARED_CLK("hdmi.emc",	"hdmi",			"emc",	&tegra_clk_emc),
 	SHARED_CLK("host.emc",	"tegra_grhost",		"emc",	&tegra_clk_emc),
 	SHARED_CLK("usbd.emc",	"fsl-tegra-udc",	"emc",	&tegra_clk_emc),
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index e354bc0..dd543f9 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -186,3 +186,5 @@ source "drivers/gpu/drm/vmwgfx/Kconfig"
 source "drivers/gpu/drm/gma500/Kconfig"
 
 source "drivers/gpu/drm/udl/Kconfig"
+
+source "drivers/gpu/drm/tegra/Kconfig"
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index c20da5b..d417d7e 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -42,4 +42,5 @@ obj-$(CONFIG_DRM_NOUVEAU) +=nouveau/
 obj-$(CONFIG_DRM_EXYNOS) +=exynos/
 obj-$(CONFIG_DRM_GMA500) += gma500/
 obj-$(CONFIG_DRM_UDL) += udl/
+obj-$(CONFIG_DRM_TEGRA) += tegra/
 obj-y			+= i2c/
diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/drm/tegra/Kconfig
new file mode 100644
index 0000000..f3382c9
--- /dev/null
+++ b/drivers/gpu/drm/tegra/Kconfig
@@ -0,0 +1,10 @@
+config DRM_TEGRA
+	tristate "NVIDIA Tegra"
+	depends on DRM && ARCH_TEGRA
+	select DRM_KMS_ENCON
+	select DRM_KMS_HELPER
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  Choose this option if you have an NVIDIA Tegra SoC.
diff --git a/drivers/gpu/drm/tegra/Makefile b/drivers/gpu/drm/tegra/Makefile
new file mode 100644
index 0000000..62c7e56a
--- /dev/null
+++ b/drivers/gpu/drm/tegra/Makefile
@@ -0,0 +1,5 @@
+ccflags-y := -Iinclude/drm
+
+tegra-drm-y := tegra_drv.o
+
+obj-$(CONFIG_DRM_TEGRA) += tegra-drm.o
diff --git a/drivers/gpu/drm/tegra/tegra_drv.c b/drivers/gpu/drm/tegra/tegra_drv.c
new file mode 100644
index 0000000..2c691dc
--- /dev/null
+++ b/drivers/gpu/drm/tegra/tegra_drv.c
@@ -0,0 +1,2241 @@
+/*
+ * Copyright (C) 2012 Avionic Design GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/iommu.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/clk.h>
+
+#include <linux/shmem_fs.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_fixed.h>
+#include <drm/tegra_drm.h>
+
+#include <mach/clk.h>
+#include <mach/iomap.h>
+
+#include "tegra_drv.h"
+
+#define DRIVER_NAME "tegra"
+#define DRIVER_DESC "NVIDIA Tegra graphics"
+#define DRIVER_DATE "20120330"
+#define DRIVER_MAJOR 0
+#define DRIVER_MINOR 0
+#define DRIVER_PATCHLEVEL 0
+
+static const unsigned int num_crtc = 1;
+
+struct tegra_gem_object;
+struct tegra_crtc_ops;
+
+struct tegra_crtc {
+	struct drm_crtc base;
+	int pipe;
+
+	struct clk *clk_emc;
+	struct clk *clk;
+
+	void __iomem *regs;
+	int irq;
+
+	struct drm_connector connector;
+	struct drm_encoder encoder;
+
+	struct tegra_drm_panel *panel;
+
+	const struct tegra_crtc_ops *ops;
+};
+
+static inline struct tegra_crtc *to_tegra_crtc(struct drm_crtc *crtc)
+{
+	return container_of(crtc, struct tegra_crtc, base);
+}
+
+struct tegra_crtc_ops {
+	int (*enable)(struct tegra_crtc *crtc);
+};
+
+static inline int tegra_crtc_enable(struct tegra_crtc *crtc)
+{
+	if (crtc && crtc->ops && crtc->ops->enable)
+		return crtc->ops->enable(crtc);
+
+	return crtc ? -ENOSYS : -EINVAL;
+}
+
+struct tegra_gem_object {
+	struct drm_gem_object base;
+	struct resource phys;
+	struct page **pages;
+	void *virt;
+};
+
+static inline struct tegra_gem_object *to_tegra_gem(struct drm_gem_object *obj)
+{
+	return container_of(obj, struct tegra_gem_object, base);
+}
+
+struct tegra_framebuffer {
+	struct drm_framebuffer base;
+	struct tegra_gem_object *obj;
+};
+
+static inline struct tegra_framebuffer *to_tegra_fb(struct drm_framebuffer *fb)
+{
+	return container_of(fb, struct tegra_framebuffer, base);
+}
+
+struct tegra_drm_private {
+	struct tegra_crtc crtc[2];
+	struct drm_encoder_connector *encon[2];
+	struct drm_fb_helper fb_helper;
+	struct tegra_framebuffer fb;
+	unsigned int num_crtcs;
+
+	struct iommu_domain *gart;
+	struct resource aperture;
+};
+
+static inline void tegra_crtc_writel(struct tegra_crtc *crtc, unsigned long value, unsigned long reg)
+{
+	writel(value, crtc->regs + (reg << 2));
+}
+
+static inline unsigned long tegra_crtc_readl(struct tegra_crtc *crtc, unsigned long reg)
+{
+	return readl(crtc->regs + (reg << 2));
+}
+
+static unsigned long pclk_best_div(unsigned long pclk, unsigned long rate)
+{
+	unsigned long div = DIV_ROUND_CLOSEST(rate * 2, pclk);
+	static const unsigned long max_pclk_khz = ULONG_MAX;
+
+	if (!div)
+		return 0;
+
+	while (rate * 2 / div > max_pclk_khz * 1000)
+		div++;
+
+	if (div < 2)
+		div = 2;
+
+	if (div > 257)
+		div = 257;
+
+	return div;
+}
+
+static unsigned long pclk_round_rate(struct clk *clk, unsigned long pclk, unsigned long *div)
+{
+	long rate = clk_round_rate(clk, pclk);
+
+	if (rate < 0)
+		rate = clk_get_rate(clk);
+
+	*div = pclk_best_div(pclk, rate);
+
+	return rate;
+}
+
+static int tegra_drmfb_create_handle(struct drm_framebuffer *fb, struct drm_file *filp, unsigned int *handle)
+{
+	struct tegra_framebuffer *privfb = to_tegra_fb(fb);
+	struct drm_device *drm = fb->dev;
+	int ret = 0;
+
+	dev_dbg(drm->dev, "> %s(fb=%p, filp=%p, handle=%p)\n", __func__, fb, filp, handle);
+
+	ret = drm_gem_handle_create(filp, &privfb->obj->base, handle);
+
+	dev_dbg(drm->dev, "< %s() = %d\n", __func__, ret);
+	return ret;
+}
+
+static void tegra_drmfb_destroy(struct drm_framebuffer *fb)
+{
+	struct tegra_framebuffer *priv = to_tegra_fb(fb);
+	struct drm_gem_object *obj = &priv->obj->base;
+	struct drm_device *drm = fb->dev;
+
+	dev_dbg(drm->dev, "> %s(fb=%p)\n", __func__, fb);
+
+	drm_framebuffer_cleanup(fb);
+	drm_gem_object_unreference_unlocked(obj);
+
+	dev_dbg(drm->dev, "< %s()\n", __func__);
+}
+
+static const struct drm_framebuffer_funcs tegra_drmfb_funcs = {
+	.create_handle = tegra_drmfb_create_handle,
+	.destroy = tegra_drmfb_destroy,
+};
+
+static int tegra_fb_init(struct drm_device *drm, struct tegra_framebuffer *fb,
+			 struct drm_mode_fb_cmd2 *mode)
+{
+	int ret = 0;
+
+	dev_dbg(drm->dev, "> %s(drm=%p, fb=%p, mode=%p)\n", __func__, drm, fb, mode);
+
+	/* TODO: add sanity checks */
+
+	ret = drm_framebuffer_init(drm, &fb->base, &tegra_drmfb_funcs);
+	if (ret < 0) {
+		DRM_ERROR("framebuffer init failed %d\n", ret);
+		return ret;
+	}
+
+	ret = drm_helper_mode_fill_fb_struct(&fb->base, mode);
+	dev_dbg(drm->dev, "< %s() = %d\n", __func__, ret);
+	return ret;
+}
+
+static struct drm_framebuffer *tegra_drm_fb_create(struct drm_device *drm,
+						   struct drm_file *filp,
+						   struct drm_mode_fb_cmd2 *cmd)
+{
+	struct drm_framebuffer *drmfb = NULL;
+	struct tegra_framebuffer *fb = NULL;
+	struct drm_gem_object *obj;
+	u32 bpp, depth;
+	int err;
+
+	dev_dbg(drm->dev, "> %s(drm=%p, filp=%p, cmd=%p)\n", __func__, drm,
+		filp, cmd);
+
+	drm_fb_get_bpp_depth(cmd->pixel_format, &depth, &bpp);
+
+	obj = drm_gem_object_lookup(drm, filp, cmd->handles[0]);
+	if (!obj) {
+		drmfb = ERR_PTR(-ENOENT);
+		goto out;
+	}
+
+	fb = devm_kzalloc(drm->dev, sizeof(*fb), GFP_KERNEL);
+	if (!fb) {
+		drmfb = ERR_PTR(-ENOMEM);
+		goto out;
+	}
+
+	err = tegra_fb_init(drm, fb, cmd);
+	if (err < 0) {
+		devm_kfree(drm->dev, fb);
+		drmfb = ERR_PTR(err);
+		goto out;
+	}
+
+	fb->obj = to_tegra_gem(obj);
+	drmfb = &fb->base;
+
+out:
+	dev_dbg(drm->dev, "< %s() = %p\n", __func__, drmfb);
+	return drmfb;
+}
+
+static void tegra_drm_fb_output_poll_changed(struct drm_device *drm)
+{
+	dev_dbg(drm->dev, "> %s(drm=%p)\n", __func__, drm);
+	dev_dbg(drm->dev, "< %s()\n", __func__);
+}
+
+static struct drm_mode_config_funcs tegra_drm_mode_funcs = {
+	.fb_create = tegra_drm_fb_create,
+	.output_poll_changed = tegra_drm_fb_output_poll_changed,
+};
+
+static void tegra_crtc_save(struct drm_crtc *crtc)
+{
+	dev_dbg(crtc->dev->dev, "> %s(crtc=%p)\n", __func__, crtc);
+	dev_dbg(crtc->dev->dev, "< %s()\n", __func__);
+}
+
+static void tegra_crtc_restore(struct drm_crtc *crtc)
+{
+	dev_dbg(crtc->dev->dev, "> %s(crtc=%p)\n", __func__, crtc);
+	dev_dbg(crtc->dev->dev, "< %s()\n", __func__);
+}
+
+static void tegra_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
+				 uint32_t start, uint32_t size)
+{
+	dev_dbg(crtc->dev->dev, "> %s(crtc=%p, r=%p, g=%p, b=%p, start=%u, size=%u)\n",
+		__func__, crtc, r, g, b, start, size);
+	dev_dbg(crtc->dev->dev, "< %s()\n", __func__);
+}
+
+static void tegra_crtc_destroy(struct drm_crtc *crtc)
+{
+	dev_dbg(crtc->dev->dev, "> %s(crtc=%p)\n", __func__, crtc);
+	dev_dbg(crtc->dev->dev, "< %s()\n", __func__);
+}
+
+static int tegra_crtc_page_flip(struct drm_crtc *crtc,
+				struct drm_framebuffer *fb,
+				struct drm_pending_vblank_event *event)
+{
+	int ret = 0;
+	dev_dbg(crtc->dev->dev, "> %s(crtc=%p, fb=%p, event=%p)\n", __func__, crtc, fb, event);
+	dev_dbg(crtc->dev->dev, "< %s() = %d\n", __func__, ret);
+	return ret;
+}
+
+static const struct drm_crtc_funcs tegra_crtc_funcs = {
+	.save = tegra_crtc_save,
+	.restore = tegra_crtc_restore,
+	.gamma_set = tegra_crtc_gamma_set,
+	.set_config = drm_crtc_helper_set_config,
+	.destroy = tegra_crtc_destroy,
+	.page_flip = tegra_crtc_page_flip,
+};
+
+static void tegra_crtc_dpms(struct drm_crtc *crtc, int mode)
+{
+	dev_dbg(crtc->dev->dev, "> %s(crtc=%p, mode=%d)\n", __func__, crtc, mode);
+	dev_dbg(crtc->dev->dev, "< %s()\n", __func__);
+}
+
+static bool tegra_crtc_mode_fixup(struct drm_crtc *crtc,
+				  struct drm_display_mode *mode,
+				  struct drm_display_mode *adjusted)
+{
+	bool ret = true;
+	dev_dbg(crtc->dev->dev, "> %s(crtc=%p, mode=%p, adjusted=%p)\n", __func__, crtc, mode, adjusted);
+	dev_dbg(crtc->dev->dev, "< %s() = %d\n", __func__, ret);
+	return ret;
+}
+
+struct crtc_mode {
+	unsigned int width;
+	unsigned int height;
+	unsigned int href_to_sync;
+	unsigned int vref_to_sync;
+	unsigned int hsync_width;
+	unsigned int vsync_width;
+	unsigned int hback_porch;
+	unsigned int vback_porch;
+	unsigned int hfront_porch;
+	unsigned int vfront_porch;
+};
+
+struct crtc_win {
+	fixed20_12 x;
+	fixed20_12 y;
+	fixed20_12 w;
+	fixed20_12 h;
+	unsigned int outx;
+	unsigned int outy;
+	unsigned int outw;
+	unsigned int outh;
+	unsigned int stride;
+	unsigned int fmt;
+};
+
+static inline u32 compute_dda_inc(fixed20_12 inf, unsigned int out, bool v,
+				  unsigned int bpp)
+{
+	fixed20_12 outf = dfixed_init(out);
+	u32 dda_inc;
+	int max;
+
+	if (v)
+		max = 15;
+	else {
+		switch (bpp) {
+		case 2:
+			max = 8;
+			break;
+
+		default:
+			WARN_ON_ONCE(1);
+			/* fallthrough */
+		case 4:
+			max = 4;
+			break;
+		}
+	}
+
+	outf.full = max_t(u32, outf.full - dfixed_const(1), dfixed_const(1));
+	inf.full -= dfixed_const(1);
+
+	dda_inc = dfixed_div(inf, outf);
+	dda_inc = min_t(u32, dda_inc, dfixed_const(max));
+
+	return dda_inc;
+}
+
+static inline u32 compute_initial_dda(fixed20_12 in)
+{
+	return dfixed_frac(in);
+}
+
+static int tegra_crtc_set_timings(struct tegra_crtc *crtc, struct drm_display_mode *mode)
+{
+	unsigned int front_porch[2];
+	unsigned int back_porch[2];
+	unsigned int sync_width[2];
+	unsigned int active[2];
+	unsigned int reftos[2];
+
+	active[0] = mode->hdisplay;
+	active[1] = mode->vdisplay;
+	reftos[0] = 0;
+	reftos[1] = 0;
+	sync_width[0] = mode->hsync_end - mode->hsync_start;
+	sync_width[1] = mode->vsync_end - mode->vsync_start;
+	back_porch[0] = mode->hsync_start - mode->hdisplay;
+	back_porch[1] = mode->vsync_start - mode->vdisplay;
+	front_porch[0] = mode->htotal - mode->hsync_end;
+	front_porch[1] = mode->vtotal - mode->vsync_end;
+
+	tegra_crtc_writel(crtc, 0x0, DISP_TIMING_OPT);
+	tegra_crtc_writel(crtc, (reftos[1] << 16) | reftos[0], DISP_REF_TO_SYNC);
+	tegra_crtc_writel(crtc, (sync_width[1] << 16) | sync_width[0], DISP_SYNC_WIDTH);
+	tegra_crtc_writel(crtc, (back_porch[1] << 16) | back_porch[0], DISP_BACK_PORCH);
+	tegra_crtc_writel(crtc, (front_porch[1] << 16) | front_porch[0], DISP_FRONT_PORCH);
+
+	tegra_crtc_writel(crtc, (active[1] << 16) | active[0], DISP_ACTIVE);
+
+	return 0;
+}
+
+static int tegra_crtc_mode_set(struct drm_crtc *crtc,
+			       struct drm_display_mode *mode,
+			       struct drm_display_mode *adjusted,
+			       int x, int y, struct drm_framebuffer *old_fb)
+{
+	struct tegra_crtc *priv = container_of(crtc, struct tegra_crtc, base);
+	unsigned long pclk = mode->clock * 1000;
+	struct tegra_framebuffer *fb;
+	unsigned long update_mask;
+	unsigned long rate, div;
+	struct crtc_win win;
+	unsigned int h_dda;
+	unsigned int v_dda;
+	unsigned long val;
+	unsigned int bpp;
+	int ret = 0;
+
+	dev_dbg(crtc->dev->dev, "> %s(crtc=%p, mode=%p, adjusted=%p, x=%d, y=%d, old_fb=%p)\n",
+		__func__, crtc, mode, adjusted, x, y, old_fb);
+
+	fb = container_of(crtc->fb, struct tegra_framebuffer, base);
+	update_mask = CMD_STATE_CTRL_GENERAL_ACT_REQ;
+
+	rate = pclk_round_rate(priv->clk, pclk, &div);
+	dev_dbg(crtc->dev->dev, "  rate:%lu div:%lu\n", rate, div);
+	clk_set_rate(priv->clk, rate);
+
+	pclk = div ? (rate * 2 / div) : 0;
+	dev_dbg(crtc->dev->dev, "  pclk:%lu\n", pclk);
+
+	/* program display mode */
+	tegra_crtc_set_timings(priv, mode);
+
+	val = DISP_DATA_ENABLE_OPT_SELECT_ACTIVE |
+	      DISP_DATA_ENABLE_OPT_CONTROL_NORMAL;
+	tegra_crtc_writel(priv, val, DISP_DATA_ENABLE_OPT);
+
+	val = tegra_crtc_readl(priv, COM_PIN_OUTPUT_POLARITY(1));
+	val &= ~COM_PIN_OUTPUT_POLARITY_PIN1_LVS_OUTPUT;
+	val &= ~COM_PIN_OUTPUT_POLARITY_PIN1_LHS_OUTPUT;
+	tegra_crtc_writel(priv, val, COM_PIN_OUTPUT_POLARITY(1));
+
+	val = DISP_INTERFACE_CTRL_DATA_FORMAT_DF1P1C |
+	      DISP_INTERFACE_CTRL_ALIGN_MSB |
+	      DISP_INTERFACE_CTRL_ORDER_RED_BLUE;
+	tegra_crtc_writel(priv, val, DISP_INTERFACE_CTRL);
+
+	tegra_crtc_writel(priv, 0x00010001, DISP_SHIFT_CLK_OPT);
+
+	val = DISP_CLK_CTRL_CLK_DIV(div - 2) | DISP_CLK_CTRL_PIXEL_CLK_DIV_PCD1;
+	tegra_crtc_writel(priv, val, DISP_CLK_CTRL);
+
+	/* setup window parameters */
+	memset(&win, 0, sizeof(win));
+	win.x.full = dfixed_const(0);
+	win.y.full = dfixed_const(0);
+	win.w.full = dfixed_const(mode->hdisplay);
+	win.h.full = dfixed_const(mode->vdisplay);
+	win.outx = 0;
+	win.outy = 0;
+	win.outw = mode->hdisplay;
+	win.outh = mode->vdisplay;
+
+	switch (crtc->fb->pixel_format) {
+	case DRM_FORMAT_XRGB8888:
+		win.fmt = WIN_COLOR_DEPTH_R8G8B8A8;
+		break;
+
+	case DRM_FORMAT_RGB565:
+		win.fmt = WIN_COLOR_DEPTH_B5G6R5;
+		break;
+
+	default:
+		win.fmt = WIN_COLOR_DEPTH_R8G8B8A8;
+		WARN_ON(1);
+		break;
+	}
+
+	bpp = crtc->fb->bits_per_pixel / 8;
+	win.stride = win.outw * bpp;
+
+	/* program window registers */
+	val = tegra_crtc_readl(priv, CMD_WIN_HEADER);
+	val |= CMD_WIN_HEADER_WINDOW_A_SELECT;
+	tegra_crtc_writel(priv, val, CMD_WIN_HEADER);
+
+	tegra_crtc_writel(priv, win.fmt, WIN_COLOR_DEPTH);
+	tegra_crtc_writel(priv, 0, WIN_BYTE_SWAP);
+
+	val = WIN_POSITION_V(win.outy) | WIN_POSITION_H(win.outx);
+	tegra_crtc_writel(priv, val, WIN_POSITION);
+
+	val = WIN_SIZE_V(win.outh) | WIN_SIZE_H(win.outw);
+	tegra_crtc_writel(priv, val, WIN_SIZE);
+
+	val = WIN_PRESCALED_SIZE_V(dfixed_trunc(win.h)) |
+	      WIN_PRESCALED_SIZE_H(dfixed_trunc(win.w) * bpp);
+	tegra_crtc_writel(priv, val, WIN_PRESCALED_SIZE);
+
+	h_dda = compute_dda_inc(win.w, win.outw, false, bpp);
+	v_dda = compute_dda_inc(win.h, win.outh, true, bpp);
+
+	val = WIN_DDA_INC_V(v_dda) | WIN_DDA_INC_H(h_dda);
+	tegra_crtc_writel(priv, val, WIN_DDA_INC);
+
+	h_dda = compute_initial_dda(win.x);
+	v_dda = compute_initial_dda(win.y);
+
+	tegra_crtc_writel(priv, h_dda, WIN_H_INITIAL_DDA);
+	tegra_crtc_writel(priv, v_dda, WIN_V_INITIAL_DDA);
+
+	tegra_crtc_writel(priv, 0, WIN_UV_BUF_STRIDE);
+	tegra_crtc_writel(priv, 0, WIN_BUF_STRIDE);
+
+	dev_dbg(crtc->dev->dev, "%s(): displaying GEM %p @%x\n", __func__,
+		fb->obj, fb->obj->phys.start);
+
+	tegra_crtc_writel(priv, fb->obj->phys.start, WINBUF_START_ADDR);
+	tegra_crtc_writel(priv, win.stride, WIN_LINE_STRIDE);
+	tegra_crtc_writel(priv, dfixed_trunc(win.x) * bpp, WINBUF_ADDR_H_OFFSET);
+	tegra_crtc_writel(priv, dfixed_trunc(win.y), WINBUF_ADDR_V_OFFSET);
+
+	val = WIN_OPT_ENABLE;
+
+	if (bpp < 24)
+		val |= WIN_OPT_COLOR_EXPAND;
+
+	tegra_crtc_writel(priv, val, WIN_OPT);
+
+	tegra_crtc_writel(priv, 0xff00, WIN_BLEND_NOKEY);
+	tegra_crtc_writel(priv, 0xff00, WIN_BLEND_1WIN);
+
+	update_mask |= CMD_STATE_CTRL_WIN_A_ACT_REQ;
+
+	tegra_crtc_writel(priv, update_mask << 8, CMD_STATE_CTRL);
+
+	val = tegra_crtc_readl(priv, CMD_INT_ENABLE);
+	val |= INT_FRAME_END;
+	tegra_crtc_writel(priv, val, CMD_INT_ENABLE);
+
+	val = tegra_crtc_readl(priv, CMD_INT_MASK);
+	val |= INT_FRAME_END;
+	tegra_crtc_writel(priv, val, CMD_INT_MASK);
+
+	tegra_crtc_writel(priv, update_mask, CMD_STATE_CTRL);
+
+	dev_dbg(crtc->dev->dev, "< %s() = %d\n", __func__, ret);
+	return ret;
+}
+
+#if 0
+static int tegra_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
+				    struct drm_framebuffer *fb)
+{
+	struct tegra_framebuffer *privfb = to_tegra_fb(fb);
+	struct tegra_crtc *priv = to_tegra_crtc(crtc);
+	int ret = 0;
+
+	dev_dbg(crtc->dev->dev, "> %s(crtc=%p, x=%d, y=%d, fb=%p)\n", __func__, crtc, x, y,
+		fb);
+
+	tegra_crtc_writel(priv, privfb->phys, WINBUF_START_ADDR);
+
+	dev_dbg(crtc->dev->dev, "< %s() = %d\n", __func__, ret);
+	return ret;
+}
+#else
+#define tegra_crtc_mode_set_base NULL
+#endif
+
+static void tegra_crtc_prepare(struct drm_crtc *crtc)
+{
+	dev_dbg(crtc->dev->dev, "> %s(crtc=%p)\n", __func__, crtc);
+	dev_dbg(crtc->dev->dev, "< %s()\n", __func__);
+}
+
+static void tegra_crtc_commit(struct drm_crtc *crtc)
+{
+	dev_dbg(crtc->dev->dev, "> %s(crtc=%p)\n", __func__, crtc);
+	dev_dbg(crtc->dev->dev, "< %s()\n", __func__);
+}
+
+static void tegra_crtc_load_lut(struct drm_crtc *crtc)
+{
+	dev_dbg(crtc->dev->dev, "> %s(crtc=%p)\n", __func__, crtc);
+	dev_dbg(crtc->dev->dev, "< %s()\n", __func__);
+}
+
+static void tegra_crtc_disable(struct drm_crtc *crtc)
+{
+	dev_dbg(crtc->dev->dev, "> %s(crtc=%p)\n", __func__, crtc);
+	dev_dbg(crtc->dev->dev, "< %s()\n", __func__);
+}
+
+static const struct drm_crtc_helper_funcs tegra_crtc_helper_funcs = {
+	.dpms = tegra_crtc_dpms,
+	.mode_fixup = tegra_crtc_mode_fixup,
+	.mode_set = tegra_crtc_mode_set,
+	.mode_set_base = tegra_crtc_mode_set_base,
+	.prepare = tegra_crtc_prepare,
+	.commit = tegra_crtc_commit,
+	.load_lut = tegra_crtc_load_lut,
+	.disable = tegra_crtc_disable,
+};
+
+#define PIN_REG_COUNT 4
+#define PIN_OUTPUT_SEL_COUNT 7
+
+static const u32 rgb_enable_tab[PIN_REG_COUNT] = {
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+};
+
+static const u32 rgb_polarity_tab[PIN_REG_COUNT] = {
+	0x00000000,
+	0x01000000,
+	0x00000000,
+	0x00000000,
+};
+
+static const u32 rgb_data_tab[PIN_REG_COUNT] = {
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+};
+
+static const u32 rgb_sel_tab[PIN_OUTPUT_SEL_COUNT] = {
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00210222,
+	0x00002200,
+	0x00020000,
+};
+
+static int tegra_connector_get_modes(struct drm_connector *connector)
+{
+	struct tegra_crtc *crtc = container_of(connector, struct tegra_crtc, connector);
+	struct tegra_drm_panel *panel = crtc->panel;
+	unsigned int i;
+	int ret = 0;
+
+	dev_dbg(&connector->kdev, "> %s(connector=%p)\n", __func__, connector);
+
+	if (!panel) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	dev_dbg(&connector->kdev, "  panel: %d\n", panel->type);
+	dev_dbg(&connector->kdev, "    size: %ux%u\n", panel->width,
+		panel->height);
+	dev_dbg(&connector->kdev, "    modes: %u\n", panel->num_modes);
+
+	for (i = 0; i < panel->num_modes; i++) {
+		struct tegra_drm_mode *mode = &panel->modes[i];
+		struct drm_display_mode *display_mode;
+
+		display_mode = drm_mode_create(connector->dev);
+		if (!display_mode) {
+			ret = -ENOMEM;
+			goto out;
+		}
+
+		display_mode->width_mm = panel->width;
+		display_mode->height_mm = panel->height;
+
+		display_mode->clock = mode->pixel_clock / 1000;
+		display_mode->vrefresh = mode->vrefresh;
+		display_mode->hdisplay = mode->width;
+		display_mode->vdisplay = mode->height;
+
+		display_mode->hsync_start = mode->width + mode->hback_porch;
+		display_mode->hsync_end = display_mode->hsync_start + mode->hsync_width;
+		display_mode->htotal = display_mode->hsync_end + mode->hfront_porch;
+
+		display_mode->vsync_start = mode->height + mode->vback_porch;
+		display_mode->vsync_end = display_mode->vsync_start + mode->vsync_width;
+		display_mode->vtotal = display_mode->vsync_end + mode->vfront_porch;
+
+		drm_mode_set_name(display_mode);
+		drm_mode_probed_add(connector, display_mode);
+	}
+
+	ret = panel->num_modes;
+
+out:
+	dev_dbg(&connector->kdev, "< %s() = %d\n", __func__, ret);
+	return ret;
+}
+
+static int tegra_connector_mode_valid(struct drm_connector *connector,
+				      struct drm_display_mode *mode)
+{
+	int ret = MODE_OK;
+	dev_dbg(&connector->kdev, "> %s(connector=%p, mode=%p)\n", __func__, connector, mode);
+	dev_dbg(&connector->kdev, "< %s() = %d\n", __func__, ret);
+	return ret;
+}
+
+static struct drm_encoder *tegra_connector_best_encoder(struct drm_connector *connector)
+{
+	struct tegra_crtc *crtc = container_of(connector, struct tegra_crtc, connector);
+	struct drm_encoder *ret = &crtc->encoder;
+	dev_dbg(&connector->kdev, "> %s(connector=%p)\n", __func__, connector);
+	dev_dbg(&connector->kdev, "< %s() = %p\n", __func__, ret);
+	return ret;
+}
+
+static const struct drm_connector_helper_funcs connector_helper_funcs = {
+	.get_modes = tegra_connector_get_modes,
+	.mode_valid = tegra_connector_mode_valid,
+	.best_encoder = tegra_connector_best_encoder,
+};
+
+static void tegra_connector_dpms(struct drm_connector *connector, int mode)
+{
+	dev_dbg(&connector->kdev, "> %s(connector=%p, mode=%d)\n", __func__, connector, mode);
+	dev_dbg(&connector->kdev, "< %s()\n", __func__);
+}
+
+static void tegra_connector_save(struct drm_connector *connector)
+{
+	dev_dbg(&connector->kdev, "> %s(connector=%p)\n", __func__, connector);
+	dev_dbg(&connector->kdev, "< %s()\n", __func__);
+}
+
+static void tegra_connector_restore(struct drm_connector *connector)
+{
+	dev_dbg(&connector->kdev, "> %s(connector=%p)\n", __func__, connector);
+	dev_dbg(&connector->kdev, "< %s()\n", __func__);
+}
+
+static void tegra_connector_reset(struct drm_connector *connector)
+{
+	dev_dbg(&connector->kdev, "> %s(connector=%p)\n", __func__, connector);
+	dev_dbg(&connector->kdev, "< %s()\n", __func__);
+}
+
+static enum drm_connector_status tegra_connector_detect(struct drm_connector *connector, bool force)
+{
+	enum drm_connector_status status = connector_status_unknown;
+
+	dev_dbg(&connector->kdev, "> %s(connector=%p, force=%d)\n", __func__, connector, force);
+
+	if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)
+		status = connector_status_connected;
+
+	dev_dbg(&connector->kdev, "< %s() = %d\n", __func__, status);
+	return status;
+}
+
+static int tegra_connector_fill_modes(struct drm_connector *connector,
+				      uint32_t max_width, uint32_t max_height)
+{
+	int ret = 0;
+
+	dev_dbg(&connector->kdev, "> %s(connector=%p, max_width=%u, max_height=%u)\n", __func__,
+		connector, max_width, max_height);
+
+	ret = drm_helper_probe_single_connector_modes(connector, max_width, max_height);
+
+	dev_dbg(&connector->kdev, "< %s() = %d\n", __func__, ret);
+	return ret;
+}
+
+static int tegra_connector_set_property(struct drm_connector *connector,
+					struct drm_property *property,
+					uint64_t value)
+{
+	int ret = 0;
+	dev_dbg(&connector->kdev, "> %s(connector=%p, property=%p, value=%llx)\n", __func__,
+		connector, property, value);
+	dev_dbg(&connector->kdev, "< %s() = %d\n", __func__, ret);
+	return ret;
+}
+
+static void tegra_connector_destroy(struct drm_connector *connector)
+{
+	pr_debug("> %s(connector=%p)\n", __func__, connector);
+	drm_sysfs_connector_remove(connector);
+	drm_connector_cleanup(connector);
+	pr_debug("< %s()\n", __func__);
+}
+
+static void tegra_connector_force(struct drm_connector *connector)
+{
+	dev_dbg(&connector->kdev, "> %s(connector=%p)\n", __func__, connector);
+	dev_dbg(&connector->kdev, "< %s()\n", __func__);
+}
+
+static const struct drm_connector_funcs connector_funcs = {
+	.dpms = tegra_connector_dpms,
+	.save = tegra_connector_save,
+	.restore = tegra_connector_restore,
+	.reset = tegra_connector_reset,
+
+	.detect = tegra_connector_detect,
+	.fill_modes = tegra_connector_fill_modes,
+	.set_property = tegra_connector_set_property,
+	.destroy = tegra_connector_destroy,
+	.force = tegra_connector_force,
+};
+
+static void tegra_encoder_reset(struct drm_encoder *encoder)
+{
+	dev_dbg(encoder->dev->dev, "> %s(encoder=%p)\n", __func__, encoder);
+	dev_dbg(encoder->dev->dev, "< %s()\n", __func__);
+}
+
+static void tegra_encoder_destroy(struct drm_encoder *encoder)
+{
+	dev_dbg(encoder->dev->dev, "> %s(encoder=%p)\n", __func__, encoder);
+	dev_dbg(encoder->dev->dev, "< %s()\n", __func__);
+}
+
+static const struct drm_encoder_funcs encoder_funcs = {
+	.reset = tegra_encoder_reset,
+	.destroy = tegra_encoder_destroy,
+};
+
+static void tegra_encoder_dpms(struct drm_encoder *encoder, int mode)
+{
+	dev_dbg(encoder->dev->dev, "> %s(encoder=%p, mode=%d)\n", __func__, encoder, mode);
+	dev_dbg(encoder->dev->dev, "< %s()\n", __func__);
+}
+
+static void tegra_encoder_save(struct drm_encoder *encoder)
+{
+	dev_dbg(encoder->dev->dev, "> %s(encoder=%p)\n", __func__, encoder);
+	dev_dbg(encoder->dev->dev, "< %s()\n", __func__);
+}
+
+static void tegra_encoder_restore(struct drm_encoder *encoder)
+{
+	dev_dbg(encoder->dev->dev, "> %s(encoder=%p)\n", __func__, encoder);
+	dev_dbg(encoder->dev->dev, "< %s()\n", __func__);
+}
+
+static bool tegra_encoder_mode_fixup(struct drm_encoder *encoder,
+				     struct drm_display_mode *mode,
+				     struct drm_display_mode *adjusted)
+{
+	bool ret = true;
+	dev_dbg(encoder->dev->dev, "> %s(encoder=%p, mode=%p, adjusted=%p)\n", __func__, encoder, mode, adjusted);
+	dev_dbg(encoder->dev->dev, "< %s() = %d\n", __func__, ret);
+	return ret;
+}
+
+static void tegra_encoder_prepare(struct drm_encoder *encoder)
+{
+	dev_dbg(encoder->dev->dev, "> %s(encoder=%p)\n", __func__, encoder);
+	dev_dbg(encoder->dev->dev, "< %s()\n", __func__);
+}
+
+static void tegra_encoder_commit(struct drm_encoder *encoder)
+{
+	dev_dbg(encoder->dev->dev, "> %s(encoder=%p)\n", __func__, encoder);
+	dev_dbg(encoder->dev->dev, "< %s()\n", __func__);
+}
+
+static void tegra_encoder_mode_set(struct drm_encoder *encoder,
+				   struct drm_display_mode *mode,
+				   struct drm_display_mode *adjusted)
+{
+	dev_dbg(encoder->dev->dev, "> %s(encoder=%p, mode=%p, adjusted=%p)\n", __func__, encoder,
+		mode, adjusted);
+	dev_dbg(encoder->dev->dev, "< %s()\n", __func__);
+}
+
+static struct drm_crtc *tegra_encoder_get_crtc(struct drm_encoder *encoder)
+{
+	struct tegra_crtc *crtc = container_of(encoder, struct tegra_crtc, encoder);
+	struct drm_crtc *ret = &crtc->base;
+	dev_dbg(encoder->dev->dev, "> %s(encoder=%p)\n", __func__, encoder);
+	dev_dbg(encoder->dev->dev, "< %s() = %p\n", __func__, ret);
+	return ret;
+}
+
+static enum drm_connector_status tegra_encoder_detect(struct drm_encoder *encoder,
+						      struct drm_connector *connector)
+{
+	enum drm_connector_status status = connector_status_unknown;
+	dev_dbg(encoder->dev->dev, "> %s(encoder=%p, connector=%p)\n", __func__, encoder, connector);
+	dev_dbg(encoder->dev->dev, "< %s() = %d\n", __func__, status);
+	return status;
+}
+
+static void tegra_encoder_disable(struct drm_encoder *encoder)
+{
+	dev_dbg(encoder->dev->dev, "> %s(encoder=%p)\n", __func__, encoder);
+	dev_dbg(encoder->dev->dev, "< %s()\n", __func__);
+}
+
+static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
+	.dpms = tegra_encoder_dpms,
+	.save = tegra_encoder_save,
+	.restore = tegra_encoder_restore,
+	.mode_fixup = tegra_encoder_mode_fixup,
+	.prepare = tegra_encoder_prepare,
+	.commit = tegra_encoder_commit,
+	.mode_set = tegra_encoder_mode_set,
+	.get_crtc = tegra_encoder_get_crtc,
+	.detect = tegra_encoder_detect,
+	.disable = tegra_encoder_disable,
+};
+
+static int tegra_crtc_rgb_enable(struct tegra_crtc *crtc)
+{
+	unsigned int i;
+
+	/* enable RGB output */
+	for (i = 0; i < PIN_REG_COUNT; i++) {
+		tegra_crtc_writel(crtc, rgb_enable_tab[i], COM_PIN_OUTPUT_ENABLE(i));
+		tegra_crtc_writel(crtc, rgb_polarity_tab[i], COM_PIN_OUTPUT_POLARITY(i));
+		tegra_crtc_writel(crtc, rgb_data_tab[i], COM_PIN_OUTPUT_DATA(i));
+	}
+
+	for (i = 0; i < PIN_OUTPUT_SEL_COUNT; i++)
+		tegra_crtc_writel(crtc, rgb_sel_tab[i], COM_PIN_OUTPUT_SEL(i));
+
+	return 0;
+}
+
+static const struct tegra_crtc_ops tegra_crtc_rgb_ops = {
+	.enable = tegra_crtc_rgb_enable,
+};
+
+static int tegra_crtc_init(struct drm_device *drm, unsigned int pipe)
+{
+	struct tegra_drm_platform_data *pdata = drm->dev->platform_data;
+	unsigned int syncpt = pipe ? SYNCPT_VBLANK1 : SYNCPT_VBLANK0;
+	struct tegra_drm_private *priv = drm->dev_private;
+	struct tegra_crtc *crtc = &priv->crtc[pipe];
+	struct tegra_drm_panel *panel;
+	unsigned long val;
+	int connector;
+	int encoder;
+	int ret = 0;
+
+	dev_dbg(drm->dev, "> %s(drm=%p, pipe=%u)\n", __func__, drm, pipe);
+
+	if (pipe >= pdata->num_panels) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	panel = crtc->panel = &pdata->panels[pipe];
+
+	switch (panel->type) {
+	case TEGRA_DRM_PANEL_RGB:
+		connector = DRM_MODE_CONNECTOR_LVDS;
+		encoder = DRM_MODE_ENCODER_LVDS;
+		crtc->ops = &tegra_crtc_rgb_ops;
+		break;
+
+	default:
+		connector = DRM_MODE_CONNECTOR_Unknown;
+		encoder = DRM_MODE_ENCODER_NONE;
+		break;
+	}
+
+	drm_connector_helper_add(&crtc->connector, &connector_helper_funcs);
+	drm_connector_init(drm, &crtc->connector, &connector_funcs, connector);
+
+	drm_encoder_init(drm, &crtc->encoder, &encoder_funcs, encoder);
+	drm_encoder_helper_add(&crtc->encoder, &encoder_helper_funcs);
+
+	drm_mode_connector_attach_encoder(&crtc->connector,
+					  &crtc->encoder);
+	drm_sysfs_connector_add(&crtc->connector);
+
+	crtc->encoder.possible_crtcs = 1 << pipe;
+
+	/* hardware initialization */
+
+	clk_enable(crtc->clk);
+	clk_enable(crtc->clk_emc);
+	tegra_periph_reset_deassert(crtc->clk);
+	msleep(10);
+
+	/* initialize display controller */
+	tegra_crtc_writel(crtc, 0x00000100, CMD_GENERAL_INCR_SYNCPT_CTRL);
+	tegra_crtc_writel(crtc, 0x100 | syncpt, CMD_CONT_SYNCPT_VSYNC);
+
+	val = INT_WIN_A_UF | INT_WIN_B_UF | INT_WIN_C_UF | INT_WIN_A_OF;
+	tegra_crtc_writel(crtc, val, CMD_INT_TYPE);
+
+	val = INT_WIN_A_UF | INT_WIN_B_UF | INT_WIN_C_UF |
+	      INT_WIN_A_OF | INT_WIN_B_OF | INT_WIN_C_OF;
+	tegra_crtc_writel(crtc, val, CMD_INT_POLARITY);
+
+	val = CMD_DISP_POWER_CTRL_PW0_ENABLE | CMD_DISP_POWER_CTRL_PW1_ENABLE |
+	      CMD_DISP_POWER_CTRL_PW2_ENABLE | CMD_DISP_POWER_CTRL_PW3_ENABLE |
+	      CMD_DISP_POWER_CTRL_PW4_ENABLE | CMD_DISP_POWER_CTRL_PM0_ENABLE |
+	      CMD_DISP_POWER_CTRL_PM1_ENABLE;
+	tegra_crtc_writel(crtc, val, CMD_DISP_POWER_CTRL);
+
+	val = tegra_crtc_readl(crtc, CMD_DISP_CMD);
+	val |= CMD_DISP_CMD_CTRL_MODE_C_DISPLAY;
+	tegra_crtc_writel(crtc, val, CMD_DISP_CMD);
+
+	/* initialize timer */
+	tegra_crtc_writel(crtc, 0x00202020, DISP_MEM_HIGH_PRI);
+	tegra_crtc_writel(crtc, 0x00010101, DISP_MEM_HIGH_PRI_TIMER);
+
+	val = INT_VBLANK | INT_WIN_A_UF | INT_WIN_B_UF | INT_WIN_C_UF;
+	tegra_crtc_writel(crtc, val, CMD_INT_MASK);
+
+	val = INT_VBLANK | INT_WIN_A_UF | INT_WIN_B_UF | INT_WIN_C_UF;
+	tegra_crtc_writel(crtc, val, CMD_INT_ENABLE);
+
+	ret = tegra_crtc_enable(crtc);
+	if (ret < 0)
+		goto out;
+
+	drm_crtc_init(drm, &crtc->base, &tegra_crtc_funcs);
+	drm_mode_crtc_set_gamma_size(&crtc->base, 256);
+	drm_crtc_helper_add(&crtc->base, &tegra_crtc_helper_funcs);
+
+out:
+	dev_dbg(drm->dev, "< %s() = %d\n", __func__, ret);
+	return ret;
+}
+
+static void tegra_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
+			       u16 blue, int regno)
+{
+	dev_dbg(crtc->dev->dev, "> %s(crtc=%p, red=%u, green=%u, blue=%u, regno=%d)\n",
+		__func__, crtc, red, green, blue, regno);
+	dev_dbg(crtc->dev->dev, "< %s()\n", __func__);
+}
+
+static void tegra_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
+			       u16 *blue, int regno)
+{
+	dev_dbg(crtc->dev->dev, "> %s(crtc=%p, red=%p, green=%p, blue=%p, regno=%d)\n",
+		__func__, crtc, red, green, blue, regno);
+	dev_dbg(crtc->dev->dev, "< %s()\n", __func__);
+}
+
+static struct fb_ops tegra_fb_ops = {
+	.owner = THIS_MODULE,
+	.fb_check_var = drm_fb_helper_check_var,
+	.fb_set_par = drm_fb_helper_set_par,
+	.fb_fillrect = cfb_fillrect,
+	.fb_copyarea = cfb_copyarea,
+	.fb_imageblit = cfb_imageblit,
+	.fb_pan_display = drm_fb_helper_pan_display,
+	.fb_blank = drm_fb_helper_blank,
+	.fb_setcmap = drm_fb_helper_setcmap,
+	.fb_debug_enter = drm_fb_helper_debug_enter,
+	.fb_debug_leave = drm_fb_helper_debug_leave,
+};
+
+static int tegra_gem_get_pages(struct drm_device *drm,
+			       struct tegra_gem_object *obj, gfp_t gfp)
+{
+	struct address_space *mapping;
+	unsigned int num_pages;
+	struct inode *inode;
+	struct page *page;
+	unsigned int i;
+	int ret = 0;
+
+	dev_dbg(drm->dev, "> %s(drm=%p, obj=%p, gfp=%x)\n", __func__, drm,
+		obj, gfp);
+
+	if (obj->pages)
+		goto out;
+
+	num_pages = obj->base.size / PAGE_SIZE;
+
+	obj->pages = drm_malloc_ab(num_pages, sizeof(page));
+	if (!obj->pages) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	inode = obj->base.filp->f_path.dentry->d_inode;
+	mapping = inode->i_mapping;
+	gfp |= mapping_gfp_mask(mapping);
+
+	for (i = 0; i < num_pages; i++) {
+		page = shmem_read_mapping_page_gfp(mapping, i, gfp);
+		if (IS_ERR(page))
+			goto err_pages;
+
+		obj->pages[i] = page;
+	}
+
+	ret = 0;
+	goto out;
+
+err_pages:
+	while (i--)
+		page_cache_release(obj->pages[i]);
+
+	ret = PTR_ERR(page);
+	drm_free_large(obj->pages);
+	obj->pages = NULL;
+out:
+	dev_dbg(drm->dev, "< %s() = %d\n", __func__, ret);
+	return ret;
+}
+
+static void tegra_gem_put_pages(struct drm_device *drm,
+				struct tegra_gem_object *obj)
+{
+	unsigned int num = obj->base.size / PAGE_SIZE;
+
+	dev_dbg(drm->dev, "> %s(drm=%p, obj=%p)\n", __func__, drm, obj);
+
+	while (num--)
+		page_cache_release(obj->pages[num]);
+
+	drm_free_large(obj->pages);
+
+	dev_dbg(drm->dev, "< %s()\n", __func__);
+}
+
+static int tegra_gem_map(struct drm_device *drm, struct tegra_gem_object *obj)
+{
+	unsigned int num_pages = obj->base.size / PAGE_SIZE;
+	int ret = -ENOSYS;
+	pgprot_t prot;
+
+	dev_dbg(drm->dev, "> %s(drm=%p, obj=%p)\n", __func__, drm, obj);
+
+	ret = tegra_gem_get_pages(drm, obj, GFP_KERNEL);
+	if (ret < 0)
+		goto out;
+
+	dev_dbg(drm->dev, "  num_pages: %u\n", num_pages);
+
+	prot = pgprot_writecombine(pgprot_kernel);
+
+	obj->virt = vmap(obj->pages, num_pages, 0, prot);
+	if (!obj->virt) {
+		tegra_gem_put_pages(drm, obj);
+		ret = -ENOMEM;
+	}
+
+	dev_dbg(drm->dev, "  virt: %p\n", obj->virt);
+
+out:
+	dev_dbg(drm->dev, "< %s() = %d\n", __func__, ret);
+	return ret;
+}
+
+static void tegra_gem_unmap(struct drm_device *drm,
+			    struct tegra_gem_object *obj)
+{
+	dev_dbg(drm->dev, "> %s(drm=%p, obj=%p)\n", __func__, drm, obj);
+
+	vunmap(obj->virt);
+	tegra_gem_put_pages(drm, obj);
+
+	dev_dbg(drm->dev, "< %s()\n", __func__);
+}
+
+static int tegra_gem_gart_map(struct drm_device *drm,
+			      struct tegra_gem_object *obj)
+{
+	unsigned int num_pages = obj->base.size / PAGE_SIZE;
+	struct tegra_drm_private *priv = drm->dev_private;
+	resource_size_t min = priv->aperture.start;
+	resource_size_t max = priv->aperture.end;
+	resource_size_t size = obj->base.size;
+	phys_addr_t iova;
+	unsigned int i;
+	int ret = 0;
+
+	dev_dbg(drm->dev, "> %s(drm=%p, obj=%p)\n", __func__, drm, obj);
+
+	if (!priv->gart) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = allocate_resource(&priv->aperture, &obj->phys, size, min, max,
+				PAGE_SIZE, NULL, NULL);
+	if (ret < 0)
+		goto out;
+
+	dev_dbg(drm->dev, "  allocation: %#x-%#x\n", obj->phys.start,
+		obj->phys.end);
+	iova = obj->phys.start;
+
+	for (i = 0; i < num_pages; i++) {
+		struct page *page = obj->pages[i];
+		phys_addr_t phys;
+		int err;
+
+		phys = page_to_phys(page);
+
+		err = iommu_map(priv->gart, iova, phys, PAGE_SIZE, 0);
+		if (err < 0)
+			dev_err(drm->dev, "iommu_map(): %d\n", err);
+
+		iova += PAGE_SIZE;
+	}
+
+out:
+	dev_dbg(drm->dev, "< %s() = %d\n", __func__, ret);
+	return ret;
+}
+
+static void tegra_gem_gart_unmap(struct drm_device *drm,
+				 struct tegra_gem_object *obj)
+{
+	struct tegra_drm_private *priv = drm->dev_private;
+	unsigned int num = obj->base.size / PAGE_SIZE;
+	phys_addr_t iova = obj->phys.start;
+
+	dev_dbg(drm->dev, "> %s(drm=%p, obj=%p)\n", __func__, drm, obj);
+
+	while (num--) {
+		iommu_unmap(priv->gart, iova, PAGE_SIZE);
+		iova += PAGE_SIZE;
+	}
+
+	release_resource(&obj->phys);
+
+	dev_dbg(drm->dev, "< %s()\n", __func__);
+}
+
+static struct tegra_gem_object *tegra_gem_alloc(struct drm_device *drm,
+						size_t size)
+{
+	struct tegra_gem_object *obj;
+	int err;
+
+	dev_dbg(drm->dev, "> %s(drm=%p, size=%zu)\n", __func__, drm, size);
+
+	obj = kzalloc(sizeof(*obj), GFP_KERNEL);
+	if (!obj)
+		goto out;
+
+	err = drm_gem_object_init(drm, &obj->base, size);
+	if (err < 0) {
+		kfree(obj);
+		goto out;
+	}
+
+	err = tegra_gem_map(drm, obj);
+	if (err < 0) {
+		dev_err(drm->dev, "tegra_gem_vmap(): %d\n", err);
+		kfree(obj);
+		obj = NULL;
+		goto out;
+	}
+
+	err = tegra_gem_gart_map(drm, obj);
+	if (err < 0) {
+		dev_err(drm->dev, "tegra_gem_gart_map(): %d\n", err);
+		tegra_gem_unmap(drm, obj);
+		kfree(obj);
+		obj = NULL;
+		goto out;
+	}
+
+	dev_dbg(drm->dev, "%s(): GEM allocated: %p @%#x/%p\n", __func__,
+		obj, obj->phys.start, obj->virt);
+
+out:
+	dev_dbg(drm->dev, "< %s() = %p\n", __func__, obj);
+	return obj;
+}
+
+static void tegra_gem_free(struct drm_device *drm,
+			   struct tegra_gem_object *obj)
+{
+	dev_dbg(drm->dev, "> %s(drm=%p, obj=%p)\n", __func__, drm, obj);
+
+	tegra_gem_gart_unmap(drm, obj);
+	tegra_gem_unmap(drm, obj);
+	drm_gem_object_release(&obj->base);
+	kfree(obj);
+
+	dev_dbg(drm->dev, "< %s()\n", __func__);
+}
+
+static int tegra_fb_create(struct drm_fb_helper *helper,
+			   struct drm_fb_helper_surface_size *sizes)
+{
+	struct drm_device *drm = helper->dev;
+	struct tegra_drm_private *priv = drm->dev_private;
+	struct drm_framebuffer *drmfb;
+	struct drm_mode_fb_cmd2 mode;
+	struct tegra_gem_object *obj;
+	struct fb_info *info;
+	size_t size;
+	int ret = 0;
+	u32 depth;
+	u32 bpp;
+
+	dev_dbg(drm->dev, "> %s(helper=%p, sizes=%p)\n", __func__, helper, sizes);
+	dev_dbg(drm->dev, "  sizes:\n");
+	dev_dbg(drm->dev, "    fb: %ux%u\n", sizes->fb_width, sizes->fb_height);
+	dev_dbg(drm->dev, "    surface: %ux%u (bpp:%u, depth=%u)\n",
+			sizes->surface_width, sizes->surface_height,
+			sizes->surface_bpp, sizes->surface_depth);
+
+	mode.width = sizes->surface_width;
+	mode.height = sizes->surface_height;
+
+	depth = sizes->surface_depth;
+	bpp = sizes->surface_bpp;
+
+	if (bpp == 24)
+		bpp = 32;
+
+	mode.pitches[0] = mode.width * DIV_ROUND_UP(bpp, 8);
+	size = mode.pitches[0] * mode.height;
+	size = ALIGN(size, PAGE_SIZE);
+
+	info = framebuffer_alloc(0, drm->dev);
+	if (!info) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	info->par = helper;
+
+	dev_dbg(drm->dev, "  bpp:%u depth:%u\n", bpp, depth);
+
+	mode.pixel_format = drm_mode_legacy_fb_format(bpp, depth);
+
+	ret = tegra_fb_init(drm, &priv->fb, &mode);
+	if (ret < 0)
+		goto out;
+
+	strcpy(info->fix.id, "tegra-drm-fb");
+
+	drmfb = &priv->fb.base;
+	priv->fb_helper.fb = drmfb;
+	priv->fb_helper.fbdev = info;
+
+	info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
+	info->fbops = &tegra_fb_ops;
+
+	obj = tegra_gem_alloc(drm, size);
+	if (!obj) {
+		dev_err(drm->dev, "tegra_gem_alloc_object() failed\n");
+		return -ENOMEM;
+	}
+
+	dev_dbg(drm->dev, "  GEM object: %p\n", obj);
+
+	info->screen_base = obj->virt;
+	priv->fb.obj = obj;
+
+	memset(info->screen_base, 0, size);
+
+	info->fix.smem_start = priv->fb.obj->phys.start;
+	info->fix.smem_len = size;
+
+	ret = fb_alloc_cmap(&info->cmap, 256, 0);
+	if (ret < 0) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	info->screen_size = size;
+
+	drm_fb_helper_fill_fix(info, drmfb->pitches[0], drmfb->depth);
+	drm_fb_helper_fill_var(info, &priv->fb_helper, sizes->fb_width,
+			       sizes->fb_height);
+
+	dev_info(drm->dev, "allocated %ux%u\n", drmfb->width, drmfb->height);
+
+out:
+	dev_dbg(drm->dev, "< %s() = %d\n", __func__, ret);
+	return ret;
+}
+
+static int tegra_fb_probe(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes)
+{
+	int ret = 0;
+
+	dev_dbg(helper->dev->dev, "> %s(helper=%p, sizes=%p)\n", __func__, helper, sizes);
+
+	if (!helper->fb) {
+		ret = tegra_fb_create(helper, sizes);
+		if (ret == 0)
+			ret = 1;
+	}
+
+	dev_dbg(helper->dev->dev, "< %s() = %d\n", __func__, ret);
+	return ret;
+}
+
+static struct drm_fb_helper_funcs tegra_fb_helper_funcs = {
+	.gamma_set = tegra_fb_gamma_set,
+	.gamma_get = tegra_fb_gamma_get,
+	.fb_probe = tegra_fb_probe,
+};
+
+static int tegra_drm_fb_init(struct drm_device *drm)
+{
+	struct tegra_drm_private *priv = drm->dev_private;
+	unsigned int i;
+	int ret = 0;
+
+	dev_dbg(drm->dev, "> %s(drm=%p)\n", __func__, drm);
+
+	drm_mode_config_init(drm);
+
+	drm->mode_config.min_width = 0;
+	drm->mode_config.min_height = 0;
+
+	drm->mode_config.max_width = 4096;
+	drm->mode_config.max_height = 4096;
+
+	drm->mode_config.funcs = &tegra_drm_mode_funcs;
+
+	drm->mode_config.fb_base = 0xdeadbeef;
+
+	for (i = 0; i < num_crtc; i++) {
+		ret = tegra_crtc_init(drm, i);
+		if (ret < 0)
+			goto out;
+
+		priv->num_crtcs++;
+	}
+
+	priv->fb_helper.funcs = &tegra_fb_helper_funcs;
+
+	ret = drm_fb_helper_init(drm, &priv->fb_helper, priv->num_crtcs,
+				 priv->num_crtcs);
+	if (ret < 0)
+		goto out;
+
+	ret = drm_fb_helper_single_add_all_connectors(&priv->fb_helper);
+	if (ret < 0)
+		goto out;
+
+	ret = drm_fb_helper_initial_config(&priv->fb_helper, 32);
+	if (ret < 0)
+		goto out;
+
+#ifndef CONFIG_FRAMEBUFFER_CONSOLE
+	ret = drm_fb_helper_restore_fbdev_mode(&priv->fb_helper);
+	if (ret < 0)
+		goto out;
+#endif
+
+	ret = 0;
+
+out:
+	dev_dbg(drm->dev, "< %s() = %d\n", __func__, ret);
+	return ret;
+}
+
+static irqreturn_t tegra_drm_irq(int irq, void *data)
+{
+	struct tegra_crtc *crtc = data;
+	unsigned long underflow;
+	unsigned long status;
+
+	dev_dbg(&crtc->connector.kdev, "> %s(irq=%d, data=%p)\n", __func__, irq, data);
+
+	status = tegra_crtc_readl(crtc, CMD_INT_STATUS);
+	tegra_crtc_writel(crtc, status, CMD_INT_STATUS);
+
+	dev_dbg(&crtc->connector.kdev, "  status: %#lx\n", status);
+
+	if (status & INT_FRAME_END)
+		dev_dbg(&crtc->connector.kdev, "%s(): frame end\n", __func__);
+
+	if (status & INT_VBLANK) {
+		dev_dbg(&crtc->connector.kdev, "%s(): V-blank\n", __func__);
+		drm_handle_vblank(crtc->connector.dev, crtc->pipe);
+	}
+
+	underflow = INT_WIN_A_UF | INT_WIN_B_UF | INT_WIN_C_UF;
+
+	if (status & underflow)
+		dev_dbg(&crtc->connector.kdev, "%s(): underflow\n", __func__);
+
+	dev_dbg(&crtc->connector.kdev, "< %s()\n", __func__);
+	return IRQ_HANDLED;
+}
+
+static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
+{
+	struct platform_device *pdev = drm->platformdev;
+	struct tegra_drm_private *priv;
+	unsigned int i;
+	int ret = 0;
+
+	dev_dbg(drm->dev, "> %s(drm=%p, flags=%lx)\n", __func__, drm, flags);
+
+	priv = devm_kzalloc(drm->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	if (drm->dev->of_node) {
+		ret = of_address_to_resource(drm->dev->of_node, 2,
+					     &priv->aperture);
+		if (ret < 0) {
+			dev_err(drm->dev, "of_address_to_resource(): %d\n", ret);
+			return ret;
+		}
+	}
+
+	if (iommu_present(drm->dev->bus)) {
+		priv->gart = iommu_domain_alloc(drm->dev->bus);
+		if (!priv->gart) {
+			ret = -ENOMEM;
+			goto out;
+		}
+
+		ret = iommu_attach_device(priv->gart, drm->dev);
+		if (ret < 0) {
+			dev_err(drm->dev, "iommu_domain_attach_device(): %d\n", ret);
+			goto out;
+		}
+	}
+
+	drm->dev_private = priv;
+
+	for (i = 0; i < num_crtc; i++) {
+		struct tegra_crtc *crtc = &priv->crtc[i];
+		struct resource *regs;
+
+		dev_dbg(drm->dev, "  initializing CRTC %u: %p\n", i, crtc);
+
+		crtc->clk = clk_get(drm->dev, NULL);
+		if (IS_ERR_OR_NULL(crtc->clk)) {
+			DRM_ERROR("failed to get clock\n");
+			ret = -ENXIO;
+			goto out;
+		}
+
+		crtc->clk_emc = clk_get(drm->dev, "emc");
+		if (IS_ERR_OR_NULL(crtc->clk_emc)) {
+			DRM_ERROR("failed to get EMC clock\n");
+			ret = -ENXIO;
+			goto out;
+		}
+
+		regs = platform_get_resource(pdev, IORESOURCE_MEM, i);
+		if (!regs) {
+			DRM_ERROR("failed to get registers\n");
+			ret = -ENXIO;
+			goto out;
+		}
+
+		crtc->regs = devm_request_and_ioremap(drm->dev, regs);
+		if (!crtc->regs) {
+			DRM_ERROR("failed to remap registers\n");
+			ret = -ENXIO;
+			goto out;
+		}
+
+		crtc->irq = platform_get_irq(pdev, i);
+		if (crtc->irq < 0) {
+			DRM_ERROR("failed to get IRQ\n");
+			ret = -ENXIO;
+			goto out;
+		}
+
+		crtc->pipe = i;
+
+		ret = devm_request_irq(drm->dev, crtc->irq, tegra_drm_irq,
+				       0, "tegra-drm", crtc);
+		if (ret < 0) {
+			DRM_ERROR("devm_request_irq(): %d\n", ret);
+			goto out;
+		}
+	}
+
+	ret = tegra_drm_fb_init(drm);
+	if (ret < 0) {
+		dev_dbg(drm->dev, "  tegra_drm_fb_init(): %d\n", ret);
+		goto out;
+	}
+
+	drm_kms_helper_poll_init(drm);
+
+out:
+	dev_dbg(drm->dev, "< %s() = %d\n", __func__, ret);
+	return ret;
+}
+
+static void tegra_drm_fbdev_fini(struct drm_device *drm)
+{
+	struct tegra_drm_private *priv = drm->dev_private;
+	struct drm_fb_helper *fb_helper = &priv->fb_helper;
+
+	dev_dbg(drm->dev, "> %s(drm=%p)\n", __func__, drm);
+	dev_dbg(drm->dev, "  fbdev: %p\n", fb_helper->fb);
+
+	if (fb_helper->fbdev) {
+		struct fb_info *info = fb_helper->fbdev;
+		int err;
+
+		dev_dbg(drm->dev, "  unregistering framebuffer...\n");
+
+		err = unregister_framebuffer(info);
+		if (err < 0)
+			dev_dbg(drm->dev, "unregister_framebuffer(): %d\n", err);
+
+		dev_dbg(drm->dev, "  done\n");
+
+		if (info->cmap.len) {
+			dev_dbg(drm->dev, "  deallocating cmap...\n");
+			fb_dealloc_cmap(&info->cmap);
+			dev_dbg(drm->dev, "  done\n");
+		}
+
+		dev_dbg(drm->dev, "  releasing framebuffer...\n");
+		framebuffer_release(info);
+		dev_dbg(drm->dev, "  done\n");
+	}
+
+	dev_dbg(drm->dev, "  finalizing DRM FB helper...\n");
+	drm_fb_helper_fini(fb_helper);
+	dev_dbg(drm->dev, "  done\n");
+
+	dev_dbg(drm->dev, "< %s()\n", __func__);
+}
+
+static int tegra_drm_unload(struct drm_device *drm)
+{
+	struct tegra_drm_private *priv = drm->dev_private;
+	int ret = 0;
+
+	dev_dbg(drm->dev, "> %s(drm=%p)\n", __func__, drm);
+
+	tegra_drm_fbdev_fini(drm);
+
+	dev_dbg(drm->dev, "  calling drm_kms_helper_poll_fini()...\n");
+	drm_kms_helper_poll_fini(drm);
+	dev_dbg(drm->dev, "  done\n");
+
+	dev_dbg(drm->dev, "  calling drm_mode_config_cleanup()...\n");
+	drm_mode_config_cleanup(drm);
+	dev_dbg(drm->dev, "  done\n");
+
+	if (priv->gart) {
+		iommu_detach_device(priv->gart, drm->dev);
+		iommu_domain_free(priv->gart);
+	}
+
+	devm_kfree(drm->dev, priv);
+
+	dev_dbg(drm->dev, "< %s() = %d\n", __func__, ret);
+	return ret;
+}
+
+static int tegra_drm_open(struct drm_device *drm, struct drm_file *filp)
+{
+	int ret = 0;
+	dev_dbg(drm->dev, "> %s(drm=%p, filp=%p)\n", __func__, drm, filp);
+	dev_dbg(drm->dev, "< %s() = %d\n", __func__, ret);
+	return ret;
+}
+
+static void tegra_drm_lastclose(struct drm_device *drm)
+{
+	struct tegra_drm_private *priv = drm->dev_private;
+	int err;
+
+	dev_dbg(drm->dev, "> %s(drm=%p)\n", __func__, drm);
+
+	err = drm_fb_helper_restore_fbdev_mode(&priv->fb_helper);
+	dev_dbg(drm->dev, "  drm_fb_helper_restore_fbdev_mode(): %d\n", err);
+
+	dev_dbg(drm->dev, "< %s()\n", __func__);
+}
+
+static int tegra_drm_suspend(struct drm_device *drm, pm_message_t state)
+{
+	int ret = -ENOSYS;
+	dev_dbg(drm->dev, "> %s(drm=%p, state=[%d])\n", __func__, drm, state.event);
+	dev_dbg(drm->dev, "< %s() = %d\n", __func__, ret);
+	return ret;
+}
+
+static int tegra_drm_resume(struct drm_device *drm)
+{
+	int ret = -ENOSYS;
+	dev_dbg(drm->dev, "> %s(drm=%p)\n", __func__, drm);
+	dev_dbg(drm->dev, "< %s() = %d\n", __func__, ret);
+	return ret;
+}
+
+static int tegra_drm_enable_vblank(struct drm_device *drm, int crtc)
+{
+	int ret = -ENOSYS;
+	dev_dbg(drm->dev, "> %s(drm=%p, crtc=%d)\n", __func__, drm, crtc);
+	dev_dbg(drm->dev, "< %s() = %d\n", __func__, ret);
+	return ret;
+}
+
+static void tegra_drm_disable_vblank(struct drm_device *drm, int crtc)
+{
+	dev_dbg(drm->dev, "> %s(drm=%p, crtc=%d)\n", __func__, drm, crtc);
+	dev_dbg(drm->dev, "< %s()\n", __func__);
+}
+
+static int tegra_gem_handle_create(struct drm_device *drm,
+				   struct drm_file *file, size_t size,
+				   unsigned long flags, u32 *handle)
+{
+	struct tegra_gem_object *obj;
+	int err = 0;
+
+	dev_dbg(drm->dev, "> %s(drm=%p, file=%p, size=%zu, flags=%#lx, handle=%p)\n",
+		__func__, drm, file, size, flags, handle);
+
+	obj = tegra_gem_alloc(drm, size);
+	if (!obj) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	err = drm_gem_handle_create(file, &obj->base, handle);
+	if (err < 0) {
+		tegra_gem_free(drm, obj);
+		goto out;
+	}
+
+	drm_gem_object_unreference(&obj->base);
+
+out:
+	dev_dbg(drm->dev, "< %s() = %d\n", __func__, err);
+	return err;
+}
+
+static inline unsigned int align_pitch(unsigned int pitch, unsigned int width, unsigned int bpp)
+{
+	return max(pitch, width * DIV_ROUND_UP(bpp, 8));
+}
+
+static int tegra_gem_dumb_create(struct drm_file *file,
+				 struct drm_device *drm,
+				 struct drm_mode_create_dumb *args)
+{
+	int ret = -ENOSYS;
+	dev_dbg(drm->dev, "> %s(file=%p, drm=%p, args=%p)\n", __func__, file, drm, args);
+
+	args->pitch = align_pitch(args->pitch, args->width, args->bpp);
+	args->size = PAGE_ALIGN(args->pitch * args->height);
+
+	ret = tegra_gem_handle_create(drm, file, args->size, 0, &args->handle);
+
+	dev_dbg(drm->dev, "< %s() = %d\n", __func__, ret);
+	return ret;
+}
+
+static int tegra_gem_dumb_map_offset(struct drm_file *file,
+				     struct drm_device *drm,
+				     uint32_t handle, uint64_t *offset)
+{
+	struct tegra_gem_object *gem;
+	struct drm_gem_object *obj;
+	int ret = 0;
+
+	dev_dbg(drm->dev, "> %s(file=%p, drm=%p, handle=%x, offset=%p)\n", __func__, file, drm, handle, offset);
+
+	mutex_lock(&drm->struct_mutex);
+
+	obj = drm_gem_object_lookup(drm, file, handle);
+	if (!obj) {
+		ret = -ENOENT;
+		goto out;
+	}
+
+	gem = to_tegra_gem(obj);
+
+	ret = tegra_gem_get_pages(drm, gem, GFP_KERNEL);
+	if (ret < 0)
+		goto unref;
+
+	if (!obj->map_list.map) {
+		ret = drm_gem_create_mmap_offset(obj);
+		if (ret < 0)
+			goto unref;
+	}
+
+	*offset = (u64)obj->map_list.hash.key << PAGE_SHIFT;
+
+unref:
+	drm_gem_object_unreference(obj);
+out:
+	mutex_unlock(&drm->struct_mutex);
+	dev_dbg(drm->dev, "< %s() = %d\n", __func__, ret);
+	return ret;
+}
+
+static int tegra_gem_dumb_destroy(struct drm_file *file,
+				  struct drm_device *drm,
+				  uint32_t handle)
+{
+	int ret = -ENOSYS;
+	dev_dbg(drm->dev, "> %s(file=%p, drm=%p, handle=%x)\n", __func__, file, drm, handle);
+	ret = drm_gem_handle_delete(file, handle);
+	dev_dbg(drm->dev, "< %s() = %d\n", __func__, ret);
+	return ret;
+}
+
+static struct drm_ioctl_desc tegra_drm_ioctls[] = {
+};
+
+static int tegra_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+	int ret = 0;
+
+	pr_debug("> %s(filp=%p, vma=%p)\n", __func__, filp, vma);
+
+	ret = drm_gem_mmap(filp, vma);
+	if (ret < 0)
+		goto out;
+
+	vma->vm_flags &= ~VM_PFNMAP;
+	vma->vm_flags |= VM_MIXEDMAP;
+
+out:
+	pr_debug("< %s() = %d\n", __func__, ret);
+	return ret;
+}
+
+static const struct file_operations tegra_drm_fops = {
+	.owner = THIS_MODULE,
+	.open = drm_open,
+	.release = drm_release,
+	.unlocked_ioctl = drm_ioctl,
+	.mmap = tegra_drm_gem_mmap,
+	.poll = drm_poll,
+	.fasync = drm_fasync,
+	.read = drm_read,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl = tegra_compat_ioctl,
+#endif
+	.llseek = noop_llseek,
+};
+
+static int tegra_debugfs_init(struct drm_minor *minor)
+{
+	int ret = 0;
+	dev_dbg(minor->dev->dev, "> %s(minor=%p)\n", __func__, minor);
+	dev_dbg(minor->dev->dev, "< %s() = %d\n", __func__, ret);
+	return ret;
+}
+
+static void tegra_debugfs_cleanup(struct drm_minor *minor)
+{
+	dev_dbg(minor->dev->dev, "> %s(minor=%p)\n", __func__, minor);
+	dev_dbg(minor->dev->dev, "< %s()\n", __func__);
+}
+
+static int tegra_gem_init_object(struct drm_gem_object *obj)
+{
+	int ret = -ENOSYS;
+	dev_dbg(obj->dev->dev, "> %s(obj=%p)\n", __func__, obj);
+	dev_dbg(obj->dev->dev, "< %s() = %d\n", __func__, ret);
+	return ret;
+}
+
+static void tegra_gem_free_object(struct drm_gem_object *obj)
+{
+	struct tegra_gem_object *gem = to_tegra_gem(obj);
+	struct drm_device *drm = obj->dev;
+
+	dev_dbg(drm->dev, "> %s(obj=%p)\n", __func__, obj);
+	dev_dbg(drm->dev, "  map_list: %p\n", obj->map_list.map);
+
+	if (obj->map_list.map)
+		drm_gem_free_mmap_offset(obj);
+
+	tegra_gem_free(obj->dev, gem);
+
+	dev_dbg(drm->dev, "< %s()\n", __func__);
+}
+
+static int tegra_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+	struct drm_gem_object *obj = vma->vm_private_data;
+	struct tegra_gem_object *gem = to_tegra_gem(obj);
+	pgoff_t page_offset;
+	struct page *page;
+	int ret;
+
+	if (!gem->pages)
+		return VM_FAULT_SIGBUS;
+
+	page_offset = ((unsigned long)vmf->virtual_address - vma->vm_start)
+		>> PAGE_SHIFT;
+	page = gem->pages[page_offset];
+
+	ret = vm_insert_page(vma, (unsigned long)vmf->virtual_address, page);
+
+	switch (ret) {
+	case -EAGAIN:
+		set_need_resched();
+		/* fallthrough */
+	case 0:
+	case -ERESTARTSYS:
+	case -EINTR:
+		return VM_FAULT_NOPAGE;
+
+	case -ENOMEM:
+		return VM_FAULT_OOM;
+	}
+
+	return VM_FAULT_SIGBUS;
+}
+
+static struct vm_operations_struct tegra_gem_vm_ops = {
+	.fault = tegra_gem_fault,
+	.open = drm_gem_vm_open,
+	.close = drm_gem_vm_close,
+};
+
+static struct drm_driver drm_driver = {
+	.driver_features = DRIVER_BUS_PLATFORM | DRIVER_MODESET | DRIVER_GEM,
+	.load = tegra_drm_load,
+	.unload = tegra_drm_unload,
+	.open = tegra_drm_open,
+	.lastclose = tegra_drm_lastclose,
+
+	.suspend = tegra_drm_suspend,
+	.resume = tegra_drm_resume,
+
+	.enable_vblank = tegra_drm_enable_vblank,
+	.disable_vblank = tegra_drm_disable_vblank,
+	.reclaim_buffers = drm_core_reclaim_buffers,
+
+#ifdef CONFIG_DEBUG_FS
+	.debugfs_init = tegra_debugfs_init,
+	.debugfs_cleanup = tegra_debugfs_cleanup,
+#endif
+
+	.gem_init_object = tegra_gem_init_object,
+	.gem_free_object = tegra_gem_free_object,
+	.gem_vm_ops = &tegra_gem_vm_ops,
+
+	.dumb_create = tegra_gem_dumb_create,
+	.dumb_map_offset = tegra_gem_dumb_map_offset,
+	.dumb_destroy = tegra_gem_dumb_destroy,
+
+	.ioctls = tegra_drm_ioctls,
+	.num_ioctls = ARRAY_SIZE(tegra_drm_ioctls),
+	.fops = &tegra_drm_fops,
+
+	.name = DRIVER_NAME,
+	.desc = DRIVER_DESC,
+	.date = DRIVER_DATE,
+	.major = DRIVER_MAJOR,
+	.minor = DRIVER_MINOR,
+	.patchlevel = DRIVER_PATCHLEVEL,
+};
+
+static const struct {
+	enum tegra_drm_panel_type type;
+	const char *name;
+} tegra_drm_panel_types[] = {
+	{ TEGRA_DRM_PANEL_RGB, "rgb" },
+};
+
+static int tegra_drm_lookup_panel_type(const char *name)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(tegra_drm_panel_types); i++) {
+		if (strcasecmp(name, tegra_drm_panel_types[i].name) == 0)
+			return tegra_drm_panel_types[i].type;
+	}
+
+	return -EINVAL;
+}
+
+static int tegra_drm_parse_dt_mode(struct device *dev,
+				   struct device_node *node,
+				   struct tegra_drm_mode *mode)
+{
+	u32 resolution[2];
+	u32 timings[4];
+	u32 value;
+	int err;
+
+	err = of_property_read_u32(node, "pixel-clock", &value);
+	if (err < 0)
+		return err;
+
+	mode->pixel_clock = value;
+
+	err = of_property_read_u32(node, "vertical-refresh", &value);
+	if (err < 0)
+		return err;
+
+	mode->vrefresh = value;
+
+	err = of_property_read_u32_array(node, "resolution", resolution,
+					 ARRAY_SIZE(resolution));
+	if (err < 0)
+		return err;
+
+	mode->width = resolution[0];
+	mode->height = resolution[1];
+
+	err = of_property_read_u32(node, "bits-per-pixel", &value);
+	if (err < 0)
+		return err;
+
+	mode->bpp = value;
+
+	err = of_property_read_u32_array(node, "horizontal-timings", timings,
+					 ARRAY_SIZE(timings));
+	if (err < 0)
+		return err;
+
+	mode->href_to_sync = timings[0];
+	mode->hsync_width = timings[1];
+	mode->hback_porch = timings[2];
+	mode->hfront_porch = timings[3];
+
+	err = of_property_read_u32_array(node, "vertical-timings", timings,
+					 ARRAY_SIZE(timings));
+	if (err < 0)
+		return err;
+
+	mode->vref_to_sync = timings[0];
+	mode->vsync_width = timings[1];
+	mode->vback_porch = timings[2];
+	mode->vfront_porch = timings[3];
+
+	return 0;
+}
+
+static int tegra_drm_parse_dt_panel(struct device *dev,
+				    struct device_node *node,
+				    struct tegra_drm_panel *panel)
+{
+	struct tegra_drm_mode *mode;
+	struct device_node *child;
+	unsigned int count = 0;
+	const char *type;
+	u32 sizes[2];
+	int err;
+
+	err = of_property_read_string(node, "type", &type);
+	if (err < 0) {
+		dev_err(dev, "failed to read \"type\" property: %d\n", err);
+		return err;
+	}
+
+	err = tegra_drm_lookup_panel_type(type);
+	if (err < 0) {
+		dev_err(dev, "failed to look up panel type: %d\n", err);
+		return err;
+	}
+
+	panel->type = err;
+
+	err = of_property_read_u32_array(node, "size", sizes,
+					 ARRAY_SIZE(sizes));
+	if (err < 0) {
+		dev_err(dev, "failed to parse \"size\" property: %d\n", err);
+		return err;
+	}
+
+	panel->width = sizes[0];
+	panel->height = sizes[1];
+
+	for_each_child_of_node(node, child)
+		count++;
+
+	if (count == 0) {
+		dev_err(dev, "no modes specified\n");
+		return -EINVAL;
+	}
+
+	panel->modes = devm_kzalloc(dev, count * sizeof(*mode), GFP_KERNEL);
+	if (!panel->modes) {
+		dev_err(dev, "failed to allocate modes\n");
+		return -ENOMEM;
+	}
+
+	for_each_child_of_node(node, child) {
+		mode = &panel->modes[panel->num_modes];
+
+		err = tegra_drm_parse_dt_mode(dev, child, mode);
+		if (err < 0) {
+			dev_err(dev, "tegra_drm_parse_dt_mode(): %d\n", err);
+			continue;
+		}
+
+		panel->num_modes++;
+	}
+
+	return 0;
+}
+
+static int tegra_drm_parse_dt(struct platform_device *pdev)
+{
+	struct tegra_drm_platform_data *pdata;
+	struct device *dev = &pdev->dev;
+	struct tegra_drm_panel *panel;
+	struct device_node *child;
+	unsigned int count = 0;
+	unsigned int i, j;
+	int err;
+
+	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return -ENOMEM;
+
+	for_each_child_of_node(dev->of_node, child)
+		count++;
+
+	if (count == 0) {
+		dev_err(dev, "no panel definitions found\n");
+		return -EINVAL;
+	}
+
+	pdata->panels = devm_kzalloc(dev, count * sizeof(*panel), GFP_KERNEL);
+	if (!pdata->panels) {
+		dev_err(dev, "failed to allocate panels\n");
+		return -ENOMEM;
+	}
+
+	for_each_child_of_node(dev->of_node, child) {
+		panel = &pdata->panels[pdata->num_panels];
+
+		err = tegra_drm_parse_dt_panel(&pdev->dev, child, panel);
+		if (err < 0) {
+			dev_err(dev, "tegra_drm_parse_dt_panel(): %d\n", err);
+			continue;
+		}
+
+		pdata->num_panels++;
+	}
+
+	for (i = 0; i < pdata->num_panels; i++) {
+		struct tegra_drm_panel *panel = &pdata->panels[i];
+
+		dev_dbg(dev, "panel %u:\n", i);
+		dev_dbg(dev, "  type: %d\n", panel->type);
+		dev_dbg(dev, "  size: %ux%u\n", panel->width, panel->height);
+
+		for (j = 0; j < panel->num_modes; j++) {
+			struct tegra_drm_mode *mode = &panel->modes[j];
+
+			dev_dbg(dev, "  mode: %u\n", j);
+			dev_dbg(dev, "    pixel-clock: %u\n", mode->pixel_clock);
+			dev_dbg(dev, "    resolution: %ux%ux%u\n",
+				 mode->width, mode->height, mode->bpp);
+
+			dev_dbg(dev, "    horizontal timings:\n");
+			dev_dbg(dev, "      ref-to-sync: %u\n", mode->href_to_sync);
+			dev_dbg(dev, "      sync-width: %u\n", mode->hsync_width);
+			dev_dbg(dev, "      back porch: %u\n", mode->hback_porch);
+			dev_dbg(dev, "      front porch: %u\n", mode->hfront_porch);
+
+			dev_dbg(dev, "    vertical timings:\n");
+			dev_dbg(dev, "      ref-to-sync: %u\n", mode->vref_to_sync);
+			dev_dbg(dev, "      sync-width: %u\n", mode->vsync_width);
+			dev_dbg(dev, "      back porch: %u\n", mode->vback_porch);
+			dev_dbg(dev, "      front porch: %u\n", mode->vfront_porch);
+		}
+	}
+
+	dev->platform_data = pdata;
+	return 0;
+}
+
+static int __devinit tegra_drm_probe(struct platform_device *pdev)
+{
+	struct tegra_drm_platform_data *pdata = pdev->dev.platform_data;
+	struct device_node *node = pdev->dev.of_node;
+	int err;
+
+	dev_dbg(&pdev->dev, "> %s(pdev=%p)\n", __func__, pdev);
+
+	if (!pdata && node) {
+		err = tegra_drm_parse_dt(pdev);
+		if (err < 0)
+			goto out;
+	}
+
+	err = drm_platform_init(&drm_driver, pdev);
+
+out:
+	dev_dbg(&pdev->dev, "< %s() = %d\n", __func__, err);
+	return err;
+}
+
+static int __devexit tegra_drm_remove(struct platform_device *pdev)
+{
+	dev_dbg(&pdev->dev, "> %s(pdev=%p)\n", __func__, pdev);
+
+	drm_platform_exit(&drm_driver, pdev);
+	pdev->dev.platform_data = NULL;
+
+	dev_dbg(&pdev->dev, "< %s()\n", __func__);
+	return 0;
+}
+
+#ifdef CONFIG_OF
+static struct of_device_id tegra_drm_of_match[] __devinitdata = {
+	{ .compatible = "nvidia,tegra20-drm", },
+	{ },
+};
+#endif
+
+static struct platform_driver tegra_drm_driver = {
+	.driver = {
+		.name = "tegra-drm",
+		.owner = THIS_MODULE,
+		.of_match_table = of_match_ptr(tegra_drm_of_match),
+	},
+	.probe = tegra_drm_probe,
+	.remove = __devexit_p(tegra_drm_remove),
+};
+
+module_platform_driver(tegra_drm_driver);
+
+MODULE_AUTHOR("Thierry Reding <thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/tegra/tegra_drv.h b/drivers/gpu/drm/tegra/tegra_drv.h
new file mode 100644
index 0000000..c0ab341
--- /dev/null
+++ b/drivers/gpu/drm/tegra/tegra_drv.h
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2012 Avionic Design GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef TEGRA_DRV_H
+#define TEGRA_DRV_H
+
+#define CMD_GENERAL_INCR_SYNCPT_CTRL 0x001
+#define CMD_CONT_SYNCPT_VSYNC 0x028
+#define CMD_DISP_CMD 0x032
+#define CMD_DISP_CMD_CTRL_MODE_STOP (0 << 5)
+#define CMD_DISP_CMD_CTRL_MODE_C_DISPLAY (1 << 5)
+#define CMD_DISP_CMD_CTRL_MODE_NC_DISPLAY (2 << 5)
+#define CMD_DISP_POWER_CTRL 0x036
+#define CMD_DISP_POWER_CTRL_PW0_ENABLE (1 <<  0)
+#define CMD_DISP_POWER_CTRL_PW1_ENABLE (1 <<  2)
+#define CMD_DISP_POWER_CTRL_PW2_ENABLE (1 <<  4)
+#define CMD_DISP_POWER_CTRL_PW3_ENABLE (1 <<  6)
+#define CMD_DISP_POWER_CTRL_PW4_ENABLE (1 <<  8)
+#define CMD_DISP_POWER_CTRL_PM0_ENABLE (1 << 16)
+#define CMD_DISP_POWER_CTRL_PM1_ENABLE (1 << 18)
+
+#define CMD_INT_STATUS 0x037
+#define CMD_INT_MASK 0x038
+#define CMD_INT_ENABLE 0x039
+#define CMD_INT_TYPE 0x03a
+#define CMD_INT_POLARITY 0x03b
+#define INT_FRAME_END (1 << 1)
+#define INT_VBLANK (1 << 2)
+#define INT_WIN_A_UF (1 << 8)
+#define INT_WIN_B_UF (1 << 9)
+#define INT_WIN_C_UF (1 << 10)
+#define INT_WIN_A_OF (1 << 14)
+#define INT_WIN_B_OF (1 << 15)
+#define INT_WIN_C_OF (1 << 16)
+
+#define COM_PIN_OUTPUT_ENABLE(x) (0x302 + (x))
+#define COM_PIN_OUTPUT_POLARITY(x) (0x306 + (x))
+#define COM_PIN_OUTPUT_DATA(x) (0x30a + (x))
+#define COM_PIN_OUTPUT_SEL(x) (0x314 + (x))
+
+#define COM_PIN_OUTPUT_POLARITY_PIN1_LVS_OUTPUT (1 << 28)
+#define COM_PIN_OUTPUT_POLARITY_PIN1_LHS_OUTPUT (1 << 30)
+
+#define DISP_MEM_HIGH_PRI 0x403
+#define DISP_MEM_HIGH_PRI_TIMER 0x404
+#define DISP_TIMING_OPT 0x405
+#define DISP_REF_TO_SYNC 0x406
+#define DISP_SYNC_WIDTH 0x407
+#define DISP_BACK_PORCH 0x408
+#define DISP_ACTIVE 0x409
+#define DISP_FRONT_PORCH 0x40a
+
+#define DISP_DATA_ENABLE_OPT 0x432
+#define DISP_DATA_ENABLE_OPT_SELECT_ACTIVE_BLANK (0 << 0)
+#define DISP_DATA_ENABLE_OPT_SELECT_ACTIVE (1 << 0)
+#define DISP_DATA_ENABLE_OPT_SELECT_ACTIVE_IS (2 << 0)
+#define DISP_DATA_ENABLE_OPT_CONTROL_ONECLK (0 << 2)
+#define DISP_DATA_ENABLE_OPT_CONTROL_NORMAL (1 << 2)
+#define DISP_DATA_ENABLE_OPT_CONTROL_EARLY_EXT (2 << 2)
+#define DISP_DATA_ENABLE_OPT_CONTROL_EARLY (3 << 2)
+#define DISP_DATA_ENABLE_OPT_CONTROL_ACTIVE_BLANK (4 << 2)
+
+#define DISP_INTERFACE_CTRL 0x42f
+#define DISP_INTERFACE_CTRL_DATA_FORMAT_DF1P1C (0 << 0)
+#define DISP_INTERFACE_CTRL_DATA_FORMAT_DF1P2C24B (1 << 0)
+#define DISP_INTERFACE_CTRL_DATA_FORMAT_DF1P2C18B (2 << 0)
+#define DISP_INTERFACE_CTRL_DATA_FORMAT_DF1P2C16B (3 << 0)
+#define DISP_INTERFACE_CTRL_DATA_FORMAT_DF2S (4 << 0)
+#define DISP_INTERFACE_CTRL_DATA_FORMAT_DF3S (5 << 0)
+#define DISP_INTERFACE_CTRL_DATA_FORMAT_DFSPI (6 << 0)
+#define DISP_INTERFACE_CTRL_DATA_FORMAT_DF1P3C24B (7 << 0)
+#define DISP_INTERFACE_CTRL_DATA_FORMAT_DF1P3C18B (8 << 0)
+#define DISP_INTERFACE_CTRL_ALIGN_MSB (0 << 8)
+#define DISP_INTERFACE_CTRL_ALIGN_LSB (1 << 8)
+#define DISP_INTERFACE_CTRL_ORDER_RED_BLUE (0 << 9)
+#define DISP_INTERFACE_CTRL_ORDER_BLUE_RED (1 << 9)
+
+#define DISP_SHIFT_CLK_OPT 0x431
+
+#define DISP_CLK_CTRL 0x42e
+#define DISP_CLK_CTRL_PIXEL_CLK_DIV_PCD1 (0 << 8)
+#define DISP_CLK_CTRL_PIXEL_CLK_DIV_PCD1H (1 << 8)
+#define DISP_CLK_CTRL_PIXEL_CLK_DIV_PCD2 (2 << 8)
+#define DISP_CLK_CTRL_PIXEL_CLK_DIV_PCD3 (3 << 8)
+#define DISP_CLK_CTRL_PIXEL_CLK_DIV_PCD4 (4 << 8)
+#define DISP_CLK_CTRL_PIXEL_CLK_DIV_PCD6 (5 << 8)
+#define DISP_CLK_CTRL_PIXEL_CLK_DIV_PCD8 (6 << 8)
+#define DISP_CLK_CTRL_PIXEL_CLK_DIV_PCD9 (7 << 8)
+#define DISP_CLK_CTRL_PIXEL_CLK_DIV_PCD12 (8 << 8)
+#define DISP_CLK_CTRL_PIXEL_CLK_DIV_PCD16 (9 << 8)
+#define DISP_CLK_CTRL_PIXEL_CLK_DIV_PCD18 (10 << 8)
+#define DISP_CLK_CTRL_PIXEL_CLK_DIV_PCD24 (11 << 8)
+#define DISP_CLK_CTRL_PIXEL_CLK_DIV_PCD13 (12 << 8)
+#define DISP_CLK_CTRL_CLK_DIV(x) ((x) & 0xff)
+
+#define CMD_WIN_HEADER 0x042
+#define CMD_WIN_HEADER_WINDOW_A_SELECT (1 << 4)
+#define CMD_WIN_HEADER_WINDOW_B_SELECT (1 << 5)
+#define CMD_WIN_HEADER_WINDOW_C_SELECT (1 << 6)
+
+#define WIN_COLOR_DEPTH 0x703
+#define WIN_COLOR_DEPTH_P1 0
+#define WIN_COLOR_DEPTH_P2 1
+#define WIN_COLOR_DEPTH_P4 2
+#define WIN_COLOR_DEPTH_P8 3
+#define WIN_COLOR_DEPTH_B4G4R4A4 4
+#define WIN_COLOR_DEPTH_B5G5R5A 5
+#define WIN_COLOR_DEPTH_B5G6R5 6
+#define WIN_COLOR_DEPTH_AB5G5R5 7
+#define WIN_COLOR_DEPTH_B8G8R8A8 12
+#define WIN_COLOR_DEPTH_R8G8B8A8 13
+#define WIN_COLOR_DEPTH_B6x2G6x2R6x2A8 14
+#define WIN_COLOR_DEPTH_R6x2G6x2B6x2A8 15
+#define WIN_COLOR_DEPTH_YCbCr422 16
+#define WIN_COLOR_DEPTH_YUV422 17
+#define WIN_COLOR_DEPTH_YCbCr420P 18
+#define WIN_COLOR_DEPTH_YUV420P 19
+#define WIN_COLOR_DEPTH_YCbCr422P 20
+#define WIN_COLOR_DEPTH_YUV422P 21
+#define WIN_COLOR_DEPTH_YCbCr422R 22
+#define WIN_COLOR_DEPTH_YUV422R 23
+#define WIN_COLOR_DEPTH_YCbCr422RA 24
+#define WIN_COLOR_DEPTH_YUV422RA 25
+
+#define WIN_BYTE_SWAP 0x701
+#define WIN_BYTE_SWAP_NOSWAP (0 << 0)
+#define WIN_BYTE_SWAP_SWAP2 (1 << 0)
+#define WIN_BYTE_SWAP_SWAP4 (2 << 0)
+#define WIN_BYTE_SWAP_SWAP4HW (3 << 0)
+
+#define WIN_POSITION 0x704
+#define WIN_POSITION_H(x) (((x) & 0x1fff) <<  0)
+#define WIN_POSITION_V(x) (((x) & 0x1fff) << 16)
+
+#define WIN_SIZE 0x705
+#define WIN_SIZE_H(x) (((x) & 0x1fff) <<  0)
+#define WIN_SIZE_V(x) (((x) & 0x1fff) << 16)
+
+#define WIN_PRESCALED_SIZE 0x706
+#define WIN_PRESCALED_SIZE_H(x) (((x) & 0x7fff) <<  0)
+#define WIN_PRESCALED_SIZE_V(x) (((x) & 0x1fff) << 16)
+
+#define WIN_H_INITIAL_DDA 0x707
+#define WIN_V_INITIAL_DDA 0x708
+
+#define WIN_DDA_INC 0x709
+#define WIN_DDA_INC_H(x) (((x) & 0xffff) <<  0)
+#define WIN_DDA_INC_V(x) (((x) & 0xffff) << 16)
+
+#define WIN_LINE_STRIDE 0x70a
+#define WIN_BUF_STRIDE 0x70b
+#define WIN_UV_BUF_STRIDE 0x70c
+
+#define WIN_OPT 0x700
+#define WIN_OPT_COLOR_EXPAND (1 << 6)
+#define WIN_OPT_ENABLE (1 << 30)
+
+#define WINBUF_START_ADDR 0x800
+#define WINBUF_ADDR_H_OFFSET 0x806
+#define WINBUF_ADDR_V_OFFSET 0x808
+
+#define WIN_BLEND_NOKEY 0x70f
+#define WIN_BLEND_1WIN 0x710
+
+#define CMD_STATE_CTRL 0x041
+#define CMD_STATE_CTRL_GENERAL_ACT_REQ	(1 <<  0)
+#define CMD_STATE_CTRL_WIN_A_ACT_REQ	(1 <<  1)
+#define CMD_STATE_CTRL_WIN_B_ACT_REQ	(1 <<  2)
+#define CMD_STATE_CTRL_WIN_C_ACT_REQ	(1 <<  3)
+#define CMD_STATE_CTRL_GENERAL_UPDATE	(1 <<  8)
+#define CMD_STATE_CTRL_WIN_A_UPDATE	(1 <<  9)
+#define CMD_STATE_CTRL_WIN_B_UPDATE	(1 << 10)
+#define CMD_STATE_CTRL_WIN_C_UPDATE	(1 << 11)
+
+/* synchronization points */
+#define SYNCPT_VBLANK0 26
+#define SYNCPT_VBLANK1 27
+
+#endif /* TEGRA_DRV_H */
diff --git a/include/drm/tegra_drm.h b/include/drm/tegra_drm.h
new file mode 100644
index 0000000..b3dd44a
--- /dev/null
+++ b/include/drm/tegra_drm.h
@@ -0,0 +1,44 @@
+#ifndef _TEGRA_DRM_H_
+#define _TEGRA_DRM_H_
+
+enum tegra_drm_panel_type {
+	TEGRA_DRM_PANEL_RGB,
+};
+
+struct tegra_drm_mode {
+	unsigned int pixel_clock;
+	unsigned int vrefresh;
+
+	unsigned int width;
+	unsigned int height;
+	unsigned int bpp;
+
+	unsigned int href_to_sync;
+	unsigned int hsync_width;
+	unsigned int hback_porch;
+	unsigned int hfront_porch;
+
+	unsigned int vref_to_sync;
+	unsigned int vsync_width;
+	unsigned int vback_porch;
+	unsigned int vfront_porch;
+};
+
+struct tegra_drm_panel {
+	enum tegra_drm_panel_type type;
+
+	/* physical size */
+	unsigned int width;
+	unsigned int height;
+
+	/* display modes */
+	struct tegra_drm_mode *modes;
+	unsigned int num_modes;
+};
+
+struct tegra_drm_platform_data {
+	struct tegra_drm_panel *panels;
+	unsigned int num_panels;
+};
+
+#endif
-- 
1.7.10

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 0/4] Add NVIDIA Tegra DRM support
       [not found] ` <1334146230-1795-1-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
                     ` (3 preceding siblings ...)
  2012-04-11 12:10   ` [RFC 4/4] drm: Add NVIDIA Tegra support Thierry Reding
@ 2012-04-11 12:25   ` Alan Cox
       [not found]     ` <20120411132548.7d738b42-38n7/U1jhRXW96NNrWNlrekiAK3p4hvP@public.gmane.org>
  2012-04-11 12:46   ` Hiroshi Doyu
  2012-04-19 17:35   ` Thierry Reding
  6 siblings, 1 reply; 65+ messages in thread
From: Alan Cox @ 2012-04-11 12:25 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Stephen Warren, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Jon Mayo,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA

On Wed, 11 Apr 2012 14:10:26 +0200
Thierry Reding <thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org> wrote:

> This series adds a basic DRM driver for NVIDIA Tegra 2 processors. It
> currently only supports the RGB output and I've successfully tested it
> against the fbcon kernel module and the xf86-video-modesetting driver.
> The code uses the Tegra's IOMMU/GART to remap non-contiguous memory.
> This means that currently video memory is limited to 32 MB, the size of
> the GART aperture.

You should only need continguous memory with GEM for the framebuffer /
console bits via /dev/fb. In theory the fb layer can be taught to hanndle
non linear framebuffers but nobody has yet done so. (Now there's a GSOC
project ... ;))

What we do on GMA500 is to allocate the kernel framebuffer from linearly
mapped memory but the normal GEM objects from anywhere as the GEM mapping
into userspace will deal with presenting it to user space as a virtually
linear buffer.

Alan

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 0/4] Add NVIDIA Tegra DRM support
       [not found] ` <1334146230-1795-1-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
                     ` (4 preceding siblings ...)
  2012-04-11 12:25   ` [RFC 0/4] Add NVIDIA Tegra DRM support Alan Cox
@ 2012-04-11 12:46   ` Hiroshi Doyu
       [not found]     ` <20120411.154642.1389197434468515943.hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  2012-04-19 17:35   ` Thierry Reding
  6 siblings, 1 reply; 65+ messages in thread
From: Hiroshi Doyu @ 2012-04-11 12:46 UTC (permalink / raw)
  To: thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB,
	joerg.roedel-5C7GfCeVMHo,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
  Cc: swarren-3lzwWm7+Weoh9ZMKESR00Q, airlied-cv59FeDIM0c,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	olof-nZhT3qVonbNeoWH0uzbU5w,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	ccross-z5hGa2qSFaRBDgjK7y7TUQ,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jon Mayo

From: Thierry Reding <thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
Subject: [RFC 0/4] Add NVIDIA Tegra DRM support
Date: Wed, 11 Apr 2012 14:10:26 +0200
Message-ID: 
 <1334146230-1795-1-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>

> This series adds a basic DRM driver for NVIDIA Tegra 2 processors. It
> currently only supports the RGB output and I've successfully tested it
> against the fbcon kernel module and the xf86-video-modesetting driver.
> The code uses the Tegra's IOMMU/GART to remap non-contiguous memory.
> This means that currently video memory is limited to 32 MB, the size of
> the GART aperture.
> 
> Note that this is very early work-in-progress and there is a lot of room
> for improvement and cleanup. You'll also note that there is still a
> whole lot of debugging output, most of which is disabled by default.
> 
> However I explicitly wanted to post this early to get feedback and to
> discuss options on how to get this included in the mainline kernel. I
> have been in contact with some people at NVIDIA and they seem to be
> willing to work together on a solution that satisfies both their
> requirements and those of the community.
> 
> Thierry
> 
> Thierry Reding (3):
>   iommu: tegra/gart: Add device tree support
>   drm: fixed: Add dfixed_frac() macro
>   drm: Add NVIDIA Tegra support
> 
> Vandana Salve (1):
>   iommu: tegra/gart: use correct gart_device

I guess that the following 2 patches can be merged now, independet of
the rest of drm patches.

  [RFC 1/4] iommu: tegra/gart: use correct gart_device
  [RFC 2/4] iommu: tegra/gart: Add device tree support

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]     ` <1334146230-1795-5-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
@ 2012-04-11 12:48       ` Daniel Vetter
       [not found]         ` <20120411124810.GK4296-dv86pmgwkMBes7Z6vYuT8azUEOm+Xw19@public.gmane.org>
  2012-04-11 18:12       ` Stephen Warren
  1 sibling, 1 reply; 65+ messages in thread
From: Daniel Vetter @ 2012-04-11 12:48 UTC (permalink / raw)
  To: Thierry Reding
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Stephen Warren, Joerg Roedel,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Jon Mayo,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	Hiroshi Doyu

On Wed, Apr 11, 2012 at 02:10:30PM +0200, Thierry Reding wrote:
> This commit adds a very basic DRM driver for NVIDIA Tegra SoCs. It
> currently has rudimentary GEM support and can run a console on the
> framebuffer as well as X using the xf86-video-modesetting driver.
> Only the RGB output is supported. Quite a lot of things still need
> to be worked out and there is a lot of room for cleanup.

Indeed, after a quick look there are tons of functions that are just stubs
;-) One thing I wonder though is why you directly use the iommu api and
not wrap it up into dma_map? Is arm infrastructure just not there yet or
do you plan to tightly integrate the tegra drm with the iommu (e.g. for
process space switching or similarly funky stuff)?

Yours, Daniel
-- 
Daniel Vetter
Mail: daniel-/w4YWyX8dFk@public.gmane.org
Mobile: +41 (0)79 365 57 48

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]         ` <20120411124810.GK4296-dv86pmgwkMBes7Z6vYuT8azUEOm+Xw19@public.gmane.org>
@ 2012-04-11 13:23           ` Thierry Reding
       [not found]             ` <20120411132326.GD27337-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
  2012-04-12 18:56           ` Jon Mayo
  1 sibling, 1 reply; 65+ messages in thread
From: Thierry Reding @ 2012-04-11 13:23 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Stephen Warren, Joerg Roedel,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Jon Mayo,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	Hiroshi Doyu

[-- Attachment #1: Type: text/plain, Size: 988 bytes --]

* Daniel Vetter wrote:
> On Wed, Apr 11, 2012 at 02:10:30PM +0200, Thierry Reding wrote:
> > This commit adds a very basic DRM driver for NVIDIA Tegra SoCs. It
> > currently has rudimentary GEM support and can run a console on the
> > framebuffer as well as X using the xf86-video-modesetting driver.
> > Only the RGB output is supported. Quite a lot of things still need
> > to be worked out and there is a lot of room for cleanup.
> 
> Indeed, after a quick look there are tons of functions that are just stubs
> ;-) One thing I wonder though is why you directly use the iommu api and
> not wrap it up into dma_map? Is arm infrastructure just not there yet or
> do you plan to tightly integrate the tegra drm with the iommu (e.g. for
> process space switching or similarly funky stuff)?

I'm not sure I know what you are referring to. Looking for all users of
iommu_map() doesn't turn up anything related to dma_map. Can you point me in
the right direction?

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 0/4] Add NVIDIA Tegra DRM support
       [not found]     ` <20120411.154642.1389197434468515943.hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
@ 2012-04-11 13:24       ` Thierry Reding
  0 siblings, 0 replies; 65+ messages in thread
From: Thierry Reding @ 2012-04-11 13:24 UTC (permalink / raw)
  To: Hiroshi Doyu
  Cc: swarren-3lzwWm7+Weoh9ZMKESR00Q, airlied-cv59FeDIM0c,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	olof-nZhT3qVonbNeoWH0uzbU5w,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	ccross-z5hGa2qSFaRBDgjK7y7TUQ,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jon Mayo


[-- Attachment #1.1: Type: text/plain, Size: 733 bytes --]

* Hiroshi Doyu wrote:
> From: Thierry Reding <thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
[...]
> > Thierry Reding (3):
> >   iommu: tegra/gart: Add device tree support
> >   drm: fixed: Add dfixed_frac() macro
> >   drm: Add NVIDIA Tegra support
> > 
> > Vandana Salve (1):
> >   iommu: tegra/gart: use correct gart_device
> 
> I guess that the following 2 patches can be merged now, independet of
> the rest of drm patches.
> 
>   [RFC 1/4] iommu: tegra/gart: use correct gart_device
>   [RFC 2/4] iommu: tegra/gart: Add device tree support

Yes, I can probably post those separately so they can be applied
independently. Should they go in via the IOMMU tree or the Tegra
tree?

Thierry

[-- Attachment #1.2: Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 190 bytes --]

_______________________________________________
iommu mailing list
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]             ` <20120411132326.GD27337-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
@ 2012-04-11 13:35               ` Daniel Vetter
       [not found]                 ` <20120411133512.GL4296-dv86pmgwkMBes7Z6vYuT8azUEOm+Xw19@public.gmane.org>
  0 siblings, 1 reply; 65+ messages in thread
From: Daniel Vetter @ 2012-04-11 13:35 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Daniel Vetter, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	Stephen Warren, Joerg Roedel,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Jon Mayo,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	Hiroshi Doyu

On Wed, Apr 11, 2012 at 03:23:26PM +0200, Thierry Reding wrote:
> * Daniel Vetter wrote:
> > On Wed, Apr 11, 2012 at 02:10:30PM +0200, Thierry Reding wrote:
> > > This commit adds a very basic DRM driver for NVIDIA Tegra SoCs. It
> > > currently has rudimentary GEM support and can run a console on the
> > > framebuffer as well as X using the xf86-video-modesetting driver.
> > > Only the RGB output is supported. Quite a lot of things still need
> > > to be worked out and there is a lot of room for cleanup.
> > 
> > Indeed, after a quick look there are tons of functions that are just stubs
> > ;-) One thing I wonder though is why you directly use the iommu api and
> > not wrap it up into dma_map? Is arm infrastructure just not there yet or
> > do you plan to tightly integrate the tegra drm with the iommu (e.g. for
> > process space switching or similarly funky stuff)?
> 
> I'm not sure I know what you are referring to. Looking for all users of
> iommu_map() doesn't turn up anything related to dma_map. Can you point me in
> the right direction?

Well, you use the iommu api to map/unmap memory into the iommu for tegra,
whereas usually device drivers just use the dma api to do that. The usual
interface is dma_map_sg/dma_unmap_sg, but there are quite a few variants
around. I'm just wondering why this you've choosen this.
-Daniel
-- 
Daniel Vetter
Mail: daniel-/w4YWyX8dFk@public.gmane.org
Mobile: +41 (0)79 365 57 48

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 0/4] Add NVIDIA Tegra DRM support
       [not found]     ` <20120411132548.7d738b42-38n7/U1jhRXW96NNrWNlrekiAK3p4hvP@public.gmane.org>
@ 2012-04-11 13:35       ` Thierry Reding
  0 siblings, 0 replies; 65+ messages in thread
From: Thierry Reding @ 2012-04-11 13:35 UTC (permalink / raw)
  To: Alan Cox
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Stephen Warren, Joerg Roedel,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Jon Mayo,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	Hiroshi Doyu

[-- Attachment #1: Type: text/plain, Size: 1648 bytes --]

* Alan Cox wrote:
> On Wed, 11 Apr 2012 14:10:26 +0200
> Thierry Reding <thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org> wrote:
> 
> > This series adds a basic DRM driver for NVIDIA Tegra 2 processors. It
> > currently only supports the RGB output and I've successfully tested it
> > against the fbcon kernel module and the xf86-video-modesetting driver.
> > The code uses the Tegra's IOMMU/GART to remap non-contiguous memory.
> > This means that currently video memory is limited to 32 MB, the size of
> > the GART aperture.
> 
> You should only need continguous memory with GEM for the framebuffer /
> console bits via /dev/fb. In theory the fb layer can be taught to hanndle
> non linear framebuffers but nobody has yet done so. (Now there's a GSOC
> project ... ;))
> 
> What we do on GMA500 is to allocate the kernel framebuffer from linearly
> mapped memory but the normal GEM objects from anywhere as the GEM mapping
> into userspace will deal with presenting it to user space as a virtually
> linear buffer.

That's actually what the driver does as well. It uses the shmfs-backed memory
provided by GEM and only maps it through the GART to provide a linear view
for the display controller which cannot do scatter-gather I/O. Neither the
kernel nor the user-space mapping go through the GART.

You are right that for anything but the framebuffer objects it probably
doesn't matter. It's a little hard to tell because I don't have any
documentation for either the 2D nor 3D engines. Eventually a better option
might be to use stolen memory instead of remapping it through the GART.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]                 ` <20120411133512.GL4296-dv86pmgwkMBes7Z6vYuT8azUEOm+Xw19@public.gmane.org>
@ 2012-04-11 14:11                   ` Thierry Reding
       [not found]                     ` <20120411141108.GI27337-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
  0 siblings, 1 reply; 65+ messages in thread
From: Thierry Reding @ 2012-04-11 14:11 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Stephen Warren, Joerg Roedel,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Jon Mayo,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	Hiroshi Doyu

[-- Attachment #1: Type: text/plain, Size: 1904 bytes --]

* Daniel Vetter wrote:
> On Wed, Apr 11, 2012 at 03:23:26PM +0200, Thierry Reding wrote:
> > * Daniel Vetter wrote:
> > > On Wed, Apr 11, 2012 at 02:10:30PM +0200, Thierry Reding wrote:
> > > > This commit adds a very basic DRM driver for NVIDIA Tegra SoCs. It
> > > > currently has rudimentary GEM support and can run a console on the
> > > > framebuffer as well as X using the xf86-video-modesetting driver.
> > > > Only the RGB output is supported. Quite a lot of things still need
> > > > to be worked out and there is a lot of room for cleanup.
> > > 
> > > Indeed, after a quick look there are tons of functions that are just stubs
> > > ;-) One thing I wonder though is why you directly use the iommu api and
> > > not wrap it up into dma_map? Is arm infrastructure just not there yet or
> > > do you plan to tightly integrate the tegra drm with the iommu (e.g. for
> > > process space switching or similarly funky stuff)?
> > 
> > I'm not sure I know what you are referring to. Looking for all users of
> > iommu_map() doesn't turn up anything related to dma_map. Can you point me in
> > the right direction?
> 
> Well, you use the iommu api to map/unmap memory into the iommu for tegra,
> whereas usually device drivers just use the dma api to do that. The usual
> interface is dma_map_sg/dma_unmap_sg, but there are quite a few variants
> around. I'm just wondering why this you've choosen this.

I don't think this works on ARM. Maybe I'm not seeing the whole picture but
judging by a quick look through the kernel tree there aren't any users that
map DMA memory through an IOMMU.

Maybe your question is answered by my reply to Alan's comment. The mapping
is actually done to get a linear view for the display controller which
doesn't support SG transfers. The kernel and user-space already have virtual
linear buffers.

Perhaps I'm being dense?

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]                     ` <20120411141108.GI27337-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
@ 2012-04-11 14:34                       ` Daniel Vetter
       [not found]                         ` <20120411143456.GM4296-dv86pmgwkMBes7Z6vYuT8azUEOm+Xw19@public.gmane.org>
  2012-04-11 14:52                       ` Alan Cox
  2012-04-11 15:18                       ` Arnd Bergmann
  2 siblings, 1 reply; 65+ messages in thread
From: Daniel Vetter @ 2012-04-11 14:34 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Daniel Vetter, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	Stephen Warren, Joerg Roedel,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Jon Mayo,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	Hiroshi Doyu

On Wed, Apr 11, 2012 at 04:11:08PM +0200, Thierry Reding wrote:
> * Daniel Vetter wrote:
> > On Wed, Apr 11, 2012 at 03:23:26PM +0200, Thierry Reding wrote:
> > > * Daniel Vetter wrote:
> > > > On Wed, Apr 11, 2012 at 02:10:30PM +0200, Thierry Reding wrote:
> > > > > This commit adds a very basic DRM driver for NVIDIA Tegra SoCs. It
> > > > > currently has rudimentary GEM support and can run a console on the
> > > > > framebuffer as well as X using the xf86-video-modesetting driver.
> > > > > Only the RGB output is supported. Quite a lot of things still need
> > > > > to be worked out and there is a lot of room for cleanup.
> > > > 
> > > > Indeed, after a quick look there are tons of functions that are just stubs
> > > > ;-) One thing I wonder though is why you directly use the iommu api and
> > > > not wrap it up into dma_map? Is arm infrastructure just not there yet or
> > > > do you plan to tightly integrate the tegra drm with the iommu (e.g. for
> > > > process space switching or similarly funky stuff)?
> > > 
> > > I'm not sure I know what you are referring to. Looking for all users of
> > > iommu_map() doesn't turn up anything related to dma_map. Can you point me in
> > > the right direction?
> > 
> > Well, you use the iommu api to map/unmap memory into the iommu for tegra,
> > whereas usually device drivers just use the dma api to do that. The usual
> > interface is dma_map_sg/dma_unmap_sg, but there are quite a few variants
> > around. I'm just wondering why this you've choosen this.
> 
> I don't think this works on ARM. Maybe I'm not seeing the whole picture but
> judging by a quick look through the kernel tree there aren't any users that
> map DMA memory through an IOMMU.
> 
> Maybe your question is answered by my reply to Alan's comment. The mapping
> is actually done to get a linear view for the display controller which
> doesn't support SG transfers. The kernel and user-space already have virtual
> linear buffers.

Hm, in that case it looks like your iommu works more like the gtt on intel
chips and less like the iommu on intel platforms (which we access through
the dma_map api). I wonder whether that will end up in some layering fun
together with dma_buf, which conceptually is at the same level as the dma
api, which usually uses an underlying iommu exposed with the iommu api
you're using.

> Perhaps I'm being dense?

Doesn't sound like that over here ;-)
-Daniel
-- 
Daniel Vetter
Mail: daniel-/w4YWyX8dFk@public.gmane.org
Mobile: +41 (0)79 365 57 48

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]                         ` <20120411143456.GM4296-dv86pmgwkMBes7Z6vYuT8azUEOm+Xw19@public.gmane.org>
@ 2012-04-11 14:43                           ` Alan Cox
       [not found]                             ` <20120411154309.1f04fb80-38n7/U1jhRXW96NNrWNlrekiAK3p4hvP@public.gmane.org>
  2012-04-11 15:00                           ` Thierry Reding
  1 sibling, 1 reply; 65+ messages in thread
From: Alan Cox @ 2012-04-11 14:43 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Stephen Warren, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	Thierry Reding, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	Jon Mayo

> Hm, in that case it looks like your iommu works more like the gtt on intel
> chips 

Don't overgeneralize there - on the GMA500/600 the GTT doesn't allow CPU
side access of the GTT map (ie you can't use it to linearise pages for
CPU view) and the 3600 is even stranger....

Alan

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]                             ` <20120411154309.1f04fb80-38n7/U1jhRXW96NNrWNlrekiAK3p4hvP@public.gmane.org>
@ 2012-04-11 14:49                               ` Daniel Vetter
  0 siblings, 0 replies; 65+ messages in thread
From: Daniel Vetter @ 2012-04-11 14:49 UTC (permalink / raw)
  To: Alan Cox
  Cc: Daniel Vetter, Thierry Reding, Stephen Warren, Joerg Roedel,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Jon Mayo,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, Hiroshi Doyu

On Wed, Apr 11, 2012 at 03:43:09PM +0100, Alan Cox wrote:
> > Hm, in that case it looks like your iommu works more like the gtt on intel
> > chips 
> 
> Don't overgeneralize there - on the GMA500/600 the GTT doesn't allow CPU
> side access of the GTT map (ie you can't use it to linearise pages for
> CPU view) and the 3600 is even stranger....

Sorry, I really try to totally ignore everything related to gma500 ;-)
-Daniel
-- 
Daniel Vetter
Mail: daniel-/w4YWyX8dFk@public.gmane.org
Mobile: +41 (0)79 365 57 48

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]                     ` <20120411141108.GI27337-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
  2012-04-11 14:34                       ` Daniel Vetter
@ 2012-04-11 14:52                       ` Alan Cox
       [not found]                         ` <20120411155237.24233afc-38n7/U1jhRXW96NNrWNlrekiAK3p4hvP@public.gmane.org>
  2012-04-11 15:18                       ` Arnd Bergmann
  2 siblings, 1 reply; 65+ messages in thread
From: Alan Cox @ 2012-04-11 14:52 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Stephen Warren, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Daniel Vetter,
	Colin Cross, Jon Mayo

> Maybe your question is answered by my reply to Alan's comment. The mapping
> is actually done to get a linear view for the display controller which
> doesn't support SG transfers. The kernel and user-space already have virtual
> linear buffers.

The framebuffer currently needs a physically contiguous map for the
console devices. Well you could vmap them but that is pretty hideous on a
32bit platform with 32bit 1080p display plugged into it!

Alan

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]                         ` <20120411143456.GM4296-dv86pmgwkMBes7Z6vYuT8azUEOm+Xw19@public.gmane.org>
  2012-04-11 14:43                           ` Alan Cox
@ 2012-04-11 15:00                           ` Thierry Reding
  1 sibling, 0 replies; 65+ messages in thread
From: Thierry Reding @ 2012-04-11 15:00 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Stephen Warren, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Jon Mayo,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA


[-- Attachment #1.1: Type: text/plain, Size: 2955 bytes --]

* Daniel Vetter wrote:
> On Wed, Apr 11, 2012 at 04:11:08PM +0200, Thierry Reding wrote:
> > * Daniel Vetter wrote:
> > > On Wed, Apr 11, 2012 at 03:23:26PM +0200, Thierry Reding wrote:
> > > > * Daniel Vetter wrote:
> > > > > On Wed, Apr 11, 2012 at 02:10:30PM +0200, Thierry Reding wrote:
> > > > > > This commit adds a very basic DRM driver for NVIDIA Tegra SoCs. It
> > > > > > currently has rudimentary GEM support and can run a console on the
> > > > > > framebuffer as well as X using the xf86-video-modesetting driver.
> > > > > > Only the RGB output is supported. Quite a lot of things still need
> > > > > > to be worked out and there is a lot of room for cleanup.
> > > > > 
> > > > > Indeed, after a quick look there are tons of functions that are just stubs
> > > > > ;-) One thing I wonder though is why you directly use the iommu api and
> > > > > not wrap it up into dma_map? Is arm infrastructure just not there yet or
> > > > > do you plan to tightly integrate the tegra drm with the iommu (e.g. for
> > > > > process space switching or similarly funky stuff)?
> > > > 
> > > > I'm not sure I know what you are referring to. Looking for all users of
> > > > iommu_map() doesn't turn up anything related to dma_map. Can you point me in
> > > > the right direction?
> > > 
> > > Well, you use the iommu api to map/unmap memory into the iommu for tegra,
> > > whereas usually device drivers just use the dma api to do that. The usual
> > > interface is dma_map_sg/dma_unmap_sg, but there are quite a few variants
> > > around. I'm just wondering why this you've choosen this.
> > 
> > I don't think this works on ARM. Maybe I'm not seeing the whole picture but
> > judging by a quick look through the kernel tree there aren't any users that
> > map DMA memory through an IOMMU.
> > 
> > Maybe your question is answered by my reply to Alan's comment. The mapping
> > is actually done to get a linear view for the display controller which
> > doesn't support SG transfers. The kernel and user-space already have virtual
> > linear buffers.
> 
> Hm, in that case it looks like your iommu works more like the gtt on intel
> chips and less like the iommu on intel platforms (which we access through
> the dma_map api).

Yes, it's very much like the GTT on Intel chips. In fact I've been using the
gma500 driver as a source for inspiration. Wikipedia confirms that GTT and
GART are synonymous.

> I wonder whether that will end up in some layering fun together with
> dma_buf, which conceptually is at the same level as the dma api, which
> usually uses an underlying iommu exposed with the iommu api you're using.

That's odd. The only users of the IOMMU API that I can find in the kernel
tree are in drivers/remoteproc and drivers/media/video/omap3isp. And omap3isp
doesn't do any actual mapping at a quick glance. Can you point me to where
this is hooked up with the Intel IOMMU?

Thierry

[-- Attachment #1.2: Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 190 bytes --]

_______________________________________________
iommu mailing list
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]                         ` <20120411155237.24233afc-38n7/U1jhRXW96NNrWNlrekiAK3p4hvP@public.gmane.org>
@ 2012-04-11 15:06                           ` Thierry Reding
       [not found]                             ` <20120411150603.GC20811-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
  0 siblings, 1 reply; 65+ messages in thread
From: Thierry Reding @ 2012-04-11 15:06 UTC (permalink / raw)
  To: Alan Cox
  Cc: Joerg Roedel, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Daniel Vetter,
	Colin Cross, Jon Mayo, Hiroshi Doyu


[-- Attachment #1.1: Type: text/plain, Size: 672 bytes --]

* Alan Cox wrote:
> > Maybe your question is answered by my reply to Alan's comment. The mapping
> > is actually done to get a linear view for the display controller which
> > doesn't support SG transfers. The kernel and user-space already have virtual
> > linear buffers.
> 
> The framebuffer currently needs a physically contiguous map for the
> console devices. Well you could vmap them but that is pretty hideous on a
> 32bit platform with 32bit 1080p display plugged into it!

Heh, vmap() is exactly what I do. =) Would you mind explaining why exactly it
is hideous?

I'll have to investigate what an appropriate alternative would look like.

Thierry

[-- Attachment #1.2: Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 192 bytes --]

_______________________________________________
devicetree-discuss mailing list
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
https://lists.ozlabs.org/listinfo/devicetree-discuss

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]                             ` <20120411150603.GC20811-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
@ 2012-04-11 15:11                               ` Alan Cox
  0 siblings, 0 replies; 65+ messages in thread
From: Alan Cox @ 2012-04-11 15:11 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Stephen Warren, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Daniel Vetter,
	Colin Cross, Jon Mayo

> Heh, vmap() is exactly what I do. =) Would you mind explaining why exactly it
> is hideous?

On x86 we don't have a vast amount of address space available for virtual
remappings and the framebuffer then eats over 8MB of it.

The ideal case is that the fb layer can be taught to do page/offset
addressing nicely. At that point we'd be able to attach the text consoles
to arbitary GEM objects.. which means we can do really cool stuff.

Alan

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]                     ` <20120411141108.GI27337-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
  2012-04-11 14:34                       ` Daniel Vetter
  2012-04-11 14:52                       ` Alan Cox
@ 2012-04-11 15:18                       ` Arnd Bergmann
       [not found]                         ` <201204111518.41968.arnd-r2nGTMty4D4@public.gmane.org>
  2 siblings, 1 reply; 65+ messages in thread
From: Arnd Bergmann @ 2012-04-11 15:18 UTC (permalink / raw)
  To: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
  Cc: Thierry Reding, Daniel Vetter, Joerg Roedel,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Jon Mayo,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, Hiroshi Doyu,
	Marek Szyprowski

On Wednesday 11 April 2012, Thierry Reding wrote:
>   * Daniel Vetter wrote:
> > On Wed, Apr 11, 2012 at 03:23:26PM +0200, Thierry Reding wrote:
> > > * Daniel Vetter wrote:
> > > > On Wed, Apr 11, 2012 at 02:10:30PM +0200, Thierry Reding wrote:
> > > > > This commit adds a very basic DRM driver for NVIDIA Tegra SoCs. It
> > > > > currently has rudimentary GEM support and can run a console on the
> > > > > framebuffer as well as X using the xf86-video-modesetting driver.
> > > > > Only the RGB output is supported. Quite a lot of things still need
> > > > > to be worked out and there is a lot of room for cleanup.
> > > > 
> > > > Indeed, after a quick look there are tons of functions that are just stubs
> > > > ;-) One thing I wonder though is why you directly use the iommu api and
> > > > not wrap it up into dma_map? Is arm infrastructure just not there yet or
> > > > do you plan to tightly integrate the tegra drm with the iommu (e.g. for
> > > > process space switching or similarly funky stuff)?
> > > 
> > > I'm not sure I know what you are referring to. Looking for all users of
> > > iommu_map() doesn't turn up anything related to dma_map. Can you point me in
> > > the right direction?
> > 
> > Well, you use the iommu api to map/unmap memory into the iommu for tegra,
> > whereas usually device drivers just use the dma api to do that. The usual
> > interface is dma_map_sg/dma_unmap_sg, but there are quite a few variants
> > around. I'm just wondering why this you've choosen this.
> 
> I don't think this works on ARM. Maybe I'm not seeing the whole picture but
> judging by a quick look through the kernel tree there aren't any users that
> map DMA memory through an IOMMU.


dma_map_sg is certainly the right interface to use, and Marek Szyprowski has
patches to make that work on ARM, hopefully going into v3.5, so you could
use those.

	Arnd

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 2/4] iommu: tegra/gart: Add device tree support
       [not found]     ` <1334146230-1795-3-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
@ 2012-04-11 17:21       ` Stephen Warren
       [not found]         ` <4F85BD9D.7050409-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
  0 siblings, 1 reply; 65+ messages in thread
From: Stephen Warren @ 2012-04-11 17:21 UTC (permalink / raw)
  To: Thierry Reding
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Olof Johansson, Colin Cross,
	Jon Mayo, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	David Airlie, iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	Joerg Roedel, Hiroshi Doyu,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

On 04/11/2012 06:10 AM, Thierry Reding wrote:
> This commit adds device tree support for the GART hardware available on
> NVIDIA Tegra 20 SoCs.
> 
> Signed-off-by: Thierry Reding <thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
> ---
>  arch/arm/boot/dts/tegra20.dtsi         |    6 ++++++
>  arch/arm/mach-tegra/board-dt-tegra20.c |    1 +
>  drivers/iommu/tegra-gart.c             |   10 ++++++++++
>  3 files changed, 17 insertions(+)

I think I'd prefer at least the tegra20.dtsi change split out into a
separate patch so I can queue it in a "dt" topic branch in the Tegra repo.

It might be a good idea to split this into two on an arch/arm vs.
drivers/iommu boundary. Looking at Olof's branches for 3.4, that split
is what happened there.

Finally, there should be a binding documentation file in
Documentation/devicetree/bindings in order to specify the number of reg
property entries needed, and their meaning, since there's more than 1
(even though you did comment it nicely in the .dtsi file)

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 3/4] drm: fixed: Add dfixed_frac() macro
       [not found]     ` <1334146230-1795-4-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
@ 2012-04-11 17:25       ` Stephen Warren
       [not found]         ` <4F85BE77.7090807-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
  0 siblings, 1 reply; 65+ messages in thread
From: Stephen Warren @ 2012-04-11 17:25 UTC (permalink / raw)
  To: Thierry Reding
  Cc: David Airlie, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Olof Johansson,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jon Mayo

On 04/11/2012 06:10 AM, Thierry Reding wrote:
> This commit is taken from the Chromium tree and was originally written
> by Robert Morell.

Maybe just cherry-pick it from there? That way, the git authorship will
show up as Robert.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]     ` <1334146230-1795-5-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
  2012-04-11 12:48       ` Daniel Vetter
@ 2012-04-11 18:12       ` Stephen Warren
       [not found]         ` <4F85C97E.50203-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
  1 sibling, 1 reply; 65+ messages in thread
From: Stephen Warren @ 2012-04-11 18:12 UTC (permalink / raw)
  To: Thierry Reding
  Cc: David Airlie, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Olof Johansson,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jon Mayo

On 04/11/2012 06:10 AM, Thierry Reding wrote:
> This commit adds a very basic DRM driver for NVIDIA Tegra SoCs. It
> currently has rudimentary GEM support and can run a console on the
> framebuffer as well as X using the xf86-video-modesetting driver.
> Only the RGB output is supported. Quite a lot of things still need
> to be worked out and there is a lot of room for cleanup.

I'll let Jon Mayo comment on the actual driver implementation, since
he's a lot more familiar with Tegra's display hardware. However, I have
some general comments below.

>  .../devicetree/bindings/gpu/drm/tegra.txt          |   24 +
>  arch/arm/mach-tegra/board-dt-tegra20.c             |    3 +
>  arch/arm/mach-tegra/tegra2_clocks.c                |    8 +-
>  drivers/gpu/drm/Kconfig                            |    2 +
>  drivers/gpu/drm/Makefile                           |    1 +
>  drivers/gpu/drm/tegra/Kconfig                      |   10 +
>  drivers/gpu/drm/tegra/Makefile                     |    5 +
>  drivers/gpu/drm/tegra/tegra_drv.c                  | 2241 ++++++++++++++++++++
>  drivers/gpu/drm/tegra/tegra_drv.h                  |  184 ++
>  include/drm/tegra_drm.h                            |   44 +

Splitting this patch into two, between arch/arm and drivers/gpu would be
a good idea.

> diff --git a/Documentation/devicetree/bindings/gpu/drm/tegra.txt b/Documentation/devicetree/bindings/gpu/drm/tegra.txt

> +	drm@54200000 {
> +		compatible = "nvidia,tegra20-drm";

This doesn't seem right; there isn't a "DRM" hardware module on Tegra,
since "DRM" is a Linux/software-specific term.

I'd at least expect to see this compatible flag be renamed to something
more like "nvidia,tegra20-dc" (dc==display controller).

Since Tegra has two display controller modules (I believe identical?),
and numerous other independent(?) blocks, I'd expect to see multiple
nodes in device tree, one per hardware block, such that each block gets
its own device and driver. That said, I'm not familiar enough with
Tegra's display and graphics HW to know if this makes sense. Jon, what's
your take here? The clock change below, and in particular the original
code there that we use downstream, lends weight to my argument.

> +		reg = < 0x54200000 0x00040000    /* display A */
> +		        0x54240000 0x00040000    /* display B */
> +		        0x58000000 0x02000000 >; /* GART aperture */
> +		interrupts = < 0 73 0x04    /* display A */
> +		               0 74 0x04 >; /* display B */
> +
> +		lvds {
> +			type = "rgb";

These sub-nodes probably want a "compatible" property rather than a
"type" property.

> +			size = <345 194>;
> +
> +			default-mode {
> +				pixel-clock = <61715000>;
> +				vertical-refresh = <50>;
> +				resolution = <1366 768>;
> +				bits-per-pixel = <16>;
> +				horizontal-timings = <4 136 2 36>;
> +				vertical-timings = <2 4 21 10>;
> +			};
> +		};

I imagine that quite a bit of thought needs to be put into the output
part of the binding in order to:

* Model the outputs/connectors separately from display controllers.
* Make sure that the basic infra-structure for representing an output is
general enough to be extensible to all the kinds of outputs we support,
not just the LVDS output.
* We were wondering about putting an EDID into the DT to represent the
display modes, so that all outputs had EDIDs rather than "real" monitors
having EDIDs, and fixed internal displays having some other
representation of capabilities.

I'm hoping that Jon will drive this.

> diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c

> -	PERIPH_CLK("disp1",	"tegradc.0",		NULL,	27,	0x138,	600000000, mux_pllp_plld_pllc_clkm,	MUX), /* scales with voltage and process_id */
> -	PERIPH_CLK("disp2",	"tegradc.1",		NULL,	26,	0x13c,	600000000, mux_pllp_plld_pllc_clkm,	MUX), /* scales with voltage and process_id */
> +	PERIPH_CLK("disp1",	"tegra-drm",		NULL,	27,	0x138,	600000000, mux_pllp_plld_pllc_clkm,	MUX), /* scales with voltage and process_id */
> +	PERIPH_CLK("disp2",	"tegra-drm",		NULL,	26,	0x13c,	600000000, mux_pllp_plld_pllc_clkm,	MUX), /* scales with voltage and process_id */

This doesn't seem right, and couples back to my assertion above that the
two display controller modules probably deserve separate device objects,
named e.g. tegradc.*.

> diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/drm/tegra/Kconfig
> new file mode 100644
> index 0000000..f3382c9
> --- /dev/null
> +++ b/drivers/gpu/drm/tegra/Kconfig
> @@ -0,0 +1,10 @@
> +config DRM_TEGRA
> +	tristate "NVIDIA Tegra"
> +	depends on DRM && ARCH_TEGRA

Jon, do you think we'll end up eventually having a unified
Tegra20/Tegra30 DRM driver, or separate top-level DRM drivers?

In other words, should this depend on ARCH_TEGRA_2x_SOC rather than
ARCH_TEGRA?

> diff --git a/drivers/gpu/drm/tegra/tegra_drv.c b/drivers/gpu/drm/tegra/tegra_drv.c

> +#define DRIVER_NAME "tegra"
> +#define DRIVER_DESC "NVIDIA Tegra graphics"

Similarly, I wonder if these should be "tegra20" and "NVIDIA Tegra20
graphics", or not?

> +static int tegra_drm_parse_dt_mode(struct device *dev,
...
> +	err = of_property_read_u32(node, "pixel-clock", &value);
> +	if (err < 0)
> +		return err;

Is it useful to call dev_err() when the DT is present but can't be
parsed, to give some clue what the problem is?

> +static int tegra_drm_parse_dt(struct platform_device *pdev)
> +{
...
> +	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
> +	if (!pdata)
> +		return -ENOMEM;
...
> +	dev->platform_data = pdata;

I don't think you should assign to dev->platform_data. If you do, then I
think the following could happen:

* During first probe, the assignment above happens
* Module is removed, hence device removed, hence dev->platform_data
freed, but not zero'd out
* Module is re-inserted, finds that dev->platform_data!=NULL and
proceeds to use it.

Instead, the active platform data should probably be stored in a
tegra_drm struct that's stored in the dev's private data.
tegra_drm_probe() might then look more like:

struct tegra_drm *tdev;

tdev = devm_kzalloc();
tdev->pdata = pdev->dev.platform_data;
if (!tdev->pdata)
    tdev->pdata = tegra_drm_parse_dt();
if (!tdev->pdata)
    return -EINVAL;

dev_set_drvdata(dev, tdev);

This is safe, since probe() will never assume that dev_get_drvdata()
might contain something valid before probe() sets it.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]         ` <4F85C97E.50203-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
@ 2012-04-12  6:50           ` Thierry Reding
       [not found]             ` <20120412065038.GB4162-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
  2012-04-12  9:21           ` Sascha Hauer
  1 sibling, 1 reply; 65+ messages in thread
From: Thierry Reding @ 2012-04-12  6:50 UTC (permalink / raw)
  To: Stephen Warren
  Cc: David Airlie, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Olof Johansson,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jon Mayo


[-- Attachment #1.1: Type: text/plain, Size: 7435 bytes --]

* Stephen Warren wrote:
> On 04/11/2012 06:10 AM, Thierry Reding wrote:
> > This commit adds a very basic DRM driver for NVIDIA Tegra SoCs. It
> > currently has rudimentary GEM support and can run a console on the
> > framebuffer as well as X using the xf86-video-modesetting driver.
> > Only the RGB output is supported. Quite a lot of things still need
> > to be worked out and there is a lot of room for cleanup.
> 
> I'll let Jon Mayo comment on the actual driver implementation, since
> he's a lot more familiar with Tegra's display hardware. However, I have
> some general comments below.
> 
> >  .../devicetree/bindings/gpu/drm/tegra.txt          |   24 +
> >  arch/arm/mach-tegra/board-dt-tegra20.c             |    3 +
> >  arch/arm/mach-tegra/tegra2_clocks.c                |    8 +-
> >  drivers/gpu/drm/Kconfig                            |    2 +
> >  drivers/gpu/drm/Makefile                           |    1 +
> >  drivers/gpu/drm/tegra/Kconfig                      |   10 +
> >  drivers/gpu/drm/tegra/Makefile                     |    5 +
> >  drivers/gpu/drm/tegra/tegra_drv.c                  | 2241 ++++++++++++++++++++
> >  drivers/gpu/drm/tegra/tegra_drv.h                  |  184 ++
> >  include/drm/tegra_drm.h                            |   44 +
> 
> Splitting this patch into two, between arch/arm and drivers/gpu would be
> a good idea.

I can certainly do that.

> > diff --git a/Documentation/devicetree/bindings/gpu/drm/tegra.txt b/Documentation/devicetree/bindings/gpu/drm/tegra.txt
> 
> > +	drm@54200000 {
> > +		compatible = "nvidia,tegra20-drm";
> 
> This doesn't seem right; there isn't a "DRM" hardware module on Tegra,
> since "DRM" is a Linux/software-specific term.
> 
> I'd at least expect to see this compatible flag be renamed to something
> more like "nvidia,tegra20-dc" (dc==display controller).
> 
> Since Tegra has two display controller modules (I believe identical?),
> and numerous other independent(?) blocks, I'd expect to see multiple
> nodes in device tree, one per hardware block, such that each block gets
> its own device and driver. That said, I'm not familiar enough with
> Tegra's display and graphics HW to know if this makes sense. Jon, what's
> your take here? The clock change below, and in particular the original
> code there that we use downstream, lends weight to my argument.
> 
> > +		reg = < 0x54200000 0x00040000    /* display A */
> > +		        0x54240000 0x00040000    /* display B */
> > +		        0x58000000 0x02000000 >; /* GART aperture */
> > +		interrupts = < 0 73 0x04    /* display A */
> > +		               0 74 0x04 >; /* display B */
> > +
> > +		lvds {
> > +			type = "rgb";
> 
> These sub-nodes probably want a "compatible" property rather than a
> "type" property.

"compatible" suggests that a driver would bind to it. However the data really
is only passed to the DC driver for configuration.

> > +			size = <345 194>;
> > +
> > +			default-mode {
> > +				pixel-clock = <61715000>;
> > +				vertical-refresh = <50>;
> > +				resolution = <1366 768>;
> > +				bits-per-pixel = <16>;
> > +				horizontal-timings = <4 136 2 36>;
> > +				vertical-timings = <2 4 21 10>;
> > +			};
> > +		};
> 
> I imagine that quite a bit of thought needs to be put into the output
> part of the binding in order to:
> 
> * Model the outputs/connectors separately from display controllers.
> * Make sure that the basic infra-structure for representing an output is
> general enough to be extensible to all the kinds of outputs we support,
> not just the LVDS output.

I haven't played around with HDMI at all yet, so I don't know of the
requirements. I'm pretty sure the above isn't anywhere near complete
though.

> * We were wondering about putting an EDID into the DT to represent the
> display modes, so that all outputs had EDIDs rather than "real" monitors
> having EDIDs, and fixed internal displays having some other
> representation of capabilities.

That's an interesting approach. I like it.

> I'm hoping that Jon will drive this.
> 
> > diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c
> 
> > -	PERIPH_CLK("disp1",	"tegradc.0",		NULL,	27,	0x138,	600000000, mux_pllp_plld_pllc_clkm,	MUX), /* scales with voltage and process_id */
> > -	PERIPH_CLK("disp2",	"tegradc.1",		NULL,	26,	0x13c,	600000000, mux_pllp_plld_pllc_clkm,	MUX), /* scales with voltage and process_id */
> > +	PERIPH_CLK("disp1",	"tegra-drm",		NULL,	27,	0x138,	600000000, mux_pllp_plld_pllc_clkm,	MUX), /* scales with voltage and process_id */
> > +	PERIPH_CLK("disp2",	"tegra-drm",		NULL,	26,	0x13c,	600000000, mux_pllp_plld_pllc_clkm,	MUX), /* scales with voltage and process_id */
> 
> This doesn't seem right, and couples back to my assertion above that the
> two display controller modules probably deserve separate device objects,
> named e.g. tegradc.*.

I think I understand where you're going with this. Does the following look
more correct?

	disp1 : dc@54200000 {
		compatible = "nvidia,tegra20-dc";
		reg = <0x54200000, 0x00040000>;
		interrupts = <0 73 0x04>;
	};

	disp2 : dc@54240000 {
		compatible = "nvidia,tegra20-dc";
		reg = <0x54240000, 0x00040000>;
		interrupts = <0 74 0x04>;
	};

	drm {
		compatible = "nvidia,tegra20-drm";

		lvds {
			compatible = "...";
			dc = <&disp1>;
		};

		hdmi {
			compatible = "...";
			dc = <&disp2>;
		};
	};

> > +static int tegra_drm_parse_dt_mode(struct device *dev,
> ...
> > +	err = of_property_read_u32(node, "pixel-clock", &value);
> > +	if (err < 0)
> > +		return err;
> 
> Is it useful to call dev_err() when the DT is present but can't be
> parsed, to give some clue what the problem is?

Yes, that might be a good idea.

> > +static int tegra_drm_parse_dt(struct platform_device *pdev)
> > +{
> ...
> > +	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
> > +	if (!pdata)
> > +		return -ENOMEM;
> ...
> > +	dev->platform_data = pdata;
> 
> I don't think you should assign to dev->platform_data. If you do, then I
> think the following could happen:
> 
> * During first probe, the assignment above happens
> * Module is removed, hence device removed, hence dev->platform_data
> freed, but not zero'd out

Actually the code does zero out platform_data in tegra_drm_remove(). In fact
I did test module unloading and reloading and it works properly. But it
should probably be zeroed in case drm_platform_init() fails as well.

> * Module is re-inserted, finds that dev->platform_data!=NULL and
> proceeds to use it.
> 
> Instead, the active platform data should probably be stored in a
> tegra_drm struct that's stored in the dev's private data.
> tegra_drm_probe() might then look more like:
> 
> struct tegra_drm *tdev;
> 
> tdev = devm_kzalloc();
> tdev->pdata = pdev->dev.platform_data;
> if (!tdev->pdata)
>     tdev->pdata = tegra_drm_parse_dt();
> if (!tdev->pdata)
>     return -EINVAL;
> 
> dev_set_drvdata(dev, tdev);
> 
> This is safe, since probe() will never assume that dev_get_drvdata()
> might contain something valid before probe() sets it.

I prefer my approach over storing the data in an extra field because the
device platform_data field is where everybody would expect it. Furthermore
this wouldn't be relevant if we decided not to support non-DT setups.

Thierry

[-- Attachment #1.2: Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 190 bytes --]

_______________________________________________
iommu mailing list
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 2/4] iommu: tegra/gart: Add device tree support
       [not found]         ` <4F85BD9D.7050409-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
@ 2012-04-12  6:51           ` Thierry Reding
  0 siblings, 0 replies; 65+ messages in thread
From: Thierry Reding @ 2012-04-12  6:51 UTC (permalink / raw)
  To: Stephen Warren
  Cc: David Airlie, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Olof Johansson,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jon Mayo


[-- Attachment #1.1: Type: text/plain, Size: 1146 bytes --]

* Stephen Warren wrote:
> On 04/11/2012 06:10 AM, Thierry Reding wrote:
> > This commit adds device tree support for the GART hardware available on
> > NVIDIA Tegra 20 SoCs.
> > 
> > Signed-off-by: Thierry Reding <thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
> > ---
> >  arch/arm/boot/dts/tegra20.dtsi         |    6 ++++++
> >  arch/arm/mach-tegra/board-dt-tegra20.c |    1 +
> >  drivers/iommu/tegra-gart.c             |   10 ++++++++++
> >  3 files changed, 17 insertions(+)
> 
> I think I'd prefer at least the tegra20.dtsi change split out into a
> separate patch so I can queue it in a "dt" topic branch in the Tegra repo.
> 
> It might be a good idea to split this into two on an arch/arm vs.
> drivers/iommu boundary. Looking at Olof's branches for 3.4, that split
> is what happened there.
> 
> Finally, there should be a binding documentation file in
> Documentation/devicetree/bindings in order to specify the number of reg
> property entries needed, and their meaning, since there's more than 1
> (even though you did comment it nicely in the .dtsi file)

Okay, I'll do that.

Thierry

[-- Attachment #1.2: Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 190 bytes --]

_______________________________________________
iommu mailing list
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 3/4] drm: fixed: Add dfixed_frac() macro
       [not found]         ` <4F85BE77.7090807-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
@ 2012-04-12  6:52           ` Thierry Reding
  0 siblings, 0 replies; 65+ messages in thread
From: Thierry Reding @ 2012-04-12  6:52 UTC (permalink / raw)
  To: Stephen Warren
  Cc: David Airlie, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Olof Johansson,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jon Mayo


[-- Attachment #1.1: Type: text/plain, Size: 358 bytes --]

* Stephen Warren wrote:
> On 04/11/2012 06:10 AM, Thierry Reding wrote:
> > This commit is taken from the Chromium tree and was originally written
> > by Robert Morell.
> 
> Maybe just cherry-pick it from there? That way, the git authorship will
> show up as Robert.

I can do that. Though I'll have to remove the Chromium-specific tags.

Thierry

[-- Attachment #1.2: Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 190 bytes --]

_______________________________________________
iommu mailing list
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]                         ` <201204111518.41968.arnd-r2nGTMty4D4@public.gmane.org>
@ 2012-04-12  7:18                           ` Thierry Reding
       [not found]                             ` <20120412071816.GA18252-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
  2012-04-12 23:10                           ` Lucas Stach
  1 sibling, 1 reply; 65+ messages in thread
From: Thierry Reding @ 2012-04-12  7:18 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Daniel Vetter,
	Joerg Roedel, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	Jon Mayo, iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	Colin Cross, linux-tegra-u79uwXL29TY76Z2rM5mHXA, Hiroshi Doyu,
	Marek Szyprowski

[-- Attachment #1: Type: text/plain, Size: 1708 bytes --]

* Arnd Bergmann wrote:
> On Wednesday 11 April 2012, Thierry Reding wrote:
> > Daniel Vetter wrote:
> > > Well, you use the iommu api to map/unmap memory into the iommu for tegra,
> > > whereas usually device drivers just use the dma api to do that. The usual
> > > interface is dma_map_sg/dma_unmap_sg, but there are quite a few variants
> > > around. I'm just wondering why this you've choosen this.
> > 
> > I don't think this works on ARM. Maybe I'm not seeing the whole picture but
> > judging by a quick look through the kernel tree there aren't any users that
> > map DMA memory through an IOMMU.
> 
> dma_map_sg is certainly the right interface to use, and Marek Szyprowski has
> patches to make that work on ARM, hopefully going into v3.5, so you could
> use those.

I've looked at Marek's patches but I don't think they'll work for Tegra 2 or
Tegra 3. The corresponding iommu_map() functions only set one PTE, regardless
of the number of bytes passed to them. However, the Tegra TRM indicates that
mapping needs to be done on a per-page basis so contiguous regions cannot be
combined. I suppose the IOMMU driver would have to be fixed to program more
than a single page in that case.

Also this doesn't yet solve the vmap() problem that is needed for the kernel
virtual mapping. I did try using dma_alloc_writecombine(), but that only
works for chunks of 2 MB or smaller, unless I use init_consistent_dma_size()
during board setup, which isn't provided for in a DT setup. I couldn't find
a better alternative, but I admit I'm not very familiar with all the VM APIs.
Do you have any suggestions on how to solve this? Otherwise I'll try and dig
in some more.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 65+ messages in thread

* RE: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]                             ` <20120412071816.GA18252-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
@ 2012-04-12  8:40                               ` Marek Szyprowski
       [not found]                                 ` <025f01cd1887$da56b6e0$8f0424a0$%szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
  0 siblings, 1 reply; 65+ messages in thread
From: Marek Szyprowski @ 2012-04-12  8:40 UTC (permalink / raw)
  To: 'Thierry Reding', 'Arnd Bergmann'
  Cc: Tomasz Stanislawski, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	'Daniel Vetter', 'Colin Cross',
	'Jon Mayo'

Hi Thierry,

On Thursday, April 12, 2012 9:18 AM Thierry Reding wrote:

> * Arnd Bergmann wrote:
> > On Wednesday 11 April 2012, Thierry Reding wrote:
> > > Daniel Vetter wrote:
> > > > Well, you use the iommu api to map/unmap memory into the iommu for tegra,
> > > > whereas usually device drivers just use the dma api to do that. The usual
> > > > interface is dma_map_sg/dma_unmap_sg, but there are quite a few variants
> > > > around. I'm just wondering why this you've choosen this.
> > >
> > > I don't think this works on ARM. Maybe I'm not seeing the whole picture but
> > > judging by a quick look through the kernel tree there aren't any users that
> > > map DMA memory through an IOMMU.
> >
> > dma_map_sg is certainly the right interface to use, and Marek Szyprowski has
> > patches to make that work on ARM, hopefully going into v3.5, so you could
> > use those.
> 
> I've looked at Marek's patches but I don't think they'll work for Tegra 2 or
> Tegra 3. The corresponding iommu_map() functions only set one PTE, regardless
> of the number of bytes passed to them. However, the Tegra TRM indicates that
> mapping needs to be done on a per-page basis so contiguous regions cannot be
> combined. I suppose the IOMMU driver would have to be fixed to program more
> than a single page in that case.

I assume you want to map a set of pages into contiguous chunk in io address space.
This can be done with dma_map_sg() call once IOMMU aware implementation has been
assigned to the given device. DMA-mapping implementation is able to merge 
consecutive chunks of the scatter list in the dma/io address space if possible
(i.e. there are no in-page offsets between the chunks). With my implementation 
of IOMMU aware dma-mapping you usually you get a single DMA chunk from the 
provided scatter-list.

I know that this approach causes a lot of confusion at the first look, but that
how dma mapping api has been designed. The scatter list based approach has some
drawbacks - it is a bit oversized for most of the typical use cases for the 
gfx/multimedia buffers, but that's all we have now. 

Scatter lists were initially designed for the disk based block io operations, 
hence the presence of the in-page offsets and lengths for each chunk. For 
multimedia use cases providing an array of struct pages and asking dma-mapping 
to map them into contiguous memory is probably all we need. I wonder if 
introducing such new calls is a good idea. Anrd, what do think? It will 
definitely simplify the drivers and improve the code understanding. On the 
other hand it requires a significant amount of work in the dma-mapping 
framework for all architectures, but that's not a big issue for me.

> Also this doesn't yet solve the vmap() problem that is needed for the kernel
> virtual mapping. I did try using dma_alloc_writecombine(), but that only
> works for chunks of 2 MB or smaller, unless I use init_consistent_dma_size()
> during board setup, which isn't provided for in a DT setup. I couldn't find
> a better alternative, but I admit I'm not very familiar with all the VM APIs.
> Do you have any suggestions on how to solve this? Otherwise I'll try and dig
> in some more.

Yes, I'm aware of this issue I'm currently working on solving it. I hope to use 
standard vmalloc range for all coherent/writecombine allocations and get rid of
the custom 'consistent_dma' region at all.

Best regards
-- 
Marek Szyprowski
Samsung Poland R&D Center

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]         ` <4F85C97E.50203-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
  2012-04-12  6:50           ` Thierry Reding
@ 2012-04-12  9:21           ` Sascha Hauer
       [not found]             ` <20120412092106.GU3852-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
  1 sibling, 1 reply; 65+ messages in thread
From: Sascha Hauer @ 2012-04-12  9:21 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Thierry Reding, Joerg Roedel,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jon Mayo, Hiroshi Doyu

On Wed, Apr 11, 2012 at 12:12:14PM -0600, Stephen Warren wrote:
> On 04/11/2012 06:10 AM, Thierry Reding wrote:
> > This commit adds a very basic DRM driver for NVIDIA Tegra SoCs. It
> > currently has rudimentary GEM support and can run a console on the
> > framebuffer as well as X using the xf86-video-modesetting driver.
> > Only the RGB output is supported. Quite a lot of things still need
> > to be worked out and there is a lot of room for cleanup.
> 
> I'll let Jon Mayo comment on the actual driver implementation, since
> he's a lot more familiar with Tegra's display hardware. However, I have
> some general comments below.
> 
> >  .../devicetree/bindings/gpu/drm/tegra.txt          |   24 +
> >  arch/arm/mach-tegra/board-dt-tegra20.c             |    3 +
> >  arch/arm/mach-tegra/tegra2_clocks.c                |    8 +-
> >  drivers/gpu/drm/Kconfig                            |    2 +
> >  drivers/gpu/drm/Makefile                           |    1 +
> >  drivers/gpu/drm/tegra/Kconfig                      |   10 +
> >  drivers/gpu/drm/tegra/Makefile                     |    5 +
> >  drivers/gpu/drm/tegra/tegra_drv.c                  | 2241 ++++++++++++++++++++
> >  drivers/gpu/drm/tegra/tegra_drv.h                  |  184 ++
> >  include/drm/tegra_drm.h                            |   44 +
> 
> Splitting this patch into two, between arch/arm and drivers/gpu would be
> a good idea.
> 
> > diff --git a/Documentation/devicetree/bindings/gpu/drm/tegra.txt b/Documentation/devicetree/bindings/gpu/drm/tegra.txt
> 
> > +	drm@54200000 {
> > +		compatible = "nvidia,tegra20-drm";
> 
> This doesn't seem right; there isn't a "DRM" hardware module on Tegra,
> since "DRM" is a Linux/software-specific term.
> 
> I'd at least expect to see this compatible flag be renamed to something
> more like "nvidia,tegra20-dc" (dc==display controller).
> 
> Since Tegra has two display controller modules (I believe identical?),
> and numerous other independent(?) blocks, I'd expect to see multiple
> nodes in device tree, one per hardware block, such that each block gets
> its own device and driver. That said, I'm not familiar enough with
> Tegra's display and graphics HW to know if this makes sense. Jon, what's
> your take here? The clock change below, and in particular the original
> code there that we use downstream, lends weight to my argument.
> 
> > +		reg = < 0x54200000 0x00040000    /* display A */
> > +		        0x54240000 0x00040000    /* display B */
> > +		        0x58000000 0x02000000 >; /* GART aperture */
> > +		interrupts = < 0 73 0x04    /* display A */
> > +		               0 74 0x04 >; /* display B */
> > +
> > +		lvds {
> > +			type = "rgb";
> 
> These sub-nodes probably want a "compatible" property rather than a
> "type" property.
> 
> > +			size = <345 194>;
> > +
> > +			default-mode {
> > +				pixel-clock = <61715000>;
> > +				vertical-refresh = <50>;
> > +				resolution = <1366 768>;
> > +				bits-per-pixel = <16>;
> > +				horizontal-timings = <4 136 2 36>;
> > +				vertical-timings = <2 4 21 10>;
> > +			};
> > +		};
> 
> I imagine that quite a bit of thought needs to be put into the output
> part of the binding in order to:
> 
> * Model the outputs/connectors separately from display controllers.
> * Make sure that the basic infra-structure for representing an output is
> general enough to be extensible to all the kinds of outputs we support,
> not just the LVDS output.
> * We were wondering about putting an EDID into the DT to represent the
> display modes, so that all outputs had EDIDs rather than "real" monitors
> having EDIDs, and fixed internal displays having some other
> representation of capabilities.

You might want to have a look at the sdrm patches I recently posted to
dri-devel and arm Linux Kernel. Among other things they allow to
register crtcs/connectors/encoders seperately so that each of them can
have its own representation in the devicetree. I haven't looked into
devicetree support for DRM, but with or without devicetree the problem
that we do not have a single PCI card for registering all DRM components
is the same.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]             ` <20120412092106.GU3852-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
@ 2012-04-12  9:33               ` Thierry Reding
       [not found]                 ` <20120412093301.GB23336-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
  0 siblings, 1 reply; 65+ messages in thread
From: Thierry Reding @ 2012-04-12  9:33 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: Stephen Warren, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Jon Mayo,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA


[-- Attachment #1.1: Type: text/plain, Size: 1146 bytes --]

* Sascha Hauer wrote:
> You might want to have a look at the sdrm patches I recently posted to
> dri-devel and arm Linux Kernel. Among other things they allow to
> register crtcs/connectors/encoders seperately so that each of them can
> have its own representation in the devicetree. I haven't looked into
> devicetree support for DRM, but with or without devicetree the problem
> that we do not have a single PCI card for registering all DRM components
> is the same.

I'll do that. One interesting use-case that's been on my mind for some time
is if it would be possible to provide a CRTC via DRM that isn't part of the
SoC or DRM "device" but which can display a framebuffer prepared by the DRM
framework.

In other words I would like to use the Tegra hardware to render content into
a framebuffer (using potentially the 3D engine or HW accelerated video
decoding blocks) but display that framebuffer with a CRTC registered by a
different driver (perhaps provided by a PCIe or USB device).

I think such a setup would be possible if the CRTC registration can be
decoupled from the DRM driver. Perhaps sdrm even supports that already?

Thierry

[-- Attachment #1.2: Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 190 bytes --]

_______________________________________________
iommu mailing list
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]                                 ` <025f01cd1887$da56b6e0$8f0424a0$%szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
@ 2012-04-12 11:18                                   ` Arnd Bergmann
       [not found]                                     ` <201204121118.19685.arnd-r2nGTMty4D4@public.gmane.org>
  2012-04-12 13:42                                   ` Thierry Reding
  1 sibling, 1 reply; 65+ messages in thread
From: Arnd Bergmann @ 2012-04-12 11:18 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: 'Thierry Reding',
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	'Daniel Vetter', 'Joerg Roedel',
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, 'Jon Mayo',
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	'Colin Cross',
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, 'Hiroshi Doyu',
	Tomasz Stanislawski

On Thursday 12 April 2012, Marek Szyprowski wrote:
> Scatter lists were initially designed for the disk based block io operations, 
> hence the presence of the in-page offsets and lengths for each chunk. For 
> multimedia use cases providing an array of struct pages and asking dma-mapping 
> to map them into contiguous memory is probably all we need. I wonder if 
> introducing such new calls is a good idea. Anrd, what do think? It will 
> definitely simplify the drivers and improve the code understanding. On the 
> other hand it requires a significant amount of work in the dma-mapping 
> framework for all architectures, but that's not a big issue for me.

My feeling is that it's too much like the existing _sg version, so I wouldn't
add yet another variant. While having a simple page array is definitely
simpler and potentially faster, I think the API is already too complex
and we need to be very careful with new additions.

	Arnd

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]                 ` <20120412093301.GB23336-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
@ 2012-04-12 13:16                   ` Alex Deucher
       [not found]                     ` <CADnq5_Oiez8zAHqFw-_qXk=3PnnEqgm3ir9M3KsWaQr-dLS5pw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 65+ messages in thread
From: Alex Deucher @ 2012-04-12 13:16 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Sascha Hauer, Stephen Warren, Joerg Roedel,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Jon Mayo,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, Hiroshi Doyu

On Thu, Apr 12, 2012 at 5:33 AM, Thierry Reding
<thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org> wrote:
> * Sascha Hauer wrote:
>> You might want to have a look at the sdrm patches I recently posted to
>> dri-devel and arm Linux Kernel. Among other things they allow to
>> register crtcs/connectors/encoders seperately so that each of them can
>> have its own representation in the devicetree. I haven't looked into
>> devicetree support for DRM, but with or without devicetree the problem
>> that we do not have a single PCI card for registering all DRM components
>> is the same.
>
> I'll do that. One interesting use-case that's been on my mind for some time
> is if it would be possible to provide a CRTC via DRM that isn't part of the
> SoC or DRM "device" but which can display a framebuffer prepared by the DRM
> framework.
>
> In other words I would like to use the Tegra hardware to render content into
> a framebuffer (using potentially the 3D engine or HW accelerated video
> decoding blocks) but display that framebuffer with a CRTC registered by a
> different driver (perhaps provided by a PCIe or USB device).
>
> I think such a setup would be possible if the CRTC registration can be
> decoupled from the DRM driver. Perhaps sdrm even supports that already?

You should be able to do something like that already with dma_buf and
the drm prime infrastructure.  There's even a drm driver for the udl
USB framebuffer devices.

Alex

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]                     ` <CADnq5_Oiez8zAHqFw-_qXk=3PnnEqgm3ir9M3KsWaQr-dLS5pw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2012-04-12 13:25                       ` Thierry Reding
       [not found]                         ` <20120412132531.GC5353-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
  0 siblings, 1 reply; 65+ messages in thread
From: Thierry Reding @ 2012-04-12 13:25 UTC (permalink / raw)
  To: Alex Deucher
  Cc: Stephen Warren, Sascha Hauer,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	Jon Mayo, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ


[-- Attachment #1.1: Type: text/plain, Size: 1396 bytes --]

* Alex Deucher wrote:
> On Thu, Apr 12, 2012 at 5:33 AM, Thierry Reding
> <thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org> wrote:
> > In other words I would like to use the Tegra hardware to render content into
> > a framebuffer (using potentially the 3D engine or HW accelerated video
> > decoding blocks) but display that framebuffer with a CRTC registered by a
> > different driver (perhaps provided by a PCIe or USB device).
> >
> > I think such a setup would be possible if the CRTC registration can be
> > decoupled from the DRM driver. Perhaps sdrm even supports that already?
> 
> You should be able to do something like that already with dma_buf and
> the drm prime infrastructure.  There's even a drm driver for the udl
> USB framebuffer devices.

Using DRM PRIME requires user-space to be involved. I was thinking more along
the lines of allowing a dumb DRM driver that only provides a CRTC to register
with another driver so that it shows up as an output for the latter DRM
device.

Then again, having user-space control this may be more flexible. Performance-
wise both should be about the same, right? What I don't quite understand yet
is how the DMABUF would be synchronized on both ends. Is there some infra-
structure to account for it or would I have to export two buffers and flip
them during the vblank of the "consumer"?

Thierry

[-- Attachment #1.2: Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 190 bytes --]

_______________________________________________
iommu mailing list
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 65+ messages in thread

* RE: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]                                     ` <201204121118.19685.arnd-r2nGTMty4D4@public.gmane.org>
@ 2012-04-12 13:30                                       ` Marek Szyprowski
       [not found]                                         ` <02aa01cd18b0$7b2586a0$717093e0$%szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
  2012-04-12 14:23                                       ` Daniel Vetter
  1 sibling, 1 reply; 65+ messages in thread
From: Marek Szyprowski @ 2012-04-12 13:30 UTC (permalink / raw)
  To: 'Arnd Bergmann'
  Cc: Tomasz Stanislawski, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	'Thierry Reding',
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	'Daniel Vetter', 'Colin Cross',
	'Jon Mayo'

Hi Arnd,

On Thursday, April 12, 2012 1:18 PM Arnd Bergmann wrote:

> On Thursday 12 April 2012, Marek Szyprowski wrote:
> > Scatter lists were initially designed for the disk based block io operations,
> > hence the presence of the in-page offsets and lengths for each chunk. For
> > multimedia use cases providing an array of struct pages and asking dma-mapping
> > to map them into contiguous memory is probably all we need. I wonder if
> > introducing such new calls is a good idea. Anrd, what do think? It will
> > definitely simplify the drivers and improve the code understanding. On the
> > other hand it requires a significant amount of work in the dma-mapping
> > framework for all architectures, but that's not a big issue for me.
> 
> My feeling is that it's too much like the existing _sg version, so I wouldn't
> add yet another variant. While having a simple page array is definitely
> simpler and potentially faster, I think the API is already too complex
> and we need to be very careful with new additions.

You are right, the API is already complex. The idea of adding page array came after
explaining once again how the _sg functions work and how to use them for this
specific use case.

There is one more point for page array. Scatter-lists are also very inefficient
in terms of the used memory. In the worst case we create a single scatterlist 
entry for every single page of the large buffer. For each entry we really use 
only a page pointer, leaving offset at zero and size set to 4KiB, dma_address
and dma_length entries are usually used only for the first element in the list.

On the other hand scatter lists are the only way to describe a complex block IO
requests which is spread across multiple io buffers, which are smaller than a
single page.

Having a specialized set of functions in the API is not bad in general. Maybe
the obscurity of the current _sg functions was the reason that almost every 
developer involved in gfx/multimedia and memory management tried to provide 
his own solution instead of using the dma-mapping api. 

We already have dma_map_page() and dma_map_single() which are very similar. 
Maybe adding dma_map_pages() won't be such a bad idea? 

If not maybe we should provide some kind of helper functions which converts 
page array to scatterlist and then maps them.

Best regards
-- 
Marek Szyprowski
Samsung Poland R&D Center

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]                                         ` <02aa01cd18b0$7b2586a0$717093e0$%szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
@ 2012-04-12 13:34                                           ` Thierry Reding
  0 siblings, 0 replies; 65+ messages in thread
From: Thierry Reding @ 2012-04-12 13:34 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Tomasz Stanislawski, 'Arnd Bergmann',
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	'Daniel Vetter', 'Colin Cross',
	'Jon Mayo'


[-- Attachment #1.1: Type: text/plain, Size: 370 bytes --]

* Marek Szyprowski wrote:
[...]
> We already have dma_map_page() and dma_map_single() which are very similar. 
> Maybe adding dma_map_pages() won't be such a bad idea? 
> 
> If not maybe we should provide some kind of helper functions which converts 
> page array to scatterlist and then maps them.

drm_prime_pages_to_sg() seems to do exactly that.

Thierry

[-- Attachment #1.2: Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 190 bytes --]

_______________________________________________
iommu mailing list
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]                                 ` <025f01cd1887$da56b6e0$8f0424a0$%szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
  2012-04-12 11:18                                   ` Arnd Bergmann
@ 2012-04-12 13:42                                   ` Thierry Reding
       [not found]                                     ` <20120412134216.GB15701-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
  1 sibling, 1 reply; 65+ messages in thread
From: Thierry Reding @ 2012-04-12 13:42 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: 'Arnd Bergmann',
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	'Daniel Vetter', 'Joerg Roedel',
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, 'Jon Mayo',
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	'Colin Cross',
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, 'Hiroshi Doyu',
	Tomasz Stanislawski

[-- Attachment #1: Type: text/plain, Size: 1150 bytes --]

* Marek Szyprowski wrote:
> Hi Thierry,
> 
> On Thursday, April 12, 2012 9:18 AM Thierry Reding wrote:
> > Also this doesn't yet solve the vmap() problem that is needed for the kernel
> > virtual mapping. I did try using dma_alloc_writecombine(), but that only
> > works for chunks of 2 MB or smaller, unless I use init_consistent_dma_size()
> > during board setup, which isn't provided for in a DT setup. I couldn't find
> > a better alternative, but I admit I'm not very familiar with all the VM APIs.
> > Do you have any suggestions on how to solve this? Otherwise I'll try and dig
> > in some more.
> 
> Yes, I'm aware of this issue I'm currently working on solving it. I hope to use 
> standard vmalloc range for all coherent/writecombine allocations and get rid of
> the custom 'consistent_dma' region at all.

Does your work aim at removing the 2 MB limitation or at remapping non-
contiguous memory to a virtually linear buffer? I have some trouble
understanding how removing the 2 MB limit would help, because if all buffers
can be allocated contiguously then there wouldn't be any need for the IOMMU,
right?

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]                         ` <20120412132531.GC5353-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
@ 2012-04-12 14:09                           ` Alex Deucher
       [not found]                             ` <CADnq5_P-iGtCxtW+1Y2N34Q6WA5dUUC7ZxZNT29BXTAV0+VfpQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 65+ messages in thread
From: Alex Deucher @ 2012-04-12 14:09 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Sascha Hauer, Stephen Warren, Joerg Roedel,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Jon Mayo,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, Hiroshi Doyu

On Thu, Apr 12, 2012 at 9:25 AM, Thierry Reding
<thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org> wrote:
> * Alex Deucher wrote:
>> On Thu, Apr 12, 2012 at 5:33 AM, Thierry Reding
>> <thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org> wrote:
>> > In other words I would like to use the Tegra hardware to render content into
>> > a framebuffer (using potentially the 3D engine or HW accelerated video
>> > decoding blocks) but display that framebuffer with a CRTC registered by a
>> > different driver (perhaps provided by a PCIe or USB device).
>> >
>> > I think such a setup would be possible if the CRTC registration can be
>> > decoupled from the DRM driver. Perhaps sdrm even supports that already?
>>
>> You should be able to do something like that already with dma_buf and
>> the drm prime infrastructure.  There's even a drm driver for the udl
>> USB framebuffer devices.
>
> Using DRM PRIME requires user-space to be involved. I was thinking more along
> the lines of allowing a dumb DRM driver that only provides a CRTC to register
> with another driver so that it shows up as an output for the latter DRM
> device.

Even then it could get tricky with synchronization depending on the hw.

>
> Then again, having user-space control this may be more flexible. Performance-
> wise both should be about the same, right? What I don't quite understand yet
> is how the DMABUF would be synchronized on both ends. Is there some infra-
> structure to account for it or would I have to export two buffers and flip
> them during the vblank of the "consumer"?

Performance should be about the same.  The tricky part is
synchronization.  dma_buf is for sharing.  There are ideas to make
generic sync objects, but for now, it's up to the userspace components
to handle it.

Alex

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]                             ` <CADnq5_P-iGtCxtW+1Y2N34Q6WA5dUUC7ZxZNT29BXTAV0+VfpQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2012-04-12 14:12                               ` Alex Deucher
       [not found]                                 ` <CADnq5_OLaKPLktd8DkQvwrmZPpaQP4zA1a4+742mQCGvRXfD7g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 65+ messages in thread
From: Alex Deucher @ 2012-04-12 14:12 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Sascha Hauer, Stephen Warren, Joerg Roedel,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Jon Mayo,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, Hiroshi Doyu

On Thu, Apr 12, 2012 at 10:09 AM, Alex Deucher <alexdeucher-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> On Thu, Apr 12, 2012 at 9:25 AM, Thierry Reding
> <thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org> wrote:
>> * Alex Deucher wrote:
>>> On Thu, Apr 12, 2012 at 5:33 AM, Thierry Reding
>>> <thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org> wrote:
>>> > In other words I would like to use the Tegra hardware to render content into
>>> > a framebuffer (using potentially the 3D engine or HW accelerated video
>>> > decoding blocks) but display that framebuffer with a CRTC registered by a
>>> > different driver (perhaps provided by a PCIe or USB device).
>>> >
>>> > I think such a setup would be possible if the CRTC registration can be
>>> > decoupled from the DRM driver. Perhaps sdrm even supports that already?
>>>
>>> You should be able to do something like that already with dma_buf and
>>> the drm prime infrastructure.  There's even a drm driver for the udl
>>> USB framebuffer devices.
>>
>> Using DRM PRIME requires user-space to be involved. I was thinking more along
>> the lines of allowing a dumb DRM driver that only provides a CRTC to register
>> with another driver so that it shows up as an output for the latter DRM
>> device.
>
> Even then it could get tricky with synchronization depending on the hw.
>
>>
>> Then again, having user-space control this may be more flexible. Performance-
>> wise both should be about the same, right? What I don't quite understand yet
>> is how the DMABUF would be synchronized on both ends. Is there some infra-
>> structure to account for it or would I have to export two buffers and flip
>> them during the vblank of the "consumer"?
>
> Performance should be about the same.  The tricky part is
> synchronization.  dma_buf is for sharing.  There are ideas to make
> generic sync objects, but for now, it's up to the userspace components
> to handle it.

Some example code:
http://lists.freedesktop.org/archives/dri-devel/2012-April/021182.html

Alex

^ permalink raw reply	[flat|nested] 65+ messages in thread

* RE: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]                                     ` <20120412134216.GB15701-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
@ 2012-04-12 14:20                                       ` Marek Szyprowski
  0 siblings, 0 replies; 65+ messages in thread
From: Marek Szyprowski @ 2012-04-12 14:20 UTC (permalink / raw)
  To: 'Thierry Reding'
  Cc: Tomasz Stanislawski, 'Arnd Bergmann',
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	'Daniel Vetter', 'Colin Cross',
	'Jon Mayo'

Hi Thierry,

On Thursday, April 12, 2012 3:42 PM Thierry Reding wrote:

> > > Also this doesn't yet solve the vmap() problem that is needed for the kernel
> > > virtual mapping. I did try using dma_alloc_writecombine(), but that only
> > > works for chunks of 2 MB or smaller, unless I use init_consistent_dma_size()
> > > during board setup, which isn't provided for in a DT setup. I couldn't find
> > > a better alternative, but I admit I'm not very familiar with all the VM APIs.
> > > Do you have any suggestions on how to solve this? Otherwise I'll try and dig
> > > in some more.
> >
> > Yes, I'm aware of this issue I'm currently working on solving it. I hope to use
> > standard vmalloc range for all coherent/writecombine allocations and get rid of
> > the custom 'consistent_dma' region at all.
> 
> Does your work aim at removing the 2 MB limitation or at remapping non-
> contiguous memory to a virtually linear buffer? I have some trouble
> understanding how removing the 2 MB limit would help, because if all buffers
> can be allocated contiguously then there wouldn't be any need for the IOMMU,
> right?

I would like to remove 2MiB limitation by moving these mapping to generic vmalloc
area. Please notice that this 2MiB limit is only applied to CPU virtual address
space and no physical memory is preallocated for consistent dma. 

ARM linear dma mapping implementation allocates coherent buffers by calling 
alloc_pages() and then creating a coherent mapping for the allocated buffer.

With IOMMU you can allocate chunks of memory and create a contiguous DMA mapping.
To fulfill dma mapping request you also need to create a cpu coherent mapping for 
them and right now my core uses the same remapping function as linear version.

The only limitation here will be vmalloc space and its fragmentation.

Best regards
-- 
Marek Szyprowski
Samsung Poland R&D Center

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]                                     ` <201204121118.19685.arnd-r2nGTMty4D4@public.gmane.org>
  2012-04-12 13:30                                       ` Marek Szyprowski
@ 2012-04-12 14:23                                       ` Daniel Vetter
  1 sibling, 0 replies; 65+ messages in thread
From: Daniel Vetter @ 2012-04-12 14:23 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Marek Szyprowski, 'Thierry Reding',
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	'Daniel Vetter', 'Joerg Roedel',
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, 'Jon Mayo',
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	'Colin Cross',
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, 'Hiroshi Doyu',
	Tomasz Stanislawski

On Thu, Apr 12, 2012 at 11:18:19AM +0000, Arnd Bergmann wrote:
> On Thursday 12 April 2012, Marek Szyprowski wrote:
> > Scatter lists were initially designed for the disk based block io operations, 
> > hence the presence of the in-page offsets and lengths for each chunk. For 
> > multimedia use cases providing an array of struct pages and asking dma-mapping 
> > to map them into contiguous memory is probably all we need. I wonder if 
> > introducing such new calls is a good idea. Anrd, what do think? It will 
> > definitely simplify the drivers and improve the code understanding. On the 
> > other hand it requires a significant amount of work in the dma-mapping 
> > framework for all architectures, but that's not a big issue for me.
> 
> My feeling is that it's too much like the existing _sg version, so I wouldn't
> add yet another variant. While having a simple page array is definitely
> simpler and potentially faster, I think the API is already too complex
> and we need to be very careful with new additions.

I concur here. For VT-d support we wrestle the pages through an sg list in
drm/i915, too. It's not beautiful, and because our gpu internal pagetables
need 2 loops to walk the sg lists, one for the sg segments, one to loop
over all pages in a segment. And additional a WARN_ON if the segment
dma address isn't page-aligned. It's ugly, but imo adding some helpers to
easier deal with this common case (like the drm_prime_pages_to_sg)
function is better than creating an entirely new interface.
-Daniel
-- 
Daniel Vetter
Mail: daniel-/w4YWyX8dFk@public.gmane.org
Mobile: +41 (0)79 365 57 48

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]             ` <20120412065038.GB4162-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
@ 2012-04-12 15:49               ` Stephen Warren
       [not found]                 ` <4F86F97C.8010508-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
  0 siblings, 1 reply; 65+ messages in thread
From: Stephen Warren @ 2012-04-12 15:49 UTC (permalink / raw)
  To: Thierry Reding
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Olof Johansson, Colin Cross,
	Jon Mayo, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	David Airlie, iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	Joerg Roedel, Hiroshi Doyu,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

On 04/12/2012 12:50 AM, Thierry Reding wrote:
> * Stephen Warren wrote:
>> On 04/11/2012 06:10 AM, Thierry Reding wrote:
>>> This commit adds a very basic DRM driver for NVIDIA Tegra SoCs. It
>>> currently has rudimentary GEM support and can run a console on the
>>> framebuffer as well as X using the xf86-video-modesetting driver.
>>> Only the RGB output is supported. Quite a lot of things still need
>>> to be worked out and there is a lot of room for cleanup.
...
>>> diff --git a/Documentation/devicetree/bindings/gpu/drm/tegra.txt b/Documentation/devicetree/bindings/gpu/drm/tegra.txt
...
>> This doesn't seem right, and couples back to my assertion above that the
>> two display controller modules probably deserve separate device objects,
>> named e.g. tegradc.*.
> 
> I think I understand where you're going with this. Does the following look
> more correct?
> 
> 	disp1 : dc@54200000 {
> 		compatible = "nvidia,tegra20-dc";
> 		reg = <0x54200000, 0x00040000>;
> 		interrupts = <0 73 0x04>;
> 	};
> 
> 	disp2 : dc@54240000 {
> 		compatible = "nvidia,tegra20-dc";
> 		reg = <0x54240000, 0x00040000>;
> 		interrupts = <0 74 0x04>;
> 	};

Those look good.

> 	drm {
> 		compatible = "nvidia,tegra20-drm";

I'm don't think having an explicit "drm" node is the right approach; drm
is after all a SW term and the DT should be describing HW. Having some
kind of top-level node almost certainly makes sense, but naming it
something related to "tegra display" than "drm" would be appropriate.

> 		lvds {
> 			compatible = "...";
> 			dc = <&disp1>;
> 		};

Aren't the outputs separate HW blocks too, such that they would have
their own compatible/reg properties and their own drivers, and be
outside the top-level drm/display node?

I believe the mapping between the output this node represents and the
display controller ("dc" above) that it uses is not static; the
connectivity should be set up at runtime, and possibly dynamically
alterable via xrandr or equivalent.

> 		hdmi {
> 			compatible = "...";
> 			dc = <&disp2>;
> 		};
> 	};

>>> +static int tegra_drm_parse_dt(struct platform_device *pdev)
>>> +{
>> ...
>>> +	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
>>> +	if (!pdata)
>>> +		return -ENOMEM;
>> ...
>>> +	dev->platform_data = pdata;
>>
>> I don't think you should assign to dev->platform_data. If you do, then I
>> think the following could happen:
>>
>> * During first probe, the assignment above happens
>> * Module is removed, hence device removed, hence dev->platform_data
>> freed, but not zero'd out
>> * Module is re-inserted, finds that dev->platform_data!=NULL and
>> proceeds to use it.
> 
> Actually the code does zero out platform_data in tegra_drm_remove(). In fact
> I did test module unloading and reloading and it works properly. But it
> should probably be zeroed in case drm_platform_init() fails as well.
>
>> Instead, the active platform data should probably be stored in a
>> tegra_drm struct that's stored in the dev's private data.
>> tegra_drm_probe() might then look more like:
>>
>> struct tegra_drm *tdev;
>>
>> tdev = devm_kzalloc();
>> tdev->pdata = pdev->dev.platform_data;
>> if (!tdev->pdata)
>>     tdev->pdata = tegra_drm_parse_dt();
>> if (!tdev->pdata)
>>     return -EINVAL;
>>
>> dev_set_drvdata(dev, tdev);
>>
>> This is safe, since probe() will never assume that dev_get_drvdata()
>> might contain something valid before probe() sets it.
> 
> I prefer my approach over storing the data in an extra field because the
> device platform_data field is where everybody would expect it. Furthermore
> this wouldn't be relevant if we decided not to support non-DT setups.

Drivers are expected to use pre-existing platform data, if provided.
This might happen in order to work around bugs in device tree content.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]                                 ` <CADnq5_OLaKPLktd8DkQvwrmZPpaQP4zA1a4+742mQCGvRXfD7g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2012-04-12 16:32                                   ` Thierry Reding
  0 siblings, 0 replies; 65+ messages in thread
From: Thierry Reding @ 2012-04-12 16:32 UTC (permalink / raw)
  To: Alex Deucher
  Cc: Stephen Warren, Sascha Hauer,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	Jon Mayo, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ


[-- Attachment #1.1: Type: text/plain, Size: 1248 bytes --]

* Alex Deucher wrote:
> On Thu, Apr 12, 2012 at 10:09 AM, Alex Deucher <alexdeucher-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> > On Thu, Apr 12, 2012 at 9:25 AM, Thierry Reding
> >> Then again, having user-space control this may be more flexible. Performance-
> >> wise both should be about the same, right? What I don't quite understand yet
> >> is how the DMABUF would be synchronized on both ends. Is there some infra-
> >> structure to account for it or would I have to export two buffers and flip
> >> them during the vblank of the "consumer"?
> >
> > Performance should be about the same.  The tricky part is
> > synchronization.  dma_buf is for sharing.  There are ideas to make
> > generic sync objects, but for now, it's up to the userspace components
> > to handle it.
> 
> Some example code:
> http://lists.freedesktop.org/archives/dri-devel/2012-April/021182.html

I saw that post too and it looks really nice. From what you're saying there
really doesn't seem to be any advantage to making the connection in the DRM
framework. Using DRM PRIME seems like a promising option and it seems to have
quite a lot of momentum. Of course I'll need to get the DRM driver up and
running properly first.

Thierry

[-- Attachment #1.2: Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 190 bytes --]

_______________________________________________
iommu mailing list
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]                 ` <4F86F97C.8010508-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
@ 2012-04-12 17:44                   ` Thierry Reding
       [not found]                     ` <20120412174429.GB10042-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
  0 siblings, 1 reply; 65+ messages in thread
From: Thierry Reding @ 2012-04-12 17:44 UTC (permalink / raw)
  To: Stephen Warren
  Cc: David Airlie, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Olof Johansson,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jon Mayo


[-- Attachment #1.1: Type: text/plain, Size: 3661 bytes --]

* Stephen Warren wrote:
> On 04/12/2012 12:50 AM, Thierry Reding wrote:
> > 	drm {
> > 		compatible = "nvidia,tegra20-drm";
> 
> I'm don't think having an explicit "drm" node is the right approach; drm
> is after all a SW term and the DT should be describing HW. Having some
> kind of top-level node almost certainly makes sense, but naming it
> something related to "tegra display" than "drm" would be appropriate.

In this case there really isn't a HW device that can be represented. But in
the end it's still the DRM driver that needs to bind to the device. However
the other graphics devices (MPE, VI/CSI, EPP, GR2D and GR3D) probably need
to be bound against.

Would it be possible for someone at NVIDIA to provide some more details about
what those other devices are? GR2D and GR3D seem obvious, MPE might be video
decoding, VI/CSI video input and camera interface? As to EPP I have no idea.

Maybe one solution would be to have a top-level DRM device with a register
map from 0x54000000 to 0x547fffff, which the TRM designates as "host
registers". Then subnodes could be used for the subdevices.

> > 		lvds {
> > 			compatible = "...";
> > 			dc = <&disp1>;
> > 		};
> 
> Aren't the outputs separate HW blocks too, such that they would have
> their own compatible/reg properties and their own drivers, and be
> outside the top-level drm/display node?

The RGB output is programmed via the display controller registers. For HDMI,
TVO and DSI there are indeed separate sets of registers in addition to the
display controller's. So perhaps for those more nodes would be required:

	hdmi : hdmi@54280000 {
		compatible = "nvidia,tegra20-hdmi";
		reg = <0x54280000 0x00040000>;
	};

And hook that up with the HDMI output node of the "DRM" node:

	drm {
		hdmi {
			compatible = "...";
			connector = <&hdmi>;
			dc = <&disp2>;
		};
	};

Maybe with this setup we no longer need the "compatible" property since it
will already be inherent in the "connector" property. There will have to be
special handling for the RGB output, which could be the default if the
"connector" property is missing.

> I believe the mapping between the output this node represents and the
> display controller ("dc" above) that it uses is not static; the
> connectivity should be set up at runtime, and possibly dynamically
> alterable via xrandr or equivalent.

I think the mapping is always static for a given board. There is no way to
switch an HDMI port to LVDS at runtime. But maybe I misunderstand what you're
saying.

> >> Instead, the active platform data should probably be stored in a
> >> tegra_drm struct that's stored in the dev's private data.
> >> tegra_drm_probe() might then look more like:
> >>
> >> struct tegra_drm *tdev;
> >>
> >> tdev = devm_kzalloc();
> >> tdev->pdata = pdev->dev.platform_data;
> >> if (!tdev->pdata)
> >>     tdev->pdata = tegra_drm_parse_dt();
> >> if (!tdev->pdata)
> >>     return -EINVAL;
> >>
> >> dev_set_drvdata(dev, tdev);
> >>
> >> This is safe, since probe() will never assume that dev_get_drvdata()
> >> might contain something valid before probe() sets it.
> > 
> > I prefer my approach over storing the data in an extra field because the
> > device platform_data field is where everybody would expect it. Furthermore
> > this wouldn't be relevant if we decided not to support non-DT setups.
> 
> Drivers are expected to use pre-existing platform data, if provided.
> This might happen in order to work around bugs in device tree content.

Okay I see. I'll have to store it in a separate field in the private
structure then.

Thierry

[-- Attachment #1.2: Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 190 bytes --]

_______________________________________________
iommu mailing list
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]         ` <20120411124810.GK4296-dv86pmgwkMBes7Z6vYuT8azUEOm+Xw19@public.gmane.org>
  2012-04-11 13:23           ` Thierry Reding
@ 2012-04-12 18:56           ` Jon Mayo
  1 sibling, 0 replies; 65+ messages in thread
From: Jon Mayo @ 2012-04-12 18:56 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Thierry Reding, linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	Stephen Warren, Joerg Roedel,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	Hiroshi Doyu


On 04/11/2012 05:48 AM, Daniel Vetter wrote:
> On Wed, Apr 11, 2012 at 02:10:30PM +0200, Thierry Reding wrote:
>> This commit adds a very basic DRM driver for NVIDIA Tegra SoCs. It
>> currently has rudimentary GEM support and can run a console on the
>> framebuffer as well as X using the xf86-video-modesetting driver.
>> Only the RGB output is supported. Quite a lot of things still need
>> to be worked out and there is a lot of room for cleanup.
>
> Indeed, after a quick look there are tons of functions that are just stubs
> ;-) One thing I wonder though is why you directly use the iommu api and
> not wrap it up into dma_map? Is arm infrastructure just not there yet or
> do you plan to tightly integrate the tegra drm with the iommu (e.g. for
> process space switching or similarly funky stuff)?
>
> Yours, Daniel

An abstraction to access iommu is preferable since Tegra2 and Tegra3 are 
quite a bit different when it comes to iommu.

But so far I'm pretty pleased with the driver Thierry has done. I'm 
hoping we can start using this as a base instead of the fb based driver 
that never made it upstream. (even if I have had a bit of a debate about 
GEM v. TTM v. ION v. ...)

- Jon

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]                     ` <20120412174429.GB10042-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
@ 2012-04-12 22:13                       ` Stephen Warren
       [not found]                         ` <4F8753A0.6040907-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
  0 siblings, 1 reply; 65+ messages in thread
From: Stephen Warren @ 2012-04-12 22:13 UTC (permalink / raw)
  To: Thierry Reding
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Olof Johansson, Colin Cross,
	Jon Mayo, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	David Airlie, iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	Joerg Roedel, Hiroshi Doyu,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

On 04/12/2012 11:44 AM, Thierry Reding wrote:
> * Stephen Warren wrote:
>> On 04/12/2012 12:50 AM, Thierry Reding wrote:
>>> 	drm {
>>> 		compatible = "nvidia,tegra20-drm";
>>
>> I'm don't think having an explicit "drm" node is the right approach; drm
>> is after all a SW term and the DT should be describing HW. Having some
>> kind of top-level node almost certainly makes sense, but naming it
>> something related to "tegra display" than "drm" would be appropriate.
> 
> In this case there really isn't a HW device that can be represented. But in
> the end it's still the DRM driver that needs to bind to the device. However
> the other graphics devices (MPE, VI/CSI, EPP, GR2D and GR3D) probably need
> to be bound against.

Well, everything graphics-related appears to be grouped within some
container. In the memory map, there's the range 0x54000000-547fffff, and
in the Tegra20 TRM, the first diagram in section 29 "Display Controller"
again lumps all the modules together into one box.

I'd say it's perfectly legitimate to create a device tree node to
represent this aggregate display/graphics-related engine. So, I think
that yes there is a real HW device to represent.

And given that, I don't think we should name the node after some
OS-specific software concept. Device tree is intended to model hardware.

> Would it be possible for someone at NVIDIA to provide some more details about
> what those other devices are? GR2D and GR3D seem obvious, MPE might be video
> decoding, VI/CSI video input and camera interface? As to EPP I have no idea.

MPE is something video encode/decode related. VI/CSI are indeed camera
related. I'm afraid I don't personally know any more details than that,
and even if I did, I'm only allowed to discuss what's in the TRM:-(

I don't think those modules should have much impact on the DRM driver
design if that's what you're worried about. I /believe/ they all just
interact directly with memory rather than the other components,
irrespective of what that first diagram in section 29 might imply.

> Maybe one solution would be to have a top-level DRM device with a register
> map from 0x54000000 to 0x547fffff, which the TRM designates as "host
> registers". Then subnodes could be used for the subdevices.

Ah yes, just what I was thinking above:-)

I don't think you'd /have/ to make the nodes sub-nodes; you could use
phandles to refer from the top-level node to the other components. One
might end up having to use phandles anyway to represent the routing from
DCA or DCB to MIPI or HDMI anyway, so it's possible that using phandles
everywhere might be simpler and more consistent than parent/child
relationships for some things and phandles for other things.

>>> 		lvds {
>>> 			compatible = "...";
>>> 			dc = <&disp1>;
>>> 		};
>>
>> Aren't the outputs separate HW blocks too, such that they would have
>> their own compatible/reg properties and their own drivers, and be
>> outside the top-level drm/display node?
> 
> The RGB output is programmed via the display controller registers. For HDMI,
> TVO and DSI there are indeed separate sets of registers in addition to the
> display controller's. So perhaps for those more nodes would be required:
> 
> 	hdmi : hdmi@54280000 {
> 		compatible = "nvidia,tegra20-hdmi";
> 		reg = <0x54280000 0x00040000>;
> 	};

Yes, looks reasonable.

> And hook that up with the HDMI output node of the "DRM" node:
> 
> 	drm {
> 		hdmi {
> 			compatible = "...";
> 			connector = <&hdmi>;
> 			dc = <&disp2>;
> 		};
> 	};
>
> Maybe with this setup we no longer need the "compatible" property since it
> will already be inherent in the "connector" property. There will have to be
> special handling for the RGB output, which could be the default if the
> "connector" property is missing.

I suspect you'd have something more like:

tegra-graphics {
    output-resources = <&hdmi &tvo &dsi ... >;
    display-controllers = <&disp1 &disp2>;
};

i.e. just a list of all extant devices. Each should provide some common
API so you could just map from phandle to of_node to device object, and
call the appropriate APIs on it.

Finally note that although I didn't really represent it correct above,
there are at least 3 levels of object/hierarchy here:

Display controllers reads from RAM and form a set of pixels to display.
I believe things like cursors, overlays, pan-scan, etc. are resolved
entirely at this level.

Output resources drive certain pins on Tegra in some specific format
such as HDMI, VGA, etc. I think all output resources can actually
display the data from either display controller. Probably even 2 ORs can
show an image from the same DC at once for mirrored display.

Finally, there are the user connectors. I suspect it's plausible for
muxes to exist between the ORs and user connectors, although that's
probably a lot less likely. I believe this is the level at which to
represent things like which I2C bus is used for EDID/DDC access, or
which GPIO is used for hotplug detect, etc.

>> I believe the mapping between the output this node represents and the
>> display controller ("dc" above) that it uses is not static; the
>> connectivity should be set up at runtime, and possibly dynamically
>> alterable via xrandr or equivalent.
> 
> I think the mapping is always static for a given board. There is no way to
> switch an HDMI port to LVDS at runtime. But maybe I misunderstand what you're
> saying.

I don't think disp2 is a property of a connector; the binding should
just specify which connectors and controllers exist, and the driver
should dynamically assign controllers to drive whichever connectors the
user wants lit up.

Note that there are more connectors than controllers, and it's quite
possible for a board to hook up 3 connectors and allow the user to
select which 1 or 2 of them to drive at run-time. That's where the
dynamic aspect comes in.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]                         ` <201204111518.41968.arnd-r2nGTMty4D4@public.gmane.org>
  2012-04-12  7:18                           ` Thierry Reding
@ 2012-04-12 23:10                           ` Lucas Stach
       [not found]                             ` <CAPM=9tztW_xLkOQ1qGjJdaPat_c5ivKPhik5-K8nD58SmF1Qrg@mail.gmail.com>
  1 sibling, 1 reply; 65+ messages in thread
From: Lucas Stach @ 2012-04-12 23:10 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Jon Mayo,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA

Am Mittwoch, den 11.04.2012, 15:18 +0000 schrieb Arnd Bergmann:
> On Wednesday 11 April 2012, Thierry Reding wrote:
> >   * Daniel Vetter wrote:
> > > On Wed, Apr 11, 2012 at 03:23:26PM +0200, Thierry Reding wrote:
> > > > * Daniel Vetter wrote:
> > > > > On Wed, Apr 11, 2012 at 02:10:30PM +0200, Thierry Reding wrote:
> > > > > > This commit adds a very basic DRM driver for NVIDIA Tegra SoCs. It
> > > > > > currently has rudimentary GEM support and can run a console on the
> > > > > > framebuffer as well as X using the xf86-video-modesetting driver.
> > > > > > Only the RGB output is supported. Quite a lot of things still need
> > > > > > to be worked out and there is a lot of room for cleanup.
> > > > > 
> > > > > Indeed, after a quick look there are tons of functions that are just stubs
> > > > > ;-) One thing I wonder though is why you directly use the iommu api and
> > > > > not wrap it up into dma_map? Is arm infrastructure just not there yet or
> > > > > do you plan to tightly integrate the tegra drm with the iommu (e.g. for
> > > > > process space switching or similarly funky stuff)?
> > > > 
> > > > I'm not sure I know what you are referring to. Looking for all users of
> > > > iommu_map() doesn't turn up anything related to dma_map. Can you point me in
> > > > the right direction?
> > > 
> > > Well, you use the iommu api to map/unmap memory into the iommu for tegra,
> > > whereas usually device drivers just use the dma api to do that. The usual
> > > interface is dma_map_sg/dma_unmap_sg, but there are quite a few variants
> > > around. I'm just wondering why this you've choosen this.
> > 
> > I don't think this works on ARM. Maybe I'm not seeing the whole picture but
> > judging by a quick look through the kernel tree there aren't any users that
> > map DMA memory through an IOMMU.
> 
> 
> dma_map_sg is certainly the right interface to use, and Marek Szyprowski has
> patches to make that work on ARM, hopefully going into v3.5, so you could
> use those.

Just jumping in here to make sure everyone understands the limitations
of the Tegra 2 GART IOMMU we are talking about here. It has no isolation
capabilities and a really small remapping window of 32MB. So it's
impossible to remap every buffer used by the graphics engines. The only
sane way to handle this is to set aside a chunk of stolen system memory
as VRAM and let a memory manager like TTM handle the allocation of
linear regions and GART mappings. This means a more tight integration of
the DRM driver and the IOMMU, where I think that using the IOMMU API
directly and completely controlling the GART from one driver is the
right way to go for a number of reasons, where my biggest concern is
that we can't implement a sane out-of-remapping space when we go through
the dma_map API.

It's too late for me to go into the details now, but I wanted to make it
clear that I think that using the IOMMU only and exclusively from the
DRM driver with a high level of tie in is the way to go. If you want to
know more details I'm available to discuss this matter in the next days.

-- Lucas
> 
> 	Arnd
> _______________________________________________
> dri-devel mailing list
> dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
> 

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]                         ` <4F8753A0.6040907-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
@ 2012-04-13  9:14                           ` Thierry Reding
       [not found]                             ` <20120413091457.GB617-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
  0 siblings, 1 reply; 65+ messages in thread
From: Thierry Reding @ 2012-04-13  9:14 UTC (permalink / raw)
  To: Stephen Warren
  Cc: David Airlie, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Olof Johansson,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jon Mayo


[-- Attachment #1.1: Type: text/plain, Size: 3347 bytes --]

* Stephen Warren wrote:
> On 04/12/2012 11:44 AM, Thierry Reding wrote:
[...]
> And given that, I don't think we should name the node after some
> OS-specific software concept. Device tree is intended to model hardware.
[...]
> > Maybe one solution would be to have a top-level DRM device with a register
> > map from 0x54000000 to 0x547fffff, which the TRM designates as "host
> > registers". Then subnodes could be used for the subdevices.
> 
> Ah yes, just what I was thinking above:-)

I came up with the following:

	/* host1x */
	host1x : host1x@50000000 {
		reg = <0x50000000 0x00024000>;
		interrupts = <0 64 0x04   /* cop syncpt */
			      0 65 0x04   /* mpcore syncpt */
			      0 66 0x04   /* cop general */
			      0 67 0x04>; /* mpcore general */
	};

	/* graphics host */
	graphics@54000000 {
		compatible = "nvidia,tegra20-graphics";

		#address-cells = <1>;
		#size-cells = <1>;
		ranges = <0 0x54000000 0x08000000>;

		host1x = <&host1x>;

		/* video-encoding/decoding */
		mpe@54040000 {
			reg = <0x54040000 0x00040000>;
			interrupts = <0 68 0x04>;
		};

		/* video input */
		vi@54080000 {
			reg = <0x54080000 0x00040000>;
			interrupts = <0 69 0x04>;
		};

		/* EPP */
		epp@540c0000 {
			reg = <0x540c0000 0x00040000>;
			interrupts = <0 70 0x04>;
		}

		/* ISP */
		isp@54100000 {
			reg = <0x54100000 0x00040000>;
			interrupts = <0 71 0x04>;
		};

		/* 2D engine */
		gr2d@54140000 {
			reg = <0x54140000 0x00040000>;
			interrupts = <0 72 0x04>;
		};

		/* 3D engine */
		gr3d@54180000 {
			reg = <0x54180000 0x00040000>;
		};

		/* display controllers */
		disp1 : dc@54200000 {
			compatible = "nvidia,tegra20-dc";
			reg = <0x54200000 0x00040000>;
			interrupts = <0 73 0x04>;
		};

		disp2 : dc@54240000 {
			compatible = "nvidia,tegra20-dc";
			reg = <0x54240000 0x00040000>;
			interrupts = <0 74 0x04>;
		};

		/* outputs */
		lvds : rgb {
			compatible = "nvidia,tegra20-rgb";
		};

		hdmi : hdmi@54280000 {
			compatible = "nvidia,tegra20-hdmi";
			reg = <0x54280000 0x00040000>;
			interrupts = <0 75 0x04>;
		};

		tvo : tvo@542c0000 {
			compatible = "nvidia,tegra20-tvo";
			reg = <0x542c0000 0x00040000>;
			interrupts = <0 76 0x04>;
		};

		dsi : dsi@54300000 {
			compatible = "nvidia,tegra20-dsi";
			reg = <0x54300000 0x00040000>;
		};

		display-controllers = <&disp1 &disp2>;
		outputs = <&lvds &hdmi &tvo &dsi>;

		/* initial configuration */
		configuration {
			lvds {
				display-controller = <&disp1>;
				output = <&lvds>;
			};

			hdmi {
				display-controller = <&disp2>;
				output = <&hdmi>;
			};
		};
	};

I added an additional node for the initial configuration so that the driver
knows which mapping to setup at boot. What I don't quite see yet is where to
attach EDID data or pass the phandle to the I2C controller for DDC/EDID
probing. The initial configuration is certainly not the right place. Perhaps
the outputs property should be made a node instead:

	outputs {
		lvds_out {
			output = <&lvds>;
			edid = <&edid>;
		};

		hdmi_out {
			output = <&hdmi>;
			ddc = <&i2c2>;
		};
	};

But then "outputs" should probably become something like "connectors"
instead and the initial configuration refers to the "_out" phandles.

Thierry

[-- Attachment #1.2: Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 190 bytes --]

_______________________________________________
iommu mailing list
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]                             ` <20120413091457.GB617-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
@ 2012-04-13 19:19                               ` Stephen Warren
       [not found]                                 ` <4F887C54.6030306-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
  0 siblings, 1 reply; 65+ messages in thread
From: Stephen Warren @ 2012-04-13 19:19 UTC (permalink / raw)
  To: Thierry Reding
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Olof Johansson, Colin Cross,
	Jon Mayo, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	David Airlie, iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	Joerg Roedel, Hiroshi Doyu,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

On 04/13/2012 03:14 AM, Thierry Reding wrote:
> * Stephen Warren wrote:
>> On 04/12/2012 11:44 AM, Thierry Reding wrote:
> [...]
>> And given that, I don't think we should name the node after some
>> OS-specific software concept. Device tree is intended to model hardware.
> [...]
>>> Maybe one solution would be to have a top-level DRM device with a register
>>> map from 0x54000000 to 0x547fffff, which the TRM designates as "host
>>> registers". Then subnodes could be used for the subdevices.
>>
>> Ah yes, just what I was thinking above:-)
> 
> I came up with the following:
> 
> 	/* host1x */
> 	host1x : host1x@50000000 {
> 		reg = <0x50000000 0x00024000>;
> 		interrupts = <0 64 0x04   /* cop syncpt */
> 			      0 65 0x04   /* mpcore syncpt */
> 			      0 66 0x04   /* cop general */
> 			      0 67 0x04>; /* mpcore general */
> 	};
> 
> 	/* graphics host */
> 	graphics@54000000 {
> 		compatible = "nvidia,tegra20-graphics";
> 
> 		#address-cells = <1>;
> 		#size-cells = <1>;
> 		ranges = <0 0x54000000 0x08000000>;
> 
> 		host1x = <&host1x>;
> 
> 		/* video-encoding/decoding */
> 		mpe@54040000 {
> 			reg = <0x54040000 0x00040000>;
> 			interrupts = <0 68 0x04>;
> 		};
... [a bunch of nodes for graphics-related HW modules]

That all looks reasonable.

> 		display-controllers = <&disp1 &disp2>;
> 		outputs = <&lvds &hdmi &tvo &dsi>;

I don't think you need both the child nodes and those two properties.

In other words, I think you either want:

	graphics@54000000 {
		... a bunch of child nodes
	};

or you want:

	disp1 : dc@54200000 {
		...
	};
	disp2 : dc@54240000 {
		...
	};
	... all the other graphics nodes

	graphics@54000000 {
		display-controllers = <&disp1 &disp2>;
		outputs = <&lvds &hdmi &tvo &dsi>;
	};

In the former case, presumably the drivers for the child nodes would
make some API call into the parent node and just register themselves
directly as a certain type of driver, so avoiding the
display-controllers/outputs properties.

> 		/* initial configuration */
> 		configuration {
> 			lvds {
> 				display-controller = <&disp1>;
> 				output = <&lvds>;
> 			};
> 
> 			hdmi {
> 				display-controller = <&disp2>;
> 				output = <&hdmi>;
> 			};
> 		};
> 	};
> 
> I added an additional node for the initial configuration so that the driver
> knows which mapping to setup at boot.

Isn't that kind of thing usually set up by the video= KMS-related kernel
command-line option? See Documentation/fb/modedb.txt. Again here, I
think the actual display controllers would be allocated to whichever
outputs get used on a first-come first-serve based, so no need for the
display-controller property above either way.

> What I don't quite see yet is where to
> attach EDID data or pass the phandle to the I2C controller for DDC/EDID
> probing.

I think there's a third node type.

1) Nodes for the display controllers in Tegra (Also known as CRTCs I
believe)

2) Nodes for the video outputs from the Tegra chips (what you have as
outputs above)

3) Connectors, which aren't represented in your DT above yet.

I think you need to add additional nodes for (3). These are where you'd
represent all the EDID/I2C/... stuff. Then, the nodes for the outputs
will point at the nodes for the connectors using phandles, or vice-versa.

(IIRC, although I didn't look at them in detail, the sdrm patches
recently mentioned something about splitting up the various object types
in DRM and allowing them to be represented separately, and I vaguely
recall something along the lines of the types I mention above. I might
expect to have a 1:1 mapping between the DRM object types and DT nodes.)

> The initial configuration is certainly not the right place. Perhaps
> the outputs property should be made a node instead:
> 
> 	outputs {
> 		lvds_out {
> 			output = <&lvds>;
> 			edid = <&edid>;
> 		};
> 
> 		hdmi_out {
> 			output = <&hdmi>;
> 			ddc = <&i2c2>;
> 		};
> 	};
> 
> But then "outputs" should probably become something like "connectors"
> instead and the initial configuration refers to the "_out" phandles.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]                               ` <1334347952.1625.12.camel@antimon>
@ 2012-04-14 12:51                                 ` Lucas Stach
  0 siblings, 0 replies; 65+ messages in thread
From: Lucas Stach @ 2012-04-14 12:51 UTC (permalink / raw)
  To: dri-devel

Oops, meant to put dri-devel on cc here.

Am Freitag, den 13.04.2012, 22:12 +0200 schrieb Lucas Stach:
> Am Freitag, den 13.04.2012, 08:33 +0100 schrieb Dave Airlie:
> > On Fri, Apr 13, 2012 at 12:10 AM, Lucas Stach <dev@lynxeye.de> wrote:
> > > Am Mittwoch, den 11.04.2012, 15:18 +0000 schrieb Arnd Bergmann:
> > >> On Wednesday 11 April 2012, Thierry Reding wrote:
> > >> >   * Daniel Vetter wrote:
> > >> > > On Wed, Apr 11, 2012 at 03:23:26PM +0200, Thierry Reding wrote:
> > >> > > > * Daniel Vetter wrote:
> > >> > > > > On Wed, Apr 11, 2012 at 02:10:30PM +0200, Thierry Reding wrote:
> > >> > > > > > This commit adds a very basic DRM driver for NVIDIA Tegra SoCs. It
> > >> > > > > > currently has rudimentary GEM support and can run a console on the
> > >> > > > > > framebuffer as well as X using the xf86-video-modesetting driver.
> > >> > > > > > Only the RGB output is supported. Quite a lot of things still need
> > >> > > > > > to be worked out and there is a lot of room for cleanup.
> > >> > > > >
> > >> > > > > Indeed, after a quick look there are tons of functions that are just stubs
> > >> > > > > ;-) One thing I wonder though is why you directly use the iommu api and
> > >> > > > > not wrap it up into dma_map? Is arm infrastructure just not there yet or
> > >> > > > > do you plan to tightly integrate the tegra drm with the iommu (e.g. for
> > >> > > > > process space switching or similarly funky stuff)?
> > >> > > >
> > >> > > > I'm not sure I know what you are referring to. Looking for all users of
> > >> > > > iommu_map() doesn't turn up anything related to dma_map. Can you point me in
> > >> > > > the right direction?
> > >> > >
> > >> > > Well, you use the iommu api to map/unmap memory into the iommu for tegra,
> > >> > > whereas usually device drivers just use the dma api to do that. The usual
> > >> > > interface is dma_map_sg/dma_unmap_sg, but there are quite a few variants
> > >> > > around. I'm just wondering why this you've choosen this.
> > >> >
> > >> > I don't think this works on ARM. Maybe I'm not seeing the whole picture but
> > >> > judging by a quick look through the kernel tree there aren't any users that
> > >> > map DMA memory through an IOMMU.
> > >>
> > >>
> > >> dma_map_sg is certainly the right interface to use, and Marek Szyprowski has
> > >> patches to make that work on ARM, hopefully going into v3.5, so you could
> > >> use those.
> > >
> > > Just jumping in here to make sure everyone understands the limitations
> > > of the Tegra 2 GART IOMMU we are talking about here. It has no isolation
> > > capabilities and a really small remapping window of 32MB. So it's
> > > impossible to remap every buffer used by the graphics engines. The only
> > > sane way to handle this is to set aside a chunk of stolen system memory
> > > as VRAM and let a memory manager like TTM handle the allocation of
> > > linear regions and GART mappings. This means a more tight integration of
> > > the DRM driver and the IOMMU, where I think that using the IOMMU API
> > > directly and completely controlling the GART from one driver is the
> > > right way to go for a number of reasons, where my biggest concern is
> > > that we can't implement a sane out-of-remapping space when we go through
> > > the dma_map API.
> > 
> > 
> > It sounds like the old AGP GARTs on PowerPC, where the CPU couldn't
> > get mappings of the GTT space,
> > and the GART was only available to the GPU device.
> > 
> 
> Yes, maybe we should treat the Tegra GART just like this. My current
> plan is to write a TTM backend on top of the IOMMU API as I think this
> is the right level of abstraction and both Tegra 2 GART and Tegra 3 SMMU
> are available through this interface.
> I think we can just allocate the real pages from highmem and flip them
> into IOMMU address space as needed - just the normal TTM use-case.
> 
> -- Lucas
> 

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]                                 ` <4F887C54.6030306-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
@ 2012-04-15  8:39                                   ` Thierry Reding
       [not found]                                     ` <20120415083905.GA15207-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
  0 siblings, 1 reply; 65+ messages in thread
From: Thierry Reding @ 2012-04-15  8:39 UTC (permalink / raw)
  To: Stephen Warren
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Olof Johansson, Colin Cross,
	Jon Mayo, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	David Airlie, iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	Joerg Roedel, Hiroshi Doyu,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

[-- Attachment #1: Type: text/plain, Size: 4908 bytes --]

* Stephen Warren wrote:
> On 04/13/2012 03:14 AM, Thierry Reding wrote:
> > 		display-controllers = <&disp1 &disp2>;
> > 		outputs = <&lvds &hdmi &tvo &dsi>;
> 
> I don't think you need both the child nodes and those two properties.
> 
> In other words, I think you either want:
> 
> 	graphics@54000000 {
> 		... a bunch of child nodes
> 	};
> 
> or you want:
> 
> 	disp1 : dc@54200000 {
> 		...
> 	};
> 	disp2 : dc@54240000 {
> 		...
> 	};
> 	... all the other graphics nodes
> 
> 	graphics@54000000 {
> 		display-controllers = <&disp1 &disp2>;
> 		outputs = <&lvds &hdmi &tvo &dsi>;
> 	};
> 
> In the former case, presumably the drivers for the child nodes would
> make some API call into the parent node and just register themselves
> directly as a certain type of driver, so avoiding the
> display-controllers/outputs properties.

I think I like the former better. The way I understand it the children of the
graphics node will have to be registered explicitly by the DRM driver because
of_platform_populate() doesn't work recursively. That would ensure that the
DRM driver can setup the CRTC and output registries before the other devices
call back into the DRM to register themselves.

> > 		/* initial configuration */
> > 		configuration {
> > 			lvds {
> > 				display-controller = <&disp1>;
> > 				output = <&lvds>;
> > 			};
> > 
> > 			hdmi {
> > 				display-controller = <&disp2>;
> > 				output = <&hdmi>;
> > 			};
> > 		};
> > 	};
> > 
> > I added an additional node for the initial configuration so that the driver
> > knows which mapping to setup at boot.
> 
> Isn't that kind of thing usually set up by the video= KMS-related kernel
> command-line option? See Documentation/fb/modedb.txt. Again here, I
> think the actual display controllers would be allocated to whichever
> outputs get used on a first-come first-serve based, so no need for the
> display-controller property above either way.

Boards should still be able to boot and display a console on the "standard"
output even if the user doesn't provide a video= option. Shouldn't there be a
way for a board DTS to specify what the default (or even allowed) connections
are?

Evaluation hardware like the Harmony might have LVDS, HDMI and VGA connectors
to provide for a wide range of use cases. The Plutux for instance has only an
HDMI connector and the Medcom has only LVDS. For the Medcom it would be quite
confusing for people to suddenly see an HDMI-1 connector pop up f.e. in
xrandr. It would be equally useless for the Plutux to show up as supporting
an LVDS or VGA connector.

> > What I don't quite see yet is where to
> > attach EDID data or pass the phandle to the I2C controller for DDC/EDID
> > probing.
> 
> I think there's a third node type.
> 
> 1) Nodes for the display controllers in Tegra (Also known as CRTCs I
> believe)
> 
> 2) Nodes for the video outputs from the Tegra chips (what you have as
> outputs above)
> 
> 3) Connectors, which aren't represented in your DT above yet.
> 
> I think you need to add additional nodes for (3). These are where you'd
> represent all the EDID/I2C/... stuff. Then, the nodes for the outputs
> will point at the nodes for the connectors using phandles, or vice-versa.

I see. Maybe this could be used for board-specific configuration? For
example, the Plutux could have something like this:

	connectors {
		hdmi {
			output = <&hdmi>;
			ddc = <&i2c2>;
		};
	};

The Medcom could have:

	connectors {
		lvds {
			output = <&lvds>;
			edid = <&edid>;
		};
	};

While Harmony could be more generic and provide more outputs:

	connectors {
		lvds {
			output = <&lvds>;
			ddc = <&i2c1>;
		};

		vga {
			/* which output is used for VGA? */
			output = <...>;
			ddc = <&i2c2>;

		hdmi {
			output = <&hdmi>;
			ddc = <&i2c3>;
		};
	};

Has there been any discussion as to how EDID data would best be represented
in DT? Should it just be a binary blob or rather some textual representation?

> (IIRC, although I didn't look at them in detail, the sdrm patches
> recently mentioned something about splitting up the various object types
> in DRM and allowing them to be represented separately, and I vaguely
> recall something along the lines of the types I mention above. I might
> expect to have a 1:1 mapping between the DRM object types and DT nodes.)

I've looked at them in more detail and I'm not sure that they're very well
suited for the Tegra. I think they may be a bit too simple to support
advanced features that will be required for Tegra. For the current state it
may be enough, but people at NVIDIA and Nouveau seem to be eager to start
working on things like 2D acceleration and I wouldn't want to convert to SDRM
now just to convert it back when somebody needs a feature that can't be added
with SDRM.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]                                     ` <20120415083905.GA15207-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
@ 2012-04-16 16:00                                       ` Stephen Warren
       [not found]                                         ` <4F8C423B.8050609-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
  0 siblings, 1 reply; 65+ messages in thread
From: Stephen Warren @ 2012-04-16 16:00 UTC (permalink / raw)
  To: Thierry Reding
  Cc: David Airlie, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Olof Johansson,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jon Mayo

On 04/15/2012 02:39 AM, Thierry Reding wrote:
> * Stephen Warren wrote:
>> On 04/13/2012 03:14 AM, Thierry Reding wrote:
>>> 		display-controllers = <&disp1 &disp2>;
>>> 		outputs = <&lvds &hdmi &tvo &dsi>;
>>
>> I don't think you need both the child nodes and those two properties.
>>
>> In other words, I think you either want:
>>
>> 	graphics@54000000 {
>> 		... a bunch of child nodes
>> 	};
>>
>> or you want:
>>
>> 	disp1 : dc@54200000 {
>> 		...
>> 	};
>> 	disp2 : dc@54240000 {
>> 		...
>> 	};
>> 	... all the other graphics nodes
>>
>> 	graphics@54000000 {
>> 		display-controllers = <&disp1 &disp2>;
>> 		outputs = <&lvds &hdmi &tvo &dsi>;
>> 	};
>>
>> In the former case, presumably the drivers for the child nodes would
>> make some API call into the parent node and just register themselves
>> directly as a certain type of driver, so avoiding the
>> display-controllers/outputs properties.
> 
> I think I like the former better. The way I understand it the children of the
> graphics node will have to be registered explicitly by the DRM driver because
> of_platform_populate() doesn't work recursively. That would ensure that the
> DRM driver can setup the CRTC and output registries before the other devices
> call back into the DRM to register themselves.

Yes, with the first way, the DRM driver will have to call
of_platform_populate() recursively to make this work.

The thing here is that the device tree should model hardware, not be
designed purely to match the device registration needs of the DRM
driver. I'm not sure that it's correct to model all those devices as
children of the top-level graphics object; I /think/ all the devices are
flat on a single bus, and hence not children of each-other. That all
said, I guess having the nodes as children isn't too far off how the HW
is designed (even if the register accesses aren't on a child bus, the
modules at least logically are grouped together in an umbrella
situation), so I wouldn't push back on the first option above that you
prefer.

>>> 		/* initial configuration */
>>> 		configuration {
>>> 			lvds {
>>> 				display-controller = <&disp1>;
>>> 				output = <&lvds>;
>>> 			};
>>>
>>> 			hdmi {
>>> 				display-controller = <&disp2>;
>>> 				output = <&hdmi>;
>>> 			};
>>> 		};
>>> 	};
>>>
>>> I added an additional node for the initial configuration so that the driver
>>> knows which mapping to setup at boot.
>>
>> Isn't that kind of thing usually set up by the video= KMS-related kernel
>> command-line option? See Documentation/fb/modedb.txt. Again here, I
>> think the actual display controllers would be allocated to whichever
>> outputs get used on a first-come first-serve based, so no need for the
>> display-controller property above either way.
> 
> Boards should still be able to boot and display a console on the "standard"
> output even if the user doesn't provide a video= option. Shouldn't there be a
> way for a board DTS to specify what the default (or even allowed) connections
> are?

Why wouldn't the default be to light up all outputs that have an
attached display, or an algorithm something like:

* If internal LCD is present, use that
* Else, if HDMI display plugged in, use that
...

> Evaluation hardware like the Harmony might have LVDS, HDMI and VGA connectors
> to provide for a wide range of use cases. The Plutux for instance has only an
> HDMI connector and the Medcom has only LVDS. For the Medcom it would be quite
> confusing for people to suddenly see an HDMI-1 connector pop up f.e. in
> xrandr. It would be equally useless for the Plutux to show up as supporting
> an LVDS or VGA connector.

So the device tree for those devices would disable (or not include) the
connectors that were not present on the board.

...
> I see. Maybe this could be used for board-specific configuration? For
> example, the Plutux could have something like this:
> 
> 	connectors {
> 		hdmi {
> 			output = <&hdmi>;
> 			ddc = <&i2c2>;
> 		};
> 	};
> 
> The Medcom could have:
> 
> 	connectors {
> 		lvds {
> 			output = <&lvds>;
> 			edid = <&edid>;
> 		};
> 	};
> 
> While Harmony could be more generic and provide more outputs:
> 
> 	connectors {
> 		lvds {
> 			output = <&lvds>;
> 			ddc = <&i2c1>;
> 		};
> 
> 		vga {
> 			/* which output is used for VGA? */
> 			output = <...>;
> 			ddc = <&i2c2>;
> 
> 		hdmi {
> 			output = <&hdmi>;
> 			ddc = <&i2c3>;
> 		};
> 	};

That looks like a reasonable start.

> Has there been any discussion as to how EDID data would best be represented
> in DT? Should it just be a binary blob or rather some textual representation?

I think a binary blob makes sense - that's the exact same format it'd
have if read over the DDC I2C bus.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]                                         ` <4F8C423B.8050609-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
@ 2012-04-16 18:48                                           ` Thierry Reding
       [not found]                                             ` <20120416184819.GA21043-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
  0 siblings, 1 reply; 65+ messages in thread
From: Thierry Reding @ 2012-04-16 18:48 UTC (permalink / raw)
  To: Stephen Warren
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Olof Johansson, Colin Cross,
	Jon Mayo, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	David Airlie, iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
	Joerg Roedel, Hiroshi Doyu,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ

[-- Attachment #1: Type: text/plain, Size: 2938 bytes --]

* Stephen Warren wrote:
> On 04/15/2012 02:39 AM, Thierry Reding wrote:
> > I think I like the former better. The way I understand it the children of the
> > graphics node will have to be registered explicitly by the DRM driver because
> > of_platform_populate() doesn't work recursively. That would ensure that the
> > DRM driver can setup the CRTC and output registries before the other devices
> > call back into the DRM to register themselves.
> 
> Yes, with the first way, the DRM driver will have to call
> of_platform_populate() recursively to make this work.
> 
> The thing here is that the device tree should model hardware, not be
> designed purely to match the device registration needs of the DRM
> driver. I'm not sure that it's correct to model all those devices as
> children of the top-level graphics object; I /think/ all the devices are
> flat on a single bus, and hence not children of each-other. That all
> said, I guess having the nodes as children isn't too far off how the HW
> is designed (even if the register accesses aren't on a child bus, the
> modules at least logically are grouped together in an umbrella
> situation), so I wouldn't push back on the first option above that you
> prefer.

After trying to implement this I'm not so sure anymore that this is the best
approach. I think I'll have to play around with this some more to see what
fits best.

> > Boards should still be able to boot and display a console on the "standard"
> > output even if the user doesn't provide a video= option. Shouldn't there be a
> > way for a board DTS to specify what the default (or even allowed) connections
> > are?
> 
> Why wouldn't the default be to light up all outputs that have an
> attached display, or an algorithm something like:
> 
> * If internal LCD is present, use that
> * Else, if HDMI display plugged in, use that
> ...

That sounds doable.

> > Evaluation hardware like the Harmony might have LVDS, HDMI and VGA connectors
> > to provide for a wide range of use cases. The Plutux for instance has only an
> > HDMI connector and the Medcom has only LVDS. For the Medcom it would be quite
> > confusing for people to suddenly see an HDMI-1 connector pop up f.e. in
> > xrandr. It would be equally useless for the Plutux to show up as supporting
> > an LVDS or VGA connector.
> 
> So the device tree for those devices would disable (or not include) the
> connectors that were not present on the board.

Okay, makes sense.

> > Has there been any discussion as to how EDID data would best be represented
> > in DT? Should it just be a binary blob or rather some textual representation?
> 
> I think a binary blob makes sense - that's the exact same format it'd
> have if read over the DDC I2C bus.

DTC has /incbin/ for that. Is arch/arm/boot/dts still the correct place for
EDID blobs? I could add tegra-medcom.edid if that's okay.

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]                                             ` <20120416184819.GA21043-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
@ 2012-04-16 18:57                                               ` Stephen Warren
       [not found]                                                 ` <4F8C6B80.4000001-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
  0 siblings, 1 reply; 65+ messages in thread
From: Stephen Warren @ 2012-04-16 18:57 UTC (permalink / raw)
  To: Thierry Reding
  Cc: David Airlie, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Olof Johansson,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jon Mayo

On 04/16/2012 12:48 PM, Thierry Reding wrote:
> * Stephen Warren wrote:
...
>>> Has there been any discussion as to how EDID data would best be represented
>>> in DT? Should it just be a binary blob or rather some textual representation?
>>
>> I think a binary blob makes sense - that's the exact same format it'd
>> have if read over the DDC I2C bus.
> 
> DTC has /incbin/ for that. Is arch/arm/boot/dts still the correct place for
> EDID blobs? I could add tegra-medcom.edid if that's okay.

As far as I know, yes.

Perhaps we'll want to start putting stuff in SoC-specific
sub-directories given the number of files we'll end up with here
(irrespective of EDID etc.), but I haven't seen any move towards that yet.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]                                                 ` <4F8C6B80.4000001-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
@ 2012-04-16 19:03                                                   ` Thierry Reding
       [not found]                                                     ` <20120416190320.GA21233-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
  0 siblings, 1 reply; 65+ messages in thread
From: Thierry Reding @ 2012-04-16 19:03 UTC (permalink / raw)
  To: Stephen Warren
  Cc: David Airlie, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Olof Johansson,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jon Mayo


[-- Attachment #1.1: Type: text/plain, Size: 1162 bytes --]

* Stephen Warren wrote:
> On 04/16/2012 12:48 PM, Thierry Reding wrote:
> > * Stephen Warren wrote:
> ...
> >>> Has there been any discussion as to how EDID data would best be represented
> >>> in DT? Should it just be a binary blob or rather some textual representation?
> >>
> >> I think a binary blob makes sense - that's the exact same format it'd
> >> have if read over the DDC I2C bus.
> > 
> > DTC has /incbin/ for that. Is arch/arm/boot/dts still the correct place for
> > EDID blobs? I could add tegra-medcom.edid if that's okay.
> 
> As far as I know, yes.
> 
> Perhaps we'll want to start putting stuff in SoC-specific
> sub-directories given the number of files we'll end up with here
> (irrespective of EDID etc.), but I haven't seen any move towards that yet.

Yes, especially as more machines are moving to DT that directory will soon
become quite cluttered. I suppose a tegra subdirectory wouldn't hurt.

I've been looking about for tools to generate EDID data but didn't find
anything useful. Does anyone know of any tool that's more convenient than
manually filling a struct edid and writing that to a file?

Thierry

[-- Attachment #1.2: Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 190 bytes --]

_______________________________________________
iommu mailing list
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 4/4] drm: Add NVIDIA Tegra support
       [not found]                                                     ` <20120416190320.GA21233-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
@ 2012-04-16 20:37                                                       ` Stephen Warren
  0 siblings, 0 replies; 65+ messages in thread
From: Stephen Warren @ 2012-04-16 20:37 UTC (permalink / raw)
  To: Thierry Reding
  Cc: David Airlie, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Olof Johansson,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jon Mayo

On 04/16/2012 01:03 PM, Thierry Reding wrote:
...
> I've been looking about for tools to generate EDID data but didn't find
> anything useful. Does anyone know of any tool that's more convenient than
> manually filling a struct edid and writing that to a file?

Sorry, no.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 0/4] Add NVIDIA Tegra DRM support
       [not found] ` <1334146230-1795-1-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
                     ` (5 preceding siblings ...)
  2012-04-11 12:46   ` Hiroshi Doyu
@ 2012-04-19 17:35   ` Thierry Reding
       [not found]     ` <20120419173537.GA7692-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
  6 siblings, 1 reply; 65+ messages in thread
From: Thierry Reding @ 2012-04-19 17:35 UTC (permalink / raw)
  To: linux-tegra-u79uwXL29TY76Z2rM5mHXA
  Cc: Stephen Warren, Joerg Roedel,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Jon Mayo,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	Hiroshi Doyu, Lucas Stach

[-- Attachment #1: Type: text/plain, Size: 679 bytes --]

Before posting the next round of patches I wanted to clarify whether we need
to take the Tegra driver through staging. Lucas brought this up referring to
previous experience with Nouveau where Linus used to complain that userspace
ABI was broken for non-staging drivers. I don't know how relevant that is
for Tegra. We could also keep it in drivers/gpu/drm and only add userspace
interfaces that we are sure are not going to change. Currently there isn't
isn't anything that could be easily broken as only some of the standard DRM
interfaces are supported anyway.

Alternatively we could keep the driver in a separate tree until it becomes
mature enough.

Any thoughts?

Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 0/4] Add NVIDIA Tegra DRM support
       [not found]     ` <20120419173537.GA7692-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
@ 2012-04-19 19:28       ` Dave Airlie
       [not found]         ` <CAPM=9tzK83yYS33eNruvFDwb62ycZxJMC31davVRN=yaZD53YA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 65+ messages in thread
From: Dave Airlie @ 2012-04-19 19:28 UTC (permalink / raw)
  To: Thierry Reding
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA, Stephen Warren, Joerg Roedel,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	Jon Mayo, Hiroshi Doyu

On Thu, Apr 19, 2012 at 6:35 PM, Thierry Reding
<thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org> wrote:
> Before posting the next round of patches I wanted to clarify whether we need
> to take the Tegra driver through staging. Lucas brought this up referring to
> previous experience with Nouveau where Linus used to complain that userspace
> ABI was broken for non-staging drivers. I don't know how relevant that is
> for Tegra. We could also keep it in drivers/gpu/drm and only add userspace
> interfaces that we are sure are not going to change. Currently there isn't
> isn't anything that could be easily broken as only some of the standard DRM
> interfaces are supported anyway.
>
> Alternatively we could keep the driver in a separate tree until it becomes
> mature enough.
>
> Any thoughts?

It's probably okay to avoid staging if it doesn't add any userspace ioctls.

A KMS driver that just supports the dumb ioctls so -modesetting works,
would be the first thing to aim for I suppose, like how the exynos
guys did it.

Adding userspace interfaces is where you'll get into ABI guarantees
etc, and these are normally required only for the accel engines.

Dave.

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 0/4] Add NVIDIA Tegra DRM support
       [not found]         ` <CAPM=9tzK83yYS33eNruvFDwb62ycZxJMC31davVRN=yaZD53YA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2012-04-19 20:40           ` Thierry Reding
       [not found]             ` <20120419204016.GA8954-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
  0 siblings, 1 reply; 65+ messages in thread
From: Thierry Reding @ 2012-04-19 20:40 UTC (permalink / raw)
  To: Dave Airlie
  Cc: Stephen Warren, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Jon Mayo,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA


[-- Attachment #1.1: Type: text/plain, Size: 1739 bytes --]

* Dave Airlie wrote:
> On Thu, Apr 19, 2012 at 6:35 PM, Thierry Reding
> <thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org> wrote:
> > Before posting the next round of patches I wanted to clarify whether we need
> > to take the Tegra driver through staging. Lucas brought this up referring to
> > previous experience with Nouveau where Linus used to complain that userspace
> > ABI was broken for non-staging drivers. I don't know how relevant that is
> > for Tegra. We could also keep it in drivers/gpu/drm and only add userspace
> > interfaces that we are sure are not going to change. Currently there isn't
> > isn't anything that could be easily broken as only some of the standard DRM
> > interfaces are supported anyway.
> >
> > Alternatively we could keep the driver in a separate tree until it becomes
> > mature enough.
> >
> > Any thoughts?
> 
> It's probably okay to avoid staging if it doesn't add any userspace ioctls.
> 
> A KMS driver that just supports the dumb ioctls so -modesetting works,
> would be the first thing to aim for I suppose, like how the exynos
> guys did it.
> 
> Adding userspace interfaces is where you'll get into ABI guarantees
> etc, and these are normally required only for the accel engines.

I think this is what Lucas was concerned about. The plan is to look at how
much can be used from the Nouveau code and make it work on the Tegra. So
would it be possible to get a basic dumb KMS driver into mainline
(non-staging) and phase in acceleration later on, with ABI guarantees? I
guess development can go on in separate trees until the ABI is stable and can
subsequently be ported to the mainline driver.

Is that an acceptable approach?

Thierry

[-- Attachment #1.2: Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 190 bytes --]

_______________________________________________
iommu mailing list
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 0/4] Add NVIDIA Tegra DRM support
       [not found]             ` <20120419204016.GA8954-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
@ 2012-04-19 20:59               ` Jon Mayo
       [not found]                 ` <4F907CBB.4080705-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  2012-04-19 22:21               ` Jerome Glisse
  1 sibling, 1 reply; 65+ messages in thread
From: Jon Mayo @ 2012-04-19 20:59 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Dave Airlie, linux-tegra-u79uwXL29TY76Z2rM5mHXA, Stephen Warren,
	Joerg Roedel, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	Hiroshi Doyu

On 04/19/2012 01:40 PM, Thierry Reding wrote:
> * PGP Signed by an unknown key
>
> * Dave Airlie wrote:
>> On Thu, Apr 19, 2012 at 6:35 PM, Thierry Reding
>> <thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>  wrote:
>>> Before posting the next round of patches I wanted to clarify whether we need
>>> to take the Tegra driver through staging. Lucas brought this up referring to
>>> previous experience with Nouveau where Linus used to complain that userspace
>>> ABI was broken for non-staging drivers. I don't know how relevant that is
>>> for Tegra. We could also keep it in drivers/gpu/drm and only add userspace
>>> interfaces that we are sure are not going to change. Currently there isn't
>>> isn't anything that could be easily broken as only some of the standard DRM
>>> interfaces are supported anyway.
>>>
>>> Alternatively we could keep the driver in a separate tree until it becomes
>>> mature enough.
>>>
>>> Any thoughts?
>>
>> It's probably okay to avoid staging if it doesn't add any userspace ioctls.
>>
>> A KMS driver that just supports the dumb ioctls so -modesetting works,
>> would be the first thing to aim for I suppose, like how the exynos
>> guys did it.
>>
>> Adding userspace interfaces is where you'll get into ABI guarantees
>> etc, and these are normally required only for the accel engines.
>
> I think this is what Lucas was concerned about. The plan is to look at how
> much can be used from the Nouveau code and make it work on the Tegra. So
> would it be possible to get a basic dumb KMS driver into mainline
> (non-staging) and phase in acceleration later on, with ABI guarantees? I
> guess development can go on in separate trees until the ABI is stable and can
> subsequently be ported to the mainline driver.
>
> Is that an acceptable approach?
>
> Thierry
>

That certainly seems like the most reasonable approach to me. Get KMS 
only in first. It's a useful driver as-is, and has the lowest barrier to 
entry into upstream.

Then later we can phase in enhancements. We certainly have plenty of 
places internally and externally to hash out acceleration interfaces, 
and come to some consensus at at later date (either on linux-tegra or 
direct email).

We have a lot of concerns here. What is best for X11, what is best for 
Android, how do we keep healthy open source implementations, and how 
does NVIDIA move forward with supporting new Tegra on an open source 
implementation. (My vote is NVIDIA starts using this DRM in-house and 
builds new extensions on top of it, sharing patches on LKML when the 
hardware is released)

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 0/4] Add NVIDIA Tegra DRM support
       [not found]             ` <20120419204016.GA8954-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
  2012-04-19 20:59               ` Jon Mayo
@ 2012-04-19 22:21               ` Jerome Glisse
       [not found]                 ` <CAH3drwZhTzuOVfybB_KBgk22csK47xXv5G4aMOuqPy+ibKd21A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  1 sibling, 1 reply; 65+ messages in thread
From: Jerome Glisse @ 2012-04-19 22:21 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Stephen Warren, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	Jon Mayo, Dave Airlie

On Thu, Apr 19, 2012 at 4:40 PM, Thierry Reding
<thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org> wrote:
> * Dave Airlie wrote:
>> On Thu, Apr 19, 2012 at 6:35 PM, Thierry Reding
>> <thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org> wrote:
>> > Before posting the next round of patches I wanted to clarify whether we need
>> > to take the Tegra driver through staging. Lucas brought this up referring to
>> > previous experience with Nouveau where Linus used to complain that userspace
>> > ABI was broken for non-staging drivers. I don't know how relevant that is
>> > for Tegra. We could also keep it in drivers/gpu/drm and only add userspace
>> > interfaces that we are sure are not going to change. Currently there isn't
>> > isn't anything that could be easily broken as only some of the standard DRM
>> > interfaces are supported anyway.
>> >
>> > Alternatively we could keep the driver in a separate tree until it becomes
>> > mature enough.
>> >
>> > Any thoughts?
>>
>> It's probably okay to avoid staging if it doesn't add any userspace ioctls.
>>
>> A KMS driver that just supports the dumb ioctls so -modesetting works,
>> would be the first thing to aim for I suppose, like how the exynos
>> guys did it.
>>
>> Adding userspace interfaces is where you'll get into ABI guarantees
>> etc, and these are normally required only for the accel engines.
>
> I think this is what Lucas was concerned about. The plan is to look at how
> much can be used from the Nouveau code and make it work on the Tegra. So
> would it be possible to get a basic dumb KMS driver into mainline
> (non-staging) and phase in acceleration later on, with ABI guarantees? I
> guess development can go on in separate trees until the ABI is stable and can
> subsequently be ported to the mainline driver.
>
> Is that an acceptable approach?
>
> Thierry
>

Or you can hide the accel ioctl behing a staging/experimental kernel
option that give you right to change the ABI and do everything upstream.
Once you like your abi you just remove the option and enable the
ioctl for the default case.

Cheers,
Jerome

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 0/4] Add NVIDIA Tegra DRM support
       [not found]                 ` <4F907CBB.4080705-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
@ 2012-04-20  5:02                   ` Thierry Reding
       [not found]                     ` <20120420050231.GA15313-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
  0 siblings, 1 reply; 65+ messages in thread
From: Thierry Reding @ 2012-04-20  5:02 UTC (permalink / raw)
  To: Jon Mayo
  Cc: Stephen Warren, devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, Dave Airlie


[-- Attachment #1.1: Type: text/plain, Size: 1963 bytes --]

* Jon Mayo wrote:
> On 04/19/2012 01:40 PM, Thierry Reding wrote:
[...]
> >So would it be possible to get a basic dumb KMS driver into mainline
> >(non-staging) and phase in acceleration later on, with ABI guarantees? I
> >guess development can go on in separate trees until the ABI is stable and can
> >subsequently be ported to the mainline driver.
> >
> >Is that an acceptable approach?
> 
> That certainly seems like the most reasonable approach to me. Get
> KMS only in first. It's a useful driver as-is, and has the lowest
> barrier to entry into upstream.
> 
> Then later we can phase in enhancements. We certainly have plenty of
> places internally and externally to hash out acceleration
> interfaces, and come to some consensus at at later date (either on
> linux-tegra or direct email).

Okay. Let's do that then.

> We have a lot of concerns here. What is best for X11, what is best
> for Android, how do we keep healthy open source implementations, and
> how does NVIDIA move forward with supporting new Tegra on an open
> source implementation.

I think by supporting the DRM we can get pretty far for X11. Writing a Tegra-
specific driver based off xf86-video-modesetting can be done to use advanced
features if they can't be abstracted away properly. DRM also paves the way
for Wayland support.

What I see as somewhat of a problem is how to get NVIDIA and the community to
work together (and work together well). We'll have to see how this works out,
but I'd hate to see more resources wasted because everybody starts doing
their own thing.

> (My vote is NVIDIA starts using this DRM in-house and builds new
> extensions on top of it, sharing patches on LKML when the hardware is
> released)

That sounds like a good plan. Ideally you should even share the patches as
soon as they're ready. That'll give viewers some head start and you can fix
the code even before the hardware is released.

Thierry

[-- Attachment #1.2: Type: application/pgp-signature, Size: 198 bytes --]

[-- Attachment #2: Type: text/plain, Size: 190 bytes --]

_______________________________________________
iommu mailing list
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 0/4] Add NVIDIA Tegra DRM support
       [not found]                 ` <CAH3drwZhTzuOVfybB_KBgk22csK47xXv5G4aMOuqPy+ibKd21A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2012-04-20  5:05                   ` Thierry Reding
  0 siblings, 0 replies; 65+ messages in thread
From: Thierry Reding @ 2012-04-20  5:05 UTC (permalink / raw)
  To: Jerome Glisse
  Cc: Dave Airlie, Stephen Warren, Joerg Roedel,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Jon Mayo,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, Hiroshi Doyu

[-- Attachment #1: Type: text/plain, Size: 350 bytes --]

* Jerome Glisse wrote:
> Or you can hide the accel ioctl behing a staging/experimental kernel
> option that give you right to change the ABI and do everything upstream.
> Once you like your abi you just remove the option and enable the
> ioctl for the default case.

If it's acceptable, that sound like the most promising way to go.

Thanks,
Thierry

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 0/4] Add NVIDIA Tegra DRM support
       [not found]                     ` <20120420050231.GA15313-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
@ 2012-04-20  6:05                       ` Lucas Stach
  2012-04-20 19:54                         ` Jon Mayo
  0 siblings, 1 reply; 65+ messages in thread
From: Lucas Stach @ 2012-04-20  6:05 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Jon Mayo, Stephen Warren, Joerg Roedel,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, Hiroshi Doyu

Am Freitag, den 20.04.2012, 07:02 +0200 schrieb Thierry Reding:
> * Jon Mayo wrote:
> > On 04/19/2012 01:40 PM, Thierry Reding wrote:
> [...]
> > >So would it be possible to get a basic dumb KMS driver into mainline
> > >(non-staging) and phase in acceleration later on, with ABI guarantees? I
> > >guess development can go on in separate trees until the ABI is stable and can
> > >subsequently be ported to the mainline driver.
> > >
> > >Is that an acceptable approach?
> > 
> > That certainly seems like the most reasonable approach to me. Get
> > KMS only in first. It's a useful driver as-is, and has the lowest
> > barrier to entry into upstream.
> > 
> > Then later we can phase in enhancements. We certainly have plenty of
> > places internally and externally to hash out acceleration
> > interfaces, and come to some consensus at at later date (either on
> > linux-tegra or direct email).
> 
> Okay. Let's do that then.

Yes, I think we should go the route that Jerome Glisse pointed out: get
in a basic KMS driver first and hide any accel ioctl under a staging
config option.
> 
> > We have a lot of concerns here. What is best for X11, what is best
> > for Android, how do we keep healthy open source implementations, and
> > how does NVIDIA move forward with supporting new Tegra on an open
> > source implementation.
> 
> I think by supporting the DRM we can get pretty far for X11. Writing a Tegra-
> specific driver based off xf86-video-modesetting can be done to use advanced
> features if they can't be abstracted away properly. DRM also paves the way
> for Wayland support.
> 
> What I see as somewhat of a problem is how to get NVIDIA and the community to
> work together (and work together well). We'll have to see how this works out,
> but I'd hate to see more resources wasted because everybody starts doing
> their own thing.

I'm really interested how this turns out in the end. I hope we can get a
somewhat stable cooperation between NVIDIA and the community, like AMD
has established at the moment.
> 
> > (My vote is NVIDIA starts using this DRM in-house and builds new
> > extensions on top of it, sharing patches on LKML when the hardware is
> > released)
> 
> That sounds like a good plan. Ideally you should even share the patches as
> soon as they're ready. That'll give viewers some head start and you can fix
> the code even before the hardware is released.

One thing I would like to have is upstream first. We have seen much
Tegra development in both the nv-linux and chromium trees, but those
things are going upstream extremely slowly. I can understand that this
strategy was beneficial for a fast bring up of the new Tegra hardware,
but the DRM driver shouldn't be time critical and so everything should
be done to meet upstream quality from the start.

-- Lucas

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RFC 0/4] Add NVIDIA Tegra DRM support
  2012-04-20  6:05                       ` Lucas Stach
@ 2012-04-20 19:54                         ` Jon Mayo
  0 siblings, 0 replies; 65+ messages in thread
From: Jon Mayo @ 2012-04-20 19:54 UTC (permalink / raw)
  To: Lucas Stach
  Cc: Thierry Reding, Stephen Warren, Joerg Roedel,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, Colin Cross,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA, Hiroshi Doyu


On 04/19/2012 11:05 PM, Lucas Stach wrote:
> Am Freitag, den 20.04.2012, 07:02 +0200 schrieb Thierry Reding:
*cut*
>
> Yes, I think we should go the route that Jerome Glisse pointed out: get
> in a basic KMS driver first and hide any accel ioctl under a staging
> config option.

Everyone seems happy with that, I have no objections.

*cut*
>
> I'm really interested how this turns out in the end. I hope we can get a
> somewhat stable cooperation between NVIDIA and the community, like AMD
> has established at the moment.

Well, we always strive to be better than AMD ;-)
But seriously, I don't think GPU technology would be where it is today 
if NVIDIA and AMD didn't compete aggressively.

But our mobile division is more like TI, Qualcomm, Freescale and other 
SoC vendors. Upstreaming changes for arch/arm has so far been a 
different challenge than only updating drivers/gpu for x86. Mostly 
because there are so many aspects to SoCs compared to a driver for a 
graphics card or PC chipset. And it doesn't help that arch/arm is a real 
mess of wildly different SoCs, and it lacks the stability and maturity 
of the x86 code base. The state of ARM is every vendor's fault, every 
chip generation can be a complete resign of one or more subsystems. x86 
tends to be layers of extensions and enhancements from 1-3 vendors.

But even if Mobile doesn't consider AMD or Intel to be among the 
competition, we certainly watch and listen to good open source 
contributors and try to learn from their successes and mistakes. (and 
our own mistakes, we're not perfect!)

What I'm trying to say is that Tegra's business needs are different, so 
you should not be surprised to see different behavior from us. There are 
a lot of difficult issues with open sourcing the work done by my desktop 
colleagues. But those barriers don't apply to Tegra. Different product, 
different market, different rules.

>>
>>> (My vote is NVIDIA starts using this DRM in-house and builds new
>>> extensions on top of it, sharing patches on LKML when the hardware is
>>> released)
>>
>> That sounds like a good plan. Ideally you should even share the patches as
>> soon as they're ready. That'll give viewers some head start and you can fix
>> the code even before the hardware is released.
>
> One thing I would like to have is upstream first. We have seen much
> Tegra development in both the nv-linux and chromium trees, but those
> things are going upstream extremely slowly. I can understand that this
> strategy was beneficial for a fast bring up of the new Tegra hardware,
> but the DRM driver shouldn't be time critical and so everything should
> be done to meet upstream quality from the start.
>
> -- Lucas
>
>

We have a team of interested engineers assigned to just that problem.
Fractured trees are not efficient for us internally either. We want 
upstream to be our common repository for most changes. And internally we 
have been stricter about conforming to Linux kernel coding conventions 
in attempt to give ourselves less work when we get to upstreaming a 
change. I'll be happy when I can tell my customers they can just grab 
the latest Tegra updates from git.kernel.org

Hopefully our efforts will begin to convince you.

- Jon

^ permalink raw reply	[flat|nested] 65+ messages in thread

end of thread, other threads:[~2012-04-20 19:54 UTC | newest]

Thread overview: 65+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-11 12:10 [RFC 0/4] Add NVIDIA Tegra DRM support Thierry Reding
     [not found] ` <1334146230-1795-1-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
2012-04-11 12:10   ` [RFC 1/4] iommu: tegra/gart: use correct gart_device Thierry Reding
2012-04-11 12:10   ` [RFC 2/4] iommu: tegra/gart: Add device tree support Thierry Reding
     [not found]     ` <1334146230-1795-3-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
2012-04-11 17:21       ` Stephen Warren
     [not found]         ` <4F85BD9D.7050409-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2012-04-12  6:51           ` Thierry Reding
2012-04-11 12:10   ` [RFC 3/4] drm: fixed: Add dfixed_frac() macro Thierry Reding
     [not found]     ` <1334146230-1795-4-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
2012-04-11 17:25       ` Stephen Warren
     [not found]         ` <4F85BE77.7090807-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2012-04-12  6:52           ` Thierry Reding
2012-04-11 12:10   ` [RFC 4/4] drm: Add NVIDIA Tegra support Thierry Reding
     [not found]     ` <1334146230-1795-5-git-send-email-thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org>
2012-04-11 12:48       ` Daniel Vetter
     [not found]         ` <20120411124810.GK4296-dv86pmgwkMBes7Z6vYuT8azUEOm+Xw19@public.gmane.org>
2012-04-11 13:23           ` Thierry Reding
     [not found]             ` <20120411132326.GD27337-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
2012-04-11 13:35               ` Daniel Vetter
     [not found]                 ` <20120411133512.GL4296-dv86pmgwkMBes7Z6vYuT8azUEOm+Xw19@public.gmane.org>
2012-04-11 14:11                   ` Thierry Reding
     [not found]                     ` <20120411141108.GI27337-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
2012-04-11 14:34                       ` Daniel Vetter
     [not found]                         ` <20120411143456.GM4296-dv86pmgwkMBes7Z6vYuT8azUEOm+Xw19@public.gmane.org>
2012-04-11 14:43                           ` Alan Cox
     [not found]                             ` <20120411154309.1f04fb80-38n7/U1jhRXW96NNrWNlrekiAK3p4hvP@public.gmane.org>
2012-04-11 14:49                               ` Daniel Vetter
2012-04-11 15:00                           ` Thierry Reding
2012-04-11 14:52                       ` Alan Cox
     [not found]                         ` <20120411155237.24233afc-38n7/U1jhRXW96NNrWNlrekiAK3p4hvP@public.gmane.org>
2012-04-11 15:06                           ` Thierry Reding
     [not found]                             ` <20120411150603.GC20811-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
2012-04-11 15:11                               ` Alan Cox
2012-04-11 15:18                       ` Arnd Bergmann
     [not found]                         ` <201204111518.41968.arnd-r2nGTMty4D4@public.gmane.org>
2012-04-12  7:18                           ` Thierry Reding
     [not found]                             ` <20120412071816.GA18252-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
2012-04-12  8:40                               ` Marek Szyprowski
     [not found]                                 ` <025f01cd1887$da56b6e0$8f0424a0$%szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2012-04-12 11:18                                   ` Arnd Bergmann
     [not found]                                     ` <201204121118.19685.arnd-r2nGTMty4D4@public.gmane.org>
2012-04-12 13:30                                       ` Marek Szyprowski
     [not found]                                         ` <02aa01cd18b0$7b2586a0$717093e0$%szyprowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2012-04-12 13:34                                           ` Thierry Reding
2012-04-12 14:23                                       ` Daniel Vetter
2012-04-12 13:42                                   ` Thierry Reding
     [not found]                                     ` <20120412134216.GB15701-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
2012-04-12 14:20                                       ` Marek Szyprowski
2012-04-12 23:10                           ` Lucas Stach
     [not found]                             ` <CAPM=9tztW_xLkOQ1qGjJdaPat_c5ivKPhik5-K8nD58SmF1Qrg@mail.gmail.com>
     [not found]                               ` <1334347952.1625.12.camel@antimon>
2012-04-14 12:51                                 ` Lucas Stach
2012-04-12 18:56           ` Jon Mayo
2012-04-11 18:12       ` Stephen Warren
     [not found]         ` <4F85C97E.50203-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2012-04-12  6:50           ` Thierry Reding
     [not found]             ` <20120412065038.GB4162-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
2012-04-12 15:49               ` Stephen Warren
     [not found]                 ` <4F86F97C.8010508-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2012-04-12 17:44                   ` Thierry Reding
     [not found]                     ` <20120412174429.GB10042-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
2012-04-12 22:13                       ` Stephen Warren
     [not found]                         ` <4F8753A0.6040907-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2012-04-13  9:14                           ` Thierry Reding
     [not found]                             ` <20120413091457.GB617-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
2012-04-13 19:19                               ` Stephen Warren
     [not found]                                 ` <4F887C54.6030306-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2012-04-15  8:39                                   ` Thierry Reding
     [not found]                                     ` <20120415083905.GA15207-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
2012-04-16 16:00                                       ` Stephen Warren
     [not found]                                         ` <4F8C423B.8050609-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2012-04-16 18:48                                           ` Thierry Reding
     [not found]                                             ` <20120416184819.GA21043-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
2012-04-16 18:57                                               ` Stephen Warren
     [not found]                                                 ` <4F8C6B80.4000001-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>
2012-04-16 19:03                                                   ` Thierry Reding
     [not found]                                                     ` <20120416190320.GA21233-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
2012-04-16 20:37                                                       ` Stephen Warren
2012-04-12  9:21           ` Sascha Hauer
     [not found]             ` <20120412092106.GU3852-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
2012-04-12  9:33               ` Thierry Reding
     [not found]                 ` <20120412093301.GB23336-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
2012-04-12 13:16                   ` Alex Deucher
     [not found]                     ` <CADnq5_Oiez8zAHqFw-_qXk=3PnnEqgm3ir9M3KsWaQr-dLS5pw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-04-12 13:25                       ` Thierry Reding
     [not found]                         ` <20120412132531.GC5353-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
2012-04-12 14:09                           ` Alex Deucher
     [not found]                             ` <CADnq5_P-iGtCxtW+1Y2N34Q6WA5dUUC7ZxZNT29BXTAV0+VfpQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-04-12 14:12                               ` Alex Deucher
     [not found]                                 ` <CADnq5_OLaKPLktd8DkQvwrmZPpaQP4zA1a4+742mQCGvRXfD7g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-04-12 16:32                                   ` Thierry Reding
2012-04-11 12:25   ` [RFC 0/4] Add NVIDIA Tegra DRM support Alan Cox
     [not found]     ` <20120411132548.7d738b42-38n7/U1jhRXW96NNrWNlrekiAK3p4hvP@public.gmane.org>
2012-04-11 13:35       ` Thierry Reding
2012-04-11 12:46   ` Hiroshi Doyu
     [not found]     ` <20120411.154642.1389197434468515943.hdoyu-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2012-04-11 13:24       ` Thierry Reding
2012-04-19 17:35   ` Thierry Reding
     [not found]     ` <20120419173537.GA7692-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
2012-04-19 19:28       ` Dave Airlie
     [not found]         ` <CAPM=9tzK83yYS33eNruvFDwb62ycZxJMC31davVRN=yaZD53YA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-04-19 20:40           ` Thierry Reding
     [not found]             ` <20120419204016.GA8954-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/A@public.gmane.org>
2012-04-19 20:59               ` Jon Mayo
     [not found]                 ` <4F907CBB.4080705-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2012-04-20  5:02                   ` Thierry Reding
     [not found]                     ` <20120420050231.GA15313-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
2012-04-20  6:05                       ` Lucas Stach
2012-04-20 19:54                         ` Jon Mayo
2012-04-19 22:21               ` Jerome Glisse
     [not found]                 ` <CAH3drwZhTzuOVfybB_KBgk22csK47xXv5G4aMOuqPy+ibKd21A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-04-20  5:05                   ` Thierry Reding

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.