All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v3 0/18] tegra: Add display driver and LCD support for Seaboard
@ 2012-07-12 15:25 Simon Glass
  2012-07-12 15:25   ` [U-Boot] " Simon Glass
                   ` (15 more replies)
  0 siblings, 16 replies; 81+ messages in thread
From: Simon Glass @ 2012-07-12 15:25 UTC (permalink / raw)
  To: u-boot

This series adds support for the Tegra2x's display peripheral. This
supports the LCD display on Seaboard and we use this to enable console
output in U-Boot on the LCD.

Configuration is via the device tree. Proposed bindings are included
in this series, taken from pwm bindings that should be in linux-next,
a Tegra video binding that might be accepted in devicetree-discuss
and a proposed video mode binding posted to dri-devel.

While I agree EDID is convenient for machines I would prefer to provide
a user-friendly way of selecting LCD settings as well, with EDID more
as a fallback and auto-detection when available.

To improve performance two optimisations are offered:

1. The LCD frame buffer is cached, with the cache being flushed after
each newline sent to putc(), and in a few other situations. This
dramatically increases performance (around 10x). This requires a few
additions to the ARM cache support.

2. The console supports scrolling in steps of more than 1 line. This
speeds up scrolling output considerably, particularly commands like
'printenv' which display a lot of output, and particular when the
dcache is off. This requires a new CONFIG and a change to the
console_scrollup() function.

Changes in v2:
- Add new patch to use const in pinmux_config_pingroup/table()
- Add nvidia prefix to device tree properties
- Align tegra display using new CONFIG_LCD_ALIGNMENT feature
- Put the LCD cache flush logic into lcd_putc() instead of lcd_puts()
- Update LCD driver to deal with new fdt bindings
- Update seaboard LCD definitions for new fdt binding
- Use a more generic config CONFIG_LCD_ALIGNMENT for lcd alignment
- Use const where possible in funcmux

Changes in v3:
- Add new commit for pwm binding and node
- Add new panel binding to fit with tegra display controller binding
- Add probe function to read in fdt parameters in display driver
- Add separate call to pwm_init() in board_init()
- Adjust LCD driver to use new SOC display driver structures
- Bring in proposed tegra display controller binding
- Decode fdt node within the pwm driver
- Fix tiny bug in mult-line lcd scrolling
- Handle a cached frame buffer out of normal U-Boot memory
- Introduce concept of a pwm channel, rather than separate peripherals
- Move some fdt decode code from LCD driver to SOC display driver
- Put the LCD cache flush logic back into lcd_puts()
- Remove LPW1 pin which is not needed by display
- Remove spurious newline from fdtdec_get_addr() debug output
- Rename fdt config structures
- Rename pwfm driver to pwm
- Separate display driver and LCD driver more in fdt
- Tidy up fdtdec_decode_gpios() debug output
- Use displaymode binding for fdt
- Use new proposed upstream pwm binding
- Use new pwm binding from pre-linux-next
- Use new upstream proposed LCD definitions

Mayuresh Kulkarni (1):
  tegra: Enable display/lcd support on Seaboard

Simon Glass (16):
  fdt: Tidy debugging, add to fdtdec_get_int/addr()
  fdt: Add header guard to fdtdec.h
  tegra: Use const for pinmux_config_pingroup/table()
  tegra: Add display support to funcmux
  tegra: fdt: Add pwm binding and node
  tegra: fdt: Add LCD definitions for Tegra
  tegra: Add support for PWM
  tegra: Add LCD driver
  tegra: Add LCD support to Nvidia boards
  arm: Add control over cachability of memory regions
  lcd: Add CONFIG_LCD_ALIGNMENT to select frame buffer alignment
  lcd: Add support for flushing LCD fb from dcache after update
  tegra: Align LCD frame buffer to section boundary
  tegra: Support control of cache settings for LCD
  tegra: fdt: Add LCD definitions for Seaboard
  lcd: Add CONSOLE_SCROLL_LINES option to speed console

Wei Ni (1):
  tegra: Add SOC support for display/lcd

 README                                         |   16 +
 arch/arm/cpu/armv7/cache_v7.c                  |   11 +
 arch/arm/cpu/armv7/tegra2/Makefile             |    1 +
 arch/arm/cpu/armv7/tegra2/display.c            |  389 +++++++++++++++++
 arch/arm/cpu/armv7/tegra2/funcmux.c            |   38 ++
 arch/arm/cpu/armv7/tegra2/pinmux.c             |    4 +-
 arch/arm/cpu/armv7/tegra2/pwm.c                |   99 +++++
 arch/arm/dts/tegra20.dtsi                      |   96 +++++
 arch/arm/include/asm/arch-tegra2/dc.h          |  544 ++++++++++++++++++++++++
 arch/arm/include/asm/arch-tegra2/display.h     |  152 +++++++
 arch/arm/include/asm/arch-tegra2/pinmux.h      |    4 +-
 arch/arm/include/asm/arch-tegra2/pwm.h         |   75 ++++
 arch/arm/include/asm/system.h                  |   30 ++
 arch/arm/lib/cache-cp15.c                      |   62 +++-
 board/nvidia/common/board.c                    |   24 +-
 board/nvidia/dts/tegra2-seaboard.dts           |   32 ++
 common/lcd.c                                   |   86 +++-
 doc/device-tree-bindings/pwm/tegra20-pwm.txt   |   18 +
 doc/device-tree-bindings/video/displaymode.txt |   42 ++
 doc/device-tree-bindings/video/tegra20-dc.txt  |   89 ++++
 drivers/video/Makefile                         |    1 +
 drivers/video/tegra.c                          |  368 ++++++++++++++++
 include/configs/seaboard.h                     |   11 +-
 include/configs/tegra2-common.h                |    3 +
 include/fdtdec.h                               |    5 +
 include/lcd.h                                  |   11 +
 lib/fdtdec.c                                   |   29 +-
 27 files changed, 2199 insertions(+), 41 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/tegra2/display.c
 create mode 100644 arch/arm/cpu/armv7/tegra2/pwm.c
 create mode 100644 arch/arm/include/asm/arch-tegra2/dc.h
 create mode 100644 arch/arm/include/asm/arch-tegra2/display.h
 create mode 100644 arch/arm/include/asm/arch-tegra2/pwm.h
 create mode 100644 doc/device-tree-bindings/pwm/tegra20-pwm.txt
 create mode 100644 doc/device-tree-bindings/video/displaymode.txt
 create mode 100644 doc/device-tree-bindings/video/tegra20-dc.txt
 create mode 100644 drivers/video/tegra.c

-- 
1.7.7.3

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

* [PATCH v3 01/18] fdt: Tidy debugging, add to fdtdec_get_int/addr()
  2012-07-12 15:25 [U-Boot] [PATCH v3 0/18] tegra: Add display driver and LCD support for Seaboard Simon Glass
@ 2012-07-12 15:25     ` Simon Glass
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 03/18] tegra: Use const for pinmux_config_pingroup/table() Simon Glass
                       ` (14 subsequent siblings)
  15 siblings, 0 replies; 81+ messages in thread
From: Simon Glass @ 2012-07-12 15:25 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: Devicetree Discuss, Tom Warren, Jerry Van Baren

The new debugging shows the value of integers and addresses read
from the device tree and tidy up GPIO output.

Signed-off-by: Simon Glass <sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
---
Changes in v3:
- Remove spurious newline from fdtdec_get_addr() debug output
- Tidy up fdtdec_decode_gpios() debug output

 lib/fdtdec.c |   27 +++++++++++++++++++--------
 1 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index cc09e06..45a0fcf 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -80,11 +80,16 @@ fdt_addr_t fdtdec_get_addr(const void *blob, int node,
 	const fdt_addr_t *cell;
 	int len;
 
-	debug("get_addr: %s\n", prop_name);
+	debug("%s: %s: ", __func__, prop_name);
 	cell = fdt_getprop(blob, node, prop_name, &len);
 	if (cell && (len == sizeof(fdt_addr_t) ||
-			len == sizeof(fdt_addr_t) * 2))
-		return fdt_addr_to_cpu(*cell);
+			len == sizeof(fdt_addr_t) * 2)) {
+		fdt_addr_t addr = fdt_addr_to_cpu(*cell);
+
+		debug("%p\n", (void *)addr);
+		return addr;
+	}
+	debug("(not found)\n");
 	return FDT_ADDR_T_NONE;
 }
 
@@ -94,10 +99,15 @@ s32 fdtdec_get_int(const void *blob, int node, const char *prop_name,
 	const s32 *cell;
 	int len;
 
-	debug("get_size: %s\n", prop_name);
+	debug("%s: %s: ", __func__, prop_name);
 	cell = fdt_getprop(blob, node, prop_name, &len);
-	if (cell && len >= sizeof(s32))
-		return fdt32_to_cpu(cell[0]);
+	if (cell && len >= sizeof(s32)) {
+		s32 val = fdt32_to_cpu(cell[0]);
+
+		debug("%#x (%d)\n", val, val);
+		return val;
+	}
+	debug("(not found)\n");
 	return default_val;
 }
 
@@ -329,6 +339,7 @@ int fdtdec_lookup_phandle(const void *blob, int node, const char *prop_name)
 	const u32 *phandle;
 	int lookup;
 
+	debug("%s: %s\n", __func__, prop_name);
 	phandle = fdt_getprop(blob, node, prop_name, NULL);
 	if (!phandle)
 		return -FDT_ERR_NOTFOUND;
@@ -428,7 +439,7 @@ static int fdtdec_decode_gpios(const void *blob, int node,
 	assert(max_count > 0);
 	prop = fdt_get_property(blob, node, prop_name, &len);
 	if (!prop) {
-		debug("FDT: %s: property '%s' missing\n", __func__, prop_name);
+		debug("%s: property '%s' missing\n", __func__, prop_name);
 		return -FDT_ERR_NOTFOUND;
 	}
 
@@ -437,7 +448,7 @@ static int fdtdec_decode_gpios(const void *blob, int node,
 	cell = (u32 *)prop->data;
 	len /= sizeof(u32) * 3;		/* 3 cells per GPIO record */
 	if (len > max_count) {
-		debug("FDT: %s: too many GPIOs / cells for "
+		debug(" %s: too many GPIOs / cells for "
 			"property '%s'\n", __func__, prop_name);
 		return -FDT_ERR_BADLAYOUT;
 	}
-- 
1.7.7.3

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

* [U-Boot] [PATCH v3 01/18] fdt: Tidy debugging, add to fdtdec_get_int/addr()
@ 2012-07-12 15:25     ` Simon Glass
  0 siblings, 0 replies; 81+ messages in thread
From: Simon Glass @ 2012-07-12 15:25 UTC (permalink / raw)
  To: u-boot

The new debugging shows the value of integers and addresses read
from the device tree and tidy up GPIO output.

Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v3:
- Remove spurious newline from fdtdec_get_addr() debug output
- Tidy up fdtdec_decode_gpios() debug output

 lib/fdtdec.c |   27 +++++++++++++++++++--------
 1 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index cc09e06..45a0fcf 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -80,11 +80,16 @@ fdt_addr_t fdtdec_get_addr(const void *blob, int node,
 	const fdt_addr_t *cell;
 	int len;
 
-	debug("get_addr: %s\n", prop_name);
+	debug("%s: %s: ", __func__, prop_name);
 	cell = fdt_getprop(blob, node, prop_name, &len);
 	if (cell && (len == sizeof(fdt_addr_t) ||
-			len == sizeof(fdt_addr_t) * 2))
-		return fdt_addr_to_cpu(*cell);
+			len == sizeof(fdt_addr_t) * 2)) {
+		fdt_addr_t addr = fdt_addr_to_cpu(*cell);
+
+		debug("%p\n", (void *)addr);
+		return addr;
+	}
+	debug("(not found)\n");
 	return FDT_ADDR_T_NONE;
 }
 
@@ -94,10 +99,15 @@ s32 fdtdec_get_int(const void *blob, int node, const char *prop_name,
 	const s32 *cell;
 	int len;
 
-	debug("get_size: %s\n", prop_name);
+	debug("%s: %s: ", __func__, prop_name);
 	cell = fdt_getprop(blob, node, prop_name, &len);
-	if (cell && len >= sizeof(s32))
-		return fdt32_to_cpu(cell[0]);
+	if (cell && len >= sizeof(s32)) {
+		s32 val = fdt32_to_cpu(cell[0]);
+
+		debug("%#x (%d)\n", val, val);
+		return val;
+	}
+	debug("(not found)\n");
 	return default_val;
 }
 
@@ -329,6 +339,7 @@ int fdtdec_lookup_phandle(const void *blob, int node, const char *prop_name)
 	const u32 *phandle;
 	int lookup;
 
+	debug("%s: %s\n", __func__, prop_name);
 	phandle = fdt_getprop(blob, node, prop_name, NULL);
 	if (!phandle)
 		return -FDT_ERR_NOTFOUND;
@@ -428,7 +439,7 @@ static int fdtdec_decode_gpios(const void *blob, int node,
 	assert(max_count > 0);
 	prop = fdt_get_property(blob, node, prop_name, &len);
 	if (!prop) {
-		debug("FDT: %s: property '%s' missing\n", __func__, prop_name);
+		debug("%s: property '%s' missing\n", __func__, prop_name);
 		return -FDT_ERR_NOTFOUND;
 	}
 
@@ -437,7 +448,7 @@ static int fdtdec_decode_gpios(const void *blob, int node,
 	cell = (u32 *)prop->data;
 	len /= sizeof(u32) * 3;		/* 3 cells per GPIO record */
 	if (len > max_count) {
-		debug("FDT: %s: too many GPIOs / cells for "
+		debug(" %s: too many GPIOs / cells for "
 			"property '%s'\n", __func__, prop_name);
 		return -FDT_ERR_BADLAYOUT;
 	}
-- 
1.7.7.3

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

* [PATCH v3 02/18] fdt: Add header guard to fdtdec.h
  2012-07-12 15:25 [U-Boot] [PATCH v3 0/18] tegra: Add display driver and LCD support for Seaboard Simon Glass
@ 2012-07-12 15:25   ` Simon Glass
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 03/18] tegra: Use const for pinmux_config_pingroup/table() Simon Glass
                     ` (14 subsequent siblings)
  15 siblings, 0 replies; 81+ messages in thread
From: Simon Glass @ 2012-07-12 15:25 UTC (permalink / raw)
  To: U-Boot Mailing List; +Cc: Devicetree Discuss, Tom Warren, Jerry Van Baren

This makes it easier to include this header from other headers.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 include/fdtdec.h |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/include/fdtdec.h b/include/fdtdec.h
index fab577e..c30947a 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -19,6 +19,8 @@
  * MA 02111-1307 USA
  */
 
+#ifndef __fdtdec_h
+#define __fdtdec_h
 
 /*
  * This file contains convenience functions for decoding useful and
@@ -382,3 +384,4 @@ int fdtdec_get_byte_array(const void *blob, int node, const char *prop_name,
  */
 const u8 *fdtdec_locate_byte_array(const void *blob, int node,
 			     const char *prop_name, int count);
+#endif
-- 
1.7.7.3

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

* [U-Boot] [PATCH v3 02/18] fdt: Add header guard to fdtdec.h
@ 2012-07-12 15:25   ` Simon Glass
  0 siblings, 0 replies; 81+ messages in thread
From: Simon Glass @ 2012-07-12 15:25 UTC (permalink / raw)
  To: u-boot

This makes it easier to include this header from other headers.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 include/fdtdec.h |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/include/fdtdec.h b/include/fdtdec.h
index fab577e..c30947a 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -19,6 +19,8 @@
  * MA 02111-1307 USA
  */
 
+#ifndef __fdtdec_h
+#define __fdtdec_h
 
 /*
  * This file contains convenience functions for decoding useful and
@@ -382,3 +384,4 @@ int fdtdec_get_byte_array(const void *blob, int node, const char *prop_name,
  */
 const u8 *fdtdec_locate_byte_array(const void *blob, int node,
 			     const char *prop_name, int count);
+#endif
-- 
1.7.7.3

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

* [U-Boot] [PATCH v3 03/18] tegra: Use const for pinmux_config_pingroup/table()
  2012-07-12 15:25 [U-Boot] [PATCH v3 0/18] tegra: Add display driver and LCD support for Seaboard Simon Glass
  2012-07-12 15:25   ` [U-Boot] " Simon Glass
@ 2012-07-12 15:25 ` Simon Glass
  2012-07-19 13:53   ` Mike Frysinger
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 04/18] tegra: Add display support to funcmux Simon Glass
                   ` (13 subsequent siblings)
  15 siblings, 1 reply; 81+ messages in thread
From: Simon Glass @ 2012-07-12 15:25 UTC (permalink / raw)
  To: u-boot

These two functions don't actually modify their arguments so add a const
keyword.

Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v2:
- Add new patch to use const in pinmux_config_pingroup/table()

 arch/arm/cpu/armv7/tegra2/pinmux.c        |    4 ++--
 arch/arm/include/asm/arch-tegra2/pinmux.h |    4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/cpu/armv7/tegra2/pinmux.c b/arch/arm/cpu/armv7/tegra2/pinmux.c
index b053f90..bf6d40d 100644
--- a/arch/arm/cpu/armv7/tegra2/pinmux.c
+++ b/arch/arm/cpu/armv7/tegra2/pinmux.c
@@ -554,7 +554,7 @@ void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func)
 	writel(reg, muxctl);
 }
 
-void pinmux_config_pingroup(struct pingroup_config *config)
+void pinmux_config_pingroup(const struct pingroup_config *config)
 {
 	enum pmux_pingrp pin = config->pingroup;
 
@@ -563,7 +563,7 @@ void pinmux_config_pingroup(struct pingroup_config *config)
 	pinmux_set_tristate(pin, config->tristate);
 }
 
-void pinmux_config_table(struct pingroup_config *config, int len)
+void pinmux_config_table(const struct pingroup_config *config, int len)
 {
 	int i;
 
diff --git a/arch/arm/include/asm/arch-tegra2/pinmux.h b/arch/arm/include/asm/arch-tegra2/pinmux.h
index 03fa7ca..797e158 100644
--- a/arch/arm/include/asm/arch-tegra2/pinmux.h
+++ b/arch/arm/include/asm/arch-tegra2/pinmux.h
@@ -339,7 +339,7 @@ void pinmux_set_pullupdown(enum pmux_pingrp pin, enum pmux_pull pupd);
 void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func);
 
 /* Set the complete configuration for a pin group */
-void pinmux_config_pingroup(struct pingroup_config *config);
+void pinmux_config_pingroup(const struct pingroup_config *config);
 
 void pinmux_set_tristate(enum pmux_pingrp pin, int enable);
 
@@ -349,6 +349,6 @@ void pinmux_set_tristate(enum pmux_pingrp pin, int enable);
  * @param config	List of config items
  * @param len		Number of config items in list
  */
-void pinmux_config_table(struct pingroup_config *config, int len);
+void pinmux_config_table(const struct pingroup_config *config, int len);
 
 #endif	/* PINMUX_H */
-- 
1.7.7.3

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

* [U-Boot] [PATCH v3 04/18] tegra: Add display support to funcmux
  2012-07-12 15:25 [U-Boot] [PATCH v3 0/18] tegra: Add display driver and LCD support for Seaboard Simon Glass
  2012-07-12 15:25   ` [U-Boot] " Simon Glass
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 03/18] tegra: Use const for pinmux_config_pingroup/table() Simon Glass
@ 2012-07-12 15:25 ` Simon Glass
  2012-07-19 13:54   ` Mike Frysinger
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 07/18] tegra: Add support for PWM Simon Glass
                   ` (12 subsequent siblings)
  15 siblings, 1 reply; 81+ messages in thread
From: Simon Glass @ 2012-07-12 15:25 UTC (permalink / raw)
  To: u-boot

Add support for a default pin mapping for display1.

Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v2:
- Use const where possible in funcmux

Changes in v3:
- Remove LPW1 pin which is not needed by display

 arch/arm/cpu/armv7/tegra2/funcmux.c |   38 +++++++++++++++++++++++++++++++++++
 1 files changed, 38 insertions(+), 0 deletions(-)

diff --git a/arch/arm/cpu/armv7/tegra2/funcmux.c b/arch/arm/cpu/armv7/tegra2/funcmux.c
index 4a31a4c..3f4143f 100644
--- a/arch/arm/cpu/armv7/tegra2/funcmux.c
+++ b/arch/arm/cpu/armv7/tegra2/funcmux.c
@@ -25,6 +25,30 @@
 #include <asm/arch/funcmux.h>
 #include <asm/arch/pinmux.h>
 
+/*
+ * The PINMUX macro is used to set up pinmux tables.
+ */
+#define PINMUX(grp, mux, pupd, tri)                   \
+	{PINGRP_##grp, PMUX_FUNC_##mux, PMUX_PULL_##pupd, PMUX_TRI_##tri}
+
+static const struct pingroup_config disp1_default[] = {
+	PINMUX(LDI,   DISPA,      NORMAL,    NORMAL),
+	PINMUX(LHP0,  DISPA,      NORMAL,    NORMAL),
+	PINMUX(LHP1,  DISPA,      NORMAL,    NORMAL),
+	PINMUX(LHP2,  DISPA,      NORMAL,    NORMAL),
+	PINMUX(LHS,   DISPA,      NORMAL,    NORMAL),
+	PINMUX(LM0,   RSVD4,      NORMAL,    NORMAL),
+	PINMUX(LPP,   DISPA,      NORMAL,    NORMAL),
+	PINMUX(LPW0,  DISPA,      NORMAL,    NORMAL),
+	PINMUX(LPW2,  DISPA,      NORMAL,    NORMAL),
+	PINMUX(LSC0,  DISPA,      NORMAL,    NORMAL),
+	PINMUX(LSPI,  DISPA,      NORMAL,    NORMAL),
+	PINMUX(LVP1,  DISPA,      NORMAL,    NORMAL),
+	PINMUX(LVS,   DISPA,      NORMAL,    NORMAL),
+	PINMUX(SLXD,  SPDIF,      NORMAL,    NORMAL),
+};
+
+
 int funcmux_select(enum periph_id id, int config)
 {
 	int bad_config = config != FUNCMUX_DEFAULT;
@@ -234,6 +258,20 @@ int funcmux_select(enum periph_id id, int config)
 		}
 		break;
 
+	case PERIPH_ID_DISP1:
+		if (config == FUNCMUX_DEFAULT) {
+			int i;
+
+			for (i = PINGRP_LD0; i <= PINGRP_LD17; i++) {
+				pinmux_set_func(i, PMUX_FUNC_DISPA);
+				pinmux_tristate_disable(i);
+				pinmux_set_pullupdown(i, PMUX_PULL_NORMAL);
+			}
+			pinmux_config_table(disp1_default,
+					    ARRAY_SIZE(disp1_default));
+		}
+		break;
+
 	default:
 		debug("%s: invalid periph_id %d", __func__, id);
 		return -1;
-- 
1.7.7.3

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

* [PATCH v3 05/18] tegra: fdt: Add pwm binding and node
  2012-07-12 15:25 [U-Boot] [PATCH v3 0/18] tegra: Add display driver and LCD support for Seaboard Simon Glass
@ 2012-07-12 15:25     ` Simon Glass
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 03/18] tegra: Use const for pinmux_config_pingroup/table() Simon Glass
                       ` (14 subsequent siblings)
  15 siblings, 0 replies; 81+ messages in thread
From: Simon Glass @ 2012-07-12 15:25 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Stephen Warren, Devicetree Discuss, Jerry Van Baren, Tom Warren

This binding will apparently soon be in linux-next. Bring it in now
since we need to do something, and may as well try to target what
Linux will have.

Signed-off-by: Simon Glass <sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
---
Changes in v3:
- Add new commit for pwm binding and node

 arch/arm/dts/tegra20.dtsi                    |    7 +++++++
 doc/device-tree-bindings/pwm/tegra20-pwm.txt |   18 ++++++++++++++++++
 2 files changed, 25 insertions(+), 0 deletions(-)
 create mode 100644 doc/device-tree-bindings/pwm/tegra20-pwm.txt

diff --git a/arch/arm/dts/tegra20.dtsi b/arch/arm/dts/tegra20.dtsi
index f95be58..e7d1688 100644
--- a/arch/arm/dts/tegra20.dtsi
+++ b/arch/arm/dts/tegra20.dtsi
@@ -204,4 +204,11 @@
 		compatible = "nvidia,tegra20-kbc";
 		reg = <0x7000e200 0x0078>;
 	};
+
+	pwm: pwm@7000a000 {
+		compatible = "nvidia,tegra20-pwm";
+		reg = <0x7000a000 0x100>;
+		#pwm-cells = <2>;
+	};
+
 };
diff --git a/doc/device-tree-bindings/pwm/tegra20-pwm.txt b/doc/device-tree-bindings/pwm/tegra20-pwm.txt
new file mode 100644
index 0000000..bbbeedb
--- /dev/null
+++ b/doc/device-tree-bindings/pwm/tegra20-pwm.txt
@@ -0,0 +1,18 @@
+Tegra SoC PWFM controller
+
+Required properties:
+- compatible: should be one of:
+  - "nvidia,tegra20-pwm"
+  - "nvidia,tegra30-pwm"
+- reg: physical base address and length of the controller's registers
+- #pwm-cells: On Tegra the number of cells used to specify a PWM is 2. The
+  first cell specifies the per-chip index of the PWM to use and the second
+  cell is the duty cycle in nanoseconds.
+
+Example:
+
+	pwm: pwm@7000a000 {
+		compatible = "nvidia,tegra20-pwm";
+		reg = <0x7000a000 0x100>;
+		#pwm-cells = <2>;
+	};
-- 
1.7.7.3

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

* [U-Boot] [PATCH v3 05/18] tegra: fdt: Add pwm binding and node
@ 2012-07-12 15:25     ` Simon Glass
  0 siblings, 0 replies; 81+ messages in thread
From: Simon Glass @ 2012-07-12 15:25 UTC (permalink / raw)
  To: u-boot

This binding will apparently soon be in linux-next. Bring it in now
since we need to do something, and may as well try to target what
Linux will have.

Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v3:
- Add new commit for pwm binding and node

 arch/arm/dts/tegra20.dtsi                    |    7 +++++++
 doc/device-tree-bindings/pwm/tegra20-pwm.txt |   18 ++++++++++++++++++
 2 files changed, 25 insertions(+), 0 deletions(-)
 create mode 100644 doc/device-tree-bindings/pwm/tegra20-pwm.txt

diff --git a/arch/arm/dts/tegra20.dtsi b/arch/arm/dts/tegra20.dtsi
index f95be58..e7d1688 100644
--- a/arch/arm/dts/tegra20.dtsi
+++ b/arch/arm/dts/tegra20.dtsi
@@ -204,4 +204,11 @@
 		compatible = "nvidia,tegra20-kbc";
 		reg = <0x7000e200 0x0078>;
 	};
+
+	pwm: pwm at 7000a000 {
+		compatible = "nvidia,tegra20-pwm";
+		reg = <0x7000a000 0x100>;
+		#pwm-cells = <2>;
+	};
+
 };
diff --git a/doc/device-tree-bindings/pwm/tegra20-pwm.txt b/doc/device-tree-bindings/pwm/tegra20-pwm.txt
new file mode 100644
index 0000000..bbbeedb
--- /dev/null
+++ b/doc/device-tree-bindings/pwm/tegra20-pwm.txt
@@ -0,0 +1,18 @@
+Tegra SoC PWFM controller
+
+Required properties:
+- compatible: should be one of:
+  - "nvidia,tegra20-pwm"
+  - "nvidia,tegra30-pwm"
+- reg: physical base address and length of the controller's registers
+- #pwm-cells: On Tegra the number of cells used to specify a PWM is 2. The
+  first cell specifies the per-chip index of the PWM to use and the second
+  cell is the duty cycle in nanoseconds.
+
+Example:
+
+	pwm: pwm at 7000a000 {
+		compatible = "nvidia,tegra20-pwm";
+		reg = <0x7000a000 0x100>;
+		#pwm-cells = <2>;
+	};
-- 
1.7.7.3

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

* [PATCH v3 06/18] tegra: fdt: Add LCD definitions for Tegra
  2012-07-12 15:25 [U-Boot] [PATCH v3 0/18] tegra: Add display driver and LCD support for Seaboard Simon Glass
@ 2012-07-12 15:25     ` Simon Glass
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 03/18] tegra: Use const for pinmux_config_pingroup/table() Simon Glass
                       ` (14 subsequent siblings)
  15 siblings, 0 replies; 81+ messages in thread
From: Simon Glass @ 2012-07-12 15:25 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Stephen Warren, Devicetree Discuss, Jerry Van Baren, Tom Warren

Add LCD definitions and also a proposed binding for LCD displays.

The PWM is as per what will likely be committed to linux-next soon.

The displaymode binding comes from a proposal here:

http://lists.freedesktop.org/archives/dri-devel/2012-July/024875.html

The panel binding is new, and fills a need to specify the panel
timings and other tegra-specific information. Should a binding appear
that allows the pwm to handle this automatically, we can revisit
this.

Signed-off-by: Simon Glass <sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
---
Changes in v2:
- Add nvidia prefix to device tree properties

Changes in v3:
- Add new panel binding to fit with tegra display controller binding
- Bring in proposed tegra display controller binding
- Use displaymode binding for fdt

 arch/arm/dts/tegra20.dtsi                      |   89 ++++++++++++++++++++++++
 doc/device-tree-bindings/video/displaymode.txt |   42 +++++++++++
 doc/device-tree-bindings/video/tegra20-dc.txt  |   89 ++++++++++++++++++++++++
 3 files changed, 220 insertions(+), 0 deletions(-)
 create mode 100644 doc/device-tree-bindings/video/displaymode.txt
 create mode 100644 doc/device-tree-bindings/video/tegra20-dc.txt

diff --git a/arch/arm/dts/tegra20.dtsi b/arch/arm/dts/tegra20.dtsi
index e7d1688..0b2ca3b 100644
--- a/arch/arm/dts/tegra20.dtsi
+++ b/arch/arm/dts/tegra20.dtsi
@@ -211,4 +211,93 @@
 		#pwm-cells = <2>;
 	};
 
+	host1x {
+		compatible = "nvidia,tegra20-host1x", "simple-bus";
+		reg = <0x50000000 0x00024000>;
+		interrupts = <0 65 0x04   /* mpcore syncpt */
+			      0 67 0x04>; /* mpcore general */
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		ranges = <0x54000000 0x54000000 0x04000000>;
+
+		/* video-encoding/decoding */
+		mpe {
+			reg = <0x54040000 0x00040000>;
+			interrupts = <0 68 0x04>;
+		};
+
+		/* video input */
+		vi {
+			reg = <0x54080000 0x00040000>;
+			interrupts = <0 69 0x04>;
+		};
+
+		/* EPP */
+		epp {
+			reg = <0x540c0000 0x00040000>;
+			interrupts = <0 70 0x04>;
+		};
+
+		/* ISP */
+		isp {
+			reg = <0x54100000 0x00040000>;
+			interrupts = <0 71 0x04>;
+		};
+
+		/* 2D engine */
+		gr2d {
+			reg = <0x54140000 0x00040000>;
+			interrupts = <0 72 0x04>;
+		};
+
+		/* 3D engine */
+		gr3d {
+			reg = <0x54180000 0x00040000>;
+		};
+
+		/* display controllers */
+		dc@54200000 {
+			compatible = "nvidia,tegra20-dc";
+			reg = <0x54200000 0x00040000>;
+			interrupts = <0 73 0x04>;
+
+			rgb {
+				status = "disabled";
+			};
+		};
+
+		dc@54240000 {
+			compatible = "nvidia,tegra20-dc";
+			reg = <0x54240000 0x00040000>;
+			interrupts = <0 74 0x04>;
+
+			rgb {
+				status = "disabled";
+			};
+		};
+
+		/* outputs */
+		hdmi {
+			compatible = "nvidia,tegra20-hdmi";
+			reg = <0x54280000 0x00040000>;
+			interrupts = <0 75 0x04>;
+			status = "disabled";
+		};
+
+		tvo {
+			compatible = "nvidia,tegra20-tvo";
+			reg = <0x542c0000 0x00040000>;
+			interrupts = <0 76 0x04>;
+			status = "disabled";
+		};
+
+		dsi {
+			compatible = "nvidia,tegra20-dsi";
+			reg = <0x54300000 0x00040000>;
+			status = "disabled";
+		};
+	};
+
 };
diff --git a/doc/device-tree-bindings/video/displaymode.txt b/doc/device-tree-bindings/video/displaymode.txt
new file mode 100644
index 0000000..45ca42d
--- /dev/null
+++ b/doc/device-tree-bindings/video/displaymode.txt
@@ -0,0 +1,42 @@
+videomode bindings
+==================
+
+(from http://lists.freedesktop.org/archives/dri-devel/2012-July/024875.html)
+
+Required properties:
+ - xres, yres: Display resolution
+ - left-margin, right-margin, hsync-len: Horizontal Display timing
+   parameters in pixels
+ - upper-margin, lower-margin, vsync-len: Vertical display timing
+   parameters in lines
+ - clock: display clock in Hz
+
+Optional properties:
+ - width-mm, height-mm: Display dimensions in mm
+ - hsync-active-high (bool): Hsync pulse is active high
+ - vsync-active-high (bool): Vsync pulse is active high
+ - interlaced (bool): This is an interlaced mode
+ - doublescan (bool): This is a doublescan mode
+
+There are different ways of describing a display mode. The devicetree
+representation corresponds to the one used by the Linux Framebuffer
+framework described here in Documentation/fb/framebuffer.txt. This
+representation has been chosen because it's the only format which does
+not allow for inconsistent parameters. Unlike the Framebuffer framework
+the devicetree has the clock in Hz instead of ps.
+
+Example:
+
+	display@0 {
+		/* 1920x1080p24 */
+		clock = <52000000>;
+		xres = <1920>;
+		yres = <1080>;
+		left-margin = <25>;
+		right-margin = <25>;
+		hsync-len = <25>;
+		lower-margin = <2>;
+		upper-margin = <2>;
+		vsync-len = <2>;
+		hsync-active-high;
+	};
diff --git a/doc/device-tree-bindings/video/tegra20-dc.txt b/doc/device-tree-bindings/video/tegra20-dc.txt
new file mode 100644
index 0000000..dcfd652
--- /dev/null
+++ b/doc/device-tree-bindings/video/tegra20-dc.txt
@@ -0,0 +1,89 @@
+Display Controller
+------------------
+
+(there isn't yet a generic binding in Linux, so this describes what is in
+U-Boot, and may change based on Linux activity)
+
+The device node for a display device is as described in the document
+"Open Firmware Recommended Practice : Universal Serial Bus" with the
+following modifications and additions :
+
+Required properties :
+ - compatible : Should be "nvidia,tegra20-dc"
+
+Required subnode 'rgb'. This has the properties listed in displaymode.txt
+as well as:
+
+Required properties (rgb) :
+ - nvidia,panel : phandle of LCD panel information
+ - nvidia,bits-per-pixel: number of bits per pixel (depth)
+
+Optional properties (rgb):
+ - nvidia,frame-buffer: address of frame buffer (if omitted it will be
+		calculated)
+	- This may be useful to share an address between U-Boot and Linux and
+		avoid boot-time corruption / flicker
+
+
+The panel node describes the panel itself.
+
+Required properties (panel) :
+ - nvidia,pwm : pwm to use to set display contrast (see tegra20-pwm.txt)
+ - nvidia,panel-timings: 4 cells containing required timings in ms:
+	* delay between panel_vdd-rise and data-rise
+	* delay between data-rise and backlight_vdd-rise
+	* delay between backlight_vdd and pwm-rise
+	* delay between pwm-rise and backlight_en-rise
+
+Optional GPIO properies all have (phandle, GPIO number, flags):
+ - nvidia,backlight-enable-gpios: backlight enable GPIO
+ - nvidia,lvds-shutdown-gpios: LVDS power shutdown GPIO
+ - nvidia,backlight-vdd-gpios: backlight power GPIO
+ - nvidia,panel-vdd-gpios: panel power GPIO
+
+Example:
+
+host1x {
+	compatible = "nvidia,tegra20-host1x", "simple-bus";
+	reg = <0x50000000 0x00024000>;
+	interrupts = <0 65 0x04   /* mpcore syncpt */
+			0 67 0x04>; /* mpcore general */
+
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	ranges = <0x54000000 0x54000000 0x04000000>;
+
+	dc@54200000 {
+		compatible = "nvidia,tegra20-dc";
+		reg = <0x54200000 0x00040000>;
+		interrupts = <0 73 0x04>;
+
+		rgb {
+			status = "okay";
+			/* Seaboard has 1366x768 */
+			clock = <70600000>;
+			xres = <1366>;
+			yres = <768>;
+			left-margin = <58>;
+			right-margin = <58>;
+			hsync-len = <58>;
+			lower-margin = <4>;
+			upper-margin = <4>;
+			vsync-len = <4>;
+			hsync-active-high;
+			nvidia,frame-buffer = <0x2f680000>;
+			nvidia,bits-per-pixel = <16>;
+			nvidia,panel = <&lcd_panel>;
+		};
+	};
+};
+
+lcd_panel: panel {
+	nvidia,pwm = <&pwm 2 0>;
+	nvidia,backlight-enable-gpios = <&gpio 28 0>;	/* PD4 */
+	nvidia,lvds-shutdown-gpios = <&gpio 10 0>;	/* PB2 */
+	nvidia,backlight-vdd-gpios = <&gpio 176 0>;	/* PW0 */
+	nvidia,panel-vdd-gpios = <&gpio 22 0>;		/* PC6 */
+	nvidia,panel-timings = <4 203 17 15>;
+};
-- 
1.7.7.3

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

* [U-Boot] [PATCH v3 06/18] tegra: fdt: Add LCD definitions for Tegra
@ 2012-07-12 15:25     ` Simon Glass
  0 siblings, 0 replies; 81+ messages in thread
From: Simon Glass @ 2012-07-12 15:25 UTC (permalink / raw)
  To: u-boot

Add LCD definitions and also a proposed binding for LCD displays.

The PWM is as per what will likely be committed to linux-next soon.

The displaymode binding comes from a proposal here:

http://lists.freedesktop.org/archives/dri-devel/2012-July/024875.html

The panel binding is new, and fills a need to specify the panel
timings and other tegra-specific information. Should a binding appear
that allows the pwm to handle this automatically, we can revisit
this.

Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v2:
- Add nvidia prefix to device tree properties

Changes in v3:
- Add new panel binding to fit with tegra display controller binding
- Bring in proposed tegra display controller binding
- Use displaymode binding for fdt

 arch/arm/dts/tegra20.dtsi                      |   89 ++++++++++++++++++++++++
 doc/device-tree-bindings/video/displaymode.txt |   42 +++++++++++
 doc/device-tree-bindings/video/tegra20-dc.txt  |   89 ++++++++++++++++++++++++
 3 files changed, 220 insertions(+), 0 deletions(-)
 create mode 100644 doc/device-tree-bindings/video/displaymode.txt
 create mode 100644 doc/device-tree-bindings/video/tegra20-dc.txt

diff --git a/arch/arm/dts/tegra20.dtsi b/arch/arm/dts/tegra20.dtsi
index e7d1688..0b2ca3b 100644
--- a/arch/arm/dts/tegra20.dtsi
+++ b/arch/arm/dts/tegra20.dtsi
@@ -211,4 +211,93 @@
 		#pwm-cells = <2>;
 	};
 
+	host1x {
+		compatible = "nvidia,tegra20-host1x", "simple-bus";
+		reg = <0x50000000 0x00024000>;
+		interrupts = <0 65 0x04   /* mpcore syncpt */
+			      0 67 0x04>; /* mpcore general */
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		ranges = <0x54000000 0x54000000 0x04000000>;
+
+		/* video-encoding/decoding */
+		mpe {
+			reg = <0x54040000 0x00040000>;
+			interrupts = <0 68 0x04>;
+		};
+
+		/* video input */
+		vi {
+			reg = <0x54080000 0x00040000>;
+			interrupts = <0 69 0x04>;
+		};
+
+		/* EPP */
+		epp {
+			reg = <0x540c0000 0x00040000>;
+			interrupts = <0 70 0x04>;
+		};
+
+		/* ISP */
+		isp {
+			reg = <0x54100000 0x00040000>;
+			interrupts = <0 71 0x04>;
+		};
+
+		/* 2D engine */
+		gr2d {
+			reg = <0x54140000 0x00040000>;
+			interrupts = <0 72 0x04>;
+		};
+
+		/* 3D engine */
+		gr3d {
+			reg = <0x54180000 0x00040000>;
+		};
+
+		/* display controllers */
+		dc at 54200000 {
+			compatible = "nvidia,tegra20-dc";
+			reg = <0x54200000 0x00040000>;
+			interrupts = <0 73 0x04>;
+
+			rgb {
+				status = "disabled";
+			};
+		};
+
+		dc at 54240000 {
+			compatible = "nvidia,tegra20-dc";
+			reg = <0x54240000 0x00040000>;
+			interrupts = <0 74 0x04>;
+
+			rgb {
+				status = "disabled";
+			};
+		};
+
+		/* outputs */
+		hdmi {
+			compatible = "nvidia,tegra20-hdmi";
+			reg = <0x54280000 0x00040000>;
+			interrupts = <0 75 0x04>;
+			status = "disabled";
+		};
+
+		tvo {
+			compatible = "nvidia,tegra20-tvo";
+			reg = <0x542c0000 0x00040000>;
+			interrupts = <0 76 0x04>;
+			status = "disabled";
+		};
+
+		dsi {
+			compatible = "nvidia,tegra20-dsi";
+			reg = <0x54300000 0x00040000>;
+			status = "disabled";
+		};
+	};
+
 };
diff --git a/doc/device-tree-bindings/video/displaymode.txt b/doc/device-tree-bindings/video/displaymode.txt
new file mode 100644
index 0000000..45ca42d
--- /dev/null
+++ b/doc/device-tree-bindings/video/displaymode.txt
@@ -0,0 +1,42 @@
+videomode bindings
+==================
+
+(from http://lists.freedesktop.org/archives/dri-devel/2012-July/024875.html)
+
+Required properties:
+ - xres, yres: Display resolution
+ - left-margin, right-margin, hsync-len: Horizontal Display timing
+   parameters in pixels
+ - upper-margin, lower-margin, vsync-len: Vertical display timing
+   parameters in lines
+ - clock: display clock in Hz
+
+Optional properties:
+ - width-mm, height-mm: Display dimensions in mm
+ - hsync-active-high (bool): Hsync pulse is active high
+ - vsync-active-high (bool): Vsync pulse is active high
+ - interlaced (bool): This is an interlaced mode
+ - doublescan (bool): This is a doublescan mode
+
+There are different ways of describing a display mode. The devicetree
+representation corresponds to the one used by the Linux Framebuffer
+framework described here in Documentation/fb/framebuffer.txt. This
+representation has been chosen because it's the only format which does
+not allow for inconsistent parameters. Unlike the Framebuffer framework
+the devicetree has the clock in Hz instead of ps.
+
+Example:
+
+	display at 0 {
+		/* 1920x1080p24 */
+		clock = <52000000>;
+		xres = <1920>;
+		yres = <1080>;
+		left-margin = <25>;
+		right-margin = <25>;
+		hsync-len = <25>;
+		lower-margin = <2>;
+		upper-margin = <2>;
+		vsync-len = <2>;
+		hsync-active-high;
+	};
diff --git a/doc/device-tree-bindings/video/tegra20-dc.txt b/doc/device-tree-bindings/video/tegra20-dc.txt
new file mode 100644
index 0000000..dcfd652
--- /dev/null
+++ b/doc/device-tree-bindings/video/tegra20-dc.txt
@@ -0,0 +1,89 @@
+Display Controller
+------------------
+
+(there isn't yet a generic binding in Linux, so this describes what is in
+U-Boot, and may change based on Linux activity)
+
+The device node for a display device is as described in the document
+"Open Firmware Recommended Practice : Universal Serial Bus" with the
+following modifications and additions :
+
+Required properties :
+ - compatible : Should be "nvidia,tegra20-dc"
+
+Required subnode 'rgb'. This has the properties listed in displaymode.txt
+as well as:
+
+Required properties (rgb) :
+ - nvidia,panel : phandle of LCD panel information
+ - nvidia,bits-per-pixel: number of bits per pixel (depth)
+
+Optional properties (rgb):
+ - nvidia,frame-buffer: address of frame buffer (if omitted it will be
+		calculated)
+	- This may be useful to share an address between U-Boot and Linux and
+		avoid boot-time corruption / flicker
+
+
+The panel node describes the panel itself.
+
+Required properties (panel) :
+ - nvidia,pwm : pwm to use to set display contrast (see tegra20-pwm.txt)
+ - nvidia,panel-timings: 4 cells containing required timings in ms:
+	* delay between panel_vdd-rise and data-rise
+	* delay between data-rise and backlight_vdd-rise
+	* delay between backlight_vdd and pwm-rise
+	* delay between pwm-rise and backlight_en-rise
+
+Optional GPIO properies all have (phandle, GPIO number, flags):
+ - nvidia,backlight-enable-gpios: backlight enable GPIO
+ - nvidia,lvds-shutdown-gpios: LVDS power shutdown GPIO
+ - nvidia,backlight-vdd-gpios: backlight power GPIO
+ - nvidia,panel-vdd-gpios: panel power GPIO
+
+Example:
+
+host1x {
+	compatible = "nvidia,tegra20-host1x", "simple-bus";
+	reg = <0x50000000 0x00024000>;
+	interrupts = <0 65 0x04   /* mpcore syncpt */
+			0 67 0x04>; /* mpcore general */
+
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	ranges = <0x54000000 0x54000000 0x04000000>;
+
+	dc at 54200000 {
+		compatible = "nvidia,tegra20-dc";
+		reg = <0x54200000 0x00040000>;
+		interrupts = <0 73 0x04>;
+
+		rgb {
+			status = "okay";
+			/* Seaboard has 1366x768 */
+			clock = <70600000>;
+			xres = <1366>;
+			yres = <768>;
+			left-margin = <58>;
+			right-margin = <58>;
+			hsync-len = <58>;
+			lower-margin = <4>;
+			upper-margin = <4>;
+			vsync-len = <4>;
+			hsync-active-high;
+			nvidia,frame-buffer = <0x2f680000>;
+			nvidia,bits-per-pixel = <16>;
+			nvidia,panel = <&lcd_panel>;
+		};
+	};
+};
+
+lcd_panel: panel {
+	nvidia,pwm = <&pwm 2 0>;
+	nvidia,backlight-enable-gpios = <&gpio 28 0>;	/* PD4 */
+	nvidia,lvds-shutdown-gpios = <&gpio 10 0>;	/* PB2 */
+	nvidia,backlight-vdd-gpios = <&gpio 176 0>;	/* PW0 */
+	nvidia,panel-vdd-gpios = <&gpio 22 0>;		/* PC6 */
+	nvidia,panel-timings = <4 203 17 15>;
+};
-- 
1.7.7.3

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

* [U-Boot] [PATCH v3 07/18] tegra: Add support for PWM
  2012-07-12 15:25 [U-Boot] [PATCH v3 0/18] tegra: Add display driver and LCD support for Seaboard Simon Glass
                   ` (2 preceding siblings ...)
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 04/18] tegra: Add display support to funcmux Simon Glass
@ 2012-07-12 15:25 ` Simon Glass
  2012-07-19 13:55   ` Mike Frysinger
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 08/18] tegra: Add SOC support for display/lcd Simon Glass
                   ` (11 subsequent siblings)
  15 siblings, 1 reply; 81+ messages in thread
From: Simon Glass @ 2012-07-12 15:25 UTC (permalink / raw)
  To: u-boot

The pulse width/frequency modulation peripheral supports generating
a repeating pulse. It is useful for controlling LCD brightness.

Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v3:
- Decode fdt node within the pwm driver
- Introduce concept of a pwm channel, rather than separate peripherals
- Rename pwfm driver to pwm
- Use new proposed upstream pwm binding

 arch/arm/cpu/armv7/tegra2/Makefile     |    1 +
 arch/arm/cpu/armv7/tegra2/pwm.c        |   99 ++++++++++++++++++++++++++++++++
 arch/arm/include/asm/arch-tegra2/pwm.h |   75 ++++++++++++++++++++++++
 include/fdtdec.h                       |    1 +
 lib/fdtdec.c                           |    1 +
 5 files changed, 177 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/tegra2/pwm.c
 create mode 100644 arch/arm/include/asm/arch-tegra2/pwm.h

diff --git a/arch/arm/cpu/armv7/tegra2/Makefile b/arch/arm/cpu/armv7/tegra2/Makefile
index 80da453..5d271c4 100644
--- a/arch/arm/cpu/armv7/tegra2/Makefile
+++ b/arch/arm/cpu/armv7/tegra2/Makefile
@@ -40,6 +40,7 @@ COBJS-$(CONFIG_TEGRA_PMU) += pmu.o
 COBJS-$(CONFIG_USB_EHCI_TEGRA) += usb.o
 COBJS-$(CONFIG_TEGRA2_LP0) += crypto.o warmboot.o warmboot_avp.o
 COBJS-$(CONFIG_CMD_ENTERRCM) += cmd_enterrcm.o
+COBJS-$(CONFIG_VIDEO_TEGRA) += pwm.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
diff --git a/arch/arm/cpu/armv7/tegra2/pwm.c b/arch/arm/cpu/armv7/tegra2/pwm.c
new file mode 100644
index 0000000..f3b1bdd
--- /dev/null
+++ b/arch/arm/cpu/armv7/tegra2/pwm.c
@@ -0,0 +1,99 @@
+/*
+ * Tegra2 pulse width frequency modulator definitions
+ *
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/pwm.h>
+
+struct pwm_info {
+	struct pwm_ctlr *pwm;		/* Registers for our pwm controller */
+	int pwm_node;			/* PWM device tree node */
+} local;
+
+void pwm_enable(unsigned channel, int rate, int pulse_width, int freq_divider)
+{
+	u32 reg;
+
+	assert(channel < PWM_NUM_CHANNELS);
+
+	/* TODO: Can we use clock_adjust_periph_pll_div() here? */
+	clock_start_periph_pll(PERIPH_ID_PWM, CLOCK_ID_SFROM32KHZ, rate);
+
+	reg = PWM_ENABLE_MASK;
+	reg |= pulse_width << PWM_WIDTH_SHIFT;
+	reg |= freq_divider << PWM_DIVIDER_SHIFT;
+	writel(reg, &local.pwm[channel].control);
+}
+
+int pwm_request(const void *blob, int node, const char *prop_name)
+{
+	int pwm_node;
+	u32 data[3];
+
+	if (fdtdec_get_int_array(blob, node, prop_name, data,
+			ARRAY_SIZE(data))) {
+		debug("%s: Cannot decode PWM property '%s'\n", __func__,
+		      prop_name);
+		return -1;
+	}
+
+	pwm_node = fdt_node_offset_by_phandle(blob, data[0]);
+	if (pwm_node != local.pwm_node) {
+		debug("%s: PWM property '%s' phandle %d not recognised"
+		      "- expecting %d\n", __func__, prop_name, data[0],
+		      local.pwm_node);
+		return -1;
+	}
+	if (data[1] >= PWM_NUM_CHANNELS) {
+		debug("%s: PWM property '%s': invalid channel %u\n", __func__,
+		      prop_name, data[1]);
+		return -1;
+	}
+
+	/*
+	 * TODO: We could maintain a list of requests, but it might not be
+	 * worth it for U-Boot.
+	 */
+	return data[1];
+}
+
+int pwm_init(const void *blob)
+{
+	local.pwm_node = fdtdec_next_compatible(blob, 0,
+						COMPAT_NVIDIA_TEGRA20_PWM);
+	if (local.pwm_node < 0) {
+		debug("%s: Cannot find device tree node\n", __func__);
+		return -1;
+	}
+
+	local.pwm = (struct pwm_ctlr *)fdtdec_get_addr(blob, local.pwm_node,
+						       "reg");
+	if (local.pwm == (struct pwm_ctlr *)FDT_ADDR_T_NONE) {
+		debug("%s: Cannot find pwm reg address\n", __func__);
+		return -1;
+	}
+
+	return 0;
+}
diff --git a/arch/arm/include/asm/arch-tegra2/pwm.h b/arch/arm/include/asm/arch-tegra2/pwm.h
new file mode 100644
index 0000000..9e03837
--- /dev/null
+++ b/arch/arm/include/asm/arch-tegra2/pwm.h
@@ -0,0 +1,75 @@
+/*
+ * Tegra pulse width frequency modulator definitions
+ *
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __ASM_ARCH_TEGRA_PWM_H
+#define __ASM_ARCH_TEGRA_PWM_H
+
+/* This is a single PWM channel */
+struct pwm_ctlr {
+	uint control;		/* Control register */
+	uint reserved[3];	/* Space space */
+};
+
+#define PWM_NUM_CHANNELS	4
+
+/* PWM_CONTROLLER_PWM_CSR_0/1/2/3_0 */
+#define PWM_ENABLE_SHIFT	31
+#define PWM_ENABLE_MASK	(0x1 << PWM_ENABLE_SHIFT)
+
+#define PWM_WIDTH_SHIFT	16
+#define PWM_WIDTH_MASK		(0x7FFF << PWM_WIDTH_SHIFT)
+
+#define PWM_DIVIDER_SHIFT	0
+#define PWM_DIVIDER_MASK	(0x1FFF << PWM_DIVIDER_SHIFT)
+
+/**
+ * Program the PWM with the given parameters.
+ *
+ * @param channel	PWM channel to update
+ * @param rate		Clock rate to use for PWM
+ * @param pulse_width	high pulse width: 0=always low, 1=1/256 pulse high,
+ *			n = n/256 pulse high
+ * @param freq_divider	frequency divider value (1 to use rate as is)
+ */
+void pwm_enable(unsigned channel, int rate, int pulse_width, int freq_divider);
+
+/**
+ * Request a pwm channel as referenced by a device tree node.
+ *
+ * This channel can then be passed to pwm_enable().
+ *
+ * @param blob		Device tree blob
+ * @param node		Node containing reference to pwm
+ * @param prop_name	Property name of pwm reference
+ * @return channel number, if ok, else -1
+ */
+int pwm_request(const void *blob, int node, const char *prop_name);
+
+/**
+ * Set up the pwm controller, by looking it up in the fdt.
+ *
+ * @return 0 if ok, -1 if the device tree node was not found or invalid.
+ */
+int pwm_init(const void *blob);
+
+#endif	/* __ASM_ARCH_TEGRA_PWM_H */
diff --git a/include/fdtdec.h b/include/fdtdec.h
index c30947a..3997bfa 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -65,6 +65,7 @@ enum fdt_compat_id {
 	COMPAT_NVIDIA_TEGRA20_EMC,	/* Tegra2 memory controller */
 	COMPAT_NVIDIA_TEGRA20_EMC_TABLE, /* Tegra2 memory timing table */
 	COMPAT_NVIDIA_TEGRA20_KBC,	/* Tegra2 Keyboard */
+	COMPAT_NVIDIA_TEGRA20_PWM,	/* Tegra 2 PWM controller */
 
 	COMPAT_COUNT,
 };
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 45a0fcf..40b0aef 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -43,6 +43,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
 	COMPAT(NVIDIA_TEGRA20_EMC, "nvidia,tegra20-emc"),
 	COMPAT(NVIDIA_TEGRA20_EMC_TABLE, "nvidia,tegra20-emc-table"),
 	COMPAT(NVIDIA_TEGRA20_KBC, "nvidia,tegra20-kbc"),
+	COMPAT(NVIDIA_TEGRA20_PWM, "nvidia,tegra20-pwm"),
 };
 
 const char *fdtdec_get_compatible(enum fdt_compat_id id)
-- 
1.7.7.3

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

* [U-Boot] [PATCH v3 08/18] tegra: Add SOC support for display/lcd
  2012-07-12 15:25 [U-Boot] [PATCH v3 0/18] tegra: Add display driver and LCD support for Seaboard Simon Glass
                   ` (3 preceding siblings ...)
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 07/18] tegra: Add support for PWM Simon Glass
@ 2012-07-12 15:25 ` Simon Glass
  2012-07-19  7:37   ` Thierry Reding
  2012-07-19  8:03   ` Adam Jiang
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 09/18] tegra: Add LCD driver Simon Glass
                   ` (10 subsequent siblings)
  15 siblings, 2 replies; 81+ messages in thread
From: Simon Glass @ 2012-07-12 15:25 UTC (permalink / raw)
  To: u-boot

From: Wei Ni <wni@nvidia.com>

Add support for the LCD peripheral at the Tegra2 SOC level. A separate
LCD driver will use this functionality to configure the display.

Mayuresh Kulkarni:
- changes to remove bitfields and clean up for submission

Simon Glass:
- simplify code, move clock control into here, clean-up

Signed-off-by: Mayuresh Kulkarni <mkulkarni@nvidia.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v3:
- Add probe function to read in fdt parameters in display driver
- Separate display driver and LCD driver more in fdt

 arch/arm/cpu/armv7/tegra2/Makefile         |    2 +-
 arch/arm/cpu/armv7/tegra2/display.c        |  389 ++++++++++++++++++++
 arch/arm/include/asm/arch-tegra2/dc.h      |  544 ++++++++++++++++++++++++++++
 arch/arm/include/asm/arch-tegra2/display.h |  152 ++++++++
 include/fdtdec.h                           |    1 +
 lib/fdtdec.c                               |    1 +
 6 files changed, 1088 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/tegra2/display.c
 create mode 100644 arch/arm/include/asm/arch-tegra2/dc.h
 create mode 100644 arch/arm/include/asm/arch-tegra2/display.h

diff --git a/arch/arm/cpu/armv7/tegra2/Makefile b/arch/arm/cpu/armv7/tegra2/Makefile
index 5d271c4..79e1319 100644
--- a/arch/arm/cpu/armv7/tegra2/Makefile
+++ b/arch/arm/cpu/armv7/tegra2/Makefile
@@ -40,7 +40,7 @@ COBJS-$(CONFIG_TEGRA_PMU) += pmu.o
 COBJS-$(CONFIG_USB_EHCI_TEGRA) += usb.o
 COBJS-$(CONFIG_TEGRA2_LP0) += crypto.o warmboot.o warmboot_avp.o
 COBJS-$(CONFIG_CMD_ENTERRCM) += cmd_enterrcm.o
-COBJS-$(CONFIG_VIDEO_TEGRA) += pwm.o
+COBJS-$(CONFIG_VIDEO_TEGRA) += display.o pwm.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
diff --git a/arch/arm/cpu/armv7/tegra2/display.c b/arch/arm/cpu/armv7/tegra2/display.c
new file mode 100644
index 0000000..267e89e
--- /dev/null
+++ b/arch/arm/cpu/armv7/tegra2/display.c
@@ -0,0 +1,389 @@
+/*
+ *  (C) Copyright 2010
+ *  NVIDIA Corporation <www.nvidia.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/clk_rst.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/timer.h>
+#include <asm/arch/tegra2.h>
+#include <asm/arch/display.h>
+#include <asm/arch/dc.h>
+
+static struct fdt_disp_config config;
+
+static void update_window(struct dc_ctlr *dc, struct disp_ctl_win *win)
+{
+	unsigned h_dda, v_dda;
+	unsigned long val;
+
+	val = readl(&dc->cmd.disp_win_header);
+	val |= WINDOW_A_SELECT;
+	writel(val, &dc->cmd.disp_win_header);
+
+	writel(win->fmt, &dc->win.color_depth);
+
+	val = readl(&dc->win.byte_swap);
+	val |= BYTE_SWAP_NOSWAP << BYTE_SWAP_SHIFT;
+	writel(val, &dc->win.byte_swap);
+
+	val = win->out_x << H_POSITION_SHIFT;
+	val |= win->out_y << V_POSITION_SHIFT;
+	writel(val, &dc->win.pos);
+
+	val = win->out_w << H_SIZE_SHIFT;
+	val |= win->out_h << V_SIZE_SHIFT;
+	writel(val, &dc->win.size);
+
+	val = (win->w * win->bpp / 8) << H_PRESCALED_SIZE_SHIFT;
+	val |= win->h << V_PRESCALED_SIZE_SHIFT;
+	writel(val, &dc->win.prescaled_size);
+
+	writel(0, &dc->win.h_initial_dda);
+	writel(0, &dc->win.v_initial_dda);
+
+	h_dda = (win->w * 0x1000) / max(win->out_w - 1, 1);
+	v_dda = (win->h * 0x1000) / max(win->out_h - 1, 1);
+
+	val = h_dda << H_DDA_INC_SHIFT;
+	val |= v_dda << V_DDA_INC_SHIFT;
+	writel(val, &dc->win.dda_increment);
+
+	writel(win->stride, &dc->win.line_stride);
+	writel(0, &dc->win.buf_stride);
+
+	val = WIN_ENABLE;
+	if (win->bpp < 24)
+		val |= COLOR_EXPAND;
+	writel(val, &dc->win.win_opt);
+
+	writel((unsigned long)win->phys_addr, &dc->winbuf.start_addr);
+	writel(win->x, &dc->winbuf.addr_h_offset);
+	writel(win->y, &dc->winbuf.addr_v_offset);
+
+	writel(0xff00, &dc->win.blend_nokey);
+	writel(0xff00, &dc->win.blend_1win);
+
+	val = GENERAL_ACT_REQ | WIN_A_ACT_REQ;
+	val |= GENERAL_UPDATE | WIN_A_UPDATE;
+	writel(val, &dc->cmd.state_ctrl);
+}
+
+static void write_pair(struct fdt_disp_config *config, int item, u32 *reg)
+{
+	writel(config->horiz_timing[item] |
+			(config->vert_timing[item] << 16), reg);
+}
+
+static int update_display_mode(struct dc_disp_reg *disp,
+		struct fdt_disp_config *config)
+{
+	unsigned long val;
+	unsigned long rate;
+	unsigned long div;
+
+	writel(0x0, &disp->disp_timing_opt);
+	write_pair(config, FDT_LCD_TIMING_REF_TO_SYNC, &disp->ref_to_sync);
+	write_pair(config, FDT_LCD_TIMING_SYNC_WIDTH, &disp->sync_width);
+	write_pair(config, FDT_LCD_TIMING_BACK_PORCH, &disp->back_porch);
+	write_pair(config, FDT_LCD_TIMING_FRONT_PORCH, &disp->front_porch);
+
+	writel(config->width | (config->height << 16), &disp->disp_active);
+
+	val = DE_SELECT_ACTIVE << DE_SELECT_SHIFT;
+	val |= DE_CONTROL_NORMAL << DE_CONTROL_SHIFT;
+	writel(val, &disp->data_enable_opt);
+
+	val = DATA_FORMAT_DF1P1C << DATA_FORMAT_SHIFT;
+	val |= DATA_ALIGNMENT_MSB << DATA_ALIGNMENT_SHIFT;
+	val |= DATA_ORDER_RED_BLUE << DATA_ORDER_SHIFT;
+	writel(val, &disp->disp_interface_ctrl);
+
+	/*
+	 * The pixel clock divider is in 7.1 format (where the bottom bit
+	 * represents 0.5). Here we calculate the divider needed to get from
+	 * the display clock (typically 600MHz) to the pixel clock. We round
+	 * up or down as requried.
+	 */
+	rate = clock_get_periph_rate(PERIPH_ID_DISP1, CLOCK_ID_CGENERAL);
+	div = ((rate * 2 + config->pixel_clock / 2) / config->pixel_clock) - 2;
+	debug("Display clock %lu, divider %lu\n", rate, div);
+
+	writel(0x00010001, &disp->shift_clk_opt);
+
+	val = PIXEL_CLK_DIVIDER_PCD1 << PIXEL_CLK_DIVIDER_SHIFT;
+	val |= div << SHIFT_CLK_DIVIDER_SHIFT;
+	writel(val, &disp->disp_clk_ctrl);
+
+	return 0;
+}
+
+/* Start up the display and turn on power to PWMs */
+static void basic_init(struct dc_cmd_reg *cmd)
+{
+	u32 val;
+
+	writel(0x00000100, &cmd->gen_incr_syncpt_ctrl);
+	writel(0x0000011a, &cmd->cont_syncpt_vsync);
+	writel(0x00000000, &cmd->int_type);
+	writel(0x00000000, &cmd->int_polarity);
+	writel(0x00000000, &cmd->int_mask);
+	writel(0x00000000, &cmd->int_enb);
+
+	val = PW0_ENABLE | PW1_ENABLE | PW2_ENABLE;
+	val |= PW3_ENABLE | PW4_ENABLE | PM0_ENABLE;
+	val |= PM1_ENABLE;
+	writel(val, &cmd->disp_pow_ctrl);
+
+	val = readl(&cmd->disp_cmd);
+	val |= CTRL_MODE_C_DISPLAY << CTRL_MODE_SHIFT;
+	writel(val, &cmd->disp_cmd);
+}
+
+static void basic_init_timer(struct dc_disp_reg *disp)
+{
+	writel(0x00000020, &disp->mem_high_pri);
+	writel(0x00000001, &disp->mem_high_pri_timer);
+}
+
+static const u32 rgb_enb_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 void rgb_enable(struct dc_com_reg *com)
+{
+	int i;
+
+	for (i = 0; i < PIN_REG_COUNT; i++) {
+		writel(rgb_enb_tab[i], &com->pin_output_enb[i]);
+		writel(rgb_polarity_tab[i], &com->pin_output_polarity[i]);
+		writel(rgb_data_tab[i], &com->pin_output_data[i]);
+	}
+
+	for (i = 0; i < PIN_OUTPUT_SEL_COUNT; i++)
+		writel(rgb_sel_tab[i], &com->pin_output_sel[i]);
+}
+
+int setup_window(struct disp_ctl_win *win, struct fdt_disp_config *config)
+{
+	win->x = 0;
+	win->y = 0;
+	win->w = config->width;
+	win->h = config->height;
+	win->out_x = 0;
+	win->out_y = 0;
+	win->out_w = config->width;
+	win->out_h = config->height;
+	win->phys_addr = config->frame_buffer;
+	win->stride = config->width * (1 << config->log2_bpp) / 8;
+	debug("%s: depth = %d\n", __func__, config->log2_bpp);
+	switch (config->log2_bpp) {
+	case 5:
+	case 24:
+		win->fmt = COLOR_DEPTH_R8G8B8A8;
+		win->bpp = 32;
+		break;
+	case 4:
+		win->fmt = COLOR_DEPTH_B5G6R5;
+		win->bpp = 16;
+		break;
+
+	default:
+		debug("Unsupported LCD bit depth");
+		return -1;
+	}
+
+	return 0;
+}
+
+struct fdt_disp_config *tegra_display_get_config(void)
+{
+	return config.valid ? &config : NULL;
+}
+
+static void debug_timing(const char *name, unsigned int timing[])
+{
+#ifdef DEBUG
+	int i;
+
+	debug("%s timing: ", name);
+	for (i = 0; i < FDT_LCD_TIMING_COUNT; i++)
+		debug("%d ", timing[i]);
+	debug("\n");
+#endif
+}
+
+/**
+ * Decode the display controller information from the fdt.
+ *
+ * @param blob		fdt blob
+ * @param config	structure to store fdt config into
+ * @return 0 if ok, -ve on error
+ */
+static int tegra_display_decode_config(const void *blob,
+				       struct fdt_disp_config *config)
+{
+	int front, back, ref;
+	int node, rgb;
+	int bpp, bit;
+
+	node = fdtdec_next_compatible(blob, 0, COMPAT_NVIDIA_TEGRA20_DC);
+	if (node < 0) {
+		debug("%s: Cannot find display controller node in fdt\n",
+		      __func__);
+		return node;
+	}
+	config->disp = (struct disp_ctlr *)fdtdec_get_addr(blob, node, "reg");
+	if (!config->disp) {
+		debug("%s: No display controller address\n", __func__);
+		return -1;
+	}
+
+	rgb = fdt_subnode_offset(blob, node, "rgb");
+
+	config->frame_buffer = fdtdec_get_addr(blob, rgb,
+					       "nvidia,frame-buffer");
+	config->width = fdtdec_get_int(blob, rgb, "xres", -1);
+	config->height = fdtdec_get_int(blob, rgb, "yres", -1);
+	bpp = fdtdec_get_int(blob, rgb, "nvidia,bits-per-pixel", -1);
+	bit = ffs(bpp) - 1;
+	if (bpp == (1 << bit))
+		config->log2_bpp = bit;
+	else
+		config->log2_bpp = bpp;
+	config->bpp = bpp;
+	config->pixel_clock = fdtdec_get_int(blob, rgb, "clock", 0);
+	if (!config->pixel_clock || bpp == -1 ||
+			config->width == -1 || config->height == -1) {
+		debug("%s: Pixel parameters missing\n", __func__);
+		return -FDT_ERR_NOTFOUND;
+	}
+
+	/* Use a ref-to-sync of 1 always, and take this from the front porch */
+	back = fdtdec_get_int(blob, rgb, "left-margin", -1);
+	front = fdtdec_get_int(blob, rgb, "right-margin", -1);
+	ref = fdtdec_get_int(blob, rgb, "hsync-len", -1);
+	if ((back | front | ref) == -1) {
+		debug("%s: Horizontal parameters missing\n", __func__);
+		return -FDT_ERR_NOTFOUND;
+	}
+	config->horiz_timing[FDT_LCD_TIMING_REF_TO_SYNC] = 11;
+	config->horiz_timing[FDT_LCD_TIMING_SYNC_WIDTH] = ref;
+	config->horiz_timing[FDT_LCD_TIMING_BACK_PORCH] = back;
+	config->horiz_timing[FDT_LCD_TIMING_FRONT_PORCH] = front -
+		config->horiz_timing[FDT_LCD_TIMING_REF_TO_SYNC];
+	debug_timing("horiz", config->horiz_timing);
+
+	back = fdtdec_get_int(blob, rgb, "upper-margin", -1);
+	front = fdtdec_get_int(blob, rgb, "lower-margin", -1);
+	ref = fdtdec_get_int(blob, rgb, "vsync-len", -1);
+	if ((back | front | ref) == -1) {
+		debug("%s: Vertical parameters missing\n", __func__);
+		return -FDT_ERR_NOTFOUND;
+	}
+	config->vert_timing[FDT_LCD_TIMING_REF_TO_SYNC] = 1;
+	config->vert_timing[FDT_LCD_TIMING_SYNC_WIDTH] = ref;
+	config->vert_timing[FDT_LCD_TIMING_BACK_PORCH] = back;
+	config->vert_timing[FDT_LCD_TIMING_FRONT_PORCH] = front -
+		config->vert_timing[FDT_LCD_TIMING_REF_TO_SYNC];
+	debug_timing("vert", config->horiz_timing);
+
+	config->panel_node = fdtdec_lookup_phandle(blob, rgb, "nvidia,panel");
+
+	config->valid = 1;	/* we have a valid configuration */
+
+	return 0;
+}
+
+int tegra_display_probe(const void *blob, void *default_lcd_base)
+{
+	struct disp_ctl_win window;
+	struct dc_ctlr *dc;
+
+	if (tegra_display_decode_config(blob, &config))
+		return -1;
+
+	/*
+	 * The framebuffer address should be specified in the device tree.
+	 * This FDT value should be the same as the one defined in Linux kernel;
+	 * otherwise, it causes screen flicker. The FDT value overrides the
+	 * framebuffer allocated at the top of memory by board_init_f().
+	 *
+	 * If the framebuffer address is not defined in the FDT, falls back to
+	 * use the address allocated by board_init_f().
+	 */
+	if (config.frame_buffer == FDT_ADDR_T_NONE)
+		config.frame_buffer = (u32)default_lcd_base;
+
+	dc = (struct dc_ctlr *)config.disp;
+
+	/*
+	 * A header file for clock constants was NAKed upstream.
+	 * TODO: Put this into the FDT and fdt_lcd struct when we have clock
+	 * support there
+	 */
+	clock_start_periph_pll(PERIPH_ID_HOST1X, CLOCK_ID_PERIPH,
+			       144 * 1000000);
+	clock_start_periph_pll(PERIPH_ID_DISP1, CLOCK_ID_CGENERAL,
+			       600 * 1000000);
+	basic_init(&dc->cmd);
+	basic_init_timer(&dc->disp);
+	rgb_enable(&dc->com);
+
+	if (config.pixel_clock)
+		update_display_mode(&dc->disp, &config);
+
+	if (setup_window(&window, &config))
+		return -1;
+
+	update_window(dc, &window);
+
+	return 0;
+}
diff --git a/arch/arm/include/asm/arch-tegra2/dc.h b/arch/arm/include/asm/arch-tegra2/dc.h
new file mode 100644
index 0000000..46c4137
--- /dev/null
+++ b/arch/arm/include/asm/arch-tegra2/dc.h
@@ -0,0 +1,544 @@
+/*
+ *  (C) Copyright 2010
+ *  NVIDIA Corporation <www.nvidia.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __ASM_ARCH_TEGRA_DC_H
+#define __ASM_ARCH_TEGRA_DC_H
+
+/* Register definitions for the Tegra display controller */
+
+/* CMD register 0x000 ~ 0x43 */
+struct dc_cmd_reg {
+	/* Address 0x000 ~ 0x002 */
+	uint gen_incr_syncpt;		/* _CMD_GENERAL_INCR_SYNCPT_0 */
+	uint gen_incr_syncpt_ctrl;	/* _CMD_GENERAL_INCR_SYNCPT_CNTRL_0 */
+	uint gen_incr_syncpt_err;	/* _CMD_GENERAL_INCR_SYNCPT_ERROR_0 */
+
+	uint reserved0[5];		/* reserved_0[5] */
+
+	/* Address 0x008 ~ 0x00a */
+	uint win_a_incr_syncpt;		/* _CMD_WIN_A_INCR_SYNCPT_0 */
+	uint win_a_incr_syncpt_ctrl;	/* _CMD_WIN_A_INCR_SYNCPT_CNTRL_0 */
+	uint win_a_incr_syncpt_err;	/* _CMD_WIN_A_INCR_SYNCPT_ERROR_0 */
+
+	uint reserved1[5];		/* reserved_1[5] */
+
+	/* Address 0x010 ~ 0x012 */
+	uint win_b_incr_syncpt;		/* _CMD_WIN_B_INCR_SYNCPT_0 */
+	uint win_b_incr_syncpt_ctrl;	/* _CMD_WIN_B_INCR_SYNCPT_CNTRL_0 */
+	uint win_b_incr_syncpt_err;	/* _CMD_WIN_B_INCR_SYNCPT_ERROR_0 */
+
+	uint reserved2[5];		/* reserved_2[5] */
+
+	/* Address 0x018 ~ 0x01a */
+	uint win_c_incr_syncpt;		/* _CMD_WIN_C_INCR_SYNCPT_0 */
+	uint win_c_incr_syncpt_ctrl;	/* _CMD_WIN_C_INCR_SYNCPT_CNTRL_0 */
+	uint win_c_incr_syncpt_err;	/* _CMD_WIN_C_INCR_SYNCPT_ERROR_0 */
+
+	uint reserved3[13];		/* reserved_3[13] */
+
+	/* Address 0x028 */
+	uint cont_syncpt_vsync;		/* _CMD_CONT_SYNCPT_VSYNC_0 */
+
+	uint reserved4[7];		/* reserved_4[7] */
+
+	/* Address 0x030 ~ 0x033 */
+	uint ctxsw;			/* _CMD_CTXSW_0 */
+	uint disp_cmd_opt0;		/* _CMD_DISPLAY_COMMAND_OPTION0_0 */
+	uint disp_cmd;			/* _CMD_DISPLAY_COMMAND_0 */
+	uint sig_raise;			/* _CMD_SIGNAL_RAISE_0 */
+
+	uint reserved5[2];		/* reserved_0[2] */
+
+	/* Address 0x036 ~ 0x03e */
+	uint disp_pow_ctrl;		/* _CMD_DISPLAY_POWER_CONTROL_0 */
+	uint int_stat;			/* _CMD_INT_STATUS_0 */
+	uint int_mask;			/* _CMD_INT_MASK_0 */
+	uint int_enb;			/* _CMD_INT_ENABLE_0 */
+	uint int_type;			/* _CMD_INT_TYPE_0 */
+	uint int_polarity;		/* _CMD_INT_POLARITY_0 */
+	uint sig_raise1;		/* _CMD_SIGNAL_RAISE1_0 */
+	uint sig_raise2;		/* _CMD_SIGNAL_RAISE2_0 */
+	uint sig_raise3;		/* _CMD_SIGNAL_RAISE3_0 */
+
+	uint reserved6;			/* reserved_6 */
+
+	/* Address 0x040 ~ 0x043 */
+	uint state_access;		/* _CMD_STATE_ACCESS_0 */
+	uint state_ctrl;		/* _CMD_STATE_CONTROL_0 */
+	uint disp_win_header;		/* _CMD_DISPLAY_WINDOW_HEADER_0 */
+	uint reg_act_ctrl;		/* _CMD_REG_ACT_CONTROL_0 */
+};
+
+enum {
+	PIN_REG_COUNT		= 4,
+	PIN_OUTPUT_SEL_COUNT	= 7,
+};
+
+/* COM register 0x300 ~ 0x329 */
+struct dc_com_reg {
+	/* Address 0x300 ~ 0x301 */
+	uint crc_ctrl;			/* _COM_CRC_CONTROL_0 */
+	uint crc_checksum;		/* _COM_CRC_CHECKSUM_0 */
+
+	/* _COM_PIN_OUTPUT_ENABLE0/1/2/3_0: Address 0x302 ~ 0x305 */
+	uint pin_output_enb[PIN_REG_COUNT];
+
+	/* _COM_PIN_OUTPUT_POLARITY0/1/2/3_0: Address 0x306 ~ 0x309 */
+	uint pin_output_polarity[PIN_REG_COUNT];
+
+	/* _COM_PIN_OUTPUT_DATA0/1/2/3_0: Address 0x30a ~ 0x30d */
+	uint pin_output_data[PIN_REG_COUNT];
+
+	/* _COM_PIN_INPUT_ENABLE0_0: Address 0x30e ~ 0x311 */
+	uint pin_input_enb[PIN_REG_COUNT];
+
+	/* Address 0x312 ~ 0x313 */
+	uint pin_input_data0;		/* _COM_PIN_INPUT_DATA0_0 */
+	uint pin_input_data1;		/* _COM_PIN_INPUT_DATA1_0 */
+
+	/* _COM_PIN_OUTPUT_SELECT0/1/2/3/4/5/6_0: Address 0x314 ~ 0x31a */
+	uint pin_output_sel[PIN_OUTPUT_SEL_COUNT];
+
+	/* Address 0x31b ~ 0x329 */
+	uint pin_misc_ctrl;		/* _COM_PIN_MISC_CONTROL_0 */
+	uint pm0_ctrl;			/* _COM_PM0_CONTROL_0 */
+	uint pm0_duty_cycle;		/* _COM_PM0_DUTY_CYCLE_0 */
+	uint pm1_ctrl;			/* _COM_PM1_CONTROL_0 */
+	uint pm1_duty_cycle;		/* _COM_PM1_DUTY_CYCLE_0 */
+	uint spi_ctrl;			/* _COM_SPI_CONTROL_0 */
+	uint spi_start_byte;		/* _COM_SPI_START_BYTE_0 */
+	uint hspi_wr_data_ab;		/* _COM_HSPI_WRITE_DATA_AB_0 */
+	uint hspi_wr_data_cd;		/* _COM_HSPI_WRITE_DATA_CD */
+	uint hspi_cs_dc;		/* _COM_HSPI_CS_DC_0 */
+	uint scratch_reg_a;		/* _COM_SCRATCH_REGISTER_A_0 */
+	uint scratch_reg_b;		/* _COM_SCRATCH_REGISTER_B_0 */
+	uint gpio_ctrl;			/* _COM_GPIO_CTRL_0 */
+	uint gpio_debounce_cnt;		/* _COM_GPIO_DEBOUNCE_COUNTER_0 */
+	uint crc_checksum_latched;	/* _COM_CRC_CHECKSUM_LATCHED_0 */
+};
+
+enum dc_disp_h_pulse_pos {
+	H_PULSE0_POSITION_A,
+	H_PULSE0_POSITION_B,
+	H_PULSE0_POSITION_C,
+	H_PULSE0_POSITION_D,
+	H_PULSE0_POSITION_COUNT,
+};
+
+struct _disp_h_pulse {
+	/* _DISP_H_PULSE0/1/2_CONTROL_0 */
+	uint h_pulse_ctrl;
+	/* _DISP_H_PULSE0/1/2_POSITION_A/B/C/D_0 */
+	uint h_pulse_pos[H_PULSE0_POSITION_COUNT];
+};
+
+enum dc_disp_v_pulse_pos {
+	V_PULSE0_POSITION_A,
+	V_PULSE0_POSITION_B,
+	V_PULSE0_POSITION_C,
+	V_PULSE0_POSITION_COUNT,
+};
+
+struct _disp_v_pulse0 {
+	/* _DISP_H_PULSE0/1_CONTROL_0 */
+	uint v_pulse_ctrl;
+	/* _DISP_H_PULSE0/1_POSITION_A/B/C_0 */
+	uint v_pulse_pos[V_PULSE0_POSITION_COUNT];
+};
+
+struct _disp_v_pulse2 {
+	/* _DISP_H_PULSE2/3_CONTROL_0 */
+	uint v_pulse_ctrl;
+	/* _DISP_H_PULSE2/3_POSITION_A_0 */
+	uint v_pulse_pos_a;
+};
+
+enum dc_disp_h_pulse_reg {
+	H_PULSE0,
+	H_PULSE1,
+	H_PULSE2,
+	H_PULSE_COUNT,
+};
+
+enum dc_disp_pp_select {
+	PP_SELECT_A,
+	PP_SELECT_B,
+	PP_SELECT_C,
+	PP_SELECT_D,
+	PP_SELECT_COUNT,
+};
+
+/* DISP register 0x400 ~ 0x4c1 */
+struct dc_disp_reg {
+	/* Address 0x400 ~ 0x40a */
+	uint disp_signal_opt0;		/* _DISP_DISP_SIGNAL_OPTIONS0_0 */
+	uint disp_signal_opt1;		/* _DISP_DISP_SIGNAL_OPTIONS1_0 */
+	uint disp_win_opt;		/* _DISP_DISP_WIN_OPTIONS_0 */
+	uint mem_high_pri;		/* _DISP_MEM_HIGH_PRIORITY_0 */
+	uint mem_high_pri_timer;	/* _DISP_MEM_HIGH_PRIORITY_TIMER_0 */
+	uint disp_timing_opt;		/* _DISP_DISP_TIMING_OPTIONS_0 */
+	uint ref_to_sync;		/* _DISP_REF_TO_SYNC_0 */
+	uint sync_width;		/* _DISP_SYNC_WIDTH_0 */
+	uint back_porch;		/* _DISP_BACK_PORCH_0 */
+	uint disp_active;		/* _DISP_DISP_ACTIVE_0 */
+	uint front_porch;		/* _DISP_FRONT_PORCH_0 */
+
+	/* Address 0x40b ~ 0x419: _DISP_H_PULSE0/1/2_  */
+	struct _disp_h_pulse h_pulse[H_PULSE_COUNT];
+
+	/* Address 0x41a ~ 0x421 */
+	struct _disp_v_pulse0 v_pulse0;	/* _DISP_V_PULSE0_ */
+	struct _disp_v_pulse0 v_pulse1;	/* _DISP_V_PULSE1_ */
+
+	/* Address 0x422 ~ 0x425 */
+	struct _disp_v_pulse2 v_pulse3;	/* _DISP_V_PULSE2_ */
+	struct _disp_v_pulse2 v_pulse4;	/* _DISP_V_PULSE3_ */
+
+	/* Address 0x426 ~ 0x429 */
+	uint m0_ctrl;			/* _DISP_M0_CONTROL_0 */
+	uint m1_ctrl;			/* _DISP_M1_CONTROL_0 */
+	uint di_ctrl;			/* _DISP_DI_CONTROL_0 */
+	uint pp_ctrl;			/* _DISP_PP_CONTROL_0 */
+
+	/* Address 0x42a ~ 0x42d: _DISP_PP_SELECT_A/B/C/D_0 */
+	uint pp_select[PP_SELECT_COUNT];
+
+	/* Address 0x42e ~ 0x435 */
+	uint disp_clk_ctrl;		/* _DISP_DISP_CLOCK_CONTROL_0 */
+	uint disp_interface_ctrl;	/* _DISP_DISP_INTERFACE_CONTROL_0 */
+	uint disp_color_ctrl;		/* _DISP_DISP_COLOR_CONTROL_0 */
+	uint shift_clk_opt;		/* _DISP_SHIFT_CLOCK_OPTIONS_0 */
+	uint data_enable_opt;		/* _DISP_DATA_ENABLE_OPTIONS_0 */
+	uint serial_interface_opt;	/* _DISP_SERIAL_INTERFACE_OPTIONS_0 */
+	uint lcd_spi_opt;		/* _DISP_LCD_SPI_OPTIONS_0 */
+	uint border_color;		/* _DISP_BORDER_COLOR_0 */
+
+	/* Address 0x436 ~ 0x439 */
+	uint color_key0_lower;		/* _DISP_COLOR_KEY0_LOWER_0 */
+	uint color_key0_upper;		/* _DISP_COLOR_KEY0_UPPER_0 */
+	uint color_key1_lower;		/* _DISP_COLOR_KEY1_LOWER_0 */
+	uint color_key1_upper;		/* _DISP_COLOR_KEY1_UPPER_0 */
+
+	uint reserved0[2];		/* reserved_0[2] */
+
+	/* Address 0x43c ~ 0x442 */
+	uint cursor_foreground;		/* _DISP_CURSOR_FOREGROUND_0 */
+	uint cursor_background;		/* _DISP_CURSOR_BACKGROUND_0 */
+	uint cursor_start_addr;		/* _DISP_CURSOR_START_ADDR_0 */
+	uint cursor_start_addr_ns;	/* _DISP_CURSOR_START_ADDR_NS_0 */
+	uint cursor_pos;		/* _DISP_CURSOR_POSITION_0 */
+	uint cursor_pos_ns;		/* _DISP_CURSOR_POSITION_NS_0 */
+	uint seq_ctrl;			/* _DISP_INIT_SEQ_CONTROL_0 */
+
+	/* Address 0x442 ~ 0x446 */
+	uint spi_init_seq_data_a;	/* _DISP_SPI_INIT_SEQ_DATA_A_0 */
+	uint spi_init_seq_data_b;	/* _DISP_SPI_INIT_SEQ_DATA_B_0 */
+	uint spi_init_seq_data_c;	/* _DISP_SPI_INIT_SEQ_DATA_C_0 */
+	uint spi_init_seq_data_d;	/* _DISP_SPI_INIT_SEQ_DATA_D_0 */
+
+	uint reserved1[0x39];		/* reserved1[0x39], */
+
+	/* Address 0x480 ~ 0x484 */
+	uint dc_mccif_fifoctrl;		/* _DISP_DC_MCCIF_FIFOCTRL_0 */
+	uint mccif_disp0a_hyst;		/* _DISP_MCCIF_DISPLAY0A_HYST_0 */
+	uint mccif_disp0b_hyst;		/* _DISP_MCCIF_DISPLAY0B_HYST_0 */
+	uint mccif_disp0c_hyst;		/* _DISP_MCCIF_DISPLAY0C_HYST_0 */
+	uint mccif_disp1b_hyst;		/* _DISP_MCCIF_DISPLAY1B_HYST_0 */
+
+	uint reserved2[0x3b];		/* reserved2[0x3b] */
+
+	/* Address 0x4c0 ~ 0x4c1 */
+	uint dac_crt_ctrl;		/* _DISP_DAC_CRT_CTRL_0 */
+	uint disp_misc_ctrl;		/* _DISP_DISP_MISC_CONTROL_0 */
+};
+
+enum dc_winc_filter_p {
+	WINC_FILTER_COUNT	= 0x10,
+};
+
+/* Window A/B/C register 0x500 ~ 0x628 */
+struct dc_winc_reg {
+
+	/* Address 0x500 */
+	uint color_palette;		/* _WINC_COLOR_PALETTE_0 */
+
+	uint reserved0[0xff];		/* reserved_0[0xff] */
+
+	/* Address 0x600 */
+	uint palette_color_ext;		/* _WINC_PALETTE_COLOR_EXT_0 */
+
+	/* _WINC_H_FILTER_P00~0F_0 */
+	/* Address 0x601 ~ 0x610 */
+	uint h_filter_p[WINC_FILTER_COUNT];
+
+	/* Address 0x611 ~ 0x618 */
+	uint csc_yof;			/* _WINC_CSC_YOF_0 */
+	uint csc_kyrgb;			/* _WINC_CSC_KYRGB_0 */
+	uint csc_kur;			/* _WINC_CSC_KUR_0 */
+	uint csc_kvr;			/* _WINC_CSC_KVR_0 */
+	uint csc_kug;			/* _WINC_CSC_KUG_0 */
+	uint csc_kvg;			/* _WINC_CSC_KVG_0 */
+	uint csc_kub;			/* _WINC_CSC_KUB_0 */
+	uint csc_kvb;			/* _WINC_CSC_KVB_0 */
+
+	/* Address 0x619 ~ 0x628: _WINC_V_FILTER_P00~0F_0 */
+	uint v_filter_p[WINC_FILTER_COUNT];
+};
+
+/* WIN A/B/C Register 0x700 ~ 0x714*/
+struct dc_win_reg {
+	/* Address 0x700 ~ 0x714 */
+	uint win_opt;			/* _WIN_WIN_OPTIONS_0 */
+	uint byte_swap;			/* _WIN_BYTE_SWAP_0 */
+	uint buffer_ctrl;		/* _WIN_BUFFER_CONTROL_0 */
+	uint color_depth;		/* _WIN_COLOR_DEPTH_0 */
+	uint pos;			/* _WIN_POSITION_0 */
+	uint size;			/* _WIN_SIZE_0 */
+	uint prescaled_size;		/* _WIN_PRESCALED_SIZE_0 */
+	uint h_initial_dda;		/* _WIN_H_INITIAL_DDA_0 */
+	uint v_initial_dda;		/* _WIN_V_INITIAL_DDA_0 */
+	uint dda_increment;		/* _WIN_DDA_INCREMENT_0 */
+	uint line_stride;		/* _WIN_LINE_STRIDE_0 */
+	uint buf_stride;		/* _WIN_BUF_STRIDE_0 */
+	uint uv_buf_stride;		/* _WIN_UV_BUF_STRIDE_0 */
+	uint buffer_addr_mode;		/* _WIN_BUFFER_ADDR_MODE_0 */
+	uint dv_ctrl;			/* _WIN_DV_CONTROL_0 */
+	uint blend_nokey;		/* _WIN_BLEND_NOKEY_0 */
+	uint blend_1win;		/* _WIN_BLEND_1WIN_0 */
+	uint blend_2win_x;		/* _WIN_BLEND_2WIN_X_0 */
+	uint blend_2win_y;		/* _WIN_BLEND_2WIN_Y_0 */
+	uint blend_3win_xy;		/* _WIN_BLEND_3WIN_XY_0 */
+	uint hp_fetch_ctrl;		/* _WIN_HP_FETCH_CONTROL_0 */
+};
+
+/* WINBUF A/B/C Register 0x800 ~ 0x80a */
+struct dc_winbuf_reg {
+	/* Address 0x800 ~ 0x80a */
+	uint start_addr;		/* _WINBUF_START_ADDR_0 */
+	uint start_addr_ns;		/* _WINBUF_START_ADDR_NS_0 */
+	uint start_addr_u;		/* _WINBUF_START_ADDR_U_0 */
+	uint start_addr_u_ns;		/* _WINBUF_START_ADDR_U_NS_0 */
+	uint start_addr_v;		/* _WINBUF_START_ADDR_V_0 */
+	uint start_addr_v_ns;		/* _WINBUF_START_ADDR_V_NS_0 */
+	uint addr_h_offset;		/* _WINBUF_ADDR_H_OFFSET_0 */
+	uint addr_h_offset_ns;		/* _WINBUF_ADDR_H_OFFSET_NS_0 */
+	uint addr_v_offset;		/* _WINBUF_ADDR_V_OFFSET_0 */
+	uint addr_v_offset_ns;		/* _WINBUF_ADDR_V_OFFSET_NS_0 */
+	uint uflow_status;		/* _WINBUF_UFLOW_STATUS_0 */
+};
+
+/* Display Controller (DC_) regs */
+struct dc_ctlr {
+	struct dc_cmd_reg cmd;		/* CMD register 0x000 ~ 0x43 */
+	uint reserved0[0x2bc];
+
+	struct dc_com_reg com;		/* COM register 0x300 ~ 0x329 */
+	uint reserved1[0xd6];
+
+	struct dc_disp_reg disp;	/* DISP register 0x400 ~ 0x4c1 */
+	uint reserved2[0x3e];
+
+	struct dc_winc_reg winc;	/* Window A/B/C 0x500 ~ 0x628 */
+	uint reserved3[0xd7];
+
+	struct dc_win_reg win;		/* WIN A/B/C 0x700 ~ 0x714*/
+	uint reserved4[0xeb];
+
+	struct dc_winbuf_reg winbuf;	/* WINBUF A/B/C 0x800 ~ 0x80a */
+};
+
+#define BIT(pos)	(1U << pos)
+
+/* DC_CMD_DISPLAY_COMMAND 0x032 */
+#define CTRL_MODE_SHIFT		5
+#define CTRL_MODE_MASK		(0x3 << CTRL_MODE_SHIFT)
+enum {
+	CTRL_MODE_STOP,
+	CTRL_MODE_C_DISPLAY,
+	CTRL_MODE_NC_DISPLAY,
+};
+
+/* _WIN_COLOR_DEPTH_0 */
+enum win_color_depth_id {
+	COLOR_DEPTH_P1,
+	COLOR_DEPTH_P2,
+	COLOR_DEPTH_P4,
+	COLOR_DEPTH_P8,
+	COLOR_DEPTH_B4G4R4A4,
+	COLOR_DEPTH_B5G5R5A,
+	COLOR_DEPTH_B5G6R5,
+	COLOR_DEPTH_AB5G5R5,
+	COLOR_DEPTH_B8G8R8A8 = 12,
+	COLOR_DEPTH_R8G8B8A8,
+	COLOR_DEPTH_B6x2G6x2R6x2A8,
+	COLOR_DEPTH_R6x2G6x2B6x2A8,
+	COLOR_DEPTH_YCbCr422,
+	COLOR_DEPTH_YUV422,
+	COLOR_DEPTH_YCbCr420P,
+	COLOR_DEPTH_YUV420P,
+	COLOR_DEPTH_YCbCr422P,
+	COLOR_DEPTH_YUV422P,
+	COLOR_DEPTH_YCbCr422R,
+	COLOR_DEPTH_YUV422R,
+	COLOR_DEPTH_YCbCr422RA,
+	COLOR_DEPTH_YUV422RA,
+};
+
+/* DC_CMD_DISPLAY_POWER_CONTROL 0x036 */
+#define PW0_ENABLE		BIT(0)
+#define PW1_ENABLE		BIT(2)
+#define PW2_ENABLE		BIT(4)
+#define PW3_ENABLE		BIT(6)
+#define PW4_ENABLE		BIT(8)
+#define PM0_ENABLE		BIT(16)
+#define PM1_ENABLE		BIT(18)
+#define SPI_ENABLE		BIT(24)
+#define HSPI_ENABLE		BIT(25)
+
+/* DC_CMD_STATE_CONTROL 0x041 */
+#define GENERAL_ACT_REQ		BIT(0)
+#define WIN_A_ACT_REQ		BIT(1)
+#define WIN_B_ACT_REQ		BIT(2)
+#define WIN_C_ACT_REQ		BIT(3)
+#define GENERAL_UPDATE		BIT(8)
+#define WIN_A_UPDATE		BIT(9)
+#define WIN_B_UPDATE		BIT(10)
+#define WIN_C_UPDATE		BIT(11)
+
+/* DC_CMD_DISPLAY_WINDOW_HEADER 0x042 */
+#define WINDOW_A_SELECT		BIT(4)
+#define WINDOW_B_SELECT		BIT(5)
+#define WINDOW_C_SELECT		BIT(6)
+
+/* DC_DISP_DISP_CLOCK_CONTROL 0x42e */
+#define SHIFT_CLK_DIVIDER_SHIFT	0
+#define SHIFT_CLK_DIVIDER_MASK	(0xff << SHIFT_CLK_DIVIDER_SHIFT)
+#define	PIXEL_CLK_DIVIDER_SHIFT	8
+#define	PIXEL_CLK_DIVIDER_MSK	(0xf << PIXEL_CLK_DIVIDER_SHIFT)
+enum {
+	PIXEL_CLK_DIVIDER_PCD1,
+	PIXEL_CLK_DIVIDER_PCD1H,
+	PIXEL_CLK_DIVIDER_PCD2,
+	PIXEL_CLK_DIVIDER_PCD3,
+	PIXEL_CLK_DIVIDER_PCD4,
+	PIXEL_CLK_DIVIDER_PCD6,
+	PIXEL_CLK_DIVIDER_PCD8,
+	PIXEL_CLK_DIVIDER_PCD9,
+	PIXEL_CLK_DIVIDER_PCD12,
+	PIXEL_CLK_DIVIDER_PCD16,
+	PIXEL_CLK_DIVIDER_PCD18,
+	PIXEL_CLK_DIVIDER_PCD24,
+	PIXEL_CLK_DIVIDER_PCD13,
+};
+
+/* DC_DISP_DISP_INTERFACE_CONTROL 0x42f */
+#define DATA_FORMAT_SHIFT	0
+#define DATA_FORMAT_MASK	(0xf << DATA_FORMAT_SHIFT)
+enum {
+	DATA_FORMAT_DF1P1C,
+	DATA_FORMAT_DF1P2C24B,
+	DATA_FORMAT_DF1P2C18B,
+	DATA_FORMAT_DF1P2C16B,
+	DATA_FORMAT_DF2S,
+	DATA_FORMAT_DF3S,
+	DATA_FORMAT_DFSPI,
+	DATA_FORMAT_DF1P3C24B,
+	DATA_FORMAT_DF1P3C18B,
+};
+#define DATA_ALIGNMENT_SHIFT	8
+enum {
+	DATA_ALIGNMENT_MSB,
+	DATA_ALIGNMENT_LSB,
+};
+#define DATA_ORDER_SHIFT	9
+enum {
+	DATA_ORDER_RED_BLUE,
+	DATA_ORDER_BLUE_RED,
+};
+
+/* DC_DISP_DATA_ENABLE_OPTIONS 0x432 */
+#define DE_SELECT_SHIFT		0
+#define DE_SELECT_MASK		(0x3 << DE_SELECT_SHIFT)
+#define DE_SELECT_ACTIVE_BLANK	0x0
+#define DE_SELECT_ACTIVE	0x1
+#define DE_SELECT_ACTIVE_IS	0x2
+#define DE_CONTROL_SHIFT	2
+#define DE_CONTROL_MASK		(0x7 << DE_CONTROL_SHIFT)
+enum {
+	DE_CONTROL_ONECLK,
+	DE_CONTROL_NORMAL,
+	DE_CONTROL_EARLY_EXT,
+	DE_CONTROL_EARLY,
+	DE_CONTROL_ACTIVE_BLANK,
+};
+
+/* DC_WIN_WIN_OPTIONS 0x700 */
+#define H_DIRECTION		BIT(0)
+enum {
+	H_DIRECTION_INCREMENT,
+	H_DIRECTION_DECREMENT,
+};
+#define V_DIRECTION		BIT(2)
+enum {
+	V_DIRECTION_INCREMENT,
+	V_DIRECTION_DECREMENT,
+};
+#define COLOR_EXPAND		BIT(6)
+#define CP_ENABLE		BIT(16)
+#define DV_ENABLE		BIT(20)
+#define WIN_ENABLE		BIT(30)
+
+/* DC_WIN_BYTE_SWAP 0x701 */
+#define BYTE_SWAP_SHIFT		0
+enum {
+	BYTE_SWAP_NOSWAP,
+	BYTE_SWAP_SWAP2,
+	BYTE_SWAP_SWAP4,
+	BYTE_SWAP_SWAP4HW
+};
+
+/* DC_WIN_POSITION 0x704 */
+#define H_POSITION_SHIFT	0
+#define H_POSITION_MASK		(0x1FFF << H_POSITION_SHIFT)
+#define V_POSITION_SHIFT	16
+#define V_POSITION_MASK		(0x1FFF << V_POSITION_SHIFT)
+
+/* DC_WIN_SIZE 0x705 */
+#define H_SIZE_SHIFT		0
+#define H_SIZE_MASK		(0x1FFF << H_SIZE_SHIFT)
+#define V_SIZE_SHIFT		16
+#define V_SIZE_MASK		(0x1FFF << V_SIZE_SHIFT)
+
+/* DC_WIN_PRESCALED_SIZE 0x706 */
+#define H_PRESCALED_SIZE_SHIFT	0
+#define H_PRESCALED_SIZE_MASK	(0x7FFF << H_PRESCALED_SIZE)
+#define V_PRESCALED_SIZE_SHIFT	16
+#define V_PRESCALED_SIZE_MASK	(0x1FFF << V_PRESCALED_SIZE)
+
+/* DC_WIN_DDA_INCREMENT 0x709 */
+#define H_DDA_INC_SHIFT		0
+#define H_DDA_INC_MASK		(0xFFFF << H_DDA_INC_SHIFT)
+#define V_DDA_INC_SHIFT		16
+#define V_DDA_INC_MASK		(0xFFFF << V_DDA_INC_SHIFT)
+
+#endif /* __ASM_ARCH_TEGRA_DC_H */
diff --git a/arch/arm/include/asm/arch-tegra2/display.h b/arch/arm/include/asm/arch-tegra2/display.h
new file mode 100644
index 0000000..7795317
--- /dev/null
+++ b/arch/arm/include/asm/arch-tegra2/display.h
@@ -0,0 +1,152 @@
+/*
+ *  (C) Copyright 2010
+ *  NVIDIA Corporation <www.nvidia.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __ASM_ARCH_TEGRA_DISPLAY_H
+#define __ASM_ARCH_TEGRA_DISPLAY_H
+
+#include <asm/arch-tegra2/dc.h>
+#include <fdtdec.h>
+
+/* This holds information about a window which can be displayed */
+struct disp_ctl_win {
+	enum win_color_depth_id fmt;	/* Color depth/format */
+	unsigned	bpp;		/* Bits per pixel */
+	phys_addr_t	phys_addr;	/* Physical address in memory */
+	unsigned	x;		/* Horizontal address offset (bytes) */
+	unsigned	y;		/* Veritical address offset (bytes) */
+	unsigned	w;		/* Width of source window */
+	unsigned	h;		/* Height of source window */
+	unsigned	stride;		/* Number of bytes per line */
+	unsigned	out_x;		/* Left edge of output window (col) */
+	unsigned	out_y;		/* Top edge of output window (row) */
+	unsigned	out_w;		/* Width of output window in pixels */
+	unsigned	out_h;		/* Height of output window in pixels */
+};
+
+#define FDT_LCD_TIMINGS	4
+
+enum {
+	FDT_LCD_TIMING_REF_TO_SYNC,
+	FDT_LCD_TIMING_SYNC_WIDTH,
+	FDT_LCD_TIMING_BACK_PORCH,
+	FDT_LCD_TIMING_FRONT_PORCH,
+
+	FDT_LCD_TIMING_COUNT,
+};
+
+enum lcd_cache_t {
+	FDT_LCD_CACHE_OFF		= 0,
+	FDT_LCD_CACHE_WRITE_THROUGH	= 1 << 0,
+	FDT_LCD_CACHE_WRITE_BACK	= 1 << 1,
+	FDT_LCD_CACHE_FLUSH		= 1 << 2,
+	FDT_LCD_CACHE_WRITE_BACK_FLUSH	= FDT_LCD_CACHE_WRITE_BACK |
+						FDT_LCD_CACHE_FLUSH,
+};
+
+/* Information about the display controller */
+struct fdt_disp_config {
+	int valid;			/* config is valid */
+	int width;			/* width in pixels */
+	int height;			/* height in pixels */
+	int bpp;			/* number of bits per pixel */
+
+	/*
+	 * log2 of number of bpp, in general, unless it bpp is 24 in which
+	 * case this field holds 24 also! This is a U-Boot thing.
+	 */
+	int log2_bpp;
+	struct disp_ctlr *disp;		/* Display controller to use */
+	fdt_addr_t frame_buffer;	/* Address of frame buffer */
+	unsigned pixel_clock;		/* Pixel clock in Hz */
+	uint horiz_timing[FDT_LCD_TIMING_COUNT];	/* Horizontal timing */
+	uint vert_timing[FDT_LCD_TIMING_COUNT];		/* Vertical timing */
+	int panel_node;			/* node offset of panel information */
+};
+
+/* Information about the LCD panel */
+struct fdt_panel_config {
+	int pwm_channel;		/* PWM channel to use for backlight */
+	enum lcd_cache_t cache_type;
+
+	struct fdt_gpio_state backlight_en;	/* GPIO for backlight enable */
+	struct fdt_gpio_state lvds_shutdown;	/* GPIO for lvds shutdown */
+	struct fdt_gpio_state backlight_vdd;	/* GPIO for backlight vdd */
+	struct fdt_gpio_state panel_vdd;	/* GPIO for panel vdd */
+	/*
+	 * Panel required timings
+	 * Timing 1: delay between panel_vdd-rise and data-rise
+	 * Timing 2: delay between data-rise and backlight_vdd-rise
+	 * Timing 3: delay between backlight_vdd and pwm-rise
+	 * Timing 4: delay between pwm-rise and backlight_en-rise
+	 */
+	uint panel_timings[FDT_LCD_TIMINGS];
+};
+
+/**
+ * Register a new display based on device tree configuration.
+ *
+ * The frame buffer can be positioned by U-Boot or overriden by the fdt.
+ * You should pass in the U-Boot address here, and check the contents of
+ * struct fdt_disp_config to see what was actually chosen.
+ *
+ * @param blob			Device tree blob
+ * @param default_lcd_base	Default address of LCD frame buffer
+ * @return 0 if ok, -1 on error (unsupported bits per pixel)
+ */
+int tegra_display_probe(const void *blob, void *default_lcd_base);
+
+/**
+ * Return the current display configuration
+ *
+ * @return pointer to display configuration, or NULL if there is no valid
+ * config
+ */
+struct fdt_disp_config *tegra_display_get_config(void);
+
+/**
+ * Perform the next stage of the LCD init if it is time to do so.
+ *
+ * LCD init can be time-consuming because of the number of delays we need
+ * while waiting for the backlight power supply, etc. This function can
+ * be called@various times during U-Boot operation to advance the
+ * initialization of the LCD to the next stage if sufficient time has
+ * passed since the last stage. It keeps track of what stage it is up to
+ * and the time that it is permitted to move to the next stage.
+ *
+ * The final call should have wait=1 to complete the init.
+ *
+ * @param blob	fdt blob containing LCD information
+ * @param wait	1 to wait until all init is complete, and then return
+ *		0 to return immediately, potentially doing nothing if it is
+ *		not yet time for the next init.
+ */
+int tegra_lcd_check_next_stage(const void *blob, int wait);
+
+/**
+ * Set up the maximum LCD size so we can size the frame buffer.
+ *
+ * @param blob	fdt blob containing LCD information
+ */
+void tegra_lcd_early_init(const void *blob);
+
+#endif /*__ASM_ARCH_TEGRA_DISPLAY_H*/
diff --git a/include/fdtdec.h b/include/fdtdec.h
index 3997bfa..b474ced 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -66,6 +66,7 @@ enum fdt_compat_id {
 	COMPAT_NVIDIA_TEGRA20_EMC_TABLE, /* Tegra2 memory timing table */
 	COMPAT_NVIDIA_TEGRA20_KBC,	/* Tegra2 Keyboard */
 	COMPAT_NVIDIA_TEGRA20_PWM,	/* Tegra 2 PWM controller */
+	COMPAT_NVIDIA_TEGRA20_DC,	/* Tegra 2 Display controller */
 
 	COMPAT_COUNT,
 };
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 40b0aef..1021560 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -44,6 +44,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
 	COMPAT(NVIDIA_TEGRA20_EMC_TABLE, "nvidia,tegra20-emc-table"),
 	COMPAT(NVIDIA_TEGRA20_KBC, "nvidia,tegra20-kbc"),
 	COMPAT(NVIDIA_TEGRA20_PWM, "nvidia,tegra20-pwm"),
+	COMPAT(NVIDIA_TEGRA20_DC, "nvidia,tegra20-dc"),
 };
 
 const char *fdtdec_get_compatible(enum fdt_compat_id id)
-- 
1.7.7.3

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

* [U-Boot] [PATCH v3 09/18] tegra: Add LCD driver
  2012-07-12 15:25 [U-Boot] [PATCH v3 0/18] tegra: Add display driver and LCD support for Seaboard Simon Glass
                   ` (4 preceding siblings ...)
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 08/18] tegra: Add SOC support for display/lcd Simon Glass
@ 2012-07-12 15:25 ` Simon Glass
  2012-07-19  7:41   ` Thierry Reding
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 10/18] tegra: Add LCD support to Nvidia boards Simon Glass
                   ` (9 subsequent siblings)
  15 siblings, 1 reply; 81+ messages in thread
From: Simon Glass @ 2012-07-12 15:25 UTC (permalink / raw)
  To: u-boot

This driver supports driving a single LCD and providing a U-Boot console
on it.

Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v2:
- Update LCD driver to deal with new fdt bindings

Changes in v3:
- Adjust LCD driver to use new SOC display driver structures
- Move some fdt decode code from LCD driver to SOC display driver
- Rename fdt config structures
- Use new pwm binding from pre-linux-next

 drivers/video/Makefile |    1 +
 drivers/video/tegra.c  |  357 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 358 insertions(+), 0 deletions(-)
 create mode 100644 drivers/video/tegra.c

diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 44b7feb..3a92465 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -47,6 +47,7 @@ COBJS-$(CONFIG_VIDEO_OMAP3) += omap3_dss.o
 COBJS-$(CONFIG_VIDEO_SED13806) += sed13806.o
 COBJS-$(CONFIG_VIDEO_SM501) += sm501.o
 COBJS-$(CONFIG_VIDEO_SMI_LYNXEM) += smiLynxEM.o videomodes.o
+COBJS-$(CONFIG_VIDEO_TEGRA) += tegra.o
 COBJS-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o
 
 COBJS	:= $(sort $(COBJS-y))
diff --git a/drivers/video/tegra.c b/drivers/video/tegra.c
new file mode 100644
index 0000000..25ff64f
--- /dev/null
+++ b/drivers/video/tegra.c
@@ -0,0 +1,357 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <fdtdec.h>
+#include <lcd.h>
+
+#include <asm/system.h>
+#include <asm/gpio.h>
+
+#include <asm/arch/clock.h>
+#include <asm/arch/funcmux.h>
+#include <asm/arch/pinmux.h>
+#include <asm/arch/pwm.h>
+#include <asm/arch/display.h>
+#include <asm/arch/timer.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* These are the stages we go throuh in enabling the LCD */
+enum stage_t {
+	STAGE_START,
+	STAGE_LVDS,
+	STAGE_BACKLIGHT_VDD,
+	STAGE_PWM,
+	STAGE_BACKLIGHT_EN,
+	STAGE_DONE,
+};
+
+static enum stage_t stage;	/* Current stage we are at */
+static unsigned long timer_next; /* Time we can move onto next stage */
+
+/* Our LCD config, set up in handle_stage() */
+static struct fdt_panel_config config;
+struct fdt_disp_config *disp_config;	/* Display controller config */
+
+enum {
+	/* Maximum LCD size we support */
+	LCD_MAX_WIDTH		= 1366,
+	LCD_MAX_HEIGHT		= 768,
+	LCD_MAX_LOG2_BPP	= 4,		/* 2^4 = 16 bpp */
+};
+
+int lcd_line_length;
+int lcd_color_fg;
+int lcd_color_bg;
+
+void *lcd_base;			/* Start of framebuffer memory	*/
+void *lcd_console_address;	/* Start of console buffer	*/
+
+short console_col;
+short console_row;
+
+vidinfo_t panel_info = {
+	/* Insert a value here so that we don't end up in the BSS */
+	.vl_col = -1,
+};
+
+char lcd_cursor_enabled;
+
+ushort lcd_cursor_width;
+ushort lcd_cursor_height;
+
+#ifndef CONFIG_OF_CONTROL
+#error "You must enable CONFIG_OF_CONTROL to get Tegra LCD support"
+#endif
+
+void lcd_cursor_size(ushort width, ushort height)
+{
+	lcd_cursor_width = width;
+	lcd_cursor_height = height;
+}
+
+void lcd_toggle_cursor(void)
+{
+	ushort x, y;
+	uchar *dest;
+	ushort row;
+
+	x = console_col * lcd_cursor_width;
+	y = console_row * lcd_cursor_height;
+	dest = (uchar *)(lcd_base + y * lcd_line_length + x * (1 << LCD_BPP) /
+			8);
+
+	for (row = 0; row < lcd_cursor_height; ++row, dest += lcd_line_length) {
+		ushort *d = (ushort *)dest;
+		ushort color;
+		int i;
+
+		for (i = 0; i < lcd_cursor_width; ++i) {
+			color = *d;
+			color ^= lcd_color_fg;
+			*d = color;
+			++d;
+		}
+	}
+}
+
+void lcd_cursor_on(void)
+{
+	lcd_cursor_enabled = 1;
+	lcd_toggle_cursor();
+}
+void lcd_cursor_off(void)
+{
+	lcd_cursor_enabled = 0;
+	lcd_toggle_cursor();
+}
+
+char lcd_is_cursor_enabled(void)
+{
+	return lcd_cursor_enabled;
+}
+
+static void update_panel_size(struct fdt_disp_config *config)
+{
+	panel_info.vl_col = config->width;
+	panel_info.vl_row = config->height;
+	panel_info.vl_bpix = config->log2_bpp;
+}
+
+/*
+ *  Main init function called by lcd driver.
+ *  Inits and then prints test pattern if required.
+ */
+
+void lcd_ctrl_init(void *lcdbase)
+{
+	int line_length, size;
+
+	assert(disp_config);
+
+	lcd_base = (void *)disp_config->frame_buffer;
+
+	/* Make sure that we can acommodate the selected LCD */
+	assert(disp_config->width <= LCD_MAX_WIDTH);
+	assert(disp_config->height <= LCD_MAX_HEIGHT);
+	assert(disp_config->log2_bpp <= LCD_MAX_LOG2_BPP);
+	if (disp_config->width <= LCD_MAX_WIDTH
+			&& disp_config->height <= LCD_MAX_HEIGHT
+			&& disp_config->log2_bpp <= LCD_MAX_LOG2_BPP)
+		update_panel_size(disp_config);
+	size = lcd_get_size(&line_length);
+
+	debug("LCD frame buffer@%p\n", lcd_base);
+}
+
+ulong calc_fbsize(void)
+{
+	return (panel_info.vl_col * panel_info.vl_row *
+		NBITS(panel_info.vl_bpix)) / 8;
+}
+
+void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue)
+{
+}
+
+void tegra_lcd_early_init(const void *blob)
+{
+	/*
+	 * Go with the maximum size for now. We will fix this up after
+	 * relocation. These values are only used for memory alocation.
+	 */
+	panel_info.vl_col = LCD_MAX_WIDTH;
+	panel_info.vl_row = LCD_MAX_HEIGHT;
+	panel_info.vl_bpix = LCD_MAX_LOG2_BPP;
+}
+
+/**
+ * Decode the panel information from the fdt.
+ *
+ * @param blob		fdt blob
+ * @param config	structure to store fdt config into
+ * @return 0 if ok, -ve on error
+ */
+static int fdt_decode_lcd(const void *blob, struct fdt_panel_config *config)
+{
+	int err;
+	int display_node;
+
+	disp_config = tegra_display_get_config();
+	if (!disp_config) {
+		debug("%s: Display controller is not configured\n", __func__);
+		return -1;
+	}
+	display_node = disp_config->panel_node;
+	if (display_node < 0) {
+		debug("%s: No panel configuration available\n", __func__);
+		return -1;
+	}
+
+	config->pwm_channel = pwm_request(blob, display_node, "nvidia,pwm");
+	if (config->pwm_channel < 0) {
+		debug("%s: Unable to request PWM channel\n", __func__);
+		return -1;
+	}
+
+	config->cache_type = fdtdec_get_int(blob, display_node,
+					    "nvidia,cache-type",
+					    FDT_LCD_CACHE_WRITE_BACK_FLUSH);
+
+	err = fdtdec_decode_gpio(blob, display_node,
+				  "nvidia,backlight-enable-gpios",
+				  &config->backlight_en);
+	err |= fdtdec_decode_gpio(blob, display_node,
+			"nvidia,lvds-shutdown-gpios", &config->lvds_shutdown);
+	fdtdec_decode_gpio(blob, display_node, "nvidia,backlight-vdd-gpios",
+			   &config->backlight_vdd);
+	err |= fdtdec_decode_gpio(blob, display_node, "nvidia,panel-vdd-gpios",
+				  &config->panel_vdd);
+	if (err)
+		return -FDT_ERR_NOTFOUND;
+
+	return fdtdec_get_int_array(blob, display_node, "nvidia,panel-timings",
+			config->panel_timings, FDT_LCD_TIMINGS);
+}
+
+/**
+ * Handle the next stage of device init
+ */
+static int handle_stage(const void *blob)
+{
+	debug("%s: stage %d\n", __func__, stage);
+
+	/* do the things for this stage */
+	switch (stage) {
+	case STAGE_START:
+		/* Initialize the Tegra display controller */
+		if (tegra_display_probe(gd->fdt_blob, lcd_base)) {
+			printf("%s: Failed to probe display driver\n",
+			__func__);
+			return -1;
+		}
+
+		/* get panel details */
+		if (fdt_decode_lcd(blob, &config)) {
+			printf("No valid LCD information in device tree\n");
+			return -1;
+		}
+
+		/*
+		 * It is possible that the FDT has requested that the LCD be
+		 * disabled. We currently don't support this. It would require
+		 * changes to U-Boot LCD subsystem to have LCD support
+		 * compiled in but not used. An easier option might be to
+		 * still have a frame buffer, but leave the backlight off and
+		 * remove all mention of lcd in the stdout environment
+		 * variable.
+		 */
+
+		funcmux_select(PERIPH_ID_DISP1, FUNCMUX_DEFAULT);
+
+		fdtdec_setup_gpio(&config.panel_vdd);
+		fdtdec_setup_gpio(&config.lvds_shutdown);
+		fdtdec_setup_gpio(&config.backlight_vdd);
+		fdtdec_setup_gpio(&config.backlight_en);
+
+		/*
+		 * TODO: If fdt includes output flag we can omit this code
+		 * since fdtdec_setup_gpio will do it for us.
+		 */
+		gpio_direction_output(config.panel_vdd.gpio, 1);
+		gpio_direction_output(config.lvds_shutdown.gpio, 0);
+		gpio_direction_output(config.backlight_vdd.gpio, 0);
+		gpio_direction_output(config.backlight_en.gpio, 0);
+		break;
+	case STAGE_LVDS:
+		gpio_set_value(config.lvds_shutdown.gpio, 1);
+		break;
+	case STAGE_BACKLIGHT_VDD:
+		if (fdt_gpio_isvalid(&config.backlight_vdd))
+			gpio_set_value(config.backlight_vdd.gpio, 1);
+		break;
+	case STAGE_PWM:
+		/* Enable PWM at 15/16 high, 32768 Hz with divider 1 */
+		pinmux_set_func(PINGRP_GPU, PMUX_FUNC_PWM);
+		pinmux_tristate_disable(PINGRP_GPU);
+
+		pwm_enable(config.pwm_channel, 32768, 0xdf, 1);
+		break;
+	case STAGE_BACKLIGHT_EN:
+		gpio_set_value(config.backlight_en.gpio, 1);
+		break;
+	case STAGE_DONE:
+		break;
+	}
+
+	/* set up timer for next stage */
+	timer_next = timer_get_us() + config.panel_timings[stage] * 1000;
+
+	/* move to next stage */
+	stage++;
+	return 0;
+}
+
+int tegra_lcd_check_next_stage(const void *blob, int wait)
+{
+	if (stage == STAGE_DONE)
+		return 0;
+
+	do {
+		/* wait if we need to */
+		debug("%s: stage %d\n", __func__, stage);
+		if (stage != STAGE_START) {
+			int delay = timer_next - timer_get_us();
+
+			if (delay > 0) {
+				if (wait)
+					udelay(delay);
+				else
+					return 0;
+			}
+		}
+
+		if (handle_stage(blob))
+			return -1;
+	} while (wait && stage != STAGE_DONE);
+	debug("%s: LCD init complete\n", __func__);
+
+	return 0;
+}
+
+void lcd_enable(void)
+{
+	/*
+	 * Backlight and power init will be done separately in
+	 * tegra_lcd_check_next_stage(), which should be called in
+	 * board_late_init().
+	 *
+	 * U-Boot code supports only colour depth, selected at compile time.
+	 * The device tree setting should match this. Otherwise the display
+	 * will not look right, and U-Boot may crash.
+	 */
+	if (disp_config->log2_bpp != LCD_BPP) {
+		printf("%s: Error: LCD depth configured in FDT (%d = %dbpp)"
+			" must match setting of LCD_BPP (%d)\n", __func__,
+		       disp_config->log2_bpp, disp_config->bpp, LCD_BPP);
+	}
+}
-- 
1.7.7.3

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

* [U-Boot] [PATCH v3 10/18] tegra: Add LCD support to Nvidia boards
  2012-07-12 15:25 [U-Boot] [PATCH v3 0/18] tegra: Add display driver and LCD support for Seaboard Simon Glass
                   ` (5 preceding siblings ...)
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 09/18] tegra: Add LCD driver Simon Glass
@ 2012-07-12 15:25 ` Simon Glass
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 11/18] arm: Add control over cachability of memory regions Simon Glass
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 81+ messages in thread
From: Simon Glass @ 2012-07-12 15:25 UTC (permalink / raw)
  To: u-boot

Add calls to the LCD driver from Nvidia board code.

Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v3:
- Add separate call to pwm_init() in board_init()

 board/nvidia/common/board.c |   24 +++++++++++++++++++++++-
 1 files changed, 23 insertions(+), 1 deletions(-)

diff --git a/board/nvidia/common/board.c b/board/nvidia/common/board.c
index e65fc9e..ff08bd1 100644
--- a/board/nvidia/common/board.c
+++ b/board/nvidia/common/board.c
@@ -29,12 +29,14 @@
 #include <asm/arch/sys_proto.h>
 
 #include <asm/arch/board.h>
+#include <asm/arch/display.h>
 #include <asm/arch/clk_rst.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/emc.h>
 #include <asm/arch/pinmux.h>
 #include <asm/arch/pmc.h>
 #include <asm/arch/pmu.h>
+#include <asm/arch/pwm.h>
 #include <asm/arch/uart.h>
 #include <asm/arch/warmboot.h>
 #include <spi.h>
@@ -93,6 +95,9 @@ int board_init(void)
 {
 	__maybe_unused int err;
 
+#ifdef CONFIG_VIDEO_TEGRA2
+	tegra_lcd_check_next_stage(gd->blob, 0);
+#endif
 	/* Do clocks and UART first so that printf() works */
 	clock_init();
 	clock_verify();
@@ -129,6 +134,11 @@ int board_init(void)
 	pin_mux_usb();
 	board_usb_init(gd->fdt_blob);
 #endif
+#if defined(CONFIG_VIDEO_TEGRA)
+	if (pwm_init(gd->fdt_blob))
+		debug("%s: Failed to init pwm\n", __func__);
+	tegra_lcd_check_next_stage(gd->fdt_blob, 0);
+#endif
 
 #ifdef CONFIG_TEGRA2_LP0
 	/* prepare the WB code to LP0 location */
@@ -156,6 +166,18 @@ int board_early_init_f(void)
 #else
 	gpio_config_uart();
 #endif
-	return 0;
+#if defined(CONFIG_VIDEO_TEGRA)
+	tegra_lcd_early_init(gd->fdt_blob);
+#endif
+return 0;
 }
 #endif	/* EARLY_INIT */
+
+int board_late_init(void)
+{
+#ifdef CONFIG_VIDEO_TEGRA
+	/* Make sure we finish initing the LCD */
+	tegra_lcd_check_next_stage(gd->fdt_blob, 1);
+#endif
+	return 0;
+}
-- 
1.7.7.3

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

* [U-Boot] [PATCH v3 11/18] arm: Add control over cachability of memory regions
  2012-07-12 15:25 [U-Boot] [PATCH v3 0/18] tegra: Add display driver and LCD support for Seaboard Simon Glass
                   ` (6 preceding siblings ...)
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 10/18] tegra: Add LCD support to Nvidia boards Simon Glass
@ 2012-07-12 15:25 ` Simon Glass
  2012-07-12 18:12   ` Albert ARIBAUD
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 12/18] lcd: Add CONFIG_LCD_ALIGNMENT to select frame buffer alignment Simon Glass
                   ` (7 subsequent siblings)
  15 siblings, 1 reply; 81+ messages in thread
From: Simon Glass @ 2012-07-12 15:25 UTC (permalink / raw)
  To: u-boot

Add support for adjusting the cachability of an L1 section by updating
the MMU. The mmu_set_region_dcache() function allows drivers to make
these changes after the MMU is set up.

It is implemented only for ARMv7 at present.

This is needed for LCD support, where we want to make the LCD frame buffer
write-through (or off) rather than write-back.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 arch/arm/cpu/armv7/cache_v7.c |   11 +++++++
 arch/arm/include/asm/system.h |   30 ++++++++++++++++++++
 arch/arm/lib/cache-cp15.c     |   62 +++++++++++++++++++++++++++++++++-------
 3 files changed, 92 insertions(+), 11 deletions(-)

diff --git a/arch/arm/cpu/armv7/cache_v7.c b/arch/arm/cpu/armv7/cache_v7.c
index 1b4e808..5f6d039 100644
--- a/arch/arm/cpu/armv7/cache_v7.c
+++ b/arch/arm/cpu/armv7/cache_v7.c
@@ -297,6 +297,12 @@ void arm_init_before_mmu(void)
 	v7_inval_tlb();
 }
 
+void mmu_page_table_flush(unsigned long start, unsigned long stop)
+{
+	flush_dcache_range(start, stop);
+	v7_inval_tlb();
+}
+
 /*
  * Flush range from all levels of d-cache/unified-cache used:
  * Affects the range [start, start + size - 1]
@@ -329,6 +335,11 @@ void arm_init_before_mmu(void)
 void  flush_cache(unsigned long start, unsigned long size)
 {
 }
+
+void mmu_page_table_flush(unsigned long start, unsigned long stop)
+{
+}
+
 #endif /* #ifndef CONFIG_SYS_DCACHE_OFF */
 
 #ifndef CONFIG_SYS_ICACHE_OFF
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index 2b28a26..f52a4fc 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -75,6 +75,36 @@ static inline void set_cr(unsigned int val)
 	isb();
 }
 
+/* options available for data cache on each page */
+enum dcache_option {
+	DCACHE_OFF,
+	DCACHE_WRITETHROUGH,
+	DCACHE_WRITEBACK,
+};
+
+/* Size of an MMU section */
+enum {
+	MMU_SECTION_SHIFT	= 20,
+	MMU_SECTION_SIZE	= 1 << MMU_SECTION_SHIFT,
+};
+
+/**
+ * Change the cache settings for a region.
+ *
+ * \param start		start address of memory region to change
+ * \param size		size of memory region to change
+ * \param option	dcache option to select
+ */
+void mmu_set_region_dcache(u32 start, int size, enum dcache_option option);
+
+/**
+ * Register an update to the page tables, and flush the TLB
+ *
+ * \param start		start address of update in page table
+ * \param stop		stop address of update in page table
+ */
+void mmu_page_table_flush(unsigned long start, unsigned long stop);
+
 #endif /* __ASSEMBLY__ */
 
 #define arch_align_stack(x) (x)
diff --git a/arch/arm/lib/cache-cp15.c b/arch/arm/lib/cache-cp15.c
index 939de10..52a1fc6 100644
--- a/arch/arm/lib/cache-cp15.c
+++ b/arch/arm/lib/cache-cp15.c
@@ -26,12 +26,6 @@
 
 #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF))
 
-#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH)
-#define CACHE_SETUP	0x1a
-#else
-#define CACHE_SETUP	0x1e
-#endif
-
 DECLARE_GLOBAL_DATA_PTR;
 
 void __arm_init_before_mmu(void)
@@ -50,9 +44,52 @@ static void cp_delay (void)
 	asm volatile("" : : : "memory");
 }
 
-static inline void dram_bank_mmu_setup(int bank)
+void set_section_dcache(int section, enum dcache_option option)
 {
+	u32 value = section << MMU_SECTION_SHIFT | (3 << 10);
 	u32 *page_table = (u32 *)gd->tlb_addr;
+
+	switch (option) {
+	case DCACHE_WRITETHROUGH:
+		value |= 0x1a;
+		break;
+
+	case DCACHE_WRITEBACK:
+		value |= 0x1e;
+		break;
+
+	case DCACHE_OFF:
+		value |= 0x12;
+		break;
+	}
+
+	page_table[section] = value;
+}
+
+void __mmu_page_table_flush(unsigned long start, unsigned long stop)
+{
+	debug("%s: Warning: not implemented\n", __func__);
+}
+
+void mmu_page_table_flush(unsigned long start, unsigned long stop)
+	__attribute__((weak, alias("__mmu_page_table_flush")));
+
+void mmu_set_region_dcache(u32 start, int size, enum dcache_option option)
+{
+	u32 *page_table = (u32 *)gd->tlb_addr;
+	u32 upto, end;
+
+	end = ALIGN(start + size, MMU_SECTION_SIZE) >> MMU_SECTION_SHIFT;
+	start = start >> MMU_SECTION_SHIFT;
+	debug("mmu_set_region_dcache start=%x, size=%x, option=%d\n",
+	      start, size, option);
+	for (upto = start; upto < end; upto++)
+		set_section_dcache(upto, option);
+	mmu_page_table_flush((u32)&page_table[start], (u32)&page_table[end]);
+}
+
+static inline void dram_bank_mmu_setup(int bank)
+{
 	bd_t *bd = gd->bd;
 	int	i;
 
@@ -60,21 +97,24 @@ static inline void dram_bank_mmu_setup(int bank)
 	for (i = bd->bi_dram[bank].start >> 20;
 	     i < (bd->bi_dram[bank].start + bd->bi_dram[bank].size) >> 20;
 	     i++) {
-		page_table[i] = i << 20 | (3 << 10) | CACHE_SETUP;
+#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH)
+		set_section_dcache(i, DCACHE_WRITETHROUGH);
+#else
+		set_section_dcache(i, DCACHE_WRITEBACK);
+#endif
 	}
 }
 
 /* to activate the MMU we need to set up virtual memory: use 1M areas */
 static inline void mmu_setup(void)
 {
-	u32 *page_table = (u32 *)gd->tlb_addr;
 	int i;
 	u32 reg;
 
 	arm_init_before_mmu();
 	/* Set up an identity-mapping for all 4GB, rw for everyone */
 	for (i = 0; i < 4096; i++)
-		page_table[i] = i << 20 | (3 << 10) | 0x12;
+		set_section_dcache(i, DCACHE_OFF);
 
 	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
 		dram_bank_mmu_setup(i);
@@ -82,7 +122,7 @@ static inline void mmu_setup(void)
 
 	/* Copy the page table address to cp15 */
 	asm volatile("mcr p15, 0, %0, c2, c0, 0"
-		     : : "r" (page_table) : "memory");
+		     : : "r" (gd->tlb_addr) : "memory");
 	/* Set the access control to all-supervisor */
 	asm volatile("mcr p15, 0, %0, c3, c0, 0"
 		     : : "r" (~0));
-- 
1.7.7.3

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

* [U-Boot] [PATCH v3 12/18] lcd: Add CONFIG_LCD_ALIGNMENT to select frame buffer alignment
  2012-07-12 15:25 [U-Boot] [PATCH v3 0/18] tegra: Add display driver and LCD support for Seaboard Simon Glass
                   ` (7 preceding siblings ...)
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 11/18] arm: Add control over cachability of memory regions Simon Glass
@ 2012-07-12 15:25 ` Simon Glass
  2012-07-19 13:59   ` Mike Frysinger
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 13/18] lcd: Add support for flushing LCD fb from dcache after update Simon Glass
                   ` (6 subsequent siblings)
  15 siblings, 1 reply; 81+ messages in thread
From: Simon Glass @ 2012-07-12 15:25 UTC (permalink / raw)
  To: u-boot

The normal alignment is PAGE_SIZE, but if this is defined, we can support
other alignments.

The motivation for this change is to make the display section-aligned on
ARM so that we can easily turn off data caching for the frame buffer region
without resorting to level 2 page tables.

Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v2:
- Use a more generic config CONFIG_LCD_ALIGNMENT for lcd alignment

 README        |   10 ++++++++++
 common/lcd.c  |   24 +++++++++++++++++++-----
 include/lcd.h |    3 +++
 3 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/README b/README
index dac46f3..64ed389 100644
--- a/README
+++ b/README
@@ -1407,6 +1407,16 @@ The following options need to be configured:
 		Normally display is black on white background; define
 		CONFIG_SYS_WHITE_ON_BLACK to get it inverted.
 
+
+		CONFIG_LCD_ALIGNMENT
+
+		Normally the LCD is page-aligned (tyically 4KB). If this is
+		defined then the LCD will be aligned to this value instead.
+		For ARM it is sometimes useful to use MMU_SECTION_SIZE
+		here, since it is cheaper to change data cache settings on
+		a per-section basis.
+
+
 - Splash Screen Support: CONFIG_SPLASH_SCREEN
 
 		If this option is set, the environment is checked for
diff --git a/common/lcd.c b/common/lcd.c
index 85c6cf4..18525a7 100644
--- a/common/lcd.c
+++ b/common/lcd.c
@@ -35,6 +35,9 @@
 #include <stdarg.h>
 #include <linux/types.h>
 #include <stdio_dev.h>
+#ifdef CONFIG_ARM
+#include <asm/system.h>
+#endif
 #if defined(CONFIG_POST)
 #include <post.h>
 #endif
@@ -72,6 +75,10 @@
 # endif
 #endif
 
+#ifndef CONFIG_LCD_ALIGNMENT
+#define CONFIG_LCD_ALIGNMENT PAGE_SIZE
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 ulong lcd_setmem (ulong addr);
@@ -326,6 +333,12 @@ static void test_pattern (void)
 /* ** GENERIC Initialization Routines					*/
 /************************************************************************/
 
+int lcd_get_size(int *line_length)
+{
+	*line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8;
+	return *line_length * panel_info.vl_row;
+}
+
 int drv_lcd_init (void)
 {
 	struct stdio_dev lcddev;
@@ -333,7 +346,7 @@ int drv_lcd_init (void)
 
 	lcd_base = (void *)(gd->fb_base);
 
-	lcd_line_length = (panel_info.vl_col * NBITS (panel_info.vl_bpix)) / 8;
+	lcd_get_size(&lcd_line_length);
 
 	lcd_init (lcd_base);		/* LCD initialization */
 
@@ -445,15 +458,16 @@ static int lcd_init (void *lcdbase)
 ulong lcd_setmem (ulong addr)
 {
 	ulong size;
-	int line_length = (panel_info.vl_col * NBITS (panel_info.vl_bpix)) / 8;
+	int line_length;
 
 	debug ("LCD panel info: %d x %d, %d bit/pix\n",
 		panel_info.vl_col, panel_info.vl_row, NBITS (panel_info.vl_bpix) );
 
-	size = line_length * panel_info.vl_row;
+	size = lcd_get_size(&line_length);
 
-	/* Round up to nearest full page */
-	size = (size + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
+	/* Round up to nearest full page, or MMU section if defined */
+	size = ALIGN(size, CONFIG_LCD_ALIGNMENT);
+	addr = ALIGN(addr - CONFIG_LCD_ALIGNMENT + 1, CONFIG_LCD_ALIGNMENT);
 
 	/* Allocate pages for the frame buffer. */
 	addr -= size;
diff --git a/include/lcd.h b/include/lcd.h
index 6e0a2a3..26f6d83 100644
--- a/include/lcd.h
+++ b/include/lcd.h
@@ -296,6 +296,9 @@ int	lcd_display_bitmap(ulong bmp_image, int x, int y);
 /* Allow boards to customize the information displayed */
 void lcd_show_board_info(void);
 
+/* Return the size of the LCD frame buffer, and the line length */
+int lcd_get_size(int *line_length);
+
 /************************************************************************/
 /* ** BITMAP DISPLAY SUPPORT						*/
 /************************************************************************/
-- 
1.7.7.3

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

* [U-Boot] [PATCH v3 13/18] lcd: Add support for flushing LCD fb from dcache after update
  2012-07-12 15:25 [U-Boot] [PATCH v3 0/18] tegra: Add display driver and LCD support for Seaboard Simon Glass
                   ` (8 preceding siblings ...)
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 12/18] lcd: Add CONFIG_LCD_ALIGNMENT to select frame buffer alignment Simon Glass
@ 2012-07-12 15:25 ` Simon Glass
  2012-07-19 14:01   ` Mike Frysinger
                     ` (2 more replies)
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 14/18] tegra: Align LCD frame buffer to section boundary Simon Glass
                   ` (5 subsequent siblings)
  15 siblings, 3 replies; 81+ messages in thread
From: Simon Glass @ 2012-07-12 15:25 UTC (permalink / raw)
  To: u-boot

This provides an option for the LCD to flush the dcache after each update
(puts, scroll or clear).

Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v2:
- Put the LCD cache flush logic into lcd_putc() instead of lcd_puts()

Changes in v3:
- Put the LCD cache flush logic back into lcd_puts()

 common/lcd.c  |   46 +++++++++++++++++++++++++++++++++++++++-------
 include/lcd.h |    8 ++++++++
 2 files changed, 47 insertions(+), 7 deletions(-)

diff --git a/common/lcd.c b/common/lcd.c
index 18525a7..f7514a4 100644
--- a/common/lcd.c
+++ b/common/lcd.c
@@ -97,6 +97,9 @@ static void lcd_setbgcolor (int color);
 
 char lcd_is_enabled = 0;
 
+static char lcd_flush_dcache;	/* 1 to flush dcache after each lcd update */
+
+
 #ifdef	NOT_USED_SO_FAR
 static void lcd_getcolreg (ushort regno,
 				ushort *red, ushort *green, ushort *blue);
@@ -105,6 +108,28 @@ static int lcd_getfgcolor (void);
 
 /************************************************************************/
 
+/* Flush LCD activity to the caches */
+void lcd_sync(void)
+{
+	/*
+	 * flush_dcache_range() is declared in common.h but it seems that some
+	 * architectures do not actually implement it. Is there a way to find
+	 * out whether it exists? For now, ARM is safe.
+	 */
+#ifdef CONFIG_ARM
+	int line_length;
+
+	if (lcd_flush_dcache)
+		flush_dcache_range((u32)lcd_base,
+			(u32)(lcd_base + lcd_get_size(&line_length)));
+#endif
+}
+
+void lcd_set_flush_dcache(int flush)
+{
+	lcd_flush_dcache = (flush != 0);
+}
+
 /*----------------------------------------------------------------------*/
 
 static void console_scrollup (void)
@@ -114,6 +139,7 @@ static void console_scrollup (void)
 
 	/* Clear the last one */
 	memset (CONSOLE_ROW_LAST, COLOR_MASK(lcd_color_bg), CONSOLE_ROW_SIZE);
+	lcd_sync();
 }
 
 /*----------------------------------------------------------------------*/
@@ -144,6 +170,8 @@ static inline void console_newline (void)
 		/* Scroll everything up */
 		console_scrollup () ;
 		--console_row;
+	} else {
+		lcd_sync();
 	}
 }
 
@@ -198,6 +226,7 @@ void lcd_puts (const char *s)
 	while (*s) {
 		lcd_putc (*s++);
 	}
+	lcd_sync();
 }
 
 /*----------------------------------------------------------------------*/
@@ -365,13 +394,6 @@ int drv_lcd_init (void)
 }
 
 /*----------------------------------------------------------------------*/
-static
-int do_lcd_clear(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
-{
-	lcd_clear();
-	return 0;
-}
-
 void lcd_clear(void)
 {
 #if LCD_BPP == LCD_MONOCHROME
@@ -413,6 +435,14 @@ void lcd_clear(void)
 
 	console_col = 0;
 	console_row = 0;
+	lcd_sync();
+}
+
+static int do_lcd_clear(cmd_tbl_t *cmdtp, int flag, int argc,
+			char *const argv[])
+{
+	lcd_clear();
+	return 0;
 }
 
 U_BOOT_CMD(
@@ -607,6 +637,7 @@ void bitmap_plot (int x, int y)
 	}
 
 	WATCHDOG_RESET();
+	lcd_sync();
 }
 #else
 static inline void bitmap_plot(int x, int y) {}
@@ -820,6 +851,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
 		break;
 	};
 
+	lcd_sync();
 	return (0);
 }
 #endif
diff --git a/include/lcd.h b/include/lcd.h
index 26f6d83..4363131 100644
--- a/include/lcd.h
+++ b/include/lcd.h
@@ -57,6 +57,14 @@ extern void lcd_initcolregs (void);
 extern struct bmp_image *gunzip_bmp(unsigned long addr, unsigned long *lenp);
 extern int bmp_display(ulong addr, int x, int y);
 
+/**
+ * Set whether we need to flush the dcache when changing the LCD image. This
+ * defaults to off.
+ *
+ * @param flush		non-zero to flush cache after update, 0 to skip
+ */
+void lcd_set_flush_dcache(int flush);
+
 #if defined CONFIG_MPC823
 /*
  * LCD controller stucture for MPC823 CPU
-- 
1.7.7.3

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

* [U-Boot] [PATCH v3 14/18] tegra: Align LCD frame buffer to section boundary
  2012-07-12 15:25 [U-Boot] [PATCH v3 0/18] tegra: Add display driver and LCD support for Seaboard Simon Glass
                   ` (9 preceding siblings ...)
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 13/18] lcd: Add support for flushing LCD fb from dcache after update Simon Glass
@ 2012-07-12 15:25 ` Simon Glass
  2012-07-19 14:01   ` Mike Frysinger
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 15/18] tegra: Support control of cache settings for LCD Simon Glass
                   ` (4 subsequent siblings)
  15 siblings, 1 reply; 81+ messages in thread
From: Simon Glass @ 2012-07-12 15:25 UTC (permalink / raw)
  To: u-boot

For tegra we want to enable the cache for the LCD. This is easier if
we can avoid using L2 page tages, so align the LCD to a section
boundary.

Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v2:
- Align tegra display using new CONFIG_LCD_ALIGNMENT feature

 include/configs/tegra2-common.h |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/include/configs/tegra2-common.h b/include/configs/tegra2-common.h
index 6807762..83b7bd2 100644
--- a/include/configs/tegra2-common.h
+++ b/include/configs/tegra2-common.h
@@ -45,6 +45,9 @@
 
 #define CONFIG_ARCH_CPU_INIT		/* Fire up the A9 core */
 
+/* Align LCD to 1MB boundary */
+#define CONFIG_LCD_ALIGNMENT	MMU_SECTION_SIZE
+
 #include <asm/arch/tegra2.h>		/* get chip and board defs */
 
 /*
-- 
1.7.7.3

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

* [U-Boot] [PATCH v3 15/18] tegra: Support control of cache settings for LCD
  2012-07-12 15:25 [U-Boot] [PATCH v3 0/18] tegra: Add display driver and LCD support for Seaboard Simon Glass
                   ` (10 preceding siblings ...)
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 14/18] tegra: Align LCD frame buffer to section boundary Simon Glass
@ 2012-07-12 15:25 ` Simon Glass
       [not found] ` <1342106718-3058-1-git-send-email-sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 81+ messages in thread
From: Simon Glass @ 2012-07-12 15:25 UTC (permalink / raw)
  To: u-boot

Add support for selecting the required cache mode for the LCD:
off, write-through or write-back.

Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v3:
- Handle a cached frame buffer out of normal U-Boot memory

 drivers/video/tegra.c |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/drivers/video/tegra.c b/drivers/video/tegra.c
index 25ff64f..2f6655a 100644
--- a/drivers/video/tegra.c
+++ b/drivers/video/tegra.c
@@ -145,6 +145,7 @@ static void update_panel_size(struct fdt_disp_config *config)
 void lcd_ctrl_init(void *lcdbase)
 {
 	int line_length, size;
+	int type = DCACHE_OFF;
 
 	assert(disp_config);
 
@@ -160,6 +161,16 @@ void lcd_ctrl_init(void *lcdbase)
 		update_panel_size(disp_config);
 	size = lcd_get_size(&line_length);
 
+	/* Set up the LCD caching as requested */
+	if (config.cache_type & FDT_LCD_CACHE_WRITE_THROUGH)
+		type = DCACHE_WRITETHROUGH;
+	else if (config.cache_type & FDT_LCD_CACHE_WRITE_BACK)
+		type = DCACHE_WRITEBACK;
+	mmu_set_region_dcache(disp_config->frame_buffer, size, type);
+
+	/* Enable flushing after LCD writes if requested */
+	lcd_set_flush_dcache(config.cache_type & FDT_LCD_CACHE_FLUSH);
+
 	debug("LCD frame buffer at %p\n", lcd_base);
 }
 
-- 
1.7.7.3

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

* [PATCH v3 16/18] tegra: fdt: Add LCD definitions for Seaboard
  2012-07-12 15:25 [U-Boot] [PATCH v3 0/18] tegra: Add display driver and LCD support for Seaboard Simon Glass
@ 2012-07-12 15:25     ` Simon Glass
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 03/18] tegra: Use const for pinmux_config_pingroup/table() Simon Glass
                       ` (14 subsequent siblings)
  15 siblings, 0 replies; 81+ messages in thread
From: Simon Glass @ 2012-07-12 15:25 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Stephen Warren, Devicetree Discuss, Jerry Van Baren, Tom Warren

The Seaboard has a 1366x768 16bpp LCD. The backlight is controlled
by one of the PWMs.

Signed-off-by: Simon Glass <sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
---
Changes in v2:
- Update seaboard LCD definitions for new fdt binding

Changes in v3:
- Use new upstream proposed LCD definitions

 board/nvidia/dts/tegra2-seaboard.dts |   32 ++++++++++++++++++++++++++++++++
 1 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/board/nvidia/dts/tegra2-seaboard.dts b/board/nvidia/dts/tegra2-seaboard.dts
index 3352539..bfb835f 100644
--- a/board/nvidia/dts/tegra2-seaboard.dts
+++ b/board/nvidia/dts/tegra2-seaboard.dts
@@ -153,4 +153,36 @@
 			0x1f04008a>;
 		linux,fn-keymap = <0x05040002>;
 	};
+
+	host1x {
+		dc@54200000 {
+			rgb {
+				status = "okay";
+				/* Seaboard has 1366x768 */
+				clock = <70600000>;
+				xres = <1366>;
+				yres = <768>;
+				left-margin = <58>;
+				right-margin = <58>;
+				hsync-len = <58>;
+				lower-margin = <4>;
+				upper-margin = <4>;
+				vsync-len = <4>;
+				hsync-active-high;
+				nvidia,frame-buffer = <0x2f680000>;
+				nvidia,bits-per-pixel = <16>;
+				nvidia,panel = <&lcd_panel>;
+			};
+		};
+	};
+
+	lcd_panel: panel {
+		nvidia,pwm = <&pwm 2 0>;
+		nvidia,backlight-enable-gpios = <&gpio 28 0>;	/* PD4 */
+		nvidia,lvds-shutdown-gpios = <&gpio 10 0>;	/* PB2 */
+		nvidia,backlight-vdd-gpios = <&gpio 176 0>;	/* PW0 */
+		nvidia,panel-vdd-gpios = <&gpio 22 0>;		/* PC6 */
+		nvidia,panel-timings = <4 203 17 15>;
+	};
+
 };
-- 
1.7.7.3

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

* [U-Boot] [PATCH v3 16/18] tegra: fdt: Add LCD definitions for Seaboard
@ 2012-07-12 15:25     ` Simon Glass
  0 siblings, 0 replies; 81+ messages in thread
From: Simon Glass @ 2012-07-12 15:25 UTC (permalink / raw)
  To: u-boot

The Seaboard has a 1366x768 16bpp LCD. The backlight is controlled
by one of the PWMs.

Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v2:
- Update seaboard LCD definitions for new fdt binding

Changes in v3:
- Use new upstream proposed LCD definitions

 board/nvidia/dts/tegra2-seaboard.dts |   32 ++++++++++++++++++++++++++++++++
 1 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/board/nvidia/dts/tegra2-seaboard.dts b/board/nvidia/dts/tegra2-seaboard.dts
index 3352539..bfb835f 100644
--- a/board/nvidia/dts/tegra2-seaboard.dts
+++ b/board/nvidia/dts/tegra2-seaboard.dts
@@ -153,4 +153,36 @@
 			0x1f04008a>;
 		linux,fn-keymap = <0x05040002>;
 	};
+
+	host1x {
+		dc at 54200000 {
+			rgb {
+				status = "okay";
+				/* Seaboard has 1366x768 */
+				clock = <70600000>;
+				xres = <1366>;
+				yres = <768>;
+				left-margin = <58>;
+				right-margin = <58>;
+				hsync-len = <58>;
+				lower-margin = <4>;
+				upper-margin = <4>;
+				vsync-len = <4>;
+				hsync-active-high;
+				nvidia,frame-buffer = <0x2f680000>;
+				nvidia,bits-per-pixel = <16>;
+				nvidia,panel = <&lcd_panel>;
+			};
+		};
+	};
+
+	lcd_panel: panel {
+		nvidia,pwm = <&pwm 2 0>;
+		nvidia,backlight-enable-gpios = <&gpio 28 0>;	/* PD4 */
+		nvidia,lvds-shutdown-gpios = <&gpio 10 0>;	/* PB2 */
+		nvidia,backlight-vdd-gpios = <&gpio 176 0>;	/* PW0 */
+		nvidia,panel-vdd-gpios = <&gpio 22 0>;		/* PC6 */
+		nvidia,panel-timings = <4 203 17 15>;
+	};
+
 };
-- 
1.7.7.3

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

* [U-Boot] [PATCH v3 17/18] lcd: Add CONSOLE_SCROLL_LINES option to speed console
  2012-07-12 15:25 [U-Boot] [PATCH v3 0/18] tegra: Add display driver and LCD support for Seaboard Simon Glass
                   ` (12 preceding siblings ...)
       [not found] ` <1342106718-3058-1-git-send-email-sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
@ 2012-07-12 15:25 ` Simon Glass
  2012-07-19 14:04   ` Mike Frysinger
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 18/18] tegra: Enable display/lcd support on Seaboard Simon Glass
  2012-07-19  7:58 ` [U-Boot] [PATCH v3 0/18] tegra: Add display driver and LCD support for Seaboard Thierry Reding
  15 siblings, 1 reply; 81+ messages in thread
From: Simon Glass @ 2012-07-12 15:25 UTC (permalink / raw)
  To: u-boot

When the cursor position gets to the end of the LCD console we normally
scroll by one line. This adds an option to increase that value.

Console scrolling is often slow, and if a large amount of output is
being sent, increasing this option to 10 or so will speed things up
considerably.

Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v3:
- Fix tiny bug in mult-line lcd scrolling

 README       |    6 ++++++
 common/lcd.c |   16 +++++++++++++---
 2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/README b/README
index 64ed389..9048bb7 100644
--- a/README
+++ b/README
@@ -1416,6 +1416,12 @@ The following options need to be configured:
 		here, since it is cheaper to change data cache settings on
 		a per-section basis.
 
+		CONSOLE_SCROLL_LINES
+
+		When the console need to be scrolled, this is the number of
+		lines to scroll by. It defaults to 1. Increasing this makes
+		the console jump but can help speed up operation when scrolling
+		is slow.
 
 - Splash Screen Support: CONFIG_SPLASH_SCREEN
 
diff --git a/common/lcd.c b/common/lcd.c
index f7514a4..5742b94 100644
--- a/common/lcd.c
+++ b/common/lcd.c
@@ -134,12 +134,23 @@ void lcd_set_flush_dcache(int flush)
 
 static void console_scrollup (void)
 {
+	int rows = 1;
+
+#ifdef CONSOLE_SCROLL_LINES
+	rows = CONSOLE_SCROLL_LINES;
+#endif
 	/* Copy up rows ignoring the first one */
-	memcpy (CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND, CONSOLE_SCROLL_SIZE);
+	memcpy(CONSOLE_ROW_FIRST,
+	       lcd_console_address + CONSOLE_ROW_SIZE * rows,
+	       CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows);
 
 	/* Clear the last one */
-	memset (CONSOLE_ROW_LAST, COLOR_MASK(lcd_color_bg), CONSOLE_ROW_SIZE);
+	memset(lcd_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows,
+		COLOR_MASK(lcd_color_bg),
+	       CONSOLE_ROW_SIZE * rows);
+
 	lcd_sync();
+	console_row -= rows;
 }
 
 /*----------------------------------------------------------------------*/
@@ -169,7 +180,6 @@ static inline void console_newline (void)
 	if (console_row >= CONSOLE_ROWS) {
 		/* Scroll everything up */
 		console_scrollup () ;
-		--console_row;
 	} else {
 		lcd_sync();
 	}
-- 
1.7.7.3

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

* [U-Boot] [PATCH v3 18/18] tegra: Enable display/lcd support on Seaboard
  2012-07-12 15:25 [U-Boot] [PATCH v3 0/18] tegra: Add display driver and LCD support for Seaboard Simon Glass
                   ` (13 preceding siblings ...)
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 17/18] lcd: Add CONSOLE_SCROLL_LINES option to speed console Simon Glass
@ 2012-07-12 15:25 ` Simon Glass
  2012-07-19  7:58 ` [U-Boot] [PATCH v3 0/18] tegra: Add display driver and LCD support for Seaboard Thierry Reding
  15 siblings, 0 replies; 81+ messages in thread
From: Simon Glass @ 2012-07-12 15:25 UTC (permalink / raw)
  To: u-boot

From: Mayuresh Kulkarni <mkulkarni@nvidia.com>

Enable the Seaboard's 16-bit LCD and use it as the console.

Signed-off-by: Mayuresh Kulkarni <mkulkarni@nvidia.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
---

 include/configs/seaboard.h |   11 +++++++++--
 1 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/include/configs/seaboard.h b/include/configs/seaboard.h
index 2a71829..d4c22e0 100644
--- a/include/configs/seaboard.h
+++ b/include/configs/seaboard.h
@@ -105,8 +105,15 @@
 
 #undef TEGRA2_DEVICE_SETTINGS
 #define TEGRA2_DEVICE_SETTINGS	"stdin=serial,tegra-kbc\0" \
-					"stdout=serial\0" \
-					"stderr=serial\0"
+					"stdout=serial,lcd\0" \
+					"stderr=serial,lcd\0"
+
+/* LCD support */
+#define CONFIG_LCD
+#define CONFIG_VIDEO_TEGRA
+#define LCD_BPP				LCD_COLOR16
+#define CONFIG_SYS_WHITE_ON_BLACK
+#define CONSOLE_SCROLL_LINES		10
 
 #include "tegra2-common-post.h"
 
-- 
1.7.7.3

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

* [U-Boot] [PATCH v3 11/18] arm: Add control over cachability of memory regions
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 11/18] arm: Add control over cachability of memory regions Simon Glass
@ 2012-07-12 18:12   ` Albert ARIBAUD
  2012-07-19 14:10     ` Mike Frysinger
  0 siblings, 1 reply; 81+ messages in thread
From: Albert ARIBAUD @ 2012-07-12 18:12 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On Thu, 12 Jul 2012 08:25:11 -0700, Simon Glass <sjg@chromium.org> wrote:
> Add support for adjusting the cachability of an L1 section by updating
> the MMU. The mmu_set_region_dcache() function allows drivers to make
> these changes after the MMU is set up.
> 
> It is implemented only for ARMv7 at present.
> 
> This is needed for LCD support, where we want to make the LCD frame buffer
> write-through (or off) rather than write-back.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
> 
>  arch/arm/cpu/armv7/cache_v7.c |   11 +++++++
>  arch/arm/include/asm/system.h |   30 ++++++++++++++++++++
>  arch/arm/lib/cache-cp15.c     |   62 +++++++++++++++++++++++++++++++++-------
>  3 files changed, 92 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/arm/cpu/armv7/cache_v7.c b/arch/arm/cpu/armv7/cache_v7.c
> index 1b4e808..5f6d039 100644
> --- a/arch/arm/cpu/armv7/cache_v7.c
> +++ b/arch/arm/cpu/armv7/cache_v7.c
> @@ -297,6 +297,12 @@ void arm_init_before_mmu(void)
>  	v7_inval_tlb();
>  }
>  
> +void mmu_page_table_flush(unsigned long start, unsigned long stop)
> +{
> +	flush_dcache_range(start, stop);
> +	v7_inval_tlb();
> +}
> +
>  /*
>   * Flush range from all levels of d-cache/unified-cache used:
>   * Affects the range [start, start + size - 1]
> @@ -329,6 +335,11 @@ void arm_init_before_mmu(void)
>  void  flush_cache(unsigned long start, unsigned long size)
>  {
>  }
> +
> +void mmu_page_table_flush(unsigned long start, unsigned long stop)
> +{
> +}
> +
>  #endif /* #ifndef CONFIG_SYS_DCACHE_OFF */
>  
>  #ifndef CONFIG_SYS_ICACHE_OFF
> diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
> index 2b28a26..f52a4fc 100644
> --- a/arch/arm/include/asm/system.h
> +++ b/arch/arm/include/asm/system.h
> @@ -75,6 +75,36 @@ static inline void set_cr(unsigned int val)
>  	isb();
>  }
>  
> +/* options available for data cache on each page */
> +enum dcache_option {
> +	DCACHE_OFF,
> +	DCACHE_WRITETHROUGH,
> +	DCACHE_WRITEBACK,
> +};
> +
> +/* Size of an MMU section */
> +enum {
> +	MMU_SECTION_SHIFT	= 20,
> +	MMU_SECTION_SIZE	= 1 << MMU_SECTION_SHIFT,
> +};
> +
> +/**
> + * Change the cache settings for a region.
> + *
> + * \param start		start address of memory region to change
> + * \param size		size of memory region to change
> + * \param option	dcache option to select
> + */
> +void mmu_set_region_dcache(u32 start, int size, enum dcache_option option);
> +
> +/**
> + * Register an update to the page tables, and flush the TLB
> + *
> + * \param start		start address of update in page table
> + * \param stop		stop address of update in page table
> + */
> +void mmu_page_table_flush(unsigned long start, unsigned long stop);
> +
>  #endif /* __ASSEMBLY__ */
>  
>  #define arch_align_stack(x) (x)
> diff --git a/arch/arm/lib/cache-cp15.c b/arch/arm/lib/cache-cp15.c
> index 939de10..52a1fc6 100644
> --- a/arch/arm/lib/cache-cp15.c
> +++ b/arch/arm/lib/cache-cp15.c
> @@ -26,12 +26,6 @@
>  
>  #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF))
>  
> -#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH)
> -#define CACHE_SETUP	0x1a
> -#else
> -#define CACHE_SETUP	0x1e
> -#endif
> -
>  DECLARE_GLOBAL_DATA_PTR;
>  
>  void __arm_init_before_mmu(void)
> @@ -50,9 +44,52 @@ static void cp_delay (void)
>  	asm volatile("" : : : "memory");
>  }
>  
> -static inline void dram_bank_mmu_setup(int bank)
> +void set_section_dcache(int section, enum dcache_option option)
>  {
> +	u32 value = section << MMU_SECTION_SHIFT | (3 << 10);
>  	u32 *page_table = (u32 *)gd->tlb_addr;
> +
> +	switch (option) {
> +	case DCACHE_WRITETHROUGH:
> +		value |= 0x1a;
> +		break;
> +
> +	case DCACHE_WRITEBACK:
> +		value |= 0x1e;
> +		break;
> +
> +	case DCACHE_OFF:
> +		value |= 0x12;
> +		break;
> +	}

what's the benefit of introducing an arbitrary enum rather than
defining DCACHE_WRITETHROUGH, DCACHE_WRITEBACK and DCACHE_OFF equal
respecitvely to 0x1a, 0x1e and 0x12? All it does is force this
switch case instead of a simple 'value |= option;' statement.

> +	page_table[section] = value;
> +}
> +
> +void __mmu_page_table_flush(unsigned long start, unsigned long stop)
> +{
> +	debug("%s: Warning: not implemented\n", __func__);
> +}
> +
> +void mmu_page_table_flush(unsigned long start, unsigned long stop)
> +	__attribute__((weak, alias("__mmu_page_table_flush")));
> +
> +void mmu_set_region_dcache(u32 start, int size, enum dcache_option option)
> +{
> +	u32 *page_table = (u32 *)gd->tlb_addr;
> +	u32 upto, end;
> +
> +	end = ALIGN(start + size, MMU_SECTION_SIZE) >> MMU_SECTION_SHIFT;
> +	start = start >> MMU_SECTION_SHIFT;
> +	debug("mmu_set_region_dcache start=%x, size=%x, option=%d\n",
> +	      start, size, option);
> +	for (upto = start; upto < end; upto++)
> +		set_section_dcache(upto, option);
> +	mmu_page_table_flush((u32)&page_table[start], (u32)&page_table[end]);
> +}
> +
> +static inline void dram_bank_mmu_setup(int bank)
> +{
>  	bd_t *bd = gd->bd;
>  	int	i;
>  
> @@ -60,21 +97,24 @@ static inline void dram_bank_mmu_setup(int bank)
>  	for (i = bd->bi_dram[bank].start >> 20;
>  	     i < (bd->bi_dram[bank].start + bd->bi_dram[bank].size) >> 20;
>  	     i++) {
> -		page_table[i] = i << 20 | (3 << 10) | CACHE_SETUP;
> +#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH)
> +		set_section_dcache(i, DCACHE_WRITETHROUGH);
> +#else
> +		set_section_dcache(i, DCACHE_WRITEBACK);
> +#endif
>  	}
>  }
>  
>  /* to activate the MMU we need to set up virtual memory: use 1M areas */
>  static inline void mmu_setup(void)
>  {
> -	u32 *page_table = (u32 *)gd->tlb_addr;
>  	int i;
>  	u32 reg;
>  
>  	arm_init_before_mmu();
>  	/* Set up an identity-mapping for all 4GB, rw for everyone */
>  	for (i = 0; i < 4096; i++)
> -		page_table[i] = i << 20 | (3 << 10) | 0x12;
> +		set_section_dcache(i, DCACHE_OFF);
>  
>  	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
>  		dram_bank_mmu_setup(i);
> @@ -82,7 +122,7 @@ static inline void mmu_setup(void)
>  
>  	/* Copy the page table address to cp15 */
>  	asm volatile("mcr p15, 0, %0, c2, c0, 0"
> -		     : : "r" (page_table) : "memory");
> +		     : : "r" (gd->tlb_addr) : "memory");
>  	/* Set the access control to all-supervisor */
>  	asm volatile("mcr p15, 0, %0, c3, c0, 0"
>  		     : : "r" (~0));


Amicalement,
-- 
Albert.

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

* [U-Boot] [PATCH v3 08/18] tegra: Add SOC support for display/lcd
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 08/18] tegra: Add SOC support for display/lcd Simon Glass
@ 2012-07-19  7:37   ` Thierry Reding
  2012-07-19  8:24     ` Adam Jiang
  2012-07-19  8:03   ` Adam Jiang
  1 sibling, 1 reply; 81+ messages in thread
From: Thierry Reding @ 2012-07-19  7:37 UTC (permalink / raw)
  To: u-boot

On Thu, Jul 12, 2012 at 08:25:08AM -0700, Simon Glass wrote:
> From: Wei Ni <wni@nvidia.com>
> 
> Add support for the LCD peripheral at the Tegra2 SOC level. A separate
> LCD driver will use this functionality to configure the display.
> 
> Mayuresh Kulkarni:
> - changes to remove bitfields and clean up for submission
> 
> Simon Glass:
> - simplify code, move clock control into here, clean-up
> 
> Signed-off-by: Mayuresh Kulkarni <mkulkarni@nvidia.com>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
> Changes in v3:
> - Add probe function to read in fdt parameters in display driver
> - Separate display driver and LCD driver more in fdt
> 
>  arch/arm/cpu/armv7/tegra2/Makefile         |    2 +-
>  arch/arm/cpu/armv7/tegra2/display.c        |  389 ++++++++++++++++++++
>  arch/arm/include/asm/arch-tegra2/dc.h      |  544 ++++++++++++++++++++++++++++
>  arch/arm/include/asm/arch-tegra2/display.h |  152 ++++++++
>  include/fdtdec.h                           |    1 +
>  lib/fdtdec.c                               |    1 +
>  6 files changed, 1088 insertions(+), 1 deletions(-)
>  create mode 100644 arch/arm/cpu/armv7/tegra2/display.c
>  create mode 100644 arch/arm/include/asm/arch-tegra2/dc.h
>  create mode 100644 arch/arm/include/asm/arch-tegra2/display.h
> 
[...]
> diff --git a/arch/arm/cpu/armv7/tegra2/display.c b/arch/arm/cpu/armv7/tegra2/display.c
[...]
> +int setup_window(struct disp_ctl_win *win, struct fdt_disp_config *config)
> +{
> +	win->x = 0;
> +	win->y = 0;
> +	win->w = config->width;
> +	win->h = config->height;
> +	win->out_x = 0;
> +	win->out_y = 0;
> +	win->out_w = config->width;
> +	win->out_h = config->height;
> +	win->phys_addr = config->frame_buffer;
> +	win->stride = config->width * (1 << config->log2_bpp) / 8;
> +	debug("%s: depth = %d\n", __func__, config->log2_bpp);
> +	switch (config->log2_bpp) {
> +	case 5:
> +	case 24:

What's the 24 doing here?

[...]
> +static int tegra_display_decode_config(const void *blob,
> +				       struct fdt_disp_config *config)
> +{
> +	int front, back, ref;
> +	int node, rgb;
> +	int bpp, bit;
> +
> +	node = fdtdec_next_compatible(blob, 0, COMPAT_NVIDIA_TEGRA20_DC);
> +	if (node < 0) {
> +		debug("%s: Cannot find display controller node in fdt\n",
> +		      __func__);
> +		return node;
> +	}
> +	config->disp = (struct disp_ctlr *)fdtdec_get_addr(blob, node, "reg");
> +	if (!config->disp) {
> +		debug("%s: No display controller address\n", __func__);
> +		return -1;
> +	}
> +
> +	rgb = fdt_subnode_offset(blob, node, "rgb");
> +
> +	config->frame_buffer = fdtdec_get_addr(blob, rgb,
> +					       "nvidia,frame-buffer");
> +	config->width = fdtdec_get_int(blob, rgb, "xres", -1);
> +	config->height = fdtdec_get_int(blob, rgb, "yres", -1);
> +	bpp = fdtdec_get_int(blob, rgb, "nvidia,bits-per-pixel", -1);
> +	bit = ffs(bpp) - 1;
> +	if (bpp == (1 << bit))
> +		config->log2_bpp = bit;
> +	else
> +		config->log2_bpp = bpp;
> +	config->bpp = bpp;
> +	config->pixel_clock = fdtdec_get_int(blob, rgb, "clock", 0);
> +	if (!config->pixel_clock || bpp == -1 ||
> +			config->width == -1 || config->height == -1) {
> +		debug("%s: Pixel parameters missing\n", __func__);
> +		return -FDT_ERR_NOTFOUND;
> +	}
> +
> +	/* Use a ref-to-sync of 1 always, and take this from the front porch */
> +	back = fdtdec_get_int(blob, rgb, "left-margin", -1);
> +	front = fdtdec_get_int(blob, rgb, "right-margin", -1);
> +	ref = fdtdec_get_int(blob, rgb, "hsync-len", -1);
> +	if ((back | front | ref) == -1) {
> +		debug("%s: Horizontal parameters missing\n", __func__);
> +		return -FDT_ERR_NOTFOUND;
> +	}
> +	config->horiz_timing[FDT_LCD_TIMING_REF_TO_SYNC] = 11;

The comment above says this should be 1.

> +	config->horiz_timing[FDT_LCD_TIMING_SYNC_WIDTH] = ref;
> +	config->horiz_timing[FDT_LCD_TIMING_BACK_PORCH] = back;
> +	config->horiz_timing[FDT_LCD_TIMING_FRONT_PORCH] = front -
> +		config->horiz_timing[FDT_LCD_TIMING_REF_TO_SYNC];
> +	debug_timing("horiz", config->horiz_timing);
> +
> +	back = fdtdec_get_int(blob, rgb, "upper-margin", -1);
> +	front = fdtdec_get_int(blob, rgb, "lower-margin", -1);
> +	ref = fdtdec_get_int(blob, rgb, "vsync-len", -1);
> +	if ((back | front | ref) == -1) {
> +		debug("%s: Vertical parameters missing\n", __func__);
> +		return -FDT_ERR_NOTFOUND;
> +	}
> +	config->vert_timing[FDT_LCD_TIMING_REF_TO_SYNC] = 1;
> +	config->vert_timing[FDT_LCD_TIMING_SYNC_WIDTH] = ref;
> +	config->vert_timing[FDT_LCD_TIMING_BACK_PORCH] = back;
> +	config->vert_timing[FDT_LCD_TIMING_FRONT_PORCH] = front -
> +		config->vert_timing[FDT_LCD_TIMING_REF_TO_SYNC];
> +	debug_timing("vert", config->horiz_timing);

This should probably be config->vert_timing.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20120719/4e7a7949/attachment.pgp>

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

* [U-Boot] [PATCH v3 09/18] tegra: Add LCD driver
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 09/18] tegra: Add LCD driver Simon Glass
@ 2012-07-19  7:41   ` Thierry Reding
  2012-09-27 17:28     ` Simon Glass
  0 siblings, 1 reply; 81+ messages in thread
From: Thierry Reding @ 2012-07-19  7:41 UTC (permalink / raw)
  To: u-boot

On Thu, Jul 12, 2012 at 08:25:09AM -0700, Simon Glass wrote:
> This driver supports driving a single LCD and providing a U-Boot console
> on it.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
> Changes in v2:
> - Update LCD driver to deal with new fdt bindings
> 
> Changes in v3:
> - Adjust LCD driver to use new SOC display driver structures
> - Move some fdt decode code from LCD driver to SOC display driver
> - Rename fdt config structures
> - Use new pwm binding from pre-linux-next
> 
>  drivers/video/Makefile |    1 +
>  drivers/video/tegra.c  |  357 ++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 358 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/video/tegra.c
> 
[...]
> diff --git a/drivers/video/tegra.c b/drivers/video/tegra.c
[...]
> +static int fdt_decode_lcd(const void *blob, struct fdt_panel_config *config)
> +{
> +	int err;
> +	int display_node;
> +
> +	disp_config = tegra_display_get_config();
> +	if (!disp_config) {
> +		debug("%s: Display controller is not configured\n", __func__);
> +		return -1;
> +	}
> +	display_node = disp_config->panel_node;
> +	if (display_node < 0) {
> +		debug("%s: No panel configuration available\n", __func__);
> +		return -1;
> +	}
> +
> +	config->pwm_channel = pwm_request(blob, display_node, "nvidia,pwm");
> +	if (config->pwm_channel < 0) {
> +		debug("%s: Unable to request PWM channel\n", __func__);
> +		return -1;
> +	}
> +
> +	config->cache_type = fdtdec_get_int(blob, display_node,
> +					    "nvidia,cache-type",
> +					    FDT_LCD_CACHE_WRITE_BACK_FLUSH);
> +
> +	err = fdtdec_decode_gpio(blob, display_node,
> +				  "nvidia,backlight-enable-gpios",
> +				  &config->backlight_en);
> +	err |= fdtdec_decode_gpio(blob, display_node,
> +			"nvidia,lvds-shutdown-gpios", &config->lvds_shutdown);
> +	fdtdec_decode_gpio(blob, display_node, "nvidia,backlight-vdd-gpios",
> +			   &config->backlight_vdd);
> +	err |= fdtdec_decode_gpio(blob, display_node, "nvidia,panel-vdd-gpios",
> +				  &config->panel_vdd);
> +	if (err)
> +		return -FDT_ERR_NOTFOUND;

This effectively makes those GPIOs mandatory. The Medcom, however,
doesn't have any of these, so I had to comment this return out to test
the series. I know that this might be an unusual setup, but it's
something that needs to be supported anyway.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20120719/59692bf3/attachment.pgp>

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

* [U-Boot] [PATCH v3 0/18] tegra: Add display driver and LCD support for Seaboard
  2012-07-12 15:25 [U-Boot] [PATCH v3 0/18] tegra: Add display driver and LCD support for Seaboard Simon Glass
                   ` (14 preceding siblings ...)
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 18/18] tegra: Enable display/lcd support on Seaboard Simon Glass
@ 2012-07-19  7:58 ` Thierry Reding
  2012-07-31  9:28   ` Simon Glass
  15 siblings, 1 reply; 81+ messages in thread
From: Thierry Reding @ 2012-07-19  7:58 UTC (permalink / raw)
  To: u-boot

On Thu, Jul 12, 2012 at 08:25:00AM -0700, Simon Glass wrote:
> This series adds support for the Tegra2x's display peripheral. This
> supports the LCD display on Seaboard and we use this to enable console
> output in U-Boot on the LCD.
> 
> Configuration is via the device tree. Proposed bindings are included
> in this series, taken from pwm bindings that should be in linux-next,
> a Tegra video binding that might be accepted in devicetree-discuss
> and a proposed video mode binding posted to dri-devel.
> 
> While I agree EDID is convenient for machines I would prefer to provide
> a user-friendly way of selecting LCD settings as well, with EDID more
> as a fallback and auto-detection when available.
> 
> To improve performance two optimisations are offered:
> 
> 1. The LCD frame buffer is cached, with the cache being flushed after
> each newline sent to putc(), and in a few other situations. This
> dramatically increases performance (around 10x). This requires a few
> additions to the ARM cache support.
> 
> 2. The console supports scrolling in steps of more than 1 line. This
> speeds up scrolling output considerably, particularly commands like
> 'printenv' which display a lot of output, and particular when the
> dcache is off. This requires a new CONFIG and a change to the
> console_scrollup() function.
> 
> Changes in v2:
> - Add new patch to use const in pinmux_config_pingroup/table()
> - Add nvidia prefix to device tree properties
> - Align tegra display using new CONFIG_LCD_ALIGNMENT feature
> - Put the LCD cache flush logic into lcd_putc() instead of lcd_puts()
> - Update LCD driver to deal with new fdt bindings
> - Update seaboard LCD definitions for new fdt binding
> - Use a more generic config CONFIG_LCD_ALIGNMENT for lcd alignment
> - Use const where possible in funcmux
> 
> Changes in v3:
> - Add new commit for pwm binding and node
> - Add new panel binding to fit with tegra display controller binding
> - Add probe function to read in fdt parameters in display driver
> - Add separate call to pwm_init() in board_init()
> - Adjust LCD driver to use new SOC display driver structures
> - Bring in proposed tegra display controller binding
> - Decode fdt node within the pwm driver
> - Fix tiny bug in mult-line lcd scrolling
> - Handle a cached frame buffer out of normal U-Boot memory
> - Introduce concept of a pwm channel, rather than separate peripherals
> - Move some fdt decode code from LCD driver to SOC display driver
> - Put the LCD cache flush logic back into lcd_puts()
> - Remove LPW1 pin which is not needed by display
> - Remove spurious newline from fdtdec_get_addr() debug output
> - Rename fdt config structures
> - Rename pwfm driver to pwm
> - Separate display driver and LCD driver more in fdt
> - Tidy up fdtdec_decode_gpios() debug output
> - Use displaymode binding for fdt
> - Use new proposed upstream pwm binding
> - Use new pwm binding from pre-linux-next
> - Use new upstream proposed LCD definitions
> 
> Mayuresh Kulkarni (1):
>   tegra: Enable display/lcd support on Seaboard
> 
> Simon Glass (16):
>   fdt: Tidy debugging, add to fdtdec_get_int/addr()
>   fdt: Add header guard to fdtdec.h
>   tegra: Use const for pinmux_config_pingroup/table()
>   tegra: Add display support to funcmux
>   tegra: fdt: Add pwm binding and node
>   tegra: fdt: Add LCD definitions for Tegra
>   tegra: Add support for PWM
>   tegra: Add LCD driver
>   tegra: Add LCD support to Nvidia boards
>   arm: Add control over cachability of memory regions
>   lcd: Add CONFIG_LCD_ALIGNMENT to select frame buffer alignment
>   lcd: Add support for flushing LCD fb from dcache after update
>   tegra: Align LCD frame buffer to section boundary
>   tegra: Support control of cache settings for LCD
>   tegra: fdt: Add LCD definitions for Seaboard
>   lcd: Add CONSOLE_SCROLL_LINES option to speed console
> 
> Wei Ni (1):
>   tegra: Add SOC support for display/lcd

I was able to make this work on the Medcom with the one workaround to
make backlight and panel GPIOs optional and adding the corresponding DTS
and configuration entries for Medcom, so:

Tested-by: Thierry Reding <thierry.reding@avionic-design.de>

The display corruption does no longer seem to happen. While I haven't
thoroughly reviewed, I think this is in pretty good shape. Thanks Simon.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20120719/ffc24a8c/attachment.pgp>

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

* [U-Boot] [PATCH v3 08/18] tegra: Add SOC support for display/lcd
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 08/18] tegra: Add SOC support for display/lcd Simon Glass
  2012-07-19  7:37   ` Thierry Reding
@ 2012-07-19  8:03   ` Adam Jiang
  2012-07-19 14:13     ` Mike Frysinger
  2012-09-27 17:44     ` Simon Glass
  1 sibling, 2 replies; 81+ messages in thread
From: Adam Jiang @ 2012-07-19  8:03 UTC (permalink / raw)
  To: u-boot

On Thu, Jul 12, 2012 at 11:25:08PM +0800, Simon Glass wrote:
> From: Wei Ni <wni@nvidia.com>
> 
> Add support for the LCD peripheral at the Tegra2 SOC level. A separate
> LCD driver will use this functionality to configure the display.
> 
> Mayuresh Kulkarni:
> - changes to remove bitfields and clean up for submission
> 
> Simon Glass:
> - simplify code, move clock control into here, clean-up
> 
> Signed-off-by: Mayuresh Kulkarni <mkulkarni@nvidia.com>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
> Changes in v3:
> - Add probe function to read in fdt parameters in display driver
> - Separate display driver and LCD driver more in fdt
> 
>  arch/arm/cpu/armv7/tegra2/Makefile         |    2 +-
>  arch/arm/cpu/armv7/tegra2/display.c        |  389 ++++++++++++++++++++
>  arch/arm/include/asm/arch-tegra2/dc.h      |  544 ++++++++++++++++++++++++++++
>  arch/arm/include/asm/arch-tegra2/display.h |  152 ++++++++
>  include/fdtdec.h                           |    1 +
>  lib/fdtdec.c                               |    1 +
>  6 files changed, 1088 insertions(+), 1 deletions(-)
>  create mode 100644 arch/arm/cpu/armv7/tegra2/display.c
>  create mode 100644 arch/arm/include/asm/arch-tegra2/dc.h
>  create mode 100644 arch/arm/include/asm/arch-tegra2/display.h
> 
> diff --git a/arch/arm/cpu/armv7/tegra2/Makefile b/arch/arm/cpu/armv7/tegra2/Makefile
> index 5d271c4..79e1319 100644
> --- a/arch/arm/cpu/armv7/tegra2/Makefile
> +++ b/arch/arm/cpu/armv7/tegra2/Makefile
> @@ -40,7 +40,7 @@ COBJS-$(CONFIG_TEGRA_PMU) += pmu.o
>  COBJS-$(CONFIG_USB_EHCI_TEGRA) += usb.o
>  COBJS-$(CONFIG_TEGRA2_LP0) += crypto.o warmboot.o warmboot_avp.o
>  COBJS-$(CONFIG_CMD_ENTERRCM) += cmd_enterrcm.o
> -COBJS-$(CONFIG_VIDEO_TEGRA) += pwm.o
> +COBJS-$(CONFIG_VIDEO_TEGRA) += display.o pwm.o
> 
>  COBJS  := $(COBJS-y)
>  SRCS   := $(SOBJS:.o=.S) $(COBJS:.o=.c)
> diff --git a/arch/arm/cpu/armv7/tegra2/display.c b/arch/arm/cpu/armv7/tegra2/display.c
> new file mode 100644
> index 0000000..267e89e
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/tegra2/display.c
> @@ -0,0 +1,389 @@
> +/*
> + *  (C) Copyright 2010
> + *  NVIDIA Corporation <www.nvidia.com>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include <common.h>
> +#include <asm/io.h>
> +#include <asm/arch/clk_rst.h>
> +#include <asm/arch/clock.h>
> +#include <asm/arch/timer.h>
> +#include <asm/arch/tegra2.h>
> +#include <asm/arch/display.h>
> +#include <asm/arch/dc.h>
> +
> +static struct fdt_disp_config config;
> +
> +static void update_window(struct dc_ctlr *dc, struct disp_ctl_win *win)
> +{
> +       unsigned h_dda, v_dda;
> +       unsigned long val;
> +
> +       val = readl(&dc->cmd.disp_win_header);
> +       val |= WINDOW_A_SELECT;
> +       writel(val, &dc->cmd.disp_win_header);
> +
> +       writel(win->fmt, &dc->win.color_depth);
> +
> +       val = readl(&dc->win.byte_swap);
> +       val |= BYTE_SWAP_NOSWAP << BYTE_SWAP_SHIFT;
> +       writel(val, &dc->win.byte_swap);
> +
> +       val = win->out_x << H_POSITION_SHIFT;
> +       val |= win->out_y << V_POSITION_SHIFT;
> +       writel(val, &dc->win.pos);
> +
> +       val = win->out_w << H_SIZE_SHIFT;
> +       val |= win->out_h << V_SIZE_SHIFT;
> +       writel(val, &dc->win.size);
> +
> +       val = (win->w * win->bpp / 8) << H_PRESCALED_SIZE_SHIFT;
> +       val |= win->h << V_PRESCALED_SIZE_SHIFT;
> +       writel(val, &dc->win.prescaled_size);
> +
> +       writel(0, &dc->win.h_initial_dda);
> +       writel(0, &dc->win.v_initial_dda);
> +
> +       h_dda = (win->w * 0x1000) / max(win->out_w - 1, 1);
> +       v_dda = (win->h * 0x1000) / max(win->out_h - 1, 1);
> +
> +       val = h_dda << H_DDA_INC_SHIFT;
> +       val |= v_dda << V_DDA_INC_SHIFT;
> +       writel(val, &dc->win.dda_increment);
> +
> +       writel(win->stride, &dc->win.line_stride);
> +       writel(0, &dc->win.buf_stride);
> +
> +       val = WIN_ENABLE;
> +       if (win->bpp < 24)
> +               val |= COLOR_EXPAND;
> +       writel(val, &dc->win.win_opt);
> +
> +       writel((unsigned long)win->phys_addr, &dc->winbuf.start_addr);
> +       writel(win->x, &dc->winbuf.addr_h_offset);
> +       writel(win->y, &dc->winbuf.addr_v_offset);
> +
> +       writel(0xff00, &dc->win.blend_nokey);
> +       writel(0xff00, &dc->win.blend_1win);
> +
> +       val = GENERAL_ACT_REQ | WIN_A_ACT_REQ;
> +       val |= GENERAL_UPDATE | WIN_A_UPDATE;
> +       writel(val, &dc->cmd.state_ctrl);
> +}
> +
> +static void write_pair(struct fdt_disp_config *config, int item, u32 *reg)
> +{
> +       writel(config->horiz_timing[item] |
> +                       (config->vert_timing[item] << 16), reg);
> +}
> +
> +static int update_display_mode(struct dc_disp_reg *disp,
> +               struct fdt_disp_config *config)
> +{
> +       unsigned long val;
> +       unsigned long rate;
> +       unsigned long div;
> +
> +       writel(0x0, &disp->disp_timing_opt);
> +       write_pair(config, FDT_LCD_TIMING_REF_TO_SYNC, &disp->ref_to_sync);
> +       write_pair(config, FDT_LCD_TIMING_SYNC_WIDTH, &disp->sync_width);
> +       write_pair(config, FDT_LCD_TIMING_BACK_PORCH, &disp->back_porch);
> +       write_pair(config, FDT_LCD_TIMING_FRONT_PORCH, &disp->front_porch);
> +
> +       writel(config->width | (config->height << 16), &disp->disp_active);
> +
> +       val = DE_SELECT_ACTIVE << DE_SELECT_SHIFT;
> +       val |= DE_CONTROL_NORMAL << DE_CONTROL_SHIFT;
> +       writel(val, &disp->data_enable_opt);
> +
> +       val = DATA_FORMAT_DF1P1C << DATA_FORMAT_SHIFT;
> +       val |= DATA_ALIGNMENT_MSB << DATA_ALIGNMENT_SHIFT;
> +       val |= DATA_ORDER_RED_BLUE << DATA_ORDER_SHIFT;
> +       writel(val, &disp->disp_interface_ctrl);
> +
> +       /*
> +        * The pixel clock divider is in 7.1 format (where the bottom bit
> +        * represents 0.5). Here we calculate the divider needed to get from
> +        * the display clock (typically 600MHz) to the pixel clock. We round
> +        * up or down as requried.
> +        */
> +       rate = clock_get_periph_rate(PERIPH_ID_DISP1, CLOCK_ID_CGENERAL);
> +       div = ((rate * 2 + config->pixel_clock / 2) / config->pixel_clock) - 2;
> +       debug("Display clock %lu, divider %lu\n", rate, div);
> +
> +       writel(0x00010001, &disp->shift_clk_opt);
> +
> +       val = PIXEL_CLK_DIVIDER_PCD1 << PIXEL_CLK_DIVIDER_SHIFT;
> +       val |= div << SHIFT_CLK_DIVIDER_SHIFT;
> +       writel(val, &disp->disp_clk_ctrl);
> +
> +       return 0;
> +}
> +
> +/* Start up the display and turn on power to PWMs */
> +static void basic_init(struct dc_cmd_reg *cmd)
> +{
> +       u32 val;
> +
> +       writel(0x00000100, &cmd->gen_incr_syncpt_ctrl);
> +       writel(0x0000011a, &cmd->cont_syncpt_vsync);
> +       writel(0x00000000, &cmd->int_type);
> +       writel(0x00000000, &cmd->int_polarity);
> +       writel(0x00000000, &cmd->int_mask);
> +       writel(0x00000000, &cmd->int_enb);
> +
> +       val = PW0_ENABLE | PW1_ENABLE | PW2_ENABLE;
> +       val |= PW3_ENABLE | PW4_ENABLE | PM0_ENABLE;
> +       val |= PM1_ENABLE;
> +       writel(val, &cmd->disp_pow_ctrl);
> +
> +       val = readl(&cmd->disp_cmd);
> +       val |= CTRL_MODE_C_DISPLAY << CTRL_MODE_SHIFT;
> +       writel(val, &cmd->disp_cmd);
> +}
> +
> +static void basic_init_timer(struct dc_disp_reg *disp)
> +{
> +       writel(0x00000020, &disp->mem_high_pri);
> +       writel(0x00000001, &disp->mem_high_pri_timer);
> +}
> +
> +static const u32 rgb_enb_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 void rgb_enable(struct dc_com_reg *com)
> +{
> +       int i;
> +
> +       for (i = 0; i < PIN_REG_COUNT; i++) {
> +               writel(rgb_enb_tab[i], &com->pin_output_enb[i]);
> +               writel(rgb_polarity_tab[i], &com->pin_output_polarity[i]);
> +               writel(rgb_data_tab[i], &com->pin_output_data[i]);
> +       }
> +
> +       for (i = 0; i < PIN_OUTPUT_SEL_COUNT; i++)
> +               writel(rgb_sel_tab[i], &com->pin_output_sel[i]);
> +}
> +
> +int setup_window(struct disp_ctl_win *win, struct fdt_disp_config *config)
> +{
> +       win->x = 0;
> +       win->y = 0;
> +       win->w = config->width;
> +       win->h = config->height;
> +       win->out_x = 0;
> +       win->out_y = 0;
> +       win->out_w = config->width;
> +       win->out_h = config->height;
> +       win->phys_addr = config->frame_buffer;
> +       win->stride = config->width * (1 << config->log2_bpp) / 8;
> +       debug("%s: depth = %d\n", __func__, config->log2_bpp);
> +       switch (config->log2_bpp) {
> +       case 5:
> +       case 24:
> +               win->fmt = COLOR_DEPTH_R8G8B8A8;
> +               win->bpp = 32;
> +               break;
> +       case 4:
> +               win->fmt = COLOR_DEPTH_B5G6R5;
> +               win->bpp = 16;
> +               break;
> +
> +       default:
> +               debug("Unsupported LCD bit depth");
> +               return -1;
> +       }
> +
> +       return 0;
> +}
> +
> +struct fdt_disp_config *tegra_display_get_config(void)
> +{
> +       return config.valid ? &config : NULL;
> +}
> +
> +static void debug_timing(const char *name, unsigned int timing[])
> +{
> +#ifdef DEBUG
> +       int i;
> +
> +       debug("%s timing: ", name);
> +       for (i = 0; i < FDT_LCD_TIMING_COUNT; i++)
> +               debug("%d ", timing[i]);
> +       debug("\n");
> +#endif
> +}
> +
> +/**
> + * Decode the display controller information from the fdt.
> + *
> + * @param blob         fdt blob
> + * @param config       structure to store fdt config into
> + * @return 0 if ok, -ve on error
> + */
> +static int tegra_display_decode_config(const void *blob,
> +                                      struct fdt_disp_config *config)
> +{
> +       int front, back, ref;
> +       int node, rgb;
> +       int bpp, bit;
> +
> +       node = fdtdec_next_compatible(blob, 0, COMPAT_NVIDIA_TEGRA20_DC);
> +       if (node < 0) {
> +               debug("%s: Cannot find display controller node in fdt\n",
> +                     __func__);
> +               return node;
> +       }
> +       config->disp = (struct disp_ctlr *)fdtdec_get_addr(blob, node, "reg");
> +       if (!config->disp) {
> +               debug("%s: No display controller address\n", __func__);
> +               return -1;
> +       }
> +
> +       rgb = fdt_subnode_offset(blob, node, "rgb");
> +
> +       config->frame_buffer = fdtdec_get_addr(blob, rgb,
> +                                              "nvidia,frame-buffer");
> +       config->width = fdtdec_get_int(blob, rgb, "xres", -1);
> +       config->height = fdtdec_get_int(blob, rgb, "yres", -1);
> +       bpp = fdtdec_get_int(blob, rgb, "nvidia,bits-per-pixel", -1);
> +       bit = ffs(bpp) - 1;
> +       if (bpp == (1 << bit))
> +               config->log2_bpp = bit;
> +       else
> +               config->log2_bpp = bpp;
> +       config->bpp = bpp;
> +       config->pixel_clock = fdtdec_get_int(blob, rgb, "clock", 0);
> +       if (!config->pixel_clock || bpp == -1 ||
> +                       config->width == -1 || config->height == -1) {
> +               debug("%s: Pixel parameters missing\n", __func__);
> +               return -FDT_ERR_NOTFOUND;
> +       }
> +
> +       /* Use a ref-to-sync of 1 always, and take this from the front porch */

ref-to-sync is supposed to be 1 here.

> +       back = fdtdec_get_int(blob, rgb, "left-margin", -1);
> +       front = fdtdec_get_int(blob, rgb, "right-margin", -1);
> +       ref = fdtdec_get_int(blob, rgb, "hsync-len", -1);
> +       if ((back | front | ref) == -1) {
> +               debug("%s: Horizontal parameters missing\n", __func__);
> +               return -FDT_ERR_NOTFOUND;
> +       }
> +       config->horiz_timing[FDT_LCD_TIMING_REF_TO_SYNC] = 11;

It is assigned to 11.

/Adam

> +       config->horiz_timing[FDT_LCD_TIMING_SYNC_WIDTH] = ref;
> +       config->horiz_timing[FDT_LCD_TIMING_BACK_PORCH] = back;
> +       config->horiz_timing[FDT_LCD_TIMING_FRONT_PORCH] = front -
> +               config->horiz_timing[FDT_LCD_TIMING_REF_TO_SYNC];
> +       debug_timing("horiz", config->horiz_timing);
> +
> +       back = fdtdec_get_int(blob, rgb, "upper-margin", -1);
> +       front = fdtdec_get_int(blob, rgb, "lower-margin", -1);
> +       ref = fdtdec_get_int(blob, rgb, "vsync-len", -1);
> +       if ((back | front | ref) == -1) {
> +               debug("%s: Vertical parameters missing\n", __func__);
> +               return -FDT_ERR_NOTFOUND;
> +       }
> +       config->vert_timing[FDT_LCD_TIMING_REF_TO_SYNC] = 1;
> +       config->vert_timing[FDT_LCD_TIMING_SYNC_WIDTH] = ref;
> +       config->vert_timing[FDT_LCD_TIMING_BACK_PORCH] = back;
> +       config->vert_timing[FDT_LCD_TIMING_FRONT_PORCH] = front -
> +               config->vert_timing[FDT_LCD_TIMING_REF_TO_SYNC];
> +       debug_timing("vert", config->horiz_timing);
> +
> +       config->panel_node = fdtdec_lookup_phandle(blob, rgb, "nvidia,panel");
> +
> +       config->valid = 1;      /* we have a valid configuration */
> +
> +       return 0;
> +}
> +
> +int tegra_display_probe(const void *blob, void *default_lcd_base)
> +{
> +       struct disp_ctl_win window;
> +       struct dc_ctlr *dc;
> +
> +       if (tegra_display_decode_config(blob, &config))
> +               return -1;
> +
> +       /*
> +        * The framebuffer address should be specified in the device tree.
> +        * This FDT value should be the same as the one defined in Linux kernel;
> +        * otherwise, it causes screen flicker. The FDT value overrides the
> +        * framebuffer allocated at the top of memory by board_init_f().
> +        *
> +        * If the framebuffer address is not defined in the FDT, falls back to
> +        * use the address allocated by board_init_f().
> +        */
> +       if (config.frame_buffer == FDT_ADDR_T_NONE)
> +               config.frame_buffer = (u32)default_lcd_base;
> +
> +       dc = (struct dc_ctlr *)config.disp;
> +
> +       /*
> +        * A header file for clock constants was NAKed upstream.
> +        * TODO: Put this into the FDT and fdt_lcd struct when we have clock
> +        * support there
> +        */
> +       clock_start_periph_pll(PERIPH_ID_HOST1X, CLOCK_ID_PERIPH,
> +                              144 * 1000000);
> +       clock_start_periph_pll(PERIPH_ID_DISP1, CLOCK_ID_CGENERAL,
> +                              600 * 1000000);
> +       basic_init(&dc->cmd);
> +       basic_init_timer(&dc->disp);
> +       rgb_enable(&dc->com);
> +
> +       if (config.pixel_clock)
> +               update_display_mode(&dc->disp, &config);
> +
> +       if (setup_window(&window, &config))
> +               return -1;
> +
> +       update_window(dc, &window);
> +
> +       return 0;
> +}
> diff --git a/arch/arm/include/asm/arch-tegra2/dc.h b/arch/arm/include/asm/arch-tegra2/dc.h
> new file mode 100644
> index 0000000..46c4137
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-tegra2/dc.h
> @@ -0,0 +1,544 @@
> +/*
> + *  (C) Copyright 2010
> + *  NVIDIA Corporation <www.nvidia.com>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#ifndef __ASM_ARCH_TEGRA_DC_H
> +#define __ASM_ARCH_TEGRA_DC_H
> +
> +/* Register definitions for the Tegra display controller */
> +
> +/* CMD register 0x000 ~ 0x43 */
> +struct dc_cmd_reg {
> +       /* Address 0x000 ~ 0x002 */
> +       uint gen_incr_syncpt;           /* _CMD_GENERAL_INCR_SYNCPT_0 */
> +       uint gen_incr_syncpt_ctrl;      /* _CMD_GENERAL_INCR_SYNCPT_CNTRL_0 */
> +       uint gen_incr_syncpt_err;       /* _CMD_GENERAL_INCR_SYNCPT_ERROR_0 */
> +
> +       uint reserved0[5];              /* reserved_0[5] */
> +
> +       /* Address 0x008 ~ 0x00a */
> +       uint win_a_incr_syncpt;         /* _CMD_WIN_A_INCR_SYNCPT_0 */
> +       uint win_a_incr_syncpt_ctrl;    /* _CMD_WIN_A_INCR_SYNCPT_CNTRL_0 */
> +       uint win_a_incr_syncpt_err;     /* _CMD_WIN_A_INCR_SYNCPT_ERROR_0 */
> +
> +       uint reserved1[5];              /* reserved_1[5] */
> +
> +       /* Address 0x010 ~ 0x012 */
> +       uint win_b_incr_syncpt;         /* _CMD_WIN_B_INCR_SYNCPT_0 */
> +       uint win_b_incr_syncpt_ctrl;    /* _CMD_WIN_B_INCR_SYNCPT_CNTRL_0 */
> +       uint win_b_incr_syncpt_err;     /* _CMD_WIN_B_INCR_SYNCPT_ERROR_0 */
> +
> +       uint reserved2[5];              /* reserved_2[5] */
> +
> +       /* Address 0x018 ~ 0x01a */
> +       uint win_c_incr_syncpt;         /* _CMD_WIN_C_INCR_SYNCPT_0 */
> +       uint win_c_incr_syncpt_ctrl;    /* _CMD_WIN_C_INCR_SYNCPT_CNTRL_0 */
> +       uint win_c_incr_syncpt_err;     /* _CMD_WIN_C_INCR_SYNCPT_ERROR_0 */
> +
> +       uint reserved3[13];             /* reserved_3[13] */
> +
> +       /* Address 0x028 */
> +       uint cont_syncpt_vsync;         /* _CMD_CONT_SYNCPT_VSYNC_0 */
> +
> +       uint reserved4[7];              /* reserved_4[7] */
> +
> +       /* Address 0x030 ~ 0x033 */
> +       uint ctxsw;                     /* _CMD_CTXSW_0 */
> +       uint disp_cmd_opt0;             /* _CMD_DISPLAY_COMMAND_OPTION0_0 */
> +       uint disp_cmd;                  /* _CMD_DISPLAY_COMMAND_0 */
> +       uint sig_raise;                 /* _CMD_SIGNAL_RAISE_0 */
> +
> +       uint reserved5[2];              /* reserved_0[2] */
> +
> +       /* Address 0x036 ~ 0x03e */
> +       uint disp_pow_ctrl;             /* _CMD_DISPLAY_POWER_CONTROL_0 */
> +       uint int_stat;                  /* _CMD_INT_STATUS_0 */
> +       uint int_mask;                  /* _CMD_INT_MASK_0 */
> +       uint int_enb;                   /* _CMD_INT_ENABLE_0 */
> +       uint int_type;                  /* _CMD_INT_TYPE_0 */
> +       uint int_polarity;              /* _CMD_INT_POLARITY_0 */
> +       uint sig_raise1;                /* _CMD_SIGNAL_RAISE1_0 */
> +       uint sig_raise2;                /* _CMD_SIGNAL_RAISE2_0 */
> +       uint sig_raise3;                /* _CMD_SIGNAL_RAISE3_0 */
> +
> +       uint reserved6;                 /* reserved_6 */
> +
> +       /* Address 0x040 ~ 0x043 */
> +       uint state_access;              /* _CMD_STATE_ACCESS_0 */
> +       uint state_ctrl;                /* _CMD_STATE_CONTROL_0 */
> +       uint disp_win_header;           /* _CMD_DISPLAY_WINDOW_HEADER_0 */
> +       uint reg_act_ctrl;              /* _CMD_REG_ACT_CONTROL_0 */
> +};
> +
> +enum {
> +       PIN_REG_COUNT           = 4,
> +       PIN_OUTPUT_SEL_COUNT    = 7,
> +};
> +
> +/* COM register 0x300 ~ 0x329 */
> +struct dc_com_reg {
> +       /* Address 0x300 ~ 0x301 */
> +       uint crc_ctrl;                  /* _COM_CRC_CONTROL_0 */
> +       uint crc_checksum;              /* _COM_CRC_CHECKSUM_0 */
> +
> +       /* _COM_PIN_OUTPUT_ENABLE0/1/2/3_0: Address 0x302 ~ 0x305 */
> +       uint pin_output_enb[PIN_REG_COUNT];
> +
> +       /* _COM_PIN_OUTPUT_POLARITY0/1/2/3_0: Address 0x306 ~ 0x309 */
> +       uint pin_output_polarity[PIN_REG_COUNT];
> +
> +       /* _COM_PIN_OUTPUT_DATA0/1/2/3_0: Address 0x30a ~ 0x30d */
> +       uint pin_output_data[PIN_REG_COUNT];
> +
> +       /* _COM_PIN_INPUT_ENABLE0_0: Address 0x30e ~ 0x311 */
> +       uint pin_input_enb[PIN_REG_COUNT];
> +
> +       /* Address 0x312 ~ 0x313 */
> +       uint pin_input_data0;           /* _COM_PIN_INPUT_DATA0_0 */
> +       uint pin_input_data1;           /* _COM_PIN_INPUT_DATA1_0 */
> +
> +       /* _COM_PIN_OUTPUT_SELECT0/1/2/3/4/5/6_0: Address 0x314 ~ 0x31a */
> +       uint pin_output_sel[PIN_OUTPUT_SEL_COUNT];
> +
> +       /* Address 0x31b ~ 0x329 */
> +       uint pin_misc_ctrl;             /* _COM_PIN_MISC_CONTROL_0 */
> +       uint pm0_ctrl;                  /* _COM_PM0_CONTROL_0 */
> +       uint pm0_duty_cycle;            /* _COM_PM0_DUTY_CYCLE_0 */
> +       uint pm1_ctrl;                  /* _COM_PM1_CONTROL_0 */
> +       uint pm1_duty_cycle;            /* _COM_PM1_DUTY_CYCLE_0 */
> +       uint spi_ctrl;                  /* _COM_SPI_CONTROL_0 */
> +       uint spi_start_byte;            /* _COM_SPI_START_BYTE_0 */
> +       uint hspi_wr_data_ab;           /* _COM_HSPI_WRITE_DATA_AB_0 */
> +       uint hspi_wr_data_cd;           /* _COM_HSPI_WRITE_DATA_CD */
> +       uint hspi_cs_dc;                /* _COM_HSPI_CS_DC_0 */
> +       uint scratch_reg_a;             /* _COM_SCRATCH_REGISTER_A_0 */
> +       uint scratch_reg_b;             /* _COM_SCRATCH_REGISTER_B_0 */
> +       uint gpio_ctrl;                 /* _COM_GPIO_CTRL_0 */
> +       uint gpio_debounce_cnt;         /* _COM_GPIO_DEBOUNCE_COUNTER_0 */
> +       uint crc_checksum_latched;      /* _COM_CRC_CHECKSUM_LATCHED_0 */
> +};
> +
> +enum dc_disp_h_pulse_pos {
> +       H_PULSE0_POSITION_A,
> +       H_PULSE0_POSITION_B,
> +       H_PULSE0_POSITION_C,
> +       H_PULSE0_POSITION_D,
> +       H_PULSE0_POSITION_COUNT,
> +};
> +
> +struct _disp_h_pulse {
> +       /* _DISP_H_PULSE0/1/2_CONTROL_0 */
> +       uint h_pulse_ctrl;
> +       /* _DISP_H_PULSE0/1/2_POSITION_A/B/C/D_0 */
> +       uint h_pulse_pos[H_PULSE0_POSITION_COUNT];
> +};
> +
> +enum dc_disp_v_pulse_pos {
> +       V_PULSE0_POSITION_A,
> +       V_PULSE0_POSITION_B,
> +       V_PULSE0_POSITION_C,
> +       V_PULSE0_POSITION_COUNT,
> +};
> +
> +struct _disp_v_pulse0 {
> +       /* _DISP_H_PULSE0/1_CONTROL_0 */
> +       uint v_pulse_ctrl;
> +       /* _DISP_H_PULSE0/1_POSITION_A/B/C_0 */
> +       uint v_pulse_pos[V_PULSE0_POSITION_COUNT];
> +};
> +
> +struct _disp_v_pulse2 {
> +       /* _DISP_H_PULSE2/3_CONTROL_0 */
> +       uint v_pulse_ctrl;
> +       /* _DISP_H_PULSE2/3_POSITION_A_0 */
> +       uint v_pulse_pos_a;
> +};
> +
> +enum dc_disp_h_pulse_reg {
> +       H_PULSE0,
> +       H_PULSE1,
> +       H_PULSE2,
> +       H_PULSE_COUNT,
> +};
> +
> +enum dc_disp_pp_select {
> +       PP_SELECT_A,
> +       PP_SELECT_B,
> +       PP_SELECT_C,
> +       PP_SELECT_D,
> +       PP_SELECT_COUNT,
> +};
> +
> +/* DISP register 0x400 ~ 0x4c1 */
> +struct dc_disp_reg {
> +       /* Address 0x400 ~ 0x40a */
> +       uint disp_signal_opt0;          /* _DISP_DISP_SIGNAL_OPTIONS0_0 */
> +       uint disp_signal_opt1;          /* _DISP_DISP_SIGNAL_OPTIONS1_0 */
> +       uint disp_win_opt;              /* _DISP_DISP_WIN_OPTIONS_0 */
> +       uint mem_high_pri;              /* _DISP_MEM_HIGH_PRIORITY_0 */
> +       uint mem_high_pri_timer;        /* _DISP_MEM_HIGH_PRIORITY_TIMER_0 */
> +       uint disp_timing_opt;           /* _DISP_DISP_TIMING_OPTIONS_0 */
> +       uint ref_to_sync;               /* _DISP_REF_TO_SYNC_0 */
> +       uint sync_width;                /* _DISP_SYNC_WIDTH_0 */
> +       uint back_porch;                /* _DISP_BACK_PORCH_0 */
> +       uint disp_active;               /* _DISP_DISP_ACTIVE_0 */
> +       uint front_porch;               /* _DISP_FRONT_PORCH_0 */
> +
> +       /* Address 0x40b ~ 0x419: _DISP_H_PULSE0/1/2_  */
> +       struct _disp_h_pulse h_pulse[H_PULSE_COUNT];
> +
> +       /* Address 0x41a ~ 0x421 */
> +       struct _disp_v_pulse0 v_pulse0; /* _DISP_V_PULSE0_ */
> +       struct _disp_v_pulse0 v_pulse1; /* _DISP_V_PULSE1_ */
> +
> +       /* Address 0x422 ~ 0x425 */
> +       struct _disp_v_pulse2 v_pulse3; /* _DISP_V_PULSE2_ */
> +       struct _disp_v_pulse2 v_pulse4; /* _DISP_V_PULSE3_ */
> +
> +       /* Address 0x426 ~ 0x429 */
> +       uint m0_ctrl;                   /* _DISP_M0_CONTROL_0 */
> +       uint m1_ctrl;                   /* _DISP_M1_CONTROL_0 */
> +       uint di_ctrl;                   /* _DISP_DI_CONTROL_0 */
> +       uint pp_ctrl;                   /* _DISP_PP_CONTROL_0 */
> +
> +       /* Address 0x42a ~ 0x42d: _DISP_PP_SELECT_A/B/C/D_0 */
> +       uint pp_select[PP_SELECT_COUNT];
> +
> +       /* Address 0x42e ~ 0x435 */
> +       uint disp_clk_ctrl;             /* _DISP_DISP_CLOCK_CONTROL_0 */
> +       uint disp_interface_ctrl;       /* _DISP_DISP_INTERFACE_CONTROL_0 */
> +       uint disp_color_ctrl;           /* _DISP_DISP_COLOR_CONTROL_0 */
> +       uint shift_clk_opt;             /* _DISP_SHIFT_CLOCK_OPTIONS_0 */
> +       uint data_enable_opt;           /* _DISP_DATA_ENABLE_OPTIONS_0 */
> +       uint serial_interface_opt;      /* _DISP_SERIAL_INTERFACE_OPTIONS_0 */
> +       uint lcd_spi_opt;               /* _DISP_LCD_SPI_OPTIONS_0 */
> +       uint border_color;              /* _DISP_BORDER_COLOR_0 */
> +
> +       /* Address 0x436 ~ 0x439 */
> +       uint color_key0_lower;          /* _DISP_COLOR_KEY0_LOWER_0 */
> +       uint color_key0_upper;          /* _DISP_COLOR_KEY0_UPPER_0 */
> +       uint color_key1_lower;          /* _DISP_COLOR_KEY1_LOWER_0 */
> +       uint color_key1_upper;          /* _DISP_COLOR_KEY1_UPPER_0 */
> +
> +       uint reserved0[2];              /* reserved_0[2] */
> +
> +       /* Address 0x43c ~ 0x442 */
> +       uint cursor_foreground;         /* _DISP_CURSOR_FOREGROUND_0 */
> +       uint cursor_background;         /* _DISP_CURSOR_BACKGROUND_0 */
> +       uint cursor_start_addr;         /* _DISP_CURSOR_START_ADDR_0 */
> +       uint cursor_start_addr_ns;      /* _DISP_CURSOR_START_ADDR_NS_0 */
> +       uint cursor_pos;                /* _DISP_CURSOR_POSITION_0 */
> +       uint cursor_pos_ns;             /* _DISP_CURSOR_POSITION_NS_0 */
> +       uint seq_ctrl;                  /* _DISP_INIT_SEQ_CONTROL_0 */
> +
> +       /* Address 0x442 ~ 0x446 */
> +       uint spi_init_seq_data_a;       /* _DISP_SPI_INIT_SEQ_DATA_A_0 */
> +       uint spi_init_seq_data_b;       /* _DISP_SPI_INIT_SEQ_DATA_B_0 */
> +       uint spi_init_seq_data_c;       /* _DISP_SPI_INIT_SEQ_DATA_C_0 */
> +       uint spi_init_seq_data_d;       /* _DISP_SPI_INIT_SEQ_DATA_D_0 */
> +
> +       uint reserved1[0x39];           /* reserved1[0x39], */
> +
> +       /* Address 0x480 ~ 0x484 */
> +       uint dc_mccif_fifoctrl;         /* _DISP_DC_MCCIF_FIFOCTRL_0 */
> +       uint mccif_disp0a_hyst;         /* _DISP_MCCIF_DISPLAY0A_HYST_0 */
> +       uint mccif_disp0b_hyst;         /* _DISP_MCCIF_DISPLAY0B_HYST_0 */
> +       uint mccif_disp0c_hyst;         /* _DISP_MCCIF_DISPLAY0C_HYST_0 */
> +       uint mccif_disp1b_hyst;         /* _DISP_MCCIF_DISPLAY1B_HYST_0 */
> +
> +       uint reserved2[0x3b];           /* reserved2[0x3b] */
> +
> +       /* Address 0x4c0 ~ 0x4c1 */
> +       uint dac_crt_ctrl;              /* _DISP_DAC_CRT_CTRL_0 */
> +       uint disp_misc_ctrl;            /* _DISP_DISP_MISC_CONTROL_0 */
> +};
> +
> +enum dc_winc_filter_p {
> +       WINC_FILTER_COUNT       = 0x10,
> +};
> +
> +/* Window A/B/C register 0x500 ~ 0x628 */
> +struct dc_winc_reg {
> +
> +       /* Address 0x500 */
> +       uint color_palette;             /* _WINC_COLOR_PALETTE_0 */
> +
> +       uint reserved0[0xff];           /* reserved_0[0xff] */
> +
> +       /* Address 0x600 */
> +       uint palette_color_ext;         /* _WINC_PALETTE_COLOR_EXT_0 */
> +
> +       /* _WINC_H_FILTER_P00~0F_0 */
> +       /* Address 0x601 ~ 0x610 */
> +       uint h_filter_p[WINC_FILTER_COUNT];
> +
> +       /* Address 0x611 ~ 0x618 */
> +       uint csc_yof;                   /* _WINC_CSC_YOF_0 */
> +       uint csc_kyrgb;                 /* _WINC_CSC_KYRGB_0 */
> +       uint csc_kur;                   /* _WINC_CSC_KUR_0 */
> +       uint csc_kvr;                   /* _WINC_CSC_KVR_0 */
> +       uint csc_kug;                   /* _WINC_CSC_KUG_0 */
> +       uint csc_kvg;                   /* _WINC_CSC_KVG_0 */
> +       uint csc_kub;                   /* _WINC_CSC_KUB_0 */
> +       uint csc_kvb;                   /* _WINC_CSC_KVB_0 */
> +
> +       /* Address 0x619 ~ 0x628: _WINC_V_FILTER_P00~0F_0 */
> +       uint v_filter_p[WINC_FILTER_COUNT];
> +};
> +
> +/* WIN A/B/C Register 0x700 ~ 0x714*/
> +struct dc_win_reg {
> +       /* Address 0x700 ~ 0x714 */
> +       uint win_opt;                   /* _WIN_WIN_OPTIONS_0 */
> +       uint byte_swap;                 /* _WIN_BYTE_SWAP_0 */
> +       uint buffer_ctrl;               /* _WIN_BUFFER_CONTROL_0 */
> +       uint color_depth;               /* _WIN_COLOR_DEPTH_0 */
> +       uint pos;                       /* _WIN_POSITION_0 */
> +       uint size;                      /* _WIN_SIZE_0 */
> +       uint prescaled_size;            /* _WIN_PRESCALED_SIZE_0 */
> +       uint h_initial_dda;             /* _WIN_H_INITIAL_DDA_0 */
> +       uint v_initial_dda;             /* _WIN_V_INITIAL_DDA_0 */
> +       uint dda_increment;             /* _WIN_DDA_INCREMENT_0 */
> +       uint line_stride;               /* _WIN_LINE_STRIDE_0 */
> +       uint buf_stride;                /* _WIN_BUF_STRIDE_0 */
> +       uint uv_buf_stride;             /* _WIN_UV_BUF_STRIDE_0 */
> +       uint buffer_addr_mode;          /* _WIN_BUFFER_ADDR_MODE_0 */
> +       uint dv_ctrl;                   /* _WIN_DV_CONTROL_0 */
> +       uint blend_nokey;               /* _WIN_BLEND_NOKEY_0 */
> +       uint blend_1win;                /* _WIN_BLEND_1WIN_0 */
> +       uint blend_2win_x;              /* _WIN_BLEND_2WIN_X_0 */
> +       uint blend_2win_y;              /* _WIN_BLEND_2WIN_Y_0 */
> +       uint blend_3win_xy;             /* _WIN_BLEND_3WIN_XY_0 */
> +       uint hp_fetch_ctrl;             /* _WIN_HP_FETCH_CONTROL_0 */
> +};
> +
> +/* WINBUF A/B/C Register 0x800 ~ 0x80a */
> +struct dc_winbuf_reg {
> +       /* Address 0x800 ~ 0x80a */
> +       uint start_addr;                /* _WINBUF_START_ADDR_0 */
> +       uint start_addr_ns;             /* _WINBUF_START_ADDR_NS_0 */
> +       uint start_addr_u;              /* _WINBUF_START_ADDR_U_0 */
> +       uint start_addr_u_ns;           /* _WINBUF_START_ADDR_U_NS_0 */
> +       uint start_addr_v;              /* _WINBUF_START_ADDR_V_0 */
> +       uint start_addr_v_ns;           /* _WINBUF_START_ADDR_V_NS_0 */
> +       uint addr_h_offset;             /* _WINBUF_ADDR_H_OFFSET_0 */
> +       uint addr_h_offset_ns;          /* _WINBUF_ADDR_H_OFFSET_NS_0 */
> +       uint addr_v_offset;             /* _WINBUF_ADDR_V_OFFSET_0 */
> +       uint addr_v_offset_ns;          /* _WINBUF_ADDR_V_OFFSET_NS_0 */
> +       uint uflow_status;              /* _WINBUF_UFLOW_STATUS_0 */
> +};
> +
> +/* Display Controller (DC_) regs */
> +struct dc_ctlr {
> +       struct dc_cmd_reg cmd;          /* CMD register 0x000 ~ 0x43 */
> +       uint reserved0[0x2bc];
> +
> +       struct dc_com_reg com;          /* COM register 0x300 ~ 0x329 */
> +       uint reserved1[0xd6];
> +
> +       struct dc_disp_reg disp;        /* DISP register 0x400 ~ 0x4c1 */
> +       uint reserved2[0x3e];
> +
> +       struct dc_winc_reg winc;        /* Window A/B/C 0x500 ~ 0x628 */
> +       uint reserved3[0xd7];
> +
> +       struct dc_win_reg win;          /* WIN A/B/C 0x700 ~ 0x714*/
> +       uint reserved4[0xeb];
> +
> +       struct dc_winbuf_reg winbuf;    /* WINBUF A/B/C 0x800 ~ 0x80a */
> +};
> +
> +#define BIT(pos)       (1U << pos)
> +
> +/* DC_CMD_DISPLAY_COMMAND 0x032 */
> +#define CTRL_MODE_SHIFT                5
> +#define CTRL_MODE_MASK         (0x3 << CTRL_MODE_SHIFT)
> +enum {
> +       CTRL_MODE_STOP,
> +       CTRL_MODE_C_DISPLAY,
> +       CTRL_MODE_NC_DISPLAY,
> +};
> +
> +/* _WIN_COLOR_DEPTH_0 */
> +enum win_color_depth_id {
> +       COLOR_DEPTH_P1,
> +       COLOR_DEPTH_P2,
> +       COLOR_DEPTH_P4,
> +       COLOR_DEPTH_P8,
> +       COLOR_DEPTH_B4G4R4A4,
> +       COLOR_DEPTH_B5G5R5A,
> +       COLOR_DEPTH_B5G6R5,
> +       COLOR_DEPTH_AB5G5R5,
> +       COLOR_DEPTH_B8G8R8A8 = 12,
> +       COLOR_DEPTH_R8G8B8A8,
> +       COLOR_DEPTH_B6x2G6x2R6x2A8,
> +       COLOR_DEPTH_R6x2G6x2B6x2A8,
> +       COLOR_DEPTH_YCbCr422,
> +       COLOR_DEPTH_YUV422,
> +       COLOR_DEPTH_YCbCr420P,
> +       COLOR_DEPTH_YUV420P,
> +       COLOR_DEPTH_YCbCr422P,
> +       COLOR_DEPTH_YUV422P,
> +       COLOR_DEPTH_YCbCr422R,
> +       COLOR_DEPTH_YUV422R,
> +       COLOR_DEPTH_YCbCr422RA,
> +       COLOR_DEPTH_YUV422RA,
> +};
> +
> +/* DC_CMD_DISPLAY_POWER_CONTROL 0x036 */
> +#define PW0_ENABLE             BIT(0)
> +#define PW1_ENABLE             BIT(2)
> +#define PW2_ENABLE             BIT(4)
> +#define PW3_ENABLE             BIT(6)
> +#define PW4_ENABLE             BIT(8)
> +#define PM0_ENABLE             BIT(16)
> +#define PM1_ENABLE             BIT(18)
> +#define SPI_ENABLE             BIT(24)
> +#define HSPI_ENABLE            BIT(25)
> +
> +/* DC_CMD_STATE_CONTROL 0x041 */
> +#define GENERAL_ACT_REQ                BIT(0)
> +#define WIN_A_ACT_REQ          BIT(1)
> +#define WIN_B_ACT_REQ          BIT(2)
> +#define WIN_C_ACT_REQ          BIT(3)
> +#define GENERAL_UPDATE         BIT(8)
> +#define WIN_A_UPDATE           BIT(9)
> +#define WIN_B_UPDATE           BIT(10)
> +#define WIN_C_UPDATE           BIT(11)
> +
> +/* DC_CMD_DISPLAY_WINDOW_HEADER 0x042 */
> +#define WINDOW_A_SELECT                BIT(4)
> +#define WINDOW_B_SELECT                BIT(5)
> +#define WINDOW_C_SELECT                BIT(6)
> +
> +/* DC_DISP_DISP_CLOCK_CONTROL 0x42e */
> +#define SHIFT_CLK_DIVIDER_SHIFT        0
> +#define SHIFT_CLK_DIVIDER_MASK (0xff << SHIFT_CLK_DIVIDER_SHIFT)
> +#define        PIXEL_CLK_DIVIDER_SHIFT 8
> +#define        PIXEL_CLK_DIVIDER_MSK   (0xf << PIXEL_CLK_DIVIDER_SHIFT)
> +enum {
> +       PIXEL_CLK_DIVIDER_PCD1,
> +       PIXEL_CLK_DIVIDER_PCD1H,
> +       PIXEL_CLK_DIVIDER_PCD2,
> +       PIXEL_CLK_DIVIDER_PCD3,
> +       PIXEL_CLK_DIVIDER_PCD4,
> +       PIXEL_CLK_DIVIDER_PCD6,
> +       PIXEL_CLK_DIVIDER_PCD8,
> +       PIXEL_CLK_DIVIDER_PCD9,
> +       PIXEL_CLK_DIVIDER_PCD12,
> +       PIXEL_CLK_DIVIDER_PCD16,
> +       PIXEL_CLK_DIVIDER_PCD18,
> +       PIXEL_CLK_DIVIDER_PCD24,
> +       PIXEL_CLK_DIVIDER_PCD13,
> +};
> +
> +/* DC_DISP_DISP_INTERFACE_CONTROL 0x42f */
> +#define DATA_FORMAT_SHIFT      0
> +#define DATA_FORMAT_MASK       (0xf << DATA_FORMAT_SHIFT)
> +enum {
> +       DATA_FORMAT_DF1P1C,
> +       DATA_FORMAT_DF1P2C24B,
> +       DATA_FORMAT_DF1P2C18B,
> +       DATA_FORMAT_DF1P2C16B,
> +       DATA_FORMAT_DF2S,
> +       DATA_FORMAT_DF3S,
> +       DATA_FORMAT_DFSPI,
> +       DATA_FORMAT_DF1P3C24B,
> +       DATA_FORMAT_DF1P3C18B,
> +};
> +#define DATA_ALIGNMENT_SHIFT   8
> +enum {
> +       DATA_ALIGNMENT_MSB,
> +       DATA_ALIGNMENT_LSB,
> +};
> +#define DATA_ORDER_SHIFT       9
> +enum {
> +       DATA_ORDER_RED_BLUE,
> +       DATA_ORDER_BLUE_RED,
> +};
> +
> +/* DC_DISP_DATA_ENABLE_OPTIONS 0x432 */
> +#define DE_SELECT_SHIFT                0
> +#define DE_SELECT_MASK         (0x3 << DE_SELECT_SHIFT)
> +#define DE_SELECT_ACTIVE_BLANK 0x0
> +#define DE_SELECT_ACTIVE       0x1
> +#define DE_SELECT_ACTIVE_IS    0x2
> +#define DE_CONTROL_SHIFT       2
> +#define DE_CONTROL_MASK                (0x7 << DE_CONTROL_SHIFT)
> +enum {
> +       DE_CONTROL_ONECLK,
> +       DE_CONTROL_NORMAL,
> +       DE_CONTROL_EARLY_EXT,
> +       DE_CONTROL_EARLY,
> +       DE_CONTROL_ACTIVE_BLANK,
> +};
> +
> +/* DC_WIN_WIN_OPTIONS 0x700 */
> +#define H_DIRECTION            BIT(0)
> +enum {
> +       H_DIRECTION_INCREMENT,
> +       H_DIRECTION_DECREMENT,
> +};
> +#define V_DIRECTION            BIT(2)
> +enum {
> +       V_DIRECTION_INCREMENT,
> +       V_DIRECTION_DECREMENT,
> +};
> +#define COLOR_EXPAND           BIT(6)
> +#define CP_ENABLE              BIT(16)
> +#define DV_ENABLE              BIT(20)
> +#define WIN_ENABLE             BIT(30)
> +
> +/* DC_WIN_BYTE_SWAP 0x701 */
> +#define BYTE_SWAP_SHIFT                0
> +enum {
> +       BYTE_SWAP_NOSWAP,
> +       BYTE_SWAP_SWAP2,
> +       BYTE_SWAP_SWAP4,
> +       BYTE_SWAP_SWAP4HW
> +};
> +
> +/* DC_WIN_POSITION 0x704 */
> +#define H_POSITION_SHIFT       0
> +#define H_POSITION_MASK                (0x1FFF << H_POSITION_SHIFT)
> +#define V_POSITION_SHIFT       16
> +#define V_POSITION_MASK                (0x1FFF << V_POSITION_SHIFT)
> +
> +/* DC_WIN_SIZE 0x705 */
> +#define H_SIZE_SHIFT           0
> +#define H_SIZE_MASK            (0x1FFF << H_SIZE_SHIFT)
> +#define V_SIZE_SHIFT           16
> +#define V_SIZE_MASK            (0x1FFF << V_SIZE_SHIFT)
> +
> +/* DC_WIN_PRESCALED_SIZE 0x706 */
> +#define H_PRESCALED_SIZE_SHIFT 0
> +#define H_PRESCALED_SIZE_MASK  (0x7FFF << H_PRESCALED_SIZE)
> +#define V_PRESCALED_SIZE_SHIFT 16
> +#define V_PRESCALED_SIZE_MASK  (0x1FFF << V_PRESCALED_SIZE)
> +
> +/* DC_WIN_DDA_INCREMENT 0x709 */
> +#define H_DDA_INC_SHIFT                0
> +#define H_DDA_INC_MASK         (0xFFFF << H_DDA_INC_SHIFT)
> +#define V_DDA_INC_SHIFT                16
> +#define V_DDA_INC_MASK         (0xFFFF << V_DDA_INC_SHIFT)
> +
> +#endif /* __ASM_ARCH_TEGRA_DC_H */
> diff --git a/arch/arm/include/asm/arch-tegra2/display.h b/arch/arm/include/asm/arch-tegra2/display.h
> new file mode 100644
> index 0000000..7795317
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-tegra2/display.h
> @@ -0,0 +1,152 @@
> +/*
> + *  (C) Copyright 2010
> + *  NVIDIA Corporation <www.nvidia.com>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#ifndef __ASM_ARCH_TEGRA_DISPLAY_H
> +#define __ASM_ARCH_TEGRA_DISPLAY_H
> +
> +#include <asm/arch-tegra2/dc.h>
> +#include <fdtdec.h>
> +
> +/* This holds information about a window which can be displayed */
> +struct disp_ctl_win {
> +       enum win_color_depth_id fmt;    /* Color depth/format */
> +       unsigned        bpp;            /* Bits per pixel */
> +       phys_addr_t     phys_addr;      /* Physical address in memory */
> +       unsigned        x;              /* Horizontal address offset (bytes) */
> +       unsigned        y;              /* Veritical address offset (bytes) */
> +       unsigned        w;              /* Width of source window */
> +       unsigned        h;              /* Height of source window */
> +       unsigned        stride;         /* Number of bytes per line */
> +       unsigned        out_x;          /* Left edge of output window (col) */
> +       unsigned        out_y;          /* Top edge of output window (row) */
> +       unsigned        out_w;          /* Width of output window in pixels */
> +       unsigned        out_h;          /* Height of output window in pixels */
> +};
> +
> +#define FDT_LCD_TIMINGS        4
> +
> +enum {
> +       FDT_LCD_TIMING_REF_TO_SYNC,
> +       FDT_LCD_TIMING_SYNC_WIDTH,
> +       FDT_LCD_TIMING_BACK_PORCH,
> +       FDT_LCD_TIMING_FRONT_PORCH,
> +
> +       FDT_LCD_TIMING_COUNT,
> +};
> +
> +enum lcd_cache_t {
> +       FDT_LCD_CACHE_OFF               = 0,
> +       FDT_LCD_CACHE_WRITE_THROUGH     = 1 << 0,
> +       FDT_LCD_CACHE_WRITE_BACK        = 1 << 1,
> +       FDT_LCD_CACHE_FLUSH             = 1 << 2,
> +       FDT_LCD_CACHE_WRITE_BACK_FLUSH  = FDT_LCD_CACHE_WRITE_BACK |
> +                                               FDT_LCD_CACHE_FLUSH,
> +};
> +
> +/* Information about the display controller */
> +struct fdt_disp_config {
> +       int valid;                      /* config is valid */
> +       int width;                      /* width in pixels */
> +       int height;                     /* height in pixels */
> +       int bpp;                        /* number of bits per pixel */
> +
> +       /*
> +        * log2 of number of bpp, in general, unless it bpp is 24 in which
> +        * case this field holds 24 also! This is a U-Boot thing.
> +        */
> +       int log2_bpp;
> +       struct disp_ctlr *disp;         /* Display controller to use */
> +       fdt_addr_t frame_buffer;        /* Address of frame buffer */
> +       unsigned pixel_clock;           /* Pixel clock in Hz */
> +       uint horiz_timing[FDT_LCD_TIMING_COUNT];        /* Horizontal timing */
> +       uint vert_timing[FDT_LCD_TIMING_COUNT];         /* Vertical timing */
> +       int panel_node;                 /* node offset of panel information */
> +};
> +
> +/* Information about the LCD panel */
> +struct fdt_panel_config {
> +       int pwm_channel;                /* PWM channel to use for backlight */
> +       enum lcd_cache_t cache_type;
> +
> +       struct fdt_gpio_state backlight_en;     /* GPIO for backlight enable */
> +       struct fdt_gpio_state lvds_shutdown;    /* GPIO for lvds shutdown */
> +       struct fdt_gpio_state backlight_vdd;    /* GPIO for backlight vdd */
> +       struct fdt_gpio_state panel_vdd;        /* GPIO for panel vdd */
> +       /*
> +        * Panel required timings
> +        * Timing 1: delay between panel_vdd-rise and data-rise
> +        * Timing 2: delay between data-rise and backlight_vdd-rise
> +        * Timing 3: delay between backlight_vdd and pwm-rise
> +        * Timing 4: delay between pwm-rise and backlight_en-rise
> +        */
> +       uint panel_timings[FDT_LCD_TIMINGS];
> +};
> +
> +/**
> + * Register a new display based on device tree configuration.
> + *
> + * The frame buffer can be positioned by U-Boot or overriden by the fdt.
> + * You should pass in the U-Boot address here, and check the contents of
> + * struct fdt_disp_config to see what was actually chosen.
> + *
> + * @param blob                 Device tree blob
> + * @param default_lcd_base     Default address of LCD frame buffer
> + * @return 0 if ok, -1 on error (unsupported bits per pixel)
> + */
> +int tegra_display_probe(const void *blob, void *default_lcd_base);
> +
> +/**
> + * Return the current display configuration
> + *
> + * @return pointer to display configuration, or NULL if there is no valid
> + * config
> + */
> +struct fdt_disp_config *tegra_display_get_config(void);
> +
> +/**
> + * Perform the next stage of the LCD init if it is time to do so.
> + *
> + * LCD init can be time-consuming because of the number of delays we need
> + * while waiting for the backlight power supply, etc. This function can
> + * be called at various times during U-Boot operation to advance the
> + * initialization of the LCD to the next stage if sufficient time has
> + * passed since the last stage. It keeps track of what stage it is up to
> + * and the time that it is permitted to move to the next stage.
> + *
> + * The final call should have wait=1 to complete the init.
> + *
> + * @param blob fdt blob containing LCD information
> + * @param wait 1 to wait until all init is complete, and then return
> + *             0 to return immediately, potentially doing nothing if it is
> + *             not yet time for the next init.
> + */
> +int tegra_lcd_check_next_stage(const void *blob, int wait);
> +
> +/**
> + * Set up the maximum LCD size so we can size the frame buffer.
> + *
> + * @param blob fdt blob containing LCD information
> + */
> +void tegra_lcd_early_init(const void *blob);
> +
> +#endif /*__ASM_ARCH_TEGRA_DISPLAY_H*/
> diff --git a/include/fdtdec.h b/include/fdtdec.h
> index 3997bfa..b474ced 100644
> --- a/include/fdtdec.h
> +++ b/include/fdtdec.h
> @@ -66,6 +66,7 @@ enum fdt_compat_id {
>         COMPAT_NVIDIA_TEGRA20_EMC_TABLE, /* Tegra2 memory timing table */
>         COMPAT_NVIDIA_TEGRA20_KBC,      /* Tegra2 Keyboard */
>         COMPAT_NVIDIA_TEGRA20_PWM,      /* Tegra 2 PWM controller */
> +       COMPAT_NVIDIA_TEGRA20_DC,       /* Tegra 2 Display controller */
> 
>         COMPAT_COUNT,
>  };
> diff --git a/lib/fdtdec.c b/lib/fdtdec.c
> index 40b0aef..1021560 100644
> --- a/lib/fdtdec.c
> +++ b/lib/fdtdec.c
> @@ -44,6 +44,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
>         COMPAT(NVIDIA_TEGRA20_EMC_TABLE, "nvidia,tegra20-emc-table"),
>         COMPAT(NVIDIA_TEGRA20_KBC, "nvidia,tegra20-kbc"),
>         COMPAT(NVIDIA_TEGRA20_PWM, "nvidia,tegra20-pwm"),
> +       COMPAT(NVIDIA_TEGRA20_DC, "nvidia,tegra20-dc"),
>  };
> 
>  const char *fdtdec_get_compatible(enum fdt_compat_id id)
> --
> 1.7.7.3
> 
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot

-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information.  Any unauthorized review, use, disclosure or distribution
is prohibited.  If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------

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

* [U-Boot] [PATCH v3 08/18] tegra: Add SOC support for display/lcd
  2012-07-19  7:37   ` Thierry Reding
@ 2012-07-19  8:24     ` Adam Jiang
  2012-07-19  8:28       ` Thierry Reding
  0 siblings, 1 reply; 81+ messages in thread
From: Adam Jiang @ 2012-07-19  8:24 UTC (permalink / raw)
  To: u-boot

On Thu, Jul 19, 2012 at 03:37:07PM +0800, Thierry Reding wrote:
> * PGP Signed by an unknown key
> 
> On Thu, Jul 12, 2012 at 08:25:08AM -0700, Simon Glass wrote:
> > From: Wei Ni <wni@nvidia.com>
> > 
> > Add support for the LCD peripheral at the Tegra2 SOC level. A separate
> > LCD driver will use this functionality to configure the display.
> > 
> > Mayuresh Kulkarni:
> > - changes to remove bitfields and clean up for submission
> > 
> > Simon Glass:
> > - simplify code, move clock control into here, clean-up
> > 
> > Signed-off-by: Mayuresh Kulkarni <mkulkarni@nvidia.com>
> > Signed-off-by: Simon Glass <sjg@chromium.org>
> > ---
> > Changes in v3:
> > - Add probe function to read in fdt parameters in display driver
> > - Separate display driver and LCD driver more in fdt
> > 
> >  arch/arm/cpu/armv7/tegra2/Makefile         |    2 +-
> >  arch/arm/cpu/armv7/tegra2/display.c        |  389 ++++++++++++++++++++
> >  arch/arm/include/asm/arch-tegra2/dc.h      |  544 ++++++++++++++++++++++++++++
> >  arch/arm/include/asm/arch-tegra2/display.h |  152 ++++++++
> >  include/fdtdec.h                           |    1 +
> >  lib/fdtdec.c                               |    1 +
> >  6 files changed, 1088 insertions(+), 1 deletions(-)
> >  create mode 100644 arch/arm/cpu/armv7/tegra2/display.c
> >  create mode 100644 arch/arm/include/asm/arch-tegra2/dc.h
> >  create mode 100644 arch/arm/include/asm/arch-tegra2/display.h
> > 
> [...]
> > diff --git a/arch/arm/cpu/armv7/tegra2/display.c b/arch/arm/cpu/armv7/tegra2/display.c
> [...]
> > +int setup_window(struct disp_ctl_win *win, struct fdt_disp_config *config)
> > +{
> > +	win->x = 0;
> > +	win->y = 0;
> > +	win->w = config->width;
> > +	win->h = config->height;
> > +	win->out_x = 0;
> > +	win->out_y = 0;
> > +	win->out_w = config->width;
> > +	win->out_h = config->height;
> > +	win->phys_addr = config->frame_buffer;
> > +	win->stride = config->width * (1 << config->log2_bpp) / 8;
> > +	debug("%s: depth = %d\n", __func__, config->log2_bpp);
> > +	switch (config->log2_bpp) {
> > +	case 5:
> > +	case 24:
> 
> What's the 24 doing here?

This has been explained in the definition of the log2_bpp. When bpp is
24, the integer holds 24 itself because there is no 2^N expression for
it.

/Adam

> 
> [...]
> > +static int tegra_display_decode_config(const void *blob,
> > +				       struct fdt_disp_config *config)
> > +{
> > +	int front, back, ref;
> > +	int node, rgb;
> > +	int bpp, bit;
> > +
> > +	node = fdtdec_next_compatible(blob, 0, COMPAT_NVIDIA_TEGRA20_DC);
> > +	if (node < 0) {
> > +		debug("%s: Cannot find display controller node in fdt\n",
> > +		      __func__);
> > +		return node;
> > +	}
> > +	config->disp = (struct disp_ctlr *)fdtdec_get_addr(blob, node, "reg");
> > +	if (!config->disp) {
> > +		debug("%s: No display controller address\n", __func__);
> > +		return -1;
> > +	}
> > +
> > +	rgb = fdt_subnode_offset(blob, node, "rgb");
> > +
> > +	config->frame_buffer = fdtdec_get_addr(blob, rgb,
> > +					       "nvidia,frame-buffer");
> > +	config->width = fdtdec_get_int(blob, rgb, "xres", -1);
> > +	config->height = fdtdec_get_int(blob, rgb, "yres", -1);
> > +	bpp = fdtdec_get_int(blob, rgb, "nvidia,bits-per-pixel", -1);
> > +	bit = ffs(bpp) - 1;
> > +	if (bpp == (1 << bit))
> > +		config->log2_bpp = bit;
> > +	else
> > +		config->log2_bpp = bpp;
> > +	config->bpp = bpp;
> > +	config->pixel_clock = fdtdec_get_int(blob, rgb, "clock", 0);
> > +	if (!config->pixel_clock || bpp == -1 ||
> > +			config->width == -1 || config->height == -1) {
> > +		debug("%s: Pixel parameters missing\n", __func__);
> > +		return -FDT_ERR_NOTFOUND;
> > +	}
> > +
> > +	/* Use a ref-to-sync of 1 always, and take this from the front porch */
> > +	back = fdtdec_get_int(blob, rgb, "left-margin", -1);
> > +	front = fdtdec_get_int(blob, rgb, "right-margin", -1);
> > +	ref = fdtdec_get_int(blob, rgb, "hsync-len", -1);
> > +	if ((back | front | ref) == -1) {
> > +		debug("%s: Horizontal parameters missing\n", __func__);
> > +		return -FDT_ERR_NOTFOUND;
> > +	}
> > +	config->horiz_timing[FDT_LCD_TIMING_REF_TO_SYNC] = 11;
> 
> The comment above says this should be 1.
> 
> > +	config->horiz_timing[FDT_LCD_TIMING_SYNC_WIDTH] = ref;
> > +	config->horiz_timing[FDT_LCD_TIMING_BACK_PORCH] = back;
> > +	config->horiz_timing[FDT_LCD_TIMING_FRONT_PORCH] = front -
> > +		config->horiz_timing[FDT_LCD_TIMING_REF_TO_SYNC];
> > +	debug_timing("horiz", config->horiz_timing);
> > +
> > +	back = fdtdec_get_int(blob, rgb, "upper-margin", -1);
> > +	front = fdtdec_get_int(blob, rgb, "lower-margin", -1);
> > +	ref = fdtdec_get_int(blob, rgb, "vsync-len", -1);
> > +	if ((back | front | ref) == -1) {
> > +		debug("%s: Vertical parameters missing\n", __func__);
> > +		return -FDT_ERR_NOTFOUND;
> > +	}
> > +	config->vert_timing[FDT_LCD_TIMING_REF_TO_SYNC] = 1;
> > +	config->vert_timing[FDT_LCD_TIMING_SYNC_WIDTH] = ref;
> > +	config->vert_timing[FDT_LCD_TIMING_BACK_PORCH] = back;
> > +	config->vert_timing[FDT_LCD_TIMING_FRONT_PORCH] = front -
> > +		config->vert_timing[FDT_LCD_TIMING_REF_TO_SYNC];
> > +	debug_timing("vert", config->horiz_timing);
> 
> This should probably be config->vert_timing.
> 
> Thierry
> 
> * Unknown Key
> * 0x7F3EB3A1

> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot


-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information.  Any unauthorized review, use, disclosure or distribution
is prohibited.  If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------

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

* [U-Boot] [PATCH v3 08/18] tegra: Add SOC support for display/lcd
  2012-07-19  8:24     ` Adam Jiang
@ 2012-07-19  8:28       ` Thierry Reding
  0 siblings, 0 replies; 81+ messages in thread
From: Thierry Reding @ 2012-07-19  8:28 UTC (permalink / raw)
  To: u-boot

On Thu, Jul 19, 2012 at 05:24:35PM +0900, Adam Jiang wrote:
> On Thu, Jul 19, 2012 at 03:37:07PM +0800, Thierry Reding wrote:
> > * PGP Signed by an unknown key
> > 
> > On Thu, Jul 12, 2012 at 08:25:08AM -0700, Simon Glass wrote:
> > > From: Wei Ni <wni@nvidia.com>
> > > 
> > > Add support for the LCD peripheral at the Tegra2 SOC level. A separate
> > > LCD driver will use this functionality to configure the display.
> > > 
> > > Mayuresh Kulkarni:
> > > - changes to remove bitfields and clean up for submission
> > > 
> > > Simon Glass:
> > > - simplify code, move clock control into here, clean-up
> > > 
> > > Signed-off-by: Mayuresh Kulkarni <mkulkarni@nvidia.com>
> > > Signed-off-by: Simon Glass <sjg@chromium.org>
> > > ---
> > > Changes in v3:
> > > - Add probe function to read in fdt parameters in display driver
> > > - Separate display driver and LCD driver more in fdt
> > > 
> > >  arch/arm/cpu/armv7/tegra2/Makefile         |    2 +-
> > >  arch/arm/cpu/armv7/tegra2/display.c        |  389 ++++++++++++++++++++
> > >  arch/arm/include/asm/arch-tegra2/dc.h      |  544 ++++++++++++++++++++++++++++
> > >  arch/arm/include/asm/arch-tegra2/display.h |  152 ++++++++
> > >  include/fdtdec.h                           |    1 +
> > >  lib/fdtdec.c                               |    1 +
> > >  6 files changed, 1088 insertions(+), 1 deletions(-)
> > >  create mode 100644 arch/arm/cpu/armv7/tegra2/display.c
> > >  create mode 100644 arch/arm/include/asm/arch-tegra2/dc.h
> > >  create mode 100644 arch/arm/include/asm/arch-tegra2/display.h
> > > 
> > [...]
> > > diff --git a/arch/arm/cpu/armv7/tegra2/display.c b/arch/arm/cpu/armv7/tegra2/display.c
> > [...]
> > > +int setup_window(struct disp_ctl_win *win, struct fdt_disp_config *config)
> > > +{
> > > +	win->x = 0;
> > > +	win->y = 0;
> > > +	win->w = config->width;
> > > +	win->h = config->height;
> > > +	win->out_x = 0;
> > > +	win->out_y = 0;
> > > +	win->out_w = config->width;
> > > +	win->out_h = config->height;
> > > +	win->phys_addr = config->frame_buffer;
> > > +	win->stride = config->width * (1 << config->log2_bpp) / 8;
> > > +	debug("%s: depth = %d\n", __func__, config->log2_bpp);
> > > +	switch (config->log2_bpp) {
> > > +	case 5:
> > > +	case 24:
> > 
> > What's the 24 doing here?
> 
> This has been explained in the definition of the log2_bpp. When bpp is
> 24, the integer holds 24 itself because there is no 2^N expression for
> it.

Right, I missed that. Thanks.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20120719/9b3edaf0/attachment.pgp>

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

* Re: [PATCH v3 02/18] fdt: Add header guard to fdtdec.h
  2012-07-12 15:25   ` [U-Boot] " Simon Glass
@ 2012-07-19 13:49     ` Mike Frysinger
  -1 siblings, 0 replies; 81+ messages in thread
From: Mike Frysinger @ 2012-07-19 13:49 UTC (permalink / raw)
  To: u-boot; +Cc: Devicetree Discuss, Jerry Van Baren, Tom Warren


[-- Attachment #1.1: Type: Text/Plain, Size: 410 bytes --]

On Thursday 12 July 2012 11:25:02 Simon Glass wrote:
> This makes it easier to include this header from other headers.

Acked-by: Mike Frysinger <vapier@gentoo.org>

> --- a/include/fdtdec.h
> +++ b/include/fdtdec.h
>
>  const u8 *fdtdec_locate_byte_array(const void *blob, int node,
>  			     const char *prop_name, int count);
> +#endif

personally, i like seeing a blank line before the final #endif
-mike

[-- Attachment #1.2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

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

* [U-Boot] [PATCH v3 02/18] fdt: Add header guard to fdtdec.h
@ 2012-07-19 13:49     ` Mike Frysinger
  0 siblings, 0 replies; 81+ messages in thread
From: Mike Frysinger @ 2012-07-19 13:49 UTC (permalink / raw)
  To: u-boot

On Thursday 12 July 2012 11:25:02 Simon Glass wrote:
> This makes it easier to include this header from other headers.

Acked-by: Mike Frysinger <vapier@gentoo.org>

> --- a/include/fdtdec.h
> +++ b/include/fdtdec.h
>
>  const u8 *fdtdec_locate_byte_array(const void *blob, int node,
>  			     const char *prop_name, int count);
> +#endif

personally, i like seeing a blank line before the final #endif
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20120719/7a1c8a70/attachment.pgp>

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

* [U-Boot] [PATCH v3 03/18] tegra: Use const for pinmux_config_pingroup/table()
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 03/18] tegra: Use const for pinmux_config_pingroup/table() Simon Glass
@ 2012-07-19 13:53   ` Mike Frysinger
  0 siblings, 0 replies; 81+ messages in thread
From: Mike Frysinger @ 2012-07-19 13:53 UTC (permalink / raw)
  To: u-boot

Acked-by: Mike Frysinger <vapier@gentoo.org>
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20120719/3cbce2c6/attachment.pgp>

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

* [U-Boot] [PATCH v3 04/18] tegra: Add display support to funcmux
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 04/18] tegra: Add display support to funcmux Simon Glass
@ 2012-07-19 13:54   ` Mike Frysinger
  0 siblings, 0 replies; 81+ messages in thread
From: Mike Frysinger @ 2012-07-19 13:54 UTC (permalink / raw)
  To: u-boot

Acked-by: Mike Frysinger <vapier@gentoo.org>
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20120719/6112a6c2/attachment.pgp>

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

* [U-Boot] [PATCH v3 07/18] tegra: Add support for PWM
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 07/18] tegra: Add support for PWM Simon Glass
@ 2012-07-19 13:55   ` Mike Frysinger
  2012-09-27 13:51     ` Simon Glass
  0 siblings, 1 reply; 81+ messages in thread
From: Mike Frysinger @ 2012-07-19 13:55 UTC (permalink / raw)
  To: u-boot

On Thursday 12 July 2012 11:25:07 Simon Glass wrote:
> --- a/arch/arm/cpu/armv7/tegra2/Makefile
> +++ b/arch/arm/cpu/armv7/tegra2/Makefile
>
> +COBJS-$(CONFIG_VIDEO_TEGRA) += pwm.o

should this get its own knob ?  PWM isn't video specific ...
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20120719/d3f353d0/attachment.pgp>

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

* [U-Boot] [PATCH v3 12/18] lcd: Add CONFIG_LCD_ALIGNMENT to select frame buffer alignment
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 12/18] lcd: Add CONFIG_LCD_ALIGNMENT to select frame buffer alignment Simon Glass
@ 2012-07-19 13:59   ` Mike Frysinger
  2012-09-27 19:20     ` Simon Glass
  0 siblings, 1 reply; 81+ messages in thread
From: Mike Frysinger @ 2012-07-19 13:59 UTC (permalink / raw)
  To: u-boot

On Thursday 12 July 2012 11:25:12 Simon Glass wrote:
> --- a/common/lcd.c
> +++ b/common/lcd.c
>
> +#ifdef CONFIG_ARM
> +#include <asm/system.h>
> +#endif

this header isn't ARM specific.  also, i think most arches just include this in 
their "main" points rather than any non-arch places including it explicitly.
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20120719/e9cd97b0/attachment.pgp>

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

* [U-Boot] [PATCH v3 13/18] lcd: Add support for flushing LCD fb from dcache after update
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 13/18] lcd: Add support for flushing LCD fb from dcache after update Simon Glass
@ 2012-07-19 14:01   ` Mike Frysinger
  2012-07-19 16:52   ` Mike Frysinger
  2012-08-09  7:43   ` Lukasz Majewski
  2 siblings, 0 replies; 81+ messages in thread
From: Mike Frysinger @ 2012-07-19 14:01 UTC (permalink / raw)
  To: u-boot

On Thursday 12 July 2012 11:25:13 Simon Glass wrote:
> --- a/common/lcd.c
> +++ b/common/lcd.c
> 
> +/* Flush LCD activity to the caches */
> +void lcd_sync(void)
> +{
> +	/*
> +	 * flush_dcache_range() is declared in common.h but it seems that some
> +	 * architectures do not actually implement it. Is there a way to find
> +	 * out whether it exists? For now, ARM is safe.
> +	 */
> +#ifdef CONFIG_ARM
> +	int line_length;
> +
> +	if (lcd_flush_dcache)
> +		flush_dcache_range((u32)lcd_base,
> +			(u32)(lcd_base + lcd_get_size(&line_length)));
> +#endif
> +}

we should just let those people build fail imo so they'll be forced to add 
this
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20120719/7d261710/attachment.pgp>

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

* [U-Boot] [PATCH v3 14/18] tegra: Align LCD frame buffer to section boundary
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 14/18] tegra: Align LCD frame buffer to section boundary Simon Glass
@ 2012-07-19 14:01   ` Mike Frysinger
  0 siblings, 0 replies; 81+ messages in thread
From: Mike Frysinger @ 2012-07-19 14:01 UTC (permalink / raw)
  To: u-boot

Acked-by: Mike Frysinger <vapier@gentoo.org>
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20120719/0c1fdc4d/attachment.pgp>

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

* [U-Boot] [PATCH v3 17/18] lcd: Add CONSOLE_SCROLL_LINES option to speed console
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 17/18] lcd: Add CONSOLE_SCROLL_LINES option to speed console Simon Glass
@ 2012-07-19 14:04   ` Mike Frysinger
  2012-09-27 19:23     ` Simon Glass
  0 siblings, 1 reply; 81+ messages in thread
From: Mike Frysinger @ 2012-07-19 14:04 UTC (permalink / raw)
  To: u-boot

On Thursday 12 July 2012 11:25:17 Simon Glass wrote:
> --- a/README
> +++ b/README
> 
> +		CONSOLE_SCROLL_LINES
> +
> +		When the console need to be scrolled, this is the number of
> +		lines to scroll by. It defaults to 1. Increasing this makes
> +		the console jump but can help speed up operation when scrolling
> +		is slow.

board knobs should be CONFIG_xxx

> --- a/common/lcd.c
> +++ b/common/lcd.c
> 
>  static void console_scrollup (void)
>  {
> +	int rows = 1;
> +
> +#ifdef CONSOLE_SCROLL_LINES
> +	rows = CONSOLE_SCROLL_LINES;
> +#endif

seems like this should be at the top of the file:
#ifndef CONSOLE_SCROLL_LINES
# define CONSOLE_SCROLL_LINES 1
#endif
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20120719/856ad090/attachment.pgp>

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

* [U-Boot] [PATCH v3 11/18] arm: Add control over cachability of memory regions
  2012-07-12 18:12   ` Albert ARIBAUD
@ 2012-07-19 14:10     ` Mike Frysinger
  2012-09-27 17:54       ` Simon Glass
  0 siblings, 1 reply; 81+ messages in thread
From: Mike Frysinger @ 2012-07-19 14:10 UTC (permalink / raw)
  To: u-boot

On Thursday 12 July 2012 14:12:41 Albert ARIBAUD wrote:
> On Thu, 12 Jul 2012 08:25:11 -0700, Simon Glass wrote:
> > --- a/arch/arm/include/asm/system.h
> > +++ b/arch/arm/include/asm/system.h
> > 
> > +/* options available for data cache on each page */
> > +enum dcache_option {
> > +	DCACHE_OFF,
> > +	DCACHE_WRITETHROUGH,
> > +	DCACHE_WRITEBACK,
> > +};
> >
> > --- a/arch/arm/lib/cache-cp15.c
> > +++ b/arch/arm/lib/cache-cp15.c
> > 
> > -static inline void dram_bank_mmu_setup(int bank)
> > +void set_section_dcache(int section, enum dcache_option option)
> >  {
> > +	u32 value = section << MMU_SECTION_SHIFT | (3 << 10);
> >  	u32 *page_table = (u32 *)gd->tlb_addr;
> > +
> > +	switch (option) {
> > +	case DCACHE_WRITETHROUGH:
> > +		value |= 0x1a;
> > +		break;
> > +
> > +	case DCACHE_WRITEBACK:
> > +		value |= 0x1e;
> > +		break;
> > +
> > +	case DCACHE_OFF:
> > +		value |= 0x12;
> > +		break;
> > +	}
> 
> what's the benefit of introducing an arbitrary enum rather than
> defining DCACHE_WRITETHROUGH, DCACHE_WRITEBACK and DCACHE_OFF equal
> respecitvely to 0x1a, 0x1e and 0x12? All it does is force this
> switch case instead of a simple 'value |= option;' statement.

if these magic bitmasks are going to be the same for all arm cores (the enum 
is in common arm header), then you can get the advantages of both:
enum dcache_option {
	DCACHE_OFF = 0x12,
	DCACHE_WRITETHROUGH = 0x1a,
	DCACHE_WRITEBACK = 0x1e,
};

then just do:
	value |= option;
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20120719/e7c46fe8/attachment.pgp>

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

* [U-Boot] [PATCH v3 08/18] tegra: Add SOC support for display/lcd
  2012-07-19  8:03   ` Adam Jiang
@ 2012-07-19 14:13     ` Mike Frysinger
  2012-09-27 17:44     ` Simon Glass
  1 sibling, 0 replies; 81+ messages in thread
From: Mike Frysinger @ 2012-07-19 14:13 UTC (permalink / raw)
  To: u-boot

On Thursday 19 July 2012 04:03:04 Adam Jiang wrote:
> On Thu, Jul 12, 2012 at 11:25:08PM +0800, Simon Glass wrote:
> > +       /* Use a ref-to-sync of 1 always, and take this from the front
> > porch */
> 
> ref-to-sync is supposed to be 1 here.
> 
> > +       back = fdtdec_get_int(blob, rgb, "left-margin", -1);
> > +       front = fdtdec_get_int(blob, rgb, "right-margin", -1);
> > +       ref = fdtdec_get_int(blob, rgb, "hsync-len", -1);
> > +       if ((back | front | ref) == -1) {
> > +               debug("%s: Horizontal parameters missing\n", __func__);
> > +               return -FDT_ERR_NOTFOUND;
> > +       }
> > +       config->horiz_timing[FDT_LCD_TIMING_REF_TO_SYNC] = 11;
> 
> It is assigned to 11.

when replying, please delete anything you aren't quoting.  in this case, there 
was over 1000 lines of content that was just noise.  it makes it hard to see 
what your responses are if you don't clip.
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20120719/464fa53e/attachment.pgp>

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

* [U-Boot] [PATCH v3 13/18] lcd: Add support for flushing LCD fb from dcache after update
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 13/18] lcd: Add support for flushing LCD fb from dcache after update Simon Glass
  2012-07-19 14:01   ` Mike Frysinger
@ 2012-07-19 16:52   ` Mike Frysinger
  2012-08-09  7:43   ` Lukasz Majewski
  2 siblings, 0 replies; 81+ messages in thread
From: Mike Frysinger @ 2012-07-19 16:52 UTC (permalink / raw)
  To: u-boot

On Thursday 12 July 2012 11:25:13 Simon Glass wrote:
> +void lcd_sync(void)
> +{
> +	/*
> +	 * flush_dcache_range() is declared in common.h but it seems that some
> +	 * architectures do not actually implement it. Is there a way to find
> +	 * out whether it exists? For now, ARM is safe.
> +	 */
> +#ifdef CONFIG_ARM
> +	int line_length;
> +
> +	if (lcd_flush_dcache)
> +		flush_dcache_range((u32)lcd_base,
> +			(u32)(lcd_base + lcd_get_size(&line_length)));
> +#endif
> +}

hmm, i think this should be more fine grained

>  	/* Clear the last one */
>  	memset (CONSOLE_ROW_LAST, COLOR_MASK(lcd_color_bg), CONSOLE_ROW_SIZE);
> +	lcd_sync();
>  }

this requires only updating one row and not the entire display right ?  so we 
should only flush that one line.  seems like other parts suffer similar over-
flushing behavior.

> +/**
> + * Set whether we need to flush the dcache when changing the LCD image.
> + * This defaults to off.

i wonder if this default is correct.  perhaps it should default to 1 since 
setting up custom memory maps to disable cache is fairly specially.
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20120719/fbbd86f2/attachment.pgp>

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

* Re: [PATCH v3 06/18] tegra: fdt: Add LCD definitions for Tegra
  2012-07-12 15:25     ` [U-Boot] " Simon Glass
@ 2012-07-31  9:27         ` Simon Glass
  -1 siblings, 0 replies; 81+ messages in thread
From: Simon Glass @ 2012-07-31  9:27 UTC (permalink / raw)
  To: U-Boot Mailing List
  Cc: Stephen Warren, Devicetree Discuss, Jerry Van Baren, Tom Warren

+Thierry

Hi,

On Thu, Jul 12, 2012 at 4:25 PM, Simon Glass <sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org> wrote:
> Add LCD definitions and also a proposed binding for LCD displays.
>
> The PWM is as per what will likely be committed to linux-next soon.
>
> The displaymode binding comes from a proposal here:
>
> http://lists.freedesktop.org/archives/dri-devel/2012-July/024875.html
>
> The panel binding is new, and fills a need to specify the panel
> timings and other tegra-specific information. Should a binding appear
> that allows the pwm to handle this automatically, we can revisit
> this.
>

Any comments on this binding please? The main addition from Thierry's
one posted on LMKL is the LCD resolution selection.

Regards,
Simon

> Signed-off-by: Simon Glass <sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
> ---
> Changes in v2:
> - Add nvidia prefix to device tree properties
>
> Changes in v3:
> - Add new panel binding to fit with tegra display controller binding
> - Bring in proposed tegra display controller binding
> - Use displaymode binding for fdt
>
>  arch/arm/dts/tegra20.dtsi                      |   89 ++++++++++++++++++++++++
>  doc/device-tree-bindings/video/displaymode.txt |   42 +++++++++++
>  doc/device-tree-bindings/video/tegra20-dc.txt  |   89 ++++++++++++++++++++++++
>  3 files changed, 220 insertions(+), 0 deletions(-)
>  create mode 100644 doc/device-tree-bindings/video/displaymode.txt
>  create mode 100644 doc/device-tree-bindings/video/tegra20-dc.txt
>
> diff --git a/arch/arm/dts/tegra20.dtsi b/arch/arm/dts/tegra20.dtsi
> index e7d1688..0b2ca3b 100644
> --- a/arch/arm/dts/tegra20.dtsi
> +++ b/arch/arm/dts/tegra20.dtsi
> @@ -211,4 +211,93 @@
>                 #pwm-cells = <2>;
>         };
>
> +       host1x {
> +               compatible = "nvidia,tegra20-host1x", "simple-bus";
> +               reg = <0x50000000 0x00024000>;
> +               interrupts = <0 65 0x04   /* mpcore syncpt */
> +                             0 67 0x04>; /* mpcore general */
> +
> +               #address-cells = <1>;
> +               #size-cells = <1>;
> +
> +               ranges = <0x54000000 0x54000000 0x04000000>;
> +
> +               /* video-encoding/decoding */
> +               mpe {
> +                       reg = <0x54040000 0x00040000>;
> +                       interrupts = <0 68 0x04>;
> +               };
> +
> +               /* video input */
> +               vi {
> +                       reg = <0x54080000 0x00040000>;
> +                       interrupts = <0 69 0x04>;
> +               };
> +
> +               /* EPP */
> +               epp {
> +                       reg = <0x540c0000 0x00040000>;
> +                       interrupts = <0 70 0x04>;
> +               };
> +
> +               /* ISP */
> +               isp {
> +                       reg = <0x54100000 0x00040000>;
> +                       interrupts = <0 71 0x04>;
> +               };
> +
> +               /* 2D engine */
> +               gr2d {
> +                       reg = <0x54140000 0x00040000>;
> +                       interrupts = <0 72 0x04>;
> +               };
> +
> +               /* 3D engine */
> +               gr3d {
> +                       reg = <0x54180000 0x00040000>;
> +               };
> +
> +               /* display controllers */
> +               dc@54200000 {
> +                       compatible = "nvidia,tegra20-dc";
> +                       reg = <0x54200000 0x00040000>;
> +                       interrupts = <0 73 0x04>;
> +
> +                       rgb {
> +                               status = "disabled";
> +                       };
> +               };
> +
> +               dc@54240000 {
> +                       compatible = "nvidia,tegra20-dc";
> +                       reg = <0x54240000 0x00040000>;
> +                       interrupts = <0 74 0x04>;
> +
> +                       rgb {
> +                               status = "disabled";
> +                       };
> +               };
> +
> +               /* outputs */
> +               hdmi {
> +                       compatible = "nvidia,tegra20-hdmi";
> +                       reg = <0x54280000 0x00040000>;
> +                       interrupts = <0 75 0x04>;
> +                       status = "disabled";
> +               };
> +
> +               tvo {
> +                       compatible = "nvidia,tegra20-tvo";
> +                       reg = <0x542c0000 0x00040000>;
> +                       interrupts = <0 76 0x04>;
> +                       status = "disabled";
> +               };
> +
> +               dsi {
> +                       compatible = "nvidia,tegra20-dsi";
> +                       reg = <0x54300000 0x00040000>;
> +                       status = "disabled";
> +               };
> +       };
> +
>  };
> diff --git a/doc/device-tree-bindings/video/displaymode.txt b/doc/device-tree-bindings/video/displaymode.txt
> new file mode 100644
> index 0000000..45ca42d
> --- /dev/null
> +++ b/doc/device-tree-bindings/video/displaymode.txt
> @@ -0,0 +1,42 @@
> +videomode bindings
> +==================
> +
> +(from http://lists.freedesktop.org/archives/dri-devel/2012-July/024875.html)
> +
> +Required properties:
> + - xres, yres: Display resolution
> + - left-margin, right-margin, hsync-len: Horizontal Display timing
> +   parameters in pixels
> + - upper-margin, lower-margin, vsync-len: Vertical display timing
> +   parameters in lines
> + - clock: display clock in Hz
> +
> +Optional properties:
> + - width-mm, height-mm: Display dimensions in mm
> + - hsync-active-high (bool): Hsync pulse is active high
> + - vsync-active-high (bool): Vsync pulse is active high
> + - interlaced (bool): This is an interlaced mode
> + - doublescan (bool): This is a doublescan mode
> +
> +There are different ways of describing a display mode. The devicetree
> +representation corresponds to the one used by the Linux Framebuffer
> +framework described here in Documentation/fb/framebuffer.txt. This
> +representation has been chosen because it's the only format which does
> +not allow for inconsistent parameters. Unlike the Framebuffer framework
> +the devicetree has the clock in Hz instead of ps.
> +
> +Example:
> +
> +       display@0 {
> +               /* 1920x1080p24 */
> +               clock = <52000000>;
> +               xres = <1920>;
> +               yres = <1080>;
> +               left-margin = <25>;
> +               right-margin = <25>;
> +               hsync-len = <25>;
> +               lower-margin = <2>;
> +               upper-margin = <2>;
> +               vsync-len = <2>;
> +               hsync-active-high;
> +       };
> diff --git a/doc/device-tree-bindings/video/tegra20-dc.txt b/doc/device-tree-bindings/video/tegra20-dc.txt
> new file mode 100644
> index 0000000..dcfd652
> --- /dev/null
> +++ b/doc/device-tree-bindings/video/tegra20-dc.txt
> @@ -0,0 +1,89 @@
> +Display Controller
> +------------------
> +
> +(there isn't yet a generic binding in Linux, so this describes what is in
> +U-Boot, and may change based on Linux activity)
> +
> +The device node for a display device is as described in the document
> +"Open Firmware Recommended Practice : Universal Serial Bus" with the
> +following modifications and additions :
> +
> +Required properties :
> + - compatible : Should be "nvidia,tegra20-dc"
> +
> +Required subnode 'rgb'. This has the properties listed in displaymode.txt
> +as well as:
> +
> +Required properties (rgb) :
> + - nvidia,panel : phandle of LCD panel information
> + - nvidia,bits-per-pixel: number of bits per pixel (depth)
> +
> +Optional properties (rgb):
> + - nvidia,frame-buffer: address of frame buffer (if omitted it will be
> +               calculated)
> +       - This may be useful to share an address between U-Boot and Linux and
> +               avoid boot-time corruption / flicker
> +
> +
> +The panel node describes the panel itself.
> +
> +Required properties (panel) :
> + - nvidia,pwm : pwm to use to set display contrast (see tegra20-pwm.txt)
> + - nvidia,panel-timings: 4 cells containing required timings in ms:
> +       * delay between panel_vdd-rise and data-rise
> +       * delay between data-rise and backlight_vdd-rise
> +       * delay between backlight_vdd and pwm-rise
> +       * delay between pwm-rise and backlight_en-rise
> +
> +Optional GPIO properies all have (phandle, GPIO number, flags):
> + - nvidia,backlight-enable-gpios: backlight enable GPIO
> + - nvidia,lvds-shutdown-gpios: LVDS power shutdown GPIO
> + - nvidia,backlight-vdd-gpios: backlight power GPIO
> + - nvidia,panel-vdd-gpios: panel power GPIO
> +
> +Example:
> +
> +host1x {
> +       compatible = "nvidia,tegra20-host1x", "simple-bus";
> +       reg = <0x50000000 0x00024000>;
> +       interrupts = <0 65 0x04   /* mpcore syncpt */
> +                       0 67 0x04>; /* mpcore general */
> +
> +       #address-cells = <1>;
> +       #size-cells = <1>;
> +
> +       ranges = <0x54000000 0x54000000 0x04000000>;
> +
> +       dc@54200000 {
> +               compatible = "nvidia,tegra20-dc";
> +               reg = <0x54200000 0x00040000>;
> +               interrupts = <0 73 0x04>;
> +
> +               rgb {
> +                       status = "okay";
> +                       /* Seaboard has 1366x768 */
> +                       clock = <70600000>;
> +                       xres = <1366>;
> +                       yres = <768>;
> +                       left-margin = <58>;
> +                       right-margin = <58>;
> +                       hsync-len = <58>;
> +                       lower-margin = <4>;
> +                       upper-margin = <4>;
> +                       vsync-len = <4>;
> +                       hsync-active-high;
> +                       nvidia,frame-buffer = <0x2f680000>;
> +                       nvidia,bits-per-pixel = <16>;
> +                       nvidia,panel = <&lcd_panel>;
> +               };
> +       };
> +};
> +
> +lcd_panel: panel {
> +       nvidia,pwm = <&pwm 2 0>;
> +       nvidia,backlight-enable-gpios = <&gpio 28 0>;   /* PD4 */
> +       nvidia,lvds-shutdown-gpios = <&gpio 10 0>;      /* PB2 */
> +       nvidia,backlight-vdd-gpios = <&gpio 176 0>;     /* PW0 */
> +       nvidia,panel-vdd-gpios = <&gpio 22 0>;          /* PC6 */
> +       nvidia,panel-timings = <4 203 17 15>;
> +};
> --
> 1.7.7.3
>

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

* [U-Boot] [PATCH v3 06/18] tegra: fdt: Add LCD definitions for Tegra
@ 2012-07-31  9:27         ` Simon Glass
  0 siblings, 0 replies; 81+ messages in thread
From: Simon Glass @ 2012-07-31  9:27 UTC (permalink / raw)
  To: u-boot

+Thierry

Hi,

On Thu, Jul 12, 2012 at 4:25 PM, Simon Glass <sjg@chromium.org> wrote:
> Add LCD definitions and also a proposed binding for LCD displays.
>
> The PWM is as per what will likely be committed to linux-next soon.
>
> The displaymode binding comes from a proposal here:
>
> http://lists.freedesktop.org/archives/dri-devel/2012-July/024875.html
>
> The panel binding is new, and fills a need to specify the panel
> timings and other tegra-specific information. Should a binding appear
> that allows the pwm to handle this automatically, we can revisit
> this.
>

Any comments on this binding please? The main addition from Thierry's
one posted on LMKL is the LCD resolution selection.

Regards,
Simon

> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
> Changes in v2:
> - Add nvidia prefix to device tree properties
>
> Changes in v3:
> - Add new panel binding to fit with tegra display controller binding
> - Bring in proposed tegra display controller binding
> - Use displaymode binding for fdt
>
>  arch/arm/dts/tegra20.dtsi                      |   89 ++++++++++++++++++++++++
>  doc/device-tree-bindings/video/displaymode.txt |   42 +++++++++++
>  doc/device-tree-bindings/video/tegra20-dc.txt  |   89 ++++++++++++++++++++++++
>  3 files changed, 220 insertions(+), 0 deletions(-)
>  create mode 100644 doc/device-tree-bindings/video/displaymode.txt
>  create mode 100644 doc/device-tree-bindings/video/tegra20-dc.txt
>
> diff --git a/arch/arm/dts/tegra20.dtsi b/arch/arm/dts/tegra20.dtsi
> index e7d1688..0b2ca3b 100644
> --- a/arch/arm/dts/tegra20.dtsi
> +++ b/arch/arm/dts/tegra20.dtsi
> @@ -211,4 +211,93 @@
>                 #pwm-cells = <2>;
>         };
>
> +       host1x {
> +               compatible = "nvidia,tegra20-host1x", "simple-bus";
> +               reg = <0x50000000 0x00024000>;
> +               interrupts = <0 65 0x04   /* mpcore syncpt */
> +                             0 67 0x04>; /* mpcore general */
> +
> +               #address-cells = <1>;
> +               #size-cells = <1>;
> +
> +               ranges = <0x54000000 0x54000000 0x04000000>;
> +
> +               /* video-encoding/decoding */
> +               mpe {
> +                       reg = <0x54040000 0x00040000>;
> +                       interrupts = <0 68 0x04>;
> +               };
> +
> +               /* video input */
> +               vi {
> +                       reg = <0x54080000 0x00040000>;
> +                       interrupts = <0 69 0x04>;
> +               };
> +
> +               /* EPP */
> +               epp {
> +                       reg = <0x540c0000 0x00040000>;
> +                       interrupts = <0 70 0x04>;
> +               };
> +
> +               /* ISP */
> +               isp {
> +                       reg = <0x54100000 0x00040000>;
> +                       interrupts = <0 71 0x04>;
> +               };
> +
> +               /* 2D engine */
> +               gr2d {
> +                       reg = <0x54140000 0x00040000>;
> +                       interrupts = <0 72 0x04>;
> +               };
> +
> +               /* 3D engine */
> +               gr3d {
> +                       reg = <0x54180000 0x00040000>;
> +               };
> +
> +               /* display controllers */
> +               dc at 54200000 {
> +                       compatible = "nvidia,tegra20-dc";
> +                       reg = <0x54200000 0x00040000>;
> +                       interrupts = <0 73 0x04>;
> +
> +                       rgb {
> +                               status = "disabled";
> +                       };
> +               };
> +
> +               dc at 54240000 {
> +                       compatible = "nvidia,tegra20-dc";
> +                       reg = <0x54240000 0x00040000>;
> +                       interrupts = <0 74 0x04>;
> +
> +                       rgb {
> +                               status = "disabled";
> +                       };
> +               };
> +
> +               /* outputs */
> +               hdmi {
> +                       compatible = "nvidia,tegra20-hdmi";
> +                       reg = <0x54280000 0x00040000>;
> +                       interrupts = <0 75 0x04>;
> +                       status = "disabled";
> +               };
> +
> +               tvo {
> +                       compatible = "nvidia,tegra20-tvo";
> +                       reg = <0x542c0000 0x00040000>;
> +                       interrupts = <0 76 0x04>;
> +                       status = "disabled";
> +               };
> +
> +               dsi {
> +                       compatible = "nvidia,tegra20-dsi";
> +                       reg = <0x54300000 0x00040000>;
> +                       status = "disabled";
> +               };
> +       };
> +
>  };
> diff --git a/doc/device-tree-bindings/video/displaymode.txt b/doc/device-tree-bindings/video/displaymode.txt
> new file mode 100644
> index 0000000..45ca42d
> --- /dev/null
> +++ b/doc/device-tree-bindings/video/displaymode.txt
> @@ -0,0 +1,42 @@
> +videomode bindings
> +==================
> +
> +(from http://lists.freedesktop.org/archives/dri-devel/2012-July/024875.html)
> +
> +Required properties:
> + - xres, yres: Display resolution
> + - left-margin, right-margin, hsync-len: Horizontal Display timing
> +   parameters in pixels
> + - upper-margin, lower-margin, vsync-len: Vertical display timing
> +   parameters in lines
> + - clock: display clock in Hz
> +
> +Optional properties:
> + - width-mm, height-mm: Display dimensions in mm
> + - hsync-active-high (bool): Hsync pulse is active high
> + - vsync-active-high (bool): Vsync pulse is active high
> + - interlaced (bool): This is an interlaced mode
> + - doublescan (bool): This is a doublescan mode
> +
> +There are different ways of describing a display mode. The devicetree
> +representation corresponds to the one used by the Linux Framebuffer
> +framework described here in Documentation/fb/framebuffer.txt. This
> +representation has been chosen because it's the only format which does
> +not allow for inconsistent parameters. Unlike the Framebuffer framework
> +the devicetree has the clock in Hz instead of ps.
> +
> +Example:
> +
> +       display at 0 {
> +               /* 1920x1080p24 */
> +               clock = <52000000>;
> +               xres = <1920>;
> +               yres = <1080>;
> +               left-margin = <25>;
> +               right-margin = <25>;
> +               hsync-len = <25>;
> +               lower-margin = <2>;
> +               upper-margin = <2>;
> +               vsync-len = <2>;
> +               hsync-active-high;
> +       };
> diff --git a/doc/device-tree-bindings/video/tegra20-dc.txt b/doc/device-tree-bindings/video/tegra20-dc.txt
> new file mode 100644
> index 0000000..dcfd652
> --- /dev/null
> +++ b/doc/device-tree-bindings/video/tegra20-dc.txt
> @@ -0,0 +1,89 @@
> +Display Controller
> +------------------
> +
> +(there isn't yet a generic binding in Linux, so this describes what is in
> +U-Boot, and may change based on Linux activity)
> +
> +The device node for a display device is as described in the document
> +"Open Firmware Recommended Practice : Universal Serial Bus" with the
> +following modifications and additions :
> +
> +Required properties :
> + - compatible : Should be "nvidia,tegra20-dc"
> +
> +Required subnode 'rgb'. This has the properties listed in displaymode.txt
> +as well as:
> +
> +Required properties (rgb) :
> + - nvidia,panel : phandle of LCD panel information
> + - nvidia,bits-per-pixel: number of bits per pixel (depth)
> +
> +Optional properties (rgb):
> + - nvidia,frame-buffer: address of frame buffer (if omitted it will be
> +               calculated)
> +       - This may be useful to share an address between U-Boot and Linux and
> +               avoid boot-time corruption / flicker
> +
> +
> +The panel node describes the panel itself.
> +
> +Required properties (panel) :
> + - nvidia,pwm : pwm to use to set display contrast (see tegra20-pwm.txt)
> + - nvidia,panel-timings: 4 cells containing required timings in ms:
> +       * delay between panel_vdd-rise and data-rise
> +       * delay between data-rise and backlight_vdd-rise
> +       * delay between backlight_vdd and pwm-rise
> +       * delay between pwm-rise and backlight_en-rise
> +
> +Optional GPIO properies all have (phandle, GPIO number, flags):
> + - nvidia,backlight-enable-gpios: backlight enable GPIO
> + - nvidia,lvds-shutdown-gpios: LVDS power shutdown GPIO
> + - nvidia,backlight-vdd-gpios: backlight power GPIO
> + - nvidia,panel-vdd-gpios: panel power GPIO
> +
> +Example:
> +
> +host1x {
> +       compatible = "nvidia,tegra20-host1x", "simple-bus";
> +       reg = <0x50000000 0x00024000>;
> +       interrupts = <0 65 0x04   /* mpcore syncpt */
> +                       0 67 0x04>; /* mpcore general */
> +
> +       #address-cells = <1>;
> +       #size-cells = <1>;
> +
> +       ranges = <0x54000000 0x54000000 0x04000000>;
> +
> +       dc at 54200000 {
> +               compatible = "nvidia,tegra20-dc";
> +               reg = <0x54200000 0x00040000>;
> +               interrupts = <0 73 0x04>;
> +
> +               rgb {
> +                       status = "okay";
> +                       /* Seaboard has 1366x768 */
> +                       clock = <70600000>;
> +                       xres = <1366>;
> +                       yres = <768>;
> +                       left-margin = <58>;
> +                       right-margin = <58>;
> +                       hsync-len = <58>;
> +                       lower-margin = <4>;
> +                       upper-margin = <4>;
> +                       vsync-len = <4>;
> +                       hsync-active-high;
> +                       nvidia,frame-buffer = <0x2f680000>;
> +                       nvidia,bits-per-pixel = <16>;
> +                       nvidia,panel = <&lcd_panel>;
> +               };
> +       };
> +};
> +
> +lcd_panel: panel {
> +       nvidia,pwm = <&pwm 2 0>;
> +       nvidia,backlight-enable-gpios = <&gpio 28 0>;   /* PD4 */
> +       nvidia,lvds-shutdown-gpios = <&gpio 10 0>;      /* PB2 */
> +       nvidia,backlight-vdd-gpios = <&gpio 176 0>;     /* PW0 */
> +       nvidia,panel-vdd-gpios = <&gpio 22 0>;          /* PC6 */
> +       nvidia,panel-timings = <4 203 17 15>;
> +};
> --
> 1.7.7.3
>

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

* [U-Boot] [PATCH v3 0/18] tegra: Add display driver and LCD support for Seaboard
  2012-07-19  7:58 ` [U-Boot] [PATCH v3 0/18] tegra: Add display driver and LCD support for Seaboard Thierry Reding
@ 2012-07-31  9:28   ` Simon Glass
  0 siblings, 0 replies; 81+ messages in thread
From: Simon Glass @ 2012-07-31  9:28 UTC (permalink / raw)
  To: u-boot

Hi Thierry,

On Thu, Jul 19, 2012 at 8:58 AM, Thierry Reding
<thierry.reding@avionic-design.de> wrote:
> On Thu, Jul 12, 2012 at 08:25:00AM -0700, Simon Glass wrote:
>> This series adds support for the Tegra2x's display peripheral. This
>> supports the LCD display on Seaboard and we use this to enable console
>> output in U-Boot on the LCD.
>>
>> Configuration is via the device tree. Proposed bindings are included
>> in this series, taken from pwm bindings that should be in linux-next,
>> a Tegra video binding that might be accepted in devicetree-discuss
>> and a proposed video mode binding posted to dri-devel.
>>
>> While I agree EDID is convenient for machines I would prefer to provide
>> a user-friendly way of selecting LCD settings as well, with EDID more
>> as a fallback and auto-detection when available.
>>
>> To improve performance two optimisations are offered:
>>
>> 1. The LCD frame buffer is cached, with the cache being flushed after
>> each newline sent to putc(), and in a few other situations. This
>> dramatically increases performance (around 10x). This requires a few
>> additions to the ARM cache support.
>>
>> 2. The console supports scrolling in steps of more than 1 line. This
>> speeds up scrolling output considerably, particularly commands like
>> 'printenv' which display a lot of output, and particular when the
>> dcache is off. This requires a new CONFIG and a change to the
>> console_scrollup() function.
>>
>> Changes in v2:
>> - Add new patch to use const in pinmux_config_pingroup/table()
>> - Add nvidia prefix to device tree properties
>> - Align tegra display using new CONFIG_LCD_ALIGNMENT feature
>> - Put the LCD cache flush logic into lcd_putc() instead of lcd_puts()
>> - Update LCD driver to deal with new fdt bindings
>> - Update seaboard LCD definitions for new fdt binding
>> - Use a more generic config CONFIG_LCD_ALIGNMENT for lcd alignment
>> - Use const where possible in funcmux
>>
>> Changes in v3:
>> - Add new commit for pwm binding and node
>> - Add new panel binding to fit with tegra display controller binding
>> - Add probe function to read in fdt parameters in display driver
>> - Add separate call to pwm_init() in board_init()
>> - Adjust LCD driver to use new SOC display driver structures
>> - Bring in proposed tegra display controller binding
>> - Decode fdt node within the pwm driver
>> - Fix tiny bug in mult-line lcd scrolling
>> - Handle a cached frame buffer out of normal U-Boot memory
>> - Introduce concept of a pwm channel, rather than separate peripherals
>> - Move some fdt decode code from LCD driver to SOC display driver
>> - Put the LCD cache flush logic back into lcd_puts()
>> - Remove LPW1 pin which is not needed by display
>> - Remove spurious newline from fdtdec_get_addr() debug output
>> - Rename fdt config structures
>> - Rename pwfm driver to pwm
>> - Separate display driver and LCD driver more in fdt
>> - Tidy up fdtdec_decode_gpios() debug output
>> - Use displaymode binding for fdt
>> - Use new proposed upstream pwm binding
>> - Use new pwm binding from pre-linux-next
>> - Use new upstream proposed LCD definitions
>>
>> Mayuresh Kulkarni (1):
>>   tegra: Enable display/lcd support on Seaboard
>>
>> Simon Glass (16):
>>   fdt: Tidy debugging, add to fdtdec_get_int/addr()
>>   fdt: Add header guard to fdtdec.h
>>   tegra: Use const for pinmux_config_pingroup/table()
>>   tegra: Add display support to funcmux
>>   tegra: fdt: Add pwm binding and node
>>   tegra: fdt: Add LCD definitions for Tegra
>>   tegra: Add support for PWM
>>   tegra: Add LCD driver
>>   tegra: Add LCD support to Nvidia boards
>>   arm: Add control over cachability of memory regions
>>   lcd: Add CONFIG_LCD_ALIGNMENT to select frame buffer alignment
>>   lcd: Add support for flushing LCD fb from dcache after update
>>   tegra: Align LCD frame buffer to section boundary
>>   tegra: Support control of cache settings for LCD
>>   tegra: fdt: Add LCD definitions for Seaboard
>>   lcd: Add CONSOLE_SCROLL_LINES option to speed console
>>
>> Wei Ni (1):
>>   tegra: Add SOC support for display/lcd
>
> I was able to make this work on the Medcom with the one workaround to
> make backlight and panel GPIOs optional and adding the corresponding DTS
> and configuration entries for Medcom, so:
>
> Tested-by: Thierry Reding <thierry.reding@avionic-design.de>

Thanks, I am waiting until the binding is agreed before addressing
comments and sending a new version.

>
> The display corruption does no longer seem to happen. While I haven't
> thoroughly reviewed, I think this is in pretty good shape. Thanks Simon.
>
> Thierry

Regards,
Simon

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

* Re: [PATCH v3 06/18] tegra: fdt: Add LCD definitions for Tegra
  2012-07-31  9:27         ` [U-Boot] " Simon Glass
@ 2012-07-31  9:51             ` Thierry Reding
  -1 siblings, 0 replies; 81+ messages in thread
From: Thierry Reding @ 2012-07-31  9:51 UTC (permalink / raw)
  To: Simon Glass
  Cc: Stephen Warren, Devicetree Discuss, U-Boot Mailing List,
	Jerry Van Baren, Tom Warren


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

On Tue, Jul 31, 2012 at 10:27:23AM +0100, Simon Glass wrote:
> +Thierry
> 
> Hi,
> 
> On Thu, Jul 12, 2012 at 4:25 PM, Simon Glass <sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org> wrote:
> > Add LCD definitions and also a proposed binding for LCD displays.
> >
> > The PWM is as per what will likely be committed to linux-next soon.
> >
> > The displaymode binding comes from a proposal here:
> >
> > http://lists.freedesktop.org/archives/dri-devel/2012-July/024875.html
> >
> > The panel binding is new, and fills a need to specify the panel
> > timings and other tegra-specific information. Should a binding appear
> > that allows the pwm to handle this automatically, we can revisit
> > this.
> >
> 
> Any comments on this binding please? The main addition from Thierry's
> one posted on LMKL is the LCD resolution selection.

There's no such thing as the panel bindings on Linux. I think nobody's
done that before, there's also no suitable software abstraction, but I
suppose that should be irrelevant for this discussion.

> > +Optional properties (rgb):
> > + - nvidia,frame-buffer: address of frame buffer (if omitted it will be
> > +               calculated)
> > +       - This may be useful to share an address between U-Boot and Linux and
> > +               avoid boot-time corruption / flicker
> > +
> > +
> > +The panel node describes the panel itself.
> > +
> > +Required properties (panel) :
> > + - nvidia,pwm : pwm to use to set display contrast (see tegra20-pwm.txt)
> > + - nvidia,panel-timings: 4 cells containing required timings in ms:
> > +       * delay between panel_vdd-rise and data-rise
> > +       * delay between data-rise and backlight_vdd-rise
> > +       * delay between backlight_vdd and pwm-rise
> > +       * delay between pwm-rise and backlight_en-rise
> > +
> > +Optional GPIO properies all have (phandle, GPIO number, flags):
> > + - nvidia,backlight-enable-gpios: backlight enable GPIO
> > + - nvidia,lvds-shutdown-gpios: LVDS power shutdown GPIO
> > + - nvidia,backlight-vdd-gpios: backlight power GPIO
> > + - nvidia,panel-vdd-gpios: panel power GPIO
> > +
> > +Example:
> > +
> > +host1x {
> > +       compatible = "nvidia,tegra20-host1x", "simple-bus";
> > +       reg = <0x50000000 0x00024000>;
> > +       interrupts = <0 65 0x04   /* mpcore syncpt */
> > +                       0 67 0x04>; /* mpcore general */
> > +
> > +       #address-cells = <1>;
> > +       #size-cells = <1>;
> > +
> > +       ranges = <0x54000000 0x54000000 0x04000000>;
> > +
> > +       dc@54200000 {
> > +               compatible = "nvidia,tegra20-dc";
> > +               reg = <0x54200000 0x00040000>;
> > +               interrupts = <0 73 0x04>;
> > +
> > +               rgb {
> > +                       status = "okay";
> > +                       /* Seaboard has 1366x768 */
> > +                       clock = <70600000>;
> > +                       xres = <1366>;
> > +                       yres = <768>;
> > +                       left-margin = <58>;
> > +                       right-margin = <58>;
> > +                       hsync-len = <58>;
> > +                       lower-margin = <4>;
> > +                       upper-margin = <4>;
> > +                       vsync-len = <4>;
> > +                       hsync-active-high;
> > +                       nvidia,frame-buffer = <0x2f680000>;
> > +                       nvidia,bits-per-pixel = <16>;
> > +                       nvidia,panel = <&lcd_panel>;
> > +               };

Perhaps it would be useful to add an extra node for the mode definition,
if only to keep the data separate from that of the rgb node. I know that
there currently are no other properties, but the rgb node was supposed
to define the output or connector. If ever the same needs to be done for
any of the TVO or DSI outputs, more properties may be needed.

Furthermore the code to parse this would be more generic because you
could pass it any DT node. Of course the nvidia,-prefixed properties
wouldn't be part of that subnode because they don't define the mode as
such.

Thinking about it some more, maybe the mode information should really be
part of the panel description below.

> > +       };
> > +};
> > +
> > +lcd_panel: panel {
> > +       nvidia,pwm = <&pwm 2 0>;
> > +       nvidia,backlight-enable-gpios = <&gpio 28 0>;   /* PD4 */
> > +       nvidia,lvds-shutdown-gpios = <&gpio 10 0>;      /* PB2 */
> > +       nvidia,backlight-vdd-gpios = <&gpio 176 0>;     /* PW0 */
> > +       nvidia,panel-vdd-gpios = <&gpio 22 0>;          /* PC6 */
> > +       nvidia,panel-timings = <4 203 17 15>;
> > +};

If we can reach some kind of agreement on the power-sequencing code that
Alexandre (Cc'ed) is working on, then this can be replaced with a more
generic description. This also has the usual problem of being a non-
addressable top-level node...

Thierry

[-- Attachment #1.2: Type: application/pgp-signature, Size: 836 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] 81+ messages in thread

* [U-Boot] [PATCH v3 06/18] tegra: fdt: Add LCD definitions for Tegra
@ 2012-07-31  9:51             ` Thierry Reding
  0 siblings, 0 replies; 81+ messages in thread
From: Thierry Reding @ 2012-07-31  9:51 UTC (permalink / raw)
  To: u-boot

On Tue, Jul 31, 2012 at 10:27:23AM +0100, Simon Glass wrote:
> +Thierry
> 
> Hi,
> 
> On Thu, Jul 12, 2012 at 4:25 PM, Simon Glass <sjg@chromium.org> wrote:
> > Add LCD definitions and also a proposed binding for LCD displays.
> >
> > The PWM is as per what will likely be committed to linux-next soon.
> >
> > The displaymode binding comes from a proposal here:
> >
> > http://lists.freedesktop.org/archives/dri-devel/2012-July/024875.html
> >
> > The panel binding is new, and fills a need to specify the panel
> > timings and other tegra-specific information. Should a binding appear
> > that allows the pwm to handle this automatically, we can revisit
> > this.
> >
> 
> Any comments on this binding please? The main addition from Thierry's
> one posted on LMKL is the LCD resolution selection.

There's no such thing as the panel bindings on Linux. I think nobody's
done that before, there's also no suitable software abstraction, but I
suppose that should be irrelevant for this discussion.

> > +Optional properties (rgb):
> > + - nvidia,frame-buffer: address of frame buffer (if omitted it will be
> > +               calculated)
> > +       - This may be useful to share an address between U-Boot and Linux and
> > +               avoid boot-time corruption / flicker
> > +
> > +
> > +The panel node describes the panel itself.
> > +
> > +Required properties (panel) :
> > + - nvidia,pwm : pwm to use to set display contrast (see tegra20-pwm.txt)
> > + - nvidia,panel-timings: 4 cells containing required timings in ms:
> > +       * delay between panel_vdd-rise and data-rise
> > +       * delay between data-rise and backlight_vdd-rise
> > +       * delay between backlight_vdd and pwm-rise
> > +       * delay between pwm-rise and backlight_en-rise
> > +
> > +Optional GPIO properies all have (phandle, GPIO number, flags):
> > + - nvidia,backlight-enable-gpios: backlight enable GPIO
> > + - nvidia,lvds-shutdown-gpios: LVDS power shutdown GPIO
> > + - nvidia,backlight-vdd-gpios: backlight power GPIO
> > + - nvidia,panel-vdd-gpios: panel power GPIO
> > +
> > +Example:
> > +
> > +host1x {
> > +       compatible = "nvidia,tegra20-host1x", "simple-bus";
> > +       reg = <0x50000000 0x00024000>;
> > +       interrupts = <0 65 0x04   /* mpcore syncpt */
> > +                       0 67 0x04>; /* mpcore general */
> > +
> > +       #address-cells = <1>;
> > +       #size-cells = <1>;
> > +
> > +       ranges = <0x54000000 0x54000000 0x04000000>;
> > +
> > +       dc at 54200000 {
> > +               compatible = "nvidia,tegra20-dc";
> > +               reg = <0x54200000 0x00040000>;
> > +               interrupts = <0 73 0x04>;
> > +
> > +               rgb {
> > +                       status = "okay";
> > +                       /* Seaboard has 1366x768 */
> > +                       clock = <70600000>;
> > +                       xres = <1366>;
> > +                       yres = <768>;
> > +                       left-margin = <58>;
> > +                       right-margin = <58>;
> > +                       hsync-len = <58>;
> > +                       lower-margin = <4>;
> > +                       upper-margin = <4>;
> > +                       vsync-len = <4>;
> > +                       hsync-active-high;
> > +                       nvidia,frame-buffer = <0x2f680000>;
> > +                       nvidia,bits-per-pixel = <16>;
> > +                       nvidia,panel = <&lcd_panel>;
> > +               };

Perhaps it would be useful to add an extra node for the mode definition,
if only to keep the data separate from that of the rgb node. I know that
there currently are no other properties, but the rgb node was supposed
to define the output or connector. If ever the same needs to be done for
any of the TVO or DSI outputs, more properties may be needed.

Furthermore the code to parse this would be more generic because you
could pass it any DT node. Of course the nvidia,-prefixed properties
wouldn't be part of that subnode because they don't define the mode as
such.

Thinking about it some more, maybe the mode information should really be
part of the panel description below.

> > +       };
> > +};
> > +
> > +lcd_panel: panel {
> > +       nvidia,pwm = <&pwm 2 0>;
> > +       nvidia,backlight-enable-gpios = <&gpio 28 0>;   /* PD4 */
> > +       nvidia,lvds-shutdown-gpios = <&gpio 10 0>;      /* PB2 */
> > +       nvidia,backlight-vdd-gpios = <&gpio 176 0>;     /* PW0 */
> > +       nvidia,panel-vdd-gpios = <&gpio 22 0>;          /* PC6 */
> > +       nvidia,panel-timings = <4 203 17 15>;
> > +};

If we can reach some kind of agreement on the power-sequencing code that
Alexandre (Cc'ed) is working on, then this can be replaced with a more
generic description. This also has the usual problem of being a non-
addressable top-level node...

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20120731/911be2da/attachment.pgp>

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

* Re: [PATCH v3 06/18] tegra: fdt: Add LCD definitions for Tegra
  2012-07-31  9:27         ` [U-Boot] " Simon Glass
@ 2012-07-31 16:12             ` Stephen Warren
  -1 siblings, 0 replies; 81+ messages in thread
From: Stephen Warren @ 2012-07-31 16:12 UTC (permalink / raw)
  To: Simon Glass
  Cc: Stephen Warren, Devicetree Discuss, U-Boot Mailing List,
	Jerry Van Baren, Tom Warren

On 07/31/2012 03:27 AM, Simon Glass wrote:
> On Thu, Jul 12, 2012 at 4:25 PM, Simon Glass <sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org> wrote:
>> Add LCD definitions and also a proposed binding for LCD displays.
>>
>> The PWM is as per what will likely be committed to linux-next soon.
>>
>> The displaymode binding comes from a proposal here:
>>
>> http://lists.freedesktop.org/archives/dri-devel/2012-July/024875.html
>>
>> The panel binding is new, and fills a need to specify the panel
>> timings and other tegra-specific information. Should a binding appear
>> that allows the pwm to handle this automatically, we can revisit
>> this.
> 
> Any comments on this binding please? The main addition from Thierry's
> one posted on LMKL is the LCD resolution selection.

I have some concerns about the way the mode is represented in the
binding; the timing parameters are quite different to how e.g. an EDID
DTD would represent them, which I think will lead to conversion mistakes
when writing the DT.

I'm trying to get along of Sascha's original email so I can join in on
that discussion.

>> diff --git a/doc/device-tree-bindings/video/tegra20-dc.txt b/doc/device-tree-bindings/video/tegra20-dc.txt

>> +Optional properties (rgb):
>> + - nvidia,frame-buffer: address of frame buffer (if omitted it will be
>> +               calculated)
>> +       - This may be useful to share an address between U-Boot and Linux and
>> +               avoid boot-time corruption / flicker

Why can't the display driver read this out of the display registers,
instead of requiring the same information to be passed using DT too?

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

* [U-Boot] [PATCH v3 06/18] tegra: fdt: Add LCD definitions for Tegra
@ 2012-07-31 16:12             ` Stephen Warren
  0 siblings, 0 replies; 81+ messages in thread
From: Stephen Warren @ 2012-07-31 16:12 UTC (permalink / raw)
  To: u-boot

On 07/31/2012 03:27 AM, Simon Glass wrote:
> On Thu, Jul 12, 2012 at 4:25 PM, Simon Glass <sjg@chromium.org> wrote:
>> Add LCD definitions and also a proposed binding for LCD displays.
>>
>> The PWM is as per what will likely be committed to linux-next soon.
>>
>> The displaymode binding comes from a proposal here:
>>
>> http://lists.freedesktop.org/archives/dri-devel/2012-July/024875.html
>>
>> The panel binding is new, and fills a need to specify the panel
>> timings and other tegra-specific information. Should a binding appear
>> that allows the pwm to handle this automatically, we can revisit
>> this.
> 
> Any comments on this binding please? The main addition from Thierry's
> one posted on LMKL is the LCD resolution selection.

I have some concerns about the way the mode is represented in the
binding; the timing parameters are quite different to how e.g. an EDID
DTD would represent them, which I think will lead to conversion mistakes
when writing the DT.

I'm trying to get along of Sascha's original email so I can join in on
that discussion.

>> diff --git a/doc/device-tree-bindings/video/tegra20-dc.txt b/doc/device-tree-bindings/video/tegra20-dc.txt

>> +Optional properties (rgb):
>> + - nvidia,frame-buffer: address of frame buffer (if omitted it will be
>> +               calculated)
>> +       - This may be useful to share an address between U-Boot and Linux and
>> +               avoid boot-time corruption / flicker

Why can't the display driver read this out of the display registers,
instead of requiring the same information to be passed using DT too?

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

* [U-Boot] [PATCH v3 13/18] lcd: Add support for flushing LCD fb from dcache after update
  2012-07-12 15:25 ` [U-Boot] [PATCH v3 13/18] lcd: Add support for flushing LCD fb from dcache after update Simon Glass
  2012-07-19 14:01   ` Mike Frysinger
  2012-07-19 16:52   ` Mike Frysinger
@ 2012-08-09  7:43   ` Lukasz Majewski
  2012-10-16 18:16     ` Simon Glass
  2 siblings, 1 reply; 81+ messages in thread
From: Lukasz Majewski @ 2012-08-09  7:43 UTC (permalink / raw)
  To: u-boot

Hi Simon,

> This provides an option for the LCD to flush the dcache after each
> update (puts, scroll or clear).
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
> Changes in v2:
> - Put the LCD cache flush logic into lcd_putc() instead of lcd_puts()
> 
> Changes in v3:
> - Put the LCD cache flush logic back into lcd_puts()
> 
>  common/lcd.c  |   46 +++++++++++++++++++++++++++++++++++++++-------
>  include/lcd.h |    8 ++++++++
>  2 files changed, 47 insertions(+), 7 deletions(-)
> 
> diff --git a/common/lcd.c b/common/lcd.c
> index 18525a7..f7514a4 100644
> --- a/common/lcd.c
> +++ b/common/lcd.c
> @@ -97,6 +97,9 @@ static void lcd_setbgcolor (int color);
>  
>  char lcd_is_enabled = 0;
>  
> +static char lcd_flush_dcache;	/* 1 to flush dcache after each
> lcd update */ +
> +
>  #ifdef	NOT_USED_SO_FAR
>  static void lcd_getcolreg (ushort regno,
>  				ushort *red, ushort *green, ushort
> *blue); @@ -105,6 +108,28 @@ static int lcd_getfgcolor (void);
>  
>  /************************************************************************/
>  
> +/* Flush LCD activity to the caches */
> +void lcd_sync(void)
> +{
> +	/*
> +	 * flush_dcache_range() is declared in common.h but it seems
> that some
> +	 * architectures do not actually implement it. Is there a
> way to find
> +	 * out whether it exists? For now, ARM is safe.
> +	 */
> +#ifdef CONFIG_ARM
> +	int line_length;
> +
> +	if (lcd_flush_dcache)
> +		flush_dcache_range((u32)lcd_base,
> +			(u32)(lcd_base +
> lcd_get_size(&line_length))); +#endif

I'm struggling with a similar problem - but not in console putc, but
at lcd_display_bitmap().

The solution (in mine case) is:
flush_dcache_range((unsigned long) fb,
		   (unsigned long) fb +
		   (lcd_line_length * height));
which takes the "real" image range (as it is defined by fb).

Flushing the lcd_base based range is a bit overkill for me.

> +}
> +
> +void lcd_set_flush_dcache(int flush)
> +{
> +	lcd_flush_dcache = (flush != 0);
> +}
> +

I'm wondering if this flush_dcache_range cannot be added directly to
relevant places in the code?

flush_dcache_* calls are either defined (for a relevant - cache aware
archs) or are dummy.

>  /*----------------------------------------------------------------------*/
>  
>  static void console_scrollup (void)
> @@ -114,6 +139,7 @@ static void console_scrollup (void)
>  
>  	/* Clear the last one */
>  	memset (CONSOLE_ROW_LAST, COLOR_MASK(lcd_color_bg),
> CONSOLE_ROW_SIZE);
> +	lcd_sync();
>  }
>  
>  /*----------------------------------------------------------------------*/
> @@ -144,6 +170,8 @@ static inline void console_newline (void)
>  		/* Scroll everything up */
>  		console_scrollup () ;
>  		--console_row;
> +	} else {
> +		lcd_sync();
>  	}
>  }
>  
> @@ -198,6 +226,7 @@ void lcd_puts (const char *s)
>  	while (*s) {
>  		lcd_putc (*s++);
>  	}
> +	lcd_sync();
>  }
>  
>  /*----------------------------------------------------------------------*/
> @@ -365,13 +394,6 @@ int drv_lcd_init (void)
>  }
>  
>  /*----------------------------------------------------------------------*/
> -static
> -int do_lcd_clear(cmd_tbl_t *cmdtp, int flag, int argc, char *const
> argv[]) -{
> -	lcd_clear();
> -	return 0;
> -}
> -
>  void lcd_clear(void)
>  {
>  #if LCD_BPP == LCD_MONOCHROME
> @@ -413,6 +435,14 @@ void lcd_clear(void)
>  
>  	console_col = 0;
>  	console_row = 0;
> +	lcd_sync();
> +}
> +
> +static int do_lcd_clear(cmd_tbl_t *cmdtp, int flag, int argc,
> +			char *const argv[])
> +{
> +	lcd_clear();
> +	return 0;
>  }
>  
>  U_BOOT_CMD(
> @@ -607,6 +637,7 @@ void bitmap_plot (int x, int y)
>  	}
>  
>  	WATCHDOG_RESET();
> +	lcd_sync();
>  }
>  #else
>  static inline void bitmap_plot(int x, int y) {}
> @@ -820,6 +851,7 @@ int lcd_display_bitmap(ulong bmp_image, int x,
> int y) break;
>  	};
>  
> +	lcd_sync();
>  	return (0);
>  }
>  #endif
> diff --git a/include/lcd.h b/include/lcd.h
> index 26f6d83..4363131 100644
> --- a/include/lcd.h
> +++ b/include/lcd.h
> @@ -57,6 +57,14 @@ extern void lcd_initcolregs (void);
>  extern struct bmp_image *gunzip_bmp(unsigned long addr, unsigned
> long *lenp); extern int bmp_display(ulong addr, int x, int y);
>  
> +/**
> + * Set whether we need to flush the dcache when changing the LCD
> image. This
> + * defaults to off.
> + *
> + * @param flush		non-zero to flush cache after update,
> 0 to skip
> + */
> +void lcd_set_flush_dcache(int flush);
> +
>  #if defined CONFIG_MPC823
>  /*
>   * LCD controller stucture for MPC823 CPU

Anyway, I'm looking forward for v4 version of this patch.

-- 
Best regards,

Lukasz Majewski

Samsung Poland R&D Center | Linux Platform Group

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

* [U-Boot] [PATCH v3 01/18] fdt: Tidy debugging, add to fdtdec_get_int/addr()
  2012-07-12 15:25     ` [U-Boot] " Simon Glass
  (?)
@ 2012-09-21 20:06     ` Anatolij Gustschin
  -1 siblings, 0 replies; 81+ messages in thread
From: Anatolij Gustschin @ 2012-09-21 20:06 UTC (permalink / raw)
  To: u-boot

On Thu, 12 Jul 2012 08:25:01 -0700
Simon Glass <sjg@chromium.org> wrote:

> The new debugging shows the value of integers and addresses read
> from the device tree and tidy up GPIO output.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
> Changes in v3:
> - Remove spurious newline from fdtdec_get_addr() debug output
> - Tidy up fdtdec_decode_gpios() debug output
> 
>  lib/fdtdec.c |   27 +++++++++++++++++++--------
>  1 files changed, 19 insertions(+), 8 deletions(-)

Applied to staging/agust at denx.de.

Thanks,
Anatolij

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

* [U-Boot] [PATCH v3 02/18] fdt: Add header guard to fdtdec.h
  2012-07-12 15:25   ` [U-Boot] " Simon Glass
  (?)
  (?)
@ 2012-09-21 20:08   ` Anatolij Gustschin
  -1 siblings, 0 replies; 81+ messages in thread
From: Anatolij Gustschin @ 2012-09-21 20:08 UTC (permalink / raw)
  To: u-boot

On Thu, 12 Jul 2012 08:25:02 -0700
Simon Glass <sjg@chromium.org> wrote:

> This makes it easier to include this header from other headers.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
> 
>  include/fdtdec.h |    3 +++
>  1 files changed, 3 insertions(+), 0 deletions(-)

Applied to staging/agust at denx.de.

Thanks,
Anatolij

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

* [U-Boot] [PATCH v3 07/18] tegra: Add support for PWM
  2012-07-19 13:55   ` Mike Frysinger
@ 2012-09-27 13:51     ` Simon Glass
  0 siblings, 0 replies; 81+ messages in thread
From: Simon Glass @ 2012-09-27 13:51 UTC (permalink / raw)
  To: u-boot

Hi Mike,

On Thu, Jul 19, 2012 at 6:55 AM, Mike Frysinger <vapier@gentoo.org> wrote:
> On Thursday 12 July 2012 11:25:07 Simon Glass wrote:
>> --- a/arch/arm/cpu/armv7/tegra2/Makefile
>> +++ b/arch/arm/cpu/armv7/tegra2/Makefile
>>
>> +COBJS-$(CONFIG_VIDEO_TEGRA) += pwm.o
>
> should this get its own knob ?  PWM isn't video specific ...

Probably a good idea, will do.

Regards,
Simon

> -mike

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

* Re: [PATCH v3 06/18] tegra: fdt: Add LCD definitions for Tegra
  2012-07-31 16:12             ` [U-Boot] " Stephen Warren
@ 2012-09-27 13:58               ` Simon Glass
  -1 siblings, 0 replies; 81+ messages in thread
From: Simon Glass @ 2012-09-27 13:58 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Stephen Warren, Devicetree Discuss, U-Boot Mailing List,
	Jerry Van Baren, Tom Warren

Hi Stephen,

On Tue, Jul 31, 2012 at 9:12 AM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 07/31/2012 03:27 AM, Simon Glass wrote:
>> On Thu, Jul 12, 2012 at 4:25 PM, Simon Glass <sjg@chromium.org> wrote:
>>> Add LCD definitions and also a proposed binding for LCD displays.
>>>
>>> The PWM is as per what will likely be committed to linux-next soon.
>>>
>>> The displaymode binding comes from a proposal here:
>>>
>>> http://lists.freedesktop.org/archives/dri-devel/2012-July/024875.html
>>>
>>> The panel binding is new, and fills a need to specify the panel
>>> timings and other tegra-specific information. Should a binding appear
>>> that allows the pwm to handle this automatically, we can revisit
>>> this.
>>
>> Any comments on this binding please? The main addition from Thierry's
>> one posted on LMKL is the LCD resolution selection.
>
> I have some concerns about the way the mode is represented in the
> binding; the timing parameters are quite different to how e.g. an EDID
> DTD would represent them, which I think will lead to conversion mistakes
> when writing the DT.
>
> I'm trying to get along of Sascha's original email so I can join in on
> that discussion.

Did you get any resolution here?

>
>>> diff --git a/doc/device-tree-bindings/video/tegra20-dc.txt b/doc/device-tree-bindings/video/tegra20-dc.txt
>
>>> +Optional properties (rgb):
>>> + - nvidia,frame-buffer: address of frame buffer (if omitted it will be
>>> +               calculated)
>>> +       - This may be useful to share an address between U-Boot and Linux and
>>> +               avoid boot-time corruption / flicker
>
> Why can't the display driver read this out of the display registers,
> instead of requiring the same information to be passed using DT too?

The U-Boot display driver needs to set this value in the display
registers - at reset I don't think we can rely on any particular
value.

Do you mean the kernel display driver? Well it could, but it doesn't.
Really this is just a way of getting U-Boot and Linux to agree on the
address, by having U-Boot know the address that the kernel will happen
to use. It isn't very robust, but we have found it useful as a means
of avoiding problems in this area.

Regards,
Simon

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

* [U-Boot] [PATCH v3 06/18] tegra: fdt: Add LCD definitions for Tegra
@ 2012-09-27 13:58               ` Simon Glass
  0 siblings, 0 replies; 81+ messages in thread
From: Simon Glass @ 2012-09-27 13:58 UTC (permalink / raw)
  To: u-boot

Hi Stephen,

On Tue, Jul 31, 2012 at 9:12 AM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 07/31/2012 03:27 AM, Simon Glass wrote:
>> On Thu, Jul 12, 2012 at 4:25 PM, Simon Glass <sjg@chromium.org> wrote:
>>> Add LCD definitions and also a proposed binding for LCD displays.
>>>
>>> The PWM is as per what will likely be committed to linux-next soon.
>>>
>>> The displaymode binding comes from a proposal here:
>>>
>>> http://lists.freedesktop.org/archives/dri-devel/2012-July/024875.html
>>>
>>> The panel binding is new, and fills a need to specify the panel
>>> timings and other tegra-specific information. Should a binding appear
>>> that allows the pwm to handle this automatically, we can revisit
>>> this.
>>
>> Any comments on this binding please? The main addition from Thierry's
>> one posted on LMKL is the LCD resolution selection.
>
> I have some concerns about the way the mode is represented in the
> binding; the timing parameters are quite different to how e.g. an EDID
> DTD would represent them, which I think will lead to conversion mistakes
> when writing the DT.
>
> I'm trying to get along of Sascha's original email so I can join in on
> that discussion.

Did you get any resolution here?

>
>>> diff --git a/doc/device-tree-bindings/video/tegra20-dc.txt b/doc/device-tree-bindings/video/tegra20-dc.txt
>
>>> +Optional properties (rgb):
>>> + - nvidia,frame-buffer: address of frame buffer (if omitted it will be
>>> +               calculated)
>>> +       - This may be useful to share an address between U-Boot and Linux and
>>> +               avoid boot-time corruption / flicker
>
> Why can't the display driver read this out of the display registers,
> instead of requiring the same information to be passed using DT too?

The U-Boot display driver needs to set this value in the display
registers - at reset I don't think we can rely on any particular
value.

Do you mean the kernel display driver? Well it could, but it doesn't.
Really this is just a way of getting U-Boot and Linux to agree on the
address, by having U-Boot know the address that the kernel will happen
to use. It isn't very robust, but we have found it useful as a means
of avoiding problems in this area.

Regards,
Simon

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

* Re: [PATCH v3 06/18] tegra: fdt: Add LCD definitions for Tegra
  2012-09-27 13:58               ` [U-Boot] " Simon Glass
@ 2012-09-27 15:49                   ` Stephen Warren
  -1 siblings, 0 replies; 81+ messages in thread
From: Stephen Warren @ 2012-09-27 15:49 UTC (permalink / raw)
  To: Simon Glass
  Cc: Stephen Warren, Devicetree Discuss, U-Boot Mailing List,
	Jerry Van Baren, Tom Warren

On 09/27/2012 07:58 AM, Simon Glass wrote:
> Hi Stephen,
> 
> On Tue, Jul 31, 2012 at 9:12 AM, Stephen Warren <swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org> wrote:
>> On 07/31/2012 03:27 AM, Simon Glass wrote:
>>> On Thu, Jul 12, 2012 at 4:25 PM, Simon Glass <sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org> wrote:
>>>> Add LCD definitions and also a proposed binding for LCD displays.
>>>>
>>>> The PWM is as per what will likely be committed to linux-next soon.
>>>>
>>>> The displaymode binding comes from a proposal here:
>>>>
>>>> http://lists.freedesktop.org/archives/dri-devel/2012-July/024875.html
>>>>
>>>> The panel binding is new, and fills a need to specify the panel
>>>> timings and other tegra-specific information. Should a binding appear
>>>> that allows the pwm to handle this automatically, we can revisit
>>>> this.
>>>
>>> Any comments on this binding please? The main addition from Thierry's
>>> one posted on LMKL is the LCD resolution selection.
>>
>> I have some concerns about the way the mode is represented in the
>> binding; the timing parameters are quite different to how e.g. an EDID
>> DTD would represent them, which I think will lead to conversion mistakes
>> when writing the DT.
>>
>> I'm trying to get along of Sascha's original email so I can join in on
>> that discussion.
> 
> Did you get any resolution here?

I think an updated version of those patches was published.

>>>> diff --git a/doc/device-tree-bindings/video/tegra20-dc.txt b/doc/device-tree-bindings/video/tegra20-dc.txt
>>
>>>> +Optional properties (rgb):
>>>> + - nvidia,frame-buffer: address of frame buffer (if omitted it will be
>>>> +               calculated)
>>>> +       - This may be useful to share an address between U-Boot and Linux and
>>>> +               avoid boot-time corruption / flicker
>>
>> Why can't the display driver read this out of the display registers,
>> instead of requiring the same information to be passed using DT too?
> 
> The U-Boot display driver needs to set this value in the display
> registers - at reset I don't think we can rely on any particular
> value.
> 
> Do you mean the kernel display driver?

Yes.

> Well it could, but it doesn't.

Well, there is no display driver in the upstream kernel at the moment,
so it's not possible to make assertions about what it does or not.

Any downstream kernels aren't relevant, since their DT bindings and/or
behaviour have not been through public review.

> Really this is just a way of getting U-Boot and Linux to agree on the
> address, by having U-Boot know the address that the kernel will happen
> to use. It isn't very robust, but we have found it useful as a means
> of avoiding problems in this area.

Right, but again, why can't the display driver simply read the address
out of the register; why is there a need to duplicate the data?

I guess one possibility is that the register only gives the base address
and not the size/mode of the allocated surface, but I don't recall if
this proposed binding did that either?

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

* [U-Boot] [PATCH v3 06/18] tegra: fdt: Add LCD definitions for Tegra
@ 2012-09-27 15:49                   ` Stephen Warren
  0 siblings, 0 replies; 81+ messages in thread
From: Stephen Warren @ 2012-09-27 15:49 UTC (permalink / raw)
  To: u-boot

On 09/27/2012 07:58 AM, Simon Glass wrote:
> Hi Stephen,
> 
> On Tue, Jul 31, 2012 at 9:12 AM, Stephen Warren <swarren@wwwdotorg.org> wrote:
>> On 07/31/2012 03:27 AM, Simon Glass wrote:
>>> On Thu, Jul 12, 2012 at 4:25 PM, Simon Glass <sjg@chromium.org> wrote:
>>>> Add LCD definitions and also a proposed binding for LCD displays.
>>>>
>>>> The PWM is as per what will likely be committed to linux-next soon.
>>>>
>>>> The displaymode binding comes from a proposal here:
>>>>
>>>> http://lists.freedesktop.org/archives/dri-devel/2012-July/024875.html
>>>>
>>>> The panel binding is new, and fills a need to specify the panel
>>>> timings and other tegra-specific information. Should a binding appear
>>>> that allows the pwm to handle this automatically, we can revisit
>>>> this.
>>>
>>> Any comments on this binding please? The main addition from Thierry's
>>> one posted on LMKL is the LCD resolution selection.
>>
>> I have some concerns about the way the mode is represented in the
>> binding; the timing parameters are quite different to how e.g. an EDID
>> DTD would represent them, which I think will lead to conversion mistakes
>> when writing the DT.
>>
>> I'm trying to get along of Sascha's original email so I can join in on
>> that discussion.
> 
> Did you get any resolution here?

I think an updated version of those patches was published.

>>>> diff --git a/doc/device-tree-bindings/video/tegra20-dc.txt b/doc/device-tree-bindings/video/tegra20-dc.txt
>>
>>>> +Optional properties (rgb):
>>>> + - nvidia,frame-buffer: address of frame buffer (if omitted it will be
>>>> +               calculated)
>>>> +       - This may be useful to share an address between U-Boot and Linux and
>>>> +               avoid boot-time corruption / flicker
>>
>> Why can't the display driver read this out of the display registers,
>> instead of requiring the same information to be passed using DT too?
> 
> The U-Boot display driver needs to set this value in the display
> registers - at reset I don't think we can rely on any particular
> value.
> 
> Do you mean the kernel display driver?

Yes.

> Well it could, but it doesn't.

Well, there is no display driver in the upstream kernel at the moment,
so it's not possible to make assertions about what it does or not.

Any downstream kernels aren't relevant, since their DT bindings and/or
behaviour have not been through public review.

> Really this is just a way of getting U-Boot and Linux to agree on the
> address, by having U-Boot know the address that the kernel will happen
> to use. It isn't very robust, but we have found it useful as a means
> of avoiding problems in this area.

Right, but again, why can't the display driver simply read the address
out of the register; why is there a need to duplicate the data?

I guess one possibility is that the register only gives the base address
and not the size/mode of the allocated surface, but I don't recall if
this proposed binding did that either?

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

* [U-Boot] [PATCH v3 09/18] tegra: Add LCD driver
  2012-07-19  7:41   ` Thierry Reding
@ 2012-09-27 17:28     ` Simon Glass
  0 siblings, 0 replies; 81+ messages in thread
From: Simon Glass @ 2012-09-27 17:28 UTC (permalink / raw)
  To: u-boot

Hi Thierry,

On Thu, Jul 19, 2012 at 12:41 AM, Thierry Reding
<thierry.reding@avionic-design.de> wrote:
> On Thu, Jul 12, 2012 at 08:25:09AM -0700, Simon Glass wrote:
>> This driver supports driving a single LCD and providing a U-Boot console
>> on it.
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> ---
>> Changes in v2:
>> - Update LCD driver to deal with new fdt bindings
>>
>> Changes in v3:
>> - Adjust LCD driver to use new SOC display driver structures
>> - Move some fdt decode code from LCD driver to SOC display driver
>> - Rename fdt config structures
>> - Use new pwm binding from pre-linux-next
>>
>>  drivers/video/Makefile |    1 +
>>  drivers/video/tegra.c  |  357 ++++++++++++++++++++++++++++++++++++++++++++++++
>>  2 files changed, 358 insertions(+), 0 deletions(-)
>>  create mode 100644 drivers/video/tegra.c
>>
> [...]
>> diff --git a/drivers/video/tegra.c b/drivers/video/tegra.c
> [...]
>> +static int fdt_decode_lcd(const void *blob, struct fdt_panel_config *config)
>> +{
>> +     int err;
>> +     int display_node;
>> +
>> +     disp_config = tegra_display_get_config();
>> +     if (!disp_config) {
>> +             debug("%s: Display controller is not configured\n", __func__);
>> +             return -1;
>> +     }
>> +     display_node = disp_config->panel_node;
>> +     if (display_node < 0) {
>> +             debug("%s: No panel configuration available\n", __func__);
>> +             return -1;
>> +     }
>> +
>> +     config->pwm_channel = pwm_request(blob, display_node, "nvidia,pwm");
>> +     if (config->pwm_channel < 0) {
>> +             debug("%s: Unable to request PWM channel\n", __func__);
>> +             return -1;
>> +     }
>> +
>> +     config->cache_type = fdtdec_get_int(blob, display_node,
>> +                                         "nvidia,cache-type",
>> +                                         FDT_LCD_CACHE_WRITE_BACK_FLUSH);
>> +
>> +     err = fdtdec_decode_gpio(blob, display_node,
>> +                               "nvidia,backlight-enable-gpios",
>> +                               &config->backlight_en);
>> +     err |= fdtdec_decode_gpio(blob, display_node,
>> +                     "nvidia,lvds-shutdown-gpios", &config->lvds_shutdown);
>> +     fdtdec_decode_gpio(blob, display_node, "nvidia,backlight-vdd-gpios",
>> +                        &config->backlight_vdd);
>> +     err |= fdtdec_decode_gpio(blob, display_node, "nvidia,panel-vdd-gpios",
>> +                               &config->panel_vdd);
>> +     if (err)
>> +             return -FDT_ERR_NOTFOUND;
>
> This effectively makes those GPIOs mandatory. The Medcom, however,
> doesn't have any of these, so I had to comment this return out to test
> the series. I know that this might be an unusual setup, but it's
> something that needs to be supported anyway.

I am taking another look at this. I will make these GPIOs optional.

Regards,
Simon

>
> Thierry

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

* [U-Boot] [PATCH v3 08/18] tegra: Add SOC support for display/lcd
  2012-07-19  8:03   ` Adam Jiang
  2012-07-19 14:13     ` Mike Frysinger
@ 2012-09-27 17:44     ` Simon Glass
  1 sibling, 0 replies; 81+ messages in thread
From: Simon Glass @ 2012-09-27 17:44 UTC (permalink / raw)
  To: u-boot

Hi,

On Thu, Jul 19, 2012 at 1:03 AM, Adam Jiang <chaoj@nvidia.com> wrote:
> On Thu, Jul 12, 2012 at 11:25:08PM +0800, Simon Glass wrote:
>> From: Wei Ni <wni@nvidia.com>
>>
>> Add support for the LCD peripheral at the Tegra2 SOC level. A separate
>> LCD driver will use this functionality to configure the display.
>>
>> Mayuresh Kulkarni:
>> - changes to remove bitfields and clean up for submission
>>
>> Simon Glass:
>> - simplify code, move clock control into here, clean-up
>>
>> Signed-off-by: Mayuresh Kulkarni <mkulkarni@nvidia.com>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> ---
>> Changes in v3:
>> - Add probe function to read in fdt parameters in display driver
>> - Separate display driver and LCD driver more in fdt
>>
>>  arch/arm/cpu/armv7/tegra2/display.c        |  389 ++++++++++++++++++++

>> +       if (!config->pixel_clock || bpp == -1 ||
>> +                       config->width == -1 || config->height == -1) {
>> +               debug("%s: Pixel parameters missing\n", __func__);
>> +               return -FDT_ERR_NOTFOUND;
>> +       }
>> +
>> +       /* Use a ref-to-sync of 1 always, and take this from the front porch */
>
> ref-to-sync is supposed to be 1 here.
>
>> +       back = fdtdec_get_int(blob, rgb, "left-margin", -1);
>> +       front = fdtdec_get_int(blob, rgb, "right-margin", -1);
>> +       ref = fdtdec_get_int(blob, rgb, "hsync-len", -1);
>> +       if ((back | front | ref) == -1) {
>> +               debug("%s: Horizontal parameters missing\n", __func__);
>> +               return -FDT_ERR_NOTFOUND;
>> +       }
>> +       config->horiz_timing[FDT_LCD_TIMING_REF_TO_SYNC] = 11;
>
> It is assigned to 11.

Thanks - have updated that.

>
> /Adam

Regards,
Simon

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

* [U-Boot] [PATCH v3 11/18] arm: Add control over cachability of memory regions
  2012-07-19 14:10     ` Mike Frysinger
@ 2012-09-27 17:54       ` Simon Glass
  0 siblings, 0 replies; 81+ messages in thread
From: Simon Glass @ 2012-09-27 17:54 UTC (permalink / raw)
  To: u-boot

Hi Albert and Mike,

On Thu, Jul 19, 2012 at 7:10 AM, Mike Frysinger <vapier@gentoo.org> wrote:
> On Thursday 12 July 2012 14:12:41 Albert ARIBAUD wrote:
>> On Thu, 12 Jul 2012 08:25:11 -0700, Simon Glass wrote:
>> > --- a/arch/arm/include/asm/system.h
>> > +++ b/arch/arm/include/asm/system.h
>> >
>> > +/* options available for data cache on each page */
>> > +enum dcache_option {
>> > +   DCACHE_OFF,
>> > +   DCACHE_WRITETHROUGH,
>> > +   DCACHE_WRITEBACK,
>> > +};
>> >
>> > --- a/arch/arm/lib/cache-cp15.c
>> > +++ b/arch/arm/lib/cache-cp15.c
>> >
>> > -static inline void dram_bank_mmu_setup(int bank)
>> > +void set_section_dcache(int section, enum dcache_option option)
>> >  {
>> > +   u32 value = section << MMU_SECTION_SHIFT | (3 << 10);
>> >     u32 *page_table = (u32 *)gd->tlb_addr;
>> > +
>> > +   switch (option) {
>> > +   case DCACHE_WRITETHROUGH:
>> > +           value |= 0x1a;
>> > +           break;
>> > +
>> > +   case DCACHE_WRITEBACK:
>> > +           value |= 0x1e;
>> > +           break;
>> > +
>> > +   case DCACHE_OFF:
>> > +           value |= 0x12;
>> > +           break;
>> > +   }
>>
>> what's the benefit of introducing an arbitrary enum rather than
>> defining DCACHE_WRITETHROUGH, DCACHE_WRITEBACK and DCACHE_OFF equal
>> respecitvely to 0x1a, 0x1e and 0x12? All it does is force this
>> switch case instead of a simple 'value |= option;' statement.
>
> if these magic bitmasks are going to be the same for all arm cores (the enum
> is in common arm header), then you can get the advantages of both:
> enum dcache_option {
>         DCACHE_OFF = 0x12,
>         DCACHE_WRITETHROUGH = 0x1a,
>         DCACHE_WRITEBACK = 0x1e,
> };
>
> then just do:
>         value |= option;

Yes you are both saying the same thing - sounds good. I will change it.

Regards,
Simon

> -mike

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

* [U-Boot] [PATCH v3 12/18] lcd: Add CONFIG_LCD_ALIGNMENT to select frame buffer alignment
  2012-07-19 13:59   ` Mike Frysinger
@ 2012-09-27 19:20     ` Simon Glass
  0 siblings, 0 replies; 81+ messages in thread
From: Simon Glass @ 2012-09-27 19:20 UTC (permalink / raw)
  To: u-boot

Hi Mike,

On Thu, Jul 19, 2012 at 6:59 AM, Mike Frysinger <vapier@gentoo.org> wrote:
> On Thursday 12 July 2012 11:25:12 Simon Glass wrote:
>> --- a/common/lcd.c
>> +++ b/common/lcd.c
>>
>> +#ifdef CONFIG_ARM
>> +#include <asm/system.h>
>> +#endif
>
> this header isn't ARM specific.  also, i think most arches just include this in
> their "main" points rather than any non-arch places including it explicitly.

Yes, I will remove this, thanks.

> -mike

Regards,
SImon

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

* [U-Boot] [PATCH v3 17/18] lcd: Add CONSOLE_SCROLL_LINES option to speed console
  2012-07-19 14:04   ` Mike Frysinger
@ 2012-09-27 19:23     ` Simon Glass
  0 siblings, 0 replies; 81+ messages in thread
From: Simon Glass @ 2012-09-27 19:23 UTC (permalink / raw)
  To: u-boot

Hi Mike,

On Thu, Jul 19, 2012 at 7:04 AM, Mike Frysinger <vapier@gentoo.org> wrote:
> On Thursday 12 July 2012 11:25:17 Simon Glass wrote:
>> --- a/README
>> +++ b/README
>>
>> +             CONSOLE_SCROLL_LINES
>> +
>> +             When the console need to be scrolled, this is the number of
>> +             lines to scroll by. It defaults to 1. Increasing this makes
>> +             the console jump but can help speed up operation when scrolling
>> +             is slow.
>
> board knobs should be CONFIG_xxx
>
>> --- a/common/lcd.c
>> +++ b/common/lcd.c
>>
>>  static void console_scrollup (void)
>>  {
>> +     int rows = 1;
>> +
>> +#ifdef CONSOLE_SCROLL_LINES
>> +     rows = CONSOLE_SCROLL_LINES;
>> +#endif
>
> seems like this should be at the top of the file:
> #ifndef CONSOLE_SCROLL_LINES
> # define CONSOLE_SCROLL_LINES 1
> #endif

Yes, both done, thanks.

> -mike

Regards,
Simon

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

* Re: [PATCH v3 06/18] tegra: fdt: Add LCD definitions for Tegra
  2012-07-31  9:51             ` [U-Boot] " Thierry Reding
@ 2012-09-27 19:44                 ` Simon Glass
  -1 siblings, 0 replies; 81+ messages in thread
From: Simon Glass @ 2012-09-27 19:44 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Stephen Warren, Devicetree Discuss, U-Boot Mailing List,
	Jerry Van Baren, Tom Warren

Hi Thierry,

On Tue, Jul 31, 2012 at 2:51 AM, Thierry Reding
<thierry.reding-RM9K5IK7kjKj5M59NBduVrNAH6kLmebB@public.gmane.org> wrote:
> On Tue, Jul 31, 2012 at 10:27:23AM +0100, Simon Glass wrote:
>> +Thierry
>>
>> Hi,
>>
>> On Thu, Jul 12, 2012 at 4:25 PM, Simon Glass <sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org> wrote:
>> > Add LCD definitions and also a proposed binding for LCD displays.
>> >
>> > The PWM is as per what will likely be committed to linux-next soon.
>> >
>> > The displaymode binding comes from a proposal here:
>> >
>> > http://lists.freedesktop.org/archives/dri-devel/2012-July/024875.html
>> >
>> > The panel binding is new, and fills a need to specify the panel
>> > timings and other tegra-specific information. Should a binding appear
>> > that allows the pwm to handle this automatically, we can revisit
>> > this.
>> >
>>
>> Any comments on this binding please? The main addition from Thierry's
>> one posted on LMKL is the LCD resolution selection.
>
> There's no such thing as the panel bindings on Linux. I think nobody's
> done that before, there's also no suitable software abstraction, but I
> suppose that should be irrelevant for this discussion.
>
>> > +Optional properties (rgb):
>> > + - nvidia,frame-buffer: address of frame buffer (if omitted it will be
>> > +               calculated)
>> > +       - This may be useful to share an address between U-Boot and Linux and
>> > +               avoid boot-time corruption / flicker
>> > +
>> > +
>> > +The panel node describes the panel itself.
>> > +
>> > +Required properties (panel) :
>> > + - nvidia,pwm : pwm to use to set display contrast (see tegra20-pwm.txt)
>> > + - nvidia,panel-timings: 4 cells containing required timings in ms:
>> > +       * delay between panel_vdd-rise and data-rise
>> > +       * delay between data-rise and backlight_vdd-rise
>> > +       * delay between backlight_vdd and pwm-rise
>> > +       * delay between pwm-rise and backlight_en-rise
>> > +
>> > +Optional GPIO properies all have (phandle, GPIO number, flags):
>> > + - nvidia,backlight-enable-gpios: backlight enable GPIO
>> > + - nvidia,lvds-shutdown-gpios: LVDS power shutdown GPIO
>> > + - nvidia,backlight-vdd-gpios: backlight power GPIO
>> > + - nvidia,panel-vdd-gpios: panel power GPIO
>> > +
>> > +Example:
>> > +
>> > +host1x {
>> > +       compatible = "nvidia,tegra20-host1x", "simple-bus";
>> > +       reg = <0x50000000 0x00024000>;
>> > +       interrupts = <0 65 0x04   /* mpcore syncpt */
>> > +                       0 67 0x04>; /* mpcore general */
>> > +
>> > +       #address-cells = <1>;
>> > +       #size-cells = <1>;
>> > +
>> > +       ranges = <0x54000000 0x54000000 0x04000000>;
>> > +
>> > +       dc@54200000 {
>> > +               compatible = "nvidia,tegra20-dc";
>> > +               reg = <0x54200000 0x00040000>;
>> > +               interrupts = <0 73 0x04>;
>> > +
>> > +               rgb {
>> > +                       status = "okay";
>> > +                       /* Seaboard has 1366x768 */
>> > +                       clock = <70600000>;
>> > +                       xres = <1366>;
>> > +                       yres = <768>;
>> > +                       left-margin = <58>;
>> > +                       right-margin = <58>;
>> > +                       hsync-len = <58>;
>> > +                       lower-margin = <4>;
>> > +                       upper-margin = <4>;
>> > +                       vsync-len = <4>;
>> > +                       hsync-active-high;
>> > +                       nvidia,frame-buffer = <0x2f680000>;
>> > +                       nvidia,bits-per-pixel = <16>;
>> > +                       nvidia,panel = <&lcd_panel>;
>> > +               };
>
> Perhaps it would be useful to add an extra node for the mode definition,
> if only to keep the data separate from that of the rgb node. I know that
> there currently are no other properties, but the rgb node was supposed
> to define the output or connector. If ever the same needs to be done for
> any of the TVO or DSI outputs, more properties may be needed.
>
> Furthermore the code to parse this would be more generic because you
> could pass it any DT node. Of course the nvidia,-prefixed properties
> wouldn't be part of that subnode because they don't define the mode as
> such.
>
> Thinking about it some more, maybe the mode information should really be
> part of the panel description below.

OK I will move it there, thanks.

>
>> > +       };
>> > +};
>> > +
>> > +lcd_panel: panel {
>> > +       nvidia,pwm = <&pwm 2 0>;
>> > +       nvidia,backlight-enable-gpios = <&gpio 28 0>;   /* PD4 */
>> > +       nvidia,lvds-shutdown-gpios = <&gpio 10 0>;      /* PB2 */
>> > +       nvidia,backlight-vdd-gpios = <&gpio 176 0>;     /* PW0 */
>> > +       nvidia,panel-vdd-gpios = <&gpio 22 0>;          /* PC6 */
>> > +       nvidia,panel-timings = <4 203 17 15>;
>> > +};
>
> If we can reach some kind of agreement on the power-sequencing code that
> Alexandre (Cc'ed) is working on, then this can be replaced with a more
> generic description. This also has the usual problem of being a non-
> addressable top-level node...

Yes, I have been following that. However, it would need quite a bit of
code to be written. I would like to leave this for a future owner if
possible.

Regards,
Simon

>
> Thierry

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

* [U-Boot] [PATCH v3 06/18] tegra: fdt: Add LCD definitions for Tegra
@ 2012-09-27 19:44                 ` Simon Glass
  0 siblings, 0 replies; 81+ messages in thread
From: Simon Glass @ 2012-09-27 19:44 UTC (permalink / raw)
  To: u-boot

Hi Thierry,

On Tue, Jul 31, 2012 at 2:51 AM, Thierry Reding
<thierry.reding@avionic-design.de> wrote:
> On Tue, Jul 31, 2012 at 10:27:23AM +0100, Simon Glass wrote:
>> +Thierry
>>
>> Hi,
>>
>> On Thu, Jul 12, 2012 at 4:25 PM, Simon Glass <sjg@chromium.org> wrote:
>> > Add LCD definitions and also a proposed binding for LCD displays.
>> >
>> > The PWM is as per what will likely be committed to linux-next soon.
>> >
>> > The displaymode binding comes from a proposal here:
>> >
>> > http://lists.freedesktop.org/archives/dri-devel/2012-July/024875.html
>> >
>> > The panel binding is new, and fills a need to specify the panel
>> > timings and other tegra-specific information. Should a binding appear
>> > that allows the pwm to handle this automatically, we can revisit
>> > this.
>> >
>>
>> Any comments on this binding please? The main addition from Thierry's
>> one posted on LMKL is the LCD resolution selection.
>
> There's no such thing as the panel bindings on Linux. I think nobody's
> done that before, there's also no suitable software abstraction, but I
> suppose that should be irrelevant for this discussion.
>
>> > +Optional properties (rgb):
>> > + - nvidia,frame-buffer: address of frame buffer (if omitted it will be
>> > +               calculated)
>> > +       - This may be useful to share an address between U-Boot and Linux and
>> > +               avoid boot-time corruption / flicker
>> > +
>> > +
>> > +The panel node describes the panel itself.
>> > +
>> > +Required properties (panel) :
>> > + - nvidia,pwm : pwm to use to set display contrast (see tegra20-pwm.txt)
>> > + - nvidia,panel-timings: 4 cells containing required timings in ms:
>> > +       * delay between panel_vdd-rise and data-rise
>> > +       * delay between data-rise and backlight_vdd-rise
>> > +       * delay between backlight_vdd and pwm-rise
>> > +       * delay between pwm-rise and backlight_en-rise
>> > +
>> > +Optional GPIO properies all have (phandle, GPIO number, flags):
>> > + - nvidia,backlight-enable-gpios: backlight enable GPIO
>> > + - nvidia,lvds-shutdown-gpios: LVDS power shutdown GPIO
>> > + - nvidia,backlight-vdd-gpios: backlight power GPIO
>> > + - nvidia,panel-vdd-gpios: panel power GPIO
>> > +
>> > +Example:
>> > +
>> > +host1x {
>> > +       compatible = "nvidia,tegra20-host1x", "simple-bus";
>> > +       reg = <0x50000000 0x00024000>;
>> > +       interrupts = <0 65 0x04   /* mpcore syncpt */
>> > +                       0 67 0x04>; /* mpcore general */
>> > +
>> > +       #address-cells = <1>;
>> > +       #size-cells = <1>;
>> > +
>> > +       ranges = <0x54000000 0x54000000 0x04000000>;
>> > +
>> > +       dc at 54200000 {
>> > +               compatible = "nvidia,tegra20-dc";
>> > +               reg = <0x54200000 0x00040000>;
>> > +               interrupts = <0 73 0x04>;
>> > +
>> > +               rgb {
>> > +                       status = "okay";
>> > +                       /* Seaboard has 1366x768 */
>> > +                       clock = <70600000>;
>> > +                       xres = <1366>;
>> > +                       yres = <768>;
>> > +                       left-margin = <58>;
>> > +                       right-margin = <58>;
>> > +                       hsync-len = <58>;
>> > +                       lower-margin = <4>;
>> > +                       upper-margin = <4>;
>> > +                       vsync-len = <4>;
>> > +                       hsync-active-high;
>> > +                       nvidia,frame-buffer = <0x2f680000>;
>> > +                       nvidia,bits-per-pixel = <16>;
>> > +                       nvidia,panel = <&lcd_panel>;
>> > +               };
>
> Perhaps it would be useful to add an extra node for the mode definition,
> if only to keep the data separate from that of the rgb node. I know that
> there currently are no other properties, but the rgb node was supposed
> to define the output or connector. If ever the same needs to be done for
> any of the TVO or DSI outputs, more properties may be needed.
>
> Furthermore the code to parse this would be more generic because you
> could pass it any DT node. Of course the nvidia,-prefixed properties
> wouldn't be part of that subnode because they don't define the mode as
> such.
>
> Thinking about it some more, maybe the mode information should really be
> part of the panel description below.

OK I will move it there, thanks.

>
>> > +       };
>> > +};
>> > +
>> > +lcd_panel: panel {
>> > +       nvidia,pwm = <&pwm 2 0>;
>> > +       nvidia,backlight-enable-gpios = <&gpio 28 0>;   /* PD4 */
>> > +       nvidia,lvds-shutdown-gpios = <&gpio 10 0>;      /* PB2 */
>> > +       nvidia,backlight-vdd-gpios = <&gpio 176 0>;     /* PW0 */
>> > +       nvidia,panel-vdd-gpios = <&gpio 22 0>;          /* PC6 */
>> > +       nvidia,panel-timings = <4 203 17 15>;
>> > +};
>
> If we can reach some kind of agreement on the power-sequencing code that
> Alexandre (Cc'ed) is working on, then this can be replaced with a more
> generic description. This also has the usual problem of being a non-
> addressable top-level node...

Yes, I have been following that. However, it would need quite a bit of
code to be written. I would like to leave this for a future owner if
possible.

Regards,
Simon

>
> Thierry

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

* Re: [PATCH v3 06/18] tegra: fdt: Add LCD definitions for Tegra
  2012-09-27 15:49                   ` [U-Boot] " Stephen Warren
@ 2012-09-27 20:27                     ` Simon Glass
  -1 siblings, 0 replies; 81+ messages in thread
From: Simon Glass @ 2012-09-27 20:27 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Stephen Warren, Devicetree Discuss, U-Boot Mailing List,
	Jerry Van Baren, Tom Warren

Hi Stephen,

On Thu, Sep 27, 2012 at 8:49 AM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 09/27/2012 07:58 AM, Simon Glass wrote:
>> Hi Stephen,
>>
>> On Tue, Jul 31, 2012 at 9:12 AM, Stephen Warren <swarren@wwwdotorg.org> wrote:
>>> On 07/31/2012 03:27 AM, Simon Glass wrote:
>>>> On Thu, Jul 12, 2012 at 4:25 PM, Simon Glass <sjg@chromium.org> wrote:
>>>>> Add LCD definitions and also a proposed binding for LCD displays.
>>>>>
>>>>> The PWM is as per what will likely be committed to linux-next soon.
>>>>>
>>>>> The displaymode binding comes from a proposal here:
>>>>>
>>>>> http://lists.freedesktop.org/archives/dri-devel/2012-July/024875.html
>>>>>
>>>>> The panel binding is new, and fills a need to specify the panel
>>>>> timings and other tegra-specific information. Should a binding appear
>>>>> that allows the pwm to handle this automatically, we can revisit
>>>>> this.
>>>>
>>>> Any comments on this binding please? The main addition from Thierry's
>>>> one posted on LMKL is the LCD resolution selection.
>>>
>>> I have some concerns about the way the mode is represented in the
>>> binding; the timing parameters are quite different to how e.g. an EDID
>>> DTD would represent them, which I think will lead to conversion mistakes
>>> when writing the DT.
>>>
>>> I'm trying to get along of Sascha's original email so I can join in on
>>> that discussion.
>>
>> Did you get any resolution here?
>
> I think an updated version of those patches was published.
>
>>>>> diff --git a/doc/device-tree-bindings/video/tegra20-dc.txt b/doc/device-tree-bindings/video/tegra20-dc.txt
>>>
>>>>> +Optional properties (rgb):
>>>>> + - nvidia,frame-buffer: address of frame buffer (if omitted it will be
>>>>> +               calculated)
>>>>> +       - This may be useful to share an address between U-Boot and Linux and
>>>>> +               avoid boot-time corruption / flicker
>>>
>>> Why can't the display driver read this out of the display registers,
>>> instead of requiring the same information to be passed using DT too?
>>
>> The U-Boot display driver needs to set this value in the display
>> registers - at reset I don't think we can rely on any particular
>> value.
>>
>> Do you mean the kernel display driver?
>
> Yes.
>
>> Well it could, but it doesn't.
>
> Well, there is no display driver in the upstream kernel at the moment,
> so it's not possible to make assertions about what it does or not.
>
> Any downstream kernels aren't relevant, since their DT bindings and/or
> behaviour have not been through public review.

OK, but typically the kernel selects its own address for the display.
It might be quite hard for the kernel to use the one defined by
U-Boot.

>
>> Really this is just a way of getting U-Boot and Linux to agree on the
>> address, by having U-Boot know the address that the kernel will happen
>> to use. It isn't very robust, but we have found it useful as a means
>> of avoiding problems in this area.
>
> Right, but again, why can't the display driver simply read the address
> out of the register; why is there a need to duplicate the data?
>
> I guess one possibility is that the register only gives the base address
> and not the size/mode of the allocated surface, but I don't recall if
> this proposed binding did that either?

So here is my explanation:

1. U-Boot would normally put the display right near the top of memory.
Instead, it figures out where the kernel will put it (somehow this
seems to often be at a fixed address) and uses that address.

2. That means that U-Boot will now have the display exactly where the
kernel wants it.

3. When U-Boot boots the kernel, it leaves the display running,
knowing that the kernel will not overwrite the frame buffer with its
own code / data.

4. The effect is that there is a seamless display transition from
U-Boot to the kernel.

Note this is only a hint - it can be omitted i.w.c. it isn't used.

So what do you think? Should we remove this entirely, or is it a useful hack?

Regards,
Simon

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

* [U-Boot] [PATCH v3 06/18] tegra: fdt: Add LCD definitions for Tegra
@ 2012-09-27 20:27                     ` Simon Glass
  0 siblings, 0 replies; 81+ messages in thread
From: Simon Glass @ 2012-09-27 20:27 UTC (permalink / raw)
  To: u-boot

Hi Stephen,

On Thu, Sep 27, 2012 at 8:49 AM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 09/27/2012 07:58 AM, Simon Glass wrote:
>> Hi Stephen,
>>
>> On Tue, Jul 31, 2012 at 9:12 AM, Stephen Warren <swarren@wwwdotorg.org> wrote:
>>> On 07/31/2012 03:27 AM, Simon Glass wrote:
>>>> On Thu, Jul 12, 2012 at 4:25 PM, Simon Glass <sjg@chromium.org> wrote:
>>>>> Add LCD definitions and also a proposed binding for LCD displays.
>>>>>
>>>>> The PWM is as per what will likely be committed to linux-next soon.
>>>>>
>>>>> The displaymode binding comes from a proposal here:
>>>>>
>>>>> http://lists.freedesktop.org/archives/dri-devel/2012-July/024875.html
>>>>>
>>>>> The panel binding is new, and fills a need to specify the panel
>>>>> timings and other tegra-specific information. Should a binding appear
>>>>> that allows the pwm to handle this automatically, we can revisit
>>>>> this.
>>>>
>>>> Any comments on this binding please? The main addition from Thierry's
>>>> one posted on LMKL is the LCD resolution selection.
>>>
>>> I have some concerns about the way the mode is represented in the
>>> binding; the timing parameters are quite different to how e.g. an EDID
>>> DTD would represent them, which I think will lead to conversion mistakes
>>> when writing the DT.
>>>
>>> I'm trying to get along of Sascha's original email so I can join in on
>>> that discussion.
>>
>> Did you get any resolution here?
>
> I think an updated version of those patches was published.
>
>>>>> diff --git a/doc/device-tree-bindings/video/tegra20-dc.txt b/doc/device-tree-bindings/video/tegra20-dc.txt
>>>
>>>>> +Optional properties (rgb):
>>>>> + - nvidia,frame-buffer: address of frame buffer (if omitted it will be
>>>>> +               calculated)
>>>>> +       - This may be useful to share an address between U-Boot and Linux and
>>>>> +               avoid boot-time corruption / flicker
>>>
>>> Why can't the display driver read this out of the display registers,
>>> instead of requiring the same information to be passed using DT too?
>>
>> The U-Boot display driver needs to set this value in the display
>> registers - at reset I don't think we can rely on any particular
>> value.
>>
>> Do you mean the kernel display driver?
>
> Yes.
>
>> Well it could, but it doesn't.
>
> Well, there is no display driver in the upstream kernel at the moment,
> so it's not possible to make assertions about what it does or not.
>
> Any downstream kernels aren't relevant, since their DT bindings and/or
> behaviour have not been through public review.

OK, but typically the kernel selects its own address for the display.
It might be quite hard for the kernel to use the one defined by
U-Boot.

>
>> Really this is just a way of getting U-Boot and Linux to agree on the
>> address, by having U-Boot know the address that the kernel will happen
>> to use. It isn't very robust, but we have found it useful as a means
>> of avoiding problems in this area.
>
> Right, but again, why can't the display driver simply read the address
> out of the register; why is there a need to duplicate the data?
>
> I guess one possibility is that the register only gives the base address
> and not the size/mode of the allocated surface, but I don't recall if
> this proposed binding did that either?

So here is my explanation:

1. U-Boot would normally put the display right near the top of memory.
Instead, it figures out where the kernel will put it (somehow this
seems to often be at a fixed address) and uses that address.

2. That means that U-Boot will now have the display exactly where the
kernel wants it.

3. When U-Boot boots the kernel, it leaves the display running,
knowing that the kernel will not overwrite the frame buffer with its
own code / data.

4. The effect is that there is a seamless display transition from
U-Boot to the kernel.

Note this is only a hint - it can be omitted i.w.c. it isn't used.

So what do you think? Should we remove this entirely, or is it a useful hack?

Regards,
Simon

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

* Re: [PATCH v3 06/18] tegra: fdt: Add LCD definitions for Tegra
  2012-09-27 20:27                     ` [U-Boot] " Simon Glass
@ 2012-09-27 23:21                         ` Stephen Warren
  -1 siblings, 0 replies; 81+ messages in thread
From: Stephen Warren @ 2012-09-27 23:21 UTC (permalink / raw)
  To: Simon Glass
  Cc: Stephen Warren, Devicetree Discuss, U-Boot Mailing List,
	Jerry Van Baren, Tom Warren

On 09/27/2012 02:27 PM, Simon Glass wrote:
> On Thu, Sep 27, 2012 at 8:49 AM, Stephen Warren <swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org> wrote:
>> On 09/27/2012 07:58 AM, Simon Glass wrote:
...
>>> Really this is just a way of getting U-Boot and Linux to agree on the
>>> address, by having U-Boot know the address that the kernel will happen
>>> to use. It isn't very robust, but we have found it useful as a means
>>> of avoiding problems in this area.
>>
>> Right, but again, why can't the display driver simply read the address
>> out of the register; why is there a need to duplicate the data?
>>
>> I guess one possibility is that the register only gives the base address
>> and not the size/mode of the allocated surface, but I don't recall if
>> this proposed binding did that either?
> 
> So here is my explanation:
> 
> 1. U-Boot would normally put the display right near the top of memory.
> Instead, it figures out where the kernel will put it (somehow this
> seems to often be at a fixed address) and uses that address.
> 
> 2. That means that U-Boot will now have the display exactly where the
> kernel wants it.

Oh, the DT property is telling U-Boot where to put the surface so that
when the kernel determines where to put it, it'll already be there?

That seems completely backwards. It's also extremely fragile; what if
the kernel suddenly starts allocating at some other random address,
which stops matching what U-Boot expects?

Far better would be for U-Boot to put the surface wherever it wants,
then manipulate the DT that's passed to the kernel to:

a) Add a /memreserve/ so that memory doesn't get re-used for anything
else during boot.

b) Add a property to the display node indicating which memreserve
represents the frame-buffer location.

When the kernel boots, it can:

* Copy the content from the U-Boot-allocated buffer to whatever display
buffer the kernel allocated before writing the new address to the HW.

* Undo the memory reservation triggered by the /memreserve/ to allow the
memory to be re-used.

> So what do you think? Should we remove this entirely, or is it a useful hack?

Yes, I think in its current form, it isn't useful.

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

* [U-Boot] [PATCH v3 06/18] tegra: fdt: Add LCD definitions for Tegra
@ 2012-09-27 23:21                         ` Stephen Warren
  0 siblings, 0 replies; 81+ messages in thread
From: Stephen Warren @ 2012-09-27 23:21 UTC (permalink / raw)
  To: u-boot

On 09/27/2012 02:27 PM, Simon Glass wrote:
> On Thu, Sep 27, 2012 at 8:49 AM, Stephen Warren <swarren@wwwdotorg.org> wrote:
>> On 09/27/2012 07:58 AM, Simon Glass wrote:
...
>>> Really this is just a way of getting U-Boot and Linux to agree on the
>>> address, by having U-Boot know the address that the kernel will happen
>>> to use. It isn't very robust, but we have found it useful as a means
>>> of avoiding problems in this area.
>>
>> Right, but again, why can't the display driver simply read the address
>> out of the register; why is there a need to duplicate the data?
>>
>> I guess one possibility is that the register only gives the base address
>> and not the size/mode of the allocated surface, but I don't recall if
>> this proposed binding did that either?
> 
> So here is my explanation:
> 
> 1. U-Boot would normally put the display right near the top of memory.
> Instead, it figures out where the kernel will put it (somehow this
> seems to often be at a fixed address) and uses that address.
> 
> 2. That means that U-Boot will now have the display exactly where the
> kernel wants it.

Oh, the DT property is telling U-Boot where to put the surface so that
when the kernel determines where to put it, it'll already be there?

That seems completely backwards. It's also extremely fragile; what if
the kernel suddenly starts allocating at some other random address,
which stops matching what U-Boot expects?

Far better would be for U-Boot to put the surface wherever it wants,
then manipulate the DT that's passed to the kernel to:

a) Add a /memreserve/ so that memory doesn't get re-used for anything
else during boot.

b) Add a property to the display node indicating which memreserve
represents the frame-buffer location.

When the kernel boots, it can:

* Copy the content from the U-Boot-allocated buffer to whatever display
buffer the kernel allocated before writing the new address to the HW.

* Undo the memory reservation triggered by the /memreserve/ to allow the
memory to be re-used.

> So what do you think? Should we remove this entirely, or is it a useful hack?

Yes, I think in its current form, it isn't useful.

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

* Re: [PATCH v3 06/18] tegra: fdt: Add LCD definitions for Tegra
  2012-09-27 23:21                         ` [U-Boot] " Stephen Warren
@ 2012-09-27 23:37                           ` Simon Glass
  -1 siblings, 0 replies; 81+ messages in thread
From: Simon Glass @ 2012-09-27 23:37 UTC (permalink / raw)
  To: Stephen Warren
  Cc: Stephen Warren, Devicetree Discuss, U-Boot Mailing List,
	Jerry Van Baren, Tom Warren

Hi Stephen,

On Thu, Sep 27, 2012 at 4:21 PM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 09/27/2012 02:27 PM, Simon Glass wrote:
>> On Thu, Sep 27, 2012 at 8:49 AM, Stephen Warren <swarren@wwwdotorg.org> wrote:
>>> On 09/27/2012 07:58 AM, Simon Glass wrote:
> ...
>>>> Really this is just a way of getting U-Boot and Linux to agree on the
>>>> address, by having U-Boot know the address that the kernel will happen
>>>> to use. It isn't very robust, but we have found it useful as a means
>>>> of avoiding problems in this area.
>>>
>>> Right, but again, why can't the display driver simply read the address
>>> out of the register; why is there a need to duplicate the data?
>>>
>>> I guess one possibility is that the register only gives the base address
>>> and not the size/mode of the allocated surface, but I don't recall if
>>> this proposed binding did that either?
>>
>> So here is my explanation:
>>
>> 1. U-Boot would normally put the display right near the top of memory.
>> Instead, it figures out where the kernel will put it (somehow this
>> seems to often be at a fixed address) and uses that address.
>>
>> 2. That means that U-Boot will now have the display exactly where the
>> kernel wants it.
>
> Oh, the DT property is telling U-Boot where to put the surface so that
> when the kernel determines where to put it, it'll already be there?
>
> That seems completely backwards. It's also extremely fragile; what if
> the kernel suddenly starts allocating at some other random address,
> which stops matching what U-Boot expects?

The screen will flicker, or may fill up with junk as the kernel boots.
We did have that happen once when the driver changed.

>
> Far better would be for U-Boot to put the surface wherever it wants,
> then manipulate the DT that's passed to the kernel to:
>
> a) Add a /memreserve/ so that memory doesn't get re-used for anything
> else during boot.
>
> b) Add a property to the display node indicating which memreserve
> represents the frame-buffer location.

Yes, I believe the Tegra video driver we used (and I take your point
that it doesn't exist upstream so there is no point in discussing it
:-) always had to use the same frame buffer address. The memory was
statically allocated. Certainly this could be encoded in the fdt.

>
> When the kernel boots, it can:
>
> * Copy the content from the U-Boot-allocated buffer to whatever display
> buffer the kernel allocated before writing the new address to the HW.
>
> * Undo the memory reservation triggered by the /memreserve/ to allow the
> memory to be re-used.
>
>> So what do you think? Should we remove this entirely, or is it a useful hack?
>
> Yes, I think in its current form, it isn't useful.

Thanks for the thorough response. Let's remove it, particularly as
there isn't even a kernel driver upstream yet.

I will do that before sending out the LCD v4 series. Thanks for your
timely comments.

Regards,
Simon

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

* [U-Boot] [PATCH v3 06/18] tegra: fdt: Add LCD definitions for Tegra
@ 2012-09-27 23:37                           ` Simon Glass
  0 siblings, 0 replies; 81+ messages in thread
From: Simon Glass @ 2012-09-27 23:37 UTC (permalink / raw)
  To: u-boot

Hi Stephen,

On Thu, Sep 27, 2012 at 4:21 PM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> On 09/27/2012 02:27 PM, Simon Glass wrote:
>> On Thu, Sep 27, 2012 at 8:49 AM, Stephen Warren <swarren@wwwdotorg.org> wrote:
>>> On 09/27/2012 07:58 AM, Simon Glass wrote:
> ...
>>>> Really this is just a way of getting U-Boot and Linux to agree on the
>>>> address, by having U-Boot know the address that the kernel will happen
>>>> to use. It isn't very robust, but we have found it useful as a means
>>>> of avoiding problems in this area.
>>>
>>> Right, but again, why can't the display driver simply read the address
>>> out of the register; why is there a need to duplicate the data?
>>>
>>> I guess one possibility is that the register only gives the base address
>>> and not the size/mode of the allocated surface, but I don't recall if
>>> this proposed binding did that either?
>>
>> So here is my explanation:
>>
>> 1. U-Boot would normally put the display right near the top of memory.
>> Instead, it figures out where the kernel will put it (somehow this
>> seems to often be at a fixed address) and uses that address.
>>
>> 2. That means that U-Boot will now have the display exactly where the
>> kernel wants it.
>
> Oh, the DT property is telling U-Boot where to put the surface so that
> when the kernel determines where to put it, it'll already be there?
>
> That seems completely backwards. It's also extremely fragile; what if
> the kernel suddenly starts allocating at some other random address,
> which stops matching what U-Boot expects?

The screen will flicker, or may fill up with junk as the kernel boots.
We did have that happen once when the driver changed.

>
> Far better would be for U-Boot to put the surface wherever it wants,
> then manipulate the DT that's passed to the kernel to:
>
> a) Add a /memreserve/ so that memory doesn't get re-used for anything
> else during boot.
>
> b) Add a property to the display node indicating which memreserve
> represents the frame-buffer location.

Yes, I believe the Tegra video driver we used (and I take your point
that it doesn't exist upstream so there is no point in discussing it
:-) always had to use the same frame buffer address. The memory was
statically allocated. Certainly this could be encoded in the fdt.

>
> When the kernel boots, it can:
>
> * Copy the content from the U-Boot-allocated buffer to whatever display
> buffer the kernel allocated before writing the new address to the HW.
>
> * Undo the memory reservation triggered by the /memreserve/ to allow the
> memory to be re-used.
>
>> So what do you think? Should we remove this entirely, or is it a useful hack?
>
> Yes, I think in its current form, it isn't useful.

Thanks for the thorough response. Let's remove it, particularly as
there isn't even a kernel driver upstream yet.

I will do that before sending out the LCD v4 series. Thanks for your
timely comments.

Regards,
Simon

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

* Re: [PATCH v3 06/18] tegra: fdt: Add LCD definitions for Tegra
  2012-09-27 23:37                           ` [U-Boot] " Simon Glass
@ 2012-09-28  5:42                               ` Thierry Reding
  -1 siblings, 0 replies; 81+ messages in thread
From: Thierry Reding @ 2012-09-28  5:42 UTC (permalink / raw)
  To: Simon Glass
  Cc: Stephen Warren, Devicetree Discuss, U-Boot Mailing List,
	Jerry Van Baren, Tom Warren


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

On Thu, Sep 27, 2012 at 04:37:41PM -0700, Simon Glass wrote:
> Hi Stephen,
> 
> On Thu, Sep 27, 2012 at 4:21 PM, Stephen Warren <swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org> wrote:
> > On 09/27/2012 02:27 PM, Simon Glass wrote:
> >> On Thu, Sep 27, 2012 at 8:49 AM, Stephen Warren <swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org> wrote:
> >>> On 09/27/2012 07:58 AM, Simon Glass wrote:
> > ...
> >>>> Really this is just a way of getting U-Boot and Linux to agree on the
> >>>> address, by having U-Boot know the address that the kernel will happen
> >>>> to use. It isn't very robust, but we have found it useful as a means
> >>>> of avoiding problems in this area.
> >>>
> >>> Right, but again, why can't the display driver simply read the address
> >>> out of the register; why is there a need to duplicate the data?
> >>>
> >>> I guess one possibility is that the register only gives the base address
> >>> and not the size/mode of the allocated surface, but I don't recall if
> >>> this proposed binding did that either?
> >>
> >> So here is my explanation:
> >>
> >> 1. U-Boot would normally put the display right near the top of memory.
> >> Instead, it figures out where the kernel will put it (somehow this
> >> seems to often be at a fixed address) and uses that address.
> >>
> >> 2. That means that U-Boot will now have the display exactly where the
> >> kernel wants it.
> >
> > Oh, the DT property is telling U-Boot where to put the surface so that
> > when the kernel determines where to put it, it'll already be there?
> >
> > That seems completely backwards. It's also extremely fragile; what if
> > the kernel suddenly starts allocating at some other random address,
> > which stops matching what U-Boot expects?
> 
> The screen will flicker, or may fill up with junk as the kernel boots.
> We did have that happen once when the driver changed.
> 
> >
> > Far better would be for U-Boot to put the surface wherever it wants,
> > then manipulate the DT that's passed to the kernel to:
> >
> > a) Add a /memreserve/ so that memory doesn't get re-used for anything
> > else during boot.
> >
> > b) Add a property to the display node indicating which memreserve
> > represents the frame-buffer location.
> 
> Yes, I believe the Tegra video driver we used (and I take your point
> that it doesn't exist upstream so there is no point in discussing it
> :-) always had to use the same frame buffer address. The memory was
> statically allocated. Certainly this could be encoded in the fdt.
> 
> >
> > When the kernel boots, it can:
> >
> > * Copy the content from the U-Boot-allocated buffer to whatever display
> > buffer the kernel allocated before writing the new address to the HW.
> >
> > * Undo the memory reservation triggered by the /memreserve/ to allow the
> > memory to be re-used.
> >
> >> So what do you think? Should we remove this entirely, or is it a useful hack?
> >
> > Yes, I think in its current form, it isn't useful.
> 
> Thanks for the thorough response. Let's remove it, particularly as
> there isn't even a kernel driver upstream yet.

We've been discussing some of these issues for quite some time and came
to the conclusion that the Tegra DRM driver should not be using static
allocations like the previous drivers did. One of the reasons is that
the amount of carveout memory needs to be fixed at boot time, which
isn't going to suit a wide range of devices well. Another, perhaps more
important reason is that starting with Tegra30 that's no longer
necessary because of the SMMU.

So in the end it wouldn't be possible to reliably determine the memory
area where the kernel will put the framebuffer. If we want a flicker-
free boot then we need to go with something more elaborate like what
Stephen suggested.

Thierry

[-- Attachment #1.2: Type: application/pgp-signature, Size: 836 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] 81+ messages in thread

* [U-Boot] [PATCH v3 06/18] tegra: fdt: Add LCD definitions for Tegra
@ 2012-09-28  5:42                               ` Thierry Reding
  0 siblings, 0 replies; 81+ messages in thread
From: Thierry Reding @ 2012-09-28  5:42 UTC (permalink / raw)
  To: u-boot

On Thu, Sep 27, 2012 at 04:37:41PM -0700, Simon Glass wrote:
> Hi Stephen,
> 
> On Thu, Sep 27, 2012 at 4:21 PM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> > On 09/27/2012 02:27 PM, Simon Glass wrote:
> >> On Thu, Sep 27, 2012 at 8:49 AM, Stephen Warren <swarren@wwwdotorg.org> wrote:
> >>> On 09/27/2012 07:58 AM, Simon Glass wrote:
> > ...
> >>>> Really this is just a way of getting U-Boot and Linux to agree on the
> >>>> address, by having U-Boot know the address that the kernel will happen
> >>>> to use. It isn't very robust, but we have found it useful as a means
> >>>> of avoiding problems in this area.
> >>>
> >>> Right, but again, why can't the display driver simply read the address
> >>> out of the register; why is there a need to duplicate the data?
> >>>
> >>> I guess one possibility is that the register only gives the base address
> >>> and not the size/mode of the allocated surface, but I don't recall if
> >>> this proposed binding did that either?
> >>
> >> So here is my explanation:
> >>
> >> 1. U-Boot would normally put the display right near the top of memory.
> >> Instead, it figures out where the kernel will put it (somehow this
> >> seems to often be at a fixed address) and uses that address.
> >>
> >> 2. That means that U-Boot will now have the display exactly where the
> >> kernel wants it.
> >
> > Oh, the DT property is telling U-Boot where to put the surface so that
> > when the kernel determines where to put it, it'll already be there?
> >
> > That seems completely backwards. It's also extremely fragile; what if
> > the kernel suddenly starts allocating at some other random address,
> > which stops matching what U-Boot expects?
> 
> The screen will flicker, or may fill up with junk as the kernel boots.
> We did have that happen once when the driver changed.
> 
> >
> > Far better would be for U-Boot to put the surface wherever it wants,
> > then manipulate the DT that's passed to the kernel to:
> >
> > a) Add a /memreserve/ so that memory doesn't get re-used for anything
> > else during boot.
> >
> > b) Add a property to the display node indicating which memreserve
> > represents the frame-buffer location.
> 
> Yes, I believe the Tegra video driver we used (and I take your point
> that it doesn't exist upstream so there is no point in discussing it
> :-) always had to use the same frame buffer address. The memory was
> statically allocated. Certainly this could be encoded in the fdt.
> 
> >
> > When the kernel boots, it can:
> >
> > * Copy the content from the U-Boot-allocated buffer to whatever display
> > buffer the kernel allocated before writing the new address to the HW.
> >
> > * Undo the memory reservation triggered by the /memreserve/ to allow the
> > memory to be re-used.
> >
> >> So what do you think? Should we remove this entirely, or is it a useful hack?
> >
> > Yes, I think in its current form, it isn't useful.
> 
> Thanks for the thorough response. Let's remove it, particularly as
> there isn't even a kernel driver upstream yet.

We've been discussing some of these issues for quite some time and came
to the conclusion that the Tegra DRM driver should not be using static
allocations like the previous drivers did. One of the reasons is that
the amount of carveout memory needs to be fixed at boot time, which
isn't going to suit a wide range of devices well. Another, perhaps more
important reason is that starting with Tegra30 that's no longer
necessary because of the SMMU.

So in the end it wouldn't be possible to reliably determine the memory
area where the kernel will put the framebuffer. If we want a flicker-
free boot then we need to go with something more elaborate like what
Stephen suggested.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20120928/59f50688/attachment.pgp>

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

* [U-Boot] [PATCH v3 13/18] lcd: Add support for flushing LCD fb from dcache after update
  2012-08-09  7:43   ` Lukasz Majewski
@ 2012-10-16 18:16     ` Simon Glass
  2012-10-17 10:38       ` Lukasz Majewski
  0 siblings, 1 reply; 81+ messages in thread
From: Simon Glass @ 2012-10-16 18:16 UTC (permalink / raw)
  To: u-boot

Hi,

On Thu, Aug 9, 2012 at 12:43 AM, Lukasz Majewski <l.majewski@samsung.com> wrote:
> Hi Simon,
>
>> This provides an option for the LCD to flush the dcache after each
>> update (puts, scroll or clear).
>>
>> Signed-off-by: Simon Glass <sjg@chromium.org>
>> ---
>> Changes in v2:
>> - Put the LCD cache flush logic into lcd_putc() instead of lcd_puts()
>>
>> Changes in v3:
>> - Put the LCD cache flush logic back into lcd_puts()
>>
>>  common/lcd.c  |   46 +++++++++++++++++++++++++++++++++++++++-------
>>  include/lcd.h |    8 ++++++++
>>  2 files changed, 47 insertions(+), 7 deletions(-)
>>
>> diff --git a/common/lcd.c b/common/lcd.c
>> index 18525a7..f7514a4 100644
>> --- a/common/lcd.c
>> +++ b/common/lcd.c
>> @@ -97,6 +97,9 @@ static void lcd_setbgcolor (int color);
>>
>>  char lcd_is_enabled = 0;
>>
>> +static char lcd_flush_dcache;        /* 1 to flush dcache after each
>> lcd update */ +
>> +
>>  #ifdef       NOT_USED_SO_FAR
>>  static void lcd_getcolreg (ushort regno,
>>                               ushort *red, ushort *green, ushort
>> *blue); @@ -105,6 +108,28 @@ static int lcd_getfgcolor (void);
>>
>>  /************************************************************************/
>>
>> +/* Flush LCD activity to the caches */
>> +void lcd_sync(void)
>> +{
>> +     /*
>> +      * flush_dcache_range() is declared in common.h but it seems
>> that some
>> +      * architectures do not actually implement it. Is there a
>> way to find
>> +      * out whether it exists? For now, ARM is safe.
>> +      */
>> +#ifdef CONFIG_ARM
>> +     int line_length;
>> +
>> +     if (lcd_flush_dcache)
>> +             flush_dcache_range((u32)lcd_base,
>> +                     (u32)(lcd_base +
>> lcd_get_size(&line_length))); +#endif
>
> I'm struggling with a similar problem - but not in console putc, but
> at lcd_display_bitmap().
>
> The solution (in mine case) is:
> flush_dcache_range((unsigned long) fb,
>                    (unsigned long) fb +
>                    (lcd_line_length * height));
> which takes the "real" image range (as it is defined by fb).
>
> Flushing the lcd_base based range is a bit overkill for me.
>
>> +}
>> +
>> +void lcd_set_flush_dcache(int flush)
>> +{
>> +     lcd_flush_dcache = (flush != 0);
>> +}
>> +
>
> I'm wondering if this flush_dcache_range cannot be added directly to
> relevant places in the code?
>
> flush_dcache_* calls are either defined (for a relevant - cache aware
> archs) or are dummy.
>
>>  /*----------------------------------------------------------------------*/
>>
>>  static void console_scrollup (void)
>> @@ -114,6 +139,7 @@ static void console_scrollup (void)
>>
>>       /* Clear the last one */
>>       memset (CONSOLE_ROW_LAST, COLOR_MASK(lcd_color_bg),
>> CONSOLE_ROW_SIZE);
>> +     lcd_sync();
>>  }
>>
>>  /*----------------------------------------------------------------------*/
>> @@ -144,6 +170,8 @@ static inline void console_newline (void)
>>               /* Scroll everything up */
>>               console_scrollup () ;
>>               --console_row;
>> +     } else {
>> +             lcd_sync();
>>       }
>>  }
>>
>> @@ -198,6 +226,7 @@ void lcd_puts (const char *s)
>>       while (*s) {
>>               lcd_putc (*s++);
>>       }
>> +     lcd_sync();
>>  }
>>
>>  /*----------------------------------------------------------------------*/
>> @@ -365,13 +394,6 @@ int drv_lcd_init (void)
>>  }
>>
>>  /*----------------------------------------------------------------------*/
>> -static
>> -int do_lcd_clear(cmd_tbl_t *cmdtp, int flag, int argc, char *const
>> argv[]) -{
>> -     lcd_clear();
>> -     return 0;
>> -}
>> -
>>  void lcd_clear(void)
>>  {
>>  #if LCD_BPP == LCD_MONOCHROME
>> @@ -413,6 +435,14 @@ void lcd_clear(void)
>>
>>       console_col = 0;
>>       console_row = 0;
>> +     lcd_sync();
>> +}
>> +
>> +static int do_lcd_clear(cmd_tbl_t *cmdtp, int flag, int argc,
>> +                     char *const argv[])
>> +{
>> +     lcd_clear();
>> +     return 0;
>>  }
>>
>>  U_BOOT_CMD(
>> @@ -607,6 +637,7 @@ void bitmap_plot (int x, int y)
>>       }
>>
>>       WATCHDOG_RESET();
>> +     lcd_sync();
>>  }
>>  #else
>>  static inline void bitmap_plot(int x, int y) {}
>> @@ -820,6 +851,7 @@ int lcd_display_bitmap(ulong bmp_image, int x,
>> int y) break;
>>       };
>>
>> +     lcd_sync();
>>       return (0);
>>  }
>>  #endif
>> diff --git a/include/lcd.h b/include/lcd.h
>> index 26f6d83..4363131 100644
>> --- a/include/lcd.h
>> +++ b/include/lcd.h
>> @@ -57,6 +57,14 @@ extern void lcd_initcolregs (void);
>>  extern struct bmp_image *gunzip_bmp(unsigned long addr, unsigned
>> long *lenp); extern int bmp_display(ulong addr, int x, int y);
>>
>> +/**
>> + * Set whether we need to flush the dcache when changing the LCD
>> image. This
>> + * defaults to off.
>> + *
>> + * @param flush              non-zero to flush cache after update,
>> 0 to skip
>> + */
>> +void lcd_set_flush_dcache(int flush);
>> +
>>  #if defined CONFIG_MPC823
>>  /*
>>   * LCD controller stucture for MPC823 CPU
>
> Anyway, I'm looking forward for v4 version of this patch.

Sorry I don't think I replied to this.

Certainly we could make the flushing more fine grained. My reasons for
not (so far) are:

1. It is simpler to flush everything (no need to figure out what part
of display has changed)
2. The performance difference is likely to be small since flushing an
already-flushed range should be fast.

Certainly we could enhance this code. I wonder though whether a
generic flushing mechanism may need to be added to support LCD and
also video drivers.

Regards,
Simon

>
> --
> Best regards,
>
> Lukasz Majewski
>
> Samsung Poland R&D Center | Linux Platform Group

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

* [U-Boot] [PATCH v3 13/18] lcd: Add support for flushing LCD fb from dcache after update
  2012-10-16 18:16     ` Simon Glass
@ 2012-10-17 10:38       ` Lukasz Majewski
  2012-10-17 15:34         ` Eric Nelson
  0 siblings, 1 reply; 81+ messages in thread
From: Lukasz Majewski @ 2012-10-17 10:38 UTC (permalink / raw)
  To: u-boot

Hi Simon,

> Hi,
> 
> On Thu, Aug 9, 2012 at 12:43 AM, Lukasz Majewski
> <l.majewski@samsung.com> wrote:
> > Hi Simon,
> >
> >> This provides an option for the LCD to flush the dcache after each
> >> update (puts, scroll or clear).
> >>
> >> Signed-off-by: Simon Glass <sjg@chromium.org>
> >> ---
> >> Changes in v2:
> >> - Put the LCD cache flush logic into lcd_putc() instead of
> >> lcd_puts()
> >>
> >> Changes in v3:
> >> - Put the LCD cache flush logic back into lcd_puts()
> >>
> >>  common/lcd.c  |   46
> >> +++++++++++++++++++++++++++++++++++++++------- include/lcd.h |
> >> 8 ++++++++ 2 files changed, 47 insertions(+), 7 deletions(-)
> >>
> >> diff --git a/common/lcd.c b/common/lcd.c
> >> index 18525a7..f7514a4 100644
> >> --- a/common/lcd.c
> >> +++ b/common/lcd.c
> >> @@ -97,6 +97,9 @@ static void lcd_setbgcolor (int color);
> >>
> >>  char lcd_is_enabled = 0;
> >>
> >> +static char lcd_flush_dcache;        /* 1 to flush dcache after
> >> each lcd update */ +
> >> +
> >>  #ifdef       NOT_USED_SO_FAR
> >>  static void lcd_getcolreg (ushort regno,
> >>                               ushort *red, ushort *green, ushort
> >> *blue); @@ -105,6 +108,28 @@ static int lcd_getfgcolor (void);
> >>
> >>  /************************************************************************/
> >>
> >> +/* Flush LCD activity to the caches */
> >> +void lcd_sync(void)
> >> +{
> >> +     /*
> >> +      * flush_dcache_range() is declared in common.h but it seems
> >> that some
> >> +      * architectures do not actually implement it. Is there a
> >> way to find
> >> +      * out whether it exists? For now, ARM is safe.
> >> +      */
> >> +#ifdef CONFIG_ARM
> >> +     int line_length;
> >> +
> >> +     if (lcd_flush_dcache)
> >> +             flush_dcache_range((u32)lcd_base,
> >> +                     (u32)(lcd_base +
> >> lcd_get_size(&line_length))); +#endif
> >
> > I'm struggling with a similar problem - but not in console putc, but
> > at lcd_display_bitmap().
> >
> > The solution (in mine case) is:
> > flush_dcache_range((unsigned long) fb,
> >                    (unsigned long) fb +
> >                    (lcd_line_length * height));
> > which takes the "real" image range (as it is defined by fb).
> >
> > Flushing the lcd_base based range is a bit overkill for me.
> >
> >> +}
> >> +
> >> +void lcd_set_flush_dcache(int flush)
> >> +{
> >> +     lcd_flush_dcache = (flush != 0);
> >> +}
> >> +
> >
> > I'm wondering if this flush_dcache_range cannot be added directly to
> > relevant places in the code?
> >
> > flush_dcache_* calls are either defined (for a relevant - cache
> > aware archs) or are dummy.
> >
> >>  /*----------------------------------------------------------------------*/
> >>
> >>  static void console_scrollup (void)
> >> @@ -114,6 +139,7 @@ static void console_scrollup (void)
> >>
> >>       /* Clear the last one */
> >>       memset (CONSOLE_ROW_LAST, COLOR_MASK(lcd_color_bg),
> >> CONSOLE_ROW_SIZE);
> >> +     lcd_sync();
> >>  }
> >>
> >>  /*----------------------------------------------------------------------*/
> >> @@ -144,6 +170,8 @@ static inline void console_newline (void)
> >>               /* Scroll everything up */
> >>               console_scrollup () ;
> >>               --console_row;
> >> +     } else {
> >> +             lcd_sync();
> >>       }
> >>  }
> >>
> >> @@ -198,6 +226,7 @@ void lcd_puts (const char *s)
> >>       while (*s) {
> >>               lcd_putc (*s++);
> >>       }
> >> +     lcd_sync();
> >>  }
> >>
> >>  /*----------------------------------------------------------------------*/
> >> @@ -365,13 +394,6 @@ int drv_lcd_init (void)
> >>  }
> >>
> >>  /*----------------------------------------------------------------------*/
> >> -static
> >> -int do_lcd_clear(cmd_tbl_t *cmdtp, int flag, int argc, char *const
> >> argv[]) -{
> >> -     lcd_clear();
> >> -     return 0;
> >> -}
> >> -
> >>  void lcd_clear(void)
> >>  {
> >>  #if LCD_BPP == LCD_MONOCHROME
> >> @@ -413,6 +435,14 @@ void lcd_clear(void)
> >>
> >>       console_col = 0;
> >>       console_row = 0;
> >> +     lcd_sync();
> >> +}
> >> +
> >> +static int do_lcd_clear(cmd_tbl_t *cmdtp, int flag, int argc,
> >> +                     char *const argv[])
> >> +{
> >> +     lcd_clear();
> >> +     return 0;
> >>  }
> >>
> >>  U_BOOT_CMD(
> >> @@ -607,6 +637,7 @@ void bitmap_plot (int x, int y)
> >>       }
> >>
> >>       WATCHDOG_RESET();
> >> +     lcd_sync();
> >>  }
> >>  #else
> >>  static inline void bitmap_plot(int x, int y) {}
> >> @@ -820,6 +851,7 @@ int lcd_display_bitmap(ulong bmp_image, int x,
> >> int y) break;
> >>       };
> >>
> >> +     lcd_sync();
> >>       return (0);
> >>  }
> >>  #endif
> >> diff --git a/include/lcd.h b/include/lcd.h
> >> index 26f6d83..4363131 100644
> >> --- a/include/lcd.h
> >> +++ b/include/lcd.h
> >> @@ -57,6 +57,14 @@ extern void lcd_initcolregs (void);
> >>  extern struct bmp_image *gunzip_bmp(unsigned long addr, unsigned
> >> long *lenp); extern int bmp_display(ulong addr, int x, int y);
> >>
> >> +/**
> >> + * Set whether we need to flush the dcache when changing the LCD
> >> image. This
> >> + * defaults to off.
> >> + *
> >> + * @param flush              non-zero to flush cache after update,
> >> 0 to skip
> >> + */
> >> +void lcd_set_flush_dcache(int flush);
> >> +
> >>  #if defined CONFIG_MPC823
> >>  /*
> >>   * LCD controller stucture for MPC823 CPU
> >
> > Anyway, I'm looking forward for v4 version of this patch.
> 
> Sorry I don't think I replied to this.
> 
Yes, this is still open issue. (not fixed I mean) I maintain the patch
locally. 

> Certainly we could make the flushing more fine grained. My reasons for
> not (so far) are:
> 
> 1. It is simpler to flush everything (no need to figure out what part
> of display has changed)
> 2. The performance difference is likely to be small since flushing an
> already-flushed range should be fast.

From the sake of "SW engineering" I would opt for fine grained
flushing. But if it turns out, that it costs too much, we can flush
everything. 

> 
> Certainly we could enhance this code. I wonder though whether a
> generic flushing mechanism may need to be added to support LCD and
> also video drivers.

We can add a generic mechanism to LCD and video.

Simon, do you plan to post some code in a near future? Or we are now
just "gathering requirements"?

> 
> Regards,
> Simon
> 
> >
> > --
> > Best regards,
> >
> > Lukasz Majewski
> >
> > Samsung Poland R&D Center | Linux Platform Group



-- 
Best regards,

Lukasz Majewski

Samsung Poland R&D Center | Linux Platform Group

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

* [U-Boot] [PATCH v3 13/18] lcd: Add support for flushing LCD fb from dcache after update
  2012-10-17 10:38       ` Lukasz Majewski
@ 2012-10-17 15:34         ` Eric Nelson
  2012-10-17 22:07           ` Simon Glass
  0 siblings, 1 reply; 81+ messages in thread
From: Eric Nelson @ 2012-10-17 15:34 UTC (permalink / raw)
  To: u-boot

On 10/17/2012 03:38 AM, Lukasz Majewski wrote:
> Hi Simon,
>
>> Hi,
>>
>> On Thu, Aug 9, 2012 at 12:43 AM, Lukasz Majewski
>> <l.majewski@samsung.com>  wrote:
>>> Hi Simon,
>>>
>>>> This provides an option for the LCD to flush the dcache after each
>>>> update (puts, scroll or clear).
>>>>
>>>> Signed-off-by: Simon Glass<sjg@chromium.org>
>>>> ---
>>>> Changes in v2:
>>>> - Put the LCD cache flush logic into lcd_putc() instead of
>>>> lcd_puts()
>>>>
>>>> Changes in v3:
>>>> - Put the LCD cache flush logic back into lcd_puts()
>>>>
>>>>   common/lcd.c  |   46
>>>> +++++++++++++++++++++++++++++++++++++++------- include/lcd.h |
>>>> 8 ++++++++ 2 files changed, 47 insertions(+), 7 deletions(-)
>>>>
>>>> diff --git a/common/lcd.c b/common/lcd.c
>>>> index 18525a7..f7514a4 100644
>>>> --- a/common/lcd.c
>>>> +++ b/common/lcd.c
>>>> @@ -97,6 +97,9 @@ static void lcd_setbgcolor (int color);
>>>>
>>>>   char lcd_is_enabled = 0;
>>>>
>>>> +static char lcd_flush_dcache;        /* 1 to flush dcache after
>>>> each lcd update */ +
>>>> +
>>>>   #ifdef       NOT_USED_SO_FAR
>>>>   static void lcd_getcolreg (ushort regno,
>>>>                                ushort *red, ushort *green, ushort
>>>> *blue); @@ -105,6 +108,28 @@ static int lcd_getfgcolor (void);
>>>>
>>>>   /************************************************************************/
>>>>
>>>> +/* Flush LCD activity to the caches */
>>>> +void lcd_sync(void)
>>>> +{
>>>> +     /*
>>>> +      * flush_dcache_range() is declared in common.h but it seems
>>>> that some
>>>> +      * architectures do not actually implement it. Is there a
>>>> way to find
>>>> +      * out whether it exists? For now, ARM is safe.
>>>> +      */
>>>> +#ifdef CONFIG_ARM
>>>> +     int line_length;
>>>> +
>>>> +     if (lcd_flush_dcache)
>>>> +             flush_dcache_range((u32)lcd_base,
>>>> +                     (u32)(lcd_base +
>>>> lcd_get_size(&line_length))); +#endif
>>>
>>> I'm struggling with a similar problem - but not in console putc, but
>>> at lcd_display_bitmap().
>>>
>>> The solution (in mine case) is:
>>> flush_dcache_range((unsigned long) fb,
>>>                     (unsigned long) fb +
>>>                     (lcd_line_length * height));
>>> which takes the "real" image range (as it is defined by fb).
>>>
>>> Flushing the lcd_base based range is a bit overkill for me.
>>>
>>>> +}
>>>> +
>>>> +void lcd_set_flush_dcache(int flush)
>>>> +{
>>>> +     lcd_flush_dcache = (flush != 0);
>>>> +}
>>>> +
>>>
>>> I'm wondering if this flush_dcache_range cannot be added directly to
>>> relevant places in the code?
>>>
>>> flush_dcache_* calls are either defined (for a relevant - cache
>>> aware archs) or are dummy.
>>>
>>>>   /*----------------------------------------------------------------------*/
>>>>
>>>>   static void console_scrollup (void)
>>>> @@ -114,6 +139,7 @@ static void console_scrollup (void)
>>>>
>>>>        /* Clear the last one */
>>>>        memset (CONSOLE_ROW_LAST, COLOR_MASK(lcd_color_bg),
>>>> CONSOLE_ROW_SIZE);
>>>> +     lcd_sync();
>>>>   }
>>>>
>>>>   /*----------------------------------------------------------------------*/
>>>> @@ -144,6 +170,8 @@ static inline void console_newline (void)
>>>>                /* Scroll everything up */
>>>>                console_scrollup () ;
>>>>                --console_row;
>>>> +     } else {
>>>> +             lcd_sync();
>>>>        }
>>>>   }
>>>>
>>>> @@ -198,6 +226,7 @@ void lcd_puts (const char *s)
>>>>        while (*s) {
>>>>                lcd_putc (*s++);
>>>>        }
>>>> +     lcd_sync();
>>>>   }
>>>>
>>>>   /*----------------------------------------------------------------------*/
>>>> @@ -365,13 +394,6 @@ int drv_lcd_init (void)
>>>>   }
>>>>
>>>>   /*----------------------------------------------------------------------*/
>>>> -static
>>>> -int do_lcd_clear(cmd_tbl_t *cmdtp, int flag, int argc, char *const
>>>> argv[]) -{
>>>> -     lcd_clear();
>>>> -     return 0;
>>>> -}
>>>> -
>>>>   void lcd_clear(void)
>>>>   {
>>>>   #if LCD_BPP == LCD_MONOCHROME
>>>> @@ -413,6 +435,14 @@ void lcd_clear(void)
>>>>
>>>>        console_col = 0;
>>>>        console_row = 0;
>>>> +     lcd_sync();
>>>> +}
>>>> +
>>>> +static int do_lcd_clear(cmd_tbl_t *cmdtp, int flag, int argc,
>>>> +                     char *const argv[])
>>>> +{
>>>> +     lcd_clear();
>>>> +     return 0;
>>>>   }
>>>>
>>>>   U_BOOT_CMD(
>>>> @@ -607,6 +637,7 @@ void bitmap_plot (int x, int y)
>>>>        }
>>>>
>>>>        WATCHDOG_RESET();
>>>> +     lcd_sync();
>>>>   }
>>>>   #else
>>>>   static inline void bitmap_plot(int x, int y) {}
>>>> @@ -820,6 +851,7 @@ int lcd_display_bitmap(ulong bmp_image, int x,
>>>> int y) break;
>>>>        };
>>>>
>>>> +     lcd_sync();
>>>>        return (0);
>>>>   }
>>>>   #endif
>>>> diff --git a/include/lcd.h b/include/lcd.h
>>>> index 26f6d83..4363131 100644
>>>> --- a/include/lcd.h
>>>> +++ b/include/lcd.h
>>>> @@ -57,6 +57,14 @@ extern void lcd_initcolregs (void);
>>>>   extern struct bmp_image *gunzip_bmp(unsigned long addr, unsigned
>>>> long *lenp); extern int bmp_display(ulong addr, int x, int y);
>>>>
>>>> +/**
>>>> + * Set whether we need to flush the dcache when changing the LCD
>>>> image. This
>>>> + * defaults to off.
>>>> + *
>>>> + * @param flush              non-zero to flush cache after update,
>>>> 0 to skip
>>>> + */
>>>> +void lcd_set_flush_dcache(int flush);
>>>> +
>>>>   #if defined CONFIG_MPC823
>>>>   /*
>>>>    * LCD controller stucture for MPC823 CPU
>>>
>>> Anyway, I'm looking forward for v4 version of this patch.
>>
>> Sorry I don't think I replied to this.
>>
> Yes, this is still open issue. (not fixed I mean) I maintain the patch
> locally.
>
>> Certainly we could make the flushing more fine grained. My reasons for
>> not (so far) are:
>>
>> 1. It is simpler to flush everything (no need to figure out what part
>> of display has changed)
>> 2. The performance difference is likely to be small since flushing an
>> already-flushed range should be fast.
>
>  From the sake of "SW engineering" I would opt for fine grained
> flushing. But if it turns out, that it costs too much, we can flush
> everything.
>

Is anybody else in a position to get some numbers about how/if
performance is better when flushing at the more granular level?

Before deciding it wasn't worth the code, I implemented granular
flushing and didn't see any noticeable degradation when just
flushing at the end of all public functions as in this patch.

	http://lists.denx.de/pipermail/u-boot/2012-September/134979.html

It seems that performance is the only reason for fine-grained
cache flush operations

>>
>> Certainly we could enhance this code. I wonder though whether a
>> generic flushing mechanism may need to be added to support LCD and
>> also video drivers.
>
> We can add a generic mechanism to LCD and video.
>
> Simon, do you plan to post some code in a near future? Or we are now
> just "gathering requirements"?
>
>>
>> Regards,
>> Simon
>>
>>>
>>> --
>>> Best regards,
>>>
>>> Lukasz Majewski
>>>
>>> Samsung Poland R&D Center | Linux Platform Group
>
>
>

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

* [U-Boot] [PATCH v3 13/18] lcd: Add support for flushing LCD fb from dcache after update
  2012-10-17 15:34         ` Eric Nelson
@ 2012-10-17 22:07           ` Simon Glass
  2012-10-18  0:41             ` Eric Nelson
  0 siblings, 1 reply; 81+ messages in thread
From: Simon Glass @ 2012-10-17 22:07 UTC (permalink / raw)
  To: u-boot

Hi Eric,

On Wed, Oct 17, 2012 at 8:34 AM, Eric Nelson
<eric.nelson@boundarydevices.com> wrote:
> On 10/17/2012 03:38 AM, Lukasz Majewski wrote:
>>
>> Hi Simon,
>>
>>> Hi,
>>>
>>> On Thu, Aug 9, 2012 at 12:43 AM, Lukasz Majewski
>>> <l.majewski@samsung.com>  wrote:
>>>>
>>>> Hi Simon,
>>>>
>>>>> This provides an option for the LCD to flush the dcache after each
>>>>> update (puts, scroll or clear).
>>>>>
>>>>> Signed-off-by: Simon Glass<sjg@chromium.org>
>>>>> ---
>>>>> Changes in v2:
>>>>> - Put the LCD cache flush logic into lcd_putc() instead of
>>>>> lcd_puts()
>>>>>
>>>>> Changes in v3:
>>>>> - Put the LCD cache flush logic back into lcd_puts()
>>>>>
>>>>>   common/lcd.c  |   46
>>>>> +++++++++++++++++++++++++++++++++++++++------- include/lcd.h |
>>>>> 8 ++++++++ 2 files changed, 47 insertions(+), 7 deletions(-)
>>>>>
>>>>> diff --git a/common/lcd.c b/common/lcd.c
>>>>> index 18525a7..f7514a4 100644
>>>>> --- a/common/lcd.c
>>>>> +++ b/common/lcd.c
>>>>> @@ -97,6 +97,9 @@ static void lcd_setbgcolor (int color);
>>>>>
>>>>>   char lcd_is_enabled = 0;
>>>>>
>>>>> +static char lcd_flush_dcache;        /* 1 to flush dcache after
>>>>> each lcd update */ +
>>>>> +
>>>>>   #ifdef       NOT_USED_SO_FAR
>>>>>   static void lcd_getcolreg (ushort regno,
>>>>>                                ushort *red, ushort *green, ushort
>>>>> *blue); @@ -105,6 +108,28 @@ static int lcd_getfgcolor (void);
>>>>>
>>>>>
>>>>> /************************************************************************/
>>>>>
>>>>> +/* Flush LCD activity to the caches */
>>>>> +void lcd_sync(void)
>>>>> +{
>>>>> +     /*
>>>>> +      * flush_dcache_range() is declared in common.h but it seems
>>>>> that some
>>>>> +      * architectures do not actually implement it. Is there a
>>>>> way to find
>>>>> +      * out whether it exists? For now, ARM is safe.
>>>>> +      */
>>>>> +#ifdef CONFIG_ARM
>>>>> +     int line_length;
>>>>> +
>>>>> +     if (lcd_flush_dcache)
>>>>> +             flush_dcache_range((u32)lcd_base,
>>>>> +                     (u32)(lcd_base +
>>>>> lcd_get_size(&line_length))); +#endif
>>>>
>>>>
>>>> I'm struggling with a similar problem - but not in console putc, but
>>>> at lcd_display_bitmap().
>>>>
>>>> The solution (in mine case) is:
>>>> flush_dcache_range((unsigned long) fb,
>>>>                     (unsigned long) fb +
>>>>                     (lcd_line_length * height));
>>>> which takes the "real" image range (as it is defined by fb).
>>>>
>>>> Flushing the lcd_base based range is a bit overkill for me.
>>>>
>>>>> +}
>>>>> +
>>>>> +void lcd_set_flush_dcache(int flush)
>>>>> +{
>>>>> +     lcd_flush_dcache = (flush != 0);
>>>>> +}
>>>>> +
>>>>
>>>>
>>>> I'm wondering if this flush_dcache_range cannot be added directly to
>>>> relevant places in the code?
>>>>
>>>> flush_dcache_* calls are either defined (for a relevant - cache
>>>> aware archs) or are dummy.
>>>>
>>>>>
>>>>> /*----------------------------------------------------------------------*/
>>>>>
>>>>>   static void console_scrollup (void)
>>>>> @@ -114,6 +139,7 @@ static void console_scrollup (void)
>>>>>
>>>>>        /* Clear the last one */
>>>>>        memset (CONSOLE_ROW_LAST, COLOR_MASK(lcd_color_bg),
>>>>> CONSOLE_ROW_SIZE);
>>>>> +     lcd_sync();
>>>>>   }
>>>>>
>>>>>
>>>>> /*----------------------------------------------------------------------*/
>>>>> @@ -144,6 +170,8 @@ static inline void console_newline (void)
>>>>>                /* Scroll everything up */
>>>>>                console_scrollup () ;
>>>>>                --console_row;
>>>>> +     } else {
>>>>> +             lcd_sync();
>>>>>        }
>>>>>   }
>>>>>
>>>>> @@ -198,6 +226,7 @@ void lcd_puts (const char *s)
>>>>>        while (*s) {
>>>>>                lcd_putc (*s++);
>>>>>        }
>>>>> +     lcd_sync();
>>>>>   }
>>>>>
>>>>>
>>>>> /*----------------------------------------------------------------------*/
>>>>> @@ -365,13 +394,6 @@ int drv_lcd_init (void)
>>>>>   }
>>>>>
>>>>>
>>>>> /*----------------------------------------------------------------------*/
>>>>> -static
>>>>> -int do_lcd_clear(cmd_tbl_t *cmdtp, int flag, int argc, char *const
>>>>> argv[]) -{
>>>>> -     lcd_clear();
>>>>> -     return 0;
>>>>> -}
>>>>> -
>>>>>   void lcd_clear(void)
>>>>>   {
>>>>>   #if LCD_BPP == LCD_MONOCHROME
>>>>> @@ -413,6 +435,14 @@ void lcd_clear(void)
>>>>>
>>>>>        console_col = 0;
>>>>>        console_row = 0;
>>>>> +     lcd_sync();
>>>>> +}
>>>>> +
>>>>> +static int do_lcd_clear(cmd_tbl_t *cmdtp, int flag, int argc,
>>>>> +                     char *const argv[])
>>>>> +{
>>>>> +     lcd_clear();
>>>>> +     return 0;
>>>>>   }
>>>>>
>>>>>   U_BOOT_CMD(
>>>>> @@ -607,6 +637,7 @@ void bitmap_plot (int x, int y)
>>>>>        }
>>>>>
>>>>>        WATCHDOG_RESET();
>>>>> +     lcd_sync();
>>>>>   }
>>>>>   #else
>>>>>   static inline void bitmap_plot(int x, int y) {}
>>>>> @@ -820,6 +851,7 @@ int lcd_display_bitmap(ulong bmp_image, int x,
>>>>> int y) break;
>>>>>        };
>>>>>
>>>>> +     lcd_sync();
>>>>>        return (0);
>>>>>   }
>>>>>   #endif
>>>>> diff --git a/include/lcd.h b/include/lcd.h
>>>>> index 26f6d83..4363131 100644
>>>>> --- a/include/lcd.h
>>>>> +++ b/include/lcd.h
>>>>> @@ -57,6 +57,14 @@ extern void lcd_initcolregs (void);
>>>>>   extern struct bmp_image *gunzip_bmp(unsigned long addr, unsigned
>>>>> long *lenp); extern int bmp_display(ulong addr, int x, int y);
>>>>>
>>>>> +/**
>>>>> + * Set whether we need to flush the dcache when changing the LCD
>>>>> image. This
>>>>> + * defaults to off.
>>>>> + *
>>>>> + * @param flush              non-zero to flush cache after update,
>>>>> 0 to skip
>>>>> + */
>>>>> +void lcd_set_flush_dcache(int flush);
>>>>> +
>>>>>   #if defined CONFIG_MPC823
>>>>>   /*
>>>>>    * LCD controller stucture for MPC823 CPU
>>>>
>>>>
>>>> Anyway, I'm looking forward for v4 version of this patch.
>>>
>>>
>>> Sorry I don't think I replied to this.
>>>
>> Yes, this is still open issue. (not fixed I mean) I maintain the patch
>> locally.
>>
>>> Certainly we could make the flushing more fine grained. My reasons for
>>> not (so far) are:
>>>
>>> 1. It is simpler to flush everything (no need to figure out what part
>>> of display has changed)
>>> 2. The performance difference is likely to be small since flushing an
>>> already-flushed range should be fast.
>>
>>
>>  From the sake of "SW engineering" I would opt for fine grained
>> flushing. But if it turns out, that it costs too much, we can flush
>> everything.
>>
>
> Is anybody else in a position to get some numbers about how/if
> performance is better when flushing at the more granular level?
>
> Before deciding it wasn't worth the code, I implemented granular
> flushing and didn't see any noticeable degradation when just
> flushing at the end of all public functions as in this patch.
>
>         http://lists.denx.de/pipermail/u-boot/2012-September/134979.html
>
> It seems that performance is the only reason for fine-grained
> cache flush operations

Also we might be talking about different things. I have taken the
approach of flushing the whole display, but only after some display
functions. We could flush only what has changed, which is what I was
referring to as 'fine-grained'. You may have meant the idea of
flushing after every function that touches the display, or a
'fine-grained' approach of only flushing after some functions.

My testing shows that flushing is pretty fast, but I was reluctant to
flush after every putc() as it seemed egregiously inefficient.

Regards,
Simon

>
>
>>>
>>> Certainly we could enhance this code. I wonder though whether a
>>> generic flushing mechanism may need to be added to support LCD and
>>> also video drivers.
>>
>>
>> We can add a generic mechanism to LCD and video.
>>
>> Simon, do you plan to post some code in a near future? Or we are now
>> just "gathering requirements"?
>>
>>>
>>> Regards,
>>> Simon
>>>
>>>>
>>>> --
>>>> Best regards,
>>>>
>>>> Lukasz Majewski
>>>>
>>>> Samsung Poland R&D Center | Linux Platform Group
>>
>>
>>
>>
>

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

* [U-Boot] [PATCH v3 13/18] lcd: Add support for flushing LCD fb from dcache after update
  2012-10-17 22:07           ` Simon Glass
@ 2012-10-18  0:41             ` Eric Nelson
  2012-10-18  0:50               ` Simon Glass
  0 siblings, 1 reply; 81+ messages in thread
From: Eric Nelson @ 2012-10-18  0:41 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On 10/17/2012 03:07 PM, Simon Glass wrote:
> Hi Eric,
>
> On Wed, Oct 17, 2012 at 8:34 AM, Eric Nelson
> <eric.nelson@boundarydevices.com>  wrote:
>> On 10/17/2012 03:38 AM, Lukasz Majewski wrote:
>>>
>>> <snip>
>>>
>>>> Certainly we could make the flushing more fine grained. My reasons for
>>>> not (so far) are:
>>>>
>>>> 1. It is simpler to flush everything (no need to figure out what part
>>>> of display has changed)
>>>> 2. The performance difference is likely to be small since flushing an
>>>> already-flushed range should be fast.
>>>
>>>
>>>    From the sake of "SW engineering" I would opt for fine grained
>>> flushing. But if it turns out, that it costs too much, we can flush
>>> everything.
>>>
>>
>> Is anybody else in a position to get some numbers about how/if
>> performance is better when flushing at the more granular level?
>>
>> Before deciding it wasn't worth the code, I implemented granular
>> flushing and didn't see any noticeable degradation when just
>> flushing at the end of all public functions as in this patch.
>>
>>          http://lists.denx.de/pipermail/u-boot/2012-September/134979.html
>>
>> It seems that performance is the only reason for fine-grained
>> cache flush operations
>
> Also we might be talking about different things. I have taken the
> approach of flushing the whole display, but only after some display
> functions. We could flush only what has changed, which is what I was
> referring to as 'fine-grained'. You may have meant the idea of
> flushing after every function that touches the display, or a
> 'fine-grained' approach of only flushing after some functions.
>

You're right. That's what I get for chiming in quickly before
attending a customer meeting: I jump to conclusions.

I thought 'finer-grained' referred to the way Anatolij originally
did things:
	http://git.denx.de/?p=u-boot.git;a=commit;h=bfd4be803bbb7d122c2e3aaf6eaf987efa8d69da

I tried to follow that lead, but it degenerated into a horrible
mess of alignment checking.

> My testing shows that flushing is pretty fast, but I was reluctant to
> flush after every putc() as it seemed egregiously inefficient.
>

I need to spend some time with the patch to figure out how you
get around cache issues for keystroke echo.

Regards,


Eric

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

* [U-Boot] [PATCH v3 13/18] lcd: Add support for flushing LCD fb from dcache after update
  2012-10-18  0:41             ` Eric Nelson
@ 2012-10-18  0:50               ` Simon Glass
  2012-10-18  1:07                 ` Eric Nelson
  0 siblings, 1 reply; 81+ messages in thread
From: Simon Glass @ 2012-10-18  0:50 UTC (permalink / raw)
  To: u-boot

Hi Eric,

On Wed, Oct 17, 2012 at 5:41 PM, Eric Nelson
<eric.nelson@boundarydevices.com> wrote:
> Hi Simon,
>
>
> On 10/17/2012 03:07 PM, Simon Glass wrote:
>>
>> Hi Eric,
>>
>> On Wed, Oct 17, 2012 at 8:34 AM, Eric Nelson
>> <eric.nelson@boundarydevices.com>  wrote:
>>>
>>> On 10/17/2012 03:38 AM, Lukasz Majewski wrote:
>>>>
>>>>
>>>> <snip>
>>>>
>>>>
>>>>> Certainly we could make the flushing more fine grained. My reasons for
>>>>> not (so far) are:
>>>>>
>>>>> 1. It is simpler to flush everything (no need to figure out what part
>>>>> of display has changed)
>>>>> 2. The performance difference is likely to be small since flushing an
>>>>> already-flushed range should be fast.
>>>>
>>>>
>>>>
>>>>    From the sake of "SW engineering" I would opt for fine grained
>>>> flushing. But if it turns out, that it costs too much, we can flush
>>>> everything.
>>>>
>>>
>>> Is anybody else in a position to get some numbers about how/if
>>> performance is better when flushing at the more granular level?
>>>
>>> Before deciding it wasn't worth the code, I implemented granular
>>> flushing and didn't see any noticeable degradation when just
>>> flushing at the end of all public functions as in this patch.
>>>
>>>          http://lists.denx.de/pipermail/u-boot/2012-September/134979.html
>>>
>>> It seems that performance is the only reason for fine-grained
>>> cache flush operations
>>
>>
>> Also we might be talking about different things. I have taken the
>> approach of flushing the whole display, but only after some display
>> functions. We could flush only what has changed, which is what I was
>> referring to as 'fine-grained'. You may have meant the idea of
>> flushing after every function that touches the display, or a
>> 'fine-grained' approach of only flushing after some functions.
>>
>
> You're right. That's what I get for chiming in quickly before
> attending a customer meeting: I jump to conclusions.
>
> I thought 'finer-grained' referred to the way Anatolij originally
> did things:
>
> http://git.denx.de/?p=u-boot.git;a=commit;h=bfd4be803bbb7d122c2e3aaf6eaf987efa8d69da
>
> I tried to follow that lead, but it degenerated into a horrible
> mess of alignment checking.
>
>
>> My testing shows that flushing is pretty fast, but I was reluctant to
>> flush after every putc() as it seemed egregiously inefficient.
>>
>
> I need to spend some time with the patch to figure out how you
> get around cache issues for keystroke echo.

Well my less-than-lovely approach was to use puts() for all character
echo. That has a flush.

Regards,
Simon

>
> Regards,
>
>
> Eric

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

* [U-Boot] [PATCH v3 13/18] lcd: Add support for flushing LCD fb from dcache after update
  2012-10-18  0:50               ` Simon Glass
@ 2012-10-18  1:07                 ` Eric Nelson
  2012-10-19 23:49                   ` Simon Glass
  0 siblings, 1 reply; 81+ messages in thread
From: Eric Nelson @ 2012-10-18  1:07 UTC (permalink / raw)
  To: u-boot

Hi Simon,

On 10/17/2012 05:50 PM, Simon Glass wrote:
> Hi Eric,
>
> On Wed, Oct 17, 2012 at 5:41 PM, Eric Nelson
> <eric.nelson@boundarydevices.com>  wrote:
>> Hi Simon,
>>
>>
>> On 10/17/2012 03:07 PM, Simon Glass wrote:
>>>
>>> Hi Eric,
>>>
>>> On Wed, Oct 17, 2012 at 8:34 AM, Eric Nelson
>>> <eric.nelson@boundarydevices.com>   wrote:
>>>>
>>>> On 10/17/2012 03:38 AM, Lukasz Majewski wrote:
>>>>>
>>>>>
>>>>> <snip>
>>>>>
>>>>>
>>>>>> Certainly we could make the flushing more fine grained. My reasons for
>>>>>> not (so far) are:
>>>>>>
>>>>>> 1. It is simpler to flush everything (no need to figure out what part
>>>>>> of display has changed)
>>>>>> 2. The performance difference is likely to be small since flushing an
>>>>>> already-flushed range should be fast.
>>>>>
>>>>>
>>>>>
>>>>>      From the sake of "SW engineering" I would opt for fine grained
>>>>> flushing. But if it turns out, that it costs too much, we can flush
>>>>> everything.
>>>>>
>>>>
>>>> Is anybody else in a position to get some numbers about how/if
>>>> performance is better when flushing at the more granular level?
>>>>
>>>> Before deciding it wasn't worth the code, I implemented granular
>>>> flushing and didn't see any noticeable degradation when just
>>>> flushing at the end of all public functions as in this patch.
>>>>
>>>>           http://lists.denx.de/pipermail/u-boot/2012-September/134979.html
>>>>
>>>> It seems that performance is the only reason for fine-grained
>>>> cache flush operations
>>>
>>>
>>> Also we might be talking about different things. I have taken the
>>> approach of flushing the whole display, but only after some display
>>> functions. We could flush only what has changed, which is what I was
>>> referring to as 'fine-grained'. You may have meant the idea of
>>> flushing after every function that touches the display, or a
>>> 'fine-grained' approach of only flushing after some functions.
>>>
>>
>> You're right. That's what I get for chiming in quickly before
>> attending a customer meeting: I jump to conclusions.
>>
>> I thought 'finer-grained' referred to the way Anatolij originally
>> did things:
>>
>> http://git.denx.de/?p=u-boot.git;a=commit;h=bfd4be803bbb7d122c2e3aaf6eaf987efa8d69da
>>
>> I tried to follow that lead, but it degenerated into a horrible
>> mess of alignment checking.
>>
>>
>>> My testing shows that flushing is pretty fast, but I was reluctant to
>>> flush after every putc() as it seemed egregiously inefficient.
>>>
>>
>> I need to spend some time with the patch to figure out how you
>> get around cache issues for keystroke echo.
>
> Well my less-than-lovely approach was to use puts() for all character
> echo. That has a flush.
>

I just read through that and it makes perfect sense.

I'm anxious to test this and your CONFIG_CONSOLE_SCROLL_LINES patch
to see how it operates at 1080P.

Without the CONFIG_CONSOLE_SCROLL_LINES patch, scrolling was incredibly
slow.

Regards,


Eric

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

* [U-Boot] [PATCH v3 13/18] lcd: Add support for flushing LCD fb from dcache after update
  2012-10-18  1:07                 ` Eric Nelson
@ 2012-10-19 23:49                   ` Simon Glass
  0 siblings, 0 replies; 81+ messages in thread
From: Simon Glass @ 2012-10-19 23:49 UTC (permalink / raw)
  To: u-boot

Hi Eric,

On Wed, Oct 17, 2012 at 6:07 PM, Eric Nelson
<eric.nelson@boundarydevices.com> wrote:
> Hi Simon,
>
>
> On 10/17/2012 05:50 PM, Simon Glass wrote:
>>
>> Hi Eric,
>>
>> On Wed, Oct 17, 2012 at 5:41 PM, Eric Nelson
>> <eric.nelson@boundarydevices.com>  wrote:
>>>
>>> Hi Simon,
>>>
>>>
>>> On 10/17/2012 03:07 PM, Simon Glass wrote:
>>>>
>>>>
>>>> Hi Eric,
>>>>
>>>> On Wed, Oct 17, 2012 at 8:34 AM, Eric Nelson
>>>> <eric.nelson@boundarydevices.com>   wrote:
>>>>>
>>>>>
>>>>> On 10/17/2012 03:38 AM, Lukasz Majewski wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>> <snip>
>>>>>>
>>>>>>
>>>>>>> Certainly we could make the flushing more fine grained. My reasons
>>>>>>> for
>>>>>>> not (so far) are:
>>>>>>>
>>>>>>> 1. It is simpler to flush everything (no need to figure out what part
>>>>>>> of display has changed)
>>>>>>> 2. The performance difference is likely to be small since flushing an
>>>>>>> already-flushed range should be fast.
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>      From the sake of "SW engineering" I would opt for fine grained
>>>>>> flushing. But if it turns out, that it costs too much, we can flush
>>>>>> everything.
>>>>>>
>>>>>
>>>>> Is anybody else in a position to get some numbers about how/if
>>>>> performance is better when flushing at the more granular level?
>>>>>
>>>>> Before deciding it wasn't worth the code, I implemented granular
>>>>> flushing and didn't see any noticeable degradation when just
>>>>> flushing at the end of all public functions as in this patch.
>>>>>
>>>>>
>>>>> http://lists.denx.de/pipermail/u-boot/2012-September/134979.html
>>>>>
>>>>> It seems that performance is the only reason for fine-grained
>>>>> cache flush operations
>>>>
>>>>
>>>>
>>>> Also we might be talking about different things. I have taken the
>>>> approach of flushing the whole display, but only after some display
>>>> functions. We could flush only what has changed, which is what I was
>>>> referring to as 'fine-grained'. You may have meant the idea of
>>>> flushing after every function that touches the display, or a
>>>> 'fine-grained' approach of only flushing after some functions.
>>>>
>>>
>>> You're right. That's what I get for chiming in quickly before
>>> attending a customer meeting: I jump to conclusions.
>>>
>>> I thought 'finer-grained' referred to the way Anatolij originally
>>> did things:
>>>
>>>
>>> http://git.denx.de/?p=u-boot.git;a=commit;h=bfd4be803bbb7d122c2e3aaf6eaf987efa8d69da
>>>
>>> I tried to follow that lead, but it degenerated into a horrible
>>> mess of alignment checking.
>>>
>>>
>>>> My testing shows that flushing is pretty fast, but I was reluctant to
>>>> flush after every putc() as it seemed egregiously inefficient.
>>>>
>>>
>>> I need to spend some time with the patch to figure out how you
>>> get around cache issues for keystroke echo.
>>
>>
>> Well my less-than-lovely approach was to use puts() for all character
>> echo. That has a flush.
>>
>
> I just read through that and it makes perfect sense.
>
> I'm anxious to test this and your CONFIG_CONSOLE_SCROLL_LINES patch
> to see how it operates at 1080P.
>
> Without the CONFIG_CONSOLE_SCROLL_LINES patch, scrolling was incredibly
> slow.

Yes, it makes a big difference. Another option would be to enable the L2 cache.

Regards,
Simon

>
> Regards,
>
>
> Eric

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

end of thread, other threads:[~2012-10-19 23:49 UTC | newest]

Thread overview: 81+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-12 15:25 [U-Boot] [PATCH v3 0/18] tegra: Add display driver and LCD support for Seaboard Simon Glass
2012-07-12 15:25 ` [PATCH v3 02/18] fdt: Add header guard to fdtdec.h Simon Glass
2012-07-12 15:25   ` [U-Boot] " Simon Glass
2012-07-19 13:49   ` Mike Frysinger
2012-07-19 13:49     ` [U-Boot] " Mike Frysinger
2012-09-21 20:08   ` Anatolij Gustschin
2012-07-12 15:25 ` [U-Boot] [PATCH v3 03/18] tegra: Use const for pinmux_config_pingroup/table() Simon Glass
2012-07-19 13:53   ` Mike Frysinger
2012-07-12 15:25 ` [U-Boot] [PATCH v3 04/18] tegra: Add display support to funcmux Simon Glass
2012-07-19 13:54   ` Mike Frysinger
2012-07-12 15:25 ` [U-Boot] [PATCH v3 07/18] tegra: Add support for PWM Simon Glass
2012-07-19 13:55   ` Mike Frysinger
2012-09-27 13:51     ` Simon Glass
2012-07-12 15:25 ` [U-Boot] [PATCH v3 08/18] tegra: Add SOC support for display/lcd Simon Glass
2012-07-19  7:37   ` Thierry Reding
2012-07-19  8:24     ` Adam Jiang
2012-07-19  8:28       ` Thierry Reding
2012-07-19  8:03   ` Adam Jiang
2012-07-19 14:13     ` Mike Frysinger
2012-09-27 17:44     ` Simon Glass
2012-07-12 15:25 ` [U-Boot] [PATCH v3 09/18] tegra: Add LCD driver Simon Glass
2012-07-19  7:41   ` Thierry Reding
2012-09-27 17:28     ` Simon Glass
2012-07-12 15:25 ` [U-Boot] [PATCH v3 10/18] tegra: Add LCD support to Nvidia boards Simon Glass
2012-07-12 15:25 ` [U-Boot] [PATCH v3 11/18] arm: Add control over cachability of memory regions Simon Glass
2012-07-12 18:12   ` Albert ARIBAUD
2012-07-19 14:10     ` Mike Frysinger
2012-09-27 17:54       ` Simon Glass
2012-07-12 15:25 ` [U-Boot] [PATCH v3 12/18] lcd: Add CONFIG_LCD_ALIGNMENT to select frame buffer alignment Simon Glass
2012-07-19 13:59   ` Mike Frysinger
2012-09-27 19:20     ` Simon Glass
2012-07-12 15:25 ` [U-Boot] [PATCH v3 13/18] lcd: Add support for flushing LCD fb from dcache after update Simon Glass
2012-07-19 14:01   ` Mike Frysinger
2012-07-19 16:52   ` Mike Frysinger
2012-08-09  7:43   ` Lukasz Majewski
2012-10-16 18:16     ` Simon Glass
2012-10-17 10:38       ` Lukasz Majewski
2012-10-17 15:34         ` Eric Nelson
2012-10-17 22:07           ` Simon Glass
2012-10-18  0:41             ` Eric Nelson
2012-10-18  0:50               ` Simon Glass
2012-10-18  1:07                 ` Eric Nelson
2012-10-19 23:49                   ` Simon Glass
2012-07-12 15:25 ` [U-Boot] [PATCH v3 14/18] tegra: Align LCD frame buffer to section boundary Simon Glass
2012-07-19 14:01   ` Mike Frysinger
2012-07-12 15:25 ` [U-Boot] [PATCH v3 15/18] tegra: Support control of cache settings for LCD Simon Glass
     [not found] ` <1342106718-3058-1-git-send-email-sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
2012-07-12 15:25   ` [PATCH v3 01/18] fdt: Tidy debugging, add to fdtdec_get_int/addr() Simon Glass
2012-07-12 15:25     ` [U-Boot] " Simon Glass
2012-09-21 20:06     ` Anatolij Gustschin
2012-07-12 15:25   ` [PATCH v3 05/18] tegra: fdt: Add pwm binding and node Simon Glass
2012-07-12 15:25     ` [U-Boot] " Simon Glass
2012-07-12 15:25   ` [PATCH v3 06/18] tegra: fdt: Add LCD definitions for Tegra Simon Glass
2012-07-12 15:25     ` [U-Boot] " Simon Glass
     [not found]     ` <1342106718-3058-7-git-send-email-sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
2012-07-31  9:27       ` Simon Glass
2012-07-31  9:27         ` [U-Boot] " Simon Glass
     [not found]         ` <CAPnjgZ2SbVVKxUdW1cvLf_9rAWLWeiVr-y6S_sz-Uw5_O_AyQA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-07-31  9:51           ` Thierry Reding
2012-07-31  9:51             ` [U-Boot] " Thierry Reding
     [not found]             ` <20120731095116.GA16155-RM9K5IK7kjIyiCvfTdI0JKcOhU4Rzj621B7CTYaBSLdn68oJJulU0Q@public.gmane.org>
2012-09-27 19:44               ` Simon Glass
2012-09-27 19:44                 ` [U-Boot] " Simon Glass
2012-07-31 16:12           ` Stephen Warren
2012-07-31 16:12             ` [U-Boot] " Stephen Warren
2012-09-27 13:58             ` Simon Glass
2012-09-27 13:58               ` [U-Boot] " Simon Glass
     [not found]               ` <CAPnjgZ2NAf4PF0_U9hQeJzpdL87ZNq+WpxsbFJQHbh4rY2MoEg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-09-27 15:49                 ` Stephen Warren
2012-09-27 15:49                   ` [U-Boot] " Stephen Warren
2012-09-27 20:27                   ` Simon Glass
2012-09-27 20:27                     ` [U-Boot] " Simon Glass
     [not found]                     ` <CAPnjgZ2R=G=xmjdoP74JeAknwH9QGx8+mED7TQ8Kd_zEmcVwtQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-09-27 23:21                       ` Stephen Warren
2012-09-27 23:21                         ` [U-Boot] " Stephen Warren
2012-09-27 23:37                         ` Simon Glass
2012-09-27 23:37                           ` [U-Boot] " Simon Glass
     [not found]                           ` <CAPnjgZ3JuE_jiSRGW6o3eCbp4cLCf1uenKz4kPCpfqLJ3Mdmjw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-09-28  5:42                             ` Thierry Reding
2012-09-28  5:42                               ` [U-Boot] " Thierry Reding
2012-07-12 15:25   ` [PATCH v3 16/18] tegra: fdt: Add LCD definitions for Seaboard Simon Glass
2012-07-12 15:25     ` [U-Boot] " Simon Glass
2012-07-12 15:25 ` [U-Boot] [PATCH v3 17/18] lcd: Add CONSOLE_SCROLL_LINES option to speed console Simon Glass
2012-07-19 14:04   ` Mike Frysinger
2012-09-27 19:23     ` Simon Glass
2012-07-12 15:25 ` [U-Boot] [PATCH v3 18/18] tegra: Enable display/lcd support on Seaboard Simon Glass
2012-07-19  7:58 ` [U-Boot] [PATCH v3 0/18] tegra: Add display driver and LCD support for Seaboard Thierry Reding
2012-07-31  9:28   ` Simon Glass

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.