tegra: Add SOC support for display/lcd

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

Signed-off-by: Mayuresh Kulkarni <mkulkarni@nvidia.com>
Mayuresh Kulkarni:
- changes to remove bitfields and clean up for submission

Signed-off-by: Simon Glass <sjg@chromium.org>
Simon Glass:
- simplify code, move clock control into here, clean-up
Signed-off-by: Tom Warren <twarren@nvidia.com>
diff --git a/arch/arm/include/asm/arch-tegra20/display.h b/arch/arm/include/asm/arch-tegra20/display.h
new file mode 100644
index 0000000..c870959
--- /dev/null
+++ b/arch/arm/include/asm/arch-tegra20/display.h
@@ -0,0 +1,152 @@
+/*
+ *  (C) Copyright 2010
+ *  NVIDIA Corporation <www.nvidia.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __ASM_ARCH_TEGRA_DISPLAY_H
+#define __ASM_ARCH_TEGRA_DISPLAY_H
+
+#include <asm/arch/dc.h>
+#include <fdtdec.h>
+
+/* This holds information about a window which can be displayed */
+struct disp_ctl_win {
+	enum win_color_depth_id fmt;	/* Color depth/format */
+	unsigned	bpp;		/* Bits per pixel */
+	phys_addr_t	phys_addr;	/* Physical address in memory */
+	unsigned	x;		/* Horizontal address offset (bytes) */
+	unsigned	y;		/* Veritical address offset (bytes) */
+	unsigned	w;		/* Width of source window */
+	unsigned	h;		/* Height of source window */
+	unsigned	stride;		/* Number of bytes per line */
+	unsigned	out_x;		/* Left edge of output window (col) */
+	unsigned	out_y;		/* Top edge of output window (row) */
+	unsigned	out_w;		/* Width of output window in pixels */
+	unsigned	out_h;		/* Height of output window in pixels */
+};
+
+#define FDT_LCD_TIMINGS	4
+
+enum {
+	FDT_LCD_TIMING_REF_TO_SYNC,
+	FDT_LCD_TIMING_SYNC_WIDTH,
+	FDT_LCD_TIMING_BACK_PORCH,
+	FDT_LCD_TIMING_FRONT_PORCH,
+
+	FDT_LCD_TIMING_COUNT,
+};
+
+enum lcd_cache_t {
+	FDT_LCD_CACHE_OFF		= 0,
+	FDT_LCD_CACHE_WRITE_THROUGH	= 1 << 0,
+	FDT_LCD_CACHE_WRITE_BACK	= 1 << 1,
+	FDT_LCD_CACHE_FLUSH		= 1 << 2,
+	FDT_LCD_CACHE_WRITE_BACK_FLUSH	= FDT_LCD_CACHE_WRITE_BACK |
+						FDT_LCD_CACHE_FLUSH,
+};
+
+/* Information about the display controller */
+struct fdt_disp_config {
+	int valid;			/* config is valid */
+	int width;			/* width in pixels */
+	int height;			/* height in pixels */
+	int bpp;			/* number of bits per pixel */
+
+	/*
+	 * log2 of number of bpp, in general, unless it bpp is 24 in which
+	 * case this field holds 24 also! This is a U-Boot thing.
+	 */
+	int log2_bpp;
+	struct disp_ctlr *disp;		/* Display controller to use */
+	fdt_addr_t frame_buffer;	/* Address of frame buffer */
+	unsigned pixel_clock;		/* Pixel clock in Hz */
+	uint horiz_timing[FDT_LCD_TIMING_COUNT];	/* Horizontal timing */
+	uint vert_timing[FDT_LCD_TIMING_COUNT];		/* Vertical timing */
+	int panel_node;			/* node offset of panel information */
+};
+
+/* Information about the LCD panel */
+struct fdt_panel_config {
+	int pwm_channel;		/* PWM channel to use for backlight */
+	enum lcd_cache_t cache_type;
+
+	struct fdt_gpio_state backlight_en;	/* GPIO for backlight enable */
+	struct fdt_gpio_state lvds_shutdown;	/* GPIO for lvds shutdown */
+	struct fdt_gpio_state backlight_vdd;	/* GPIO for backlight vdd */
+	struct fdt_gpio_state panel_vdd;	/* GPIO for panel vdd */
+	/*
+	 * Panel required timings
+	 * Timing 1: delay between panel_vdd-rise and data-rise
+	 * Timing 2: delay between data-rise and backlight_vdd-rise
+	 * Timing 3: delay between backlight_vdd and pwm-rise
+	 * Timing 4: delay between pwm-rise and backlight_en-rise
+	 */
+	uint panel_timings[FDT_LCD_TIMINGS];
+};
+
+/**
+ * Register a new display based on device tree configuration.
+ *
+ * The frame buffer can be positioned by U-Boot or overriden by the fdt.
+ * You should pass in the U-Boot address here, and check the contents of
+ * struct fdt_disp_config to see what was actually chosen.
+ *
+ * @param blob			Device tree blob
+ * @param default_lcd_base	Default address of LCD frame buffer
+ * @return 0 if ok, -1 on error (unsupported bits per pixel)
+ */
+int tegra_display_probe(const void *blob, void *default_lcd_base);
+
+/**
+ * Return the current display configuration
+ *
+ * @return pointer to display configuration, or NULL if there is no valid
+ * config
+ */
+struct fdt_disp_config *tegra_display_get_config(void);
+
+/**
+ * Perform the next stage of the LCD init if it is time to do so.
+ *
+ * LCD init can be time-consuming because of the number of delays we need
+ * while waiting for the backlight power supply, etc. This function can
+ * be called at various times during U-Boot operation to advance the
+ * initialization of the LCD to the next stage if sufficient time has
+ * passed since the last stage. It keeps track of what stage it is up to
+ * and the time that it is permitted to move to the next stage.
+ *
+ * The final call should have wait=1 to complete the init.
+ *
+ * @param blob	fdt blob containing LCD information
+ * @param wait	1 to wait until all init is complete, and then return
+ *		0 to return immediately, potentially doing nothing if it is
+ *		not yet time for the next init.
+ */
+int tegra_lcd_check_next_stage(const void *blob, int wait);
+
+/**
+ * Set up the maximum LCD size so we can size the frame buffer.
+ *
+ * @param blob	fdt blob containing LCD information
+ */
+void tegra_lcd_early_init(const void *blob);
+
+#endif /*__ASM_ARCH_TEGRA_DISPLAY_H*/