summaryrefslogtreecommitdiff
path: root/board/st/u8500/mcde.h
blob: c13a2c935886a8024ab12fe9f4ad595fa6c9c602 (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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
/*
* Copyright (C) ST-Ericsson SA 2010
*
* Author: Marcus Lorentzon <marcus.xm.lorentzon@stericsson.com>
* for ST-Ericsson.
*
* License terms: GNU General Public License (GPL), version 2.
*/
#ifndef __MCDE__H__
#define __MCDE__H__

#define mdelay(n) ({unsigned long msec = (n); while (msec--) udelay(1000); })

/* Physical interface types */
enum mcde_port_type {
	MCDE_PORTTYPE_DSI = 0,
	MCDE_PORTTYPE_DPI = 1,
};

/* Interface mode */
enum mcde_port_mode {
	MCDE_PORTMODE_CMD = 0,
	MCDE_PORTMODE_VID = 1,
};

/* MCDE fifos */
enum mcde_fifo {
	MCDE_FIFO_A  = 0,
	MCDE_FIFO_B  = 1,
	MCDE_FIFO_C0 = 2,
	MCDE_FIFO_C1 = 3,
};

/* MCDE channels (pixel pipelines) */
enum mcde_chnl {
	MCDE_CHNL_A  = 0,
	MCDE_CHNL_B  = 1,
	MCDE_CHNL_C0 = 2,
	MCDE_CHNL_C1 = 3,
};

/* Display power modes */
enum mcde_display_power_mode {
	MCDE_DISPLAY_PM_OFF     = 0, /* Power off */
	MCDE_DISPLAY_PM_STANDBY = 1, /* DCS sleep mode */
	MCDE_DISPLAY_PM_ON      = 2, /* DCS normal mode, display on */
};

/* Update sync mode */
#define MCDE_CHNLPATH(__chnl, __fifo, __type, __ifc, __link) \
	(((__chnl) << 16) | ((__fifo) << 12) | \
	 ((__type) << 8) | ((__ifc) << 4) | ((__link) << 0))
enum mcde_chnl_path {
	/* Channel A */
	MCDE_CHNLPATH_CHNLA_FIFOA_DPI_0 = MCDE_CHNLPATH(MCDE_CHNL_A,
		MCDE_FIFO_A, MCDE_PORTTYPE_DPI, 0, 0),
	MCDE_CHNLPATH_CHNLA_FIFOA_DSI_IFC0_0 = MCDE_CHNLPATH(MCDE_CHNL_A,
		MCDE_FIFO_A, MCDE_PORTTYPE_DSI, 0, 0),
	MCDE_CHNLPATH_CHNLA_FIFOA_DSI_IFC0_1 = MCDE_CHNLPATH(MCDE_CHNL_A,
		MCDE_FIFO_A, MCDE_PORTTYPE_DSI, 0, 1),
	MCDE_CHNLPATH_CHNLA_FIFOC0_DSI_IFC0_2 = MCDE_CHNLPATH(MCDE_CHNL_A,
		MCDE_FIFO_C0, MCDE_PORTTYPE_DSI, 0, 2),
	MCDE_CHNLPATH_CHNLA_FIFOC0_DSI_IFC1_0 = MCDE_CHNLPATH(MCDE_CHNL_A,
		MCDE_FIFO_C0, MCDE_PORTTYPE_DSI, 1, 0),
	MCDE_CHNLPATH_CHNLA_FIFOC0_DSI_IFC1_1 = MCDE_CHNLPATH(MCDE_CHNL_A,
		MCDE_FIFO_C0, MCDE_PORTTYPE_DSI, 1, 1),
	MCDE_CHNLPATH_CHNLA_FIFOA_DSI_IFC1_2 = MCDE_CHNLPATH(MCDE_CHNL_A,
		MCDE_FIFO_A, MCDE_PORTTYPE_DSI, 1, 2),
	/* Channel B */
	MCDE_CHNLPATH_CHNLB_FIFOB_DPI_1 = MCDE_CHNLPATH(MCDE_CHNL_B,
		MCDE_FIFO_B, MCDE_PORTTYPE_DPI, 0, 1),
	MCDE_CHNLPATH_CHNLB_FIFOB_DSI_IFC0_0 = MCDE_CHNLPATH(MCDE_CHNL_B,
		MCDE_FIFO_B, MCDE_PORTTYPE_DSI, 0, 0),
	MCDE_CHNLPATH_CHNLB_FIFOB_DSI_IFC0_1 = MCDE_CHNLPATH(MCDE_CHNL_B,
		MCDE_FIFO_B, MCDE_PORTTYPE_DSI, 0, 1),
	MCDE_CHNLPATH_CHNLB_FIFOC1_DSI_IFC0_2 = MCDE_CHNLPATH(MCDE_CHNL_B,
		MCDE_FIFO_C1, MCDE_PORTTYPE_DSI, 0, 2),
	MCDE_CHNLPATH_CHNLB_FIFOC1_DSI_IFC1_0 = MCDE_CHNLPATH(MCDE_CHNL_B,
		MCDE_FIFO_C1, MCDE_PORTTYPE_DSI, 1, 0),
	MCDE_CHNLPATH_CHNLB_FIFOC1_DSI_IFC1_1 = MCDE_CHNLPATH(MCDE_CHNL_B,
		MCDE_FIFO_C1, MCDE_PORTTYPE_DSI, 1, 1),
	MCDE_CHNLPATH_CHNLB_FIFOB_DSI_IFC1_2 = MCDE_CHNLPATH(MCDE_CHNL_B,
		MCDE_FIFO_B, MCDE_PORTTYPE_DSI, 1, 2),
	/* Channel C0 */
	MCDE_CHNLPATH_CHNLC0_FIFOA_DSI_IFC0_0 = MCDE_CHNLPATH(MCDE_CHNL_C0,
		MCDE_FIFO_A, MCDE_PORTTYPE_DSI, 0, 0),
	MCDE_CHNLPATH_CHNLC0_FIFOA_DSI_IFC0_1 = MCDE_CHNLPATH(MCDE_CHNL_C0,
		MCDE_FIFO_A, MCDE_PORTTYPE_DSI, 0, 1),
	MCDE_CHNLPATH_CHNLC0_FIFOC0_DSI_IFC0_2 = MCDE_CHNLPATH(MCDE_CHNL_C0,
		MCDE_FIFO_C0, MCDE_PORTTYPE_DSI, 0, 2),
	MCDE_CHNLPATH_CHNLC0_FIFOC0_DSI_IFC1_0 = MCDE_CHNLPATH(MCDE_CHNL_C0,
		MCDE_FIFO_C0, MCDE_PORTTYPE_DSI, 1, 0),
	MCDE_CHNLPATH_CHNLC0_FIFOC0_DSI_IFC1_1 = MCDE_CHNLPATH(MCDE_CHNL_C0,
		MCDE_FIFO_C0, MCDE_PORTTYPE_DSI, 1, 1),
	MCDE_CHNLPATH_CHNLC0_FIFOA_DSI_IFC1_2 = MCDE_CHNLPATH(MCDE_CHNL_C0,
		MCDE_FIFO_A, MCDE_PORTTYPE_DSI, 1, 2),
	/* Channel C1 */
	MCDE_CHNLPATH_CHNLC1_FIFOB_DSI_IFC0_0 = MCDE_CHNLPATH(MCDE_CHNL_C1,
		MCDE_FIFO_B, MCDE_PORTTYPE_DSI, 0, 0),
	MCDE_CHNLPATH_CHNLC1_FIFOB_DSI_IFC0_1 = MCDE_CHNLPATH(MCDE_CHNL_C1,
		MCDE_FIFO_B, MCDE_PORTTYPE_DSI, 0, 1),
	MCDE_CHNLPATH_CHNLC1_FIFOC1_DSI_IFC0_2 = MCDE_CHNLPATH(MCDE_CHNL_C1,
		MCDE_FIFO_C1, MCDE_PORTTYPE_DSI, 0, 2),
	MCDE_CHNLPATH_CHNLC1_FIFOC1_DSI_IFC1_0 = MCDE_CHNLPATH(MCDE_CHNL_C1,
		MCDE_FIFO_C1, MCDE_PORTTYPE_DSI, 1, 0),
	MCDE_CHNLPATH_CHNLC1_FIFOC1_DSI_IFC1_1 = MCDE_CHNLPATH(MCDE_CHNL_C1,
		MCDE_FIFO_C1, MCDE_PORTTYPE_DSI, 1, 1),
	MCDE_CHNLPATH_CHNLC1_FIFOB_DSI_IFC1_2 = MCDE_CHNLPATH(MCDE_CHNL_C1,
		MCDE_FIFO_B, MCDE_PORTTYPE_DSI, 1, 2),
};

/* Update sync mode */
enum mcde_sync_src {
	MCDE_SYNCSRC_OFF = 0, /* No sync */
	MCDE_SYNCSRC_TE0 = 1, /* MCDE ext TE0 */
	MCDE_SYNCSRC_TE1 = 2, /* MCDE ext TE1 */
	MCDE_SYNCSRC_BTA = 3, /* DSI BTA */
};

/* Interface pixel formats (output) */
enum mcde_port_pix_fmt {
	/* MIPI standard formats */

	MCDE_PORTPIXFMT_DPI_16BPP_C1 =     0x21,
	MCDE_PORTPIXFMT_DPI_16BPP_C2 =     0x22,
	MCDE_PORTPIXFMT_DPI_16BPP_C3 =     0x23,
	MCDE_PORTPIXFMT_DPI_18BPP_C1 =     0x24,
	MCDE_PORTPIXFMT_DPI_18BPP_C2 =     0x25,
	MCDE_PORTPIXFMT_DPI_24BPP =        0x26,

	MCDE_PORTPIXFMT_DSI_16BPP =        0x31,
	MCDE_PORTPIXFMT_DSI_18BPP =        0x32,
	MCDE_PORTPIXFMT_DSI_18BPP_PACKED = 0x33,
	MCDE_PORTPIXFMT_DSI_24BPP =        0x34,

	/* Custom formats */
	MCDE_PORTPIXFMT_DSI_YCBCR422 =     0x40,
};

#define MCDE_PORT_DPI_NO_CLOCK_DIV	0

#define DPI_ACT_HIGH_ALL	0 /* all signals are active high	  */
#define DPI_ACT_LOW_HSYNC	1 /* horizontal sync signal is active low */
#define DPI_ACT_LOW_VSYNC	2 /* vertical sync signal is active low	  */
#define DPI_ACT_LOW_DATA_ENABLE	4 /* data enable signal is active low	  */
#define DPI_ACT_ON_FALLING_EDGE	8 /* drive data on the falling edge of the
				   * pixel clock
				   */

struct mcde_port {
	enum mcde_port_type type;
	enum mcde_port_mode mode;
	enum mcde_port_pix_fmt pixel_format;
	u8 ifc;
	u8 link;
	enum mcde_sync_src sync_src;
	u8 update_auto_trig;
	union {
		struct {
			u8 virt_id;
			u8 num_data_lanes;
			u8 ui;
			u8 clk_cont;
			u8 data_lanes_swap;
		} dsi;
		struct {
			u8 bus_width;
			u8 tv_mode;
			u16 clock_div;	/* use 0 or 1 for no clock divider */
			u32 polarity;	/* see DPI_ACT_LOW_* definitions */
		} dpi;
	} phy;
};

/* Overlay pixel formats (input) */
enum mcde_ovly_pix_fmt {
	MCDE_OVLYPIXFMT_RGB565   = 1,
	MCDE_OVLYPIXFMT_RGB888   = 4,
};

#define MCDE_FIFO_AB_SIZE 640
#define MCDE_FIFO_C0C1_SIZE 160

#define MCDE_PIXFETCH_LARGE_WTRMRKLVL 128
#define MCDE_PIXFETCH_MEDIUM_WTRMRKLVL 32
#define MCDE_PIXFETCH_SMALL_WTRMRKLVL 16

/* Tv-out defines */
#define MCDE_CONFIG_TVOUT_HBORDER 2
#define MCDE_CONFIG_TVOUT_VBORDER 2
#define MCDE_CONFIG_TVOUT_BACKGROUND_LUMINANCE		0x83
#define MCDE_CONFIG_TVOUT_BACKGROUND_CHROMINANCE_CB	0x9C
#define MCDE_CONFIG_TVOUT_BACKGROUND_CHROMINANCE_CR	0x2C

/* In seconds */
#define MCDE_AUTO_SYNC_WATCHDOG 5

/* Hardware versions */
#define MCDE_CHIP_VERSION_3_0_8 2
#define MCDE_CHIP_VERSION_3_0_5 1
#define MCDE_CHIP_VERSION_3	0

/* DSI modes */
#define DSI_VIDEO_MODE	0
#define DSI_CMD_MODE	1

/* Video mode descriptor */
struct mcde_video_mode {
	u32 xres;
	u32 yres;
	u32 pixclock;	/* pixel clock in ps (pico seconds) */
	u32 hbp;	/* hor back porch = left_margin */
	u32 hfp;	/* hor front porch equals to right_margin */
	u32 hsw;	/* horizontal sync width */
	u32 vbp1;	/* field 1: vert back porch equals to upper_margin */
	u32 vfp1;	/* field 1: vert front porch equals to lower_margin */
	u32 vbp2;	/* field 2: vert back porch equals to upper_margin */
	u32 vfp2;	/* field 2: vert front porch equals to lower_margin */
	u32 vsw;	/* vertical sync width*/
	u8 interlaced;
	u8 bckcol[3];	/* background color */
};

struct mcde_rectangle {
	u16 x;
	u16 y;
	u16 w;
	u16 h;
};

struct mcde_chnl_state;

struct mcde_chnl_state *mcde_chnl_get(enum mcde_chnl chnl_id,
	enum mcde_fifo fifo, const struct mcde_port *port);
void mcde_chnl_set_update_area(struct mcde_chnl_state *chnl,
	u16 x, u16 y, u16 w, u16 h);
void mcde_chnl_set_pixel_format(struct mcde_chnl_state *chnl,
	enum mcde_port_pix_fmt pix_fmt);
void mcde_chnl_apply(struct mcde_chnl_state *chnl);
int mcde_chnl_update(struct mcde_chnl_state *chnl,
					struct mcde_rectangle *update_area);

void mcde_enable_dss(void);

/* MCDE overlay */
struct mcde_ovly_state;

struct mcde_ovly_state *mcde_ovly_get(struct mcde_chnl_state *chnl);
void mcde_ovly_set_source_buf(struct mcde_ovly_state *ovly,
	u32 paddr);
void mcde_ovly_set_source_info(struct mcde_ovly_state *ovly,
	u32 stride, enum mcde_ovly_pix_fmt pix_fmt);
void mcde_ovly_set_source_area(struct mcde_ovly_state *ovly,
	u16 x, u16 y, u16 w, u16 h);
void mcde_ovly_set_dest_pos(struct mcde_ovly_state *ovly,
	u16 x, u16 y, u8 z);
void mcde_ovly_apply(struct mcde_ovly_state *ovly);

/* MCDE dsi */

#define MCDE_MAX_DCS_WRITE		15
#define DCS_CMD_WRITE_START           0x2C
#define DCS_CMD_WRITE_CONTINUE        0x3C

int mcde_dsi_dcs_write(struct mcde_port *port, u8 cmd, u8* data, int len);

struct mcde_platform_data {
	/* DSI */
	int num_dsilinks;

	/* DPI */
	u8 outmux[5]; /* MCDE_CONF0.OUTMUXx */
	u8 syncmux;   /* MCDE_CONF0.SYNCMUXx */
};


/* MCDE */

extern int dpi_display_platform_enable(void);
extern void mcde_get_hardware_version(void);
extern void update_mcde_registers(struct mcde_platform_data *pdata);
extern int mcde_chnl_set_video_mode(struct mcde_chnl_state *chnl,
				struct mcde_video_mode *vmode);

extern int mcde_chnl_set_power_mode(struct mcde_chnl_state *chnl,
	enum mcde_display_power_mode power_mode);
extern int mcde_chnl_set_video_mode(struct mcde_chnl_state *chnl,
				struct mcde_video_mode *vmode);
int mcde_turn_on_display_dpi(void);
int mcde_turn_on_display_dsi(void);
int mcde_probe(u8 num_data_lanes, struct mcde_platform_data *pdata);
void mcde_init(void);
void mcde_exit(void);

#endif /* __MCDE__H__ */