1/*
2 * Copyright (c) 2006 Intel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
16 *
17 * Authors:
18 *    Eric Anholt <eric@anholt.net>
19 *
20 */
21
22#ifndef _I830_BIOS_H_
23#define _I830_BIOS_H_
24
25#include <drm/drmP.h>
26
27struct vbt_header {
28	u8 signature[20];		/**< Always starts with 'VBT$' */
29	u16 version;			/**< decimal */
30	u16 header_size;		/**< in bytes */
31	u16 vbt_size;			/**< in bytes */
32	u8 vbt_checksum;
33	u8 reserved0;
34	u32 bdb_offset;			/**< from beginning of VBT */
35	u32 aim_offset[4];		/**< from beginning of VBT */
36} __attribute__((packed));
37
38
39struct bdb_header {
40	u8 signature[16];		/**< Always 'BIOS_DATA_BLOCK' */
41	u16 version;			/**< decimal */
42	u16 header_size;		/**< in bytes */
43	u16 bdb_size;			/**< in bytes */
44};
45
46/* strictly speaking, this is a "skip" block, but it has interesting info */
47struct vbios_data {
48	u8 type; /* 0 == desktop, 1 == mobile */
49	u8 relstage;
50	u8 chipset;
51	u8 lvds_present:1;
52	u8 tv_present:1;
53	u8 rsvd2:6; /* finish byte */
54	u8 rsvd3[4];
55	u8 signon[155];
56	u8 copyright[61];
57	u16 code_segment;
58	u8 dos_boot_mode;
59	u8 bandwidth_percent;
60	u8 rsvd4; /* popup memory size */
61	u8 resize_pci_bios;
62	u8 rsvd5; /* is crt already on ddc2 */
63} __attribute__((packed));
64
65/*
66 * There are several types of BIOS data blocks (BDBs), each block has
67 * an ID and size in the first 3 bytes (ID in first, size in next 2).
68 * Known types are listed below.
69 */
70#define BDB_GENERAL_FEATURES	  1
71#define BDB_GENERAL_DEFINITIONS	  2
72#define BDB_OLD_TOGGLE_LIST	  3
73#define BDB_MODE_SUPPORT_LIST	  4
74#define BDB_GENERIC_MODE_TABLE	  5
75#define BDB_EXT_MMIO_REGS	  6
76#define BDB_SWF_IO		  7
77#define BDB_SWF_MMIO		  8
78#define BDB_DOT_CLOCK_TABLE	  9
79#define BDB_MODE_REMOVAL_TABLE	 10
80#define BDB_CHILD_DEVICE_TABLE	 11
81#define BDB_DRIVER_FEATURES	 12
82#define BDB_DRIVER_PERSISTENCE	 13
83#define BDB_EXT_TABLE_PTRS	 14
84#define BDB_DOT_CLOCK_OVERRIDE	 15
85#define BDB_DISPLAY_SELECT	 16
86/* 17 rsvd */
87#define BDB_DRIVER_ROTATION	 18
88#define BDB_DISPLAY_REMOVE	 19
89#define BDB_OEM_CUSTOM		 20
90#define BDB_EFP_LIST		 21 /* workarounds for VGA hsync/vsync */
91#define BDB_SDVO_LVDS_OPTIONS	 22
92#define BDB_SDVO_PANEL_DTDS	 23
93#define BDB_SDVO_LVDS_PNP_IDS	 24
94#define BDB_SDVO_LVDS_POWER_SEQ	 25
95#define BDB_TV_OPTIONS		 26
96#define BDB_LVDS_OPTIONS	 40
97#define BDB_LVDS_LFP_DATA_PTRS	 41
98#define BDB_LVDS_LFP_DATA	 42
99#define BDB_LVDS_BACKLIGHT	 43
100#define BDB_LVDS_POWER		 44
101#define BDB_SKIP		254 /* VBIOS private block, ignore */
102
103struct bdb_general_features {
104	/* bits 1 */
105	u8 panel_fitting:2;
106	u8 flexaim:1;
107	u8 msg_enable:1;
108	u8 clear_screen:3;
109	u8 color_flip:1;
110
111	/* bits 2 */
112	u8 download_ext_vbt:1;
113	u8 enable_ssc:1;
114	u8 ssc_freq:1;
115	u8 enable_lfp_on_override:1;
116	u8 disable_ssc_ddt:1;
117	u8 rsvd8:3; /* finish byte */
118
119	/* bits 3 */
120	u8 disable_smooth_vision:1;
121	u8 single_dvi:1;
122	u8 rsvd9:6; /* finish byte */
123
124	/* bits 4 */
125	u8 legacy_monitor_detect;
126
127	/* bits 5 */
128	u8 int_crt_support:1;
129	u8 int_tv_support:1;
130	u8 rsvd11:6; /* finish byte */
131} __attribute__((packed));
132
133struct bdb_general_definitions {
134	/* DDC GPIO */
135	u8 crt_ddc_gmbus_pin;
136
137	/* DPMS bits */
138	u8 dpms_acpi:1;
139	u8 skip_boot_crt_detect:1;
140	u8 dpms_aim:1;
141	u8 rsvd1:5; /* finish byte */
142
143	/* boot device bits */
144	u8 boot_display[2];
145	u8 child_dev_size;
146
147	/* device info */
148	u8 tv_or_lvds_info[33];
149	u8 dev1[33];
150	u8 dev2[33];
151	u8 dev3[33];
152	u8 dev4[33];
153	/* may be another device block here on some platforms */
154};
155
156struct bdb_lvds_options {
157	u8 panel_type;
158	u8 rsvd1;
159	/* LVDS capabilities, stored in a dword */
160	u8 pfit_mode:2;
161	u8 pfit_text_mode_enhanced:1;
162	u8 pfit_gfx_mode_enhanced:1;
163	u8 pfit_ratio_auto:1;
164	u8 pixel_dither:1;
165	u8 lvds_edid:1;
166	u8 rsvd2:1;
167	u8 rsvd4;
168} __attribute__((packed));
169
170struct bdb_lvds_backlight {
171	u8 type:2;
172	u8 pol:1;
173	u8 gpio:3;
174	u8 gmbus:2;
175	u16 freq;
176	u8 minbrightness;
177	u8 i2caddr;
178	u8 brightnesscmd;
179	/*FIXME: more...*/
180} __attribute__((packed));
181
182/* LFP pointer table contains entries to the struct below */
183struct bdb_lvds_lfp_data_ptr {
184	u16 fp_timing_offset; /* offsets are from start of bdb */
185	u8 fp_table_size;
186	u16 dvo_timing_offset;
187	u8 dvo_table_size;
188	u16 panel_pnp_id_offset;
189	u8 pnp_table_size;
190} __attribute__((packed));
191
192struct bdb_lvds_lfp_data_ptrs {
193	u8 lvds_entries; /* followed by one or more lvds_data_ptr structs */
194	struct bdb_lvds_lfp_data_ptr ptr[16];
195} __attribute__((packed));
196
197/* LFP data has 3 blocks per entry */
198struct lvds_fp_timing {
199	u16 x_res;
200	u16 y_res;
201	u32 lvds_reg;
202	u32 lvds_reg_val;
203	u32 pp_on_reg;
204	u32 pp_on_reg_val;
205	u32 pp_off_reg;
206	u32 pp_off_reg_val;
207	u32 pp_cycle_reg;
208	u32 pp_cycle_reg_val;
209	u32 pfit_reg;
210	u32 pfit_reg_val;
211	u16 terminator;
212} __attribute__((packed));
213
214struct lvds_dvo_timing {
215	u16 clock;		/**< In 10khz */
216	u8 hactive_lo;
217	u8 hblank_lo;
218	u8 hblank_hi:4;
219	u8 hactive_hi:4;
220	u8 vactive_lo;
221	u8 vblank_lo;
222	u8 vblank_hi:4;
223	u8 vactive_hi:4;
224	u8 hsync_off_lo;
225	u8 hsync_pulse_width;
226	u8 vsync_pulse_width:4;
227	u8 vsync_off:4;
228	u8 rsvd0:6;
229	u8 hsync_off_hi:2;
230	u8 h_image;
231	u8 v_image;
232	u8 max_hv;
233	u8 h_border;
234	u8 v_border;
235	u8 rsvd1:3;
236	u8 digital:2;
237	u8 vsync_positive:1;
238	u8 hsync_positive:1;
239	u8 rsvd2:1;
240} __attribute__((packed));
241
242struct lvds_pnp_id {
243	u16 mfg_name;
244	u16 product_code;
245	u32 serial;
246	u8 mfg_week;
247	u8 mfg_year;
248} __attribute__((packed));
249
250struct bdb_lvds_lfp_data_entry {
251	struct lvds_fp_timing fp_timing;
252	struct lvds_dvo_timing dvo_timing;
253	struct lvds_pnp_id pnp_id;
254} __attribute__((packed));
255
256struct bdb_lvds_lfp_data {
257	struct bdb_lvds_lfp_data_entry data[16];
258} __attribute__((packed));
259
260struct aimdb_header {
261	char signature[16];
262	char oem_device[20];
263	u16 aimdb_version;
264	u16 aimdb_header_size;
265	u16 aimdb_size;
266} __attribute__((packed));
267
268struct aimdb_block {
269	u8 aimdb_id;
270	u16 aimdb_size;
271} __attribute__((packed));
272
273struct vch_panel_data {
274	u16 fp_timing_offset;
275	u8 fp_timing_size;
276	u16 dvo_timing_offset;
277	u8 dvo_timing_size;
278	u16 text_fitting_offset;
279	u8 text_fitting_size;
280	u16 graphics_fitting_offset;
281	u8 graphics_fitting_size;
282} __attribute__((packed));
283
284struct vch_bdb_22 {
285	struct aimdb_block aimdb_block;
286	struct vch_panel_data panels[16];
287} __attribute__((packed));
288
289struct bdb_sdvo_lvds_options {
290	u8 panel_backlight;
291	u8 h40_set_panel_type;
292	u8 panel_type;
293	u8 ssc_clk_freq;
294	u16 als_low_trip;
295	u16 als_high_trip;
296	u8 sclalarcoeff_tab_row_num;
297	u8 sclalarcoeff_tab_row_size;
298	u8 coefficient[8];
299	u8 panel_misc_bits_1;
300	u8 panel_misc_bits_2;
301	u8 panel_misc_bits_3;
302	u8 panel_misc_bits_4;
303} __attribute__((packed));
304
305
306extern bool psb_intel_init_bios(struct drm_device *dev);
307extern void psb_intel_destroy_bios(struct drm_device *dev);
308
309/*
310 * Driver<->VBIOS interaction occurs through scratch bits in
311 * GR18 & SWF*.
312 */
313
314/* GR18 bits are set on display switch and hotkey events */
315#define GR18_DRIVER_SWITCH_EN	(1<<7) /* 0: VBIOS control, 1: driver control */
316#define GR18_HOTKEY_MASK	0x78 /* See also SWF4 15:0 */
317#define   GR18_HK_NONE		(0x0<<3)
318#define   GR18_HK_LFP_STRETCH	(0x1<<3)
319#define   GR18_HK_TOGGLE_DISP	(0x2<<3)
320#define   GR18_HK_DISP_SWITCH	(0x4<<3) /* see SWF14 15:0 for what to enable */
321#define   GR18_HK_POPUP_DISABLED (0x6<<3)
322#define   GR18_HK_POPUP_ENABLED	(0x7<<3)
323#define   GR18_HK_PFIT		(0x8<<3)
324#define   GR18_HK_APM_CHANGE	(0xa<<3)
325#define   GR18_HK_MULTIPLE	(0xc<<3)
326#define GR18_USER_INT_EN	(1<<2)
327#define GR18_A0000_FLUSH_EN	(1<<1)
328#define GR18_SMM_EN		(1<<0)
329
330/* Set by driver, cleared by VBIOS */
331#define SWF00_YRES_SHIFT	16
332#define SWF00_XRES_SHIFT	0
333#define SWF00_RES_MASK		0xffff
334
335/* Set by VBIOS at boot time and driver at runtime */
336#define SWF01_TV2_FORMAT_SHIFT	8
337#define SWF01_TV1_FORMAT_SHIFT	0
338#define SWF01_TV_FORMAT_MASK	0xffff
339
340#define SWF10_VBIOS_BLC_I2C_EN	(1<<29)
341#define SWF10_GTT_OVERRIDE_EN	(1<<28)
342#define SWF10_LFP_DPMS_OVR	(1<<27) /* override DPMS on display switch */
343#define SWF10_ACTIVE_TOGGLE_LIST_MASK (7<<24)
344#define   SWF10_OLD_TOGGLE	0x0
345#define   SWF10_TOGGLE_LIST_1	0x1
346#define   SWF10_TOGGLE_LIST_2	0x2
347#define   SWF10_TOGGLE_LIST_3	0x3
348#define   SWF10_TOGGLE_LIST_4	0x4
349#define SWF10_PANNING_EN	(1<<23)
350#define SWF10_DRIVER_LOADED	(1<<22)
351#define SWF10_EXTENDED_DESKTOP	(1<<21)
352#define SWF10_EXCLUSIVE_MODE	(1<<20)
353#define SWF10_OVERLAY_EN	(1<<19)
354#define SWF10_PLANEB_HOLDOFF	(1<<18)
355#define SWF10_PLANEA_HOLDOFF	(1<<17)
356#define SWF10_VGA_HOLDOFF	(1<<16)
357#define SWF10_ACTIVE_DISP_MASK	0xffff
358#define   SWF10_PIPEB_LFP2	(1<<15)
359#define   SWF10_PIPEB_EFP2	(1<<14)
360#define   SWF10_PIPEB_TV2	(1<<13)
361#define   SWF10_PIPEB_CRT2	(1<<12)
362#define   SWF10_PIPEB_LFP	(1<<11)
363#define   SWF10_PIPEB_EFP	(1<<10)
364#define   SWF10_PIPEB_TV	(1<<9)
365#define   SWF10_PIPEB_CRT	(1<<8)
366#define   SWF10_PIPEA_LFP2	(1<<7)
367#define   SWF10_PIPEA_EFP2	(1<<6)
368#define   SWF10_PIPEA_TV2	(1<<5)
369#define   SWF10_PIPEA_CRT2	(1<<4)
370#define   SWF10_PIPEA_LFP	(1<<3)
371#define   SWF10_PIPEA_EFP	(1<<2)
372#define   SWF10_PIPEA_TV	(1<<1)
373#define   SWF10_PIPEA_CRT	(1<<0)
374
375#define SWF11_MEMORY_SIZE_SHIFT	16
376#define SWF11_SV_TEST_EN	(1<<15)
377#define SWF11_IS_AGP		(1<<14)
378#define SWF11_DISPLAY_HOLDOFF	(1<<13)
379#define SWF11_DPMS_REDUCED	(1<<12)
380#define SWF11_IS_VBE_MODE	(1<<11)
381#define SWF11_PIPEB_ACCESS	(1<<10) /* 0 here means pipe a */
382#define SWF11_DPMS_MASK		0x07
383#define   SWF11_DPMS_OFF	(1<<2)
384#define   SWF11_DPMS_SUSPEND	(1<<1)
385#define   SWF11_DPMS_STANDBY	(1<<0)
386#define   SWF11_DPMS_ON		0
387
388#define SWF14_GFX_PFIT_EN	(1<<31)
389#define SWF14_TEXT_PFIT_EN	(1<<30)
390#define SWF14_LID_STATUS_CLOSED	(1<<29) /* 0 here means open */
391#define SWF14_POPUP_EN		(1<<28)
392#define SWF14_DISPLAY_HOLDOFF	(1<<27)
393#define SWF14_DISP_DETECT_EN	(1<<26)
394#define SWF14_DOCKING_STATUS_DOCKED (1<<25) /* 0 here means undocked */
395#define SWF14_DRIVER_STATUS	(1<<24)
396#define SWF14_OS_TYPE_WIN9X	(1<<23)
397#define SWF14_OS_TYPE_WINNT	(1<<22)
398/* 21:19 rsvd */
399#define SWF14_PM_TYPE_MASK	0x00070000
400#define   SWF14_PM_ACPI_VIDEO	(0x4 << 16)
401#define   SWF14_PM_ACPI		(0x3 << 16)
402#define   SWF14_PM_APM_12	(0x2 << 16)
403#define   SWF14_PM_APM_11	(0x1 << 16)
404#define SWF14_HK_REQUEST_MASK	0x0000ffff /* see GR18 6:3 for event type */
405	  /* if GR18 indicates a display switch */
406#define   SWF14_DS_PIPEB_LFP2_EN (1<<15)
407#define   SWF14_DS_PIPEB_EFP2_EN (1<<14)
408#define   SWF14_DS_PIPEB_TV2_EN  (1<<13)
409#define   SWF14_DS_PIPEB_CRT2_EN (1<<12)
410#define   SWF14_DS_PIPEB_LFP_EN  (1<<11)
411#define   SWF14_DS_PIPEB_EFP_EN  (1<<10)
412#define   SWF14_DS_PIPEB_TV_EN	 (1<<9)
413#define   SWF14_DS_PIPEB_CRT_EN  (1<<8)
414#define   SWF14_DS_PIPEA_LFP2_EN (1<<7)
415#define   SWF14_DS_PIPEA_EFP2_EN (1<<6)
416#define   SWF14_DS_PIPEA_TV2_EN  (1<<5)
417#define   SWF14_DS_PIPEA_CRT2_EN (1<<4)
418#define   SWF14_DS_PIPEA_LFP_EN  (1<<3)
419#define   SWF14_DS_PIPEA_EFP_EN  (1<<2)
420#define   SWF14_DS_PIPEA_TV_EN	 (1<<1)
421#define   SWF14_DS_PIPEA_CRT_EN  (1<<0)
422	  /* if GR18 indicates a panel fitting request */
423#define   SWF14_PFIT_EN		(1<<0) /* 0 means disable */
424	  /* if GR18 indicates an APM change request */
425#define   SWF14_APM_HIBERNATE	0x4
426#define   SWF14_APM_SUSPEND	0x3
427#define   SWF14_APM_STANDBY	0x1
428#define   SWF14_APM_RESTORE	0x0
429
430#endif /* _I830_BIOS_H_ */
431