summaryrefslogtreecommitdiff
path: root/arch/arm/include/asm/arch-tegra20/display.h
blob: 6feeda3ba83ec42674f589f4dbd4fb1e3948774d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*
 *  (C) Copyright 2010
 *  NVIDIA Corporation <www.nvidia.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#ifndef __ASM_ARCH_TEGRA_DISPLAY_H
#define __ASM_ARCH_TEGRA_DISPLAY_H

#include <asm/arch/dc.h>
#include <fdtdec.h>
#include <asm/gpio.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 gpio_desc backlight_en;	/* GPIO for backlight enable */
	struct gpio_desc lvds_shutdown;	/* GPIO for lvds shutdown */
	struct gpio_desc backlight_vdd;	/* GPIO for backlight vdd */
	struct gpio_desc 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*/