aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2008-11-07 17:24:08 -0500
committerDave Airlie <airlied@linux.ie>2008-12-29 02:47:23 -0500
commit79e539453b34e35f39299a899d263b0a1f1670bd (patch)
tree6d1285f2b78fab399aab75a3557b7d6bc0dbd112 /drivers/gpu/drm/i915
parentf453ba0460742ad027ae0c4c7d61e62817b3e7ef (diff)
DRM: i915: add mode setting support
This commit adds i915 driver support for the DRM mode setting APIs. Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are supported. HDMI, DisplayPort and additional SDVO output support will follow. Support for the mode setting code is controlled by the new 'modeset' module option. A new config option, CONFIG_DRM_I915_KMS controls the default behavior, and whether a PCI ID list is built into the module for use by user level module utilities. Note that if mode setting is enabled, user level drivers that access display registers directly or that don't use the kernel graphics memory manager will likely corrupt kernel graphics memory, disrupt output configuration (possibly leading to hangs and/or blank displays), and prevent panic/oops messages from appearing. So use caution when enabling this code; be sure your user level code supports the new interfaces. A new SysRq key, 'g', provides emergency support for switching back to the kernel's framebuffer console; which is useful for testing. Co-authors: Dave Airlie <airlied@linux.ie>, Hong Liu <hong.liu@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Eric Anholt <eric@anholt.net> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r--drivers/gpu/drm/i915/Makefile17
-rw-r--r--drivers/gpu/drm/i915/dvo.h151
-rw-r--r--drivers/gpu/drm/i915/dvo_ch7017.c454
-rw-r--r--drivers/gpu/drm/i915/dvo_ch7xxx.c368
-rw-r--r--drivers/gpu/drm/i915/dvo_ivch.c442
-rw-r--r--drivers/gpu/drm/i915/dvo_sil164.c302
-rw-r--r--drivers/gpu/drm/i915/dvo_tfp410.c335
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c258
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c33
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h45
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c132
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c21
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c193
-rw-r--r--drivers/gpu/drm/i915/intel_bios.h405
-rw-r--r--drivers/gpu/drm/i915/intel_crt.c284
-rw-r--r--drivers/gpu/drm/i915/intel_display.c1621
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h146
-rw-r--r--drivers/gpu/drm/i915/intel_dvo.c501
-rw-r--r--drivers/gpu/drm/i915/intel_fb.c926
-rw-r--r--drivers/gpu/drm/i915/intel_i2c.c184
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c525
-rw-r--r--drivers/gpu/drm/i915/intel_modes.c83
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c1127
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo_regs.h327
-rw-r--r--drivers/gpu/drm/i915/intel_tv.c1725
25 files changed, 10555 insertions, 50 deletions
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index d8fb5d8ee7ea..dd57a5bd4572 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -8,7 +8,22 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \
8 i915_gem.o \ 8 i915_gem.o \
9 i915_gem_debug.o \ 9 i915_gem_debug.o \
10 i915_gem_proc.o \ 10 i915_gem_proc.o \
11 i915_gem_tiling.o 11 i915_gem_tiling.o \
12 intel_display.o \
13 intel_crt.o \
14 intel_lvds.o \
15 intel_bios.o \
16 intel_sdvo.o \
17 intel_modes.o \
18 intel_i2c.o \
19 intel_fb.o \
20 intel_tv.o \
21 intel_dvo.o \
22 dvo_ch7xxx.o \
23 dvo_ch7017.o \
24 dvo_ivch.o \
25 dvo_tfp410.o \
26 dvo_sil164.o
12 27
13i915-$(CONFIG_ACPI) += i915_opregion.o 28i915-$(CONFIG_ACPI) += i915_opregion.o
14i915-$(CONFIG_COMPAT) += i915_ioc32.o 29i915-$(CONFIG_COMPAT) += i915_ioc32.o
diff --git a/drivers/gpu/drm/i915/dvo.h b/drivers/gpu/drm/i915/dvo.h
new file mode 100644
index 000000000000..e80866c5e1ae
--- /dev/null
+++ b/drivers/gpu/drm/i915/dvo.h
@@ -0,0 +1,151 @@
1/*
2 * Copyright © 2006 Eric Anholt
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting documentation, and
8 * that the name of the copyright holders not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission. The copyright holders make no representations
11 * about the suitability of this software for any purpose. It is provided "as
12 * is" without express or implied warranty.
13 *
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20 * OF THIS SOFTWARE.
21 */
22
23#ifndef _INTEL_DVO_H
24#define _INTEL_DVO_H
25
26#include <linux/i2c.h>
27#include "drmP.h"
28#include "drm.h"
29#include "drm_crtc.h"
30#include "intel_drv.h"
31
32struct intel_dvo_device {
33 char *name;
34 int type;
35 /* DVOA/B/C output register */
36 u32 dvo_reg;
37 /* GPIO register used for i2c bus to control this device */
38 u32 gpio;
39 int slave_addr;
40 struct intel_i2c_chan *i2c_bus;
41
42 const struct intel_dvo_dev_ops *dev_ops;
43 void *dev_priv;
44
45 struct drm_display_mode *panel_fixed_mode;
46 bool panel_wants_dither;
47};
48
49struct intel_dvo_dev_ops {
50 /*
51 * Initialize the device at startup time.
52 * Returns NULL if the device does not exist.
53 */
54 bool (*init)(struct intel_dvo_device *dvo,
55 struct intel_i2c_chan *i2cbus);
56
57 /*
58 * Called to allow the output a chance to create properties after the
59 * RandR objects have been created.
60 */
61 void (*create_resources)(struct intel_dvo_device *dvo);
62
63 /*
64 * Turn on/off output or set intermediate power levels if available.
65 *
66 * Unsupported intermediate modes drop to the lower power setting.
67 * If the mode is DPMSModeOff, the output must be disabled,
68 * as the DPLL may be disabled afterwards.
69 */
70 void (*dpms)(struct intel_dvo_device *dvo, int mode);
71
72 /*
73 * Saves the output's state for restoration on VT switch.
74 */
75 void (*save)(struct intel_dvo_device *dvo);
76
77 /*
78 * Restore's the output's state at VT switch.
79 */
80 void (*restore)(struct intel_dvo_device *dvo);
81
82 /*
83 * Callback for testing a video mode for a given output.
84 *
85 * This function should only check for cases where a mode can't
86 * be supported on the output specifically, and not represent
87 * generic CRTC limitations.
88 *
89 * \return MODE_OK if the mode is valid, or another MODE_* otherwise.
90 */
91 int (*mode_valid)(struct intel_dvo_device *dvo,
92 struct drm_display_mode *mode);
93
94 /*
95 * Callback to adjust the mode to be set in the CRTC.
96 *
97 * This allows an output to adjust the clock or even the entire set of
98 * timings, which is used for panels with fixed timings or for
99 * buses with clock limitations.
100 */
101 bool (*mode_fixup)(struct intel_dvo_device *dvo,
102 struct drm_display_mode *mode,
103 struct drm_display_mode *adjusted_mode);
104
105 /*
106 * Callback for preparing mode changes on an output
107 */
108 void (*prepare)(struct intel_dvo_device *dvo);
109
110 /*
111 * Callback for committing mode changes on an output
112 */
113 void (*commit)(struct intel_dvo_device *dvo);
114
115 /*
116 * Callback for setting up a video mode after fixups have been made.
117 *
118 * This is only called while the output is disabled. The dpms callback
119 * must be all that's necessary for the output, to turn the output on
120 * after this function is called.
121 */
122 void (*mode_set)(struct intel_dvo_device *dvo,
123 struct drm_display_mode *mode,
124 struct drm_display_mode *adjusted_mode);
125
126 /*
127 * Probe for a connected output, and return detect_status.
128 */
129 enum drm_connector_status (*detect)(struct intel_dvo_device *dvo);
130
131 /**
132 * Query the device for the modes it provides.
133 *
134 * This function may also update MonInfo, mm_width, and mm_height.
135 *
136 * \return singly-linked list of modes or NULL if no modes found.
137 */
138 struct drm_display_mode *(*get_modes)(struct intel_dvo_device *dvo);
139
140 /**
141 * Clean up driver-specific bits of the output
142 */
143 void (*destroy) (struct intel_dvo_device *dvo);
144
145 /**
146 * Debugging hook to dump device registers to log file
147 */
148 void (*dump_regs)(struct intel_dvo_device *dvo);
149};
150
151#endif /* _INTEL_DVO_H */
diff --git a/drivers/gpu/drm/i915/dvo_ch7017.c b/drivers/gpu/drm/i915/dvo_ch7017.c
new file mode 100644
index 000000000000..03d4b4973b02
--- /dev/null
+++ b/drivers/gpu/drm/i915/dvo_ch7017.c
@@ -0,0 +1,454 @@
1/*
2 * Copyright © 2006 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 *
23 * Authors:
24 * Eric Anholt <eric@anholt.net>
25 *
26 */
27
28#include "dvo.h"
29
30#define CH7017_TV_DISPLAY_MODE 0x00
31#define CH7017_FLICKER_FILTER 0x01
32#define CH7017_VIDEO_BANDWIDTH 0x02
33#define CH7017_TEXT_ENHANCEMENT 0x03
34#define CH7017_START_ACTIVE_VIDEO 0x04
35#define CH7017_HORIZONTAL_POSITION 0x05
36#define CH7017_VERTICAL_POSITION 0x06
37#define CH7017_BLACK_LEVEL 0x07
38#define CH7017_CONTRAST_ENHANCEMENT 0x08
39#define CH7017_TV_PLL 0x09
40#define CH7017_TV_PLL_M 0x0a
41#define CH7017_TV_PLL_N 0x0b
42#define CH7017_SUB_CARRIER_0 0x0c
43#define CH7017_CIV_CONTROL 0x10
44#define CH7017_CIV_0 0x11
45#define CH7017_CHROMA_BOOST 0x14
46#define CH7017_CLOCK_MODE 0x1c
47#define CH7017_INPUT_CLOCK 0x1d
48#define CH7017_GPIO_CONTROL 0x1e
49#define CH7017_INPUT_DATA_FORMAT 0x1f
50#define CH7017_CONNECTION_DETECT 0x20
51#define CH7017_DAC_CONTROL 0x21
52#define CH7017_BUFFERED_CLOCK_OUTPUT 0x22
53#define CH7017_DEFEAT_VSYNC 0x47
54#define CH7017_TEST_PATTERN 0x48
55
56#define CH7017_POWER_MANAGEMENT 0x49
57/** Enables the TV output path. */
58#define CH7017_TV_EN (1 << 0)
59#define CH7017_DAC0_POWER_DOWN (1 << 1)
60#define CH7017_DAC1_POWER_DOWN (1 << 2)
61#define CH7017_DAC2_POWER_DOWN (1 << 3)
62#define CH7017_DAC3_POWER_DOWN (1 << 4)
63/** Powers down the TV out block, and DAC0-3 */
64#define CH7017_TV_POWER_DOWN_EN (1 << 5)
65
66#define CH7017_VERSION_ID 0x4a
67
68#define CH7017_DEVICE_ID 0x4b
69#define CH7017_DEVICE_ID_VALUE 0x1b
70#define CH7018_DEVICE_ID_VALUE 0x1a
71#define CH7019_DEVICE_ID_VALUE 0x19
72
73#define CH7017_XCLK_D2_ADJUST 0x53
74#define CH7017_UP_SCALER_COEFF_0 0x55
75#define CH7017_UP_SCALER_COEFF_1 0x56
76#define CH7017_UP_SCALER_COEFF_2 0x57
77#define CH7017_UP_SCALER_COEFF_3 0x58
78#define CH7017_UP_SCALER_COEFF_4 0x59
79#define CH7017_UP_SCALER_VERTICAL_INC_0 0x5a
80#define CH7017_UP_SCALER_VERTICAL_INC_1 0x5b
81#define CH7017_GPIO_INVERT 0x5c
82#define CH7017_UP_SCALER_HORIZONTAL_INC_0 0x5d
83#define CH7017_UP_SCALER_HORIZONTAL_INC_1 0x5e
84
85#define CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT 0x5f
86/**< Low bits of horizontal active pixel input */
87
88#define CH7017_ACTIVE_INPUT_LINE_OUTPUT 0x60
89/** High bits of horizontal active pixel input */
90#define CH7017_LVDS_HAP_INPUT_MASK (0x7 << 0)
91/** High bits of vertical active line output */
92#define CH7017_LVDS_VAL_HIGH_MASK (0x7 << 3)
93
94#define CH7017_VERTICAL_ACTIVE_LINE_OUTPUT 0x61
95/**< Low bits of vertical active line output */
96
97#define CH7017_HORIZONTAL_ACTIVE_PIXEL_OUTPUT 0x62
98/**< Low bits of horizontal active pixel output */
99
100#define CH7017_LVDS_POWER_DOWN 0x63
101/** High bits of horizontal active pixel output */
102#define CH7017_LVDS_HAP_HIGH_MASK (0x7 << 0)
103/** Enables the LVDS power down state transition */
104#define CH7017_LVDS_POWER_DOWN_EN (1 << 6)
105/** Enables the LVDS upscaler */
106#define CH7017_LVDS_UPSCALER_EN (1 << 7)
107#define CH7017_LVDS_POWER_DOWN_DEFAULT_RESERVED 0x08
108
109#define CH7017_LVDS_ENCODING 0x64
110#define CH7017_LVDS_DITHER_2D (1 << 2)
111#define CH7017_LVDS_DITHER_DIS (1 << 3)
112#define CH7017_LVDS_DUAL_CHANNEL_EN (1 << 4)
113#define CH7017_LVDS_24_BIT (1 << 5)
114
115#define CH7017_LVDS_ENCODING_2 0x65
116
117#define CH7017_LVDS_PLL_CONTROL 0x66
118/** Enables the LVDS panel output path */
119#define CH7017_LVDS_PANEN (1 << 0)
120/** Enables the LVDS panel backlight */
121#define CH7017_LVDS_BKLEN (1 << 3)
122
123#define CH7017_POWER_SEQUENCING_T1 0x67
124#define CH7017_POWER_SEQUENCING_T2 0x68
125#define CH7017_POWER_SEQUENCING_T3 0x69
126#define CH7017_POWER_SEQUENCING_T4 0x6a
127#define CH7017_POWER_SEQUENCING_T5 0x6b
128#define CH7017_GPIO_DRIVER_TYPE 0x6c
129#define CH7017_GPIO_DATA 0x6d
130#define CH7017_GPIO_DIRECTION_CONTROL 0x6e
131
132#define CH7017_LVDS_PLL_FEEDBACK_DIV 0x71
133# define CH7017_LVDS_PLL_FEED_BACK_DIVIDER_SHIFT 4
134# define CH7017_LVDS_PLL_FEED_FORWARD_DIVIDER_SHIFT 0
135# define CH7017_LVDS_PLL_FEEDBACK_DEFAULT_RESERVED 0x80
136
137#define CH7017_LVDS_PLL_VCO_CONTROL 0x72
138# define CH7017_LVDS_PLL_VCO_DEFAULT_RESERVED 0x80
139# define CH7017_LVDS_PLL_VCO_SHIFT 4
140# define CH7017_LVDS_PLL_POST_SCALE_DIV_SHIFT 0
141
142#define CH7017_OUTPUTS_ENABLE 0x73
143# define CH7017_CHARGE_PUMP_LOW 0x0
144# define CH7017_CHARGE_PUMP_HIGH 0x3
145# define CH7017_LVDS_CHANNEL_A (1 << 3)
146# define CH7017_LVDS_CHANNEL_B (1 << 4)
147# define CH7017_TV_DAC_A (1 << 5)
148# define CH7017_TV_DAC_B (1 << 6)
149# define CH7017_DDC_SELECT_DC2 (1 << 7)
150
151#define CH7017_LVDS_OUTPUT_AMPLITUDE 0x74
152#define CH7017_LVDS_PLL_EMI_REDUCTION 0x75
153#define CH7017_LVDS_POWER_DOWN_FLICKER 0x76
154
155#define CH7017_LVDS_CONTROL_2 0x78
156# define CH7017_LOOP_FILTER_SHIFT 5
157# define CH7017_PHASE_DETECTOR_SHIFT 0
158
159#define CH7017_BANG_LIMIT_CONTROL 0x7f
160
161struct ch7017_priv {
162 uint8_t save_hapi;
163 uint8_t save_vali;
164 uint8_t save_valo;
165 uint8_t save_ailo;
166 uint8_t save_lvds_pll_vco;
167 uint8_t save_feedback_div;
168 uint8_t save_lvds_control_2;
169 uint8_t save_outputs_enable;
170 uint8_t save_lvds_power_down;
171 uint8_t save_power_management;
172};
173
174static void ch7017_dump_regs(struct intel_dvo_device *dvo);
175static void ch7017_dpms(struct intel_dvo_device *dvo, int mode);
176
177static bool ch7017_read(struct intel_dvo_device *dvo, int addr, uint8_t *val)
178{
179 struct intel_i2c_chan *i2cbus = dvo->i2c_bus;
180 u8 out_buf[2];
181 u8 in_buf[2];
182
183 struct i2c_msg msgs[] = {
184 {
185 .addr = i2cbus->slave_addr,
186 .flags = 0,
187 .len = 1,
188 .buf = out_buf,
189 },
190 {
191 .addr = i2cbus->slave_addr,
192 .flags = I2C_M_RD,
193 .len = 1,
194 .buf = in_buf,
195 }
196 };
197
198 out_buf[0] = addr;
199 out_buf[1] = 0;
200
201 if (i2c_transfer(&i2cbus->adapter, msgs, 2) == 2) {
202 *val= in_buf[0];
203 return true;
204 };
205
206 return false;
207}
208
209static bool ch7017_write(struct intel_dvo_device *dvo, int addr, uint8_t val)
210{
211 struct intel_i2c_chan *i2cbus = dvo->i2c_bus;
212 uint8_t out_buf[2];
213 struct i2c_msg msg = {
214 .addr = i2cbus->slave_addr,
215 .flags = 0,
216 .len = 2,
217 .buf = out_buf,
218 };
219
220 out_buf[0] = addr;
221 out_buf[1] = val;
222
223 if (i2c_transfer(&i2cbus->adapter, &msg, 1) == 1)
224 return true;
225
226 return false;
227}
228
229/** Probes for a CH7017 on the given bus and slave address. */
230static bool ch7017_init(struct intel_dvo_device *dvo,
231 struct intel_i2c_chan *i2cbus)
232{
233 struct ch7017_priv *priv;
234 uint8_t val;
235
236 priv = kzalloc(sizeof(struct ch7017_priv), GFP_KERNEL);
237 if (priv == NULL)
238 return false;
239
240 dvo->i2c_bus = i2cbus;
241 dvo->i2c_bus->slave_addr = dvo->slave_addr;
242 dvo->dev_priv = priv;
243
244 if (!ch7017_read(dvo, CH7017_DEVICE_ID, &val))
245 goto fail;
246
247 if (val != CH7017_DEVICE_ID_VALUE &&
248 val != CH7018_DEVICE_ID_VALUE &&
249 val != CH7019_DEVICE_ID_VALUE) {
250 DRM_DEBUG("ch701x not detected, got %d: from %s Slave %d.\n",
251 val, i2cbus->adapter.name,i2cbus->slave_addr);
252 goto fail;
253 }
254
255 return true;
256fail:
257 kfree(priv);
258 return false;
259}
260
261static enum drm_connector_status ch7017_detect(struct intel_dvo_device *dvo)
262{
263 return connector_status_unknown;
264}
265
266static enum drm_mode_status ch7017_mode_valid(struct intel_dvo_device *dvo,
267 struct drm_display_mode *mode)
268{
269 if (mode->clock > 160000)
270 return MODE_CLOCK_HIGH;
271
272 return MODE_OK;
273}
274
275static void ch7017_mode_set(struct intel_dvo_device *dvo,
276 struct drm_display_mode *mode,
277 struct drm_display_mode *adjusted_mode)
278{
279 uint8_t lvds_pll_feedback_div, lvds_pll_vco_control;
280 uint8_t outputs_enable, lvds_control_2, lvds_power_down;
281 uint8_t horizontal_active_pixel_input;
282 uint8_t horizontal_active_pixel_output, vertical_active_line_output;
283 uint8_t active_input_line_output;
284
285 DRM_DEBUG("Registers before mode setting\n");
286 ch7017_dump_regs(dvo);
287
288 /* LVDS PLL settings from page 75 of 7017-7017ds.pdf*/
289 if (mode->clock < 100000) {
290 outputs_enable = CH7017_LVDS_CHANNEL_A | CH7017_CHARGE_PUMP_LOW;
291 lvds_pll_feedback_div = CH7017_LVDS_PLL_FEEDBACK_DEFAULT_RESERVED |
292 (2 << CH7017_LVDS_PLL_FEED_BACK_DIVIDER_SHIFT) |
293 (13 << CH7017_LVDS_PLL_FEED_FORWARD_DIVIDER_SHIFT);
294 lvds_pll_vco_control = CH7017_LVDS_PLL_VCO_DEFAULT_RESERVED |
295 (2 << CH7017_LVDS_PLL_VCO_SHIFT) |
296 (3 << CH7017_LVDS_PLL_POST_SCALE_DIV_SHIFT);
297 lvds_control_2 = (1 << CH7017_LOOP_FILTER_SHIFT) |
298 (0 << CH7017_PHASE_DETECTOR_SHIFT);
299 } else {
300 outputs_enable = CH7017_LVDS_CHANNEL_A | CH7017_CHARGE_PUMP_HIGH;
301 lvds_pll_feedback_div = CH7017_LVDS_PLL_FEEDBACK_DEFAULT_RESERVED |
302 (2 << CH7017_LVDS_PLL_FEED_BACK_DIVIDER_SHIFT) |
303 (3 << CH7017_LVDS_PLL_FEED_FORWARD_DIVIDER_SHIFT);
304 lvds_pll_feedback_div = 35;
305 lvds_control_2 = (3 << CH7017_LOOP_FILTER_SHIFT) |
306 (0 << CH7017_PHASE_DETECTOR_SHIFT);
307 if (1) { /* XXX: dual channel panel detection. Assume yes for now. */
308 outputs_enable |= CH7017_LVDS_CHANNEL_B;
309 lvds_pll_vco_control = CH7017_LVDS_PLL_VCO_DEFAULT_RESERVED |
310 (2 << CH7017_LVDS_PLL_VCO_SHIFT) |
311 (13 << CH7017_LVDS_PLL_POST_SCALE_DIV_SHIFT);
312 } else {
313 lvds_pll_vco_control = CH7017_LVDS_PLL_VCO_DEFAULT_RESERVED |
314 (1 << CH7017_LVDS_PLL_VCO_SHIFT) |
315 (13 << CH7017_LVDS_PLL_POST_SCALE_DIV_SHIFT);
316 }
317 }
318
319 horizontal_active_pixel_input = mode->hdisplay & 0x00ff;
320
321 vertical_active_line_output = mode->vdisplay & 0x00ff;
322 horizontal_active_pixel_output = mode->hdisplay & 0x00ff;
323
324 active_input_line_output = ((mode->hdisplay & 0x0700) >> 8) |
325 (((mode->vdisplay & 0x0700) >> 8) << 3);
326
327 lvds_power_down = CH7017_LVDS_POWER_DOWN_DEFAULT_RESERVED |
328 (mode->hdisplay & 0x0700) >> 8;
329
330 ch7017_dpms(dvo, DRM_MODE_DPMS_OFF);
331 ch7017_write(dvo, CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT,
332 horizontal_active_pixel_input);
333 ch7017_write(dvo, CH7017_HORIZONTAL_ACTIVE_PIXEL_OUTPUT,
334 horizontal_active_pixel_output);
335 ch7017_write(dvo, CH7017_VERTICAL_ACTIVE_LINE_OUTPUT,
336 vertical_active_line_output);
337 ch7017_write(dvo, CH7017_ACTIVE_INPUT_LINE_OUTPUT,
338 active_input_line_output);
339 ch7017_write(dvo, CH7017_LVDS_PLL_VCO_CONTROL, lvds_pll_vco_control);
340 ch7017_write(dvo, CH7017_LVDS_PLL_FEEDBACK_DIV, lvds_pll_feedback_div);
341 ch7017_write(dvo, CH7017_LVDS_CONTROL_2, lvds_control_2);
342 ch7017_write(dvo, CH7017_OUTPUTS_ENABLE, outputs_enable);
343
344 /* Turn the LVDS back on with new settings. */
345 ch7017_write(dvo, CH7017_LVDS_POWER_DOWN, lvds_power_down);
346
347 DRM_DEBUG("Registers after mode setting\n");
348 ch7017_dump_regs(dvo);
349}
350
351/* set the CH7017 power state */
352static void ch7017_dpms(struct intel_dvo_device *dvo, int mode)
353{
354 uint8_t val;
355
356 ch7017_read(dvo, CH7017_LVDS_POWER_DOWN, &val);
357
358 /* Turn off TV/VGA, and never turn it on since we don't support it. */
359 ch7017_write(dvo, CH7017_POWER_MANAGEMENT,
360 CH7017_DAC0_POWER_DOWN |
361 CH7017_DAC1_POWER_DOWN |
362 CH7017_DAC2_POWER_DOWN |
363 CH7017_DAC3_POWER_DOWN |
364 CH7017_TV_POWER_DOWN_EN);
365
366 if (mode == DRM_MODE_DPMS_ON) {
367 /* Turn on the LVDS */
368 ch7017_write(dvo, CH7017_LVDS_POWER_DOWN,
369 val & ~CH7017_LVDS_POWER_DOWN_EN);
370 } else {
371 /* Turn off the LVDS */
372 ch7017_write(dvo, CH7017_LVDS_POWER_DOWN,
373 val | CH7017_LVDS_POWER_DOWN_EN);
374 }
375
376 /* XXX: Should actually wait for update power status somehow */
377 udelay(20000);
378}
379
380static void ch7017_dump_regs(struct intel_dvo_device *dvo)
381{
382 uint8_t val;
383
384#define DUMP(reg) \
385do { \
386 ch7017_read(dvo, reg, &val); \
387 DRM_DEBUG(#reg ": %02x\n", val); \
388} while (0)
389
390 DUMP(CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT);
391 DUMP(CH7017_HORIZONTAL_ACTIVE_PIXEL_OUTPUT);
392 DUMP(CH7017_VERTICAL_ACTIVE_LINE_OUTPUT);
393 DUMP(CH7017_ACTIVE_INPUT_LINE_OUTPUT);
394 DUMP(CH7017_LVDS_PLL_VCO_CONTROL);
395 DUMP(CH7017_LVDS_PLL_FEEDBACK_DIV);
396 DUMP(CH7017_LVDS_CONTROL_2);
397 DUMP(CH7017_OUTPUTS_ENABLE);
398 DUMP(CH7017_LVDS_POWER_DOWN);
399}
400
401static void ch7017_save(struct intel_dvo_device *dvo)
402{
403 struct ch7017_priv *priv = dvo->dev_priv;
404
405 ch7017_read(dvo, CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT, &priv->save_hapi);
406 ch7017_read(dvo, CH7017_VERTICAL_ACTIVE_LINE_OUTPUT, &priv->save_valo);
407 ch7017_read(dvo, CH7017_ACTIVE_INPUT_LINE_OUTPUT, &priv->save_ailo);
408 ch7017_read(dvo, CH7017_LVDS_PLL_VCO_CONTROL, &priv->save_lvds_pll_vco);
409 ch7017_read(dvo, CH7017_LVDS_PLL_FEEDBACK_DIV, &priv->save_feedback_div);
410 ch7017_read(dvo, CH7017_LVDS_CONTROL_2, &priv->save_lvds_control_2);
411 ch7017_read(dvo, CH7017_OUTPUTS_ENABLE, &priv->save_outputs_enable);
412 ch7017_read(dvo, CH7017_LVDS_POWER_DOWN, &priv->save_lvds_power_down);
413 ch7017_read(dvo, CH7017_POWER_MANAGEMENT, &priv->save_power_management);
414}
415
416static void ch7017_restore(struct intel_dvo_device *dvo)
417{
418 struct ch7017_priv *priv = dvo->dev_priv;
419
420 /* Power down before changing mode */
421 ch7017_dpms(dvo, DRM_MODE_DPMS_OFF);
422
423 ch7017_write(dvo, CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT, priv->save_hapi);
424 ch7017_write(dvo, CH7017_VERTICAL_ACTIVE_LINE_OUTPUT, priv->save_valo);
425 ch7017_write(dvo, CH7017_ACTIVE_INPUT_LINE_OUTPUT, priv->save_ailo);
426 ch7017_write(dvo, CH7017_LVDS_PLL_VCO_CONTROL, priv->save_lvds_pll_vco);
427 ch7017_write(dvo, CH7017_LVDS_PLL_FEEDBACK_DIV, priv->save_feedback_div);
428 ch7017_write(dvo, CH7017_LVDS_CONTROL_2, priv->save_lvds_control_2);
429 ch7017_write(dvo, CH7017_OUTPUTS_ENABLE, priv->save_outputs_enable);
430 ch7017_write(dvo, CH7017_LVDS_POWER_DOWN, priv->save_lvds_power_down);
431 ch7017_write(dvo, CH7017_POWER_MANAGEMENT, priv->save_power_management);
432}
433
434static void ch7017_destroy(struct intel_dvo_device *dvo)
435{
436 struct ch7017_priv *priv = dvo->dev_priv;
437
438 if (priv) {
439 kfree(priv);
440 dvo->dev_priv = NULL;
441 }
442}
443
444struct intel_dvo_dev_ops ch7017_ops = {
445 .init = ch7017_init,
446 .detect = ch7017_detect,
447 .mode_valid = ch7017_mode_valid,
448 .mode_set = ch7017_mode_set,
449 .dpms = ch7017_dpms,
450 .dump_regs = ch7017_dump_regs,
451 .save = ch7017_save,
452 .restore = ch7017_restore,
453 .destroy = ch7017_destroy,
454};
diff --git a/drivers/gpu/drm/i915/dvo_ch7xxx.c b/drivers/gpu/drm/i915/dvo_ch7xxx.c
new file mode 100644
index 000000000000..d2fd95dbd034
--- /dev/null
+++ b/drivers/gpu/drm/i915/dvo_ch7xxx.c
@@ -0,0 +1,368 @@
1/**************************************************************************
2
3Copyright © 2006 Dave Airlie
4
5All Rights Reserved.
6
7Permission is hereby granted, free of charge, to any person obtaining a
8copy of this software and associated documentation files (the
9"Software"), to deal in the Software without restriction, including
10without limitation the rights to use, copy, modify, merge, publish,
11distribute, sub license, and/or sell copies of the Software, and to
12permit persons to whom the Software is furnished to do so, subject to
13the following conditions:
14
15The above copyright notice and this permission notice (including the
16next paragraph) shall be included in all copies or substantial portions
17of the Software.
18
19THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
23ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
27**************************************************************************/
28
29#include "dvo.h"
30
31#define CH7xxx_REG_VID 0x4a
32#define CH7xxx_REG_DID 0x4b
33
34#define CH7011_VID 0x83 /* 7010 as well */
35#define CH7009A_VID 0x84
36#define CH7009B_VID 0x85
37#define CH7301_VID 0x95
38
39#define CH7xxx_VID 0x84
40#define CH7xxx_DID 0x17
41
42#define CH7xxx_NUM_REGS 0x4c
43
44#define CH7xxx_CM 0x1c
45#define CH7xxx_CM_XCM (1<<0)
46#define CH7xxx_CM_MCP (1<<2)
47#define CH7xxx_INPUT_CLOCK 0x1d
48#define CH7xxx_GPIO 0x1e
49#define CH7xxx_GPIO_HPIR (1<<3)
50#define CH7xxx_IDF 0x1f
51
52#define CH7xxx_IDF_HSP (1<<3)
53#define CH7xxx_IDF_VSP (1<<4)
54
55#define CH7xxx_CONNECTION_DETECT 0x20
56#define CH7xxx_CDET_DVI (1<<5)
57
58#define CH7301_DAC_CNTL 0x21
59#define CH7301_HOTPLUG 0x23
60#define CH7xxx_TCTL 0x31
61#define CH7xxx_TVCO 0x32
62#define CH7xxx_TPCP 0x33
63#define CH7xxx_TPD 0x34
64#define CH7xxx_TPVT 0x35
65#define CH7xxx_TLPF 0x36
66#define CH7xxx_TCT 0x37
67#define CH7301_TEST_PATTERN 0x48
68
69#define CH7xxx_PM 0x49
70#define CH7xxx_PM_FPD (1<<0)
71#define CH7301_PM_DACPD0 (1<<1)
72#define CH7301_PM_DACPD1 (1<<2)
73#define CH7301_PM_DACPD2 (1<<3)
74#define CH7xxx_PM_DVIL (1<<6)
75#define CH7xxx_PM_DVIP (1<<7)
76
77#define CH7301_SYNC_POLARITY 0x56
78#define CH7301_SYNC_RGB_YUV (1<<0)
79#define CH7301_SYNC_POL_DVI (1<<5)
80
81/** @file
82 * driver for the Chrontel 7xxx DVI chip over DVO.
83 */
84
85static struct ch7xxx_id_struct {
86 uint8_t vid;
87 char *name;
88} ch7xxx_ids[] = {
89 { CH7011_VID, "CH7011" },
90 { CH7009A_VID, "CH7009A" },
91 { CH7009B_VID, "CH7009B" },
92 { CH7301_VID, "CH7301" },
93};
94
95struct ch7xxx_reg_state {
96 uint8_t regs[CH7xxx_NUM_REGS];
97};
98
99struct ch7xxx_priv {
100 bool quiet;
101
102 struct ch7xxx_reg_state save_reg;
103 struct ch7xxx_reg_state mode_reg;
104 uint8_t save_TCTL, save_TPCP, save_TPD, save_TPVT;
105 uint8_t save_TLPF, save_TCT, save_PM, save_IDF;
106};
107
108static void ch7xxx_save(struct intel_dvo_device *dvo);
109
110static char *ch7xxx_get_id(uint8_t vid)
111{
112 int i;
113
114 for (i = 0; i < ARRAY_SIZE(ch7xxx_ids); i++) {
115 if (ch7xxx_ids[i].vid == vid)
116 return ch7xxx_ids[i].name;
117 }
118
119 return NULL;
120}
121
122/** Reads an 8 bit register */
123static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
124{
125 struct ch7xxx_priv *ch7xxx= dvo->dev_priv;
126 struct intel_i2c_chan *i2cbus = dvo->i2c_bus;
127 u8 out_buf[2];
128 u8 in_buf[2];
129
130 struct i2c_msg msgs[] = {
131 {
132 .addr = i2cbus->slave_addr,
133 .flags = 0,
134 .len = 1,
135 .buf = out_buf,
136 },
137 {
138 .addr = i2cbus->slave_addr,
139 .flags = I2C_M_RD,
140 .len = 1,
141 .buf = in_buf,
142 }
143 };
144
145 out_buf[0] = addr;
146 out_buf[1] = 0;
147
148 if (i2c_transfer(&i2cbus->adapter, msgs, 2) == 2) {
149 *ch = in_buf[0];
150 return true;
151 };
152
153 if (!ch7xxx->quiet) {
154 DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n",
155 addr, i2cbus->adapter.name, i2cbus->slave_addr);
156 }
157 return false;
158}
159
160/** Writes an 8 bit register */
161static bool ch7xxx_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch)
162{
163 struct ch7xxx_priv *ch7xxx = dvo->dev_priv;
164 struct intel_i2c_chan *i2cbus = dvo->i2c_bus;
165 uint8_t out_buf[2];
166 struct i2c_msg msg = {
167 .addr = i2cbus->slave_addr,
168 .flags = 0,
169 .len = 2,
170 .buf = out_buf,
171 };
172
173 out_buf[0] = addr;
174 out_buf[1] = ch;
175
176 if (i2c_transfer(&i2cbus->adapter, &msg, 1) == 1)
177 return true;
178
179 if (!ch7xxx->quiet) {
180 DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n",
181 addr, i2cbus->adapter.name, i2cbus->slave_addr);
182 }
183
184 return false;
185}
186
187static bool ch7xxx_init(struct intel_dvo_device *dvo,
188 struct intel_i2c_chan *i2cbus)
189{
190 /* this will detect the CH7xxx chip on the specified i2c bus */
191 struct ch7xxx_priv *ch7xxx;
192 uint8_t vendor, device;
193 char *name;
194
195 ch7xxx = kzalloc(sizeof(struct ch7xxx_priv), GFP_KERNEL);
196 if (ch7xxx == NULL)
197 return false;
198
199 dvo->i2c_bus = i2cbus;
200 dvo->i2c_bus->slave_addr = dvo->slave_addr;
201 dvo->dev_priv = ch7xxx;
202 ch7xxx->quiet = true;
203
204 if (!ch7xxx_readb(dvo, CH7xxx_REG_VID, &vendor))
205 goto out;
206
207 name = ch7xxx_get_id(vendor);
208 if (!name) {
209 DRM_DEBUG("ch7xxx not detected; got 0x%02x from %s slave %d.\n",
210 vendor, i2cbus->adapter.name, i2cbus->slave_addr);
211 goto out;
212 }
213
214
215 if (!ch7xxx_readb(dvo, CH7xxx_REG_DID, &device))
216 goto out;
217
218 if (device != CH7xxx_DID) {
219 DRM_DEBUG("ch7xxx not detected; got 0x%02x from %s slave %d.\n",
220 vendor, i2cbus->adapter.name, i2cbus->slave_addr);
221 goto out;
222 }
223
224 ch7xxx->quiet = false;
225 DRM_DEBUG("Detected %s chipset, vendor/device ID 0x%02x/0x%02x\n",
226 name, vendor, device);
227 return true;
228out:
229 kfree(ch7xxx);
230 return false;
231}
232
233static enum drm_connector_status ch7xxx_detect(struct intel_dvo_device *dvo)
234{
235 uint8_t cdet, orig_pm, pm;
236
237 ch7xxx_readb(dvo, CH7xxx_PM, &orig_pm);
238
239 pm = orig_pm;
240 pm &= ~CH7xxx_PM_FPD;
241 pm |= CH7xxx_PM_DVIL | CH7xxx_PM_DVIP;
242
243 ch7xxx_writeb(dvo, CH7xxx_PM, pm);
244
245 ch7xxx_readb(dvo, CH7xxx_CONNECTION_DETECT, &cdet);
246
247 ch7xxx_writeb(dvo, CH7xxx_PM, orig_pm);
248
249 if (cdet & CH7xxx_CDET_DVI)
250 return connector_status_connected;
251 return connector_status_disconnected;
252}
253
254static enum drm_mode_status ch7xxx_mode_valid(struct intel_dvo_device *dvo,
255 struct drm_display_mode *mode)
256{
257 if (mode->clock > 165000)
258 return MODE_CLOCK_HIGH;
259
260 return MODE_OK;
261}
262
263static void ch7xxx_mode_set(struct intel_dvo_device *dvo,
264 struct drm_display_mode *mode,
265 struct drm_display_mode *adjusted_mode)
266{
267 uint8_t tvco, tpcp, tpd, tlpf, idf;
268
269 if (mode->clock <= 65000) {
270 tvco = 0x23;
271 tpcp = 0x08;
272 tpd = 0x16;
273 tlpf = 0x60;
274 } else {
275 tvco = 0x2d;
276 tpcp = 0x06;
277 tpd = 0x26;
278 tlpf = 0xa0;
279 }
280
281 ch7xxx_writeb(dvo, CH7xxx_TCTL, 0x00);
282 ch7xxx_writeb(dvo, CH7xxx_TVCO, tvco);
283 ch7xxx_writeb(dvo, CH7xxx_TPCP, tpcp);
284 ch7xxx_writeb(dvo, CH7xxx_TPD, tpd);
285 ch7xxx_writeb(dvo, CH7xxx_TPVT, 0x30);
286 ch7xxx_writeb(dvo, CH7xxx_TLPF, tlpf);
287 ch7xxx_writeb(dvo, CH7xxx_TCT, 0x00);
288
289 ch7xxx_readb(dvo, CH7xxx_IDF, &idf);
290
291 idf &= ~(CH7xxx_IDF_HSP | CH7xxx_IDF_VSP);
292 if (mode->flags & DRM_MODE_FLAG_PHSYNC)
293 idf |= CH7xxx_IDF_HSP;
294
295 if (mode->flags & DRM_MODE_FLAG_PVSYNC)
296 idf |= CH7xxx_IDF_HSP;
297
298 ch7xxx_writeb(dvo, CH7xxx_IDF, idf);
299}
300
301/* set the CH7xxx power state */
302static void ch7xxx_dpms(struct intel_dvo_device *dvo, int mode)
303{
304 if (mode == DRM_MODE_DPMS_ON)
305 ch7xxx_writeb(dvo, CH7xxx_PM, CH7xxx_PM_DVIL | CH7xxx_PM_DVIP);
306 else
307 ch7xxx_writeb(dvo, CH7xxx_PM, CH7xxx_PM_FPD);
308}
309
310static void ch7xxx_dump_regs(struct intel_dvo_device *dvo)
311{
312 struct ch7xxx_priv *ch7xxx = dvo->dev_priv;
313 int i;
314
315 for (i = 0; i < CH7xxx_NUM_REGS; i++) {
316 if ((i % 8) == 0 )
317 DRM_DEBUG("\n %02X: ", i);
318 DRM_DEBUG("%02X ", ch7xxx->mode_reg.regs[i]);
319 }
320}
321
322static void ch7xxx_save(struct intel_dvo_device *dvo)
323{
324 struct ch7xxx_priv *ch7xxx= dvo->dev_priv;
325
326 ch7xxx_readb(dvo, CH7xxx_TCTL, &ch7xxx->save_TCTL);
327 ch7xxx_readb(dvo, CH7xxx_TPCP, &ch7xxx->save_TPCP);
328 ch7xxx_readb(dvo, CH7xxx_TPD, &ch7xxx->save_TPD);
329 ch7xxx_readb(dvo, CH7xxx_TPVT, &ch7xxx->save_TPVT);
330 ch7xxx_readb(dvo, CH7xxx_TLPF, &ch7xxx->save_TLPF);
331 ch7xxx_readb(dvo, CH7xxx_PM, &ch7xxx->save_PM);
332 ch7xxx_readb(dvo, CH7xxx_IDF, &ch7xxx->save_IDF);
333}
334
335static void ch7xxx_restore(struct intel_dvo_device *dvo)
336{
337 struct ch7xxx_priv *ch7xxx = dvo->dev_priv;
338
339 ch7xxx_writeb(dvo, CH7xxx_TCTL, ch7xxx->save_TCTL);
340 ch7xxx_writeb(dvo, CH7xxx_TPCP, ch7xxx->save_TPCP);
341 ch7xxx_writeb(dvo, CH7xxx_TPD, ch7xxx->save_TPD);
342 ch7xxx_writeb(dvo, CH7xxx_TPVT, ch7xxx->save_TPVT);
343 ch7xxx_writeb(dvo, CH7xxx_TLPF, ch7xxx->save_TLPF);
344 ch7xxx_writeb(dvo, CH7xxx_IDF, ch7xxx->save_IDF);
345 ch7xxx_writeb(dvo, CH7xxx_PM, ch7xxx->save_PM);
346}
347
348static void ch7xxx_destroy(struct intel_dvo_device *dvo)
349{
350 struct ch7xxx_priv *ch7xxx = dvo->dev_priv;
351
352 if (ch7xxx) {
353 kfree(ch7xxx);
354 dvo->dev_priv = NULL;
355 }
356}
357
358struct intel_dvo_dev_ops ch7xxx_ops = {
359 .init = ch7xxx_init,
360 .detect = ch7xxx_detect,
361 .mode_valid = ch7xxx_mode_valid,
362 .mode_set = ch7xxx_mode_set,
363 .dpms = ch7xxx_dpms,
364 .dump_regs = ch7xxx_dump_regs,
365 .save = ch7xxx_save,
366 .restore = ch7xxx_restore,
367 .destroy = ch7xxx_destroy,
368};
diff --git a/drivers/gpu/drm/i915/dvo_ivch.c b/drivers/gpu/drm/i915/dvo_ivch.c
new file mode 100644
index 000000000000..0c8d375e8e37
--- /dev/null
+++ b/drivers/gpu/drm/i915/dvo_ivch.c
@@ -0,0 +1,442 @@
1/*
2 * Copyright © 2006 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 *
23 * Authors:
24 * Eric Anholt <eric@anholt.net>
25 *
26 */
27
28#include "dvo.h"
29
30/*
31 * register definitions for the i82807aa.
32 *
33 * Documentation on this chipset can be found in datasheet #29069001 at
34 * intel.com.
35 */
36
37/*
38 * VCH Revision & GMBus Base Addr
39 */
40#define VR00 0x00
41# define VR00_BASE_ADDRESS_MASK 0x007f
42
43/*
44 * Functionality Enable
45 */
46#define VR01 0x01
47
48/*
49 * Enable the panel fitter
50 */
51# define VR01_PANEL_FIT_ENABLE (1 << 3)
52/*
53 * Enables the LCD display.
54 *
55 * This must not be set while VR01_DVO_BYPASS_ENABLE is set.
56 */
57# define VR01_LCD_ENABLE (1 << 2)
58/** Enables the DVO repeater. */
59# define VR01_DVO_BYPASS_ENABLE (1 << 1)
60/** Enables the DVO clock */
61# define VR01_DVO_ENABLE (1 << 0)
62
63/*
64 * LCD Interface Format
65 */
66#define VR10 0x10
67/** Enables LVDS output instead of CMOS */
68# define VR10_LVDS_ENABLE (1 << 4)
69/** Enables 18-bit LVDS output. */
70# define VR10_INTERFACE_1X18 (0 << 2)
71/** Enables 24-bit LVDS or CMOS output */
72# define VR10_INTERFACE_1X24 (1 << 2)
73/** Enables 2x18-bit LVDS or CMOS output. */
74# define VR10_INTERFACE_2X18 (2 << 2)
75/** Enables 2x24-bit LVDS output */
76# define VR10_INTERFACE_2X24 (3 << 2)
77
78/*
79 * VR20 LCD Horizontal Display Size
80 */
81#define VR20 0x20
82
83/*
84 * LCD Vertical Display Size
85 */
86#define VR21 0x20
87
88/*
89 * Panel power down status
90 */
91#define VR30 0x30
92/** Read only bit indicating that the panel is not in a safe poweroff state. */
93# define VR30_PANEL_ON (1 << 15)
94
95#define VR40 0x40
96# define VR40_STALL_ENABLE (1 << 13)
97# define VR40_VERTICAL_INTERP_ENABLE (1 << 12)
98# define VR40_ENHANCED_PANEL_FITTING (1 << 11)
99# define VR40_HORIZONTAL_INTERP_ENABLE (1 << 10)
100# define VR40_AUTO_RATIO_ENABLE (1 << 9)
101# define VR40_CLOCK_GATING_ENABLE (1 << 8)
102
103/*
104 * Panel Fitting Vertical Ratio
105 * (((image_height - 1) << 16) / ((panel_height - 1))) >> 2
106 */
107#define VR41 0x41
108
109/*
110 * Panel Fitting Horizontal Ratio
111 * (((image_width - 1) << 16) / ((panel_width - 1))) >> 2
112 */
113#define VR42 0x42
114
115/*
116 * Horizontal Image Size
117 */
118#define VR43 0x43
119
120/* VR80 GPIO 0
121 */
122#define VR80 0x80
123#define VR81 0x81
124#define VR82 0x82
125#define VR83 0x83
126#define VR84 0x84
127#define VR85 0x85
128#define VR86 0x86
129#define VR87 0x87
130
131/* VR88 GPIO 8
132 */
133#define VR88 0x88
134
135/* Graphics BIOS scratch 0
136 */
137#define VR8E 0x8E
138# define VR8E_PANEL_TYPE_MASK (0xf << 0)
139# define VR8E_PANEL_INTERFACE_CMOS (0 << 4)
140# define VR8E_PANEL_INTERFACE_LVDS (1 << 4)
141# define VR8E_FORCE_DEFAULT_PANEL (1 << 5)
142
143/* Graphics BIOS scratch 1
144 */
145#define VR8F 0x8F
146# define VR8F_VCH_PRESENT (1 << 0)
147# define VR8F_DISPLAY_CONN (1 << 1)
148# define VR8F_POWER_MASK (0x3c)
149# define VR8F_POWER_POS (2)
150
151
152struct ivch_priv {
153 bool quiet;
154
155 uint16_t width, height;
156
157 uint16_t save_VR01;
158 uint16_t save_VR40;
159};
160
161
162static void ivch_dump_regs(struct intel_dvo_device *dvo);
163
164/**
165 * Reads a register on the ivch.
166 *
167 * Each of the 256 registers are 16 bits long.
168 */
169static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data)
170{
171 struct ivch_priv *priv = dvo->dev_priv;
172 struct intel_i2c_chan *i2cbus = dvo->i2c_bus;
173 u8 out_buf[1];
174 u8 in_buf[2];
175
176 struct i2c_msg msgs[] = {
177 {
178 .addr = i2cbus->slave_addr,
179 .flags = I2C_M_RD,
180 .len = 0,
181 },
182 {
183 .addr = 0,
184 .flags = I2C_M_NOSTART,
185 .len = 1,
186 .buf = out_buf,
187 },
188 {
189 .addr = i2cbus->slave_addr,
190 .flags = I2C_M_RD | I2C_M_NOSTART,
191 .len = 2,
192 .buf = in_buf,
193 }
194 };
195
196 out_buf[0] = addr;
197
198 if (i2c_transfer(&i2cbus->adapter, msgs, 3) == 3) {
199 *data = (in_buf[1] << 8) | in_buf[0];
200 return true;
201 };
202
203 if (!priv->quiet) {
204 DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n",
205 addr, i2cbus->adapter.name, i2cbus->slave_addr);
206 }
207 return false;
208}
209
210/** Writes a 16-bit register on the ivch */
211static bool ivch_write(struct intel_dvo_device *dvo, int addr, uint16_t data)
212{
213 struct ivch_priv *priv = dvo->dev_priv;
214 struct intel_i2c_chan *i2cbus = dvo->i2c_bus;
215 u8 out_buf[3];
216 struct i2c_msg msg = {
217 .addr = i2cbus->slave_addr,
218 .flags = 0,
219 .len = 3,
220 .buf = out_buf,
221 };
222
223 out_buf[0] = addr;
224 out_buf[1] = data & 0xff;
225 out_buf[2] = data >> 8;
226
227 if (i2c_transfer(&i2cbus->adapter, &msg, 1) == 1)
228 return true;
229
230 if (!priv->quiet) {
231 DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n",
232 addr, i2cbus->adapter.name, i2cbus->slave_addr);
233 }
234
235 return false;
236}
237
238/** Probes the given bus and slave address for an ivch */
239static bool ivch_init(struct intel_dvo_device *dvo,
240 struct intel_i2c_chan *i2cbus)
241{
242 struct ivch_priv *priv;
243 uint16_t temp;
244
245 priv = kzalloc(sizeof(struct ivch_priv), GFP_KERNEL);
246 if (priv == NULL)
247 return false;
248
249 dvo->i2c_bus = i2cbus;
250 dvo->i2c_bus->slave_addr = dvo->slave_addr;
251 dvo->dev_priv = priv;
252 priv->quiet = true;
253
254 if (!ivch_read(dvo, VR00, &temp))
255 goto out;
256 priv->quiet = false;
257
258 /* Since the identification bits are probably zeroes, which doesn't seem
259 * very unique, check that the value in the base address field matches
260 * the address it's responding on.
261 */
262 if ((temp & VR00_BASE_ADDRESS_MASK) != dvo->slave_addr) {
263 DRM_DEBUG("ivch detect failed due to address mismatch "
264 "(%d vs %d)\n",
265 (temp & VR00_BASE_ADDRESS_MASK), dvo->slave_addr);
266 goto out;
267 }
268
269 ivch_read(dvo, VR20, &priv->width);
270 ivch_read(dvo, VR21, &priv->height);
271
272 return true;
273
274out:
275 kfree(priv);
276 return false;
277}
278
279static enum drm_connector_status ivch_detect(struct intel_dvo_device *dvo)
280{
281 return connector_status_connected;
282}
283
284static enum drm_mode_status ivch_mode_valid(struct intel_dvo_device *dvo,
285 struct drm_display_mode *mode)
286{
287 if (mode->clock > 112000)
288 return MODE_CLOCK_HIGH;
289
290 return MODE_OK;
291}
292
293/** Sets the power state of the panel connected to the ivch */
294static void ivch_dpms(struct intel_dvo_device *dvo, int mode)
295{
296 int i;
297 uint16_t vr01, vr30, backlight;
298
299 /* Set the new power state of the panel. */
300 if (!ivch_read(dvo, VR01, &vr01))
301 return;
302
303 if (mode == DRM_MODE_DPMS_ON)
304 backlight = 1;
305 else
306 backlight = 0;
307 ivch_write(dvo, VR80, backlight);
308
309 if (mode == DRM_MODE_DPMS_ON)
310 vr01 |= VR01_LCD_ENABLE | VR01_DVO_ENABLE;
311 else
312 vr01 &= ~(VR01_LCD_ENABLE | VR01_DVO_ENABLE);
313
314 ivch_write(dvo, VR01, vr01);
315
316 /* Wait for the panel to make its state transition */
317 for (i = 0; i < 100; i++) {
318 if (!ivch_read(dvo, VR30, &vr30))
319 break;
320
321 if (((vr30 & VR30_PANEL_ON) != 0) == (mode == DRM_MODE_DPMS_ON))
322 break;
323 udelay(1000);
324 }
325 /* wait some more; vch may fail to resync sometimes without this */
326 udelay(16 * 1000);
327}
328
329static void ivch_mode_set(struct intel_dvo_device *dvo,
330 struct drm_display_mode *mode,
331 struct drm_display_mode *adjusted_mode)
332{
333 uint16_t vr40 = 0;
334 uint16_t vr01;
335
336 vr01 = 0;
337 vr40 = (VR40_STALL_ENABLE | VR40_VERTICAL_INTERP_ENABLE |
338 VR40_HORIZONTAL_INTERP_ENABLE);
339
340 if (mode->hdisplay != adjusted_mode->hdisplay ||
341 mode->vdisplay != adjusted_mode->vdisplay) {
342 uint16_t x_ratio, y_ratio;
343
344 vr01 |= VR01_PANEL_FIT_ENABLE;
345 vr40 |= VR40_CLOCK_GATING_ENABLE;
346 x_ratio = (((mode->hdisplay - 1) << 16) /
347 (adjusted_mode->hdisplay - 1)) >> 2;
348 y_ratio = (((mode->vdisplay - 1) << 16) /
349 (adjusted_mode->vdisplay - 1)) >> 2;
350 ivch_write (dvo, VR42, x_ratio);
351 ivch_write (dvo, VR41, y_ratio);
352 } else {
353 vr01 &= ~VR01_PANEL_FIT_ENABLE;
354 vr40 &= ~VR40_CLOCK_GATING_ENABLE;
355 }
356 vr40 &= ~VR40_AUTO_RATIO_ENABLE;
357
358 ivch_write(dvo, VR01, vr01);
359 ivch_write(dvo, VR40, vr40);
360
361 ivch_dump_regs(dvo);
362}
363
364static void ivch_dump_regs(struct intel_dvo_device *dvo)
365{
366 uint16_t val;
367
368 ivch_read(dvo, VR00, &val);
369 DRM_DEBUG("VR00: 0x%04x\n", val);
370 ivch_read(dvo, VR01, &val);
371 DRM_DEBUG("VR01: 0x%04x\n", val);
372 ivch_read(dvo, VR30, &val);
373 DRM_DEBUG("VR30: 0x%04x\n", val);
374 ivch_read(dvo, VR40, &val);
375 DRM_DEBUG("VR40: 0x%04x\n", val);
376
377 /* GPIO registers */
378 ivch_read(dvo, VR80, &val);
379 DRM_DEBUG("VR80: 0x%04x\n", val);
380 ivch_read(dvo, VR81, &val);
381 DRM_DEBUG("VR81: 0x%04x\n", val);
382 ivch_read(dvo, VR82, &val);
383 DRM_DEBUG("VR82: 0x%04x\n", val);
384 ivch_read(dvo, VR83, &val);
385 DRM_DEBUG("VR83: 0x%04x\n", val);
386 ivch_read(dvo, VR84, &val);
387 DRM_DEBUG("VR84: 0x%04x\n", val);
388 ivch_read(dvo, VR85, &val);
389 DRM_DEBUG("VR85: 0x%04x\n", val);
390 ivch_read(dvo, VR86, &val);
391 DRM_DEBUG("VR86: 0x%04x\n", val);
392 ivch_read(dvo, VR87, &val);
393 DRM_DEBUG("VR87: 0x%04x\n", val);
394 ivch_read(dvo, VR88, &val);
395 DRM_DEBUG("VR88: 0x%04x\n", val);
396
397 /* Scratch register 0 - AIM Panel type */
398 ivch_read(dvo, VR8E, &val);
399 DRM_DEBUG("VR8E: 0x%04x\n", val);
400
401 /* Scratch register 1 - Status register */
402 ivch_read(dvo, VR8F, &val);
403 DRM_DEBUG("VR8F: 0x%04x\n", val);
404}
405
406static void ivch_save(struct intel_dvo_device *dvo)
407{
408 struct ivch_priv *priv = dvo->dev_priv;
409
410 ivch_read(dvo, VR01, &priv->save_VR01);
411 ivch_read(dvo, VR40, &priv->save_VR40);
412}
413
414static void ivch_restore(struct intel_dvo_device *dvo)
415{
416 struct ivch_priv *priv = dvo->dev_priv;
417
418 ivch_write(dvo, VR01, priv->save_VR01);
419 ivch_write(dvo, VR40, priv->save_VR40);
420}
421
422static void ivch_destroy(struct intel_dvo_device *dvo)
423{
424 struct ivch_priv *priv = dvo->dev_priv;
425
426 if (priv) {
427 kfree(priv);
428 dvo->dev_priv = NULL;
429 }
430}
431
432struct intel_dvo_dev_ops ivch_ops= {
433 .init = ivch_init,
434 .dpms = ivch_dpms,
435 .save = ivch_save,
436 .restore = ivch_restore,
437 .mode_valid = ivch_mode_valid,
438 .mode_set = ivch_mode_set,
439 .detect = ivch_detect,
440 .dump_regs = ivch_dump_regs,
441 .destroy = ivch_destroy,
442};
diff --git a/drivers/gpu/drm/i915/dvo_sil164.c b/drivers/gpu/drm/i915/dvo_sil164.c
new file mode 100644
index 000000000000..033a4bb070b2
--- /dev/null
+++ b/drivers/gpu/drm/i915/dvo_sil164.c
@@ -0,0 +1,302 @@
1/**************************************************************************
2
3Copyright © 2006 Dave Airlie
4
5All Rights Reserved.
6
7Permission is hereby granted, free of charge, to any person obtaining a
8copy of this software and associated documentation files (the
9"Software"), to deal in the Software without restriction, including
10without limitation the rights to use, copy, modify, merge, publish,
11distribute, sub license, and/or sell copies of the Software, and to
12permit persons to whom the Software is furnished to do so, subject to
13the following conditions:
14
15The above copyright notice and this permission notice (including the
16next paragraph) shall be included in all copies or substantial portions
17of the Software.
18
19THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
23ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
27**************************************************************************/
28
29#include "dvo.h"
30
31#define SIL164_VID 0x0001
32#define SIL164_DID 0x0006
33
34#define SIL164_VID_LO 0x00
35#define SIL164_VID_HI 0x01
36#define SIL164_DID_LO 0x02
37#define SIL164_DID_HI 0x03
38#define SIL164_REV 0x04
39#define SIL164_RSVD 0x05
40#define SIL164_FREQ_LO 0x06
41#define SIL164_FREQ_HI 0x07
42
43#define SIL164_REG8 0x08
44#define SIL164_8_VEN (1<<5)
45#define SIL164_8_HEN (1<<4)
46#define SIL164_8_DSEL (1<<3)
47#define SIL164_8_BSEL (1<<2)
48#define SIL164_8_EDGE (1<<1)
49#define SIL164_8_PD (1<<0)
50
51#define SIL164_REG9 0x09
52#define SIL164_9_VLOW (1<<7)
53#define SIL164_9_MSEL_MASK (0x7<<4)
54#define SIL164_9_TSEL (1<<3)
55#define SIL164_9_RSEN (1<<2)
56#define SIL164_9_HTPLG (1<<1)
57#define SIL164_9_MDI (1<<0)
58
59#define SIL164_REGC 0x0c
60
61struct sil164_save_rec {
62 uint8_t reg8;
63 uint8_t reg9;
64 uint8_t regc;
65};
66
67struct sil164_priv {
68 //I2CDevRec d;
69 bool quiet;
70 struct sil164_save_rec save_regs;
71 struct sil164_save_rec mode_regs;
72};
73
74#define SILPTR(d) ((SIL164Ptr)(d->DriverPrivate.ptr))
75
76static bool sil164_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
77{
78 struct sil164_priv *sil = dvo->dev_priv;
79 struct intel_i2c_chan *i2cbus = dvo->i2c_bus;
80 u8 out_buf[2];
81 u8 in_buf[2];
82
83 struct i2c_msg msgs[] = {
84 {
85 .addr = i2cbus->slave_addr,
86 .flags = 0,
87 .len = 1,
88 .buf = out_buf,
89 },
90 {
91 .addr = i2cbus->slave_addr,
92 .flags = I2C_M_RD,
93 .len = 1,
94 .buf = in_buf,
95 }
96 };
97
98 out_buf[0] = addr;
99 out_buf[1] = 0;
100
101 if (i2c_transfer(&i2cbus->adapter, msgs, 2) == 2) {
102 *ch = in_buf[0];
103 return true;
104 };
105
106 if (!sil->quiet) {
107 DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n",
108 addr, i2cbus->adapter.name, i2cbus->slave_addr);
109 }
110 return false;
111}
112
113static bool sil164_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch)
114{
115 struct sil164_priv *sil= dvo->dev_priv;
116 struct intel_i2c_chan *i2cbus = dvo->i2c_bus;
117 uint8_t out_buf[2];
118 struct i2c_msg msg = {
119 .addr = i2cbus->slave_addr,
120 .flags = 0,
121 .len = 2,
122 .buf = out_buf,
123 };
124
125 out_buf[0] = addr;
126 out_buf[1] = ch;
127
128 if (i2c_transfer(&i2cbus->adapter, &msg, 1) == 1)
129 return true;
130
131 if (!sil->quiet) {
132 DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n",
133 addr, i2cbus->adapter.name, i2cbus->slave_addr);
134 }
135
136 return false;
137}
138
139/* Silicon Image 164 driver for chip on i2c bus */
140static bool sil164_init(struct intel_dvo_device *dvo,
141 struct intel_i2c_chan *i2cbus)
142{
143 /* this will detect the SIL164 chip on the specified i2c bus */
144 struct sil164_priv *sil;
145 unsigned char ch;
146
147 sil = kzalloc(sizeof(struct sil164_priv), GFP_KERNEL);
148 if (sil == NULL)
149 return false;
150
151 dvo->i2c_bus = i2cbus;
152 dvo->i2c_bus->slave_addr = dvo->slave_addr;
153 dvo->dev_priv = sil;
154 sil->quiet = true;
155
156 if (!sil164_readb(dvo, SIL164_VID_LO, &ch))
157 goto out;
158
159 if (ch != (SIL164_VID & 0xff)) {
160 DRM_DEBUG("sil164 not detected got %d: from %s Slave %d.\n",
161 ch, i2cbus->adapter.name, i2cbus->slave_addr);
162 goto out;
163 }
164
165 if (!sil164_readb(dvo, SIL164_DID_LO, &ch))
166 goto out;
167
168 if (ch != (SIL164_DID & 0xff)) {
169 DRM_DEBUG("sil164 not detected got %d: from %s Slave %d.\n",
170 ch, i2cbus->adapter.name, i2cbus->slave_addr);
171 goto out;
172 }
173 sil->quiet = false;
174
175 DRM_DEBUG("init sil164 dvo controller successfully!\n");
176 return true;
177
178out:
179 kfree(sil);
180 return false;
181}
182
183static enum drm_connector_status sil164_detect(struct intel_dvo_device *dvo)
184{
185 uint8_t reg9;
186
187 sil164_readb(dvo, SIL164_REG9, &reg9);
188
189 if (reg9 & SIL164_9_HTPLG)
190 return connector_status_connected;
191 else
192 return connector_status_disconnected;
193}
194
195static enum drm_mode_status sil164_mode_valid(struct intel_dvo_device *dvo,
196 struct drm_display_mode *mode)
197{
198 return MODE_OK;
199}
200
201static void sil164_mode_set(struct intel_dvo_device *dvo,
202 struct drm_display_mode *mode,
203 struct drm_display_mode *adjusted_mode)
204{
205 /* As long as the basics are set up, since we don't have clock
206 * dependencies in the mode setup, we can just leave the
207 * registers alone and everything will work fine.
208 */
209 /* recommended programming sequence from doc */
210 /*sil164_writeb(sil, 0x08, 0x30);
211 sil164_writeb(sil, 0x09, 0x00);
212 sil164_writeb(sil, 0x0a, 0x90);
213 sil164_writeb(sil, 0x0c, 0x89);
214 sil164_writeb(sil, 0x08, 0x31);*/
215 /* don't do much */
216 return;
217}
218
219/* set the SIL164 power state */
220static void sil164_dpms(struct intel_dvo_device *dvo, int mode)
221{
222 int ret;
223 unsigned char ch;
224
225 ret = sil164_readb(dvo, SIL164_REG8, &ch);
226 if (ret == false)
227 return;
228
229 if (mode == DRM_MODE_DPMS_ON)
230 ch |= SIL164_8_PD;
231 else
232 ch &= ~SIL164_8_PD;
233
234 sil164_writeb(dvo, SIL164_REG8, ch);
235 return;
236}
237
238static void sil164_dump_regs(struct intel_dvo_device *dvo)
239{
240 uint8_t val;
241
242 sil164_readb(dvo, SIL164_FREQ_LO, &val);
243 DRM_DEBUG("SIL164_FREQ_LO: 0x%02x\n", val);
244 sil164_readb(dvo, SIL164_FREQ_HI, &val);
245 DRM_DEBUG("SIL164_FREQ_HI: 0x%02x\n", val);
246 sil164_readb(dvo, SIL164_REG8, &val);
247 DRM_DEBUG("SIL164_REG8: 0x%02x\n", val);
248 sil164_readb(dvo, SIL164_REG9, &val);
249 DRM_DEBUG("SIL164_REG9: 0x%02x\n", val);
250 sil164_readb(dvo, SIL164_REGC, &val);
251 DRM_DEBUG("SIL164_REGC: 0x%02x\n", val);
252}
253
254static void sil164_save(struct intel_dvo_device *dvo)
255{
256 struct sil164_priv *sil= dvo->dev_priv;
257
258 if (!sil164_readb(dvo, SIL164_REG8, &sil->save_regs.reg8))
259 return;
260
261 if (!sil164_readb(dvo, SIL164_REG9, &sil->save_regs.reg9))
262 return;
263
264 if (!sil164_readb(dvo, SIL164_REGC, &sil->save_regs.regc))
265 return;
266
267 return;
268}
269
270static void sil164_restore(struct intel_dvo_device *dvo)
271{
272 struct sil164_priv *sil = dvo->dev_priv;
273
274 /* Restore it powered down initially */
275 sil164_writeb(dvo, SIL164_REG8, sil->save_regs.reg8 & ~0x1);
276
277 sil164_writeb(dvo, SIL164_REG9, sil->save_regs.reg9);
278 sil164_writeb(dvo, SIL164_REGC, sil->save_regs.regc);
279 sil164_writeb(dvo, SIL164_REG8, sil->save_regs.reg8);
280}
281
282static void sil164_destroy(struct intel_dvo_device *dvo)
283{
284 struct sil164_priv *sil = dvo->dev_priv;
285
286 if (sil) {
287 kfree(sil);
288 dvo->dev_priv = NULL;
289 }
290}
291
292struct intel_dvo_dev_ops sil164_ops = {
293 .init = sil164_init,
294 .detect = sil164_detect,
295 .mode_valid = sil164_mode_valid,
296 .mode_set = sil164_mode_set,
297 .dpms = sil164_dpms,
298 .dump_regs = sil164_dump_regs,
299 .save = sil164_save,
300 .restore = sil164_restore,
301 .destroy = sil164_destroy,
302};
diff --git a/drivers/gpu/drm/i915/dvo_tfp410.c b/drivers/gpu/drm/i915/dvo_tfp410.c
new file mode 100644
index 000000000000..207fda806ebf
--- /dev/null
+++ b/drivers/gpu/drm/i915/dvo_tfp410.c
@@ -0,0 +1,335 @@
1/*
2 * Copyright © 2007 Dave Mueller
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 * Dave Mueller <dave.mueller@gmx.ch>
25 *
26 */
27
28#include "dvo.h"
29
30/* register definitions according to the TFP410 data sheet */
31#define TFP410_VID 0x014C
32#define TFP410_DID 0x0410
33
34#define TFP410_VID_LO 0x00
35#define TFP410_VID_HI 0x01
36#define TFP410_DID_LO 0x02
37#define TFP410_DID_HI 0x03
38#define TFP410_REV 0x04
39
40#define TFP410_CTL_1 0x08
41#define TFP410_CTL_1_TDIS (1<<6)
42#define TFP410_CTL_1_VEN (1<<5)
43#define TFP410_CTL_1_HEN (1<<4)
44#define TFP410_CTL_1_DSEL (1<<3)
45#define TFP410_CTL_1_BSEL (1<<2)
46#define TFP410_CTL_1_EDGE (1<<1)
47#define TFP410_CTL_1_PD (1<<0)
48
49#define TFP410_CTL_2 0x09
50#define TFP410_CTL_2_VLOW (1<<7)
51#define TFP410_CTL_2_MSEL_MASK (0x7<<4)
52#define TFP410_CTL_2_MSEL (1<<4)
53#define TFP410_CTL_2_TSEL (1<<3)
54#define TFP410_CTL_2_RSEN (1<<2)
55#define TFP410_CTL_2_HTPLG (1<<1)
56#define TFP410_CTL_2_MDI (1<<0)
57
58#define TFP410_CTL_3 0x0A
59#define TFP410_CTL_3_DK_MASK (0x7<<5)
60#define TFP410_CTL_3_DK (1<<5)
61#define TFP410_CTL_3_DKEN (1<<4)
62#define TFP410_CTL_3_CTL_MASK (0x7<<1)
63#define TFP410_CTL_3_CTL (1<<1)
64
65#define TFP410_USERCFG 0x0B
66
67#define TFP410_DE_DLY 0x32
68
69#define TFP410_DE_CTL 0x33
70#define TFP410_DE_CTL_DEGEN (1<<6)
71#define TFP410_DE_CTL_VSPOL (1<<5)
72#define TFP410_DE_CTL_HSPOL (1<<4)
73#define TFP410_DE_CTL_DEDLY8 (1<<0)
74
75#define TFP410_DE_TOP 0x34
76
77#define TFP410_DE_CNT_LO 0x36
78#define TFP410_DE_CNT_HI 0x37
79
80#define TFP410_DE_LIN_LO 0x38
81#define TFP410_DE_LIN_HI 0x39
82
83#define TFP410_H_RES_LO 0x3A
84#define TFP410_H_RES_HI 0x3B
85
86#define TFP410_V_RES_LO 0x3C
87#define TFP410_V_RES_HI 0x3D
88
89struct tfp410_save_rec {
90 uint8_t ctl1;
91 uint8_t ctl2;
92};
93
94struct tfp410_priv {
95 bool quiet;
96
97 struct tfp410_save_rec saved_reg;
98 struct tfp410_save_rec mode_reg;
99};
100
101static bool tfp410_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch)
102{
103 struct tfp410_priv *tfp = dvo->dev_priv;
104 struct intel_i2c_chan *i2cbus = dvo->i2c_bus;
105 u8 out_buf[2];
106 u8 in_buf[2];
107
108 struct i2c_msg msgs[] = {
109 {
110 .addr = i2cbus->slave_addr,
111 .flags = 0,
112 .len = 1,
113 .buf = out_buf,
114 },
115 {
116 .addr = i2cbus->slave_addr,
117 .flags = I2C_M_RD,
118 .len = 1,
119 .buf = in_buf,
120 }
121 };
122
123 out_buf[0] = addr;
124 out_buf[1] = 0;
125
126 if (i2c_transfer(&i2cbus->adapter, msgs, 2) == 2) {
127 *ch = in_buf[0];
128 return true;
129 };
130
131 if (!tfp->quiet) {
132 DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n",
133 addr, i2cbus->adapter.name, i2cbus->slave_addr);
134 }
135 return false;
136}
137
138static bool tfp410_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch)
139{
140 struct tfp410_priv *tfp = dvo->dev_priv;
141 struct intel_i2c_chan *i2cbus = dvo->i2c_bus;
142 uint8_t out_buf[2];
143 struct i2c_msg msg = {
144 .addr = i2cbus->slave_addr,
145 .flags = 0,
146 .len = 2,
147 .buf = out_buf,
148 };
149
150 out_buf[0] = addr;
151 out_buf[1] = ch;
152
153 if (i2c_transfer(&i2cbus->adapter, &msg, 1) == 1)
154 return true;
155
156 if (!tfp->quiet) {
157 DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n",
158 addr, i2cbus->adapter.name, i2cbus->slave_addr);
159 }
160
161 return false;
162}
163
164static int tfp410_getid(struct intel_dvo_device *dvo, int addr)
165{
166 uint8_t ch1, ch2;
167
168 if (tfp410_readb(dvo, addr+0, &ch1) &&
169 tfp410_readb(dvo, addr+1, &ch2))
170 return ((ch2 << 8) & 0xFF00) | (ch1 & 0x00FF);
171
172 return -1;
173}
174
175/* Ti TFP410 driver for chip on i2c bus */
176static bool tfp410_init(struct intel_dvo_device *dvo,
177 struct intel_i2c_chan *i2cbus)
178{
179 /* this will detect the tfp410 chip on the specified i2c bus */
180 struct tfp410_priv *tfp;
181 int id;
182
183 tfp = kzalloc(sizeof(struct tfp410_priv), GFP_KERNEL);
184 if (tfp == NULL)
185 return false;
186
187 dvo->i2c_bus = i2cbus;
188 dvo->i2c_bus->slave_addr = dvo->slave_addr;
189 dvo->dev_priv = tfp;
190 tfp->quiet = true;
191
192 if ((id = tfp410_getid(dvo, TFP410_VID_LO)) != TFP410_VID) {
193 DRM_DEBUG("tfp410 not detected got VID %X: from %s Slave %d.\n",
194 id, i2cbus->adapter.name, i2cbus->slave_addr);
195 goto out;
196 }
197
198 if ((id = tfp410_getid(dvo, TFP410_DID_LO)) != TFP410_DID) {
199 DRM_DEBUG("tfp410 not detected got DID %X: from %s Slave %d.\n",
200 id, i2cbus->adapter.name, i2cbus->slave_addr);
201 goto out;
202 }
203 tfp->quiet = false;
204 return true;
205out:
206 kfree(tfp);
207 return false;
208}
209
210static enum drm_connector_status tfp410_detect(struct intel_dvo_device *dvo)
211{
212 enum drm_connector_status ret = connector_status_disconnected;
213 uint8_t ctl2;
214
215 if (tfp410_readb(dvo, TFP410_CTL_2, &ctl2)) {
216 if (ctl2 & TFP410_CTL_2_HTPLG)
217 ret = connector_status_connected;
218 else
219 ret = connector_status_disconnected;
220 }
221
222 return ret;
223}
224
225static enum drm_mode_status tfp410_mode_valid(struct intel_dvo_device *dvo,
226 struct drm_display_mode *mode)
227{
228 return MODE_OK;
229}
230
231static void tfp410_mode_set(struct intel_dvo_device *dvo,
232 struct drm_display_mode *mode,
233 struct drm_display_mode *adjusted_mode)
234{
235 /* As long as the basics are set up, since we don't have clock dependencies
236 * in the mode setup, we can just leave the registers alone and everything
237 * will work fine.
238 */
239 /* don't do much */
240 return;
241}
242
243/* set the tfp410 power state */
244static void tfp410_dpms(struct intel_dvo_device *dvo, int mode)
245{
246 uint8_t ctl1;
247
248 if (!tfp410_readb(dvo, TFP410_CTL_1, &ctl1))
249 return;
250
251 if (mode == DRM_MODE_DPMS_ON)
252 ctl1 |= TFP410_CTL_1_PD;
253 else
254 ctl1 &= ~TFP410_CTL_1_PD;
255
256 tfp410_writeb(dvo, TFP410_CTL_1, ctl1);
257}
258
259static void tfp410_dump_regs(struct intel_dvo_device *dvo)
260{
261 uint8_t val, val2;
262
263 tfp410_readb(dvo, TFP410_REV, &val);
264 DRM_DEBUG("TFP410_REV: 0x%02X\n", val);
265 tfp410_readb(dvo, TFP410_CTL_1, &val);
266 DRM_DEBUG("TFP410_CTL1: 0x%02X\n", val);
267 tfp410_readb(dvo, TFP410_CTL_2, &val);
268 DRM_DEBUG("TFP410_CTL2: 0x%02X\n", val);
269 tfp410_readb(dvo, TFP410_CTL_3, &val);
270 DRM_DEBUG("TFP410_CTL3: 0x%02X\n", val);
271 tfp410_readb(dvo, TFP410_USERCFG, &val);
272 DRM_DEBUG("TFP410_USERCFG: 0x%02X\n", val);
273 tfp410_readb(dvo, TFP410_DE_DLY, &val);
274 DRM_DEBUG("TFP410_DE_DLY: 0x%02X\n", val);
275 tfp410_readb(dvo, TFP410_DE_CTL, &val);
276 DRM_DEBUG("TFP410_DE_CTL: 0x%02X\n", val);
277 tfp410_readb(dvo, TFP410_DE_TOP, &val);
278 DRM_DEBUG("TFP410_DE_TOP: 0x%02X\n", val);
279 tfp410_readb(dvo, TFP410_DE_CNT_LO, &val);
280 tfp410_readb(dvo, TFP410_DE_CNT_HI, &val2);
281 DRM_DEBUG("TFP410_DE_CNT: 0x%02X%02X\n", val2, val);
282 tfp410_readb(dvo, TFP410_DE_LIN_LO, &val);
283 tfp410_readb(dvo, TFP410_DE_LIN_HI, &val2);
284 DRM_DEBUG("TFP410_DE_LIN: 0x%02X%02X\n", val2, val);
285 tfp410_readb(dvo, TFP410_H_RES_LO, &val);
286 tfp410_readb(dvo, TFP410_H_RES_HI, &val2);
287 DRM_DEBUG("TFP410_H_RES: 0x%02X%02X\n", val2, val);
288 tfp410_readb(dvo, TFP410_V_RES_LO, &val);
289 tfp410_readb(dvo, TFP410_V_RES_HI, &val2);
290 DRM_DEBUG("TFP410_V_RES: 0x%02X%02X\n", val2, val);
291}
292
293static void tfp410_save(struct intel_dvo_device *dvo)
294{
295 struct tfp410_priv *tfp = dvo->dev_priv;
296
297 if (!tfp410_readb(dvo, TFP410_CTL_1, &tfp->saved_reg.ctl1))
298 return;
299
300 if (!tfp410_readb(dvo, TFP410_CTL_2, &tfp->saved_reg.ctl2))
301 return;
302}
303
304static void tfp410_restore(struct intel_dvo_device *dvo)
305{
306 struct tfp410_priv *tfp = dvo->dev_priv;
307
308 /* Restore it powered down initially */
309 tfp410_writeb(dvo, TFP410_CTL_1, tfp->saved_reg.ctl1 & ~0x1);
310
311 tfp410_writeb(dvo, TFP410_CTL_2, tfp->saved_reg.ctl2);
312 tfp410_writeb(dvo, TFP410_CTL_1, tfp->saved_reg.ctl1);
313}
314
315static void tfp410_destroy(struct intel_dvo_device *dvo)
316{
317 struct tfp410_priv *tfp = dvo->dev_priv;
318
319 if (tfp) {
320 kfree(tfp);
321 dvo->dev_priv = NULL;
322 }
323}
324
325struct intel_dvo_dev_ops tfp410_ops = {
326 .init = tfp410_init,
327 .detect = tfp410_detect,
328 .mode_valid = tfp410_mode_valid,
329 .mode_set = tfp410_mode_set,
330 .dpms = tfp410_dpms,
331 .dump_regs = tfp410_dump_regs,
332 .save = tfp410_save,
333 .restore = tfp410_restore,
334 .destroy = tfp410_destroy,
335};
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 1b81b6a6d81b..b5d0809eecb1 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -28,6 +28,8 @@
28 28
29#include "drmP.h" 29#include "drmP.h"
30#include "drm.h" 30#include "drm.h"
31#include "drm_crtc_helper.h"
32#include "intel_drv.h"
31#include "i915_drm.h" 33#include "i915_drm.h"
32#include "i915_drv.h" 34#include "i915_drv.h"
33 35
@@ -125,6 +127,13 @@ void i915_kernel_lost_context(struct drm_device * dev)
125 struct drm_i915_master_private *master_priv; 127 struct drm_i915_master_private *master_priv;
126 drm_i915_ring_buffer_t *ring = &(dev_priv->ring); 128 drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
127 129
130 /*
131 * We should never lose context on the ring with modesetting
132 * as we don't expose it to userspace
133 */
134 if (drm_core_check_feature(dev, DRIVER_MODESET))
135 return;
136
128 ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR; 137 ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
129 ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; 138 ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR;
130 ring->space = ring->head - (ring->tail + 8); 139 ring->space = ring->head - (ring->tail + 8);
@@ -769,6 +778,11 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
769 return -EINVAL; 778 return -EINVAL;
770 } 779 }
771 780
781 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
782 WARN(1, "tried to set status page when mode setting active\n");
783 return 0;
784 }
785
772 printk(KERN_DEBUG "set status page addr 0x%08x\n", (u32)hws->addr); 786 printk(KERN_DEBUG "set status page addr 0x%08x\n", (u32)hws->addr);
773 787
774 dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12); 788 dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12);
@@ -797,6 +811,173 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
797 return 0; 811 return 0;
798} 812}
799 813
814/**
815 * i915_probe_agp - get AGP bootup configuration
816 * @pdev: PCI device
817 * @aperture_size: returns AGP aperture configured size
818 * @preallocated_size: returns size of BIOS preallocated AGP space
819 *
820 * Since Intel integrated graphics are UMA, the BIOS has to set aside
821 * some RAM for the framebuffer at early boot. This code figures out
822 * how much was set aside so we can use it for our own purposes.
823 */
824int i915_probe_agp(struct pci_dev *pdev, unsigned long *aperture_size,
825 unsigned long *preallocated_size)
826{
827 struct pci_dev *bridge_dev;
828 u16 tmp = 0;
829 unsigned long overhead;
830
831 bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
832 if (!bridge_dev) {
833 DRM_ERROR("bridge device not found\n");
834 return -1;
835 }
836
837 /* Get the fb aperture size and "stolen" memory amount. */
838 pci_read_config_word(bridge_dev, INTEL_GMCH_CTRL, &tmp);
839 pci_dev_put(bridge_dev);
840
841 *aperture_size = 1024 * 1024;
842 *preallocated_size = 1024 * 1024;
843
844 switch (pdev->device) {
845 case PCI_DEVICE_ID_INTEL_82830_CGC:
846 case PCI_DEVICE_ID_INTEL_82845G_IG:
847 case PCI_DEVICE_ID_INTEL_82855GM_IG:
848 case PCI_DEVICE_ID_INTEL_82865_IG:
849 if ((tmp & INTEL_GMCH_MEM_MASK) == INTEL_GMCH_MEM_64M)
850 *aperture_size *= 64;
851 else
852 *aperture_size *= 128;
853 break;
854 default:
855 /* 9xx supports large sizes, just look at the length */
856 *aperture_size = pci_resource_len(pdev, 2);
857 break;
858 }
859
860 /*
861 * Some of the preallocated space is taken by the GTT
862 * and popup. GTT is 1K per MB of aperture size, and popup is 4K.
863 */
864 overhead = (*aperture_size / 1024) + 4096;
865 switch (tmp & INTEL_855_GMCH_GMS_MASK) {
866 case INTEL_855_GMCH_GMS_STOLEN_1M:
867 break; /* 1M already */
868 case INTEL_855_GMCH_GMS_STOLEN_4M:
869 *preallocated_size *= 4;
870 break;
871 case INTEL_855_GMCH_GMS_STOLEN_8M:
872 *preallocated_size *= 8;
873 break;
874 case INTEL_855_GMCH_GMS_STOLEN_16M:
875 *preallocated_size *= 16;
876 break;
877 case INTEL_855_GMCH_GMS_STOLEN_32M:
878 *preallocated_size *= 32;
879 break;
880 case INTEL_915G_GMCH_GMS_STOLEN_48M:
881 *preallocated_size *= 48;
882 break;
883 case INTEL_915G_GMCH_GMS_STOLEN_64M:
884 *preallocated_size *= 64;
885 break;
886 case INTEL_855_GMCH_GMS_DISABLED:
887 DRM_ERROR("video memory is disabled\n");
888 return -1;
889 default:
890 DRM_ERROR("unexpected GMCH_GMS value: 0x%02x\n",
891 tmp & INTEL_855_GMCH_GMS_MASK);
892 return -1;
893 }
894 *preallocated_size -= overhead;
895
896 return 0;
897}
898
899static int i915_load_modeset_init(struct drm_device *dev)
900{
901 struct drm_i915_private *dev_priv = dev->dev_private;
902 unsigned long agp_size, prealloc_size;
903 int fb_bar = IS_I9XX(dev) ? 2 : 0;
904 int ret = 0;
905
906 dev->mode_config.fb_base = drm_get_resource_start(dev, fb_bar) &
907 0xff000000;
908
909 DRM_DEBUG("*** fb base 0x%08lx\n", dev->mode_config.fb_base);
910
911 if (IS_MOBILE(dev) || (IS_I9XX(dev) && !IS_I965G(dev) && !IS_G33(dev)))
912 dev_priv->cursor_needs_physical = true;
913 else
914 dev_priv->cursor_needs_physical = false;
915
916 i915_probe_agp(dev->pdev, &agp_size, &prealloc_size);
917
918 /* Basic memrange allocator for stolen space (aka vram) */
919 drm_mm_init(&dev_priv->vram, 0, prealloc_size);
920
921 /* Let GEM Manage from end of prealloc space to end of aperture */
922 i915_gem_do_init(dev, prealloc_size, agp_size);
923
924 ret = i915_gem_init_ringbuffer(dev);
925 if (ret)
926 goto out;
927
928 dev_priv->mm.gtt_mapping =
929 io_mapping_create_wc(dev->agp->base,
930 dev->agp->agp_info.aper_size * 1024*1024);
931
932 /* Allow hardware batchbuffers unless told otherwise.
933 */
934 dev_priv->allow_batchbuffer = 1;
935
936 ret = intel_init_bios(dev);
937 if (ret)
938 DRM_INFO("failed to find VBIOS tables\n");
939
940 ret = drm_irq_install(dev);
941 if (ret)
942 goto destroy_ringbuffer;
943
944 /* FIXME: re-add hotplug support */
945#if 0
946 ret = drm_hotplug_init(dev);
947 if (ret)
948 goto destroy_ringbuffer;
949#endif
950
951 /* Always safe in the mode setting case. */
952 /* FIXME: do pre/post-mode set stuff in core KMS code */
953 dev->vblank_disable_allowed = 1;
954
955 /*
956 * Initialize the hardware status page IRQ location.
957 */
958
959 I915_WRITE(INSTPM, (1 << 5) | (1 << 21));
960
961 intel_modeset_init(dev);
962
963 drm_helper_initial_config(dev, false);
964
965 dev->devname = kstrdup(DRIVER_NAME, GFP_KERNEL);
966 if (!dev->devname) {
967 ret = -ENOMEM;
968 goto modeset_cleanup;
969 }
970
971 return 0;
972
973modeset_cleanup:
974 intel_modeset_cleanup(dev);
975destroy_ringbuffer:
976 i915_gem_cleanup_ringbuffer(dev);
977out:
978 return ret;
979}
980
800int i915_master_create(struct drm_device *dev, struct drm_master *master) 981int i915_master_create(struct drm_device *dev, struct drm_master *master)
801{ 982{
802 struct drm_i915_master_private *master_priv; 983 struct drm_i915_master_private *master_priv;
@@ -821,6 +1002,25 @@ void i915_master_destroy(struct drm_device *dev, struct drm_master *master)
821 master->driver_priv = NULL; 1002 master->driver_priv = NULL;
822} 1003}
823 1004
1005
1006int i915_driver_firstopen(struct drm_device *dev)
1007{
1008 if (drm_core_check_feature(dev, DRIVER_MODESET))
1009 return 0;
1010 return 0;
1011}
1012
1013/**
1014 * i915_driver_load - setup chip and create an initial config
1015 * @dev: DRM device
1016 * @flags: startup flags
1017 *
1018 * The driver load routine has to do several things:
1019 * - drive output discovery via intel_modeset_init()
1020 * - initialize the memory manager
1021 * - allocate initial config memory
1022 * - setup the DRM framebuffer with the allocated memory
1023 */
824int i915_driver_load(struct drm_device *dev, unsigned long flags) 1024int i915_driver_load(struct drm_device *dev, unsigned long flags)
825{ 1025{
826 struct drm_i915_private *dev_priv = dev->dev_private; 1026 struct drm_i915_private *dev_priv = dev->dev_private;
@@ -848,6 +1048,11 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
848 size = drm_get_resource_len(dev, mmio_bar); 1048 size = drm_get_resource_len(dev, mmio_bar);
849 1049
850 dev_priv->regs = ioremap(base, size); 1050 dev_priv->regs = ioremap(base, size);
1051 if (!dev_priv->regs) {
1052 DRM_ERROR("failed to map registers\n");
1053 ret = -EIO;
1054 goto free_priv;
1055 }
851 1056
852#ifdef CONFIG_HIGHMEM64G 1057#ifdef CONFIG_HIGHMEM64G
853 /* don't enable GEM on PAE - needs agp + set_memory_* interface fixes */ 1058 /* don't enable GEM on PAE - needs agp + set_memory_* interface fixes */
@@ -863,7 +1068,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
863 if (!I915_NEED_GFX_HWS(dev)) { 1068 if (!I915_NEED_GFX_HWS(dev)) {
864 ret = i915_init_phys_hws(dev); 1069 ret = i915_init_phys_hws(dev);
865 if (ret != 0) 1070 if (ret != 0)
866 return ret; 1071 goto out_rmmap;
867 } 1072 }
868 1073
869 /* On the 945G/GM, the chipset reports the MSI capability on the 1074 /* On the 945G/GM, the chipset reports the MSI capability on the
@@ -883,6 +1088,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
883 intel_opregion_init(dev); 1088 intel_opregion_init(dev);
884 1089
885 spin_lock_init(&dev_priv->user_irq_lock); 1090 spin_lock_init(&dev_priv->user_irq_lock);
1091 dev_priv->user_irq_refcount = 0;
886 1092
887 ret = drm_vblank_init(dev, I915_NUM_PIPE); 1093 ret = drm_vblank_init(dev, I915_NUM_PIPE);
888 1094
@@ -891,6 +1097,20 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
891 return ret; 1097 return ret;
892 } 1098 }
893 1099
1100 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
1101 ret = i915_load_modeset_init(dev);
1102 if (ret < 0) {
1103 DRM_ERROR("failed to init modeset\n");
1104 goto out_rmmap;
1105 }
1106 }
1107
1108 return 0;
1109
1110out_rmmap:
1111 iounmap(dev_priv->regs);
1112free_priv:
1113 drm_free(dev_priv, sizeof(struct drm_i915_private), DRM_MEM_DRIVER);
894 return ret; 1114 return ret;
895} 1115}
896 1116
@@ -898,16 +1118,29 @@ int i915_driver_unload(struct drm_device *dev)
898{ 1118{
899 struct drm_i915_private *dev_priv = dev->dev_private; 1119 struct drm_i915_private *dev_priv = dev->dev_private;
900 1120
1121 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
1122 io_mapping_free(dev_priv->mm.gtt_mapping);
1123 drm_irq_uninstall(dev);
1124 }
1125
901 if (dev->pdev->msi_enabled) 1126 if (dev->pdev->msi_enabled)
902 pci_disable_msi(dev->pdev); 1127 pci_disable_msi(dev->pdev);
903 1128
904 i915_free_hws(dev);
905
906 if (dev_priv->regs != NULL) 1129 if (dev_priv->regs != NULL)
907 iounmap(dev_priv->regs); 1130 iounmap(dev_priv->regs);
908 1131
909 intel_opregion_free(dev); 1132 intel_opregion_free(dev);
910 1133
1134 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
1135 intel_modeset_cleanup(dev);
1136
1137 mutex_lock(&dev->struct_mutex);
1138 i915_gem_cleanup_ringbuffer(dev);
1139 mutex_unlock(&dev->struct_mutex);
1140 drm_mm_takedown(&dev_priv->vram);
1141 i915_gem_lastclose(dev);
1142 }
1143
911 drm_free(dev->dev_private, sizeof(drm_i915_private_t), 1144 drm_free(dev->dev_private, sizeof(drm_i915_private_t),
912 DRM_MEM_DRIVER); 1145 DRM_MEM_DRIVER);
913 1146
@@ -933,12 +1166,26 @@ int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv)
933 return 0; 1166 return 0;
934} 1167}
935 1168
1169/**
1170 * i915_driver_lastclose - clean up after all DRM clients have exited
1171 * @dev: DRM device
1172 *
1173 * Take care of cleaning up after all DRM clients have exited. In the
1174 * mode setting case, we want to restore the kernel's initial mode (just
1175 * in case the last client left us in a bad state).
1176 *
1177 * Additionally, in the non-mode setting case, we'll tear down the AGP
1178 * and DMA structures, since the kernel won't be using them, and clea
1179 * up any GEM state.
1180 */
936void i915_driver_lastclose(struct drm_device * dev) 1181void i915_driver_lastclose(struct drm_device * dev)
937{ 1182{
938 drm_i915_private_t *dev_priv = dev->dev_private; 1183 drm_i915_private_t *dev_priv = dev->dev_private;
939 1184
940 if (!dev_priv) 1185 if (!dev_priv || drm_core_check_feature(dev, DRIVER_MODESET)) {
1186 intelfb_restore();
941 return; 1187 return;
1188 }
942 1189
943 i915_gem_lastclose(dev); 1190 i915_gem_lastclose(dev);
944 1191
@@ -951,7 +1198,8 @@ void i915_driver_lastclose(struct drm_device * dev)
951void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) 1198void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv)
952{ 1199{
953 drm_i915_private_t *dev_priv = dev->dev_private; 1200 drm_i915_private_t *dev_priv = dev->dev_private;
954 i915_mem_release(dev, file_priv, dev_priv->agp_heap); 1201 if (!drm_core_check_feature(dev, DRIVER_MODESET))
1202 i915_mem_release(dev, file_priv, dev_priv->agp_heap);
955} 1203}
956 1204
957void i915_driver_postclose(struct drm_device *dev, struct drm_file *file_priv) 1205void i915_driver_postclose(struct drm_device *dev, struct drm_file *file_priv)
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index e0d996ed9026..cbee41c32417 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -33,11 +33,22 @@
33#include "i915_drv.h" 33#include "i915_drv.h"
34 34
35#include "drm_pciids.h" 35#include "drm_pciids.h"
36#include <linux/console.h>
37
38unsigned int i915_modeset = -1;
39module_param_named(modeset, i915_modeset, int, 0400);
40
41unsigned int i915_fbpercrtc = 0;
42module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400);
36 43
37static struct pci_device_id pciidlist[] = { 44static struct pci_device_id pciidlist[] = {
38 i915_PCI_IDS 45 i915_PCI_IDS
39}; 46};
40 47
48#if defined(CONFIG_DRM_I915_KMS)
49MODULE_DEVICE_TABLE(pci, pciidlist);
50#endif
51
41static int i915_suspend(struct drm_device *dev, pm_message_t state) 52static int i915_suspend(struct drm_device *dev, pm_message_t state)
42{ 53{
43 struct drm_i915_private *dev_priv = dev->dev_private; 54 struct drm_i915_private *dev_priv = dev->dev_private;
@@ -148,6 +159,28 @@ static struct drm_driver driver = {
148static int __init i915_init(void) 159static int __init i915_init(void)
149{ 160{
150 driver.num_ioctls = i915_max_ioctl; 161 driver.num_ioctls = i915_max_ioctl;
162
163 /*
164 * If CONFIG_DRM_I915_KMS is set, default to KMS unless
165 * explicitly disabled with the module pararmeter.
166 *
167 * Otherwise, just follow the parameter (defaulting to off).
168 *
169 * Allow optional vga_text_mode_force boot option to override
170 * the default behavior.
171 */
172#if defined(CONFIG_DRM_I915_KMS)
173 if (i915_modeset != 0)
174 driver.driver_features |= DRIVER_MODESET;
175#endif
176 if (i915_modeset == 1)
177 driver.driver_features |= DRIVER_MODESET;
178
179#ifdef CONFIG_VGA_CONSOLE
180 if (vgacon_text_force() && i915_modeset == -1)
181 driver.driver_features &= ~DRIVER_MODESET;
182#endif
183
151 return drm_init(&driver); 184 return drm_init(&driver);
152} 185}
153 186
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 85a072e80637..6f18ee68d06a 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -31,6 +31,7 @@
31#define _I915_DRV_H_ 31#define _I915_DRV_H_
32 32
33#include "i915_reg.h" 33#include "i915_reg.h"
34#include "intel_bios.h"
34#include <linux/io-mapping.h> 35#include <linux/io-mapping.h>
35 36
36/* General customization: 37/* General customization:
@@ -152,8 +153,26 @@ typedef struct drm_i915_private {
152 unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; 153 unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds;
153 int vblank_pipe; 154 int vblank_pipe;
154 155
156 bool cursor_needs_physical;
157
158 struct drm_mm vram;
159
160 int irq_enabled;
161
155 struct intel_opregion opregion; 162 struct intel_opregion opregion;
156 163
164 /* LVDS info */
165 int backlight_duty_cycle; /* restore backlight to this value */
166 bool panel_wants_dither;
167 struct drm_display_mode *panel_fixed_mode;
168 struct drm_display_mode *vbt_mode; /* if any */
169
170 /* Feature bits from the VBIOS */
171 int int_tv_support:1;
172 int lvds_dither:1;
173 int lvds_vbt:1;
174 int int_crt_support:1;
175
157 struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */ 176 struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */
158 int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ 177 int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */
159 int num_fence_regs; /* 8 on pre-965, 16 otherwise */ 178 int num_fence_regs; /* 8 on pre-965, 16 otherwise */
@@ -413,6 +432,10 @@ struct drm_i915_gem_object {
413 * flags which individual pages are valid. 432 * flags which individual pages are valid.
414 */ 433 */
415 uint8_t *page_cpu_valid; 434 uint8_t *page_cpu_valid;
435
436 /** User space pin count and filp owning the pin */
437 uint32_t user_pin_count;
438 struct drm_file *pin_filp;
416}; 439};
417 440
418/** 441/**
@@ -442,8 +465,16 @@ struct drm_i915_file_private {
442 } mm; 465 } mm;
443}; 466};
444 467
468enum intel_chip_family {
469 CHIP_I8XX = 0x01,
470 CHIP_I9XX = 0x02,
471 CHIP_I915 = 0x04,
472 CHIP_I965 = 0x08,
473};
474
445extern struct drm_ioctl_desc i915_ioctls[]; 475extern struct drm_ioctl_desc i915_ioctls[];
446extern int i915_max_ioctl; 476extern int i915_max_ioctl;
477extern unsigned int i915_fbpercrtc;
447 478
448extern int i915_master_create(struct drm_device *dev, struct drm_master *master); 479extern int i915_master_create(struct drm_device *dev, struct drm_master *master);
449extern void i915_master_destroy(struct drm_device *dev, struct drm_master *master); 480extern void i915_master_destroy(struct drm_device *dev, struct drm_master *master);
@@ -472,6 +503,7 @@ extern int i915_irq_wait(struct drm_device *dev, void *data,
472 struct drm_file *file_priv); 503 struct drm_file *file_priv);
473void i915_user_irq_get(struct drm_device *dev); 504void i915_user_irq_get(struct drm_device *dev);
474void i915_user_irq_put(struct drm_device *dev); 505void i915_user_irq_put(struct drm_device *dev);
506extern void i915_enable_interrupt (struct drm_device *dev);
475 507
476extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); 508extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
477extern void i915_driver_irq_preinstall(struct drm_device * dev); 509extern void i915_driver_irq_preinstall(struct drm_device * dev);
@@ -556,7 +588,16 @@ uint32_t i915_get_gem_seqno(struct drm_device *dev);
556void i915_gem_retire_requests(struct drm_device *dev); 588void i915_gem_retire_requests(struct drm_device *dev);
557void i915_gem_retire_work_handler(struct work_struct *work); 589void i915_gem_retire_work_handler(struct work_struct *work);
558void i915_gem_clflush_object(struct drm_gem_object *obj); 590void i915_gem_clflush_object(struct drm_gem_object *obj);
591int i915_gem_object_set_domain(struct drm_gem_object *obj,
592 uint32_t read_domains,
593 uint32_t write_domain);
594int i915_gem_init_ringbuffer(struct drm_device *dev);
595void i915_gem_cleanup_ringbuffer(struct drm_device *dev);
596int i915_gem_do_init(struct drm_device *dev, unsigned long start,
597 unsigned long end);
559int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); 598int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
599int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj,
600 int write);
560 601
561/* i915_gem_tiling.c */ 602/* i915_gem_tiling.c */
562void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); 603void i915_gem_detect_bit_6_swizzle(struct drm_device *dev);
@@ -595,6 +636,10 @@ static inline void opregion_asle_intr(struct drm_device *dev) { return; }
595static inline void opregion_enable_asle(struct drm_device *dev) { return; } 636static inline void opregion_enable_asle(struct drm_device *dev) { return; }
596#endif 637#endif
597 638
639/* modesetting */
640extern void intel_modeset_init(struct drm_device *dev);
641extern void intel_modeset_cleanup(struct drm_device *dev);
642
598/** 643/**
599 * Lock test for when it's just for synchronization of ring access. 644 * Lock test for when it's just for synchronization of ring access.
600 * 645 *
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 0ac977112f72..c4ccaf3b3c7f 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -30,6 +30,7 @@
30#include "i915_drm.h" 30#include "i915_drm.h"
31#include "i915_drv.h" 31#include "i915_drv.h"
32#include <linux/swap.h> 32#include <linux/swap.h>
33#include <linux/pci.h>
33 34
34#define I915_GEM_GPU_DOMAINS (~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT)) 35#define I915_GEM_GPU_DOMAINS (~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT))
35 36
@@ -40,8 +41,6 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj,
40static void i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj); 41static void i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj);
41static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj); 42static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj);
42static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj); 43static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj);
43static int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj,
44 int write);
45static int i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, 44static int i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj,
46 int write); 45 int write);
47static int i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj, 46static int i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj,
@@ -57,33 +56,37 @@ static void i915_gem_object_get_fence_reg(struct drm_gem_object *obj);
57static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); 56static void i915_gem_clear_fence_reg(struct drm_gem_object *obj);
58static int i915_gem_evict_something(struct drm_device *dev); 57static int i915_gem_evict_something(struct drm_device *dev);
59 58
60static void 59int i915_gem_do_init(struct drm_device *dev, unsigned long start,
61i915_gem_cleanup_ringbuffer(struct drm_device *dev); 60 unsigned long end)
62
63int
64i915_gem_init_ioctl(struct drm_device *dev, void *data,
65 struct drm_file *file_priv)
66{ 61{
67 drm_i915_private_t *dev_priv = dev->dev_private; 62 drm_i915_private_t *dev_priv = dev->dev_private;
68 struct drm_i915_gem_init *args = data;
69
70 mutex_lock(&dev->struct_mutex);
71 63
72 if (args->gtt_start >= args->gtt_end || 64 if (start >= end ||
73 (args->gtt_start & (PAGE_SIZE - 1)) != 0 || 65 (start & (PAGE_SIZE - 1)) != 0 ||
74 (args->gtt_end & (PAGE_SIZE - 1)) != 0) { 66 (end & (PAGE_SIZE - 1)) != 0) {
75 mutex_unlock(&dev->struct_mutex);
76 return -EINVAL; 67 return -EINVAL;
77 } 68 }
78 69
79 drm_mm_init(&dev_priv->mm.gtt_space, args->gtt_start, 70 drm_mm_init(&dev_priv->mm.gtt_space, start,
80 args->gtt_end - args->gtt_start); 71 end - start);
81 72
82 dev->gtt_total = (uint32_t) (args->gtt_end - args->gtt_start); 73 dev->gtt_total = (uint32_t) (end - start);
74
75 return 0;
76}
83 77
78int
79i915_gem_init_ioctl(struct drm_device *dev, void *data,
80 struct drm_file *file_priv)
81{
82 struct drm_i915_gem_init *args = data;
83 int ret;
84
85 mutex_lock(&dev->struct_mutex);
86 ret = i915_gem_do_init(dev, args->gtt_start, args->gtt_end);
84 mutex_unlock(&dev->struct_mutex); 87 mutex_unlock(&dev->struct_mutex);
85 88
86 return 0; 89 return ret;
87} 90}
88 91
89int 92int
@@ -1246,7 +1249,8 @@ i915_gem_object_unbind(struct drm_gem_object *obj)
1246 1249
1247 /* blow away mappings if mapped through GTT */ 1250 /* blow away mappings if mapped through GTT */
1248 offset = ((loff_t) obj->map_list.hash.key) << PAGE_SHIFT; 1251 offset = ((loff_t) obj->map_list.hash.key) << PAGE_SHIFT;
1249 unmap_mapping_range(dev->dev_mapping, offset, obj->size, 1); 1252 if (dev->dev_mapping)
1253 unmap_mapping_range(dev->dev_mapping, offset, obj->size, 1);
1250 1254
1251 if (obj_priv->fence_reg != I915_FENCE_REG_NONE) 1255 if (obj_priv->fence_reg != I915_FENCE_REG_NONE)
1252 i915_gem_clear_fence_reg(obj); 1256 i915_gem_clear_fence_reg(obj);
@@ -1508,7 +1512,7 @@ static void
1508i915_gem_object_get_fence_reg(struct drm_gem_object *obj) 1512i915_gem_object_get_fence_reg(struct drm_gem_object *obj)
1509{ 1513{
1510 struct drm_device *dev = obj->dev; 1514 struct drm_device *dev = obj->dev;
1511 drm_i915_private_t *dev_priv = dev->dev_private; 1515 struct drm_i915_private *dev_priv = dev->dev_private;
1512 struct drm_i915_gem_object *obj_priv = obj->driver_private; 1516 struct drm_i915_gem_object *obj_priv = obj->driver_private;
1513 struct drm_i915_fence_reg *reg = NULL; 1517 struct drm_i915_fence_reg *reg = NULL;
1514 int i, ret; 1518 int i, ret;
@@ -1567,8 +1571,9 @@ try_again:
1567 * for this object next time we need it. 1571 * for this object next time we need it.
1568 */ 1572 */
1569 offset = ((loff_t) reg->obj->map_list.hash.key) << PAGE_SHIFT; 1573 offset = ((loff_t) reg->obj->map_list.hash.key) << PAGE_SHIFT;
1570 unmap_mapping_range(dev->dev_mapping, offset, 1574 if (dev->dev_mapping)
1571 reg->obj->size, 1); 1575 unmap_mapping_range(dev->dev_mapping, offset,
1576 reg->obj->size, 1);
1572 old_obj_priv->fence_reg = I915_FENCE_REG_NONE; 1577 old_obj_priv->fence_reg = I915_FENCE_REG_NONE;
1573 } 1578 }
1574 1579
@@ -1594,7 +1599,7 @@ static void
1594i915_gem_clear_fence_reg(struct drm_gem_object *obj) 1599i915_gem_clear_fence_reg(struct drm_gem_object *obj)
1595{ 1600{
1596 struct drm_device *dev = obj->dev; 1601 struct drm_device *dev = obj->dev;
1597 struct drm_i915_private *dev_priv = dev->dev_private; 1602 drm_i915_private_t *dev_priv = dev->dev_private;
1598 struct drm_i915_gem_object *obj_priv = obj->driver_private; 1603 struct drm_i915_gem_object *obj_priv = obj->driver_private;
1599 1604
1600 if (IS_I965G(dev)) 1605 if (IS_I965G(dev))
@@ -1764,7 +1769,7 @@ i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj)
1764 * This function returns when the move is complete, including waiting on 1769 * This function returns when the move is complete, including waiting on
1765 * flushes to occur. 1770 * flushes to occur.
1766 */ 1771 */
1767static int 1772int
1768i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write) 1773i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write)
1769{ 1774{
1770 struct drm_i915_gem_object *obj_priv = obj->driver_private; 1775 struct drm_i915_gem_object *obj_priv = obj->driver_private;
@@ -2706,11 +2711,22 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data,
2706 } 2711 }
2707 obj_priv = obj->driver_private; 2712 obj_priv = obj->driver_private;
2708 2713
2709 ret = i915_gem_object_pin(obj, args->alignment); 2714 if (obj_priv->pin_filp != NULL && obj_priv->pin_filp != file_priv) {
2710 if (ret != 0) { 2715 DRM_ERROR("Already pinned in i915_gem_pin_ioctl(): %d\n",
2711 drm_gem_object_unreference(obj); 2716 args->handle);
2712 mutex_unlock(&dev->struct_mutex); 2717 mutex_unlock(&dev->struct_mutex);
2713 return ret; 2718 return -EINVAL;
2719 }
2720
2721 obj_priv->user_pin_count++;
2722 obj_priv->pin_filp = file_priv;
2723 if (obj_priv->user_pin_count == 1) {
2724 ret = i915_gem_object_pin(obj, args->alignment);
2725 if (ret != 0) {
2726 drm_gem_object_unreference(obj);
2727 mutex_unlock(&dev->struct_mutex);
2728 return ret;
2729 }
2714 } 2730 }
2715 2731
2716 /* XXX - flush the CPU caches for pinned objects 2732 /* XXX - flush the CPU caches for pinned objects
@@ -2730,6 +2746,7 @@ i915_gem_unpin_ioctl(struct drm_device *dev, void *data,
2730{ 2746{
2731 struct drm_i915_gem_pin *args = data; 2747 struct drm_i915_gem_pin *args = data;
2732 struct drm_gem_object *obj; 2748 struct drm_gem_object *obj;
2749 struct drm_i915_gem_object *obj_priv;
2733 2750
2734 mutex_lock(&dev->struct_mutex); 2751 mutex_lock(&dev->struct_mutex);
2735 2752
@@ -2741,7 +2758,19 @@ i915_gem_unpin_ioctl(struct drm_device *dev, void *data,
2741 return -EBADF; 2758 return -EBADF;
2742 } 2759 }
2743 2760
2744 i915_gem_object_unpin(obj); 2761 obj_priv = obj->driver_private;
2762 if (obj_priv->pin_filp != file_priv) {
2763 DRM_ERROR("Not pinned by caller in i915_gem_pin_ioctl(): %d\n",
2764 args->handle);
2765 drm_gem_object_unreference(obj);
2766 mutex_unlock(&dev->struct_mutex);
2767 return -EINVAL;
2768 }
2769 obj_priv->user_pin_count--;
2770 if (obj_priv->user_pin_count == 0) {
2771 obj_priv->pin_filp = NULL;
2772 i915_gem_object_unpin(obj);
2773 }
2745 2774
2746 drm_gem_object_unreference(obj); 2775 drm_gem_object_unreference(obj);
2747 mutex_unlock(&dev->struct_mutex); 2776 mutex_unlock(&dev->struct_mutex);
@@ -3036,12 +3065,13 @@ i915_gem_init_hws(struct drm_device *dev)
3036 return 0; 3065 return 0;
3037} 3066}
3038 3067
3039static int 3068int
3040i915_gem_init_ringbuffer(struct drm_device *dev) 3069i915_gem_init_ringbuffer(struct drm_device *dev)
3041{ 3070{
3042 drm_i915_private_t *dev_priv = dev->dev_private; 3071 drm_i915_private_t *dev_priv = dev->dev_private;
3043 struct drm_gem_object *obj; 3072 struct drm_gem_object *obj;
3044 struct drm_i915_gem_object *obj_priv; 3073 struct drm_i915_gem_object *obj_priv;
3074 drm_i915_ring_buffer_t *ring = &dev_priv->ring;
3045 int ret; 3075 int ret;
3046 u32 head; 3076 u32 head;
3047 3077
@@ -3063,24 +3093,24 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
3063 } 3093 }
3064 3094
3065 /* Set up the kernel mapping for the ring. */ 3095 /* Set up the kernel mapping for the ring. */
3066 dev_priv->ring.Size = obj->size; 3096 ring->Size = obj->size;
3067 dev_priv->ring.tail_mask = obj->size - 1; 3097 ring->tail_mask = obj->size - 1;
3068 3098
3069 dev_priv->ring.map.offset = dev->agp->base + obj_priv->gtt_offset; 3099 ring->map.offset = dev->agp->base + obj_priv->gtt_offset;
3070 dev_priv->ring.map.size = obj->size; 3100 ring->map.size = obj->size;
3071 dev_priv->ring.map.type = 0; 3101 ring->map.type = 0;
3072 dev_priv->ring.map.flags = 0; 3102 ring->map.flags = 0;
3073 dev_priv->ring.map.mtrr = 0; 3103 ring->map.mtrr = 0;
3074 3104
3075 drm_core_ioremap_wc(&dev_priv->ring.map, dev); 3105 drm_core_ioremap_wc(&ring->map, dev);
3076 if (dev_priv->ring.map.handle == NULL) { 3106 if (ring->map.handle == NULL) {
3077 DRM_ERROR("Failed to map ringbuffer.\n"); 3107 DRM_ERROR("Failed to map ringbuffer.\n");
3078 memset(&dev_priv->ring, 0, sizeof(dev_priv->ring)); 3108 memset(&dev_priv->ring, 0, sizeof(dev_priv->ring));
3079 drm_gem_object_unreference(obj); 3109 drm_gem_object_unreference(obj);
3080 return -EINVAL; 3110 return -EINVAL;
3081 } 3111 }
3082 dev_priv->ring.ring_obj = obj; 3112 ring->ring_obj = obj;
3083 dev_priv->ring.virtual_start = dev_priv->ring.map.handle; 3113 ring->virtual_start = ring->map.handle;
3084 3114
3085 /* Stop the ring if it's running. */ 3115 /* Stop the ring if it's running. */
3086 I915_WRITE(PRB0_CTL, 0); 3116 I915_WRITE(PRB0_CTL, 0);
@@ -3128,12 +3158,20 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
3128 } 3158 }
3129 3159
3130 /* Update our cache of the ring state */ 3160 /* Update our cache of the ring state */
3131 i915_kernel_lost_context(dev); 3161 if (!drm_core_check_feature(dev, DRIVER_MODESET))
3162 i915_kernel_lost_context(dev);
3163 else {
3164 ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
3165 ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR;
3166 ring->space = ring->head - (ring->tail + 8);
3167 if (ring->space < 0)
3168 ring->space += ring->Size;
3169 }
3132 3170
3133 return 0; 3171 return 0;
3134} 3172}
3135 3173
3136static void 3174void
3137i915_gem_cleanup_ringbuffer(struct drm_device *dev) 3175i915_gem_cleanup_ringbuffer(struct drm_device *dev)
3138{ 3176{
3139 drm_i915_private_t *dev_priv = dev->dev_private; 3177 drm_i915_private_t *dev_priv = dev->dev_private;
@@ -3171,6 +3209,9 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
3171 drm_i915_private_t *dev_priv = dev->dev_private; 3209 drm_i915_private_t *dev_priv = dev->dev_private;
3172 int ret; 3210 int ret;
3173 3211
3212 if (drm_core_check_feature(dev, DRIVER_MODESET))
3213 return 0;
3214
3174 if (dev_priv->mm.wedged) { 3215 if (dev_priv->mm.wedged) {
3175 DRM_ERROR("Reenabling wedged hardware, good luck\n"); 3216 DRM_ERROR("Reenabling wedged hardware, good luck\n");
3176 dev_priv->mm.wedged = 0; 3217 dev_priv->mm.wedged = 0;
@@ -3204,6 +3245,9 @@ i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
3204 drm_i915_private_t *dev_priv = dev->dev_private; 3245 drm_i915_private_t *dev_priv = dev->dev_private;
3205 int ret; 3246 int ret;
3206 3247
3248 if (drm_core_check_feature(dev, DRIVER_MODESET))
3249 return 0;
3250
3207 ret = i915_gem_idle(dev); 3251 ret = i915_gem_idle(dev);
3208 drm_irq_uninstall(dev); 3252 drm_irq_uninstall(dev);
3209 3253
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 9b673d2f912b..0cadafbef411 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -30,6 +30,7 @@
30#include "drm.h" 30#include "drm.h"
31#include "i915_drm.h" 31#include "i915_drm.h"
32#include "i915_drv.h" 32#include "i915_drv.h"
33#include "intel_drv.h"
33 34
34#define MAX_NOPID ((u32)~0) 35#define MAX_NOPID ((u32)~0)
35 36
@@ -51,6 +52,15 @@
51#define I915_INTERRUPT_ENABLE_MASK (I915_INTERRUPT_ENABLE_FIX | \ 52#define I915_INTERRUPT_ENABLE_MASK (I915_INTERRUPT_ENABLE_FIX | \
52 I915_INTERRUPT_ENABLE_VAR) 53 I915_INTERRUPT_ENABLE_VAR)
53 54
55#define I915_PIPE_VBLANK_STATUS (PIPE_START_VBLANK_INTERRUPT_STATUS |\
56 PIPE_VBLANK_INTERRUPT_STATUS)
57
58#define I915_PIPE_VBLANK_ENABLE (PIPE_START_VBLANK_INTERRUPT_ENABLE |\
59 PIPE_VBLANK_INTERRUPT_ENABLE)
60
61#define DRM_I915_VBLANK_PIPE_ALL (DRM_I915_VBLANK_PIPE_A | \
62 DRM_I915_VBLANK_PIPE_B)
63
54void 64void
55i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask) 65i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask)
56{ 66{
@@ -201,6 +211,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
201 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); 211 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
202 pipea_stats = I915_READ(PIPEASTAT); 212 pipea_stats = I915_READ(PIPEASTAT);
203 pipeb_stats = I915_READ(PIPEBSTAT); 213 pipeb_stats = I915_READ(PIPEBSTAT);
214
204 /* 215 /*
205 * Clear the PIPE(A|B)STAT regs before the IIR 216 * Clear the PIPE(A|B)STAT regs before the IIR
206 */ 217 */
@@ -427,6 +438,14 @@ void i915_disable_vblank(struct drm_device *dev, int pipe)
427 spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); 438 spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
428} 439}
429 440
441void i915_enable_interrupt (struct drm_device *dev)
442{
443 struct drm_i915_private *dev_priv = dev->dev_private;
444 opregion_enable_asle(dev);
445 dev_priv->irq_enabled = 1;
446}
447
448
430/* Set the vblank monitor pipe 449/* Set the vblank monitor pipe
431 */ 450 */
432int i915_vblank_pipe_set(struct drm_device *dev, void *data, 451int i915_vblank_pipe_set(struct drm_device *dev, void *data,
@@ -487,6 +506,8 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
487{ 506{
488 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 507 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
489 508
509 atomic_set(&dev_priv->irq_received, 0);
510
490 I915_WRITE(HWSTAM, 0xeffe); 511 I915_WRITE(HWSTAM, 0xeffe);
491 I915_WRITE(PIPEASTAT, 0); 512 I915_WRITE(PIPEASTAT, 0);
492 I915_WRITE(PIPEBSTAT, 0); 513 I915_WRITE(PIPEBSTAT, 0);
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
new file mode 100644
index 000000000000..4ca82a025525
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -0,0 +1,193 @@
1/*
2 * Copyright © 2006 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 *
23 * Authors:
24 * Eric Anholt <eric@anholt.net>
25 *
26 */
27#include "drmP.h"
28#include "drm.h"
29#include "i915_drm.h"
30#include "i915_drv.h"
31#include "intel_bios.h"
32
33
34static void *
35find_section(struct bdb_header *bdb, int section_id)
36{
37 u8 *base = (u8 *)bdb;
38 int index = 0;
39 u16 total, current_size;
40 u8 current_id;
41
42 /* skip to first section */
43 index += bdb->header_size;
44 total = bdb->bdb_size;
45
46 /* walk the sections looking for section_id */
47 while (index < total) {
48 current_id = *(base + index);
49 index++;
50 current_size = *((u16 *)(base + index));
51 index += 2;
52 if (current_id == section_id)
53 return base + index;
54 index += current_size;
55 }
56
57 return NULL;
58}
59
60/* Try to find panel data */
61static void
62parse_panel_data(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
63{
64 struct bdb_lvds_options *lvds_options;
65 struct bdb_lvds_lfp_data *lvds_lfp_data;
66 struct bdb_lvds_lfp_data_entry *entry;
67 struct lvds_dvo_timing *dvo_timing;
68 struct drm_display_mode *panel_fixed_mode;
69
70 /* Defaults if we can't find VBT info */
71 dev_priv->lvds_dither = 0;
72 dev_priv->lvds_vbt = 0;
73
74 lvds_options = find_section(bdb, BDB_LVDS_OPTIONS);
75 if (!lvds_options)
76 return;
77
78 dev_priv->lvds_dither = lvds_options->pixel_dither;
79 if (lvds_options->panel_type == 0xff)
80 return;
81
82 lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA);
83 if (!lvds_lfp_data)
84 return;
85
86 dev_priv->lvds_vbt = 1;
87
88 entry = &lvds_lfp_data->data[lvds_options->panel_type];
89 dvo_timing = &entry->dvo_timing;
90
91 panel_fixed_mode = drm_calloc(1, sizeof(*panel_fixed_mode),
92 DRM_MEM_DRIVER);
93
94 panel_fixed_mode->hdisplay = (dvo_timing->hactive_hi << 8) |
95 dvo_timing->hactive_lo;
96 panel_fixed_mode->hsync_start = panel_fixed_mode->hdisplay +
97 ((dvo_timing->hsync_off_hi << 8) | dvo_timing->hsync_off_lo);
98 panel_fixed_mode->hsync_end = panel_fixed_mode->hsync_start +
99 dvo_timing->hsync_pulse_width;
100 panel_fixed_mode->htotal = panel_fixed_mode->hdisplay +
101 ((dvo_timing->hblank_hi << 8) | dvo_timing->hblank_lo);
102
103 panel_fixed_mode->vdisplay = (dvo_timing->vactive_hi << 8) |
104 dvo_timing->vactive_lo;
105 panel_fixed_mode->vsync_start = panel_fixed_mode->vdisplay +
106 dvo_timing->vsync_off;
107 panel_fixed_mode->vsync_end = panel_fixed_mode->vsync_start +
108 dvo_timing->vsync_pulse_width;
109 panel_fixed_mode->vtotal = panel_fixed_mode->vdisplay +
110 ((dvo_timing->vblank_hi << 8) | dvo_timing->vblank_lo);
111 panel_fixed_mode->clock = dvo_timing->clock * 10;
112 panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED;
113
114 drm_mode_set_name(panel_fixed_mode);
115
116 dev_priv->vbt_mode = panel_fixed_mode;
117
118 DRM_DEBUG("Found panel mode in BIOS VBT tables:\n");
119 drm_mode_debug_printmodeline(panel_fixed_mode);
120
121 return;
122}
123
124static void
125parse_general_features(struct drm_i915_private *dev_priv,
126 struct bdb_header *bdb)
127{
128 struct bdb_general_features *general;
129
130 /* Set sensible defaults in case we can't find the general block */
131 dev_priv->int_tv_support = 1;
132 dev_priv->int_crt_support = 1;
133
134 general = find_section(bdb, BDB_GENERAL_FEATURES);
135 if (general) {
136 dev_priv->int_tv_support = general->int_tv_support;
137 dev_priv->int_crt_support = general->int_crt_support;
138 }
139}
140
141/**
142 * intel_init_bios - initialize VBIOS settings & find VBT
143 * @dev: DRM device
144 *
145 * Loads the Video BIOS and checks that the VBT exists. Sets scratch registers
146 * to appropriate values.
147 *
148 * VBT existence is a sanity check that is relied on by other i830_bios.c code.
149 * Note that it would be better to use a BIOS call to get the VBT, as BIOSes may
150 * feed an updated VBT back through that, compared to what we'll fetch using
151 * this method of groping around in the BIOS data.
152 *
153 * Returns 0 on success, nonzero on failure.
154 */
155bool
156intel_init_bios(struct drm_device *dev)
157{
158 struct drm_i915_private *dev_priv = dev->dev_private;
159 struct pci_dev *pdev = dev->pdev;
160 struct vbt_header *vbt = NULL;
161 struct bdb_header *bdb;
162 u8 __iomem *bios;
163 size_t size;
164 int i;
165
166 bios = pci_map_rom(pdev, &size);
167 if (!bios)
168 return -1;
169
170 /* Scour memory looking for the VBT signature */
171 for (i = 0; i + 4 < size; i++) {
172 if (!memcmp(bios + i, "$VBT", 4)) {
173 vbt = (struct vbt_header *)(bios + i);
174 break;
175 }
176 }
177
178 if (!vbt) {
179 DRM_ERROR("VBT signature missing\n");
180 pci_unmap_rom(pdev, bios);
181 return -1;
182 }
183
184 bdb = (struct bdb_header *)(bios + i + vbt->bdb_offset);
185
186 /* Grab useful general definitions */
187 parse_general_features(dev_priv, bdb);
188 parse_panel_data(dev_priv, bdb);
189
190 pci_unmap_rom(pdev, bios);
191
192 return 0;
193}
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
new file mode 100644
index 000000000000..5ea715ace3a0
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -0,0 +1,405 @@
1/*
2 * Copyright © 2006 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 *
23 * Authors:
24 * Eric Anholt <eric@anholt.net>
25 *
26 */
27
28#ifndef _I830_BIOS_H_
29#define _I830_BIOS_H_
30
31#include "drmP.h"
32
33struct vbt_header {
34 u8 signature[20]; /**< Always starts with 'VBT$' */
35 u16 version; /**< decimal */
36 u16 header_size; /**< in bytes */
37 u16 vbt_size; /**< in bytes */
38 u8 vbt_checksum;
39 u8 reserved0;
40 u32 bdb_offset; /**< from beginning of VBT */
41 u32 aim_offset[4]; /**< from beginning of VBT */
42} __attribute__((packed));
43
44struct bdb_header {
45 u8 signature[16]; /**< Always 'BIOS_DATA_BLOCK' */
46 u16 version; /**< decimal */
47 u16 header_size; /**< in bytes */
48 u16 bdb_size; /**< in bytes */
49};
50
51/* strictly speaking, this is a "skip" block, but it has interesting info */
52struct vbios_data {
53 u8 type; /* 0 == desktop, 1 == mobile */
54 u8 relstage;
55 u8 chipset;
56 u8 lvds_present:1;
57 u8 tv_present:1;
58 u8 rsvd2:6; /* finish byte */
59 u8 rsvd3[4];
60 u8 signon[155];
61 u8 copyright[61];
62 u16 code_segment;
63 u8 dos_boot_mode;
64 u8 bandwidth_percent;
65 u8 rsvd4; /* popup memory size */
66 u8 resize_pci_bios;
67 u8 rsvd5; /* is crt already on ddc2 */
68} __attribute__((packed));
69
70/*
71 * There are several types of BIOS data blocks (BDBs), each block has
72 * an ID and size in the first 3 bytes (ID in first, size in next 2).
73 * Known types are listed below.
74 */
75#define BDB_GENERAL_FEATURES 1
76#define BDB_GENERAL_DEFINITIONS 2
77#define BDB_OLD_TOGGLE_LIST 3
78#define BDB_MODE_SUPPORT_LIST 4
79#define BDB_GENERIC_MODE_TABLE 5
80#define BDB_EXT_MMIO_REGS 6
81#define BDB_SWF_IO 7
82#define BDB_SWF_MMIO 8
83#define BDB_DOT_CLOCK_TABLE 9
84#define BDB_MODE_REMOVAL_TABLE 10
85#define BDB_CHILD_DEVICE_TABLE 11
86#define BDB_DRIVER_FEATURES 12
87#define BDB_DRIVER_PERSISTENCE 13
88#define BDB_EXT_TABLE_PTRS 14
89#define BDB_DOT_CLOCK_OVERRIDE 15
90#define BDB_DISPLAY_SELECT 16
91/* 17 rsvd */
92#define BDB_DRIVER_ROTATION 18
93#define BDB_DISPLAY_REMOVE 19
94#define BDB_OEM_CUSTOM 20
95#define BDB_EFP_LIST 21 /* workarounds for VGA hsync/vsync */
96#define BDB_SDVO_LVDS_OPTIONS 22
97#define BDB_SDVO_PANEL_DTDS 23
98#define BDB_SDVO_LVDS_PNP_IDS 24
99#define BDB_SDVO_LVDS_POWER_SEQ 25
100#define BDB_TV_OPTIONS 26
101#define BDB_LVDS_OPTIONS 40
102#define BDB_LVDS_LFP_DATA_PTRS 41
103#define BDB_LVDS_LFP_DATA 42
104#define BDB_LVDS_BACKLIGHT 43
105#define BDB_LVDS_POWER 44
106#define BDB_SKIP 254 /* VBIOS private block, ignore */
107
108struct bdb_general_features {
109 /* bits 1 */
110 u8 panel_fitting:2;
111 u8 flexaim:1;
112 u8 msg_enable:1;
113 u8 clear_screen:3;
114 u8 color_flip:1;
115
116 /* bits 2 */
117 u8 download_ext_vbt:1;
118 u8 enable_ssc:1;
119 u8 ssc_freq:1;
120 u8 enable_lfp_on_override:1;
121 u8 disable_ssc_ddt:1;
122 u8 rsvd8:3; /* finish byte */
123
124 /* bits 3 */
125 u8 disable_smooth_vision:1;
126 u8 single_dvi:1;
127 u8 rsvd9:6; /* finish byte */
128
129 /* bits 4 */
130 u8 legacy_monitor_detect;
131
132 /* bits 5 */
133 u8 int_crt_support:1;
134 u8 int_tv_support:1;
135 u8 rsvd11:6; /* finish byte */
136} __attribute__((packed));
137
138struct bdb_general_definitions {
139 /* DDC GPIO */
140 u8 crt_ddc_gmbus_pin;
141
142 /* DPMS bits */
143 u8 dpms_acpi:1;
144 u8 skip_boot_crt_detect:1;
145 u8 dpms_aim:1;
146 u8 rsvd1:5; /* finish byte */
147
148 /* boot device bits */
149 u8 boot_display[2];
150 u8 child_dev_size;
151
152 /* device info */
153 u8 tv_or_lvds_info[33];
154 u8 dev1[33];
155 u8 dev2[33];
156 u8 dev3[33];
157 u8 dev4[33];
158 /* may be another device block here on some platforms */
159};
160
161struct bdb_lvds_options {
162 u8 panel_type;
163 u8 rsvd1;
164 /* LVDS capabilities, stored in a dword */
165 u8 rsvd2:1;
166 u8 lvds_edid:1;
167 u8 pixel_dither:1;
168 u8 pfit_ratio_auto:1;
169 u8 pfit_gfx_mode_enhanced:1;
170 u8 pfit_text_mode_enhanced:1;
171 u8 pfit_mode:2;
172 u8 rsvd4;
173} __attribute__((packed));
174
175/* LFP pointer table contains entries to the struct below */
176struct bdb_lvds_lfp_data_ptr {
177 u16 fp_timing_offset; /* offsets are from start of bdb */
178 u8 fp_table_size;
179 u16 dvo_timing_offset;
180 u8 dvo_table_size;
181 u16 panel_pnp_id_offset;
182 u8 pnp_table_size;
183} __attribute__((packed));
184
185struct bdb_lvds_lfp_data_ptrs {
186 u8 lvds_entries; /* followed by one or more lvds_data_ptr structs */
187 struct bdb_lvds_lfp_data_ptr ptr[16];
188} __attribute__((packed));
189
190/* LFP data has 3 blocks per entry */
191struct lvds_fp_timing {
192 u16 x_res;
193 u16 y_res;
194 u32 lvds_reg;
195 u32 lvds_reg_val;
196 u32 pp_on_reg;
197 u32 pp_on_reg_val;
198 u32 pp_off_reg;
199 u32 pp_off_reg_val;
200 u32 pp_cycle_reg;
201 u32 pp_cycle_reg_val;
202 u32 pfit_reg;
203 u32 pfit_reg_val;
204 u16 terminator;
205} __attribute__((packed));
206
207struct lvds_dvo_timing {
208 u16 clock; /**< In 10khz */
209 u8 hactive_lo;
210 u8 hblank_lo;
211 u8 hblank_hi:4;
212 u8 hactive_hi:4;
213 u8 vactive_lo;
214 u8 vblank_lo;
215 u8 vblank_hi:4;
216 u8 vactive_hi:4;
217 u8 hsync_off_lo;
218 u8 hsync_pulse_width;
219 u8 vsync_pulse_width:4;
220 u8 vsync_off:4;
221 u8 rsvd0:6;
222 u8 hsync_off_hi:2;
223 u8 h_image;
224 u8 v_image;
225 u8 max_hv;
226 u8 h_border;
227 u8 v_border;
228 u8 rsvd1:3;
229 u8 digital:2;
230 u8 vsync_positive:1;
231 u8 hsync_positive:1;
232 u8 rsvd2:1;
233} __attribute__((packed));
234
235struct lvds_pnp_id {
236 u16 mfg_name;
237 u16 product_code;
238 u32 serial;
239 u8 mfg_week;
240 u8 mfg_year;
241} __attribute__((packed));
242
243struct bdb_lvds_lfp_data_entry {
244 struct lvds_fp_timing fp_timing;
245 struct lvds_dvo_timing dvo_timing;
246 struct lvds_pnp_id pnp_id;
247} __attribute__((packed));
248
249struct bdb_lvds_lfp_data {
250 struct bdb_lvds_lfp_data_entry data[16];
251} __attribute__((packed));
252
253struct aimdb_header {
254 char signature[16];
255 char oem_device[20];
256 u16 aimdb_version;
257 u16 aimdb_header_size;
258 u16 aimdb_size;
259} __attribute__((packed));
260
261struct aimdb_block {
262 u8 aimdb_id;
263 u16 aimdb_size;
264} __attribute__((packed));
265
266struct vch_panel_data {
267 u16 fp_timing_offset;
268 u8 fp_timing_size;
269 u16 dvo_timing_offset;
270 u8 dvo_timing_size;
271 u16 text_fitting_offset;
272 u8 text_fitting_size;
273 u16 graphics_fitting_offset;
274 u8 graphics_fitting_size;
275} __attribute__((packed));
276
277struct vch_bdb_22 {
278 struct aimdb_block aimdb_block;
279 struct vch_panel_data panels[16];
280} __attribute__((packed));
281
282bool intel_init_bios(struct drm_device *dev);
283
284/*
285 * Driver<->VBIOS interaction occurs through scratch bits in
286 * GR18 & SWF*.
287 */
288
289/* GR18 bits are set on display switch and hotkey events */
290#define GR18_DRIVER_SWITCH_EN (1<<7) /* 0: VBIOS control, 1: driver control */
291#define GR18_HOTKEY_MASK 0x78 /* See also SWF4 15:0 */
292#define GR18_HK_NONE (0x0<<3)
293#define GR18_HK_LFP_STRETCH (0x1<<3)
294#define GR18_HK_TOGGLE_DISP (0x2<<3)
295#define GR18_HK_DISP_SWITCH (0x4<<3) /* see SWF14 15:0 for what to enable */
296#define GR18_HK_POPUP_DISABLED (0x6<<3)
297#define GR18_HK_POPUP_ENABLED (0x7<<3)
298#define GR18_HK_PFIT (0x8<<3)
299#define GR18_HK_APM_CHANGE (0xa<<3)
300#define GR18_HK_MULTIPLE (0xc<<3)
301#define GR18_USER_INT_EN (1<<2)
302#define GR18_A0000_FLUSH_EN (1<<1)
303#define GR18_SMM_EN (1<<0)
304
305/* Set by driver, cleared by VBIOS */
306#define SWF00_YRES_SHIFT 16
307#define SWF00_XRES_SHIFT 0
308#define SWF00_RES_MASK 0xffff
309
310/* Set by VBIOS at boot time and driver at runtime */
311#define SWF01_TV2_FORMAT_SHIFT 8
312#define SWF01_TV1_FORMAT_SHIFT 0
313#define SWF01_TV_FORMAT_MASK 0xffff
314
315#define SWF10_VBIOS_BLC_I2C_EN (1<<29)
316#define SWF10_GTT_OVERRIDE_EN (1<<28)
317#define SWF10_LFP_DPMS_OVR (1<<27) /* override DPMS on display switch */
318#define SWF10_ACTIVE_TOGGLE_LIST_MASK (7<<24)
319#define SWF10_OLD_TOGGLE 0x0
320#define SWF10_TOGGLE_LIST_1 0x1
321#define SWF10_TOGGLE_LIST_2 0x2
322#define SWF10_TOGGLE_LIST_3 0x3
323#define SWF10_TOGGLE_LIST_4 0x4
324#define SWF10_PANNING_EN (1<<23)
325#define SWF10_DRIVER_LOADED (1<<22)
326#define SWF10_EXTENDED_DESKTOP (1<<21)
327#define SWF10_EXCLUSIVE_MODE (1<<20)
328#define SWF10_OVERLAY_EN (1<<19)
329#define SWF10_PLANEB_HOLDOFF (1<<18)
330#define SWF10_PLANEA_HOLDOFF (1<<17)
331#define SWF10_VGA_HOLDOFF (1<<16)
332#define SWF10_ACTIVE_DISP_MASK 0xffff
333#define SWF10_PIPEB_LFP2 (1<<15)
334#define SWF10_PIPEB_EFP2 (1<<14)
335#define SWF10_PIPEB_TV2 (1<<13)
336#define SWF10_PIPEB_CRT2 (1<<12)
337#define SWF10_PIPEB_LFP (1<<11)
338#define SWF10_PIPEB_EFP (1<<10)
339#define SWF10_PIPEB_TV (1<<9)
340#define SWF10_PIPEB_CRT (1<<8)
341#define SWF10_PIPEA_LFP2 (1<<7)
342#define SWF10_PIPEA_EFP2 (1<<6)
343#define SWF10_PIPEA_TV2 (1<<5)
344#define SWF10_PIPEA_CRT2 (1<<4)
345#define SWF10_PIPEA_LFP (1<<3)
346#define SWF10_PIPEA_EFP (1<<2)
347#define SWF10_PIPEA_TV (1<<1)
348#define SWF10_PIPEA_CRT (1<<0)
349
350#define SWF11_MEMORY_SIZE_SHIFT 16
351#define SWF11_SV_TEST_EN (1<<15)
352#define SWF11_IS_AGP (1<<14)
353#define SWF11_DISPLAY_HOLDOFF (1<<13)
354#define SWF11_DPMS_REDUCED (1<<12)
355#define SWF11_IS_VBE_MODE (1<<11)
356#define SWF11_PIPEB_ACCESS (1<<10) /* 0 here means pipe a */
357#define SWF11_DPMS_MASK 0x07
358#define SWF11_DPMS_OFF (1<<2)
359#define SWF11_DPMS_SUSPEND (1<<1)
360#define SWF11_DPMS_STANDBY (1<<0)
361#define SWF11_DPMS_ON 0
362
363#define SWF14_GFX_PFIT_EN (1<<31)
364#define SWF14_TEXT_PFIT_EN (1<<30)
365#define SWF14_LID_STATUS_CLOSED (1<<29) /* 0 here means open */
366#define SWF14_POPUP_EN (1<<28)
367#define SWF14_DISPLAY_HOLDOFF (1<<27)
368#define SWF14_DISP_DETECT_EN (1<<26)
369#define SWF14_DOCKING_STATUS_DOCKED (1<<25) /* 0 here means undocked */
370#define SWF14_DRIVER_STATUS (1<<24)
371#define SWF14_OS_TYPE_WIN9X (1<<23)
372#define SWF14_OS_TYPE_WINNT (1<<22)
373/* 21:19 rsvd */
374#define SWF14_PM_TYPE_MASK 0x00070000
375#define SWF14_PM_ACPI_VIDEO (0x4 << 16)
376#define SWF14_PM_ACPI (0x3 << 16)
377#define SWF14_PM_APM_12 (0x2 << 16)
378#define SWF14_PM_APM_11 (0x1 << 16)
379#define SWF14_HK_REQUEST_MASK 0x0000ffff /* see GR18 6:3 for event type */
380 /* if GR18 indicates a display switch */
381#define SWF14_DS_PIPEB_LFP2_EN (1<<15)
382#define SWF14_DS_PIPEB_EFP2_EN (1<<14)
383#define SWF14_DS_PIPEB_TV2_EN (1<<13)
384#define SWF14_DS_PIPEB_CRT2_EN (1<<12)
385#define SWF14_DS_PIPEB_LFP_EN (1<<11)
386#define SWF14_DS_PIPEB_EFP_EN (1<<10)
387#define SWF14_DS_PIPEB_TV_EN (1<<9)
388#define SWF14_DS_PIPEB_CRT_EN (1<<8)
389#define SWF14_DS_PIPEA_LFP2_EN (1<<7)
390#define SWF14_DS_PIPEA_EFP2_EN (1<<6)
391#define SWF14_DS_PIPEA_TV2_EN (1<<5)
392#define SWF14_DS_PIPEA_CRT2_EN (1<<4)
393#define SWF14_DS_PIPEA_LFP_EN (1<<3)
394#define SWF14_DS_PIPEA_EFP_EN (1<<2)
395#define SWF14_DS_PIPEA_TV_EN (1<<1)
396#define SWF14_DS_PIPEA_CRT_EN (1<<0)
397 /* if GR18 indicates a panel fitting request */
398#define SWF14_PFIT_EN (1<<0) /* 0 means disable */
399 /* if GR18 indicates an APM change request */
400#define SWF14_APM_HIBERNATE 0x4
401#define SWF14_APM_SUSPEND 0x3
402#define SWF14_APM_STANDBY 0x1
403#define SWF14_APM_RESTORE 0x0
404
405#endif /* _I830_BIOS_H_ */
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
new file mode 100644
index 000000000000..5d9c94eb7055
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -0,0 +1,284 @@
1/*
2 * Copyright © 2006-2007 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 *
23 * Authors:
24 * Eric Anholt <eric@anholt.net>
25 */
26
27#include <linux/i2c.h>
28#include "drmP.h"
29#include "drm.h"
30#include "drm_crtc.h"
31#include "drm_crtc_helper.h"
32#include "intel_drv.h"
33#include "i915_drm.h"
34#include "i915_drv.h"
35
36static void intel_crt_dpms(struct drm_encoder *encoder, int mode)
37{
38 struct drm_device *dev = encoder->dev;
39 struct drm_i915_private *dev_priv = dev->dev_private;
40 u32 temp;
41
42 temp = I915_READ(ADPA);
43 temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);
44 temp &= ~ADPA_DAC_ENABLE;
45
46 switch(mode) {
47 case DRM_MODE_DPMS_ON:
48 temp |= ADPA_DAC_ENABLE;
49 break;
50 case DRM_MODE_DPMS_STANDBY:
51 temp |= ADPA_DAC_ENABLE | ADPA_HSYNC_CNTL_DISABLE;
52 break;
53 case DRM_MODE_DPMS_SUSPEND:
54 temp |= ADPA_DAC_ENABLE | ADPA_VSYNC_CNTL_DISABLE;
55 break;
56 case DRM_MODE_DPMS_OFF:
57 temp |= ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE;
58 break;
59 }
60
61 I915_WRITE(ADPA, temp);
62}
63
64static int intel_crt_mode_valid(struct drm_connector *connector,
65 struct drm_display_mode *mode)
66{
67 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
68 return MODE_NO_DBLESCAN;
69
70 if (mode->clock > 400000 || mode->clock < 25000)
71 return MODE_CLOCK_RANGE;
72
73 return MODE_OK;
74}
75
76static bool intel_crt_mode_fixup(struct drm_encoder *encoder,
77 struct drm_display_mode *mode,
78 struct drm_display_mode *adjusted_mode)
79{
80 return true;
81}
82
83static void intel_crt_mode_set(struct drm_encoder *encoder,
84 struct drm_display_mode *mode,
85 struct drm_display_mode *adjusted_mode)
86{
87
88 struct drm_device *dev = encoder->dev;
89 struct drm_crtc *crtc = encoder->crtc;
90 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
91 struct drm_i915_private *dev_priv = dev->dev_private;
92 int dpll_md_reg;
93 u32 adpa, dpll_md;
94
95 if (intel_crtc->pipe == 0)
96 dpll_md_reg = DPLL_A_MD;
97 else
98 dpll_md_reg = DPLL_B_MD;
99
100 /*
101 * Disable separate mode multiplier used when cloning SDVO to CRT
102 * XXX this needs to be adjusted when we really are cloning
103 */
104 if (IS_I965G(dev)) {
105 dpll_md = I915_READ(dpll_md_reg);
106 I915_WRITE(dpll_md_reg,
107 dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK);
108 }
109
110 adpa = 0;
111 if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
112 adpa |= ADPA_HSYNC_ACTIVE_HIGH;
113 if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
114 adpa |= ADPA_VSYNC_ACTIVE_HIGH;
115
116 if (intel_crtc->pipe == 0)
117 adpa |= ADPA_PIPE_A_SELECT;
118 else
119 adpa |= ADPA_PIPE_B_SELECT;
120
121 I915_WRITE(ADPA, adpa);
122}
123
124/**
125 * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect CRT presence.
126 *
127 * Not for i915G/i915GM
128 *
129 * \return true if CRT is connected.
130 * \return false if CRT is disconnected.
131 */
132static bool intel_crt_detect_hotplug(struct drm_connector *connector)
133{
134 struct drm_device *dev = connector->dev;
135 struct drm_i915_private *dev_priv = dev->dev_private;
136 u32 temp;
137
138 unsigned long timeout = jiffies + msecs_to_jiffies(1000);
139
140 temp = I915_READ(PORT_HOTPLUG_EN);
141
142 I915_WRITE(PORT_HOTPLUG_EN,
143 temp | CRT_HOTPLUG_FORCE_DETECT | (1 << 5));
144
145 do {
146 if (!(I915_READ(PORT_HOTPLUG_EN) & CRT_HOTPLUG_FORCE_DETECT))
147 break;
148 msleep(1);
149 } while (time_after(timeout, jiffies));
150
151 if ((I915_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) ==
152 CRT_HOTPLUG_MONITOR_COLOR)
153 return true;
154
155 return false;
156}
157
158static bool intel_crt_detect_ddc(struct drm_connector *connector)
159{
160 struct intel_output *intel_output = to_intel_output(connector);
161
162 /* CRT should always be at 0, but check anyway */
163 if (intel_output->type != INTEL_OUTPUT_ANALOG)
164 return false;
165
166 return intel_ddc_probe(intel_output);
167}
168
169static enum drm_connector_status intel_crt_detect(struct drm_connector *connector)
170{
171 struct drm_device *dev = connector->dev;
172
173 if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) {
174 if (intel_crt_detect_hotplug(connector))
175 return connector_status_connected;
176 else
177 return connector_status_disconnected;
178 }
179
180 if (intel_crt_detect_ddc(connector))
181 return connector_status_connected;
182
183 /* TODO use load detect */
184 return connector_status_unknown;
185}
186
187static void intel_crt_destroy(struct drm_connector *connector)
188{
189 struct intel_output *intel_output = to_intel_output(connector);
190
191 intel_i2c_destroy(intel_output->ddc_bus);
192 drm_sysfs_connector_remove(connector);
193 drm_connector_cleanup(connector);
194 kfree(connector);
195}
196
197static int intel_crt_get_modes(struct drm_connector *connector)
198{
199 struct intel_output *intel_output = to_intel_output(connector);
200 return intel_ddc_get_modes(intel_output);
201}
202
203static int intel_crt_set_property(struct drm_connector *connector,
204 struct drm_property *property,
205 uint64_t value)
206{
207 struct drm_device *dev = connector->dev;
208
209 if (property == dev->mode_config.dpms_property && connector->encoder)
210 intel_crt_dpms(connector->encoder, (uint32_t)(value & 0xf));
211
212 return 0;
213}
214
215/*
216 * Routines for controlling stuff on the analog port
217 */
218
219static const struct drm_encoder_helper_funcs intel_crt_helper_funcs = {
220 .dpms = intel_crt_dpms,
221 .mode_fixup = intel_crt_mode_fixup,
222 .prepare = intel_encoder_prepare,
223 .commit = intel_encoder_commit,
224 .mode_set = intel_crt_mode_set,
225};
226
227static const struct drm_connector_funcs intel_crt_connector_funcs = {
228 .detect = intel_crt_detect,
229 .fill_modes = drm_helper_probe_single_connector_modes,
230 .destroy = intel_crt_destroy,
231 .set_property = intel_crt_set_property,
232};
233
234static const struct drm_connector_helper_funcs intel_crt_connector_helper_funcs = {
235 .mode_valid = intel_crt_mode_valid,
236 .get_modes = intel_crt_get_modes,
237 .best_encoder = intel_best_encoder,
238};
239
240void intel_crt_enc_destroy(struct drm_encoder *encoder)
241{
242 drm_encoder_cleanup(encoder);
243}
244
245static const struct drm_encoder_funcs intel_crt_enc_funcs = {
246 .destroy = intel_crt_enc_destroy,
247};
248
249void intel_crt_init(struct drm_device *dev)
250{
251 struct drm_connector *connector;
252 struct intel_output *intel_output;
253
254 intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL);
255 if (!intel_output)
256 return;
257
258 connector = &intel_output->base;
259 drm_connector_init(dev, &intel_output->base,
260 &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA);
261
262 drm_encoder_init(dev, &intel_output->enc, &intel_crt_enc_funcs,
263 DRM_MODE_ENCODER_DAC);
264
265 drm_mode_connector_attach_encoder(&intel_output->base,
266 &intel_output->enc);
267
268 /* Set up the DDC bus. */
269 intel_output->ddc_bus = intel_i2c_create(dev, GPIOA, "CRTDDC_A");
270 if (!intel_output->ddc_bus) {
271 dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
272 "failed.\n");
273 return;
274 }
275
276 intel_output->type = INTEL_OUTPUT_ANALOG;
277 connector->interlace_allowed = 0;
278 connector->doublescan_allowed = 0;
279
280 drm_encoder_helper_add(&intel_output->enc, &intel_crt_helper_funcs);
281 drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);
282
283 drm_sysfs_connector_add(connector);
284}
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
new file mode 100644
index 000000000000..96c2da5b74e3
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -0,0 +1,1621 @@
1/*
2 * Copyright © 2006-2007 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 *
23 * Authors:
24 * Eric Anholt <eric@anholt.net>
25 */
26
27#include <linux/i2c.h>
28#include "drmP.h"
29#include "intel_drv.h"
30#include "i915_drm.h"
31#include "i915_drv.h"
32
33#include "drm_crtc_helper.h"
34
35bool intel_pipe_has_type (struct drm_crtc *crtc, int type);
36
37typedef struct {
38 /* given values */
39 int n;
40 int m1, m2;
41 int p1, p2;
42 /* derived values */
43 int dot;
44 int vco;
45 int m;
46 int p;
47} intel_clock_t;
48
49typedef struct {
50 int min, max;
51} intel_range_t;
52
53typedef struct {
54 int dot_limit;
55 int p2_slow, p2_fast;
56} intel_p2_t;
57
58#define INTEL_P2_NUM 2
59
60typedef struct {
61 intel_range_t dot, vco, n, m, m1, m2, p, p1;
62 intel_p2_t p2;
63} intel_limit_t;
64
65#define I8XX_DOT_MIN 25000
66#define I8XX_DOT_MAX 350000
67#define I8XX_VCO_MIN 930000
68#define I8XX_VCO_MAX 1400000
69#define I8XX_N_MIN 3
70#define I8XX_N_MAX 16
71#define I8XX_M_MIN 96
72#define I8XX_M_MAX 140
73#define I8XX_M1_MIN 18
74#define I8XX_M1_MAX 26
75#define I8XX_M2_MIN 6
76#define I8XX_M2_MAX 16
77#define I8XX_P_MIN 4
78#define I8XX_P_MAX 128
79#define I8XX_P1_MIN 2
80#define I8XX_P1_MAX 33
81#define I8XX_P1_LVDS_MIN 1
82#define I8XX_P1_LVDS_MAX 6
83#define I8XX_P2_SLOW 4
84#define I8XX_P2_FAST 2
85#define I8XX_P2_LVDS_SLOW 14
86#define I8XX_P2_LVDS_FAST 14 /* No fast option */
87#define I8XX_P2_SLOW_LIMIT 165000
88
89#define I9XX_DOT_MIN 20000
90#define I9XX_DOT_MAX 400000
91#define I9XX_VCO_MIN 1400000
92#define I9XX_VCO_MAX 2800000
93#define I9XX_N_MIN 3
94#define I9XX_N_MAX 8
95#define I9XX_M_MIN 70
96#define I9XX_M_MAX 120
97#define I9XX_M1_MIN 10
98#define I9XX_M1_MAX 20
99#define I9XX_M2_MIN 5
100#define I9XX_M2_MAX 9
101#define I9XX_P_SDVO_DAC_MIN 5
102#define I9XX_P_SDVO_DAC_MAX 80
103#define I9XX_P_LVDS_MIN 7
104#define I9XX_P_LVDS_MAX 98
105#define I9XX_P1_MIN 1
106#define I9XX_P1_MAX 8
107#define I9XX_P2_SDVO_DAC_SLOW 10
108#define I9XX_P2_SDVO_DAC_FAST 5
109#define I9XX_P2_SDVO_DAC_SLOW_LIMIT 200000
110#define I9XX_P2_LVDS_SLOW 14
111#define I9XX_P2_LVDS_FAST 7
112#define I9XX_P2_LVDS_SLOW_LIMIT 112000
113
114#define INTEL_LIMIT_I8XX_DVO_DAC 0
115#define INTEL_LIMIT_I8XX_LVDS 1
116#define INTEL_LIMIT_I9XX_SDVO_DAC 2
117#define INTEL_LIMIT_I9XX_LVDS 3
118
119static const intel_limit_t intel_limits[] = {
120 { /* INTEL_LIMIT_I8XX_DVO_DAC */
121 .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX },
122 .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX },
123 .n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX },
124 .m = { .min = I8XX_M_MIN, .max = I8XX_M_MAX },
125 .m1 = { .min = I8XX_M1_MIN, .max = I8XX_M1_MAX },
126 .m2 = { .min = I8XX_M2_MIN, .max = I8XX_M2_MAX },
127 .p = { .min = I8XX_P_MIN, .max = I8XX_P_MAX },
128 .p1 = { .min = I8XX_P1_MIN, .max = I8XX_P1_MAX },
129 .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT,
130 .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST },
131 },
132 { /* INTEL_LIMIT_I8XX_LVDS */
133 .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX },
134 .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX },
135 .n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX },
136 .m = { .min = I8XX_M_MIN, .max = I8XX_M_MAX },
137 .m1 = { .min = I8XX_M1_MIN, .max = I8XX_M1_MAX },
138 .m2 = { .min = I8XX_M2_MIN, .max = I8XX_M2_MAX },
139 .p = { .min = I8XX_P_MIN, .max = I8XX_P_MAX },
140 .p1 = { .min = I8XX_P1_LVDS_MIN, .max = I8XX_P1_LVDS_MAX },
141 .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT,
142 .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST },
143 },
144 { /* INTEL_LIMIT_I9XX_SDVO_DAC */
145 .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX },
146 .vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX },
147 .n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX },
148 .m = { .min = I9XX_M_MIN, .max = I9XX_M_MAX },
149 .m1 = { .min = I9XX_M1_MIN, .max = I9XX_M1_MAX },
150 .m2 = { .min = I9XX_M2_MIN, .max = I9XX_M2_MAX },
151 .p = { .min = I9XX_P_SDVO_DAC_MIN, .max = I9XX_P_SDVO_DAC_MAX },
152 .p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX },
153 .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
154 .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST },
155 },
156 { /* INTEL_LIMIT_I9XX_LVDS */
157 .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX },
158 .vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX },
159 .n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX },
160 .m = { .min = I9XX_M_MIN, .max = I9XX_M_MAX },
161 .m1 = { .min = I9XX_M1_MIN, .max = I9XX_M1_MAX },
162 .m2 = { .min = I9XX_M2_MIN, .max = I9XX_M2_MAX },
163 .p = { .min = I9XX_P_LVDS_MIN, .max = I9XX_P_LVDS_MAX },
164 .p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX },
165 /* The single-channel range is 25-112Mhz, and dual-channel
166 * is 80-224Mhz. Prefer single channel as much as possible.
167 */
168 .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
169 .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST },
170 },
171};
172
173static const intel_limit_t *intel_limit(struct drm_crtc *crtc)
174{
175 struct drm_device *dev = crtc->dev;
176 const intel_limit_t *limit;
177
178 if (IS_I9XX(dev)) {
179 if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
180 limit = &intel_limits[INTEL_LIMIT_I9XX_LVDS];
181 else
182 limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC];
183 } else {
184 if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
185 limit = &intel_limits[INTEL_LIMIT_I8XX_LVDS];
186 else
187 limit = &intel_limits[INTEL_LIMIT_I8XX_DVO_DAC];
188 }
189 return limit;
190}
191
192/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */
193
194static void i8xx_clock(int refclk, intel_clock_t *clock)
195{
196 clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
197 clock->p = clock->p1 * clock->p2;
198 clock->vco = refclk * clock->m / (clock->n + 2);
199 clock->dot = clock->vco / clock->p;
200}
201
202/** Derive the pixel clock for the given refclk and divisors for 9xx chips. */
203
204static void i9xx_clock(int refclk, intel_clock_t *clock)
205{
206 clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
207 clock->p = clock->p1 * clock->p2;
208 clock->vco = refclk * clock->m / (clock->n + 2);
209 clock->dot = clock->vco / clock->p;
210}
211
212static void intel_clock(struct drm_device *dev, int refclk,
213 intel_clock_t *clock)
214{
215 if (IS_I9XX(dev))
216 return i9xx_clock (refclk, clock);
217 else
218 return i8xx_clock (refclk, clock);
219}
220
221/**
222 * Returns whether any output on the specified pipe is of the specified type
223 */
224bool intel_pipe_has_type (struct drm_crtc *crtc, int type)
225{
226 struct drm_device *dev = crtc->dev;
227 struct drm_mode_config *mode_config = &dev->mode_config;
228 struct drm_connector *l_entry;
229
230 list_for_each_entry(l_entry, &mode_config->connector_list, head) {
231 if (l_entry->encoder &&
232 l_entry->encoder->crtc == crtc) {
233 struct intel_output *intel_output = to_intel_output(l_entry);
234 if (intel_output->type == type)
235 return true;
236 }
237 }
238 return false;
239}
240
241#define INTELPllInvalid(s) { /* ErrorF (s) */; return false; }
242/**
243 * Returns whether the given set of divisors are valid for a given refclk with
244 * the given connectors.
245 */
246
247static bool intel_PLL_is_valid(struct drm_crtc *crtc, intel_clock_t *clock)
248{
249 const intel_limit_t *limit = intel_limit (crtc);
250
251 if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1)
252 INTELPllInvalid ("p1 out of range\n");
253 if (clock->p < limit->p.min || limit->p.max < clock->p)
254 INTELPllInvalid ("p out of range\n");
255 if (clock->m2 < limit->m2.min || limit->m2.max < clock->m2)
256 INTELPllInvalid ("m2 out of range\n");
257 if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1)
258 INTELPllInvalid ("m1 out of range\n");
259 if (clock->m1 <= clock->m2)
260 INTELPllInvalid ("m1 <= m2\n");
261 if (clock->m < limit->m.min || limit->m.max < clock->m)
262 INTELPllInvalid ("m out of range\n");
263 if (clock->n < limit->n.min || limit->n.max < clock->n)
264 INTELPllInvalid ("n out of range\n");
265 if (clock->vco < limit->vco.min || limit->vco.max < clock->vco)
266 INTELPllInvalid ("vco out of range\n");
267 /* XXX: We may need to be checking "Dot clock" depending on the multiplier,
268 * connector, etc., rather than just a single range.
269 */
270 if (clock->dot < limit->dot.min || limit->dot.max < clock->dot)
271 INTELPllInvalid ("dot out of range\n");
272
273 return true;
274}
275
276/**
277 * Returns a set of divisors for the desired target clock with the given
278 * refclk, or FALSE. The returned values represent the clock equation:
279 * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
280 */
281static bool intel_find_best_PLL(struct drm_crtc *crtc, int target,
282 int refclk, intel_clock_t *best_clock)
283{
284 struct drm_device *dev = crtc->dev;
285 struct drm_i915_private *dev_priv = dev->dev_private;
286 intel_clock_t clock;
287 const intel_limit_t *limit = intel_limit(crtc);
288 int err = target;
289
290 if (IS_I9XX(dev) && intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
291 (I915_READ(LVDS) & LVDS_PORT_EN) != 0) {
292 /*
293 * For LVDS, if the panel is on, just rely on its current
294 * settings for dual-channel. We haven't figured out how to
295 * reliably set up different single/dual channel state, if we
296 * even can.
297 */
298 if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
299 LVDS_CLKB_POWER_UP)
300 clock.p2 = limit->p2.p2_fast;
301 else
302 clock.p2 = limit->p2.p2_slow;
303 } else {
304 if (target < limit->p2.dot_limit)
305 clock.p2 = limit->p2.p2_slow;
306 else
307 clock.p2 = limit->p2.p2_fast;
308 }
309
310 memset (best_clock, 0, sizeof (*best_clock));
311
312 for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) {
313 for (clock.m2 = limit->m2.min; clock.m2 < clock.m1 &&
314 clock.m2 <= limit->m2.max; clock.m2++) {
315 for (clock.n = limit->n.min; clock.n <= limit->n.max;
316 clock.n++) {
317 for (clock.p1 = limit->p1.min;
318 clock.p1 <= limit->p1.max; clock.p1++) {
319 int this_err;
320
321 intel_clock(dev, refclk, &clock);
322
323 if (!intel_PLL_is_valid(crtc, &clock))
324 continue;
325
326 this_err = abs(clock.dot - target);
327 if (this_err < err) {
328 *best_clock = clock;
329 err = this_err;
330 }
331 }
332 }
333 }
334 }
335
336 return (err != target);
337}
338
339void
340intel_wait_for_vblank(struct drm_device *dev)
341{
342 /* Wait for 20ms, i.e. one cycle at 50hz. */
343 udelay(20000);
344}
345
346void
347intel_pipe_set_base(struct drm_crtc *crtc, int x, int y)
348{
349 struct drm_device *dev = crtc->dev;
350 struct drm_i915_private *dev_priv = dev->dev_private;
351 struct drm_i915_master_private *master_priv;
352 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
353 struct intel_framebuffer *intel_fb;
354 struct drm_i915_gem_object *obj_priv;
355 struct drm_gem_object *obj;
356 int pipe = intel_crtc->pipe;
357 unsigned long Start, Offset;
358 int dspbase = (pipe == 0 ? DSPAADDR : DSPBADDR);
359 int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
360 int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
361 int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
362 u32 dspcntr;
363
364 /* no fb bound */
365 if (!crtc->fb) {
366 DRM_DEBUG("No FB bound\n");
367 return;
368 }
369
370 intel_fb = to_intel_framebuffer(crtc->fb);
371
372 obj = intel_fb->obj;
373 obj_priv = obj->driver_private;
374
375 Start = obj_priv->gtt_offset;
376 Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8);
377
378 I915_WRITE(dspstride, crtc->fb->pitch);
379
380 dspcntr = I915_READ(dspcntr_reg);
381 switch (crtc->fb->bits_per_pixel) {
382 case 8:
383 dspcntr |= DISPPLANE_8BPP;
384 break;
385 case 16:
386 if (crtc->fb->depth == 15)
387 dspcntr |= DISPPLANE_15_16BPP;
388 else
389 dspcntr |= DISPPLANE_16BPP;
390 break;
391 case 24:
392 case 32:
393 dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
394 break;
395 default:
396 DRM_ERROR("Unknown color depth\n");
397 return;
398 }
399 I915_WRITE(dspcntr_reg, dspcntr);
400
401 DRM_DEBUG("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y);
402 if (IS_I965G(dev)) {
403 I915_WRITE(dspbase, Offset);
404 I915_READ(dspbase);
405 I915_WRITE(dspsurf, Start);
406 I915_READ(dspsurf);
407 } else {
408 I915_WRITE(dspbase, Start + Offset);
409 I915_READ(dspbase);
410 }
411
412
413 if (!dev->primary->master)
414 return;
415
416 master_priv = dev->primary->master->driver_priv;
417 if (!master_priv->sarea_priv)
418 return;
419
420 switch (pipe) {
421 case 0:
422 master_priv->sarea_priv->pipeA_x = x;
423 master_priv->sarea_priv->pipeA_y = y;
424 break;
425 case 1:
426 master_priv->sarea_priv->pipeB_x = x;
427 master_priv->sarea_priv->pipeB_y = y;
428 break;
429 default:
430 DRM_ERROR("Can't update pipe %d in SAREA\n", pipe);
431 break;
432 }
433}
434
435
436
437/**
438 * Sets the power management mode of the pipe and plane.
439 *
440 * This code should probably grow support for turning the cursor off and back
441 * on appropriately at the same time as we're turning the pipe off/on.
442 */
443static void intel_crtc_dpms(struct drm_crtc *crtc, int mode)
444{
445 struct drm_device *dev = crtc->dev;
446 struct drm_i915_master_private *master_priv;
447 struct drm_i915_private *dev_priv = dev->dev_private;
448 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
449 int pipe = intel_crtc->pipe;
450 int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
451 int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
452 int dspbase_reg = (pipe == 0) ? DSPAADDR : DSPBADDR;
453 int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
454 u32 temp;
455 bool enabled;
456
457 /* XXX: When our outputs are all unaware of DPMS modes other than off
458 * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
459 */
460 switch (mode) {
461 case DRM_MODE_DPMS_ON:
462 case DRM_MODE_DPMS_STANDBY:
463 case DRM_MODE_DPMS_SUSPEND:
464 /* Enable the DPLL */
465 temp = I915_READ(dpll_reg);
466 if ((temp & DPLL_VCO_ENABLE) == 0) {
467 I915_WRITE(dpll_reg, temp);
468 I915_READ(dpll_reg);
469 /* Wait for the clocks to stabilize. */
470 udelay(150);
471 I915_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
472 I915_READ(dpll_reg);
473 /* Wait for the clocks to stabilize. */
474 udelay(150);
475 I915_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
476 I915_READ(dpll_reg);
477 /* Wait for the clocks to stabilize. */
478 udelay(150);
479 }
480
481 /* Enable the pipe */
482 temp = I915_READ(pipeconf_reg);
483 if ((temp & PIPEACONF_ENABLE) == 0)
484 I915_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE);
485
486 /* Enable the plane */
487 temp = I915_READ(dspcntr_reg);
488 if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
489 I915_WRITE(dspcntr_reg, temp | DISPLAY_PLANE_ENABLE);
490 /* Flush the plane changes */
491 I915_WRITE(dspbase_reg, I915_READ(dspbase_reg));
492 }
493
494 intel_crtc_load_lut(crtc);
495
496 /* Give the overlay scaler a chance to enable if it's on this pipe */
497 //intel_crtc_dpms_video(crtc, true); TODO
498 break;
499 case DRM_MODE_DPMS_OFF:
500 /* Give the overlay scaler a chance to disable if it's on this pipe */
501 //intel_crtc_dpms_video(crtc, FALSE); TODO
502
503 /* Disable the VGA plane that we never use */
504 I915_WRITE(VGACNTRL, VGA_DISP_DISABLE);
505
506 /* Disable display plane */
507 temp = I915_READ(dspcntr_reg);
508 if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
509 I915_WRITE(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE);
510 /* Flush the plane changes */
511 I915_WRITE(dspbase_reg, I915_READ(dspbase_reg));
512 I915_READ(dspbase_reg);
513 }
514
515 if (!IS_I9XX(dev)) {
516 /* Wait for vblank for the disable to take effect */
517 intel_wait_for_vblank(dev);
518 }
519
520 /* Next, disable display pipes */
521 temp = I915_READ(pipeconf_reg);
522 if ((temp & PIPEACONF_ENABLE) != 0) {
523 I915_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE);
524 I915_READ(pipeconf_reg);
525 }
526
527 /* Wait for vblank for the disable to take effect. */
528 intel_wait_for_vblank(dev);
529
530 temp = I915_READ(dpll_reg);
531 if ((temp & DPLL_VCO_ENABLE) != 0) {
532 I915_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE);
533 I915_READ(dpll_reg);
534 }
535
536 /* Wait for the clocks to turn off. */
537 udelay(150);
538 break;
539 }
540
541 if (!dev->primary->master)
542 return;
543
544 master_priv = dev->primary->master->driver_priv;
545 if (!master_priv->sarea_priv)
546 return;
547
548 enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF;
549
550 switch (pipe) {
551 case 0:
552 master_priv->sarea_priv->pipeA_w = enabled ? crtc->mode.hdisplay : 0;
553 master_priv->sarea_priv->pipeA_h = enabled ? crtc->mode.vdisplay : 0;
554 break;
555 case 1:
556 master_priv->sarea_priv->pipeB_w = enabled ? crtc->mode.hdisplay : 0;
557 master_priv->sarea_priv->pipeB_h = enabled ? crtc->mode.vdisplay : 0;
558 break;
559 default:
560 DRM_ERROR("Can't update pipe %d in SAREA\n", pipe);
561 break;
562 }
563
564 intel_crtc->dpms_mode = mode;
565}
566
567static void intel_crtc_prepare (struct drm_crtc *crtc)
568{
569 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
570 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
571}
572
573static void intel_crtc_commit (struct drm_crtc *crtc)
574{
575 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
576 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
577}
578
579void intel_encoder_prepare (struct drm_encoder *encoder)
580{
581 struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
582 /* lvds has its own version of prepare see intel_lvds_prepare */
583 encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF);
584}
585
586void intel_encoder_commit (struct drm_encoder *encoder)
587{
588 struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
589 /* lvds has its own version of commit see intel_lvds_commit */
590 encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
591}
592
593static bool intel_crtc_mode_fixup(struct drm_crtc *crtc,
594 struct drm_display_mode *mode,
595 struct drm_display_mode *adjusted_mode)
596{
597 return true;
598}
599
600
601/** Returns the core display clock speed for i830 - i945 */
602static int intel_get_core_clock_speed(struct drm_device *dev)
603{
604
605 /* Core clock values taken from the published datasheets.
606 * The 830 may go up to 166 Mhz, which we should check.
607 */
608 if (IS_I945G(dev))
609 return 400000;
610 else if (IS_I915G(dev))
611 return 333000;
612 else if (IS_I945GM(dev) || IS_845G(dev))
613 return 200000;
614 else if (IS_I915GM(dev)) {
615 u16 gcfgc = 0;
616
617 pci_read_config_word(dev->pdev, GCFGC, &gcfgc);
618
619 if (gcfgc & GC_LOW_FREQUENCY_ENABLE)
620 return 133000;
621 else {
622 switch (gcfgc & GC_DISPLAY_CLOCK_MASK) {
623 case GC_DISPLAY_CLOCK_333_MHZ:
624 return 333000;
625 default:
626 case GC_DISPLAY_CLOCK_190_200_MHZ:
627 return 190000;
628 }
629 }
630 } else if (IS_I865G(dev))
631 return 266000;
632 else if (IS_I855(dev)) {
633 u16 hpllcc = 0;
634 /* Assume that the hardware is in the high speed state. This
635 * should be the default.
636 */
637 switch (hpllcc & GC_CLOCK_CONTROL_MASK) {
638 case GC_CLOCK_133_200:
639 case GC_CLOCK_100_200:
640 return 200000;
641 case GC_CLOCK_166_250:
642 return 250000;
643 case GC_CLOCK_100_133:
644 return 133000;
645 }
646 } else /* 852, 830 */
647 return 133000;
648
649 return 0; /* Silence gcc warning */
650}
651
652
653/**
654 * Return the pipe currently connected to the panel fitter,
655 * or -1 if the panel fitter is not present or not in use
656 */
657static int intel_panel_fitter_pipe (struct drm_device *dev)
658{
659 struct drm_i915_private *dev_priv = dev->dev_private;
660 u32 pfit_control;
661
662 /* i830 doesn't have a panel fitter */
663 if (IS_I830(dev))
664 return -1;
665
666 pfit_control = I915_READ(PFIT_CONTROL);
667
668 /* See if the panel fitter is in use */
669 if ((pfit_control & PFIT_ENABLE) == 0)
670 return -1;
671
672 /* 965 can place panel fitter on either pipe */
673 if (IS_I965G(dev))
674 return (pfit_control >> 29) & 0x3;
675
676 /* older chips can only use pipe 1 */
677 return 1;
678}
679
680static void intel_crtc_mode_set(struct drm_crtc *crtc,
681 struct drm_display_mode *mode,
682 struct drm_display_mode *adjusted_mode,
683 int x, int y)
684{
685 struct drm_device *dev = crtc->dev;
686 struct drm_i915_private *dev_priv = dev->dev_private;
687 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
688 int pipe = intel_crtc->pipe;
689 int fp_reg = (pipe == 0) ? FPA0 : FPB0;
690 int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
691 int dpll_md_reg = (intel_crtc->pipe == 0) ? DPLL_A_MD : DPLL_B_MD;
692 int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
693 int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
694 int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
695 int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
696 int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
697 int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
698 int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
699 int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
700 int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE;
701 int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
702 int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
703 int refclk;
704 intel_clock_t clock;
705 u32 dpll = 0, fp = 0, dspcntr, pipeconf;
706 bool ok, is_sdvo = false, is_dvo = false;
707 bool is_crt = false, is_lvds = false, is_tv = false;
708 struct drm_mode_config *mode_config = &dev->mode_config;
709 struct drm_connector *connector;
710
711 drm_vblank_pre_modeset(dev, pipe);
712
713 list_for_each_entry(connector, &mode_config->connector_list, head) {
714 struct intel_output *intel_output = to_intel_output(connector);
715
716 if (!connector->encoder || connector->encoder->crtc != crtc)
717 continue;
718
719 switch (intel_output->type) {
720 case INTEL_OUTPUT_LVDS:
721 is_lvds = true;
722 break;
723 case INTEL_OUTPUT_SDVO:
724 is_sdvo = true;
725 break;
726 case INTEL_OUTPUT_DVO:
727 is_dvo = true;
728 break;
729 case INTEL_OUTPUT_TVOUT:
730 is_tv = true;
731 break;
732 case INTEL_OUTPUT_ANALOG:
733 is_crt = true;
734 break;
735 }
736 }
737
738 if (IS_I9XX(dev)) {
739 refclk = 96000;
740 } else {
741 refclk = 48000;
742 }
743
744 ok = intel_find_best_PLL(crtc, adjusted_mode->clock, refclk, &clock);
745 if (!ok) {
746 DRM_ERROR("Couldn't find PLL settings for mode!\n");
747 return;
748 }
749
750 fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
751
752 dpll = DPLL_VGA_MODE_DIS;
753 if (IS_I9XX(dev)) {
754 if (is_lvds)
755 dpll |= DPLLB_MODE_LVDS;
756 else
757 dpll |= DPLLB_MODE_DAC_SERIAL;
758 if (is_sdvo) {
759 dpll |= DPLL_DVO_HIGH_SPEED;
760 if (IS_I945G(dev) || IS_I945GM(dev)) {
761 int sdvo_pixel_multiply = adjusted_mode->clock / mode->clock;
762 dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES;
763 }
764 }
765
766 /* compute bitmask from p1 value */
767 dpll |= (1 << (clock.p1 - 1)) << 16;
768 switch (clock.p2) {
769 case 5:
770 dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5;
771 break;
772 case 7:
773 dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7;
774 break;
775 case 10:
776 dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10;
777 break;
778 case 14:
779 dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
780 break;
781 }
782 if (IS_I965G(dev))
783 dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT);
784 } else {
785 if (is_lvds) {
786 dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
787 } else {
788 if (clock.p1 == 2)
789 dpll |= PLL_P1_DIVIDE_BY_TWO;
790 else
791 dpll |= (clock.p1 - 2) << DPLL_FPA01_P1_POST_DIV_SHIFT;
792 if (clock.p2 == 4)
793 dpll |= PLL_P2_DIVIDE_BY_4;
794 }
795 }
796
797 if (is_tv) {
798 /* XXX: just matching BIOS for now */
799/* dpll |= PLL_REF_INPUT_TVCLKINBC; */
800 dpll |= 3;
801 }
802 else
803 dpll |= PLL_REF_INPUT_DREFCLK;
804
805 /* setup pipeconf */
806 pipeconf = I915_READ(pipeconf_reg);
807
808 /* Set up the display plane register */
809 dspcntr = DISPPLANE_GAMMA_ENABLE;
810
811 if (pipe == 0)
812 dspcntr |= DISPPLANE_SEL_PIPE_A;
813 else
814 dspcntr |= DISPPLANE_SEL_PIPE_B;
815
816 if (pipe == 0 && !IS_I965G(dev)) {
817 /* Enable pixel doubling when the dot clock is > 90% of the (display)
818 * core speed.
819 *
820 * XXX: No double-wide on 915GM pipe B. Is that the only reason for the
821 * pipe == 0 check?
822 */
823 if (mode->clock > intel_get_core_clock_speed(dev) * 9 / 10)
824 pipeconf |= PIPEACONF_DOUBLE_WIDE;
825 else
826 pipeconf &= ~PIPEACONF_DOUBLE_WIDE;
827 }
828
829 dspcntr |= DISPLAY_PLANE_ENABLE;
830 pipeconf |= PIPEACONF_ENABLE;
831 dpll |= DPLL_VCO_ENABLE;
832
833
834 /* Disable the panel fitter if it was on our pipe */
835 if (intel_panel_fitter_pipe(dev) == pipe)
836 I915_WRITE(PFIT_CONTROL, 0);
837
838 DRM_DEBUG("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B');
839 drm_mode_debug_printmodeline(mode);
840
841
842 if (dpll & DPLL_VCO_ENABLE) {
843 I915_WRITE(fp_reg, fp);
844 I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
845 I915_READ(dpll_reg);
846 udelay(150);
847 }
848
849 /* The LVDS pin pair needs to be on before the DPLLs are enabled.
850 * This is an exception to the general rule that mode_set doesn't turn
851 * things on.
852 */
853 if (is_lvds) {
854 u32 lvds = I915_READ(LVDS);
855
856 lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP | LVDS_PIPEB_SELECT;
857 /* Set the B0-B3 data pairs corresponding to whether we're going to
858 * set the DPLLs for dual-channel mode or not.
859 */
860 if (clock.p2 == 7)
861 lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
862 else
863 lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
864
865 /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
866 * appropriately here, but we need to look more thoroughly into how
867 * panels behave in the two modes.
868 */
869
870 I915_WRITE(LVDS, lvds);
871 I915_READ(LVDS);
872 }
873
874 I915_WRITE(fp_reg, fp);
875 I915_WRITE(dpll_reg, dpll);
876 I915_READ(dpll_reg);
877 /* Wait for the clocks to stabilize. */
878 udelay(150);
879
880 if (IS_I965G(dev)) {
881 int sdvo_pixel_multiply = adjusted_mode->clock / mode->clock;
882 I915_WRITE(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) |
883 ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT));
884 } else {
885 /* write it again -- the BIOS does, after all */
886 I915_WRITE(dpll_reg, dpll);
887 }
888 I915_READ(dpll_reg);
889 /* Wait for the clocks to stabilize. */
890 udelay(150);
891
892 I915_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) |
893 ((adjusted_mode->crtc_htotal - 1) << 16));
894 I915_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) |
895 ((adjusted_mode->crtc_hblank_end - 1) << 16));
896 I915_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) |
897 ((adjusted_mode->crtc_hsync_end - 1) << 16));
898 I915_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) |
899 ((adjusted_mode->crtc_vtotal - 1) << 16));
900 I915_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) |
901 ((adjusted_mode->crtc_vblank_end - 1) << 16));
902 I915_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) |
903 ((adjusted_mode->crtc_vsync_end - 1) << 16));
904 /* pipesrc and dspsize control the size that is scaled from, which should
905 * always be the user's requested size.
906 */
907 I915_WRITE(dspsize_reg, ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1));
908 I915_WRITE(dsppos_reg, 0);
909 I915_WRITE(pipesrc_reg, ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
910 I915_WRITE(pipeconf_reg, pipeconf);
911 I915_READ(pipeconf_reg);
912
913 intel_wait_for_vblank(dev);
914
915 I915_WRITE(dspcntr_reg, dspcntr);
916
917 /* Flush the plane changes */
918 intel_pipe_set_base(crtc, x, y);
919
920 intel_wait_for_vblank(dev);
921
922 drm_vblank_post_modeset(dev, pipe);
923}
924
925/** Loads the palette/gamma unit for the CRTC with the prepared values */
926void intel_crtc_load_lut(struct drm_crtc *crtc)
927{
928 struct drm_device *dev = crtc->dev;
929 struct drm_i915_private *dev_priv = dev->dev_private;
930 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
931 int palreg = (intel_crtc->pipe == 0) ? PALETTE_A : PALETTE_B;
932 int i;
933
934 /* The clocks have to be on to load the palette. */
935 if (!crtc->enabled)
936 return;
937
938 for (i = 0; i < 256; i++) {
939 I915_WRITE(palreg + 4 * i,
940 (intel_crtc->lut_r[i] << 16) |
941 (intel_crtc->lut_g[i] << 8) |
942 intel_crtc->lut_b[i]);
943 }
944}
945
946static int intel_crtc_cursor_set(struct drm_crtc *crtc,
947 struct drm_file *file_priv,
948 uint32_t handle,
949 uint32_t width, uint32_t height)
950{
951 struct drm_device *dev = crtc->dev;
952 struct drm_i915_private *dev_priv = dev->dev_private;
953 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
954 struct drm_gem_object *bo;
955 struct drm_i915_gem_object *obj_priv;
956 int pipe = intel_crtc->pipe;
957 uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR;
958 uint32_t base = (pipe == 0) ? CURABASE : CURBBASE;
959 uint32_t temp;
960 size_t addr;
961
962 DRM_DEBUG("\n");
963
964 /* if we want to turn off the cursor ignore width and height */
965 if (!handle) {
966 DRM_DEBUG("cursor off\n");
967 /* turn of the cursor */
968 temp = 0;
969 temp |= CURSOR_MODE_DISABLE;
970
971 I915_WRITE(control, temp);
972 I915_WRITE(base, 0);
973 return 0;
974 }
975
976 /* Currently we only support 64x64 cursors */
977 if (width != 64 || height != 64) {
978 DRM_ERROR("we currently only support 64x64 cursors\n");
979 return -EINVAL;
980 }
981
982 bo = drm_gem_object_lookup(dev, file_priv, handle);
983 if (!bo)
984 return -ENOENT;
985
986 obj_priv = bo->driver_private;
987
988 if (bo->size < width * height * 4) {
989 DRM_ERROR("buffer is to small\n");
990 drm_gem_object_unreference(bo);
991 return -ENOMEM;
992 }
993
994 if (dev_priv->cursor_needs_physical) {
995 addr = dev->agp->base + obj_priv->gtt_offset;
996 } else {
997 addr = obj_priv->gtt_offset;
998 }
999
1000 intel_crtc->cursor_addr = addr;
1001 temp = 0;
1002 /* set the pipe for the cursor */
1003 temp |= (pipe << 28);
1004 temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
1005
1006 I915_WRITE(control, temp);
1007 I915_WRITE(base, addr);
1008
1009 return 0;
1010}
1011
1012static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
1013{
1014 struct drm_device *dev = crtc->dev;
1015 struct drm_i915_private *dev_priv = dev->dev_private;
1016 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1017 int pipe = intel_crtc->pipe;
1018 uint32_t temp = 0;
1019 uint32_t adder;
1020
1021 if (x < 0) {
1022 temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
1023 x = -x;
1024 }
1025 if (y < 0) {
1026 temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
1027 y = -y;
1028 }
1029
1030 temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
1031 temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
1032
1033 adder = intel_crtc->cursor_addr;
1034 I915_WRITE((pipe == 0) ? CURAPOS : CURBPOS, temp);
1035 I915_WRITE((pipe == 0) ? CURABASE : CURBBASE, adder);
1036
1037 return 0;
1038}
1039
1040/** Sets the color ramps on behalf of RandR */
1041void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
1042 u16 blue, int regno)
1043{
1044 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1045
1046 intel_crtc->lut_r[regno] = red >> 8;
1047 intel_crtc->lut_g[regno] = green >> 8;
1048 intel_crtc->lut_b[regno] = blue >> 8;
1049}
1050
1051static void intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
1052 u16 *blue, uint32_t size)
1053{
1054 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1055 int i;
1056
1057 if (size != 256)
1058 return;
1059
1060 for (i = 0; i < 256; i++) {
1061 intel_crtc->lut_r[i] = red[i] >> 8;
1062 intel_crtc->lut_g[i] = green[i] >> 8;
1063 intel_crtc->lut_b[i] = blue[i] >> 8;
1064 }
1065
1066 intel_crtc_load_lut(crtc);
1067}
1068
1069/**
1070 * Get a pipe with a simple mode set on it for doing load-based monitor
1071 * detection.
1072 *
1073 * It will be up to the load-detect code to adjust the pipe as appropriate for
1074 * its requirements. The pipe will be connected to no other outputs.
1075 *
1076 * Currently this code will only succeed if there is a pipe with no outputs
1077 * configured for it. In the future, it could choose to temporarily disable
1078 * some outputs to free up a pipe for its use.
1079 *
1080 * \return crtc, or NULL if no pipes are available.
1081 */
1082
1083/* VESA 640x480x72Hz mode to set on the pipe */
1084static struct drm_display_mode load_detect_mode = {
1085 DRM_MODE("640x480", DRM_MODE_TYPE_DEFAULT, 31500, 640, 664,
1086 704, 832, 0, 480, 489, 491, 520, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
1087};
1088
1089struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output,
1090 struct drm_display_mode *mode,
1091 int *dpms_mode)
1092{
1093 struct intel_crtc *intel_crtc;
1094 struct drm_crtc *possible_crtc;
1095 struct drm_crtc *supported_crtc =NULL;
1096 struct drm_encoder *encoder = &intel_output->enc;
1097 struct drm_crtc *crtc = NULL;
1098 struct drm_device *dev = encoder->dev;
1099 struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
1100 struct drm_crtc_helper_funcs *crtc_funcs;
1101 int i = -1;
1102
1103 /*
1104 * Algorithm gets a little messy:
1105 * - if the connector already has an assigned crtc, use it (but make
1106 * sure it's on first)
1107 * - try to find the first unused crtc that can drive this connector,
1108 * and use that if we find one
1109 * - if there are no unused crtcs available, try to use the first
1110 * one we found that supports the connector
1111 */
1112
1113 /* See if we already have a CRTC for this connector */
1114 if (encoder->crtc) {
1115 crtc = encoder->crtc;
1116 /* Make sure the crtc and connector are running */
1117 intel_crtc = to_intel_crtc(crtc);
1118 *dpms_mode = intel_crtc->dpms_mode;
1119 if (intel_crtc->dpms_mode != DRM_MODE_DPMS_ON) {
1120 crtc_funcs = crtc->helper_private;
1121 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
1122 encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
1123 }
1124 return crtc;
1125 }
1126
1127 /* Find an unused one (if possible) */
1128 list_for_each_entry(possible_crtc, &dev->mode_config.crtc_list, head) {
1129 i++;
1130 if (!(encoder->possible_crtcs & (1 << i)))
1131 continue;
1132 if (!possible_crtc->enabled) {
1133 crtc = possible_crtc;
1134 break;
1135 }
1136 if (!supported_crtc)
1137 supported_crtc = possible_crtc;
1138 }
1139
1140 /*
1141 * If we didn't find an unused CRTC, don't use any.
1142 */
1143 if (!crtc) {
1144 return NULL;
1145 }
1146
1147 encoder->crtc = crtc;
1148 intel_output->load_detect_temp = true;
1149
1150 intel_crtc = to_intel_crtc(crtc);
1151 *dpms_mode = intel_crtc->dpms_mode;
1152
1153 if (!crtc->enabled) {
1154 if (!mode)
1155 mode = &load_detect_mode;
1156 drm_crtc_helper_set_mode(crtc, mode, 0, 0);
1157 } else {
1158 if (intel_crtc->dpms_mode != DRM_MODE_DPMS_ON) {
1159 crtc_funcs = crtc->helper_private;
1160 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
1161 }
1162
1163 /* Add this connector to the crtc */
1164 encoder_funcs->mode_set(encoder, &crtc->mode, &crtc->mode);
1165 encoder_funcs->commit(encoder);
1166 }
1167 /* let the connector get through one full cycle before testing */
1168 intel_wait_for_vblank(dev);
1169
1170 return crtc;
1171}
1172
1173void intel_release_load_detect_pipe(struct intel_output *intel_output, int dpms_mode)
1174{
1175 struct drm_encoder *encoder = &intel_output->enc;
1176 struct drm_device *dev = encoder->dev;
1177 struct drm_crtc *crtc = encoder->crtc;
1178 struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
1179 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
1180
1181 if (intel_output->load_detect_temp) {
1182 encoder->crtc = NULL;
1183 intel_output->load_detect_temp = false;
1184 crtc->enabled = drm_helper_crtc_in_use(crtc);
1185 drm_helper_disable_unused_functions(dev);
1186 }
1187
1188 /* Switch crtc and output back off if necessary */
1189 if (crtc->enabled && dpms_mode != DRM_MODE_DPMS_ON) {
1190 if (encoder->crtc == crtc)
1191 encoder_funcs->dpms(encoder, dpms_mode);
1192 crtc_funcs->dpms(crtc, dpms_mode);
1193 }
1194}
1195
1196/* Returns the clock of the currently programmed mode of the given pipe. */
1197static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc)
1198{
1199 struct drm_i915_private *dev_priv = dev->dev_private;
1200 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1201 int pipe = intel_crtc->pipe;
1202 u32 dpll = I915_READ((pipe == 0) ? DPLL_A : DPLL_B);
1203 u32 fp;
1204 intel_clock_t clock;
1205
1206 if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
1207 fp = I915_READ((pipe == 0) ? FPA0 : FPB0);
1208 else
1209 fp = I915_READ((pipe == 0) ? FPA1 : FPB1);
1210
1211 clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT;
1212 clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT;
1213 clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT;
1214 if (IS_I9XX(dev)) {
1215 clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK) >>
1216 DPLL_FPA01_P1_POST_DIV_SHIFT);
1217
1218 switch (dpll & DPLL_MODE_MASK) {
1219 case DPLLB_MODE_DAC_SERIAL:
1220 clock.p2 = dpll & DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 ?
1221 5 : 10;
1222 break;
1223 case DPLLB_MODE_LVDS:
1224 clock.p2 = dpll & DPLLB_LVDS_P2_CLOCK_DIV_7 ?
1225 7 : 14;
1226 break;
1227 default:
1228 DRM_DEBUG("Unknown DPLL mode %08x in programmed "
1229 "mode\n", (int)(dpll & DPLL_MODE_MASK));
1230 return 0;
1231 }
1232
1233 /* XXX: Handle the 100Mhz refclk */
1234 i9xx_clock(96000, &clock);
1235 } else {
1236 bool is_lvds = (pipe == 1) && (I915_READ(LVDS) & LVDS_PORT_EN);
1237
1238 if (is_lvds) {
1239 clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >>
1240 DPLL_FPA01_P1_POST_DIV_SHIFT);
1241 clock.p2 = 14;
1242
1243 if ((dpll & PLL_REF_INPUT_MASK) ==
1244 PLLB_REF_INPUT_SPREADSPECTRUMIN) {
1245 /* XXX: might not be 66MHz */
1246 i8xx_clock(66000, &clock);
1247 } else
1248 i8xx_clock(48000, &clock);
1249 } else {
1250 if (dpll & PLL_P1_DIVIDE_BY_TWO)
1251 clock.p1 = 2;
1252 else {
1253 clock.p1 = ((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830) >>
1254 DPLL_FPA01_P1_POST_DIV_SHIFT) + 2;
1255 }
1256 if (dpll & PLL_P2_DIVIDE_BY_4)
1257 clock.p2 = 4;
1258 else
1259 clock.p2 = 2;
1260
1261 i8xx_clock(48000, &clock);
1262 }
1263 }
1264
1265 /* XXX: It would be nice to validate the clocks, but we can't reuse
1266 * i830PllIsValid() because it relies on the xf86_config connector
1267 * configuration being accurate, which it isn't necessarily.
1268 */
1269
1270 return clock.dot;
1271}
1272
1273/** Returns the currently programmed mode of the given pipe. */
1274struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
1275 struct drm_crtc *crtc)
1276{
1277 struct drm_i915_private *dev_priv = dev->dev_private;
1278 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1279 int pipe = intel_crtc->pipe;
1280 struct drm_display_mode *mode;
1281 int htot = I915_READ((pipe == 0) ? HTOTAL_A : HTOTAL_B);
1282 int hsync = I915_READ((pipe == 0) ? HSYNC_A : HSYNC_B);
1283 int vtot = I915_READ((pipe == 0) ? VTOTAL_A : VTOTAL_B);
1284 int vsync = I915_READ((pipe == 0) ? VSYNC_A : VSYNC_B);
1285
1286 mode = kzalloc(sizeof(*mode), GFP_KERNEL);
1287 if (!mode)
1288 return NULL;
1289
1290 mode->clock = intel_crtc_clock_get(dev, crtc);
1291 mode->hdisplay = (htot & 0xffff) + 1;
1292 mode->htotal = ((htot & 0xffff0000) >> 16) + 1;
1293 mode->hsync_start = (hsync & 0xffff) + 1;
1294 mode->hsync_end = ((hsync & 0xffff0000) >> 16) + 1;
1295 mode->vdisplay = (vtot & 0xffff) + 1;
1296 mode->vtotal = ((vtot & 0xffff0000) >> 16) + 1;
1297 mode->vsync_start = (vsync & 0xffff) + 1;
1298 mode->vsync_end = ((vsync & 0xffff0000) >> 16) + 1;
1299
1300 drm_mode_set_name(mode);
1301 drm_mode_set_crtcinfo(mode, 0);
1302
1303 return mode;
1304}
1305
1306static void intel_crtc_destroy(struct drm_crtc *crtc)
1307{
1308 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1309
1310 drm_crtc_cleanup(crtc);
1311 kfree(intel_crtc);
1312}
1313
1314static const struct drm_crtc_helper_funcs intel_helper_funcs = {
1315 .dpms = intel_crtc_dpms,
1316 .mode_fixup = intel_crtc_mode_fixup,
1317 .mode_set = intel_crtc_mode_set,
1318 .mode_set_base = intel_pipe_set_base,
1319 .prepare = intel_crtc_prepare,
1320 .commit = intel_crtc_commit,
1321};
1322
1323static const struct drm_crtc_funcs intel_crtc_funcs = {
1324 .cursor_set = intel_crtc_cursor_set,
1325 .cursor_move = intel_crtc_cursor_move,
1326 .gamma_set = intel_crtc_gamma_set,
1327 .set_config = drm_crtc_helper_set_config,
1328 .destroy = intel_crtc_destroy,
1329};
1330
1331
1332void intel_crtc_init(struct drm_device *dev, int pipe)
1333{
1334 struct intel_crtc *intel_crtc;
1335 int i;
1336
1337 intel_crtc = kzalloc(sizeof(struct intel_crtc) + (INTELFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
1338 if (intel_crtc == NULL)
1339 return;
1340
1341 drm_crtc_init(dev, &intel_crtc->base, &intel_crtc_funcs);
1342
1343 drm_mode_crtc_set_gamma_size(&intel_crtc->base, 256);
1344 intel_crtc->pipe = pipe;
1345 for (i = 0; i < 256; i++) {
1346 intel_crtc->lut_r[i] = i;
1347 intel_crtc->lut_g[i] = i;
1348 intel_crtc->lut_b[i] = i;
1349 }
1350
1351 intel_crtc->cursor_addr = 0;
1352 intel_crtc->dpms_mode = DRM_MODE_DPMS_OFF;
1353 drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
1354
1355 intel_crtc->mode_set.crtc = &intel_crtc->base;
1356 intel_crtc->mode_set.connectors = (struct drm_connector **)(intel_crtc + 1);
1357 intel_crtc->mode_set.num_connectors = 0;
1358
1359 if (i915_fbpercrtc) {
1360
1361
1362
1363 }
1364}
1365
1366struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe)
1367{
1368 struct drm_crtc *crtc = NULL;
1369
1370 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
1371 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1372 if (intel_crtc->pipe == pipe)
1373 break;
1374 }
1375 return crtc;
1376}
1377
1378int intel_connector_clones(struct drm_device *dev, int type_mask)
1379{
1380 int index_mask = 0;
1381 struct drm_connector *connector;
1382 int entry = 0;
1383
1384 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
1385 struct intel_output *intel_output = to_intel_output(connector);
1386 if (type_mask & (1 << intel_output->type))
1387 index_mask |= (1 << entry);
1388 entry++;
1389 }
1390 return index_mask;
1391}
1392
1393
1394static void intel_setup_outputs(struct drm_device *dev)
1395{
1396 struct drm_connector *connector;
1397
1398 intel_crt_init(dev);
1399
1400 /* Set up integrated LVDS */
1401 if (IS_MOBILE(dev) && !IS_I830(dev))
1402 intel_lvds_init(dev);
1403
1404 if (IS_I9XX(dev)) {
1405 intel_sdvo_init(dev, SDVOB);
1406 intel_sdvo_init(dev, SDVOC);
1407 } else
1408 intel_dvo_init(dev);
1409
1410 if (IS_I9XX(dev) && !IS_I915G(dev))
1411 intel_tv_init(dev);
1412
1413 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
1414 struct intel_output *intel_output = to_intel_output(connector);
1415 struct drm_encoder *encoder = &intel_output->enc;
1416 int crtc_mask = 0, clone_mask = 0;
1417
1418 /* valid crtcs */
1419 switch(intel_output->type) {
1420 case INTEL_OUTPUT_DVO:
1421 case INTEL_OUTPUT_SDVO:
1422 crtc_mask = ((1 << 0)|
1423 (1 << 1));
1424 clone_mask = ((1 << INTEL_OUTPUT_ANALOG) |
1425 (1 << INTEL_OUTPUT_DVO) |
1426 (1 << INTEL_OUTPUT_SDVO));
1427 break;
1428 case INTEL_OUTPUT_ANALOG:
1429 crtc_mask = ((1 << 0)|
1430 (1 << 1));
1431 clone_mask = ((1 << INTEL_OUTPUT_ANALOG) |
1432 (1 << INTEL_OUTPUT_DVO) |
1433 (1 << INTEL_OUTPUT_SDVO));
1434 break;
1435 case INTEL_OUTPUT_LVDS:
1436 crtc_mask = (1 << 1);
1437 clone_mask = (1 << INTEL_OUTPUT_LVDS);
1438 break;
1439 case INTEL_OUTPUT_TVOUT:
1440 crtc_mask = ((1 << 0) |
1441 (1 << 1));
1442 clone_mask = (1 << INTEL_OUTPUT_TVOUT);
1443 break;
1444 }
1445 encoder->possible_crtcs = crtc_mask;
1446 encoder->possible_clones = intel_connector_clones(dev, clone_mask);
1447 }
1448}
1449
1450static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb)
1451{
1452 struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
1453 struct drm_device *dev = fb->dev;
1454
1455 if (fb->fbdev)
1456 intelfb_remove(dev, fb);
1457
1458 drm_framebuffer_cleanup(fb);
1459 mutex_lock(&dev->struct_mutex);
1460 drm_gem_object_unreference(intel_fb->obj);
1461 mutex_unlock(&dev->struct_mutex);
1462
1463 kfree(intel_fb);
1464}
1465
1466static int intel_user_framebuffer_create_handle(struct drm_framebuffer *fb,
1467 struct drm_file *file_priv,
1468 unsigned int *handle)
1469{
1470 struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
1471 struct drm_gem_object *object = intel_fb->obj;
1472
1473 return drm_gem_handle_create(file_priv, object, handle);
1474}
1475
1476static const struct drm_framebuffer_funcs intel_fb_funcs = {
1477 .destroy = intel_user_framebuffer_destroy,
1478 .create_handle = intel_user_framebuffer_create_handle,
1479};
1480
1481int intel_framebuffer_create(struct drm_device *dev,
1482 struct drm_mode_fb_cmd *mode_cmd,
1483 struct drm_framebuffer **fb,
1484 struct drm_gem_object *obj)
1485{
1486 struct intel_framebuffer *intel_fb;
1487 int ret;
1488
1489 intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
1490 if (!intel_fb)
1491 return -ENOMEM;
1492
1493 ret = drm_framebuffer_init(dev, &intel_fb->base, &intel_fb_funcs);
1494 if (ret) {
1495 DRM_ERROR("framebuffer init failed %d\n", ret);
1496 return ret;
1497 }
1498
1499 drm_helper_mode_fill_fb_struct(&intel_fb->base, mode_cmd);
1500
1501 intel_fb->obj = obj;
1502
1503 *fb = &intel_fb->base;
1504
1505 return 0;
1506}
1507
1508
1509static struct drm_framebuffer *
1510intel_user_framebuffer_create(struct drm_device *dev,
1511 struct drm_file *filp,
1512 struct drm_mode_fb_cmd *mode_cmd)
1513{
1514 struct drm_gem_object *obj;
1515 struct drm_framebuffer *fb;
1516 int ret;
1517
1518 obj = drm_gem_object_lookup(dev, filp, mode_cmd->handle);
1519 if (!obj)
1520 return NULL;
1521
1522 ret = intel_framebuffer_create(dev, mode_cmd, &fb, obj);
1523 if (ret) {
1524 drm_gem_object_unreference(obj);
1525 return NULL;
1526 }
1527
1528 return fb;
1529}
1530
1531static int intel_insert_new_fb(struct drm_device *dev,
1532 struct drm_file *file_priv,
1533 struct drm_framebuffer *fb,
1534 struct drm_mode_fb_cmd *mode_cmd)
1535{
1536 struct intel_framebuffer *intel_fb;
1537 struct drm_gem_object *obj;
1538 struct drm_crtc *crtc;
1539
1540 intel_fb = to_intel_framebuffer(fb);
1541
1542 obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle);
1543
1544 if (!obj)
1545 return -EINVAL;
1546
1547 intel_fb->obj = obj;
1548 drm_gem_object_unreference(intel_fb->obj);
1549 drm_helper_mode_fill_fb_struct(fb, mode_cmd);
1550 mutex_unlock(&dev->struct_mutex);
1551
1552 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
1553 if (crtc->fb == fb) {
1554 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
1555 crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y);
1556 }
1557 }
1558 return 0;
1559}
1560
1561static const struct drm_mode_config_funcs intel_mode_funcs = {
1562 .resize_fb = intel_insert_new_fb,
1563 .fb_create = intel_user_framebuffer_create,
1564 .fb_changed = intelfb_probe,
1565};
1566
1567void intel_modeset_init(struct drm_device *dev)
1568{
1569 int num_pipe;
1570 int i;
1571
1572 drm_mode_config_init(dev);
1573
1574 dev->mode_config.min_width = 0;
1575 dev->mode_config.min_height = 0;
1576
1577 dev->mode_config.funcs = (void *)&intel_mode_funcs;
1578
1579 if (IS_I965G(dev)) {
1580 dev->mode_config.max_width = 8192;
1581 dev->mode_config.max_height = 8192;
1582 } else {
1583 dev->mode_config.max_width = 2048;
1584 dev->mode_config.max_height = 2048;
1585 }
1586
1587 /* set memory base */
1588 if (IS_I9XX(dev))
1589 dev->mode_config.fb_base = pci_resource_start(dev->pdev, 2);
1590 else
1591 dev->mode_config.fb_base = pci_resource_start(dev->pdev, 0);
1592
1593 if (IS_MOBILE(dev) || IS_I9XX(dev))
1594 num_pipe = 2;
1595 else
1596 num_pipe = 1;
1597 DRM_DEBUG("%d display pipe%s available.\n",
1598 num_pipe, num_pipe > 1 ? "s" : "");
1599
1600 for (i = 0; i < num_pipe; i++) {
1601 intel_crtc_init(dev, i);
1602 }
1603
1604 intel_setup_outputs(dev);
1605}
1606
1607void intel_modeset_cleanup(struct drm_device *dev)
1608{
1609 drm_mode_config_cleanup(dev);
1610}
1611
1612
1613/* current intel driver doesn't take advantage of encoders
1614 always give back the encoder for the connector
1615*/
1616struct drm_encoder *intel_best_encoder(struct drm_connector *connector)
1617{
1618 struct intel_output *intel_output = to_intel_output(connector);
1619
1620 return &intel_output->enc;
1621}
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
new file mode 100644
index 000000000000..407edd5bf582
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -0,0 +1,146 @@
1/*
2 * Copyright (c) 2006 Dave Airlie <airlied@linux.ie>
3 * Copyright (c) 2007-2008 Intel Corporation
4 * Jesse Barnes <jesse.barnes@intel.com>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 * IN THE SOFTWARE.
24 */
25#ifndef __INTEL_DRV_H__
26#define __INTEL_DRV_H__
27
28#include <linux/i2c.h>
29#include <linux/i2c-id.h>
30#include <linux/i2c-algo-bit.h>
31#include "drm_crtc.h"
32
33#include "drm_crtc_helper.h"
34/*
35 * Display related stuff
36 */
37
38/* store information about an Ixxx DVO */
39/* The i830->i865 use multiple DVOs with multiple i2cs */
40/* the i915, i945 have a single sDVO i2c bus - which is different */
41#define MAX_OUTPUTS 6
42/* maximum connectors per crtcs in the mode set */
43#define INTELFB_CONN_LIMIT 4
44
45#define INTEL_I2C_BUS_DVO 1
46#define INTEL_I2C_BUS_SDVO 2
47
48/* these are outputs from the chip - integrated only
49 external chips are via DVO or SDVO output */
50#define INTEL_OUTPUT_UNUSED 0
51#define INTEL_OUTPUT_ANALOG 1
52#define INTEL_OUTPUT_DVO 2
53#define INTEL_OUTPUT_SDVO 3
54#define INTEL_OUTPUT_LVDS 4
55#define INTEL_OUTPUT_TVOUT 5
56
57#define INTEL_DVO_CHIP_NONE 0
58#define INTEL_DVO_CHIP_LVDS 1
59#define INTEL_DVO_CHIP_TMDS 2
60#define INTEL_DVO_CHIP_TVOUT 4
61
62struct intel_i2c_chan {
63 struct drm_device *drm_dev; /* for getting at dev. private (mmio etc.) */
64 u32 reg; /* GPIO reg */
65 struct i2c_adapter adapter;
66 struct i2c_algo_bit_data algo;
67 u8 slave_addr;
68};
69
70struct intel_framebuffer {
71 struct drm_framebuffer base;
72 struct drm_gem_object *obj;
73};
74
75
76struct intel_output {
77 struct drm_connector base;
78
79 struct drm_encoder enc;
80 int type;
81 struct intel_i2c_chan *i2c_bus; /* for control functions */
82 struct intel_i2c_chan *ddc_bus; /* for DDC only stuff */
83 bool load_detect_temp;
84 void *dev_priv;
85};
86
87struct intel_crtc {
88 struct drm_crtc base;
89 int pipe;
90 int plane;
91 uint32_t cursor_addr;
92 u8 lut_r[256], lut_g[256], lut_b[256];
93 int dpms_mode;
94 struct intel_framebuffer *fbdev_fb;
95 /* a mode_set for fbdev users on this crtc */
96 struct drm_mode_set mode_set;
97};
98
99#define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
100#define to_intel_output(x) container_of(x, struct intel_output, base)
101#define enc_to_intel_output(x) container_of(x, struct intel_output, enc)
102#define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base)
103
104struct intel_i2c_chan *intel_i2c_create(struct drm_device *dev, const u32 reg,
105 const char *name);
106void intel_i2c_destroy(struct intel_i2c_chan *chan);
107int intel_ddc_get_modes(struct intel_output *intel_output);
108extern bool intel_ddc_probe(struct intel_output *intel_output);
109
110extern void intel_crt_init(struct drm_device *dev);
111extern void intel_sdvo_init(struct drm_device *dev, int output_device);
112extern void intel_dvo_init(struct drm_device *dev);
113extern void intel_tv_init(struct drm_device *dev);
114extern void intel_lvds_init(struct drm_device *dev);
115
116extern void intel_crtc_load_lut(struct drm_crtc *crtc);
117extern void intel_encoder_prepare (struct drm_encoder *encoder);
118extern void intel_encoder_commit (struct drm_encoder *encoder);
119
120extern struct drm_encoder *intel_best_encoder(struct drm_connector *connector);
121
122extern struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
123 struct drm_crtc *crtc);
124extern void intel_wait_for_vblank(struct drm_device *dev);
125extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe);
126extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output,
127 struct drm_display_mode *mode,
128 int *dpms_mode);
129extern void intel_release_load_detect_pipe(struct intel_output *intel_output,
130 int dpms_mode);
131
132extern struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB);
133extern int intel_sdvo_supports_hotplug(struct drm_connector *connector);
134extern void intel_sdvo_set_hotplug(struct drm_connector *connector, int enable);
135extern int intelfb_probe(struct drm_device *dev);
136extern int intelfb_remove(struct drm_device *dev, struct drm_framebuffer *fb);
137extern int intelfb_resize(struct drm_device *dev, struct drm_crtc *crtc);
138extern void intelfb_restore(void);
139extern void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
140 u16 blue, int regno);
141
142extern int intel_framebuffer_create(struct drm_device *dev,
143 struct drm_mode_fb_cmd *mode_cmd,
144 struct drm_framebuffer **fb,
145 struct drm_gem_object *obj);
146#endif /* __INTEL_DRV_H__ */
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c
new file mode 100644
index 000000000000..008bfaed4614
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_dvo.c
@@ -0,0 +1,501 @@
1/*
2 * Copyright 2006 Dave Airlie <airlied@linux.ie>
3 * Copyright © 2006-2007 Intel Corporation
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Eric Anholt <eric@anholt.net>
26 */
27#include <linux/i2c.h>
28#include "drmP.h"
29#include "drm.h"
30#include "drm_crtc.h"
31#include "intel_drv.h"
32#include "i915_drm.h"
33#include "i915_drv.h"
34#include "dvo.h"
35
36#define SIL164_ADDR 0x38
37#define CH7xxx_ADDR 0x76
38#define TFP410_ADDR 0x38
39
40extern struct intel_dvo_dev_ops sil164_ops;
41extern struct intel_dvo_dev_ops ch7xxx_ops;
42extern struct intel_dvo_dev_ops ivch_ops;
43extern struct intel_dvo_dev_ops tfp410_ops;
44extern struct intel_dvo_dev_ops ch7017_ops;
45
46struct intel_dvo_device intel_dvo_devices[] = {
47 {
48 .type = INTEL_DVO_CHIP_TMDS,
49 .name = "sil164",
50 .dvo_reg = DVOC,
51 .slave_addr = SIL164_ADDR,
52 .dev_ops = &sil164_ops,
53 },
54 {
55 .type = INTEL_DVO_CHIP_TMDS,
56 .name = "ch7xxx",
57 .dvo_reg = DVOC,
58 .slave_addr = CH7xxx_ADDR,
59 .dev_ops = &ch7xxx_ops,
60 },
61 {
62 .type = INTEL_DVO_CHIP_LVDS,
63 .name = "ivch",
64 .dvo_reg = DVOA,
65 .slave_addr = 0x02, /* Might also be 0x44, 0x84, 0xc4 */
66 .dev_ops = &ivch_ops,
67 },
68 {
69 .type = INTEL_DVO_CHIP_TMDS,
70 .name = "tfp410",
71 .dvo_reg = DVOC,
72 .slave_addr = TFP410_ADDR,
73 .dev_ops = &tfp410_ops,
74 },
75 {
76 .type = INTEL_DVO_CHIP_LVDS,
77 .name = "ch7017",
78 .dvo_reg = DVOC,
79 .slave_addr = 0x75,
80 .gpio = GPIOE,
81 .dev_ops = &ch7017_ops,
82 }
83};
84
85static void intel_dvo_dpms(struct drm_encoder *encoder, int mode)
86{
87 struct drm_i915_private *dev_priv = encoder->dev->dev_private;
88 struct intel_output *intel_output = enc_to_intel_output(encoder);
89 struct intel_dvo_device *dvo = intel_output->dev_priv;
90 u32 dvo_reg = dvo->dvo_reg;
91 u32 temp = I915_READ(dvo_reg);
92
93 if (mode == DRM_MODE_DPMS_ON) {
94 I915_WRITE(dvo_reg, temp | DVO_ENABLE);
95 I915_READ(dvo_reg);
96 dvo->dev_ops->dpms(dvo, mode);
97 } else {
98 dvo->dev_ops->dpms(dvo, mode);
99 I915_WRITE(dvo_reg, temp & ~DVO_ENABLE);
100 I915_READ(dvo_reg);
101 }
102}
103
104static void intel_dvo_save(struct drm_connector *connector)
105{
106 struct drm_i915_private *dev_priv = connector->dev->dev_private;
107 struct intel_output *intel_output = to_intel_output(connector);
108 struct intel_dvo_device *dvo = intel_output->dev_priv;
109
110 /* Each output should probably just save the registers it touches,
111 * but for now, use more overkill.
112 */
113 dev_priv->saveDVOA = I915_READ(DVOA);
114 dev_priv->saveDVOB = I915_READ(DVOB);
115 dev_priv->saveDVOC = I915_READ(DVOC);
116
117 dvo->dev_ops->save(dvo);
118}
119
120static void intel_dvo_restore(struct drm_connector *connector)
121{
122 struct drm_i915_private *dev_priv = connector->dev->dev_private;
123 struct intel_output *intel_output = to_intel_output(connector);
124 struct intel_dvo_device *dvo = intel_output->dev_priv;
125
126 dvo->dev_ops->restore(dvo);
127
128 I915_WRITE(DVOA, dev_priv->saveDVOA);
129 I915_WRITE(DVOB, dev_priv->saveDVOB);
130 I915_WRITE(DVOC, dev_priv->saveDVOC);
131}
132
133static int intel_dvo_mode_valid(struct drm_connector *connector,
134 struct drm_display_mode *mode)
135{
136 struct intel_output *intel_output = to_intel_output(connector);
137 struct intel_dvo_device *dvo = intel_output->dev_priv;
138
139 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
140 return MODE_NO_DBLESCAN;
141
142 /* XXX: Validate clock range */
143
144 if (dvo->panel_fixed_mode) {
145 if (mode->hdisplay > dvo->panel_fixed_mode->hdisplay)
146 return MODE_PANEL;
147 if (mode->vdisplay > dvo->panel_fixed_mode->vdisplay)
148 return MODE_PANEL;
149 }
150
151 return dvo->dev_ops->mode_valid(dvo, mode);
152}
153
154static bool intel_dvo_mode_fixup(struct drm_encoder *encoder,
155 struct drm_display_mode *mode,
156 struct drm_display_mode *adjusted_mode)
157{
158 struct intel_output *intel_output = enc_to_intel_output(encoder);
159 struct intel_dvo_device *dvo = intel_output->dev_priv;
160
161 /* If we have timings from the BIOS for the panel, put them in
162 * to the adjusted mode. The CRTC will be set up for this mode,
163 * with the panel scaling set up to source from the H/VDisplay
164 * of the original mode.
165 */
166 if (dvo->panel_fixed_mode != NULL) {
167#define C(x) adjusted_mode->x = dvo->panel_fixed_mode->x
168 C(hdisplay);
169 C(hsync_start);
170 C(hsync_end);
171 C(htotal);
172 C(vdisplay);
173 C(vsync_start);
174 C(vsync_end);
175 C(vtotal);
176 C(clock);
177 drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
178#undef C
179 }
180
181 if (dvo->dev_ops->mode_fixup)
182 return dvo->dev_ops->mode_fixup(dvo, mode, adjusted_mode);
183
184 return true;
185}
186
187static void intel_dvo_mode_set(struct drm_encoder *encoder,
188 struct drm_display_mode *mode,
189 struct drm_display_mode *adjusted_mode)
190{
191 struct drm_device *dev = encoder->dev;
192 struct drm_i915_private *dev_priv = dev->dev_private;
193 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
194 struct intel_output *intel_output = enc_to_intel_output(encoder);
195 struct intel_dvo_device *dvo = intel_output->dev_priv;
196 int pipe = intel_crtc->pipe;
197 u32 dvo_val;
198 u32 dvo_reg = dvo->dvo_reg, dvo_srcdim_reg;
199 int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
200
201 switch (dvo_reg) {
202 case DVOA:
203 default:
204 dvo_srcdim_reg = DVOA_SRCDIM;
205 break;
206 case DVOB:
207 dvo_srcdim_reg = DVOB_SRCDIM;
208 break;
209 case DVOC:
210 dvo_srcdim_reg = DVOC_SRCDIM;
211 break;
212 }
213
214 dvo->dev_ops->mode_set(dvo, mode, adjusted_mode);
215
216 /* Save the data order, since I don't know what it should be set to. */
217 dvo_val = I915_READ(dvo_reg) &
218 (DVO_PRESERVE_MASK | DVO_DATA_ORDER_GBRG);
219 dvo_val |= DVO_DATA_ORDER_FP | DVO_BORDER_ENABLE |
220 DVO_BLANK_ACTIVE_HIGH;
221
222 if (pipe == 1)
223 dvo_val |= DVO_PIPE_B_SELECT;
224 dvo_val |= DVO_PIPE_STALL;
225 if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
226 dvo_val |= DVO_HSYNC_ACTIVE_HIGH;
227 if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
228 dvo_val |= DVO_VSYNC_ACTIVE_HIGH;
229
230 I915_WRITE(dpll_reg, I915_READ(dpll_reg) | DPLL_DVO_HIGH_SPEED);
231
232 /*I915_WRITE(DVOB_SRCDIM,
233 (adjusted_mode->hdisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) |
234 (adjusted_mode->VDisplay << DVO_SRCDIM_VERTICAL_SHIFT));*/
235 I915_WRITE(dvo_srcdim_reg,
236 (adjusted_mode->hdisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) |
237 (adjusted_mode->vdisplay << DVO_SRCDIM_VERTICAL_SHIFT));
238 /*I915_WRITE(DVOB, dvo_val);*/
239 I915_WRITE(dvo_reg, dvo_val);
240}
241
242/**
243 * Detect the output connection on our DVO device.
244 *
245 * Unimplemented.
246 */
247static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector)
248{
249 struct intel_output *intel_output = to_intel_output(connector);
250 struct intel_dvo_device *dvo = intel_output->dev_priv;
251
252 return dvo->dev_ops->detect(dvo);
253}
254
255static int intel_dvo_get_modes(struct drm_connector *connector)
256{
257 struct intel_output *intel_output = to_intel_output(connector);
258 struct intel_dvo_device *dvo = intel_output->dev_priv;
259
260 /* We should probably have an i2c driver get_modes function for those
261 * devices which will have a fixed set of modes determined by the chip
262 * (TV-out, for example), but for now with just TMDS and LVDS,
263 * that's not the case.
264 */
265 intel_ddc_get_modes(intel_output);
266 if (!list_empty(&connector->probed_modes))
267 return 1;
268
269
270 if (dvo->panel_fixed_mode != NULL) {
271 struct drm_display_mode *mode;
272 mode = drm_mode_duplicate(connector->dev, dvo->panel_fixed_mode);
273 if (mode) {
274 drm_mode_probed_add(connector, mode);
275 return 1;
276 }
277 }
278 return 0;
279}
280
281static void intel_dvo_destroy (struct drm_connector *connector)
282{
283 struct intel_output *intel_output = to_intel_output(connector);
284 struct intel_dvo_device *dvo = intel_output->dev_priv;
285
286 if (dvo) {
287 if (dvo->dev_ops->destroy)
288 dvo->dev_ops->destroy(dvo);
289 if (dvo->panel_fixed_mode)
290 kfree(dvo->panel_fixed_mode);
291 /* no need, in i830_dvoices[] now */
292 //kfree(dvo);
293 }
294 if (intel_output->i2c_bus)
295 intel_i2c_destroy(intel_output->i2c_bus);
296 if (intel_output->ddc_bus)
297 intel_i2c_destroy(intel_output->ddc_bus);
298 drm_sysfs_connector_remove(connector);
299 drm_connector_cleanup(connector);
300 kfree(intel_output);
301}
302
303#ifdef RANDR_GET_CRTC_INTERFACE
304static struct drm_crtc *intel_dvo_get_crtc(struct drm_connector *connector)
305{
306 struct drm_device *dev = connector->dev;
307 struct drm_i915_private *dev_priv = dev->dev_private;
308 struct intel_output *intel_output = to_intel_output(connector);
309 struct intel_dvo_device *dvo = intel_output->dev_priv;
310 int pipe = !!(I915_READ(dvo->dvo_reg) & SDVO_PIPE_B_SELECT);
311
312 return intel_pipe_to_crtc(pScrn, pipe);
313}
314#endif
315
316static const struct drm_encoder_helper_funcs intel_dvo_helper_funcs = {
317 .dpms = intel_dvo_dpms,
318 .mode_fixup = intel_dvo_mode_fixup,
319 .prepare = intel_encoder_prepare,
320 .mode_set = intel_dvo_mode_set,
321 .commit = intel_encoder_commit,
322};
323
324static const struct drm_connector_funcs intel_dvo_connector_funcs = {
325 .save = intel_dvo_save,
326 .restore = intel_dvo_restore,
327 .detect = intel_dvo_detect,
328 .destroy = intel_dvo_destroy,
329 .fill_modes = drm_helper_probe_single_connector_modes,
330};
331
332static const struct drm_connector_helper_funcs intel_dvo_connector_helper_funcs = {
333 .mode_valid = intel_dvo_mode_valid,
334 .get_modes = intel_dvo_get_modes,
335 .best_encoder = intel_best_encoder,
336};
337
338void intel_dvo_enc_destroy(struct drm_encoder *encoder)
339{
340 drm_encoder_cleanup(encoder);
341}
342
343static const struct drm_encoder_funcs intel_dvo_enc_funcs = {
344 .destroy = intel_dvo_enc_destroy,
345};
346
347
348/**
349 * Attempts to get a fixed panel timing for LVDS (currently only the i830).
350 *
351 * Other chips with DVO LVDS will need to extend this to deal with the LVDS
352 * chip being on DVOB/C and having multiple pipes.
353 */
354static struct drm_display_mode *
355intel_dvo_get_current_mode (struct drm_connector *connector)
356{
357 struct drm_device *dev = connector->dev;
358 struct drm_i915_private *dev_priv = dev->dev_private;
359 struct intel_output *intel_output = to_intel_output(connector);
360 struct intel_dvo_device *dvo = intel_output->dev_priv;
361 uint32_t dvo_reg = dvo->dvo_reg;
362 uint32_t dvo_val = I915_READ(dvo_reg);
363 struct drm_display_mode *mode = NULL;
364
365 /* If the DVO port is active, that'll be the LVDS, so we can pull out
366 * its timings to get how the BIOS set up the panel.
367 */
368 if (dvo_val & DVO_ENABLE) {
369 struct drm_crtc *crtc;
370 int pipe = (dvo_val & DVO_PIPE_B_SELECT) ? 1 : 0;
371
372 crtc = intel_get_crtc_from_pipe(dev, pipe);
373 if (crtc) {
374 mode = intel_crtc_mode_get(dev, crtc);
375
376 if (mode) {
377 mode->type |= DRM_MODE_TYPE_PREFERRED;
378 if (dvo_val & DVO_HSYNC_ACTIVE_HIGH)
379 mode->flags |= DRM_MODE_FLAG_PHSYNC;
380 if (dvo_val & DVO_VSYNC_ACTIVE_HIGH)
381 mode->flags |= DRM_MODE_FLAG_PVSYNC;
382 }
383 }
384 }
385 return mode;
386}
387
388void intel_dvo_init(struct drm_device *dev)
389{
390 struct intel_output *intel_output;
391 struct intel_dvo_device *dvo;
392 struct intel_i2c_chan *i2cbus = NULL;
393 int ret = 0;
394 int i;
395 int gpio_inited = 0;
396 int encoder_type = DRM_MODE_ENCODER_NONE;
397 intel_output = kzalloc (sizeof(struct intel_output), GFP_KERNEL);
398 if (!intel_output)
399 return;
400
401 /* Set up the DDC bus */
402 intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D");
403 if (!intel_output->ddc_bus)
404 goto free_intel;
405
406 /* Now, try to find a controller */
407 for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) {
408 struct drm_connector *connector = &intel_output->base;
409 int gpio;
410
411 dvo = &intel_dvo_devices[i];
412
413 /* Allow the I2C driver info to specify the GPIO to be used in
414 * special cases, but otherwise default to what's defined
415 * in the spec.
416 */
417 if (dvo->gpio != 0)
418 gpio = dvo->gpio;
419 else if (dvo->type == INTEL_DVO_CHIP_LVDS)
420 gpio = GPIOB;
421 else
422 gpio = GPIOE;
423
424 /* Set up the I2C bus necessary for the chip we're probing.
425 * It appears that everything is on GPIOE except for panels
426 * on i830 laptops, which are on GPIOB (DVOA).
427 */
428 if (gpio_inited != gpio) {
429 if (i2cbus != NULL)
430 intel_i2c_destroy(i2cbus);
431 if (!(i2cbus = intel_i2c_create(dev, gpio,
432 gpio == GPIOB ? "DVOI2C_B" : "DVOI2C_E"))) {
433 continue;
434 }
435 gpio_inited = gpio;
436 }
437
438 if (dvo->dev_ops!= NULL)
439 ret = dvo->dev_ops->init(dvo, i2cbus);
440 else
441 ret = false;
442
443 if (!ret)
444 continue;
445
446 intel_output->type = INTEL_OUTPUT_DVO;
447 switch (dvo->type) {
448 case INTEL_DVO_CHIP_TMDS:
449 drm_connector_init(dev, connector,
450 &intel_dvo_connector_funcs,
451 DRM_MODE_CONNECTOR_DVII);
452 encoder_type = DRM_MODE_ENCODER_TMDS;
453 break;
454 case INTEL_DVO_CHIP_LVDS:
455 drm_connector_init(dev, connector,
456 &intel_dvo_connector_funcs,
457 DRM_MODE_CONNECTOR_LVDS);
458 encoder_type = DRM_MODE_ENCODER_LVDS;
459 break;
460 }
461
462 drm_connector_helper_add(connector,
463 &intel_dvo_connector_helper_funcs);
464 connector->display_info.subpixel_order = SubPixelHorizontalRGB;
465 connector->interlace_allowed = false;
466 connector->doublescan_allowed = false;
467
468 intel_output->dev_priv = dvo;
469 intel_output->i2c_bus = i2cbus;
470
471 drm_encoder_init(dev, &intel_output->enc,
472 &intel_dvo_enc_funcs, encoder_type);
473 drm_encoder_helper_add(&intel_output->enc,
474 &intel_dvo_helper_funcs);
475
476 drm_mode_connector_attach_encoder(&intel_output->base,
477 &intel_output->enc);
478 if (dvo->type == INTEL_DVO_CHIP_LVDS) {
479 /* For our LVDS chipsets, we should hopefully be able
480 * to dig the fixed panel mode out of the BIOS data.
481 * However, it's in a different format from the BIOS
482 * data on chipsets with integrated LVDS (stored in AIM
483 * headers, likely), so for now, just get the current
484 * mode being output through DVO.
485 */
486 dvo->panel_fixed_mode =
487 intel_dvo_get_current_mode(connector);
488 dvo->panel_wants_dither = true;
489 }
490
491 drm_sysfs_connector_add(connector);
492 return;
493 }
494
495 intel_i2c_destroy(intel_output->ddc_bus);
496 /* Didn't find a chip, so tear down. */
497 if (i2cbus != NULL)
498 intel_i2c_destroy(i2cbus);
499free_intel:
500 kfree(intel_output);
501}
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
new file mode 100644
index 000000000000..a89ebea7b76d
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -0,0 +1,926 @@
1/*
2 * Copyright © 2007 David Airlie
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 *
23 * Authors:
24 * David Airlie
25 */
26
27#include <linux/module.h>
28#include <linux/kernel.h>
29#include <linux/errno.h>
30#include <linux/string.h>
31#include <linux/mm.h>
32#include <linux/tty.h>
33#include <linux/slab.h>
34#include <linux/sysrq.h>
35#include <linux/delay.h>
36#include <linux/fb.h>
37#include <linux/init.h>
38
39#include "drmP.h"
40#include "drm.h"
41#include "drm_crtc.h"
42#include "intel_drv.h"
43#include "i915_drm.h"
44#include "i915_drv.h"
45
46struct intelfb_par {
47 struct drm_device *dev;
48 struct drm_display_mode *our_mode;
49 struct intel_framebuffer *intel_fb;
50 int crtc_count;
51 /* crtc currently bound to this */
52 uint32_t crtc_ids[2];
53};
54
55static int intelfb_setcolreg(unsigned regno, unsigned red, unsigned green,
56 unsigned blue, unsigned transp,
57 struct fb_info *info)
58{
59 struct intelfb_par *par = info->par;
60 struct drm_device *dev = par->dev;
61 struct drm_crtc *crtc;
62 int i;
63
64 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
65 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
66 struct drm_mode_set *modeset = &intel_crtc->mode_set;
67 struct drm_framebuffer *fb = modeset->fb;
68
69 for (i = 0; i < par->crtc_count; i++)
70 if (crtc->base.id == par->crtc_ids[i])
71 break;
72
73 if (i == par->crtc_count)
74 continue;
75
76
77 if (regno > 255)
78 return 1;
79
80 if (fb->depth == 8) {
81 intel_crtc_fb_gamma_set(crtc, red, green, blue, regno);
82 return 0;
83 }
84
85 if (regno < 16) {
86 switch (fb->depth) {
87 case 15:
88 fb->pseudo_palette[regno] = ((red & 0xf800) >> 1) |
89 ((green & 0xf800) >> 6) |
90 ((blue & 0xf800) >> 11);
91 break;
92 case 16:
93 fb->pseudo_palette[regno] = (red & 0xf800) |
94 ((green & 0xfc00) >> 5) |
95 ((blue & 0xf800) >> 11);
96 break;
97 case 24:
98 case 32:
99 fb->pseudo_palette[regno] = ((red & 0xff00) << 8) |
100 (green & 0xff00) |
101 ((blue & 0xff00) >> 8);
102 break;
103 }
104 }
105 }
106 return 0;
107}
108
109static int intelfb_check_var(struct fb_var_screeninfo *var,
110 struct fb_info *info)
111{
112 struct intelfb_par *par = info->par;
113 struct intel_framebuffer *intel_fb = par->intel_fb;
114 struct drm_framebuffer *fb = &intel_fb->base;
115 int depth;
116
117 if (var->pixclock == -1 || !var->pixclock)
118 return -EINVAL;
119
120 /* Need to resize the fb object !!! */
121 if (var->xres > fb->width || var->yres > fb->height) {
122 DRM_ERROR("Requested width/height is greater than current fb object %dx%d > %dx%d\n",var->xres,var->yres,fb->width,fb->height);
123 DRM_ERROR("Need resizing code.\n");
124 return -EINVAL;
125 }
126
127 switch (var->bits_per_pixel) {
128 case 16:
129 depth = (var->green.length == 6) ? 16 : 15;
130 break;
131 case 32:
132 depth = (var->transp.length > 0) ? 32 : 24;
133 break;
134 default:
135 depth = var->bits_per_pixel;
136 break;
137 }
138
139 switch (depth) {
140 case 8:
141 var->red.offset = 0;
142 var->green.offset = 0;
143 var->blue.offset = 0;
144 var->red.length = 8;
145 var->green.length = 8;
146 var->blue.length = 8;
147 var->transp.length = 0;
148 var->transp.offset = 0;
149 break;
150 case 15:
151 var->red.offset = 10;
152 var->green.offset = 5;
153 var->blue.offset = 0;
154 var->red.length = 5;
155 var->green.length = 5;
156 var->blue.length = 5;
157 var->transp.length = 1;
158 var->transp.offset = 15;
159 break;
160 case 16:
161 var->red.offset = 11;
162 var->green.offset = 5;
163 var->blue.offset = 0;
164 var->red.length = 5;
165 var->green.length = 6;
166 var->blue.length = 5;
167 var->transp.length = 0;
168 var->transp.offset = 0;
169 break;
170 case 24:
171 var->red.offset = 16;
172 var->green.offset = 8;
173 var->blue.offset = 0;
174 var->red.length = 8;
175 var->green.length = 8;
176 var->blue.length = 8;
177 var->transp.length = 0;
178 var->transp.offset = 0;
179 break;
180 case 32:
181 var->red.offset = 16;
182 var->green.offset = 8;
183 var->blue.offset = 0;
184 var->red.length = 8;
185 var->green.length = 8;
186 var->blue.length = 8;
187 var->transp.length = 8;
188 var->transp.offset = 24;
189 break;
190 default:
191 return -EINVAL;
192 }
193
194 return 0;
195}
196
197/* this will let fbcon do the mode init */
198/* FIXME: take mode config lock? */
199static int intelfb_set_par(struct fb_info *info)
200{
201 struct intelfb_par *par = info->par;
202 struct drm_device *dev = par->dev;
203 struct fb_var_screeninfo *var = &info->var;
204 int i;
205
206 DRM_DEBUG("%d %d\n", var->xres, var->pixclock);
207
208 if (var->pixclock != -1) {
209
210 DRM_ERROR("PIXEL CLCOK SET\n");
211 return -EINVAL;
212 } else {
213 struct drm_crtc *crtc;
214 int ret;
215
216 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
217 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
218
219 for (i = 0; i < par->crtc_count; i++)
220 if (crtc->base.id == par->crtc_ids[i])
221 break;
222
223 if (i == par->crtc_count)
224 continue;
225
226 if (crtc->fb == intel_crtc->mode_set.fb) {
227 mutex_lock(&dev->mode_config.mutex);
228 ret = crtc->funcs->set_config(&intel_crtc->mode_set);
229 mutex_unlock(&dev->mode_config.mutex);
230 if (ret)
231 return ret;
232 }
233 }
234 return 0;
235 }
236}
237
238static int intelfb_pan_display(struct fb_var_screeninfo *var,
239 struct fb_info *info)
240{
241 struct intelfb_par *par = info->par;
242 struct drm_device *dev = par->dev;
243 struct drm_mode_set *modeset;
244 struct drm_crtc *crtc;
245 struct intel_crtc *intel_crtc;
246 int ret = 0;
247 int i;
248
249 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
250 for (i = 0; i < par->crtc_count; i++)
251 if (crtc->base.id == par->crtc_ids[i])
252 break;
253
254 if (i == par->crtc_count)
255 continue;
256
257 intel_crtc = to_intel_crtc(crtc);
258 modeset = &intel_crtc->mode_set;
259
260 modeset->x = var->xoffset;
261 modeset->y = var->yoffset;
262
263 if (modeset->num_connectors) {
264 mutex_lock(&dev->mode_config.mutex);
265 ret = crtc->funcs->set_config(modeset);
266 mutex_unlock(&dev->mode_config.mutex);
267 if (!ret) {
268 info->var.xoffset = var->xoffset;
269 info->var.yoffset = var->yoffset;
270 }
271 }
272 }
273
274 return ret;
275}
276
277static void intelfb_on(struct fb_info *info)
278{
279 struct intelfb_par *par = info->par;
280 struct drm_device *dev = par->dev;
281 struct drm_crtc *crtc;
282 struct drm_encoder *encoder;
283 int i;
284
285 /*
286 * For each CRTC in this fb, find all associated encoders
287 * and turn them off, then turn off the CRTC.
288 */
289 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
290 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
291
292 for (i = 0; i < par->crtc_count; i++)
293 if (crtc->base.id == par->crtc_ids[i])
294 break;
295
296 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
297
298 /* Found a CRTC on this fb, now find encoders */
299 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
300 if (encoder->crtc == crtc) {
301 struct drm_encoder_helper_funcs *encoder_funcs;
302 encoder_funcs = encoder->helper_private;
303 encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
304 }
305 }
306 }
307}
308
309static void intelfb_off(struct fb_info *info, int dpms_mode)
310{
311 struct intelfb_par *par = info->par;
312 struct drm_device *dev = par->dev;
313 struct drm_crtc *crtc;
314 struct drm_encoder *encoder;
315 int i;
316
317 /*
318 * For each CRTC in this fb, find all associated encoders
319 * and turn them off, then turn off the CRTC.
320 */
321 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
322 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
323
324 for (i = 0; i < par->crtc_count; i++)
325 if (crtc->base.id == par->crtc_ids[i])
326 break;
327
328 /* Found a CRTC on this fb, now find encoders */
329 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
330 if (encoder->crtc == crtc) {
331 struct drm_encoder_helper_funcs *encoder_funcs;
332 encoder_funcs = encoder->helper_private;
333 encoder_funcs->dpms(encoder, dpms_mode);
334 }
335 }
336 if (dpms_mode == DRM_MODE_DPMS_OFF)
337 crtc_funcs->dpms(crtc, dpms_mode);
338 }
339}
340
341int intelfb_blank(int blank, struct fb_info *info)
342{
343 switch (blank) {
344 case FB_BLANK_UNBLANK:
345 intelfb_on(info);
346 break;
347 case FB_BLANK_NORMAL:
348 intelfb_off(info, DRM_MODE_DPMS_STANDBY);
349 break;
350 case FB_BLANK_HSYNC_SUSPEND:
351 intelfb_off(info, DRM_MODE_DPMS_STANDBY);
352 break;
353 case FB_BLANK_VSYNC_SUSPEND:
354 intelfb_off(info, DRM_MODE_DPMS_SUSPEND);
355 break;
356 case FB_BLANK_POWERDOWN:
357 intelfb_off(info, DRM_MODE_DPMS_OFF);
358 break;
359 }
360 return 0;
361}
362
363static struct fb_ops intelfb_ops = {
364 .owner = THIS_MODULE,
365 .fb_check_var = intelfb_check_var,
366 .fb_set_par = intelfb_set_par,
367 .fb_setcolreg = intelfb_setcolreg,
368 .fb_fillrect = cfb_fillrect,
369 .fb_copyarea = cfb_copyarea,
370 .fb_imageblit = cfb_imageblit,
371 .fb_pan_display = intelfb_pan_display,
372 .fb_blank = intelfb_blank,
373};
374
375/**
376 * Curretly it is assumed that the old framebuffer is reused.
377 *
378 * LOCKING
379 * caller should hold the mode config lock.
380 *
381 */
382int intelfb_resize(struct drm_device *dev, struct drm_crtc *crtc)
383{
384 struct fb_info *info;
385 struct drm_framebuffer *fb;
386 struct drm_display_mode *mode = crtc->desired_mode;
387
388 fb = crtc->fb;
389 if (!fb)
390 return 1;
391
392 info = fb->fbdev;
393 if (!info)
394 return 1;
395
396 if (!mode)
397 return 1;
398
399 info->var.xres = mode->hdisplay;
400 info->var.right_margin = mode->hsync_start - mode->hdisplay;
401 info->var.hsync_len = mode->hsync_end - mode->hsync_start;
402 info->var.left_margin = mode->htotal - mode->hsync_end;
403 info->var.yres = mode->vdisplay;
404 info->var.lower_margin = mode->vsync_start - mode->vdisplay;
405 info->var.vsync_len = mode->vsync_end - mode->vsync_start;
406 info->var.upper_margin = mode->vtotal - mode->vsync_end;
407 info->var.pixclock = 10000000 / mode->htotal * 1000 / mode->vtotal * 100;
408 /* avoid overflow */
409 info->var.pixclock = info->var.pixclock * 1000 / mode->vrefresh;
410
411 return 0;
412}
413EXPORT_SYMBOL(intelfb_resize);
414
415static struct drm_mode_set kernelfb_mode;
416
417int intelfb_panic(struct notifier_block *n, unsigned long ununsed,
418 void *panic_str)
419{
420 DRM_ERROR("panic occurred, switching back to text console\n");
421
422 intelfb_restore();
423 return 0;
424}
425EXPORT_SYMBOL(intelfb_panic);
426
427static struct notifier_block paniced = {
428 .notifier_call = intelfb_panic,
429};
430
431int intelfb_create(struct drm_device *dev, uint32_t fb_width,
432 uint32_t fb_height, uint32_t surface_width,
433 uint32_t surface_height,
434 struct intel_framebuffer **intel_fb_p)
435{
436 struct fb_info *info;
437 struct intelfb_par *par;
438 struct drm_framebuffer *fb;
439 struct intel_framebuffer *intel_fb;
440 struct drm_mode_fb_cmd mode_cmd;
441 struct drm_gem_object *fbo = NULL;
442 struct drm_i915_gem_object *obj_priv;
443 struct device *device = &dev->pdev->dev;
444 int size, ret, mmio_bar = IS_I9XX(dev) ? 0 : 1;
445
446 mode_cmd.width = surface_width;
447 mode_cmd.height = surface_height;
448
449 mode_cmd.bpp = 32;
450 mode_cmd.pitch = mode_cmd.width * ((mode_cmd.bpp + 1) / 8);
451 mode_cmd.depth = 24;
452
453 size = mode_cmd.pitch * mode_cmd.height;
454 size = ALIGN(size, PAGE_SIZE);
455 fbo = drm_gem_object_alloc(dev, size);
456 if (!fbo) {
457 printk(KERN_ERR "failed to allocate framebuffer\n");
458 ret = -ENOMEM;
459 goto out;
460 }
461 obj_priv = fbo->driver_private;
462
463 mutex_lock(&dev->struct_mutex);
464
465 ret = i915_gem_object_pin(fbo, PAGE_SIZE);
466 if (ret) {
467 DRM_ERROR("failed to pin fb: %d\n", ret);
468 goto out_unref;
469 }
470
471 /* Flush everything out, we'll be doing GTT only from now on */
472 i915_gem_object_set_to_gtt_domain(fbo, 1);
473
474 ret = intel_framebuffer_create(dev, &mode_cmd, &fb, fbo);
475 if (ret) {
476 DRM_ERROR("failed to allocate fb.\n");
477 goto out_unref;
478 }
479
480 list_add(&fb->filp_head, &dev->mode_config.fb_kernel_list);
481
482 intel_fb = to_intel_framebuffer(fb);
483 *intel_fb_p = intel_fb;
484
485 info = framebuffer_alloc(sizeof(struct intelfb_par), device);
486 if (!info) {
487 ret = -ENOMEM;
488 goto out_unref;
489 }
490
491 par = info->par;
492
493 strcpy(info->fix.id, "inteldrmfb");
494 info->fix.type = FB_TYPE_PACKED_PIXELS;
495 info->fix.visual = FB_VISUAL_TRUECOLOR;
496 info->fix.type_aux = 0;
497 info->fix.xpanstep = 1; /* doing it in hw */
498 info->fix.ypanstep = 1; /* doing it in hw */
499 info->fix.ywrapstep = 0;
500 info->fix.accel = FB_ACCEL_I830;
501 info->fix.type_aux = 0;
502
503 info->flags = FBINFO_DEFAULT;
504
505 info->fbops = &intelfb_ops;
506
507 info->fix.line_length = fb->pitch;
508 info->fix.smem_start = dev->mode_config.fb_base + obj_priv->gtt_offset;
509 info->fix.smem_len = size;
510
511 info->flags = FBINFO_DEFAULT;
512
513 info->screen_base = ioremap_wc(dev->agp->base + obj_priv->gtt_offset,
514 size);
515 if (!info->screen_base) {
516 ret = -ENOSPC;
517 goto out_unref;
518 }
519 info->screen_size = size;
520
521// memset(info->screen_base, 0, size);
522
523 info->pseudo_palette = fb->pseudo_palette;
524 info->var.xres_virtual = fb->width;
525 info->var.yres_virtual = fb->height;
526 info->var.bits_per_pixel = fb->bits_per_pixel;
527 info->var.xoffset = 0;
528 info->var.yoffset = 0;
529 info->var.activate = FB_ACTIVATE_NOW;
530 info->var.height = -1;
531 info->var.width = -1;
532
533 info->var.xres = fb_width;
534 info->var.yres = fb_height;
535
536 /* FIXME: we really shouldn't expose mmio space at all */
537 info->fix.mmio_start = pci_resource_start(dev->pdev, mmio_bar);
538 info->fix.mmio_len = pci_resource_len(dev->pdev, mmio_bar);
539
540 info->pixmap.size = 64*1024;
541 info->pixmap.buf_align = 8;
542 info->pixmap.access_align = 32;
543 info->pixmap.flags = FB_PIXMAP_SYSTEM;
544 info->pixmap.scan_align = 1;
545
546 switch(fb->depth) {
547 case 8:
548 info->var.red.offset = 0;
549 info->var.green.offset = 0;
550 info->var.blue.offset = 0;
551 info->var.red.length = 8; /* 8bit DAC */
552 info->var.green.length = 8;
553 info->var.blue.length = 8;
554 info->var.transp.offset = 0;
555 info->var.transp.length = 0;
556 break;
557 case 15:
558 info->var.red.offset = 10;
559 info->var.green.offset = 5;
560 info->var.blue.offset = 0;
561 info->var.red.length = 5;
562 info->var.green.length = 5;
563 info->var.blue.length = 5;
564 info->var.transp.offset = 15;
565 info->var.transp.length = 1;
566 break;
567 case 16:
568 info->var.red.offset = 11;
569 info->var.green.offset = 5;
570 info->var.blue.offset = 0;
571 info->var.red.length = 5;
572 info->var.green.length = 6;
573 info->var.blue.length = 5;
574 info->var.transp.offset = 0;
575 break;
576 case 24:
577 info->var.red.offset = 16;
578 info->var.green.offset = 8;
579 info->var.blue.offset = 0;
580 info->var.red.length = 8;
581 info->var.green.length = 8;
582 info->var.blue.length = 8;
583 info->var.transp.offset = 0;
584 info->var.transp.length = 0;
585 break;
586 case 32:
587 info->var.red.offset = 16;
588 info->var.green.offset = 8;
589 info->var.blue.offset = 0;
590 info->var.red.length = 8;
591 info->var.green.length = 8;
592 info->var.blue.length = 8;
593 info->var.transp.offset = 24;
594 info->var.transp.length = 8;
595 break;
596 default:
597 break;
598 }
599
600 fb->fbdev = info;
601
602 par->intel_fb = intel_fb;
603 par->dev = dev;
604
605 /* To allow resizeing without swapping buffers */
606 printk("allocated %dx%d fb: 0x%08x, bo %p\n", intel_fb->base.width,
607 intel_fb->base.height, obj_priv->gtt_offset, fbo);
608
609 mutex_unlock(&dev->struct_mutex);
610 return 0;
611
612out_unref:
613 drm_gem_object_unreference(fbo);
614 mutex_unlock(&dev->struct_mutex);
615out:
616 return ret;
617}
618
619static int intelfb_multi_fb_probe_crtc(struct drm_device *dev, struct drm_crtc *crtc)
620{
621 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
622 struct intel_framebuffer *intel_fb;
623 struct drm_framebuffer *fb;
624 struct drm_connector *connector;
625 struct fb_info *info;
626 struct intelfb_par *par;
627 struct drm_mode_set *modeset;
628 unsigned int width, height;
629 int new_fb = 0;
630 int ret, i, conn_count;
631
632 if (!drm_helper_crtc_in_use(crtc))
633 return 0;
634
635 if (!crtc->desired_mode)
636 return 0;
637
638 width = crtc->desired_mode->hdisplay;
639 height = crtc->desired_mode->vdisplay;
640
641 /* is there an fb bound to this crtc already */
642 if (!intel_crtc->mode_set.fb) {
643 ret = intelfb_create(dev, width, height, width, height, &intel_fb);
644 if (ret)
645 return -EINVAL;
646 new_fb = 1;
647 } else {
648 fb = intel_crtc->mode_set.fb;
649 intel_fb = to_intel_framebuffer(fb);
650 if ((intel_fb->base.width < width) || (intel_fb->base.height < height))
651 return -EINVAL;
652 }
653
654 info = intel_fb->base.fbdev;
655 par = info->par;
656
657 modeset = &intel_crtc->mode_set;
658 modeset->fb = &intel_fb->base;
659 conn_count = 0;
660 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
661 if (connector->encoder)
662 if (connector->encoder->crtc == modeset->crtc) {
663 modeset->connectors[conn_count] = connector;
664 conn_count++;
665 if (conn_count > INTELFB_CONN_LIMIT)
666 BUG();
667 }
668 }
669
670 for (i = conn_count; i < INTELFB_CONN_LIMIT; i++)
671 modeset->connectors[i] = NULL;
672
673 par->crtc_ids[0] = crtc->base.id;
674
675 modeset->num_connectors = conn_count;
676 if (modeset->mode != modeset->crtc->desired_mode)
677 modeset->mode = modeset->crtc->desired_mode;
678
679 par->crtc_count = 1;
680
681 if (new_fb) {
682 info->var.pixclock = -1;
683 if (register_framebuffer(info) < 0)
684 return -EINVAL;
685 } else
686 intelfb_set_par(info);
687
688 printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
689 info->fix.id);
690
691 /* Switch back to kernel console on panic */
692 kernelfb_mode = *modeset;
693 atomic_notifier_chain_register(&panic_notifier_list, &paniced);
694 printk(KERN_INFO "registered panic notifier\n");
695
696 return 0;
697}
698
699static int intelfb_multi_fb_probe(struct drm_device *dev)
700{
701
702 struct drm_crtc *crtc;
703 int ret = 0;
704
705 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
706 ret = intelfb_multi_fb_probe_crtc(dev, crtc);
707 if (ret)
708 return ret;
709 }
710 return ret;
711}
712
713static int intelfb_single_fb_probe(struct drm_device *dev)
714{
715 struct drm_crtc *crtc;
716 struct drm_connector *connector;
717 unsigned int fb_width = (unsigned)-1, fb_height = (unsigned)-1;
718 unsigned int surface_width = 0, surface_height = 0;
719 int new_fb = 0;
720 int crtc_count = 0;
721 int ret, i, conn_count = 0;
722 struct intel_framebuffer *intel_fb;
723 struct fb_info *info;
724 struct intelfb_par *par;
725 struct drm_mode_set *modeset = NULL;
726
727 DRM_DEBUG("\n");
728
729 /* Get a count of crtcs now in use and new min/maxes width/heights */
730 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
731 if (!drm_helper_crtc_in_use(crtc))
732 continue;
733
734 crtc_count++;
735 if (!crtc->desired_mode)
736 continue;
737
738 /* Smallest mode determines console size... */
739 if (crtc->desired_mode->hdisplay < fb_width)
740 fb_width = crtc->desired_mode->hdisplay;
741
742 if (crtc->desired_mode->vdisplay < fb_height)
743 fb_height = crtc->desired_mode->vdisplay;
744
745 /* ... but largest for memory allocation dimensions */
746 if (crtc->desired_mode->hdisplay > surface_width)
747 surface_width = crtc->desired_mode->hdisplay;
748
749 if (crtc->desired_mode->vdisplay > surface_height)
750 surface_height = crtc->desired_mode->vdisplay;
751 }
752
753 if (crtc_count == 0 || fb_width == -1 || fb_height == -1) {
754 /* hmm everyone went away - assume VGA cable just fell out
755 and will come back later. */
756 DRM_DEBUG("no CRTCs available?\n");
757 return 0;
758 }
759
760//fail
761 /* Find the fb for our new config */
762 if (list_empty(&dev->mode_config.fb_kernel_list)) {
763 DRM_DEBUG("creating new fb (console size %dx%d, "
764 "buffer size %dx%d)\n", fb_width, fb_height,
765 surface_width, surface_height);
766 ret = intelfb_create(dev, fb_width, fb_height, surface_width,
767 surface_height, &intel_fb);
768 if (ret)
769 return -EINVAL;
770 new_fb = 1;
771 } else {
772 struct drm_framebuffer *fb;
773
774 fb = list_first_entry(&dev->mode_config.fb_kernel_list,
775 struct drm_framebuffer, filp_head);
776 intel_fb = to_intel_framebuffer(fb);
777
778 /* if someone hotplugs something bigger than we have already
779 * allocated, we are pwned. As really we can't resize an
780 * fbdev that is in the wild currently due to fbdev not really
781 * being designed for the lower layers moving stuff around
782 * under it.
783 * - so in the grand style of things - punt.
784 */
785 if ((fb->width < surface_width) ||
786 (fb->height < surface_height)) {
787 DRM_ERROR("fb not large enough for console\n");
788 return -EINVAL;
789 }
790 }
791// fail
792
793 info = intel_fb->base.fbdev;
794 par = info->par;
795
796 crtc_count = 0;
797 /*
798 * For each CRTC, set up the connector list for the CRTC's mode
799 * set configuration.
800 */
801 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
802 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
803
804 modeset = &intel_crtc->mode_set;
805 modeset->fb = &intel_fb->base;
806 conn_count = 0;
807 list_for_each_entry(connector, &dev->mode_config.connector_list,
808 head) {
809 if (!connector->encoder)
810 continue;
811
812 if(connector->encoder->crtc == modeset->crtc) {
813 modeset->connectors[conn_count++] = connector;
814 if (conn_count > INTELFB_CONN_LIMIT)
815 BUG();
816 }
817 }
818
819 /* Zero out remaining connector pointers */
820 for (i = conn_count; i < INTELFB_CONN_LIMIT; i++)
821 modeset->connectors[i] = NULL;
822
823 par->crtc_ids[crtc_count++] = crtc->base.id;
824
825 modeset->num_connectors = conn_count;
826 if (modeset->mode != modeset->crtc->desired_mode)
827 modeset->mode = modeset->crtc->desired_mode;
828 }
829 par->crtc_count = crtc_count;
830
831 if (new_fb) {
832 info->var.pixclock = -1;
833 if (register_framebuffer(info) < 0)
834 return -EINVAL;
835 } else
836 intelfb_set_par(info);
837
838 printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
839 info->fix.id);
840
841 /* Switch back to kernel console on panic */
842 kernelfb_mode = *modeset;
843 atomic_notifier_chain_register(&panic_notifier_list, &paniced);
844 printk(KERN_INFO "registered panic notifier\n");
845
846 return 0;
847}
848
849/**
850 * intelfb_restore - restore the framebuffer console (kernel) config
851 *
852 * Restore's the kernel's fbcon mode, used for lastclose & panic paths.
853 */
854void intelfb_restore(void)
855{
856 drm_crtc_helper_set_config(&kernelfb_mode);
857}
858
859static void intelfb_sysrq(int dummy1, struct tty_struct *dummy3)
860{
861 intelfb_restore();
862}
863
864static struct sysrq_key_op sysrq_intelfb_restore_op = {
865 .handler = intelfb_sysrq,
866 .help_msg = "force fb",
867 .action_msg = "force restore of fb console",
868};
869
870int intelfb_probe(struct drm_device *dev)
871{
872 int ret;
873
874 DRM_DEBUG("\n");
875
876 /* something has changed in the lower levels of hell - deal with it
877 here */
878
879 /* two modes : a) 1 fb to rule all crtcs.
880 b) one fb per crtc.
881 two actions 1) new connected device
882 2) device removed.
883 case a/1 : if the fb surface isn't big enough - resize the surface fb.
884 if the fb size isn't big enough - resize fb into surface.
885 if everything big enough configure the new crtc/etc.
886 case a/2 : undo the configuration
887 possibly resize down the fb to fit the new configuration.
888 case b/1 : see if it is on a new crtc - setup a new fb and add it.
889 case b/2 : teardown the new fb.
890 */
891
892 /* mode a first */
893 /* search for an fb */
894 if (i915_fbpercrtc == 1) {
895 ret = intelfb_multi_fb_probe(dev);
896 } else {
897 ret = intelfb_single_fb_probe(dev);
898 }
899
900 register_sysrq_key('g', &sysrq_intelfb_restore_op);
901
902 return ret;
903}
904EXPORT_SYMBOL(intelfb_probe);
905
906int intelfb_remove(struct drm_device *dev, struct drm_framebuffer *fb)
907{
908 struct fb_info *info;
909
910 if (!fb)
911 return -EINVAL;
912
913 info = fb->fbdev;
914
915 if (info) {
916 unregister_framebuffer(info);
917 iounmap(info->screen_base);
918 framebuffer_release(info);
919 }
920
921 atomic_notifier_chain_unregister(&panic_notifier_list, &paniced);
922 memset(&kernelfb_mode, 0, sizeof(struct drm_mode_set));
923 return 0;
924}
925EXPORT_SYMBOL(intelfb_remove);
926MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c
new file mode 100644
index 000000000000..a5a2f5339e9e
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_i2c.c
@@ -0,0 +1,184 @@
1/*
2 * Copyright (c) 2006 Dave Airlie <airlied@linux.ie>
3 * Copyright © 2006-2008 Intel Corporation
4 * Jesse Barnes <jesse.barnes@intel.com>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 *
25 * Authors:
26 * Eric Anholt <eric@anholt.net>
27 */
28#include <linux/i2c.h>
29#include <linux/i2c-id.h>
30#include <linux/i2c-algo-bit.h>
31#include "drmP.h"
32#include "drm.h"
33#include "intel_drv.h"
34#include "i915_drm.h"
35#include "i915_drv.h"
36
37/*
38 * Intel GPIO access functions
39 */
40
41#define I2C_RISEFALL_TIME 20
42
43static int get_clock(void *data)
44{
45 struct intel_i2c_chan *chan = data;
46 struct drm_i915_private *dev_priv = chan->drm_dev->dev_private;
47 u32 val;
48
49 val = I915_READ(chan->reg);
50 return ((val & GPIO_CLOCK_VAL_IN) != 0);
51}
52
53static int get_data(void *data)
54{
55 struct intel_i2c_chan *chan = data;
56 struct drm_i915_private *dev_priv = chan->drm_dev->dev_private;
57 u32 val;
58
59 val = I915_READ(chan->reg);
60 return ((val & GPIO_DATA_VAL_IN) != 0);
61}
62
63static void set_clock(void *data, int state_high)
64{
65 struct intel_i2c_chan *chan = data;
66 struct drm_device *dev = chan->drm_dev;
67 struct drm_i915_private *dev_priv = chan->drm_dev->dev_private;
68 u32 reserved = 0, clock_bits;
69
70 /* On most chips, these bits must be preserved in software. */
71 if (!IS_I830(dev) && !IS_845G(dev))
72 reserved = I915_READ(chan->reg) & (GPIO_DATA_PULLUP_DISABLE |
73 GPIO_CLOCK_PULLUP_DISABLE);
74
75 if (state_high)
76 clock_bits = GPIO_CLOCK_DIR_IN | GPIO_CLOCK_DIR_MASK;
77 else
78 clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK |
79 GPIO_CLOCK_VAL_MASK;
80 I915_WRITE(chan->reg, reserved | clock_bits);
81 udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */
82}
83
84static void set_data(void *data, int state_high)
85{
86 struct intel_i2c_chan *chan = data;
87 struct drm_device *dev = chan->drm_dev;
88 struct drm_i915_private *dev_priv = chan->drm_dev->dev_private;
89 u32 reserved = 0, data_bits;
90
91 /* On most chips, these bits must be preserved in software. */
92 if (!IS_I830(dev) && !IS_845G(dev))
93 reserved = I915_READ(chan->reg) & (GPIO_DATA_PULLUP_DISABLE |
94 GPIO_CLOCK_PULLUP_DISABLE);
95
96 if (state_high)
97 data_bits = GPIO_DATA_DIR_IN | GPIO_DATA_DIR_MASK;
98 else
99 data_bits = GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK |
100 GPIO_DATA_VAL_MASK;
101
102 I915_WRITE(chan->reg, reserved | data_bits);
103 udelay(I2C_RISEFALL_TIME); /* wait for the line to change state */
104}
105
106/**
107 * intel_i2c_create - instantiate an Intel i2c bus using the specified GPIO reg
108 * @dev: DRM device
109 * @output: driver specific output device
110 * @reg: GPIO reg to use
111 * @name: name for this bus
112 *
113 * Creates and registers a new i2c bus with the Linux i2c layer, for use
114 * in output probing and control (e.g. DDC or SDVO control functions).
115 *
116 * Possible values for @reg include:
117 * %GPIOA
118 * %GPIOB
119 * %GPIOC
120 * %GPIOD
121 * %GPIOE
122 * %GPIOF
123 * %GPIOG
124 * %GPIOH
125 * see PRM for details on how these different busses are used.
126 */
127struct intel_i2c_chan *intel_i2c_create(struct drm_device *dev, const u32 reg,
128 const char *name)
129{
130 struct intel_i2c_chan *chan;
131
132 chan = kzalloc(sizeof(struct intel_i2c_chan), GFP_KERNEL);
133 if (!chan)
134 goto out_free;
135
136 chan->drm_dev = dev;
137 chan->reg = reg;
138 snprintf(chan->adapter.name, I2C_NAME_SIZE, "intel drm %s", name);
139 chan->adapter.owner = THIS_MODULE;
140#ifndef I2C_HW_B_INTELFB
141#define I2C_HW_B_INTELFB I2C_HW_B_I810
142#endif
143 chan->adapter.id = I2C_HW_B_INTELFB;
144 chan->adapter.algo_data = &chan->algo;
145 chan->adapter.dev.parent = &dev->pdev->dev;
146 chan->algo.setsda = set_data;
147 chan->algo.setscl = set_clock;
148 chan->algo.getsda = get_data;
149 chan->algo.getscl = get_clock;
150 chan->algo.udelay = 20;
151 chan->algo.timeout = usecs_to_jiffies(2200);
152 chan->algo.data = chan;
153
154 i2c_set_adapdata(&chan->adapter, chan);
155
156 if(i2c_bit_add_bus(&chan->adapter))
157 goto out_free;
158
159 /* JJJ: raise SCL and SDA? */
160 set_data(chan, 1);
161 set_clock(chan, 1);
162 udelay(20);
163
164 return chan;
165
166out_free:
167 kfree(chan);
168 return NULL;
169}
170
171/**
172 * intel_i2c_destroy - unregister and free i2c bus resources
173 * @output: channel to free
174 *
175 * Unregister the adapter from the i2c layer, then free the structure.
176 */
177void intel_i2c_destroy(struct intel_i2c_chan *chan)
178{
179 if (!chan)
180 return;
181
182 i2c_del_adapter(&chan->adapter);
183 kfree(chan);
184}
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
new file mode 100644
index 000000000000..ccecfaf6307b
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -0,0 +1,525 @@
1/*
2 * Copyright © 2006-2007 Intel Corporation
3 * Copyright (c) 2006 Dave Airlie <airlied@linux.ie>
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Eric Anholt <eric@anholt.net>
26 * Dave Airlie <airlied@linux.ie>
27 * Jesse Barnes <jesse.barnes@intel.com>
28 */
29
30#include <linux/i2c.h>
31#include "drmP.h"
32#include "drm.h"
33#include "drm_crtc.h"
34#include "drm_edid.h"
35#include "intel_drv.h"
36#include "i915_drm.h"
37#include "i915_drv.h"
38
39/**
40 * Sets the backlight level.
41 *
42 * \param level backlight level, from 0 to intel_lvds_get_max_backlight().
43 */
44static void intel_lvds_set_backlight(struct drm_device *dev, int level)
45{
46 struct drm_i915_private *dev_priv = dev->dev_private;
47 u32 blc_pwm_ctl;
48
49 blc_pwm_ctl = I915_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
50 I915_WRITE(BLC_PWM_CTL, (blc_pwm_ctl |
51 (level << BACKLIGHT_DUTY_CYCLE_SHIFT)));
52}
53
54/**
55 * Returns the maximum level of the backlight duty cycle field.
56 */
57static u32 intel_lvds_get_max_backlight(struct drm_device *dev)
58{
59 struct drm_i915_private *dev_priv = dev->dev_private;
60
61 return ((I915_READ(BLC_PWM_CTL) & BACKLIGHT_MODULATION_FREQ_MASK) >>
62 BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
63}
64
65/**
66 * Sets the power state for the panel.
67 */
68static void intel_lvds_set_power(struct drm_device *dev, bool on)
69{
70 struct drm_i915_private *dev_priv = dev->dev_private;
71 u32 pp_status;
72
73 if (on) {
74 I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) |
75 POWER_TARGET_ON);
76 do {
77 pp_status = I915_READ(PP_STATUS);
78 } while ((pp_status & PP_ON) == 0);
79
80 intel_lvds_set_backlight(dev, dev_priv->backlight_duty_cycle);
81 } else {
82 intel_lvds_set_backlight(dev, 0);
83
84 I915_WRITE(PP_CONTROL, I915_READ(PP_CONTROL) &
85 ~POWER_TARGET_ON);
86 do {
87 pp_status = I915_READ(PP_STATUS);
88 } while (pp_status & PP_ON);
89 }
90}
91
92static void intel_lvds_dpms(struct drm_encoder *encoder, int mode)
93{
94 struct drm_device *dev = encoder->dev;
95
96 if (mode == DRM_MODE_DPMS_ON)
97 intel_lvds_set_power(dev, true);
98 else
99 intel_lvds_set_power(dev, false);
100
101 /* XXX: We never power down the LVDS pairs. */
102}
103
104static void intel_lvds_save(struct drm_connector *connector)
105{
106 struct drm_device *dev = connector->dev;
107 struct drm_i915_private *dev_priv = dev->dev_private;
108
109 dev_priv->savePP_ON = I915_READ(PP_ON_DELAYS);
110 dev_priv->savePP_OFF = I915_READ(PP_OFF_DELAYS);
111 dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL);
112 dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR);
113 dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL);
114 dev_priv->backlight_duty_cycle = (dev_priv->saveBLC_PWM_CTL &
115 BACKLIGHT_DUTY_CYCLE_MASK);
116
117 /*
118 * If the light is off at server startup, just make it full brightness
119 */
120 if (dev_priv->backlight_duty_cycle == 0)
121 dev_priv->backlight_duty_cycle =
122 intel_lvds_get_max_backlight(dev);
123}
124
125static void intel_lvds_restore(struct drm_connector *connector)
126{
127 struct drm_device *dev = connector->dev;
128 struct drm_i915_private *dev_priv = dev->dev_private;
129
130 I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL);
131 I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON);
132 I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF);
133 I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR);
134 I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL);
135 if (dev_priv->savePP_CONTROL & POWER_TARGET_ON)
136 intel_lvds_set_power(dev, true);
137 else
138 intel_lvds_set_power(dev, false);
139}
140
141static int intel_lvds_mode_valid(struct drm_connector *connector,
142 struct drm_display_mode *mode)
143{
144 struct drm_device *dev = connector->dev;
145 struct drm_i915_private *dev_priv = dev->dev_private;
146 struct drm_display_mode *fixed_mode = dev_priv->panel_fixed_mode;
147
148 if (fixed_mode) {
149 if (mode->hdisplay > fixed_mode->hdisplay)
150 return MODE_PANEL;
151 if (mode->vdisplay > fixed_mode->vdisplay)
152 return MODE_PANEL;
153 }
154
155 return MODE_OK;
156}
157
158static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
159 struct drm_display_mode *mode,
160 struct drm_display_mode *adjusted_mode)
161{
162 struct drm_device *dev = encoder->dev;
163 struct drm_i915_private *dev_priv = dev->dev_private;
164 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
165 struct drm_encoder *tmp_encoder;
166
167 /* Should never happen!! */
168 if (!IS_I965G(dev) && intel_crtc->pipe == 0) {
169 printk(KERN_ERR "Can't support LVDS on pipe A\n");
170 return false;
171 }
172
173 /* Should never happen!! */
174 list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list, head) {
175 if (tmp_encoder != encoder && tmp_encoder->crtc == encoder->crtc) {
176 printk(KERN_ERR "Can't enable LVDS and another "
177 "encoder on the same pipe\n");
178 return false;
179 }
180 }
181
182 /*
183 * If we have timings from the BIOS for the panel, put them in
184 * to the adjusted mode. The CRTC will be set up for this mode,
185 * with the panel scaling set up to source from the H/VDisplay
186 * of the original mode.
187 */
188 if (dev_priv->panel_fixed_mode != NULL) {
189 adjusted_mode->hdisplay = dev_priv->panel_fixed_mode->hdisplay;
190 adjusted_mode->hsync_start =
191 dev_priv->panel_fixed_mode->hsync_start;
192 adjusted_mode->hsync_end =
193 dev_priv->panel_fixed_mode->hsync_end;
194 adjusted_mode->htotal = dev_priv->panel_fixed_mode->htotal;
195 adjusted_mode->vdisplay = dev_priv->panel_fixed_mode->vdisplay;
196 adjusted_mode->vsync_start =
197 dev_priv->panel_fixed_mode->vsync_start;
198 adjusted_mode->vsync_end =
199 dev_priv->panel_fixed_mode->vsync_end;
200 adjusted_mode->vtotal = dev_priv->panel_fixed_mode->vtotal;
201 adjusted_mode->clock = dev_priv->panel_fixed_mode->clock;
202 drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
203 }
204
205 /*
206 * XXX: It would be nice to support lower refresh rates on the
207 * panels to reduce power consumption, and perhaps match the
208 * user's requested refresh rate.
209 */
210
211 return true;
212}
213
214static void intel_lvds_prepare(struct drm_encoder *encoder)
215{
216 struct drm_device *dev = encoder->dev;
217 struct drm_i915_private *dev_priv = dev->dev_private;
218
219 dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL);
220 dev_priv->backlight_duty_cycle = (dev_priv->saveBLC_PWM_CTL &
221 BACKLIGHT_DUTY_CYCLE_MASK);
222
223 intel_lvds_set_power(dev, false);
224}
225
226static void intel_lvds_commit( struct drm_encoder *encoder)
227{
228 struct drm_device *dev = encoder->dev;
229 struct drm_i915_private *dev_priv = dev->dev_private;
230
231 if (dev_priv->backlight_duty_cycle == 0)
232 dev_priv->backlight_duty_cycle =
233 intel_lvds_get_max_backlight(dev);
234
235 intel_lvds_set_power(dev, true);
236}
237
238static void intel_lvds_mode_set(struct drm_encoder *encoder,
239 struct drm_display_mode *mode,
240 struct drm_display_mode *adjusted_mode)
241{
242 struct drm_device *dev = encoder->dev;
243 struct drm_i915_private *dev_priv = dev->dev_private;
244 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
245 u32 pfit_control;
246
247 /*
248 * The LVDS pin pair will already have been turned on in the
249 * intel_crtc_mode_set since it has a large impact on the DPLL
250 * settings.
251 */
252
253 /*
254 * Enable automatic panel scaling so that non-native modes fill the
255 * screen. Should be enabled before the pipe is enabled, according to
256 * register description and PRM.
257 */
258 if (mode->hdisplay != adjusted_mode->hdisplay ||
259 mode->vdisplay != adjusted_mode->vdisplay)
260 pfit_control = (PFIT_ENABLE | VERT_AUTO_SCALE |
261 HORIZ_AUTO_SCALE | VERT_INTERP_BILINEAR |
262 HORIZ_INTERP_BILINEAR);
263 else
264 pfit_control = 0;
265
266 if (!IS_I965G(dev)) {
267 if (dev_priv->panel_wants_dither)
268 pfit_control |= PANEL_8TO6_DITHER_ENABLE;
269 }
270 else
271 pfit_control |= intel_crtc->pipe << PFIT_PIPE_SHIFT;
272
273 I915_WRITE(PFIT_CONTROL, pfit_control);
274}
275
276/**
277 * Detect the LVDS connection.
278 *
279 * This always returns CONNECTOR_STATUS_CONNECTED. This connector should only have
280 * been set up if the LVDS was actually connected anyway.
281 */
282static enum drm_connector_status intel_lvds_detect(struct drm_connector *connector)
283{
284 return connector_status_connected;
285}
286
287/**
288 * Return the list of DDC modes if available, or the BIOS fixed mode otherwise.
289 */
290static int intel_lvds_get_modes(struct drm_connector *connector)
291{
292 struct drm_device *dev = connector->dev;
293 struct intel_output *intel_output = to_intel_output(connector);
294 struct drm_i915_private *dev_priv = dev->dev_private;
295 int ret = 0;
296
297 ret = intel_ddc_get_modes(intel_output);
298
299 if (ret)
300 return ret;
301
302 /* Didn't get an EDID, so
303 * Set wide sync ranges so we get all modes
304 * handed to valid_mode for checking
305 */
306 connector->display_info.min_vfreq = 0;
307 connector->display_info.max_vfreq = 200;
308 connector->display_info.min_hfreq = 0;
309 connector->display_info.max_hfreq = 200;
310
311 if (dev_priv->panel_fixed_mode != NULL) {
312 struct drm_display_mode *mode;
313
314 mutex_unlock(&dev->mode_config.mutex);
315 mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode);
316 drm_mode_probed_add(connector, mode);
317 mutex_unlock(&dev->mode_config.mutex);
318
319 return 1;
320 }
321
322 return 0;
323}
324
325/**
326 * intel_lvds_destroy - unregister and free LVDS structures
327 * @connector: connector to free
328 *
329 * Unregister the DDC bus for this connector then free the driver private
330 * structure.
331 */
332static void intel_lvds_destroy(struct drm_connector *connector)
333{
334 struct intel_output *intel_output = to_intel_output(connector);
335
336 if (intel_output->ddc_bus)
337 intel_i2c_destroy(intel_output->ddc_bus);
338 drm_sysfs_connector_remove(connector);
339 drm_connector_cleanup(connector);
340 kfree(connector);
341}
342
343static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = {
344 .dpms = intel_lvds_dpms,
345 .mode_fixup = intel_lvds_mode_fixup,
346 .prepare = intel_lvds_prepare,
347 .mode_set = intel_lvds_mode_set,
348 .commit = intel_lvds_commit,
349};
350
351static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs = {
352 .get_modes = intel_lvds_get_modes,
353 .mode_valid = intel_lvds_mode_valid,
354 .best_encoder = intel_best_encoder,
355};
356
357static const struct drm_connector_funcs intel_lvds_connector_funcs = {
358 .save = intel_lvds_save,
359 .restore = intel_lvds_restore,
360 .detect = intel_lvds_detect,
361 .fill_modes = drm_helper_probe_single_connector_modes,
362 .destroy = intel_lvds_destroy,
363};
364
365
366static void intel_lvds_enc_destroy(struct drm_encoder *encoder)
367{
368 drm_encoder_cleanup(encoder);
369}
370
371static const struct drm_encoder_funcs intel_lvds_enc_funcs = {
372 .destroy = intel_lvds_enc_destroy,
373};
374
375
376
377/**
378 * intel_lvds_init - setup LVDS connectors on this device
379 * @dev: drm device
380 *
381 * Create the connector, register the LVDS DDC bus, and try to figure out what
382 * modes we can display on the LVDS panel (if present).
383 */
384void intel_lvds_init(struct drm_device *dev)
385{
386 struct drm_i915_private *dev_priv = dev->dev_private;
387 struct intel_output *intel_output;
388 struct drm_connector *connector;
389 struct drm_encoder *encoder;
390 struct drm_display_mode *scan; /* *modes, *bios_mode; */
391 struct drm_crtc *crtc;
392 u32 lvds;
393 int pipe;
394
395 intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL);
396 if (!intel_output) {
397 return;
398 }
399
400 connector = &intel_output->base;
401 encoder = &intel_output->enc;
402 drm_connector_init(dev, &intel_output->base, &intel_lvds_connector_funcs,
403 DRM_MODE_CONNECTOR_LVDS);
404
405 drm_encoder_init(dev, &intel_output->enc, &intel_lvds_enc_funcs,
406 DRM_MODE_ENCODER_LVDS);
407
408 drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
409 intel_output->type = INTEL_OUTPUT_LVDS;
410
411 drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs);
412 drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs);
413 connector->display_info.subpixel_order = SubPixelHorizontalRGB;
414 connector->interlace_allowed = false;
415 connector->doublescan_allowed = false;
416
417
418 /*
419 * LVDS discovery:
420 * 1) check for EDID on DDC
421 * 2) check for VBT data
422 * 3) check to see if LVDS is already on
423 * if none of the above, no panel
424 * 4) make sure lid is open
425 * if closed, act like it's not there for now
426 */
427
428 /* Set up the DDC bus. */
429 intel_output->ddc_bus = intel_i2c_create(dev, GPIOC, "LVDSDDC_C");
430 if (!intel_output->ddc_bus) {
431 dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
432 "failed.\n");
433 goto failed;
434 }
435
436 /*
437 * Attempt to get the fixed panel mode from DDC. Assume that the
438 * preferred mode is the right one.
439 */
440 intel_ddc_get_modes(intel_output);
441
442 list_for_each_entry(scan, &connector->probed_modes, head) {
443 mutex_lock(&dev->mode_config.mutex);
444 if (scan->type & DRM_MODE_TYPE_PREFERRED) {
445 dev_priv->panel_fixed_mode =
446 drm_mode_duplicate(dev, scan);
447 mutex_unlock(&dev->mode_config.mutex);
448 goto out; /* FIXME: check for quirks */
449 }
450 mutex_unlock(&dev->mode_config.mutex);
451 }
452
453 /* Failed to get EDID, what about VBT? */
454 if (dev_priv->vbt_mode) {
455 mutex_lock(&dev->mode_config.mutex);
456 dev_priv->panel_fixed_mode =
457 drm_mode_duplicate(dev, dev_priv->vbt_mode);
458 mutex_unlock(&dev->mode_config.mutex);
459 }
460
461 /*
462 * If we didn't get EDID, try checking if the panel is already turned
463 * on. If so, assume that whatever is currently programmed is the
464 * correct mode.
465 */
466 lvds = I915_READ(LVDS);
467 pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0;
468 crtc = intel_get_crtc_from_pipe(dev, pipe);
469
470 if (crtc && (lvds & LVDS_PORT_EN)) {
471 dev_priv->panel_fixed_mode = intel_crtc_mode_get(dev, crtc);
472 if (dev_priv->panel_fixed_mode) {
473 dev_priv->panel_fixed_mode->type |=
474 DRM_MODE_TYPE_PREFERRED;
475 goto out; /* FIXME: check for quirks */
476 }
477 }
478
479 /* If we still don't have a mode after all that, give up. */
480 if (!dev_priv->panel_fixed_mode)
481 goto failed;
482
483 /* FIXME: detect aopen & mac mini type stuff automatically? */
484 /*
485 * Blacklist machines with BIOSes that list an LVDS panel without
486 * actually having one.
487 */
488 if (IS_I945GM(dev)) {
489 /* aopen mini pc */
490 if (dev->pdev->subsystem_vendor == 0xa0a0)
491 goto failed;
492
493 if ((dev->pdev->subsystem_vendor == 0x8086) &&
494 (dev->pdev->subsystem_device == 0x7270)) {
495 /* It's a Mac Mini or Macbook Pro.
496 *
497 * Apple hardware is out to get us. The macbook pro
498 * has a real LVDS panel, but the mac mini does not,
499 * and they have the same device IDs. We'll
500 * distinguish by panel size, on the assumption
501 * that Apple isn't about to make any machines with an
502 * 800x600 display.
503 */
504
505 if (dev_priv->panel_fixed_mode != NULL &&
506 dev_priv->panel_fixed_mode->hdisplay == 800 &&
507 dev_priv->panel_fixed_mode->vdisplay == 600) {
508 DRM_DEBUG("Suspected Mac Mini, ignoring the LVDS\n");
509 goto failed;
510 }
511 }
512 }
513
514
515out:
516 drm_sysfs_connector_add(connector);
517 return;
518
519failed:
520 DRM_DEBUG("No LVDS modes found, disabling.\n");
521 if (intel_output->ddc_bus)
522 intel_i2c_destroy(intel_output->ddc_bus);
523 drm_connector_cleanup(connector);
524 kfree(connector);
525}
diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c
new file mode 100644
index 000000000000..e42019e5d661
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_modes.c
@@ -0,0 +1,83 @@
1/*
2 * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
3 * Copyright (c) 2007 Intel Corporation
4 * Jesse Barnes <jesse.barnes@intel.com>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 */
25
26#include <linux/i2c.h>
27#include <linux/fb.h>
28#include "drmP.h"
29#include "intel_drv.h"
30
31/**
32 * intel_ddc_probe
33 *
34 */
35bool intel_ddc_probe(struct intel_output *intel_output)
36{
37 u8 out_buf[] = { 0x0, 0x0};
38 u8 buf[2];
39 int ret;
40 struct i2c_msg msgs[] = {
41 {
42 .addr = 0x50,
43 .flags = 0,
44 .len = 1,
45 .buf = out_buf,
46 },
47 {
48 .addr = 0x50,
49 .flags = I2C_M_RD,
50 .len = 1,
51 .buf = buf,
52 }
53 };
54
55 ret = i2c_transfer(&intel_output->ddc_bus->adapter, msgs, 2);
56 if (ret == 2)
57 return true;
58
59 return false;
60}
61
62/**
63 * intel_ddc_get_modes - get modelist from monitor
64 * @connector: DRM connector device to use
65 *
66 * Fetch the EDID information from @connector using the DDC bus.
67 */
68int intel_ddc_get_modes(struct intel_output *intel_output)
69{
70 struct edid *edid;
71 int ret = 0;
72
73 edid = drm_get_edid(&intel_output->base,
74 &intel_output->ddc_bus->adapter);
75 if (edid) {
76 drm_mode_connector_update_edid_property(&intel_output->base,
77 edid);
78 ret = drm_add_edid_modes(&intel_output->base, edid);
79 kfree(edid);
80 }
81
82 return ret;
83}
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
new file mode 100644
index 000000000000..626258d72c90
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -0,0 +1,1127 @@
1/*
2 * Copyright 2006 Dave Airlie <airlied@linux.ie>
3 * Copyright © 2006-2007 Intel Corporation
4 * Jesse Barnes <jesse.barnes@intel.com>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 *
25 * Authors:
26 * Eric Anholt <eric@anholt.net>
27 */
28#include <linux/i2c.h>
29#include <linux/delay.h>
30#include "drmP.h"
31#include "drm.h"
32#include "drm_crtc.h"
33#include "intel_drv.h"
34#include "i915_drm.h"
35#include "i915_drv.h"
36#include "intel_sdvo_regs.h"
37
38#undef SDVO_DEBUG
39
40struct intel_sdvo_priv {
41 struct intel_i2c_chan *i2c_bus;
42 int slaveaddr;
43 int output_device;
44
45 u16 active_outputs;
46
47 struct intel_sdvo_caps caps;
48 int pixel_clock_min, pixel_clock_max;
49
50 int save_sdvo_mult;
51 u16 save_active_outputs;
52 struct intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2;
53 struct intel_sdvo_dtd save_output_dtd[16];
54 u32 save_SDVOX;
55};
56
57/**
58 * Writes the SDVOB or SDVOC with the given value, but always writes both
59 * SDVOB and SDVOC to work around apparent hardware issues (according to
60 * comments in the BIOS).
61 */
62void intel_sdvo_write_sdvox(struct intel_output *intel_output, u32 val)
63{
64 struct drm_device *dev = intel_output->base.dev;
65 struct drm_i915_private *dev_priv = dev->dev_private;
66 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
67 u32 bval = val, cval = val;
68 int i;
69
70 if (sdvo_priv->output_device == SDVOB) {
71 cval = I915_READ(SDVOC);
72 } else {
73 bval = I915_READ(SDVOB);
74 }
75 /*
76 * Write the registers twice for luck. Sometimes,
77 * writing them only once doesn't appear to 'stick'.
78 * The BIOS does this too. Yay, magic
79 */
80 for (i = 0; i < 2; i++)
81 {
82 I915_WRITE(SDVOB, bval);
83 I915_READ(SDVOB);
84 I915_WRITE(SDVOC, cval);
85 I915_READ(SDVOC);
86 }
87}
88
89static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr,
90 u8 *ch)
91{
92 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
93 u8 out_buf[2];
94 u8 buf[2];
95 int ret;
96
97 struct i2c_msg msgs[] = {
98 {
99 .addr = sdvo_priv->i2c_bus->slave_addr,
100 .flags = 0,
101 .len = 1,
102 .buf = out_buf,
103 },
104 {
105 .addr = sdvo_priv->i2c_bus->slave_addr,
106 .flags = I2C_M_RD,
107 .len = 1,
108 .buf = buf,
109 }
110 };
111
112 out_buf[0] = addr;
113 out_buf[1] = 0;
114
115 if ((ret = i2c_transfer(&sdvo_priv->i2c_bus->adapter, msgs, 2)) == 2)
116 {
117 *ch = buf[0];
118 return true;
119 }
120
121 DRM_DEBUG("i2c transfer returned %d\n", ret);
122 return false;
123}
124
125static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr,
126 u8 ch)
127{
128 u8 out_buf[2];
129 struct i2c_msg msgs[] = {
130 {
131 .addr = intel_output->i2c_bus->slave_addr,
132 .flags = 0,
133 .len = 2,
134 .buf = out_buf,
135 }
136 };
137
138 out_buf[0] = addr;
139 out_buf[1] = ch;
140
141 if (i2c_transfer(&intel_output->i2c_bus->adapter, msgs, 1) == 1)
142 {
143 return true;
144 }
145 return false;
146}
147
148#define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd}
149/** Mapping of command numbers to names, for debug output */
150const static struct _sdvo_cmd_name {
151 u8 cmd;
152 char *name;
153} sdvo_cmd_names[] = {
154 SDVO_CMD_NAME_ENTRY(SDVO_CMD_RESET),
155 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DEVICE_CAPS),
156 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FIRMWARE_REV),
157 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TRAINED_INPUTS),
158 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_OUTPUTS),
159 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_OUTPUTS),
160 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_IN_OUT_MAP),
161 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_IN_OUT_MAP),
162 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ATTACHED_DISPLAYS),
163 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HOT_PLUG_SUPPORT),
164 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_HOT_PLUG),
165 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_HOT_PLUG),
166 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE),
167 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_INPUT),
168 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_OUTPUT),
169 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART1),
170 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART2),
171 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1),
172 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART2),
173 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1),
174 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART1),
175 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART2),
176 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART1),
177 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART2),
178 SDVO_CMD_NAME_ENTRY(SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING),
179 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1),
180 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2),
181 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE),
182 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE),
183 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_CLOCK_RATE_MULTS),
184 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_CLOCK_RATE_MULT),
185 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CLOCK_RATE_MULT),
186 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_TV_FORMATS),
187 SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_FORMAT),
188 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_FORMAT),
189 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_RESOLUTION_SUPPORT),
190 SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTROL_BUS_SWITCH),
191};
192
193#define SDVO_NAME(dev_priv) ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC")
194#define SDVO_PRIV(output) ((struct intel_sdvo_priv *) (output)->dev_priv)
195
196#ifdef SDVO_DEBUG
197static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd,
198 void *args, int args_len)
199{
200 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
201 int i;
202
203 DRM_DEBUG("%s: W: %02X ", SDVO_NAME(sdvo_priv), cmd);
204 for (i = 0; i < args_len; i++)
205 printk("%02X ", ((u8 *)args)[i]);
206 for (; i < 8; i++)
207 printk(" ");
208 for (i = 0; i < sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0]); i++) {
209 if (cmd == sdvo_cmd_names[i].cmd) {
210 printk("(%s)", sdvo_cmd_names[i].name);
211 break;
212 }
213 }
214 if (i == sizeof(sdvo_cmd_names)/ sizeof(sdvo_cmd_names[0]))
215 printk("(%02X)",cmd);
216 printk("\n");
217}
218#else
219#define intel_sdvo_debug_write(o, c, a, l)
220#endif
221
222static void intel_sdvo_write_cmd(struct intel_output *intel_output, u8 cmd,
223 void *args, int args_len)
224{
225 int i;
226
227 intel_sdvo_debug_write(intel_output, cmd, args, args_len);
228
229 for (i = 0; i < args_len; i++) {
230 intel_sdvo_write_byte(intel_output, SDVO_I2C_ARG_0 - i,
231 ((u8*)args)[i]);
232 }
233
234 intel_sdvo_write_byte(intel_output, SDVO_I2C_OPCODE, cmd);
235}
236
237#ifdef SDVO_DEBUG
238static const char *cmd_status_names[] = {
239 "Power on",
240 "Success",
241 "Not supported",
242 "Invalid arg",
243 "Pending",
244 "Target not specified",
245 "Scaling not supported"
246};
247
248static void intel_sdvo_debug_response(struct intel_output *intel_output,
249 void *response, int response_len,
250 u8 status)
251{
252 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
253
254 DRM_DEBUG("%s: R: ", SDVO_NAME(sdvo_priv));
255 for (i = 0; i < response_len; i++)
256 printk("%02X ", ((u8 *)response)[i]);
257 for (; i < 8; i++)
258 printk(" ");
259 if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP)
260 printk("(%s)", cmd_status_names[status]);
261 else
262 printk("(??? %d)", status);
263 printk("\n");
264}
265#else
266#define intel_sdvo_debug_response(o, r, l, s)
267#endif
268
269static u8 intel_sdvo_read_response(struct intel_output *intel_output,
270 void *response, int response_len)
271{
272 int i;
273 u8 status;
274 u8 retry = 50;
275
276 while (retry--) {
277 /* Read the command response */
278 for (i = 0; i < response_len; i++) {
279 intel_sdvo_read_byte(intel_output,
280 SDVO_I2C_RETURN_0 + i,
281 &((u8 *)response)[i]);
282 }
283
284 /* read the return status */
285 intel_sdvo_read_byte(intel_output, SDVO_I2C_CMD_STATUS,
286 &status);
287
288 intel_sdvo_debug_response(intel_output, response, response_len,
289 status);
290 if (status != SDVO_CMD_STATUS_PENDING)
291 return status;
292
293 mdelay(50);
294 }
295
296 return status;
297}
298
299int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode)
300{
301 if (mode->clock >= 100000)
302 return 1;
303 else if (mode->clock >= 50000)
304 return 2;
305 else
306 return 4;
307}
308
309/**
310 * Don't check status code from this as it switches the bus back to the
311 * SDVO chips which defeats the purpose of doing a bus switch in the first
312 * place.
313 */
314void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output, u8 target)
315{
316 intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_CONTROL_BUS_SWITCH, &target, 1);
317}
318
319static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool target_0, bool target_1)
320{
321 struct intel_sdvo_set_target_input_args targets = {0};
322 u8 status;
323
324 if (target_0 && target_1)
325 return SDVO_CMD_STATUS_NOTSUPP;
326
327 if (target_1)
328 targets.target_1 = 1;
329
330 intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_TARGET_INPUT, &targets,
331 sizeof(targets));
332
333 status = intel_sdvo_read_response(intel_output, NULL, 0);
334
335 return (status == SDVO_CMD_STATUS_SUCCESS);
336}
337
338/**
339 * Return whether each input is trained.
340 *
341 * This function is making an assumption about the layout of the response,
342 * which should be checked against the docs.
343 */
344static bool intel_sdvo_get_trained_inputs(struct intel_output *intel_output, bool *input_1, bool *input_2)
345{
346 struct intel_sdvo_get_trained_inputs_response response;
347 u8 status;
348
349 intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0);
350 status = intel_sdvo_read_response(intel_output, &response, sizeof(response));
351 if (status != SDVO_CMD_STATUS_SUCCESS)
352 return false;
353
354 *input_1 = response.input0_trained;
355 *input_2 = response.input1_trained;
356 return true;
357}
358
359static bool intel_sdvo_get_active_outputs(struct intel_output *intel_output,
360 u16 *outputs)
361{
362 u8 status;
363
364 intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_OUTPUTS, NULL, 0);
365 status = intel_sdvo_read_response(intel_output, outputs, sizeof(*outputs));
366
367 return (status == SDVO_CMD_STATUS_SUCCESS);
368}
369
370static bool intel_sdvo_set_active_outputs(struct intel_output *intel_output,
371 u16 outputs)
372{
373 u8 status;
374
375 intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs,
376 sizeof(outputs));
377 status = intel_sdvo_read_response(intel_output, NULL, 0);
378 return (status == SDVO_CMD_STATUS_SUCCESS);
379}
380
381static bool intel_sdvo_set_encoder_power_state(struct intel_output *intel_output,
382 int mode)
383{
384 u8 status, state = SDVO_ENCODER_STATE_ON;
385
386 switch (mode) {
387 case DRM_MODE_DPMS_ON:
388 state = SDVO_ENCODER_STATE_ON;
389 break;
390 case DRM_MODE_DPMS_STANDBY:
391 state = SDVO_ENCODER_STATE_STANDBY;
392 break;
393 case DRM_MODE_DPMS_SUSPEND:
394 state = SDVO_ENCODER_STATE_SUSPEND;
395 break;
396 case DRM_MODE_DPMS_OFF:
397 state = SDVO_ENCODER_STATE_OFF;
398 break;
399 }
400
401 intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ENCODER_POWER_STATE, &state,
402 sizeof(state));
403 status = intel_sdvo_read_response(intel_output, NULL, 0);
404
405 return (status == SDVO_CMD_STATUS_SUCCESS);
406}
407
408static bool intel_sdvo_get_input_pixel_clock_range(struct intel_output *intel_output,
409 int *clock_min,
410 int *clock_max)
411{
412 struct intel_sdvo_pixel_clock_range clocks;
413 u8 status;
414
415 intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE,
416 NULL, 0);
417
418 status = intel_sdvo_read_response(intel_output, &clocks, sizeof(clocks));
419
420 if (status != SDVO_CMD_STATUS_SUCCESS)
421 return false;
422
423 /* Convert the values from units of 10 kHz to kHz. */
424 *clock_min = clocks.min * 10;
425 *clock_max = clocks.max * 10;
426
427 return true;
428}
429
430static bool intel_sdvo_set_target_output(struct intel_output *intel_output,
431 u16 outputs)
432{
433 u8 status;
434
435 intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_TARGET_OUTPUT, &outputs,
436 sizeof(outputs));
437
438 status = intel_sdvo_read_response(intel_output, NULL, 0);
439 return (status == SDVO_CMD_STATUS_SUCCESS);
440}
441
442static bool intel_sdvo_get_timing(struct intel_output *intel_output, u8 cmd,
443 struct intel_sdvo_dtd *dtd)
444{
445 u8 status;
446
447 intel_sdvo_write_cmd(intel_output, cmd, NULL, 0);
448 status = intel_sdvo_read_response(intel_output, &dtd->part1,
449 sizeof(dtd->part1));
450 if (status != SDVO_CMD_STATUS_SUCCESS)
451 return false;
452
453 intel_sdvo_write_cmd(intel_output, cmd + 1, NULL, 0);
454 status = intel_sdvo_read_response(intel_output, &dtd->part2,
455 sizeof(dtd->part2));
456 if (status != SDVO_CMD_STATUS_SUCCESS)
457 return false;
458
459 return true;
460}
461
462static bool intel_sdvo_get_input_timing(struct intel_output *intel_output,
463 struct intel_sdvo_dtd *dtd)
464{
465 return intel_sdvo_get_timing(intel_output,
466 SDVO_CMD_GET_INPUT_TIMINGS_PART1, dtd);
467}
468
469static bool intel_sdvo_get_output_timing(struct intel_output *intel_output,
470 struct intel_sdvo_dtd *dtd)
471{
472 return intel_sdvo_get_timing(intel_output,
473 SDVO_CMD_GET_OUTPUT_TIMINGS_PART1, dtd);
474}
475
476static bool intel_sdvo_set_timing(struct intel_output *intel_output, u8 cmd,
477 struct intel_sdvo_dtd *dtd)
478{
479 u8 status;
480
481 intel_sdvo_write_cmd(intel_output, cmd, &dtd->part1, sizeof(dtd->part1));
482 status = intel_sdvo_read_response(intel_output, NULL, 0);
483 if (status != SDVO_CMD_STATUS_SUCCESS)
484 return false;
485
486 intel_sdvo_write_cmd(intel_output, cmd + 1, &dtd->part2, sizeof(dtd->part2));
487 status = intel_sdvo_read_response(intel_output, NULL, 0);
488 if (status != SDVO_CMD_STATUS_SUCCESS)
489 return false;
490
491 return true;
492}
493
494static bool intel_sdvo_set_input_timing(struct intel_output *intel_output,
495 struct intel_sdvo_dtd *dtd)
496{
497 return intel_sdvo_set_timing(intel_output,
498 SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd);
499}
500
501static bool intel_sdvo_set_output_timing(struct intel_output *intel_output,
502 struct intel_sdvo_dtd *dtd)
503{
504 return intel_sdvo_set_timing(intel_output,
505 SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd);
506}
507
508
509static int intel_sdvo_get_clock_rate_mult(struct intel_output *intel_output)
510{
511 u8 response, status;
512
513 intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_CLOCK_RATE_MULT, NULL, 0);
514 status = intel_sdvo_read_response(intel_output, &response, 1);
515
516 if (status != SDVO_CMD_STATUS_SUCCESS) {
517 DRM_DEBUG("Couldn't get SDVO clock rate multiplier\n");
518 return SDVO_CLOCK_RATE_MULT_1X;
519 } else {
520 DRM_DEBUG("Current clock rate multiplier: %d\n", response);
521 }
522
523 return response;
524}
525
526static bool intel_sdvo_set_clock_rate_mult(struct intel_output *intel_output, u8 val)
527{
528 u8 status;
529
530 intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1);
531 status = intel_sdvo_read_response(intel_output, NULL, 0);
532 if (status != SDVO_CMD_STATUS_SUCCESS)
533 return false;
534
535 return true;
536}
537
538static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
539 struct drm_display_mode *mode,
540 struct drm_display_mode *adjusted_mode)
541{
542 /* Make the CRTC code factor in the SDVO pixel multiplier. The SDVO
543 * device will be told of the multiplier during mode_set.
544 */
545 adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode);
546 return true;
547}
548
549static void intel_sdvo_mode_set(struct drm_encoder *encoder,
550 struct drm_display_mode *mode,
551 struct drm_display_mode *adjusted_mode)
552{
553 struct drm_device *dev = encoder->dev;
554 struct drm_i915_private *dev_priv = dev->dev_private;
555 struct drm_crtc *crtc = encoder->crtc;
556 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
557 struct intel_output *intel_output = enc_to_intel_output(encoder);
558 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
559 u16 width, height;
560 u16 h_blank_len, h_sync_len, v_blank_len, v_sync_len;
561 u16 h_sync_offset, v_sync_offset;
562 u32 sdvox;
563 struct intel_sdvo_dtd output_dtd;
564 int sdvo_pixel_multiply;
565
566 if (!mode)
567 return;
568
569 width = mode->crtc_hdisplay;
570 height = mode->crtc_vdisplay;
571
572 /* do some mode translations */
573 h_blank_len = mode->crtc_hblank_end - mode->crtc_hblank_start;
574 h_sync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
575
576 v_blank_len = mode->crtc_vblank_end - mode->crtc_vblank_start;
577 v_sync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
578
579 h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start;
580 v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start;
581
582 output_dtd.part1.clock = mode->clock / 10;
583 output_dtd.part1.h_active = width & 0xff;
584 output_dtd.part1.h_blank = h_blank_len & 0xff;
585 output_dtd.part1.h_high = (((width >> 8) & 0xf) << 4) |
586 ((h_blank_len >> 8) & 0xf);
587 output_dtd.part1.v_active = height & 0xff;
588 output_dtd.part1.v_blank = v_blank_len & 0xff;
589 output_dtd.part1.v_high = (((height >> 8) & 0xf) << 4) |
590 ((v_blank_len >> 8) & 0xf);
591
592 output_dtd.part2.h_sync_off = h_sync_offset;
593 output_dtd.part2.h_sync_width = h_sync_len & 0xff;
594 output_dtd.part2.v_sync_off_width = (v_sync_offset & 0xf) << 4 |
595 (v_sync_len & 0xf);
596 output_dtd.part2.sync_off_width_high = ((h_sync_offset & 0x300) >> 2) |
597 ((h_sync_len & 0x300) >> 4) | ((v_sync_offset & 0x30) >> 2) |
598 ((v_sync_len & 0x30) >> 4);
599
600 output_dtd.part2.dtd_flags = 0x18;
601 if (mode->flags & DRM_MODE_FLAG_PHSYNC)
602 output_dtd.part2.dtd_flags |= 0x2;
603 if (mode->flags & DRM_MODE_FLAG_PVSYNC)
604 output_dtd.part2.dtd_flags |= 0x4;
605
606 output_dtd.part2.sdvo_flags = 0;
607 output_dtd.part2.v_sync_off_high = v_sync_offset & 0xc0;
608 output_dtd.part2.reserved = 0;
609
610 /* Set the output timing to the screen */
611 intel_sdvo_set_target_output(intel_output, sdvo_priv->active_outputs);
612 intel_sdvo_set_output_timing(intel_output, &output_dtd);
613
614 /* Set the input timing to the screen. Assume always input 0. */
615 intel_sdvo_set_target_input(intel_output, true, false);
616
617 /* We would like to use i830_sdvo_create_preferred_input_timing() to
618 * provide the device with a timing it can support, if it supports that
619 * feature. However, presumably we would need to adjust the CRTC to
620 * output the preferred timing, and we don't support that currently.
621 */
622 intel_sdvo_set_input_timing(intel_output, &output_dtd);
623
624 switch (intel_sdvo_get_pixel_multiplier(mode)) {
625 case 1:
626 intel_sdvo_set_clock_rate_mult(intel_output,
627 SDVO_CLOCK_RATE_MULT_1X);
628 break;
629 case 2:
630 intel_sdvo_set_clock_rate_mult(intel_output,
631 SDVO_CLOCK_RATE_MULT_2X);
632 break;
633 case 4:
634 intel_sdvo_set_clock_rate_mult(intel_output,
635 SDVO_CLOCK_RATE_MULT_4X);
636 break;
637 }
638
639 /* Set the SDVO control regs. */
640 if (0/*IS_I965GM(dev)*/) {
641 sdvox = SDVO_BORDER_ENABLE;
642 } else {
643 sdvox = I915_READ(sdvo_priv->output_device);
644 switch (sdvo_priv->output_device) {
645 case SDVOB:
646 sdvox &= SDVOB_PRESERVE_MASK;
647 break;
648 case SDVOC:
649 sdvox &= SDVOC_PRESERVE_MASK;
650 break;
651 }
652 sdvox |= (9 << 19) | SDVO_BORDER_ENABLE;
653 }
654 if (intel_crtc->pipe == 1)
655 sdvox |= SDVO_PIPE_B_SELECT;
656
657 sdvo_pixel_multiply = intel_sdvo_get_pixel_multiplier(mode);
658 if (IS_I965G(dev)) {
659 /* done in crtc_mode_set as the dpll_md reg must be written
660 early */
661 } else if (IS_I945G(dev) || IS_I945GM(dev)) {
662 /* done in crtc_mode_set as it lives inside the
663 dpll register */
664 } else {
665 sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT;
666 }
667
668 intel_sdvo_write_sdvox(intel_output, sdvox);
669}
670
671static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
672{
673 struct drm_device *dev = encoder->dev;
674 struct drm_i915_private *dev_priv = dev->dev_private;
675 struct intel_output *intel_output = enc_to_intel_output(encoder);
676 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
677 u32 temp;
678
679 if (mode != DRM_MODE_DPMS_ON) {
680 intel_sdvo_set_active_outputs(intel_output, 0);
681 if (0)
682 intel_sdvo_set_encoder_power_state(intel_output, mode);
683
684 if (mode == DRM_MODE_DPMS_OFF) {
685 temp = I915_READ(sdvo_priv->output_device);
686 if ((temp & SDVO_ENABLE) != 0) {
687 intel_sdvo_write_sdvox(intel_output, temp & ~SDVO_ENABLE);
688 }
689 }
690 } else {
691 bool input1, input2;
692 int i;
693 u8 status;
694
695 temp = I915_READ(sdvo_priv->output_device);
696 if ((temp & SDVO_ENABLE) == 0)
697 intel_sdvo_write_sdvox(intel_output, temp | SDVO_ENABLE);
698 for (i = 0; i < 2; i++)
699 intel_wait_for_vblank(dev);
700
701 status = intel_sdvo_get_trained_inputs(intel_output, &input1,
702 &input2);
703
704
705 /* Warn if the device reported failure to sync.
706 * A lot of SDVO devices fail to notify of sync, but it's
707 * a given it the status is a success, we succeeded.
708 */
709 if (status == SDVO_CMD_STATUS_SUCCESS && !input1) {
710 DRM_DEBUG("First %s output reported failure to sync\n",
711 SDVO_NAME(sdvo_priv));
712 }
713
714 if (0)
715 intel_sdvo_set_encoder_power_state(intel_output, mode);
716 intel_sdvo_set_active_outputs(intel_output, sdvo_priv->active_outputs);
717 }
718 return;
719}
720
721static void intel_sdvo_save(struct drm_connector *connector)
722{
723 struct drm_device *dev = connector->dev;
724 struct drm_i915_private *dev_priv = dev->dev_private;
725 struct intel_output *intel_output = to_intel_output(connector);
726 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
727 int o;
728
729 sdvo_priv->save_sdvo_mult = intel_sdvo_get_clock_rate_mult(intel_output);
730 intel_sdvo_get_active_outputs(intel_output, &sdvo_priv->save_active_outputs);
731
732 if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) {
733 intel_sdvo_set_target_input(intel_output, true, false);
734 intel_sdvo_get_input_timing(intel_output,
735 &sdvo_priv->save_input_dtd_1);
736 }
737
738 if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) {
739 intel_sdvo_set_target_input(intel_output, false, true);
740 intel_sdvo_get_input_timing(intel_output,
741 &sdvo_priv->save_input_dtd_2);
742 }
743
744 for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++)
745 {
746 u16 this_output = (1 << o);
747 if (sdvo_priv->caps.output_flags & this_output)
748 {
749 intel_sdvo_set_target_output(intel_output, this_output);
750 intel_sdvo_get_output_timing(intel_output,
751 &sdvo_priv->save_output_dtd[o]);
752 }
753 }
754
755 sdvo_priv->save_SDVOX = I915_READ(sdvo_priv->output_device);
756}
757
758static void intel_sdvo_restore(struct drm_connector *connector)
759{
760 struct drm_device *dev = connector->dev;
761 struct drm_i915_private *dev_priv = dev->dev_private;
762 struct intel_output *intel_output = to_intel_output(connector);
763 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
764 int o;
765 int i;
766 bool input1, input2;
767 u8 status;
768
769 intel_sdvo_set_active_outputs(intel_output, 0);
770
771 for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++)
772 {
773 u16 this_output = (1 << o);
774 if (sdvo_priv->caps.output_flags & this_output) {
775 intel_sdvo_set_target_output(intel_output, this_output);
776 intel_sdvo_set_output_timing(intel_output, &sdvo_priv->save_output_dtd[o]);
777 }
778 }
779
780 if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) {
781 intel_sdvo_set_target_input(intel_output, true, false);
782 intel_sdvo_set_input_timing(intel_output, &sdvo_priv->save_input_dtd_1);
783 }
784
785 if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) {
786 intel_sdvo_set_target_input(intel_output, false, true);
787 intel_sdvo_set_input_timing(intel_output, &sdvo_priv->save_input_dtd_2);
788 }
789
790 intel_sdvo_set_clock_rate_mult(intel_output, sdvo_priv->save_sdvo_mult);
791
792 I915_WRITE(sdvo_priv->output_device, sdvo_priv->save_SDVOX);
793
794 if (sdvo_priv->save_SDVOX & SDVO_ENABLE)
795 {
796 for (i = 0; i < 2; i++)
797 intel_wait_for_vblank(dev);
798 status = intel_sdvo_get_trained_inputs(intel_output, &input1, &input2);
799 if (status == SDVO_CMD_STATUS_SUCCESS && !input1)
800 DRM_DEBUG("First %s output reported failure to sync\n",
801 SDVO_NAME(sdvo_priv));
802 }
803
804 intel_sdvo_set_active_outputs(intel_output, sdvo_priv->save_active_outputs);
805}
806
807static int intel_sdvo_mode_valid(struct drm_connector *connector,
808 struct drm_display_mode *mode)
809{
810 struct intel_output *intel_output = to_intel_output(connector);
811 struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
812
813 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
814 return MODE_NO_DBLESCAN;
815
816 if (sdvo_priv->pixel_clock_min > mode->clock)
817 return MODE_CLOCK_LOW;
818
819 if (sdvo_priv->pixel_clock_max < mode->clock)
820 return MODE_CLOCK_HIGH;
821
822 return MODE_OK;
823}
824
825static bool intel_sdvo_get_capabilities(struct intel_output *intel_output, struct intel_sdvo_caps *caps)
826{
827 u8 status;
828
829 intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0);
830 status = intel_sdvo_read_response(intel_output, caps, sizeof(*caps));
831 if (status != SDVO_CMD_STATUS_SUCCESS)
832 return false;
833
834 return true;
835}
836
837struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB)
838{
839 struct drm_connector *connector = NULL;
840 struct intel_output *iout = NULL;
841 struct intel_sdvo_priv *sdvo;
842
843 /* find the sdvo connector */
844 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
845 iout = to_intel_output(connector);
846
847 if (iout->type != INTEL_OUTPUT_SDVO)
848 continue;
849
850 sdvo = iout->dev_priv;
851
852 if (sdvo->output_device == SDVOB && sdvoB)
853 return connector;
854
855 if (sdvo->output_device == SDVOC && !sdvoB)
856 return connector;
857
858 }
859
860 return NULL;
861}
862
863int intel_sdvo_supports_hotplug(struct drm_connector *connector)
864{
865 u8 response[2];
866 u8 status;
867 struct intel_output *intel_output;
868 DRM_DEBUG("\n");
869
870 if (!connector)
871 return 0;
872
873 intel_output = to_intel_output(connector);
874
875 intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
876 status = intel_sdvo_read_response(intel_output, &response, 2);
877
878 if (response[0] !=0)
879 return 1;
880
881 return 0;
882}
883
884void intel_sdvo_set_hotplug(struct drm_connector *connector, int on)
885{
886 u8 response[2];
887 u8 status;
888 struct intel_output *intel_output = to_intel_output(connector);
889
890 intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
891 intel_sdvo_read_response(intel_output, &response, 2);
892
893 if (on) {
894 intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
895 status = intel_sdvo_read_response(intel_output, &response, 2);
896
897 intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
898 } else {
899 response[0] = 0;
900 response[1] = 0;
901 intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
902 }
903
904 intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
905 intel_sdvo_read_response(intel_output, &response, 2);
906}
907
908static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector)
909{
910 u8 response[2];
911 u8 status;
912 struct intel_output *intel_output = to_intel_output(connector);
913
914 intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0);
915 status = intel_sdvo_read_response(intel_output, &response, 2);
916
917 DRM_DEBUG("SDVO response %d %d\n", response[0], response[1]);
918 if ((response[0] != 0) || (response[1] != 0))
919 return connector_status_connected;
920 else
921 return connector_status_disconnected;
922}
923
924static int intel_sdvo_get_modes(struct drm_connector *connector)
925{
926 struct intel_output *intel_output = to_intel_output(connector);
927
928 /* set the bus switch and get the modes */
929 intel_sdvo_set_control_bus_switch(intel_output, SDVO_CONTROL_BUS_DDC2);
930 intel_ddc_get_modes(intel_output);
931
932 if (list_empty(&connector->probed_modes))
933 return 0;
934 return 1;
935}
936
937static void intel_sdvo_destroy(struct drm_connector *connector)
938{
939 struct intel_output *intel_output = to_intel_output(connector);
940
941 if (intel_output->i2c_bus)
942 intel_i2c_destroy(intel_output->i2c_bus);
943 drm_sysfs_connector_remove(connector);
944 drm_connector_cleanup(connector);
945 kfree(intel_output);
946}
947
948static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = {
949 .dpms = intel_sdvo_dpms,
950 .mode_fixup = intel_sdvo_mode_fixup,
951 .prepare = intel_encoder_prepare,
952 .mode_set = intel_sdvo_mode_set,
953 .commit = intel_encoder_commit,
954};
955
956static const struct drm_connector_funcs intel_sdvo_connector_funcs = {
957 .save = intel_sdvo_save,
958 .restore = intel_sdvo_restore,
959 .detect = intel_sdvo_detect,
960 .fill_modes = drm_helper_probe_single_connector_modes,
961 .destroy = intel_sdvo_destroy,
962};
963
964static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs = {
965 .get_modes = intel_sdvo_get_modes,
966 .mode_valid = intel_sdvo_mode_valid,
967 .best_encoder = intel_best_encoder,
968};
969
970void intel_sdvo_enc_destroy(struct drm_encoder *encoder)
971{
972 drm_encoder_cleanup(encoder);
973}
974
975static const struct drm_encoder_funcs intel_sdvo_enc_funcs = {
976 .destroy = intel_sdvo_enc_destroy,
977};
978
979
980void intel_sdvo_init(struct drm_device *dev, int output_device)
981{
982 struct drm_connector *connector;
983 struct intel_output *intel_output;
984 struct intel_sdvo_priv *sdvo_priv;
985 struct intel_i2c_chan *i2cbus = NULL;
986 int connector_type;
987 u8 ch[0x40];
988 int i;
989 int encoder_type, output_id;
990
991 intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL);
992 if (!intel_output) {
993 return;
994 }
995
996 connector = &intel_output->base;
997
998 drm_connector_init(dev, connector, &intel_sdvo_connector_funcs,
999 DRM_MODE_CONNECTOR_Unknown);
1000 drm_connector_helper_add(connector, &intel_sdvo_connector_helper_funcs);
1001 sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1);
1002 intel_output->type = INTEL_OUTPUT_SDVO;
1003
1004 connector->interlace_allowed = 0;
1005 connector->doublescan_allowed = 0;
1006
1007 /* setup the DDC bus. */
1008 if (output_device == SDVOB)
1009 i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB");
1010 else
1011 i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC");
1012
1013 if (!i2cbus)
1014 goto err_connector;
1015
1016 sdvo_priv->i2c_bus = i2cbus;
1017
1018 if (output_device == SDVOB) {
1019 output_id = 1;
1020 sdvo_priv->i2c_bus->slave_addr = 0x38;
1021 } else {
1022 output_id = 2;
1023 sdvo_priv->i2c_bus->slave_addr = 0x39;
1024 }
1025
1026 sdvo_priv->output_device = output_device;
1027 intel_output->i2c_bus = i2cbus;
1028 intel_output->dev_priv = sdvo_priv;
1029
1030
1031 /* Read the regs to test if we can talk to the device */
1032 for (i = 0; i < 0x40; i++) {
1033 if (!intel_sdvo_read_byte(intel_output, i, &ch[i])) {
1034 DRM_DEBUG("No SDVO device found on SDVO%c\n",
1035 output_device == SDVOB ? 'B' : 'C');
1036 goto err_i2c;
1037 }
1038 }
1039
1040 intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps);
1041
1042 memset(&sdvo_priv->active_outputs, 0, sizeof(sdvo_priv->active_outputs));
1043
1044 /* TODO, CVBS, SVID, YPRPB & SCART outputs. */
1045 if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB0)
1046 {
1047 sdvo_priv->active_outputs = SDVO_OUTPUT_RGB0;
1048 connector->display_info.subpixel_order = SubPixelHorizontalRGB;
1049 encoder_type = DRM_MODE_ENCODER_DAC;
1050 connector_type = DRM_MODE_CONNECTOR_VGA;
1051 }
1052 else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB1)
1053 {
1054 sdvo_priv->active_outputs = SDVO_OUTPUT_RGB1;
1055 connector->display_info.subpixel_order = SubPixelHorizontalRGB;
1056 encoder_type = DRM_MODE_ENCODER_DAC;
1057 connector_type = DRM_MODE_CONNECTOR_VGA;
1058 }
1059 else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0)
1060 {
1061 sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS0;
1062 connector->display_info.subpixel_order = SubPixelHorizontalRGB;
1063 encoder_type = DRM_MODE_ENCODER_TMDS;
1064 connector_type = DRM_MODE_CONNECTOR_DVID;
1065 }
1066 else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS1)
1067 {
1068 sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS1;
1069 connector->display_info.subpixel_order = SubPixelHorizontalRGB;
1070 encoder_type = DRM_MODE_ENCODER_TMDS;
1071 connector_type = DRM_MODE_CONNECTOR_DVID;
1072 }
1073 else
1074 {
1075 unsigned char bytes[2];
1076
1077 memcpy (bytes, &sdvo_priv->caps.output_flags, 2);
1078 DRM_DEBUG("%s: No active RGB or TMDS outputs (0x%02x%02x)\n",
1079 SDVO_NAME(sdvo_priv),
1080 bytes[0], bytes[1]);
1081 goto err_i2c;
1082 }
1083
1084 drm_encoder_init(dev, &intel_output->enc, &intel_sdvo_enc_funcs, encoder_type);
1085 drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs);
1086 connector->connector_type = connector_type;
1087
1088 drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
1089 drm_sysfs_connector_add(connector);
1090
1091 /* Set the input timing to the screen. Assume always input 0. */
1092 intel_sdvo_set_target_input(intel_output, true, false);
1093
1094 intel_sdvo_get_input_pixel_clock_range(intel_output,
1095 &sdvo_priv->pixel_clock_min,
1096 &sdvo_priv->pixel_clock_max);
1097
1098
1099 DRM_DEBUG("%s device VID/DID: %02X:%02X.%02X, "
1100 "clock range %dMHz - %dMHz, "
1101 "input 1: %c, input 2: %c, "
1102 "output 1: %c, output 2: %c\n",
1103 SDVO_NAME(sdvo_priv),
1104 sdvo_priv->caps.vendor_id, sdvo_priv->caps.device_id,
1105 sdvo_priv->caps.device_rev_id,
1106 sdvo_priv->pixel_clock_min / 1000,
1107 sdvo_priv->pixel_clock_max / 1000,
1108 (sdvo_priv->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N',
1109 (sdvo_priv->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N',
1110 /* check currently supported outputs */
1111 sdvo_priv->caps.output_flags &
1112 (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0) ? 'Y' : 'N',
1113 sdvo_priv->caps.output_flags &
1114 (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N');
1115
1116 intel_output->ddc_bus = i2cbus;
1117
1118 return;
1119
1120err_i2c:
1121 intel_i2c_destroy(intel_output->i2c_bus);
1122err_connector:
1123 drm_connector_cleanup(connector);
1124 kfree(intel_output);
1125
1126 return;
1127}
diff --git a/drivers/gpu/drm/i915/intel_sdvo_regs.h b/drivers/gpu/drm/i915/intel_sdvo_regs.h
new file mode 100644
index 000000000000..861a43f8693c
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_sdvo_regs.h
@@ -0,0 +1,327 @@
1/*
2 * Copyright © 2006-2007 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 *
23 * Authors:
24 * Eric Anholt <eric@anholt.net>
25 */
26
27/**
28 * @file SDVO command definitions and structures.
29 */
30
31#define SDVO_OUTPUT_FIRST (0)
32#define SDVO_OUTPUT_TMDS0 (1 << 0)
33#define SDVO_OUTPUT_RGB0 (1 << 1)
34#define SDVO_OUTPUT_CVBS0 (1 << 2)
35#define SDVO_OUTPUT_SVID0 (1 << 3)
36#define SDVO_OUTPUT_YPRPB0 (1 << 4)
37#define SDVO_OUTPUT_SCART0 (1 << 5)
38#define SDVO_OUTPUT_LVDS0 (1 << 6)
39#define SDVO_OUTPUT_TMDS1 (1 << 8)
40#define SDVO_OUTPUT_RGB1 (1 << 9)
41#define SDVO_OUTPUT_CVBS1 (1 << 10)
42#define SDVO_OUTPUT_SVID1 (1 << 11)
43#define SDVO_OUTPUT_YPRPB1 (1 << 12)
44#define SDVO_OUTPUT_SCART1 (1 << 13)
45#define SDVO_OUTPUT_LVDS1 (1 << 14)
46#define SDVO_OUTPUT_LAST (14)
47
48struct intel_sdvo_caps {
49 u8 vendor_id;
50 u8 device_id;
51 u8 device_rev_id;
52 u8 sdvo_version_major;
53 u8 sdvo_version_minor;
54 unsigned int sdvo_inputs_mask:2;
55 unsigned int smooth_scaling:1;
56 unsigned int sharp_scaling:1;
57 unsigned int up_scaling:1;
58 unsigned int down_scaling:1;
59 unsigned int stall_support:1;
60 unsigned int pad:1;
61 u16 output_flags;
62} __attribute__((packed));
63
64/** This matches the EDID DTD structure, more or less */
65struct intel_sdvo_dtd {
66 struct {
67 u16 clock; /**< pixel clock, in 10kHz units */
68 u8 h_active; /**< lower 8 bits (pixels) */
69 u8 h_blank; /**< lower 8 bits (pixels) */
70 u8 h_high; /**< upper 4 bits each h_active, h_blank */
71 u8 v_active; /**< lower 8 bits (lines) */
72 u8 v_blank; /**< lower 8 bits (lines) */
73 u8 v_high; /**< upper 4 bits each v_active, v_blank */
74 } part1;
75
76 struct {
77 u8 h_sync_off; /**< lower 8 bits, from hblank start */
78 u8 h_sync_width; /**< lower 8 bits (pixels) */
79 /** lower 4 bits each vsync offset, vsync width */
80 u8 v_sync_off_width;
81 /**
82 * 2 high bits of hsync offset, 2 high bits of hsync width,
83 * bits 4-5 of vsync offset, and 2 high bits of vsync width.
84 */
85 u8 sync_off_width_high;
86 u8 dtd_flags;
87 u8 sdvo_flags;
88 /** bits 6-7 of vsync offset at bits 6-7 */
89 u8 v_sync_off_high;
90 u8 reserved;
91 } part2;
92} __attribute__((packed));
93
94struct intel_sdvo_pixel_clock_range {
95 u16 min; /**< pixel clock, in 10kHz units */
96 u16 max; /**< pixel clock, in 10kHz units */
97} __attribute__((packed));
98
99struct intel_sdvo_preferred_input_timing_args {
100 u16 clock;
101 u16 width;
102 u16 height;
103} __attribute__((packed));
104
105/* I2C registers for SDVO */
106#define SDVO_I2C_ARG_0 0x07
107#define SDVO_I2C_ARG_1 0x06
108#define SDVO_I2C_ARG_2 0x05
109#define SDVO_I2C_ARG_3 0x04
110#define SDVO_I2C_ARG_4 0x03
111#define SDVO_I2C_ARG_5 0x02
112#define SDVO_I2C_ARG_6 0x01
113#define SDVO_I2C_ARG_7 0x00
114#define SDVO_I2C_OPCODE 0x08
115#define SDVO_I2C_CMD_STATUS 0x09
116#define SDVO_I2C_RETURN_0 0x0a
117#define SDVO_I2C_RETURN_1 0x0b
118#define SDVO_I2C_RETURN_2 0x0c
119#define SDVO_I2C_RETURN_3 0x0d
120#define SDVO_I2C_RETURN_4 0x0e
121#define SDVO_I2C_RETURN_5 0x0f
122#define SDVO_I2C_RETURN_6 0x10
123#define SDVO_I2C_RETURN_7 0x11
124#define SDVO_I2C_VENDOR_BEGIN 0x20
125
126/* Status results */
127#define SDVO_CMD_STATUS_POWER_ON 0x0
128#define SDVO_CMD_STATUS_SUCCESS 0x1
129#define SDVO_CMD_STATUS_NOTSUPP 0x2
130#define SDVO_CMD_STATUS_INVALID_ARG 0x3
131#define SDVO_CMD_STATUS_PENDING 0x4
132#define SDVO_CMD_STATUS_TARGET_NOT_SPECIFIED 0x5
133#define SDVO_CMD_STATUS_SCALING_NOT_SUPP 0x6
134
135/* SDVO commands, argument/result registers */
136
137#define SDVO_CMD_RESET 0x01
138
139/** Returns a struct intel_sdvo_caps */
140#define SDVO_CMD_GET_DEVICE_CAPS 0x02
141
142#define SDVO_CMD_GET_FIRMWARE_REV 0x86
143# define SDVO_DEVICE_FIRMWARE_MINOR SDVO_I2C_RETURN_0
144# define SDVO_DEVICE_FIRMWARE_MAJOR SDVO_I2C_RETURN_1
145# define SDVO_DEVICE_FIRMWARE_PATCH SDVO_I2C_RETURN_2
146
147/**
148 * Reports which inputs are trained (managed to sync).
149 *
150 * Devices must have trained within 2 vsyncs of a mode change.
151 */
152#define SDVO_CMD_GET_TRAINED_INPUTS 0x03
153struct intel_sdvo_get_trained_inputs_response {
154 unsigned int input0_trained:1;
155 unsigned int input1_trained:1;
156 unsigned int pad:6;
157} __attribute__((packed));
158
159/** Returns a struct intel_sdvo_output_flags of active outputs. */
160#define SDVO_CMD_GET_ACTIVE_OUTPUTS 0x04
161
162/**
163 * Sets the current set of active outputs.
164 *
165 * Takes a struct intel_sdvo_output_flags. Must be preceded by a SET_IN_OUT_MAP
166 * on multi-output devices.
167 */
168#define SDVO_CMD_SET_ACTIVE_OUTPUTS 0x05
169
170/**
171 * Returns the current mapping of SDVO inputs to outputs on the device.
172 *
173 * Returns two struct intel_sdvo_output_flags structures.
174 */
175#define SDVO_CMD_GET_IN_OUT_MAP 0x06
176
177/**
178 * Sets the current mapping of SDVO inputs to outputs on the device.
179 *
180 * Takes two struct i380_sdvo_output_flags structures.
181 */
182#define SDVO_CMD_SET_IN_OUT_MAP 0x07
183
184/**
185 * Returns a struct intel_sdvo_output_flags of attached displays.
186 */
187#define SDVO_CMD_GET_ATTACHED_DISPLAYS 0x0b
188
189/**
190 * Returns a struct intel_sdvo_ouptut_flags of displays supporting hot plugging.
191 */
192#define SDVO_CMD_GET_HOT_PLUG_SUPPORT 0x0c
193
194/**
195 * Takes a struct intel_sdvo_output_flags.
196 */
197#define SDVO_CMD_SET_ACTIVE_HOT_PLUG 0x0d
198
199/**
200 * Returns a struct intel_sdvo_output_flags of displays with hot plug
201 * interrupts enabled.
202 */
203#define SDVO_CMD_GET_ACTIVE_HOT_PLUG 0x0e
204
205#define SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE 0x0f
206struct intel_sdvo_get_interrupt_event_source_response {
207 u16 interrupt_status;
208 unsigned int ambient_light_interrupt:1;
209 unsigned int pad:7;
210} __attribute__((packed));
211
212/**
213 * Selects which input is affected by future input commands.
214 *
215 * Commands affected include SET_INPUT_TIMINGS_PART[12],
216 * GET_INPUT_TIMINGS_PART[12], GET_PREFERRED_INPUT_TIMINGS_PART[12],
217 * GET_INPUT_PIXEL_CLOCK_RANGE, and CREATE_PREFERRED_INPUT_TIMINGS.
218 */
219#define SDVO_CMD_SET_TARGET_INPUT 0x10
220struct intel_sdvo_set_target_input_args {
221 unsigned int target_1:1;
222 unsigned int pad:7;
223} __attribute__((packed));
224
225/**
226 * Takes a struct intel_sdvo_output_flags of which outputs are targetted by
227 * future output commands.
228 *
229 * Affected commands inclue SET_OUTPUT_TIMINGS_PART[12],
230 * GET_OUTPUT_TIMINGS_PART[12], and GET_OUTPUT_PIXEL_CLOCK_RANGE.
231 */
232#define SDVO_CMD_SET_TARGET_OUTPUT 0x11
233
234#define SDVO_CMD_GET_INPUT_TIMINGS_PART1 0x12
235#define SDVO_CMD_GET_INPUT_TIMINGS_PART2 0x13
236#define SDVO_CMD_SET_INPUT_TIMINGS_PART1 0x14
237#define SDVO_CMD_SET_INPUT_TIMINGS_PART2 0x15
238#define SDVO_CMD_SET_OUTPUT_TIMINGS_PART1 0x16
239#define SDVO_CMD_SET_OUTPUT_TIMINGS_PART2 0x17
240#define SDVO_CMD_GET_OUTPUT_TIMINGS_PART1 0x18
241#define SDVO_CMD_GET_OUTPUT_TIMINGS_PART2 0x19
242/* Part 1 */
243# define SDVO_DTD_CLOCK_LOW SDVO_I2C_ARG_0
244# define SDVO_DTD_CLOCK_HIGH SDVO_I2C_ARG_1
245# define SDVO_DTD_H_ACTIVE SDVO_I2C_ARG_2
246# define SDVO_DTD_H_BLANK SDVO_I2C_ARG_3
247# define SDVO_DTD_H_HIGH SDVO_I2C_ARG_4
248# define SDVO_DTD_V_ACTIVE SDVO_I2C_ARG_5
249# define SDVO_DTD_V_BLANK SDVO_I2C_ARG_6
250# define SDVO_DTD_V_HIGH SDVO_I2C_ARG_7
251/* Part 2 */
252# define SDVO_DTD_HSYNC_OFF SDVO_I2C_ARG_0
253# define SDVO_DTD_HSYNC_WIDTH SDVO_I2C_ARG_1
254# define SDVO_DTD_VSYNC_OFF_WIDTH SDVO_I2C_ARG_2
255# define SDVO_DTD_SYNC_OFF_WIDTH_HIGH SDVO_I2C_ARG_3
256# define SDVO_DTD_DTD_FLAGS SDVO_I2C_ARG_4
257# define SDVO_DTD_DTD_FLAG_INTERLACED (1 << 7)
258# define SDVO_DTD_DTD_FLAG_STEREO_MASK (3 << 5)
259# define SDVO_DTD_DTD_FLAG_INPUT_MASK (3 << 3)
260# define SDVO_DTD_DTD_FLAG_SYNC_MASK (3 << 1)
261# define SDVO_DTD_SDVO_FLAS SDVO_I2C_ARG_5
262# define SDVO_DTD_SDVO_FLAG_STALL (1 << 7)
263# define SDVO_DTD_SDVO_FLAG_CENTERED (0 << 6)
264# define SDVO_DTD_SDVO_FLAG_UPPER_LEFT (1 << 6)
265# define SDVO_DTD_SDVO_FLAG_SCALING_MASK (3 << 4)
266# define SDVO_DTD_SDVO_FLAG_SCALING_NONE (0 << 4)
267# define SDVO_DTD_SDVO_FLAG_SCALING_SHARP (1 << 4)
268# define SDVO_DTD_SDVO_FLAG_SCALING_SMOOTH (2 << 4)
269# define SDVO_DTD_VSYNC_OFF_HIGH SDVO_I2C_ARG_6
270
271/**
272 * Generates a DTD based on the given width, height, and flags.
273 *
274 * This will be supported by any device supporting scaling or interlaced
275 * modes.
276 */
277#define SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING 0x1a
278# define SDVO_PREFERRED_INPUT_TIMING_CLOCK_LOW SDVO_I2C_ARG_0
279# define SDVO_PREFERRED_INPUT_TIMING_CLOCK_HIGH SDVO_I2C_ARG_1
280# define SDVO_PREFERRED_INPUT_TIMING_WIDTH_LOW SDVO_I2C_ARG_2
281# define SDVO_PREFERRED_INPUT_TIMING_WIDTH_HIGH SDVO_I2C_ARG_3
282# define SDVO_PREFERRED_INPUT_TIMING_HEIGHT_LOW SDVO_I2C_ARG_4
283# define SDVO_PREFERRED_INPUT_TIMING_HEIGHT_HIGH SDVO_I2C_ARG_5
284# define SDVO_PREFERRED_INPUT_TIMING_FLAGS SDVO_I2C_ARG_6
285# define SDVO_PREFERRED_INPUT_TIMING_FLAGS_INTERLACED (1 << 0)
286# define SDVO_PREFERRED_INPUT_TIMING_FLAGS_SCALED (1 << 1)
287
288#define SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1 0x1b
289#define SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2 0x1c
290
291/** Returns a struct intel_sdvo_pixel_clock_range */
292#define SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE 0x1d
293/** Returns a struct intel_sdvo_pixel_clock_range */
294#define SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE 0x1e
295
296/** Returns a byte bitfield containing SDVO_CLOCK_RATE_MULT_* flags */
297#define SDVO_CMD_GET_SUPPORTED_CLOCK_RATE_MULTS 0x1f
298
299/** Returns a byte containing a SDVO_CLOCK_RATE_MULT_* flag */
300#define SDVO_CMD_GET_CLOCK_RATE_MULT 0x20
301/** Takes a byte containing a SDVO_CLOCK_RATE_MULT_* flag */
302#define SDVO_CMD_SET_CLOCK_RATE_MULT 0x21
303# define SDVO_CLOCK_RATE_MULT_1X (1 << 0)
304# define SDVO_CLOCK_RATE_MULT_2X (1 << 1)
305# define SDVO_CLOCK_RATE_MULT_4X (1 << 3)
306
307#define SDVO_CMD_GET_SUPPORTED_TV_FORMATS 0x27
308
309#define SDVO_CMD_GET_TV_FORMAT 0x28
310
311#define SDVO_CMD_SET_TV_FORMAT 0x29
312
313#define SDVO_CMD_GET_SUPPORTED_POWER_STATES 0x2a
314#define SDVO_CMD_GET_ENCODER_POWER_STATE 0x2b
315#define SDVO_CMD_SET_ENCODER_POWER_STATE 0x2c
316# define SDVO_ENCODER_STATE_ON (1 << 0)
317# define SDVO_ENCODER_STATE_STANDBY (1 << 1)
318# define SDVO_ENCODER_STATE_SUSPEND (1 << 2)
319# define SDVO_ENCODER_STATE_OFF (1 << 3)
320
321#define SDVO_CMD_SET_TV_RESOLUTION_SUPPORT 0x93
322
323#define SDVO_CMD_SET_CONTROL_BUS_SWITCH 0x7a
324# define SDVO_CONTROL_BUS_PROM 0x0
325# define SDVO_CONTROL_BUS_DDC1 0x1
326# define SDVO_CONTROL_BUS_DDC2 0x2
327# define SDVO_CONTROL_BUS_DDC3 0x3
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
new file mode 100644
index 000000000000..d409b8637883
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -0,0 +1,1725 @@
1/*
2 * Copyright © 2006-2008 Intel Corporation
3 * Jesse Barnes <jesse.barnes@intel.com>
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Eric Anholt <eric@anholt.net>
26 *
27 */
28
29/** @file
30 * Integrated TV-out support for the 915GM and 945GM.
31 */
32
33#include "drmP.h"
34#include "drm.h"
35#include "drm_crtc.h"
36#include "drm_edid.h"
37#include "intel_drv.h"
38#include "i915_drm.h"
39#include "i915_drv.h"
40
41enum tv_margin {
42 TV_MARGIN_LEFT, TV_MARGIN_TOP,
43 TV_MARGIN_RIGHT, TV_MARGIN_BOTTOM
44};
45
46/** Private structure for the integrated TV support */
47struct intel_tv_priv {
48 int type;
49 char *tv_format;
50 int margin[4];
51 u32 save_TV_H_CTL_1;
52 u32 save_TV_H_CTL_2;
53 u32 save_TV_H_CTL_3;
54 u32 save_TV_V_CTL_1;
55 u32 save_TV_V_CTL_2;
56 u32 save_TV_V_CTL_3;
57 u32 save_TV_V_CTL_4;
58 u32 save_TV_V_CTL_5;
59 u32 save_TV_V_CTL_6;
60 u32 save_TV_V_CTL_7;
61 u32 save_TV_SC_CTL_1, save_TV_SC_CTL_2, save_TV_SC_CTL_3;
62
63 u32 save_TV_CSC_Y;
64 u32 save_TV_CSC_Y2;
65 u32 save_TV_CSC_U;
66 u32 save_TV_CSC_U2;
67 u32 save_TV_CSC_V;
68 u32 save_TV_CSC_V2;
69 u32 save_TV_CLR_KNOBS;
70 u32 save_TV_CLR_LEVEL;
71 u32 save_TV_WIN_POS;
72 u32 save_TV_WIN_SIZE;
73 u32 save_TV_FILTER_CTL_1;
74 u32 save_TV_FILTER_CTL_2;
75 u32 save_TV_FILTER_CTL_3;
76
77 u32 save_TV_H_LUMA[60];
78 u32 save_TV_H_CHROMA[60];
79 u32 save_TV_V_LUMA[43];
80 u32 save_TV_V_CHROMA[43];
81
82 u32 save_TV_DAC;
83 u32 save_TV_CTL;
84};
85
86struct video_levels {
87 int blank, black, burst;
88};
89
90struct color_conversion {
91 u16 ry, gy, by, ay;
92 u16 ru, gu, bu, au;
93 u16 rv, gv, bv, av;
94};
95
96static const u32 filter_table[] = {
97 0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140,
98 0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000,
99 0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160,
100 0x2D202EF0, 0xB1203380, 0xB1603000, 0x2F303780,
101 0x33002CC0, 0x3000B100, 0x3820B160, 0x2C802F50,
102 0xB10032A0, 0xB1603000, 0x2F9038C0, 0x32202C20,
103 0x3000B0E0, 0x3980B160, 0x2BC02FC0, 0xB0E031C0,
104 0xB1603000, 0x2FF03A20, 0x31602B60, 0xB020B0C0,
105 0x3AE0B160, 0x2B001810, 0xB0C03120, 0xB140B020,
106 0x18283BA0, 0x30C02A80, 0xB020B0A0, 0x3C60B140,
107 0x2A201838, 0xB0A03080, 0xB120B020, 0x18383D20,
108 0x304029C0, 0xB040B080, 0x3DE0B100, 0x29601848,
109 0xB0803000, 0xB100B040, 0x18483EC0, 0xB0402900,
110 0xB040B060, 0x3F80B0C0, 0x28801858, 0xB060B080,
111 0xB0A0B060, 0x18602820, 0xB0A02820, 0x0000B060,
112 0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140,
113 0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000,
114 0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160,
115 0x2D202EF0, 0xB1203380, 0xB1603000, 0x2F303780,
116 0x33002CC0, 0x3000B100, 0x3820B160, 0x2C802F50,
117 0xB10032A0, 0xB1603000, 0x2F9038C0, 0x32202C20,
118 0x3000B0E0, 0x3980B160, 0x2BC02FC0, 0xB0E031C0,
119 0xB1603000, 0x2FF03A20, 0x31602B60, 0xB020B0C0,
120 0x3AE0B160, 0x2B001810, 0xB0C03120, 0xB140B020,
121 0x18283BA0, 0x30C02A80, 0xB020B0A0, 0x3C60B140,
122 0x2A201838, 0xB0A03080, 0xB120B020, 0x18383D20,
123 0x304029C0, 0xB040B080, 0x3DE0B100, 0x29601848,
124 0xB0803000, 0xB100B040, 0x18483EC0, 0xB0402900,
125 0xB040B060, 0x3F80B0C0, 0x28801858, 0xB060B080,
126 0xB0A0B060, 0x18602820, 0xB0A02820, 0x0000B060,
127 0x36403000, 0x2D002CC0, 0x30003640, 0x2D0036C0,
128 0x35C02CC0, 0x37403000, 0x2C802D40, 0x30003540,
129 0x2D8037C0, 0x34C02C40, 0x38403000, 0x2BC02E00,
130 0x30003440, 0x2E2038C0, 0x34002B80, 0x39803000,
131 0x2B402E40, 0x30003380, 0x2E603A00, 0x33402B00,
132 0x3A803040, 0x2A802EA0, 0x30403300, 0x2EC03B40,
133 0x32802A40, 0x3C003040, 0x2A002EC0, 0x30803240,
134 0x2EC03C80, 0x320029C0, 0x3D403080, 0x29402F00,
135 0x308031C0, 0x2F203DC0, 0x31802900, 0x3E8030C0,
136 0x28802F40, 0x30C03140, 0x2F203F40, 0x31402840,
137 0x28003100, 0x28002F00, 0x00003100, 0x36403000,
138 0x2D002CC0, 0x30003640, 0x2D0036C0,
139 0x35C02CC0, 0x37403000, 0x2C802D40, 0x30003540,
140 0x2D8037C0, 0x34C02C40, 0x38403000, 0x2BC02E00,
141 0x30003440, 0x2E2038C0, 0x34002B80, 0x39803000,
142 0x2B402E40, 0x30003380, 0x2E603A00, 0x33402B00,
143 0x3A803040, 0x2A802EA0, 0x30403300, 0x2EC03B40,
144 0x32802A40, 0x3C003040, 0x2A002EC0, 0x30803240,
145 0x2EC03C80, 0x320029C0, 0x3D403080, 0x29402F00,
146 0x308031C0, 0x2F203DC0, 0x31802900, 0x3E8030C0,
147 0x28802F40, 0x30C03140, 0x2F203F40, 0x31402840,
148 0x28003100, 0x28002F00, 0x00003100,
149};
150
151/*
152 * Color conversion values have 3 separate fixed point formats:
153 *
154 * 10 bit fields (ay, au)
155 * 1.9 fixed point (b.bbbbbbbbb)
156 * 11 bit fields (ry, by, ru, gu, gv)
157 * exp.mantissa (ee.mmmmmmmmm)
158 * ee = 00 = 10^-1 (0.mmmmmmmmm)
159 * ee = 01 = 10^-2 (0.0mmmmmmmmm)
160 * ee = 10 = 10^-3 (0.00mmmmmmmmm)
161 * ee = 11 = 10^-4 (0.000mmmmmmmmm)
162 * 12 bit fields (gy, rv, bu)
163 * exp.mantissa (eee.mmmmmmmmm)
164 * eee = 000 = 10^-1 (0.mmmmmmmmm)
165 * eee = 001 = 10^-2 (0.0mmmmmmmmm)
166 * eee = 010 = 10^-3 (0.00mmmmmmmmm)
167 * eee = 011 = 10^-4 (0.000mmmmmmmmm)
168 * eee = 100 = reserved
169 * eee = 101 = reserved
170 * eee = 110 = reserved
171 * eee = 111 = 10^0 (m.mmmmmmmm) (only usable for 1.0 representation)
172 *
173 * Saturation and contrast are 8 bits, with their own representation:
174 * 8 bit field (saturation, contrast)
175 * exp.mantissa (ee.mmmmmm)
176 * ee = 00 = 10^-1 (0.mmmmmm)
177 * ee = 01 = 10^0 (m.mmmmm)
178 * ee = 10 = 10^1 (mm.mmmm)
179 * ee = 11 = 10^2 (mmm.mmm)
180 *
181 * Simple conversion function:
182 *
183 * static u32
184 * float_to_csc_11(float f)
185 * {
186 * u32 exp;
187 * u32 mant;
188 * u32 ret;
189 *
190 * if (f < 0)
191 * f = -f;
192 *
193 * if (f >= 1) {
194 * exp = 0x7;
195 * mant = 1 << 8;
196 * } else {
197 * for (exp = 0; exp < 3 && f < 0.5; exp++)
198 * f *= 2.0;
199 * mant = (f * (1 << 9) + 0.5);
200 * if (mant >= (1 << 9))
201 * mant = (1 << 9) - 1;
202 * }
203 * ret = (exp << 9) | mant;
204 * return ret;
205 * }
206 */
207
208/*
209 * Behold, magic numbers! If we plant them they might grow a big
210 * s-video cable to the sky... or something.
211 *
212 * Pre-converted to appropriate hex value.
213 */
214
215/*
216 * PAL & NTSC values for composite & s-video connections
217 */
218static const struct color_conversion ntsc_m_csc_composite = {
219 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
220 .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0f00,
221 .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0f00,
222};
223
224static const struct video_levels ntsc_m_levels_composite = {
225 .blank = 225, .black = 267, .burst = 113,
226};
227
228static const struct color_conversion ntsc_m_csc_svideo = {
229 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0134,
230 .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0f00,
231 .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0f00,
232};
233
234static const struct video_levels ntsc_m_levels_svideo = {
235 .blank = 266, .black = 316, .burst = 133,
236};
237
238static const struct color_conversion ntsc_j_csc_composite = {
239 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0119,
240 .ru = 0x074c, .gu = 0x0546, .bu = 0x05ec, .au = 0x0f00,
241 .rv = 0x035a, .gv = 0x0322, .bv = 0x06e1, .av = 0x0f00,
242};
243
244static const struct video_levels ntsc_j_levels_composite = {
245 .blank = 225, .black = 225, .burst = 113,
246};
247
248static const struct color_conversion ntsc_j_csc_svideo = {
249 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x014c,
250 .ru = 0x0788, .gu = 0x0581, .bu = 0x0322, .au = 0x0f00,
251 .rv = 0x0399, .gv = 0x0356, .bv = 0x070a, .av = 0x0f00,
252};
253
254static const struct video_levels ntsc_j_levels_svideo = {
255 .blank = 266, .black = 266, .burst = 133,
256};
257
258static const struct color_conversion pal_csc_composite = {
259 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0113,
260 .ru = 0x0745, .gu = 0x053f, .bu = 0x05e1, .au = 0x0f00,
261 .rv = 0x0353, .gv = 0x031c, .bv = 0x06dc, .av = 0x0f00,
262};
263
264static const struct video_levels pal_levels_composite = {
265 .blank = 237, .black = 237, .burst = 118,
266};
267
268static const struct color_conversion pal_csc_svideo = {
269 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0145,
270 .ru = 0x0780, .gu = 0x0579, .bu = 0x031c, .au = 0x0f00,
271 .rv = 0x0390, .gv = 0x034f, .bv = 0x0705, .av = 0x0f00,
272};
273
274static const struct video_levels pal_levels_svideo = {
275 .blank = 280, .black = 280, .burst = 139,
276};
277
278static const struct color_conversion pal_m_csc_composite = {
279 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
280 .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0f00,
281 .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0f00,
282};
283
284static const struct video_levels pal_m_levels_composite = {
285 .blank = 225, .black = 267, .burst = 113,
286};
287
288static const struct color_conversion pal_m_csc_svideo = {
289 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0134,
290 .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0f00,
291 .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0f00,
292};
293
294static const struct video_levels pal_m_levels_svideo = {
295 .blank = 266, .black = 316, .burst = 133,
296};
297
298static const struct color_conversion pal_n_csc_composite = {
299 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0104,
300 .ru = 0x0733, .gu = 0x052d, .bu = 0x05c7, .au = 0x0f00,
301 .rv = 0x0340, .gv = 0x030c, .bv = 0x06d0, .av = 0x0f00,
302};
303
304static const struct video_levels pal_n_levels_composite = {
305 .blank = 225, .black = 267, .burst = 118,
306};
307
308static const struct color_conversion pal_n_csc_svideo = {
309 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0134,
310 .ru = 0x076a, .gu = 0x0564, .bu = 0x030d, .au = 0x0f00,
311 .rv = 0x037a, .gv = 0x033d, .bv = 0x06f6, .av = 0x0f00,
312};
313
314static const struct video_levels pal_n_levels_svideo = {
315 .blank = 266, .black = 316, .burst = 139,
316};
317
318/*
319 * Component connections
320 */
321static const struct color_conversion sdtv_csc_yprpb = {
322 .ry = 0x0332, .gy = 0x012d, .by = 0x07d3, .ay = 0x0146,
323 .ru = 0x0559, .gu = 0x0353, .bu = 0x0100, .au = 0x0f00,
324 .rv = 0x0100, .gv = 0x03ad, .bv = 0x074d, .av = 0x0f00,
325};
326
327static const struct color_conversion sdtv_csc_rgb = {
328 .ry = 0x0000, .gy = 0x0f00, .by = 0x0000, .ay = 0x0166,
329 .ru = 0x0000, .gu = 0x0000, .bu = 0x0f00, .au = 0x0166,
330 .rv = 0x0f00, .gv = 0x0000, .bv = 0x0000, .av = 0x0166,
331};
332
333static const struct color_conversion hdtv_csc_yprpb = {
334 .ry = 0x05b3, .gy = 0x016e, .by = 0x0728, .ay = 0x0146,
335 .ru = 0x07d5, .gu = 0x038b, .bu = 0x0100, .au = 0x0f00,
336 .rv = 0x0100, .gv = 0x03d1, .bv = 0x06bc, .av = 0x0f00,
337};
338
339static const struct color_conversion hdtv_csc_rgb = {
340 .ry = 0x0000, .gy = 0x0f00, .by = 0x0000, .ay = 0x0166,
341 .ru = 0x0000, .gu = 0x0000, .bu = 0x0f00, .au = 0x0166,
342 .rv = 0x0f00, .gv = 0x0000, .bv = 0x0000, .av = 0x0166,
343};
344
345static const struct video_levels component_levels = {
346 .blank = 279, .black = 279, .burst = 0,
347};
348
349
350struct tv_mode {
351 char *name;
352 int clock;
353 int refresh; /* in millihertz (for precision) */
354 u32 oversample;
355 int hsync_end, hblank_start, hblank_end, htotal;
356 bool progressive, trilevel_sync, component_only;
357 int vsync_start_f1, vsync_start_f2, vsync_len;
358 bool veq_ena;
359 int veq_start_f1, veq_start_f2, veq_len;
360 int vi_end_f1, vi_end_f2, nbr_end;
361 bool burst_ena;
362 int hburst_start, hburst_len;
363 int vburst_start_f1, vburst_end_f1;
364 int vburst_start_f2, vburst_end_f2;
365 int vburst_start_f3, vburst_end_f3;
366 int vburst_start_f4, vburst_end_f4;
367 /*
368 * subcarrier programming
369 */
370 int dda2_size, dda3_size, dda1_inc, dda2_inc, dda3_inc;
371 u32 sc_reset;
372 bool pal_burst;
373 /*
374 * blank/black levels
375 */
376 const struct video_levels *composite_levels, *svideo_levels;
377 const struct color_conversion *composite_color, *svideo_color;
378 const u32 *filter_table;
379 int max_srcw;
380};
381
382
383/*
384 * Sub carrier DDA
385 *
386 * I think this works as follows:
387 *
388 * subcarrier freq = pixel_clock * (dda1_inc + dda2_inc / dda2_size) / 4096
389 *
390 * Presumably, when dda3 is added in, it gets to adjust the dda2_inc value
391 *
392 * So,
393 * dda1_ideal = subcarrier/pixel * 4096
394 * dda1_inc = floor (dda1_ideal)
395 * dda2 = dda1_ideal - dda1_inc
396 *
397 * then pick a ratio for dda2 that gives the closest approximation. If
398 * you can't get close enough, you can play with dda3 as well. This
399 * seems likely to happen when dda2 is small as the jumps would be larger
400 *
401 * To invert this,
402 *
403 * pixel_clock = subcarrier * 4096 / (dda1_inc + dda2_inc / dda2_size)
404 *
405 * The constants below were all computed using a 107.520MHz clock
406 */
407
408/**
409 * Register programming values for TV modes.
410 *
411 * These values account for -1s required.
412 */
413
414const static struct tv_mode tv_modes[] = {
415 {
416 .name = "NTSC-M",
417 .clock = 107520,
418 .refresh = 29970,
419 .oversample = TV_OVERSAMPLE_8X,
420 .component_only = 0,
421 /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
422
423 .hsync_end = 64, .hblank_end = 124,
424 .hblank_start = 836, .htotal = 857,
425
426 .progressive = false, .trilevel_sync = false,
427
428 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
429 .vsync_len = 6,
430
431 .veq_ena = true, .veq_start_f1 = 0,
432 .veq_start_f2 = 1, .veq_len = 18,
433
434 .vi_end_f1 = 20, .vi_end_f2 = 21,
435 .nbr_end = 240,
436
437 .burst_ena = true,
438 .hburst_start = 72, .hburst_len = 34,
439 .vburst_start_f1 = 9, .vburst_end_f1 = 240,
440 .vburst_start_f2 = 10, .vburst_end_f2 = 240,
441 .vburst_start_f3 = 9, .vburst_end_f3 = 240,
442 .vburst_start_f4 = 10, .vburst_end_f4 = 240,
443
444 /* desired 3.5800000 actual 3.5800000 clock 107.52 */
445 .dda1_inc = 136,
446 .dda2_inc = 7624, .dda2_size = 20013,
447 .dda3_inc = 0, .dda3_size = 0,
448 .sc_reset = TV_SC_RESET_EVERY_4,
449 .pal_burst = false,
450
451 .composite_levels = &ntsc_m_levels_composite,
452 .composite_color = &ntsc_m_csc_composite,
453 .svideo_levels = &ntsc_m_levels_svideo,
454 .svideo_color = &ntsc_m_csc_svideo,
455
456 .filter_table = filter_table,
457 },
458 {
459 .name = "NTSC-443",
460 .clock = 107520,
461 .refresh = 29970,
462 .oversample = TV_OVERSAMPLE_8X,
463 .component_only = 0,
464 /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 4.43MHz */
465 .hsync_end = 64, .hblank_end = 124,
466 .hblank_start = 836, .htotal = 857,
467
468 .progressive = false, .trilevel_sync = false,
469
470 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
471 .vsync_len = 6,
472
473 .veq_ena = true, .veq_start_f1 = 0,
474 .veq_start_f2 = 1, .veq_len = 18,
475
476 .vi_end_f1 = 20, .vi_end_f2 = 21,
477 .nbr_end = 240,
478
479 .burst_ena = 8,
480 .hburst_start = 72, .hburst_len = 34,
481 .vburst_start_f1 = 9, .vburst_end_f1 = 240,
482 .vburst_start_f2 = 10, .vburst_end_f2 = 240,
483 .vburst_start_f3 = 9, .vburst_end_f3 = 240,
484 .vburst_start_f4 = 10, .vburst_end_f4 = 240,
485
486 /* desired 4.4336180 actual 4.4336180 clock 107.52 */
487 .dda1_inc = 168,
488 .dda2_inc = 18557, .dda2_size = 20625,
489 .dda3_inc = 0, .dda3_size = 0,
490 .sc_reset = TV_SC_RESET_EVERY_8,
491 .pal_burst = true,
492
493 .composite_levels = &ntsc_m_levels_composite,
494 .composite_color = &ntsc_m_csc_composite,
495 .svideo_levels = &ntsc_m_levels_svideo,
496 .svideo_color = &ntsc_m_csc_svideo,
497
498 .filter_table = filter_table,
499 },
500 {
501 .name = "NTSC-J",
502 .clock = 107520,
503 .refresh = 29970,
504 .oversample = TV_OVERSAMPLE_8X,
505 .component_only = 0,
506
507 /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
508 .hsync_end = 64, .hblank_end = 124,
509 .hblank_start = 836, .htotal = 857,
510
511 .progressive = false, .trilevel_sync = false,
512
513 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
514 .vsync_len = 6,
515
516 .veq_ena = true, .veq_start_f1 = 0,
517 .veq_start_f2 = 1, .veq_len = 18,
518
519 .vi_end_f1 = 20, .vi_end_f2 = 21,
520 .nbr_end = 240,
521
522 .burst_ena = true,
523 .hburst_start = 72, .hburst_len = 34,
524 .vburst_start_f1 = 9, .vburst_end_f1 = 240,
525 .vburst_start_f2 = 10, .vburst_end_f2 = 240,
526 .vburst_start_f3 = 9, .vburst_end_f3 = 240,
527 .vburst_start_f4 = 10, .vburst_end_f4 = 240,
528
529 /* desired 3.5800000 actual 3.5800000 clock 107.52 */
530 .dda1_inc = 136,
531 .dda2_inc = 7624, .dda2_size = 20013,
532 .dda3_inc = 0, .dda3_size = 0,
533 .sc_reset = TV_SC_RESET_EVERY_4,
534 .pal_burst = false,
535
536 .composite_levels = &ntsc_j_levels_composite,
537 .composite_color = &ntsc_j_csc_composite,
538 .svideo_levels = &ntsc_j_levels_svideo,
539 .svideo_color = &ntsc_j_csc_svideo,
540
541 .filter_table = filter_table,
542 },
543 {
544 .name = "PAL-M",
545 .clock = 107520,
546 .refresh = 29970,
547 .oversample = TV_OVERSAMPLE_8X,
548 .component_only = 0,
549
550 /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */
551 .hsync_end = 64, .hblank_end = 124,
552 .hblank_start = 836, .htotal = 857,
553
554 .progressive = false, .trilevel_sync = false,
555
556 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
557 .vsync_len = 6,
558
559 .veq_ena = true, .veq_start_f1 = 0,
560 .veq_start_f2 = 1, .veq_len = 18,
561
562 .vi_end_f1 = 20, .vi_end_f2 = 21,
563 .nbr_end = 240,
564
565 .burst_ena = true,
566 .hburst_start = 72, .hburst_len = 34,
567 .vburst_start_f1 = 9, .vburst_end_f1 = 240,
568 .vburst_start_f2 = 10, .vburst_end_f2 = 240,
569 .vburst_start_f3 = 9, .vburst_end_f3 = 240,
570 .vburst_start_f4 = 10, .vburst_end_f4 = 240,
571
572 /* desired 3.5800000 actual 3.5800000 clock 107.52 */
573 .dda1_inc = 136,
574 .dda2_inc = 7624, .dda2_size = 20013,
575 .dda3_inc = 0, .dda3_size = 0,
576 .sc_reset = TV_SC_RESET_EVERY_4,
577 .pal_burst = false,
578
579 .composite_levels = &pal_m_levels_composite,
580 .composite_color = &pal_m_csc_composite,
581 .svideo_levels = &pal_m_levels_svideo,
582 .svideo_color = &pal_m_csc_svideo,
583
584 .filter_table = filter_table,
585 },
586 {
587 /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
588 .name = "PAL-N",
589 .clock = 107520,
590 .refresh = 25000,
591 .oversample = TV_OVERSAMPLE_8X,
592 .component_only = 0,
593
594 .hsync_end = 64, .hblank_end = 128,
595 .hblank_start = 844, .htotal = 863,
596
597 .progressive = false, .trilevel_sync = false,
598
599
600 .vsync_start_f1 = 6, .vsync_start_f2 = 7,
601 .vsync_len = 6,
602
603 .veq_ena = true, .veq_start_f1 = 0,
604 .veq_start_f2 = 1, .veq_len = 18,
605
606 .vi_end_f1 = 24, .vi_end_f2 = 25,
607 .nbr_end = 286,
608
609 .burst_ena = true,
610 .hburst_start = 73, .hburst_len = 34,
611 .vburst_start_f1 = 8, .vburst_end_f1 = 285,
612 .vburst_start_f2 = 8, .vburst_end_f2 = 286,
613 .vburst_start_f3 = 9, .vburst_end_f3 = 286,
614 .vburst_start_f4 = 9, .vburst_end_f4 = 285,
615
616
617 /* desired 4.4336180 actual 4.4336180 clock 107.52 */
618 .dda1_inc = 168,
619 .dda2_inc = 18557, .dda2_size = 20625,
620 .dda3_inc = 0, .dda3_size = 0,
621 .sc_reset = TV_SC_RESET_EVERY_8,
622 .pal_burst = true,
623
624 .composite_levels = &pal_n_levels_composite,
625 .composite_color = &pal_n_csc_composite,
626 .svideo_levels = &pal_n_levels_svideo,
627 .svideo_color = &pal_n_csc_svideo,
628
629 .filter_table = filter_table,
630 },
631 {
632 /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */
633 .name = "PAL",
634 .clock = 107520,
635 .refresh = 25000,
636 .oversample = TV_OVERSAMPLE_8X,
637 .component_only = 0,
638
639 .hsync_end = 64, .hblank_end = 128,
640 .hblank_start = 844, .htotal = 863,
641
642 .progressive = false, .trilevel_sync = false,
643
644 .vsync_start_f1 = 5, .vsync_start_f2 = 6,
645 .vsync_len = 5,
646
647 .veq_ena = true, .veq_start_f1 = 0,
648 .veq_start_f2 = 1, .veq_len = 15,
649
650 .vi_end_f1 = 24, .vi_end_f2 = 25,
651 .nbr_end = 286,
652
653 .burst_ena = true,
654 .hburst_start = 73, .hburst_len = 32,
655 .vburst_start_f1 = 8, .vburst_end_f1 = 285,
656 .vburst_start_f2 = 8, .vburst_end_f2 = 286,
657 .vburst_start_f3 = 9, .vburst_end_f3 = 286,
658 .vburst_start_f4 = 9, .vburst_end_f4 = 285,
659
660 /* desired 4.4336180 actual 4.4336180 clock 107.52 */
661 .dda1_inc = 168,
662 .dda2_inc = 18557, .dda2_size = 20625,
663 .dda3_inc = 0, .dda3_size = 0,
664 .sc_reset = TV_SC_RESET_EVERY_8,
665 .pal_burst = true,
666
667 .composite_levels = &pal_levels_composite,
668 .composite_color = &pal_csc_composite,
669 .svideo_levels = &pal_levels_svideo,
670 .svideo_color = &pal_csc_svideo,
671
672 .filter_table = filter_table,
673 },
674 {
675 .name = "480p@59.94Hz",
676 .clock = 107520,
677 .refresh = 59940,
678 .oversample = TV_OVERSAMPLE_4X,
679 .component_only = 1,
680
681 .hsync_end = 64, .hblank_end = 122,
682 .hblank_start = 842, .htotal = 857,
683
684 .progressive = true,.trilevel_sync = false,
685
686 .vsync_start_f1 = 12, .vsync_start_f2 = 12,
687 .vsync_len = 12,
688
689 .veq_ena = false,
690
691 .vi_end_f1 = 44, .vi_end_f2 = 44,
692 .nbr_end = 496,
693
694 .burst_ena = false,
695
696 .filter_table = filter_table,
697 },
698 {
699 .name = "480p@60Hz",
700 .clock = 107520,
701 .refresh = 60000,
702 .oversample = TV_OVERSAMPLE_4X,
703 .component_only = 1,
704
705 .hsync_end = 64, .hblank_end = 122,
706 .hblank_start = 842, .htotal = 856,
707
708 .progressive = true,.trilevel_sync = false,
709
710 .vsync_start_f1 = 12, .vsync_start_f2 = 12,
711 .vsync_len = 12,
712
713 .veq_ena = false,
714
715 .vi_end_f1 = 44, .vi_end_f2 = 44,
716 .nbr_end = 496,
717
718 .burst_ena = false,
719
720 .filter_table = filter_table,
721 },
722 {
723 .name = "576p",
724 .clock = 107520,
725 .refresh = 50000,
726 .oversample = TV_OVERSAMPLE_4X,
727 .component_only = 1,
728
729 .hsync_end = 64, .hblank_end = 139,
730 .hblank_start = 859, .htotal = 863,
731
732 .progressive = true, .trilevel_sync = false,
733
734 .vsync_start_f1 = 10, .vsync_start_f2 = 10,
735 .vsync_len = 10,
736
737 .veq_ena = false,
738
739 .vi_end_f1 = 48, .vi_end_f2 = 48,
740 .nbr_end = 575,
741
742 .burst_ena = false,
743
744 .filter_table = filter_table,
745 },
746 {
747 .name = "720p@60Hz",
748 .clock = 148800,
749 .refresh = 60000,
750 .oversample = TV_OVERSAMPLE_2X,
751 .component_only = 1,
752
753 .hsync_end = 80, .hblank_end = 300,
754 .hblank_start = 1580, .htotal = 1649,
755
756 .progressive = true, .trilevel_sync = true,
757
758 .vsync_start_f1 = 10, .vsync_start_f2 = 10,
759 .vsync_len = 10,
760
761 .veq_ena = false,
762
763 .vi_end_f1 = 29, .vi_end_f2 = 29,
764 .nbr_end = 719,
765
766 .burst_ena = false,
767
768 .filter_table = filter_table,
769 },
770 {
771 .name = "720p@59.94Hz",
772 .clock = 148800,
773 .refresh = 59940,
774 .oversample = TV_OVERSAMPLE_2X,
775 .component_only = 1,
776
777 .hsync_end = 80, .hblank_end = 300,
778 .hblank_start = 1580, .htotal = 1651,
779
780 .progressive = true, .trilevel_sync = true,
781
782 .vsync_start_f1 = 10, .vsync_start_f2 = 10,
783 .vsync_len = 10,
784
785 .veq_ena = false,
786
787 .vi_end_f1 = 29, .vi_end_f2 = 29,
788 .nbr_end = 719,
789
790 .burst_ena = false,
791
792 .filter_table = filter_table,
793 },
794 {
795 .name = "720p@50Hz",
796 .clock = 148800,
797 .refresh = 50000,
798 .oversample = TV_OVERSAMPLE_2X,
799 .component_only = 1,
800
801 .hsync_end = 80, .hblank_end = 300,
802 .hblank_start = 1580, .htotal = 1979,
803
804 .progressive = true, .trilevel_sync = true,
805
806 .vsync_start_f1 = 10, .vsync_start_f2 = 10,
807 .vsync_len = 10,
808
809 .veq_ena = false,
810
811 .vi_end_f1 = 29, .vi_end_f2 = 29,
812 .nbr_end = 719,
813
814 .burst_ena = false,
815
816 .filter_table = filter_table,
817 .max_srcw = 800
818 },
819 {
820 .name = "1080i@50Hz",
821 .clock = 148800,
822 .refresh = 25000,
823 .oversample = TV_OVERSAMPLE_2X,
824 .component_only = 1,
825
826 .hsync_end = 88, .hblank_end = 235,
827 .hblank_start = 2155, .htotal = 2639,
828
829 .progressive = false, .trilevel_sync = true,
830
831 .vsync_start_f1 = 4, .vsync_start_f2 = 5,
832 .vsync_len = 10,
833
834 .veq_ena = true, .veq_start_f1 = 4,
835 .veq_start_f2 = 4, .veq_len = 10,
836
837
838 .vi_end_f1 = 21, .vi_end_f2 = 22,
839 .nbr_end = 539,
840
841 .burst_ena = false,
842
843 .filter_table = filter_table,
844 },
845 {
846 .name = "1080i@60Hz",
847 .clock = 148800,
848 .refresh = 30000,
849 .oversample = TV_OVERSAMPLE_2X,
850 .component_only = 1,
851
852 .hsync_end = 88, .hblank_end = 235,
853 .hblank_start = 2155, .htotal = 2199,
854
855 .progressive = false, .trilevel_sync = true,
856
857 .vsync_start_f1 = 4, .vsync_start_f2 = 5,
858 .vsync_len = 10,
859
860 .veq_ena = true, .veq_start_f1 = 4,
861 .veq_start_f2 = 4, .veq_len = 10,
862
863
864 .vi_end_f1 = 21, .vi_end_f2 = 22,
865 .nbr_end = 539,
866
867 .burst_ena = false,
868
869 .filter_table = filter_table,
870 },
871 {
872 .name = "1080i@59.94Hz",
873 .clock = 148800,
874 .refresh = 29970,
875 .oversample = TV_OVERSAMPLE_2X,
876 .component_only = 1,
877
878 .hsync_end = 88, .hblank_end = 235,
879 .hblank_start = 2155, .htotal = 2200,
880
881 .progressive = false, .trilevel_sync = true,
882
883 .vsync_start_f1 = 4, .vsync_start_f2 = 5,
884 .vsync_len = 10,
885
886 .veq_ena = true, .veq_start_f1 = 4,
887 .veq_start_f2 = 4, .veq_len = 10,
888
889
890 .vi_end_f1 = 21, .vi_end_f2 = 22,
891 .nbr_end = 539,
892
893 .burst_ena = false,
894
895 .filter_table = filter_table,
896 },
897};
898
899#define NUM_TV_MODES sizeof(tv_modes) / sizeof (tv_modes[0])
900
901static void
902intel_tv_dpms(struct drm_encoder *encoder, int mode)
903{
904 struct drm_device *dev = encoder->dev;
905 struct drm_i915_private *dev_priv = dev->dev_private;
906
907 switch(mode) {
908 case DRM_MODE_DPMS_ON:
909 I915_WRITE(TV_CTL, I915_READ(TV_CTL) | TV_ENC_ENABLE);
910 break;
911 case DRM_MODE_DPMS_STANDBY:
912 case DRM_MODE_DPMS_SUSPEND:
913 case DRM_MODE_DPMS_OFF:
914 I915_WRITE(TV_CTL, I915_READ(TV_CTL) & ~TV_ENC_ENABLE);
915 break;
916 }
917}
918
919static void
920intel_tv_save(struct drm_connector *connector)
921{
922 struct drm_device *dev = connector->dev;
923 struct drm_i915_private *dev_priv = dev->dev_private;
924 struct intel_output *intel_output = to_intel_output(connector);
925 struct intel_tv_priv *tv_priv = intel_output->dev_priv;
926 int i;
927
928 tv_priv->save_TV_H_CTL_1 = I915_READ(TV_H_CTL_1);
929 tv_priv->save_TV_H_CTL_2 = I915_READ(TV_H_CTL_2);
930 tv_priv->save_TV_H_CTL_3 = I915_READ(TV_H_CTL_3);
931 tv_priv->save_TV_V_CTL_1 = I915_READ(TV_V_CTL_1);
932 tv_priv->save_TV_V_CTL_2 = I915_READ(TV_V_CTL_2);
933 tv_priv->save_TV_V_CTL_3 = I915_READ(TV_V_CTL_3);
934 tv_priv->save_TV_V_CTL_4 = I915_READ(TV_V_CTL_4);
935 tv_priv->save_TV_V_CTL_5 = I915_READ(TV_V_CTL_5);
936 tv_priv->save_TV_V_CTL_6 = I915_READ(TV_V_CTL_6);
937 tv_priv->save_TV_V_CTL_7 = I915_READ(TV_V_CTL_7);
938 tv_priv->save_TV_SC_CTL_1 = I915_READ(TV_SC_CTL_1);
939 tv_priv->save_TV_SC_CTL_2 = I915_READ(TV_SC_CTL_2);
940 tv_priv->save_TV_SC_CTL_3 = I915_READ(TV_SC_CTL_3);
941
942 tv_priv->save_TV_CSC_Y = I915_READ(TV_CSC_Y);
943 tv_priv->save_TV_CSC_Y2 = I915_READ(TV_CSC_Y2);
944 tv_priv->save_TV_CSC_U = I915_READ(TV_CSC_U);
945 tv_priv->save_TV_CSC_U2 = I915_READ(TV_CSC_U2);
946 tv_priv->save_TV_CSC_V = I915_READ(TV_CSC_V);
947 tv_priv->save_TV_CSC_V2 = I915_READ(TV_CSC_V2);
948 tv_priv->save_TV_CLR_KNOBS = I915_READ(TV_CLR_KNOBS);
949 tv_priv->save_TV_CLR_LEVEL = I915_READ(TV_CLR_LEVEL);
950 tv_priv->save_TV_WIN_POS = I915_READ(TV_WIN_POS);
951 tv_priv->save_TV_WIN_SIZE = I915_READ(TV_WIN_SIZE);
952 tv_priv->save_TV_FILTER_CTL_1 = I915_READ(TV_FILTER_CTL_1);
953 tv_priv->save_TV_FILTER_CTL_2 = I915_READ(TV_FILTER_CTL_2);
954 tv_priv->save_TV_FILTER_CTL_3 = I915_READ(TV_FILTER_CTL_3);
955
956 for (i = 0; i < 60; i++)
957 tv_priv->save_TV_H_LUMA[i] = I915_READ(TV_H_LUMA_0 + (i <<2));
958 for (i = 0; i < 60; i++)
959 tv_priv->save_TV_H_CHROMA[i] = I915_READ(TV_H_CHROMA_0 + (i <<2));
960 for (i = 0; i < 43; i++)
961 tv_priv->save_TV_V_LUMA[i] = I915_READ(TV_V_LUMA_0 + (i <<2));
962 for (i = 0; i < 43; i++)
963 tv_priv->save_TV_V_CHROMA[i] = I915_READ(TV_V_CHROMA_0 + (i <<2));
964
965 tv_priv->save_TV_DAC = I915_READ(TV_DAC);
966 tv_priv->save_TV_CTL = I915_READ(TV_CTL);
967}
968
969static void
970intel_tv_restore(struct drm_connector *connector)
971{
972 struct drm_device *dev = connector->dev;
973 struct drm_i915_private *dev_priv = dev->dev_private;
974 struct intel_output *intel_output = to_intel_output(connector);
975 struct intel_tv_priv *tv_priv = intel_output->dev_priv;
976 struct drm_crtc *crtc = connector->encoder->crtc;
977 struct intel_crtc *intel_crtc;
978 int i;
979
980 /* FIXME: No CRTC? */
981 if (!crtc)
982 return;
983
984 intel_crtc = to_intel_crtc(crtc);
985 I915_WRITE(TV_H_CTL_1, tv_priv->save_TV_H_CTL_1);
986 I915_WRITE(TV_H_CTL_2, tv_priv->save_TV_H_CTL_2);
987 I915_WRITE(TV_H_CTL_3, tv_priv->save_TV_H_CTL_3);
988 I915_WRITE(TV_V_CTL_1, tv_priv->save_TV_V_CTL_1);
989 I915_WRITE(TV_V_CTL_2, tv_priv->save_TV_V_CTL_2);
990 I915_WRITE(TV_V_CTL_3, tv_priv->save_TV_V_CTL_3);
991 I915_WRITE(TV_V_CTL_4, tv_priv->save_TV_V_CTL_4);
992 I915_WRITE(TV_V_CTL_5, tv_priv->save_TV_V_CTL_5);
993 I915_WRITE(TV_V_CTL_6, tv_priv->save_TV_V_CTL_6);
994 I915_WRITE(TV_V_CTL_7, tv_priv->save_TV_V_CTL_7);
995 I915_WRITE(TV_SC_CTL_1, tv_priv->save_TV_SC_CTL_1);
996 I915_WRITE(TV_SC_CTL_2, tv_priv->save_TV_SC_CTL_2);
997 I915_WRITE(TV_SC_CTL_3, tv_priv->save_TV_SC_CTL_3);
998
999 I915_WRITE(TV_CSC_Y, tv_priv->save_TV_CSC_Y);
1000 I915_WRITE(TV_CSC_Y2, tv_priv->save_TV_CSC_Y2);
1001 I915_WRITE(TV_CSC_U, tv_priv->save_TV_CSC_U);
1002 I915_WRITE(TV_CSC_U2, tv_priv->save_TV_CSC_U2);
1003 I915_WRITE(TV_CSC_V, tv_priv->save_TV_CSC_V);
1004 I915_WRITE(TV_CSC_V2, tv_priv->save_TV_CSC_V2);
1005 I915_WRITE(TV_CLR_KNOBS, tv_priv->save_TV_CLR_KNOBS);
1006 I915_WRITE(TV_CLR_LEVEL, tv_priv->save_TV_CLR_LEVEL);
1007
1008 {
1009 int pipeconf_reg = (intel_crtc->pipe == 0) ?
1010 PIPEACONF : PIPEBCONF;
1011 int dspcntr_reg = (intel_crtc->plane == 0) ?
1012 DSPACNTR : DSPBCNTR;
1013 int pipeconf = I915_READ(pipeconf_reg);
1014 int dspcntr = I915_READ(dspcntr_reg);
1015 int dspbase_reg = (intel_crtc->plane == 0) ?
1016 DSPAADDR : DSPBADDR;
1017 /* Pipe must be off here */
1018 I915_WRITE(dspcntr_reg, dspcntr & ~DISPLAY_PLANE_ENABLE);
1019 /* Flush the plane changes */
1020 I915_WRITE(dspbase_reg, I915_READ(dspbase_reg));
1021
1022 if (!IS_I9XX(dev)) {
1023 /* Wait for vblank for the disable to take effect */
1024 intel_wait_for_vblank(dev);
1025 }
1026
1027 I915_WRITE(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE);
1028 /* Wait for vblank for the disable to take effect. */
1029 intel_wait_for_vblank(dev);
1030
1031 /* Filter ctl must be set before TV_WIN_SIZE */
1032 I915_WRITE(TV_FILTER_CTL_1, tv_priv->save_TV_FILTER_CTL_1);
1033 I915_WRITE(TV_FILTER_CTL_2, tv_priv->save_TV_FILTER_CTL_2);
1034 I915_WRITE(TV_FILTER_CTL_3, tv_priv->save_TV_FILTER_CTL_3);
1035 I915_WRITE(TV_WIN_POS, tv_priv->save_TV_WIN_POS);
1036 I915_WRITE(TV_WIN_SIZE, tv_priv->save_TV_WIN_SIZE);
1037 I915_WRITE(pipeconf_reg, pipeconf);
1038 I915_WRITE(dspcntr_reg, dspcntr);
1039 /* Flush the plane changes */
1040 I915_WRITE(dspbase_reg, I915_READ(dspbase_reg));
1041 }
1042
1043 for (i = 0; i < 60; i++)
1044 I915_WRITE(TV_H_LUMA_0 + (i <<2), tv_priv->save_TV_H_LUMA[i]);
1045 for (i = 0; i < 60; i++)
1046 I915_WRITE(TV_H_CHROMA_0 + (i <<2), tv_priv->save_TV_H_CHROMA[i]);
1047 for (i = 0; i < 43; i++)
1048 I915_WRITE(TV_V_LUMA_0 + (i <<2), tv_priv->save_TV_V_LUMA[i]);
1049 for (i = 0; i < 43; i++)
1050 I915_WRITE(TV_V_CHROMA_0 + (i <<2), tv_priv->save_TV_V_CHROMA[i]);
1051
1052 I915_WRITE(TV_DAC, tv_priv->save_TV_DAC);
1053 I915_WRITE(TV_CTL, tv_priv->save_TV_CTL);
1054}
1055
1056static const struct tv_mode *
1057intel_tv_mode_lookup (char *tv_format)
1058{
1059 int i;
1060
1061 for (i = 0; i < sizeof(tv_modes) / sizeof (tv_modes[0]); i++) {
1062 const struct tv_mode *tv_mode = &tv_modes[i];
1063
1064 if (!strcmp(tv_format, tv_mode->name))
1065 return tv_mode;
1066 }
1067 return NULL;
1068}
1069
1070static const struct tv_mode *
1071intel_tv_mode_find (struct intel_output *intel_output)
1072{
1073 struct intel_tv_priv *tv_priv = intel_output->dev_priv;
1074
1075 return intel_tv_mode_lookup(tv_priv->tv_format);
1076}
1077
1078static enum drm_mode_status
1079intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode)
1080{
1081 struct intel_output *intel_output = to_intel_output(connector);
1082 const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
1083
1084 /* Ensure TV refresh is close to desired refresh */
1085 if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode)) < 1)
1086 return MODE_OK;
1087 return MODE_CLOCK_RANGE;
1088}
1089
1090
1091static bool
1092intel_tv_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
1093 struct drm_display_mode *adjusted_mode)
1094{
1095 struct drm_device *dev = encoder->dev;
1096 struct drm_mode_config *drm_config = &dev->mode_config;
1097 struct intel_output *intel_output = enc_to_intel_output(encoder);
1098 const struct tv_mode *tv_mode = intel_tv_mode_find (intel_output);
1099 struct drm_encoder *other_encoder;
1100
1101 if (!tv_mode)
1102 return false;
1103
1104 /* FIXME: lock encoder list */
1105 list_for_each_entry(other_encoder, &drm_config->encoder_list, head) {
1106 if (other_encoder != encoder &&
1107 other_encoder->crtc == encoder->crtc)
1108 return false;
1109 }
1110
1111 adjusted_mode->clock = tv_mode->clock;
1112 return true;
1113}
1114
1115static void
1116intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
1117 struct drm_display_mode *adjusted_mode)
1118{
1119 struct drm_device *dev = encoder->dev;
1120 struct drm_i915_private *dev_priv = dev->dev_private;
1121 struct drm_crtc *crtc = encoder->crtc;
1122 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1123 struct intel_output *intel_output = enc_to_intel_output(encoder);
1124 struct intel_tv_priv *tv_priv = intel_output->dev_priv;
1125 const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
1126 u32 tv_ctl;
1127 u32 hctl1, hctl2, hctl3;
1128 u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
1129 u32 scctl1, scctl2, scctl3;
1130 int i, j;
1131 const struct video_levels *video_levels;
1132 const struct color_conversion *color_conversion;
1133 bool burst_ena;
1134
1135 if (!tv_mode)
1136 return; /* can't happen (mode_prepare prevents this) */
1137
1138 tv_ctl = 0;
1139
1140 switch (tv_priv->type) {
1141 default:
1142 case DRM_MODE_CONNECTOR_Unknown:
1143 case DRM_MODE_CONNECTOR_Composite:
1144 tv_ctl |= TV_ENC_OUTPUT_COMPOSITE;
1145 video_levels = tv_mode->composite_levels;
1146 color_conversion = tv_mode->composite_color;
1147 burst_ena = tv_mode->burst_ena;
1148 break;
1149 case DRM_MODE_CONNECTOR_Component:
1150 tv_ctl |= TV_ENC_OUTPUT_COMPONENT;
1151 video_levels = &component_levels;
1152 if (tv_mode->burst_ena)
1153 color_conversion = &sdtv_csc_yprpb;
1154 else
1155 color_conversion = &hdtv_csc_yprpb;
1156 burst_ena = false;
1157 break;
1158 case DRM_MODE_CONNECTOR_SVIDEO:
1159 tv_ctl |= TV_ENC_OUTPUT_SVIDEO;
1160 video_levels = tv_mode->svideo_levels;
1161 color_conversion = tv_mode->svideo_color;
1162 burst_ena = tv_mode->burst_ena;
1163 break;
1164 }
1165 hctl1 = (tv_mode->hsync_end << TV_HSYNC_END_SHIFT) |
1166 (tv_mode->htotal << TV_HTOTAL_SHIFT);
1167
1168 hctl2 = (tv_mode->hburst_start << 16) |
1169 (tv_mode->hburst_len << TV_HBURST_LEN_SHIFT);
1170
1171 if (burst_ena)
1172 hctl2 |= TV_BURST_ENA;
1173
1174 hctl3 = (tv_mode->hblank_start << TV_HBLANK_START_SHIFT) |
1175 (tv_mode->hblank_end << TV_HBLANK_END_SHIFT);
1176
1177 vctl1 = (tv_mode->nbr_end << TV_NBR_END_SHIFT) |
1178 (tv_mode->vi_end_f1 << TV_VI_END_F1_SHIFT) |
1179 (tv_mode->vi_end_f2 << TV_VI_END_F2_SHIFT);
1180
1181 vctl2 = (tv_mode->vsync_len << TV_VSYNC_LEN_SHIFT) |
1182 (tv_mode->vsync_start_f1 << TV_VSYNC_START_F1_SHIFT) |
1183 (tv_mode->vsync_start_f2 << TV_VSYNC_START_F2_SHIFT);
1184
1185 vctl3 = (tv_mode->veq_len << TV_VEQ_LEN_SHIFT) |
1186 (tv_mode->veq_start_f1 << TV_VEQ_START_F1_SHIFT) |
1187 (tv_mode->veq_start_f2 << TV_VEQ_START_F2_SHIFT);
1188
1189 if (tv_mode->veq_ena)
1190 vctl3 |= TV_EQUAL_ENA;
1191
1192 vctl4 = (tv_mode->vburst_start_f1 << TV_VBURST_START_F1_SHIFT) |
1193 (tv_mode->vburst_end_f1 << TV_VBURST_END_F1_SHIFT);
1194
1195 vctl5 = (tv_mode->vburst_start_f2 << TV_VBURST_START_F2_SHIFT) |
1196 (tv_mode->vburst_end_f2 << TV_VBURST_END_F2_SHIFT);
1197
1198 vctl6 = (tv_mode->vburst_start_f3 << TV_VBURST_START_F3_SHIFT) |
1199 (tv_mode->vburst_end_f3 << TV_VBURST_END_F3_SHIFT);
1200
1201 vctl7 = (tv_mode->vburst_start_f4 << TV_VBURST_START_F4_SHIFT) |
1202 (tv_mode->vburst_end_f4 << TV_VBURST_END_F4_SHIFT);
1203
1204 if (intel_crtc->pipe == 1)
1205 tv_ctl |= TV_ENC_PIPEB_SELECT;
1206 tv_ctl |= tv_mode->oversample;
1207
1208 if (tv_mode->progressive)
1209 tv_ctl |= TV_PROGRESSIVE;
1210 if (tv_mode->trilevel_sync)
1211 tv_ctl |= TV_TRILEVEL_SYNC;
1212 if (tv_mode->pal_burst)
1213 tv_ctl |= TV_PAL_BURST;
1214 scctl1 = 0;
1215 /* dda1 implies valid video levels */
1216 if (tv_mode->dda1_inc) {
1217 scctl1 |= TV_SC_DDA1_EN;
1218 scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT;
1219 }
1220
1221 if (tv_mode->dda2_inc)
1222 scctl1 |= TV_SC_DDA2_EN;
1223
1224 if (tv_mode->dda3_inc)
1225 scctl1 |= TV_SC_DDA3_EN;
1226
1227 scctl1 |= tv_mode->sc_reset;
1228 scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT;
1229
1230 scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT |
1231 tv_mode->dda2_inc << TV_SCDDA2_INC_SHIFT;
1232
1233 scctl3 = tv_mode->dda3_size << TV_SCDDA3_SIZE_SHIFT |
1234 tv_mode->dda3_inc << TV_SCDDA3_INC_SHIFT;
1235
1236 /* Enable two fixes for the chips that need them. */
1237 if (dev->pci_device < 0x2772)
1238 tv_ctl |= TV_ENC_C0_FIX | TV_ENC_SDP_FIX;
1239
1240 I915_WRITE(TV_H_CTL_1, hctl1);
1241 I915_WRITE(TV_H_CTL_2, hctl2);
1242 I915_WRITE(TV_H_CTL_3, hctl3);
1243 I915_WRITE(TV_V_CTL_1, vctl1);
1244 I915_WRITE(TV_V_CTL_2, vctl2);
1245 I915_WRITE(TV_V_CTL_3, vctl3);
1246 I915_WRITE(TV_V_CTL_4, vctl4);
1247 I915_WRITE(TV_V_CTL_5, vctl5);
1248 I915_WRITE(TV_V_CTL_6, vctl6);
1249 I915_WRITE(TV_V_CTL_7, vctl7);
1250 I915_WRITE(TV_SC_CTL_1, scctl1);
1251 I915_WRITE(TV_SC_CTL_2, scctl2);
1252 I915_WRITE(TV_SC_CTL_3, scctl3);
1253
1254 if (color_conversion) {
1255 I915_WRITE(TV_CSC_Y, (color_conversion->ry << 16) |
1256 color_conversion->gy);
1257 I915_WRITE(TV_CSC_Y2,(color_conversion->by << 16) |
1258 color_conversion->ay);
1259 I915_WRITE(TV_CSC_U, (color_conversion->ru << 16) |
1260 color_conversion->gu);
1261 I915_WRITE(TV_CSC_U2, (color_conversion->bu << 16) |
1262 color_conversion->au);
1263 I915_WRITE(TV_CSC_V, (color_conversion->rv << 16) |
1264 color_conversion->gv);
1265 I915_WRITE(TV_CSC_V2, (color_conversion->bv << 16) |
1266 color_conversion->av);
1267 }
1268
1269 I915_WRITE(TV_CLR_KNOBS, 0x00606000);
1270 if (video_levels)
1271 I915_WRITE(TV_CLR_LEVEL,
1272 ((video_levels->black << TV_BLACK_LEVEL_SHIFT) |
1273 (video_levels->blank << TV_BLANK_LEVEL_SHIFT)));
1274 {
1275 int pipeconf_reg = (intel_crtc->pipe == 0) ?
1276 PIPEACONF : PIPEBCONF;
1277 int dspcntr_reg = (intel_crtc->plane == 0) ?
1278 DSPACNTR : DSPBCNTR;
1279 int pipeconf = I915_READ(pipeconf_reg);
1280 int dspcntr = I915_READ(dspcntr_reg);
1281 int dspbase_reg = (intel_crtc->plane == 0) ?
1282 DSPAADDR : DSPBADDR;
1283 int xpos = 0x0, ypos = 0x0;
1284 unsigned int xsize, ysize;
1285 /* Pipe must be off here */
1286 I915_WRITE(dspcntr_reg, dspcntr & ~DISPLAY_PLANE_ENABLE);
1287 /* Flush the plane changes */
1288 I915_WRITE(dspbase_reg, I915_READ(dspbase_reg));
1289
1290 /* Wait for vblank for the disable to take effect */
1291 if (!IS_I9XX(dev))
1292 intel_wait_for_vblank(dev);
1293
1294 I915_WRITE(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE);
1295 /* Wait for vblank for the disable to take effect. */
1296 intel_wait_for_vblank(dev);
1297
1298 /* Filter ctl must be set before TV_WIN_SIZE */
1299 I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE);
1300 xsize = tv_mode->hblank_start - tv_mode->hblank_end;
1301 if (tv_mode->progressive)
1302 ysize = tv_mode->nbr_end + 1;
1303 else
1304 ysize = 2*tv_mode->nbr_end + 1;
1305
1306 xpos += tv_priv->margin[TV_MARGIN_LEFT];
1307 ypos += tv_priv->margin[TV_MARGIN_TOP];
1308 xsize -= (tv_priv->margin[TV_MARGIN_LEFT] +
1309 tv_priv->margin[TV_MARGIN_RIGHT]);
1310 ysize -= (tv_priv->margin[TV_MARGIN_TOP] +
1311 tv_priv->margin[TV_MARGIN_BOTTOM]);
1312 I915_WRITE(TV_WIN_POS, (xpos<<16)|ypos);
1313 I915_WRITE(TV_WIN_SIZE, (xsize<<16)|ysize);
1314
1315 I915_WRITE(pipeconf_reg, pipeconf);
1316 I915_WRITE(dspcntr_reg, dspcntr);
1317 /* Flush the plane changes */
1318 I915_WRITE(dspbase_reg, I915_READ(dspbase_reg));
1319 }
1320
1321 j = 0;
1322 for (i = 0; i < 60; i++)
1323 I915_WRITE(TV_H_LUMA_0 + (i<<2), tv_mode->filter_table[j++]);
1324 for (i = 0; i < 60; i++)
1325 I915_WRITE(TV_H_CHROMA_0 + (i<<2), tv_mode->filter_table[j++]);
1326 for (i = 0; i < 43; i++)
1327 I915_WRITE(TV_V_LUMA_0 + (i<<2), tv_mode->filter_table[j++]);
1328 for (i = 0; i < 43; i++)
1329 I915_WRITE(TV_V_CHROMA_0 + (i<<2), tv_mode->filter_table[j++]);
1330 I915_WRITE(TV_DAC, 0);
1331 I915_WRITE(TV_CTL, tv_ctl);
1332}
1333
1334static const struct drm_display_mode reported_modes[] = {
1335 {
1336 .name = "NTSC 480i",
1337 .clock = 107520,
1338 .hdisplay = 1280,
1339 .hsync_start = 1368,
1340 .hsync_end = 1496,
1341 .htotal = 1712,
1342
1343 .vdisplay = 1024,
1344 .vsync_start = 1027,
1345 .vsync_end = 1034,
1346 .vtotal = 1104,
1347 .type = DRM_MODE_TYPE_DRIVER,
1348 },
1349};
1350
1351/**
1352 * Detects TV presence by checking for load.
1353 *
1354 * Requires that the current pipe's DPLL is active.
1355
1356 * \return true if TV is connected.
1357 * \return false if TV is disconnected.
1358 */
1359static int
1360intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output)
1361{
1362 struct drm_encoder *encoder = &intel_output->enc;
1363 struct drm_device *dev = encoder->dev;
1364 struct drm_i915_private *dev_priv = dev->dev_private;
1365 unsigned long irqflags;
1366 u32 tv_ctl, save_tv_ctl;
1367 u32 tv_dac, save_tv_dac;
1368 int type = DRM_MODE_CONNECTOR_Unknown;
1369
1370 tv_dac = I915_READ(TV_DAC);
1371
1372 /* Disable TV interrupts around load detect or we'll recurse */
1373 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
1374 i915_disable_pipestat(dev_priv, 0, PIPE_HOTPLUG_INTERRUPT_ENABLE |
1375 PIPE_HOTPLUG_TV_INTERRUPT_ENABLE);
1376 spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
1377
1378 /*
1379 * Detect TV by polling)
1380 */
1381 if (intel_output->load_detect_temp) {
1382 /* TV not currently running, prod it with destructive detect */
1383 save_tv_dac = tv_dac;
1384 tv_ctl = I915_READ(TV_CTL);
1385 save_tv_ctl = tv_ctl;
1386 tv_ctl &= ~TV_ENC_ENABLE;
1387 tv_ctl &= ~TV_TEST_MODE_MASK;
1388 tv_ctl |= TV_TEST_MODE_MONITOR_DETECT;
1389 tv_dac &= ~TVDAC_SENSE_MASK;
1390 tv_dac |= (TVDAC_STATE_CHG_EN |
1391 TVDAC_A_SENSE_CTL |
1392 TVDAC_B_SENSE_CTL |
1393 TVDAC_C_SENSE_CTL |
1394 DAC_CTL_OVERRIDE |
1395 DAC_A_0_7_V |
1396 DAC_B_0_7_V |
1397 DAC_C_0_7_V);
1398 I915_WRITE(TV_CTL, tv_ctl);
1399 I915_WRITE(TV_DAC, tv_dac);
1400 intel_wait_for_vblank(dev);
1401 tv_dac = I915_READ(TV_DAC);
1402 I915_WRITE(TV_DAC, save_tv_dac);
1403 I915_WRITE(TV_CTL, save_tv_ctl);
1404 }
1405 /*
1406 * A B C
1407 * 0 1 1 Composite
1408 * 1 0 X svideo
1409 * 0 0 0 Component
1410 */
1411 if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) {
1412 DRM_DEBUG("Detected Composite TV connection\n");
1413 type = DRM_MODE_CONNECTOR_Composite;
1414 } else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) {
1415 DRM_DEBUG("Detected S-Video TV connection\n");
1416 type = DRM_MODE_CONNECTOR_SVIDEO;
1417 } else if ((tv_dac & TVDAC_SENSE_MASK) == 0) {
1418 DRM_DEBUG("Detected Component TV connection\n");
1419 type = DRM_MODE_CONNECTOR_Component;
1420 } else {
1421 DRM_DEBUG("No TV connection detected\n");
1422 type = -1;
1423 }
1424
1425 /* Restore interrupt config */
1426 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
1427 i915_enable_pipestat(dev_priv, 0, PIPE_HOTPLUG_INTERRUPT_ENABLE |
1428 PIPE_HOTPLUG_TV_INTERRUPT_ENABLE);
1429 spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
1430
1431 return type;
1432}
1433
1434/**
1435 * Detect the TV connection.
1436 *
1437 * Currently this always returns CONNECTOR_STATUS_UNKNOWN, as we need to be sure
1438 * we have a pipe programmed in order to probe the TV.
1439 */
1440static enum drm_connector_status
1441intel_tv_detect(struct drm_connector *connector)
1442{
1443 struct drm_crtc *crtc;
1444 struct drm_display_mode mode;
1445 struct intel_output *intel_output = to_intel_output(connector);
1446 struct intel_tv_priv *tv_priv = intel_output->dev_priv;
1447 struct drm_encoder *encoder = &intel_output->enc;
1448 int dpms_mode;
1449 int type = tv_priv->type;
1450
1451 mode = reported_modes[0];
1452 drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V);
1453
1454 if (encoder->crtc) {
1455 type = intel_tv_detect_type(encoder->crtc, intel_output);
1456 } else {
1457 crtc = intel_get_load_detect_pipe(intel_output, &mode, &dpms_mode);
1458 if (crtc) {
1459 type = intel_tv_detect_type(crtc, intel_output);
1460 intel_release_load_detect_pipe(intel_output, dpms_mode);
1461 } else
1462 type = -1;
1463 }
1464
1465 if (type < 0)
1466 return connector_status_disconnected;
1467
1468 return connector_status_connected;
1469}
1470
1471static struct input_res {
1472 char *name;
1473 int w, h;
1474} input_res_table[] =
1475{
1476 {"640x480", 640, 480},
1477 {"800x600", 800, 600},
1478 {"1024x768", 1024, 768},
1479 {"1280x1024", 1280, 1024},
1480 {"848x480", 848, 480},
1481 {"1280x720", 1280, 720},
1482 {"1920x1080", 1920, 1080},
1483};
1484
1485/**
1486 * Stub get_modes function.
1487 *
1488 * This should probably return a set of fixed modes, unless we can figure out
1489 * how to probe modes off of TV connections.
1490 */
1491
1492static int
1493intel_tv_get_modes(struct drm_connector *connector)
1494{
1495 struct drm_display_mode *mode_ptr;
1496 struct intel_output *intel_output = to_intel_output(connector);
1497 const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
1498 int j;
1499
1500 for (j = 0; j < sizeof(input_res_table) / sizeof(input_res_table[0]);
1501 j++) {
1502 struct input_res *input = &input_res_table[j];
1503 unsigned int hactive_s = input->w;
1504 unsigned int vactive_s = input->h;
1505
1506 if (tv_mode->max_srcw && input->w > tv_mode->max_srcw)
1507 continue;
1508
1509 if (input->w > 1024 && (!tv_mode->progressive
1510 && !tv_mode->component_only))
1511 continue;
1512
1513 mode_ptr = drm_calloc(1, sizeof(struct drm_display_mode),
1514 DRM_MEM_DRIVER);
1515 strncpy(mode_ptr->name, input->name, DRM_DISPLAY_MODE_LEN);
1516
1517 mode_ptr->hdisplay = hactive_s;
1518 mode_ptr->hsync_start = hactive_s + 1;
1519 mode_ptr->hsync_end = hactive_s + 64;
1520 if (mode_ptr->hsync_end <= mode_ptr->hsync_start)
1521 mode_ptr->hsync_end = mode_ptr->hsync_start + 1;
1522 mode_ptr->htotal = hactive_s + 96;
1523
1524 mode_ptr->vdisplay = vactive_s;
1525 mode_ptr->vsync_start = vactive_s + 1;
1526 mode_ptr->vsync_end = vactive_s + 32;
1527 if (mode_ptr->vsync_end <= mode_ptr->vsync_start)
1528 mode_ptr->vsync_end = mode_ptr->vsync_start + 1;
1529 mode_ptr->vtotal = vactive_s + 33;
1530
1531 mode_ptr->clock = (int) (tv_mode->refresh *
1532 mode_ptr->vtotal *
1533 mode_ptr->htotal / 1000) / 1000;
1534
1535 mode_ptr->type = DRM_MODE_TYPE_DRIVER;
1536 drm_mode_probed_add(connector, mode_ptr);
1537 }
1538
1539 return 0;
1540}
1541
1542static void
1543intel_tv_destroy (struct drm_connector *connector)
1544{
1545 struct intel_output *intel_output = to_intel_output(connector);
1546
1547 drm_sysfs_connector_remove(connector);
1548 drm_connector_cleanup(connector);
1549 drm_free(intel_output, sizeof(struct intel_output) + sizeof(struct intel_tv_priv),
1550 DRM_MEM_DRIVER);
1551}
1552
1553
1554static int
1555intel_tv_set_property(struct drm_connector *connector, struct drm_property *property,
1556 uint64_t val)
1557{
1558 struct drm_device *dev = connector->dev;
1559 struct intel_output *intel_output = to_intel_output(connector);
1560 struct intel_tv_priv *tv_priv = intel_output->dev_priv;
1561 int ret = 0;
1562
1563 ret = drm_connector_property_set_value(connector, property, val);
1564 if (ret < 0)
1565 goto out;
1566
1567 if (property == dev->mode_config.tv_left_margin_property)
1568 tv_priv->margin[TV_MARGIN_LEFT] = val;
1569 else if (property == dev->mode_config.tv_right_margin_property)
1570 tv_priv->margin[TV_MARGIN_RIGHT] = val;
1571 else if (property == dev->mode_config.tv_top_margin_property)
1572 tv_priv->margin[TV_MARGIN_TOP] = val;
1573 else if (property == dev->mode_config.tv_bottom_margin_property)
1574 tv_priv->margin[TV_MARGIN_BOTTOM] = val;
1575 else if (property == dev->mode_config.tv_mode_property) {
1576 if (val >= NUM_TV_MODES) {
1577 ret = -EINVAL;
1578 goto out;
1579 }
1580 tv_priv->tv_format = tv_modes[val].name;
1581 intel_tv_mode_set(&intel_output->enc, NULL, NULL);
1582 } else {
1583 ret = -EINVAL;
1584 goto out;
1585 }
1586
1587 intel_tv_mode_set(&intel_output->enc, NULL, NULL);
1588out:
1589 return ret;
1590}
1591
1592static const struct drm_encoder_helper_funcs intel_tv_helper_funcs = {
1593 .dpms = intel_tv_dpms,
1594 .mode_fixup = intel_tv_mode_fixup,
1595 .prepare = intel_encoder_prepare,
1596 .mode_set = intel_tv_mode_set,
1597 .commit = intel_encoder_commit,
1598};
1599
1600static const struct drm_connector_funcs intel_tv_connector_funcs = {
1601 .save = intel_tv_save,
1602 .restore = intel_tv_restore,
1603 .detect = intel_tv_detect,
1604 .destroy = intel_tv_destroy,
1605 .set_property = intel_tv_set_property,
1606 .fill_modes = drm_helper_probe_single_connector_modes,
1607};
1608
1609static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = {
1610 .mode_valid = intel_tv_mode_valid,
1611 .get_modes = intel_tv_get_modes,
1612 .best_encoder = intel_best_encoder,
1613};
1614
1615void intel_tv_enc_destroy(struct drm_encoder *encoder)
1616{
1617 drm_encoder_cleanup(encoder);
1618}
1619
1620static const struct drm_encoder_funcs intel_tv_enc_funcs = {
1621 .destroy = intel_tv_enc_destroy,
1622};
1623
1624
1625void
1626intel_tv_init(struct drm_device *dev)
1627{
1628 struct drm_i915_private *dev_priv = dev->dev_private;
1629 struct drm_connector *connector;
1630 struct intel_output *intel_output;
1631 struct intel_tv_priv *tv_priv;
1632 u32 tv_dac_on, tv_dac_off, save_tv_dac;
1633 char **tv_format_names;
1634 int i, initial_mode = 0;
1635
1636 if ((I915_READ(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
1637 return;
1638
1639 /* Even if we have an encoder we may not have a connector */
1640 if (!dev_priv->int_tv_support)
1641 return;
1642
1643 /*
1644 * Sanity check the TV output by checking to see if the
1645 * DAC register holds a value
1646 */
1647 save_tv_dac = I915_READ(TV_DAC);
1648
1649 I915_WRITE(TV_DAC, save_tv_dac | TVDAC_STATE_CHG_EN);
1650 tv_dac_on = I915_READ(TV_DAC);
1651
1652 I915_WRITE(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN);
1653 tv_dac_off = I915_READ(TV_DAC);
1654
1655 I915_WRITE(TV_DAC, save_tv_dac);
1656
1657 /*
1658 * If the register does not hold the state change enable
1659 * bit, (either as a 0 or a 1), assume it doesn't really
1660 * exist
1661 */
1662 if ((tv_dac_on & TVDAC_STATE_CHG_EN) == 0 ||
1663 (tv_dac_off & TVDAC_STATE_CHG_EN) != 0)
1664 return;
1665
1666 intel_output = drm_calloc(1, sizeof(struct intel_output) +
1667 sizeof(struct intel_tv_priv), DRM_MEM_DRIVER);
1668 if (!intel_output) {
1669 return;
1670 }
1671 connector = &intel_output->base;
1672
1673 drm_connector_init(dev, connector, &intel_tv_connector_funcs,
1674 DRM_MODE_CONNECTOR_SVIDEO);
1675
1676 drm_encoder_init(dev, &intel_output->enc, &intel_tv_enc_funcs,
1677 DRM_MODE_ENCODER_TVDAC);
1678
1679 drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
1680 tv_priv = (struct intel_tv_priv *)(intel_output + 1);
1681 intel_output->type = INTEL_OUTPUT_TVOUT;
1682 intel_output->enc.possible_crtcs = ((1 << 0) | (1 << 1));
1683 intel_output->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT);
1684 intel_output->dev_priv = tv_priv;
1685 tv_priv->type = DRM_MODE_CONNECTOR_Unknown;
1686
1687 /* BIOS margin values */
1688 tv_priv->margin[TV_MARGIN_LEFT] = 54;
1689 tv_priv->margin[TV_MARGIN_TOP] = 36;
1690 tv_priv->margin[TV_MARGIN_RIGHT] = 46;
1691 tv_priv->margin[TV_MARGIN_BOTTOM] = 37;
1692
1693 tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL);
1694
1695 drm_encoder_helper_add(&intel_output->enc, &intel_tv_helper_funcs);
1696 drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs);
1697 connector->interlace_allowed = false;
1698 connector->doublescan_allowed = false;
1699
1700 /* Create TV properties then attach current values */
1701 tv_format_names = drm_alloc(sizeof(char *) * NUM_TV_MODES,
1702 DRM_MEM_DRIVER);
1703 if (!tv_format_names)
1704 goto out;
1705 for (i = 0; i < NUM_TV_MODES; i++)
1706 tv_format_names[i] = tv_modes[i].name;
1707 drm_mode_create_tv_properties(dev, NUM_TV_MODES, tv_format_names);
1708
1709 drm_connector_attach_property(connector, dev->mode_config.tv_mode_property,
1710 initial_mode);
1711 drm_connector_attach_property(connector,
1712 dev->mode_config.tv_left_margin_property,
1713 tv_priv->margin[TV_MARGIN_LEFT]);
1714 drm_connector_attach_property(connector,
1715 dev->mode_config.tv_top_margin_property,
1716 tv_priv->margin[TV_MARGIN_TOP]);
1717 drm_connector_attach_property(connector,
1718 dev->mode_config.tv_right_margin_property,
1719 tv_priv->margin[TV_MARGIN_RIGHT]);
1720 drm_connector_attach_property(connector,
1721 dev->mode_config.tv_bottom_margin_property,
1722 tv_priv->margin[TV_MARGIN_BOTTOM]);
1723out:
1724 drm_sysfs_connector_add(connector);
1725}