xref: /rk3399_rockchip-uboot/arch/arm/include/asm/arch-tegra20/display.h (revision 2eb70de6b1a340fbad28ac36d34adb8e6c809c5c)
187540de3SWei Ni /*
287540de3SWei Ni  *  (C) Copyright 2010
387540de3SWei Ni  *  NVIDIA Corporation <www.nvidia.com>
487540de3SWei Ni  *
51a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
687540de3SWei Ni  */
787540de3SWei Ni 
887540de3SWei Ni #ifndef __ASM_ARCH_TEGRA_DISPLAY_H
987540de3SWei Ni #define __ASM_ARCH_TEGRA_DISPLAY_H
1087540de3SWei Ni 
11*2eb70de6SSimon Glass #include <asm/arch-tegra/dc.h>
1287540de3SWei Ni #include <fdtdec.h>
1304072cbaSSimon Glass #include <asm/gpio.h>
1487540de3SWei Ni 
1587540de3SWei Ni /* This holds information about a window which can be displayed */
1687540de3SWei Ni struct disp_ctl_win {
1787540de3SWei Ni 	enum win_color_depth_id fmt;	/* Color depth/format */
1887540de3SWei Ni 	unsigned	bpp;		/* Bits per pixel */
1987540de3SWei Ni 	phys_addr_t	phys_addr;	/* Physical address in memory */
2087540de3SWei Ni 	unsigned	x;		/* Horizontal address offset (bytes) */
2187540de3SWei Ni 	unsigned	y;		/* Veritical address offset (bytes) */
2287540de3SWei Ni 	unsigned	w;		/* Width of source window */
2387540de3SWei Ni 	unsigned	h;		/* Height of source window */
2487540de3SWei Ni 	unsigned	stride;		/* Number of bytes per line */
2587540de3SWei Ni 	unsigned	out_x;		/* Left edge of output window (col) */
2687540de3SWei Ni 	unsigned	out_y;		/* Top edge of output window (row) */
2787540de3SWei Ni 	unsigned	out_w;		/* Width of output window in pixels */
2887540de3SWei Ni 	unsigned	out_h;		/* Height of output window in pixels */
2987540de3SWei Ni };
3087540de3SWei Ni 
3187540de3SWei Ni #define FDT_LCD_TIMINGS	4
3287540de3SWei Ni 
3387540de3SWei Ni enum {
3487540de3SWei Ni 	FDT_LCD_TIMING_REF_TO_SYNC,
3587540de3SWei Ni 	FDT_LCD_TIMING_SYNC_WIDTH,
3687540de3SWei Ni 	FDT_LCD_TIMING_BACK_PORCH,
3787540de3SWei Ni 	FDT_LCD_TIMING_FRONT_PORCH,
3887540de3SWei Ni 
3987540de3SWei Ni 	FDT_LCD_TIMING_COUNT,
4087540de3SWei Ni };
4187540de3SWei Ni 
4287540de3SWei Ni enum lcd_cache_t {
4387540de3SWei Ni 	FDT_LCD_CACHE_OFF		= 0,
4487540de3SWei Ni 	FDT_LCD_CACHE_WRITE_THROUGH	= 1 << 0,
4587540de3SWei Ni 	FDT_LCD_CACHE_WRITE_BACK	= 1 << 1,
4687540de3SWei Ni 	FDT_LCD_CACHE_FLUSH		= 1 << 2,
4787540de3SWei Ni 	FDT_LCD_CACHE_WRITE_BACK_FLUSH	= FDT_LCD_CACHE_WRITE_BACK |
4887540de3SWei Ni 						FDT_LCD_CACHE_FLUSH,
4987540de3SWei Ni };
5087540de3SWei Ni 
5187540de3SWei Ni /* Information about the display controller */
5287540de3SWei Ni struct fdt_disp_config {
5387540de3SWei Ni 	int valid;			/* config is valid */
5487540de3SWei Ni 	int width;			/* width in pixels */
5587540de3SWei Ni 	int height;			/* height in pixels */
5687540de3SWei Ni 	int bpp;			/* number of bits per pixel */
5787540de3SWei Ni 
5887540de3SWei Ni 	/*
5987540de3SWei Ni 	 * log2 of number of bpp, in general, unless it bpp is 24 in which
6087540de3SWei Ni 	 * case this field holds 24 also! This is a U-Boot thing.
6187540de3SWei Ni 	 */
6287540de3SWei Ni 	int log2_bpp;
6387540de3SWei Ni 	struct disp_ctlr *disp;		/* Display controller to use */
6487540de3SWei Ni 	fdt_addr_t frame_buffer;	/* Address of frame buffer */
6587540de3SWei Ni 	unsigned pixel_clock;		/* Pixel clock in Hz */
6687540de3SWei Ni 	uint horiz_timing[FDT_LCD_TIMING_COUNT];	/* Horizontal timing */
6787540de3SWei Ni 	uint vert_timing[FDT_LCD_TIMING_COUNT];		/* Vertical timing */
6887540de3SWei Ni 	int panel_node;			/* node offset of panel information */
6987540de3SWei Ni };
7087540de3SWei Ni 
7187540de3SWei Ni /* Information about the LCD panel */
7287540de3SWei Ni struct fdt_panel_config {
7387540de3SWei Ni 	int pwm_channel;		/* PWM channel to use for backlight */
7487540de3SWei Ni 	enum lcd_cache_t cache_type;
7587540de3SWei Ni 
7604072cbaSSimon Glass 	struct gpio_desc backlight_en;	/* GPIO for backlight enable */
7704072cbaSSimon Glass 	struct gpio_desc lvds_shutdown;	/* GPIO for lvds shutdown */
7804072cbaSSimon Glass 	struct gpio_desc backlight_vdd;	/* GPIO for backlight vdd */
7904072cbaSSimon Glass 	struct gpio_desc panel_vdd;	/* GPIO for panel vdd */
8087540de3SWei Ni 	/*
8187540de3SWei Ni 	 * Panel required timings
8287540de3SWei Ni 	 * Timing 1: delay between panel_vdd-rise and data-rise
8387540de3SWei Ni 	 * Timing 2: delay between data-rise and backlight_vdd-rise
8487540de3SWei Ni 	 * Timing 3: delay between backlight_vdd and pwm-rise
8587540de3SWei Ni 	 * Timing 4: delay between pwm-rise and backlight_en-rise
8687540de3SWei Ni 	 */
8787540de3SWei Ni 	uint panel_timings[FDT_LCD_TIMINGS];
8887540de3SWei Ni };
8987540de3SWei Ni 
9087540de3SWei Ni /**
9187540de3SWei Ni  * Register a new display based on device tree configuration.
9287540de3SWei Ni  *
9387540de3SWei Ni  * The frame buffer can be positioned by U-Boot or overriden by the fdt.
9487540de3SWei Ni  * You should pass in the U-Boot address here, and check the contents of
9587540de3SWei Ni  * struct fdt_disp_config to see what was actually chosen.
9687540de3SWei Ni  *
9787540de3SWei Ni  * @param blob			Device tree blob
9887540de3SWei Ni  * @param default_lcd_base	Default address of LCD frame buffer
9987540de3SWei Ni  * @return 0 if ok, -1 on error (unsupported bits per pixel)
10087540de3SWei Ni  */
10187540de3SWei Ni int tegra_display_probe(const void *blob, void *default_lcd_base);
10287540de3SWei Ni 
10387540de3SWei Ni /**
10487540de3SWei Ni  * Return the current display configuration
10587540de3SWei Ni  *
10687540de3SWei Ni  * @return pointer to display configuration, or NULL if there is no valid
10787540de3SWei Ni  * config
10887540de3SWei Ni  */
10987540de3SWei Ni struct fdt_disp_config *tegra_display_get_config(void);
11087540de3SWei Ni 
11187540de3SWei Ni /**
11287540de3SWei Ni  * Perform the next stage of the LCD init if it is time to do so.
11387540de3SWei Ni  *
11487540de3SWei Ni  * LCD init can be time-consuming because of the number of delays we need
11587540de3SWei Ni  * while waiting for the backlight power supply, etc. This function can
11687540de3SWei Ni  * be called at various times during U-Boot operation to advance the
11787540de3SWei Ni  * initialization of the LCD to the next stage if sufficient time has
11887540de3SWei Ni  * passed since the last stage. It keeps track of what stage it is up to
11987540de3SWei Ni  * and the time that it is permitted to move to the next stage.
12087540de3SWei Ni  *
12187540de3SWei Ni  * The final call should have wait=1 to complete the init.
12287540de3SWei Ni  *
12387540de3SWei Ni  * @param blob	fdt blob containing LCD information
12487540de3SWei Ni  * @param wait	1 to wait until all init is complete, and then return
12587540de3SWei Ni  *		0 to return immediately, potentially doing nothing if it is
12687540de3SWei Ni  *		not yet time for the next init.
12787540de3SWei Ni  */
12887540de3SWei Ni int tegra_lcd_check_next_stage(const void *blob, int wait);
12987540de3SWei Ni 
13087540de3SWei Ni /**
13187540de3SWei Ni  * Set up the maximum LCD size so we can size the frame buffer.
13287540de3SWei Ni  *
13387540de3SWei Ni  * @param blob	fdt blob containing LCD information
13487540de3SWei Ni  */
13587540de3SWei Ni void tegra_lcd_early_init(const void *blob);
13687540de3SWei Ni 
13787540de3SWei Ni #endif /*__ASM_ARCH_TEGRA_DISPLAY_H*/
138