Skip to contentSkip to conversation

tegra: Add display driver and LCD support for Seaboard

PATCH Superseded Simon Glass 8 participants 40 messages Sep 28, 2012 – Oct 8, 2012 6 messages not in the archive

Subsystems (4)

v4 of 7 Superseded Latest is v7 →

lore
Share & tools
lore
#0 lore raw

v4 cover tegra: Add display driver and LCD support for Seaboard

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()
- Use const where possible in funcmux
- Add nvidia prefix to device tree properties
- Update LCD driver to deal with new fdt bindings
- Use a more generic config CONFIG_LCD_ALIGNMENT for lcd alignment
- Put the LCD cache flush logic into lcd_putc() instead of lcd_puts()
- Align tegra display using new CONFIG_LCD_ALIGNMENT feature
- Update seaboard LCD definitions for new fdt binding

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

Changes in v4:
- Moved panel information into panel node (was in rgb node)
- Add CONFIG_PWM_TEGRA to control inclusion of PWM support
- Add a little more debugging to the PWM driver
- Move code to set up PWM into the PWM commit
- Rebase on top of new tegra common directory structure
- Adjust fdt binding according to Thierry and Stephen's comments
- Remove LCD frame buffer address property hack
- Rebase on top of new tegra common directory structure
- Change LCD panel GPIOs to be entirely optional
- Only indicate that LCD init is complete when all stages complete
- Change order of LCD init so that PWM comes first
- Use system bit values for enum dcache_option instead of arbitrary numbers
- Remove system.h header which is included anyway by most archs
- Use lcd_puts() for echoing user input so lcd cached data is flushed
- Adjust LCD fdt nodes for new binding
- Use CONFIG_CONSOLE_SCROLL_LINES instead of CONSOLE_SCROLL_LINES
- Put default CONFIG_CONSOLE_SCROLL_LINES at top of file
- Add CONFIG_BOARD_LATE_INIT to enable LCD
- Enable separate CONFIG_PWM_TEGRA option

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

Simon Glass (14):
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/tegra20/Makefile            |    2 +
 arch/arm/cpu/armv7/tegra20/display.c           |  409 ++++++++++++++++++
 arch/arm/cpu/armv7/tegra20/pwm.c               |  101 +++++
 arch/arm/cpu/tegra20-common/funcmux.c          |   37 ++
 arch/arm/cpu/tegra20-common/pinmux.c           |    4 +-
 arch/arm/dts/tegra20.dtsi                      |   96 +++++
 arch/arm/include/asm/arch-tegra20/dc.h         |  545 ++++++++++++++++++++++++
 arch/arm/include/asm/arch-tegra20/display.h    |  152 +++++++
 arch/arm/include/asm/arch-tegra20/pinmux.h     |    4 +-
 arch/arm/include/asm/arch-tegra20/pwm.h        |   75 ++++
 arch/arm/include/asm/system.h                  |   30 ++
 arch/arm/lib/cache-cp15.c                      |   50 ++-
 board/nvidia/common/board.c                    |   26 ++-
 board/nvidia/dts/tegra20-seaboard.dts          |   31 ++
 common/lcd.c                                   |   85 +++-
 common/main.c                                  |   12 +-
 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  |   82 ++++
 drivers/video/Makefile                         |    1 +
 drivers/video/tegra.c                          |  372 ++++++++++++++++
 include/configs/seaboard.h                     |   13 +-
 include/configs/tegra20-common.h               |    3 +
 include/fdtdec.h                               |    2 +
 include/lcd.h                                  |   11 +
 lib/fdtdec.c                                   |    2 +
 28 files changed, 2197 insertions(+), 35 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/tegra20/display.c
 create mode 100644 arch/arm/cpu/armv7/tegra20/pwm.c
 create mode 100644 arch/arm/include/asm/arch-tegra20/dc.h
 create mode 100644 arch/arm/include/asm/arch-tegra20/display.h
 create mode 100644 arch/arm/include/asm/arch-tegra20/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
Signature · 1 line
1.7.7.3
#1 lore raw

PATCH v4 1/16 tegra: Use const for pinmux_config_pingroup/table()

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

---
Changes in v2:
- Add new patch to use const in pinmux_config_pingroup/table()

 arch/arm/cpu/tegra20-common/pinmux.c       |    4 ++--
 arch/arm/include/asm/arch-tegra20/pinmux.h |    4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)
arch/arm/cpu/tegra20-common/pinmux.c +2 -2
index 08b8305..a2a0916 100644
@@ -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;
 
arch/arm/include/asm/arch-tegra20/pinmux.h +2 -2
index 03fa7ca..797e158 100644
@@ -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 */
Signature · 1 line
1.7.7.3
#2 lore raw

PATCH v4 2/16 tegra: Add display support to funcmux

In reply to Simon Glass

Add support for a default pin mapping for display1.

---
Changes in v2:
- Use const where possible in funcmux

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

 arch/arm/cpu/tegra20-common/funcmux.c |   37 +++++++++++++++++++++++++++++++++
 1 files changed, 37 insertions(+), 0 deletions(-)
arch/arm/cpu/tegra20-common/funcmux.c +37 -0
index b2129ad..ca20f93 100644
@@ -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;
@@ -240,6 +264,19 @@ int funcmux_select(enum periph_id id, int config)
 			pinmux_tristate_disable(PINGRP_ATC);
 		}
 		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);
Signature · 1 line
1.7.7.3

A message that is not in the archive (sent off-list or not yet received): 1348793077-10126-1-git-send-email-sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org

#4 lore raw

PATCH v4 3/16 tegra: fdt: Add pwm binding and node

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.

---
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
arch/arm/dts/tegra20.dtsi +7 -0
index d936b1e..3221bc9 100644
@@ -211,4 +211,11 @@
 		compatible = "nvidia,tegra20-nand";
 		reg = <0x70008000 0x100>;
 	};
+
+	pwm: pwm@7000a000 {
+		compatible = "nvidia,tegra20-pwm";
+		reg = <0x7000a000 0x100>;
+		#pwm-cells = <2>;
+	};
+
 };
doc/device-tree-bindings/pwm/tegra20-pwm.txt new file +18 -0
new file mode 100644
index 0000000..bbbeedb
@@ -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>;
+	};
Signature · 1 line
1.7.7.3
#5 lore raw

Re: [PATCH v4 03/16] tegra: fdt: Add pwm binding and node

Quoted 36 lines · Simon Glass

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.

---
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
arch/arm/dts/tegra20.dtsi +7 -0
index d936b1e..3221bc9 100644
@@ -211,4 +211,11 @@
 		compatible = "nvidia,tegra20-nand";
 		reg = <0x70008000 0x100>;
 	};
+
+	pwm: pwm@7000a000 {
+		compatible = "nvidia,tegra20-pwm";
+		reg = <0x7000a000 0x100>;
+		#pwm-cells = <2>;
+	};
+
 };
doc/device-tree-bindings/pwm/tegra20-pwm.txt new file +0 -0
new file mode 100644
index 0000000..bbbeedb

doc/device-tree-bindings/pwm/tegra20-pwm.txt line 10

Quoted 10 lines
doc/device-tree-bindings/pwm/tegra20-pwm.txt new file +10 -0
@@ -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.

This is a mistake in the Linux kernel documentation. The second cell specifies the period in nanoseconds, not the duty cycle. I'll fix this up in the kernel.

Thierry

_______________________________________________
U-Boot mailing list
[email protected]
http://lists.denx.de/mailman/listinfo/u-boot

A message that is not in the archive (sent off-list or not yet received): 20120928200817.GB30777-RM9K5IK7kjIQXX3q8xo1gnVAuStQJXxyR5q1nwbD4aMs9pC9oP6+/[email protected]

#7 lore raw

Re: [PATCH v4 03/16] tegra: fdt: Add pwm binding and node

Hi Thierry,

Quoted 43 lines · Thierry Reding
Quoted 42 lines · Simon Glass

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.

---
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
arch/arm/dts/tegra20.dtsi +7 -0
index d936b1e..3221bc9 100644
@@ -211,4 +211,11 @@
              compatible = "nvidia,tegra20-nand";
              reg = <0x70008000 0x100>;
      };
+
+     pwm: pwm@7000a000 {
+             compatible = "nvidia,tegra20-pwm";
+             reg = <0x7000a000 0x100>;
+             #pwm-cells = <2>;
+     };
+
 };
doc/device-tree-bindings/pwm/tegra20-pwm.txt new file +6 -0
new file mode 100644
index 0000000..bbbeedb
@@ -0,0 +1,18 @@
+Tegra SoC PWFM controller
+
+Required properties:
+- compatible: should be one of:
+  - "nvidia,tegra20-pwm"
+  - "nvidia,tegra30-pwm"
Quoted 8 lines

doc/device-tree-bindings/pwm/tegra20-pwm.txt line 10

Quoted 4 lines
doc/device-tree-bindings/pwm/tegra20-pwm.txt new file +4 -0
+- 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.

This is a mistake in the Linux kernel documentation. The second cell specifies the period in nanoseconds, not the duty cycle. I'll fix this up in the kernel.

Oh ok, thanks. I will update this patch.

Regards,
Simon

Quoted 2 lines

Thierry

#8 lore raw

PATCH v4 4/16 tegra: fdt: Add LCD definitions for Tegra

In reply to a message not in the archive

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.

---
Changes in v2:
- Add nvidia prefix to device tree properties

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

Changes in v4:
- Moved panel information into panel node (was in rgb node)
- Remove LCD frame buffer address property hack

 arch/arm/dts/tegra20.dtsi                      |   89 ++++++++++++++++++++++++
 doc/device-tree-bindings/video/displaymode.txt |   42 +++++++++++
 doc/device-tree-bindings/video/tegra20-dc.txt  |   82 ++++++++++++++++++++++
 3 files changed, 213 insertions(+), 0 deletions(-)
 create mode 100644 doc/device-tree-bindings/video/displaymode.txt
 create mode 100644 doc/device-tree-bindings/video/tegra20-dc.txt
arch/arm/dts/tegra20.dtsi +89 -0
index 3221bc9..5fb1fd7 100644
@@ -218,4 +218,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";
+		};
+	};
+
 };
doc/device-tree-bindings/video/displaymode.txt new file +42 -0

42 lines not on this page · raw message

doc/device-tree-bindings/video/tegra20-dc.txt new file +82 -0

82 lines not on this page · raw message

Signature · 1 line
1.7.7.3

A message that is not in the archive (sent off-list or not yet received): 1348793077-10126-5-git-send-email-sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org

#10 lore raw

Re: [PATCH v4 04/16] tegra: fdt: Add LCD definitions for Tegra

Quoted 14 lines · Simon Glass

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.

doc/device-tree-bindings/video/displaymode.txt line 30

Quoted 4 lines
doc/device-tree-bindings/video/displaymode.txt +3 -0
 
+Example:
+
+	display@0 {

That should really be "mode" or "timing", since it's describing a display mode/timing not a display. I believe the latest messages in that thread indicate a similar change will be made to the proposed Linux binding.

doc/device-tree-bindings/video/tegra20-dc.txt line 21

Quoted 8 lines
doc/device-tree-bindings/video/tegra20-dc.txt +6 -0
 
+Required properties (rgb) :
+ - nvidia,panel : phandle of LCD panel information
+
+
+The panel node describes the panel itself. This has the properties listed in
+displaymode.txt as well as:

It should really be a sub-node; like:

panel {
    ... all the panel-specific stuff from this binding ...
    modes {
        default {
            ... all the stuff from displaymode.txt ...
        };
    };
};

Since the panel itself and the (potentially, list of) modes it can support are separate things.

#11 lore raw

Re: [PATCH v4 04/16] tegra: fdt: Add LCD definitions for Tegra

In reply to a message not in the archive
Quoted 21 lines · Simon Glass

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.

arch/arm/dts/tegra20.dtsi +6 -0
 
+	host1x {
+		compatible = "nvidia,tegra20-host1x", "simple-bus";
+		reg = <0x50000000 0x00024000>;
+		interrupts = <0 65 0x04   /* mpcore syncpt */
+			      0 67 0x04>; /* mpcore general */
+

arch/arm/dts/tegra20.dtsi line 236

Quoted 10 lines
arch/arm/dts/tegra20.dtsi +10 -0
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		ranges = <0x54000000 0x54000000 0x04000000>;
+
+		/* video-encoding/decoding */
+		mpe {
+			reg = <0x54040000 0x00040000>;
+			interrupts = <0 68 0x04>;
+		};

Shouldn't all of these nodes have status="disabled", since in general boards will want to opt-in to these modules. In fact, many of these nodes won't end up (ever?) being used in U-Boot; perhaps we should only add the nodes we care about.

arch/arm/dts/tegra20.dtsi line 276

Quoted 10 lines
arch/arm/dts/tegra20.dtsi +10 -0
+		/* display controllers */
+		dc@54200000 {
+			compatible = "nvidia,tegra20-dc";
+			reg = <0x54200000 0x00040000>;
+			interrupts = <0 73 0x04>;
+
+			rgb {
+				status = "disabled";
+			};
+		};

I think we definitely want status="disabled" in the dc nodes themselves, since we definitely want boards in U-Boot to control whether to enable the dc.

A message that is not in the archive (sent off-list or not yet received): [email protected]

#13 lore raw

Re: [PATCH v4 04/16] tegra: fdt: Add LCD definitions for Tegra

Hi Stephen,

Quoted 49 lines · Stephen Warren
Quoted 21 lines · Simon Glass

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.

arch/arm/dts/tegra20.dtsi +6 -0
 
+     host1x {
+             compatible = "nvidia,tegra20-host1x", "simple-bus";
+             reg = <0x50000000 0x00024000>;
+             interrupts = <0 65 0x04   /* mpcore syncpt */
+                           0 67 0x04>; /* mpcore general */
+

arch/arm/dts/tegra20.dtsi line 236

Quoted 10 lines
arch/arm/dts/tegra20.dtsi +10 -0
+             #address-cells = <1>;
+             #size-cells = <1>;
+
+             ranges = <0x54000000 0x54000000 0x04000000>;
+
+             /* video-encoding/decoding */
+             mpe {
+                     reg = <0x54040000 0x00040000>;
+                     interrupts = <0 68 0x04>;
+             };

Shouldn't all of these nodes have status="disabled", since in general boards will want to opt-in to these modules. In fact, many of these nodes won't end up (ever?) being used in U-Boot; perhaps we should only add the nodes we care about.

arch/arm/dts/tegra20.dtsi line 276

Quoted 10 lines
arch/arm/dts/tegra20.dtsi +10 -0
+             /* display controllers */
+             dc@54200000 {
+                     compatible = "nvidia,tegra20-dc";
+                     reg = <0x54200000 0x00040000>;
+                     interrupts = <0 73 0x04>;
+
+                     rgb {
+                             status = "disabled";
+                     };
+             };
Quoted 4 lines

I think we definitely want status="disabled" in the dc nodes themselves, since we definitely want boards in U-Boot to control whether to enable the dc.

OK I will update these, thanks.

Regards,
Simon

#14 lore raw

PATCH v4 14/16 tegra: fdt: Add LCD definitions for Seaboard

In reply to a message not in the archive

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

---
Changes in v2:
- Update seaboard LCD definitions for new fdt binding

Changes in v3:
- Use new upstream proposed LCD definitions

Changes in v4:
- Adjust LCD fdt nodes for new binding
- Remove LCD frame buffer address property hack

 board/nvidia/dts/tegra20-seaboard.dts |   31 +++++++++++++++++++++++++++++++
 1 files changed, 31 insertions(+), 0 deletions(-)
board/nvidia/dts/tegra20-seaboard.dts +31 -0
index 25a63a0..df730f5 100644
@@ -163,4 +163,35 @@
 			compatible = "hynix,hy27uf4g2b", "nand-flash";
 		};
 	};
+
+	host1x {
+		dc@54200000 {
+			rgb {
+				status = "okay";
+				nvidia,panel = <&lcd_panel>;
+			};
+		};
+	};
+
+	lcd_panel: panel {
+		/* 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,bits-per-pixel = <16>;
+		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>;
+	};
+
 };
Signature · 1 line
1.7.7.3

A message that is not in the archive (sent off-list or not yet received): 1348793077-10126-15-git-send-email-sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org

#16 lore raw

Re: [PATCH v4 14/16] tegra: fdt: Add LCD definitions for Seaboard

board/nvidia/dts/tegra20-seaboard.dts line 168

Quoted 7 lines · Simon Glass

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

board/nvidia/dts/tegra20-seaboard.dts +2 -0
 
+	host1x {
+		dc@54200000 {

So based on my previous comment, I think you want status="okay" at this level too, perhaps even at the host1x level.

Quoted 6 lines
board/nvidia/dts/tegra20-seaboard.dts +6 -0
+			rgb {
+				status = "okay";
+				nvidia,panel = <&lcd_panel>;
+			};
+		};
+	};

A message that is not in the archive (sent off-list or not yet received): [email protected]

#18 lore raw

Re: [PATCH v4 14/16] tegra: fdt: Add LCD definitions for Seaboard

Hi Stephen,

Quoted 11 lines · Stephen Warren

board/nvidia/dts/tegra20-seaboard.dts line 168

Quoted 7 lines · Simon Glass

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

board/nvidia/dts/tegra20-seaboard.dts +2 -0
 
+     host1x {
+             dc@54200000 {

So based on my previous comment, I think you want status="okay" at this level too, perhaps even at the host1x level.

Yes I will do this.

Quoted 8 lines

board/nvidia/dts/tegra20-seaboard.dts line 174

Quoted 7 lines
board/nvidia/dts/tegra20-seaboard.dts +6 -0
+                     rgb {
+                             status = "okay";
+                             nvidia,panel = <&lcd_panel>;
+                     };
+             };
+     };

Regards,
Simon

#19 lore raw

PATCH v4 5/16 tegra: Add support for PWM

In reply to Simon Glass

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

---
Changes in v3:
- Rename pwfm driver to pwm
- Use new proposed upstream pwm binding
- Decode fdt node within the pwm driver
- Introduce concept of a pwm channel, rather than separate peripherals

Changes in v4:
- Add CONFIG_PWM_TEGRA to control inclusion of PWM support
- Add a little more debugging to the PWM driver
- Move code to set up PWM into the PWM commit

 arch/arm/cpu/armv7/tegra20/Makefile     |    1 +
 arch/arm/cpu/armv7/tegra20/pwm.c        |  101 +++++++++++++++++++++++++++++++
 arch/arm/include/asm/arch-tegra20/pwm.h |   75 +++++++++++++++++++++++
 board/nvidia/common/board.c             |    5 ++
 include/fdtdec.h                        |    1 +
 lib/fdtdec.c                            |    1 +
 6 files changed, 184 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/tegra20/pwm.c
 create mode 100644 arch/arm/include/asm/arch-tegra20/pwm.h
arch/arm/cpu/armv7/tegra20/Makefile +1 -0
index 09a0314..77cb4d1 100644
@@ -28,6 +28,7 @@ include $(TOPDIR)/config.mk
 LIB	=  $(obj)lib$(SOC).o
 
 COBJS-$(CONFIG_USB_EHCI_TEGRA) += usb.o
+COBJS-$(CONFIG_PWM_TEGRA) += pwm.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
arch/arm/cpu/armv7/tegra20/pwm.c new file +101 -0

101 lines not on this page · raw message

arch/arm/include/asm/arch-tegra20/pwm.h new file +75 -0

75 lines not on this page · raw message

board/nvidia/common/board.c +5 -0
index 8821fdf..7a7d55c 100644
@@ -29,6 +29,7 @@
 #include <asm/arch/emc.h>
 #include <asm/arch/pinmux.h>
 #include <asm/arch/pmu.h>
+#include <asm/arch/pwm.h>
 #include <asm/arch/tegra.h>
 #include <asm/arch/usb.h>
 #include <asm/arch-tegra/board.h>
@@ -105,6 +106,10 @@ int board_init(void)
 	pin_mux_spi();
 	spi_init();
 #endif
+#ifdef CONFIG_PWM_TEGRA
+	if (pwm_init(gd->fdt_blob))
+		debug("%s: Failed to init pwm\n", __func__);
+#endif
 	/* boot param addr */
 	gd->bd->bi_boot_params = (NV_PA_SDRAM_BASE + 0x100);
 
include/fdtdec.h +1 -0
index 0b14075..cdc87eb 100644
@@ -66,6 +66,7 @@ enum fdt_compat_id {
 	COMPAT_NVIDIA_TEGRA20_EMC_TABLE, /* Tegra20 memory timing table */
 	COMPAT_NVIDIA_TEGRA20_KBC,	/* Tegra20 Keyboard */
 	COMPAT_NVIDIA_TEGRA20_NAND,	/* Tegra2 NAND controller */
+	COMPAT_NVIDIA_TEGRA20_PWM,	/* Tegra 2 PWM controller */
 
 	COMPAT_COUNT,
 };
lib/fdtdec.c +1 -0
index 4c23f45..947f7c0 100644
@@ -43,6 +43,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_NAND, "nvidia,tegra20-nand"),
+	COMPAT(NVIDIA_TEGRA20_PWM, "nvidia,tegra20-pwm"),
 };
 
 const char *fdtdec_get_compatible(enum fdt_compat_id id)
Signature · 1 line
1.7.7.3
#20 lore raw

PATCH v4 6/16 tegra: Add SOC support for display/lcd

In reply to Simon Glass

From: Wei Ni <[email protected]>

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

---
Changes in v3:
- Separate display driver and LCD driver more in fdt
- Add probe function to read in fdt parameters in display driver

Changes in v4:
- Rebase on top of new tegra common directory structure
- Adjust fdt binding according to Thierry and Stephen's comments
- Remove LCD frame buffer address property hack

 arch/arm/cpu/armv7/tegra20/Makefile         |    1 +
 arch/arm/cpu/armv7/tegra20/display.c        |  409 ++++++++++++++++++++
 arch/arm/include/asm/arch-tegra20/dc.h      |  545 +++++++++++++++++++++++++++
 arch/arm/include/asm/arch-tegra20/display.h |  152 ++++++++
 include/fdtdec.h                            |    1 +
 lib/fdtdec.c                                |    1 +
 6 files changed, 1109 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/tegra20/display.c
 create mode 100644 arch/arm/include/asm/arch-tegra20/dc.h
 create mode 100644 arch/arm/include/asm/arch-tegra20/display.h
arch/arm/cpu/armv7/tegra20/Makefile +1 -0
index 77cb4d1..54ed8c4 100644
@@ -29,6 +29,7 @@ LIB	=  $(obj)lib$(SOC).o
 
 COBJS-$(CONFIG_USB_EHCI_TEGRA) += usb.o
 COBJS-$(CONFIG_PWM_TEGRA) += pwm.o
+COBJS-$(CONFIG_VIDEO_TEGRA) += display.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
arch/arm/cpu/armv7/tegra20/display.c new file +409 -0

409 lines not on this page · raw message

arch/arm/include/asm/arch-tegra20/dc.h new file +545 -0

545 lines not on this page · raw message

arch/arm/include/asm/arch-tegra20/display.h new file +152 -0

152 lines not on this page · raw message

include/fdtdec.h +1 -0
index cdc87eb..64e5cff 100644
@@ -67,6 +67,7 @@ enum fdt_compat_id {
 	COMPAT_NVIDIA_TEGRA20_KBC,	/* Tegra20 Keyboard */
 	COMPAT_NVIDIA_TEGRA20_NAND,	/* Tegra2 NAND controller */
 	COMPAT_NVIDIA_TEGRA20_PWM,	/* Tegra 2 PWM controller */
+	COMPAT_NVIDIA_TEGRA20_DC,	/* Tegra 2 Display controller */
 
 	COMPAT_COUNT,
 };
lib/fdtdec.c +1 -0
index 947f7c0..23e0205 100644
@@ -44,6 +44,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
 	COMPAT(NVIDIA_TEGRA20_KBC, "nvidia,tegra20-kbc"),
 	COMPAT(NVIDIA_TEGRA20_NAND, "nvidia,tegra20-nand"),
 	COMPAT(NVIDIA_TEGRA20_PWM, "nvidia,tegra20-pwm"),
+	COMPAT(NVIDIA_TEGRA20_DC, "nvidia,tegra20-dc"),
 };
 
 const char *fdtdec_get_compatible(enum fdt_compat_id id)
Signature · 1 line
1.7.7.3
#21 lore raw

PATCH v4 7/16 tegra: Add LCD driver

In reply to Simon Glass

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

---
Changes in v2:
- Update LCD driver to deal with new fdt bindings

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

Changes in v4:
- Rebase on top of new tegra common directory structure
- Change LCD panel GPIOs to be entirely optional
- Only indicate that LCD init is complete when all stages complete

 drivers/video/Makefile |    1 +
 drivers/video/tegra.c  |  361 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 362 insertions(+), 0 deletions(-)
 create mode 100644 drivers/video/tegra.c
drivers/video/Makefile +1 -0
index ebb6da8..78a7668 100644
@@ -49,6 +49,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))
drivers/video/tegra.c new file +361 -0

361 lines not on this page · raw message

Signature · 1 line
1.7.7.3
#22 lore raw

PATCH v4 7/16 tegra: Add LCD driver

Simon,

I tried to adapt this for paz00. I only get backlight and an all white screen. On checking what's wrong I stumpled about something strange below...

Marc

Quoted 184 lines · On Thursday 27 September 2012 17:44:28 Simon Glass wrote:

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

---
Changes in v2:
- Update LCD driver to deal with new fdt bindings

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

Changes in v4:
- Rebase on top of new tegra common directory structure
- Change LCD panel GPIOs to be entirely optional
- Only indicate that LCD init is complete when all stages complete

 drivers/video/Makefile |    1 +
 drivers/video/tegra.c  |  361
++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 362
insertions(+), 0 deletions(-)
 create mode 100644 drivers/video/tegra.c
drivers/video/Makefile +1 -0
index ebb6da8..78a7668 100644
@@ -49,6 +49,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))
drivers/video/tegra.c new file +141 -0
new file mode 100644
index 0000000..9df2bd3
@@ -0,0 +1,361 @@
+/*
+ * 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-tegra/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.

drivers/video/tegra.c line 151

Quoted 10 lines
drivers/video/tegra.c new file +10 -0
+ *  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;

this is always NULL, because it is defined in a circular manner (see arch/arm/cpu/armv7/tegra20/display.c:383) and ...

Quoted 82 lines
drivers/video/tegra.c new file +42 -0
+	/* 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 at %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) +{

drivers/video/tegra.c new file +39 -0
+	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);
+
+	/* These GPIOs are all optional */
+	fdtdec_decode_gpio(blob, display_node, "nvidia,backlight-enable-gpios",
+			    &config->backlight_en);
+	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);
+	fdtdec_decode_gpio(blob, display_node, "nvidia,panel-vdd-gpios",
+			   &config->panel_vdd);
+
+	return fdtdec_get_int_array(blob, display_node, "nvidia,panel-timings",
+			config->panel_timings, FDT_LCD_TIMINGS);
+}
+
+/**
+ * Handle the next stage of device init

drivers/video/tegra.c line 244

Quoted 10 lines
drivers/video/tegra.c new file +10 -0
+ */
+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)) {

.... here.

Quoted 117 lines
drivers/video/tegra.c new file +117 -0
+			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.
+		 */
+		if (fdt_gpio_isvalid(&config.panel_vdd))
+			gpio_direction_output(config.panel_vdd.gpio, 1);
+		if (fdt_gpio_isvalid(&config.lvds_shutdown))
+			gpio_direction_output(config.lvds_shutdown.gpio, 0);
+		if (fdt_gpio_isvalid(&config.backlight_vdd))
+			gpio_direction_output(config.backlight_vdd.gpio, 0);
+		if (fdt_gpio_isvalid(&config.backlight_en))
+			gpio_direction_output(config.backlight_en.gpio, 0);
+		break;
+	case STAGE_LVDS:
+		if (fdt_gpio_isvalid(&config.lvds_shutdown))
+			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:
+		if (fdt_gpio_isvalid(&config.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);
+	if (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);
+	}
+}
#23 lore raw

PATCH v4 7/16 tegra: Add LCD driver

Hi Marc,

Quoted 3 lines · Marc Dietrich

Simon,

I tried to adapt this for paz00. I only get backlight and an all white screen.

I'm not sure about that. One possibility is that your PWM is connected up differently. On Seaboard at least, I found that without the PWM I would get nothing on the display.

Quoted 289 lines

On checking what's wrong I stumpled about something strange below...

Marc

Quoted 184 lines · On Thursday 27 September 2012 17:44:28 Simon Glass wrote:

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

---
Changes in v2:
- Update LCD driver to deal with new fdt bindings

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

Changes in v4:
- Rebase on top of new tegra common directory structure
- Change LCD panel GPIOs to be entirely optional
- Only indicate that LCD init is complete when all stages complete

 drivers/video/Makefile |    1 +
 drivers/video/tegra.c  |  361
++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 362
insertions(+), 0 deletions(-)
 create mode 100644 drivers/video/tegra.c
drivers/video/Makefile +1 -0
index ebb6da8..78a7668 100644
@@ -49,6 +49,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))
drivers/video/tegra.c new file +141 -0
new file mode 100644
index 0000000..9df2bd3
@@ -0,0 +1,361 @@
+/*
+ * 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-tegra/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.

drivers/video/tegra.c line 151

Quoted 10 lines
drivers/video/tegra.c new file +10 -0
+ *  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;

this is always NULL, because it is defined in a circular manner (see arch/arm/cpu/armv7/tegra20/display.c:383) and ...

Quoted 86 lines
drivers/video/tegra.c new file +42 -0
+     /* 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 at %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) +{

drivers/video/tegra.c new file +43 -0
+     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);
+
+     /* These GPIOs are all optional */
+     fdtdec_decode_gpio(blob, display_node, "nvidia,backlight-enable-gpios",
+                         &config->backlight_en);
+     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);
+     fdtdec_decode_gpio(blob, display_node, "nvidia,panel-vdd-gpios",
+                        &config->panel_vdd);
+
+     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);
Quoted 8 lines

drivers/video/tegra.c line 244

Quoted 6 lines
drivers/video/tegra.c new file +6 -0
+
+     /* 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)) {

.... here.

Yes, that should be gd->fb_base I think. I will update it.

Quoted 110 lines
Quoted 110 lines
drivers/video/tegra.c new file +109 -0
+                     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.
+              */
+             if (fdt_gpio_isvalid(&config.panel_vdd))
+                     gpio_direction_output(config.panel_vdd.gpio, 1);
+             if (fdt_gpio_isvalid(&config.lvds_shutdown))
+                     gpio_direction_output(config.lvds_shutdown.gpio, 0);
+             if (fdt_gpio_isvalid(&config.backlight_vdd))
+                     gpio_direction_output(config.backlight_vdd.gpio, 0);
+             if (fdt_gpio_isvalid(&config.backlight_en))
+                     gpio_direction_output(config.backlight_en.gpio, 0);
+             break;
+     case STAGE_LVDS:
+             if (fdt_gpio_isvalid(&config.lvds_shutdown))
+                     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:
+             if (fdt_gpio_isvalid(&config.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);
+     if (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
Quoted 8 lines

drivers/video/tegra.c line 361

Quoted 8 lines
drivers/video/tegra.c new file +8 -0
+      * 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);
+     }
+}

Regards,
Simon

#24 lore raw

PATCH v4 7/16 tegra: Add LCD driver

Quoted 10 lines · Simon Glass

Hi Marc,

Quoted 3 lines · Marc Dietrich

Simon,

I tried to adapt this for paz00. I only get backlight and an all white screen.

I'm not sure about that. One possibility is that your PWM is connected up differently. On Seaboard at least, I found that without the PWM I would get nothing on the display.

BTW, while fiddling around trying to find the corrupted-display-after-reboot problem on Seaboard, I turned off/on random display-related things. IIRC, when the panel VDD was off, but the backlight was on, the display was all-white. Now, there are probably a ton of other reasons that might happen, but that one would be simple to verify with a few "gpio set" or "gpio clear" commands on your system...

#25 lore raw

PATCH v4 8/16 tegra: Add LCD support to Nvidia boards

In reply to Simon Glass

Add calls to the LCD driver from Nvidia board code.

---
Changes in v3:
- Add separate call to pwm_init() in board_init()

Changes in v4:
- Change order of LCD init so that PWM comes first

 board/nvidia/common/board.c |   21 ++++++++++++++++++++-
 1 files changed, 20 insertions(+), 1 deletions(-)
board/nvidia/common/board.c +20 -1
index 7a7d55c..17aafb6 100644
@@ -26,6 +26,7 @@
 #include <linux/compiler.h>
 #include <asm/io.h>
 #include <asm/arch/clock.h>
+#include <asm/arch/display.h>
 #include <asm/arch/emc.h>
 #include <asm/arch/pinmux.h>
 #include <asm/arch/pmu.h>
@@ -110,6 +111,9 @@ int board_init(void)
 	if (pwm_init(gd->fdt_blob))
 		debug("%s: Failed to init pwm\n", __func__);
 #endif
+#ifdef CONFIG_LCD
+	tegra_lcd_check_next_stage(gd->fdt_blob, 0);
+#endif
 	/* boot param addr */
 	gd->bd->bi_boot_params = (NV_PA_SDRAM_BASE + 0x100);
 
@@ -135,6 +139,9 @@ int board_init(void)
 	pin_mux_usb();
 	board_usb_init(gd->fdt_blob);
 #endif
+#ifdef CONFIG_LCD
+	tegra_lcd_check_next_stage(gd->fdt_blob, 0);
+#endif
 
 #ifdef CONFIG_TEGRA_LP0
 	/* save Sdram params to PMC 2, 4, and 24 for WB0 */
@@ -165,6 +172,18 @@ int board_early_init_f(void)
 #else
 	gpio_config_uart();
 #endif
-	return 0;
+#ifdef CONFIG_LCD
+	tegra_lcd_early_init(gd->fdt_blob);
+#endif
+return 0;
 }
 #endif	/* EARLY_INIT */
+
+int board_late_init(void)
+{
+#ifdef CONFIG_LCD
+	/* Make sure we finish initing the LCD */
+	tegra_lcd_check_next_stage(gd->fdt_blob, 1);
+#endif
+	return 0;
+}
Signature · 1 line
1.7.7.3
#26 lore raw

PATCH v4 9/16 arm: Add control over cachability of memory regions

In reply to Simon Glass

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.

---
Changes in v4:
- Use system bit values for enum dcache_option instead of arbitrary numbers

 arch/arm/cpu/armv7/cache_v7.c |   11 +++++++++
 arch/arm/include/asm/system.h |   30 ++++++++++++++++++++++++
 arch/arm/lib/cache-cp15.c     |   50 ++++++++++++++++++++++++++++++++---------
 3 files changed, 80 insertions(+), 11 deletions(-)
arch/arm/cpu/armv7/cache_v7.c +11 -0
index 1b4e808..5f6d039 100644
@@ -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
arch/arm/include/asm/system.h +30 -0
index 2b28a26..9a05211 100644
@@ -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 = 0x12,
+	DCACHE_WRITETHROUGH = 0x1a,
+	DCACHE_WRITEBACK = 0x1e,
+};
+
+/* 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)
arch/arm/lib/cache-cp15.c +39 -11

88 lines not on this page · raw message

Signature · 1 line
1.7.7.3
#27 lore raw

PATCH v4 10/16 lcd: Add CONFIG_LCD_ALIGNMENT to select frame buffer alignment

In reply to Simon Glass

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.

---
Changes in v2:
- Use a more generic config CONFIG_LCD_ALIGNMENT for lcd alignment

Changes in v4:
- Remove system.h header which is included anyway by most archs

 README        |   10 ++++++++++
 common/lcd.c  |   21 ++++++++++++++++-----
 include/lcd.h |    3 +++
 3 files changed, 29 insertions(+), 5 deletions(-)
README +10 -0
index 5793b0a..1d0ce50 100644
@@ -1440,6 +1440,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
common/lcd.c +16 -5
index b6be800..37b0393 100644
@@ -72,6 +72,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 +330,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 +343,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 +455,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;
include/lcd.h +3 -0
index 42070d7..6a600ee 100644
@@ -297,6 +297,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						*/
 /************************************************************************/
Signature · 1 line
1.7.7.3
#28 lore raw

PATCH v4 11/16 lcd: Add support for flushing LCD fb from dcache after update

In reply to Simon Glass

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

---
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()

Changes in v4:
- Use lcd_puts() for echoing user input so lcd cached data is flushed

 common/lcd.c  |   46 +++++++++++++++++++++++++++++++++++++++-------
 common/main.c |   12 ++++++++++--
 include/lcd.h |    8 ++++++++
 3 files changed, 57 insertions(+), 9 deletions(-)
common/lcd.c +39 -7
index 37b0393..74fa3f9 100644
@@ -94,6 +94,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);
@@ -102,6 +105,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)
@@ -111,6 +136,7 @@ static void console_scrollup(void)
 
 	/* Clear the last one */
 	memset(CONSOLE_ROW_LAST, COLOR_MASK(lcd_color_bg), CONSOLE_ROW_SIZE);
+	lcd_sync();
 }
 
 /*----------------------------------------------------------------------*/
@@ -140,6 +166,8 @@ static inline void console_newline(void)
 		/* Scroll everything up */
 		console_scrollup();
 		--console_row;
+	} else {
+		lcd_sync();
 	}
 }
 
@@ -195,6 +223,7 @@ void lcd_puts(const char *s)
 	while (*s) {
 		lcd_putc(*s++);
 	}
+	lcd_sync();
 }
 
 /*----------------------------------------------------------------------*/
@@ -362,13 +391,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
@@ -410,6 +432,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(
@@ -621,6 +651,7 @@ void bitmap_plot(int x, int y)
 	}
 
 	WATCHDOG_RESET();
+	lcd_sync();
 }
 #else
 static inline void bitmap_plot(int x, int y) {}
@@ -842,6 +873,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
 		break;
 	};
 
+	lcd_sync();
 	return 0;
 }
 #endif
common/main.c +10 -2
index 81984ac..d3356e1 100644
@@ -1040,8 +1040,16 @@ int readline_into_buffer(const char *const prompt, char *buffer, int timeout)
 					puts (tab_seq+(col&07));
 					col += 8 - (col&07);
 				} else {
-					++col;		/* echo input		*/
-					putc (c);
+					char buf[2];
+
+					/*
+					 * Echo input using puts() to force am
+					 * LCD flush if we are using an LCD
+					 */
+					++col;
+					buf[0] = c;
+					buf[1] = '\0';
+					puts(buf);
 				}
 				*p++ = c;
 				++n;
include/lcd.h +8 -0
index 6a600ee..8f84741 100644
@@ -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
Signature · 1 line
1.7.7.3
#29 lore raw

PATCH v4 12/16 tegra: Align LCD frame buffer to section boundary

In reply to Simon Glass

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.

---
Changes in v2:
- Align tegra display using new CONFIG_LCD_ALIGNMENT feature

 include/configs/tegra20-common.h |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)
include/configs/tegra20-common.h +3 -0
index fa14a1c..a96233a 100644
@@ -45,6 +45,9 @@
 
 #include <asm/arch/tegra.h>		/* get chip and board defs */
 
+/* Align LCD to 1MB boundary */
+#define CONFIG_LCD_ALIGNMENT	MMU_SECTION_SIZE
+
 /*
  * Display CPU and Board information
  */
Signature · 1 line
1.7.7.3
#30 lore raw

PATCH v4 13/16 tegra: Support control of cache settings for LCD

In reply to Simon Glass

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

---
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(-)
drivers/video/tegra.c +11 -0
index 9df2bd3..ff2b70e 100644
@@ -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);
 }
 
Signature · 1 line
1.7.7.3
#31 lore raw

PATCH v4 15/16 lcd: Add CONSOLE_SCROLL_LINES option to speed console

In reply to Simon Glass

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.

---
Changes in v3:
- Fix tiny bug in mult-line lcd scrolling

Changes in v4:
- Use CONFIG_CONSOLE_SCROLL_LINES instead of CONSOLE_SCROLL_LINES
- Put default CONFIG_CONSOLE_SCROLL_LINES at top of file

 README       |    6 ++++++
 common/lcd.c |   18 +++++++++++++++---
 2 files changed, 21 insertions(+), 3 deletions(-)
README +6 -0
index 1d0ce50..14b1f83 100644
@@ -1449,6 +1449,12 @@ The following options need to be configured:
 		here, since it is cheaper to change data cache settings on
 		a per-section basis.
 
+		CONFIG_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
 
common/lcd.c +15 -3
index 74fa3f9..460f0ca 100644
@@ -76,6 +76,11 @@
 #define CONFIG_LCD_ALIGNMENT PAGE_SIZE
 #endif
 
+/* By default we scroll by a single line */
+#ifndef CONFIG_CONSOLE_SCROLL_LINES
+#define CONFIG_CONSOLE_SCROLL_LINES 1
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 ulong lcd_setmem (ulong addr);
@@ -131,12 +136,20 @@ void lcd_set_flush_dcache(int flush)
 
 static void console_scrollup(void)
 {
+	const int rows = CONFIG_CONSOLE_SCROLL_LINES;
+
 	/* 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;
 }
 
 /*----------------------------------------------------------------------*/
@@ -165,7 +178,6 @@ static inline void console_newline(void)
 	if (console_row >= CONSOLE_ROWS) {
 		/* Scroll everything up */
 		console_scrollup();
-		--console_row;
 	} else {
 		lcd_sync();
 	}
Signature · 1 line
1.7.7.3
#32 lore raw

PATCH v4 15/16 lcd: Add CONSOLE_SCROLL_LINES option to speed console

Am Donnerstag, den 27.09.2012, 17:44 -0700 schrieb Simon Glass:

Quoted 54 lines

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.

---
Changes in v3:
- Fix tiny bug in mult-line lcd scrolling

Changes in v4:
- Use CONFIG_CONSOLE_SCROLL_LINES instead of CONSOLE_SCROLL_LINES
- Put default CONFIG_CONSOLE_SCROLL_LINES at top of file

 README       |    6 ++++++
 common/lcd.c |   18 +++++++++++++++---
 2 files changed, 21 insertions(+), 3 deletions(-)
README +6 -0
index 1d0ce50..14b1f83 100644
@@ -1449,6 +1449,12 @@ The following options need to be configured:
 		here, since it is cheaper to change data cache settings on
 		a per-section basis.
 
+		CONFIG_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
 
common/lcd.c +5 -0
index 74fa3f9..460f0ca 100644
@@ -76,6 +76,11 @@
 #define CONFIG_LCD_ALIGNMENT PAGE_SIZE
 #endif
 
+/* By default we scroll by a single line */
+#ifndef CONFIG_CONSOLE_SCROLL_LINES
+#define CONFIG_CONSOLE_SCROLL_LINES 1
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 ulong lcd_setmem (ulong addr);

common/lcd.c void lcd_set_flush_dcache(int flush) · line 141

Quoted 6 lines
common/lcd.c +2 -0
@@ -131,12 +136,20 @@ void lcd_set_flush_dcache(int flush)
 
 static void console_scrollup(void)
 {
+	const int rows = CONFIG_CONSOLE_SCROLL_LINES;
+
 	/* Copy up rows ignoring the first one */

Comment is inaccurate as you possibly ignore more than the first line.

common/lcd.c void lcd_set_flush_dcache(int flush) · line 146

Quoted 6 lines
common/lcd.c +3 -1
-	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 */

Same as above.

Quoted 18 lines
common/lcd.c +5 -2
-	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;
 }
 
 /*----------------------------------------------------------------------*/
@@ -165,7 +178,6 @@ static inline void console_newline(void)
 	if (console_row >= CONSOLE_ROWS) {
 		/* Scroll everything up */
 		console_scrollup();
-		--console_row;
 	} else {
 		lcd_sync();
 	}
#33 lore raw

PATCH v4 15/16 lcd: Add CONSOLE_SCROLL_LINES option to speed console

Hi Lucas,

Quoted 63 lines · Lucas Stach

Am Donnerstag, den 27.09.2012, 17:44 -0700 schrieb Simon Glass:

Quoted 54 lines

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.

---
Changes in v3:
- Fix tiny bug in mult-line lcd scrolling

Changes in v4:
- Use CONFIG_CONSOLE_SCROLL_LINES instead of CONSOLE_SCROLL_LINES
- Put default CONFIG_CONSOLE_SCROLL_LINES at top of file

 README       |    6 ++++++
 common/lcd.c |   18 +++++++++++++++---
 2 files changed, 21 insertions(+), 3 deletions(-)
README +6 -0
index 1d0ce50..14b1f83 100644
@@ -1449,6 +1449,12 @@ The following options need to be configured:
              here, since it is cheaper to change data cache settings on
              a per-section basis.
 
+             CONFIG_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
 
common/lcd.c +5 -0
index 74fa3f9..460f0ca 100644
@@ -76,6 +76,11 @@
 #define CONFIG_LCD_ALIGNMENT PAGE_SIZE
 #endif
 
+/* By default we scroll by a single line */
+#ifndef CONFIG_CONSOLE_SCROLL_LINES
+#define CONFIG_CONSOLE_SCROLL_LINES 1
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 ulong lcd_setmem (ulong addr);

common/lcd.c void lcd_set_flush_dcache(int flush) · line 141

Quoted 6 lines
common/lcd.c +2 -0
@@ -131,12 +136,20 @@ void lcd_set_flush_dcache(int flush)
 
 static void console_scrollup(void)
 {
+     const int rows = CONFIG_CONSOLE_SCROLL_LINES;
+
      /* Copy up rows ignoring the first one */

Comment is inaccurate as you possibly ignore more than the first line.

Quoted 7 lines

common/lcd.c void lcd_set_flush_dcache(int flush) · line 146

Quoted 6 lines
common/lcd.c +3 -1
-     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 */

Same as above.

OK thanks, I will tidy these up.

Quoted 10 lines
Quoted 10 lines
common/lcd.c +5 -1
-     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;
 }
 
Quoted 11 lines

common/lcd.c static inline void console_newline(void) · line 183

Quoted 9 lines
common/lcd.c +0 -1
 /*----------------------------------------------------------------------*/
@@ -165,7 +178,6 @@ static inline void console_newline(void)
      if (console_row >= CONSOLE_ROWS) {
              /* Scroll everything up */
              console_scrollup();
-             --console_row;
      } else {
              lcd_sync();
      }

Regards,
Simon

#34 lore raw

PATCH v4 16/16 tegra: Enable display/lcd support on Seaboard

In reply to Simon Glass

From: Mayuresh Kulkarni <[email protected]>

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

---
Changes in v4:
- Add CONFIG_BOARD_LATE_INIT to enable LCD
- Use CONFIG_CONSOLE_SCROLL_LINES instead of CONSOLE_SCROLL_LINES
- Enable separate CONFIG_PWM_TEGRA option

 include/configs/seaboard.h |   13 +++++++++++--
 1 files changed, 11 insertions(+), 2 deletions(-)
include/configs/seaboard.h +11 -2
index de19e38..19c5bf3 100644
@@ -55,6 +55,7 @@
 #define CONFIG_MACH_TYPE		MACH_TYPE_SEABOARD
 
 #define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_BOARD_LATE_INIT		/* Make sure LCD init is complete */
 
 /* I2C */
 #define CONFIG_TEGRA_I2C
@@ -101,8 +102,16 @@
 
 #undef TEGRA_DEVICE_SETTINGS
 #define TEGRA_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_PWM_TEGRA
+#define CONFIG_VIDEO_TEGRA
+#define LCD_BPP				LCD_COLOR16
+#define CONFIG_SYS_WHITE_ON_BLACK
+#define CONFIG_CONSOLE_SCROLL_LINES	10
 
 #include "tegra-common-post.h"
 
Signature · 1 line
1.7.7.3
#35 lore raw

v4 cover tegra: Add display driver and LCD support for Seaboard

In reply to Simon Glass
Quoted 3 lines · Simon Glass

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.

I tested this on Seaboard, and found a couple of minor issues:

1) Nothing sets up the environment to enable LCD output; I had to execute:

setenv stdout serial,lcd

... in order to see anything on the display. I'd expect patch 16/16 to cause this to happen automatically?

It's probably best to fix this by revising patch 16 rather than later, since I presume this is trivial to fix?

2) The display works fine for cold boot, or hitting the physical reset button, but when I execute "reset" at the U-Boot prompt, or "reboot" within Linux, the display is messed up; it looks like the LCD isn't able to sync to the timings sent by the display controller or something similar.

Since this is slightly a corner case, it may be OK to fix it later (but not much later; reboot is very useful to me.)

I'll provide review comments on the patches themselves later.

#36 lore raw

v4 cover tegra: Add display driver and LCD support for Seaboard

Quoted 9 lines · Stephen Warren
Quoted 3 lines · Simon Glass

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.

I tested this on Seaboard, and found a couple of minor issues:

1) Nothing sets up the environment to enable LCD output; I had to execute:

Quoted 7 lines

setenv stdout serial,lcd

... in order to see anything on the display. I'd expect patch 16/16 to cause this to happen automatically?

It's probably best to fix this by revising patch 16 rather than later, since I presume this is trivial to fix?

This is a false alarm. I had a valid environment in flash before which didn't set stdout to LCD obviously. As soon as I run "env default -a", everything works as expected.

#37 lore raw

v4 cover tegra: Add display driver and LCD support for Seaboard

In reply to Stephen Warren

Hi Stephen,

Quoted 9 lines · Stephen Warren
Quoted 3 lines · Simon Glass

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.

I tested this on Seaboard, and found a couple of minor issues:

1) Nothing sets up the environment to enable LCD output; I had to execute:

Quoted 7 lines

setenv stdout serial,lcd

... in order to see anything on the display. I'd expect patch 16/16 to cause this to happen automatically?

It's probably best to fix this by revising patch 16 rather than later, since I presume this is trivial to fix?

OK, skipping this as per your next message.

Quoted 8 lines

2) The display works fine for cold boot, or hitting the physical reset button, but when I execute "reset" at the U-Boot prompt, or "reboot" within Linux, the display is messed up; it looks like the LCD isn't able to sync to the timings sent by the display controller or something similar.

Since this is slightly a corner case, it may be OK to fix it later (but not much later; reboot is very useful to me.)

Yes I also noticed this, and I think we discussed it with the previous version also. Sorry I didn't add this to the commit message. It seems odd that a s/w reset would put it into a different state that a physical reset. I am not too sure how to approach this problem - I wonder if it might be one for Nvidia to look at?

Quoted 3 lines

I'll provide review comments on the patches themselves later.

Regards,
Simon

#38 lore raw

v4 cover tegra: Add display driver and LCD support for Seaboard

In reply to Stephen Warren
Quoted 4 lines · Stephen Warren
Quoted 3 lines · Simon Glass

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.

...

Quoted 7 lines

2) The display works fine for cold boot, or hitting the physical reset button, but when I execute "reset" at the U-Boot prompt, or "reboot" within Linux, the display is messed up; it looks like the LCD isn't able to sync to the timings sent by the display controller or something similar.

Since this is slightly a corner case, it may be OK to fix it later (but not much later; reboot is very useful to me.)

A couple more points:

BTW, I tried the same tests on Springbank which is basically Seaboard with a slightly different PCB layout, and didn't see this issue. That leads me to suspect some timing issue interacting with the panel, which I believe is different albeit theoretically compatible resolution/scan-timing wise.

Second, I first applied Tom's Tegra30 patches and tested those, then applied your LCD series. The LCD series as-is breaks compilation of the Tegra30 support. I have no idea which order Tom might apply these in, but this is a heads-up there will be conflicts and one needs to be rebased on top of the other.

#39 lore raw

v4 cover tegra: Add display driver and LCD support for Seaboard

Hi Stephen,

Quoted 14 lines · Stephen Warren
Quoted 4 lines · Stephen Warren
Quoted 3 lines · Simon Glass

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.

...

Quoted 7 lines

2) The display works fine for cold boot, or hitting the physical reset button, but when I execute "reset" at the U-Boot prompt, or "reboot" within Linux, the display is messed up; it looks like the LCD isn't able to sync to the timings sent by the display controller or something similar.

Since this is slightly a corner case, it may be OK to fix it later (but not much later; reboot is very useful to me.)

Quoted 7 lines

A couple more points:

BTW, I tried the same tests on Springbank which is basically Seaboard with a slightly different PCB layout, and didn't see this issue. That leads me to suspect some timing issue interacting with the panel, which I believe is different albeit theoretically compatible resolution/scan-timing wise.

OK. I wonder the panel does not get reset properly on Seaboard?

Quoted 6 lines

Second, I first applied Tom's Tegra30 patches and tested those, then applied your LCD series. The LCD series as-is breaks compilation of the Tegra30 support. I have no idea which order Tom might apply these in, but this is a heads-up there will be conflicts and one needs to be rebased on top of the other.

OK, let's see what Tom wants to do on that one.

Regards,
Simon

#40 lore raw

v4 cover tegra: Add display driver and LCD support for Seaboard

Simon/Stephen,

Quoted 39 lines

-----Original Message-----
From: sjg at google.com [mailto:sjg at google.com] On Behalf Of Simon Glass
Sent: Monday, October 08, 2012 1:06 PM
To: Stephen Warren
Cc: U-Boot Mailing List; Tom Warren
Subject: Re: [PATCH v4 0/16] tegra: Add display driver and LCD support for Seaboard

Hi Stephen,

Quoted 8 lines · Stephen Warren
Quoted 4 lines · Stephen Warren
Quoted 3 lines · Simon Glass

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.

...

Quoted 2 lines

2) The display works fine for cold boot, or hitting the physical reset button, but when I execute "reset" at the U-Boot prompt, or

"reboot"

Quoted 2 lines
Quoted 2 lines

within Linux, the display is messed up; it looks like the LCD isn't able to sync to the timings sent by the display controller or something

similar.

Quoted 11 lines
Quoted 3 lines

Since this is slightly a corner case, it may be OK to fix it later (but not much later; reboot is very useful to me.)

A couple more points:

BTW, I tried the same tests on Springbank which is basically Seaboard with a slightly different PCB layout, and didn't see this issue. That leads me to suspect some timing issue interacting with the panel, which I believe is different albeit theoretically compatible resolution/scan-timing wise.

OK. I wonder the panel does not get reset properly on Seaboard?

Quoted 1 line
Quoted 8 lines
Quoted 6 lines

Second, I first applied Tom's Tegra30 patches and tested those, then applied your LCD series. The LCD series as-is breaks compilation of the
Tegra30 support. I have no idea which order Tom might apply these in, but this is a heads-up there will be conflicts and one needs to be rebased on top of the other.

OK, let's see what Tom wants to do on that one.

I'll have to wait to address this until I get back from HQ (next week, most likely).

Thanks,

Tom

Quoted 3 lines

Regards,
Simon

Signature · 1 line
nvpublic
#41 lore raw

v4 cover tegra: Add display driver and LCD support for Seaboard

In reply to Simon Glass
Quoted 19 lines · Simon Glass

Hi Stephen,

Quoted 16 lines · Stephen Warren
Quoted 4 lines · Stephen Warren
Quoted 3 lines · Simon Glass

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.

...

Quoted 7 lines

2) The display works fine for cold boot, or hitting the physical reset button, but when I execute "reset" at the U-Boot prompt, or "reboot" within Linux, the display is messed up; it looks like the LCD isn't able to sync to the timings sent by the display controller or something similar.

Since this is slightly a corner case, it may be OK to fix it later (but not much later; reboot is very useful to me.)

A couple more points:

Quoted 7 lines
Quoted 5 lines

BTW, I tried the same tests on Springbank which is basically Seaboard with a slightly different PCB layout, and didn't see this issue. That leads me to suspect some timing issue interacting with the panel, which I believe is different albeit theoretically compatible resolution/scan-timing wise.

OK. I wonder the panel does not get reset properly on Seaboard?

I looked at the panel spec for the panels on the two boards. Both of them specify that when vdd_pnl is dropped to zero, you must wait at least 400mS before raising it again. Evidently the Seaboard panel actually cares about this, yet the Springbank panel seems to be more flexible than the specification. So, modifying drivers/video/tegra.c:handle_stage() case STAGE_START to:

    if (fdt_gpio_isvalid(&config.panel_vdd)) {
        udelay(400000);
        gpio_direction_output(config.panel_vdd.gpio, 1);
    }

... appears to solve the problem; I can run "reset" in U-Boot many many times without any issue after that change.

I guess this means that the nvidia,panel-timings DT property needs a pre-delay entry for STAGE_START, or something like that?

Also, I wondered if we shouldn't explicitly do:

    gpio_direction_output(config.panel_vdd.gpio, 0);
    udelay(400000);
    gpio_direction_output(config.panel_vdd.gpio, 1);

... although that doesn't make a difference; the particular GPIO used on Seaboard appears to default to 0. I'm not sure that all GPIOs are guaranteed to though.

Slightly related, I notice that handle_stage() always executes:

timer_next = timer_get_us() + config.panel_timings[stage] * 1000;

However, that function is called for stage==0..4 (or perhaps 0..5 given the set of case statements it supports, but not looking at the code at the call site), yet there are only entries 0..3 in that array; there's an overrun there.

#42 lore raw

v4 cover tegra: Add display driver and LCD support for Seaboard

Hi Stephen,

Quoted 48 lines · Stephen Warren
Quoted 19 lines · Simon Glass

Hi Stephen,

Quoted 16 lines · Stephen Warren
Quoted 4 lines · Stephen Warren
Quoted 3 lines · Simon Glass

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.

...

Quoted 7 lines

2) The display works fine for cold boot, or hitting the physical reset button, but when I execute "reset" at the U-Boot prompt, or "reboot" within Linux, the display is messed up; it looks like the LCD isn't able to sync to the timings sent by the display controller or something similar.

Since this is slightly a corner case, it may be OK to fix it later (but not much later; reboot is very useful to me.)

A couple more points:

Quoted 7 lines
Quoted 5 lines

BTW, I tried the same tests on Springbank which is basically Seaboard with a slightly different PCB layout, and didn't see this issue. That leads me to suspect some timing issue interacting with the panel, which I believe is different albeit theoretically compatible resolution/scan-timing wise.

OK. I wonder the panel does not get reset properly on Seaboard?

I looked at the panel spec for the panels on the two boards. Both of them specify that when vdd_pnl is dropped to zero, you must wait at least 400mS before raising it again. Evidently the Seaboard panel actually cares about this, yet the Springbank panel seems to be more flexible than the specification. So, modifying drivers/video/tegra.c:handle_stage() case STAGE_START to:

    if (fdt_gpio_isvalid(&config.panel_vdd)) {
        udelay(400000);
        gpio_direction_output(config.panel_vdd.gpio, 1);
    }

... appears to solve the problem; I can run "reset" in U-Boot many many times without any issue after that change.

I guess this means that the nvidia,panel-timings DT property needs a pre-delay entry for STAGE_START, or something like that?

Also, I wondered if we shouldn't explicitly do:

Quoted 7 lines
    gpio_direction_output(config.panel_vdd.gpio, 0);
    udelay(400000);
    gpio_direction_output(config.panel_vdd.gpio, 1);

... although that doesn't make a difference; the particular GPIO used on Seaboard appears to default to 0. I'm not sure that all GPIOs are guaranteed to though.

So reset is causing the line to go low? OK, there's probably nothing we can do here except wait for 400ms. Is there any way to detect this condition? Adding 400ms is quite a big jump in boot time.

Quoted 9 lines

Slightly related, I notice that handle_stage() always executes:

timer_next = timer_get_us() + config.panel_timings[stage] * 1000;

However, that function is called for stage==0..4 (or perhaps 0..5 given the set of case statements it supports, but not looking at the code at the call site), yet there are only entries 0..3 in that array; there's an overrun there.

I will add a check there,

Regards,
Simon

#43 lore raw

v4 cover tegra: Add display driver and LCD support for Seaboard

Quoted 55 lines · Simon Glass

Hi Stephen,

Quoted 52 lines · Stephen Warren
Quoted 19 lines · Simon Glass

Hi Stephen,

Quoted 16 lines · Stephen Warren
Quoted 4 lines · Stephen Warren
Quoted 3 lines · Simon Glass

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.

...

Quoted 7 lines

2) The display works fine for cold boot, or hitting the physical reset button, but when I execute "reset" at the U-Boot prompt, or "reboot" within Linux, the display is messed up; it looks like the LCD isn't able to sync to the timings sent by the display controller or something similar.

Since this is slightly a corner case, it may be OK to fix it later (but not much later; reboot is very useful to me.)

A couple more points:

Quoted 7 lines
Quoted 5 lines

BTW, I tried the same tests on Springbank which is basically Seaboard with a slightly different PCB layout, and didn't see this issue. That leads me to suspect some timing issue interacting with the panel, which I believe is different albeit theoretically compatible resolution/scan-timing wise.

OK. I wonder the panel does not get reset properly on Seaboard?

I looked at the panel spec for the panels on the two boards. Both of them specify that when vdd_pnl is dropped to zero, you must wait at least 400mS before raising it again. Evidently the Seaboard panel actually cares about this, yet the Springbank panel seems to be more flexible than the specification. So, modifying drivers/video/tegra.c:handle_stage() case STAGE_START to:

    if (fdt_gpio_isvalid(&config.panel_vdd)) {
        udelay(400000);
        gpio_direction_output(config.panel_vdd.gpio, 1);
    }

... appears to solve the problem; I can run "reset" in U-Boot many many times without any issue after that change.

I guess this means that the nvidia,panel-timings DT property needs a pre-delay entry for STAGE_START, or something like that?

Also, I wondered if we shouldn't explicitly do:

    gpio_direction_output(config.panel_vdd.gpio, 0);
    udelay(400000);
    gpio_direction_output(config.panel_vdd.gpio, 1);
Quoted 5 lines
Quoted 3 lines

... although that doesn't make a difference; the particular GPIO used on Seaboard appears to default to 0. I'm not sure that all GPIOs are guaranteed to though.

So reset is causing the line to go low?

I would imagine so.

Quoted 3 lines

OK, there's probably nothing
we can do here except wait for 400ms. Is there any way to detect this condition? Adding 400ms is quite a big jump in boot time.

I think the PMIC has a "power-on/reset reason" register. However, I don't know exactly how long the minimum time between powering off and immediately powering on is; it's plausible it isn't safe to skip some waiting even in that case.

#44 lore raw

v4 cover tegra: Add display driver and LCD support for Seaboard

In reply to Simon Glass
Quoted 3 lines · Simon Glass

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.

Aside from the comments I made just now, the whole series,

At this stage, I figure it's more important to get this feature checked in and enabled than anything else. For this version of the series, I only briefly scanned the patches, and mostly concentrated on the device tree files themselves. They're obviously close enough to the proposed kernel bindings that we should be able to migrate them easily enough to the finalized bindings when they're available.

#45 lore raw

v4 cover tegra: Add display driver and LCD support for Seaboard

Hi Stephen,

Quoted 7 lines · Stephen Warren
Quoted 3 lines · Simon Glass

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.

Aside from the comments I made just now, the whole series,

Quoted 8 lines

At this stage, I figure it's more important to get this feature checked in and enabled than anything else. For this version of the series, I only briefly scanned the patches, and mostly concentrated on the device tree files themselves. They're obviously close enough to the proposed kernel bindings that we should be able to migrate them easily enough to the finalized bindings when they're available.

Yes I think so. Thanks.

I will address the comments and send out a new series likely Monday.

Regards,
Simon